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, 2025 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 18065 : convertMultiplexMod(const char *mod, const char *op)
31 : {
32 18065 : if (strcmp(op, "=") == 0)
33 0 : return "calc";
34 : return mod;
35 : }
36 :
37 : static const char *
38 327232 : convertMultiplexFcn(const char *op)
39 : {
40 327232 : if (strcmp(op, "=") == 0)
41 52415 : return "==";
42 : return op;
43 : }
44 :
45 : static InstrPtr
46 17989 : multiplex2(MalBlkPtr mb, const char *mod, const char *name, int o1, int o2, int rtype)
47 : {
48 17989 : InstrPtr q = NULL;
49 :
50 17989 : q = newStmt(mb, malRef, multiplexRef);
51 17989 : if (q == NULL)
52 : return NULL;
53 17989 : setVarType(mb, getArg(q, 0), newBatType(rtype));
54 17989 : q = pushStr(mb, q, convertMultiplexMod(mod, name));
55 17989 : q = pushStr(mb, q, convertMultiplexFcn(name));
56 17989 : q = pushArgument(mb, q, o1);
57 17989 : q = pushArgument(mb, q, o2);
58 17989 : pushInstruction(mb, q);
59 17989 : return q;
60 : }
61 :
62 : static InstrPtr
63 51576 : dump_1(MalBlkPtr mb, const char *mod, const char *name, stmt *o1)
64 : {
65 51576 : InstrPtr q = NULL;
66 :
67 51576 : if (o1 == NULL || o1->nr < 0)
68 : return NULL;
69 51576 : q = newStmt(mb, mod, name);
70 51576 : q = pushArgument(mb, q, o1->nr);
71 51576 : pushInstruction(mb, q);
72 51576 : return q;
73 : }
74 :
75 : static InstrPtr
76 181007 : dump_2(MalBlkPtr mb, const char *mod, const char *name, stmt *o1, stmt *o2)
77 : {
78 181007 : InstrPtr q = NULL;
79 :
80 181007 : if (o1 == NULL || o2 == NULL || o1->nr < 0 || o2->nr < 0)
81 : return NULL;
82 181007 : q = newStmt(mb, mod, name);
83 181007 : q = pushArgument(mb, q, o1->nr);
84 181007 : q = pushArgument(mb, q, o2->nr);
85 181007 : pushInstruction(mb, q);
86 181007 : return q;
87 : }
88 :
89 : InstrPtr
90 319 : pushPtr(MalBlkPtr mb, InstrPtr q, ptr val)
91 : {
92 319 : int _t;
93 319 : ValRecord cst;
94 :
95 319 : if (q == NULL || mb->errors)
96 : return q;
97 319 : cst.vtype= TYPE_ptr;
98 319 : cst.val.pval = val;
99 319 : cst.len = 0;
100 319 : _t = defConstant(mb, TYPE_ptr, &cst);
101 319 : if( _t >= 0)
102 319 : return pushArgument(mb, q, _t);
103 : return q;
104 : }
105 :
106 : static InstrPtr
107 2210306 : pushSchema(MalBlkPtr mb, InstrPtr q, sql_table *t)
108 : {
109 2210306 : if (t->s)
110 2210306 : 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 211 : stmt_atom_string(backend *be, const char *S)
126 : {
127 211 : const char *s = sa_strdup(be->mvc->sa, S);
128 211 : sql_subtype t;
129 :
130 211 : if (s == NULL)
131 : return NULL;
132 211 : sql_find_subtype(&t, "varchar", _strlen(s), 0);
133 211 : return stmt_atom(be, atom_string(be->mvc->sa, &t, s));
134 : }
135 :
136 : stmt *
137 19926 : stmt_atom_string_nil(backend *be)
138 : {
139 19926 : sql_subtype t;
140 :
141 19926 : sql_find_subtype(&t, "varchar", 0, 0);
142 19926 : return stmt_atom(be, atom_string(be->mvc->sa, &t, NULL));
143 : }
144 :
145 : stmt *
146 5902 : stmt_atom_int(backend *be, int i)
147 : {
148 5902 : sql_subtype t;
149 :
150 5902 : sql_find_subtype(&t, "int", 32, 0);
151 5902 : return stmt_atom(be, atom_int(be->mvc->sa, &t, i));
152 : }
153 :
154 : stmt *
155 117369 : stmt_atom_lng(backend *be, lng i)
156 : {
157 117369 : sql_subtype t;
158 :
159 117369 : sql_find_subtype(&t, "bigint", 64, 0);
160 117380 : 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 43097 : stmt_bool(backend *be, int b)
174 : {
175 43097 : sql_subtype t;
176 :
177 43097 : sql_find_subtype(&t, "boolean", 0, 0);
178 :
179 43097 : if (b == bit_nil) {
180 0 : return stmt_atom(be, atom_bool(be->mvc->sa, &t, bit_nil));
181 43097 : } else if (b) {
182 41966 : return stmt_atom(be, atom_bool(be->mvc->sa, &t, TRUE));
183 : } else {
184 1131 : return stmt_atom(be, atom_bool(be->mvc->sa, &t, FALSE));
185 : }
186 : }
187 :
188 : static stmt *
189 18203066 : stmt_create(allocator *sa, st_type type)
190 : {
191 18203066 : stmt *s = SA_NEW(sa, stmt);
192 :
193 18202613 : if (!s)
194 : return NULL;
195 18202613 : *s = (stmt) {
196 : .type = type,
197 : };
198 18202613 : return s;
199 : }
200 :
201 : stmt *
202 28191 : stmt_group(backend *be, stmt *s, stmt *grp, stmt *ext, stmt *cnt, int done)
203 : {
204 28191 : MalBlkPtr mb = be->mb;
205 28191 : InstrPtr q = NULL;
206 :
207 28191 : if (s == NULL || s->nr < 0)
208 0 : goto bailout;
209 28191 : if (grp && (grp->nr < 0 || ext->nr < 0 || cnt->nr < 0))
210 0 : goto bailout;
211 :
212 49975 : q = newStmt(mb, groupRef, done ? grp ? subgroupdoneRef : groupdoneRef : grp ? subgroupRef : groupRef);
213 28191 : if (q == NULL)
214 0 : goto bailout;
215 :
216 : /* output variables extent and hist */
217 28191 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
218 28191 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
219 28191 : q = pushArgument(mb, q, s->nr);
220 28191 : if (grp)
221 6407 : q = pushArgument(mb, q, grp->nr);
222 :
223 28191 : bool enabled = be->mvc->sa->eb.enabled;
224 28191 : be->mvc->sa->eb.enabled = false;
225 28191 : stmt *ns = stmt_create(be->mvc->sa, st_group);
226 28191 : be->mvc->sa->eb.enabled = enabled;
227 28191 : if (ns == NULL) {
228 0 : freeInstruction(q);
229 0 : goto bailout;
230 : }
231 :
232 28191 : ns->op1 = s;
233 :
234 28191 : if (grp) {
235 6407 : ns->op2 = grp;
236 6407 : ns->op3 = ext;
237 6407 : ns->op4.stval = cnt;
238 : }
239 28191 : ns->nrcols = s->nrcols;
240 28191 : ns->key = 0;
241 28191 : ns->q = q;
242 28191 : ns->nr = getDestVar(q);
243 28191 : pushInstruction(mb, q);
244 28191 : return ns;
245 :
246 0 : bailout:
247 0 : if (be->mvc->sa->eb.enabled)
248 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
249 : return NULL;
250 : }
251 :
252 : stmt *
253 76 : stmt_unique(backend *be, stmt *s)
254 : {
255 76 : MalBlkPtr mb = be->mb;
256 76 : InstrPtr q = NULL;
257 :
258 76 : if (s == NULL || s->nr < 0)
259 0 : goto bailout;
260 :
261 76 : q = newStmt(mb, algebraRef, uniqueRef);
262 76 : if (q == NULL)
263 0 : goto bailout;
264 :
265 76 : q = pushArgument(mb, q, s->nr);
266 76 : q = pushNilBat(mb, q); /* candidate list */
267 :
268 76 : bool enabled = be->mvc->sa->eb.enabled;
269 76 : be->mvc->sa->eb.enabled = false;
270 76 : stmt *ns = stmt_create(be->mvc->sa, st_unique);
271 76 : be->mvc->sa->eb.enabled = enabled;
272 76 : if (ns == NULL) {
273 0 : freeInstruction(q);
274 0 : goto bailout;
275 : }
276 :
277 76 : ns->op1 = s;
278 76 : ns->nrcols = s->nrcols;
279 76 : ns->key = 1;
280 76 : ns->q = q;
281 76 : ns->nr = getDestVar(q);
282 76 : pushInstruction(mb, q);
283 76 : return ns;
284 :
285 0 : bailout:
286 0 : if (be->mvc->sa->eb.enabled)
287 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
288 : return NULL;
289 : }
290 :
291 : stmt *
292 0 : stmt_none(backend *be)
293 : {
294 0 : return stmt_create(be->mvc->sa, st_none);
295 : }
296 :
297 : static int
298 55 : create_bat(MalBlkPtr mb, int tt)
299 : {
300 55 : InstrPtr q = newStmt(mb, batRef, newRef);
301 :
302 55 : if (q == NULL)
303 : return -1;
304 55 : setVarType(mb, getArg(q, 0), newBatType(tt));
305 55 : q = pushType(mb, q, tt);
306 55 : pushInstruction(mb, q);
307 55 : return getDestVar(q);
308 : }
309 :
310 : stmt *
311 116 : stmt_bat_new(backend *be, sql_subtype *tpe, lng estimate)
312 : {
313 116 : InstrPtr q = newStmt(be->mb, batRef, newRef);
314 116 : int tt = tpe->type->localtype;
315 :
316 116 : if (q == NULL)
317 : return NULL;
318 116 : if (tt == TYPE_void)
319 1 : tt = TYPE_bte;
320 116 : setVarType(be->mb, getArg(q, 0), newBatType(tt));
321 116 : q = pushType(be->mb, q, tt);
322 116 : if (estimate > 0)
323 0 : q = pushInt(be->mb, q, (int)estimate);
324 116 : pushInstruction(be->mb, q);
325 :
326 116 : stmt *s = stmt_create(be->mvc->sa, st_alias);
327 116 : s->op4.typeval = *tpe;
328 116 : s->q = q;
329 116 : s->nr = q->argv[0];
330 116 : s->nrcols = 2;
331 116 : return s;
332 : }
333 :
334 : static int *
335 20 : dump_table(allocator *sa, MalBlkPtr mb, sql_table *t)
336 : {
337 20 : int i = 0;
338 20 : node *n;
339 20 : int *l = SA_NEW_ARRAY(sa, int, ol_length(t->columns) + 1);
340 :
341 20 : if (!l)
342 : return NULL;
343 :
344 : /* tid column */
345 20 : if ((l[i++] = create_bat(mb, TYPE_oid)) < 0)
346 : return NULL;
347 :
348 55 : for (n = ol_first_node(t->columns); n; n = n->next) {
349 35 : sql_column *c = n->data;
350 :
351 35 : if ((l[i++] = create_bat(mb, c->type.type->localtype)) < 0)
352 : return NULL;
353 : }
354 : return l;
355 : }
356 :
357 : stmt *
358 2780 : stmt_var(backend *be, const char *sname, const char *varname, sql_subtype *t, int declare, int level)
359 : {
360 2780 : MalBlkPtr mb = be->mb;
361 2780 : InstrPtr q = NULL;
362 2780 : char *buf;
363 :
364 2780 : 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 2349 : } else if (!declare) {
376 1959 : char levelstr[16];
377 :
378 1959 : assert(!sname);
379 1959 : snprintf(levelstr, sizeof(levelstr), "%d", level);
380 1959 : buf = SA_NEW_ARRAY(be->mvc->sa, char, strlen(levelstr) + strlen(varname) + 3);
381 1959 : if (!buf)
382 1 : goto bailout;
383 1959 : stpcpy(stpcpy(stpcpy(stpcpy(buf, "A"), levelstr), "%"), varname); /* mangle variable name */
384 1959 : q = newAssignment(mb);
385 1959 : if (q == NULL)
386 1 : goto bailout;
387 1958 : q = pushArgumentId(mb, q, buf);
388 : } else {
389 390 : int tt = t->type->localtype;
390 390 : char levelstr[16];
391 :
392 390 : assert(!sname);
393 390 : snprintf(levelstr, sizeof(levelstr), "%d", level);
394 390 : buf = SA_NEW_ARRAY(be->mvc->sa, char, strlen(levelstr) + strlen(varname) + 3);
395 390 : if (!buf)
396 0 : goto bailout;
397 390 : stpcpy(stpcpy(stpcpy(stpcpy(buf, "A"), levelstr), "%"), varname); /* mangle variable name */
398 :
399 390 : q = newInstruction(mb, NULL, NULL);
400 390 : if (q == NULL) {
401 0 : goto bailout;
402 : }
403 390 : q->argc = q->retc = 0;
404 390 : q = pushArgumentId(mb, q, buf);
405 390 : q = pushNil(mb, q, tt);
406 390 : q->retc++;
407 : }
408 2779 : bool enabled = be->mvc->sa->eb.enabled;
409 2779 : be->mvc->sa->eb.enabled = false;
410 2779 : stmt *s = stmt_create(be->mvc->sa, st_var);
411 2779 : be->mvc->sa->eb.enabled = enabled;
412 2779 : if (s == NULL) {
413 0 : freeInstruction(q);
414 0 : goto bailout;
415 : }
416 :
417 2779 : if (t)
418 2779 : s->op4.typeval = *t;
419 : else
420 0 : s->op4.typeval.type = NULL;
421 2779 : s->flag = declare + (level << 1);
422 2779 : s->key = 1;
423 2779 : s->q = q;
424 2779 : s->nr = getDestVar(q);
425 2779 : pushInstruction(mb, q);
426 2779 : 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 2050 : stmt_varnr(backend *be, int nr, sql_subtype *t)
466 : {
467 2050 : MalBlkPtr mb = be->mb;
468 2050 : InstrPtr q = newAssignment(mb);
469 2050 : char buf[IDLENGTH];
470 :
471 2050 : if (q == NULL)
472 0 : goto bailout;
473 :
474 2050 : (void) snprintf(buf, sizeof(buf), "A%d", nr);
475 2050 : q = pushArgumentId(mb, q, buf);
476 :
477 2050 : bool enabled = be->mvc->sa->eb.enabled;
478 2050 : be->mvc->sa->eb.enabled = false;
479 2050 : stmt *s = stmt_create(be->mvc->sa, st_var);
480 2050 : be->mvc->sa->eb.enabled = enabled;
481 2050 : if (s == NULL) {
482 0 : freeInstruction(q);
483 0 : goto bailout;
484 : }
485 :
486 2050 : s->op1 = NULL;
487 2050 : if (t)
488 2050 : s->op4.typeval = *t;
489 : else
490 0 : s->op4.typeval.type = NULL;
491 2050 : s->flag = nr;
492 2050 : s->key = 1;
493 2050 : s->q = q;
494 2050 : s->nr = getDestVar(q);
495 2050 : pushInstruction(mb, q);
496 2050 : 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 689 : stmt_table(backend *be, stmt *cols, int temp)
506 : {
507 689 : MalBlkPtr mb = be->mb;
508 :
509 689 : if (cols == NULL || cols->nr < 0)
510 0 : goto bailout;
511 :
512 689 : stmt *s = stmt_create(be->mvc->sa, st_table);
513 :
514 689 : if (s == NULL)
515 0 : goto bailout;
516 :
517 689 : 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 689 : s->op1 = cols;
529 689 : s->flag = temp;
530 689 : s->nr = cols->nr;
531 689 : s->nrcols = cols->nrcols;
532 689 : 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 222333 : stmt_temp(backend *be, sql_subtype *t)
542 : {
543 222333 : int tt = t->type->localtype;
544 222333 : MalBlkPtr mb = be->mb;
545 222333 : InstrPtr q = newStmt(mb, batRef, newRef);
546 :
547 223233 : if (q == NULL)
548 0 : goto bailout;
549 223233 : setVarType(mb, getArg(q, 0), newBatType(tt));
550 223233 : q = pushType(mb, q, tt);
551 223083 : bool enabled = be->mvc->sa->eb.enabled;
552 223083 : be->mvc->sa->eb.enabled = false;
553 223083 : stmt *s = stmt_create(be->mvc->sa, st_temp);
554 222982 : be->mvc->sa->eb.enabled = enabled;
555 :
556 222982 : if (s == NULL) {
557 0 : freeInstruction(q);
558 0 : goto bailout;
559 : }
560 222982 : s->op4.typeval = *t;
561 222982 : s->nrcols = 1;
562 222982 : s->q = q;
563 222982 : s->nr = getDestVar(q);
564 222982 : pushInstruction(mb, q);
565 222982 : 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 408 : stmt_blackbox_result(backend *be, InstrPtr q, int retnr, sql_subtype *t)
575 : {
576 408 : if (q == NULL)
577 : return NULL;
578 408 : stmt *s = stmt_create(be->mvc->sa, st_result);
579 408 : if (s == NULL)
580 : return NULL;
581 408 : s->op4.typeval = *t;
582 408 : s->nrcols = 1;
583 408 : s->q = q;
584 408 : s->nr = getArg(q, retnr);
585 408 : s->flag = retnr;
586 408 : return s;
587 : }
588 :
589 :
590 : stmt *
591 205020 : stmt_tid(backend *be, sql_table *t, int partition)
592 : {
593 205020 : int tt = TYPE_oid;
594 205020 : MalBlkPtr mb = be->mb;
595 205020 : InstrPtr q;
596 :
597 205020 : 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 205004 : q = newStmt(mb, sqlRef, tidRef);
612 205178 : if (q == NULL)
613 0 : goto bailout;
614 205178 : setVarType(mb, getArg(q, 0), newBatType(tt));
615 205178 : q = pushArgument(mb, q, be->mvc_var);
616 205180 : q = pushSchema(mb, q, t);
617 205160 : q = pushStr(mb, q, t->base.name);
618 205166 : if (t && isTable(t) && partition) {
619 76851 : sql_trans *tr = be->mvc->session->tr;
620 76851 : sqlstore *store = tr->store;
621 76851 : BUN rows = (BUN) store->storage_api.count_col(tr, ol_first_node(t->columns)->data, RDONLY);
622 76851 : setRowCnt(mb,getArg(q,0),rows);
623 : }
624 :
625 205166 : bool enabled = be->mvc->sa->eb.enabled;
626 205166 : be->mvc->sa->eb.enabled = false;
627 205166 : stmt *s = stmt_create(be->mvc->sa, st_tid);
628 205061 : be->mvc->sa->eb.enabled = enabled;
629 205061 : if (s == NULL) {
630 0 : freeInstruction(q);
631 0 : goto bailout;
632 : }
633 :
634 205061 : s->partition = partition;
635 205061 : s->op4.tval = t;
636 205061 : s->nrcols = 1;
637 205061 : s->nr = getDestVar(q);
638 205061 : s->q = q;
639 205061 : pushInstruction(mb, q);
640 205061 : 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 1004059 : find_real_column(backend *be, sql_column *c)
650 : {
651 1004059 : 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 1004058 : stmt_bat(backend *be, sql_column *c, int access, int partition)
664 : {
665 1004058 : int tt = c->type.type->localtype;
666 1004058 : MalBlkPtr mb = be->mb;
667 1004058 : InstrPtr q;
668 :
669 1004058 : c = find_real_column(be, c);
670 :
671 1004081 : if (access == RD_EXT)
672 176 : partition = 0;
673 :
674 : /* for read access tid.project(col) */
675 1004081 : 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 1004058 : q = newStmtArgs(mb, sqlRef, bindRef, 9);
693 1004115 : if (q == NULL)
694 0 : goto bailout;
695 1004115 : 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 1003939 : if (access == RD_UPD_ID) {
706 487811 : q = pushReturn(mb, q, newTmpVariable(mb, newBatType(tt)));
707 : } else {
708 516304 : setVarType(mb, getArg(q, 0), newBatType(tt));
709 : }
710 1004112 : q = pushArgument(mb, q, be->mvc_var);
711 1004112 : q = pushSchema(mb, q, c->t);
712 1004115 : q = pushArgument(mb, q, getStrConstant(mb,c->t->base.name));
713 1004098 : q = pushArgument(mb, q, getStrConstant(mb,c->base.name));
714 1004063 : q = pushArgument(mb, q, getIntConstant(mb,access));
715 :
716 1004067 : if (access == RD_UPD_ID) {
717 487798 : setVarType(mb, getArg(q, 1), newBatType(tt));
718 : }
719 1004067 : if (partition) {
720 555583 : sql_trans *tr = be->mvc->session->tr;
721 555583 : sqlstore *store = tr->store;
722 :
723 555583 : if (c && isTable(c->t)) {
724 555577 : BUN rows = (BUN) store->storage_api.count_col(tr, c, RDONLY);
725 555646 : setRowCnt(mb,getArg(q,0),rows);
726 : }
727 : }
728 :
729 1004136 : bool enabled = be->mvc->sa->eb.enabled;
730 1004136 : be->mvc->sa->eb.enabled = false;
731 1004136 : stmt *s = stmt_create(be->mvc->sa, st_bat);
732 1004124 : be->mvc->sa->eb.enabled = enabled;
733 1004124 : if (s == NULL) {
734 0 : freeInstruction(q);
735 0 : goto bailout;
736 : }
737 :
738 1004124 : s->partition = partition;
739 1004124 : s->op4.cval = c;
740 1004124 : s->nrcols = 1;
741 1004124 : s->flag = access;
742 1004124 : s->nr = getDestVar(q);
743 1004124 : s->q = q;
744 1004124 : s->tname = c->t->base.name;
745 1004124 : s->cname = c->base.name;
746 1004124 : pushInstruction(mb, q);
747 1004124 : 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 6472 : stmt_idxbat(backend *be, sql_idx *i, int access, int partition)
757 : {
758 6472 : int tt = hash_index(i->type)?TYPE_lng:TYPE_oid;
759 6472 : MalBlkPtr mb = be->mb;
760 6472 : InstrPtr q = newStmtArgs(mb, sqlRef, bindidxRef, 9);
761 :
762 6472 : if (q == NULL)
763 0 : goto bailout;
764 :
765 6472 : if (access == RD_UPD_ID) {
766 2871 : q = pushReturn(mb, q, newTmpVariable(mb, newBatType(tt)));
767 : } else {
768 3601 : setVarType(mb, getArg(q, 0), newBatType(tt));
769 : }
770 :
771 6472 : q = pushArgument(mb, q, be->mvc_var);
772 6472 : q = pushSchema(mb, q, i->t);
773 6472 : q = pushArgument(mb, q, getStrConstant(mb, i->t->base.name));
774 6472 : q = pushArgument(mb, q, getStrConstant(mb, i->base.name));
775 6472 : q = pushArgument(mb, q, getIntConstant(mb, access));
776 :
777 6472 : if (access == RD_UPD_ID) {
778 2871 : setVarType(mb, getArg(q, 1), newBatType(tt));
779 : }
780 6472 : if (partition) {
781 3529 : sql_trans *tr = be->mvc->session->tr;
782 3529 : sqlstore *store = tr->store;
783 :
784 3529 : if (i && isTable(i->t)) {
785 3529 : BUN rows = (BUN) store->storage_api.count_idx(tr, i, QUICK);
786 3529 : setRowCnt(mb,getArg(q,0),rows);
787 : }
788 : }
789 :
790 6472 : bool enabled = be->mvc->sa->eb.enabled;
791 6472 : be->mvc->sa->eb.enabled = false;
792 6472 : stmt *s = stmt_create(be->mvc->sa, st_idxbat);
793 6472 : be->mvc->sa->eb.enabled = enabled;
794 6472 : if (s == NULL) {
795 0 : freeInstruction(q);
796 0 : goto bailout;
797 : }
798 :
799 6472 : s->partition = partition;
800 6472 : s->op4.idxval = i;
801 6472 : s->nrcols = 1;
802 6472 : s->flag = access;
803 6472 : s->nr = getDestVar(q);
804 6472 : s->q = q;
805 6472 : s->tname = i->t->base.name;
806 6472 : s->cname = i->base.name;
807 6472 : pushInstruction(mb, q);
808 6472 : 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 674554 : stmt_append_col(backend *be, sql_column *c, stmt *offset, stmt *b, int *mvc_var_update, int fake)
818 : {
819 674554 : MalBlkPtr mb = be->mb;
820 674554 : InstrPtr q = NULL;
821 :
822 674554 : if (b == NULL || b->nr < 0)
823 0 : goto bailout;
824 :
825 674554 : 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 674531 : } else if (!fake) { /* fake append */
844 674531 : if (offset == NULL || offset->nr < 0)
845 0 : goto bailout;
846 674531 : q = newStmt(mb, sqlRef, appendRef);
847 675095 : if (q == NULL)
848 0 : goto bailout;
849 675095 : q = pushArgument(mb, q, be->mvc_var);
850 675084 : int tmpvar = newTmpVariable(mb, TYPE_int);
851 675083 : getArg(q, 0) = tmpvar;
852 675083 : if (mvc_var_update != NULL)
853 675083 : *mvc_var_update = tmpvar;
854 675083 : q = pushSchema(mb, q, c->t);
855 675058 : q = pushStr(mb, q, c->t->base.name);
856 675105 : q = pushStr(mb, q, c->base.name);
857 674946 : q = pushArgument(mb, q, offset->nr);
858 : /* also the offsets */
859 674979 : assert(offset->q->retc == 2);
860 674979 : q = pushArgument(mb, q, getArg(offset->q, 1));
861 674941 : q = pushArgument(mb, q, b->nr);
862 674917 : if (mvc_var_update != NULL)
863 674917 : *mvc_var_update = getDestVar(q);
864 : } else {
865 : return b;
866 : }
867 674940 : bool enabled = be->mvc->sa->eb.enabled;
868 674940 : be->mvc->sa->eb.enabled = false;
869 674940 : stmt *s = stmt_create(be->mvc->sa, st_append_col);
870 674815 : be->mvc->sa->eb.enabled = enabled;
871 :
872 674815 : if (s == NULL) {
873 0 : freeInstruction(q);
874 0 : goto bailout;
875 : }
876 674815 : s->op1 = b;
877 674815 : s->op2 = offset;
878 674815 : s->op4.cval = c;
879 674815 : s->q = q;
880 674815 : s->nr = getDestVar(q);
881 674815 : pushInstruction(mb, q);
882 674815 : 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 2225 : stmt_append_idx(backend *be, sql_idx *i, stmt *offset, stmt *b)
892 : {
893 2225 : MalBlkPtr mb = be->mb;
894 2225 : InstrPtr q = NULL;
895 :
896 2225 : if (offset == NULL || b == NULL || offset->nr < 0 || b->nr < 0)
897 0 : goto bailout;
898 :
899 2225 : q = newStmt(mb, sqlRef, appendRef);
900 2225 : if (q == NULL)
901 0 : goto bailout;
902 2225 : q = pushArgument(mb, q, be->mvc_var);
903 2225 : getArg(q, 0) = be->mvc_var = newTmpVariable(mb, TYPE_int);
904 2225 : q = pushSchema(mb, q, i->t);
905 2225 : q = pushStr(mb, q, i->t->base.name);
906 2225 : q = pushStr(mb, q, sa_strconcat(be->mvc->sa, "%", i->base.name));
907 2225 : q = pushArgument(mb, q, offset->nr);
908 : /* also the offsets */
909 2225 : assert(offset->q->retc == 2);
910 2225 : q = pushArgument(mb, q, getArg(offset->q, 1));
911 2225 : q = pushArgument(mb, q, b->nr);
912 2225 : be->mvc_var = getDestVar(q);
913 :
914 2225 : bool enabled = be->mvc->sa->eb.enabled;
915 2225 : be->mvc->sa->eb.enabled = false;
916 2225 : stmt *s = stmt_create(be->mvc->sa, st_append_idx);
917 2225 : be->mvc->sa->eb.enabled = enabled;
918 2225 : if (s == NULL) {
919 0 : freeInstruction(q);
920 0 : goto bailout;
921 : }
922 :
923 2225 : s->op1 = b;
924 2225 : s->op2 = offset;
925 2225 : s->op4.idxval = i;
926 2225 : s->q = q;
927 2225 : s->nr = getDestVar(q);
928 2225 : pushInstruction(mb, q);
929 2225 : 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 3259 : stmt_update_col(backend *be, sql_column *c, stmt *tids, stmt *upd)
939 : {
940 3259 : MalBlkPtr mb = be->mb;
941 3259 : InstrPtr q = NULL;
942 :
943 3259 : if (tids == NULL || upd == NULL || tids->nr < 0 || upd->nr < 0)
944 0 : goto bailout;
945 :
946 3260 : 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 3258 : q = newStmt(mb, sqlRef, updateRef);
957 3258 : if (q == NULL)
958 0 : goto bailout;
959 3258 : q = pushArgument(mb, q, be->mvc_var);
960 3258 : getArg(q, 0) = be->mvc_var = newTmpVariable(mb, TYPE_int);
961 3258 : q = pushSchema(mb, q, c->t);
962 3258 : q = pushStr(mb, q, c->t->base.name);
963 3258 : q = pushStr(mb, q, c->base.name);
964 3258 : q = pushArgument(mb, q, tids->nr);
965 3258 : q = pushArgument(mb, q, upd->nr);
966 3258 : be->mvc_var = getDestVar(q);
967 : }
968 3259 : bool enabled = be->mvc->sa->eb.enabled;
969 3259 : be->mvc->sa->eb.enabled = false;
970 3259 : stmt *s = stmt_create(be->mvc->sa, st_update_col);
971 3259 : be->mvc->sa->eb.enabled = enabled;
972 :
973 3259 : if (s == NULL) {
974 0 : freeInstruction(q);
975 0 : goto bailout;
976 : }
977 3259 : s->op1 = tids;
978 3259 : s->op2 = upd;
979 3259 : s->op4.cval = c;
980 3259 : s->q = q;
981 3259 : s->nr = getDestVar(q);
982 3259 : pushInstruction(mb, q);
983 3259 : 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 127261 : stmt_const(backend *be, stmt *s, stmt *val)
1087 : {
1088 127261 : InstrPtr q = NULL;
1089 127261 : MalBlkPtr mb = be->mb;
1090 :
1091 127261 : if (s == NULL)
1092 0 : goto bailout;
1093 127261 : if (val)
1094 127261 : q = dump_2(mb, algebraRef, projectRef, s, val);
1095 : else
1096 0 : q = dump_1(mb, algebraRef, projectRef, s);
1097 127261 : if (q) {
1098 127261 : stmt *ns = stmt_create(be->mvc->sa, st_const);
1099 127261 : if (ns == NULL) {
1100 0 : goto bailout;
1101 : }
1102 :
1103 127261 : ns->op1 = s;
1104 127261 : ns->op2 = val;
1105 127261 : ns->nrcols = s->nrcols;
1106 127261 : ns->key = s->key;
1107 127261 : ns->aggr = s->aggr;
1108 127261 : ns->q = q;
1109 127261 : ns->nr = getDestVar(q);
1110 127261 : ns->tname = val->tname;
1111 127261 : ns->cname = val->cname;
1112 127261 : 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 51576 : stmt_mirror(backend *be, stmt *s)
1154 : {
1155 51576 : MalBlkPtr mb = be->mb;
1156 :
1157 51576 : if (s == NULL)
1158 0 : goto bailout;
1159 :
1160 51576 : InstrPtr q = dump_1(mb, batRef, mirrorRef, s);
1161 :
1162 51576 : if (q) {
1163 51576 : stmt *ns = stmt_create(be->mvc->sa, st_mirror);
1164 51576 : if (ns == NULL) {
1165 0 : goto bailout;
1166 : }
1167 :
1168 51576 : ns->op1 = s;
1169 51576 : ns->nrcols = 2;
1170 51576 : ns->key = s->key;
1171 51576 : ns->aggr = s->aggr;
1172 51576 : ns->q = q;
1173 51576 : ns->nr = getDestVar(q);
1174 51576 : 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 329955 : stmt_result(backend *be, stmt *s, int nr)
1185 : {
1186 329955 : stmt *ns;
1187 :
1188 329955 : if (s == NULL)
1189 : return NULL;
1190 :
1191 329955 : if (s->type == st_join && s->flag == cmp_joined) {
1192 5560 : if (nr)
1193 2324 : return s->op2;
1194 3236 : return s->op1;
1195 : }
1196 :
1197 324395 : if (s->op1->nr < 0)
1198 : return NULL;
1199 :
1200 324395 : ns = stmt_create(be->mvc->sa, st_result);
1201 324395 : if(!ns) {
1202 : return NULL;
1203 : }
1204 324395 : if (s->op1->type == st_join && s->op1->flag == cmp_joined) {
1205 0 : assert(0);
1206 324395 : } else if (nr) {
1207 186188 : int v = getArg(s->q, nr);
1208 :
1209 186188 : assert(s->q->retc > nr);
1210 186188 : ns->nr = v;
1211 : } else {
1212 138207 : ns->nr = s->nr;
1213 : }
1214 324395 : ns->op1 = s;
1215 324395 : if (!nr && (s->type == st_order || s->type == st_reorder))
1216 26268 : ns->op4.typeval = *tail_type(s->op1);
1217 186188 : else if (nr && ((s->type == st_join && s->flag == MARKJOIN) || (s->type == st_uselect2 && s->flag == MARKJOIN)))
1218 2978 : ns->op4.typeval = *sql_bind_localtype("bit");
1219 : else
1220 295149 : ns->op4.typeval = *sql_bind_localtype("oid");
1221 324395 : ns->flag = nr;
1222 324395 : ns->nrcols = s->nrcols;
1223 324395 : ns->key = s->key;
1224 324395 : ns->aggr = s->aggr;
1225 324395 : return ns;
1226 : }
1227 :
1228 :
1229 : /* limit maybe atom nil */
1230 : stmt *
1231 17547 : 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 17547 : MalBlkPtr mb = be->mb;
1234 17547 : InstrPtr q = NULL;
1235 17547 : int l, g, c;
1236 :
1237 17547 : if (col == NULL || offset == NULL || limit == NULL || col->nr < 0 || offset->nr < 0 || limit->nr < 0)
1238 0 : goto bailout;
1239 17547 : if (piv && (piv->nr < 0 || (gid && gid->nr < 0)))
1240 0 : goto bailout;
1241 :
1242 17547 : c = (col) ? col->nr : 0;
1243 17547 : g = (gid) ? gid->nr : 0;
1244 :
1245 : /* first insert single value into a bat */
1246 17547 : 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 17547 : 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 16957 : int len;
1329 :
1330 16957 : q = newStmt(mb, calcRef, plusRef);
1331 16986 : if (q == NULL)
1332 0 : goto bailout;
1333 16986 : q = pushArgument(mb, q, offset->nr);
1334 16986 : q = pushArgument(mb, q, limit->nr);
1335 16986 : len = getDestVar(q);
1336 16986 : pushInstruction(mb, q);
1337 :
1338 : /* since both arguments of algebra.subslice are
1339 : inclusive correct the LIMIT value by
1340 : subtracting 1 */
1341 16986 : q = newStmt(mb, calcRef, minusRef);
1342 16987 : if (q == NULL)
1343 0 : goto bailout;
1344 16987 : q = pushArgument(mb, q, len);
1345 16987 : q = pushInt(mb, q, 1);
1346 16987 : len = getDestVar(q);
1347 16987 : pushInstruction(mb, q);
1348 :
1349 16987 : q = newStmt(mb, algebraRef, subsliceRef);
1350 16987 : if (q == NULL)
1351 0 : goto bailout;
1352 16987 : q = pushArgument(mb, q, c);
1353 16987 : q = pushArgument(mb, q, offset->nr);
1354 16987 : q = pushArgument(mb, q, len);
1355 16986 : l = getDestVar(q);
1356 16986 : pushInstruction(mb, q);
1357 : }
1358 : /* retrieve the single values again */
1359 17576 : 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 34842 : stmt *ns = stmt_create(be->mvc->sa, piv?st_limit2:st_limit);
1370 17576 : if (ns == NULL) {
1371 0 : goto bailout;
1372 : }
1373 :
1374 17576 : ns->op1 = col;
1375 17576 : ns->op2 = offset;
1376 17576 : ns->op3 = limit;
1377 17576 : ns->nrcols = col->nrcols;
1378 17576 : ns->key = col->key;
1379 17576 : ns->aggr = col->aggr;
1380 17576 : ns->q = q;
1381 17576 : ns->nr = l;
1382 17576 : 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 12970 : stmt_order(backend *be, stmt *s, int direction, int nullslast)
1445 : {
1446 12970 : MalBlkPtr mb = be->mb;
1447 12970 : InstrPtr q = NULL;
1448 :
1449 12970 : if (s == NULL || s->nr < 0)
1450 0 : goto bailout;
1451 12970 : q = newStmt(mb, algebraRef, sortRef);
1452 12970 : if (q == NULL)
1453 0 : goto bailout;
1454 : /* both ordered result and oid's order en subgroups */
1455 12970 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
1456 12970 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
1457 12970 : q = pushArgument(mb, q, s->nr);
1458 12970 : q = pushBit(mb, q, !direction);
1459 12970 : q = pushBit(mb, q, nullslast);
1460 12970 : q = pushBit(mb, q, FALSE);
1461 :
1462 12970 : bool enabled = be->mvc->sa->eb.enabled;
1463 12970 : be->mvc->sa->eb.enabled = false;
1464 12970 : stmt *ns = stmt_create(be->mvc->sa, st_order);
1465 12970 : be->mvc->sa->eb.enabled = enabled;
1466 12970 : if (ns == NULL) {
1467 0 : freeInstruction(q);
1468 0 : goto bailout;
1469 : }
1470 :
1471 12970 : ns->op1 = s;
1472 12970 : ns->flag = direction;
1473 12970 : ns->nrcols = s->nrcols;
1474 12970 : ns->key = s->key;
1475 12970 : ns->aggr = s->aggr;
1476 12970 : ns->q = q;
1477 12970 : ns->nr = getDestVar(q);
1478 12970 : pushInstruction(mb, q);
1479 12970 : 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 13823 : stmt_reorder(backend *be, stmt *s, int direction, int nullslast, stmt *orderby_ids, stmt *orderby_grp)
1489 : {
1490 13823 : MalBlkPtr mb = be->mb;
1491 13823 : InstrPtr q = NULL;
1492 :
1493 13823 : 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 13823 : q = newStmtArgs(mb, algebraRef, sortRef, 9);
1496 13823 : if (q == NULL)
1497 0 : goto bailout;
1498 : /* both ordered result and oid's order en subgroups */
1499 13823 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
1500 13823 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
1501 13823 : q = pushArgument(mb, q, s->nr);
1502 13823 : q = pushArgument(mb, q, orderby_ids->nr);
1503 13823 : q = pushArgument(mb, q, orderby_grp->nr);
1504 13823 : q = pushBit(mb, q, !direction);
1505 13823 : q = pushBit(mb, q, nullslast);
1506 13823 : q = pushBit(mb, q, FALSE);
1507 :
1508 13823 : bool enabled = be->mvc->sa->eb.enabled;
1509 13823 : be->mvc->sa->eb.enabled = false;
1510 13823 : stmt *ns = stmt_create(be->mvc->sa, st_reorder);
1511 13823 : be->mvc->sa->eb.enabled = enabled;
1512 13823 : if (ns == NULL) {
1513 0 : freeInstruction(q);
1514 0 : goto bailout;
1515 : }
1516 :
1517 13823 : ns->op1 = s;
1518 13823 : ns->op2 = orderby_ids;
1519 13823 : ns->op3 = orderby_grp;
1520 13823 : ns->flag = direction;
1521 13823 : ns->nrcols = s->nrcols;
1522 13823 : ns->key = s->key;
1523 13823 : ns->aggr = s->aggr;
1524 13823 : ns->nr = getDestVar(q);
1525 13823 : ns->q = q;
1526 13823 : pushInstruction(mb, q);
1527 13823 : 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 3502791 : stmt_atom(backend *be, atom *a)
1537 : {
1538 3502791 : MalBlkPtr mb = be->mb;
1539 :
1540 3502791 : if (a == NULL)
1541 0 : goto bailout;
1542 :
1543 3502791 : InstrPtr q = EC_TEMP_FRAC(atom_type(a)->type->eclass) ? newStmt(mb, calcRef, atom_type(a)->type->impl) : newAssignment(mb);
1544 :
1545 3503252 : if (q == NULL)
1546 0 : goto bailout;
1547 3503252 : if (atom_null(a)) {
1548 157529 : q = pushNil(mb, q, atom_type(a)->type->localtype);
1549 : } else {
1550 3345723 : int k;
1551 3345723 : if ((k = constantAtom(be, mb, a)) == -1) {
1552 0 : freeInstruction(q);
1553 0 : goto bailout;
1554 : }
1555 3345254 : q = pushArgument(mb, q, k);
1556 : }
1557 : /* digits of the result timestamp/daytime */
1558 3502841 : if (EC_TEMP_FRAC(atom_type(a)->type->eclass))
1559 47378 : q = pushInt(mb, q, atom_type(a)->digits);
1560 3503211 : bool enabled = be->mvc->sa->eb.enabled;
1561 3503211 : be->mvc->sa->eb.enabled = false;
1562 3503211 : stmt *s = stmt_create(be->mvc->sa, st_atom);
1563 3502421 : be->mvc->sa->eb.enabled = enabled;
1564 3502421 : if (s == NULL) {
1565 0 : freeInstruction(q);
1566 0 : goto bailout;
1567 : }
1568 :
1569 3502421 : s->op4.aval = a;
1570 3502421 : s->key = 1; /* values are also unique */
1571 3502421 : s->q = q;
1572 3502421 : s->nr = getDestVar(q);
1573 3502421 : pushInstruction(mb, q);
1574 3502421 : 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 3639 : stmt_genselect(backend *be, stmt *lops, stmt *rops, sql_subfunc *f, stmt *sub, int anti)
1584 : {
1585 3639 : MalBlkPtr mb = be->mb;
1586 3639 : InstrPtr q = NULL;
1587 3639 : const char *mod, *op;
1588 3639 : node *n;
1589 3639 : int k;
1590 :
1591 3639 : if (lops == NULL || rops == NULL)
1592 0 : goto bailout;
1593 :
1594 3639 : if (backend_create_subfunc(be, f, NULL) < 0)
1595 0 : goto bailout;
1596 3639 : op = backend_function_imp(be, f->func);
1597 3639 : mod = sql_func_mod(f->func);
1598 :
1599 3639 : if (rops->nrcols >= 1) {
1600 55 : bit need_not = FALSE;
1601 :
1602 55 : int narg = 3;
1603 110 : for (n = lops->op4.lval->h; n; n = n->next)
1604 55 : narg++;
1605 174 : for (n = rops->op4.lval->h; n; n = n->next)
1606 119 : narg++;
1607 55 : q = newStmtArgs(mb, malRef, multiplexRef, narg);
1608 55 : if (q == NULL)
1609 0 : goto bailout;
1610 55 : setVarType(mb, getArg(q, 0), newBatType(TYPE_bit));
1611 55 : q = pushStr(mb, q, convertMultiplexMod(mod, op));
1612 55 : q = pushStr(mb, q, convertMultiplexFcn(op));
1613 110 : for (n = lops->op4.lval->h; n; n = n->next) {
1614 55 : stmt *op = n->data;
1615 :
1616 55 : q = pushArgument(mb, q, op->nr);
1617 : }
1618 174 : for (n = rops->op4.lval->h; n; n = n->next) {
1619 119 : stmt *op = n->data;
1620 :
1621 119 : q = pushArgument(mb, q, op->nr);
1622 : }
1623 55 : k = getDestVar(q);
1624 55 : pushInstruction(mb, q);
1625 :
1626 55 : q = newStmtArgs(mb, algebraRef, selectRef, 9);
1627 55 : if (q == NULL)
1628 0 : goto bailout;
1629 55 : q = pushArgument(mb, q, k);
1630 55 : if (sub)
1631 35 : q = pushArgument(mb, q, sub->nr);
1632 55 : q = pushBit(mb, q, !need_not);
1633 55 : q = pushBit(mb, q, !need_not);
1634 55 : q = pushBit(mb, q, TRUE);
1635 55 : q = pushBit(mb, q, TRUE);
1636 55 : q = pushBit(mb, q, anti);
1637 : } else {
1638 3584 : node *n;
1639 :
1640 3584 : op = sa_strconcat(be->mvc->sa, op, selectRef);
1641 3584 : q = newStmtArgs(mb, mod, convertMultiplexFcn(op), 9);
1642 3584 : 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 3584 : 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 3584 : if (f->func->lang == FUNC_LANG_R || f->func->lang >= FUNC_LANG_PY)
1650 0 : q = pushStr(mb, q, f->func->query);
1651 :
1652 7168 : for (n = lops->op4.lval->h; n; n = n->next) {
1653 3584 : stmt *op = n->data;
1654 :
1655 3584 : q = pushArgument(mb, q, op->nr);
1656 : }
1657 : /* candidate lists */
1658 3584 : if (sub)
1659 3516 : q = pushArgument(mb, q, sub->nr);
1660 : else
1661 68 : q = pushNilBat(mb, q);
1662 :
1663 14085 : for (n = rops->op4.lval->h; n; n = n->next) {
1664 10501 : stmt *op = n->data;
1665 :
1666 10501 : q = pushArgument(mb, q, op->nr);
1667 : }
1668 :
1669 3584 : q = pushBit(mb, q, anti);
1670 : }
1671 :
1672 3639 : bool enabled = be->mvc->sa->eb.enabled;
1673 3639 : be->mvc->sa->eb.enabled = false;
1674 3639 : stmt *s = stmt_create(be->mvc->sa, st_uselect);
1675 3639 : be->mvc->sa->eb.enabled = enabled;
1676 3639 : if (s == NULL) {
1677 0 : freeInstruction(q);
1678 0 : goto bailout;
1679 : }
1680 :
1681 3639 : s->op1 = lops;
1682 3639 : s->op2 = rops;
1683 3639 : s->op3 = sub;
1684 3639 : s->key = lops->nrcols == 0 && rops->nrcols == 0;
1685 3639 : s->flag = cmp_filter;
1686 3639 : s->nrcols = lops->nrcols;
1687 3639 : s->nr = getDestVar(q);
1688 3639 : s->q = q;
1689 3639 : s->cand = sub;
1690 3639 : pushInstruction(mb, q);
1691 3639 : 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 203859 : stmt_uselect(backend *be, stmt *op1, stmt *op2, comp_type cmptype, stmt *sub, int anti, int is_semantics)
1701 : {
1702 203859 : MalBlkPtr mb = be->mb;
1703 203859 : InstrPtr q = NULL;
1704 203859 : int l, r;
1705 203859 : stmt *sel = sub;
1706 :
1707 203859 : if (op1 == NULL || op2 == NULL || op1->nr < 0 || op2->nr < 0 || (sub && sub->nr < 0))
1708 0 : goto bailout;
1709 203859 : l = op1->nr;
1710 203859 : r = op2->nr;
1711 :
1712 203859 : if (op2->nrcols >= 1 && op1->nrcols == 0) { /* swap */
1713 79 : stmt *v = op1;
1714 79 : op1 = op2;
1715 79 : op2 = v;
1716 79 : int n = l;
1717 79 : l = r;
1718 79 : r = n;
1719 79 : cmptype = swap_compare(cmptype);
1720 : }
1721 203859 : if (op2->nrcols >= 1) {
1722 17989 : bit need_not = FALSE;
1723 17989 : const char *mod = calcRef;
1724 17989 : const char *op = "=";
1725 17989 : int k;
1726 :
1727 17989 : switch (cmptype) {
1728 : case cmp_equal:
1729 : op = "=";
1730 : break;
1731 : case cmp_notequal:
1732 17989 : op = "!=";
1733 : break;
1734 917 : case cmp_lt:
1735 917 : op = "<";
1736 917 : 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 28391 : if ((q = multiplex2(mb, mod, convertMultiplexFcn(op), l, r, TYPE_bit)) == NULL)
1751 0 : goto bailout;
1752 17989 : if (sub && (op1->cand || op2->cand)) {
1753 1756 : 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 1726 : } else if (!op1->cand && op2->cand) {
1758 1692 : q = pushArgument(mb, q, sub->nr);
1759 1692 : if (op2->nrcols > 0)
1760 1692 : q = pushNilBat(mb, q);
1761 : }
1762 : sub = NULL;
1763 : }
1764 17989 : if (is_semantics)
1765 2998 : q = pushBit(mb, q, TRUE);
1766 17989 : k = getDestVar(q);
1767 :
1768 17989 : q = newStmtArgs(mb, algebraRef, selectRef, 9);
1769 17989 : if (q == NULL)
1770 0 : goto bailout;
1771 17989 : q = pushArgument(mb, q, k);
1772 17989 : if (sub)
1773 4362 : q = pushArgument(mb, q, sub->nr);
1774 17989 : q = pushBit(mb, q, !need_not);
1775 17989 : q = pushBit(mb, q, !need_not);
1776 17989 : q = pushBit(mb, q, TRUE);
1777 17989 : q = pushBit(mb, q, TRUE);
1778 17989 : q = pushBit(mb, q, anti);
1779 17989 : k = getDestVar(q);
1780 : } else {
1781 185870 : assert (cmptype != cmp_filter);
1782 185870 : q = newStmt(mb, algebraRef, thetaselectRef);
1783 185871 : if (q == NULL)
1784 0 : goto bailout;
1785 185871 : q = pushArgument(mb, q, l);
1786 185870 : if (sub && !op1->cand) {
1787 112107 : q = pushArgument(mb, q, sub->nr);
1788 : } else {
1789 2631 : assert(!sub || op1->cand == sub);
1790 73763 : q = pushNilBat(mb, q);
1791 73763 : sub = NULL;
1792 : }
1793 185871 : q = pushArgument(mb, q, r);
1794 185855 : switch (cmptype) {
1795 167688 : case cmp_equal:
1796 167688 : if (is_semantics)
1797 35044 : q = pushStr(mb, q, anti?"ne":"eq");
1798 : else
1799 295253 : q = pushStr(mb, q, anti?"!=":"==");
1800 : break;
1801 15092 : case cmp_notequal:
1802 15092 : if (is_semantics)
1803 153 : q = pushStr(mb, q, anti?"eq":"ne");
1804 : else
1805 30026 : q = pushStr(mb, q, anti?"==":"!=");
1806 : break;
1807 436 : case cmp_lt:
1808 436 : q = pushStr(mb, q, anti?">=":"<");
1809 436 : break;
1810 71 : case cmp_lte:
1811 71 : q = pushStr(mb, q, anti?">":"<=");
1812 71 : break;
1813 2289 : case cmp_gt:
1814 2289 : q = pushStr(mb, q, anti?"<=":">");
1815 2289 : 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 203852 : bool enabled = be->mvc->sa->eb.enabled;
1829 203852 : be->mvc->sa->eb.enabled = false;
1830 203852 : stmt *s = stmt_create(be->mvc->sa, st_uselect);
1831 203843 : be->mvc->sa->eb.enabled = enabled;
1832 203843 : if (s == NULL) {
1833 0 : freeInstruction(q);
1834 0 : goto bailout;
1835 : }
1836 :
1837 203843 : s->op1 = op1;
1838 203843 : s->op2 = op2;
1839 203843 : s->op3 = sub;
1840 203843 : s->flag = cmptype;
1841 203843 : s->key = op1->nrcols == 0 && op2->nrcols == 0;
1842 203843 : s->nrcols = op1->nrcols;
1843 203843 : s->nr = getDestVar(q);
1844 203843 : s->q = q;
1845 203843 : s->cand = sub;
1846 203843 : pushInstruction(mb, q);
1847 203854 : if (!sub && sel) /* project back the old ids */
1848 4387 : 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 5113 : 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 5113 : MalBlkPtr mb = be->mb;
1909 5113 : InstrPtr p, q;
1910 5113 : int l;
1911 5113 : const char *cmd = (type == st_uselect2) ? selectRef : rangejoinRef;
1912 5113 : stmt *sub = (Sub)?*Sub:NULL;
1913 :
1914 5113 : if (op1 == NULL || op2 == NULL || op3 == NULL || op1->nr < 0 || (sub && sub->nr < 0))
1915 0 : goto bailout;
1916 5113 : l = op1->nr;
1917 8475 : if ((symmetric || op2->nrcols > 0 || op3->nrcols > 0 || !reduce) && (type == st_uselect2)) {
1918 3610 : int k;
1919 3610 : int nrcols = (op1->nrcols || op2->nrcols || op3->nrcols);
1920 :
1921 3610 : if (op2->nr < 0 || op3->nr < 0)
1922 0 : goto bailout;
1923 :
1924 3610 : if (nrcols)
1925 3567 : p = newStmtArgs(mb, batcalcRef, betweenRef, 12);
1926 : else
1927 43 : p = newStmtArgs(mb, calcRef, betweenRef, 9);
1928 3610 : if (p == NULL)
1929 0 : goto bailout;
1930 3610 : p = pushArgument(mb, p, l);
1931 3610 : p = pushArgument(mb, p, op2->nr);
1932 3610 : p = pushArgument(mb, p, op3->nr);
1933 :
1934 : /* cands */
1935 3610 : if ((sub && !reduce) || op1->cand || op2->cand || op3->cand) { /* some already handled the previous selection */
1936 1576 : if (op1->cand && op1->nrcols)
1937 1290 : p = pushNilBat(mb, p);
1938 286 : else if (op1->nrcols)
1939 286 : p = pushArgument(mb, p, sub->nr);
1940 1576 : 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 1576 : 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 3610 : p = pushBit(mb, p, (symmetric)?TRUE:FALSE); /* symmetric */
1956 3610 : p = pushBit(mb, p, (cmp & 1) != 0); /* lo inclusive */
1957 3610 : p = pushBit(mb, p, (cmp & 2) != 0); /* hi inclusive */
1958 3610 : p = pushBit(mb, p, FALSE); /* nils_false */
1959 3610 : p = pushBit(mb, p, (anti)?TRUE:FALSE); /* anti */
1960 3610 : pushInstruction(mb, p);
1961 3610 : if (!reduce)
1962 : return p;
1963 3362 : k = getDestVar(p);
1964 :
1965 3362 : q = newStmtArgs(mb, algebraRef, selectRef, 9);
1966 3362 : if (q == NULL)
1967 0 : goto bailout;
1968 3362 : q = pushArgument(mb, q, k);
1969 3362 : if (sub)
1970 896 : q = pushArgument(mb, q, sub->nr);
1971 3362 : q = pushBit(mb, q, TRUE);
1972 3362 : q = pushBit(mb, q, TRUE);
1973 3362 : q = pushBit(mb, q, TRUE);
1974 3362 : q = pushBit(mb, q, TRUE);
1975 3362 : q = pushBit(mb, q, FALSE);
1976 3362 : 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 1503 : int r1 = op2->nr;
2004 1503 : int r2 = op3->nr;
2005 1503 : int rs = 0;
2006 1503 : q = newStmtArgs(mb, algebraRef, cmd, 12);
2007 1503 : if (q == NULL)
2008 0 : goto bailout;
2009 1503 : if (type == st_join2)
2010 54 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
2011 1503 : q = pushArgument(mb, q, l);
2012 1503 : if (sub) {
2013 1185 : int cand = op1->cand || op2->cand || op3->cand;
2014 1179 : if (cand) {
2015 6 : assert(!op1->nrcols || op1->cand);
2016 6 : assert(!op2->nrcols || op2->cand);
2017 6 : assert(!op3->nrcols || op3->cand);
2018 : sub = NULL;
2019 : }
2020 : }
2021 1179 : if (sub) /* only for uselect2 */
2022 1179 : q = pushArgument(mb, q, sub->nr);
2023 1503 : if (rs) {
2024 : q = pushArgument(mb, q, rs);
2025 : } else {
2026 1503 : q = pushArgument(mb, q, r1);
2027 1503 : q = pushArgument(mb, q, r2);
2028 : }
2029 1503 : if (type == st_join2) {
2030 54 : q = pushNilBat(mb, q);
2031 54 : q = pushNilBat(mb, q);
2032 : }
2033 :
2034 1503 : 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 1203 : case 3:
2048 1203 : q = pushBit(mb, q, TRUE);
2049 1203 : q = pushBit(mb, q, TRUE);
2050 1203 : break;
2051 : }
2052 1503 : q = pushBit(mb, q, anti);
2053 1503 : if (type == st_uselect2) {
2054 1449 : q = pushBit(mb, q, TRUE); /* all nil's are != */
2055 : } else {
2056 54 : q = pushBit(mb, q, (symmetric)?TRUE:FALSE);
2057 : }
2058 1503 : if (type == st_join2)
2059 54 : q = pushNil(mb, q, TYPE_lng); /* estimate */
2060 1503 : pushInstruction(mb, q);
2061 1503 : 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 4865 : if (Sub)
2074 4811 : *Sub = sub;
2075 : return q;
2076 :
2077 0 : bailout:
2078 0 : if (be->mvc->sa->eb.enabled)
2079 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
2080 : return NULL;
2081 : }
2082 :
2083 : stmt *
2084 38 : stmt_outerselect(backend *be, stmt *g, stmt *m, stmt *p, bool any)
2085 : {
2086 38 : MalBlkPtr mb = be->mb;
2087 38 : InstrPtr q;
2088 :
2089 38 : q = newStmtArgs(mb, algebraRef, outerselectRef, 6);
2090 38 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
2091 38 : q = pushArgument(mb, q, g->nr); /* group ids */
2092 38 : q = pushArgument(mb, q, m->nr); /* mark flag */
2093 38 : q = pushArgument(mb, q, p->nr); /* predicate */
2094 38 : q = pushBit(mb, q, (any)?TRUE:FALSE);
2095 38 : pushInstruction(mb, q);
2096 :
2097 38 : if (!q)
2098 : return NULL;
2099 38 : stmt *s = stmt_create(be->mvc->sa, st_uselect2);
2100 38 : if (s == NULL) {
2101 0 : freeInstruction(q);
2102 0 : return NULL;
2103 : }
2104 :
2105 38 : s->op1 = g;
2106 38 : s->op2 = m;
2107 38 : s->flag = MARKJOIN;
2108 38 : s->key = 0;
2109 38 : s->nrcols = g->nrcols;
2110 38 : s->nr = getDestVar(q);
2111 38 : s->q = q;
2112 38 : return s;
2113 : }
2114 :
2115 : stmt *
2116 404 : stmt_markselect(backend *be, stmt *g, stmt *m, stmt *p, bool any)
2117 : {
2118 404 : MalBlkPtr mb = be->mb;
2119 404 : InstrPtr q;
2120 :
2121 404 : q = newStmtArgs(mb, algebraRef, markselectRef, 6);
2122 404 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
2123 404 : q = pushArgument(mb, q, g->nr); /* left ids */
2124 404 : q = pushArgument(mb, q, m->nr); /* mark info mask */
2125 404 : q = pushArgument(mb, q, p->nr); /* predicate */
2126 404 : q = pushBit(mb, q, (any)?TRUE:FALSE);
2127 404 : pushInstruction(mb, q);
2128 :
2129 404 : if (!q)
2130 : return NULL;
2131 404 : stmt *s = stmt_create(be->mvc->sa, st_uselect2);
2132 404 : if (s == NULL) {
2133 0 : freeInstruction(q);
2134 0 : return NULL;
2135 : }
2136 :
2137 404 : s->op1 = g;
2138 404 : s->op2 = m;
2139 404 : s->flag = MARKJOIN;
2140 404 : s->key = 0;
2141 404 : s->nrcols = g->nrcols;
2142 404 : s->nr = getDestVar(q);
2143 404 : s->q = q;
2144 404 : return s;
2145 : }
2146 :
2147 : stmt *
2148 2531 : stmt_markjoin(backend *be, stmt *l, stmt *r, bool final)
2149 : {
2150 2531 : MalBlkPtr mb = be->mb;
2151 2531 : InstrPtr q;
2152 :
2153 2531 : q = newStmtArgs(mb, algebraRef, markjoinRef, 8);
2154 2531 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
2155 2531 : if (!final)
2156 5 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
2157 2531 : q = pushArgument(mb, q, l->nr); /* left ids */
2158 2531 : q = pushArgument(mb, q, r->nr); /* mark info mask */
2159 2531 : q = pushNilBat(mb, q);
2160 2531 : q = pushNilBat(mb, q);
2161 2531 : q = pushNil(mb, q, TYPE_lng);
2162 2531 : pushInstruction(mb, q);
2163 :
2164 2531 : if (!q)
2165 : return NULL;
2166 2531 : stmt *s = stmt_create(be->mvc->sa, st_join);
2167 2531 : if (s == NULL) {
2168 0 : freeInstruction(q);
2169 0 : return NULL;
2170 : }
2171 :
2172 2531 : s->op1 = l;
2173 2531 : s->op2 = r;
2174 2531 : s->flag = MARKJOIN;
2175 2531 : s->key = 0;
2176 2531 : s->nrcols = l->nrcols;
2177 2531 : s->nr = getDestVar(q);
2178 2531 : s->q = q;
2179 2531 : return s;
2180 : }
2181 :
2182 : stmt *
2183 5059 : stmt_uselect2(backend *be, stmt *op1, stmt *op2, stmt *op3, int cmp, stmt *sub, int anti, int symmetric, int reduce)
2184 : {
2185 5059 : stmt *sel = sub;
2186 5059 : InstrPtr q = select2_join2(be, op1, op2, op3, cmp, &sub, anti, symmetric, 0, st_uselect2, reduce);
2187 :
2188 5059 : if (q == NULL)
2189 : return NULL;
2190 :
2191 5059 : stmt *s = stmt_create(be->mvc->sa, st_uselect2);
2192 5059 : if (s == NULL) {
2193 : return NULL;
2194 : }
2195 :
2196 5059 : s->op1 = op1;
2197 5059 : s->op2 = op2;
2198 5059 : s->op3 = op3;
2199 5059 : s->op4.stval = sub;
2200 5059 : s->flag = cmp;
2201 5059 : s->nrcols = op1->nrcols;
2202 5059 : s->key = op1->nrcols == 0 && op2->nrcols == 0 && op3->nrcols == 0;
2203 5059 : s->nr = getDestVar(q);
2204 5059 : s->q = q;
2205 5059 : s->cand = sub;
2206 5059 : s->reduce = reduce;
2207 5059 : if (!sub && sel) /* project back the old ids */
2208 1451 : return stmt_project(be, s, sel);
2209 : return s;
2210 : }
2211 :
2212 : stmt *
2213 51346 : stmt_tunion(backend *be, stmt *op1, stmt *op2)
2214 : {
2215 51346 : InstrPtr q = NULL;
2216 51346 : MalBlkPtr mb = be->mb;
2217 :
2218 51346 : q = dump_2(mb, batRef, mergecandRef, op1, op2);
2219 51346 : if (q) {
2220 51346 : stmt *s = stmt_create(be->mvc->sa, st_tunion);
2221 51346 : if (s == NULL) {
2222 : return NULL;
2223 : }
2224 :
2225 51346 : s->op1 = op1;
2226 51346 : s->op2 = op2;
2227 51346 : s->nrcols = op1->nrcols;
2228 51346 : s->key = op1->key;
2229 51346 : s->aggr = op1->aggr;
2230 51346 : s->nr = getDestVar(q);
2231 51346 : s->q = q;
2232 51346 : 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 44915 : stmt_tdiff(backend *be, stmt *op1, stmt *op2, stmt *lcand)
2242 : {
2243 44915 : InstrPtr q = NULL;
2244 44915 : MalBlkPtr mb = be->mb;
2245 :
2246 44915 : if (op1 == NULL || op2 == NULL || op1->nr < 0 || op2->nr < 0)
2247 0 : goto bailout;
2248 44915 : q = newStmt(mb, algebraRef, differenceRef);
2249 44915 : if (q == NULL)
2250 0 : goto bailout;
2251 44915 : q = pushArgument(mb, q, op1->nr); /* left */
2252 44915 : q = pushArgument(mb, q, op2->nr); /* right */
2253 44915 : if (lcand)
2254 0 : q = pushArgument(mb, q, lcand->nr); /* left */
2255 : else
2256 44915 : q = pushNilBat(mb, q); /* left candidate */
2257 44915 : q = pushNilBat(mb, q); /* right candidate */
2258 44915 : q = pushBit(mb, q, FALSE); /* nil matches */
2259 44915 : q = pushBit(mb, q, FALSE); /* do not clear nils */
2260 44915 : q = pushNil(mb, q, TYPE_lng); /* estimate */
2261 :
2262 44915 : bool enabled = be->mvc->sa->eb.enabled;
2263 44915 : be->mvc->sa->eb.enabled = false;
2264 44915 : stmt *s = stmt_create(be->mvc->sa, st_tdiff);
2265 44915 : be->mvc->sa->eb.enabled = enabled;
2266 44915 : if (s == NULL) {
2267 0 : freeInstruction(q);
2268 0 : goto bailout;
2269 : }
2270 :
2271 44915 : s->op1 = op1;
2272 44915 : s->op2 = op2;
2273 44915 : s->nrcols = op1->nrcols;
2274 44915 : s->key = op1->key;
2275 44915 : s->aggr = op1->aggr;
2276 44915 : s->nr = getDestVar(q);
2277 44915 : s->q = q;
2278 44915 : pushInstruction(mb, q);
2279 44915 : return s;
2280 :
2281 0 : bailout:
2282 0 : if (be->mvc->sa->eb.enabled)
2283 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
2284 : return NULL;
2285 : }
2286 :
2287 : stmt *
2288 1378 : stmt_tdiff2(backend *be, stmt *op1, stmt *op2, stmt *lcand)
2289 : {
2290 1378 : InstrPtr q = NULL;
2291 1378 : MalBlkPtr mb = be->mb;
2292 :
2293 1378 : if (op1 == NULL || op2 == NULL || op1->nr < 0 || op2->nr < 0)
2294 0 : goto bailout;
2295 1378 : q = newStmt(mb, algebraRef, differenceRef);
2296 1378 : if (q == NULL)
2297 0 : goto bailout;
2298 1378 : q = pushArgument(mb, q, op1->nr); /* left */
2299 1378 : q = pushArgument(mb, q, op2->nr); /* right */
2300 1378 : if (lcand)
2301 0 : q = pushArgument(mb, q, lcand->nr); /* left */
2302 : else
2303 1378 : q = pushNilBat(mb, q); /* left candidate */
2304 1378 : q = pushNilBat(mb, q); /* right candidate */
2305 1378 : q = pushBit(mb, q, FALSE); /* nil matches */
2306 1378 : q = pushBit(mb, q, TRUE); /* not in */
2307 1378 : q = pushNil(mb, q, TYPE_lng); /* estimate */
2308 :
2309 1378 : bool enabled = be->mvc->sa->eb.enabled;
2310 1378 : be->mvc->sa->eb.enabled = false;
2311 1378 : stmt *s = stmt_create(be->mvc->sa, st_tdiff);
2312 1378 : be->mvc->sa->eb.enabled = enabled;
2313 1378 : if (s == NULL) {
2314 0 : freeInstruction(q);
2315 0 : goto bailout;
2316 : }
2317 :
2318 1378 : s->op1 = op1;
2319 1378 : s->op2 = op2;
2320 1378 : s->nrcols = op1->nrcols;
2321 1378 : s->key = op1->key;
2322 1378 : s->aggr = op1->aggr;
2323 1378 : s->nr = getDestVar(q);
2324 1378 : s->q = q;
2325 1378 : pushInstruction(mb, q);
2326 1378 : return s;
2327 :
2328 0 : bailout:
2329 0 : if (be->mvc->sa->eb.enabled)
2330 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
2331 : return NULL;
2332 : }
2333 :
2334 : stmt *
2335 2113 : stmt_tinter(backend *be, stmt *op1, stmt *op2, bool single)
2336 : {
2337 2113 : InstrPtr q = NULL;
2338 2113 : MalBlkPtr mb = be->mb;
2339 :
2340 2113 : if (op1 == NULL || op2 == NULL || op1->nr < 0 || op2->nr < 0)
2341 0 : goto bailout;
2342 2113 : q = newStmt(mb, algebraRef, intersectRef);
2343 2113 : if (q == NULL)
2344 0 : goto bailout;
2345 2113 : q = pushArgument(mb, q, op1->nr); /* left */
2346 2113 : q = pushArgument(mb, q, op2->nr); /* right */
2347 2113 : q = pushNilBat(mb, q); /* left candidate */
2348 2113 : q = pushNilBat(mb, q); /* right candidate */
2349 2113 : q = pushBit(mb, q, FALSE); /* nil matches */
2350 2113 : q = pushBit(mb, q, single?TRUE:FALSE); /* max_one */
2351 2113 : q = pushNil(mb, q, TYPE_lng); /* estimate */
2352 :
2353 2113 : bool enabled = be->mvc->sa->eb.enabled;
2354 2113 : be->mvc->sa->eb.enabled = false;
2355 2113 : stmt *s = stmt_create(be->mvc->sa, st_tinter);
2356 2113 : be->mvc->sa->eb.enabled = enabled;
2357 2113 : if (s == NULL) {
2358 0 : freeInstruction(q);
2359 0 : goto bailout;
2360 : }
2361 :
2362 2113 : s->op1 = op1;
2363 2113 : s->op2 = op2;
2364 2113 : s->nrcols = op1->nrcols;
2365 2113 : s->key = op1->key;
2366 2113 : s->aggr = op1->aggr;
2367 2113 : s->nr = getDestVar(q);
2368 2113 : s->q = q;
2369 2113 : pushInstruction(mb, q);
2370 2113 : 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 95123 : 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 95123 : MalBlkPtr mb = be->mb;
2382 95123 : InstrPtr q = NULL;
2383 95123 : const char *sjt = inner?joinRef:outerjoinRef;
2384 :
2385 95123 : (void)anti;
2386 95123 : (void)inner;
2387 :
2388 95123 : if (need_left) {
2389 653 : cmptype = cmp_equal;
2390 653 : sjt = leftjoinRef;
2391 : }
2392 95123 : if (op1 == NULL || op2 == NULL || op1->nr < 0 || op2->nr < 0)
2393 0 : goto bailout;
2394 :
2395 95123 : assert (!single || cmptype == cmp_all);
2396 :
2397 95123 : switch (cmptype) {
2398 77196 : case cmp_equal:
2399 77196 : q = newStmtArgs(mb, algebraRef, sjt, 9);
2400 77196 : if (q == NULL)
2401 0 : goto bailout;
2402 77196 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
2403 77196 : q = pushArgument(mb, q, op1->nr);
2404 77196 : q = pushArgument(mb, q, op2->nr);
2405 77196 : if (!lcand)
2406 76094 : q = pushNilBat(mb, q);
2407 : else
2408 1102 : q = pushArgument(mb, q, lcand->nr);
2409 77196 : if (!rcand)
2410 77196 : q = pushNilBat(mb, q);
2411 : else
2412 0 : q = pushArgument(mb, q, rcand->nr);
2413 77196 : q = pushBit(mb, q, is_semantics?TRUE:FALSE);
2414 77196 : if (!inner)
2415 76 : q = pushBit(mb, q, FALSE); /* not match_one */
2416 77196 : q = pushNil(mb, q, TYPE_lng);
2417 77196 : pushInstruction(mb, q);
2418 77196 : break;
2419 31 : case cmp_notequal:
2420 31 : if (inner)
2421 31 : sjt = thetajoinRef;
2422 31 : q = newStmtArgs(mb, algebraRef, sjt, 9);
2423 31 : if (q == NULL)
2424 0 : goto bailout;
2425 31 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
2426 31 : q = pushArgument(mb, q, op1->nr);
2427 31 : q = pushArgument(mb, q, op2->nr);
2428 31 : if (!lcand)
2429 31 : q = pushNilBat(mb, q);
2430 : else
2431 0 : q = pushArgument(mb, q, lcand->nr);
2432 31 : if (!rcand)
2433 31 : q = pushNilBat(mb, q);
2434 : else
2435 0 : q = pushArgument(mb, q, rcand->nr);
2436 31 : if (inner)
2437 31 : q = pushInt(mb, q, JOIN_NE);
2438 31 : q = pushBit(mb, q, is_semantics?TRUE:FALSE);
2439 31 : if (!inner)
2440 0 : q = pushBit(mb, q, FALSE); /* not match_one */
2441 31 : q = pushNil(mb, q, TYPE_lng);
2442 31 : pushInstruction(mb, q);
2443 31 : break;
2444 2584 : case cmp_lt:
2445 : case cmp_lte:
2446 : case cmp_gt:
2447 : case cmp_gte:
2448 2584 : q = newStmtArgs(mb, algebraRef, thetajoinRef, 9);
2449 2584 : if (q == NULL)
2450 0 : goto bailout;
2451 2584 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
2452 2584 : q = pushArgument(mb, q, op1->nr);
2453 2584 : q = pushArgument(mb, q, op2->nr);
2454 2584 : if (!lcand)
2455 2584 : q = pushNilBat(mb, q);
2456 : else
2457 0 : q = pushArgument(mb, q, lcand->nr);
2458 2584 : if (!rcand)
2459 2584 : q = pushNilBat(mb, q);
2460 : else
2461 0 : q = pushArgument(mb, q, rcand->nr);
2462 2584 : if (cmptype == cmp_lt)
2463 2068 : q = pushInt(mb, q, JOIN_LT);
2464 516 : else if (cmptype == cmp_lte)
2465 8 : q = pushInt(mb, q, JOIN_LE);
2466 508 : else if (cmptype == cmp_gt)
2467 503 : q = pushInt(mb, q, JOIN_GT);
2468 5 : else if (cmptype == cmp_gte)
2469 5 : q = pushInt(mb, q, JOIN_GE);
2470 2584 : q = pushBit(mb, q, is_semantics?TRUE:FALSE);
2471 2584 : q = pushNil(mb, q, TYPE_lng);
2472 2584 : pushInstruction(mb, q);
2473 2584 : break;
2474 12076 : case cmp_all: /* aka cross table */
2475 12513 : q = newStmt(mb, algebraRef, inner?crossRef:outercrossRef);
2476 12076 : if (q == NULL)
2477 0 : goto bailout;
2478 12076 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
2479 12076 : q = pushArgument(mb, q, op1->nr);
2480 12076 : q = pushArgument(mb, q, op2->nr);
2481 12076 : if (!inner) {
2482 437 : q = pushNilBat(mb, q);
2483 437 : q = pushNilBat(mb, q);
2484 : }
2485 12076 : q = pushBit(mb, q, single?TRUE:FALSE); /* max_one */
2486 12076 : assert(!lcand && !rcand);
2487 12076 : pushInstruction(mb, q);
2488 12076 : break;
2489 3236 : case cmp_joined:
2490 3236 : q = op1->q;
2491 3236 : if (q == NULL)
2492 0 : goto bailout;
2493 : break;
2494 0 : default:
2495 0 : TRC_ERROR(SQL_EXECUTION, "Impossible action\n");
2496 : }
2497 :
2498 95123 : stmt *s = stmt_create(be->mvc->sa, st_join);
2499 95123 : if (s == NULL) {
2500 0 : goto bailout;
2501 : }
2502 :
2503 95123 : s->op1 = op1;
2504 95123 : s->op2 = op2;
2505 95123 : s->flag = cmptype;
2506 95123 : s->key = 0;
2507 95123 : s->nrcols = 2;
2508 95123 : s->nr = getDestVar(q);
2509 95123 : s->q = q;
2510 95123 : 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 90878 : stmt_join(backend *be, stmt *l, stmt *r, int anti, comp_type cmptype, int need_left, int is_semantics, bool single)
2520 : {
2521 90878 : return stmt_join_cand(be, l, r, NULL, NULL, anti, cmptype, need_left, is_semantics, single, true);
2522 : }
2523 :
2524 : stmt *
2525 1468 : stmt_semijoin(backend *be, stmt *op1, stmt *op2, stmt *lcand, stmt *rcand, int is_semantics, bool single)
2526 : {
2527 1468 : MalBlkPtr mb = be->mb;
2528 1468 : InstrPtr q = NULL;
2529 :
2530 1468 : if (op1 == NULL || op2 == NULL || op1->nr < 0 || op2->nr < 0)
2531 0 : goto bailout;
2532 :
2533 1468 : if (single) {
2534 284 : q = newStmtArgs(mb, algebraRef, semijoinRef, 9);
2535 284 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
2536 : } else
2537 1184 : q = newStmt(mb, algebraRef, intersectRef);
2538 1468 : if (q == NULL)
2539 0 : goto bailout;
2540 1468 : q = pushArgument(mb, q, op1->nr);
2541 1468 : q = pushArgument(mb, q, op2->nr);
2542 1468 : if (lcand)
2543 1181 : q = pushArgument(mb, q, lcand->nr);
2544 : else
2545 287 : q = pushNilBat(mb, q);
2546 1468 : if (rcand)
2547 0 : q = pushArgument(mb, q, rcand->nr);
2548 : else
2549 1468 : q = pushNilBat(mb, q);
2550 1468 : q = pushBit(mb, q, is_semantics?TRUE:FALSE);
2551 1468 : q = pushBit(mb, q, single?TRUE:FALSE); /* max_one */
2552 1468 : q = pushNil(mb, q, TYPE_lng);
2553 :
2554 1468 : bool enabled = be->mvc->sa->eb.enabled;
2555 1468 : be->mvc->sa->eb.enabled = false;
2556 1468 : stmt *s = stmt_create(be->mvc->sa, st_semijoin);
2557 1468 : be->mvc->sa->eb.enabled = enabled;
2558 1468 : if (s == NULL) {
2559 0 : freeInstruction(q);
2560 0 : goto bailout;
2561 : }
2562 :
2563 1468 : s->op1 = op1;
2564 1468 : s->op2 = op2;
2565 1468 : s->flag = cmp_equal;
2566 1468 : s->key = 0;
2567 1468 : s->nrcols = 1;
2568 1468 : if (single)
2569 284 : s->nrcols = 2;
2570 1468 : s->nr = getDestVar(q);
2571 1468 : s->q = q;
2572 1468 : pushInstruction(mb, q);
2573 1468 : 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 3548345 : stmt_project_join(backend *be, stmt *op1, stmt *op2, bool delta)
2583 : {
2584 3548345 : MalBlkPtr mb = be->mb;
2585 3548345 : InstrPtr q = NULL;
2586 :
2587 3548345 : if (op1 == NULL || op2 == NULL || op1->nr < 0 || op2->nr < 0)
2588 : return NULL;
2589 : /* delta bat */
2590 3548345 : if (delta) {
2591 490656 : int uval = getArg(op2->q, 1);
2592 :
2593 490656 : q = newStmt(mb, sqlRef, deltaRef);
2594 490687 : q = pushArgument(mb, q, op1->nr);
2595 490686 : q = pushArgument(mb, q, op2->nr);
2596 490687 : q = pushArgument(mb, q, uval);
2597 : } else {
2598 : /* projections, ie left is void headed */
2599 3057689 : q = newStmt(mb, algebraRef, projectionRef);
2600 3057741 : q = pushArgument(mb, q, op1->nr);
2601 3057741 : q = pushArgument(mb, q, op2->nr);
2602 : }
2603 3548429 : pushInstruction(mb, q);
2604 3548429 : return q;
2605 : }
2606 :
2607 : stmt *
2608 3066969 : stmt_project(backend *be, stmt *op1, stmt *op2)
2609 : {
2610 3066969 : if (op1 == NULL || op2 == NULL)
2611 : return NULL;
2612 3066969 : if (!op2->nrcols)
2613 9286 : return stmt_const(be, op1, op2);
2614 3057683 : InstrPtr q = stmt_project_join(be, op1, op2, false);
2615 3057740 : if (q) {
2616 3057740 : stmt *s = stmt_create(be->mvc->sa, st_join);
2617 3057721 : if (s == NULL) {
2618 : return NULL;
2619 : }
2620 :
2621 3057721 : s->op1 = op1;
2622 3057721 : s->op2 = op2;
2623 3057721 : s->flag = cmp_project;
2624 3057721 : s->key = 0;
2625 3057721 : s->nrcols = MAX(op1->nrcols,op2->nrcols);
2626 3057721 : s->nr = getDestVar(q);
2627 3057721 : s->q = q;
2628 3057721 : s->tname = op2->tname;
2629 3057721 : s->cname = op2->cname;
2630 3057721 : s->label = op2->label;
2631 3057721 : 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 490663 : stmt_project_delta(backend *be, stmt *col, stmt *upd)
2640 : {
2641 490663 : InstrPtr q = stmt_project_join(be, col, upd, true);
2642 490687 : if (q) {
2643 490687 : stmt *s = stmt_create(be->mvc->sa, st_join);
2644 490674 : if (s == NULL) {
2645 : return NULL;
2646 : }
2647 :
2648 490674 : s->op1 = col;
2649 490674 : s->op2 = upd;
2650 490674 : s->flag = cmp_project;
2651 490674 : s->key = 0;
2652 490674 : s->nrcols = 2;
2653 490674 : s->nr = getDestVar(q);
2654 490674 : s->q = q;
2655 490674 : s->tname = col->tname;
2656 490674 : s->cname = col->cname;
2657 490674 : 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 48 : stmt_genjoin(backend *be, stmt *l, stmt *r, sql_subfunc *op, int anti, int swapped)
2815 : {
2816 48 : MalBlkPtr mb = be->mb;
2817 48 : InstrPtr q = NULL;
2818 48 : const char *mod, *fimp;
2819 48 : node *n;
2820 :
2821 48 : if (l == NULL || r == NULL)
2822 0 : goto bailout;
2823 48 : if (backend_create_subfunc(be, op, NULL) < 0)
2824 0 : goto bailout;
2825 48 : mod = sql_func_mod(op->func);
2826 48 : fimp = backend_function_imp(be, op->func);
2827 48 : fimp = sa_strconcat(be->mvc->sa, fimp, "join");
2828 :
2829 : /* filter qualifying tuples, return oids of h and tail */
2830 48 : q = newStmtArgs(mb, mod, fimp, list_length(l->op4.lval) + list_length(r->op4.lval) + 7);
2831 48 : if (q == NULL)
2832 0 : goto bailout;
2833 48 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
2834 96 : for (n = l->op4.lval->h; n; n = n->next) {
2835 48 : stmt *op = n->data;
2836 :
2837 48 : q = pushArgument(mb, q, op->nr);
2838 : }
2839 :
2840 158 : for (n = r->op4.lval->h; n; n = n->next) {
2841 110 : stmt *op = n->data;
2842 :
2843 110 : q = pushArgument(mb, q, op->nr);
2844 : }
2845 48 : q = pushNilBat(mb, q); /* candidate lists */
2846 48 : q = pushNilBat(mb, q); /* candidate lists */
2847 48 : q = pushBit(mb, q, TRUE); /* nil_matches */
2848 48 : q = pushNil(mb, q, TYPE_lng); /* estimate */
2849 48 : q = pushBit(mb, q, anti?TRUE:FALSE); /* 'not' matching */
2850 48 : pushInstruction(mb, q);
2851 :
2852 48 : if (swapped) {
2853 2 : InstrPtr r = newInstruction(mb, NULL, NULL);
2854 2 : if (r == NULL)
2855 0 : goto bailout;
2856 2 : getArg(r, 0) = newTmpVariable(mb, TYPE_any);
2857 2 : r = pushReturn(mb, r, newTmpVariable(mb, TYPE_any));
2858 2 : r = pushArgument(mb, r, getArg(q,1));
2859 2 : r = pushArgument(mb, r, getArg(q,0));
2860 2 : pushInstruction(mb, r);
2861 2 : q = r;
2862 : }
2863 :
2864 48 : stmt *s = stmt_create(be->mvc->sa, st_joinN);
2865 48 : if (s == NULL) {
2866 0 : goto bailout;
2867 : }
2868 :
2869 48 : s->op1 = l;
2870 48 : s->op2 = r;
2871 48 : s->op4.funcval = op;
2872 48 : s->nrcols = 2;
2873 48 : if (swapped)
2874 2 : s->flag |= SWAPPED;
2875 48 : s->nr = getDestVar(q);
2876 48 : s->q = q;
2877 48 : 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 26015 : stmt_rs_column(backend *be, stmt *rs, int i, sql_subtype *tpe)
2887 : {
2888 26015 : InstrPtr q = NULL;
2889 :
2890 26015 : if (rs == NULL || rs->nr < 0)
2891 : return NULL;
2892 26015 : q = rs->q;
2893 26015 : if (q) {
2894 25607 : stmt *s = stmt_create(be->mvc->sa, st_rs_column);
2895 25607 : if (s == NULL) {
2896 : return NULL;
2897 : }
2898 :
2899 25607 : s->op1 = rs;
2900 25607 : s->op4.typeval = *tpe;
2901 25607 : s->flag = i;
2902 25607 : s->nrcols = 1;
2903 25607 : s->key = 0;
2904 25607 : s->q = q;
2905 25607 : s->nr = getArg(q, s->flag);
2906 25607 : return s;
2907 408 : } else if (rs->type == st_list) {
2908 408 : list *cols = rs->op4.lval;
2909 408 : if (i < list_length(cols))
2910 408 : 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 291347 : stmt_catalog(backend *be, int type, stmt *args)
3143 : {
3144 291347 : MalBlkPtr mb = be->mb;
3145 291347 : InstrPtr q = NULL;
3146 291347 : node *n;
3147 :
3148 291347 : if (args == NULL || args->nr < 0)
3149 0 : goto bailout;
3150 :
3151 : /* cast them into properly named operations */
3152 291347 : const char *ref;
3153 291347 : 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 1100 : case ddl_create_schema: ref = create_schemaRef; break;
3158 193 : case ddl_drop_schema: ref = drop_schemaRef; break;
3159 10230 : case ddl_create_table: ref = create_tableRef; break;
3160 22911 : case ddl_create_view: ref = create_viewRef; break;
3161 3738 : 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 922 : 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 18907 : case ddl_grant: ref = grantRef; break;
3170 15 : case ddl_revoke: ref = revokeRef; break;
3171 101527 : case ddl_grant_func: ref = grant_functionRef; break;
3172 1 : case ddl_revoke_func: ref = revoke_functionRef; break;
3173 362 : 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 688 : case ddl_drop_function: ref = drop_functionRef; break;
3181 123923 : case ddl_create_function: ref = create_functionRef; break;
3182 349 : 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 2350 : 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 358 : 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 291347 : q = newStmtArgs(mb, sqlcatalogRef, ref, list_length(args->op4.lval) + 1);
3198 291347 : if (q == NULL)
3199 0 : goto bailout;
3200 : // pass all arguments as before
3201 1741780 : for (n = args->op4.lval->h; n; n = n->next) {
3202 1450433 : stmt *c = n->data;
3203 :
3204 1450433 : q = pushArgument(mb, q, c->nr);
3205 : }
3206 :
3207 291347 : bool enabled = be->mvc->sa->eb.enabled;
3208 291347 : be->mvc->sa->eb.enabled = false;
3209 291347 : stmt *s = stmt_create(be->mvc->sa, st_catalog);
3210 291347 : be->mvc->sa->eb.enabled = enabled;
3211 291347 : if(!s) {
3212 0 : freeInstruction(q);
3213 0 : goto bailout;
3214 : }
3215 291347 : s->op1 = args;
3216 291347 : s->flag = type;
3217 291347 : s->q = q;
3218 291347 : s->nr = getDestVar(q);
3219 291347 : pushInstruction(mb, q);
3220 291347 : 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 1993648 : stmt_set_nrcols(stmt *s)
3230 : {
3231 1993648 : unsigned nrcols = 0;
3232 1993648 : int key = 1;
3233 1993648 : node *n;
3234 1993648 : list *l = s->op4.lval;
3235 :
3236 1993648 : assert(s->type == st_list);
3237 9422885 : for (n = l->h; n; n = n->next) {
3238 7429237 : stmt *f = n->data;
3239 :
3240 7429237 : if (!f)
3241 0 : continue;
3242 7429237 : if (f->nrcols > nrcols)
3243 : nrcols = f->nrcols;
3244 7429237 : key &= f->key;
3245 7429237 : s->nr = f->nr;
3246 : }
3247 1993648 : s->nrcols = nrcols;
3248 1993648 : s->key = key;
3249 1993648 : }
3250 :
3251 : stmt *
3252 1578934 : stmt_list(backend *be, list *l)
3253 : {
3254 1578934 : if (l == NULL)
3255 : return NULL;
3256 1578934 : stmt *s = stmt_create(be->mvc->sa, st_list);
3257 1578979 : if(!s) {
3258 : return NULL;
3259 : }
3260 1578979 : s->op4.lval = l;
3261 1578979 : stmt_set_nrcols(s);
3262 1578979 : return s;
3263 : }
3264 :
3265 : static InstrPtr
3266 68343 : dump_header(mvc *sql, MalBlkPtr mb, list *l)
3267 : {
3268 68343 : node *n;
3269 : // gather the meta information
3270 68343 : int tblId, nmeId, tpeId, lenId, scaleId;
3271 68343 : int args;
3272 68343 : InstrPtr list;
3273 68343 : InstrPtr tblPtr, nmePtr, tpePtr, lenPtr, scalePtr;
3274 :
3275 68343 : args = list_length(l) + 1;
3276 :
3277 68343 : list = newInstructionArgs(mb,sqlRef, resultSetRef, args + 5);
3278 68351 : if(!list) {
3279 : return NULL;
3280 : }
3281 68351 : getArg(list,0) = newTmpVariable(mb,TYPE_int);
3282 68348 : meta(tblPtr, tblId, TYPE_str, args);
3283 68354 : meta(nmePtr, nmeId, TYPE_str, args);
3284 68354 : meta(tpePtr, tpeId, TYPE_str, args);
3285 68354 : meta(lenPtr, lenId, TYPE_int, args);
3286 68354 : meta(scalePtr, scaleId, TYPE_int, args);
3287 68354 : if(tblPtr == NULL || nmePtr == NULL || tpePtr == NULL || lenPtr == NULL || scalePtr == NULL)
3288 : return NULL;
3289 :
3290 351937 : for (n = l->h; n; n = n->next) {
3291 283591 : stmt *c = n->data;
3292 283591 : sql_subtype *t = tail_type(c);
3293 283591 : const char *tname = table_name(sql->sa, c);
3294 283597 : const char *sname = schema_name(sql->sa, c);
3295 283577 : const char *_empty = "";
3296 283577 : const char *tn = (tname) ? tname : _empty;
3297 283577 : const char *sn = (sname) ? sname : _empty;
3298 283577 : const char *cn = column_name(sql->sa, c);
3299 283585 : const char *ntn = sql_escape_ident(sql->ta, tn);
3300 283579 : const char *nsn = sql_escape_ident(sql->ta, sn);
3301 283602 : size_t fqtnl;
3302 :
3303 283602 : if (ntn && nsn && (fqtnl = strlen(ntn) + 1 + strlen(nsn) + 1) ){
3304 283602 : char *fqtn = SA_NEW_ARRAY(sql->ta, char, fqtnl);
3305 283599 : if (fqtn == NULL)
3306 : return NULL;
3307 283599 : snprintf(fqtn, fqtnl, "%s.%s", nsn, ntn);
3308 283599 : tblPtr = pushStr(mb, tblPtr, fqtn);
3309 283588 : nmePtr = pushStr(mb, nmePtr, cn);
3310 283587 : tpePtr = pushStr(mb, tpePtr, (t->type->localtype == TYPE_void ? "char" : t->type->base.name));
3311 283603 : lenPtr = pushInt(mb, lenPtr, t->digits);
3312 283571 : scalePtr = pushInt(mb, scalePtr, t->scale);
3313 283579 : list = pushArgument(mb,list,c->nr);
3314 : } else
3315 : return NULL;
3316 : }
3317 68346 : sa_reset(sql->ta);
3318 68323 : pushInstruction(mb,list);
3319 68323 : return list;
3320 : }
3321 :
3322 : int
3323 128753 : stmt_output(backend *be, stmt *lst)
3324 : {
3325 128753 : MalBlkPtr mb = be->mb;
3326 128753 : InstrPtr q = NULL;
3327 128753 : list *l = lst->op4.lval;
3328 128753 : int cnt = list_length(l), ok = 0;
3329 128814 : node *n = l->h;
3330 128814 : stmt *first = n->data;
3331 :
3332 : /* single value result, has a fast exit */
3333 128814 : if (cnt == 1 && first->nrcols <= 0 ){
3334 60468 : stmt *c = n->data;
3335 60468 : sql_subtype *t = tail_type(c);
3336 60402 : const char *tname = table_name(be->mvc->sa, c);
3337 60395 : const char *sname = schema_name(be->mvc->sa, c);
3338 60396 : const char *_empty = "";
3339 60396 : const char *tn = (tname) ? tname : _empty;
3340 60396 : const char *sn = (sname) ? sname : _empty;
3341 60396 : const char *cn = column_name(be->mvc->sa, c);
3342 60401 : const char *ntn = sql_escape_ident(be->mvc->ta, tn);
3343 60500 : const char *nsn = sql_escape_ident(be->mvc->ta, sn);
3344 :
3345 60507 : if (ntn && nsn) {
3346 60507 : size_t fqtnl = strlen(ntn) + 1 + strlen(nsn) + 1;
3347 60507 : char *fqtn = SA_NEW_ARRAY(be->mvc->ta, char, fqtnl);
3348 60507 : if (fqtn == NULL)
3349 : return -1;
3350 60507 : ok = 1;
3351 60507 : snprintf(fqtn, fqtnl, "%s.%s", nsn, ntn);
3352 :
3353 60507 : q = newStmt(mb, sqlRef, resultSetRef);
3354 60506 : if (q == NULL)
3355 : return -1;
3356 60506 : getArg(q,0) = newTmpVariable(mb,TYPE_int);
3357 60507 : q = pushStr(mb, q, fqtn);
3358 60505 : q = pushStr(mb, q, cn);
3359 60506 : q = pushStr(mb, q, t->type->localtype == TYPE_void ? "char" : t->type->base.name);
3360 60504 : q = pushInt(mb, q, t->digits);
3361 60501 : q = pushInt(mb, q, t->scale);
3362 60504 : q = pushInt(mb, q, t->type->eclass);
3363 60500 : q = pushArgument(mb, q, c->nr);
3364 60503 : pushInstruction(mb, q);
3365 : }
3366 60489 : sa_reset(be->mvc->ta);
3367 60477 : if (!ok)
3368 : return -1;
3369 : } else {
3370 68346 : if ((q = dump_header(be->mvc, mb, l)) == NULL)
3371 : return -1;
3372 : }
3373 : return 0;
3374 : }
3375 :
3376 : int
3377 149478 : stmt_affected_rows(backend *be, int lastnr)
3378 : {
3379 149478 : MalBlkPtr mb = be->mb;
3380 149478 : InstrPtr q = NULL;
3381 :
3382 149478 : q = newStmt(mb, sqlRef, affectedRowsRef);
3383 149724 : if (q == NULL)
3384 : return -1;
3385 149724 : q = pushArgument(mb, q, be->mvc_var);
3386 149723 : getArg(q, 0) = be->mvc_var = newTmpVariable(mb, TYPE_int);
3387 149720 : q = pushArgument(mb, q, lastnr);
3388 149720 : pushInstruction(mb, q);
3389 149724 : be->mvc_var = getDestVar(q);
3390 149724 : return 0;
3391 : }
3392 :
3393 : stmt *
3394 176719 : stmt_append(backend *be, stmt *c, stmt *a)
3395 : {
3396 176719 : MalBlkPtr mb = be->mb;
3397 176719 : InstrPtr q = NULL;
3398 :
3399 176719 : if (c == NULL || a == NULL || c->nr < 0 || a->nr < 0)
3400 0 : goto bailout;
3401 176719 : q = newStmt(mb, batRef, appendRef);
3402 176719 : if (q == NULL)
3403 0 : goto bailout;
3404 176719 : q = pushArgument(mb, q, c->nr);
3405 176719 : q = pushArgument(mb, q, a->nr);
3406 176719 : q = pushBit(mb, q, TRUE);
3407 176719 : bool enabled = be->mvc->sa->eb.enabled;
3408 176719 : be->mvc->sa->eb.enabled = false;
3409 176719 : stmt *s = stmt_create(be->mvc->sa, st_append);
3410 176719 : be->mvc->sa->eb.enabled = enabled;
3411 176719 : if(!s) {
3412 0 : freeInstruction(q);
3413 0 : goto bailout;
3414 : }
3415 176719 : s->op1 = c;
3416 176719 : s->op2 = a;
3417 176719 : s->nrcols = c->nrcols;
3418 176719 : s->key = c->key;
3419 176719 : s->nr = getDestVar(q);
3420 176719 : s->q = q;
3421 176719 : pushInstruction(mb, q);
3422 176719 : 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 137695 : stmt_append_bulk(backend *be, stmt *c, list *l)
3432 : {
3433 137695 : MalBlkPtr mb = be->mb;
3434 137695 : InstrPtr q = NULL;
3435 137695 : bool needs_columns = false;
3436 :
3437 137695 : 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 890002 : for (node *n = l->h; n; n = n->next) {
3443 752307 : stmt *t = n->data;
3444 752307 : needs_columns |= t->nrcols > 0;
3445 : }
3446 137695 : 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 137695 : q = newStmtArgs(mb, batRef, appendBulkRef, list_length(l) + 3);
3455 138042 : if (q == NULL)
3456 0 : goto bailout;
3457 138042 : q = pushArgument(mb, q, c->nr);
3458 138033 : q = pushBit(mb, q, TRUE);
3459 890544 : for (node *n = l->h ; n ; n = n->next) {
3460 752556 : stmt *a = n->data;
3461 752556 : q = pushArgument(mb, q, a->nr);
3462 : }
3463 137988 : bool enabled = be->mvc->sa->eb.enabled;
3464 137988 : be->mvc->sa->eb.enabled = false;
3465 137988 : stmt *s = stmt_create(be->mvc->sa, st_append_bulk);
3466 137835 : be->mvc->sa->eb.enabled = enabled;
3467 137835 : if(!s) {
3468 0 : freeInstruction(q);
3469 0 : goto bailout;
3470 : }
3471 137835 : s->op1 = c;
3472 137835 : s->op4.lval = l;
3473 137835 : s->nrcols = c->nrcols;
3474 137835 : s->key = c->key;
3475 137835 : s->nr = getDestVar(q);
3476 137835 : s->q = q;
3477 137835 : pushInstruction(mb, q);
3478 137835 : 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 16083 : stmt_pack(backend *be, stmt *c, int n)
3488 : {
3489 16083 : MalBlkPtr mb = be->mb;
3490 16083 : InstrPtr q = NULL;
3491 :
3492 16083 : if (c == NULL || c->nr < 0)
3493 0 : goto bailout;
3494 16083 : q = newStmtArgs(mb, matRef, packIncrementRef, 3);
3495 16083 : if (q == NULL)
3496 0 : goto bailout;
3497 16083 : q = pushArgument(mb, q, c->nr);
3498 16083 : q = pushInt(mb, q, n);
3499 16083 : bool enabled = be->mvc->sa->eb.enabled;
3500 16083 : be->mvc->sa->eb.enabled = false;
3501 16083 : stmt *s = stmt_create(be->mvc->sa, st_append);
3502 16083 : be->mvc->sa->eb.enabled = enabled;
3503 16083 : if(!s) {
3504 0 : freeInstruction(q);
3505 0 : goto bailout;
3506 : }
3507 16083 : s->op1 = c;
3508 16083 : s->nrcols = c->nrcols;
3509 16083 : s->key = c->key;
3510 16083 : s->nr = getDestVar(q);
3511 16083 : s->q = q;
3512 16083 : pushInstruction(mb, q);
3513 16083 : 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 29782 : stmt_pack_add(backend *be, stmt *c, stmt *a)
3524 : {
3525 29782 : MalBlkPtr mb = be->mb;
3526 29782 : InstrPtr q = NULL;
3527 :
3528 29782 : if (c == NULL || a == NULL || c->nr < 0 || a->nr < 0)
3529 0 : goto bailout;
3530 29782 : q = newStmtArgs(mb, matRef, packIncrementRef, 3);
3531 29782 : if (q == NULL)
3532 0 : goto bailout;
3533 29782 : q = pushArgument(mb, q, c->nr);
3534 29782 : q = pushArgument(mb, q, a->nr);
3535 29782 : bool enabled = be->mvc->sa->eb.enabled;
3536 29782 : be->mvc->sa->eb.enabled = false;
3537 29782 : stmt *s = stmt_create(be->mvc->sa, st_append);
3538 29782 : be->mvc->sa->eb.enabled = enabled;
3539 29782 : if(!s) {
3540 0 : freeInstruction(q);
3541 0 : goto bailout;
3542 : }
3543 29782 : s->op1 = c;
3544 29782 : s->op2 = a;
3545 29782 : s->nrcols = c->nrcols;
3546 29782 : s->key = c->key;
3547 29782 : s->nr = getDestVar(q);
3548 29782 : s->q = q;
3549 29782 : pushInstruction(mb, q);
3550 29782 : 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 106274 : stmt_claim(backend *be, sql_table *t, stmt *cnt)
3560 : {
3561 106274 : MalBlkPtr mb = be->mb;
3562 106274 : InstrPtr q = NULL;
3563 :
3564 106274 : if (!t || cnt->nr < 0)
3565 0 : goto bailout;
3566 106274 : assert(t->s); /* declared table */
3567 106274 : q = newStmtArgs(mb, sqlRef, claimRef, 6);
3568 106376 : if (q == NULL)
3569 0 : goto bailout;
3570 : /* returns offset or offsets */
3571 106376 : q = pushReturn(mb, q, newTmpVariable(mb, newBatType(TYPE_oid)));
3572 106370 : q = pushArgument(mb, q, be->mvc_var);
3573 106358 : q = pushSchema(mb, q, t);
3574 106336 : q = pushStr(mb, q, t->base.name);
3575 106346 : q = pushArgument(mb, q, cnt->nr);
3576 106354 : bool enabled = be->mvc->sa->eb.enabled;
3577 106354 : be->mvc->sa->eb.enabled = false;
3578 106354 : stmt *s = stmt_create(be->mvc->sa, st_claim);
3579 106306 : be->mvc->sa->eb.enabled = enabled;
3580 106306 : if(!s) {
3581 0 : freeInstruction(q);
3582 0 : goto bailout;
3583 : }
3584 106306 : s->op1 = cnt;
3585 106306 : s->op4.tval = t;
3586 106306 : s->nr = getDestVar(q);
3587 106306 : s->q = q;
3588 106306 : pushInstruction(mb, q);
3589 106306 : 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 149409 : stmt_add_dependency_change(backend *be, sql_table *t, stmt *cnt)
3599 : {
3600 149409 : MalBlkPtr mb = be->mb;
3601 149409 : InstrPtr q = NULL;
3602 :
3603 149409 : if (!t || cnt->nr < 0)
3604 0 : goto bailout;
3605 149409 : q = newStmtArgs(mb, sqlRef, dependRef, 4);
3606 149965 : if (q == NULL)
3607 0 : goto bailout;
3608 149965 : q = pushSchema(mb, q, t);
3609 149952 : q = pushStr(mb, q, t->base.name);
3610 149958 : q = pushArgument(mb, q, cnt->nr);
3611 149961 : pushInstruction(mb, q);
3612 149961 : 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 14835 : stmt_add_column_predicate(backend *be, sql_column *c)
3621 : {
3622 14835 : MalBlkPtr mb = be->mb;
3623 14835 : InstrPtr q = NULL;
3624 :
3625 14835 : if (!c)
3626 0 : goto bailout;
3627 14835 : q = newStmtArgs(mb, sqlRef, predicateRef, 4);
3628 14891 : if (q == NULL)
3629 0 : goto bailout;
3630 14891 : q = pushSchema(mb, q, c->t);
3631 14890 : q = pushStr(mb, q, c->t->base.name);
3632 14891 : q = pushStr(mb, q, c->base.name);
3633 14891 : pushInstruction(mb, q);
3634 14891 : 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 55751 : stmt_replace(backend *be, stmt *r, stmt *id, stmt *val)
3643 : {
3644 55751 : MalBlkPtr mb = be->mb;
3645 55751 : InstrPtr q = NULL;
3646 :
3647 55751 : if (r->nr < 0)
3648 0 : goto bailout;
3649 :
3650 55751 : q = newStmt(mb, batRef, replaceRef);
3651 55751 : if (q == NULL)
3652 0 : goto bailout;
3653 55751 : q = pushArgument(mb, q, r->nr);
3654 55751 : q = pushArgument(mb, q, id->nr);
3655 55751 : q = pushArgument(mb, q, val->nr);
3656 55751 : q = pushBit(mb, q, TRUE); /* forced */
3657 55751 : bool enabled = be->mvc->sa->eb.enabled;
3658 55751 : be->mvc->sa->eb.enabled = false;
3659 55751 : stmt *s = stmt_create(be->mvc->sa, st_replace);
3660 55751 : be->mvc->sa->eb.enabled = enabled;
3661 55751 : if(!s) {
3662 0 : freeInstruction(q);
3663 0 : goto bailout;
3664 : }
3665 55751 : s->op1 = r;
3666 55751 : s->op2 = id;
3667 55751 : s->op3 = val;
3668 55751 : s->nrcols = r->nrcols;
3669 55751 : s->key = r->key;
3670 55751 : s->nr = getDestVar(q);
3671 55751 : s->q = q;
3672 55751 : s->cand = r->cand;
3673 55751 : pushInstruction(mb, q);
3674 55751 : 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 41468 : stmt_table_clear(backend *be, sql_table *t, int restart_sequences)
3684 : {
3685 41468 : MalBlkPtr mb = be->mb;
3686 41468 : InstrPtr q = NULL;
3687 :
3688 41468 : 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 41466 : q = newStmt(mb, sqlRef, clear_tableRef);
3701 41823 : if (q == NULL)
3702 0 : goto bailout;
3703 41823 : q = pushSchema(mb, q, t);
3704 41808 : q = pushStr(mb, q, t->base.name);
3705 41758 : q = pushInt(mb, q, restart_sequences);
3706 41735 : pushInstruction(mb, q);
3707 : }
3708 41759 : 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 39473 : stmt_exception(backend *be, stmt *cond, const char *errstr, int errcode)
3727 : {
3728 39473 : MalBlkPtr mb = be->mb;
3729 39473 : InstrPtr q = NULL;
3730 :
3731 39473 : if (cond->nr < 0)
3732 : return NULL;
3733 :
3734 : /* if(bit(l)) { error(r);} ==raising an exception */
3735 39473 : q = newStmt(mb, sqlRef, assertRef);
3736 39524 : if (q == NULL)
3737 0 : goto bailout;
3738 39524 : q = pushArgument(mb, q, cond->nr);
3739 39524 : q = pushStr(mb, q, errstr);
3740 39524 : bool enabled = be->mvc->sa->eb.enabled;
3741 39524 : be->mvc->sa->eb.enabled = false;
3742 39524 : stmt *s = stmt_create(be->mvc->sa, st_exception);
3743 39524 : be->mvc->sa->eb.enabled = enabled;
3744 39524 : if(!s) {
3745 0 : freeInstruction(q);
3746 0 : return NULL;
3747 : }
3748 39524 : assert(cond);
3749 39524 : s->op1 = cond;
3750 39524 : (void)errcode;
3751 39524 : s->nrcols = 0;
3752 39524 : s->q = q;
3753 39524 : s->nr = getDestVar(q);
3754 39524 : pushInstruction(mb, q);
3755 39524 : 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 17543 : tail_set_type(mvc *m, stmt *st, sql_subtype *t)
3767 : {
3768 43125 : for (;;) {
3769 43125 : switch (st->type) {
3770 3689 : case st_const:
3771 3689 : st = st->op2;
3772 3689 : continue;
3773 18271 : case st_alias:
3774 : case st_gen_group:
3775 : case st_order:
3776 18271 : st = st->op1;
3777 18271 : continue;
3778 0 : case st_list:
3779 0 : st = st->op4.lval->h->data;
3780 0 : continue;
3781 3622 : case st_join:
3782 : case st_join2:
3783 : case st_joinN:
3784 3622 : if (st->flag == cmp_project) {
3785 3622 : st = st->op2;
3786 3622 : continue;
3787 : }
3788 : return;
3789 2782 : case st_aggr:
3790 : case st_Nop: {
3791 2782 : list *res = st->op4.funcval->res;
3792 :
3793 2782 : if (res && list_length(res) == 1)
3794 2782 : res->h->data = t;
3795 : return;
3796 : }
3797 9190 : case st_atom:
3798 9190 : st->op4.aval = atom_set_type(m->sa, st->op4.aval, t);
3799 9190 : 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 54695 : stmt_convert(backend *be, stmt *v, stmt *sel, sql_subtype *f, sql_subtype *t)
3939 : {
3940 54695 : MalBlkPtr mb = be->mb;
3941 54695 : InstrPtr q = NULL;
3942 54695 : const char *convert = t->type->impl, *mod = calcRef;
3943 54695 : int pushed = (v->cand && v->cand == sel), no_candidates = 0;
3944 54695 : bool add_tz = false;
3945 : /* convert types and make sure they are rounded up correctly */
3946 :
3947 54695 : if (v->nr < 0)
3948 0 : goto bailout;
3949 :
3950 54695 : if (f->type->eclass != EC_EXTERNAL && t->type->eclass != EC_EXTERNAL &&
3951 : /* general cases */
3952 54328 : ((t->type->localtype == f->type->localtype && t->type->eclass == f->type->eclass &&
3953 54328 : !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 1786 : (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 44923 : (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 17543 : tail_set_type(be->mvc, v, t);
3960 17543 : return v;
3961 : }
3962 :
3963 : /* external types have sqlname convert functions,
3964 : these can generate errors (fromstr cannot) */
3965 37152 : if (t->type->eclass == EC_EXTERNAL)
3966 339 : convert = t->type->base.name;
3967 36813 : else if (t->type->eclass == EC_MONTH)
3968 : convert = "month_interval";
3969 36763 : else if (t->type->eclass == EC_SEC)
3970 194 : convert = "second_interval";
3971 :
3972 37152 : no_candidates = t->type->eclass == EC_EXTERNAL && strcmp(convert, "uuid") != 0; /* uuids conversions support candidate lists */
3973 :
3974 37152 : 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 37028 : if (v->nrcols == 0 && (!sel || sel->nrcols == 0)) { /* simple calc */
3986 8480 : q = newStmtArgs(mb, mod, convert, 13);
3987 8480 : if (q == NULL)
3988 0 : goto bailout;
3989 28569 : } 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 28527 : 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 28527 : q = newStmtArgs(mb, mod==calcRef?batcalcRef:batmtimeRef, convert, 13);
4011 28527 : 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 37194 : if (EC_VARCHAR(t->type->eclass) && !(trivial_string_conversion(f->type->eclass) && t->digits == 0)) {
4017 1926 : q = pushInt(mb, q, f->type->eclass);
4018 1926 : q = pushInt(mb, q, f->digits);
4019 1926 : q = pushInt(mb, q, f->scale);
4020 1926 : q = pushInt(mb, q, type_has_tz(f));
4021 35102 : } else if (f->type->eclass == EC_DEC) {
4022 : /* scale of the current decimal */
4023 1566 : q = pushInt(mb, q, f->scale);
4024 33536 : } 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 37028 : q = pushArgument(mb, q, v->nr);
4029 37028 : if (add_tz)
4030 : q = pushLng(mb, q, be->mvc->timezone);
4031 37028 : if (sel && !pushed && !v->cand) {
4032 3578 : q = pushArgument(mb, q, sel->nr);
4033 3578 : pushed = 1;
4034 33450 : } else if (v->nrcols > 0 && !no_candidates) {
4035 24949 : q = pushNilBat(mb, q);
4036 : }
4037 37028 : 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 3192 : q = pushInt(mb, q, t->digits);
4040 3192 : if (!EC_TEMP_FRAC(t->type->eclass))
4041 2853 : q = pushInt(mb, q, t->scale);
4042 : }
4043 : /* convert to string, give error on to large strings */
4044 37194 : if (EC_VARCHAR(t->type->eclass) && !(trivial_string_conversion(f->type->eclass) && t->digits == 0))
4045 1926 : q = pushInt(mb, q, t->digits);
4046 : /* convert a string to a time(stamp) with time zone */
4047 37028 : 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 37028 : 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 37028 : bool enabled = be->mvc->sa->eb.enabled;
4073 37028 : be->mvc->sa->eb.enabled = false;
4074 37028 : stmt *s = stmt_create(be->mvc->sa, st_convert);
4075 37028 : be->mvc->sa->eb.enabled = enabled;
4076 37028 : if(!s) {
4077 0 : freeInstruction(q);
4078 0 : goto bailout;
4079 : }
4080 37028 : s->op1 = v;
4081 37028 : s->nrcols = 0; /* function without arguments returns single value */
4082 37028 : s->key = v->key;
4083 37028 : s->nrcols = v->nrcols;
4084 37028 : s->aggr = v->aggr;
4085 37028 : s->op4.typeval = *t;
4086 37028 : s->nr = getDestVar(q);
4087 37028 : s->q = q;
4088 37028 : s->cand = pushed ? sel : NULL;
4089 37028 : pushInstruction(mb, q);
4090 37028 : 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 27099 : stmt_unop(backend *be, stmt *op1, stmt *sel, sql_subfunc *op)
4102 : {
4103 27099 : list *ops = sa_list(be->mvc->sa);
4104 27134 : list_append(ops, op1);
4105 27140 : stmt *r = stmt_Nop(be, stmt_list(be, ops), sel, op, NULL);
4106 27146 : if (r && !r->cand)
4107 27146 : r->cand = op1->cand;
4108 27146 : return r;
4109 : }
4110 :
4111 : stmt *
4112 47378 : stmt_binop(backend *be, stmt *op1, stmt *op2, stmt *sel, sql_subfunc *op)
4113 : {
4114 47378 : list *ops = sa_list(be->mvc->sa);
4115 47379 : list_append(ops, op1);
4116 47383 : list_append(ops, op2);
4117 47384 : stmt *r = stmt_Nop(be, stmt_list(be, ops), sel, op, NULL);
4118 47384 : if (r && !r->cand)
4119 47384 : r->cand = op1->cand?op1->cand:op2->cand;
4120 47384 : return r;
4121 : }
4122 :
4123 : #define LANG_INT_OR_MAL(l) ((l)==FUNC_LANG_INT || (l)==FUNC_LANG_MAL)
4124 :
4125 : stmt *
4126 287561 : stmt_Nop(backend *be, stmt *ops, stmt *sel, sql_subfunc *f, stmt* rows)
4127 : {
4128 287561 : MalBlkPtr mb = be->mb;
4129 287561 : InstrPtr q = NULL;
4130 287561 : const char *mod = sql_func_mod(f->func), *fimp = backend_function_imp(be, f->func);
4131 287657 : sql_subtype *tpe = NULL;
4132 287657 : int push_cands = 0, default_nargs;
4133 287657 : stmt *o = NULL, *card = NULL;
4134 :
4135 287657 : if (ops == NULL)
4136 0 : goto bailout;
4137 :
4138 287657 : 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 287552 : } else if (list_length(ops->op4.lval)) {
4143 285690 : o = ops->op4.lval->h->data;
4144 821170 : for (node *n = ops->op4.lval->h; n; n = n->next) {
4145 535480 : stmt *c = n->data;
4146 :
4147 535480 : if (c && o->nrcols < c->nrcols)
4148 535480 : o = c;
4149 : }
4150 : }
4151 :
4152 : /* handle nullif */
4153 287679 : if (list_length(ops->op4.lval) == 2 &&
4154 172585 : 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 287592 : if (backend_create_subfunc(be, f, ops->op4.lval) < 0)
4185 2 : goto bailout;
4186 287544 : mod = sql_func_mod(f->func);
4187 287614 : fimp = convertMultiplexFcn(backend_function_imp(be, f->func));
4188 287594 : push_cands = f->func->type == F_FUNC && can_push_cands(sel, mod, fimp);
4189 329443 : 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 287566 : 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 287566 : if (o && o->nrcols > 0 && f->func->type != F_LOADER && f->func->type != F_PROC) {
4196 174619 : sql_subtype *res = f->res->h->data;
4197 :
4198 349222 : q = newStmtArgs(mb, f->func->type == F_UNION ? batmalRef : malRef, multiplexRef, default_nargs);
4199 174619 : if (q == NULL)
4200 0 : goto bailout;
4201 174619 : if (rows)
4202 105 : q = pushArgument(mb, q, card->nr);
4203 174619 : q = pushStr(mb, q, mod);
4204 174619 : q = pushStr(mb, q, fimp);
4205 174619 : setVarType(mb, getArg(q, 0), newBatType(res->type->localtype));
4206 : } else {
4207 112947 : q = newStmtArgs(mb, mod, fimp, default_nargs);
4208 113040 : if (q == NULL)
4209 0 : goto bailout;
4210 :
4211 113040 : if (rows)
4212 0 : q = pushArgument(mb, q, card->nr);
4213 113040 : if (f->res && list_length(f->res)) {
4214 71197 : sql_subtype *res = f->res->h->data;
4215 :
4216 71197 : setVarType(mb, getArg(q, 0), res->type->localtype);
4217 : }
4218 : }
4219 287659 : 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 287659 : if (f->func->lang == FUNC_LANG_C) {
4229 35 : q = pushBit(mb, q, 0);
4230 287624 : } else if (f->func->lang == FUNC_LANG_CPP) {
4231 1 : q = pushBit(mb, q, 1);
4232 : }
4233 287659 : 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 287659 : if (f->func->type == F_UNION || (f->func->type == F_LOADER && f->res != NULL))
4239 2785 : q = table_func_create_result(mb, q, f->func, f->res);
4240 287659 : if (list_length(ops->op4.lval))
4241 285774 : tpe = tail_type(ops->op4.lval->h->data);
4242 :
4243 823333 : for (node *n = ops->op4.lval->h; n; n = n->next) {
4244 535680 : stmt *op = n->data;
4245 535680 : q = pushArgument(mb, q, op->nr);
4246 : }
4247 : /* push candidate lists if that's the case */
4248 287653 : if (push_cands) {
4249 178314 : for (node *n = ops->op4.lval->h; n; n = n->next) {
4250 118336 : stmt *op = n->data;
4251 :
4252 118336 : if (op->nrcols > 0) {
4253 78102 : if (op->cand && op->cand == sel) {
4254 35479 : q = pushNilBat(mb, q);
4255 : } else {
4256 42623 : q = pushArgument(mb, q, sel->nr);
4257 : }
4258 : }
4259 : }
4260 : }
4261 : /* special case for round function on decimals */
4262 287653 : 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 287653 : pushInstruction(mb, q);
4267 : }
4268 :
4269 287749 : stmt *s = stmt_create(be->mvc->sa, st_Nop);
4270 287747 : if(!s) {
4271 0 : goto bailout;
4272 : }
4273 287747 : s->op1 = ops;
4274 287747 : if (o) {
4275 285878 : s->nrcols = o->nrcols;
4276 285878 : s->key = o->key;
4277 285878 : s->aggr = o->aggr;
4278 : } else {
4279 1869 : s->nrcols = 0;
4280 1869 : s->key = 1;
4281 : }
4282 287747 : s->op4.funcval = f;
4283 287747 : s->nr = getDestVar(q);
4284 287747 : s->q = q;
4285 287747 : if (sel && push_cands && s->nrcols)
4286 58457 : 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 188 : stmt_func(backend *be, stmt *ops, const char *name, sql_rel *rel, int f_union)
4314 : {
4315 188 : MalBlkPtr mb = be->mb;
4316 188 : InstrPtr q = NULL;
4317 188 : prop *p = NULL;
4318 :
4319 : /* dump args */
4320 188 : if (ops && ops->nr < 0)
4321 0 : goto bailout;
4322 :
4323 188 : if ((p = find_prop(rel->p, PROP_REMOTE)))
4324 188 : rel->p = prop_remove(rel->p, p);
4325 : /* sql_processrelation may split projections, so make sure the topmost relation only contains references */
4326 188 : int opt = rel->opt;
4327 188 : rel = rel_project(be->mvc->sa, rel, rel_projections(be->mvc, rel, NULL, 1, 1));
4328 188 : if (!(rel = sql_processrelation(be->mvc, rel, 0, 0, 1, 1)))
4329 0 : goto bailout;
4330 188 : if (p) {
4331 188 : p->p = rel->p;
4332 188 : rel->p = p;
4333 : }
4334 188 : rel->opt = opt;
4335 :
4336 188 : if (monet5_create_relational_function(be->mvc, sql_private_module_name, name, rel, ops, NULL, 1) < 0)
4337 0 : goto bailout;
4338 :
4339 188 : int nargs;
4340 188 : sql_rel *r = relational_func_create_result_part1(be->mvc, rel, &nargs);
4341 188 : if (ops)
4342 186 : nargs += list_length(ops->op4.lval);
4343 188 : if (f_union)
4344 0 : q = newStmt(mb, batmalRef, multiplexRef);
4345 : else
4346 188 : q = newStmt(mb, sql_private_module_name, name);
4347 188 : if (q == NULL)
4348 0 : goto bailout;
4349 188 : q = relational_func_create_result_part2(mb, q, r);
4350 188 : if (f_union) {
4351 0 : q = pushStr(mb, q, sql_private_module_name);
4352 0 : q = pushStr(mb, q, name);
4353 : }
4354 188 : if (ops) {
4355 208 : for (node *n = ops->op4.lval->h; n; n = n->next) {
4356 22 : stmt *op = n->data;
4357 :
4358 22 : q = pushArgument(mb, q, op->nr);
4359 : }
4360 : }
4361 :
4362 188 : allocator *sa = be->mvc->sa;
4363 188 : bool enabled = be->mvc->sa->eb.enabled;
4364 188 : be->mvc->sa->eb.enabled = false;
4365 188 : stmt *o = NULL, *s = stmt_create(sa, st_func);
4366 188 : be->mvc->sa->eb.enabled = enabled;
4367 188 : if(!s) {
4368 0 : freeInstruction(q);
4369 0 : goto bailout;
4370 : }
4371 188 : s->op1 = ops;
4372 188 : s->op2 = stmt_atom_string(be, name);
4373 188 : s->op4.rel = rel;
4374 188 : s->flag = f_union;
4375 188 : if (ops && list_length(ops->op4.lval)) {
4376 10 : node *n;
4377 32 : for (n = ops->op4.lval->h, o = n->data; n; n = n->next) {
4378 22 : stmt *c = n->data;
4379 :
4380 22 : if (o->nrcols < c->nrcols)
4381 0 : o = c;
4382 : }
4383 : }
4384 :
4385 10 : if (o) {
4386 10 : s->nrcols = o->nrcols;
4387 10 : s->key = o->key;
4388 10 : s->aggr = o->aggr;
4389 : } else {
4390 178 : s->nrcols = 0;
4391 178 : s->key = 1;
4392 : }
4393 188 : s->nr = getDestVar(q);
4394 188 : s->q = q;
4395 188 : pushInstruction(mb, q);
4396 188 : return s;
4397 :
4398 0 : bailout:
4399 0 : if (be->mvc->sa->eb.enabled)
4400 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
4401 : return NULL;
4402 : }
4403 :
4404 : stmt *
4405 85343 : stmt_aggr(backend *be, stmt *op1, stmt *grp, stmt *ext, sql_subfunc *op, int reduce, int no_nil, int nil_if_empty)
4406 : {
4407 85343 : MalBlkPtr mb = be->mb;
4408 85343 : InstrPtr q = NULL;
4409 85343 : const char *mod, *aggrfunc;
4410 85343 : sql_subtype *res = op->res->h->data;
4411 85343 : int restype = res->type->localtype;
4412 85343 : bool complex_aggr = false;
4413 85343 : int *stmt_nr = NULL;
4414 85343 : int avg = 0;
4415 :
4416 85343 : if (op1->nr < 0)
4417 0 : goto bailout;
4418 85343 : if (backend_create_subfunc(be, op, NULL) < 0)
4419 0 : goto bailout;
4420 85570 : mod = sql_func_mod(op->func);
4421 85516 : aggrfunc = backend_function_imp(be, op->func);
4422 :
4423 85551 : if (LANG_INT_OR_MAL(op->func->lang)) {
4424 85237 : if (strcmp(aggrfunc, "avg") == 0)
4425 : avg = 1;
4426 83864 : if (avg || strcmp(aggrfunc, "sum") == 0 || strcmp(aggrfunc, "prod") == 0
4427 76785 : || strcmp(aggrfunc, "str_group_concat") == 0)
4428 : complex_aggr = true;
4429 85237 : if (restype == TYPE_dbl)
4430 1564 : avg = 0;
4431 : }
4432 :
4433 171102 : int argc = 1
4434 85551 : + 2 * avg
4435 85551 : + (LANG_EXT(op->func->lang) != 0)
4436 85551 : + 2 * (op->func->lang == FUNC_LANG_C || op->func->lang == FUNC_LANG_CPP)
4437 85551 : + (op->func->lang == FUNC_LANG_PY || op->func->lang == FUNC_LANG_R)
4438 85551 : + (op1->type != st_list ? 1 : list_length(op1->op4.lval))
4439 85551 : + (grp ? 4 : avg + 1);
4440 :
4441 85551 : if (grp) {
4442 6718 : char *aggrF = SA_NEW_ARRAY(be->mvc->sa, char, strlen(aggrfunc) + 4);
4443 6718 : if (!aggrF)
4444 0 : goto bailout;
4445 6718 : stpcpy(stpcpy(aggrF, "sub"), aggrfunc);
4446 6718 : aggrfunc = aggrF;
4447 6718 : if ((grp && grp->nr < 0) || (ext && ext->nr < 0))
4448 0 : goto bailout;
4449 :
4450 6718 : q = newStmtArgs(mb, mod, aggrfunc, argc);
4451 6718 : if (q == NULL)
4452 0 : goto bailout;
4453 6718 : setVarType(mb, getArg(q, 0), newBatType(restype));
4454 6718 : if (avg) { /* for avg also return rest and count */
4455 96 : q = pushReturn(mb, q, newTmpVariable(mb, newBatType(TYPE_lng)));
4456 96 : q = pushReturn(mb, q, newTmpVariable(mb, newBatType(TYPE_lng)));
4457 : }
4458 : } else {
4459 78833 : q = newStmtArgs(mb, mod, aggrfunc, argc);
4460 79010 : if (q == NULL)
4461 0 : goto bailout;
4462 79010 : if (complex_aggr) {
4463 6783 : setVarType(mb, getArg(q, 0), restype);
4464 6783 : if (avg) { /* for avg also return rest and count */
4465 57 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_lng));
4466 57 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_lng));
4467 : }
4468 : }
4469 : }
4470 :
4471 85728 : if (LANG_EXT(op->func->lang))
4472 47 : q = pushPtr(mb, q, op->func);
4473 85727 : if (op->func->lang == FUNC_LANG_R ||
4474 85692 : op->func->lang >= FUNC_LANG_PY ||
4475 : op->func->lang == FUNC_LANG_C ||
4476 : op->func->lang == FUNC_LANG_CPP) {
4477 47 : if (!grp) {
4478 20 : setVarType(mb, getArg(q, 0), restype);
4479 : }
4480 47 : if (op->func->lang == FUNC_LANG_C) {
4481 12 : q = pushBit(mb, q, 0);
4482 35 : } else if (op->func->lang == FUNC_LANG_CPP) {
4483 0 : q = pushBit(mb, q, 1);
4484 : }
4485 47 : q = pushStr(mb, q, op->func->query);
4486 : }
4487 :
4488 85727 : if (op1->type != st_list) {
4489 79951 : q = pushArgument(mb, q, op1->nr);
4490 : } else {
4491 5776 : int i;
4492 5776 : node *n;
4493 :
4494 11974 : for (i=0, n = op1->op4.lval->h; n; n = n->next, i++) {
4495 6199 : stmt *op = n->data;
4496 :
4497 6199 : if (stmt_nr)
4498 : q = pushArgument(mb, q, stmt_nr[i]);
4499 : else
4500 6199 : q = pushArgument(mb, q, op->nr);
4501 : }
4502 : }
4503 85726 : if (grp) {
4504 6718 : q = pushArgument(mb, q, grp->nr);
4505 6718 : q = pushArgument(mb, q, ext->nr);
4506 6718 : if (LANG_INT_OR_MAL(op->func->lang)) {
4507 6691 : if (avg) /* push nil candidates */
4508 96 : q = pushNilBat(mb, q);
4509 6691 : q = pushBit(mb, q, no_nil);
4510 : }
4511 79008 : } else if (LANG_INT_OR_MAL(op->func->lang) && no_nil && strncmp(aggrfunc, "count", 5) == 0) {
4512 1641 : q = pushBit(mb, q, no_nil);
4513 77367 : } else if (LANG_INT_OR_MAL(op->func->lang) && !nil_if_empty && strncmp(aggrfunc, "sum", 3) == 0) {
4514 0 : q = pushBit(mb, q, FALSE);
4515 77367 : } else if (LANG_INT_OR_MAL(op->func->lang) && avg) { /* push candidates */
4516 57 : q = pushNilBat(mb, q);
4517 57 : q = pushBit(mb, q, no_nil);
4518 : }
4519 :
4520 85726 : bool enabled = be->mvc->sa->eb.enabled;
4521 85726 : be->mvc->sa->eb.enabled = false;
4522 85726 : stmt *s = stmt_create(be->mvc->sa, st_aggr);
4523 85718 : be->mvc->sa->eb.enabled = enabled;
4524 85718 : if(!s) {
4525 0 : freeInstruction(q);
4526 0 : goto bailout;
4527 : }
4528 85718 : s->op1 = op1;
4529 85718 : if (grp) {
4530 6718 : s->op2 = grp;
4531 6718 : s->op3 = ext;
4532 6718 : s->nrcols = 1;
4533 : } else {
4534 79000 : if (!reduce)
4535 0 : s->nrcols = 1;
4536 : }
4537 85718 : s->key = reduce;
4538 85718 : s->aggr = reduce;
4539 85718 : s->flag = no_nil;
4540 85718 : s->op4.funcval = op;
4541 85718 : s->nr = getDestVar(q);
4542 85718 : s->q = q;
4543 85718 : pushInstruction(mb, q);
4544 85718 : return s;
4545 :
4546 0 : bailout:
4547 0 : if (be->mvc->sa->eb.enabled)
4548 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
4549 : return NULL;
4550 : }
4551 :
4552 : static stmt *
4553 5097844 : stmt_alias_(backend *be, stmt *op1, int label, const char *tname, const char *alias)
4554 : {
4555 5097844 : assert(label);
4556 5097844 : stmt *s = stmt_create(be->mvc->sa, st_alias);
4557 5097414 : if(!s) {
4558 : return NULL;
4559 : }
4560 5097414 : s->label = label;
4561 5097414 : s->op1 = op1;
4562 5097414 : s->nrcols = op1->nrcols;
4563 5097414 : s->key = op1->key;
4564 5097414 : s->aggr = op1->aggr;
4565 :
4566 5097414 : s->tname = tname;
4567 5097414 : s->cname = alias;
4568 5097414 : s->nr = op1->nr;
4569 5097414 : s->q = op1->q;
4570 5097414 : return s;
4571 : }
4572 :
4573 : stmt *
4574 4519622 : stmt_alias(backend *be, stmt *op1, int label, const char *tname, const char *alias)
4575 : {
4576 : /*
4577 : if (((!op1->tname && !tname) ||
4578 : (op1->tname && tname && strcmp(op1->tname, tname)==0)) &&
4579 : op1->cname && strcmp(op1->cname, alias)==0)
4580 : return op1;
4581 : */
4582 4519622 : return stmt_alias_(be, op1, label, tname, alias);
4583 : }
4584 :
4585 : stmt *
4586 578213 : stmt_as(backend *be, stmt *s, stmt *org)
4587 : {
4588 578213 : assert(org->type == st_alias);
4589 578213 : return stmt_alias_(be, s, org->label, org->tname, org->cname);
4590 : }
4591 :
4592 : sql_subtype *
4593 1652271 : tail_type(stmt *st)
4594 : {
4595 8847907 : for (;;) {
4596 8847907 : switch (st->type) {
4597 37282 : case st_const:
4598 37282 : st = st->op2;
4599 37282 : continue;
4600 3365 : case st_uselect:
4601 : case st_semijoin:
4602 : case st_limit:
4603 : case st_limit2:
4604 : case st_sample:
4605 : case st_tunion:
4606 : case st_tdiff:
4607 : case st_tinter:
4608 3365 : return sql_bind_localtype("oid");
4609 594 : case st_uselect2:
4610 594 : if (!st->reduce)
4611 68 : return sql_bind_localtype("bit");
4612 526 : return sql_bind_localtype("oid");
4613 3505439 : case st_alias:
4614 3505439 : if (!st->op1)
4615 183 : return &st->op4.typeval;
4616 : /* fall through */
4617 : case st_append:
4618 : case st_append_bulk:
4619 : case st_replace:
4620 : case st_gen_group:
4621 : case st_order:
4622 3965642 : st = st->op1;
4623 3965642 : continue;
4624 0 : case st_list:
4625 0 : st = st->op4.lval->h->data;
4626 0 : continue;
4627 940828 : case st_bat:
4628 940828 : return &st->op4.cval->type;
4629 2023 : case st_idxbat:
4630 2023 : if (hash_index(st->op4.idxval->type)) {
4631 274 : return sql_bind_localtype("lng");
4632 1749 : } else if (oid_index(st->op4.idxval->type)) {
4633 1749 : return sql_bind_localtype("oid");
4634 : }
4635 : /* fall through */
4636 : case st_join:
4637 : case st_join2:
4638 : case st_joinN:
4639 3192748 : if (st->flag == cmp_project) {
4640 3192712 : st = st->op2;
4641 3192712 : continue;
4642 : }
4643 : /* fall through */
4644 : case st_reorder:
4645 : case st_group:
4646 : case st_tid:
4647 : case st_mirror:
4648 15586 : return sql_bind_localtype("oid");
4649 31451 : case st_result:
4650 31451 : return &st->op4.typeval;
4651 0 : case st_table_clear:
4652 0 : return sql_bind_localtype("lng");
4653 173029 : case st_aggr:
4654 : case st_Nop: {
4655 173029 : list *res = st->op4.funcval->res;
4656 :
4657 173029 : if (res && list_length(res) == 1)
4658 173029 : return res->h->data;
4659 :
4660 : return NULL;
4661 : }
4662 191644 : case st_atom:
4663 191644 : return atom_type(st->op4.aval);
4664 291253 : case st_convert:
4665 : case st_temp:
4666 : case st_single:
4667 : case st_rs_column:
4668 291253 : return &st->op4.typeval;
4669 2307 : case st_var:
4670 2307 : if (st->op4.typeval.type)
4671 2307 : return &st->op4.typeval;
4672 : /* fall through */
4673 : case st_exception:
4674 : return NULL;
4675 8 : case st_table:
4676 8 : return sql_bind_localtype("bat");
4677 : default:
4678 0 : assert(0);
4679 : return NULL;
4680 : }
4681 : }
4682 : }
4683 :
4684 : int
4685 6727 : stmt_has_null(stmt *s)
4686 : {
4687 21250 : switch (s->type) {
4688 : case st_aggr:
4689 : case st_semijoin:
4690 : case st_uselect:
4691 : case st_uselect2:
4692 : case st_atom:
4693 : return 0;
4694 8347 : case st_alias:
4695 8347 : return stmt_has_null(s->op1);
4696 6176 : case st_join:
4697 6176 : return stmt_has_null(s->op2);
4698 4276 : case st_bat:
4699 4276 : return s->op4.cval->null;
4700 :
4701 2451 : default:
4702 2451 : return 1;
4703 : }
4704 : }
4705 :
4706 : static const char *
4707 0 : func_name(allocator *sa, const char *n1, const char *n2)
4708 : {
4709 0 : size_t l1 = _strlen(n1), l2;
4710 :
4711 0 : if (!sa)
4712 : return n1;
4713 0 : if (!n2)
4714 0 : return sa_strdup(sa, n1);
4715 0 : l2 = _strlen(n2);
4716 :
4717 0 : if (l2 > 16) { /* only support short names */
4718 0 : char *ns = SA_NEW_ARRAY(sa, char, l2 + 1);
4719 0 : if(!ns)
4720 : return NULL;
4721 0 : snprintf(ns, l2 + 1, "%s", n2);
4722 0 : return ns;
4723 : } else {
4724 0 : char *ns = SA_NEW_ARRAY(sa, char, l1 + l2 + 2), *s = ns;
4725 0 : if(!ns)
4726 : return NULL;
4727 0 : snprintf(ns, l1 + l2 + 2, "%s_%s", n1, n2);
4728 0 : return s;
4729 : }
4730 : }
4731 :
4732 : static const char *_column_name(allocator *sa, stmt *st);
4733 :
4734 : const char *
4735 2676404 : column_name(allocator *sa, stmt *st)
4736 : {
4737 2676404 : if (!st->cname)
4738 0 : st->cname = _column_name(sa, st);
4739 2676404 : return st->cname;
4740 : }
4741 :
4742 : static const char *
4743 0 : _column_name(allocator *sa, stmt *st)
4744 : {
4745 0 : switch (st->type) {
4746 0 : case st_order:
4747 : case st_reorder:
4748 0 : return column_name(sa, st->op1);
4749 0 : case st_const:
4750 : case st_join:
4751 : case st_join2:
4752 : case st_joinN:
4753 0 : return column_name(sa, st->op2);
4754 :
4755 0 : case st_mirror:
4756 : case st_group:
4757 : case st_result:
4758 : case st_append:
4759 : case st_append_bulk:
4760 : case st_replace:
4761 : case st_gen_group:
4762 : case st_semijoin:
4763 : case st_uselect:
4764 : case st_uselect2:
4765 : case st_limit:
4766 : case st_limit2:
4767 : case st_sample:
4768 : case st_tunion:
4769 : case st_tdiff:
4770 : case st_tinter:
4771 : case st_convert:
4772 0 : return column_name(sa, st->op1);
4773 0 : case st_Nop:
4774 : case st_aggr:
4775 : {
4776 0 : const char *cn = column_name(sa, st->op1);
4777 0 : return func_name(sa, st->op4.funcval->func->base.name, cn);
4778 : }
4779 0 : case st_alias:
4780 0 : if (st->op3)
4781 0 : return column_name(sa, st->op3);
4782 : break;
4783 0 : case st_bat:
4784 0 : return st->op4.cval->base.name;
4785 0 : case st_atom:
4786 0 : if (st->op4.aval->data.vtype == TYPE_str)
4787 0 : return atom2string(sa, st->op4.aval);
4788 : /* fall through */
4789 : case st_var:
4790 : case st_temp:
4791 : case st_single:
4792 0 : if (sa)
4793 0 : return sa_strdup(sa, "single_value");
4794 : return "single_value";
4795 :
4796 0 : case st_list:
4797 0 : if (list_length(st->op4.lval))
4798 0 : return column_name(sa, st->op4.lval->h->data);
4799 : /* fall through */
4800 : case st_rs_column:
4801 : return NULL;
4802 : default:
4803 : return NULL;
4804 : }
4805 : return NULL;
4806 : }
4807 :
4808 : const char *
4809 2661066 : table_name(allocator *sa, stmt *st)
4810 : {
4811 2661066 : (void)sa;
4812 2661066 : return st->tname;
4813 : }
4814 :
4815 : const char *
4816 344123 : schema_name(allocator *sa, stmt *st)
4817 : {
4818 3140994 : switch (st->type) {
4819 1205266 : case st_const:
4820 : case st_semijoin:
4821 : case st_join:
4822 : case st_join2:
4823 : case st_joinN:
4824 1205266 : return schema_name(sa, st->op2);
4825 121376 : case st_mirror:
4826 : case st_group:
4827 : case st_result:
4828 : case st_append:
4829 : case st_append_bulk:
4830 : case st_replace:
4831 : case st_gen_group:
4832 : case st_uselect:
4833 : case st_uselect2:
4834 : case st_limit:
4835 : case st_limit2:
4836 : case st_sample:
4837 : case st_tunion:
4838 : case st_tdiff:
4839 : case st_tinter:
4840 : case st_convert:
4841 : case st_Nop:
4842 : case st_aggr:
4843 : /* there are no schema aliases, ie look into the base column */
4844 121376 : if (st->op1)
4845 : return schema_name(sa, st->op1);
4846 : return NULL;
4847 1439044 : case st_alias:
4848 1439044 : if (!st->op1)
4849 : return NULL;
4850 : return schema_name(sa, st->op1);
4851 204011 : case st_bat:
4852 204011 : return st->op4.cval->t->s->base.name;
4853 : case st_atom:
4854 : return NULL;
4855 : case st_var:
4856 : case st_temp:
4857 : case st_single:
4858 : return NULL;
4859 31532 : case st_list:
4860 31532 : if (list_length(st->op4.lval))
4861 31412 : return schema_name(sa, st->op4.lval->h->data);
4862 : return NULL;
4863 : default:
4864 : return NULL;
4865 : }
4866 : }
4867 :
4868 : stmt *
4869 1120 : stmt_cond(backend *be, stmt *cond, stmt *outer, int loop /* 0 if, 1 while */, int anti )
4870 : {
4871 1120 : MalBlkPtr mb = be->mb;
4872 1120 : InstrPtr q = NULL;
4873 :
4874 1120 : if (cond->nr < 0)
4875 0 : goto bailout;
4876 1120 : if (anti) {
4877 25 : sql_subtype *bt = sql_bind_localtype("bit");
4878 25 : sql_subfunc *not = sql_bind_func(be->mvc, "sys", "not", bt, NULL, F_FUNC, true, true);
4879 25 : sql_subfunc *or = sql_bind_func(be->mvc, "sys", "or", bt, bt, F_FUNC, true, true);
4880 25 : sql_subfunc *isnull = sql_bind_func(be->mvc, "sys", "isnull", bt, NULL, F_FUNC, true, true);
4881 25 : cond = stmt_binop(be,
4882 : stmt_unop(be, cond, NULL, not),
4883 : stmt_unop(be, cond, NULL, isnull), NULL, or);
4884 : }
4885 1120 : if (!loop) { /* if */
4886 1103 : q = newAssignment(mb);
4887 1103 : if (q == NULL)
4888 0 : goto bailout;
4889 1103 : q->barrier = BARRIERsymbol;
4890 1103 : q = pushArgument(mb, q, cond->nr);
4891 : } else { /* while */
4892 17 : int c;
4893 :
4894 17 : if (outer->nr < 0)
4895 0 : goto bailout;
4896 : /* leave barrier */
4897 17 : q = newStmt(mb, calcRef, notRef);
4898 17 : if (q == NULL)
4899 0 : goto bailout;
4900 17 : q = pushArgument(mb, q, cond->nr);
4901 17 : c = getArg(q, 0);
4902 17 : pushInstruction(mb, q);
4903 :
4904 17 : q = newAssignment(mb);
4905 17 : if (q == NULL)
4906 0 : goto bailout;
4907 17 : getArg(q, 0) = outer->nr;
4908 17 : q->barrier = LEAVEsymbol;
4909 17 : q = pushArgument(mb, q, c);
4910 : }
4911 :
4912 1120 : bool enabled = be->mvc->sa->eb.enabled;
4913 1120 : be->mvc->sa->eb.enabled = false;
4914 1120 : stmt *s = stmt_create(be->mvc->sa, st_cond);
4915 1120 : be->mvc->sa->eb.enabled = enabled;
4916 1120 : if(!s) {
4917 0 : freeInstruction(q);
4918 0 : goto bailout;
4919 : }
4920 1120 : s->flag = be->mvc_var; /* keep the mvc_var of the outer context */
4921 1120 : s->loop = loop;
4922 1120 : s->op1 = cond;
4923 1120 : s->nr = getArg(q, 0);
4924 1120 : pushInstruction(mb, q);
4925 1120 : return s;
4926 :
4927 0 : bailout:
4928 0 : if (be->mvc->sa->eb.enabled)
4929 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
4930 : return NULL;
4931 : }
4932 :
4933 : stmt *
4934 1119 : stmt_control_end(backend *be, stmt *cond)
4935 : {
4936 1119 : MalBlkPtr mb = be->mb;
4937 1119 : InstrPtr q = NULL;
4938 :
4939 1119 : if (cond->nr < 0)
4940 0 : goto bailout;
4941 :
4942 1119 : if (cond->loop) { /* while */
4943 : /* redo barrier */
4944 17 : q = newAssignment(mb);
4945 17 : if (q == NULL)
4946 0 : goto bailout;
4947 17 : getArg(q, 0) = cond->nr;
4948 17 : q->argc = q->retc = 1;
4949 17 : q->barrier = REDOsymbol;
4950 17 : q = pushBit(mb, q, TRUE);
4951 : } else {
4952 1102 : q = newAssignment(mb);
4953 1103 : if (q == NULL)
4954 0 : goto bailout;
4955 1103 : getArg(q, 0) = cond->nr;
4956 1103 : q->argc = q->retc = 1;
4957 1103 : q->barrier = EXITsymbol;
4958 : }
4959 1120 : be->mvc_var = cond->flag; /* restore old mvc_var from before the barrier */
4960 1120 : bool enabled = be->mvc->sa->eb.enabled;
4961 1120 : be->mvc->sa->eb.enabled = false;
4962 1120 : stmt *s = stmt_create(be->mvc->sa, st_control_end);
4963 1120 : be->mvc->sa->eb.enabled = enabled;
4964 1120 : if(!s) {
4965 0 : freeInstruction(q);
4966 0 : goto bailout;
4967 : }
4968 1120 : s->op1 = cond;
4969 1120 : s->nr = getArg(q, 0);
4970 1120 : pushInstruction(mb, q);
4971 1120 : return s;
4972 :
4973 0 : bailout:
4974 0 : if (be->mvc->sa->eb.enabled)
4975 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
4976 : return NULL;
4977 : }
4978 :
4979 :
4980 : static InstrPtr
4981 208 : dump_cols(MalBlkPtr mb, list *l, InstrPtr q)
4982 : {
4983 208 : int i;
4984 208 : node *n;
4985 :
4986 208 : if (q == NULL)
4987 : return NULL;
4988 208 : q->retc = q->argc = 0;
4989 1670 : for (i = 0, n = l->h; n; n = n->next, i++) {
4990 1462 : stmt *c = n->data;
4991 :
4992 1462 : q = pushArgument(mb, q, c->nr);
4993 : }
4994 208 : if (q == NULL)
4995 : return NULL;
4996 208 : q->retc = q->argc;
4997 : /* Let's make it a proper assignment */
4998 1670 : for (i = 0, n = l->h; n; n = n->next, i++) {
4999 1462 : stmt *c = n->data;
5000 :
5001 1462 : q = pushArgument(mb, q, c->nr);
5002 : }
5003 : return q;
5004 : }
5005 :
5006 : stmt *
5007 664 : stmt_return(backend *be, stmt *val, int nr_declared_tables)
5008 : {
5009 664 : MalBlkPtr mb = be->mb;
5010 664 : InstrPtr q = NULL;
5011 :
5012 664 : if (val->nr < 0)
5013 0 : goto bailout;
5014 664 : int args = val->type == st_table ? 2 * list_length(val->op1->op4.lval) : 0;
5015 207 : if (args < MAXARG)
5016 : args = MAXARG;
5017 664 : q = newInstructionArgs(mb, NULL, NULL, args);
5018 664 : if (q == NULL)
5019 0 : goto bailout;
5020 664 : q->barrier= RETURNsymbol;
5021 664 : if (val->type == st_table) {
5022 208 : list *l = val->op1->op4.lval;
5023 :
5024 208 : q = dump_cols(mb, l, q);
5025 : } else {
5026 456 : getArg(q, 0) = getArg(getInstrPtr(mb, 0), 0);
5027 456 : q = pushArgument(mb, q, val->nr);
5028 : }
5029 :
5030 664 : bool enabled = be->mvc->sa->eb.enabled;
5031 664 : be->mvc->sa->eb.enabled = false;
5032 664 : stmt *s = stmt_create(be->mvc->sa, st_return);
5033 664 : be->mvc->sa->eb.enabled = enabled;
5034 664 : if(!s) {
5035 0 : freeInstruction(q);
5036 0 : goto bailout;
5037 : }
5038 664 : s->op1 = val;
5039 664 : s->flag = nr_declared_tables;
5040 664 : s->nr = getDestVar(q);
5041 664 : s->q = q;
5042 664 : pushInstruction(mb, q);
5043 664 : return s;
5044 :
5045 0 : bailout:
5046 0 : if (be->mvc->sa->eb.enabled)
5047 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
5048 : return NULL;
5049 : }
5050 :
5051 : stmt *
5052 1423 : stmt_assign(backend *be, const char *sname, const char *varname, stmt *val, int level)
5053 : {
5054 1423 : MalBlkPtr mb = be->mb;
5055 1423 : InstrPtr q = NULL;
5056 :
5057 1423 : if (val && val->nr < 0)
5058 0 : goto bailout;
5059 1423 : if (level != 0) {
5060 1039 : char *buf, levelstr[16];
5061 :
5062 1039 : if (!val) {
5063 : /* drop declared table */
5064 0 : assert(0);
5065 : }
5066 :
5067 1039 : assert(!sname);
5068 1039 : snprintf(levelstr, sizeof(levelstr), "%d", level);
5069 1039 : buf = SA_NEW_ARRAY(be->mvc->sa, char, strlen(levelstr) + strlen(varname) + 3);
5070 1039 : if (!buf)
5071 0 : goto bailout;
5072 1039 : stpcpy(stpcpy(stpcpy(stpcpy(buf, "A"), levelstr), "%"), varname); /* mangle variable name */
5073 1039 : q = newInstruction(mb, NULL, NULL);
5074 1039 : if (q == NULL) {
5075 0 : goto bailout;
5076 : }
5077 1039 : q->argc = q->retc = 0;
5078 1039 : q = pushArgumentId(mb, q, buf);
5079 1039 : pushInstruction(mb, q);
5080 1039 : q->retc++;
5081 : } else {
5082 384 : assert(sname); /* all global variables have a schema */
5083 384 : q = newStmt(mb, sqlRef, setVariableRef);
5084 384 : if (q == NULL)
5085 0 : goto bailout;
5086 384 : q = pushArgument(mb, q, be->mvc_var);
5087 384 : q = pushStr(mb, q, sname);
5088 384 : q = pushStr(mb, q, varname);
5089 384 : getArg(q, 0) = be->mvc_var = newTmpVariable(mb, TYPE_int);
5090 384 : pushInstruction(mb, q);
5091 384 : be->mvc_var = getDestVar(q);
5092 : }
5093 1423 : q = pushArgument(mb, q, val->nr);
5094 :
5095 1423 : bool enabled = be->mvc->sa->eb.enabled;
5096 1423 : be->mvc->sa->eb.enabled = false;
5097 1423 : stmt *s = stmt_create(be->mvc->sa, st_assign);
5098 1422 : be->mvc->sa->eb.enabled = enabled;
5099 1422 : if(!s) {
5100 0 : goto bailout;
5101 : }
5102 1422 : s->op2 = val;
5103 1422 : s->flag = (level << 1);
5104 1422 : s->q = q;
5105 1422 : s->nr = 1;
5106 1422 : return s;
5107 :
5108 0 : bailout:
5109 0 : if (be->mvc->sa->eb.enabled)
5110 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
5111 : return NULL;
5112 : }
5113 :
5114 : stmt *
5115 26389 : const_column(backend *be, stmt *val)
5116 : {
5117 26389 : sql_subtype *ct = tail_type(val);
5118 26389 : MalBlkPtr mb = be->mb;
5119 26389 : InstrPtr q = NULL;
5120 26389 : int tt = ct->type->localtype;
5121 :
5122 26389 : if (val->nr < 0)
5123 0 : goto bailout;
5124 26389 : q = newStmt(mb, batRef, singleRef);
5125 26389 : if (q == NULL)
5126 0 : goto bailout;
5127 26389 : setVarType(mb, getArg(q, 0), newBatType(tt));
5128 26389 : q = pushArgument(mb, q, val->nr);
5129 :
5130 26389 : bool enabled = be->mvc->sa->eb.enabled;
5131 26389 : be->mvc->sa->eb.enabled = false;
5132 26389 : stmt *s = stmt_create(be->mvc->sa, st_single);
5133 26389 : be->mvc->sa->eb.enabled = enabled;
5134 26389 : if(!s) {
5135 0 : freeInstruction(q);
5136 0 : goto bailout;
5137 : }
5138 26389 : s->op1 = val;
5139 26389 : s->op4.typeval = *ct;
5140 26389 : s->nrcols = 1;
5141 :
5142 26389 : s->tname = val->tname;
5143 26389 : s->cname = val->cname;
5144 26389 : s->nr = getDestVar(q);
5145 26389 : s->q = q;
5146 26389 : pushInstruction(mb, q);
5147 26389 : return s;
5148 :
5149 0 : bailout:
5150 0 : if (be->mvc->sa->eb.enabled)
5151 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
5152 : return NULL;
5153 : }
5154 :
5155 : stmt *
5156 10 : stmt_fetch(backend *be, stmt *val)
5157 : {
5158 10 : sql_subtype *ct;
5159 10 : MalBlkPtr mb = be->mb;
5160 10 : InstrPtr q = NULL;
5161 10 : int tt;
5162 :
5163 10 : if (val->nr < 0)
5164 0 : goto bailout;
5165 : /* pick from first column on a table case */
5166 10 : if (val->type == st_table) {
5167 0 : if (list_length(val->op1->op4.lval) > 1)
5168 0 : goto bailout;
5169 0 : val = val->op1->op4.lval->h->data;
5170 : }
5171 10 : ct = tail_type(val);
5172 10 : tt = ct->type->localtype;
5173 :
5174 10 : q = newStmt(mb, algebraRef, fetchRef);
5175 10 : if (q == NULL)
5176 0 : goto bailout;
5177 10 : setVarType(mb, getArg(q, 0), tt);
5178 10 : q = pushArgument(mb, q, val->nr);
5179 10 : q = pushOid(mb, q, 0);
5180 :
5181 10 : bool enabled = be->mvc->sa->eb.enabled;
5182 10 : be->mvc->sa->eb.enabled = false;
5183 10 : stmt *s = stmt_create(be->mvc->sa, st_single);
5184 10 : be->mvc->sa->eb.enabled = enabled;
5185 10 : if(!s) {
5186 0 : freeInstruction(q);
5187 0 : goto bailout;
5188 : }
5189 10 : s->op1 = val;
5190 10 : s->op4.typeval = *ct;
5191 10 : s->nrcols = 0;
5192 :
5193 10 : s->tname = val->tname;
5194 10 : s->cname = val->cname;
5195 10 : s->nr = getDestVar(q);
5196 10 : s->q = q;
5197 10 : pushInstruction(mb, q);
5198 10 : return s;
5199 :
5200 0 : bailout:
5201 0 : if (be->mvc->sa->eb.enabled)
5202 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
5203 : return NULL;
5204 : }
5205 :
5206 : stmt *
5207 1644962 : stmt_rename(backend *be, sql_exp *exp, stmt *s )
5208 : {
5209 1644962 : int label = exp_get_label(exp);
5210 1644878 : const char *name = exp_name(exp);
5211 1645167 : const char *rname = exp_relname(exp);
5212 1644830 : stmt *o = s;
5213 :
5214 1644830 : if (!name && exp_is_atom(exp))
5215 0 : name = sa_strdup(be->mvc->sa, "single_value");
5216 0 : assert(name);
5217 1644830 : s = stmt_alias(be, s, label, rname, name);
5218 1644994 : if (o->flag & OUTER_ZERO)
5219 521 : s->flag |= OUTER_ZERO;
5220 1644994 : return s;
5221 : }
|