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