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 18191 : convertMultiplexMod(const char *mod, const char *op)
31 : {
32 18191 : if (strcmp(op, "=") == 0)
33 0 : return "calc";
34 : return mod;
35 : }
36 :
37 : static const char *
38 260340 : convertMultiplexFcn(const char *op)
39 : {
40 260340 : if (strcmp(op, "=") == 0)
41 34648 : return "==";
42 : return op;
43 : }
44 :
45 : static InstrPtr
46 18114 : multiplex2(MalBlkPtr mb, const char *mod, const char *name, int o1, int o2, int rtype)
47 : {
48 18114 : InstrPtr q = NULL;
49 :
50 18114 : q = newStmt(mb, malRef, multiplexRef);
51 18114 : if (q == NULL)
52 : return NULL;
53 18114 : setVarType(mb, getArg(q, 0), newBatType(rtype));
54 18114 : q = pushStr(mb, q, convertMultiplexMod(mod, name));
55 18114 : q = pushStr(mb, q, convertMultiplexFcn(name));
56 18114 : q = pushArgument(mb, q, o1);
57 18114 : q = pushArgument(mb, q, o2);
58 18114 : pushInstruction(mb, q);
59 18114 : return q;
60 : }
61 :
62 : static InstrPtr
63 51554 : dump_1(MalBlkPtr mb, const char *mod, const char *name, stmt *o1)
64 : {
65 51554 : InstrPtr q = NULL;
66 :
67 51554 : if (o1 == NULL || o1->nr < 0)
68 : return NULL;
69 51554 : q = newStmt(mb, mod, name);
70 51554 : q = pushArgument(mb, q, o1->nr);
71 51554 : pushInstruction(mb, q);
72 51554 : return q;
73 : }
74 :
75 : static InstrPtr
76 181108 : dump_2(MalBlkPtr mb, const char *mod, const char *name, stmt *o1, stmt *o2)
77 : {
78 181108 : InstrPtr q = NULL;
79 :
80 181108 : if (o1 == NULL || o2 == NULL || o1->nr < 0 || o2->nr < 0)
81 : return NULL;
82 181108 : q = newStmt(mb, mod, name);
83 181108 : q = pushArgument(mb, q, o1->nr);
84 181108 : q = pushArgument(mb, q, o2->nr);
85 181108 : pushInstruction(mb, q);
86 181108 : 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 2206600 : pushSchema(MalBlkPtr mb, InstrPtr q, sql_table *t)
108 : {
109 2206600 : if (t->s)
110 2206600 : 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 19671 : stmt_atom_string_nil(backend *be)
138 : {
139 19671 : sql_subtype t;
140 :
141 19671 : sql_find_subtype(&t, "varchar", 0, 0);
142 19671 : return stmt_atom(be, atom_string(be->mvc->sa, &t, NULL));
143 : }
144 :
145 : stmt *
146 5886 : stmt_atom_int(backend *be, int i)
147 : {
148 5886 : sql_subtype t;
149 :
150 5886 : sql_find_subtype(&t, "int", 32, 0);
151 5886 : return stmt_atom(be, atom_int(be->mvc->sa, &t, i));
152 : }
153 :
154 : stmt *
155 117254 : stmt_atom_lng(backend *be, lng i)
156 : {
157 117254 : sql_subtype t;
158 :
159 117254 : sql_find_subtype(&t, "bigint", 64, 0);
160 117271 : 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 40619 : stmt_bool(backend *be, int b)
174 : {
175 40619 : sql_subtype t;
176 :
177 40619 : sql_find_subtype(&t, "boolean", 0, 0);
178 :
179 40619 : if (b == bit_nil) {
180 0 : return stmt_atom(be, atom_bool(be->mvc->sa, &t, bit_nil));
181 40619 : } else if (b) {
182 39490 : return stmt_atom(be, atom_bool(be->mvc->sa, &t, TRUE));
183 : } else {
184 1129 : return stmt_atom(be, atom_bool(be->mvc->sa, &t, FALSE));
185 : }
186 : }
187 :
188 : static stmt *
189 17882690 : stmt_create(allocator *sa, st_type type)
190 : {
191 17882690 : stmt *s = SA_NEW(sa, stmt);
192 :
193 17882272 : if (!s)
194 : return NULL;
195 17882272 : *s = (stmt) {
196 : .type = type,
197 : };
198 17882272 : return s;
199 : }
200 :
201 : stmt *
202 28196 : stmt_group(backend *be, stmt *s, stmt *grp, stmt *ext, stmt *cnt, int done)
203 : {
204 28196 : MalBlkPtr mb = be->mb;
205 28196 : InstrPtr q = NULL;
206 :
207 28196 : if (s == NULL || s->nr < 0)
208 0 : goto bailout;
209 28196 : if (grp && (grp->nr < 0 || ext->nr < 0 || cnt->nr < 0))
210 0 : goto bailout;
211 :
212 49972 : q = newStmt(mb, groupRef, done ? grp ? subgroupdoneRef : groupdoneRef : grp ? subgroupRef : groupRef);
213 28196 : if (q == NULL)
214 0 : goto bailout;
215 :
216 : /* output variables extent and hist */
217 28196 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
218 28196 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
219 28196 : q = pushArgument(mb, q, s->nr);
220 28196 : if (grp)
221 6420 : q = pushArgument(mb, q, grp->nr);
222 :
223 28196 : bool enabled = be->mvc->sa->eb.enabled;
224 28196 : be->mvc->sa->eb.enabled = false;
225 28196 : stmt *ns = stmt_create(be->mvc->sa, st_group);
226 28196 : be->mvc->sa->eb.enabled = enabled;
227 28196 : if (ns == NULL) {
228 0 : freeInstruction(q);
229 0 : goto bailout;
230 : }
231 :
232 28196 : ns->op1 = s;
233 :
234 28196 : if (grp) {
235 6420 : ns->op2 = grp;
236 6420 : ns->op3 = ext;
237 6420 : ns->op4.stval = cnt;
238 : }
239 28196 : ns->nrcols = s->nrcols;
240 28196 : ns->key = 0;
241 28196 : ns->q = q;
242 28196 : ns->nr = getDestVar(q);
243 28196 : pushInstruction(mb, q);
244 28196 : 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 114 : stmt_bat_new(backend *be, sql_subtype *tpe, lng estimate)
312 : {
313 114 : InstrPtr q = newStmt(be->mb, batRef, newRef);
314 114 : int tt = tpe->type->localtype;
315 :
316 114 : if (q == NULL)
317 : return NULL;
318 114 : if (tt == TYPE_void)
319 1 : tt = TYPE_bte;
320 114 : setVarType(be->mb, getArg(q, 0), newBatType(tt));
321 114 : q = pushType(be->mb, q, tt);
322 114 : if (estimate > 0)
323 0 : q = pushInt(be->mb, q, (int)estimate);
324 114 : pushInstruction(be->mb, q);
325 :
326 114 : stmt *s = stmt_create(be->mvc->sa, st_alias);
327 114 : s->op4.typeval = *tpe;
328 114 : s->q = q;
329 114 : s->nr = q->argv[0];
330 114 : s->nrcols = 2;
331 114 : 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 2774 : stmt_var(backend *be, const char *sname, const char *varname, sql_subtype *t, int declare, int level)
359 : {
360 2774 : MalBlkPtr mb = be->mb;
361 2774 : InstrPtr q = NULL;
362 2774 : char *buf;
363 :
364 2774 : 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 2343 : } else if (!declare) {
376 1954 : char levelstr[16];
377 :
378 1954 : assert(!sname);
379 1954 : snprintf(levelstr, sizeof(levelstr), "%d", level);
380 1954 : buf = SA_NEW_ARRAY(be->mvc->sa, char, strlen(levelstr) + strlen(varname) + 3);
381 1954 : if (!buf)
382 1 : goto bailout;
383 1954 : stpcpy(stpcpy(stpcpy(stpcpy(buf, "A"), levelstr), "%"), varname); /* mangle variable name */
384 1954 : q = newAssignment(mb);
385 1954 : if (q == NULL)
386 1 : goto bailout;
387 1953 : 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 2773 : bool enabled = be->mvc->sa->eb.enabled;
409 2773 : be->mvc->sa->eb.enabled = false;
410 2773 : stmt *s = stmt_create(be->mvc->sa, st_var);
411 2773 : be->mvc->sa->eb.enabled = enabled;
412 2773 : if (s == NULL) {
413 0 : freeInstruction(q);
414 0 : goto bailout;
415 : }
416 :
417 2773 : if (t)
418 2773 : s->op4.typeval = *t;
419 : else
420 0 : s->op4.typeval.type = NULL;
421 2773 : s->flag = declare + (level << 1);
422 2773 : s->key = 1;
423 2773 : s->q = q;
424 2773 : s->nr = getDestVar(q);
425 2773 : pushInstruction(mb, q);
426 2773 : 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 222348 : stmt_temp(backend *be, sql_subtype *t)
542 : {
543 222348 : int tt = t->type->localtype;
544 222348 : MalBlkPtr mb = be->mb;
545 222348 : InstrPtr q = newStmt(mb, batRef, newRef);
546 :
547 223121 : if (q == NULL)
548 0 : goto bailout;
549 223121 : setVarType(mb, getArg(q, 0), newBatType(tt));
550 223121 : q = pushType(mb, q, tt);
551 222954 : bool enabled = be->mvc->sa->eb.enabled;
552 222954 : be->mvc->sa->eb.enabled = false;
553 222954 : stmt *s = stmt_create(be->mvc->sa, st_temp);
554 222874 : be->mvc->sa->eb.enabled = enabled;
555 :
556 222874 : if (s == NULL) {
557 0 : freeInstruction(q);
558 0 : goto bailout;
559 : }
560 222874 : s->op4.typeval = *t;
561 222874 : s->nrcols = 1;
562 222874 : s->q = q;
563 222874 : s->nr = getDestVar(q);
564 222874 : pushInstruction(mb, q);
565 222874 : 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 204610 : stmt_tid(backend *be, sql_table *t, int partition)
592 : {
593 204610 : int tt = TYPE_oid;
594 204610 : MalBlkPtr mb = be->mb;
595 204610 : InstrPtr q;
596 :
597 204610 : 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 204594 : q = newStmt(mb, sqlRef, tidRef);
612 204734 : if (q == NULL)
613 0 : goto bailout;
614 204734 : setVarType(mb, getArg(q, 0), newBatType(tt));
615 204734 : q = pushArgument(mb, q, be->mvc_var);
616 204730 : q = pushSchema(mb, q, t);
617 204714 : q = pushStr(mb, q, t->base.name);
618 204717 : if (t && isTable(t) && partition) {
619 76496 : sql_trans *tr = be->mvc->session->tr;
620 76496 : sqlstore *store = tr->store;
621 76496 : BUN rows = (BUN) store->storage_api.count_col(tr, ol_first_node(t->columns)->data, RDONLY);
622 76498 : setRowCnt(mb,getArg(q,0),rows);
623 : }
624 :
625 204719 : bool enabled = be->mvc->sa->eb.enabled;
626 204719 : be->mvc->sa->eb.enabled = false;
627 204719 : stmt *s = stmt_create(be->mvc->sa, st_tid);
628 204585 : be->mvc->sa->eb.enabled = enabled;
629 204585 : if (s == NULL) {
630 0 : freeInstruction(q);
631 0 : goto bailout;
632 : }
633 :
634 204585 : s->partition = partition;
635 204585 : s->op4.tval = t;
636 204585 : s->nrcols = 1;
637 204585 : s->nr = getDestVar(q);
638 204585 : s->q = q;
639 204585 : pushInstruction(mb, q);
640 204585 : 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 999331 : find_real_column(backend *be, sql_column *c)
650 : {
651 999331 : if (c && c->t && c->t->s && c->t->persistence == SQL_DECLARED_TABLE) {
652 36780 : sql_table *nt = find_sql_table_id(be->mvc->session->tr, c->t->s, c->t->base.id);
653 36780 : if (nt) {
654 36780 : node *n = ol_find_id(nt->columns, c->base.id);
655 36780 : if (n)
656 36780 : return n->data;
657 : }
658 : }
659 : return c;
660 : }
661 :
662 : stmt *
663 999328 : stmt_bat(backend *be, sql_column *c, int access, int partition)
664 : {
665 999328 : int tt = c->type.type->localtype;
666 999328 : MalBlkPtr mb = be->mb;
667 999328 : InstrPtr q;
668 :
669 999328 : c = find_real_column(be, c);
670 :
671 999342 : if (access == RD_EXT)
672 176 : partition = 0;
673 :
674 : /* for read access tid.project(col) */
675 999342 : 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 999319 : q = newStmtArgs(mb, sqlRef, bindRef, 9);
693 999352 : if (q == NULL)
694 0 : goto bailout;
695 999352 : 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 999176 : if (access == RD_UPD_ID) {
706 485503 : q = pushReturn(mb, q, newTmpVariable(mb, newBatType(tt)));
707 : } else {
708 513849 : setVarType(mb, getArg(q, 0), newBatType(tt));
709 : }
710 999352 : q = pushArgument(mb, q, be->mvc_var);
711 999338 : q = pushSchema(mb, q, c->t);
712 999339 : q = pushArgument(mb, q, getStrConstant(mb,c->t->base.name));
713 999336 : q = pushArgument(mb, q, getStrConstant(mb,c->base.name));
714 999311 : q = pushArgument(mb, q, getIntConstant(mb,access));
715 :
716 999284 : if (access == RD_UPD_ID) {
717 485486 : setVarType(mb, getArg(q, 1), newBatType(tt));
718 : }
719 999284 : if (partition) {
720 552028 : sql_trans *tr = be->mvc->session->tr;
721 552028 : sqlstore *store = tr->store;
722 :
723 552028 : if (c && isTable(c->t)) {
724 552034 : BUN rows = (BUN) store->storage_api.count_col(tr, c, RDONLY);
725 552110 : setRowCnt(mb,getArg(q,0),rows);
726 : }
727 : }
728 :
729 999360 : bool enabled = be->mvc->sa->eb.enabled;
730 999360 : be->mvc->sa->eb.enabled = false;
731 999360 : stmt *s = stmt_create(be->mvc->sa, st_bat);
732 999355 : be->mvc->sa->eb.enabled = enabled;
733 999355 : if (s == NULL) {
734 0 : freeInstruction(q);
735 0 : goto bailout;
736 : }
737 :
738 999355 : s->partition = partition;
739 999355 : s->op4.cval = c;
740 999355 : s->nrcols = 1;
741 999355 : s->flag = access;
742 999355 : s->nr = getDestVar(q);
743 999355 : s->q = q;
744 999355 : s->tname = c->t->base.name;
745 999355 : s->cname = c->base.name;
746 999355 : pushInstruction(mb, q);
747 999355 : 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 675772 : stmt_append_col(backend *be, sql_column *c, stmt *offset, stmt *b, int *mvc_var_update, int fake)
818 : {
819 675772 : MalBlkPtr mb = be->mb;
820 675772 : InstrPtr q = NULL;
821 :
822 675772 : if (b == NULL || b->nr < 0)
823 0 : goto bailout;
824 :
825 675772 : 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 675749 : } else if (!fake) { /* fake append */
844 675749 : if (offset == NULL || offset->nr < 0)
845 0 : goto bailout;
846 675749 : q = newStmt(mb, sqlRef, appendRef);
847 676334 : if (q == NULL)
848 0 : goto bailout;
849 676334 : q = pushArgument(mb, q, be->mvc_var);
850 676329 : int tmpvar = newTmpVariable(mb, TYPE_int);
851 676332 : getArg(q, 0) = tmpvar;
852 676332 : if (mvc_var_update != NULL)
853 676332 : *mvc_var_update = tmpvar;
854 676332 : q = pushSchema(mb, q, c->t);
855 676279 : q = pushStr(mb, q, c->t->base.name);
856 676304 : q = pushStr(mb, q, c->base.name);
857 676171 : q = pushArgument(mb, q, offset->nr);
858 : /* also the offsets */
859 676217 : assert(offset->q->retc == 2);
860 676217 : q = pushArgument(mb, q, getArg(offset->q, 1));
861 676213 : q = pushArgument(mb, q, b->nr);
862 676207 : if (mvc_var_update != NULL)
863 676207 : *mvc_var_update = getDestVar(q);
864 : } else {
865 : return b;
866 : }
867 676230 : bool enabled = be->mvc->sa->eb.enabled;
868 676230 : be->mvc->sa->eb.enabled = false;
869 676230 : stmt *s = stmt_create(be->mvc->sa, st_append_col);
870 676045 : be->mvc->sa->eb.enabled = enabled;
871 :
872 676045 : if (s == NULL) {
873 0 : freeInstruction(q);
874 0 : goto bailout;
875 : }
876 676045 : s->op1 = b;
877 676045 : s->op2 = offset;
878 676045 : s->op4.cval = c;
879 676045 : s->q = q;
880 676045 : s->nr = getDestVar(q);
881 676045 : pushInstruction(mb, q);
882 676045 : 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 3195 : stmt_update_col(backend *be, sql_column *c, stmt *tids, stmt *upd)
939 : {
940 3195 : MalBlkPtr mb = be->mb;
941 3195 : InstrPtr q = NULL;
942 :
943 3195 : if (tids == NULL || upd == NULL || tids->nr < 0 || upd->nr < 0)
944 0 : goto bailout;
945 :
946 3196 : 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 3194 : q = newStmt(mb, sqlRef, updateRef);
957 3194 : if (q == NULL)
958 0 : goto bailout;
959 3194 : q = pushArgument(mb, q, be->mvc_var);
960 3194 : getArg(q, 0) = be->mvc_var = newTmpVariable(mb, TYPE_int);
961 3194 : q = pushSchema(mb, q, c->t);
962 3194 : q = pushStr(mb, q, c->t->base.name);
963 3194 : q = pushStr(mb, q, c->base.name);
964 3194 : q = pushArgument(mb, q, tids->nr);
965 3194 : q = pushArgument(mb, q, upd->nr);
966 3194 : be->mvc_var = getDestVar(q);
967 : }
968 3195 : bool enabled = be->mvc->sa->eb.enabled;
969 3195 : be->mvc->sa->eb.enabled = false;
970 3195 : stmt *s = stmt_create(be->mvc->sa, st_update_col);
971 3195 : be->mvc->sa->eb.enabled = enabled;
972 :
973 3195 : if (s == NULL) {
974 0 : freeInstruction(q);
975 0 : goto bailout;
976 : }
977 3195 : s->op1 = tids;
978 3195 : s->op2 = upd;
979 3195 : s->op4.cval = c;
980 3195 : s->q = q;
981 3195 : s->nr = getDestVar(q);
982 3195 : pushInstruction(mb, q);
983 3195 : 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 124495 : stmt_const(backend *be, stmt *s, stmt *val)
1087 : {
1088 124495 : InstrPtr q = NULL;
1089 124495 : MalBlkPtr mb = be->mb;
1090 :
1091 124495 : if (s == NULL)
1092 0 : goto bailout;
1093 124495 : if (val)
1094 124495 : q = dump_2(mb, algebraRef, projectRef, s, val);
1095 : else
1096 0 : q = dump_1(mb, algebraRef, projectRef, s);
1097 124495 : if (q) {
1098 124495 : stmt *ns = stmt_create(be->mvc->sa, st_const);
1099 124495 : if (ns == NULL) {
1100 0 : goto bailout;
1101 : }
1102 :
1103 124495 : ns->op1 = s;
1104 124495 : ns->op2 = val;
1105 124495 : ns->nrcols = s->nrcols;
1106 124495 : ns->key = s->key;
1107 124495 : ns->aggr = s->aggr;
1108 124495 : ns->q = q;
1109 124495 : ns->nr = getDestVar(q);
1110 124495 : ns->tname = val->tname;
1111 124495 : ns->cname = val->cname;
1112 124495 : 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 51554 : stmt_mirror(backend *be, stmt *s)
1154 : {
1155 51554 : MalBlkPtr mb = be->mb;
1156 :
1157 51554 : if (s == NULL)
1158 0 : goto bailout;
1159 :
1160 51554 : InstrPtr q = dump_1(mb, batRef, mirrorRef, s);
1161 :
1162 51554 : if (q) {
1163 51554 : stmt *ns = stmt_create(be->mvc->sa, st_mirror);
1164 51554 : if (ns == NULL) {
1165 0 : goto bailout;
1166 : }
1167 :
1168 51554 : ns->op1 = s;
1169 51554 : ns->nrcols = 2;
1170 51554 : ns->key = s->key;
1171 51554 : ns->aggr = s->aggr;
1172 51554 : ns->q = q;
1173 51554 : ns->nr = getDestVar(q);
1174 51554 : 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 322742 : stmt_result(backend *be, stmt *s, int nr)
1185 : {
1186 322742 : stmt *ns;
1187 :
1188 322742 : if (s == NULL)
1189 : return NULL;
1190 :
1191 322742 : if (s->type == st_join && s->flag == cmp_joined) {
1192 5545 : if (nr)
1193 2322 : return s->op2;
1194 3223 : return s->op1;
1195 : }
1196 :
1197 317197 : if (s->op1->nr < 0)
1198 : return NULL;
1199 :
1200 317197 : ns = stmt_create(be->mvc->sa, st_result);
1201 317197 : if(!ns) {
1202 : return NULL;
1203 : }
1204 317197 : if (s->op1->type == st_join && s->op1->flag == cmp_joined) {
1205 0 : assert(0);
1206 317197 : } else if (nr) {
1207 181401 : int v = getArg(s->q, nr);
1208 :
1209 181401 : assert(s->q->retc > nr);
1210 181401 : ns->nr = v;
1211 : } else {
1212 135796 : ns->nr = s->nr;
1213 : }
1214 317197 : ns->op1 = s;
1215 317197 : if (!nr && (s->type == st_order || s->type == st_reorder))
1216 23839 : ns->op4.typeval = *tail_type(s->op1);
1217 181401 : else if (nr && ((s->type == st_join && s->flag == MARKJOIN) || (s->type == st_uselect2 && s->flag == MARKJOIN)))
1218 2967 : ns->op4.typeval = *sql_bind_localtype("bit");
1219 : else
1220 290391 : ns->op4.typeval = *sql_bind_localtype("oid");
1221 317197 : ns->flag = nr;
1222 317197 : ns->nrcols = s->nrcols;
1223 317197 : ns->key = s->key;
1224 317197 : ns->aggr = s->aggr;
1225 317197 : return ns;
1226 : }
1227 :
1228 :
1229 : /* limit maybe atom nil */
1230 : stmt *
1231 17294 : 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 17294 : MalBlkPtr mb = be->mb;
1234 17294 : InstrPtr q = NULL;
1235 17294 : int l, g, c;
1236 :
1237 17294 : if (col == NULL || offset == NULL || limit == NULL || col->nr < 0 || offset->nr < 0 || limit->nr < 0)
1238 0 : goto bailout;
1239 17294 : if (piv && (piv->nr < 0 || (gid && gid->nr < 0)))
1240 0 : goto bailout;
1241 :
1242 17294 : c = (col) ? col->nr : 0;
1243 17294 : g = (gid) ? gid->nr : 0;
1244 :
1245 : /* first insert single value into a bat */
1246 17294 : 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 17294 : 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 16704 : int len;
1329 :
1330 16704 : q = newStmt(mb, calcRef, plusRef);
1331 16730 : if (q == NULL)
1332 0 : goto bailout;
1333 16730 : q = pushArgument(mb, q, offset->nr);
1334 16729 : q = pushArgument(mb, q, limit->nr);
1335 16729 : len = getDestVar(q);
1336 16729 : pushInstruction(mb, q);
1337 :
1338 : /* since both arguments of algebra.subslice are
1339 : inclusive correct the LIMIT value by
1340 : subtracting 1 */
1341 16730 : q = newStmt(mb, calcRef, minusRef);
1342 16730 : if (q == NULL)
1343 0 : goto bailout;
1344 16730 : q = pushArgument(mb, q, len);
1345 16730 : q = pushInt(mb, q, 1);
1346 16729 : len = getDestVar(q);
1347 16729 : pushInstruction(mb, q);
1348 :
1349 16729 : q = newStmt(mb, algebraRef, subsliceRef);
1350 16730 : if (q == NULL)
1351 0 : goto bailout;
1352 16730 : q = pushArgument(mb, q, c);
1353 16730 : q = pushArgument(mb, q, offset->nr);
1354 16730 : q = pushArgument(mb, q, len);
1355 16730 : l = getDestVar(q);
1356 16730 : pushInstruction(mb, q);
1357 : }
1358 : /* retrieve the single values again */
1359 17320 : 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 34330 : stmt *ns = stmt_create(be->mvc->sa, piv?st_limit2:st_limit);
1370 17320 : if (ns == NULL) {
1371 0 : goto bailout;
1372 : }
1373 :
1374 17320 : ns->op1 = col;
1375 17320 : ns->op2 = offset;
1376 17320 : ns->op3 = limit;
1377 17320 : ns->nrcols = col->nrcols;
1378 17320 : ns->key = col->key;
1379 17320 : ns->aggr = col->aggr;
1380 17320 : ns->q = q;
1381 17320 : ns->nr = l;
1382 17320 : 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 10538 : stmt_order(backend *be, stmt *s, int direction, int nullslast)
1445 : {
1446 10538 : MalBlkPtr mb = be->mb;
1447 10538 : InstrPtr q = NULL;
1448 :
1449 10538 : if (s == NULL || s->nr < 0)
1450 0 : goto bailout;
1451 10538 : q = newStmt(mb, algebraRef, sortRef);
1452 10538 : if (q == NULL)
1453 0 : goto bailout;
1454 : /* both ordered result and oid's order en subgroups */
1455 10538 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
1456 10538 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
1457 10538 : q = pushArgument(mb, q, s->nr);
1458 10538 : q = pushBit(mb, q, !direction);
1459 10538 : q = pushBit(mb, q, nullslast);
1460 10538 : q = pushBit(mb, q, FALSE);
1461 :
1462 10538 : bool enabled = be->mvc->sa->eb.enabled;
1463 10538 : be->mvc->sa->eb.enabled = false;
1464 10538 : stmt *ns = stmt_create(be->mvc->sa, st_order);
1465 10538 : be->mvc->sa->eb.enabled = enabled;
1466 10538 : if (ns == NULL) {
1467 0 : freeInstruction(q);
1468 0 : goto bailout;
1469 : }
1470 :
1471 10538 : ns->op1 = s;
1472 10538 : ns->flag = direction;
1473 10538 : ns->nrcols = s->nrcols;
1474 10538 : ns->key = s->key;
1475 10538 : ns->aggr = s->aggr;
1476 10538 : ns->q = q;
1477 10538 : ns->nr = getDestVar(q);
1478 10538 : pushInstruction(mb, q);
1479 10538 : 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 13816 : stmt_reorder(backend *be, stmt *s, int direction, int nullslast, stmt *orderby_ids, stmt *orderby_grp)
1489 : {
1490 13816 : MalBlkPtr mb = be->mb;
1491 13816 : InstrPtr q = NULL;
1492 :
1493 13816 : 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 13816 : q = newStmtArgs(mb, algebraRef, sortRef, 9);
1496 13816 : if (q == NULL)
1497 0 : goto bailout;
1498 : /* both ordered result and oid's order en subgroups */
1499 13816 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
1500 13816 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
1501 13816 : q = pushArgument(mb, q, s->nr);
1502 13816 : q = pushArgument(mb, q, orderby_ids->nr);
1503 13816 : q = pushArgument(mb, q, orderby_grp->nr);
1504 13816 : q = pushBit(mb, q, !direction);
1505 13816 : q = pushBit(mb, q, nullslast);
1506 13816 : q = pushBit(mb, q, FALSE);
1507 :
1508 13816 : bool enabled = be->mvc->sa->eb.enabled;
1509 13816 : be->mvc->sa->eb.enabled = false;
1510 13816 : stmt *ns = stmt_create(be->mvc->sa, st_reorder);
1511 13816 : be->mvc->sa->eb.enabled = enabled;
1512 13816 : if (ns == NULL) {
1513 0 : freeInstruction(q);
1514 0 : goto bailout;
1515 : }
1516 :
1517 13816 : ns->op1 = s;
1518 13816 : ns->op2 = orderby_ids;
1519 13816 : ns->op3 = orderby_grp;
1520 13816 : ns->flag = direction;
1521 13816 : ns->nrcols = s->nrcols;
1522 13816 : ns->key = s->key;
1523 13816 : ns->aggr = s->aggr;
1524 13816 : ns->nr = getDestVar(q);
1525 13816 : ns->q = q;
1526 13816 : pushInstruction(mb, q);
1527 13816 : 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 3429639 : stmt_atom(backend *be, atom *a)
1537 : {
1538 3429639 : MalBlkPtr mb = be->mb;
1539 :
1540 3429639 : if (a == NULL)
1541 0 : goto bailout;
1542 :
1543 3429639 : InstrPtr q = EC_TEMP_FRAC(atom_type(a)->type->eclass) ? newStmt(mb, calcRef, atom_type(a)->type->impl) : newAssignment(mb);
1544 :
1545 3430821 : if (q == NULL)
1546 0 : goto bailout;
1547 3430821 : if (atom_null(a)) {
1548 151904 : q = pushNil(mb, q, atom_type(a)->type->localtype);
1549 : } else {
1550 3278917 : int k;
1551 3278917 : if ((k = constantAtom(be, mb, a)) == -1) {
1552 0 : freeInstruction(q);
1553 0 : goto bailout;
1554 : }
1555 3278131 : q = pushArgument(mb, q, k);
1556 : }
1557 : /* digits of the result timestamp/daytime */
1558 3429765 : if (EC_TEMP_FRAC(atom_type(a)->type->eclass))
1559 47316 : q = pushInt(mb, q, atom_type(a)->digits);
1560 3430269 : bool enabled = be->mvc->sa->eb.enabled;
1561 3430269 : be->mvc->sa->eb.enabled = false;
1562 3430269 : stmt *s = stmt_create(be->mvc->sa, st_atom);
1563 3429776 : be->mvc->sa->eb.enabled = enabled;
1564 3429776 : if (s == NULL) {
1565 0 : freeInstruction(q);
1566 0 : goto bailout;
1567 : }
1568 :
1569 3429776 : s->op4.aval = a;
1570 3429776 : s->key = 1; /* values are also unique */
1571 3429776 : s->q = q;
1572 3429776 : s->nr = getDestVar(q);
1573 3429776 : pushInstruction(mb, q);
1574 3429776 : 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 3618 : stmt_genselect(backend *be, stmt *lops, stmt *rops, sql_subfunc *f, stmt *sub, int anti)
1584 : {
1585 3618 : MalBlkPtr mb = be->mb;
1586 3618 : InstrPtr q = NULL;
1587 3618 : const char *mod, *op;
1588 3618 : node *n;
1589 3618 : int k;
1590 :
1591 3618 : if (lops == NULL || rops == NULL)
1592 0 : goto bailout;
1593 :
1594 3618 : if (backend_create_subfunc(be, f, NULL) < 0)
1595 0 : goto bailout;
1596 3618 : op = backend_function_imp(be, f->func);
1597 3618 : mod = sql_func_mod(f->func);
1598 :
1599 3618 : 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 3562 : node *n;
1639 :
1640 3562 : op = sa_strconcat(be->mvc->sa, op, selectRef);
1641 3562 : q = newStmtArgs(mb, mod, convertMultiplexFcn(op), 9);
1642 3562 : 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 3562 : 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 3562 : if (f->func->lang == FUNC_LANG_R || f->func->lang >= FUNC_LANG_PY)
1650 0 : q = pushStr(mb, q, f->func->query);
1651 :
1652 7124 : for (n = lops->op4.lval->h; n; n = n->next) {
1653 3562 : stmt *op = n->data;
1654 :
1655 3562 : q = pushArgument(mb, q, op->nr);
1656 : }
1657 : /* candidate lists */
1658 3562 : if (sub)
1659 3493 : q = pushArgument(mb, q, sub->nr);
1660 : else
1661 69 : q = pushNilBat(mb, q);
1662 :
1663 14001 : for (n = rops->op4.lval->h; n; n = n->next) {
1664 10439 : stmt *op = n->data;
1665 :
1666 10439 : q = pushArgument(mb, q, op->nr);
1667 : }
1668 :
1669 3562 : q = pushBit(mb, q, anti);
1670 : }
1671 :
1672 3618 : bool enabled = be->mvc->sa->eb.enabled;
1673 3618 : be->mvc->sa->eb.enabled = false;
1674 3618 : stmt *s = stmt_create(be->mvc->sa, st_uselect);
1675 3618 : be->mvc->sa->eb.enabled = enabled;
1676 3618 : if (s == NULL) {
1677 0 : freeInstruction(q);
1678 0 : goto bailout;
1679 : }
1680 :
1681 3618 : s->op1 = lops;
1682 3618 : s->op2 = rops;
1683 3618 : s->op3 = sub;
1684 3618 : s->key = lops->nrcols == 0 && rops->nrcols == 0;
1685 3618 : s->flag = cmp_filter;
1686 3618 : s->nrcols = lops->nrcols;
1687 3618 : s->nr = getDestVar(q);
1688 3618 : s->q = q;
1689 3618 : s->cand = sub;
1690 3618 : pushInstruction(mb, q);
1691 3618 : 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 216735 : stmt_uselect(backend *be, stmt *op1, stmt *op2, comp_type cmptype, stmt *sub, int anti, int is_semantics)
1701 : {
1702 216735 : MalBlkPtr mb = be->mb;
1703 216735 : InstrPtr q = NULL;
1704 216735 : int l, r;
1705 216735 : stmt *sel = sub;
1706 :
1707 216735 : if (op1 == NULL || op2 == NULL || op1->nr < 0 || op2->nr < 0 || (sub && sub->nr < 0))
1708 0 : goto bailout;
1709 216735 : l = op1->nr;
1710 216735 : r = op2->nr;
1711 :
1712 216735 : 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 216735 : if (op2->nrcols >= 1) {
1722 18114 : bit need_not = FALSE;
1723 18114 : const char *mod = calcRef;
1724 18114 : const char *op = "=";
1725 18114 : int k;
1726 :
1727 18114 : switch (cmptype) {
1728 : case cmp_equal:
1729 : op = "=";
1730 : break;
1731 : case cmp_notequal:
1732 18114 : op = "!=";
1733 : break;
1734 919 : case cmp_lt:
1735 919 : op = "<";
1736 919 : 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 28636 : if ((q = multiplex2(mb, mod, convertMultiplexFcn(op), l, r, TYPE_bit)) == NULL)
1751 0 : goto bailout;
1752 18114 : 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 18114 : if (is_semantics)
1765 2986 : q = pushBit(mb, q, TRUE);
1766 18114 : k = getDestVar(q);
1767 :
1768 18114 : q = newStmtArgs(mb, algebraRef, selectRef, 9);
1769 18114 : if (q == NULL)
1770 0 : goto bailout;
1771 18114 : q = pushArgument(mb, q, k);
1772 18114 : if (sub)
1773 4363 : q = pushArgument(mb, q, sub->nr);
1774 18114 : q = pushBit(mb, q, !need_not);
1775 18114 : q = pushBit(mb, q, !need_not);
1776 18114 : q = pushBit(mb, q, TRUE);
1777 18114 : q = pushBit(mb, q, TRUE);
1778 18114 : q = pushBit(mb, q, anti);
1779 18114 : k = getDestVar(q);
1780 : } else {
1781 198621 : assert (cmptype != cmp_filter);
1782 198621 : q = newStmt(mb, algebraRef, thetaselectRef);
1783 198622 : if (q == NULL)
1784 0 : goto bailout;
1785 198622 : q = pushArgument(mb, q, l);
1786 198622 : if (sub && !op1->cand) {
1787 129706 : q = pushArgument(mb, q, sub->nr);
1788 : } else {
1789 630 : assert(!sub || op1->cand == sub);
1790 68916 : q = pushNilBat(mb, q);
1791 68916 : sub = NULL;
1792 : }
1793 198621 : q = pushArgument(mb, q, r);
1794 198616 : switch (cmptype) {
1795 162707 : case cmp_equal:
1796 162707 : if (is_semantics)
1797 34899 : q = pushStr(mb, q, anti?"ne":"eq");
1798 : else
1799 285462 : q = pushStr(mb, q, anti?"!=":"==");
1800 : break;
1801 32831 : case cmp_notequal:
1802 32831 : if (is_semantics)
1803 150 : q = pushStr(mb, q, anti?"eq":"ne");
1804 : else
1805 65512 : q = pushStr(mb, q, anti?"==":"!=");
1806 : break;
1807 434 : case cmp_lt:
1808 434 : q = pushStr(mb, q, anti?">=":"<");
1809 434 : break;
1810 74 : case cmp_lte:
1811 74 : q = pushStr(mb, q, anti?">":"<=");
1812 74 : break;
1813 2291 : case cmp_gt:
1814 2291 : q = pushStr(mb, q, anti?"<=":">");
1815 2291 : 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 216735 : bool enabled = be->mvc->sa->eb.enabled;
1829 216735 : be->mvc->sa->eb.enabled = false;
1830 216735 : stmt *s = stmt_create(be->mvc->sa, st_uselect);
1831 216733 : be->mvc->sa->eb.enabled = enabled;
1832 216733 : if (s == NULL) {
1833 0 : freeInstruction(q);
1834 0 : goto bailout;
1835 : }
1836 :
1837 216733 : s->op1 = op1;
1838 216733 : s->op2 = op2;
1839 216733 : s->op3 = sub;
1840 216733 : s->flag = cmptype;
1841 216733 : s->key = op1->nrcols == 0 && op2->nrcols == 0;
1842 216733 : s->nrcols = op1->nrcols;
1843 216733 : s->nr = getDestVar(q);
1844 216733 : s->q = q;
1845 216733 : s->cand = sub;
1846 216733 : pushInstruction(mb, q);
1847 216735 : 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 5109 : 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 5109 : MalBlkPtr mb = be->mb;
1909 5109 : InstrPtr p, q;
1910 5109 : int l;
1911 5109 : const char *cmd = (type == st_uselect2) ? selectRef : rangejoinRef;
1912 5109 : stmt *sub = (Sub)?*Sub:NULL;
1913 :
1914 5109 : if (op1 == NULL || op2 == NULL || op3 == NULL || op1->nr < 0 || (sub && sub->nr < 0))
1915 0 : goto bailout;
1916 5109 : l = op1->nr;
1917 8481 : if ((symmetric || op2->nrcols > 0 || op3->nrcols > 0 || !reduce) && (type == st_uselect2)) {
1918 3601 : int k;
1919 3601 : int nrcols = (op1->nrcols || op2->nrcols || op3->nrcols);
1920 :
1921 3601 : if (op2->nr < 0 || op3->nr < 0)
1922 0 : goto bailout;
1923 :
1924 3601 : if (nrcols)
1925 3560 : p = newStmtArgs(mb, batcalcRef, betweenRef, 12);
1926 : else
1927 41 : p = newStmtArgs(mb, calcRef, betweenRef, 9);
1928 3601 : if (p == NULL)
1929 0 : goto bailout;
1930 3601 : p = pushArgument(mb, p, l);
1931 3601 : p = pushArgument(mb, p, op2->nr);
1932 3601 : p = pushArgument(mb, p, op3->nr);
1933 :
1934 : /* cands */
1935 3601 : 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 3601 : p = pushBit(mb, p, (symmetric)?TRUE:FALSE); /* symmetric */
1956 3601 : p = pushBit(mb, p, (cmp & 1) != 0); /* lo inclusive */
1957 3601 : p = pushBit(mb, p, (cmp & 2) != 0); /* hi inclusive */
1958 3601 : p = pushBit(mb, p, FALSE); /* nils_false */
1959 3601 : p = pushBit(mb, p, (anti)?TRUE:FALSE); /* anti */
1960 3601 : pushInstruction(mb, p);
1961 3601 : 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 402 : stmt_markselect(backend *be, stmt *g, stmt *m, stmt *p, bool any)
2117 : {
2118 402 : MalBlkPtr mb = be->mb;
2119 402 : InstrPtr q;
2120 :
2121 402 : q = newStmtArgs(mb, algebraRef, markselectRef, 6);
2122 402 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
2123 402 : q = pushArgument(mb, q, g->nr); /* left ids */
2124 402 : q = pushArgument(mb, q, m->nr); /* mark info mask */
2125 402 : q = pushArgument(mb, q, p->nr); /* predicate */
2126 402 : q = pushBit(mb, q, (any)?TRUE:FALSE);
2127 402 : pushInstruction(mb, q);
2128 :
2129 402 : if (!q)
2130 : return NULL;
2131 402 : stmt *s = stmt_create(be->mvc->sa, st_uselect2);
2132 402 : if (s == NULL) {
2133 0 : freeInstruction(q);
2134 0 : return NULL;
2135 : }
2136 :
2137 402 : s->op1 = g;
2138 402 : s->op2 = m;
2139 402 : s->flag = MARKJOIN;
2140 402 : s->key = 0;
2141 402 : s->nrcols = g->nrcols;
2142 402 : s->nr = getDestVar(q);
2143 402 : s->q = q;
2144 402 : return s;
2145 : }
2146 :
2147 : stmt *
2148 2522 : stmt_markjoin(backend *be, stmt *l, stmt *r, bool final)
2149 : {
2150 2522 : MalBlkPtr mb = be->mb;
2151 2522 : InstrPtr q;
2152 :
2153 2522 : q = newStmtArgs(mb, algebraRef, markjoinRef, 8);
2154 2522 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
2155 2522 : if (!final)
2156 5 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
2157 2522 : q = pushArgument(mb, q, l->nr); /* left ids */
2158 2522 : q = pushArgument(mb, q, r->nr); /* mark info mask */
2159 2522 : q = pushNilBat(mb, q);
2160 2522 : q = pushNilBat(mb, q);
2161 2522 : q = pushNil(mb, q, TYPE_lng);
2162 2522 : pushInstruction(mb, q);
2163 :
2164 2522 : if (!q)
2165 : return NULL;
2166 2522 : stmt *s = stmt_create(be->mvc->sa, st_join);
2167 2522 : if (s == NULL) {
2168 0 : freeInstruction(q);
2169 0 : return NULL;
2170 : }
2171 :
2172 2522 : s->op1 = l;
2173 2522 : s->op2 = r;
2174 2522 : s->flag = MARKJOIN;
2175 2522 : s->key = 0;
2176 2522 : s->nrcols = l->nrcols;
2177 2522 : s->nr = getDestVar(q);
2178 2522 : s->q = q;
2179 2522 : return s;
2180 : }
2181 :
2182 : stmt *
2183 5055 : stmt_uselect2(backend *be, stmt *op1, stmt *op2, stmt *op3, int cmp, stmt *sub, int anti, int symmetric, int reduce)
2184 : {
2185 5055 : stmt *sel = sub;
2186 5055 : InstrPtr q = select2_join2(be, op1, op2, op3, cmp, &sub, anti, symmetric, 0, st_uselect2, reduce);
2187 :
2188 5055 : if (q == NULL)
2189 : return NULL;
2190 :
2191 5055 : stmt *s = stmt_create(be->mvc->sa, st_uselect2);
2192 5055 : if (s == NULL) {
2193 : return NULL;
2194 : }
2195 :
2196 5055 : s->op1 = op1;
2197 5055 : s->op2 = op2;
2198 5055 : s->op3 = op3;
2199 5055 : s->op4.stval = sub;
2200 5055 : s->flag = cmp;
2201 5055 : s->nrcols = op1->nrcols;
2202 5055 : s->key = op1->nrcols == 0 && op2->nrcols == 0 && op3->nrcols == 0;
2203 5055 : s->nr = getDestVar(q);
2204 5055 : s->q = q;
2205 5055 : s->cand = sub;
2206 5055 : s->reduce = reduce;
2207 5055 : if (!sub && sel) /* project back the old ids */
2208 1458 : return stmt_project(be, s, sel);
2209 : return s;
2210 : }
2211 :
2212 : stmt *
2213 54213 : stmt_tunion(backend *be, stmt *op1, stmt *op2)
2214 : {
2215 54213 : InstrPtr q = NULL;
2216 54213 : MalBlkPtr mb = be->mb;
2217 :
2218 54213 : q = dump_2(mb, batRef, mergecandRef, op1, op2);
2219 54213 : if (q) {
2220 54213 : stmt *s = stmt_create(be->mvc->sa, st_tunion);
2221 54213 : if (s == NULL) {
2222 : return NULL;
2223 : }
2224 :
2225 54213 : s->op1 = op1;
2226 54213 : s->op2 = op2;
2227 54213 : s->nrcols = op1->nrcols;
2228 54213 : s->key = op1->key;
2229 54213 : s->aggr = op1->aggr;
2230 54213 : s->nr = getDestVar(q);
2231 54213 : s->q = q;
2232 54213 : 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 44835 : stmt_tdiff(backend *be, stmt *op1, stmt *op2, stmt *lcand)
2242 : {
2243 44835 : InstrPtr q = NULL;
2244 44835 : MalBlkPtr mb = be->mb;
2245 :
2246 44835 : if (op1 == NULL || op2 == NULL || op1->nr < 0 || op2->nr < 0)
2247 0 : goto bailout;
2248 44835 : q = newStmt(mb, algebraRef, differenceRef);
2249 44835 : if (q == NULL)
2250 0 : goto bailout;
2251 44835 : q = pushArgument(mb, q, op1->nr); /* left */
2252 44835 : q = pushArgument(mb, q, op2->nr); /* right */
2253 44835 : if (lcand)
2254 0 : q = pushArgument(mb, q, lcand->nr); /* left */
2255 : else
2256 44835 : q = pushNilBat(mb, q); /* left candidate */
2257 44835 : q = pushNilBat(mb, q); /* right candidate */
2258 44835 : q = pushBit(mb, q, FALSE); /* nil matches */
2259 44835 : q = pushBit(mb, q, FALSE); /* do not clear nils */
2260 44835 : q = pushNil(mb, q, TYPE_lng); /* estimate */
2261 :
2262 44835 : bool enabled = be->mvc->sa->eb.enabled;
2263 44835 : be->mvc->sa->eb.enabled = false;
2264 44835 : stmt *s = stmt_create(be->mvc->sa, st_tdiff);
2265 44835 : be->mvc->sa->eb.enabled = enabled;
2266 44835 : if (s == NULL) {
2267 0 : freeInstruction(q);
2268 0 : goto bailout;
2269 : }
2270 :
2271 44835 : s->op1 = op1;
2272 44835 : s->op2 = op2;
2273 44835 : s->nrcols = op1->nrcols;
2274 44835 : s->key = op1->key;
2275 44835 : s->aggr = op1->aggr;
2276 44835 : s->nr = getDestVar(q);
2277 44835 : s->q = q;
2278 44835 : pushInstruction(mb, q);
2279 44835 : 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 1377 : stmt_tdiff2(backend *be, stmt *op1, stmt *op2, stmt *lcand)
2289 : {
2290 1377 : InstrPtr q = NULL;
2291 1377 : MalBlkPtr mb = be->mb;
2292 :
2293 1377 : if (op1 == NULL || op2 == NULL || op1->nr < 0 || op2->nr < 0)
2294 0 : goto bailout;
2295 1377 : q = newStmt(mb, algebraRef, differenceRef);
2296 1377 : if (q == NULL)
2297 0 : goto bailout;
2298 1377 : q = pushArgument(mb, q, op1->nr); /* left */
2299 1377 : q = pushArgument(mb, q, op2->nr); /* right */
2300 1377 : if (lcand)
2301 0 : q = pushArgument(mb, q, lcand->nr); /* left */
2302 : else
2303 1377 : q = pushNilBat(mb, q); /* left candidate */
2304 1377 : q = pushNilBat(mb, q); /* right candidate */
2305 1377 : q = pushBit(mb, q, FALSE); /* nil matches */
2306 1377 : q = pushBit(mb, q, TRUE); /* not in */
2307 1377 : q = pushNil(mb, q, TYPE_lng); /* estimate */
2308 :
2309 1377 : bool enabled = be->mvc->sa->eb.enabled;
2310 1377 : be->mvc->sa->eb.enabled = false;
2311 1377 : stmt *s = stmt_create(be->mvc->sa, st_tdiff);
2312 1377 : be->mvc->sa->eb.enabled = enabled;
2313 1377 : if (s == NULL) {
2314 0 : freeInstruction(q);
2315 0 : goto bailout;
2316 : }
2317 :
2318 1377 : s->op1 = op1;
2319 1377 : s->op2 = op2;
2320 1377 : s->nrcols = op1->nrcols;
2321 1377 : s->key = op1->key;
2322 1377 : s->aggr = op1->aggr;
2323 1377 : s->nr = getDestVar(q);
2324 1377 : s->q = q;
2325 1377 : pushInstruction(mb, q);
2326 1377 : 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 2106 : stmt_tinter(backend *be, stmt *op1, stmt *op2, bool single)
2336 : {
2337 2106 : InstrPtr q = NULL;
2338 2106 : MalBlkPtr mb = be->mb;
2339 :
2340 2106 : if (op1 == NULL || op2 == NULL || op1->nr < 0 || op2->nr < 0)
2341 0 : goto bailout;
2342 2106 : q = newStmt(mb, algebraRef, intersectRef);
2343 2106 : if (q == NULL)
2344 0 : goto bailout;
2345 2106 : q = pushArgument(mb, q, op1->nr); /* left */
2346 2106 : q = pushArgument(mb, q, op2->nr); /* right */
2347 2106 : q = pushNilBat(mb, q); /* left candidate */
2348 2106 : q = pushNilBat(mb, q); /* right candidate */
2349 2106 : q = pushBit(mb, q, FALSE); /* nil matches */
2350 2106 : q = pushBit(mb, q, single?TRUE:FALSE); /* max_one */
2351 2106 : q = pushNil(mb, q, TYPE_lng); /* estimate */
2352 :
2353 2106 : bool enabled = be->mvc->sa->eb.enabled;
2354 2106 : be->mvc->sa->eb.enabled = false;
2355 2106 : stmt *s = stmt_create(be->mvc->sa, st_tinter);
2356 2106 : be->mvc->sa->eb.enabled = enabled;
2357 2106 : if (s == NULL) {
2358 0 : freeInstruction(q);
2359 0 : goto bailout;
2360 : }
2361 :
2362 2106 : s->op1 = op1;
2363 2106 : s->op2 = op2;
2364 2106 : s->nrcols = op1->nrcols;
2365 2106 : s->key = op1->key;
2366 2106 : s->aggr = op1->aggr;
2367 2106 : s->nr = getDestVar(q);
2368 2106 : s->q = q;
2369 2106 : pushInstruction(mb, q);
2370 2106 : 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 95067 : 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 95067 : MalBlkPtr mb = be->mb;
2382 95067 : InstrPtr q = NULL;
2383 95067 : const char *sjt = inner?joinRef:outerjoinRef;
2384 :
2385 95067 : (void)anti;
2386 95067 : (void)inner;
2387 :
2388 95067 : if (need_left) {
2389 653 : cmptype = cmp_equal;
2390 653 : sjt = leftjoinRef;
2391 : }
2392 95067 : if (op1 == NULL || op2 == NULL || op1->nr < 0 || op2->nr < 0)
2393 0 : goto bailout;
2394 :
2395 95067 : assert (!single || cmptype == cmp_all);
2396 :
2397 95067 : switch (cmptype) {
2398 77018 : case cmp_equal:
2399 77018 : q = newStmtArgs(mb, algebraRef, sjt, 9);
2400 77018 : if (q == NULL)
2401 0 : goto bailout;
2402 77018 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
2403 77018 : q = pushArgument(mb, q, op1->nr);
2404 77018 : q = pushArgument(mb, q, op2->nr);
2405 77018 : if (!lcand)
2406 75930 : q = pushNilBat(mb, q);
2407 : else
2408 1088 : q = pushArgument(mb, q, lcand->nr);
2409 77018 : if (!rcand)
2410 77018 : q = pushNilBat(mb, q);
2411 : else
2412 0 : q = pushArgument(mb, q, rcand->nr);
2413 77018 : q = pushBit(mb, q, is_semantics?TRUE:FALSE);
2414 77018 : if (!inner)
2415 75 : q = pushBit(mb, q, FALSE); /* not match_one */
2416 77018 : q = pushNil(mb, q, TYPE_lng);
2417 77018 : pushInstruction(mb, q);
2418 77018 : 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 2583 : case cmp_lt:
2445 : case cmp_lte:
2446 : case cmp_gt:
2447 : case cmp_gte:
2448 2583 : q = newStmtArgs(mb, algebraRef, thetajoinRef, 9);
2449 2583 : if (q == NULL)
2450 0 : goto bailout;
2451 2583 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
2452 2583 : q = pushArgument(mb, q, op1->nr);
2453 2583 : q = pushArgument(mb, q, op2->nr);
2454 2583 : if (!lcand)
2455 2583 : q = pushNilBat(mb, q);
2456 : else
2457 0 : q = pushArgument(mb, q, lcand->nr);
2458 2583 : if (!rcand)
2459 2583 : q = pushNilBat(mb, q);
2460 : else
2461 0 : q = pushArgument(mb, q, rcand->nr);
2462 2583 : if (cmptype == cmp_lt)
2463 2067 : 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 2583 : q = pushBit(mb, q, is_semantics?TRUE:FALSE);
2471 2583 : q = pushNil(mb, q, TYPE_lng);
2472 2583 : pushInstruction(mb, q);
2473 2583 : break;
2474 12209 : case cmp_all: /* aka cross table */
2475 12645 : q = newStmt(mb, algebraRef, inner?crossRef:outercrossRef);
2476 12209 : if (q == NULL)
2477 0 : goto bailout;
2478 12209 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
2479 12209 : q = pushArgument(mb, q, op1->nr);
2480 12209 : q = pushArgument(mb, q, op2->nr);
2481 12209 : if (!inner) {
2482 436 : q = pushNilBat(mb, q);
2483 436 : q = pushNilBat(mb, q);
2484 : }
2485 12209 : q = pushBit(mb, q, single?TRUE:FALSE); /* max_one */
2486 12209 : assert(!lcand && !rcand);
2487 12209 : pushInstruction(mb, q);
2488 12209 : break;
2489 3223 : case cmp_joined:
2490 3223 : q = op1->q;
2491 3223 : if (q == NULL)
2492 0 : goto bailout;
2493 : break;
2494 0 : default:
2495 0 : TRC_ERROR(SQL_EXECUTION, "Impossible action\n");
2496 : }
2497 :
2498 95067 : stmt *s = stmt_create(be->mvc->sa, st_join);
2499 95067 : if (s == NULL) {
2500 0 : goto bailout;
2501 : }
2502 :
2503 95067 : s->op1 = op1;
2504 95067 : s->op2 = op2;
2505 95067 : s->flag = cmptype;
2506 95067 : s->key = 0;
2507 95067 : s->nrcols = 2;
2508 95067 : s->nr = getDestVar(q);
2509 95067 : s->q = q;
2510 95067 : 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 90852 : stmt_join(backend *be, stmt *l, stmt *r, int anti, comp_type cmptype, int need_left, int is_semantics, bool single)
2520 : {
2521 90852 : return stmt_join_cand(be, l, r, NULL, NULL, anti, cmptype, need_left, is_semantics, single, true);
2522 : }
2523 :
2524 : stmt *
2525 1453 : stmt_semijoin(backend *be, stmt *op1, stmt *op2, stmt *lcand, stmt *rcand, int is_semantics, bool single)
2526 : {
2527 1453 : MalBlkPtr mb = be->mb;
2528 1453 : InstrPtr q = NULL;
2529 :
2530 1453 : if (op1 == NULL || op2 == NULL || op1->nr < 0 || op2->nr < 0)
2531 0 : goto bailout;
2532 :
2533 1453 : if (single) {
2534 282 : q = newStmtArgs(mb, algebraRef, semijoinRef, 9);
2535 282 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
2536 : } else
2537 1171 : q = newStmt(mb, algebraRef, intersectRef);
2538 1453 : if (q == NULL)
2539 0 : goto bailout;
2540 1453 : q = pushArgument(mb, q, op1->nr);
2541 1453 : q = pushArgument(mb, q, op2->nr);
2542 1453 : if (lcand)
2543 1168 : q = pushArgument(mb, q, lcand->nr);
2544 : else
2545 285 : q = pushNilBat(mb, q);
2546 1453 : if (rcand)
2547 0 : q = pushArgument(mb, q, rcand->nr);
2548 : else
2549 1453 : q = pushNilBat(mb, q);
2550 1453 : q = pushBit(mb, q, is_semantics?TRUE:FALSE);
2551 1453 : q = pushBit(mb, q, single?TRUE:FALSE); /* max_one */
2552 1453 : q = pushNil(mb, q, TYPE_lng);
2553 :
2554 1453 : bool enabled = be->mvc->sa->eb.enabled;
2555 1453 : be->mvc->sa->eb.enabled = false;
2556 1453 : stmt *s = stmt_create(be->mvc->sa, st_semijoin);
2557 1453 : be->mvc->sa->eb.enabled = enabled;
2558 1453 : if (s == NULL) {
2559 0 : freeInstruction(q);
2560 0 : goto bailout;
2561 : }
2562 :
2563 1453 : s->op1 = op1;
2564 1453 : s->op2 = op2;
2565 1453 : s->flag = cmp_equal;
2566 1453 : s->key = 0;
2567 1453 : s->nrcols = 1;
2568 1453 : if (single)
2569 282 : s->nrcols = 2;
2570 1453 : s->nr = getDestVar(q);
2571 1453 : s->q = q;
2572 1453 : pushInstruction(mb, q);
2573 1453 : 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 3532386 : stmt_project_join(backend *be, stmt *op1, stmt *op2, bool delta)
2583 : {
2584 3532386 : MalBlkPtr mb = be->mb;
2585 3532386 : InstrPtr q = NULL;
2586 :
2587 3532386 : if (op1 == NULL || op2 == NULL || op1->nr < 0 || op2->nr < 0)
2588 : return NULL;
2589 : /* delta bat */
2590 3532386 : if (delta) {
2591 488364 : int uval = getArg(op2->q, 1);
2592 :
2593 488364 : q = newStmt(mb, sqlRef, deltaRef);
2594 488379 : q = pushArgument(mb, q, op1->nr);
2595 488379 : q = pushArgument(mb, q, op2->nr);
2596 488379 : q = pushArgument(mb, q, uval);
2597 : } else {
2598 : /* projections, ie left is void headed */
2599 3044022 : q = newStmt(mb, algebraRef, projectionRef);
2600 3044059 : q = pushArgument(mb, q, op1->nr);
2601 3044060 : q = pushArgument(mb, q, op2->nr);
2602 : }
2603 3532439 : pushInstruction(mb, q);
2604 3532439 : return q;
2605 : }
2606 :
2607 : stmt *
2608 3053310 : stmt_project(backend *be, stmt *op1, stmt *op2)
2609 : {
2610 3053310 : if (op1 == NULL || op2 == NULL)
2611 : return NULL;
2612 3053310 : if (!op2->nrcols)
2613 9286 : return stmt_const(be, op1, op2);
2614 3044024 : InstrPtr q = stmt_project_join(be, op1, op2, false);
2615 3044059 : if (q) {
2616 3044059 : stmt *s = stmt_create(be->mvc->sa, st_join);
2617 3044046 : if (s == NULL) {
2618 : return NULL;
2619 : }
2620 :
2621 3044046 : s->op1 = op1;
2622 3044046 : s->op2 = op2;
2623 3044046 : s->flag = cmp_project;
2624 3044046 : s->key = 0;
2625 3044046 : s->nrcols = MAX(op1->nrcols,op2->nrcols);
2626 3044046 : s->nr = getDestVar(q);
2627 3044046 : s->q = q;
2628 3044046 : s->tname = op2->tname;
2629 3044046 : s->cname = op2->cname;
2630 3044046 : s->label = op2->label;
2631 3044046 : 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 488367 : stmt_project_delta(backend *be, stmt *col, stmt *upd)
2640 : {
2641 488367 : InstrPtr q = stmt_project_join(be, col, upd, true);
2642 488378 : if (q) {
2643 488378 : stmt *s = stmt_create(be->mvc->sa, st_join);
2644 488374 : if (s == NULL) {
2645 : return NULL;
2646 : }
2647 :
2648 488374 : s->op1 = col;
2649 488374 : s->op2 = upd;
2650 488374 : s->flag = cmp_project;
2651 488374 : s->key = 0;
2652 488374 : s->nrcols = 2;
2653 488374 : s->nr = getDestVar(q);
2654 488374 : s->q = q;
2655 488374 : s->tname = col->tname;
2656 488374 : s->cname = col->cname;
2657 488374 : 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 286268 : stmt_catalog(backend *be, int type, stmt *args)
3143 : {
3144 286268 : MalBlkPtr mb = be->mb;
3145 286268 : InstrPtr q = NULL;
3146 286268 : node *n;
3147 :
3148 286268 : if (args == NULL || args->nr < 0)
3149 0 : goto bailout;
3150 :
3151 : /* cast them into properly named operations */
3152 286268 : const char *ref;
3153 286268 : 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 1088 : case ddl_create_schema: ref = create_schemaRef; break;
3158 193 : case ddl_drop_schema: ref = drop_schemaRef; break;
3159 10160 : case ddl_create_table: ref = create_tableRef; break;
3160 22620 : case ddl_create_view: ref = create_viewRef; break;
3161 3716 : 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 1372 : 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 99475 : 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 121587 : 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 286268 : q = newStmtArgs(mb, sqlcatalogRef, ref, list_length(args->op4.lval) + 1);
3198 286268 : if (q == NULL)
3199 0 : goto bailout;
3200 : // pass all arguments as before
3201 1711280 : for (n = args->op4.lval->h; n; n = n->next) {
3202 1425012 : stmt *c = n->data;
3203 :
3204 1425012 : q = pushArgument(mb, q, c->nr);
3205 : }
3206 :
3207 286268 : bool enabled = be->mvc->sa->eb.enabled;
3208 286268 : be->mvc->sa->eb.enabled = false;
3209 286268 : stmt *s = stmt_create(be->mvc->sa, st_catalog);
3210 286268 : be->mvc->sa->eb.enabled = enabled;
3211 286268 : if(!s) {
3212 0 : freeInstruction(q);
3213 0 : goto bailout;
3214 : }
3215 286268 : s->op1 = args;
3216 286268 : s->flag = type;
3217 286268 : s->q = q;
3218 286268 : s->nr = getDestVar(q);
3219 286268 : pushInstruction(mb, q);
3220 286268 : 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 1867143 : stmt_set_nrcols(stmt *s)
3230 : {
3231 1867143 : unsigned nrcols = 0;
3232 1867143 : int key = 1;
3233 1867143 : node *n;
3234 1867143 : list *l = s->op4.lval;
3235 :
3236 1867143 : assert(s->type == st_list);
3237 9100328 : for (n = l->h; n; n = n->next) {
3238 7233185 : stmt *f = n->data;
3239 :
3240 7233185 : if (!f)
3241 0 : continue;
3242 7233185 : if (f->nrcols > nrcols)
3243 : nrcols = f->nrcols;
3244 7233185 : key &= f->key;
3245 7233185 : s->nr = f->nr;
3246 : }
3247 1867143 : s->nrcols = nrcols;
3248 1867143 : s->key = key;
3249 1867143 : }
3250 :
3251 : stmt *
3252 1457885 : stmt_list(backend *be, list *l)
3253 : {
3254 1457885 : if (l == NULL)
3255 : return NULL;
3256 1457885 : stmt *s = stmt_create(be->mvc->sa, st_list);
3257 1457914 : if(!s) {
3258 : return NULL;
3259 : }
3260 1457914 : s->op4.lval = l;
3261 1457914 : stmt_set_nrcols(s);
3262 1457914 : return s;
3263 : }
3264 :
3265 : static InstrPtr
3266 65318 : dump_header(mvc *sql, MalBlkPtr mb, list *l)
3267 : {
3268 65318 : node *n;
3269 : // gather the meta information
3270 65318 : int tblId, nmeId, tpeId, lenId, scaleId;
3271 65318 : int args;
3272 65318 : InstrPtr list;
3273 65318 : InstrPtr tblPtr, nmePtr, tpePtr, lenPtr, scalePtr;
3274 :
3275 65318 : args = list_length(l) + 1;
3276 :
3277 65323 : list = newInstructionArgs(mb,sqlRef, resultSetRef, args + 5);
3278 65326 : if(!list) {
3279 : return NULL;
3280 : }
3281 65326 : getArg(list,0) = newTmpVariable(mb,TYPE_int);
3282 65327 : meta(tblPtr, tblId, TYPE_str, args);
3283 65331 : meta(nmePtr, nmeId, TYPE_str, args);
3284 65331 : meta(tpePtr, tpeId, TYPE_str, args);
3285 65330 : meta(lenPtr, lenId, TYPE_int, args);
3286 65331 : meta(scalePtr, scaleId, TYPE_int, args);
3287 65331 : if(tblPtr == NULL || nmePtr == NULL || tpePtr == NULL || lenPtr == NULL || scalePtr == NULL)
3288 : return NULL;
3289 :
3290 342798 : for (n = l->h; n; n = n->next) {
3291 277468 : stmt *c = n->data;
3292 277468 : sql_subtype *t = tail_type(c);
3293 277476 : const char *tname = table_name(sql->sa, c);
3294 277476 : const char *sname = schema_name(sql->sa, c);
3295 277468 : const char *_empty = "";
3296 277468 : const char *tn = (tname) ? tname : _empty;
3297 277468 : const char *sn = (sname) ? sname : _empty;
3298 277468 : const char *cn = column_name(sql->sa, c);
3299 277470 : const char *ntn = sql_escape_ident(sql->ta, tn);
3300 277458 : const char *nsn = sql_escape_ident(sql->ta, sn);
3301 277472 : size_t fqtnl;
3302 :
3303 277472 : if (ntn && nsn && (fqtnl = strlen(ntn) + 1 + strlen(nsn) + 1) ){
3304 277472 : char *fqtn = SA_NEW_ARRAY(sql->ta, char, fqtnl);
3305 277468 : if (fqtn == NULL)
3306 : return NULL;
3307 277468 : snprintf(fqtn, fqtnl, "%s.%s", nsn, ntn);
3308 277468 : tblPtr = pushStr(mb, tblPtr, fqtn);
3309 277456 : nmePtr = pushStr(mb, nmePtr, cn);
3310 277461 : tpePtr = pushStr(mb, tpePtr, (t->type->localtype == TYPE_void ? "char" : t->type->base.name));
3311 277466 : lenPtr = pushInt(mb, lenPtr, t->digits);
3312 277474 : scalePtr = pushInt(mb, scalePtr, t->scale);
3313 277471 : list = pushArgument(mb,list,c->nr);
3314 : } else
3315 : return NULL;
3316 : }
3317 65330 : sa_reset(sql->ta);
3318 65315 : pushInstruction(mb,list);
3319 65315 : return list;
3320 : }
3321 :
3322 : int
3323 125723 : stmt_output(backend *be, stmt *lst)
3324 : {
3325 125723 : MalBlkPtr mb = be->mb;
3326 125723 : InstrPtr q = NULL;
3327 125723 : list *l = lst->op4.lval;
3328 125723 : int cnt = list_length(l), ok = 0;
3329 125771 : node *n = l->h;
3330 125771 : stmt *first = n->data;
3331 :
3332 : /* single value result, has a fast exit */
3333 125771 : if (cnt == 1 && first->nrcols <= 0 ){
3334 60460 : stmt *c = n->data;
3335 60460 : sql_subtype *t = tail_type(c);
3336 60413 : const char *tname = table_name(be->mvc->sa, c);
3337 60370 : const char *sname = schema_name(be->mvc->sa, c);
3338 60360 : const char *_empty = "";
3339 60360 : const char *tn = (tname) ? tname : _empty;
3340 60360 : const char *sn = (sname) ? sname : _empty;
3341 60360 : const char *cn = column_name(be->mvc->sa, c);
3342 60354 : const char *ntn = sql_escape_ident(be->mvc->ta, tn);
3343 60485 : const char *nsn = sql_escape_ident(be->mvc->ta, sn);
3344 :
3345 60492 : if (ntn && nsn) {
3346 60492 : size_t fqtnl = strlen(ntn) + 1 + strlen(nsn) + 1;
3347 60492 : char *fqtn = SA_NEW_ARRAY(be->mvc->ta, char, fqtnl);
3348 60491 : if (fqtn == NULL)
3349 : return -1;
3350 60491 : ok = 1;
3351 60491 : snprintf(fqtn, fqtnl, "%s.%s", nsn, ntn);
3352 :
3353 60491 : q = newStmt(mb, sqlRef, resultSetRef);
3354 60497 : if (q == NULL)
3355 : return -1;
3356 60497 : getArg(q,0) = newTmpVariable(mb,TYPE_int);
3357 60498 : q = pushStr(mb, q, fqtn);
3358 60498 : q = pushStr(mb, q, cn);
3359 60496 : q = pushStr(mb, q, t->type->localtype == TYPE_void ? "char" : t->type->base.name);
3360 60498 : q = pushInt(mb, q, t->digits);
3361 60497 : q = pushInt(mb, q, t->scale);
3362 60495 : q = pushInt(mb, q, t->type->eclass);
3363 60494 : q = pushArgument(mb, q, c->nr);
3364 60482 : pushInstruction(mb, q);
3365 : }
3366 60482 : sa_reset(be->mvc->ta);
3367 60452 : if (!ok)
3368 : return -1;
3369 : } else {
3370 65311 : if ((q = dump_header(be->mvc, mb, l)) == NULL)
3371 : return -1;
3372 : }
3373 : return 0;
3374 : }
3375 :
3376 : int
3377 149624 : stmt_affected_rows(backend *be, int lastnr)
3378 : {
3379 149624 : MalBlkPtr mb = be->mb;
3380 149624 : InstrPtr q = NULL;
3381 :
3382 149624 : q = newStmt(mb, sqlRef, affectedRowsRef);
3383 149903 : if (q == NULL)
3384 : return -1;
3385 149903 : q = pushArgument(mb, q, be->mvc_var);
3386 149903 : getArg(q, 0) = be->mvc_var = newTmpVariable(mb, TYPE_int);
3387 149902 : q = pushArgument(mb, q, lastnr);
3388 149901 : pushInstruction(mb, q);
3389 149900 : be->mvc_var = getDestVar(q);
3390 149900 : return 0;
3391 : }
3392 :
3393 : stmt *
3394 176389 : stmt_append(backend *be, stmt *c, stmt *a)
3395 : {
3396 176389 : MalBlkPtr mb = be->mb;
3397 176389 : InstrPtr q = NULL;
3398 :
3399 176389 : if (c == NULL || a == NULL || c->nr < 0 || a->nr < 0)
3400 0 : goto bailout;
3401 176389 : q = newStmt(mb, batRef, appendRef);
3402 176389 : if (q == NULL)
3403 0 : goto bailout;
3404 176389 : q = pushArgument(mb, q, c->nr);
3405 176389 : q = pushArgument(mb, q, a->nr);
3406 176389 : q = pushBit(mb, q, TRUE);
3407 176389 : bool enabled = be->mvc->sa->eb.enabled;
3408 176389 : be->mvc->sa->eb.enabled = false;
3409 176389 : stmt *s = stmt_create(be->mvc->sa, st_append);
3410 176389 : be->mvc->sa->eb.enabled = enabled;
3411 176389 : if(!s) {
3412 0 : freeInstruction(q);
3413 0 : goto bailout;
3414 : }
3415 176389 : s->op1 = c;
3416 176389 : s->op2 = a;
3417 176389 : s->nrcols = c->nrcols;
3418 176389 : s->key = c->key;
3419 176389 : s->nr = getDestVar(q);
3420 176389 : s->q = q;
3421 176389 : pushInstruction(mb, q);
3422 176389 : 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 137772 : stmt_append_bulk(backend *be, stmt *c, list *l)
3432 : {
3433 137772 : MalBlkPtr mb = be->mb;
3434 137772 : InstrPtr q = NULL;
3435 137772 : bool needs_columns = false;
3436 :
3437 137772 : 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 888959 : for (node *n = l->h; n; n = n->next) {
3443 751187 : stmt *t = n->data;
3444 751187 : needs_columns |= t->nrcols > 0;
3445 : }
3446 137772 : 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 137772 : q = newStmtArgs(mb, batRef, appendBulkRef, list_length(l) + 3);
3455 138132 : if (q == NULL)
3456 0 : goto bailout;
3457 138132 : q = pushArgument(mb, q, c->nr);
3458 138130 : q = pushBit(mb, q, TRUE);
3459 889364 : for (node *n = l->h ; n ; n = n->next) {
3460 751348 : stmt *a = n->data;
3461 751348 : q = pushArgument(mb, q, a->nr);
3462 : }
3463 138016 : bool enabled = be->mvc->sa->eb.enabled;
3464 138016 : be->mvc->sa->eb.enabled = false;
3465 138016 : stmt *s = stmt_create(be->mvc->sa, st_append_bulk);
3466 137890 : be->mvc->sa->eb.enabled = enabled;
3467 137890 : if(!s) {
3468 0 : freeInstruction(q);
3469 0 : goto bailout;
3470 : }
3471 137890 : s->op1 = c;
3472 137890 : s->op4.lval = l;
3473 137890 : s->nrcols = c->nrcols;
3474 137890 : s->key = c->key;
3475 137890 : s->nr = getDestVar(q);
3476 137890 : s->q = q;
3477 137890 : pushInstruction(mb, q);
3478 137890 : 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 16007 : stmt_pack(backend *be, stmt *c, int n)
3488 : {
3489 16007 : MalBlkPtr mb = be->mb;
3490 16007 : InstrPtr q = NULL;
3491 :
3492 16007 : if (c == NULL || c->nr < 0)
3493 0 : goto bailout;
3494 16007 : q = newStmtArgs(mb, matRef, packIncrementRef, 3);
3495 16007 : if (q == NULL)
3496 0 : goto bailout;
3497 16007 : q = pushArgument(mb, q, c->nr);
3498 16007 : q = pushInt(mb, q, n);
3499 16007 : bool enabled = be->mvc->sa->eb.enabled;
3500 16007 : be->mvc->sa->eb.enabled = false;
3501 16007 : stmt *s = stmt_create(be->mvc->sa, st_append);
3502 16007 : be->mvc->sa->eb.enabled = enabled;
3503 16007 : if(!s) {
3504 0 : freeInstruction(q);
3505 0 : goto bailout;
3506 : }
3507 16007 : s->op1 = c;
3508 16007 : s->nrcols = c->nrcols;
3509 16007 : s->key = c->key;
3510 16007 : s->nr = getDestVar(q);
3511 16007 : s->q = q;
3512 16007 : pushInstruction(mb, q);
3513 16007 : 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 29761 : stmt_pack_add(backend *be, stmt *c, stmt *a)
3524 : {
3525 29761 : MalBlkPtr mb = be->mb;
3526 29761 : InstrPtr q = NULL;
3527 :
3528 29761 : if (c == NULL || a == NULL || c->nr < 0 || a->nr < 0)
3529 0 : goto bailout;
3530 29761 : q = newStmtArgs(mb, matRef, packIncrementRef, 3);
3531 29761 : if (q == NULL)
3532 0 : goto bailout;
3533 29761 : q = pushArgument(mb, q, c->nr);
3534 29761 : q = pushArgument(mb, q, a->nr);
3535 29761 : bool enabled = be->mvc->sa->eb.enabled;
3536 29761 : be->mvc->sa->eb.enabled = false;
3537 29761 : stmt *s = stmt_create(be->mvc->sa, st_append);
3538 29761 : be->mvc->sa->eb.enabled = enabled;
3539 29761 : if(!s) {
3540 0 : freeInstruction(q);
3541 0 : goto bailout;
3542 : }
3543 29761 : s->op1 = c;
3544 29761 : s->op2 = a;
3545 29761 : s->nrcols = c->nrcols;
3546 29761 : s->key = c->key;
3547 29761 : s->nr = getDestVar(q);
3548 29761 : s->q = q;
3549 29761 : pushInstruction(mb, q);
3550 29761 : 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 106535 : stmt_claim(backend *be, sql_table *t, stmt *cnt)
3560 : {
3561 106535 : MalBlkPtr mb = be->mb;
3562 106535 : InstrPtr q = NULL;
3563 :
3564 106535 : if (!t || cnt->nr < 0)
3565 0 : goto bailout;
3566 106535 : assert(t->s); /* declared table */
3567 106535 : q = newStmtArgs(mb, sqlRef, claimRef, 6);
3568 106601 : if (q == NULL)
3569 0 : goto bailout;
3570 : /* returns offset or offsets */
3571 106601 : q = pushReturn(mb, q, newTmpVariable(mb, newBatType(TYPE_oid)));
3572 106591 : q = pushArgument(mb, q, be->mvc_var);
3573 106598 : q = pushSchema(mb, q, t);
3574 106563 : q = pushStr(mb, q, t->base.name);
3575 106559 : q = pushArgument(mb, q, cnt->nr);
3576 106567 : bool enabled = be->mvc->sa->eb.enabled;
3577 106567 : be->mvc->sa->eb.enabled = false;
3578 106567 : stmt *s = stmt_create(be->mvc->sa, st_claim);
3579 106487 : be->mvc->sa->eb.enabled = enabled;
3580 106487 : if(!s) {
3581 0 : freeInstruction(q);
3582 0 : goto bailout;
3583 : }
3584 106487 : s->op1 = cnt;
3585 106487 : s->op4.tval = t;
3586 106487 : s->nr = getDestVar(q);
3587 106487 : s->q = q;
3588 106487 : pushInstruction(mb, q);
3589 106487 : 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 149613 : stmt_add_dependency_change(backend *be, sql_table *t, stmt *cnt)
3599 : {
3600 149613 : MalBlkPtr mb = be->mb;
3601 149613 : InstrPtr q = NULL;
3602 :
3603 149613 : if (!t || cnt->nr < 0)
3604 0 : goto bailout;
3605 149613 : q = newStmtArgs(mb, sqlRef, dependRef, 4);
3606 150133 : if (q == NULL)
3607 0 : goto bailout;
3608 150133 : q = pushSchema(mb, q, t);
3609 150106 : q = pushStr(mb, q, t->base.name);
3610 150120 : q = pushArgument(mb, q, cnt->nr);
3611 150126 : pushInstruction(mb, q);
3612 150126 : 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 14814 : stmt_add_column_predicate(backend *be, sql_column *c)
3621 : {
3622 14814 : MalBlkPtr mb = be->mb;
3623 14814 : InstrPtr q = NULL;
3624 :
3625 14814 : if (!c)
3626 0 : goto bailout;
3627 14814 : 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 55631 : stmt_replace(backend *be, stmt *r, stmt *id, stmt *val)
3643 : {
3644 55631 : MalBlkPtr mb = be->mb;
3645 55631 : InstrPtr q = NULL;
3646 :
3647 55631 : if (r->nr < 0)
3648 0 : goto bailout;
3649 :
3650 55631 : q = newStmt(mb, batRef, replaceRef);
3651 55631 : if (q == NULL)
3652 0 : goto bailout;
3653 55631 : q = pushArgument(mb, q, r->nr);
3654 55631 : q = pushArgument(mb, q, id->nr);
3655 55631 : q = pushArgument(mb, q, val->nr);
3656 55631 : q = pushBit(mb, q, TRUE); /* forced */
3657 55631 : bool enabled = be->mvc->sa->eb.enabled;
3658 55631 : be->mvc->sa->eb.enabled = false;
3659 55631 : stmt *s = stmt_create(be->mvc->sa, st_replace);
3660 55631 : be->mvc->sa->eb.enabled = enabled;
3661 55631 : if(!s) {
3662 0 : freeInstruction(q);
3663 0 : goto bailout;
3664 : }
3665 55631 : s->op1 = r;
3666 55631 : s->op2 = id;
3667 55631 : s->op3 = val;
3668 55631 : s->nrcols = r->nrcols;
3669 55631 : s->key = r->key;
3670 55631 : s->nr = getDestVar(q);
3671 55631 : s->q = q;
3672 55631 : s->cand = r->cand;
3673 55631 : pushInstruction(mb, q);
3674 55631 : 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 41375 : stmt_table_clear(backend *be, sql_table *t, int restart_sequences)
3684 : {
3685 41375 : MalBlkPtr mb = be->mb;
3686 41375 : InstrPtr q = NULL;
3687 :
3688 41375 : 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 41373 : q = newStmt(mb, sqlRef, clear_tableRef);
3701 41823 : if (q == NULL)
3702 0 : goto bailout;
3703 41823 : q = pushSchema(mb, q, t);
3704 41818 : q = pushStr(mb, q, t->base.name);
3705 41802 : q = pushInt(mb, q, restart_sequences);
3706 41785 : pushInstruction(mb, q);
3707 : }
3708 41781 : stmt *s = stmt_create(be->mvc->sa, st_table_clear);
3709 :
3710 41641 : if(!s) {
3711 0 : goto bailout;
3712 : }
3713 41641 : s->op4.tval = t;
3714 41641 : s->nrcols = 0;
3715 41641 : s->nr = getDestVar(q);
3716 41641 : s->q = q;
3717 41641 : 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 39386 : stmt_exception(backend *be, stmt *cond, const char *errstr, int errcode)
3727 : {
3728 39386 : MalBlkPtr mb = be->mb;
3729 39386 : InstrPtr q = NULL;
3730 :
3731 39386 : if (cond->nr < 0)
3732 : return NULL;
3733 :
3734 : /* if(bit(l)) { error(r);} ==raising an exception */
3735 39386 : q = newStmt(mb, sqlRef, assertRef);
3736 39402 : if (q == NULL)
3737 0 : goto bailout;
3738 39402 : q = pushArgument(mb, q, cond->nr);
3739 39402 : q = pushStr(mb, q, errstr);
3740 39403 : bool enabled = be->mvc->sa->eb.enabled;
3741 39403 : be->mvc->sa->eb.enabled = false;
3742 39403 : 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 15116 : tail_set_type(mvc *m, stmt *st, sql_subtype *t)
3767 : {
3768 40679 : for (;;) {
3769 40679 : switch (st->type) {
3770 3689 : case st_const:
3771 3689 : st = st->op2;
3772 3689 : continue;
3773 18262 : case st_alias:
3774 : case st_gen_group:
3775 : case st_order:
3776 18262 : st = st->op1;
3777 18262 : 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 2780 : case st_aggr:
3790 : case st_Nop: {
3791 2780 : list *res = st->op4.funcval->res;
3792 :
3793 2780 : if (res && list_length(res) == 1)
3794 2780 : res->h->data = t;
3795 : return;
3796 : }
3797 6787 : case st_atom:
3798 6787 : st->op4.aval = atom_set_type(m->sa, st->op4.aval, t);
3799 6787 : 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 51904 : stmt_convert(backend *be, stmt *v, stmt *sel, sql_subtype *f, sql_subtype *t)
3939 : {
3940 51904 : MalBlkPtr mb = be->mb;
3941 51904 : InstrPtr q = NULL;
3942 51904 : const char *convert = t->type->impl, *mod = calcRef;
3943 51904 : int pushed = (v->cand && v->cand == sel), no_candidates = 0;
3944 51904 : bool add_tz = false;
3945 : /* convert types and make sure they are rounded up correctly */
3946 :
3947 51904 : if (v->nr < 0)
3948 0 : goto bailout;
3949 :
3950 51904 : if (f->type->eclass != EC_EXTERNAL && t->type->eclass != EC_EXTERNAL &&
3951 : /* general cases */
3952 51545 : ((t->type->localtype == f->type->localtype && t->type->eclass == f->type->eclass &&
3953 51545 : !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 1769 : (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 44572 : (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 15116 : tail_set_type(be->mvc, v, t);
3960 15116 : return v;
3961 : }
3962 :
3963 : /* external types have sqlname convert functions,
3964 : these can generate errors (fromstr cannot) */
3965 36788 : if (t->type->eclass == EC_EXTERNAL)
3966 331 : convert = t->type->base.name;
3967 36457 : else if (t->type->eclass == EC_MONTH)
3968 : convert = "month_interval";
3969 36434 : else if (t->type->eclass == EC_SEC)
3970 100 : convert = "second_interval";
3971 :
3972 36788 : no_candidates = t->type->eclass == EC_EXTERNAL && strcmp(convert, "uuid") != 0; /* uuids conversions support candidate lists */
3973 :
3974 36788 : 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 36664 : if (v->nrcols == 0 && (!sel || sel->nrcols == 0)) { /* simple calc */
3986 8172 : q = newStmtArgs(mb, mod, convert, 13);
3987 8172 : if (q == NULL)
3988 0 : goto bailout;
3989 28513 : } 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 28471 : 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 28471 : q = newStmtArgs(mb, mod==calcRef?batcalcRef:batmtimeRef, convert, 13);
4011 28471 : 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 36840 : if (EC_VARCHAR(t->type->eclass) && !(trivial_string_conversion(f->type->eclass) && t->digits == 0)) {
4017 1919 : q = pushInt(mb, q, f->type->eclass);
4018 1919 : q = pushInt(mb, q, f->digits);
4019 1919 : q = pushInt(mb, q, f->scale);
4020 1919 : q = pushInt(mb, q, type_has_tz(f));
4021 34745 : } else if (f->type->eclass == EC_DEC) {
4022 : /* scale of the current decimal */
4023 1553 : q = pushInt(mb, q, f->scale);
4024 33192 : } 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 36664 : q = pushArgument(mb, q, v->nr);
4029 36664 : if (add_tz)
4030 : q = pushLng(mb, q, be->mvc->timezone);
4031 36664 : if (sel && !pushed && !v->cand) {
4032 3576 : q = pushArgument(mb, q, sel->nr);
4033 3576 : pushed = 1;
4034 33088 : } else if (v->nrcols > 0 && !no_candidates) {
4035 24895 : q = pushNilBat(mb, q);
4036 : }
4037 36664 : 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 3058 : q = pushInt(mb, q, t->digits);
4040 3058 : if (!EC_TEMP_FRAC(t->type->eclass))
4041 2719 : q = pushInt(mb, q, t->scale);
4042 : }
4043 : /* convert to string, give error on to large strings */
4044 36840 : if (EC_VARCHAR(t->type->eclass) && !(trivial_string_conversion(f->type->eclass) && t->digits == 0))
4045 1919 : q = pushInt(mb, q, t->digits);
4046 : /* convert a string to a time(stamp) with time zone */
4047 36664 : 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 36664 : 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 36664 : bool enabled = be->mvc->sa->eb.enabled;
4073 36664 : be->mvc->sa->eb.enabled = false;
4074 36664 : stmt *s = stmt_create(be->mvc->sa, st_convert);
4075 36664 : be->mvc->sa->eb.enabled = enabled;
4076 36664 : if(!s) {
4077 0 : freeInstruction(q);
4078 0 : goto bailout;
4079 : }
4080 36664 : s->op1 = v;
4081 36664 : s->nrcols = 0; /* function without arguments returns single value */
4082 36664 : s->key = v->key;
4083 36664 : s->nrcols = v->nrcols;
4084 36664 : s->aggr = v->aggr;
4085 36664 : s->op4.typeval = *t;
4086 36664 : s->nr = getDestVar(q);
4087 36664 : s->q = q;
4088 36664 : s->cand = pushed ? sel : NULL;
4089 36664 : pushInstruction(mb, q);
4090 36664 : 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 27070 : stmt_unop(backend *be, stmt *op1, stmt *sel, sql_subfunc *op)
4102 : {
4103 27070 : list *ops = sa_list(be->mvc->sa);
4104 27084 : list_append(ops, op1);
4105 27086 : stmt *r = stmt_Nop(be, stmt_list(be, ops), sel, op, NULL);
4106 27086 : if (r && !r->cand)
4107 27086 : r->cand = op1->cand;
4108 27086 : return r;
4109 : }
4110 :
4111 : stmt *
4112 47212 : stmt_binop(backend *be, stmt *op1, stmt *op2, stmt *sel, sql_subfunc *op)
4113 : {
4114 47212 : list *ops = sa_list(be->mvc->sa);
4115 47217 : list_append(ops, op1);
4116 47217 : list_append(ops, op2);
4117 47218 : stmt *r = stmt_Nop(be, stmt_list(be, ops), sel, op, NULL);
4118 47219 : if (r && !r->cand)
4119 47219 : r->cand = op1->cand?op1->cand:op2->cand;
4120 47219 : return r;
4121 : }
4122 :
4123 : #define LANG_INT_OR_MAL(l) ((l)==FUNC_LANG_INT || (l)==FUNC_LANG_MAL)
4124 :
4125 : stmt *
4126 220556 : stmt_Nop(backend *be, stmt *ops, stmt *sel, sql_subfunc *f, stmt* rows)
4127 : {
4128 220556 : MalBlkPtr mb = be->mb;
4129 220556 : InstrPtr q = NULL;
4130 220556 : const char *mod = sql_func_mod(f->func), *fimp = backend_function_imp(be, f->func);
4131 220573 : sql_subtype *tpe = NULL;
4132 220573 : int push_cands = 0, default_nargs;
4133 220573 : stmt *o = NULL, *card = NULL;
4134 :
4135 220573 : if (ops == NULL)
4136 0 : goto bailout;
4137 :
4138 220573 : if (rows) {
4139 105 : if (sel) /* if there's a candidate list, use it instead of 'rows' */
4140 0 : rows = sel;
4141 : o = rows;
4142 220468 : } else if (list_length(ops->op4.lval)) {
4143 218668 : o = ops->op4.lval->h->data;
4144 652986 : for (node *n = ops->op4.lval->h; n; n = n->next) {
4145 434318 : stmt *c = n->data;
4146 :
4147 434318 : if (c && o->nrcols < c->nrcols)
4148 434318 : o = c;
4149 : }
4150 : }
4151 :
4152 : /* handle nullif */
4153 220574 : if (list_length(ops->op4.lval) == 2 &&
4154 138643 : 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 220476 : if (backend_create_subfunc(be, f, ops->op4.lval) < 0)
4185 2 : goto bailout;
4186 220480 : mod = sql_func_mod(f->func);
4187 220484 : fimp = convertMultiplexFcn(backend_function_imp(be, f->func));
4188 220473 : push_cands = f->func->type == F_FUNC && can_push_cands(sel, mod, fimp);
4189 229634 : 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 220482 : if (rows) {
4191 105 : 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 105 : default_nargs++;
4193 : }
4194 :
4195 220482 : if (o && o->nrcols > 0 && f->func->type != F_LOADER && f->func->type != F_PROC) {
4196 140665 : sql_subtype *res = f->res->h->data;
4197 :
4198 281314 : q = newStmtArgs(mb, f->func->type == F_UNION ? batmalRef : malRef, multiplexRef, default_nargs);
4199 140665 : if (q == NULL)
4200 0 : goto bailout;
4201 140665 : if (rows)
4202 105 : q = pushArgument(mb, q, card->nr);
4203 140665 : q = pushStr(mb, q, mod);
4204 140665 : q = pushStr(mb, q, fimp);
4205 140665 : setVarType(mb, getArg(q, 0), newBatType(res->type->localtype));
4206 : } else {
4207 79817 : q = newStmtArgs(mb, mod, fimp, default_nargs);
4208 79828 : if (q == NULL)
4209 0 : goto bailout;
4210 :
4211 79828 : if (rows)
4212 0 : q = pushArgument(mb, q, card->nr);
4213 79828 : if (f->res && list_length(f->res)) {
4214 70670 : sql_subtype *res = f->res->h->data;
4215 :
4216 70670 : setVarType(mb, getArg(q, 0), res->type->localtype);
4217 : }
4218 : }
4219 220493 : 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 220493 : if (f->func->lang == FUNC_LANG_C) {
4229 35 : q = pushBit(mb, q, 0);
4230 220458 : } else if (f->func->lang == FUNC_LANG_CPP) {
4231 1 : q = pushBit(mb, q, 1);
4232 : }
4233 220493 : 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 220493 : 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 220493 : if (list_length(ops->op4.lval))
4241 218673 : tpe = tail_type(ops->op4.lval->h->data);
4242 :
4243 654827 : for (node *n = ops->op4.lval->h; n; n = n->next) {
4244 434334 : stmt *op = n->data;
4245 434334 : q = pushArgument(mb, q, op->nr);
4246 : }
4247 : /* push candidate lists if that's the case */
4248 220493 : if (push_cands) {
4249 77099 : for (node *n = ops->op4.lval->h; n; n = n->next) {
4250 50861 : stmt *op = n->data;
4251 :
4252 50861 : if (op->nrcols > 0) {
4253 28526 : if (op->cand && op->cand == sel) {
4254 3788 : q = pushNilBat(mb, q);
4255 : } else {
4256 24738 : q = pushArgument(mb, q, sel->nr);
4257 : }
4258 : }
4259 : }
4260 : }
4261 : /* special case for round function on decimals */
4262 220493 : 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 220493 : pushInstruction(mb, q);
4267 : }
4268 :
4269 220588 : stmt *s = stmt_create(be->mvc->sa, st_Nop);
4270 220587 : if(!s) {
4271 0 : goto bailout;
4272 : }
4273 220587 : s->op1 = ops;
4274 220587 : if (o) {
4275 218785 : s->nrcols = o->nrcols;
4276 218785 : s->key = o->key;
4277 218785 : s->aggr = o->aggr;
4278 : } else {
4279 1802 : s->nrcols = 0;
4280 1802 : s->key = 1;
4281 : }
4282 220587 : s->op4.funcval = f;
4283 220587 : s->nr = getDestVar(q);
4284 220587 : s->q = q;
4285 220587 : if (sel && push_cands && s->nrcols)
4286 24727 : 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 85201 : stmt_aggr(backend *be, stmt *op1, stmt *grp, stmt *ext, sql_subfunc *op, int reduce, int no_nil, int nil_if_empty)
4404 : {
4405 85201 : MalBlkPtr mb = be->mb;
4406 85201 : InstrPtr q = NULL;
4407 85201 : const char *mod, *aggrfunc;
4408 85201 : sql_subtype *res = op->res->h->data;
4409 85201 : int restype = res->type->localtype;
4410 85201 : bool complex_aggr = false;
4411 85201 : int *stmt_nr = NULL;
4412 85201 : int avg = 0;
4413 :
4414 85201 : if (op1->nr < 0)
4415 0 : goto bailout;
4416 85201 : if (backend_create_subfunc(be, op, NULL) < 0)
4417 0 : goto bailout;
4418 85403 : mod = sql_func_mod(op->func);
4419 85249 : aggrfunc = backend_function_imp(be, op->func);
4420 :
4421 85326 : if (LANG_INT_OR_MAL(op->func->lang)) {
4422 85209 : if (strcmp(aggrfunc, "avg") == 0)
4423 : avg = 1;
4424 83839 : if (avg || strcmp(aggrfunc, "sum") == 0 || strcmp(aggrfunc, "prod") == 0
4425 76689 : || strcmp(aggrfunc, "str_group_concat") == 0)
4426 : complex_aggr = true;
4427 85209 : if (restype == TYPE_dbl)
4428 1561 : avg = 0;
4429 : }
4430 :
4431 170652 : int argc = 1
4432 85326 : + 2 * avg
4433 85326 : + (LANG_EXT(op->func->lang) != 0)
4434 85326 : + 2 * (op->func->lang == FUNC_LANG_C || op->func->lang == FUNC_LANG_CPP)
4435 85326 : + (op->func->lang == FUNC_LANG_PY || op->func->lang == FUNC_LANG_R)
4436 85326 : + (op1->type != st_list ? 1 : list_length(op1->op4.lval))
4437 85326 : + (grp ? 4 : avg + 1);
4438 :
4439 85326 : 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 78479 : q = newStmtArgs(mb, mod, aggrfunc, argc);
4458 78723 : if (q == NULL)
4459 0 : goto bailout;
4460 78723 : if (complex_aggr) {
4461 6744 : setVarType(mb, getArg(q, 0), restype);
4462 6744 : 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 85570 : if (LANG_EXT(op->func->lang))
4470 47 : q = pushPtr(mb, q, op->func);
4471 85573 : if (op->func->lang == FUNC_LANG_R ||
4472 85538 : 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 85572 : if (op1->type != st_list) {
4487 79671 : q = pushArgument(mb, q, op1->nr);
4488 : } else {
4489 5901 : int i;
4490 5901 : node *n;
4491 :
4492 12224 : for (i=0, n = op1->op4.lval->h; n; n = n->next, i++) {
4493 6323 : stmt *op = n->data;
4494 :
4495 6323 : if (stmt_nr)
4496 : q = pushArgument(mb, q, stmt_nr[i]);
4497 : else
4498 6323 : q = pushArgument(mb, q, op->nr);
4499 : }
4500 : }
4501 85570 : 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 78723 : } 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 77080 : } 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 77080 : } 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 85570 : bool enabled = be->mvc->sa->eb.enabled;
4519 85570 : be->mvc->sa->eb.enabled = false;
4520 85570 : stmt *s = stmt_create(be->mvc->sa, st_aggr);
4521 85555 : be->mvc->sa->eb.enabled = enabled;
4522 85555 : if(!s) {
4523 0 : freeInstruction(q);
4524 0 : goto bailout;
4525 : }
4526 85555 : s->op1 = op1;
4527 85555 : if (grp) {
4528 6847 : s->op2 = grp;
4529 6847 : s->op3 = ext;
4530 6847 : s->nrcols = 1;
4531 : } else {
4532 78708 : if (!reduce)
4533 0 : s->nrcols = 1;
4534 : }
4535 85555 : s->key = reduce;
4536 85555 : s->aggr = reduce;
4537 85555 : s->flag = no_nil;
4538 85555 : s->op4.funcval = op;
4539 85555 : s->nr = getDestVar(q);
4540 85555 : s->q = q;
4541 85555 : pushInstruction(mb, q);
4542 85555 : 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 5066742 : stmt_alias_(backend *be, stmt *op1, int label, const char *tname, const char *alias)
4552 : {
4553 5066742 : assert(label);
4554 5066742 : stmt *s = stmt_create(be->mvc->sa, st_alias);
4555 5066748 : if(!s) {
4556 : return NULL;
4557 : }
4558 5066748 : s->label = label;
4559 5066748 : s->op1 = op1;
4560 5066748 : s->nrcols = op1->nrcols;
4561 5066748 : s->key = op1->key;
4562 5066748 : s->aggr = op1->aggr;
4563 :
4564 5066748 : s->tname = tname;
4565 5066748 : s->cname = alias;
4566 5066748 : s->nr = op1->nr;
4567 5066748 : s->q = op1->q;
4568 5066748 : return s;
4569 : }
4570 :
4571 : stmt *
4572 4495590 : 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 4495590 : return stmt_alias_(be, op1, label, tname, alias);
4581 : }
4582 :
4583 : stmt *
4584 571253 : stmt_as(backend *be, stmt *s, stmt *org)
4585 : {
4586 571253 : assert(org->type == st_alias);
4587 571253 : return stmt_alias_(be, s, org->label, org->tname, org->cname);
4588 : }
4589 :
4590 : sql_subtype *
4591 1565032 : tail_type(stmt *st)
4592 : {
4593 8680394 : for (;;) {
4594 8680394 : switch (st->type) {
4595 37120 : case st_const:
4596 37120 : st = st->op2;
4597 37120 : 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 3457644 : case st_alias:
4612 3457644 : if (!st->op1)
4613 179 : 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 3917355 : st = st->op1;
4621 3917355 : continue;
4622 0 : case st_list:
4623 0 : st = st->op4.lval->h->data;
4624 0 : continue;
4625 920449 : case st_bat:
4626 920449 : 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 3160921 : if (st->flag == cmp_project) {
4638 3160887 : st = st->op2;
4639 3160887 : continue;
4640 : }
4641 : /* fall through */
4642 : case st_reorder:
4643 : case st_group:
4644 : case st_tid:
4645 : case st_mirror:
4646 15497 : return sql_bind_localtype("oid");
4647 31211 : case st_result:
4648 31211 : return &st->op4.typeval;
4649 0 : case st_table_clear:
4650 0 : return sql_bind_localtype("lng");
4651 156570 : case st_aggr:
4652 : case st_Nop: {
4653 156570 : list *res = st->op4.funcval->res;
4654 :
4655 156570 : if (res && list_length(res) == 1)
4656 156570 : return res->h->data;
4657 :
4658 : return NULL;
4659 : }
4660 151915 : case st_atom:
4661 151915 : return atom_type(st->op4.aval);
4662 280962 : case st_convert:
4663 : case st_temp:
4664 : case st_single:
4665 : case st_rs_column:
4666 280962 : return &st->op4.typeval;
4667 2295 : case st_var:
4668 2295 : if (st->op4.typeval.type)
4669 2295 : 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 6684 : stmt_has_null(stmt *s)
4684 : {
4685 21114 : 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 8276 : case st_alias:
4693 8276 : return stmt_has_null(s->op1);
4694 6154 : case st_join:
4695 6154 : return stmt_has_null(s->op2);
4696 4255 : case st_bat:
4697 4255 : return s->op4.cval->null;
4698 :
4699 2429 : default:
4700 2429 : 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 2660895 : column_name(allocator *sa, stmt *st)
4734 : {
4735 2660895 : if (!st->cname)
4736 0 : st->cname = _column_name(sa, st);
4737 2660895 : 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 2645583 : table_name(allocator *sa, stmt *st)
4808 : {
4809 2645583 : (void)sa;
4810 2645583 : return st->tname;
4811 : }
4812 :
4813 : const char *
4814 337974 : schema_name(allocator *sa, stmt *st)
4815 : {
4816 3109278 : switch (st->type) {
4817 1195909 : case st_const:
4818 : case st_semijoin:
4819 : case st_join:
4820 : case st_join2:
4821 : case st_joinN:
4822 1195909 : return schema_name(sa, st->op2);
4823 120797 : 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 120797 : if (st->op1)
4843 : return schema_name(sa, st->op1);
4844 : return NULL;
4845 1423332 : case st_alias:
4846 1423332 : if (!st->op1)
4847 : return NULL;
4848 : return schema_name(sa, st->op1);
4849 202409 : case st_bat:
4850 202409 : 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 31421 : case st_list:
4858 31421 : if (list_length(st->op4.lval))
4859 31301 : 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 205 : dump_cols(MalBlkPtr mb, list *l, InstrPtr q)
4980 : {
4981 205 : int i;
4982 205 : node *n;
4983 :
4984 205 : if (q == NULL)
4985 : return NULL;
4986 205 : q->retc = q->argc = 0;
4987 1649 : for (i = 0, n = l->h; n; n = n->next, i++) {
4988 1444 : stmt *c = n->data;
4989 :
4990 1444 : q = pushArgument(mb, q, c->nr);
4991 : }
4992 205 : if (q == NULL)
4993 : return NULL;
4994 205 : q->retc = q->argc;
4995 : /* Let's make it a proper assignment */
4996 1650 : for (i = 0, n = l->h; n; n = n->next, i++) {
4997 1444 : stmt *c = n->data;
4998 :
4999 1444 : q = pushArgument(mb, q, c->nr);
5000 : }
5001 : return q;
5002 : }
5003 :
5004 : stmt *
5005 658 : stmt_return(backend *be, stmt *val, int nr_declared_tables)
5006 : {
5007 658 : MalBlkPtr mb = be->mb;
5008 658 : InstrPtr q = NULL;
5009 :
5010 658 : if (val->nr < 0)
5011 0 : goto bailout;
5012 658 : int args = val->type == st_table ? 2 * list_length(val->op1->op4.lval) : 0;
5013 205 : if (args < MAXARG)
5014 : args = MAXARG;
5015 658 : q = newInstructionArgs(mb, NULL, NULL, args);
5016 657 : if (q == NULL)
5017 0 : goto bailout;
5018 657 : q->barrier= RETURNsymbol;
5019 657 : if (val->type == st_table) {
5020 205 : list *l = val->op1->op4.lval;
5021 :
5022 205 : q = dump_cols(mb, l, q);
5023 : } else {
5024 452 : getArg(q, 0) = getArg(getInstrPtr(mb, 0), 0);
5025 452 : q = pushArgument(mb, q, val->nr);
5026 : }
5027 :
5028 658 : bool enabled = be->mvc->sa->eb.enabled;
5029 658 : be->mvc->sa->eb.enabled = false;
5030 658 : stmt *s = stmt_create(be->mvc->sa, st_return);
5031 658 : be->mvc->sa->eb.enabled = enabled;
5032 658 : if(!s) {
5033 0 : freeInstruction(q);
5034 0 : goto bailout;
5035 : }
5036 658 : s->op1 = val;
5037 658 : s->flag = nr_declared_tables;
5038 658 : s->nr = getDestVar(q);
5039 658 : s->q = q;
5040 658 : pushInstruction(mb, q);
5041 658 : 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 1418 : stmt_assign(backend *be, const char *sname, const char *varname, stmt *val, int level)
5051 : {
5052 1418 : MalBlkPtr mb = be->mb;
5053 1418 : InstrPtr q = NULL;
5054 :
5055 1418 : if (val && val->nr < 0)
5056 0 : goto bailout;
5057 1418 : 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 381 : assert(sname); /* all global variables have a schema */
5081 381 : q = newStmt(mb, sqlRef, setVariableRef);
5082 381 : if (q == NULL)
5083 0 : goto bailout;
5084 381 : q = pushArgument(mb, q, be->mvc_var);
5085 381 : q = pushStr(mb, q, sname);
5086 381 : q = pushStr(mb, q, varname);
5087 381 : getArg(q, 0) = be->mvc_var = newTmpVariable(mb, TYPE_int);
5088 381 : pushInstruction(mb, q);
5089 381 : be->mvc_var = getDestVar(q);
5090 : }
5091 1418 : q = pushArgument(mb, q, val->nr);
5092 :
5093 1418 : bool enabled = be->mvc->sa->eb.enabled;
5094 1418 : be->mvc->sa->eb.enabled = false;
5095 1418 : stmt *s = stmt_create(be->mvc->sa, st_assign);
5096 1418 : be->mvc->sa->eb.enabled = enabled;
5097 1418 : if(!s) {
5098 0 : goto bailout;
5099 : }
5100 1418 : s->op2 = val;
5101 1418 : s->flag = (level << 1);
5102 1418 : s->q = q;
5103 1418 : s->nr = 1;
5104 1418 : 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 21627 : const_column(backend *be, stmt *val)
5114 : {
5115 21627 : sql_subtype *ct = tail_type(val);
5116 21627 : MalBlkPtr mb = be->mb;
5117 21627 : InstrPtr q = NULL;
5118 21627 : int tt = ct->type->localtype;
5119 :
5120 21627 : if (val->nr < 0)
5121 0 : goto bailout;
5122 21627 : q = newStmt(mb, batRef, singleRef);
5123 21627 : if (q == NULL)
5124 0 : goto bailout;
5125 21627 : setVarType(mb, getArg(q, 0), newBatType(tt));
5126 21627 : q = pushArgument(mb, q, val->nr);
5127 :
5128 21627 : bool enabled = be->mvc->sa->eb.enabled;
5129 21627 : be->mvc->sa->eb.enabled = false;
5130 21627 : stmt *s = stmt_create(be->mvc->sa, st_single);
5131 21627 : be->mvc->sa->eb.enabled = enabled;
5132 21627 : if(!s) {
5133 0 : freeInstruction(q);
5134 0 : goto bailout;
5135 : }
5136 21627 : s->op1 = val;
5137 21627 : s->op4.typeval = *ct;
5138 21627 : s->nrcols = 1;
5139 :
5140 21627 : s->tname = val->tname;
5141 21627 : s->cname = val->cname;
5142 21627 : s->nr = getDestVar(q);
5143 21627 : s->q = q;
5144 21627 : pushInstruction(mb, q);
5145 21627 : 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 1633155 : stmt_rename(backend *be, sql_exp *exp, stmt *s )
5206 : {
5207 1633155 : int label = exp_get_label(exp);
5208 1632999 : const char *name = exp_name(exp);
5209 1633312 : const char *rname = exp_relname(exp);
5210 1632979 : stmt *o = s;
5211 :
5212 1632979 : if (!name && exp_is_atom(exp))
5213 0 : name = sa_strdup(be->mvc->sa, "single_value");
5214 0 : assert(name);
5215 1632979 : s = stmt_alias(be, s, label, rname, name);
5216 1633075 : if (o->flag & OUTER_ZERO)
5217 521 : s->flag |= OUTER_ZERO;
5218 1633075 : return s;
5219 : }
|