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