Line data Source code
1 : /*
2 : * SPDX-License-Identifier: MPL-2.0
3 : *
4 : * This Source Code Form is subject to the terms of the Mozilla Public
5 : * License, v. 2.0. If a copy of the MPL was not distributed with this
6 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7 : *
8 : * Copyright 2024 MonetDB Foundation;
9 : * Copyright August 2008 - 2023 MonetDB B.V.;
10 : * Copyright 1997 - July 2008 CWI.
11 : */
12 :
13 : #include "monetdb_config.h"
14 : #include "sql_mem.h"
15 : #include "sql_stack.h"
16 : #include "sql_statement.h"
17 : #include "sql_gencode.h"
18 : #include "rel_rel.h"
19 : #include "rel_exp.h"
20 : #include "rel_prop.h"
21 :
22 : #include "mal_namespace.h"
23 : #include "mal_builder.h"
24 :
25 : /*
26 : * Some utility routines to generate code
27 : * The equality operator in MAL is '==' instead of '='.
28 : */
29 : static const char *
30 18213 : convertMultiplexMod(const char *mod, const char *op)
31 : {
32 18213 : if (strcmp(op, "=") == 0)
33 0 : return "calc";
34 : return mod;
35 : }
36 :
37 : static const char *
38 260297 : convertMultiplexFcn(const char *op)
39 : {
40 260297 : if (strcmp(op, "=") == 0)
41 34662 : return "==";
42 : return op;
43 : }
44 :
45 : static InstrPtr
46 18136 : multiplex2(MalBlkPtr mb, const char *mod, const char *name, int o1, int o2, int rtype)
47 : {
48 18136 : InstrPtr q = NULL;
49 :
50 18136 : q = newStmt(mb, malRef, multiplexRef);
51 18136 : if (q == NULL)
52 : return NULL;
53 18136 : setVarType(mb, getArg(q, 0), newBatType(rtype));
54 18136 : q = pushStr(mb, q, convertMultiplexMod(mod, name));
55 18136 : q = pushStr(mb, q, convertMultiplexFcn(name));
56 18136 : q = pushArgument(mb, q, o1);
57 18136 : q = pushArgument(mb, q, o2);
58 18136 : pushInstruction(mb, q);
59 18136 : return q;
60 : }
61 :
62 : static InstrPtr
63 51591 : dump_1(MalBlkPtr mb, const char *mod, const char *name, stmt *o1)
64 : {
65 51591 : InstrPtr q = NULL;
66 :
67 51591 : if (o1 == NULL || o1->nr < 0)
68 : return NULL;
69 51591 : q = newStmt(mb, mod, name);
70 51591 : q = pushArgument(mb, q, o1->nr);
71 51591 : pushInstruction(mb, q);
72 51591 : return q;
73 : }
74 :
75 : static InstrPtr
76 181139 : dump_2(MalBlkPtr mb, const char *mod, const char *name, stmt *o1, stmt *o2)
77 : {
78 181139 : InstrPtr q = NULL;
79 :
80 181139 : if (o1 == NULL || o2 == NULL || o1->nr < 0 || o2->nr < 0)
81 : return NULL;
82 181139 : q = newStmt(mb, mod, name);
83 181140 : q = pushArgument(mb, q, o1->nr);
84 181140 : q = pushArgument(mb, q, o2->nr);
85 181140 : pushInstruction(mb, q);
86 181140 : return q;
87 : }
88 :
89 : static InstrPtr
90 268 : pushPtr(MalBlkPtr mb, InstrPtr q, ptr val)
91 : {
92 268 : int _t;
93 268 : ValRecord cst;
94 :
95 268 : if (q == NULL || mb->errors)
96 : return q;
97 268 : cst.vtype= TYPE_ptr;
98 268 : cst.val.pval = val;
99 268 : cst.len = 0;
100 268 : _t = defConstant(mb, TYPE_ptr, &cst);
101 268 : if( _t >= 0)
102 268 : return pushArgument(mb, q, _t);
103 : return q;
104 : }
105 :
106 : static InstrPtr
107 2208240 : pushSchema(MalBlkPtr mb, InstrPtr q, sql_table *t)
108 : {
109 2208240 : if (t->s)
110 2208240 : return pushArgument(mb, q, getStrConstant(mb,t->s->base.name));
111 : else
112 0 : return pushNil(mb, q, TYPE_str);
113 : }
114 :
115 : int
116 0 : stmt_key(stmt *s)
117 : {
118 0 : const char *nme = column_name(NULL, s);
119 :
120 0 : return hash_key(nme);
121 : }
122 :
123 : /* #TODO make proper traversal operations */
124 : stmt *
125 209 : stmt_atom_string(backend *be, const char *S)
126 : {
127 209 : const char *s = sa_strdup(be->mvc->sa, S);
128 209 : sql_subtype t;
129 :
130 209 : if (s == NULL)
131 : return NULL;
132 209 : sql_find_subtype(&t, "varchar", _strlen(s), 0);
133 209 : return stmt_atom(be, atom_string(be->mvc->sa, &t, s));
134 : }
135 :
136 : stmt *
137 19669 : stmt_atom_string_nil(backend *be)
138 : {
139 19669 : sql_subtype t;
140 :
141 19669 : sql_find_subtype(&t, "varchar", 0, 0);
142 19669 : return stmt_atom(be, atom_string(be->mvc->sa, &t, NULL));
143 : }
144 :
145 : stmt *
146 5890 : stmt_atom_int(backend *be, int i)
147 : {
148 5890 : sql_subtype t;
149 :
150 5890 : sql_find_subtype(&t, "int", 32, 0);
151 5890 : return stmt_atom(be, atom_int(be->mvc->sa, &t, i));
152 : }
153 :
154 : stmt *
155 117246 : stmt_atom_lng(backend *be, lng i)
156 : {
157 117246 : sql_subtype t;
158 :
159 117246 : sql_find_subtype(&t, "bigint", 64, 0);
160 117277 : return stmt_atom(be, atom_int(be->mvc->sa, &t, i));
161 : }
162 :
163 : stmt *
164 26 : stmt_atom_lng_nil(backend *be)
165 : {
166 26 : sql_subtype t;
167 :
168 26 : sql_find_subtype(&t, "bigint", 64, 0);
169 26 : return stmt_atom(be, atom_general(be->mvc->sa, &t, NULL, 0));
170 : }
171 :
172 : stmt *
173 40616 : stmt_bool(backend *be, int b)
174 : {
175 40616 : sql_subtype t;
176 :
177 40616 : sql_find_subtype(&t, "boolean", 0, 0);
178 :
179 40616 : if (b == bit_nil) {
180 0 : return stmt_atom(be, atom_bool(be->mvc->sa, &t, bit_nil));
181 40616 : } else if (b) {
182 39485 : return stmt_atom(be, atom_bool(be->mvc->sa, &t, TRUE));
183 : } else {
184 1131 : return stmt_atom(be, atom_bool(be->mvc->sa, &t, FALSE));
185 : }
186 : }
187 :
188 : static stmt *
189 17903166 : stmt_create(allocator *sa, st_type type)
190 : {
191 17903166 : stmt *s = SA_NEW(sa, stmt);
192 :
193 17902668 : if (!s)
194 : return NULL;
195 17902668 : *s = (stmt) {
196 : .type = type,
197 : };
198 17902668 : return s;
199 : }
200 :
201 : stmt *
202 28202 : stmt_group(backend *be, stmt *s, stmt *grp, stmt *ext, stmt *cnt, int done)
203 : {
204 28202 : MalBlkPtr mb = be->mb;
205 28202 : InstrPtr q = NULL;
206 :
207 28202 : if (s == NULL || s->nr < 0)
208 0 : goto bailout;
209 28202 : if (grp && (grp->nr < 0 || ext->nr < 0 || cnt->nr < 0))
210 0 : goto bailout;
211 :
212 49981 : q = newStmt(mb, groupRef, done ? grp ? subgroupdoneRef : groupdoneRef : grp ? subgroupRef : groupRef);
213 28202 : if (q == NULL)
214 0 : goto bailout;
215 :
216 : /* output variables extent and hist */
217 28202 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
218 28202 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
219 28202 : q = pushArgument(mb, q, s->nr);
220 28202 : if (grp)
221 6423 : q = pushArgument(mb, q, grp->nr);
222 :
223 28202 : bool enabled = be->mvc->sa->eb.enabled;
224 28202 : be->mvc->sa->eb.enabled = false;
225 28202 : stmt *ns = stmt_create(be->mvc->sa, st_group);
226 28202 : be->mvc->sa->eb.enabled = enabled;
227 28202 : if (ns == NULL) {
228 0 : freeInstruction(q);
229 0 : goto bailout;
230 : }
231 :
232 28202 : ns->op1 = s;
233 :
234 28202 : if (grp) {
235 6423 : ns->op2 = grp;
236 6423 : ns->op3 = ext;
237 6423 : ns->op4.stval = cnt;
238 : }
239 28202 : ns->nrcols = s->nrcols;
240 28202 : ns->key = 0;
241 28202 : ns->q = q;
242 28202 : ns->nr = getDestVar(q);
243 28202 : pushInstruction(mb, q);
244 28202 : return ns;
245 :
246 0 : bailout:
247 0 : if (be->mvc->sa->eb.enabled)
248 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
249 : return NULL;
250 : }
251 :
252 : stmt *
253 76 : stmt_unique(backend *be, stmt *s)
254 : {
255 76 : MalBlkPtr mb = be->mb;
256 76 : InstrPtr q = NULL;
257 :
258 76 : if (s == NULL || s->nr < 0)
259 0 : goto bailout;
260 :
261 76 : q = newStmt(mb, algebraRef, uniqueRef);
262 76 : if (q == NULL)
263 0 : goto bailout;
264 :
265 76 : q = pushArgument(mb, q, s->nr);
266 76 : q = pushNilBat(mb, q); /* candidate list */
267 :
268 76 : bool enabled = be->mvc->sa->eb.enabled;
269 76 : be->mvc->sa->eb.enabled = false;
270 76 : stmt *ns = stmt_create(be->mvc->sa, st_unique);
271 76 : be->mvc->sa->eb.enabled = enabled;
272 76 : if (ns == NULL) {
273 0 : freeInstruction(q);
274 0 : goto bailout;
275 : }
276 :
277 76 : ns->op1 = s;
278 76 : ns->nrcols = s->nrcols;
279 76 : ns->key = 1;
280 76 : ns->q = q;
281 76 : ns->nr = getDestVar(q);
282 76 : pushInstruction(mb, q);
283 76 : return ns;
284 :
285 0 : bailout:
286 0 : if (be->mvc->sa->eb.enabled)
287 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
288 : return NULL;
289 : }
290 :
291 : stmt *
292 0 : stmt_none(backend *be)
293 : {
294 0 : return stmt_create(be->mvc->sa, st_none);
295 : }
296 :
297 : static int
298 55 : create_bat(MalBlkPtr mb, int tt)
299 : {
300 55 : InstrPtr q = newStmt(mb, batRef, newRef);
301 :
302 55 : if (q == NULL)
303 : return -1;
304 55 : setVarType(mb, getArg(q, 0), newBatType(tt));
305 55 : q = pushType(mb, q, tt);
306 55 : pushInstruction(mb, q);
307 55 : return getDestVar(q);
308 : }
309 :
310 : stmt *
311 116 : stmt_bat_new(backend *be, sql_subtype *tpe, lng estimate)
312 : {
313 116 : InstrPtr q = newStmt(be->mb, batRef, newRef);
314 116 : int tt = tpe->type->localtype;
315 :
316 116 : if (q == NULL)
317 : return NULL;
318 116 : if (tt == TYPE_void)
319 1 : tt = TYPE_bte;
320 116 : setVarType(be->mb, getArg(q, 0), newBatType(tt));
321 116 : q = pushType(be->mb, q, tt);
322 116 : if (estimate > 0)
323 0 : q = pushInt(be->mb, q, (int)estimate);
324 116 : pushInstruction(be->mb, q);
325 :
326 116 : stmt *s = stmt_create(be->mvc->sa, st_alias);
327 116 : s->op4.typeval = *tpe;
328 116 : s->q = q;
329 116 : s->nr = q->argv[0];
330 116 : s->nrcols = 2;
331 116 : return s;
332 : }
333 :
334 : static int *
335 20 : dump_table(allocator *sa, MalBlkPtr mb, sql_table *t)
336 : {
337 20 : int i = 0;
338 20 : node *n;
339 20 : int *l = SA_NEW_ARRAY(sa, int, ol_length(t->columns) + 1);
340 :
341 20 : if (!l)
342 : return NULL;
343 :
344 : /* tid column */
345 20 : if ((l[i++] = create_bat(mb, TYPE_oid)) < 0)
346 : return NULL;
347 :
348 55 : for (n = ol_first_node(t->columns); n; n = n->next) {
349 35 : sql_column *c = n->data;
350 :
351 35 : if ((l[i++] = create_bat(mb, c->type.type->localtype)) < 0)
352 : return NULL;
353 : }
354 : return l;
355 : }
356 :
357 : stmt *
358 2778 : stmt_var(backend *be, const char *sname, const char *varname, sql_subtype *t, int declare, int level)
359 : {
360 2778 : MalBlkPtr mb = be->mb;
361 2778 : InstrPtr q = NULL;
362 2778 : char *buf;
363 :
364 2778 : if (level == 0) { /* global */
365 431 : int tt = t->type->localtype;
366 :
367 431 : assert(sname);
368 431 : q = newStmt(mb, sqlRef, getVariableRef);
369 431 : if (q == NULL)
370 0 : goto bailout;
371 431 : q = pushArgument(mb, q, be->mvc_var);
372 431 : q = pushStr(mb, q, sname); /* all global variables have a schema */
373 431 : q = pushStr(mb, q, varname);
374 431 : setVarType(mb, getArg(q, 0), tt);
375 2347 : } else if (!declare) {
376 1958 : char levelstr[16];
377 :
378 1958 : assert(!sname);
379 1958 : snprintf(levelstr, sizeof(levelstr), "%d", level);
380 1958 : buf = SA_NEW_ARRAY(be->mvc->sa, char, strlen(levelstr) + strlen(varname) + 3);
381 1958 : if (!buf)
382 1 : goto bailout;
383 1958 : stpcpy(stpcpy(stpcpy(stpcpy(buf, "A"), levelstr), "%"), varname); /* mangle variable name */
384 1958 : q = newAssignment(mb);
385 1958 : if (q == NULL)
386 1 : goto bailout;
387 1957 : q = pushArgumentId(mb, q, buf);
388 : } else {
389 389 : int tt = t->type->localtype;
390 389 : char levelstr[16];
391 :
392 389 : assert(!sname);
393 389 : snprintf(levelstr, sizeof(levelstr), "%d", level);
394 389 : buf = SA_NEW_ARRAY(be->mvc->sa, char, strlen(levelstr) + strlen(varname) + 3);
395 389 : if (!buf)
396 0 : goto bailout;
397 389 : stpcpy(stpcpy(stpcpy(stpcpy(buf, "A"), levelstr), "%"), varname); /* mangle variable name */
398 :
399 389 : q = newInstruction(mb, NULL, NULL);
400 389 : if (q == NULL) {
401 0 : goto bailout;
402 : }
403 389 : q->argc = q->retc = 0;
404 389 : q = pushArgumentId(mb, q, buf);
405 389 : q = pushNil(mb, q, tt);
406 389 : q->retc++;
407 : }
408 2777 : bool enabled = be->mvc->sa->eb.enabled;
409 2777 : be->mvc->sa->eb.enabled = false;
410 2777 : stmt *s = stmt_create(be->mvc->sa, st_var);
411 2777 : be->mvc->sa->eb.enabled = enabled;
412 2777 : if (s == NULL) {
413 0 : freeInstruction(q);
414 0 : goto bailout;
415 : }
416 :
417 2777 : if (t)
418 2777 : s->op4.typeval = *t;
419 : else
420 0 : s->op4.typeval.type = NULL;
421 2777 : s->flag = declare + (level << 1);
422 2777 : s->key = 1;
423 2777 : s->q = q;
424 2777 : s->nr = getDestVar(q);
425 2777 : pushInstruction(mb, q);
426 2777 : return s;
427 :
428 1 : bailout:
429 1 : if (be->mvc->sa->eb.enabled)
430 1 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
431 : return NULL;
432 : }
433 :
434 : stmt *
435 20 : stmt_vars(backend *be, const char *varname, sql_table *t, int declare, int level)
436 : {
437 20 : MalBlkPtr mb = be->mb;
438 20 : int *l;
439 :
440 20 : (void)varname;
441 : /* declared table */
442 20 : if ((l = dump_table(be->mvc->sa, mb, t)) != NULL) {
443 20 : stmt *s = stmt_create(be->mvc->sa, st_var);
444 :
445 20 : if (s == NULL) {
446 : return NULL;
447 : }
448 :
449 20 : ATOMIC_PTR_SET(&t->data, l);
450 : /*
451 : s->op2 = (stmt*)l;
452 : s->op3 = (stmt*)t;
453 : */
454 20 : s->flag = declare + (level << 1);
455 20 : s->key = 1;
456 20 : s->nr = l[0];
457 20 : return s;
458 : }
459 0 : if (be->mvc->sa->eb.enabled)
460 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
461 : return NULL;
462 : }
463 :
464 : stmt *
465 2052 : stmt_varnr(backend *be, int nr, sql_subtype *t)
466 : {
467 2052 : MalBlkPtr mb = be->mb;
468 2052 : InstrPtr q = newAssignment(mb);
469 2052 : char buf[IDLENGTH];
470 :
471 2052 : if (q == NULL)
472 0 : goto bailout;
473 :
474 2052 : (void) snprintf(buf, sizeof(buf), "A%d", nr);
475 2052 : q = pushArgumentId(mb, q, buf);
476 :
477 2052 : bool enabled = be->mvc->sa->eb.enabled;
478 2052 : be->mvc->sa->eb.enabled = false;
479 2052 : stmt *s = stmt_create(be->mvc->sa, st_var);
480 2052 : be->mvc->sa->eb.enabled = enabled;
481 2052 : if (s == NULL) {
482 0 : freeInstruction(q);
483 0 : goto bailout;
484 : }
485 :
486 2052 : s->op1 = NULL;
487 2052 : if (t)
488 2052 : s->op4.typeval = *t;
489 : else
490 0 : s->op4.typeval.type = NULL;
491 2052 : s->flag = nr;
492 2052 : s->key = 1;
493 2052 : s->q = q;
494 2052 : s->nr = getDestVar(q);
495 2052 : pushInstruction(mb, q);
496 2052 : return s;
497 :
498 0 : bailout:
499 0 : if (be->mvc->sa->eb.enabled)
500 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
501 : return NULL;
502 : }
503 :
504 : stmt *
505 687 : stmt_table(backend *be, stmt *cols, int temp)
506 : {
507 687 : MalBlkPtr mb = be->mb;
508 :
509 687 : if (cols == NULL || cols->nr < 0)
510 0 : goto bailout;
511 :
512 687 : stmt *s = stmt_create(be->mvc->sa, st_table);
513 :
514 687 : if (s == NULL)
515 0 : goto bailout;
516 :
517 687 : if (cols->type != st_list) {
518 0 : InstrPtr q = newAssignment(mb);
519 0 : if (q == NULL)
520 0 : goto bailout;
521 0 : pushInstruction(mb, q);
522 0 : q = newStmt(mb, sqlRef, printRef);
523 0 : if (q == NULL)
524 0 : goto bailout;
525 0 : q = pushStr(mb, q, "not a valid output list\n");
526 0 : pushInstruction(mb, q);
527 : }
528 687 : s->op1 = cols;
529 687 : s->flag = temp;
530 687 : s->nr = cols->nr;
531 687 : s->nrcols = cols->nrcols;
532 687 : return s;
533 :
534 0 : bailout:
535 0 : if (be->mvc->sa->eb.enabled)
536 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
537 : return NULL;
538 : }
539 :
540 : stmt *
541 222125 : stmt_temp(backend *be, sql_subtype *t)
542 : {
543 222125 : int tt = t->type->localtype;
544 222125 : MalBlkPtr mb = be->mb;
545 222125 : InstrPtr q = newStmt(mb, batRef, newRef);
546 :
547 223126 : if (q == NULL)
548 0 : goto bailout;
549 223126 : setVarType(mb, getArg(q, 0), newBatType(tt));
550 223126 : q = pushType(mb, q, tt);
551 222947 : bool enabled = be->mvc->sa->eb.enabled;
552 222947 : be->mvc->sa->eb.enabled = false;
553 222947 : stmt *s = stmt_create(be->mvc->sa, st_temp);
554 222906 : be->mvc->sa->eb.enabled = enabled;
555 :
556 222906 : if (s == NULL) {
557 0 : freeInstruction(q);
558 0 : goto bailout;
559 : }
560 222906 : s->op4.typeval = *t;
561 222906 : s->nrcols = 1;
562 222906 : s->q = q;
563 222906 : s->nr = getDestVar(q);
564 222906 : pushInstruction(mb, q);
565 222906 : return s;
566 :
567 0 : bailout:
568 0 : if (be->mvc->sa->eb.enabled)
569 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
570 : return NULL;
571 : }
572 :
573 : stmt *
574 216 : stmt_blackbox_result(backend *be, InstrPtr q, int retnr, sql_subtype *t)
575 : {
576 216 : if (q == NULL)
577 : return NULL;
578 216 : stmt *s = stmt_create(be->mvc->sa, st_result);
579 216 : if (s == NULL)
580 : return NULL;
581 216 : s->op4.typeval = *t;
582 216 : s->nrcols = 1;
583 216 : s->q = q;
584 216 : s->nr = getArg(q, retnr);
585 216 : s->flag = retnr;
586 216 : return s;
587 : }
588 :
589 :
590 : stmt *
591 204935 : stmt_tid(backend *be, sql_table *t, int partition)
592 : {
593 204935 : int tt = TYPE_oid;
594 204935 : MalBlkPtr mb = be->mb;
595 204935 : InstrPtr q;
596 :
597 204935 : if (!t->s && ATOMIC_PTR_GET(&t->data)) { /* declared table */
598 16 : stmt *s = stmt_create(be->mvc->sa, st_tid);
599 16 : int *l = ATOMIC_PTR_GET(&t->data);
600 :
601 16 : if (s == NULL) {
602 0 : goto bailout;
603 : }
604 16 : assert(partition == 0);
605 16 : s->partition = partition;
606 16 : s->op4.tval = t;
607 16 : s->nrcols = 1;
608 16 : s->nr = l[0];
609 16 : return s;
610 : }
611 204919 : q = newStmt(mb, sqlRef, tidRef);
612 205104 : if (q == NULL)
613 0 : goto bailout;
614 205104 : setVarType(mb, getArg(q, 0), newBatType(tt));
615 205104 : q = pushArgument(mb, q, be->mvc_var);
616 205100 : q = pushSchema(mb, q, t);
617 205083 : q = pushStr(mb, q, t->base.name);
618 205089 : if (t && isTable(t) && partition) {
619 76841 : sql_trans *tr = be->mvc->session->tr;
620 76841 : sqlstore *store = tr->store;
621 76841 : BUN rows = (BUN) store->storage_api.count_col(tr, ol_first_node(t->columns)->data, RDONLY);
622 76841 : setRowCnt(mb,getArg(q,0),rows);
623 : }
624 :
625 205089 : bool enabled = be->mvc->sa->eb.enabled;
626 205089 : be->mvc->sa->eb.enabled = false;
627 205089 : stmt *s = stmt_create(be->mvc->sa, st_tid);
628 204931 : be->mvc->sa->eb.enabled = enabled;
629 204931 : if (s == NULL) {
630 0 : freeInstruction(q);
631 0 : goto bailout;
632 : }
633 :
634 204931 : s->partition = partition;
635 204931 : s->op4.tval = t;
636 204931 : s->nrcols = 1;
637 204931 : s->nr = getDestVar(q);
638 204931 : s->q = q;
639 204931 : pushInstruction(mb, q);
640 204931 : return s;
641 :
642 0 : bailout:
643 0 : if (be->mvc->sa->eb.enabled)
644 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
645 : return NULL;
646 : }
647 :
648 : static sql_column *
649 1003062 : find_real_column(backend *be, sql_column *c)
650 : {
651 1003062 : if (c && c->t && c->t->s && c->t->persistence == SQL_DECLARED_TABLE) {
652 36774 : sql_table *nt = find_sql_table_id(be->mvc->session->tr, c->t->s, c->t->base.id);
653 36774 : if (nt) {
654 36774 : node *n = ol_find_id(nt->columns, c->base.id);
655 36774 : if (n)
656 36774 : return n->data;
657 : }
658 : }
659 : return c;
660 : }
661 :
662 : stmt *
663 1003059 : stmt_bat(backend *be, sql_column *c, int access, int partition)
664 : {
665 1003059 : int tt = c->type.type->localtype;
666 1003059 : MalBlkPtr mb = be->mb;
667 1003059 : InstrPtr q;
668 :
669 1003059 : c = find_real_column(be, c);
670 :
671 1003093 : if (access == RD_EXT)
672 176 : partition = 0;
673 :
674 : /* for read access tid.project(col) */
675 1003093 : if (!c->t->s && ATOMIC_PTR_GET(&c->t->data)) { /* declared table */
676 23 : stmt *s = stmt_create(be->mvc->sa, st_bat);
677 23 : int *l = ATOMIC_PTR_GET(&c->t->data);
678 :
679 23 : if (s == NULL) {
680 0 : goto bailout;
681 : }
682 23 : assert(partition == 0);
683 23 : s->partition = partition;
684 23 : s->op4.cval = c;
685 23 : s->nrcols = 1;
686 23 : s->flag = access;
687 23 : s->nr = l[c->colnr+1];
688 23 : s->tname = c->t?c->t->base.name:NULL;
689 23 : s->cname = c->base.name;
690 23 : return s;
691 : }
692 1003070 : q = newStmtArgs(mb, sqlRef, bindRef, 9);
693 1003150 : if (q == NULL)
694 0 : goto bailout;
695 1003150 : if (c->storage_type && access != RD_EXT) {
696 368 : sql_trans *tr = be->mvc->session->tr;
697 368 : sqlstore *store = tr->store;
698 368 : BAT *b = store->storage_api.bind_col(tr, c, QUICK);
699 368 : if (!b) {
700 0 : freeInstruction(q);
701 0 : goto bailout;
702 : }
703 368 : tt = b->ttype;
704 : }
705 1002974 : if (access == RD_UPD_ID) {
706 487390 : q = pushReturn(mb, q, newTmpVariable(mb, newBatType(tt)));
707 : } else {
708 515760 : setVarType(mb, getArg(q, 0), newBatType(tt));
709 : }
710 1003153 : q = pushArgument(mb, q, be->mvc_var);
711 1003133 : q = pushSchema(mb, q, c->t);
712 1003137 : q = pushArgument(mb, q, getStrConstant(mb,c->t->base.name));
713 1003141 : q = pushArgument(mb, q, getStrConstant(mb,c->base.name));
714 1003088 : q = pushArgument(mb, q, getIntConstant(mb,access));
715 :
716 1003085 : if (access == RD_UPD_ID) {
717 487377 : setVarType(mb, getArg(q, 1), newBatType(tt));
718 : }
719 1003085 : if (partition) {
720 555365 : sql_trans *tr = be->mvc->session->tr;
721 555365 : sqlstore *store = tr->store;
722 :
723 555365 : if (c && isTable(c->t)) {
724 555369 : BUN rows = (BUN) store->storage_api.count_col(tr, c, RDONLY);
725 555440 : setRowCnt(mb,getArg(q,0),rows);
726 : }
727 : }
728 :
729 1003156 : bool enabled = be->mvc->sa->eb.enabled;
730 1003156 : be->mvc->sa->eb.enabled = false;
731 1003156 : stmt *s = stmt_create(be->mvc->sa, st_bat);
732 1003145 : be->mvc->sa->eb.enabled = enabled;
733 1003145 : if (s == NULL) {
734 0 : freeInstruction(q);
735 0 : goto bailout;
736 : }
737 :
738 1003145 : s->partition = partition;
739 1003145 : s->op4.cval = c;
740 1003145 : s->nrcols = 1;
741 1003145 : s->flag = access;
742 1003145 : s->nr = getDestVar(q);
743 1003145 : s->q = q;
744 1003145 : s->tname = c->t->base.name;
745 1003145 : s->cname = c->base.name;
746 1003145 : pushInstruction(mb, q);
747 1003145 : return s;
748 :
749 0 : bailout:
750 0 : if (be->mvc->sa->eb.enabled)
751 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
752 : return NULL;
753 : }
754 :
755 : stmt *
756 6467 : stmt_idxbat(backend *be, sql_idx *i, int access, int partition)
757 : {
758 6467 : int tt = hash_index(i->type)?TYPE_lng:TYPE_oid;
759 6467 : MalBlkPtr mb = be->mb;
760 6467 : InstrPtr q = newStmtArgs(mb, sqlRef, bindidxRef, 9);
761 :
762 6467 : if (q == NULL)
763 0 : goto bailout;
764 :
765 6467 : if (access == RD_UPD_ID) {
766 2871 : q = pushReturn(mb, q, newTmpVariable(mb, newBatType(tt)));
767 : } else {
768 3596 : setVarType(mb, getArg(q, 0), newBatType(tt));
769 : }
770 :
771 6467 : q = pushArgument(mb, q, be->mvc_var);
772 6467 : q = pushSchema(mb, q, i->t);
773 6467 : q = pushArgument(mb, q, getStrConstant(mb, i->t->base.name));
774 6467 : q = pushArgument(mb, q, getStrConstant(mb, i->base.name));
775 6467 : q = pushArgument(mb, q, getIntConstant(mb, access));
776 :
777 6467 : if (access == RD_UPD_ID) {
778 2871 : setVarType(mb, getArg(q, 1), newBatType(tt));
779 : }
780 6467 : if (partition) {
781 3550 : sql_trans *tr = be->mvc->session->tr;
782 3550 : sqlstore *store = tr->store;
783 :
784 3550 : if (i && isTable(i->t)) {
785 3550 : BUN rows = (BUN) store->storage_api.count_idx(tr, i, QUICK);
786 3550 : setRowCnt(mb,getArg(q,0),rows);
787 : }
788 : }
789 :
790 6467 : bool enabled = be->mvc->sa->eb.enabled;
791 6467 : be->mvc->sa->eb.enabled = false;
792 6467 : stmt *s = stmt_create(be->mvc->sa, st_idxbat);
793 6467 : be->mvc->sa->eb.enabled = enabled;
794 6467 : if (s == NULL) {
795 0 : freeInstruction(q);
796 0 : goto bailout;
797 : }
798 :
799 6467 : s->partition = partition;
800 6467 : s->op4.idxval = i;
801 6467 : s->nrcols = 1;
802 6467 : s->flag = access;
803 6467 : s->nr = getDestVar(q);
804 6467 : s->q = q;
805 6467 : s->tname = i->t->base.name;
806 6467 : s->cname = i->base.name;
807 6467 : pushInstruction(mb, q);
808 6467 : return s;
809 :
810 0 : bailout:
811 0 : if (be->mvc->sa->eb.enabled)
812 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
813 : return NULL;
814 : }
815 :
816 : stmt *
817 673994 : stmt_append_col(backend *be, sql_column *c, stmt *offset, stmt *b, int *mvc_var_update, int fake)
818 : {
819 673994 : MalBlkPtr mb = be->mb;
820 673994 : InstrPtr q = NULL;
821 :
822 673994 : if (b == NULL || b->nr < 0)
823 0 : goto bailout;
824 :
825 673994 : if (!c->t->s && ATOMIC_PTR_GET(&c->t->data)) { /* declared table */
826 23 : int *l = ATOMIC_PTR_GET(&c->t->data);
827 :
828 23 : if (c->colnr == 0) { /* append to tid column */
829 18 : q = newStmt(mb, sqlRef, growRef);
830 18 : if (q == NULL)
831 0 : goto bailout;
832 18 : q = pushArgument(mb, q, l[0]);
833 18 : q = pushArgument(mb, q, b->nr);
834 18 : pushInstruction(mb, q);
835 : }
836 23 : q = newStmt(mb, batRef, appendRef);
837 23 : if (q == NULL)
838 0 : goto bailout;
839 23 : q = pushArgument(mb, q, l[c->colnr+1]);
840 23 : q = pushArgument(mb, q, b->nr);
841 23 : q = pushBit(mb, q, TRUE);
842 23 : getArg(q,0) = l[c->colnr+1];
843 673971 : } else if (!fake) { /* fake append */
844 673971 : if (offset == NULL || offset->nr < 0)
845 0 : goto bailout;
846 673971 : q = newStmt(mb, sqlRef, appendRef);
847 674504 : if (q == NULL)
848 0 : goto bailout;
849 674504 : q = pushArgument(mb, q, be->mvc_var);
850 674500 : int tmpvar = newTmpVariable(mb, TYPE_int);
851 674504 : getArg(q, 0) = tmpvar;
852 674504 : if (mvc_var_update != NULL)
853 674504 : *mvc_var_update = tmpvar;
854 674504 : q = pushSchema(mb, q, c->t);
855 674485 : q = pushStr(mb, q, c->t->base.name);
856 674483 : q = pushStr(mb, q, c->base.name);
857 674375 : q = pushArgument(mb, q, offset->nr);
858 : /* also the offsets */
859 674405 : assert(offset->q->retc == 2);
860 674405 : q = pushArgument(mb, q, getArg(offset->q, 1));
861 674371 : q = pushArgument(mb, q, b->nr);
862 674309 : if (mvc_var_update != NULL)
863 674309 : *mvc_var_update = getDestVar(q);
864 : } else {
865 : return b;
866 : }
867 674332 : bool enabled = be->mvc->sa->eb.enabled;
868 674332 : be->mvc->sa->eb.enabled = false;
869 674332 : stmt *s = stmt_create(be->mvc->sa, st_append_col);
870 674190 : be->mvc->sa->eb.enabled = enabled;
871 :
872 674190 : if (s == NULL) {
873 0 : freeInstruction(q);
874 0 : goto bailout;
875 : }
876 674190 : s->op1 = b;
877 674190 : s->op2 = offset;
878 674190 : s->op4.cval = c;
879 674190 : s->q = q;
880 674190 : s->nr = getDestVar(q);
881 674190 : pushInstruction(mb, q);
882 674190 : return s;
883 :
884 0 : bailout:
885 0 : if (be->mvc->sa->eb.enabled)
886 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
887 : return NULL;
888 : }
889 :
890 : stmt *
891 2220 : stmt_append_idx(backend *be, sql_idx *i, stmt *offset, stmt *b)
892 : {
893 2220 : MalBlkPtr mb = be->mb;
894 2220 : InstrPtr q = NULL;
895 :
896 2220 : if (offset == NULL || b == NULL || offset->nr < 0 || b->nr < 0)
897 0 : goto bailout;
898 :
899 2220 : q = newStmt(mb, sqlRef, appendRef);
900 2220 : if (q == NULL)
901 0 : goto bailout;
902 2220 : q = pushArgument(mb, q, be->mvc_var);
903 2220 : getArg(q, 0) = be->mvc_var = newTmpVariable(mb, TYPE_int);
904 2220 : q = pushSchema(mb, q, i->t);
905 2220 : q = pushStr(mb, q, i->t->base.name);
906 2220 : q = pushStr(mb, q, sa_strconcat(be->mvc->sa, "%", i->base.name));
907 2220 : q = pushArgument(mb, q, offset->nr);
908 : /* also the offsets */
909 2220 : assert(offset->q->retc == 2);
910 2220 : q = pushArgument(mb, q, getArg(offset->q, 1));
911 2220 : q = pushArgument(mb, q, b->nr);
912 2220 : be->mvc_var = getDestVar(q);
913 :
914 2220 : bool enabled = be->mvc->sa->eb.enabled;
915 2220 : be->mvc->sa->eb.enabled = false;
916 2220 : stmt *s = stmt_create(be->mvc->sa, st_append_idx);
917 2220 : be->mvc->sa->eb.enabled = enabled;
918 2220 : if (s == NULL) {
919 0 : freeInstruction(q);
920 0 : goto bailout;
921 : }
922 :
923 2220 : s->op1 = b;
924 2220 : s->op2 = offset;
925 2220 : s->op4.idxval = i;
926 2220 : s->q = q;
927 2220 : s->nr = getDestVar(q);
928 2220 : pushInstruction(mb, q);
929 2220 : return s;
930 :
931 0 : bailout:
932 0 : if (be->mvc->sa->eb.enabled)
933 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
934 : return NULL;
935 : }
936 :
937 : stmt *
938 3208 : stmt_update_col(backend *be, sql_column *c, stmt *tids, stmt *upd)
939 : {
940 3208 : MalBlkPtr mb = be->mb;
941 3208 : InstrPtr q = NULL;
942 :
943 3208 : if (tids == NULL || upd == NULL || tids->nr < 0 || upd->nr < 0)
944 0 : goto bailout;
945 :
946 3209 : if (!c->t->s && ATOMIC_PTR_GET(&c->t->data)) { /* declared table */
947 1 : int *l = ATOMIC_PTR_GET(&c->t->data);
948 :
949 1 : q = newStmt(mb, batRef, replaceRef);
950 1 : if (q == NULL)
951 0 : goto bailout;
952 1 : q = pushArgument(mb, q, l[c->colnr+1]);
953 1 : q = pushArgument(mb, q, tids->nr);
954 1 : q = pushArgument(mb, q, upd->nr);
955 : } else {
956 3207 : q = newStmt(mb, sqlRef, updateRef);
957 3207 : if (q == NULL)
958 0 : goto bailout;
959 3207 : q = pushArgument(mb, q, be->mvc_var);
960 3207 : getArg(q, 0) = be->mvc_var = newTmpVariable(mb, TYPE_int);
961 3207 : q = pushSchema(mb, q, c->t);
962 3207 : q = pushStr(mb, q, c->t->base.name);
963 3207 : q = pushStr(mb, q, c->base.name);
964 3207 : q = pushArgument(mb, q, tids->nr);
965 3207 : q = pushArgument(mb, q, upd->nr);
966 3207 : be->mvc_var = getDestVar(q);
967 : }
968 3208 : bool enabled = be->mvc->sa->eb.enabled;
969 3208 : be->mvc->sa->eb.enabled = false;
970 3208 : stmt *s = stmt_create(be->mvc->sa, st_update_col);
971 3208 : be->mvc->sa->eb.enabled = enabled;
972 :
973 3208 : if (s == NULL) {
974 0 : freeInstruction(q);
975 0 : goto bailout;
976 : }
977 3208 : s->op1 = tids;
978 3208 : s->op2 = upd;
979 3208 : s->op4.cval = c;
980 3208 : s->q = q;
981 3208 : s->nr = getDestVar(q);
982 3208 : pushInstruction(mb, q);
983 3208 : return s;
984 :
985 0 : bailout:
986 0 : if (be->mvc->sa->eb.enabled)
987 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
988 : return NULL;
989 : }
990 :
991 :
992 : stmt *
993 823 : stmt_update_idx(backend *be, sql_idx *i, stmt *tids, stmt *upd)
994 : {
995 823 : MalBlkPtr mb = be->mb;
996 823 : InstrPtr q = NULL;
997 :
998 823 : if (tids == NULL || upd == NULL || tids->nr < 0 || upd->nr < 0)
999 0 : goto bailout;
1000 :
1001 823 : q = newStmt(mb, sqlRef, updateRef);
1002 823 : if (q == NULL)
1003 0 : goto bailout;
1004 823 : q = pushArgument(mb, q, be->mvc_var);
1005 823 : getArg(q, 0) = be->mvc_var = newTmpVariable(mb, TYPE_int);
1006 823 : q = pushSchema(mb, q, i->t);
1007 823 : q = pushStr(mb, q, i->t->base.name);
1008 823 : q = pushStr(mb, q, sa_strconcat(be->mvc->sa, "%", i->base.name));
1009 823 : q = pushArgument(mb, q, tids->nr);
1010 823 : q = pushArgument(mb, q, upd->nr);
1011 823 : be->mvc_var = getDestVar(q);
1012 823 : bool enabled = be->mvc->sa->eb.enabled;
1013 823 : be->mvc->sa->eb.enabled = false;
1014 823 : stmt *s = stmt_create(be->mvc->sa, st_update_idx);
1015 823 : be->mvc->sa->eb.enabled = enabled;
1016 823 : if (s == NULL) {
1017 0 : freeInstruction(q);
1018 0 : goto bailout;
1019 : }
1020 :
1021 823 : s->op1 = tids;
1022 823 : s->op2 = upd;
1023 823 : s->op4.idxval = i;
1024 823 : s->q = q;
1025 823 : s->nr = getDestVar(q);
1026 823 : pushInstruction(mb, q);
1027 823 : return s;
1028 :
1029 0 : bailout:
1030 0 : if (be->mvc->sa->eb.enabled)
1031 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
1032 : return NULL;
1033 : }
1034 :
1035 : stmt *
1036 383 : stmt_delete(backend *be, sql_table *t, stmt *tids)
1037 : {
1038 383 : MalBlkPtr mb = be->mb;
1039 383 : InstrPtr q = NULL;
1040 :
1041 383 : if (tids == NULL || tids->nr < 0)
1042 0 : goto bailout;
1043 :
1044 384 : if (!t->s && ATOMIC_PTR_GET(&t->data)) { /* declared table */
1045 1 : int *l = ATOMIC_PTR_GET(&t->data);
1046 :
1047 1 : q = newStmt(mb, batRef, deleteRef);
1048 1 : if (q == NULL)
1049 0 : goto bailout;
1050 1 : q = pushArgument(mb, q, l[0]);
1051 1 : q = pushArgument(mb, q, tids->nr);
1052 : } else {
1053 382 : q = newStmt(mb, sqlRef, deleteRef);
1054 382 : if (q == NULL)
1055 0 : goto bailout;
1056 382 : q = pushArgument(mb, q, be->mvc_var);
1057 382 : getArg(q, 0) = be->mvc_var = newTmpVariable(mb, TYPE_int);
1058 382 : q = pushSchema(mb, q, t);
1059 382 : q = pushStr(mb, q, t->base.name);
1060 382 : q = pushArgument(mb, q, tids->nr);
1061 382 : be->mvc_var = getDestVar(q);
1062 : }
1063 383 : bool enabled = be->mvc->sa->eb.enabled;
1064 383 : be->mvc->sa->eb.enabled = false;
1065 383 : stmt *s = stmt_create(be->mvc->sa, st_delete);
1066 383 : be->mvc->sa->eb.enabled = enabled;
1067 383 : if (s == NULL) {
1068 0 : freeInstruction(q);
1069 0 : goto bailout;
1070 : }
1071 :
1072 383 : s->op1 = tids;
1073 383 : s->op4.tval = t;
1074 383 : s->q = q;
1075 383 : s->nr = getDestVar(q);
1076 383 : pushInstruction(mb, q);
1077 383 : return s;
1078 :
1079 0 : bailout:
1080 0 : if (be->mvc->sa->eb.enabled)
1081 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
1082 : return NULL;
1083 : }
1084 :
1085 : stmt *
1086 124510 : stmt_const(backend *be, stmt *s, stmt *val)
1087 : {
1088 124510 : InstrPtr q = NULL;
1089 124510 : MalBlkPtr mb = be->mb;
1090 :
1091 124510 : if (s == NULL)
1092 0 : goto bailout;
1093 124510 : if (val)
1094 124510 : q = dump_2(mb, algebraRef, projectRef, s, val);
1095 : else
1096 0 : q = dump_1(mb, algebraRef, projectRef, s);
1097 124511 : if (q) {
1098 124511 : stmt *ns = stmt_create(be->mvc->sa, st_const);
1099 124511 : if (ns == NULL) {
1100 0 : goto bailout;
1101 : }
1102 :
1103 124511 : ns->op1 = s;
1104 124511 : ns->op2 = val;
1105 124511 : ns->nrcols = s->nrcols;
1106 124511 : ns->key = s->key;
1107 124511 : ns->aggr = s->aggr;
1108 124511 : ns->q = q;
1109 124511 : ns->nr = getDestVar(q);
1110 124511 : ns->tname = val->tname;
1111 124511 : ns->cname = val->cname;
1112 124511 : return ns;
1113 : }
1114 0 : bailout:
1115 0 : if (be->mvc->sa->eb.enabled)
1116 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
1117 : return NULL;
1118 : }
1119 :
1120 : stmt *
1121 2400 : stmt_gen_group(backend *be, stmt *gids, stmt *cnts)
1122 : {
1123 2400 : MalBlkPtr mb = be->mb;
1124 :
1125 2400 : if (gids == NULL || cnts == NULL)
1126 0 : goto bailout;
1127 :
1128 2400 : InstrPtr q = dump_2(mb, algebraRef, groupbyRef, gids, cnts);
1129 :
1130 2400 : if (q) {
1131 2400 : stmt *ns = stmt_create(be->mvc->sa, st_gen_group);
1132 2400 : if (ns == NULL) {
1133 0 : goto bailout;
1134 : }
1135 :
1136 2400 : ns->op1 = gids;
1137 2400 : ns->op2 = cnts;
1138 :
1139 2400 : ns->nrcols = gids->nrcols;
1140 2400 : ns->key = 0;
1141 2400 : ns->aggr = 0;
1142 2400 : ns->q = q;
1143 2400 : ns->nr = getDestVar(q);
1144 2400 : return ns;
1145 : }
1146 0 : bailout:
1147 0 : if (be->mvc->sa->eb.enabled)
1148 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
1149 : return NULL;
1150 : }
1151 :
1152 : stmt *
1153 51591 : stmt_mirror(backend *be, stmt *s)
1154 : {
1155 51591 : MalBlkPtr mb = be->mb;
1156 :
1157 51591 : if (s == NULL)
1158 0 : goto bailout;
1159 :
1160 51591 : InstrPtr q = dump_1(mb, batRef, mirrorRef, s);
1161 :
1162 51591 : if (q) {
1163 51591 : stmt *ns = stmt_create(be->mvc->sa, st_mirror);
1164 51591 : if (ns == NULL) {
1165 0 : goto bailout;
1166 : }
1167 :
1168 51591 : ns->op1 = s;
1169 51591 : ns->nrcols = 2;
1170 51591 : ns->key = s->key;
1171 51591 : ns->aggr = s->aggr;
1172 51591 : ns->q = q;
1173 51591 : ns->nr = getDestVar(q);
1174 51591 : return ns;
1175 : }
1176 0 : bailout:
1177 0 : if (be->mvc->sa->eb.enabled)
1178 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
1179 : return NULL;
1180 : }
1181 :
1182 : #define MARKJOIN 100
1183 : stmt *
1184 322704 : stmt_result(backend *be, stmt *s, int nr)
1185 : {
1186 322704 : stmt *ns;
1187 :
1188 322704 : if (s == NULL)
1189 : return NULL;
1190 :
1191 322704 : if (s->type == st_join && s->flag == cmp_joined) {
1192 5547 : if (nr)
1193 2322 : return s->op2;
1194 3225 : return s->op1;
1195 : }
1196 :
1197 317157 : if (s->op1->nr < 0)
1198 : return NULL;
1199 :
1200 317157 : ns = stmt_create(be->mvc->sa, st_result);
1201 317157 : if(!ns) {
1202 : return NULL;
1203 : }
1204 317157 : if (s->op1->type == st_join && s->op1->flag == cmp_joined) {
1205 0 : assert(0);
1206 317157 : } else if (nr) {
1207 181363 : int v = getArg(s->q, nr);
1208 :
1209 181363 : assert(s->q->retc > nr);
1210 181363 : ns->nr = v;
1211 : } else {
1212 135794 : ns->nr = s->nr;
1213 : }
1214 317157 : ns->op1 = s;
1215 317157 : if (!nr && (s->type == st_order || s->type == st_reorder))
1216 23799 : ns->op4.typeval = *tail_type(s->op1);
1217 181363 : else if (nr && ((s->type == st_join && s->flag == MARKJOIN) || (s->type == st_uselect2 && s->flag == MARKJOIN)))
1218 2965 : ns->op4.typeval = *sql_bind_localtype("bit");
1219 : else
1220 290393 : ns->op4.typeval = *sql_bind_localtype("oid");
1221 317157 : ns->flag = nr;
1222 317157 : ns->nrcols = s->nrcols;
1223 317157 : ns->key = s->key;
1224 317157 : ns->aggr = s->aggr;
1225 317157 : return ns;
1226 : }
1227 :
1228 :
1229 : /* limit maybe atom nil */
1230 : stmt *
1231 17658 : stmt_limit(backend *be, stmt *col, stmt *piv, stmt *gid, stmt *offset, stmt *limit, int distinct, int dir, int nullslast, int nr_obe, int order)
1232 : {
1233 17658 : MalBlkPtr mb = be->mb;
1234 17658 : InstrPtr q = NULL;
1235 17658 : int l, g, c;
1236 :
1237 17658 : if (col == NULL || offset == NULL || limit == NULL || col->nr < 0 || offset->nr < 0 || limit->nr < 0)
1238 0 : goto bailout;
1239 17658 : if (piv && (piv->nr < 0 || (gid && gid->nr < 0)))
1240 0 : goto bailout;
1241 :
1242 17658 : c = (col) ? col->nr : 0;
1243 17658 : g = (gid) ? gid->nr : 0;
1244 :
1245 : /* first insert single value into a bat */
1246 17658 : if (col->nrcols == 0) {
1247 0 : int k, tt = tail_type(col)->type->localtype;
1248 :
1249 0 : q = newStmt(mb, batRef, newRef);
1250 0 : if (q == NULL)
1251 0 : goto bailout;
1252 0 : setVarType(mb, getArg(q, 0), newBatType(tt));
1253 0 : q = pushType(mb, q, tt);
1254 0 : k = getDestVar(q);
1255 0 : pushInstruction(mb, q);
1256 :
1257 0 : q = newStmt(mb, batRef, appendRef);
1258 0 : if (q == NULL)
1259 0 : goto bailout;
1260 0 : q = pushArgument(mb, q, k);
1261 0 : q = pushArgument(mb, q, c);
1262 0 : pushInstruction(mb, q);
1263 0 : c = k;
1264 : }
1265 17658 : if (order) {
1266 590 : if (piv && piv->q) {
1267 0 : q = piv->q;
1268 0 : q = pushArgument(mb, q, c);
1269 0 : q = pushBit(mb, q, dir);
1270 0 : q = pushBit(mb, q, nullslast);
1271 0 : return piv;
1272 : } else {
1273 590 : int topn = 0;
1274 :
1275 590 : q = newStmt(mb, calcRef, plusRef);
1276 590 : if (q == NULL)
1277 0 : goto bailout;
1278 590 : q = pushArgument(mb, q, offset->nr);
1279 590 : q = pushArgument(mb, q, limit->nr);
1280 590 : topn = getDestVar(q);
1281 590 : pushInstruction(mb, q);
1282 :
1283 1174 : if (!gid || (piv && !piv->q)) { /* use algebra.firstn (possibly concurrently) */
1284 584 : int p = (piv) ? piv->nr : 0;
1285 584 : q = newStmtArgs(mb, algebraRef, firstnRef, 9);
1286 584 : if (q == NULL)
1287 0 : goto bailout;
1288 584 : if (nr_obe > 1) /* we need the groups for the next firstn */
1289 310 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
1290 584 : q = pushArgument(mb, q, c);
1291 584 : if (p)
1292 310 : q = pushArgument(mb, q, p);
1293 : else
1294 274 : q = pushNilBat(mb, q);
1295 584 : if (g)
1296 310 : q = pushArgument(mb, q, g);
1297 : else
1298 274 : q = pushNilBat(mb, q);
1299 584 : q = pushArgument(mb, q, topn);
1300 584 : q = pushBit(mb, q, dir);
1301 584 : q = pushBit(mb, q, nullslast);
1302 584 : q = pushBit(mb, q, distinct != 0);
1303 :
1304 584 : l = getArg(q, 0);
1305 584 : l = getDestVar(q);
1306 584 : pushInstruction(mb, q);
1307 : } else {
1308 6 : q = newStmtArgs(mb, algebraRef, groupedfirstnRef, (nr_obe*3)+6);
1309 6 : if (q == NULL)
1310 0 : goto bailout;
1311 6 : q = pushArgument(mb, q, topn);
1312 6 : q = pushNilBat(mb, q); /* candidates */
1313 6 : if (g) /* grouped case */
1314 6 : q = pushArgument(mb, q, g);
1315 : else
1316 0 : q = pushNilBat(mb, q);
1317 :
1318 6 : q = pushArgument(mb, q, c);
1319 6 : q = pushBit(mb, q, dir);
1320 6 : q = pushBit(mb, q, nullslast);
1321 :
1322 6 : l = getArg(q, 0);
1323 6 : l = getDestVar(q);
1324 6 : pushInstruction(mb, q);
1325 : }
1326 : }
1327 : } else {
1328 17068 : int len;
1329 :
1330 17068 : q = newStmt(mb, calcRef, plusRef);
1331 17092 : if (q == NULL)
1332 0 : goto bailout;
1333 17092 : q = pushArgument(mb, q, offset->nr);
1334 17092 : q = pushArgument(mb, q, limit->nr);
1335 17092 : len = getDestVar(q);
1336 17092 : pushInstruction(mb, q);
1337 :
1338 : /* since both arguments of algebra.subslice are
1339 : inclusive correct the LIMIT value by
1340 : subtracting 1 */
1341 17092 : q = newStmt(mb, calcRef, minusRef);
1342 17091 : if (q == NULL)
1343 0 : goto bailout;
1344 17091 : q = pushArgument(mb, q, len);
1345 17092 : q = pushInt(mb, q, 1);
1346 17092 : len = getDestVar(q);
1347 17092 : pushInstruction(mb, q);
1348 :
1349 17092 : q = newStmt(mb, algebraRef, subsliceRef);
1350 17092 : if (q == NULL)
1351 0 : goto bailout;
1352 17092 : q = pushArgument(mb, q, c);
1353 17091 : q = pushArgument(mb, q, offset->nr);
1354 17091 : q = pushArgument(mb, q, len);
1355 17092 : l = getDestVar(q);
1356 17092 : pushInstruction(mb, q);
1357 : }
1358 : /* retrieve the single values again */
1359 17681 : if (col->nrcols == 0) {
1360 0 : q = newStmt(mb, algebraRef, findRef);
1361 0 : if (q == NULL)
1362 0 : goto bailout;
1363 0 : q = pushArgument(mb, q, l);
1364 0 : q = pushOid(mb, q, 0);
1365 0 : l = getDestVar(q);
1366 0 : pushInstruction(mb, q);
1367 : }
1368 :
1369 35052 : stmt *ns = stmt_create(be->mvc->sa, piv?st_limit2:st_limit);
1370 17681 : if (ns == NULL) {
1371 0 : goto bailout;
1372 : }
1373 :
1374 17681 : ns->op1 = col;
1375 17681 : ns->op2 = offset;
1376 17681 : ns->op3 = limit;
1377 17681 : ns->nrcols = col->nrcols;
1378 17681 : ns->key = col->key;
1379 17681 : ns->aggr = col->aggr;
1380 17681 : ns->q = q;
1381 17681 : ns->nr = l;
1382 17681 : return ns;
1383 :
1384 0 : bailout:
1385 0 : if (be->mvc->sa->eb.enabled)
1386 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
1387 : return NULL;
1388 : }
1389 :
1390 : stmt *
1391 21 : stmt_sample(backend *be, stmt *s, stmt *sample, stmt *seed)
1392 : {
1393 21 : MalBlkPtr mb = be->mb;
1394 21 : InstrPtr q = NULL;
1395 :
1396 21 : if (s == NULL || sample == NULL || s->nr < 0 || sample->nr < 0)
1397 0 : goto bailout;
1398 21 : q = newStmt(mb, sampleRef, subuniformRef);
1399 21 : if (q == NULL)
1400 0 : goto bailout;
1401 21 : q = pushArgument(mb, q, s->nr);
1402 21 : q = pushArgument(mb, q, sample->nr);
1403 :
1404 21 : if (seed) {
1405 12 : if (seed->nr < 0)
1406 0 : goto bailout;
1407 :
1408 12 : q = pushArgument(mb, q, seed->nr);
1409 : }
1410 :
1411 21 : bool enabled = be->mvc->sa->eb.enabled;
1412 21 : be->mvc->sa->eb.enabled = false;
1413 21 : stmt *ns = stmt_create(be->mvc->sa, st_sample);
1414 21 : be->mvc->sa->eb.enabled = enabled;
1415 21 : if (ns == NULL) {
1416 0 : freeInstruction(q);
1417 0 : goto bailout;
1418 : }
1419 :
1420 21 : ns->op1 = s;
1421 21 : ns->op2 = sample;
1422 :
1423 21 : if (seed) {
1424 12 : ns->op3 = seed;
1425 : }
1426 :
1427 21 : ns->nrcols = s->nrcols;
1428 21 : ns->key = s->key;
1429 21 : ns->aggr = s->aggr;
1430 21 : ns->flag = 0;
1431 21 : ns->q = q;
1432 21 : ns->nr = getDestVar(q);
1433 21 : pushInstruction(mb, q);
1434 21 : return ns;
1435 :
1436 0 : bailout:
1437 0 : if (be->mvc->sa->eb.enabled)
1438 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
1439 : return NULL;
1440 : }
1441 :
1442 :
1443 : stmt *
1444 10520 : stmt_order(backend *be, stmt *s, int direction, int nullslast)
1445 : {
1446 10520 : MalBlkPtr mb = be->mb;
1447 10520 : InstrPtr q = NULL;
1448 :
1449 10520 : if (s == NULL || s->nr < 0)
1450 0 : goto bailout;
1451 10520 : q = newStmt(mb, algebraRef, sortRef);
1452 10520 : if (q == NULL)
1453 0 : goto bailout;
1454 : /* both ordered result and oid's order en subgroups */
1455 10520 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
1456 10520 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
1457 10520 : q = pushArgument(mb, q, s->nr);
1458 10520 : q = pushBit(mb, q, !direction);
1459 10520 : q = pushBit(mb, q, nullslast);
1460 10520 : q = pushBit(mb, q, FALSE);
1461 :
1462 10520 : bool enabled = be->mvc->sa->eb.enabled;
1463 10520 : be->mvc->sa->eb.enabled = false;
1464 10520 : stmt *ns = stmt_create(be->mvc->sa, st_order);
1465 10520 : be->mvc->sa->eb.enabled = enabled;
1466 10520 : if (ns == NULL) {
1467 0 : freeInstruction(q);
1468 0 : goto bailout;
1469 : }
1470 :
1471 10520 : ns->op1 = s;
1472 10520 : ns->flag = direction;
1473 10520 : ns->nrcols = s->nrcols;
1474 10520 : ns->key = s->key;
1475 10520 : ns->aggr = s->aggr;
1476 10520 : ns->q = q;
1477 10520 : ns->nr = getDestVar(q);
1478 10520 : pushInstruction(mb, q);
1479 10520 : return ns;
1480 :
1481 0 : bailout:
1482 0 : if (be->mvc->sa->eb.enabled)
1483 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
1484 : return NULL;
1485 : }
1486 :
1487 : stmt *
1488 13794 : stmt_reorder(backend *be, stmt *s, int direction, int nullslast, stmt *orderby_ids, stmt *orderby_grp)
1489 : {
1490 13794 : MalBlkPtr mb = be->mb;
1491 13794 : InstrPtr q = NULL;
1492 :
1493 13794 : if (s == NULL || orderby_ids == NULL || orderby_grp == NULL || s->nr < 0 || orderby_ids->nr < 0 || orderby_grp->nr < 0)
1494 0 : goto bailout;
1495 13794 : q = newStmtArgs(mb, algebraRef, sortRef, 9);
1496 13794 : if (q == NULL)
1497 0 : goto bailout;
1498 : /* both ordered result and oid's order en subgroups */
1499 13794 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
1500 13794 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
1501 13794 : q = pushArgument(mb, q, s->nr);
1502 13794 : q = pushArgument(mb, q, orderby_ids->nr);
1503 13794 : q = pushArgument(mb, q, orderby_grp->nr);
1504 13794 : q = pushBit(mb, q, !direction);
1505 13794 : q = pushBit(mb, q, nullslast);
1506 13794 : q = pushBit(mb, q, FALSE);
1507 :
1508 13794 : bool enabled = be->mvc->sa->eb.enabled;
1509 13794 : be->mvc->sa->eb.enabled = false;
1510 13794 : stmt *ns = stmt_create(be->mvc->sa, st_reorder);
1511 13794 : be->mvc->sa->eb.enabled = enabled;
1512 13794 : if (ns == NULL) {
1513 0 : freeInstruction(q);
1514 0 : goto bailout;
1515 : }
1516 :
1517 13794 : ns->op1 = s;
1518 13794 : ns->op2 = orderby_ids;
1519 13794 : ns->op3 = orderby_grp;
1520 13794 : ns->flag = direction;
1521 13794 : ns->nrcols = s->nrcols;
1522 13794 : ns->key = s->key;
1523 13794 : ns->aggr = s->aggr;
1524 13794 : ns->nr = getDestVar(q);
1525 13794 : ns->q = q;
1526 13794 : pushInstruction(mb, q);
1527 13794 : return ns;
1528 :
1529 0 : bailout:
1530 0 : if (be->mvc->sa->eb.enabled)
1531 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
1532 : return NULL;
1533 : }
1534 :
1535 : stmt *
1536 3432734 : stmt_atom(backend *be, atom *a)
1537 : {
1538 3432734 : MalBlkPtr mb = be->mb;
1539 :
1540 3432734 : if (a == NULL)
1541 0 : goto bailout;
1542 :
1543 3432734 : InstrPtr q = EC_TEMP_FRAC(atom_type(a)->type->eclass) ? newStmt(mb, calcRef, atom_type(a)->type->impl) : newAssignment(mb);
1544 :
1545 3433955 : if (q == NULL)
1546 0 : goto bailout;
1547 3433955 : if (atom_null(a)) {
1548 151902 : q = pushNil(mb, q, atom_type(a)->type->localtype);
1549 : } else {
1550 3282053 : int k;
1551 3282053 : if ((k = constantAtom(be, mb, a)) == -1) {
1552 0 : freeInstruction(q);
1553 0 : goto bailout;
1554 : }
1555 3281012 : q = pushArgument(mb, q, k);
1556 : }
1557 : /* digits of the result timestamp/daytime */
1558 3432960 : if (EC_TEMP_FRAC(atom_type(a)->type->eclass))
1559 47402 : q = pushInt(mb, q, atom_type(a)->digits);
1560 3433145 : bool enabled = be->mvc->sa->eb.enabled;
1561 3433145 : be->mvc->sa->eb.enabled = false;
1562 3433145 : stmt *s = stmt_create(be->mvc->sa, st_atom);
1563 3432398 : be->mvc->sa->eb.enabled = enabled;
1564 3432398 : if (s == NULL) {
1565 0 : freeInstruction(q);
1566 0 : goto bailout;
1567 : }
1568 :
1569 3432398 : s->op4.aval = a;
1570 3432398 : s->key = 1; /* values are also unique */
1571 3432398 : s->q = q;
1572 3432398 : s->nr = getDestVar(q);
1573 3432398 : pushInstruction(mb, q);
1574 3432398 : return s;
1575 :
1576 0 : bailout:
1577 0 : if (be->mvc->sa->eb.enabled)
1578 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
1579 : return NULL;
1580 : }
1581 :
1582 : stmt *
1583 3616 : stmt_genselect(backend *be, stmt *lops, stmt *rops, sql_subfunc *f, stmt *sub, int anti)
1584 : {
1585 3616 : MalBlkPtr mb = be->mb;
1586 3616 : InstrPtr q = NULL;
1587 3616 : const char *mod, *op;
1588 3616 : node *n;
1589 3616 : int k;
1590 :
1591 3616 : if (lops == NULL || rops == NULL)
1592 0 : goto bailout;
1593 :
1594 3616 : if (backend_create_subfunc(be, f, NULL) < 0)
1595 0 : goto bailout;
1596 3616 : op = backend_function_imp(be, f->func);
1597 3616 : mod = sql_func_mod(f->func);
1598 :
1599 3616 : if (rops->nrcols >= 1) {
1600 56 : bit need_not = FALSE;
1601 :
1602 56 : int narg = 3;
1603 112 : for (n = lops->op4.lval->h; n; n = n->next)
1604 56 : narg++;
1605 178 : for (n = rops->op4.lval->h; n; n = n->next)
1606 122 : narg++;
1607 56 : q = newStmtArgs(mb, malRef, multiplexRef, narg);
1608 56 : if (q == NULL)
1609 0 : goto bailout;
1610 56 : setVarType(mb, getArg(q, 0), newBatType(TYPE_bit));
1611 56 : q = pushStr(mb, q, convertMultiplexMod(mod, op));
1612 56 : q = pushStr(mb, q, convertMultiplexFcn(op));
1613 112 : for (n = lops->op4.lval->h; n; n = n->next) {
1614 56 : stmt *op = n->data;
1615 :
1616 56 : q = pushArgument(mb, q, op->nr);
1617 : }
1618 178 : for (n = rops->op4.lval->h; n; n = n->next) {
1619 122 : stmt *op = n->data;
1620 :
1621 122 : q = pushArgument(mb, q, op->nr);
1622 : }
1623 56 : k = getDestVar(q);
1624 56 : pushInstruction(mb, q);
1625 :
1626 56 : q = newStmtArgs(mb, algebraRef, selectRef, 9);
1627 56 : if (q == NULL)
1628 0 : goto bailout;
1629 56 : q = pushArgument(mb, q, k);
1630 56 : if (sub)
1631 36 : q = pushArgument(mb, q, sub->nr);
1632 56 : q = pushBit(mb, q, !need_not);
1633 56 : q = pushBit(mb, q, !need_not);
1634 56 : q = pushBit(mb, q, TRUE);
1635 56 : q = pushBit(mb, q, TRUE);
1636 56 : q = pushBit(mb, q, anti);
1637 : } else {
1638 3560 : node *n;
1639 :
1640 3560 : op = sa_strconcat(be->mvc->sa, op, selectRef);
1641 3560 : q = newStmtArgs(mb, mod, convertMultiplexFcn(op), 9);
1642 3560 : if (q == NULL)
1643 0 : goto bailout;
1644 : // push pointer to the SQL structure into the MAL call
1645 : // allows getting argument names for example
1646 3560 : if (LANG_EXT(f->func->lang))
1647 0 : q = pushPtr(mb, q, f->func); // nothing to see here, please move along
1648 : // f->query contains the R code to be run
1649 3560 : if (f->func->lang == FUNC_LANG_R || f->func->lang >= FUNC_LANG_PY)
1650 0 : q = pushStr(mb, q, f->func->query);
1651 :
1652 7120 : for (n = lops->op4.lval->h; n; n = n->next) {
1653 3560 : stmt *op = n->data;
1654 :
1655 3560 : q = pushArgument(mb, q, op->nr);
1656 : }
1657 : /* candidate lists */
1658 3560 : if (sub)
1659 3491 : q = pushArgument(mb, q, sub->nr);
1660 : else
1661 69 : q = pushNilBat(mb, q);
1662 :
1663 13993 : for (n = rops->op4.lval->h; n; n = n->next) {
1664 10433 : stmt *op = n->data;
1665 :
1666 10433 : q = pushArgument(mb, q, op->nr);
1667 : }
1668 :
1669 3560 : q = pushBit(mb, q, anti);
1670 : }
1671 :
1672 3616 : bool enabled = be->mvc->sa->eb.enabled;
1673 3616 : be->mvc->sa->eb.enabled = false;
1674 3616 : stmt *s = stmt_create(be->mvc->sa, st_uselect);
1675 3616 : be->mvc->sa->eb.enabled = enabled;
1676 3616 : if (s == NULL) {
1677 0 : freeInstruction(q);
1678 0 : goto bailout;
1679 : }
1680 :
1681 3616 : s->op1 = lops;
1682 3616 : s->op2 = rops;
1683 3616 : s->op3 = sub;
1684 3616 : s->key = lops->nrcols == 0 && rops->nrcols == 0;
1685 3616 : s->flag = cmp_filter;
1686 3616 : s->nrcols = lops->nrcols;
1687 3616 : s->nr = getDestVar(q);
1688 3616 : s->q = q;
1689 3616 : s->cand = sub;
1690 3616 : pushInstruction(mb, q);
1691 3616 : return s;
1692 :
1693 0 : bailout:
1694 0 : if (be->mvc->sa->eb.enabled)
1695 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
1696 : return NULL;
1697 : }
1698 :
1699 : stmt *
1700 216797 : stmt_uselect(backend *be, stmt *op1, stmt *op2, comp_type cmptype, stmt *sub, int anti, int is_semantics)
1701 : {
1702 216797 : MalBlkPtr mb = be->mb;
1703 216797 : InstrPtr q = NULL;
1704 216797 : int l, r;
1705 216797 : stmt *sel = sub;
1706 :
1707 216797 : if (op1 == NULL || op2 == NULL || op1->nr < 0 || op2->nr < 0 || (sub && sub->nr < 0))
1708 0 : goto bailout;
1709 216797 : l = op1->nr;
1710 216797 : r = op2->nr;
1711 :
1712 216797 : if (op2->nrcols >= 1 && op1->nrcols == 0) { /* swap */
1713 80 : stmt *v = op1;
1714 80 : op1 = op2;
1715 80 : op2 = v;
1716 80 : int n = l;
1717 80 : l = r;
1718 80 : r = n;
1719 80 : cmptype = swap_compare(cmptype);
1720 : }
1721 216797 : if (op2->nrcols >= 1) {
1722 18136 : bit need_not = FALSE;
1723 18136 : const char *mod = calcRef;
1724 18136 : const char *op = "=";
1725 18136 : int k;
1726 :
1727 18136 : switch (cmptype) {
1728 : case cmp_equal:
1729 : op = "=";
1730 : break;
1731 : case cmp_notequal:
1732 18136 : op = "!=";
1733 : break;
1734 920 : case cmp_lt:
1735 920 : op = "<";
1736 920 : break;
1737 775 : case cmp_lte:
1738 775 : op = "<=";
1739 775 : break;
1740 4831 : case cmp_gt:
1741 4831 : op = ">";
1742 4831 : break;
1743 800 : case cmp_gte:
1744 800 : op = ">=";
1745 800 : break;
1746 0 : default:
1747 0 : TRC_ERROR(SQL_EXECUTION, "Unknown operator\n");
1748 : }
1749 :
1750 28679 : if ((q = multiplex2(mb, mod, convertMultiplexFcn(op), l, r, TYPE_bit)) == NULL)
1751 0 : goto bailout;
1752 18136 : if (sub && (op1->cand || op2->cand)) {
1753 1758 : if (op1->cand && !op2->cand) {
1754 30 : if (op1->nrcols > 0)
1755 30 : q = pushNilBat(mb, q);
1756 30 : q = pushArgument(mb, q, sub->nr);
1757 1728 : } else if (!op1->cand && op2->cand) {
1758 1693 : q = pushArgument(mb, q, sub->nr);
1759 1693 : if (op2->nrcols > 0)
1760 1693 : q = pushNilBat(mb, q);
1761 : }
1762 : sub = NULL;
1763 : }
1764 18136 : if (is_semantics)
1765 2988 : q = pushBit(mb, q, TRUE);
1766 18136 : k = getDestVar(q);
1767 :
1768 18136 : q = newStmtArgs(mb, algebraRef, selectRef, 9);
1769 18136 : if (q == NULL)
1770 0 : goto bailout;
1771 18136 : q = pushArgument(mb, q, k);
1772 18136 : if (sub)
1773 4363 : q = pushArgument(mb, q, sub->nr);
1774 18136 : q = pushBit(mb, q, !need_not);
1775 18136 : q = pushBit(mb, q, !need_not);
1776 18136 : q = pushBit(mb, q, TRUE);
1777 18136 : q = pushBit(mb, q, TRUE);
1778 18136 : q = pushBit(mb, q, anti);
1779 18136 : k = getDestVar(q);
1780 : } else {
1781 198661 : assert (cmptype != cmp_filter);
1782 198661 : q = newStmt(mb, algebraRef, thetaselectRef);
1783 198667 : if (q == NULL)
1784 0 : goto bailout;
1785 198667 : q = pushArgument(mb, q, l);
1786 198665 : if (sub && !op1->cand) {
1787 129770 : q = pushArgument(mb, q, sub->nr);
1788 : } else {
1789 630 : assert(!sub || op1->cand == sub);
1790 68895 : q = pushNilBat(mb, q);
1791 68895 : sub = NULL;
1792 : }
1793 198668 : q = pushArgument(mb, q, r);
1794 198642 : switch (cmptype) {
1795 162725 : case cmp_equal:
1796 162725 : if (is_semantics)
1797 34875 : q = pushStr(mb, q, anti?"ne":"eq");
1798 : else
1799 285530 : q = pushStr(mb, q, anti?"!=":"==");
1800 : break;
1801 32838 : case cmp_notequal:
1802 32838 : if (is_semantics)
1803 150 : q = pushStr(mb, q, anti?"eq":"ne");
1804 : else
1805 65526 : q = pushStr(mb, q, anti?"==":"!=");
1806 : break;
1807 436 : case cmp_lt:
1808 436 : q = pushStr(mb, q, anti?">=":"<");
1809 436 : break;
1810 74 : case cmp_lte:
1811 74 : q = pushStr(mb, q, anti?">":"<=");
1812 74 : break;
1813 2290 : case cmp_gt:
1814 2290 : q = pushStr(mb, q, anti?"<=":">");
1815 2290 : break;
1816 279 : case cmp_gte:
1817 279 : q = pushStr(mb, q, anti?"<":">=");
1818 279 : break;
1819 0 : default:
1820 0 : TRC_ERROR(SQL_EXECUTION, "Impossible select compare\n");
1821 0 : if (q)
1822 0 : freeInstruction(q);
1823 0 : q = NULL;
1824 0 : goto bailout;
1825 : }
1826 : }
1827 :
1828 216802 : bool enabled = be->mvc->sa->eb.enabled;
1829 216802 : be->mvc->sa->eb.enabled = false;
1830 216802 : stmt *s = stmt_create(be->mvc->sa, st_uselect);
1831 216782 : be->mvc->sa->eb.enabled = enabled;
1832 216782 : if (s == NULL) {
1833 0 : freeInstruction(q);
1834 0 : goto bailout;
1835 : }
1836 :
1837 216782 : s->op1 = op1;
1838 216782 : s->op2 = op2;
1839 216782 : s->op3 = sub;
1840 216782 : s->flag = cmptype;
1841 216782 : s->key = op1->nrcols == 0 && op2->nrcols == 0;
1842 216782 : s->nrcols = op1->nrcols;
1843 216782 : s->nr = getDestVar(q);
1844 216782 : s->q = q;
1845 216782 : s->cand = sub;
1846 216782 : pushInstruction(mb, q);
1847 216802 : if (!sub && sel) /* project back the old ids */
1848 2388 : return stmt_project(be, s, sel);
1849 : return s;
1850 :
1851 0 : bailout:
1852 0 : if (be->mvc->sa->eb.enabled)
1853 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
1854 : return NULL;
1855 : }
1856 :
1857 : /*
1858 : static int
1859 : range_join_convertable(stmt *s, stmt **base, stmt **L, stmt **H)
1860 : {
1861 : int ls = 0, hs = 0;
1862 : stmt *l = NULL, *h = NULL;
1863 : stmt *bl = s->op2, *bh = s->op3;
1864 : int tt = tail_type(s->op2)->type->localtype;
1865 :
1866 : #ifdef HAVE_HGE
1867 : if (tt > TYPE_hge)
1868 : #else
1869 : if (tt > TYPE_lng)
1870 : #endif
1871 : return 0;
1872 : if (s->op2->type == st_Nop && list_length(s->op2->op1->op4.lval) == 2) {
1873 : bl = s->op2->op1->op4.lval->h->data;
1874 : l = s->op2->op1->op4.lval->t->data;
1875 : }
1876 : if (s->op3->type == st_Nop && list_length(s->op3->op1->op4.lval) == 2) {
1877 : bh = s->op3->op1->op4.lval->h->data;
1878 : h = s->op3->op1->op4.lval->t->data;
1879 : }
1880 :
1881 : if (((ls = (l && strcmp(s->op2->op4.funcval->func->base.name, "sql_sub") == 0 && l->nrcols == 0)) || (hs = (h && strcmp(s->op3->op4.funcval->func->base.name, "sql_add") == 0 && h->nrcols == 0))) && (ls || hs) && bl == bh) {
1882 : *base = bl;
1883 : *L = l;
1884 : *H = h;
1885 : return 1;
1886 : }
1887 : return 0;
1888 : }
1889 :
1890 : static int
1891 : argumentZero(MalBlkPtr mb, int tpe)
1892 : {
1893 : ValRecord cst;
1894 : str msg;
1895 :
1896 : cst.vtype = TYPE_int;
1897 : cst.val.ival = 0;
1898 : msg = convertConstant(tpe, &cst);
1899 : if( msg)
1900 : freeException(msg); // will not be called
1901 : return defConstant(mb, tpe, &cst);
1902 : }
1903 : */
1904 :
1905 : static InstrPtr
1906 5110 : select2_join2(backend *be, stmt *op1, stmt *op2, stmt *op3, int cmp, stmt **Sub, int anti, int symmetric, int swapped, int type, int reduce)
1907 : {
1908 5110 : MalBlkPtr mb = be->mb;
1909 5110 : InstrPtr p, q;
1910 5110 : int l;
1911 5110 : const char *cmd = (type == st_uselect2) ? selectRef : rangejoinRef;
1912 5110 : stmt *sub = (Sub)?*Sub:NULL;
1913 :
1914 5110 : if (op1 == NULL || op2 == NULL || op3 == NULL || op1->nr < 0 || (sub && sub->nr < 0))
1915 0 : goto bailout;
1916 5110 : l = op1->nr;
1917 8482 : if ((symmetric || op2->nrcols > 0 || op3->nrcols > 0 || !reduce) && (type == st_uselect2)) {
1918 3602 : int k;
1919 3602 : int nrcols = (op1->nrcols || op2->nrcols || op3->nrcols);
1920 :
1921 3602 : if (op2->nr < 0 || op3->nr < 0)
1922 0 : goto bailout;
1923 :
1924 3602 : if (nrcols)
1925 3561 : p = newStmtArgs(mb, batcalcRef, betweenRef, 12);
1926 : else
1927 41 : p = newStmtArgs(mb, calcRef, betweenRef, 9);
1928 3602 : if (p == NULL)
1929 0 : goto bailout;
1930 3602 : p = pushArgument(mb, p, l);
1931 3602 : p = pushArgument(mb, p, op2->nr);
1932 3602 : p = pushArgument(mb, p, op3->nr);
1933 :
1934 : /* cands */
1935 3602 : if ((sub && !reduce) || op1->cand || op2->cand || op3->cand) { /* some already handled the previous selection */
1936 1570 : if (op1->cand && op1->nrcols)
1937 1287 : p = pushNilBat(mb, p);
1938 283 : else if (op1->nrcols)
1939 283 : p = pushArgument(mb, p, sub->nr);
1940 1570 : if (op2->nrcols) {
1941 1466 : if (op2->cand)
1942 1220 : p = pushNilBat(mb, p);
1943 246 : else if (op2->nrcols)
1944 246 : p = pushArgument(mb, p, sub->nr);
1945 : }
1946 1570 : if (op3->nrcols) {
1947 1461 : if (op3->cand)
1948 1336 : p = pushNilBat(mb, p);
1949 125 : else if (op3->nrcols)
1950 125 : p = pushArgument(mb, p, sub->nr);
1951 : }
1952 : sub = NULL;
1953 : }
1954 :
1955 3602 : p = pushBit(mb, p, (symmetric)?TRUE:FALSE); /* symmetric */
1956 3602 : p = pushBit(mb, p, (cmp & 1) != 0); /* lo inclusive */
1957 3602 : p = pushBit(mb, p, (cmp & 2) != 0); /* hi inclusive */
1958 3602 : p = pushBit(mb, p, FALSE); /* nils_false */
1959 3602 : p = pushBit(mb, p, (anti)?TRUE:FALSE); /* anti */
1960 3602 : pushInstruction(mb, p);
1961 3602 : if (!reduce)
1962 : return p;
1963 3372 : k = getDestVar(p);
1964 :
1965 3372 : q = newStmtArgs(mb, algebraRef, selectRef, 9);
1966 3372 : if (q == NULL)
1967 0 : goto bailout;
1968 3372 : q = pushArgument(mb, q, k);
1969 3372 : if (sub)
1970 896 : q = pushArgument(mb, q, sub->nr);
1971 3372 : q = pushBit(mb, q, TRUE);
1972 3372 : q = pushBit(mb, q, TRUE);
1973 3372 : q = pushBit(mb, q, TRUE);
1974 3372 : q = pushBit(mb, q, TRUE);
1975 3372 : q = pushBit(mb, q, FALSE);
1976 3372 : pushInstruction(mb, q);
1977 : } else {
1978 : /* if st_join2 try to convert to bandjoin */
1979 : /* ie check if we subtract/add a constant, to the
1980 : same column */
1981 : /* move this optimization into the relational phase! */
1982 : /*
1983 : stmt *base, *low = NULL, *high = NULL;
1984 : if (type == st_join2 && range_join_convertable(s, &base, &low, &high)) {
1985 : int tt = tail_type(base)->type->localtype;
1986 :
1987 : if ((rs = _dumpstmt(sql, mb, base)) < 0)
1988 : return -1;
1989 : if (low) {
1990 : if ((r1 = _dumpstmt(sql, mb, low)) < 0)
1991 : return -1;
1992 : } else
1993 : r1 = argumentZero(mb, tt);
1994 : if (high) {
1995 : if ((r2 = _dumpstmt(sql, mb, high)) < 0)
1996 : return -1;
1997 : } else
1998 : r2 = argumentZero(mb, tt);
1999 : cmd = bandjoinRef;
2000 : }
2001 : */
2002 :
2003 1508 : int r1 = op2->nr;
2004 1508 : int r2 = op3->nr;
2005 1508 : int rs = 0;
2006 1508 : q = newStmtArgs(mb, algebraRef, cmd, 12);
2007 1508 : if (q == NULL)
2008 0 : goto bailout;
2009 1508 : if (type == st_join2)
2010 54 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
2011 1508 : q = pushArgument(mb, q, l);
2012 1508 : if (sub) {
2013 1189 : int cand = op1->cand || op2->cand || op3->cand;
2014 1182 : if (cand) {
2015 7 : assert(!op1->nrcols || op1->cand);
2016 7 : assert(!op2->nrcols || op2->cand);
2017 7 : assert(!op3->nrcols || op3->cand);
2018 : sub = NULL;
2019 : }
2020 : }
2021 1182 : if (sub) /* only for uselect2 */
2022 1182 : q = pushArgument(mb, q, sub->nr);
2023 1508 : if (rs) {
2024 : q = pushArgument(mb, q, rs);
2025 : } else {
2026 1508 : q = pushArgument(mb, q, r1);
2027 1508 : q = pushArgument(mb, q, r2);
2028 : }
2029 1508 : if (type == st_join2) {
2030 54 : q = pushNilBat(mb, q);
2031 54 : q = pushNilBat(mb, q);
2032 : }
2033 :
2034 1508 : switch (cmp & 3) {
2035 61 : case 0:
2036 61 : q = pushBit(mb, q, FALSE);
2037 61 : q = pushBit(mb, q, FALSE);
2038 61 : break;
2039 228 : case 1:
2040 228 : q = pushBit(mb, q, TRUE);
2041 228 : q = pushBit(mb, q, FALSE);
2042 228 : break;
2043 11 : case 2:
2044 11 : q = pushBit(mb, q, FALSE);
2045 11 : q = pushBit(mb, q, TRUE);
2046 11 : break;
2047 1208 : case 3:
2048 1208 : q = pushBit(mb, q, TRUE);
2049 1208 : q = pushBit(mb, q, TRUE);
2050 1208 : break;
2051 : }
2052 1508 : q = pushBit(mb, q, anti);
2053 1508 : if (type == st_uselect2) {
2054 1454 : q = pushBit(mb, q, TRUE); /* all nil's are != */
2055 : } else {
2056 54 : q = pushBit(mb, q, (symmetric)?TRUE:FALSE);
2057 : }
2058 1508 : if (type == st_join2)
2059 54 : q = pushNil(mb, q, TYPE_lng); /* estimate */
2060 1508 : pushInstruction(mb, q);
2061 1508 : if (swapped) {
2062 2 : InstrPtr r = newInstruction(mb, NULL, NULL);
2063 2 : if (r == NULL)
2064 0 : goto bailout;
2065 2 : getArg(r, 0) = newTmpVariable(mb, TYPE_any);
2066 2 : r = pushReturn(mb, r, newTmpVariable(mb, TYPE_any));
2067 2 : r = pushArgument(mb, r, getArg(q,1));
2068 2 : r = pushArgument(mb, r, getArg(q,0));
2069 2 : pushInstruction(mb, r);
2070 2 : q = r;
2071 : }
2072 : }
2073 4880 : if (Sub)
2074 4826 : *Sub = sub;
2075 : return q;
2076 :
2077 0 : bailout:
2078 0 : if (be->mvc->sa->eb.enabled)
2079 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
2080 : return NULL;
2081 : }
2082 :
2083 : stmt *
2084 38 : stmt_outerselect(backend *be, stmt *g, stmt *m, stmt *p, bool any)
2085 : {
2086 38 : MalBlkPtr mb = be->mb;
2087 38 : InstrPtr q;
2088 :
2089 38 : q = newStmtArgs(mb, algebraRef, outerselectRef, 6);
2090 38 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
2091 38 : q = pushArgument(mb, q, g->nr); /* group ids */
2092 38 : q = pushArgument(mb, q, m->nr); /* mark flag */
2093 38 : q = pushArgument(mb, q, p->nr); /* predicate */
2094 38 : q = pushBit(mb, q, (any)?TRUE:FALSE);
2095 38 : pushInstruction(mb, q);
2096 :
2097 38 : if (!q)
2098 : return NULL;
2099 38 : stmt *s = stmt_create(be->mvc->sa, st_uselect2);
2100 38 : if (s == NULL) {
2101 0 : freeInstruction(q);
2102 0 : return NULL;
2103 : }
2104 :
2105 38 : s->op1 = g;
2106 38 : s->op2 = m;
2107 38 : s->flag = MARKJOIN;
2108 38 : s->key = 0;
2109 38 : s->nrcols = g->nrcols;
2110 38 : s->nr = getDestVar(q);
2111 38 : s->q = q;
2112 38 : return s;
2113 : }
2114 :
2115 : stmt *
2116 404 : stmt_markselect(backend *be, stmt *g, stmt *m, stmt *p, bool any)
2117 : {
2118 404 : MalBlkPtr mb = be->mb;
2119 404 : InstrPtr q;
2120 :
2121 404 : q = newStmtArgs(mb, algebraRef, markselectRef, 6);
2122 404 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
2123 404 : q = pushArgument(mb, q, g->nr); /* left ids */
2124 404 : q = pushArgument(mb, q, m->nr); /* mark info mask */
2125 404 : q = pushArgument(mb, q, p->nr); /* predicate */
2126 404 : q = pushBit(mb, q, (any)?TRUE:FALSE);
2127 404 : pushInstruction(mb, q);
2128 :
2129 404 : if (!q)
2130 : return NULL;
2131 404 : stmt *s = stmt_create(be->mvc->sa, st_uselect2);
2132 404 : if (s == NULL) {
2133 0 : freeInstruction(q);
2134 0 : return NULL;
2135 : }
2136 :
2137 404 : s->op1 = g;
2138 404 : s->op2 = m;
2139 404 : s->flag = MARKJOIN;
2140 404 : s->key = 0;
2141 404 : s->nrcols = g->nrcols;
2142 404 : s->nr = getDestVar(q);
2143 404 : s->q = q;
2144 404 : return s;
2145 : }
2146 :
2147 : stmt *
2148 2518 : stmt_markjoin(backend *be, stmt *l, stmt *r, bool final)
2149 : {
2150 2518 : MalBlkPtr mb = be->mb;
2151 2518 : InstrPtr q;
2152 :
2153 2518 : q = newStmtArgs(mb, algebraRef, markjoinRef, 8);
2154 2518 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
2155 2518 : if (!final)
2156 5 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
2157 2518 : q = pushArgument(mb, q, l->nr); /* left ids */
2158 2518 : q = pushArgument(mb, q, r->nr); /* mark info mask */
2159 2518 : q = pushNilBat(mb, q);
2160 2518 : q = pushNilBat(mb, q);
2161 2518 : q = pushNil(mb, q, TYPE_lng);
2162 2518 : pushInstruction(mb, q);
2163 :
2164 2518 : if (!q)
2165 : return NULL;
2166 2518 : stmt *s = stmt_create(be->mvc->sa, st_join);
2167 2518 : if (s == NULL) {
2168 0 : freeInstruction(q);
2169 0 : return NULL;
2170 : }
2171 :
2172 2518 : s->op1 = l;
2173 2518 : s->op2 = r;
2174 2518 : s->flag = MARKJOIN;
2175 2518 : s->key = 0;
2176 2518 : s->nrcols = l->nrcols;
2177 2518 : s->nr = getDestVar(q);
2178 2518 : s->q = q;
2179 2518 : return s;
2180 : }
2181 :
2182 : stmt *
2183 5056 : stmt_uselect2(backend *be, stmt *op1, stmt *op2, stmt *op3, int cmp, stmt *sub, int anti, int symmetric, int reduce)
2184 : {
2185 5056 : stmt *sel = sub;
2186 5056 : InstrPtr q = select2_join2(be, op1, op2, op3, cmp, &sub, anti, symmetric, 0, st_uselect2, reduce);
2187 :
2188 5056 : if (q == NULL)
2189 : return NULL;
2190 :
2191 5056 : stmt *s = stmt_create(be->mvc->sa, st_uselect2);
2192 5056 : if (s == NULL) {
2193 : return NULL;
2194 : }
2195 :
2196 5056 : s->op1 = op1;
2197 5056 : s->op2 = op2;
2198 5056 : s->op3 = op3;
2199 5056 : s->op4.stval = sub;
2200 5056 : s->flag = cmp;
2201 5056 : s->nrcols = op1->nrcols;
2202 5056 : s->key = op1->nrcols == 0 && op2->nrcols == 0 && op3->nrcols == 0;
2203 5056 : s->nr = getDestVar(q);
2204 5056 : s->q = q;
2205 5056 : s->cand = sub;
2206 5056 : s->reduce = reduce;
2207 5056 : if (!sub && sel) /* project back the old ids */
2208 1458 : return stmt_project(be, s, sel);
2209 : return s;
2210 : }
2211 :
2212 : stmt *
2213 54229 : stmt_tunion(backend *be, stmt *op1, stmt *op2)
2214 : {
2215 54229 : InstrPtr q = NULL;
2216 54229 : MalBlkPtr mb = be->mb;
2217 :
2218 54229 : q = dump_2(mb, batRef, mergecandRef, op1, op2);
2219 54229 : if (q) {
2220 54229 : stmt *s = stmt_create(be->mvc->sa, st_tunion);
2221 54229 : if (s == NULL) {
2222 : return NULL;
2223 : }
2224 :
2225 54229 : s->op1 = op1;
2226 54229 : s->op2 = op2;
2227 54229 : s->nrcols = op1->nrcols;
2228 54229 : s->key = op1->key;
2229 54229 : s->aggr = op1->aggr;
2230 54229 : s->nr = getDestVar(q);
2231 54229 : s->q = q;
2232 54229 : return s;
2233 : }
2234 :
2235 0 : if (be->mvc->sa->eb.enabled)
2236 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
2237 : return NULL;
2238 : }
2239 :
2240 : stmt *
2241 44838 : stmt_tdiff(backend *be, stmt *op1, stmt *op2, stmt *lcand)
2242 : {
2243 44838 : InstrPtr q = NULL;
2244 44838 : MalBlkPtr mb = be->mb;
2245 :
2246 44838 : if (op1 == NULL || op2 == NULL || op1->nr < 0 || op2->nr < 0)
2247 0 : goto bailout;
2248 44838 : q = newStmt(mb, algebraRef, differenceRef);
2249 44838 : if (q == NULL)
2250 0 : goto bailout;
2251 44838 : q = pushArgument(mb, q, op1->nr); /* left */
2252 44838 : q = pushArgument(mb, q, op2->nr); /* right */
2253 44838 : if (lcand)
2254 0 : q = pushArgument(mb, q, lcand->nr); /* left */
2255 : else
2256 44838 : q = pushNilBat(mb, q); /* left candidate */
2257 44838 : q = pushNilBat(mb, q); /* right candidate */
2258 44838 : q = pushBit(mb, q, FALSE); /* nil matches */
2259 44838 : q = pushBit(mb, q, FALSE); /* do not clear nils */
2260 44838 : q = pushNil(mb, q, TYPE_lng); /* estimate */
2261 :
2262 44838 : bool enabled = be->mvc->sa->eb.enabled;
2263 44838 : be->mvc->sa->eb.enabled = false;
2264 44838 : stmt *s = stmt_create(be->mvc->sa, st_tdiff);
2265 44838 : be->mvc->sa->eb.enabled = enabled;
2266 44838 : if (s == NULL) {
2267 0 : freeInstruction(q);
2268 0 : goto bailout;
2269 : }
2270 :
2271 44838 : s->op1 = op1;
2272 44838 : s->op2 = op2;
2273 44838 : s->nrcols = op1->nrcols;
2274 44838 : s->key = op1->key;
2275 44838 : s->aggr = op1->aggr;
2276 44838 : s->nr = getDestVar(q);
2277 44838 : s->q = q;
2278 44838 : pushInstruction(mb, q);
2279 44838 : return s;
2280 :
2281 0 : bailout:
2282 0 : if (be->mvc->sa->eb.enabled)
2283 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
2284 : return NULL;
2285 : }
2286 :
2287 : stmt *
2288 1378 : stmt_tdiff2(backend *be, stmt *op1, stmt *op2, stmt *lcand)
2289 : {
2290 1378 : InstrPtr q = NULL;
2291 1378 : MalBlkPtr mb = be->mb;
2292 :
2293 1378 : if (op1 == NULL || op2 == NULL || op1->nr < 0 || op2->nr < 0)
2294 0 : goto bailout;
2295 1378 : q = newStmt(mb, algebraRef, differenceRef);
2296 1378 : if (q == NULL)
2297 0 : goto bailout;
2298 1378 : q = pushArgument(mb, q, op1->nr); /* left */
2299 1378 : q = pushArgument(mb, q, op2->nr); /* right */
2300 1378 : if (lcand)
2301 0 : q = pushArgument(mb, q, lcand->nr); /* left */
2302 : else
2303 1378 : q = pushNilBat(mb, q); /* left candidate */
2304 1378 : q = pushNilBat(mb, q); /* right candidate */
2305 1378 : q = pushBit(mb, q, FALSE); /* nil matches */
2306 1378 : q = pushBit(mb, q, TRUE); /* not in */
2307 1378 : q = pushNil(mb, q, TYPE_lng); /* estimate */
2308 :
2309 1378 : bool enabled = be->mvc->sa->eb.enabled;
2310 1378 : be->mvc->sa->eb.enabled = false;
2311 1378 : stmt *s = stmt_create(be->mvc->sa, st_tdiff);
2312 1378 : be->mvc->sa->eb.enabled = enabled;
2313 1378 : if (s == NULL) {
2314 0 : freeInstruction(q);
2315 0 : goto bailout;
2316 : }
2317 :
2318 1378 : s->op1 = op1;
2319 1378 : s->op2 = op2;
2320 1378 : s->nrcols = op1->nrcols;
2321 1378 : s->key = op1->key;
2322 1378 : s->aggr = op1->aggr;
2323 1378 : s->nr = getDestVar(q);
2324 1378 : s->q = q;
2325 1378 : pushInstruction(mb, q);
2326 1378 : return s;
2327 :
2328 0 : bailout:
2329 0 : if (be->mvc->sa->eb.enabled)
2330 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
2331 : return NULL;
2332 : }
2333 :
2334 : stmt *
2335 2109 : stmt_tinter(backend *be, stmt *op1, stmt *op2, bool single)
2336 : {
2337 2109 : InstrPtr q = NULL;
2338 2109 : MalBlkPtr mb = be->mb;
2339 :
2340 2109 : if (op1 == NULL || op2 == NULL || op1->nr < 0 || op2->nr < 0)
2341 0 : goto bailout;
2342 2109 : q = newStmt(mb, algebraRef, intersectRef);
2343 2109 : if (q == NULL)
2344 0 : goto bailout;
2345 2109 : q = pushArgument(mb, q, op1->nr); /* left */
2346 2109 : q = pushArgument(mb, q, op2->nr); /* right */
2347 2109 : q = pushNilBat(mb, q); /* left candidate */
2348 2109 : q = pushNilBat(mb, q); /* right candidate */
2349 2109 : q = pushBit(mb, q, FALSE); /* nil matches */
2350 2109 : q = pushBit(mb, q, single?TRUE:FALSE); /* max_one */
2351 2109 : q = pushNil(mb, q, TYPE_lng); /* estimate */
2352 :
2353 2109 : bool enabled = be->mvc->sa->eb.enabled;
2354 2109 : be->mvc->sa->eb.enabled = false;
2355 2109 : stmt *s = stmt_create(be->mvc->sa, st_tinter);
2356 2109 : be->mvc->sa->eb.enabled = enabled;
2357 2109 : if (s == NULL) {
2358 0 : freeInstruction(q);
2359 0 : goto bailout;
2360 : }
2361 :
2362 2109 : s->op1 = op1;
2363 2109 : s->op2 = op2;
2364 2109 : s->nrcols = op1->nrcols;
2365 2109 : s->key = op1->key;
2366 2109 : s->aggr = op1->aggr;
2367 2109 : s->nr = getDestVar(q);
2368 2109 : s->q = q;
2369 2109 : pushInstruction(mb, q);
2370 2109 : return s;
2371 :
2372 0 : bailout:
2373 0 : if (be->mvc->sa->eb.enabled)
2374 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
2375 : return NULL;
2376 : }
2377 :
2378 : stmt *
2379 95102 : stmt_join_cand(backend *be, stmt *op1, stmt *op2, stmt *lcand, stmt *rcand, int anti, comp_type cmptype, int need_left, int is_semantics, bool single, bool inner)
2380 : {
2381 95102 : MalBlkPtr mb = be->mb;
2382 95102 : InstrPtr q = NULL;
2383 95102 : const char *sjt = inner?joinRef:outerjoinRef;
2384 :
2385 95102 : (void)anti;
2386 95102 : (void)inner;
2387 :
2388 95102 : if (need_left) {
2389 653 : cmptype = cmp_equal;
2390 653 : sjt = leftjoinRef;
2391 : }
2392 95102 : if (op1 == NULL || op2 == NULL || op1->nr < 0 || op2->nr < 0)
2393 0 : goto bailout;
2394 :
2395 95102 : assert (!single || cmptype == cmp_all);
2396 :
2397 95102 : switch (cmptype) {
2398 77024 : case cmp_equal:
2399 77024 : q = newStmtArgs(mb, algebraRef, sjt, 9);
2400 77024 : if (q == NULL)
2401 0 : goto bailout;
2402 77024 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
2403 77024 : q = pushArgument(mb, q, op1->nr);
2404 77024 : q = pushArgument(mb, q, op2->nr);
2405 77024 : if (!lcand)
2406 75936 : q = pushNilBat(mb, q);
2407 : else
2408 1088 : q = pushArgument(mb, q, lcand->nr);
2409 77024 : if (!rcand)
2410 77024 : q = pushNilBat(mb, q);
2411 : else
2412 0 : q = pushArgument(mb, q, rcand->nr);
2413 77024 : q = pushBit(mb, q, is_semantics?TRUE:FALSE);
2414 77024 : if (!inner)
2415 75 : q = pushBit(mb, q, FALSE); /* not match_one */
2416 77024 : q = pushNil(mb, q, TYPE_lng);
2417 77024 : pushInstruction(mb, q);
2418 77024 : break;
2419 34 : case cmp_notequal:
2420 34 : if (inner)
2421 34 : sjt = thetajoinRef;
2422 34 : q = newStmtArgs(mb, algebraRef, sjt, 9);
2423 34 : if (q == NULL)
2424 0 : goto bailout;
2425 34 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
2426 34 : q = pushArgument(mb, q, op1->nr);
2427 34 : q = pushArgument(mb, q, op2->nr);
2428 34 : if (!lcand)
2429 34 : q = pushNilBat(mb, q);
2430 : else
2431 0 : q = pushArgument(mb, q, lcand->nr);
2432 34 : if (!rcand)
2433 34 : q = pushNilBat(mb, q);
2434 : else
2435 0 : q = pushArgument(mb, q, rcand->nr);
2436 34 : if (inner)
2437 34 : q = pushInt(mb, q, JOIN_NE);
2438 34 : q = pushBit(mb, q, is_semantics?TRUE:FALSE);
2439 34 : if (!inner)
2440 0 : q = pushBit(mb, q, FALSE); /* not match_one */
2441 34 : q = pushNil(mb, q, TYPE_lng);
2442 34 : pushInstruction(mb, q);
2443 34 : break;
2444 2584 : case cmp_lt:
2445 : case cmp_lte:
2446 : case cmp_gt:
2447 : case cmp_gte:
2448 2584 : q = newStmtArgs(mb, algebraRef, thetajoinRef, 9);
2449 2584 : if (q == NULL)
2450 0 : goto bailout;
2451 2584 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
2452 2584 : q = pushArgument(mb, q, op1->nr);
2453 2584 : q = pushArgument(mb, q, op2->nr);
2454 2584 : if (!lcand)
2455 2584 : q = pushNilBat(mb, q);
2456 : else
2457 0 : q = pushArgument(mb, q, lcand->nr);
2458 2584 : if (!rcand)
2459 2584 : q = pushNilBat(mb, q);
2460 : else
2461 0 : q = pushArgument(mb, q, rcand->nr);
2462 2584 : if (cmptype == cmp_lt)
2463 2068 : q = pushInt(mb, q, JOIN_LT);
2464 516 : else if (cmptype == cmp_lte)
2465 8 : q = pushInt(mb, q, JOIN_LE);
2466 508 : else if (cmptype == cmp_gt)
2467 503 : q = pushInt(mb, q, JOIN_GT);
2468 5 : else if (cmptype == cmp_gte)
2469 5 : q = pushInt(mb, q, JOIN_GE);
2470 2584 : q = pushBit(mb, q, is_semantics?TRUE:FALSE);
2471 2584 : q = pushNil(mb, q, TYPE_lng);
2472 2584 : pushInstruction(mb, q);
2473 2584 : break;
2474 12235 : case cmp_all: /* aka cross table */
2475 12673 : q = newStmt(mb, algebraRef, inner?crossRef:outercrossRef);
2476 12235 : if (q == NULL)
2477 0 : goto bailout;
2478 12235 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
2479 12235 : q = pushArgument(mb, q, op1->nr);
2480 12235 : q = pushArgument(mb, q, op2->nr);
2481 12235 : if (!inner) {
2482 438 : q = pushNilBat(mb, q);
2483 438 : q = pushNilBat(mb, q);
2484 : }
2485 12235 : q = pushBit(mb, q, single?TRUE:FALSE); /* max_one */
2486 12235 : assert(!lcand && !rcand);
2487 12235 : pushInstruction(mb, q);
2488 12235 : break;
2489 3225 : case cmp_joined:
2490 3225 : q = op1->q;
2491 3225 : if (q == NULL)
2492 0 : goto bailout;
2493 : break;
2494 0 : default:
2495 0 : TRC_ERROR(SQL_EXECUTION, "Impossible action\n");
2496 : }
2497 :
2498 95102 : stmt *s = stmt_create(be->mvc->sa, st_join);
2499 95102 : if (s == NULL) {
2500 0 : goto bailout;
2501 : }
2502 :
2503 95102 : s->op1 = op1;
2504 95102 : s->op2 = op2;
2505 95102 : s->flag = cmptype;
2506 95102 : s->key = 0;
2507 95102 : s->nrcols = 2;
2508 95102 : s->nr = getDestVar(q);
2509 95102 : s->q = q;
2510 95102 : return s;
2511 :
2512 0 : bailout:
2513 0 : if (be->mvc->sa->eb.enabled)
2514 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
2515 : return NULL;
2516 : }
2517 :
2518 : stmt *
2519 90882 : stmt_join(backend *be, stmt *l, stmt *r, int anti, comp_type cmptype, int need_left, int is_semantics, bool single)
2520 : {
2521 90882 : return stmt_join_cand(be, l, r, NULL, NULL, anti, cmptype, need_left, is_semantics, single, true);
2522 : }
2523 :
2524 : stmt *
2525 1454 : stmt_semijoin(backend *be, stmt *op1, stmt *op2, stmt *lcand, stmt *rcand, int is_semantics, bool single)
2526 : {
2527 1454 : MalBlkPtr mb = be->mb;
2528 1454 : InstrPtr q = NULL;
2529 :
2530 1454 : if (op1 == NULL || op2 == NULL || op1->nr < 0 || op2->nr < 0)
2531 0 : goto bailout;
2532 :
2533 1454 : if (single) {
2534 284 : q = newStmtArgs(mb, algebraRef, semijoinRef, 9);
2535 284 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
2536 : } else
2537 1170 : q = newStmt(mb, algebraRef, intersectRef);
2538 1454 : if (q == NULL)
2539 0 : goto bailout;
2540 1454 : q = pushArgument(mb, q, op1->nr);
2541 1454 : q = pushArgument(mb, q, op2->nr);
2542 1454 : if (lcand)
2543 1167 : q = pushArgument(mb, q, lcand->nr);
2544 : else
2545 287 : q = pushNilBat(mb, q);
2546 1454 : if (rcand)
2547 0 : q = pushArgument(mb, q, rcand->nr);
2548 : else
2549 1454 : q = pushNilBat(mb, q);
2550 1454 : q = pushBit(mb, q, is_semantics?TRUE:FALSE);
2551 1454 : q = pushBit(mb, q, single?TRUE:FALSE); /* max_one */
2552 1454 : q = pushNil(mb, q, TYPE_lng);
2553 :
2554 1454 : bool enabled = be->mvc->sa->eb.enabled;
2555 1454 : be->mvc->sa->eb.enabled = false;
2556 1454 : stmt *s = stmt_create(be->mvc->sa, st_semijoin);
2557 1454 : be->mvc->sa->eb.enabled = enabled;
2558 1454 : if (s == NULL) {
2559 0 : freeInstruction(q);
2560 0 : goto bailout;
2561 : }
2562 :
2563 1454 : s->op1 = op1;
2564 1454 : s->op2 = op2;
2565 1454 : s->flag = cmp_equal;
2566 1454 : s->key = 0;
2567 1454 : s->nrcols = 1;
2568 1454 : if (single)
2569 284 : s->nrcols = 2;
2570 1454 : s->nr = getDestVar(q);
2571 1454 : s->q = q;
2572 1454 : pushInstruction(mb, q);
2573 1454 : return s;
2574 :
2575 0 : bailout:
2576 0 : if (be->mvc->sa->eb.enabled)
2577 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
2578 : return NULL;
2579 : }
2580 :
2581 : static InstrPtr
2582 3538527 : stmt_project_join(backend *be, stmt *op1, stmt *op2, bool delta)
2583 : {
2584 3538527 : MalBlkPtr mb = be->mb;
2585 3538527 : InstrPtr q = NULL;
2586 :
2587 3538527 : if (op1 == NULL || op2 == NULL || op1->nr < 0 || op2->nr < 0)
2588 : return NULL;
2589 : /* delta bat */
2590 3538527 : if (delta) {
2591 490235 : int uval = getArg(op2->q, 1);
2592 :
2593 490235 : q = newStmt(mb, sqlRef, deltaRef);
2594 490263 : q = pushArgument(mb, q, op1->nr);
2595 490263 : q = pushArgument(mb, q, op2->nr);
2596 490263 : q = pushArgument(mb, q, uval);
2597 : } else {
2598 : /* projections, ie left is void headed */
2599 3048292 : q = newStmt(mb, algebraRef, projectionRef);
2600 3048342 : q = pushArgument(mb, q, op1->nr);
2601 3048340 : q = pushArgument(mb, q, op2->nr);
2602 : }
2603 3538600 : pushInstruction(mb, q);
2604 3538600 : return q;
2605 : }
2606 :
2607 : stmt *
2608 3057578 : stmt_project(backend *be, stmt *op1, stmt *op2)
2609 : {
2610 3057578 : if (op1 == NULL || op2 == NULL)
2611 : return NULL;
2612 3057578 : if (!op2->nrcols)
2613 9286 : return stmt_const(be, op1, op2);
2614 3048292 : InstrPtr q = stmt_project_join(be, op1, op2, false);
2615 3048340 : if (q) {
2616 3048340 : stmt *s = stmt_create(be->mvc->sa, st_join);
2617 3048321 : if (s == NULL) {
2618 : return NULL;
2619 : }
2620 :
2621 3048321 : s->op1 = op1;
2622 3048321 : s->op2 = op2;
2623 3048321 : s->flag = cmp_project;
2624 3048321 : s->key = 0;
2625 3048321 : s->nrcols = MAX(op1->nrcols,op2->nrcols);
2626 3048321 : s->nr = getDestVar(q);
2627 3048321 : s->q = q;
2628 3048321 : s->tname = op2->tname;
2629 3048321 : s->cname = op2->cname;
2630 3048321 : s->label = op2->label;
2631 3048321 : return s;
2632 : }
2633 0 : if (be->mvc->sa->eb.enabled)
2634 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : be->mb->errors ? be->mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
2635 : return NULL;
2636 : }
2637 :
2638 : stmt *
2639 490235 : stmt_project_delta(backend *be, stmt *col, stmt *upd)
2640 : {
2641 490235 : InstrPtr q = stmt_project_join(be, col, upd, true);
2642 490261 : if (q) {
2643 490261 : stmt *s = stmt_create(be->mvc->sa, st_join);
2644 490258 : if (s == NULL) {
2645 : return NULL;
2646 : }
2647 :
2648 490258 : s->op1 = col;
2649 490258 : s->op2 = upd;
2650 490258 : s->flag = cmp_project;
2651 490258 : s->key = 0;
2652 490258 : s->nrcols = 2;
2653 490258 : s->nr = getDestVar(q);
2654 490258 : s->q = q;
2655 490258 : s->tname = col->tname;
2656 490258 : s->cname = col->cname;
2657 490258 : return s;
2658 : }
2659 :
2660 0 : if (be->mvc->sa->eb.enabled)
2661 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : be->mb->errors ? be->mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
2662 : return NULL;
2663 : }
2664 :
2665 : stmt *
2666 43 : stmt_left_project(backend *be, stmt *op1, stmt *op2, stmt *op3)
2667 : {
2668 43 : MalBlkPtr mb = be->mb;
2669 43 : InstrPtr q = NULL;
2670 43 : if (op1 == NULL || op2 == NULL || op3 == NULL || op1->nr < 0 || op2->nr < 0 || op3->nr < 0)
2671 0 : goto bailout;
2672 :
2673 43 : q = newStmt(mb, sqlRef, projectRef);
2674 43 : if (q == NULL)
2675 0 : goto bailout;
2676 43 : q = pushArgument(mb, q, op1->nr);
2677 43 : q = pushArgument(mb, q, op2->nr);
2678 43 : q = pushArgument(mb, q, op3->nr);
2679 :
2680 43 : bool enabled = be->mvc->sa->eb.enabled;
2681 43 : be->mvc->sa->eb.enabled = false;
2682 43 : stmt *s = stmt_create(be->mvc->sa, st_join);
2683 43 : be->mvc->sa->eb.enabled = enabled;
2684 43 : if (s == NULL) {
2685 0 : freeInstruction(q);
2686 0 : goto bailout;
2687 : }
2688 :
2689 43 : s->op1 = op1;
2690 43 : s->op2 = op2;
2691 43 : s->op3 = op3;
2692 43 : s->flag = cmp_left_project;
2693 43 : s->key = 0;
2694 43 : s->nrcols = 2;
2695 43 : s->nr = getDestVar(q);
2696 43 : s->q = q;
2697 43 : pushInstruction(mb, q);
2698 43 : return s;
2699 :
2700 0 : bailout:
2701 0 : if (be->mvc->sa->eb.enabled)
2702 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
2703 : return NULL;
2704 : }
2705 :
2706 : stmt *
2707 176 : stmt_dict(backend *be, stmt *op1, stmt *op2)
2708 : {
2709 176 : MalBlkPtr mb = be->mb;
2710 176 : InstrPtr q = NULL;
2711 :
2712 176 : if (op1 == NULL || op2 == NULL || op1->nr < 0 || op2->nr < 0)
2713 : return NULL;
2714 :
2715 176 : q = newStmt(mb, dictRef, decompressRef);
2716 176 : if (q == NULL)
2717 0 : goto bailout;
2718 176 : q = pushArgument(mb, q, op1->nr);
2719 176 : q = pushArgument(mb, q, op2->nr);
2720 :
2721 176 : bool enabled = be->mvc->sa->eb.enabled;
2722 176 : be->mvc->sa->eb.enabled = false;
2723 176 : stmt *s = stmt_create(be->mvc->sa, st_join);
2724 176 : be->mvc->sa->eb.enabled = enabled;
2725 176 : if (s == NULL) {
2726 0 : freeInstruction(q);
2727 0 : return NULL;
2728 : }
2729 :
2730 176 : s->op1 = op1;
2731 176 : s->op2 = op2;
2732 176 : s->flag = cmp_project;
2733 176 : s->key = 0;
2734 176 : s->nrcols = MAX(op1->nrcols,op2->nrcols);
2735 176 : s->nr = getDestVar(q);
2736 176 : s->q = q;
2737 176 : s->tname = op1->tname;
2738 176 : s->cname = op1->cname;
2739 176 : pushInstruction(mb, q);
2740 176 : return s;
2741 :
2742 0 : bailout:
2743 0 : if (be->mvc->sa->eb.enabled)
2744 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
2745 : return NULL;
2746 : }
2747 :
2748 : stmt *
2749 8 : stmt_for(backend *be, stmt *op1, stmt *min_val)
2750 : {
2751 8 : MalBlkPtr mb = be->mb;
2752 8 : InstrPtr q = NULL;
2753 :
2754 8 : if (op1 == NULL || min_val == NULL || op1->nr < 0)
2755 : return NULL;
2756 :
2757 8 : q = newStmt(mb, forRef, decompressRef);
2758 8 : if (q == NULL)
2759 0 : goto bailout;
2760 8 : q = pushArgument(mb, q, op1->nr);
2761 8 : q = pushArgument(mb, q, min_val->nr);
2762 :
2763 8 : bool enabled = be->mvc->sa->eb.enabled;
2764 8 : be->mvc->sa->eb.enabled = false;
2765 8 : stmt *s = stmt_create(be->mvc->sa, st_join);
2766 8 : be->mvc->sa->eb.enabled = enabled;
2767 8 : if (s == NULL) {
2768 0 : freeInstruction(q);
2769 0 : return NULL;
2770 : }
2771 :
2772 8 : s->op1 = op1;
2773 8 : s->op2 = min_val;
2774 8 : s->flag = cmp_project;
2775 8 : s->key = 0;
2776 8 : s->nrcols = op1->nrcols;
2777 8 : s->nr = getDestVar(q);
2778 8 : s->q = q;
2779 8 : s->tname = op1->tname;
2780 8 : s->cname = op1->cname;
2781 8 : pushInstruction(mb, q);
2782 8 : return s;
2783 :
2784 0 : bailout:
2785 0 : if (be->mvc->sa->eb.enabled)
2786 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
2787 : return NULL;
2788 : }
2789 :
2790 : stmt *
2791 54 : stmt_join2(backend *be, stmt *l, stmt *ra, stmt *rb, int cmp, int anti, int symmetric, int swapped)
2792 : {
2793 54 : InstrPtr q = select2_join2(be, l, ra, rb, cmp, NULL, anti, symmetric, swapped, st_join2, 1/*reduce semantics*/);
2794 54 : if (q == NULL)
2795 : return NULL;
2796 :
2797 54 : stmt *s = stmt_create(be->mvc->sa, st_join2);
2798 54 : if (s == NULL) {
2799 : return NULL;
2800 : }
2801 :
2802 54 : s->op1 = l;
2803 54 : s->op2 = ra;
2804 54 : s->op3 = rb;
2805 54 : s->flag = cmp;
2806 54 : s->nrcols = 2;
2807 54 : s->nr = getDestVar(q);
2808 54 : s->q = q;
2809 54 : s->reduce = 1;
2810 54 : return s;
2811 : }
2812 :
2813 : stmt *
2814 49 : stmt_genjoin(backend *be, stmt *l, stmt *r, sql_subfunc *op, int anti, int swapped)
2815 : {
2816 49 : MalBlkPtr mb = be->mb;
2817 49 : InstrPtr q = NULL;
2818 49 : const char *mod, *fimp;
2819 49 : node *n;
2820 :
2821 49 : if (l == NULL || r == NULL)
2822 0 : goto bailout;
2823 49 : if (backend_create_subfunc(be, op, NULL) < 0)
2824 0 : goto bailout;
2825 49 : mod = sql_func_mod(op->func);
2826 49 : fimp = backend_function_imp(be, op->func);
2827 49 : fimp = sa_strconcat(be->mvc->sa, fimp, "join");
2828 :
2829 : /* filter qualifying tuples, return oids of h and tail */
2830 49 : q = newStmtArgs(mb, mod, fimp, list_length(l->op4.lval) + list_length(r->op4.lval) + 7);
2831 49 : if (q == NULL)
2832 0 : goto bailout;
2833 49 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
2834 98 : for (n = l->op4.lval->h; n; n = n->next) {
2835 49 : stmt *op = n->data;
2836 :
2837 49 : q = pushArgument(mb, q, op->nr);
2838 : }
2839 :
2840 162 : for (n = r->op4.lval->h; n; n = n->next) {
2841 113 : stmt *op = n->data;
2842 :
2843 113 : q = pushArgument(mb, q, op->nr);
2844 : }
2845 49 : q = pushNilBat(mb, q); /* candidate lists */
2846 49 : q = pushNilBat(mb, q); /* candidate lists */
2847 49 : q = pushBit(mb, q, TRUE); /* nil_matches */
2848 49 : q = pushNil(mb, q, TYPE_lng); /* estimate */
2849 49 : q = pushBit(mb, q, anti?TRUE:FALSE); /* 'not' matching */
2850 49 : pushInstruction(mb, q);
2851 :
2852 49 : if (swapped) {
2853 7 : InstrPtr r = newInstruction(mb, NULL, NULL);
2854 7 : if (r == NULL)
2855 0 : goto bailout;
2856 7 : getArg(r, 0) = newTmpVariable(mb, TYPE_any);
2857 7 : r = pushReturn(mb, r, newTmpVariable(mb, TYPE_any));
2858 7 : r = pushArgument(mb, r, getArg(q,1));
2859 7 : r = pushArgument(mb, r, getArg(q,0));
2860 7 : pushInstruction(mb, r);
2861 7 : q = r;
2862 : }
2863 :
2864 49 : stmt *s = stmt_create(be->mvc->sa, st_joinN);
2865 49 : if (s == NULL) {
2866 0 : goto bailout;
2867 : }
2868 :
2869 49 : s->op1 = l;
2870 49 : s->op2 = r;
2871 49 : s->op4.funcval = op;
2872 49 : s->nrcols = 2;
2873 49 : if (swapped)
2874 7 : s->flag |= SWAPPED;
2875 49 : s->nr = getDestVar(q);
2876 49 : s->q = q;
2877 49 : return s;
2878 :
2879 0 : bailout:
2880 0 : if (be->mvc->sa->eb.enabled)
2881 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
2882 : return NULL;
2883 : }
2884 :
2885 : stmt *
2886 25624 : stmt_rs_column(backend *be, stmt *rs, int i, sql_subtype *tpe)
2887 : {
2888 25624 : InstrPtr q = NULL;
2889 :
2890 25624 : if (rs == NULL || rs->nr < 0)
2891 : return NULL;
2892 25624 : q = rs->q;
2893 25624 : if (q) {
2894 25408 : stmt *s = stmt_create(be->mvc->sa, st_rs_column);
2895 25408 : if (s == NULL) {
2896 : return NULL;
2897 : }
2898 :
2899 25408 : s->op1 = rs;
2900 25408 : s->op4.typeval = *tpe;
2901 25408 : s->flag = i;
2902 25408 : s->nrcols = 1;
2903 25408 : s->key = 0;
2904 25408 : s->q = q;
2905 25408 : s->nr = getArg(q, s->flag);
2906 25408 : return s;
2907 216 : } else if (rs->type == st_list) {
2908 216 : list *cols = rs->op4.lval;
2909 216 : if (i < list_length(cols))
2910 216 : return list_fetch(cols, i);
2911 : }
2912 : return NULL;
2913 : }
2914 :
2915 : /*
2916 : * The dump_header produces a sequence of instructions for
2917 : * the front-end to prepare presentation of a result table.
2918 : *
2919 : * A secondary scheme is added to assemble all information
2920 : * in columns first. Then it can be returned to the environment.
2921 : */
2922 : #define NEWRESULTSET
2923 :
2924 : #define meta(P, Id, Tpe, Args) \
2925 : do { \
2926 : P = newStmtArgs(mb, batRef, packRef, Args); \
2927 : if (P) { \
2928 : Id = getArg(P,0); \
2929 : setVarType(mb, Id, newBatType(Tpe)); \
2930 : setVarFixed(mb, Id); \
2931 : list = pushArgument(mb, list, Id); \
2932 : pushInstruction(mb, P); \
2933 : } \
2934 : } while (0)
2935 :
2936 : static int
2937 32 : dump_export_header(mvc *sql, MalBlkPtr mb, list *l, int file, const char * format, const char * sep,const char * rsep,const char * ssep,const char * ns, int onclient)
2938 : {
2939 32 : node *n;
2940 32 : int ret = -1;
2941 32 : int args;
2942 :
2943 : // gather the meta information
2944 32 : int tblId, nmeId, tpeId, lenId, scaleId;
2945 32 : InstrPtr list;
2946 32 : InstrPtr tblPtr, nmePtr, tpePtr, lenPtr, scalePtr;
2947 :
2948 32 : args = list_length(l) + 1;
2949 :
2950 32 : list = newInstructionArgs(mb, sqlRef, export_tableRef, args + 13);
2951 32 : if (list == NULL)
2952 : return -1;
2953 32 : getArg(list,0) = newTmpVariable(mb,TYPE_int);
2954 32 : if( file >= 0){
2955 32 : list = pushArgument(mb, list, file);
2956 32 : list = pushStr(mb, list, format);
2957 32 : list = pushStr(mb, list, sep);
2958 32 : list = pushStr(mb, list, rsep);
2959 32 : list = pushStr(mb, list, ssep);
2960 32 : list = pushStr(mb, list, ns);
2961 32 : list = pushInt(mb, list, onclient);
2962 : }
2963 32 : meta(tblPtr, tblId, TYPE_str, args);
2964 32 : meta(nmePtr, nmeId, TYPE_str, args);
2965 32 : meta(tpePtr, tpeId, TYPE_str, args);
2966 32 : meta(lenPtr, lenId, TYPE_int, args);
2967 32 : meta(scalePtr, scaleId, TYPE_int, args);
2968 32 : if(tblPtr == NULL || nmePtr == NULL || tpePtr == NULL || lenPtr == NULL || scalePtr == NULL)
2969 : return -1;
2970 :
2971 172 : for (n = l->h; n; n = n->next) {
2972 140 : stmt *c = n->data;
2973 140 : sql_subtype *t = tail_type(c);
2974 140 : const char *tname = table_name(sql->sa, c);
2975 140 : const char *sname = schema_name(sql->sa, c);
2976 140 : const char *_empty = "";
2977 140 : const char *tn = (tname) ? tname : _empty;
2978 140 : const char *sn = (sname) ? sname : _empty;
2979 140 : const char *cn = column_name(sql->sa, c);
2980 140 : const char *ntn = sql_escape_ident(sql->ta, tn);
2981 140 : const char *nsn = sql_escape_ident(sql->ta, sn);
2982 140 : size_t fqtnl;
2983 140 : char *fqtn = NULL;
2984 :
2985 140 : if (ntn && nsn && (fqtnl = strlen(ntn) + 1 + strlen(nsn) + 1) ){
2986 140 : fqtn = SA_NEW_ARRAY(sql->ta, char, fqtnl);
2987 140 : if (fqtn == NULL)
2988 : return -1;
2989 140 : snprintf(fqtn, fqtnl, "%s.%s", nsn, ntn);
2990 140 : tblPtr = pushStr(mb, tblPtr, fqtn);
2991 140 : nmePtr = pushStr(mb, nmePtr, cn);
2992 140 : tpePtr = pushStr(mb, tpePtr, (t->type->localtype == TYPE_void ? "char" : t->type->base.name));
2993 140 : lenPtr = pushInt(mb, lenPtr, t->digits);
2994 140 : scalePtr = pushInt(mb, scalePtr, t->scale);
2995 140 : list = pushArgument(mb, list, c->nr);
2996 : } else
2997 : return -1;
2998 : }
2999 32 : sa_reset(sql->ta);
3000 32 : ret = getArg(list,0);
3001 32 : pushInstruction(mb,list);
3002 32 : return ret;
3003 : }
3004 :
3005 :
3006 : stmt *
3007 32 : stmt_export(backend *be, stmt *t, const char *sep, const char *rsep, const char *ssep, const char *null_string, int onclient, stmt *file)
3008 : {
3009 32 : MalBlkPtr mb = be->mb;
3010 32 : InstrPtr q = NULL;
3011 32 : int fnr;
3012 32 : list *l;
3013 :
3014 32 : if (t == NULL || t->nr < 0)
3015 0 : goto bailout;
3016 32 : l = t->op4.lval;
3017 32 : if (file) {
3018 23 : if (file->nr < 0)
3019 0 : goto bailout;
3020 : fnr = file->nr;
3021 : } else {
3022 9 : q = newAssignment(mb);
3023 9 : if (q == NULL)
3024 0 : goto bailout;
3025 9 : q = pushStr(mb,q,"stdout");
3026 9 : fnr = getArg(q,0);
3027 9 : pushInstruction(mb, q);
3028 : }
3029 32 : if (t->type == st_list) {
3030 32 : if (dump_export_header(be->mvc, mb, l, fnr, "csv", sep, rsep, ssep, null_string, onclient) < 0)
3031 0 : goto bailout;
3032 : } else {
3033 0 : q = newStmt(mb, sqlRef, raiseRef);
3034 0 : if (q == NULL)
3035 0 : goto bailout;
3036 0 : q = pushStr(mb, q, "not a valid output list\n");
3037 0 : pushInstruction(mb, q);
3038 : }
3039 32 : stmt *s = stmt_create(be->mvc->sa, st_export);
3040 32 : if(!s) {
3041 0 : goto bailout;
3042 : }
3043 32 : s->op1 = t;
3044 32 : s->op2 = file;
3045 32 : s->q = q;
3046 32 : s->nr = 1;
3047 32 : return s;
3048 :
3049 0 : bailout:
3050 0 : if (be->mvc->sa->eb.enabled)
3051 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
3052 : return NULL;
3053 : }
3054 :
3055 : stmt *
3056 150 : stmt_export_bin(backend *be, stmt *colstmt, bool byteswap, const char *filename, int on_client)
3057 : {
3058 150 : MalBlkPtr mb = be->mb;
3059 150 : InstrPtr q;
3060 :
3061 150 : if (colstmt == NULL)
3062 0 : goto bailout;
3063 150 : q = newStmt(mb, sqlRef, export_bin_columnRef);
3064 150 : if (q == NULL)
3065 0 : goto bailout;
3066 150 : pushArgument(mb, q, colstmt->nr);
3067 150 : pushBit(mb, q, byteswap);
3068 150 : pushStr(mb, q, filename);
3069 150 : pushInt(mb, q, on_client);
3070 150 : pushInstruction(mb, q);
3071 :
3072 150 : stmt *s = stmt_create(be->mvc->sa, st_export);
3073 150 : if (!s)
3074 0 : goto bailout;
3075 :
3076 150 : s->q = q;
3077 150 : return s;
3078 :
3079 0 : bailout:
3080 0 : if (be->mvc->sa->eb.enabled)
3081 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
3082 : return NULL;
3083 : }
3084 :
3085 : stmt *
3086 3162 : stmt_trans(backend *be, int type, stmt *chain, stmt *name)
3087 : {
3088 3162 : MalBlkPtr mb = be->mb;
3089 3162 : InstrPtr q = NULL;
3090 :
3091 3162 : if (chain == NULL || chain->nr < 0)
3092 0 : goto bailout;
3093 :
3094 3162 : switch(type){
3095 13 : case ddl_release:
3096 13 : q = newStmt(mb, sqlRef, transaction_releaseRef);
3097 13 : break;
3098 558 : case ddl_commit:
3099 558 : q = newStmt(mb, sqlRef, transaction_commitRef);
3100 558 : break;
3101 1084 : case ddl_rollback:
3102 1084 : q = newStmt(mb, sqlRef, transaction_rollbackRef);
3103 1084 : break;
3104 1507 : case ddl_trans:
3105 1507 : q = newStmt(mb, sqlRef, transaction_beginRef);
3106 1507 : break;
3107 0 : default:
3108 0 : TRC_ERROR(SQL_EXECUTION, "Unknown transaction type\n");
3109 0 : goto bailout;
3110 : }
3111 3162 : if (q == NULL)
3112 0 : goto bailout;
3113 3162 : q = pushArgument(mb, q, chain->nr);
3114 3162 : if (name)
3115 79 : q = pushArgument(mb, q, name->nr);
3116 : else
3117 3083 : q = pushNil(mb, q, TYPE_str);
3118 :
3119 3162 : bool enabled = be->mvc->sa->eb.enabled;
3120 3162 : be->mvc->sa->eb.enabled = false;
3121 3162 : stmt *s = stmt_create(be->mvc->sa, st_trans);
3122 3162 : be->mvc->sa->eb.enabled = enabled;
3123 3162 : if(!s) {
3124 0 : freeInstruction(q);
3125 0 : goto bailout;
3126 : }
3127 3162 : s->op1 = chain;
3128 3162 : s->op2 = name;
3129 3162 : s->flag = type;
3130 3162 : s->q = q;
3131 3162 : s->nr = getDestVar(q);
3132 3162 : pushInstruction(mb, q);
3133 3162 : return s;
3134 :
3135 0 : bailout:
3136 0 : if (be->mvc->sa->eb.enabled)
3137 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
3138 : return NULL;
3139 : }
3140 :
3141 : stmt *
3142 287219 : stmt_catalog(backend *be, int type, stmt *args)
3143 : {
3144 287219 : MalBlkPtr mb = be->mb;
3145 287219 : InstrPtr q = NULL;
3146 287219 : node *n;
3147 :
3148 287219 : if (args == NULL || args->nr < 0)
3149 0 : goto bailout;
3150 :
3151 : /* cast them into properly named operations */
3152 287219 : const char *ref;
3153 287219 : switch(type){
3154 : case ddl_create_seq: ref = create_seqRef; break;
3155 47 : case ddl_alter_seq: ref = alter_seqRef; break;
3156 32 : case ddl_drop_seq: ref = drop_seqRef; break;
3157 1086 : case ddl_create_schema: ref = create_schemaRef; break;
3158 191 : case ddl_drop_schema: ref = drop_schemaRef; break;
3159 10157 : case ddl_create_table: ref = create_tableRef; break;
3160 22620 : case ddl_create_view: ref = create_viewRef; break;
3161 3712 : case ddl_drop_table: ref = drop_tableRef; break;
3162 475 : case ddl_drop_view: ref = drop_viewRef; break;
3163 150 : case ddl_drop_constraint: ref = drop_constraintRef; break;
3164 1369 : case ddl_alter_table: ref = alter_tableRef; break;
3165 910 : case ddl_create_type: ref = create_typeRef; break;
3166 4 : case ddl_drop_type: ref = drop_typeRef; break;
3167 40 : case ddl_grant_roles: ref = grant_rolesRef; break;
3168 10 : case ddl_revoke_roles: ref = revoke_rolesRef; break;
3169 18664 : case ddl_grant: ref = grantRef; break;
3170 15 : case ddl_revoke: ref = revokeRef; break;
3171 99959 : case ddl_grant_func: ref = grant_functionRef; break;
3172 1 : case ddl_revoke_func: ref = revoke_functionRef; break;
3173 359 : case ddl_create_user: ref = create_userRef; break;
3174 107 : case ddl_drop_user: ref = drop_userRef; break;
3175 83 : case ddl_alter_user: ref = alter_userRef; break;
3176 5 : case ddl_rename_user: ref = rename_userRef; break;
3177 26 : case ddl_create_role: ref = create_roleRef; break;
3178 19 : case ddl_drop_role: ref = drop_roleRef; break;
3179 160 : case ddl_drop_index: ref = drop_indexRef; break;
3180 686 : case ddl_drop_function: ref = drop_functionRef; break;
3181 122071 : case ddl_create_function: ref = create_functionRef; break;
3182 346 : case ddl_create_trigger: ref = create_triggerRef; break;
3183 84 : case ddl_drop_trigger: ref = drop_triggerRef; break;
3184 312 : case ddl_alter_table_add_table: ref = alter_add_tableRef; break;
3185 180 : case ddl_alter_table_del_table: ref = alter_del_tableRef; break;
3186 2320 : case ddl_alter_table_set_access:ref = alter_set_tableRef; break;
3187 225 : case ddl_alter_table_add_range_partition: ref = alter_add_range_partitionRef; break;
3188 60 : case ddl_alter_table_add_list_partition: ref = alter_add_value_partitionRef; break;
3189 355 : case ddl_comment_on: ref = comment_onRef; break;
3190 8 : case ddl_rename_schema: ref = rename_schemaRef; break;
3191 45 : case ddl_rename_table: ref = rename_tableRef; break;
3192 13 : case ddl_rename_column: ref = rename_columnRef; break;
3193 0 : default:
3194 0 : TRC_ERROR(SQL_EXECUTION, "Unknown catalog operation\n");
3195 0 : goto bailout;
3196 : }
3197 287219 : q = newStmtArgs(mb, sqlcatalogRef, ref, list_length(args->op4.lval) + 1);
3198 287219 : if (q == NULL)
3199 0 : goto bailout;
3200 : // pass all arguments as before
3201 1717004 : for (n = args->op4.lval->h; n; n = n->next) {
3202 1429786 : stmt *c = n->data;
3203 :
3204 1429786 : q = pushArgument(mb, q, c->nr);
3205 : }
3206 :
3207 287218 : bool enabled = be->mvc->sa->eb.enabled;
3208 287218 : be->mvc->sa->eb.enabled = false;
3209 287218 : stmt *s = stmt_create(be->mvc->sa, st_catalog);
3210 287218 : be->mvc->sa->eb.enabled = enabled;
3211 287218 : if(!s) {
3212 0 : freeInstruction(q);
3213 0 : goto bailout;
3214 : }
3215 287218 : s->op1 = args;
3216 287218 : s->flag = type;
3217 287218 : s->q = q;
3218 287218 : s->nr = getDestVar(q);
3219 287218 : pushInstruction(mb, q);
3220 287218 : return s;
3221 :
3222 0 : bailout:
3223 0 : if (be->mvc->sa->eb.enabled)
3224 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
3225 : return NULL;
3226 : }
3227 :
3228 : void
3229 1869180 : stmt_set_nrcols(stmt *s)
3230 : {
3231 1869180 : unsigned nrcols = 0;
3232 1869180 : int key = 1;
3233 1869180 : node *n;
3234 1869180 : list *l = s->op4.lval;
3235 :
3236 1869180 : assert(s->type == st_list);
3237 9113518 : for (n = l->h; n; n = n->next) {
3238 7244338 : stmt *f = n->data;
3239 :
3240 7244338 : if (!f)
3241 0 : continue;
3242 7244338 : if (f->nrcols > nrcols)
3243 : nrcols = f->nrcols;
3244 7244338 : key &= f->key;
3245 7244338 : s->nr = f->nr;
3246 : }
3247 1869180 : s->nrcols = nrcols;
3248 1869180 : s->key = key;
3249 1869180 : }
3250 :
3251 : stmt *
3252 1459902 : stmt_list(backend *be, list *l)
3253 : {
3254 1459902 : if (l == NULL)
3255 : return NULL;
3256 1459902 : stmt *s = stmt_create(be->mvc->sa, st_list);
3257 1459972 : if(!s) {
3258 : return NULL;
3259 : }
3260 1459972 : s->op4.lval = l;
3261 1459972 : stmt_set_nrcols(s);
3262 1459972 : return s;
3263 : }
3264 :
3265 : static InstrPtr
3266 65650 : dump_header(mvc *sql, MalBlkPtr mb, list *l)
3267 : {
3268 65650 : node *n;
3269 : // gather the meta information
3270 65650 : int tblId, nmeId, tpeId, lenId, scaleId;
3271 65650 : int args;
3272 65650 : InstrPtr list;
3273 65650 : InstrPtr tblPtr, nmePtr, tpePtr, lenPtr, scalePtr;
3274 :
3275 65650 : args = list_length(l) + 1;
3276 :
3277 65658 : list = newInstructionArgs(mb,sqlRef, resultSetRef, args + 5);
3278 65668 : if(!list) {
3279 : return NULL;
3280 : }
3281 65668 : getArg(list,0) = newTmpVariable(mb,TYPE_int);
3282 65667 : meta(tblPtr, tblId, TYPE_str, args);
3283 65669 : meta(nmePtr, nmeId, TYPE_str, args);
3284 65670 : meta(tpePtr, tpeId, TYPE_str, args);
3285 65669 : meta(lenPtr, lenId, TYPE_int, args);
3286 65670 : meta(scalePtr, scaleId, TYPE_int, args);
3287 65670 : if(tblPtr == NULL || nmePtr == NULL || tpePtr == NULL || lenPtr == NULL || scalePtr == NULL)
3288 : return NULL;
3289 :
3290 344821 : for (n = l->h; n; n = n->next) {
3291 279155 : stmt *c = n->data;
3292 279155 : sql_subtype *t = tail_type(c);
3293 279160 : const char *tname = table_name(sql->sa, c);
3294 279161 : const char *sname = schema_name(sql->sa, c);
3295 279153 : const char *_empty = "";
3296 279153 : const char *tn = (tname) ? tname : _empty;
3297 279153 : const char *sn = (sname) ? sname : _empty;
3298 279153 : const char *cn = column_name(sql->sa, c);
3299 279153 : const char *ntn = sql_escape_ident(sql->ta, tn);
3300 279144 : const char *nsn = sql_escape_ident(sql->ta, sn);
3301 279162 : size_t fqtnl;
3302 :
3303 279162 : if (ntn && nsn && (fqtnl = strlen(ntn) + 1 + strlen(nsn) + 1) ){
3304 279162 : char *fqtn = SA_NEW_ARRAY(sql->ta, char, fqtnl);
3305 279159 : if (fqtn == NULL)
3306 : return NULL;
3307 279159 : snprintf(fqtn, fqtnl, "%s.%s", nsn, ntn);
3308 279159 : tblPtr = pushStr(mb, tblPtr, fqtn);
3309 279155 : nmePtr = pushStr(mb, nmePtr, cn);
3310 279151 : tpePtr = pushStr(mb, tpePtr, (t->type->localtype == TYPE_void ? "char" : t->type->base.name));
3311 279157 : lenPtr = pushInt(mb, lenPtr, t->digits);
3312 279151 : scalePtr = pushInt(mb, scalePtr, t->scale);
3313 279153 : list = pushArgument(mb,list,c->nr);
3314 : } else
3315 : return NULL;
3316 : }
3317 65666 : sa_reset(sql->ta);
3318 65654 : pushInstruction(mb,list);
3319 65654 : return list;
3320 : }
3321 :
3322 : int
3323 126040 : stmt_output(backend *be, stmt *lst)
3324 : {
3325 126040 : MalBlkPtr mb = be->mb;
3326 126040 : InstrPtr q = NULL;
3327 126040 : list *l = lst->op4.lval;
3328 126040 : int cnt = list_length(l), ok = 0;
3329 126101 : node *n = l->h;
3330 126101 : stmt *first = n->data;
3331 :
3332 : /* single value result, has a fast exit */
3333 126101 : if (cnt == 1 && first->nrcols <= 0 ){
3334 60447 : stmt *c = n->data;
3335 60447 : sql_subtype *t = tail_type(c);
3336 60392 : const char *tname = table_name(be->mvc->sa, c);
3337 60337 : const char *sname = schema_name(be->mvc->sa, c);
3338 60337 : const char *_empty = "";
3339 60337 : const char *tn = (tname) ? tname : _empty;
3340 60337 : const char *sn = (sname) ? sname : _empty;
3341 60337 : const char *cn = column_name(be->mvc->sa, c);
3342 60341 : const char *ntn = sql_escape_ident(be->mvc->ta, tn);
3343 60481 : const char *nsn = sql_escape_ident(be->mvc->ta, sn);
3344 :
3345 60494 : if (ntn && nsn) {
3346 60494 : size_t fqtnl = strlen(ntn) + 1 + strlen(nsn) + 1;
3347 60494 : char *fqtn = SA_NEW_ARRAY(be->mvc->ta, char, fqtnl);
3348 60493 : if (fqtn == NULL)
3349 : return -1;
3350 60493 : ok = 1;
3351 60493 : snprintf(fqtn, fqtnl, "%s.%s", nsn, ntn);
3352 :
3353 60493 : q = newStmt(mb, sqlRef, resultSetRef);
3354 60498 : if (q == NULL)
3355 : return -1;
3356 60498 : getArg(q,0) = newTmpVariable(mb,TYPE_int);
3357 60498 : q = pushStr(mb, q, fqtn);
3358 60495 : q = pushStr(mb, q, cn);
3359 60495 : q = pushStr(mb, q, t->type->localtype == TYPE_void ? "char" : t->type->base.name);
3360 60496 : q = pushInt(mb, q, t->digits);
3361 60493 : q = pushInt(mb, q, t->scale);
3362 60498 : q = pushInt(mb, q, t->type->eclass);
3363 60488 : q = pushArgument(mb, q, c->nr);
3364 60487 : pushInstruction(mb, q);
3365 : }
3366 60482 : sa_reset(be->mvc->ta);
3367 60441 : if (!ok)
3368 : return -1;
3369 : } else {
3370 65654 : if ((q = dump_header(be->mvc, mb, l)) == NULL)
3371 : return -1;
3372 : }
3373 : return 0;
3374 : }
3375 :
3376 : int
3377 149287 : stmt_affected_rows(backend *be, int lastnr)
3378 : {
3379 149287 : MalBlkPtr mb = be->mb;
3380 149287 : InstrPtr q = NULL;
3381 :
3382 149287 : q = newStmt(mb, sqlRef, affectedRowsRef);
3383 149550 : if (q == NULL)
3384 : return -1;
3385 149550 : q = pushArgument(mb, q, be->mvc_var);
3386 149550 : getArg(q, 0) = be->mvc_var = newTmpVariable(mb, TYPE_int);
3387 149551 : q = pushArgument(mb, q, lastnr);
3388 149550 : pushInstruction(mb, q);
3389 149548 : be->mvc_var = getDestVar(q);
3390 149548 : return 0;
3391 : }
3392 :
3393 : stmt *
3394 176551 : stmt_append(backend *be, stmt *c, stmt *a)
3395 : {
3396 176551 : MalBlkPtr mb = be->mb;
3397 176551 : InstrPtr q = NULL;
3398 :
3399 176551 : if (c == NULL || a == NULL || c->nr < 0 || a->nr < 0)
3400 0 : goto bailout;
3401 176551 : q = newStmt(mb, batRef, appendRef);
3402 176551 : if (q == NULL)
3403 0 : goto bailout;
3404 176551 : q = pushArgument(mb, q, c->nr);
3405 176551 : q = pushArgument(mb, q, a->nr);
3406 176551 : q = pushBit(mb, q, TRUE);
3407 176551 : bool enabled = be->mvc->sa->eb.enabled;
3408 176551 : be->mvc->sa->eb.enabled = false;
3409 176551 : stmt *s = stmt_create(be->mvc->sa, st_append);
3410 176551 : be->mvc->sa->eb.enabled = enabled;
3411 176551 : if(!s) {
3412 0 : freeInstruction(q);
3413 0 : goto bailout;
3414 : }
3415 176551 : s->op1 = c;
3416 176551 : s->op2 = a;
3417 176551 : s->nrcols = c->nrcols;
3418 176551 : s->key = c->key;
3419 176551 : s->nr = getDestVar(q);
3420 176551 : s->q = q;
3421 176551 : pushInstruction(mb, q);
3422 176551 : return s;
3423 :
3424 0 : bailout:
3425 0 : if (be->mvc->sa->eb.enabled)
3426 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
3427 : return NULL;
3428 : }
3429 :
3430 : stmt *
3431 137647 : stmt_append_bulk(backend *be, stmt *c, list *l)
3432 : {
3433 137647 : MalBlkPtr mb = be->mb;
3434 137647 : InstrPtr q = NULL;
3435 137647 : bool needs_columns = false;
3436 :
3437 137647 : if (c->nr < 0)
3438 0 : goto bailout;
3439 :
3440 : /* currently appendBulk accepts its inputs all either scalar or vectors
3441 : if there is one vector and any scala, then the scalars mut be upgraded to vectors */
3442 888393 : for (node *n = l->h; n; n = n->next) {
3443 750746 : stmt *t = n->data;
3444 750746 : needs_columns |= t->nrcols > 0;
3445 : }
3446 137647 : if (needs_columns) {
3447 0 : for (node *n = l->h; n; n = n->next) {
3448 0 : stmt *t = n->data;
3449 0 : if (t->nrcols == 0)
3450 0 : n->data = const_column(be, t);
3451 : }
3452 : }
3453 :
3454 137647 : q = newStmtArgs(mb, batRef, appendBulkRef, list_length(l) + 3);
3455 138039 : if (q == NULL)
3456 0 : goto bailout;
3457 138039 : q = pushArgument(mb, q, c->nr);
3458 138034 : q = pushBit(mb, q, TRUE);
3459 889096 : for (node *n = l->h ; n ; n = n->next) {
3460 751182 : stmt *a = n->data;
3461 751182 : q = pushArgument(mb, q, a->nr);
3462 : }
3463 137914 : bool enabled = be->mvc->sa->eb.enabled;
3464 137914 : be->mvc->sa->eb.enabled = false;
3465 137914 : stmt *s = stmt_create(be->mvc->sa, st_append_bulk);
3466 137820 : be->mvc->sa->eb.enabled = enabled;
3467 137820 : if(!s) {
3468 0 : freeInstruction(q);
3469 0 : goto bailout;
3470 : }
3471 137820 : s->op1 = c;
3472 137820 : s->op4.lval = l;
3473 137820 : s->nrcols = c->nrcols;
3474 137820 : s->key = c->key;
3475 137820 : s->nr = getDestVar(q);
3476 137820 : s->q = q;
3477 137820 : pushInstruction(mb, q);
3478 137820 : return s;
3479 :
3480 0 : bailout:
3481 0 : if (be->mvc->sa->eb.enabled)
3482 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
3483 : return NULL;
3484 : }
3485 :
3486 : stmt *
3487 16049 : stmt_pack(backend *be, stmt *c, int n)
3488 : {
3489 16049 : MalBlkPtr mb = be->mb;
3490 16049 : InstrPtr q = NULL;
3491 :
3492 16049 : if (c == NULL || c->nr < 0)
3493 0 : goto bailout;
3494 16049 : q = newStmtArgs(mb, matRef, packIncrementRef, 3);
3495 16049 : if (q == NULL)
3496 0 : goto bailout;
3497 16049 : q = pushArgument(mb, q, c->nr);
3498 16049 : q = pushInt(mb, q, n);
3499 16049 : bool enabled = be->mvc->sa->eb.enabled;
3500 16049 : be->mvc->sa->eb.enabled = false;
3501 16049 : stmt *s = stmt_create(be->mvc->sa, st_append);
3502 16049 : be->mvc->sa->eb.enabled = enabled;
3503 16049 : if(!s) {
3504 0 : freeInstruction(q);
3505 0 : goto bailout;
3506 : }
3507 16049 : s->op1 = c;
3508 16049 : s->nrcols = c->nrcols;
3509 16049 : s->key = c->key;
3510 16049 : s->nr = getDestVar(q);
3511 16049 : s->q = q;
3512 16049 : pushInstruction(mb, q);
3513 16049 : return s;
3514 :
3515 0 : bailout:
3516 0 : if (be->mvc->sa->eb.enabled)
3517 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
3518 : return NULL;
3519 :
3520 : }
3521 :
3522 : stmt *
3523 29785 : stmt_pack_add(backend *be, stmt *c, stmt *a)
3524 : {
3525 29785 : MalBlkPtr mb = be->mb;
3526 29785 : InstrPtr q = NULL;
3527 :
3528 29785 : if (c == NULL || a == NULL || c->nr < 0 || a->nr < 0)
3529 0 : goto bailout;
3530 29785 : q = newStmtArgs(mb, matRef, packIncrementRef, 3);
3531 29785 : if (q == NULL)
3532 0 : goto bailout;
3533 29785 : q = pushArgument(mb, q, c->nr);
3534 29785 : q = pushArgument(mb, q, a->nr);
3535 29785 : bool enabled = be->mvc->sa->eb.enabled;
3536 29785 : be->mvc->sa->eb.enabled = false;
3537 29785 : stmt *s = stmt_create(be->mvc->sa, st_append);
3538 29785 : be->mvc->sa->eb.enabled = enabled;
3539 29785 : if(!s) {
3540 0 : freeInstruction(q);
3541 0 : goto bailout;
3542 : }
3543 29785 : s->op1 = c;
3544 29785 : s->op2 = a;
3545 29785 : s->nrcols = c->nrcols;
3546 29785 : s->key = c->key;
3547 29785 : s->nr = getDestVar(q);
3548 29785 : s->q = q;
3549 29785 : pushInstruction(mb, q);
3550 29785 : return s;
3551 :
3552 0 : bailout:
3553 0 : if (be->mvc->sa->eb.enabled)
3554 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
3555 : return NULL;
3556 : }
3557 :
3558 : stmt *
3559 106159 : stmt_claim(backend *be, sql_table *t, stmt *cnt)
3560 : {
3561 106159 : MalBlkPtr mb = be->mb;
3562 106159 : InstrPtr q = NULL;
3563 :
3564 106159 : if (!t || cnt->nr < 0)
3565 0 : goto bailout;
3566 106159 : assert(t->s); /* declared table */
3567 106159 : q = newStmtArgs(mb, sqlRef, claimRef, 6);
3568 106241 : if (q == NULL)
3569 0 : goto bailout;
3570 : /* returns offset or offsets */
3571 106241 : q = pushReturn(mb, q, newTmpVariable(mb, newBatType(TYPE_oid)));
3572 106237 : q = pushArgument(mb, q, be->mvc_var);
3573 106229 : q = pushSchema(mb, q, t);
3574 106206 : q = pushStr(mb, q, t->base.name);
3575 106206 : q = pushArgument(mb, q, cnt->nr);
3576 106209 : bool enabled = be->mvc->sa->eb.enabled;
3577 106209 : be->mvc->sa->eb.enabled = false;
3578 106209 : stmt *s = stmt_create(be->mvc->sa, st_claim);
3579 106147 : be->mvc->sa->eb.enabled = enabled;
3580 106147 : if(!s) {
3581 0 : freeInstruction(q);
3582 0 : goto bailout;
3583 : }
3584 106147 : s->op1 = cnt;
3585 106147 : s->op4.tval = t;
3586 106147 : s->nr = getDestVar(q);
3587 106147 : s->q = q;
3588 106147 : pushInstruction(mb, q);
3589 106147 : return s;
3590 :
3591 0 : bailout:
3592 0 : if (be->mvc->sa->eb.enabled)
3593 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
3594 : return NULL;
3595 : }
3596 :
3597 : void
3598 149240 : stmt_add_dependency_change(backend *be, sql_table *t, stmt *cnt)
3599 : {
3600 149240 : MalBlkPtr mb = be->mb;
3601 149240 : InstrPtr q = NULL;
3602 :
3603 149240 : if (!t || cnt->nr < 0)
3604 0 : goto bailout;
3605 149240 : q = newStmtArgs(mb, sqlRef, dependRef, 4);
3606 149786 : if (q == NULL)
3607 0 : goto bailout;
3608 149786 : q = pushSchema(mb, q, t);
3609 149763 : q = pushStr(mb, q, t->base.name);
3610 149771 : q = pushArgument(mb, q, cnt->nr);
3611 149765 : pushInstruction(mb, q);
3612 149765 : return;
3613 :
3614 0 : bailout:
3615 0 : if (be->mvc->sa->eb.enabled)
3616 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : be->mb->errors ? be->mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
3617 : }
3618 :
3619 : void
3620 14737 : stmt_add_column_predicate(backend *be, sql_column *c)
3621 : {
3622 14737 : MalBlkPtr mb = be->mb;
3623 14737 : InstrPtr q = NULL;
3624 :
3625 14737 : if (!c)
3626 0 : goto bailout;
3627 14737 : q = newStmtArgs(mb, sqlRef, predicateRef, 4);
3628 14830 : if (q == NULL)
3629 0 : goto bailout;
3630 14830 : q = pushSchema(mb, q, c->t);
3631 14830 : q = pushStr(mb, q, c->t->base.name);
3632 14830 : q = pushStr(mb, q, c->base.name);
3633 14830 : pushInstruction(mb, q);
3634 14830 : return;
3635 :
3636 0 : bailout:
3637 0 : if (be->mvc->sa->eb.enabled)
3638 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : be->mb->errors ? be->mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
3639 : }
3640 :
3641 : stmt *
3642 55617 : stmt_replace(backend *be, stmt *r, stmt *id, stmt *val)
3643 : {
3644 55617 : MalBlkPtr mb = be->mb;
3645 55617 : InstrPtr q = NULL;
3646 :
3647 55617 : if (r->nr < 0)
3648 0 : goto bailout;
3649 :
3650 55617 : q = newStmt(mb, batRef, replaceRef);
3651 55617 : if (q == NULL)
3652 0 : goto bailout;
3653 55617 : q = pushArgument(mb, q, r->nr);
3654 55617 : q = pushArgument(mb, q, id->nr);
3655 55617 : q = pushArgument(mb, q, val->nr);
3656 55617 : q = pushBit(mb, q, TRUE); /* forced */
3657 55617 : bool enabled = be->mvc->sa->eb.enabled;
3658 55617 : be->mvc->sa->eb.enabled = false;
3659 55617 : stmt *s = stmt_create(be->mvc->sa, st_replace);
3660 55617 : be->mvc->sa->eb.enabled = enabled;
3661 55617 : if(!s) {
3662 0 : freeInstruction(q);
3663 0 : goto bailout;
3664 : }
3665 55617 : s->op1 = r;
3666 55617 : s->op2 = id;
3667 55617 : s->op3 = val;
3668 55617 : s->nrcols = r->nrcols;
3669 55617 : s->key = r->key;
3670 55617 : s->nr = getDestVar(q);
3671 55617 : s->q = q;
3672 55617 : s->cand = r->cand;
3673 55617 : pushInstruction(mb, q);
3674 55617 : return s;
3675 :
3676 0 : bailout:
3677 0 : if (be->mvc->sa->eb.enabled)
3678 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
3679 : return NULL;
3680 : }
3681 :
3682 : stmt *
3683 41381 : stmt_table_clear(backend *be, sql_table *t, int restart_sequences)
3684 : {
3685 41381 : MalBlkPtr mb = be->mb;
3686 41381 : InstrPtr q = NULL;
3687 :
3688 41381 : if (!t->s && ATOMIC_PTR_GET(&t->data)) { /* declared table */
3689 2 : int *l = ATOMIC_PTR_GET(&t->data), cnt = ol_length(t->columns)+1;
3690 :
3691 6 : for (int i = 0; i < cnt; i++) {
3692 4 : q = newStmt(mb, batRef, deleteRef);
3693 4 : if (q == NULL)
3694 0 : goto bailout;
3695 4 : q = pushArgument(mb, q, l[i]);
3696 4 : pushInstruction(mb, q);
3697 : }
3698 : /* declared tables don't have sequences */
3699 : } else {
3700 41379 : q = newStmt(mb, sqlRef, clear_tableRef);
3701 41829 : if (q == NULL)
3702 0 : goto bailout;
3703 41829 : q = pushSchema(mb, q, t);
3704 41818 : q = pushStr(mb, q, t->base.name);
3705 41787 : q = pushInt(mb, q, restart_sequences);
3706 41791 : pushInstruction(mb, q);
3707 : }
3708 41788 : stmt *s = stmt_create(be->mvc->sa, st_table_clear);
3709 :
3710 41663 : if(!s) {
3711 0 : goto bailout;
3712 : }
3713 41663 : s->op4.tval = t;
3714 41663 : s->nrcols = 0;
3715 41663 : s->nr = getDestVar(q);
3716 41663 : s->q = q;
3717 41663 : return s;
3718 :
3719 0 : bailout:
3720 0 : if (be->mvc->sa->eb.enabled)
3721 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
3722 : return NULL;
3723 : }
3724 :
3725 : stmt *
3726 39304 : stmt_exception(backend *be, stmt *cond, const char *errstr, int errcode)
3727 : {
3728 39304 : MalBlkPtr mb = be->mb;
3729 39304 : InstrPtr q = NULL;
3730 :
3731 39304 : if (cond->nr < 0)
3732 : return NULL;
3733 :
3734 : /* if(bit(l)) { error(r);} ==raising an exception */
3735 39304 : q = newStmt(mb, sqlRef, assertRef);
3736 39401 : if (q == NULL)
3737 0 : goto bailout;
3738 39401 : q = pushArgument(mb, q, cond->nr);
3739 39401 : q = pushStr(mb, q, errstr);
3740 39401 : bool enabled = be->mvc->sa->eb.enabled;
3741 39401 : be->mvc->sa->eb.enabled = false;
3742 39401 : stmt *s = stmt_create(be->mvc->sa, st_exception);
3743 39401 : be->mvc->sa->eb.enabled = enabled;
3744 39401 : if(!s) {
3745 0 : freeInstruction(q);
3746 0 : return NULL;
3747 : }
3748 39401 : assert(cond);
3749 39401 : s->op1 = cond;
3750 39401 : (void)errcode;
3751 39401 : s->nrcols = 0;
3752 39401 : s->q = q;
3753 39401 : s->nr = getDestVar(q);
3754 39401 : pushInstruction(mb, q);
3755 39401 : return s;
3756 :
3757 0 : bailout:
3758 0 : if (be->mvc->sa->eb.enabled)
3759 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
3760 : return NULL;
3761 : }
3762 :
3763 : /* The type setting is not propagated to statements such as st_bat and st_append,
3764 : because they are not considered projections */
3765 : static void
3766 15104 : tail_set_type(mvc *m, stmt *st, sql_subtype *t)
3767 : {
3768 40656 : for (;;) {
3769 40656 : switch (st->type) {
3770 3689 : case st_const:
3771 3689 : st = st->op2;
3772 3689 : continue;
3773 18251 : case st_alias:
3774 : case st_gen_group:
3775 : case st_order:
3776 18251 : st = st->op1;
3777 18251 : continue;
3778 0 : case st_list:
3779 0 : st = st->op4.lval->h->data;
3780 0 : continue;
3781 3612 : case st_join:
3782 : case st_join2:
3783 : case st_joinN:
3784 3612 : if (st->flag == cmp_project) {
3785 3612 : st = st->op2;
3786 3612 : continue;
3787 : }
3788 : return;
3789 2779 : case st_aggr:
3790 : case st_Nop: {
3791 2779 : list *res = st->op4.funcval->res;
3792 :
3793 2779 : if (res && list_length(res) == 1)
3794 2779 : res->h->data = t;
3795 : return;
3796 : }
3797 6778 : case st_atom:
3798 6778 : st->op4.aval = atom_set_type(m->sa, st->op4.aval, t);
3799 6778 : return;
3800 60 : case st_convert:
3801 : case st_temp:
3802 : case st_single:
3803 60 : st->op4.typeval = *t;
3804 60 : return;
3805 86 : case st_var:
3806 86 : if (st->op4.typeval.type)
3807 86 : st->op4.typeval = *t;
3808 : return;
3809 : default:
3810 : return;
3811 : }
3812 : }
3813 : }
3814 :
3815 : #define trivial_string_conversion(x) ((x) == EC_BIT || (x) == EC_CHAR || (x) == EC_STRING || (x) == EC_NUM || (x) == EC_POS || (x) == EC_FLT \
3816 : || (x) == EC_DATE || (x) == EC_BLOB || (x) == EC_MONTH)
3817 :
3818 : static stmt *
3819 351 : temporal_convert(backend *be, stmt *v, stmt *sel, sql_subtype *f, sql_subtype *t, bool before)
3820 : {
3821 351 : MalBlkPtr mb = be->mb;
3822 351 : InstrPtr q = NULL;
3823 351 : const char *convert = t->type->impl, *mod = mtimeRef;
3824 351 : bool add_tz = false, pushed = (v->cand && v->cand == sel), cand = 0;
3825 :
3826 351 : if (before) {
3827 290 : if (f->type->eclass == EC_TIMESTAMP_TZ && (t->type->eclass == EC_TIMESTAMP || t->type->eclass == EC_TIME)) {
3828 : /* call timestamp+local_timezone */
3829 : convert = "timestamp_add_msec_interval";
3830 : add_tz = true;
3831 211 : } else if (f->type->eclass == EC_TIMESTAMP_TZ && t->type->eclass == EC_DATE) {
3832 : /* call convert timestamp with tz to date */
3833 : convert = "datetz";
3834 : mod = calcRef;
3835 : add_tz = true;
3836 198 : } else if (f->type->eclass == EC_TIMESTAMP && t->type->eclass == EC_TIMESTAMP_TZ) {
3837 : /* call timestamp+local_timezone */
3838 : convert = "timestamp_sub_msec_interval";
3839 : add_tz = true;
3840 159 : } else if (f->type->eclass == EC_TIME_TZ && (t->type->eclass == EC_TIME || t->type->eclass == EC_TIMESTAMP)) {
3841 : /* call times+local_timezone */
3842 : convert = "time_add_msec_interval";
3843 : add_tz = true;
3844 146 : } else if (f->type->eclass == EC_TIME && t->type->eclass == EC_TIME_TZ) {
3845 : /* call times+local_timezone */
3846 : convert = "time_sub_msec_interval";
3847 : add_tz = true;
3848 131 : } else if (EC_VARCHAR(f->type->eclass) && EC_TEMP_TZ(t->type->eclass)) {
3849 124 : if (t->type->eclass == EC_TIME_TZ)
3850 : convert = "daytimetz";
3851 : else
3852 100 : convert = "timestamptz";
3853 : mod = calcRef;
3854 : add_tz = true;
3855 : cand = 1;
3856 : } else {
3857 : return v;
3858 : }
3859 : } else {
3860 61 : if (f->type->eclass == EC_DATE && t->type->eclass == EC_TIMESTAMP_TZ) {
3861 : convert = "timestamp_sub_msec_interval";
3862 : add_tz = true;
3863 56 : } else if (f->type->eclass == EC_DATE && t->type->eclass == EC_TIME_TZ) {
3864 : convert = "time_sub_msec_interval";
3865 : add_tz = true;
3866 : } else {
3867 : return v;
3868 : }
3869 : }
3870 :
3871 288 : if (v->nrcols == 0 && (!sel || sel->nrcols == 0)) { /* simple calc */
3872 171 : q = newStmtArgs(mb, mod, convert, 13);
3873 171 : if (q == NULL)
3874 0 : goto bailout;
3875 : } else {
3876 117 : if (sel && !pushed && v->nrcols == 0) {
3877 1 : pushed = 1;
3878 1 : v = stmt_project(be, sel, v);
3879 1 : v->cand = sel;
3880 : }
3881 191 : q = newStmtArgs(mb, mod==calcRef?batcalcRef:batmtimeRef, convert, 13);
3882 117 : if (q == NULL)
3883 0 : goto bailout;
3884 : }
3885 288 : q = pushArgument(mb, q, v->nr);
3886 :
3887 288 : if (cand) {
3888 124 : if (sel && !pushed && !v->cand) {
3889 14 : q = pushArgument(mb, q, sel->nr);
3890 14 : pushed = 1;
3891 110 : } else if (v->nrcols > 0) {
3892 18 : q = pushNilBat(mb, q);
3893 : }
3894 : }
3895 :
3896 288 : if (EC_VARCHAR(f->type->eclass))
3897 124 : q = pushInt(mb, q, t->digits);
3898 :
3899 288 : if (add_tz)
3900 288 : q = pushLng(mb, q, be->mvc->timezone);
3901 :
3902 288 : if (!cand) {
3903 164 : if (sel && !pushed && !v->cand) {
3904 2 : q = pushArgument(mb, q, sel->nr);
3905 2 : pushed = 1;
3906 162 : } else if (v->nrcols > 0) {
3907 83 : q = pushNilBat(mb, q);
3908 : }
3909 : }
3910 :
3911 288 : bool enabled = be->mvc->sa->eb.enabled;
3912 288 : be->mvc->sa->eb.enabled = false;
3913 288 : stmt *s = stmt_create(be->mvc->sa, st_convert);
3914 288 : be->mvc->sa->eb.enabled = enabled;
3915 288 : if(!s) {
3916 0 : freeInstruction(q);
3917 0 : goto bailout;
3918 : }
3919 288 : s->op1 = v;
3920 288 : s->nrcols = 0; /* function without arguments returns single value */
3921 288 : s->key = v->key;
3922 288 : s->nrcols = v->nrcols;
3923 288 : s->aggr = v->aggr;
3924 288 : s->op4.typeval = *t;
3925 288 : s->nr = getDestVar(q);
3926 288 : s->q = q;
3927 288 : s->cand = pushed ? sel : NULL;
3928 288 : pushInstruction(mb, q);
3929 288 : return s;
3930 :
3931 0 : bailout:
3932 0 : if (be->mvc->sa->eb.enabled)
3933 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
3934 : return NULL;
3935 : }
3936 :
3937 : stmt *
3938 51913 : stmt_convert(backend *be, stmt *v, stmt *sel, sql_subtype *f, sql_subtype *t)
3939 : {
3940 51913 : MalBlkPtr mb = be->mb;
3941 51913 : InstrPtr q = NULL;
3942 51913 : const char *convert = t->type->impl, *mod = calcRef;
3943 51913 : int pushed = (v->cand && v->cand == sel), no_candidates = 0;
3944 51913 : bool add_tz = false;
3945 : /* convert types and make sure they are rounded up correctly */
3946 :
3947 51913 : if (v->nr < 0)
3948 0 : goto bailout;
3949 :
3950 51913 : if (f->type->eclass != EC_EXTERNAL && t->type->eclass != EC_EXTERNAL &&
3951 : /* general cases */
3952 51555 : ((t->type->localtype == f->type->localtype && t->type->eclass == f->type->eclass &&
3953 51555 : !EC_INTERVAL(f->type->eclass) && f->type->eclass != EC_DEC && (t->digits == 0 || f->digits == t->digits) && type_has_tz(t) == type_has_tz(f)) ||
3954 : /* trivial decimal cases */
3955 1773 : (f->type->eclass == EC_DEC && t->type->eclass == EC_DEC && f->scale == t->scale && f->type->localtype == t->type->localtype) ||
3956 : /* trivial string cases */
3957 44583 : (EC_VARCHAR(f->type->eclass) && EC_VARCHAR(t->type->eclass) && (t->digits == 0 || (f->digits > 0 && t->digits >= f->digits))))) {
3958 : /* set output type. Despite the MAL code already being generated, the output type may still be checked */
3959 15104 : tail_set_type(be->mvc, v, t);
3960 15104 : return v;
3961 : }
3962 :
3963 : /* external types have sqlname convert functions,
3964 : these can generate errors (fromstr cannot) */
3965 36809 : if (t->type->eclass == EC_EXTERNAL)
3966 331 : convert = t->type->base.name;
3967 36478 : else if (t->type->eclass == EC_MONTH)
3968 : convert = "month_interval";
3969 36455 : else if (t->type->eclass == EC_SEC)
3970 100 : convert = "second_interval";
3971 :
3972 36809 : no_candidates = t->type->eclass == EC_EXTERNAL && strcmp(convert, "uuid") != 0; /* uuids conversions support candidate lists */
3973 :
3974 36809 : if ((type_has_tz(f) && !type_has_tz(t) && !EC_VARCHAR(t->type->eclass)) || (!type_has_tz(f) && type_has_tz(t))) {
3975 290 : v = temporal_convert(be, v, sel, f, t, true);
3976 290 : sel = NULL;
3977 290 : pushed = 0;
3978 290 : if (EC_VARCHAR(f->type->eclass))
3979 : return v;
3980 : }
3981 :
3982 : /* Lookup the sql convert function, there is no need
3983 : * for single value vs bat, this is handled by the
3984 : * mal function resolution */
3985 36685 : if (v->nrcols == 0 && (!sel || sel->nrcols == 0)) { /* simple calc */
3986 8186 : q = newStmtArgs(mb, mod, convert, 13);
3987 8186 : if (q == NULL)
3988 0 : goto bailout;
3989 28520 : } else if ((v->nrcols > 0 || (sel && sel->nrcols > 0)) && no_candidates) {
3990 21 : int type = t->type->localtype;
3991 :
3992 : /* with our current implementation, all internal SQL types have candidate list support on their conversions */
3993 21 : if (sel && !pushed) {
3994 0 : pushed = 1;
3995 0 : v = stmt_project(be, sel, v);
3996 0 : v->cand = sel;
3997 : }
3998 21 : q = newStmtArgs(mb, malRef, multiplexRef, 15);
3999 21 : if (q == NULL)
4000 0 : goto bailout;
4001 21 : setVarType(mb, getArg(q, 0), newBatType(type));
4002 21 : q = pushStr(mb, q, convertMultiplexMod(mod, convert));
4003 21 : q = pushStr(mb, q, convertMultiplexFcn(convert));
4004 : } else {
4005 28478 : if (v->nrcols == 0 && sel && !pushed) {
4006 877 : pushed = 1;
4007 877 : v = stmt_project(be, sel, v);
4008 877 : v->cand = sel;
4009 : }
4010 28478 : q = newStmtArgs(mb, mod==calcRef?batcalcRef:batmtimeRef, convert, 13);
4011 28479 : if (q == NULL)
4012 0 : goto bailout;
4013 : }
4014 :
4015 : /* convert to string is complex, we need full type info and mvc for the timezone */
4016 36852 : if (EC_VARCHAR(t->type->eclass) && !(trivial_string_conversion(f->type->eclass) && t->digits == 0)) {
4017 1904 : q = pushInt(mb, q, f->type->eclass);
4018 1904 : q = pushInt(mb, q, f->digits);
4019 1904 : q = pushInt(mb, q, f->scale);
4020 1904 : q = pushInt(mb, q, type_has_tz(f));
4021 34782 : } else if (f->type->eclass == EC_DEC) {
4022 : /* scale of the current decimal */
4023 1561 : q = pushInt(mb, q, f->scale);
4024 33221 : } else if (f->type->eclass == EC_SEC && (EC_COMPUTE(t->type->eclass) || t->type->eclass == EC_DEC)) {
4025 : /* scale of the current decimal */
4026 0 : q = pushInt(mb, q, 3);
4027 : }
4028 36686 : q = pushArgument(mb, q, v->nr);
4029 36685 : if (add_tz)
4030 : q = pushLng(mb, q, be->mvc->timezone);
4031 36685 : if (sel && !pushed && !v->cand) {
4032 3572 : q = pushArgument(mb, q, sel->nr);
4033 3572 : pushed = 1;
4034 33113 : } else if (v->nrcols > 0 && !no_candidates) {
4035 24907 : q = pushNilBat(mb, q);
4036 : }
4037 36685 : if (!add_tz && (t->type->eclass == EC_DEC || EC_TEMP_FRAC(t->type->eclass) || EC_INTERVAL(t->type->eclass))) {
4038 : /* digits, scale of the result decimal */
4039 3069 : q = pushInt(mb, q, t->digits);
4040 3069 : if (!EC_TEMP_FRAC(t->type->eclass))
4041 2730 : q = pushInt(mb, q, t->scale);
4042 : }
4043 : /* convert to string, give error on to large strings */
4044 36851 : if (EC_VARCHAR(t->type->eclass) && !(trivial_string_conversion(f->type->eclass) && t->digits == 0))
4045 1904 : q = pushInt(mb, q, t->digits);
4046 : /* convert a string to a time(stamp) with time zone */
4047 36685 : if (EC_VARCHAR(f->type->eclass) && EC_TEMP_TZ(t->type->eclass))
4048 : //q = pushInt(mb, q, type_has_tz(t));
4049 0 : q = pushLng(mb, q, be->mvc->timezone);
4050 36685 : if (t->type->eclass == EC_GEOM) {
4051 : /* push the type and coordinates of the column */
4052 687 : q = pushInt(mb, q, t->digits);
4053 : /* push the SRID of the whole columns */
4054 687 : q = pushInt(mb, q, t->scale);
4055 : /* push the type and coordinates of the inserted value */
4056 : //q = pushInt(mb, q, f->digits);
4057 : /* push the SRID of the inserted value */
4058 : //q = pushInt(mb, q, f->scale);
4059 : /* we decided to create the EWKB type also used by PostGIS and has the SRID provided by the user inside already */
4060 : /* push the SRID provided for this value */
4061 : /* GEOS library is able to store in the returned wkb the type an
4062 : * number if coordinates but not the SRID so SRID should be provided
4063 : * from this level */
4064 : /* if(be->argc > 1)
4065 : f->scale = ((ValRecord)((atom*)(be->mvc)->args[1])->data).val.ival;
4066 :
4067 : q = pushInt(mb, q, f->digits);
4068 : q = pushInt(mb, q, f->scale);
4069 : */ //q = pushInt(mb, q, ((ValRecord)((atom*)(be->mvc)->args[1])->data).val.ival);
4070 : }
4071 :
4072 36685 : bool enabled = be->mvc->sa->eb.enabled;
4073 36685 : be->mvc->sa->eb.enabled = false;
4074 36685 : stmt *s = stmt_create(be->mvc->sa, st_convert);
4075 36686 : be->mvc->sa->eb.enabled = enabled;
4076 36686 : if(!s) {
4077 0 : freeInstruction(q);
4078 0 : goto bailout;
4079 : }
4080 36686 : s->op1 = v;
4081 36686 : s->nrcols = 0; /* function without arguments returns single value */
4082 36686 : s->key = v->key;
4083 36686 : s->nrcols = v->nrcols;
4084 36686 : s->aggr = v->aggr;
4085 36686 : s->op4.typeval = *t;
4086 36686 : s->nr = getDestVar(q);
4087 36686 : s->q = q;
4088 36686 : s->cand = pushed ? sel : NULL;
4089 36686 : pushInstruction(mb, q);
4090 36685 : if ((!type_has_tz(f) && type_has_tz(t)))
4091 61 : return temporal_convert(be, s, NULL, f, t, false);
4092 : return s;
4093 :
4094 0 : bailout:
4095 0 : if (be->mvc->sa->eb.enabled)
4096 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
4097 : return NULL;
4098 : }
4099 :
4100 : stmt *
4101 27006 : stmt_unop(backend *be, stmt *op1, stmt *sel, sql_subfunc *op)
4102 : {
4103 27006 : list *ops = sa_list(be->mvc->sa);
4104 27077 : list_append(ops, op1);
4105 27089 : stmt *r = stmt_Nop(be, stmt_list(be, ops), sel, op, NULL);
4106 27090 : if (r && !r->cand)
4107 27091 : r->cand = op1->cand;
4108 27090 : return r;
4109 : }
4110 :
4111 : stmt *
4112 47190 : stmt_binop(backend *be, stmt *op1, stmt *op2, stmt *sel, sql_subfunc *op)
4113 : {
4114 47190 : list *ops = sa_list(be->mvc->sa);
4115 47202 : list_append(ops, op1);
4116 47204 : list_append(ops, op2);
4117 47206 : stmt *r = stmt_Nop(be, stmt_list(be, ops), sel, op, NULL);
4118 47207 : if (r && !r->cand)
4119 47207 : r->cand = op1->cand?op1->cand:op2->cand;
4120 47207 : return r;
4121 : }
4122 :
4123 : #define LANG_INT_OR_MAL(l) ((l)==FUNC_LANG_INT || (l)==FUNC_LANG_MAL)
4124 :
4125 : stmt *
4126 220457 : stmt_Nop(backend *be, stmt *ops, stmt *sel, sql_subfunc *f, stmt* rows)
4127 : {
4128 220457 : MalBlkPtr mb = be->mb;
4129 220457 : InstrPtr q = NULL;
4130 220457 : const char *mod = sql_func_mod(f->func), *fimp = backend_function_imp(be, f->func);
4131 220501 : sql_subtype *tpe = NULL;
4132 220501 : int push_cands = 0, default_nargs;
4133 220501 : stmt *o = NULL, *card = NULL;
4134 :
4135 220501 : if (ops == NULL)
4136 0 : goto bailout;
4137 :
4138 220501 : if (rows) {
4139 103 : if (sel) /* if there's a candidate list, use it instead of 'rows' */
4140 0 : rows = sel;
4141 : o = rows;
4142 220398 : } else if (list_length(ops->op4.lval)) {
4143 218597 : o = ops->op4.lval->h->data;
4144 652792 : for (node *n = ops->op4.lval->h; n; n = n->next) {
4145 434195 : stmt *c = n->data;
4146 :
4147 434195 : if (c && o->nrcols < c->nrcols)
4148 434195 : o = c;
4149 : }
4150 : }
4151 :
4152 : /* handle nullif */
4153 220521 : if (list_length(ops->op4.lval) == 2 &&
4154 138546 : strcmp(mod, "") == 0 && strcmp(fimp, "") == 0) {
4155 95 : stmt *e1 = ops->op4.lval->h->data;
4156 95 : stmt *e2 = ops->op4.lval->h->next->data;
4157 95 : int nrcols = 0;
4158 :
4159 95 : nrcols = e1->nrcols>e2->nrcols ? e1->nrcols:e2->nrcols;
4160 : /* nullif(e1,e2) -> ifthenelse(e1==e2),NULL,e1) */
4161 95 : if (strcmp(f->func->base.name, "nullif") == 0) {
4162 95 : const char *mod = (!nrcols)?calcRef:batcalcRef;
4163 95 : sql_subtype *t = tail_type(e1);
4164 95 : int tt = t->type->localtype;
4165 95 : q = newStmt(mb, mod, "==");
4166 95 : if (q == NULL)
4167 0 : goto bailout;
4168 95 : q = pushArgument(mb, q, e1->nr);
4169 95 : q = pushArgument(mb, q, e2->nr);
4170 95 : int nr = getDestVar(q);
4171 95 : pushInstruction(mb, q);
4172 :
4173 95 : q = newStmt(mb, mod, ifthenelseRef);
4174 95 : if (q == NULL)
4175 0 : goto bailout;
4176 95 : q = pushArgument(mb, q, nr);
4177 95 : q = pushNil(mb, q, tt);
4178 95 : q = pushArgument(mb, q, e1->nr);
4179 95 : pushInstruction(mb, q);
4180 : }
4181 95 : push_cands = f->func->type == F_FUNC && can_push_cands(sel, mod, fimp);
4182 : }
4183 95 : if (q == NULL) {
4184 220389 : if (backend_create_subfunc(be, f, ops->op4.lval) < 0)
4185 2 : goto bailout;
4186 220419 : mod = sql_func_mod(f->func);
4187 220434 : fimp = convertMultiplexFcn(backend_function_imp(be, f->func));
4188 220388 : push_cands = f->func->type == F_FUNC && can_push_cands(sel, mod, fimp);
4189 229578 : default_nargs = (f->res && list_length(f->res) ? list_length(f->res) : 1) + list_length(ops->op4.lval) + (o && o->nrcols > 0 ? 6 : 4);
4190 220442 : if (rows) {
4191 103 : card = stmt_aggr(be, rows, NULL, NULL, sql_bind_func(be->mvc, "sys", "count", sql_bind_localtype("void"), NULL, F_AGGR, true, true), 1, 0, 1);
4192 103 : default_nargs++;
4193 : }
4194 :
4195 220442 : if (o && o->nrcols > 0 && f->func->type != F_LOADER && f->func->type != F_PROC) {
4196 140686 : sql_subtype *res = f->res->h->data;
4197 :
4198 281356 : q = newStmtArgs(mb, f->func->type == F_UNION ? batmalRef : malRef, multiplexRef, default_nargs);
4199 140687 : if (q == NULL)
4200 0 : goto bailout;
4201 140687 : if (rows)
4202 103 : q = pushArgument(mb, q, card->nr);
4203 140687 : q = pushStr(mb, q, mod);
4204 140687 : q = pushStr(mb, q, fimp);
4205 140687 : setVarType(mb, getArg(q, 0), newBatType(res->type->localtype));
4206 : } else {
4207 79756 : q = newStmtArgs(mb, mod, fimp, default_nargs);
4208 79778 : if (q == NULL)
4209 0 : goto bailout;
4210 :
4211 79778 : if (rows)
4212 0 : q = pushArgument(mb, q, card->nr);
4213 79778 : if (f->res && list_length(f->res)) {
4214 70622 : sql_subtype *res = f->res->h->data;
4215 :
4216 70622 : setVarType(mb, getArg(q, 0), res->type->localtype);
4217 : }
4218 : }
4219 220465 : if (LANG_EXT(f->func->lang)) {
4220 : /* TODO LOADER functions still use information in sql_subfunc struct
4221 : that won't be visible to other sessions if another function uses them.
4222 : It has to be cleaned up */
4223 221 : if (f->func->type == F_LOADER)
4224 25 : q = pushPtr(mb, q, f);
4225 : else
4226 196 : q = pushPtr(mb, q, f->func);
4227 : }
4228 220465 : if (f->func->lang == FUNC_LANG_C) {
4229 35 : q = pushBit(mb, q, 0);
4230 220430 : } else if (f->func->lang == FUNC_LANG_CPP) {
4231 1 : q = pushBit(mb, q, 1);
4232 : }
4233 220465 : if (f->func->lang == FUNC_LANG_R || f->func->lang >= FUNC_LANG_PY ||
4234 : f->func->lang == FUNC_LANG_C || f->func->lang == FUNC_LANG_CPP) {
4235 221 : q = pushStr(mb, q, f->func->query);
4236 : }
4237 : /* first dynamic output of copy* functions */
4238 220465 : if (f->func->type == F_UNION || (f->func->type == F_LOADER && f->res != NULL))
4239 2709 : q = table_func_create_result(mb, q, f->func, f->res);
4240 220465 : if (list_length(ops->op4.lval))
4241 218655 : tpe = tail_type(ops->op4.lval->h->data);
4242 :
4243 654800 : for (node *n = ops->op4.lval->h; n; n = n->next) {
4244 434335 : stmt *op = n->data;
4245 434335 : q = pushArgument(mb, q, op->nr);
4246 : }
4247 : /* push candidate lists if that's the case */
4248 220465 : if (push_cands) {
4249 77090 : for (node *n = ops->op4.lval->h; n; n = n->next) {
4250 50855 : stmt *op = n->data;
4251 :
4252 50855 : if (op->nrcols > 0) {
4253 28523 : if (op->cand && op->cand == sel) {
4254 3788 : q = pushNilBat(mb, q);
4255 : } else {
4256 24735 : q = pushArgument(mb, q, sel->nr);
4257 : }
4258 : }
4259 : }
4260 : }
4261 : /* special case for round function on decimals */
4262 220465 : if (LANG_INT_OR_MAL(f->func->lang) && strcmp(fimp, "round") == 0 && tpe && tpe->type->eclass == EC_DEC && ops->op4.lval->h && ops->op4.lval->h->data) {
4263 48 : q = pushInt(mb, q, tpe->digits);
4264 48 : q = pushInt(mb, q, tpe->scale);
4265 : }
4266 220465 : pushInstruction(mb, q);
4267 : }
4268 :
4269 220560 : stmt *s = stmt_create(be->mvc->sa, st_Nop);
4270 220559 : if(!s) {
4271 0 : goto bailout;
4272 : }
4273 220559 : s->op1 = ops;
4274 220559 : if (o) {
4275 218767 : s->nrcols = o->nrcols;
4276 218767 : s->key = o->key;
4277 218767 : s->aggr = o->aggr;
4278 : } else {
4279 1792 : s->nrcols = 0;
4280 1792 : s->key = 1;
4281 : }
4282 220559 : s->op4.funcval = f;
4283 220559 : s->nr = getDestVar(q);
4284 220559 : s->q = q;
4285 220559 : if (sel && push_cands && s->nrcols)
4286 24724 : s->cand = sel;
4287 : return s;
4288 :
4289 2 : bailout:
4290 2 : if (be->mvc->sa->eb.enabled)
4291 2 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
4292 : return NULL;
4293 : }
4294 :
4295 : stmt *
4296 23 : stmt_direct_func(backend *be, InstrPtr q)
4297 : {
4298 23 : if (q) {
4299 23 : stmt *s = stmt_create(be->mvc->sa, st_func);
4300 23 : if(!s) {
4301 : return NULL;
4302 : }
4303 23 : s->flag = op_union;
4304 23 : s->nrcols = 3;
4305 23 : s->nr = getDestVar(q);
4306 23 : s->q = q;
4307 23 : return s;
4308 : }
4309 : return NULL;
4310 : }
4311 :
4312 : stmt *
4313 186 : stmt_func(backend *be, stmt *ops, const char *name, sql_rel *rel, int f_union)
4314 : {
4315 186 : MalBlkPtr mb = be->mb;
4316 186 : InstrPtr q = NULL;
4317 186 : prop *p = NULL;
4318 :
4319 : /* dump args */
4320 186 : if (ops && ops->nr < 0)
4321 0 : goto bailout;
4322 :
4323 186 : if ((p = find_prop(rel->p, PROP_REMOTE)))
4324 186 : rel->p = prop_remove(rel->p, p);
4325 : /* sql_processrelation may split projections, so make sure the topmost relation only contains references */
4326 186 : rel = rel_project(be->mvc->sa, rel, rel_projections(be->mvc, rel, NULL, 1, 1));
4327 186 : if (!(rel = sql_processrelation(be->mvc, rel, 0, 0, 1, 1)))
4328 0 : goto bailout;
4329 186 : if (p) {
4330 186 : p->p = rel->p;
4331 186 : rel->p = p;
4332 : }
4333 :
4334 186 : if (monet5_create_relational_function(be->mvc, sql_private_module_name, name, rel, ops, NULL, 1) < 0)
4335 0 : goto bailout;
4336 :
4337 186 : int nargs;
4338 186 : sql_rel *r = relational_func_create_result_part1(be->mvc, rel, &nargs);
4339 186 : if (ops)
4340 186 : nargs += list_length(ops->op4.lval);
4341 186 : if (f_union)
4342 0 : q = newStmt(mb, batmalRef, multiplexRef);
4343 : else
4344 186 : q = newStmt(mb, sql_private_module_name, name);
4345 186 : if (q == NULL)
4346 0 : goto bailout;
4347 186 : q = relational_func_create_result_part2(mb, q, r);
4348 186 : if (f_union) {
4349 0 : q = pushStr(mb, q, sql_private_module_name);
4350 0 : q = pushStr(mb, q, name);
4351 : }
4352 186 : if (ops) {
4353 208 : for (node *n = ops->op4.lval->h; n; n = n->next) {
4354 22 : stmt *op = n->data;
4355 :
4356 22 : q = pushArgument(mb, q, op->nr);
4357 : }
4358 : }
4359 :
4360 186 : allocator *sa = be->mvc->sa;
4361 186 : bool enabled = be->mvc->sa->eb.enabled;
4362 186 : be->mvc->sa->eb.enabled = false;
4363 186 : stmt *o = NULL, *s = stmt_create(sa, st_func);
4364 186 : be->mvc->sa->eb.enabled = enabled;
4365 186 : if(!s) {
4366 0 : freeInstruction(q);
4367 0 : goto bailout;
4368 : }
4369 186 : s->op1 = ops;
4370 186 : s->op2 = stmt_atom_string(be, name);
4371 186 : s->op4.rel = rel;
4372 186 : s->flag = f_union;
4373 186 : if (ops && list_length(ops->op4.lval)) {
4374 10 : node *n;
4375 32 : for (n = ops->op4.lval->h, o = n->data; n; n = n->next) {
4376 22 : stmt *c = n->data;
4377 :
4378 22 : if (o->nrcols < c->nrcols)
4379 0 : o = c;
4380 : }
4381 : }
4382 :
4383 10 : if (o) {
4384 10 : s->nrcols = o->nrcols;
4385 10 : s->key = o->key;
4386 10 : s->aggr = o->aggr;
4387 : } else {
4388 176 : s->nrcols = 0;
4389 176 : s->key = 1;
4390 : }
4391 186 : s->nr = getDestVar(q);
4392 186 : s->q = q;
4393 186 : pushInstruction(mb, q);
4394 186 : return s;
4395 :
4396 0 : bailout:
4397 0 : if (be->mvc->sa->eb.enabled)
4398 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
4399 : return NULL;
4400 : }
4401 :
4402 : stmt *
4403 85131 : stmt_aggr(backend *be, stmt *op1, stmt *grp, stmt *ext, sql_subfunc *op, int reduce, int no_nil, int nil_if_empty)
4404 : {
4405 85131 : MalBlkPtr mb = be->mb;
4406 85131 : InstrPtr q = NULL;
4407 85131 : const char *mod, *aggrfunc;
4408 85131 : sql_subtype *res = op->res->h->data;
4409 85131 : int restype = res->type->localtype;
4410 85131 : bool complex_aggr = false;
4411 85131 : int *stmt_nr = NULL;
4412 85131 : int avg = 0;
4413 :
4414 85131 : if (op1->nr < 0)
4415 0 : goto bailout;
4416 85131 : if (backend_create_subfunc(be, op, NULL) < 0)
4417 0 : goto bailout;
4418 85378 : mod = sql_func_mod(op->func);
4419 85446 : aggrfunc = backend_function_imp(be, op->func);
4420 :
4421 85473 : if (LANG_INT_OR_MAL(op->func->lang)) {
4422 85020 : if (strcmp(aggrfunc, "avg") == 0)
4423 : avg = 1;
4424 83650 : if (avg || strcmp(aggrfunc, "sum") == 0 || strcmp(aggrfunc, "prod") == 0
4425 76465 : || strcmp(aggrfunc, "str_group_concat") == 0)
4426 : complex_aggr = true;
4427 85020 : if (restype == TYPE_dbl)
4428 1561 : avg = 0;
4429 : }
4430 :
4431 170946 : int argc = 1
4432 85473 : + 2 * avg
4433 85473 : + (LANG_EXT(op->func->lang) != 0)
4434 85473 : + 2 * (op->func->lang == FUNC_LANG_C || op->func->lang == FUNC_LANG_CPP)
4435 85473 : + (op->func->lang == FUNC_LANG_PY || op->func->lang == FUNC_LANG_R)
4436 85473 : + (op1->type != st_list ? 1 : list_length(op1->op4.lval))
4437 85473 : + (grp ? 4 : avg + 1);
4438 :
4439 85473 : if (grp) {
4440 6847 : char *aggrF = SA_NEW_ARRAY(be->mvc->sa, char, strlen(aggrfunc) + 4);
4441 6847 : if (!aggrF)
4442 0 : goto bailout;
4443 6847 : stpcpy(stpcpy(aggrF, "sub"), aggrfunc);
4444 6847 : aggrfunc = aggrF;
4445 6847 : if ((grp && grp->nr < 0) || (ext && ext->nr < 0))
4446 0 : goto bailout;
4447 :
4448 6847 : q = newStmtArgs(mb, mod, aggrfunc, argc);
4449 6847 : if (q == NULL)
4450 0 : goto bailout;
4451 6847 : setVarType(mb, getArg(q, 0), newBatType(restype));
4452 6847 : if (avg) { /* for avg also return rest and count */
4453 96 : q = pushReturn(mb, q, newTmpVariable(mb, newBatType(TYPE_lng)));
4454 96 : q = pushReturn(mb, q, newTmpVariable(mb, newBatType(TYPE_lng)));
4455 : }
4456 : } else {
4457 78626 : q = newStmtArgs(mb, mod, aggrfunc, argc);
4458 78711 : if (q == NULL)
4459 0 : goto bailout;
4460 78711 : if (complex_aggr) {
4461 6745 : setVarType(mb, getArg(q, 0), restype);
4462 6745 : if (avg) { /* for avg also return rest and count */
4463 57 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_lng));
4464 57 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_lng));
4465 : }
4466 : }
4467 : }
4468 :
4469 85558 : if (LANG_EXT(op->func->lang))
4470 47 : q = pushPtr(mb, q, op->func);
4471 85560 : if (op->func->lang == FUNC_LANG_R ||
4472 85525 : op->func->lang >= FUNC_LANG_PY ||
4473 : op->func->lang == FUNC_LANG_C ||
4474 : op->func->lang == FUNC_LANG_CPP) {
4475 47 : if (!grp) {
4476 20 : setVarType(mb, getArg(q, 0), restype);
4477 : }
4478 47 : if (op->func->lang == FUNC_LANG_C) {
4479 12 : q = pushBit(mb, q, 0);
4480 35 : } else if (op->func->lang == FUNC_LANG_CPP) {
4481 0 : q = pushBit(mb, q, 1);
4482 : }
4483 47 : q = pushStr(mb, q, op->func->query);
4484 : }
4485 :
4486 85560 : if (op1->type != st_list) {
4487 79653 : q = pushArgument(mb, q, op1->nr);
4488 : } else {
4489 5907 : int i;
4490 5907 : node *n;
4491 :
4492 12236 : for (i=0, n = op1->op4.lval->h; n; n = n->next, i++) {
4493 6329 : stmt *op = n->data;
4494 :
4495 6329 : if (stmt_nr)
4496 : q = pushArgument(mb, q, stmt_nr[i]);
4497 : else
4498 6329 : q = pushArgument(mb, q, op->nr);
4499 : }
4500 : }
4501 85557 : if (grp) {
4502 6847 : q = pushArgument(mb, q, grp->nr);
4503 6847 : q = pushArgument(mb, q, ext->nr);
4504 6847 : if (LANG_INT_OR_MAL(op->func->lang)) {
4505 6820 : if (avg) /* push nil candidates */
4506 96 : q = pushNilBat(mb, q);
4507 6820 : q = pushBit(mb, q, no_nil);
4508 : }
4509 78710 : } else if (LANG_INT_OR_MAL(op->func->lang) && no_nil && strncmp(aggrfunc, "count", 5) == 0) {
4510 1643 : q = pushBit(mb, q, no_nil);
4511 77067 : } else if (LANG_INT_OR_MAL(op->func->lang) && !nil_if_empty && strncmp(aggrfunc, "sum", 3) == 0) {
4512 0 : q = pushBit(mb, q, FALSE);
4513 77067 : } else if (LANG_INT_OR_MAL(op->func->lang) && avg) { /* push candidates */
4514 57 : q = pushNilBat(mb, q);
4515 57 : q = pushBit(mb, q, no_nil);
4516 : }
4517 :
4518 85557 : bool enabled = be->mvc->sa->eb.enabled;
4519 85557 : be->mvc->sa->eb.enabled = false;
4520 85557 : stmt *s = stmt_create(be->mvc->sa, st_aggr);
4521 85541 : be->mvc->sa->eb.enabled = enabled;
4522 85541 : if(!s) {
4523 0 : freeInstruction(q);
4524 0 : goto bailout;
4525 : }
4526 85541 : s->op1 = op1;
4527 85541 : if (grp) {
4528 6847 : s->op2 = grp;
4529 6847 : s->op3 = ext;
4530 6847 : s->nrcols = 1;
4531 : } else {
4532 78694 : if (!reduce)
4533 0 : s->nrcols = 1;
4534 : }
4535 85541 : s->key = reduce;
4536 85541 : s->aggr = reduce;
4537 85541 : s->flag = no_nil;
4538 85541 : s->op4.funcval = op;
4539 85541 : s->nr = getDestVar(q);
4540 85541 : s->q = q;
4541 85541 : pushInstruction(mb, q);
4542 85541 : return s;
4543 :
4544 0 : bailout:
4545 0 : if (be->mvc->sa->eb.enabled)
4546 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
4547 : return NULL;
4548 : }
4549 :
4550 : static stmt *
4551 5072987 : stmt_alias_(backend *be, stmt *op1, int label, const char *tname, const char *alias)
4552 : {
4553 5072987 : assert(label);
4554 5072987 : stmt *s = stmt_create(be->mvc->sa, st_alias);
4555 5072580 : if(!s) {
4556 : return NULL;
4557 : }
4558 5072580 : s->label = label;
4559 5072580 : s->op1 = op1;
4560 5072580 : s->nrcols = op1->nrcols;
4561 5072580 : s->key = op1->key;
4562 5072580 : s->aggr = op1->aggr;
4563 :
4564 5072580 : s->tname = tname;
4565 5072580 : s->cname = alias;
4566 5072580 : s->nr = op1->nr;
4567 5072580 : s->q = op1->q;
4568 5072580 : return s;
4569 : }
4570 :
4571 : stmt *
4572 4499613 : stmt_alias(backend *be, stmt *op1, int label, const char *tname, const char *alias)
4573 : {
4574 : /*
4575 : if (((!op1->tname && !tname) ||
4576 : (op1->tname && tname && strcmp(op1->tname, tname)==0)) &&
4577 : op1->cname && strcmp(op1->cname, alias)==0)
4578 : return op1;
4579 : */
4580 4499613 : return stmt_alias_(be, op1, label, tname, alias);
4581 : }
4582 :
4583 : stmt *
4584 573424 : stmt_as(backend *be, stmt *s, stmt *org)
4585 : {
4586 573424 : assert(org->type == st_alias);
4587 573424 : return stmt_alias_(be, s, org->label, org->tname, org->cname);
4588 : }
4589 :
4590 : sql_subtype *
4591 1567427 : tail_type(stmt *st)
4592 : {
4593 8693593 : for (;;) {
4594 8693593 : switch (st->type) {
4595 37114 : case st_const:
4596 37114 : st = st->op2;
4597 37114 : continue;
4598 3340 : case st_uselect:
4599 : case st_semijoin:
4600 : case st_limit:
4601 : case st_limit2:
4602 : case st_sample:
4603 : case st_tunion:
4604 : case st_tdiff:
4605 : case st_tinter:
4606 3340 : return sql_bind_localtype("oid");
4607 587 : case st_uselect2:
4608 587 : if (!st->reduce)
4609 61 : return sql_bind_localtype("bit");
4610 526 : return sql_bind_localtype("oid");
4611 3462719 : case st_alias:
4612 3462719 : if (!st->op1)
4613 183 : return &st->op4.typeval;
4614 : /* fall through */
4615 : case st_append:
4616 : case st_append_bulk:
4617 : case st_replace:
4618 : case st_gen_group:
4619 : case st_order:
4620 3922352 : st = st->op1;
4621 3922352 : continue;
4622 0 : case st_list:
4623 0 : st = st->op4.lval->h->data;
4624 0 : continue;
4625 922400 : case st_bat:
4626 922400 : return &st->op4.cval->type;
4627 2019 : case st_idxbat:
4628 2019 : if (hash_index(st->op4.idxval->type)) {
4629 272 : return sql_bind_localtype("lng");
4630 1747 : } else if (oid_index(st->op4.idxval->type)) {
4631 1747 : return sql_bind_localtype("oid");
4632 : }
4633 : /* fall through */
4634 : case st_join:
4635 : case st_join2:
4636 : case st_joinN:
4637 3166726 : if (st->flag == cmp_project) {
4638 3166700 : st = st->op2;
4639 3166700 : continue;
4640 : }
4641 : /* fall through */
4642 : case st_reorder:
4643 : case st_group:
4644 : case st_tid:
4645 : case st_mirror:
4646 15561 : return sql_bind_localtype("oid");
4647 31195 : case st_result:
4648 31195 : return &st->op4.typeval;
4649 0 : case st_table_clear:
4650 0 : return sql_bind_localtype("lng");
4651 156483 : case st_aggr:
4652 : case st_Nop: {
4653 156483 : list *res = st->op4.funcval->res;
4654 :
4655 156483 : if (res && list_length(res) == 1)
4656 156483 : return res->h->data;
4657 :
4658 : return NULL;
4659 : }
4660 152392 : case st_atom:
4661 152392 : return atom_type(st->op4.aval);
4662 280951 : case st_convert:
4663 : case st_temp:
4664 : case st_single:
4665 : case st_rs_column:
4666 280951 : return &st->op4.typeval;
4667 2308 : case st_var:
4668 2308 : if (st->op4.typeval.type)
4669 2308 : return &st->op4.typeval;
4670 : /* fall through */
4671 : case st_exception:
4672 : return NULL;
4673 8 : case st_table:
4674 8 : return sql_bind_localtype("bat");
4675 : default:
4676 0 : assert(0);
4677 : return NULL;
4678 : }
4679 : }
4680 : }
4681 :
4682 : int
4683 6685 : stmt_has_null(stmt *s)
4684 : {
4685 21118 : switch (s->type) {
4686 : case st_aggr:
4687 : case st_semijoin:
4688 : case st_uselect:
4689 : case st_uselect2:
4690 : case st_atom:
4691 : return 0;
4692 8278 : case st_alias:
4693 8278 : return stmt_has_null(s->op1);
4694 6155 : case st_join:
4695 6155 : return stmt_has_null(s->op2);
4696 4255 : case st_bat:
4697 4255 : return s->op4.cval->null;
4698 :
4699 2430 : default:
4700 2430 : return 1;
4701 : }
4702 : }
4703 :
4704 : static const char *
4705 0 : func_name(allocator *sa, const char *n1, const char *n2)
4706 : {
4707 0 : size_t l1 = _strlen(n1), l2;
4708 :
4709 0 : if (!sa)
4710 : return n1;
4711 0 : if (!n2)
4712 0 : return sa_strdup(sa, n1);
4713 0 : l2 = _strlen(n2);
4714 :
4715 0 : if (l2 > 16) { /* only support short names */
4716 0 : char *ns = SA_NEW_ARRAY(sa, char, l2 + 1);
4717 0 : if(!ns)
4718 : return NULL;
4719 0 : snprintf(ns, l2 + 1, "%s", n2);
4720 0 : return ns;
4721 : } else {
4722 0 : char *ns = SA_NEW_ARRAY(sa, char, l1 + l2 + 2), *s = ns;
4723 0 : if(!ns)
4724 : return NULL;
4725 0 : snprintf(ns, l1 + l2 + 2, "%s_%s", n1, n2);
4726 0 : return s;
4727 : }
4728 : }
4729 :
4730 : static const char *_column_name(allocator *sa, stmt *st);
4731 :
4732 : const char *
4733 2664704 : column_name(allocator *sa, stmt *st)
4734 : {
4735 2664704 : if (!st->cname)
4736 0 : st->cname = _column_name(sa, st);
4737 2664704 : return st->cname;
4738 : }
4739 :
4740 : static const char *
4741 0 : _column_name(allocator *sa, stmt *st)
4742 : {
4743 0 : switch (st->type) {
4744 0 : case st_order:
4745 : case st_reorder:
4746 0 : return column_name(sa, st->op1);
4747 0 : case st_const:
4748 : case st_join:
4749 : case st_join2:
4750 : case st_joinN:
4751 0 : return column_name(sa, st->op2);
4752 :
4753 0 : case st_mirror:
4754 : case st_group:
4755 : case st_result:
4756 : case st_append:
4757 : case st_append_bulk:
4758 : case st_replace:
4759 : case st_gen_group:
4760 : case st_semijoin:
4761 : case st_uselect:
4762 : case st_uselect2:
4763 : case st_limit:
4764 : case st_limit2:
4765 : case st_sample:
4766 : case st_tunion:
4767 : case st_tdiff:
4768 : case st_tinter:
4769 : case st_convert:
4770 0 : return column_name(sa, st->op1);
4771 0 : case st_Nop:
4772 : case st_aggr:
4773 : {
4774 0 : const char *cn = column_name(sa, st->op1);
4775 0 : return func_name(sa, st->op4.funcval->func->base.name, cn);
4776 : }
4777 0 : case st_alias:
4778 0 : if (st->op3)
4779 0 : return column_name(sa, st->op3);
4780 : break;
4781 0 : case st_bat:
4782 0 : return st->op4.cval->base.name;
4783 0 : case st_atom:
4784 0 : if (st->op4.aval->data.vtype == TYPE_str)
4785 0 : return atom2string(sa, st->op4.aval);
4786 : /* fall through */
4787 : case st_var:
4788 : case st_temp:
4789 : case st_single:
4790 0 : if (sa)
4791 0 : return sa_strdup(sa, "single_value");
4792 : return "single_value";
4793 :
4794 0 : case st_list:
4795 0 : if (list_length(st->op4.lval))
4796 0 : return column_name(sa, st->op4.lval->h->data);
4797 : /* fall through */
4798 : case st_rs_column:
4799 : return NULL;
4800 : default:
4801 : return NULL;
4802 : }
4803 : return NULL;
4804 : }
4805 :
4806 : const char *
4807 2649382 : table_name(allocator *sa, stmt *st)
4808 : {
4809 2649382 : (void)sa;
4810 2649382 : return st->tname;
4811 : }
4812 :
4813 : const char *
4814 339635 : schema_name(allocator *sa, stmt *st)
4815 : {
4816 3120826 : switch (st->type) {
4817 1200893 : case st_const:
4818 : case st_semijoin:
4819 : case st_join:
4820 : case st_join2:
4821 : case st_joinN:
4822 1200893 : return schema_name(sa, st->op2);
4823 120710 : case st_mirror:
4824 : case st_group:
4825 : case st_result:
4826 : case st_append:
4827 : case st_append_bulk:
4828 : case st_replace:
4829 : case st_gen_group:
4830 : case st_uselect:
4831 : case st_uselect2:
4832 : case st_limit:
4833 : case st_limit2:
4834 : case st_sample:
4835 : case st_tunion:
4836 : case st_tdiff:
4837 : case st_tinter:
4838 : case st_convert:
4839 : case st_Nop:
4840 : case st_aggr:
4841 : /* there are no schema aliases, ie look into the base column */
4842 120710 : if (st->op1)
4843 : return schema_name(sa, st->op1);
4844 : return NULL;
4845 1428365 : case st_alias:
4846 1428365 : if (!st->op1)
4847 : return NULL;
4848 : return schema_name(sa, st->op1);
4849 204049 : case st_bat:
4850 204049 : return st->op4.cval->t->s->base.name;
4851 : case st_atom:
4852 : return NULL;
4853 : case st_var:
4854 : case st_temp:
4855 : case st_single:
4856 : return NULL;
4857 31378 : case st_list:
4858 31378 : if (list_length(st->op4.lval))
4859 31258 : return schema_name(sa, st->op4.lval->h->data);
4860 : return NULL;
4861 : default:
4862 : return NULL;
4863 : }
4864 : }
4865 :
4866 : stmt *
4867 1118 : stmt_cond(backend *be, stmt *cond, stmt *outer, int loop /* 0 if, 1 while */, int anti )
4868 : {
4869 1118 : MalBlkPtr mb = be->mb;
4870 1118 : InstrPtr q = NULL;
4871 :
4872 1118 : if (cond->nr < 0)
4873 0 : goto bailout;
4874 1118 : if (anti) {
4875 25 : sql_subtype *bt = sql_bind_localtype("bit");
4876 25 : sql_subfunc *not = sql_bind_func(be->mvc, "sys", "not", bt, NULL, F_FUNC, true, true);
4877 25 : sql_subfunc *or = sql_bind_func(be->mvc, "sys", "or", bt, bt, F_FUNC, true, true);
4878 25 : sql_subfunc *isnull = sql_bind_func(be->mvc, "sys", "isnull", bt, NULL, F_FUNC, true, true);
4879 25 : cond = stmt_binop(be,
4880 : stmt_unop(be, cond, NULL, not),
4881 : stmt_unop(be, cond, NULL, isnull), NULL, or);
4882 : }
4883 1118 : if (!loop) { /* if */
4884 1101 : q = newAssignment(mb);
4885 1101 : if (q == NULL)
4886 0 : goto bailout;
4887 1101 : q->barrier = BARRIERsymbol;
4888 1101 : q = pushArgument(mb, q, cond->nr);
4889 : } else { /* while */
4890 17 : int c;
4891 :
4892 17 : if (outer->nr < 0)
4893 0 : goto bailout;
4894 : /* leave barrier */
4895 17 : q = newStmt(mb, calcRef, notRef);
4896 17 : if (q == NULL)
4897 0 : goto bailout;
4898 17 : q = pushArgument(mb, q, cond->nr);
4899 17 : c = getArg(q, 0);
4900 17 : pushInstruction(mb, q);
4901 :
4902 17 : q = newAssignment(mb);
4903 17 : if (q == NULL)
4904 0 : goto bailout;
4905 17 : getArg(q, 0) = outer->nr;
4906 17 : q->barrier = LEAVEsymbol;
4907 17 : q = pushArgument(mb, q, c);
4908 : }
4909 :
4910 1118 : bool enabled = be->mvc->sa->eb.enabled;
4911 1118 : be->mvc->sa->eb.enabled = false;
4912 1118 : stmt *s = stmt_create(be->mvc->sa, st_cond);
4913 1118 : be->mvc->sa->eb.enabled = enabled;
4914 1118 : if(!s) {
4915 0 : freeInstruction(q);
4916 0 : goto bailout;
4917 : }
4918 1118 : s->flag = be->mvc_var; /* keep the mvc_var of the outer context */
4919 1118 : s->loop = loop;
4920 1118 : s->op1 = cond;
4921 1118 : s->nr = getArg(q, 0);
4922 1118 : pushInstruction(mb, q);
4923 1118 : return s;
4924 :
4925 0 : bailout:
4926 0 : if (be->mvc->sa->eb.enabled)
4927 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
4928 : return NULL;
4929 : }
4930 :
4931 : stmt *
4932 1118 : stmt_control_end(backend *be, stmt *cond)
4933 : {
4934 1118 : MalBlkPtr mb = be->mb;
4935 1118 : InstrPtr q = NULL;
4936 :
4937 1118 : if (cond->nr < 0)
4938 0 : goto bailout;
4939 :
4940 1118 : if (cond->loop) { /* while */
4941 : /* redo barrier */
4942 17 : q = newAssignment(mb);
4943 17 : if (q == NULL)
4944 0 : goto bailout;
4945 17 : getArg(q, 0) = cond->nr;
4946 17 : q->argc = q->retc = 1;
4947 17 : q->barrier = REDOsymbol;
4948 17 : q = pushBit(mb, q, TRUE);
4949 : } else {
4950 1101 : q = newAssignment(mb);
4951 1101 : if (q == NULL)
4952 0 : goto bailout;
4953 1101 : getArg(q, 0) = cond->nr;
4954 1101 : q->argc = q->retc = 1;
4955 1101 : q->barrier = EXITsymbol;
4956 : }
4957 1118 : be->mvc_var = cond->flag; /* restore old mvc_var from before the barrier */
4958 1118 : bool enabled = be->mvc->sa->eb.enabled;
4959 1118 : be->mvc->sa->eb.enabled = false;
4960 1118 : stmt *s = stmt_create(be->mvc->sa, st_control_end);
4961 1118 : be->mvc->sa->eb.enabled = enabled;
4962 1118 : if(!s) {
4963 0 : freeInstruction(q);
4964 0 : goto bailout;
4965 : }
4966 1118 : s->op1 = cond;
4967 1118 : s->nr = getArg(q, 0);
4968 1118 : pushInstruction(mb, q);
4969 1118 : return s;
4970 :
4971 0 : bailout:
4972 0 : if (be->mvc->sa->eb.enabled)
4973 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
4974 : return NULL;
4975 : }
4976 :
4977 :
4978 : static InstrPtr
4979 206 : dump_cols(MalBlkPtr mb, list *l, InstrPtr q)
4980 : {
4981 206 : int i;
4982 206 : node *n;
4983 :
4984 206 : if (q == NULL)
4985 : return NULL;
4986 206 : q->retc = q->argc = 0;
4987 1651 : for (i = 0, n = l->h; n; n = n->next, i++) {
4988 1445 : stmt *c = n->data;
4989 :
4990 1445 : q = pushArgument(mb, q, c->nr);
4991 : }
4992 206 : if (q == NULL)
4993 : return NULL;
4994 206 : q->retc = q->argc;
4995 : /* Let's make it a proper assignment */
4996 1651 : for (i = 0, n = l->h; n; n = n->next, i++) {
4997 1445 : stmt *c = n->data;
4998 :
4999 1445 : q = pushArgument(mb, q, c->nr);
5000 : }
5001 : return q;
5002 : }
5003 :
5004 : stmt *
5005 662 : stmt_return(backend *be, stmt *val, int nr_declared_tables)
5006 : {
5007 662 : MalBlkPtr mb = be->mb;
5008 662 : InstrPtr q = NULL;
5009 :
5010 662 : if (val->nr < 0)
5011 0 : goto bailout;
5012 662 : int args = val->type == st_table ? 2 * list_length(val->op1->op4.lval) : 0;
5013 206 : if (args < MAXARG)
5014 : args = MAXARG;
5015 662 : q = newInstructionArgs(mb, NULL, NULL, args);
5016 662 : if (q == NULL)
5017 0 : goto bailout;
5018 662 : q->barrier= RETURNsymbol;
5019 662 : if (val->type == st_table) {
5020 206 : list *l = val->op1->op4.lval;
5021 :
5022 206 : q = dump_cols(mb, l, q);
5023 : } else {
5024 456 : getArg(q, 0) = getArg(getInstrPtr(mb, 0), 0);
5025 456 : q = pushArgument(mb, q, val->nr);
5026 : }
5027 :
5028 662 : bool enabled = be->mvc->sa->eb.enabled;
5029 662 : be->mvc->sa->eb.enabled = false;
5030 662 : stmt *s = stmt_create(be->mvc->sa, st_return);
5031 662 : be->mvc->sa->eb.enabled = enabled;
5032 662 : if(!s) {
5033 0 : freeInstruction(q);
5034 0 : goto bailout;
5035 : }
5036 662 : s->op1 = val;
5037 662 : s->flag = nr_declared_tables;
5038 662 : s->nr = getDestVar(q);
5039 662 : s->q = q;
5040 662 : pushInstruction(mb, q);
5041 662 : return s;
5042 :
5043 0 : bailout:
5044 0 : if (be->mvc->sa->eb.enabled)
5045 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
5046 : return NULL;
5047 : }
5048 :
5049 : stmt *
5050 1416 : stmt_assign(backend *be, const char *sname, const char *varname, stmt *val, int level)
5051 : {
5052 1416 : MalBlkPtr mb = be->mb;
5053 1416 : InstrPtr q = NULL;
5054 :
5055 1416 : if (val && val->nr < 0)
5056 0 : goto bailout;
5057 1416 : if (level != 0) {
5058 1037 : char *buf, levelstr[16];
5059 :
5060 1037 : if (!val) {
5061 : /* drop declared table */
5062 0 : assert(0);
5063 : }
5064 :
5065 1037 : assert(!sname);
5066 1037 : snprintf(levelstr, sizeof(levelstr), "%d", level);
5067 1037 : buf = SA_NEW_ARRAY(be->mvc->sa, char, strlen(levelstr) + strlen(varname) + 3);
5068 1037 : if (!buf)
5069 0 : goto bailout;
5070 1037 : stpcpy(stpcpy(stpcpy(stpcpy(buf, "A"), levelstr), "%"), varname); /* mangle variable name */
5071 1037 : q = newInstruction(mb, NULL, NULL);
5072 1037 : if (q == NULL) {
5073 0 : goto bailout;
5074 : }
5075 1037 : q->argc = q->retc = 0;
5076 1037 : q = pushArgumentId(mb, q, buf);
5077 1037 : pushInstruction(mb, q);
5078 1037 : q->retc++;
5079 : } else {
5080 379 : assert(sname); /* all global variables have a schema */
5081 379 : q = newStmt(mb, sqlRef, setVariableRef);
5082 379 : if (q == NULL)
5083 0 : goto bailout;
5084 379 : q = pushArgument(mb, q, be->mvc_var);
5085 379 : q = pushStr(mb, q, sname);
5086 379 : q = pushStr(mb, q, varname);
5087 379 : getArg(q, 0) = be->mvc_var = newTmpVariable(mb, TYPE_int);
5088 379 : pushInstruction(mb, q);
5089 379 : be->mvc_var = getDestVar(q);
5090 : }
5091 1416 : q = pushArgument(mb, q, val->nr);
5092 :
5093 1416 : bool enabled = be->mvc->sa->eb.enabled;
5094 1416 : be->mvc->sa->eb.enabled = false;
5095 1416 : stmt *s = stmt_create(be->mvc->sa, st_assign);
5096 1416 : be->mvc->sa->eb.enabled = enabled;
5097 1416 : if(!s) {
5098 0 : goto bailout;
5099 : }
5100 1416 : s->op2 = val;
5101 1416 : s->flag = (level << 1);
5102 1416 : s->q = q;
5103 1416 : s->nr = 1;
5104 1416 : return s;
5105 :
5106 0 : bailout:
5107 0 : if (be->mvc->sa->eb.enabled)
5108 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
5109 : return NULL;
5110 : }
5111 :
5112 : stmt *
5113 21622 : const_column(backend *be, stmt *val)
5114 : {
5115 21622 : sql_subtype *ct = tail_type(val);
5116 21622 : MalBlkPtr mb = be->mb;
5117 21622 : InstrPtr q = NULL;
5118 21622 : int tt = ct->type->localtype;
5119 :
5120 21622 : if (val->nr < 0)
5121 0 : goto bailout;
5122 21622 : q = newStmt(mb, batRef, singleRef);
5123 21622 : if (q == NULL)
5124 0 : goto bailout;
5125 21622 : setVarType(mb, getArg(q, 0), newBatType(tt));
5126 21622 : q = pushArgument(mb, q, val->nr);
5127 :
5128 21622 : bool enabled = be->mvc->sa->eb.enabled;
5129 21622 : be->mvc->sa->eb.enabled = false;
5130 21622 : stmt *s = stmt_create(be->mvc->sa, st_single);
5131 21622 : be->mvc->sa->eb.enabled = enabled;
5132 21622 : if(!s) {
5133 0 : freeInstruction(q);
5134 0 : goto bailout;
5135 : }
5136 21622 : s->op1 = val;
5137 21622 : s->op4.typeval = *ct;
5138 21622 : s->nrcols = 1;
5139 :
5140 21622 : s->tname = val->tname;
5141 21622 : s->cname = val->cname;
5142 21622 : s->nr = getDestVar(q);
5143 21622 : s->q = q;
5144 21622 : pushInstruction(mb, q);
5145 21622 : return s;
5146 :
5147 0 : bailout:
5148 0 : if (be->mvc->sa->eb.enabled)
5149 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
5150 : return NULL;
5151 : }
5152 :
5153 : stmt *
5154 10 : stmt_fetch(backend *be, stmt *val)
5155 : {
5156 10 : sql_subtype *ct;
5157 10 : MalBlkPtr mb = be->mb;
5158 10 : InstrPtr q = NULL;
5159 10 : int tt;
5160 :
5161 10 : if (val->nr < 0)
5162 0 : goto bailout;
5163 : /* pick from first column on a table case */
5164 10 : if (val->type == st_table) {
5165 0 : if (list_length(val->op1->op4.lval) > 1)
5166 0 : goto bailout;
5167 0 : val = val->op1->op4.lval->h->data;
5168 : }
5169 10 : ct = tail_type(val);
5170 10 : tt = ct->type->localtype;
5171 :
5172 10 : q = newStmt(mb, algebraRef, fetchRef);
5173 10 : if (q == NULL)
5174 0 : goto bailout;
5175 10 : setVarType(mb, getArg(q, 0), tt);
5176 10 : q = pushArgument(mb, q, val->nr);
5177 10 : q = pushOid(mb, q, 0);
5178 :
5179 10 : bool enabled = be->mvc->sa->eb.enabled;
5180 10 : be->mvc->sa->eb.enabled = false;
5181 10 : stmt *s = stmt_create(be->mvc->sa, st_single);
5182 10 : be->mvc->sa->eb.enabled = enabled;
5183 10 : if(!s) {
5184 0 : freeInstruction(q);
5185 0 : goto bailout;
5186 : }
5187 10 : s->op1 = val;
5188 10 : s->op4.typeval = *ct;
5189 10 : s->nrcols = 0;
5190 :
5191 10 : s->tname = val->tname;
5192 10 : s->cname = val->cname;
5193 10 : s->nr = getDestVar(q);
5194 10 : s->q = q;
5195 10 : pushInstruction(mb, q);
5196 10 : return s;
5197 :
5198 0 : bailout:
5199 0 : if (be->mvc->sa->eb.enabled)
5200 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
5201 : return NULL;
5202 : }
5203 :
5204 : stmt *
5205 1633008 : stmt_rename(backend *be, sql_exp *exp, stmt *s )
5206 : {
5207 1633008 : int label = exp_get_label(exp);
5208 1633015 : const char *name = exp_name(exp);
5209 1633335 : const char *rname = exp_relname(exp);
5210 1632905 : stmt *o = s;
5211 :
5212 1632905 : if (!name && exp_is_atom(exp))
5213 0 : name = sa_strdup(be->mvc->sa, "single_value");
5214 0 : assert(name);
5215 1632905 : s = stmt_alias(be, s, label, rname, name);
5216 1633031 : if (o->flag & OUTER_ZERO)
5217 521 : s->flag |= OUTER_ZERO;
5218 1633031 : return s;
5219 : }
|