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 17920 : convertMultiplexMod(const char *mod, const char *op)
32 : {
33 17920 : if (strcmp(op, "=") == 0)
34 0 : return "calc";
35 : return mod;
36 : }
37 :
38 : static const char *
39 258452 : convertMultiplexFcn(const char *op)
40 : {
41 258452 : if (strcmp(op, "=") == 0)
42 34324 : return "==";
43 : return op;
44 : }
45 :
46 : static InstrPtr
47 17845 : multiplex2(MalBlkPtr mb, const char *mod, const char *name, int o1, int o2, int rtype)
48 : {
49 17845 : InstrPtr q = NULL;
50 :
51 17845 : q = newStmt(mb, malRef, multiplexRef);
52 17845 : if (q == NULL)
53 : return NULL;
54 17845 : setVarType(mb, getArg(q, 0), newBatType(rtype));
55 17845 : q = pushStr(mb, q, convertMultiplexMod(mod, name));
56 17845 : q = pushStr(mb, q, convertMultiplexFcn(name));
57 17845 : q = pushArgument(mb, q, o1);
58 17845 : q = pushArgument(mb, q, o2);
59 17845 : pushInstruction(mb, q);
60 17845 : return q;
61 : }
62 :
63 : static InstrPtr
64 50950 : dump_1(MalBlkPtr mb, const char *mod, const char *name, stmt *o1)
65 : {
66 50950 : InstrPtr q = NULL;
67 :
68 50950 : if (o1 == NULL || o1->nr < 0)
69 : return NULL;
70 50950 : q = newStmt(mb, mod, name);
71 50950 : q = pushArgument(mb, q, o1->nr);
72 50950 : pushInstruction(mb, q);
73 50950 : return q;
74 : }
75 :
76 : static InstrPtr
77 180046 : dump_2(MalBlkPtr mb, const char *mod, const char *name, stmt *o1, stmt *o2)
78 : {
79 180046 : InstrPtr q = NULL;
80 :
81 180046 : if (o1 == NULL || o2 == NULL || o1->nr < 0 || o2->nr < 0)
82 : return NULL;
83 180046 : q = newStmt(mb, mod, name);
84 180046 : q = pushArgument(mb, q, o1->nr);
85 180046 : q = pushArgument(mb, q, o2->nr);
86 180046 : pushInstruction(mb, q);
87 180046 : 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 2179212 : pushSchema(MalBlkPtr mb, InstrPtr q, sql_table *t)
109 : {
110 2179212 : if (t->s)
111 2179212 : 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 19488 : stmt_atom_string_nil(backend *be)
139 : {
140 19488 : sql_subtype t;
141 :
142 19488 : sql_find_subtype(&t, "varchar", 0, 0);
143 19488 : return stmt_atom(be, atom_string(be->mvc->sa, &t, NULL));
144 : }
145 :
146 : stmt *
147 5810 : stmt_atom_int(backend *be, int i)
148 : {
149 5810 : sql_subtype t;
150 :
151 5810 : sql_find_subtype(&t, "int", 32, 0);
152 5810 : return stmt_atom(be, atom_int(be->mvc->sa, &t, i));
153 : }
154 :
155 : stmt *
156 117359 : stmt_atom_lng(backend *be, lng i)
157 : {
158 117359 : sql_subtype t;
159 :
160 117359 : sql_find_subtype(&t, "bigint", 64, 0);
161 117359 : 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 40439 : stmt_bool(backend *be, int b)
175 : {
176 40439 : sql_subtype t;
177 :
178 40439 : sql_find_subtype(&t, "boolean", 0, 0);
179 :
180 40439 : if (b == bit_nil) {
181 0 : return stmt_atom(be, atom_bool(be->mvc->sa, &t, bit_nil));
182 40439 : } else if (b) {
183 39310 : return stmt_atom(be, atom_bool(be->mvc->sa, &t, TRUE));
184 : } else {
185 1129 : return stmt_atom(be, atom_bool(be->mvc->sa, &t, FALSE));
186 : }
187 : }
188 :
189 : static stmt *
190 17760825 : stmt_create(allocator *sa, st_type type)
191 : {
192 17760825 : stmt *s = SA_NEW(sa, stmt);
193 :
194 17760694 : if (!s)
195 : return NULL;
196 17760694 : *s = (stmt) {
197 : .type = type,
198 : };
199 17760694 : return s;
200 : }
201 :
202 : stmt *
203 27764 : stmt_group(backend *be, stmt *s, stmt *grp, stmt *ext, stmt *cnt, int done)
204 : {
205 27764 : MalBlkPtr mb = be->mb;
206 27764 : InstrPtr q = NULL;
207 :
208 27764 : if (s == NULL || s->nr < 0)
209 0 : goto bailout;
210 27764 : if (grp && (grp->nr < 0 || ext->nr < 0 || cnt->nr < 0))
211 0 : goto bailout;
212 :
213 27764 : q = newStmt(mb, groupRef, done ? grp ? subgroupdoneRef : groupdoneRef : grp ? subgroupRef : groupRef);
214 27764 : if (q == NULL)
215 0 : goto bailout;
216 :
217 : /* output variables extent and hist */
218 27764 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
219 27764 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
220 27764 : q = pushArgument(mb, q, s->nr);
221 27764 : if (grp)
222 6188 : q = pushArgument(mb, q, grp->nr);
223 :
224 27764 : bool enabled = be->mvc->sa->eb.enabled;
225 27764 : be->mvc->sa->eb.enabled = false;
226 27764 : stmt *ns = stmt_create(be->mvc->sa, st_group);
227 27764 : be->mvc->sa->eb.enabled = enabled;
228 27764 : if (ns == NULL) {
229 0 : freeInstruction(q);
230 0 : goto bailout;
231 : }
232 :
233 27764 : ns->op1 = s;
234 :
235 27764 : if (grp) {
236 6188 : ns->op2 = grp;
237 6188 : ns->op3 = ext;
238 6188 : ns->op4.stval = cnt;
239 : }
240 27764 : ns->nrcols = s->nrcols;
241 27764 : ns->key = 0;
242 27764 : ns->q = q;
243 27764 : ns->nr = getDestVar(q);
244 27764 : pushInstruction(mb, q);
245 27764 : 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 2774 : stmt_var(backend *be, const char *sname, const char *varname, sql_subtype *t, int declare, int level)
336 : {
337 2774 : MalBlkPtr mb = be->mb;
338 2774 : InstrPtr q = NULL;
339 2774 : char *buf;
340 :
341 2774 : 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 2343 : } else if (!declare) {
353 1954 : char levelstr[16];
354 :
355 1954 : assert(!sname);
356 1954 : snprintf(levelstr, sizeof(levelstr), "%d", level);
357 1954 : buf = SA_NEW_ARRAY(be->mvc->sa, char, strlen(levelstr) + strlen(varname) + 3);
358 1954 : if (!buf)
359 1 : goto bailout;
360 1954 : stpcpy(stpcpy(stpcpy(stpcpy(buf, "A"), levelstr), "%"), varname); /* mangle variable name */
361 1954 : q = newAssignment(mb);
362 1954 : if (q == NULL)
363 1 : goto bailout;
364 1953 : q = pushArgumentId(mb, q, buf);
365 : } else {
366 389 : int tt = t->type->localtype;
367 389 : char levelstr[16];
368 :
369 389 : assert(!sname);
370 389 : snprintf(levelstr, sizeof(levelstr), "%d", level);
371 389 : buf = SA_NEW_ARRAY(be->mvc->sa, char, strlen(levelstr) + strlen(varname) + 3);
372 389 : if (!buf)
373 0 : goto bailout;
374 389 : stpcpy(stpcpy(stpcpy(stpcpy(buf, "A"), levelstr), "%"), varname); /* mangle variable name */
375 :
376 389 : q = newInstruction(mb, NULL, NULL);
377 389 : if (q == NULL) {
378 0 : goto bailout;
379 : }
380 389 : q->argc = q->retc = 0;
381 389 : q = pushArgumentId(mb, q, buf);
382 389 : q = pushNil(mb, q, tt);
383 389 : q->retc++;
384 : }
385 2773 : bool enabled = be->mvc->sa->eb.enabled;
386 2773 : be->mvc->sa->eb.enabled = false;
387 2773 : stmt *s = stmt_create(be->mvc->sa, st_var);
388 2773 : be->mvc->sa->eb.enabled = enabled;
389 2773 : if (s == NULL) {
390 0 : freeInstruction(q);
391 0 : goto bailout;
392 : }
393 :
394 2773 : if (t)
395 2773 : s->op4.typeval = *t;
396 : else
397 0 : s->op4.typeval.type = NULL;
398 2773 : s->flag = declare + (level << 1);
399 2773 : s->key = 1;
400 2773 : s->q = q;
401 2773 : s->nr = getDestVar(q);
402 2773 : pushInstruction(mb, q);
403 2773 : 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 688 : stmt_table(backend *be, stmt *cols, int temp)
483 : {
484 688 : MalBlkPtr mb = be->mb;
485 :
486 688 : if (cols == NULL || cols->nr < 0)
487 0 : goto bailout;
488 :
489 688 : stmt *s = stmt_create(be->mvc->sa, st_table);
490 :
491 688 : if (s == NULL)
492 0 : goto bailout;
493 :
494 688 : 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 688 : s->op1 = cols;
506 688 : s->flag = temp;
507 688 : s->nr = cols->nr;
508 688 : s->nrcols = cols->nrcols;
509 688 : 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 223201 : stmt_temp(backend *be, sql_subtype *t)
519 : {
520 223201 : int tt = t->type->localtype;
521 223201 : MalBlkPtr mb = be->mb;
522 223201 : InstrPtr q = newStmt(mb, batRef, newRef);
523 :
524 223255 : if (q == NULL)
525 0 : goto bailout;
526 223255 : setVarType(mb, getArg(q, 0), newBatType(tt));
527 223255 : q = pushType(mb, q, tt);
528 223226 : bool enabled = be->mvc->sa->eb.enabled;
529 223226 : be->mvc->sa->eb.enabled = false;
530 223226 : stmt *s = stmt_create(be->mvc->sa, st_temp);
531 223220 : be->mvc->sa->eb.enabled = enabled;
532 :
533 223220 : if (s == NULL) {
534 0 : freeInstruction(q);
535 0 : goto bailout;
536 : }
537 223220 : s->op4.typeval = *t;
538 223220 : s->nrcols = 1;
539 223220 : s->q = q;
540 223220 : s->nr = getDestVar(q);
541 223220 : pushInstruction(mb, q);
542 223220 : 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 203225 : stmt_tid(backend *be, sql_table *t, int partition)
569 : {
570 203225 : int tt = TYPE_oid;
571 203225 : MalBlkPtr mb = be->mb;
572 203225 : InstrPtr q;
573 :
574 203225 : 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 203209 : q = newStmt(mb, sqlRef, tidRef);
589 203208 : if (q == NULL)
590 0 : goto bailout;
591 203208 : setVarType(mb, getArg(q, 0), newBatType(tt));
592 203208 : q = pushArgument(mb, q, be->mvc_var);
593 203209 : q = pushSchema(mb, q, t);
594 203209 : q = pushStr(mb, q, t->base.name);
595 203209 : if (t && isTable(t) && partition) {
596 75668 : sql_trans *tr = be->mvc->session->tr;
597 75668 : sqlstore *store = tr->store;
598 75668 : BUN rows = (BUN) store->storage_api.count_col(tr, ol_first_node(t->columns)->data, RDONLY);
599 75668 : setRowCnt(mb,getArg(q,0),rows);
600 : }
601 :
602 203209 : bool enabled = be->mvc->sa->eb.enabled;
603 203209 : be->mvc->sa->eb.enabled = false;
604 203209 : stmt *s = stmt_create(be->mvc->sa, st_tid);
605 203209 : be->mvc->sa->eb.enabled = enabled;
606 203209 : if (s == NULL) {
607 0 : freeInstruction(q);
608 0 : goto bailout;
609 : }
610 :
611 203209 : s->partition = partition;
612 203209 : s->op4.tval = t;
613 203209 : s->nrcols = 1;
614 203209 : s->nr = getDestVar(q);
615 203209 : s->q = q;
616 203209 : pushInstruction(mb, q);
617 203209 : 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 986509 : find_real_column(backend *be, sql_column *c)
627 : {
628 986509 : 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 986508 : stmt_bat(backend *be, sql_column *c, int access, int partition)
641 : {
642 986508 : int tt = c->type.type->localtype;
643 986508 : MalBlkPtr mb = be->mb;
644 986508 : InstrPtr q;
645 :
646 986508 : c = find_real_column(be, c);
647 :
648 986508 : if (access == RD_EXT)
649 176 : partition = 0;
650 :
651 : /* for read access tid.project(col) */
652 986508 : 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 986485 : q = newStmtArgs(mb, sqlRef, bindRef, 9);
670 986497 : if (q == NULL)
671 0 : goto bailout;
672 986497 : 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 986321 : if (access == RD_UPD_ID) {
683 479330 : q = pushReturn(mb, q, newTmpVariable(mb, newBatType(tt)));
684 : } else {
685 507167 : setVarType(mb, getArg(q, 0), newBatType(tt));
686 : }
687 986496 : q = pushArgument(mb, q, be->mvc_var);
688 986493 : q = pushSchema(mb, q, c->t);
689 986492 : q = pushArgument(mb, q, getStrConstant(mb,c->t->base.name));
690 986471 : q = pushArgument(mb, q, getStrConstant(mb,c->base.name));
691 986485 : q = pushArgument(mb, q, getIntConstant(mb,access));
692 :
693 986476 : if (access == RD_UPD_ID) {
694 479324 : setVarType(mb, getArg(q, 1), newBatType(tt));
695 : }
696 986476 : if (partition) {
697 544764 : sql_trans *tr = be->mvc->session->tr;
698 544764 : sqlstore *store = tr->store;
699 :
700 544764 : if (c && isTable(c->t)) {
701 544765 : BUN rows = (BUN) store->storage_api.count_col(tr, c, RDONLY);
702 544791 : setRowCnt(mb,getArg(q,0),rows);
703 : }
704 : }
705 :
706 986502 : bool enabled = be->mvc->sa->eb.enabled;
707 986502 : be->mvc->sa->eb.enabled = false;
708 986502 : stmt *s = stmt_create(be->mvc->sa, st_bat);
709 986499 : be->mvc->sa->eb.enabled = enabled;
710 986499 : if (s == NULL) {
711 0 : freeInstruction(q);
712 0 : goto bailout;
713 : }
714 :
715 986499 : s->partition = partition;
716 986499 : s->op4.cval = c;
717 986499 : s->nrcols = 1;
718 986499 : s->flag = access;
719 986499 : s->nr = getDestVar(q);
720 986499 : s->q = q;
721 986499 : s->tname = c->t->base.name;
722 986499 : s->cname = c->base.name;
723 986499 : pushInstruction(mb, q);
724 986499 : 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 663778 : stmt_append_col(backend *be, sql_column *c, stmt *offset, stmt *b, int *mvc_var_update, int fake)
795 : {
796 663778 : MalBlkPtr mb = be->mb;
797 663778 : InstrPtr q = NULL;
798 :
799 663778 : if (b == NULL || b->nr < 0)
800 0 : goto bailout;
801 :
802 663778 : 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 663755 : } else if (!fake) { /* fake append */
821 663755 : if (offset == NULL || offset->nr < 0)
822 0 : goto bailout;
823 663755 : q = newStmt(mb, sqlRef, appendRef);
824 663768 : if (q == NULL)
825 0 : goto bailout;
826 663768 : q = pushArgument(mb, q, be->mvc_var);
827 663769 : int tmpvar = newTmpVariable(mb, TYPE_int);
828 663770 : getArg(q, 0) = tmpvar;
829 663770 : if (mvc_var_update != NULL)
830 663770 : *mvc_var_update = tmpvar;
831 663770 : q = pushSchema(mb, q, c->t);
832 663768 : q = pushStr(mb, q, c->t->base.name);
833 663768 : q = pushStr(mb, q, c->base.name);
834 663743 : q = pushArgument(mb, q, offset->nr);
835 : /* also the offsets */
836 663742 : assert(offset->q->retc == 2);
837 663742 : q = pushArgument(mb, q, getArg(offset->q, 1));
838 663745 : q = pushArgument(mb, q, b->nr);
839 663739 : if (mvc_var_update != NULL)
840 663739 : *mvc_var_update = getDestVar(q);
841 : } else {
842 : return b;
843 : }
844 663762 : bool enabled = be->mvc->sa->eb.enabled;
845 663762 : be->mvc->sa->eb.enabled = false;
846 663762 : stmt *s = stmt_create(be->mvc->sa, st_append_col);
847 663766 : be->mvc->sa->eb.enabled = enabled;
848 :
849 663766 : if (s == NULL) {
850 0 : freeInstruction(q);
851 0 : goto bailout;
852 : }
853 663766 : s->op1 = b;
854 663766 : s->op2 = offset;
855 663766 : s->op4.cval = c;
856 663766 : s->q = q;
857 663766 : s->nr = getDestVar(q);
858 663766 : pushInstruction(mb, q);
859 663766 : 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 3059 : stmt_update_col(backend *be, sql_column *c, stmt *tids, stmt *upd)
916 : {
917 3059 : MalBlkPtr mb = be->mb;
918 3059 : InstrPtr q = NULL;
919 :
920 3059 : if (tids == NULL || upd == NULL || tids->nr < 0 || upd->nr < 0)
921 0 : goto bailout;
922 :
923 3060 : 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 3058 : q = newStmt(mb, sqlRef, updateRef);
934 3058 : if (q == NULL)
935 0 : goto bailout;
936 3058 : q = pushArgument(mb, q, be->mvc_var);
937 3058 : getArg(q, 0) = be->mvc_var = newTmpVariable(mb, TYPE_int);
938 3058 : q = pushSchema(mb, q, c->t);
939 3058 : q = pushStr(mb, q, c->t->base.name);
940 3058 : q = pushStr(mb, q, c->base.name);
941 3058 : q = pushArgument(mb, q, tids->nr);
942 3058 : q = pushArgument(mb, q, upd->nr);
943 3058 : be->mvc_var = getDestVar(q);
944 : }
945 3059 : bool enabled = be->mvc->sa->eb.enabled;
946 3059 : be->mvc->sa->eb.enabled = false;
947 3059 : stmt *s = stmt_create(be->mvc->sa, st_update_col);
948 3059 : be->mvc->sa->eb.enabled = enabled;
949 :
950 3059 : if (s == NULL) {
951 0 : freeInstruction(q);
952 0 : goto bailout;
953 : }
954 3059 : s->op1 = tids;
955 3059 : s->op2 = upd;
956 3059 : s->op4.cval = c;
957 3059 : s->q = q;
958 3059 : s->nr = getDestVar(q);
959 3059 : pushInstruction(mb, q);
960 3059 : 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 367 : stmt_delete(backend *be, sql_table *t, stmt *tids)
1014 : {
1015 367 : MalBlkPtr mb = be->mb;
1016 367 : InstrPtr q = NULL;
1017 :
1018 367 : if (tids == NULL || tids->nr < 0)
1019 0 : goto bailout;
1020 :
1021 368 : 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 366 : q = newStmt(mb, sqlRef, deleteRef);
1031 366 : if (q == NULL)
1032 0 : goto bailout;
1033 366 : q = pushArgument(mb, q, be->mvc_var);
1034 366 : getArg(q, 0) = be->mvc_var = newTmpVariable(mb, TYPE_int);
1035 366 : q = pushSchema(mb, q, t);
1036 366 : q = pushStr(mb, q, t->base.name);
1037 366 : q = pushArgument(mb, q, tids->nr);
1038 366 : be->mvc_var = getDestVar(q);
1039 : }
1040 367 : bool enabled = be->mvc->sa->eb.enabled;
1041 367 : be->mvc->sa->eb.enabled = false;
1042 367 : stmt *s = stmt_create(be->mvc->sa, st_delete);
1043 367 : be->mvc->sa->eb.enabled = enabled;
1044 367 : if (s == NULL) {
1045 0 : freeInstruction(q);
1046 0 : goto bailout;
1047 : }
1048 :
1049 367 : s->op1 = tids;
1050 367 : s->op4.tval = t;
1051 367 : s->q = q;
1052 367 : s->nr = getDestVar(q);
1053 367 : pushInstruction(mb, q);
1054 367 : 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 123660 : stmt_const(backend *be, stmt *s, stmt *val)
1064 : {
1065 123660 : InstrPtr q = NULL;
1066 123660 : MalBlkPtr mb = be->mb;
1067 :
1068 123660 : if (s == NULL)
1069 0 : goto bailout;
1070 123660 : if (val)
1071 123660 : q = dump_2(mb, algebraRef, projectRef, s, val);
1072 : else
1073 0 : q = dump_1(mb, algebraRef, projectRef, s);
1074 123660 : if (q) {
1075 123660 : stmt *ns = stmt_create(be->mvc->sa, st_const);
1076 123660 : if (ns == NULL) {
1077 0 : goto bailout;
1078 : }
1079 :
1080 123660 : ns->op1 = s;
1081 123660 : ns->op2 = val;
1082 123660 : ns->nrcols = s->nrcols;
1083 123660 : ns->key = s->key;
1084 123660 : ns->aggr = s->aggr;
1085 123660 : ns->q = q;
1086 123660 : ns->nr = getDestVar(q);
1087 123660 : ns->tname = val->tname;
1088 123660 : ns->cname = val->cname;
1089 123660 : 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 2397 : stmt_gen_group(backend *be, stmt *gids, stmt *cnts)
1099 : {
1100 2397 : MalBlkPtr mb = be->mb;
1101 :
1102 2397 : if (gids == NULL || cnts == NULL)
1103 0 : goto bailout;
1104 :
1105 2397 : InstrPtr q = dump_2(mb, algebraRef, groupbyRef, gids, cnts);
1106 :
1107 2397 : if (q) {
1108 2397 : stmt *ns = stmt_create(be->mvc->sa, st_gen_group);
1109 2397 : if (ns == NULL) {
1110 0 : goto bailout;
1111 : }
1112 :
1113 2397 : ns->op1 = gids;
1114 2397 : ns->op2 = cnts;
1115 :
1116 2397 : ns->nrcols = gids->nrcols;
1117 2397 : ns->key = 0;
1118 2397 : ns->aggr = 0;
1119 2397 : ns->q = q;
1120 2397 : ns->nr = getDestVar(q);
1121 2397 : 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 50950 : stmt_mirror(backend *be, stmt *s)
1131 : {
1132 50950 : MalBlkPtr mb = be->mb;
1133 :
1134 50950 : if (s == NULL)
1135 0 : goto bailout;
1136 :
1137 50950 : InstrPtr q = dump_1(mb, batRef, mirrorRef, s);
1138 :
1139 50950 : if (q) {
1140 50950 : stmt *ns = stmt_create(be->mvc->sa, st_mirror);
1141 50950 : if (ns == NULL) {
1142 0 : goto bailout;
1143 : }
1144 :
1145 50950 : ns->op1 = s;
1146 50950 : ns->nrcols = 2;
1147 50950 : ns->key = s->key;
1148 50950 : ns->aggr = s->aggr;
1149 50950 : ns->q = q;
1150 50950 : ns->nr = getDestVar(q);
1151 50950 : 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 319592 : stmt_result(backend *be, stmt *s, int nr)
1162 : {
1163 319592 : stmt *ns;
1164 :
1165 319592 : if (s == NULL)
1166 : return NULL;
1167 :
1168 319592 : if (s->type == st_join && s->flag == cmp_joined) {
1169 5519 : if (nr)
1170 2334 : return s->op2;
1171 3185 : return s->op1;
1172 : }
1173 :
1174 314073 : if (s->op1->nr < 0)
1175 : return NULL;
1176 :
1177 314073 : ns = stmt_create(be->mvc->sa, st_result);
1178 314073 : if(!ns) {
1179 : return NULL;
1180 : }
1181 314073 : if (s->op1->type == st_join && s->op1->flag == cmp_joined) {
1182 0 : assert(0);
1183 314073 : } else if (nr) {
1184 179584 : int v = getArg(s->q, nr);
1185 :
1186 179584 : assert(s->q->retc > nr);
1187 179584 : ns->nr = v;
1188 : } else {
1189 134489 : ns->nr = s->nr;
1190 : }
1191 314073 : ns->op1 = s;
1192 314073 : if (!nr && (s->type == st_order || s->type == st_reorder))
1193 23695 : ns->op4.typeval = *tail_type(s->op1);
1194 179584 : else if (nr && ((s->type == st_join && s->flag == MARKJOIN) || (s->type == st_uselect2 && s->flag == MARKJOIN)))
1195 2937 : ns->op4.typeval = *sql_bind_localtype("bit");
1196 : else
1197 287441 : ns->op4.typeval = *sql_bind_localtype("oid");
1198 314073 : ns->flag = nr;
1199 314073 : ns->nrcols = s->nrcols;
1200 314073 : ns->key = s->key;
1201 314073 : ns->aggr = s->aggr;
1202 314073 : return ns;
1203 : }
1204 :
1205 :
1206 : /* limit maybe atom nil */
1207 : stmt *
1208 17494 : 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 17494 : MalBlkPtr mb = be->mb;
1211 17494 : InstrPtr q = NULL;
1212 17494 : int l, p, g, c;
1213 :
1214 17494 : if (col == NULL || offset == NULL || limit == NULL || col->nr < 0 || offset->nr < 0 || limit->nr < 0)
1215 0 : goto bailout;
1216 17494 : if (piv && (piv->nr < 0 || gid->nr < 0))
1217 0 : goto bailout;
1218 :
1219 17494 : c = (col) ? col->nr : 0;
1220 17494 : p = (piv) ? piv->nr : 0;
1221 17494 : g = (gid) ? gid->nr : 0;
1222 :
1223 : /* first insert single value into a bat */
1224 17494 : 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 17494 : if (order) {
1244 584 : int topn = 0;
1245 :
1246 584 : q = newStmt(mb, calcRef, plusRef);
1247 584 : if (q == NULL)
1248 0 : goto bailout;
1249 584 : q = pushArgument(mb, q, offset->nr);
1250 584 : q = pushArgument(mb, q, limit->nr);
1251 584 : topn = getDestVar(q);
1252 584 : pushInstruction(mb, q);
1253 :
1254 584 : q = newStmtArgs(mb, algebraRef, firstnRef, 9);
1255 584 : if (q == NULL)
1256 0 : goto bailout;
1257 584 : if (!last) /* we need the groups for the next firstn */
1258 310 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
1259 584 : q = pushArgument(mb, q, c);
1260 584 : if (p)
1261 310 : q = pushArgument(mb, q, p);
1262 : else
1263 274 : q = pushNilBat(mb, q);
1264 584 : if (g)
1265 310 : q = pushArgument(mb, q, g);
1266 : else
1267 274 : q = pushNilBat(mb, q);
1268 584 : q = pushArgument(mb, q, topn);
1269 584 : q = pushBit(mb, q, dir);
1270 584 : q = pushBit(mb, q, nullslast);
1271 584 : q = pushBit(mb, q, distinct != 0);
1272 :
1273 584 : l = getArg(q, 0);
1274 584 : l = getDestVar(q);
1275 584 : pushInstruction(mb, q);
1276 : } else {
1277 16910 : int len;
1278 :
1279 16910 : q = newStmt(mb, calcRef, plusRef);
1280 16911 : if (q == NULL)
1281 0 : goto bailout;
1282 16911 : q = pushArgument(mb, q, offset->nr);
1283 16911 : q = pushArgument(mb, q, limit->nr);
1284 16911 : len = getDestVar(q);
1285 16911 : pushInstruction(mb, q);
1286 :
1287 : /* since both arguments of algebra.subslice are
1288 : inclusive correct the LIMIT value by
1289 : subtracting 1 */
1290 16911 : q = newStmt(mb, calcRef, minusRef);
1291 16911 : if (q == NULL)
1292 0 : goto bailout;
1293 16911 : q = pushArgument(mb, q, len);
1294 16911 : q = pushInt(mb, q, 1);
1295 16910 : len = getDestVar(q);
1296 16910 : pushInstruction(mb, q);
1297 :
1298 16910 : q = newStmt(mb, algebraRef, subsliceRef);
1299 16911 : if (q == NULL)
1300 0 : goto bailout;
1301 16911 : q = pushArgument(mb, q, c);
1302 16911 : q = pushArgument(mb, q, offset->nr);
1303 16911 : q = pushArgument(mb, q, len);
1304 16911 : l = getDestVar(q);
1305 16911 : pushInstruction(mb, q);
1306 : }
1307 : /* retrieve the single values again */
1308 17495 : 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 34680 : stmt *ns = stmt_create(be->mvc->sa, piv?st_limit2:st_limit);
1319 17495 : if (ns == NULL) {
1320 0 : goto bailout;
1321 : }
1322 :
1323 17495 : ns->op1 = col;
1324 17495 : ns->op2 = offset;
1325 17495 : ns->op3 = limit;
1326 17495 : ns->nrcols = col->nrcols;
1327 17495 : ns->key = col->key;
1328 17495 : ns->aggr = col->aggr;
1329 17495 : ns->q = q;
1330 17495 : ns->nr = l;
1331 17495 : return ns;
1332 :
1333 0 : bailout:
1334 0 : if (be->mvc->sa->eb.enabled)
1335 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
1336 : return NULL;
1337 : }
1338 :
1339 : stmt *
1340 21 : stmt_sample(backend *be, stmt *s, stmt *sample, stmt *seed)
1341 : {
1342 21 : MalBlkPtr mb = be->mb;
1343 21 : InstrPtr q = NULL;
1344 :
1345 21 : if (s == NULL || sample == NULL || s->nr < 0 || sample->nr < 0)
1346 0 : goto bailout;
1347 21 : q = newStmt(mb, sampleRef, subuniformRef);
1348 21 : if (q == NULL)
1349 0 : goto bailout;
1350 21 : q = pushArgument(mb, q, s->nr);
1351 21 : q = pushArgument(mb, q, sample->nr);
1352 :
1353 21 : if (seed) {
1354 12 : if (seed->nr < 0)
1355 0 : goto bailout;
1356 :
1357 12 : q = pushArgument(mb, q, seed->nr);
1358 : }
1359 :
1360 21 : bool enabled = be->mvc->sa->eb.enabled;
1361 21 : be->mvc->sa->eb.enabled = false;
1362 21 : stmt *ns = stmt_create(be->mvc->sa, st_sample);
1363 21 : be->mvc->sa->eb.enabled = enabled;
1364 21 : if (ns == NULL) {
1365 0 : freeInstruction(q);
1366 0 : goto bailout;
1367 : }
1368 :
1369 21 : ns->op1 = s;
1370 21 : ns->op2 = sample;
1371 :
1372 21 : if (seed) {
1373 12 : ns->op3 = seed;
1374 : }
1375 :
1376 21 : ns->nrcols = s->nrcols;
1377 21 : ns->key = s->key;
1378 21 : ns->aggr = s->aggr;
1379 21 : ns->flag = 0;
1380 21 : ns->q = q;
1381 21 : ns->nr = getDestVar(q);
1382 21 : pushInstruction(mb, q);
1383 21 : return ns;
1384 :
1385 0 : bailout:
1386 0 : if (be->mvc->sa->eb.enabled)
1387 0 : eb_error(&be->mvc->sa->eb, be->mvc->errstr[0] ? be->mvc->errstr : mb->errors ? mb->errors : *GDKerrbuf ? GDKerrbuf : "out of memory", 1000);
1388 : return NULL;
1389 : }
1390 :
1391 :
1392 : stmt *
1393 10511 : stmt_order(backend *be, stmt *s, int direction, int nullslast)
1394 : {
1395 10511 : MalBlkPtr mb = be->mb;
1396 10511 : InstrPtr q = NULL;
1397 :
1398 10511 : if (s == NULL || s->nr < 0)
1399 0 : goto bailout;
1400 10511 : q = newStmt(mb, algebraRef, sortRef);
1401 10511 : if (q == NULL)
1402 0 : goto bailout;
1403 : /* both ordered result and oid's order en subgroups */
1404 10511 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
1405 10511 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
1406 10511 : q = pushArgument(mb, q, s->nr);
1407 10511 : q = pushBit(mb, q, !direction);
1408 10511 : q = pushBit(mb, q, nullslast);
1409 10511 : q = pushBit(mb, q, FALSE);
1410 :
1411 10511 : bool enabled = be->mvc->sa->eb.enabled;
1412 10511 : be->mvc->sa->eb.enabled = false;
1413 10511 : stmt *ns = stmt_create(be->mvc->sa, st_order);
1414 10511 : be->mvc->sa->eb.enabled = enabled;
1415 10511 : if (ns == NULL) {
1416 0 : freeInstruction(q);
1417 0 : goto bailout;
1418 : }
1419 :
1420 10511 : ns->op1 = s;
1421 10511 : ns->flag = direction;
1422 10511 : ns->nrcols = s->nrcols;
1423 10511 : ns->key = s->key;
1424 10511 : ns->aggr = s->aggr;
1425 10511 : ns->q = q;
1426 10511 : ns->nr = getDestVar(q);
1427 10511 : pushInstruction(mb, q);
1428 10511 : 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 13699 : stmt_reorder(backend *be, stmt *s, int direction, int nullslast, stmt *orderby_ids, stmt *orderby_grp)
1438 : {
1439 13699 : MalBlkPtr mb = be->mb;
1440 13699 : InstrPtr q = NULL;
1441 :
1442 13699 : 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 13699 : q = newStmtArgs(mb, algebraRef, sortRef, 9);
1445 13699 : if (q == NULL)
1446 0 : goto bailout;
1447 : /* both ordered result and oid's order en subgroups */
1448 13699 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
1449 13699 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
1450 13699 : q = pushArgument(mb, q, s->nr);
1451 13699 : q = pushArgument(mb, q, orderby_ids->nr);
1452 13699 : q = pushArgument(mb, q, orderby_grp->nr);
1453 13699 : q = pushBit(mb, q, !direction);
1454 13699 : q = pushBit(mb, q, nullslast);
1455 13699 : q = pushBit(mb, q, FALSE);
1456 :
1457 13699 : bool enabled = be->mvc->sa->eb.enabled;
1458 13699 : be->mvc->sa->eb.enabled = false;
1459 13699 : stmt *ns = stmt_create(be->mvc->sa, st_reorder);
1460 13699 : be->mvc->sa->eb.enabled = enabled;
1461 13699 : if (ns == NULL) {
1462 0 : freeInstruction(q);
1463 0 : goto bailout;
1464 : }
1465 :
1466 13699 : ns->op1 = s;
1467 13699 : ns->op2 = orderby_ids;
1468 13699 : ns->op3 = orderby_grp;
1469 13699 : ns->flag = direction;
1470 13699 : ns->nrcols = s->nrcols;
1471 13699 : ns->key = s->key;
1472 13699 : ns->aggr = s->aggr;
1473 13699 : ns->nr = getDestVar(q);
1474 13699 : ns->q = q;
1475 13699 : pushInstruction(mb, q);
1476 13699 : 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 3407025 : stmt_atom(backend *be, atom *a)
1486 : {
1487 3407025 : MalBlkPtr mb = be->mb;
1488 :
1489 3407025 : if (a == NULL)
1490 0 : goto bailout;
1491 :
1492 3407025 : InstrPtr q = EC_TEMP_FRAC(atom_type(a)->type->eclass) ? newStmt(mb, calcRef, atom_type(a)->type->impl) : newAssignment(mb);
1493 :
1494 3407091 : if (q == NULL)
1495 0 : goto bailout;
1496 3407091 : if (atom_null(a)) {
1497 151609 : q = pushNil(mb, q, atom_type(a)->type->localtype);
1498 : } else {
1499 3255482 : int k;
1500 3255482 : if ((k = constantAtom(be, mb, a)) == -1) {
1501 0 : freeInstruction(q);
1502 0 : goto bailout;
1503 : }
1504 3255252 : q = pushArgument(mb, q, k);
1505 : }
1506 : /* digits of the result timestamp/daytime */
1507 3406875 : if (EC_TEMP_FRAC(atom_type(a)->type->eclass))
1508 47457 : q = pushInt(mb, q, atom_type(a)->digits);
1509 3406835 : bool enabled = be->mvc->sa->eb.enabled;
1510 3406835 : be->mvc->sa->eb.enabled = false;
1511 3406835 : stmt *s = stmt_create(be->mvc->sa, st_atom);
1512 3406838 : be->mvc->sa->eb.enabled = enabled;
1513 3406838 : if (s == NULL) {
1514 0 : freeInstruction(q);
1515 0 : goto bailout;
1516 : }
1517 :
1518 3406838 : s->op4.aval = a;
1519 3406838 : s->key = 1; /* values are also unique */
1520 3406838 : s->q = q;
1521 3406838 : s->nr = getDestVar(q);
1522 3406838 : pushInstruction(mb, q);
1523 3406838 : 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 3256 : stmt_genselect(backend *be, stmt *lops, stmt *rops, sql_subfunc *f, stmt *sub, int anti)
1533 : {
1534 3256 : MalBlkPtr mb = be->mb;
1535 3256 : InstrPtr q = NULL;
1536 3256 : const char *mod, *op;
1537 3256 : node *n;
1538 3256 : int k;
1539 :
1540 3256 : if (lops == NULL || rops == NULL)
1541 0 : goto bailout;
1542 :
1543 3256 : if (backend_create_subfunc(be, f, NULL) < 0)
1544 0 : goto bailout;
1545 3256 : op = backend_function_imp(be, f->func);
1546 3256 : mod = sql_func_mod(f->func);
1547 :
1548 3256 : 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 3202 : node *n;
1588 :
1589 3202 : op = sa_strconcat(be->mvc->sa, op, selectRef);
1590 3202 : q = newStmtArgs(mb, mod, convertMultiplexFcn(op), 9);
1591 3202 : 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 3202 : 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 3202 : if (f->func->lang == FUNC_LANG_R || f->func->lang >= FUNC_LANG_PY)
1599 0 : q = pushStr(mb, q, f->func->query);
1600 :
1601 6404 : for (n = lops->op4.lval->h; n; n = n->next) {
1602 3202 : stmt *op = n->data;
1603 :
1604 3202 : q = pushArgument(mb, q, op->nr);
1605 : }
1606 : /* candidate lists */
1607 3202 : if (sub)
1608 3133 : q = pushArgument(mb, q, sub->nr);
1609 : else
1610 69 : q = pushNilBat(mb, q);
1611 :
1612 12791 : for (n = rops->op4.lval->h; n; n = n->next) {
1613 9589 : stmt *op = n->data;
1614 :
1615 9589 : q = pushArgument(mb, q, op->nr);
1616 : }
1617 :
1618 3202 : q = pushBit(mb, q, anti);
1619 : }
1620 :
1621 3256 : bool enabled = be->mvc->sa->eb.enabled;
1622 3256 : be->mvc->sa->eb.enabled = false;
1623 3256 : stmt *s = stmt_create(be->mvc->sa, st_uselect);
1624 3256 : be->mvc->sa->eb.enabled = enabled;
1625 3256 : if (s == NULL) {
1626 0 : freeInstruction(q);
1627 0 : goto bailout;
1628 : }
1629 :
1630 3256 : s->op1 = lops;
1631 3256 : s->op2 = rops;
1632 3256 : s->op3 = sub;
1633 3256 : s->key = lops->nrcols == 0 && rops->nrcols == 0;
1634 3256 : s->flag = cmp_filter;
1635 3256 : s->nrcols = lops->nrcols;
1636 3256 : s->nr = getDestVar(q);
1637 3256 : s->q = q;
1638 3256 : s->cand = sub;
1639 3256 : pushInstruction(mb, q);
1640 3256 : 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 214013 : stmt_uselect(backend *be, stmt *op1, stmt *op2, comp_type cmptype, stmt *sub, int anti, int is_semantics)
1650 : {
1651 214013 : MalBlkPtr mb = be->mb;
1652 214013 : InstrPtr q = NULL;
1653 214013 : int l, r;
1654 214013 : stmt *sel = sub;
1655 :
1656 214013 : if (op1 == NULL || op2 == NULL || op1->nr < 0 || op2->nr < 0 || (sub && sub->nr < 0))
1657 0 : goto bailout;
1658 214013 : l = op1->nr;
1659 214013 : r = op2->nr;
1660 :
1661 214013 : if (op2->nrcols >= 1 && op1->nrcols == 0) { /* swap */
1662 79 : stmt *v = op1;
1663 79 : op1 = op2;
1664 79 : op2 = v;
1665 79 : int n = l;
1666 79 : l = r;
1667 79 : r = n;
1668 79 : cmptype = swap_compare(cmptype);
1669 : }
1670 214013 : if (op2->nrcols >= 1) {
1671 17845 : bit need_not = FALSE;
1672 17845 : const char *mod = calcRef;
1673 17845 : const char *op = "=";
1674 17845 : int k;
1675 :
1676 17845 : switch (cmptype) {
1677 : case cmp_equal:
1678 : op = "=";
1679 : break;
1680 : case cmp_notequal:
1681 17845 : op = "!=";
1682 : break;
1683 917 : case cmp_lt:
1684 917 : op = "<";
1685 917 : break;
1686 775 : case cmp_lte:
1687 775 : op = "<=";
1688 775 : break;
1689 4831 : case cmp_gt:
1690 4831 : op = ">";
1691 4831 : 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 28101 : if ((q = multiplex2(mb, mod, convertMultiplexFcn(op), l, r, TYPE_bit)) == NULL)
1700 0 : goto bailout;
1701 17845 : if (sub && (op1->cand || op2->cand)) {
1702 1694 : 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 1664 : } else if (!op1->cand && op2->cand) {
1707 1629 : q = pushArgument(mb, q, sub->nr);
1708 1629 : if (op2->nrcols > 0)
1709 1629 : q = pushNilBat(mb, q);
1710 : }
1711 : sub = NULL;
1712 : }
1713 17845 : if (is_semantics)
1714 2972 : q = pushBit(mb, q, TRUE);
1715 17845 : k = getDestVar(q);
1716 :
1717 17845 : q = newStmtArgs(mb, algebraRef, selectRef, 9);
1718 17845 : if (q == NULL)
1719 0 : goto bailout;
1720 17845 : q = pushArgument(mb, q, k);
1721 17845 : if (sub)
1722 4363 : q = pushArgument(mb, q, sub->nr);
1723 17845 : q = pushBit(mb, q, !need_not);
1724 17845 : q = pushBit(mb, q, !need_not);
1725 17845 : q = pushBit(mb, q, TRUE);
1726 17845 : q = pushBit(mb, q, TRUE);
1727 17845 : q = pushBit(mb, q, anti);
1728 17845 : k = getDestVar(q);
1729 : } else {
1730 196168 : assert (cmptype != cmp_filter);
1731 196168 : q = newStmt(mb, algebraRef, thetaselectRef);
1732 196168 : if (q == NULL)
1733 0 : goto bailout;
1734 196168 : q = pushArgument(mb, q, l);
1735 196168 : if (sub && !op1->cand) {
1736 127483 : q = pushArgument(mb, q, sub->nr);
1737 : } else {
1738 630 : assert(!sub || op1->cand == sub);
1739 68685 : q = pushNilBat(mb, q);
1740 68685 : sub = NULL;
1741 : }
1742 196168 : q = pushArgument(mb, q, r);
1743 196168 : switch (cmptype) {
1744 160487 : case cmp_equal:
1745 160487 : if (is_semantics)
1746 34838 : q = pushStr(mb, q, anti?"ne":"eq");
1747 : else
1748 281095 : q = pushStr(mb, q, anti?"!=":"==");
1749 : break;
1750 32664 : case cmp_notequal:
1751 32664 : if (is_semantics)
1752 150 : q = pushStr(mb, q, anti?"eq":"ne");
1753 : else
1754 65178 : q = pushStr(mb, q, anti?"==":"!=");
1755 : break;
1756 376 : case cmp_lt:
1757 376 : q = pushStr(mb, q, anti?">=":"<");
1758 376 : break;
1759 73 : case cmp_lte:
1760 73 : q = pushStr(mb, q, anti?">":"<=");
1761 73 : break;
1762 2289 : case cmp_gt:
1763 2289 : q = pushStr(mb, q, anti?"<=":">");
1764 2289 : break;
1765 279 : case cmp_gte:
1766 279 : q = pushStr(mb, q, anti?"<":">=");
1767 279 : 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 214013 : bool enabled = be->mvc->sa->eb.enabled;
1778 214013 : be->mvc->sa->eb.enabled = false;
1779 214013 : stmt *s = stmt_create(be->mvc->sa, st_uselect);
1780 214013 : be->mvc->sa->eb.enabled = enabled;
1781 214013 : if (s == NULL) {
1782 0 : freeInstruction(q);
1783 0 : goto bailout;
1784 : }
1785 :
1786 214013 : s->op1 = op1;
1787 214013 : s->op2 = op2;
1788 214013 : s->op3 = sub;
1789 214013 : s->flag = cmptype;
1790 214013 : s->key = op1->nrcols == 0 && op2->nrcols == 0;
1791 214013 : s->nrcols = op1->nrcols;
1792 214013 : s->nr = getDestVar(q);
1793 214013 : s->q = q;
1794 214013 : s->cand = sub;
1795 214013 : pushInstruction(mb, q);
1796 214013 : if (!sub && sel) /* project back the old ids */
1797 2324 : 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 5107 : 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 5107 : MalBlkPtr mb = be->mb;
1858 5107 : InstrPtr p, q;
1859 5107 : int l;
1860 5107 : const char *cmd = (type == st_uselect2) ? selectRef : rangejoinRef;
1861 5107 : stmt *sub = (Sub)?*Sub:NULL;
1862 :
1863 5107 : if (op1 == NULL || op2 == NULL || op3 == NULL || op1->nr < 0 || (sub && sub->nr < 0))
1864 0 : goto bailout;
1865 5107 : l = op1->nr;
1866 8479 : if ((symmetric || op2->nrcols > 0 || op3->nrcols > 0 || !reduce) && (type == st_uselect2)) {
1867 3601 : int k;
1868 3601 : int nrcols = (op1->nrcols || op2->nrcols || op3->nrcols);
1869 :
1870 3601 : if (op2->nr < 0 || op3->nr < 0)
1871 0 : goto bailout;
1872 :
1873 3601 : if (nrcols)
1874 3560 : p = newStmtArgs(mb, batcalcRef, betweenRef, 12);
1875 : else
1876 41 : p = newStmtArgs(mb, calcRef, betweenRef, 9);
1877 3601 : if (p == NULL)
1878 0 : goto bailout;
1879 3601 : p = pushArgument(mb, p, l);
1880 3601 : p = pushArgument(mb, p, op2->nr);
1881 3601 : p = pushArgument(mb, p, op3->nr);
1882 :
1883 : /* cands */
1884 3601 : 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 3601 : p = pushBit(mb, p, (symmetric)?TRUE:FALSE); /* symmetric */
1905 3601 : p = pushBit(mb, p, (cmp & 1) != 0); /* lo inclusive */
1906 3601 : p = pushBit(mb, p, (cmp & 2) != 0); /* hi inclusive */
1907 3601 : p = pushBit(mb, p, FALSE); /* nils_false */
1908 3601 : p = pushBit(mb, p, (anti)?TRUE:FALSE); /* anti */
1909 3601 : pushInstruction(mb, p);
1910 3601 : 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 38 : stmt_outerselect(backend *be, stmt *g, stmt *m, stmt *p, bool any)
2034 : {
2035 38 : MalBlkPtr mb = be->mb;
2036 38 : InstrPtr q;
2037 :
2038 38 : q = newStmtArgs(mb, algebraRef, outerselectRef, 6);
2039 38 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
2040 38 : q = pushArgument(mb, q, g->nr); /* group ids */
2041 38 : q = pushArgument(mb, q, m->nr); /* mark flag */
2042 38 : q = pushArgument(mb, q, p->nr); /* predicate */
2043 38 : q = pushBit(mb, q, (any)?TRUE:FALSE);
2044 38 : pushInstruction(mb, q);
2045 :
2046 38 : if (!q)
2047 : return NULL;
2048 38 : stmt *s = stmt_create(be->mvc->sa, st_uselect2);
2049 38 : if (s == NULL) {
2050 0 : freeInstruction(q);
2051 0 : return NULL;
2052 : }
2053 :
2054 38 : s->op1 = g;
2055 38 : s->op2 = m;
2056 38 : s->flag = MARKJOIN;
2057 38 : s->key = 0;
2058 38 : s->nrcols = g->nrcols;
2059 38 : s->nr = getDestVar(q);
2060 38 : s->q = q;
2061 38 : return s;
2062 : }
2063 :
2064 : stmt *
2065 402 : stmt_markselect(backend *be, stmt *g, stmt *m, stmt *p, bool any)
2066 : {
2067 402 : MalBlkPtr mb = be->mb;
2068 402 : InstrPtr q;
2069 :
2070 402 : q = newStmtArgs(mb, algebraRef, markselectRef, 6);
2071 402 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
2072 402 : q = pushArgument(mb, q, g->nr); /* left ids */
2073 402 : q = pushArgument(mb, q, m->nr); /* mark info mask */
2074 402 : q = pushArgument(mb, q, p->nr); /* predicate */
2075 402 : q = pushBit(mb, q, (any)?TRUE:FALSE);
2076 402 : pushInstruction(mb, q);
2077 :
2078 402 : if (!q)
2079 : return NULL;
2080 402 : stmt *s = stmt_create(be->mvc->sa, st_uselect2);
2081 402 : if (s == NULL) {
2082 0 : freeInstruction(q);
2083 0 : return NULL;
2084 : }
2085 :
2086 402 : s->op1 = g;
2087 402 : s->op2 = m;
2088 402 : s->flag = MARKJOIN;
2089 402 : s->key = 0;
2090 402 : s->nrcols = g->nrcols;
2091 402 : s->nr = getDestVar(q);
2092 402 : s->q = q;
2093 402 : return s;
2094 : }
2095 :
2096 : stmt *
2097 2492 : stmt_markjoin(backend *be, stmt *l, stmt *r, bool final)
2098 : {
2099 2492 : MalBlkPtr mb = be->mb;
2100 2492 : InstrPtr q;
2101 :
2102 2492 : q = newStmtArgs(mb, algebraRef, markjoinRef, 8);
2103 2492 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
2104 2492 : if (!final)
2105 5 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
2106 2492 : q = pushArgument(mb, q, l->nr); /* left ids */
2107 2492 : q = pushArgument(mb, q, r->nr); /* mark info mask */
2108 2492 : q = pushNilBat(mb, q);
2109 2492 : q = pushNilBat(mb, q);
2110 2492 : q = pushNil(mb, q, TYPE_lng);
2111 2492 : pushInstruction(mb, q);
2112 :
2113 2492 : if (!q)
2114 : return NULL;
2115 2492 : stmt *s = stmt_create(be->mvc->sa, st_join);
2116 2492 : if (s == NULL) {
2117 0 : freeInstruction(q);
2118 0 : return NULL;
2119 : }
2120 :
2121 2492 : s->op1 = l;
2122 2492 : s->op2 = r;
2123 2492 : s->flag = MARKJOIN;
2124 2492 : s->key = 0;
2125 2492 : s->nrcols = l->nrcols;
2126 2492 : s->nr = getDestVar(q);
2127 2492 : s->q = q;
2128 2492 : return s;
2129 : }
2130 :
2131 : stmt *
2132 5053 : stmt_uselect2(backend *be, stmt *op1, stmt *op2, stmt *op3, int cmp, stmt *sub, int anti, int symmetric, int reduce)
2133 : {
2134 5053 : stmt *sel = sub;
2135 5053 : InstrPtr q = select2_join2(be, op1, op2, op3, cmp, &sub, anti, symmetric, 0, st_uselect2, reduce);
2136 :
2137 5053 : if (q == NULL)
2138 : return NULL;
2139 :
2140 5053 : stmt *s = stmt_create(be->mvc->sa, st_uselect2);
2141 5053 : if (s == NULL) {
2142 : return NULL;
2143 : }
2144 :
2145 5053 : s->op1 = op1;
2146 5053 : s->op2 = op2;
2147 5053 : s->op3 = op3;
2148 5053 : s->op4.stval = sub;
2149 5053 : s->flag = cmp;
2150 5053 : s->nrcols = op1->nrcols;
2151 5053 : s->key = op1->nrcols == 0 && op2->nrcols == 0 && op3->nrcols == 0;
2152 5053 : s->nr = getDestVar(q);
2153 5053 : s->q = q;
2154 5053 : s->cand = sub;
2155 5053 : s->reduce = reduce;
2156 5053 : if (!sub && sel) /* project back the old ids */
2157 1458 : return stmt_project(be, s, sel);
2158 : return s;
2159 : }
2160 :
2161 : stmt *
2162 53989 : stmt_tunion(backend *be, stmt *op1, stmt *op2)
2163 : {
2164 53989 : InstrPtr q = NULL;
2165 53989 : MalBlkPtr mb = be->mb;
2166 :
2167 53989 : q = dump_2(mb, batRef, mergecandRef, op1, op2);
2168 53989 : if (q) {
2169 53989 : stmt *s = stmt_create(be->mvc->sa, st_tunion);
2170 53989 : if (s == NULL) {
2171 : return NULL;
2172 : }
2173 :
2174 53989 : s->op1 = op1;
2175 53989 : s->op2 = op2;
2176 53989 : s->nrcols = op1->nrcols;
2177 53989 : s->key = op1->key;
2178 53989 : s->aggr = op1->aggr;
2179 53989 : s->nr = getDestVar(q);
2180 53989 : s->q = q;
2181 53989 : 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 44620 : stmt_tdiff(backend *be, stmt *op1, stmt *op2, stmt *lcand)
2191 : {
2192 44620 : InstrPtr q = NULL;
2193 44620 : MalBlkPtr mb = be->mb;
2194 :
2195 44620 : if (op1 == NULL || op2 == NULL || op1->nr < 0 || op2->nr < 0)
2196 0 : goto bailout;
2197 44620 : q = newStmt(mb, algebraRef, differenceRef);
2198 44620 : if (q == NULL)
2199 0 : goto bailout;
2200 44620 : q = pushArgument(mb, q, op1->nr); /* left */
2201 44620 : q = pushArgument(mb, q, op2->nr); /* right */
2202 44620 : if (lcand)
2203 0 : q = pushArgument(mb, q, lcand->nr); /* left */
2204 : else
2205 44620 : q = pushNilBat(mb, q); /* left candidate */
2206 44620 : q = pushNilBat(mb, q); /* right candidate */
2207 44620 : q = pushBit(mb, q, FALSE); /* nil matches */
2208 44620 : q = pushBit(mb, q, FALSE); /* do not clear nils */
2209 44620 : q = pushNil(mb, q, TYPE_lng); /* estimate */
2210 :
2211 44620 : bool enabled = be->mvc->sa->eb.enabled;
2212 44620 : be->mvc->sa->eb.enabled = false;
2213 44620 : stmt *s = stmt_create(be->mvc->sa, st_tdiff);
2214 44620 : be->mvc->sa->eb.enabled = enabled;
2215 44620 : if (s == NULL) {
2216 0 : freeInstruction(q);
2217 0 : goto bailout;
2218 : }
2219 :
2220 44620 : s->op1 = op1;
2221 44620 : s->op2 = op2;
2222 44620 : s->nrcols = op1->nrcols;
2223 44620 : s->key = op1->key;
2224 44620 : s->aggr = op1->aggr;
2225 44620 : s->nr = getDestVar(q);
2226 44620 : s->q = q;
2227 44620 : pushInstruction(mb, q);
2228 44620 : 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 1345 : stmt_tdiff2(backend *be, stmt *op1, stmt *op2, stmt *lcand)
2238 : {
2239 1345 : InstrPtr q = NULL;
2240 1345 : MalBlkPtr mb = be->mb;
2241 :
2242 1345 : if (op1 == NULL || op2 == NULL || op1->nr < 0 || op2->nr < 0)
2243 0 : goto bailout;
2244 1345 : q = newStmt(mb, algebraRef, differenceRef);
2245 1345 : if (q == NULL)
2246 0 : goto bailout;
2247 1345 : q = pushArgument(mb, q, op1->nr); /* left */
2248 1345 : q = pushArgument(mb, q, op2->nr); /* right */
2249 1345 : if (lcand)
2250 0 : q = pushArgument(mb, q, lcand->nr); /* left */
2251 : else
2252 1345 : q = pushNilBat(mb, q); /* left candidate */
2253 1345 : q = pushNilBat(mb, q); /* right candidate */
2254 1345 : q = pushBit(mb, q, FALSE); /* nil matches */
2255 1345 : q = pushBit(mb, q, TRUE); /* not in */
2256 1345 : q = pushNil(mb, q, TYPE_lng); /* estimate */
2257 :
2258 1345 : bool enabled = be->mvc->sa->eb.enabled;
2259 1345 : be->mvc->sa->eb.enabled = false;
2260 1345 : stmt *s = stmt_create(be->mvc->sa, st_tdiff);
2261 1345 : be->mvc->sa->eb.enabled = enabled;
2262 1345 : if (s == NULL) {
2263 0 : freeInstruction(q);
2264 0 : goto bailout;
2265 : }
2266 :
2267 1345 : s->op1 = op1;
2268 1345 : s->op2 = op2;
2269 1345 : s->nrcols = op1->nrcols;
2270 1345 : s->key = op1->key;
2271 1345 : s->aggr = op1->aggr;
2272 1345 : s->nr = getDestVar(q);
2273 1345 : s->q = q;
2274 1345 : pushInstruction(mb, q);
2275 1345 : 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 2060 : stmt_tinter(backend *be, stmt *op1, stmt *op2, bool single)
2285 : {
2286 2060 : InstrPtr q = NULL;
2287 2060 : MalBlkPtr mb = be->mb;
2288 :
2289 2060 : if (op1 == NULL || op2 == NULL || op1->nr < 0 || op2->nr < 0)
2290 0 : goto bailout;
2291 2060 : q = newStmt(mb, algebraRef, intersectRef);
2292 2060 : if (q == NULL)
2293 0 : goto bailout;
2294 2060 : q = pushArgument(mb, q, op1->nr); /* left */
2295 2060 : q = pushArgument(mb, q, op2->nr); /* right */
2296 2060 : q = pushNilBat(mb, q); /* left candidate */
2297 2060 : q = pushNilBat(mb, q); /* right candidate */
2298 2060 : q = pushBit(mb, q, FALSE); /* nil matches */
2299 2060 : q = pushBit(mb, q, single?TRUE:FALSE); /* max_one */
2300 2060 : q = pushNil(mb, q, TYPE_lng); /* estimate */
2301 :
2302 2060 : bool enabled = be->mvc->sa->eb.enabled;
2303 2060 : be->mvc->sa->eb.enabled = false;
2304 2060 : stmt *s = stmt_create(be->mvc->sa, st_tinter);
2305 2060 : be->mvc->sa->eb.enabled = enabled;
2306 2060 : if (s == NULL) {
2307 0 : freeInstruction(q);
2308 0 : goto bailout;
2309 : }
2310 :
2311 2060 : s->op1 = op1;
2312 2060 : s->op2 = op2;
2313 2060 : s->nrcols = op1->nrcols;
2314 2060 : s->key = op1->key;
2315 2060 : s->aggr = op1->aggr;
2316 2060 : s->nr = getDestVar(q);
2317 2060 : s->q = q;
2318 2060 : pushInstruction(mb, q);
2319 2060 : 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 94233 : 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 94233 : MalBlkPtr mb = be->mb;
2331 94233 : InstrPtr q = NULL;
2332 94233 : const char *sjt = inner?joinRef:outerjoinRef;
2333 :
2334 94233 : (void)anti;
2335 94233 : (void)inner;
2336 :
2337 94233 : if (need_left) {
2338 653 : cmptype = cmp_equal;
2339 653 : sjt = leftjoinRef;
2340 : }
2341 94233 : if (op1 == NULL || op2 == NULL || op1->nr < 0 || op2->nr < 0)
2342 0 : goto bailout;
2343 :
2344 94233 : assert (!single || cmptype == cmp_all);
2345 :
2346 94233 : switch (cmptype) {
2347 76462 : case cmp_equal:
2348 76462 : q = newStmtArgs(mb, algebraRef, sjt, 9);
2349 76462 : if (q == NULL)
2350 0 : goto bailout;
2351 76462 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
2352 76462 : q = pushArgument(mb, q, op1->nr);
2353 76462 : q = pushArgument(mb, q, op2->nr);
2354 76462 : if (!lcand)
2355 75396 : q = pushNilBat(mb, q);
2356 : else
2357 1066 : q = pushArgument(mb, q, lcand->nr);
2358 76462 : if (!rcand)
2359 76462 : q = pushNilBat(mb, q);
2360 : else
2361 0 : q = pushArgument(mb, q, rcand->nr);
2362 76462 : q = pushBit(mb, q, is_semantics?TRUE:FALSE);
2363 76462 : if (!inner)
2364 75 : q = pushBit(mb, q, FALSE); /* not match_one */
2365 76462 : q = pushNil(mb, q, TYPE_lng);
2366 76462 : pushInstruction(mb, q);
2367 76462 : break;
2368 34 : case cmp_notequal:
2369 34 : if (inner)
2370 34 : sjt = thetajoinRef;
2371 34 : q = newStmtArgs(mb, algebraRef, sjt, 9);
2372 34 : if (q == NULL)
2373 0 : goto bailout;
2374 34 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
2375 34 : q = pushArgument(mb, q, op1->nr);
2376 34 : q = pushArgument(mb, q, op2->nr);
2377 34 : if (!lcand)
2378 34 : q = pushNilBat(mb, q);
2379 : else
2380 0 : q = pushArgument(mb, q, lcand->nr);
2381 34 : if (!rcand)
2382 34 : q = pushNilBat(mb, q);
2383 : else
2384 0 : q = pushArgument(mb, q, rcand->nr);
2385 34 : if (inner)
2386 34 : q = pushInt(mb, q, JOIN_NE);
2387 34 : q = pushBit(mb, q, is_semantics?TRUE:FALSE);
2388 34 : if (!inner)
2389 0 : q = pushBit(mb, q, FALSE); /* not match_one */
2390 34 : q = pushNil(mb, q, TYPE_lng);
2391 34 : pushInstruction(mb, q);
2392 34 : break;
2393 2583 : case cmp_lt:
2394 : case cmp_lte:
2395 : case cmp_gt:
2396 : case cmp_gte:
2397 2583 : q = newStmtArgs(mb, algebraRef, thetajoinRef, 9);
2398 2583 : if (q == NULL)
2399 0 : goto bailout;
2400 2583 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
2401 2583 : q = pushArgument(mb, q, op1->nr);
2402 2583 : q = pushArgument(mb, q, op2->nr);
2403 2583 : if (!lcand)
2404 2583 : q = pushNilBat(mb, q);
2405 : else
2406 0 : q = pushArgument(mb, q, lcand->nr);
2407 2583 : if (!rcand)
2408 2583 : q = pushNilBat(mb, q);
2409 : else
2410 0 : q = pushArgument(mb, q, rcand->nr);
2411 2583 : if (cmptype == cmp_lt)
2412 2067 : q = pushInt(mb, q, JOIN_LT);
2413 516 : else if (cmptype == cmp_lte)
2414 8 : q = pushInt(mb, q, JOIN_LE);
2415 508 : else if (cmptype == cmp_gt)
2416 503 : q = pushInt(mb, q, JOIN_GT);
2417 5 : else if (cmptype == cmp_gte)
2418 5 : q = pushInt(mb, q, JOIN_GE);
2419 2583 : q = pushBit(mb, q, is_semantics?TRUE:FALSE);
2420 2583 : q = pushNil(mb, q, TYPE_lng);
2421 2583 : pushInstruction(mb, q);
2422 2583 : break;
2423 11969 : case cmp_all: /* aka cross table */
2424 11969 : q = newStmt(mb, algebraRef, inner?crossRef:outercrossRef);
2425 11969 : if (q == NULL)
2426 0 : goto bailout;
2427 11969 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
2428 11969 : q = pushArgument(mb, q, op1->nr);
2429 11969 : q = pushArgument(mb, q, op2->nr);
2430 11969 : if (!inner) {
2431 436 : q = pushNilBat(mb, q);
2432 436 : q = pushNilBat(mb, q);
2433 : }
2434 11969 : q = pushBit(mb, q, single?TRUE:FALSE); /* max_one */
2435 11969 : assert(!lcand && !rcand);
2436 11969 : pushInstruction(mb, q);
2437 11969 : break;
2438 3185 : case cmp_joined:
2439 3185 : q = op1->q;
2440 3185 : if (q == NULL)
2441 0 : goto bailout;
2442 : break;
2443 0 : default:
2444 0 : TRC_ERROR(SQL_EXECUTION, "Impossible action\n");
2445 : }
2446 :
2447 94233 : stmt *s = stmt_create(be->mvc->sa, st_join);
2448 94233 : if (s == NULL) {
2449 0 : goto bailout;
2450 : }
2451 :
2452 94233 : s->op1 = op1;
2453 94233 : s->op2 = op2;
2454 94233 : s->flag = cmptype;
2455 94233 : s->key = 0;
2456 94233 : s->nrcols = 2;
2457 94233 : s->nr = getDestVar(q);
2458 94233 : s->q = q;
2459 94233 : 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 90145 : stmt_join(backend *be, stmt *l, stmt *r, int anti, comp_type cmptype, int need_left, int is_semantics, bool single)
2469 : {
2470 90145 : return stmt_join_cand(be, l, r, NULL, NULL, anti, cmptype, need_left, is_semantics, single, true);
2471 : }
2472 :
2473 : stmt *
2474 1429 : stmt_semijoin(backend *be, stmt *op1, stmt *op2, stmt *lcand, stmt *rcand, int is_semantics, bool single)
2475 : {
2476 1429 : MalBlkPtr mb = be->mb;
2477 1429 : InstrPtr q = NULL;
2478 :
2479 1429 : if (op1 == NULL || op2 == NULL || op1->nr < 0 || op2->nr < 0)
2480 0 : goto bailout;
2481 :
2482 1429 : if (single) {
2483 280 : q = newStmtArgs(mb, algebraRef, semijoinRef, 9);
2484 280 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
2485 : } else
2486 1149 : q = newStmt(mb, algebraRef, intersectRef);
2487 1429 : if (q == NULL)
2488 0 : goto bailout;
2489 1429 : q = pushArgument(mb, q, op1->nr);
2490 1429 : q = pushArgument(mb, q, op2->nr);
2491 1429 : if (lcand)
2492 1146 : q = pushArgument(mb, q, lcand->nr);
2493 : else
2494 283 : q = pushNilBat(mb, q);
2495 1429 : if (rcand)
2496 0 : q = pushArgument(mb, q, rcand->nr);
2497 : else
2498 1429 : q = pushNilBat(mb, q);
2499 1429 : q = pushBit(mb, q, is_semantics?TRUE:FALSE);
2500 1429 : q = pushBit(mb, q, single?TRUE:FALSE); /* max_one */
2501 1429 : q = pushNil(mb, q, TYPE_lng);
2502 :
2503 1429 : bool enabled = be->mvc->sa->eb.enabled;
2504 1429 : be->mvc->sa->eb.enabled = false;
2505 1429 : stmt *s = stmt_create(be->mvc->sa, st_semijoin);
2506 1429 : be->mvc->sa->eb.enabled = enabled;
2507 1429 : if (s == NULL) {
2508 0 : freeInstruction(q);
2509 0 : goto bailout;
2510 : }
2511 :
2512 1429 : s->op1 = op1;
2513 1429 : s->op2 = op2;
2514 1429 : s->flag = cmp_equal;
2515 1429 : s->key = 0;
2516 1429 : s->nrcols = 1;
2517 1429 : if (single)
2518 280 : s->nrcols = 2;
2519 1429 : s->nr = getDestVar(q);
2520 1429 : s->q = q;
2521 1429 : pushInstruction(mb, q);
2522 1429 : 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 3512994 : stmt_project_join(backend *be, stmt *op1, stmt *op2, bool delta)
2532 : {
2533 3512994 : MalBlkPtr mb = be->mb;
2534 3512994 : InstrPtr q = NULL;
2535 :
2536 3512994 : if (op1 == NULL || op2 == NULL || op1->nr < 0 || op2->nr < 0)
2537 : return NULL;
2538 : /* delta bat */
2539 3512994 : if (delta) {
2540 482203 : int uval = getArg(op2->q, 1);
2541 :
2542 482203 : q = newStmt(mb, sqlRef, deltaRef);
2543 482201 : q = pushArgument(mb, q, op1->nr);
2544 482201 : q = pushArgument(mb, q, op2->nr);
2545 482201 : q = pushArgument(mb, q, uval);
2546 : } else {
2547 : /* projections, ie left is void headed */
2548 3030791 : q = newStmt(mb, algebraRef, projectionRef);
2549 3030796 : q = pushArgument(mb, q, op1->nr);
2550 3030797 : q = pushArgument(mb, q, op2->nr);
2551 : }
2552 3512997 : pushInstruction(mb, q);
2553 3512997 : return q;
2554 : }
2555 :
2556 : stmt *
2557 3040076 : stmt_project(backend *be, stmt *op1, stmt *op2)
2558 : {
2559 3040076 : if (op1 == NULL || op2 == NULL)
2560 : return NULL;
2561 3040076 : if (!op2->nrcols)
2562 9286 : return stmt_const(be, op1, op2);
2563 3030790 : InstrPtr q = stmt_project_join(be, op1, op2, false);
2564 3030797 : if (q) {
2565 3030797 : stmt *s = stmt_create(be->mvc->sa, st_join);
2566 3030780 : if (s == NULL) {
2567 : return NULL;
2568 : }
2569 :
2570 3030780 : s->op1 = op1;
2571 3030780 : s->op2 = op2;
2572 3030780 : s->flag = cmp_project;
2573 3030780 : s->key = 0;
2574 3030780 : s->nrcols = MAX(op1->nrcols,op2->nrcols);
2575 3030780 : s->nr = getDestVar(q);
2576 3030780 : s->q = q;
2577 3030780 : s->tname = op2->tname;
2578 3030780 : s->cname = op2->cname;
2579 3030780 : s->label = op2->label;
2580 3030780 : 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 482203 : stmt_project_delta(backend *be, stmt *col, stmt *upd)
2589 : {
2590 482203 : InstrPtr q = stmt_project_join(be, col, upd, true);
2591 482201 : if (q) {
2592 482201 : stmt *s = stmt_create(be->mvc->sa, st_join);
2593 482201 : if (s == NULL) {
2594 : return NULL;
2595 : }
2596 :
2597 482201 : s->op1 = col;
2598 482201 : s->op2 = upd;
2599 482201 : s->flag = cmp_project;
2600 482201 : s->key = 0;
2601 482201 : s->nrcols = 2;
2602 482201 : s->nr = getDestVar(q);
2603 482201 : s->q = q;
2604 482201 : s->tname = col->tname;
2605 482201 : s->cname = col->cname;
2606 482201 : 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 25574 : stmt_rs_column(backend *be, stmt *rs, int i, sql_subtype *tpe)
2836 : {
2837 25574 : InstrPtr q = NULL;
2838 :
2839 25574 : if (rs == NULL || rs->nr < 0)
2840 : return NULL;
2841 25574 : q = rs->q;
2842 25574 : if (q) {
2843 25358 : stmt *s = stmt_create(be->mvc->sa, st_rs_column);
2844 25358 : if (s == NULL) {
2845 : return NULL;
2846 : }
2847 :
2848 25358 : s->op1 = rs;
2849 25358 : s->op4.typeval = *tpe;
2850 25358 : s->flag = i;
2851 25358 : s->nrcols = 1;
2852 25358 : s->key = 0;
2853 25358 : s->q = q;
2854 25358 : s->nr = getArg(q, s->flag);
2855 25358 : 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 3162 : stmt_trans(backend *be, int type, stmt *chain, stmt *name)
3036 : {
3037 3162 : MalBlkPtr mb = be->mb;
3038 3162 : InstrPtr q = NULL;
3039 :
3040 3162 : if (chain == NULL || chain->nr < 0)
3041 0 : goto bailout;
3042 :
3043 3162 : switch(type){
3044 13 : case ddl_release:
3045 13 : q = newStmt(mb, sqlRef, transaction_releaseRef);
3046 13 : break;
3047 558 : case ddl_commit:
3048 558 : q = newStmt(mb, sqlRef, transaction_commitRef);
3049 558 : break;
3050 1084 : case ddl_rollback:
3051 1084 : q = newStmt(mb, sqlRef, transaction_rollbackRef);
3052 1084 : break;
3053 1507 : case ddl_trans:
3054 1507 : q = newStmt(mb, sqlRef, transaction_beginRef);
3055 1507 : break;
3056 0 : default:
3057 0 : TRC_ERROR(SQL_EXECUTION, "Unknown transaction type\n");
3058 0 : goto bailout;
3059 : }
3060 3162 : if (q == NULL)
3061 0 : goto bailout;
3062 3162 : q = pushArgument(mb, q, chain->nr);
3063 3162 : if (name)
3064 79 : q = pushArgument(mb, q, name->nr);
3065 : else
3066 3083 : q = pushNil(mb, q, TYPE_str);
3067 :
3068 3162 : bool enabled = be->mvc->sa->eb.enabled;
3069 3162 : be->mvc->sa->eb.enabled = false;
3070 3162 : stmt *s = stmt_create(be->mvc->sa, st_trans);
3071 3162 : be->mvc->sa->eb.enabled = enabled;
3072 3162 : if(!s) {
3073 0 : freeInstruction(q);
3074 0 : goto bailout;
3075 : }
3076 3162 : s->op1 = chain;
3077 3162 : s->op2 = name;
3078 3162 : s->flag = type;
3079 3162 : s->q = q;
3080 3162 : s->nr = getDestVar(q);
3081 3162 : pushInstruction(mb, q);
3082 3162 : 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 285073 : stmt_catalog(backend *be, int type, stmt *args)
3092 : {
3093 285073 : MalBlkPtr mb = be->mb;
3094 285073 : InstrPtr q = NULL;
3095 285073 : node *n;
3096 :
3097 285073 : if (args == NULL || args->nr < 0)
3098 0 : goto bailout;
3099 :
3100 : /* cast them into properly named operations */
3101 285073 : const char *ref;
3102 285073 : switch(type){
3103 313 : case ddl_create_seq: ref = create_seqRef; break;
3104 47 : case ddl_alter_seq: ref = alter_seqRef; break;
3105 32 : case ddl_drop_seq: ref = drop_seqRef; break;
3106 1082 : case ddl_create_schema: ref = create_schemaRef; break;
3107 191 : case ddl_drop_schema: ref = drop_schemaRef; break;
3108 10115 : case ddl_create_table: ref = create_tableRef; break;
3109 22390 : case ddl_create_view: ref = create_viewRef; break;
3110 3691 : case ddl_drop_table: ref = drop_tableRef; break;
3111 346 : 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 906 : 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 18487 : case ddl_grant: ref = grantRef; break;
3119 15 : case ddl_revoke: ref = revokeRef; break;
3120 99259 : case ddl_grant_func: ref = grant_functionRef; break;
3121 1 : case ddl_revoke_func: ref = revoke_functionRef; break;
3122 358 : 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 670 : case ddl_drop_function: ref = drop_functionRef; break;
3130 121261 : case ddl_create_function: ref = create_functionRef; break;
3131 345 : 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 2310 : case ddl_alter_table_set_access:ref = alter_set_tableRef; break;
3136 225 : 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 354 : 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 285073 : q = newStmtArgs(mb, sqlcatalogRef, ref, list_length(args->op4.lval) + 1);
3147 285073 : if (q == NULL)
3148 0 : goto bailout;
3149 : // pass all arguments as before
3150 1704107 : for (n = args->op4.lval->h; n; n = n->next) {
3151 1419034 : stmt *c = n->data;
3152 :
3153 1419034 : q = pushArgument(mb, q, c->nr);
3154 : }
3155 :
3156 285073 : bool enabled = be->mvc->sa->eb.enabled;
3157 285073 : be->mvc->sa->eb.enabled = false;
3158 285073 : stmt *s = stmt_create(be->mvc->sa, st_catalog);
3159 285073 : be->mvc->sa->eb.enabled = enabled;
3160 285073 : if(!s) {
3161 0 : freeInstruction(q);
3162 0 : goto bailout;
3163 : }
3164 285073 : s->op1 = args;
3165 285073 : s->flag = type;
3166 285073 : s->q = q;
3167 285073 : s->nr = getDestVar(q);
3168 285073 : pushInstruction(mb, q);
3169 285073 : 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 1854477 : stmt_set_nrcols(stmt *s)
3179 : {
3180 1854477 : unsigned nrcols = 0;
3181 1854477 : int key = 1;
3182 1854477 : node *n;
3183 1854477 : list *l = s->op4.lval;
3184 :
3185 1854477 : assert(s->type == st_list);
3186 9033852 : for (n = l->h; n; n = n->next) {
3187 7179375 : stmt *f = n->data;
3188 :
3189 7179375 : if (!f)
3190 0 : continue;
3191 7179375 : if (f->nrcols > nrcols)
3192 : nrcols = f->nrcols;
3193 7179375 : key &= f->key;
3194 7179375 : s->nr = f->nr;
3195 : }
3196 1854477 : s->nrcols = nrcols;
3197 1854477 : s->key = key;
3198 1854477 : }
3199 :
3200 : stmt *
3201 1447104 : stmt_list(backend *be, list *l)
3202 : {
3203 1447104 : if (l == NULL)
3204 : return NULL;
3205 1447104 : stmt *s = stmt_create(be->mvc->sa, st_list);
3206 1447095 : if(!s) {
3207 : return NULL;
3208 : }
3209 1447095 : s->op4.lval = l;
3210 1447095 : stmt_set_nrcols(s);
3211 1447095 : return s;
3212 : }
3213 :
3214 : static InstrPtr
3215 64568 : dump_header(mvc *sql, MalBlkPtr mb, list *l)
3216 : {
3217 64568 : node *n;
3218 : // gather the meta information
3219 64568 : int tblId, nmeId, tpeId, lenId, scaleId;
3220 64568 : int args;
3221 64568 : InstrPtr list;
3222 64568 : InstrPtr tblPtr, nmePtr, tpePtr, lenPtr, scalePtr;
3223 :
3224 64568 : args = list_length(l) + 1;
3225 :
3226 64568 : list = newInstructionArgs(mb,sqlRef, resultSetRef, args + 5);
3227 64568 : if(!list) {
3228 : return NULL;
3229 : }
3230 64568 : getArg(list,0) = newTmpVariable(mb,TYPE_int);
3231 64568 : meta(tblPtr, tblId, TYPE_str, args);
3232 64568 : meta(nmePtr, nmeId, TYPE_str, args);
3233 64568 : meta(tpePtr, tpeId, TYPE_str, args);
3234 64568 : meta(lenPtr, lenId, TYPE_int, args);
3235 64568 : meta(scalePtr, scaleId, TYPE_int, args);
3236 64568 : if(tblPtr == NULL || nmePtr == NULL || tpePtr == NULL || lenPtr == NULL || scalePtr == NULL)
3237 : return NULL;
3238 :
3239 339712 : for (n = l->h; n; n = n->next) {
3240 275144 : stmt *c = n->data;
3241 275144 : sql_subtype *t = tail_type(c);
3242 275148 : const char *tname = table_name(sql->sa, c);
3243 275149 : const char *sname = schema_name(sql->sa, c);
3244 275151 : const char *_empty = "";
3245 275151 : const char *tn = (tname) ? tname : _empty;
3246 275151 : const char *sn = (sname) ? sname : _empty;
3247 275151 : const char *cn = column_name(sql->sa, c);
3248 275150 : const char *ntn = sql_escape_ident(sql->ta, tn);
3249 275147 : const char *nsn = sql_escape_ident(sql->ta, sn);
3250 275158 : size_t fqtnl;
3251 :
3252 275158 : if (ntn && nsn && (fqtnl = strlen(ntn) + 1 + strlen(nsn) + 1) ){
3253 275158 : char *fqtn = SA_NEW_ARRAY(sql->ta, char, fqtnl);
3254 275155 : if (fqtn == NULL)
3255 : return NULL;
3256 275155 : snprintf(fqtn, fqtnl, "%s.%s", nsn, ntn);
3257 275155 : tblPtr = pushStr(mb, tblPtr, fqtn);
3258 275157 : nmePtr = pushStr(mb, nmePtr, cn);
3259 275151 : tpePtr = pushStr(mb, tpePtr, (t->type->localtype == TYPE_void ? "char" : t->type->base.name));
3260 275150 : lenPtr = pushInt(mb, lenPtr, t->digits);
3261 275148 : scalePtr = pushInt(mb, scalePtr, t->scale);
3262 275146 : list = pushArgument(mb,list,c->nr);
3263 : } else
3264 : return NULL;
3265 : }
3266 64568 : sa_reset(sql->ta);
3267 64568 : pushInstruction(mb,list);
3268 64568 : return list;
3269 : }
3270 :
3271 : int
3272 125047 : stmt_output(backend *be, stmt *lst)
3273 : {
3274 125047 : MalBlkPtr mb = be->mb;
3275 125047 : InstrPtr q = NULL;
3276 125047 : list *l = lst->op4.lval;
3277 125047 : int cnt = list_length(l), ok = 0;
3278 125046 : node *n = l->h;
3279 125046 : stmt *first = n->data;
3280 :
3281 : /* single value result, has a fast exit */
3282 125046 : if (cnt == 1 && first->nrcols <= 0 ){
3283 60480 : stmt *c = n->data;
3284 60480 : sql_subtype *t = tail_type(c);
3285 60479 : const char *tname = table_name(be->mvc->sa, c);
3286 60481 : const char *sname = schema_name(be->mvc->sa, c);
3287 60479 : const char *_empty = "";
3288 60479 : const char *tn = (tname) ? tname : _empty;
3289 60479 : const char *sn = (sname) ? sname : _empty;
3290 60479 : const char *cn = column_name(be->mvc->sa, c);
3291 60478 : const char *ntn = sql_escape_ident(be->mvc->ta, tn);
3292 60473 : const char *nsn = sql_escape_ident(be->mvc->ta, sn);
3293 :
3294 60478 : if (ntn && nsn) {
3295 60478 : size_t fqtnl = strlen(ntn) + 1 + strlen(nsn) + 1;
3296 60478 : char *fqtn = SA_NEW_ARRAY(be->mvc->ta, char, fqtnl);
3297 60475 : if (fqtn == NULL)
3298 : return -1;
3299 60475 : ok = 1;
3300 60475 : snprintf(fqtn, fqtnl, "%s.%s", nsn, ntn);
3301 :
3302 60475 : q = newStmt(mb, sqlRef, resultSetRef);
3303 60483 : if (q == NULL)
3304 : return -1;
3305 60483 : getArg(q,0) = newTmpVariable(mb,TYPE_int);
3306 60483 : q = pushStr(mb, q, fqtn);
3307 60483 : q = pushStr(mb, q, cn);
3308 60483 : q = pushStr(mb, q, t->type->localtype == TYPE_void ? "char" : t->type->base.name);
3309 60481 : q = pushInt(mb, q, t->digits);
3310 60483 : q = pushInt(mb, q, t->scale);
3311 60483 : q = pushInt(mb, q, t->type->eclass);
3312 60483 : q = pushArgument(mb, q, c->nr);
3313 60483 : pushInstruction(mb, q);
3314 : }
3315 60483 : sa_reset(be->mvc->ta);
3316 60483 : if (!ok)
3317 : return -1;
3318 : } else {
3319 64566 : if ((q = dump_header(be->mvc, mb, l)) == NULL)
3320 : return -1;
3321 : }
3322 : return 0;
3323 : }
3324 :
3325 : int
3326 149492 : stmt_affected_rows(backend *be, int lastnr)
3327 : {
3328 149492 : MalBlkPtr mb = be->mb;
3329 149492 : InstrPtr q = NULL;
3330 :
3331 149492 : q = newStmt(mb, sqlRef, affectedRowsRef);
3332 149490 : if (q == NULL)
3333 : return -1;
3334 149490 : q = pushArgument(mb, q, be->mvc_var);
3335 149490 : getArg(q, 0) = be->mvc_var = newTmpVariable(mb, TYPE_int);
3336 149490 : q = pushArgument(mb, q, lastnr);
3337 149488 : pushInstruction(mb, q);
3338 149489 : be->mvc_var = getDestVar(q);
3339 149489 : return 0;
3340 : }
3341 :
3342 : stmt *
3343 177306 : stmt_append(backend *be, stmt *c, stmt *a)
3344 : {
3345 177306 : MalBlkPtr mb = be->mb;
3346 177306 : InstrPtr q = NULL;
3347 :
3348 177306 : if (c == NULL || a == NULL || c->nr < 0 || a->nr < 0)
3349 0 : goto bailout;
3350 177306 : q = newStmt(mb, batRef, appendRef);
3351 177306 : if (q == NULL)
3352 0 : goto bailout;
3353 177306 : q = pushArgument(mb, q, c->nr);
3354 177306 : q = pushArgument(mb, q, a->nr);
3355 177306 : q = pushBit(mb, q, TRUE);
3356 177306 : bool enabled = be->mvc->sa->eb.enabled;
3357 177306 : be->mvc->sa->eb.enabled = false;
3358 177306 : stmt *s = stmt_create(be->mvc->sa, st_append);
3359 177306 : be->mvc->sa->eb.enabled = enabled;
3360 177306 : if(!s) {
3361 0 : freeInstruction(q);
3362 0 : goto bailout;
3363 : }
3364 177306 : s->op1 = c;
3365 177306 : s->op2 = a;
3366 177306 : s->nrcols = c->nrcols;
3367 177306 : s->key = c->key;
3368 177306 : s->nr = getDestVar(q);
3369 177306 : s->q = q;
3370 177306 : pushInstruction(mb, q);
3371 177306 : 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 137722 : stmt_append_bulk(backend *be, stmt *c, list *l)
3381 : {
3382 137722 : MalBlkPtr mb = be->mb;
3383 137722 : InstrPtr q = NULL;
3384 137722 : bool needs_columns = false;
3385 :
3386 137722 : 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 887879 : for (node *n = l->h; n; n = n->next) {
3392 750157 : stmt *t = n->data;
3393 750157 : needs_columns |= t->nrcols > 0;
3394 : }
3395 137722 : 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 137722 : q = newStmtArgs(mb, batRef, appendBulkRef, list_length(l) + 3);
3404 137742 : if (q == NULL)
3405 0 : goto bailout;
3406 137742 : q = pushArgument(mb, q, c->nr);
3407 137749 : q = pushBit(mb, q, TRUE);
3408 887862 : for (node *n = l->h ; n ; n = n->next) {
3409 750139 : stmt *a = n->data;
3410 750139 : q = pushArgument(mb, q, a->nr);
3411 : }
3412 137723 : bool enabled = be->mvc->sa->eb.enabled;
3413 137723 : be->mvc->sa->eb.enabled = false;
3414 137723 : stmt *s = stmt_create(be->mvc->sa, st_append_bulk);
3415 137724 : be->mvc->sa->eb.enabled = enabled;
3416 137724 : if(!s) {
3417 0 : freeInstruction(q);
3418 0 : goto bailout;
3419 : }
3420 137724 : s->op1 = c;
3421 137724 : s->op4.lval = l;
3422 137724 : s->nrcols = c->nrcols;
3423 137724 : s->key = c->key;
3424 137724 : s->nr = getDestVar(q);
3425 137724 : s->q = q;
3426 137724 : pushInstruction(mb, q);
3427 137724 : 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 15921 : stmt_pack(backend *be, stmt *c, int n)
3437 : {
3438 15921 : MalBlkPtr mb = be->mb;
3439 15921 : InstrPtr q = NULL;
3440 :
3441 15921 : if (c == NULL || c->nr < 0)
3442 0 : goto bailout;
3443 15921 : q = newStmtArgs(mb, matRef, packIncrementRef, 3);
3444 15921 : if (q == NULL)
3445 0 : goto bailout;
3446 15921 : q = pushArgument(mb, q, c->nr);
3447 15921 : q = pushInt(mb, q, n);
3448 15921 : bool enabled = be->mvc->sa->eb.enabled;
3449 15921 : be->mvc->sa->eb.enabled = false;
3450 15921 : stmt *s = stmt_create(be->mvc->sa, st_append);
3451 15921 : be->mvc->sa->eb.enabled = enabled;
3452 15921 : if(!s) {
3453 0 : freeInstruction(q);
3454 0 : goto bailout;
3455 : }
3456 15921 : s->op1 = c;
3457 15921 : s->nrcols = c->nrcols;
3458 15921 : s->key = c->key;
3459 15921 : s->nr = getDestVar(q);
3460 15921 : s->q = q;
3461 15921 : pushInstruction(mb, q);
3462 15921 : 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 29641 : stmt_pack_add(backend *be, stmt *c, stmt *a)
3473 : {
3474 29641 : MalBlkPtr mb = be->mb;
3475 29641 : InstrPtr q = NULL;
3476 :
3477 29641 : if (c == NULL || a == NULL || c->nr < 0 || a->nr < 0)
3478 0 : goto bailout;
3479 29641 : q = newStmtArgs(mb, matRef, packIncrementRef, 3);
3480 29641 : if (q == NULL)
3481 0 : goto bailout;
3482 29641 : q = pushArgument(mb, q, c->nr);
3483 29641 : q = pushArgument(mb, q, a->nr);
3484 29641 : bool enabled = be->mvc->sa->eb.enabled;
3485 29641 : be->mvc->sa->eb.enabled = false;
3486 29641 : stmt *s = stmt_create(be->mvc->sa, st_append);
3487 29641 : be->mvc->sa->eb.enabled = enabled;
3488 29641 : if(!s) {
3489 0 : freeInstruction(q);
3490 0 : goto bailout;
3491 : }
3492 29641 : s->op1 = c;
3493 29641 : s->op2 = a;
3494 29641 : s->nrcols = c->nrcols;
3495 29641 : s->key = c->key;
3496 29641 : s->nr = getDestVar(q);
3497 29641 : s->q = q;
3498 29641 : pushInstruction(mb, q);
3499 29641 : 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 106399 : stmt_claim(backend *be, sql_table *t, stmt *cnt)
3509 : {
3510 106399 : MalBlkPtr mb = be->mb;
3511 106399 : InstrPtr q = NULL;
3512 :
3513 106399 : if (!t || cnt->nr < 0)
3514 0 : goto bailout;
3515 106399 : assert(t->s); /* declared table */
3516 106399 : q = newStmtArgs(mb, sqlRef, claimRef, 6);
3517 106399 : if (q == NULL)
3518 0 : goto bailout;
3519 : /* returns offset or offsets */
3520 106399 : q = pushReturn(mb, q, newTmpVariable(mb, newBatType(TYPE_oid)));
3521 106399 : q = pushArgument(mb, q, be->mvc_var);
3522 106399 : q = pushSchema(mb, q, t);
3523 106399 : q = pushStr(mb, q, t->base.name);
3524 106399 : q = pushArgument(mb, q, cnt->nr);
3525 106399 : bool enabled = be->mvc->sa->eb.enabled;
3526 106399 : be->mvc->sa->eb.enabled = false;
3527 106399 : stmt *s = stmt_create(be->mvc->sa, st_claim);
3528 106399 : be->mvc->sa->eb.enabled = enabled;
3529 106399 : if(!s) {
3530 0 : freeInstruction(q);
3531 0 : goto bailout;
3532 : }
3533 106399 : s->op1 = cnt;
3534 106399 : s->op4.tval = t;
3535 106399 : s->nr = getDestVar(q);
3536 106399 : s->q = q;
3537 106399 : pushInstruction(mb, q);
3538 106399 : 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 149722 : stmt_add_dependency_change(backend *be, sql_table *t, stmt *cnt)
3548 : {
3549 149722 : MalBlkPtr mb = be->mb;
3550 149722 : InstrPtr q = NULL;
3551 :
3552 149722 : if (!t || cnt->nr < 0)
3553 0 : goto bailout;
3554 149722 : q = newStmtArgs(mb, sqlRef, dependRef, 4);
3555 149725 : if (q == NULL)
3556 0 : goto bailout;
3557 149725 : q = pushSchema(mb, q, t);
3558 149725 : q = pushStr(mb, q, t->base.name);
3559 149722 : q = pushArgument(mb, q, cnt->nr);
3560 149721 : pushInstruction(mb, q);
3561 149721 : 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 14878 : stmt_add_column_predicate(backend *be, sql_column *c)
3570 : {
3571 14878 : MalBlkPtr mb = be->mb;
3572 14878 : InstrPtr q = NULL;
3573 :
3574 14878 : if (!c)
3575 0 : goto bailout;
3576 14878 : q = newStmtArgs(mb, sqlRef, predicateRef, 4);
3577 14878 : if (q == NULL)
3578 0 : goto bailout;
3579 14878 : q = pushSchema(mb, q, c->t);
3580 14878 : q = pushStr(mb, q, c->t->base.name);
3581 14878 : q = pushStr(mb, q, c->base.name);
3582 14878 : pushInstruction(mb, q);
3583 14878 : 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 55272 : stmt_replace(backend *be, stmt *r, stmt *id, stmt *val)
3592 : {
3593 55272 : MalBlkPtr mb = be->mb;
3594 55272 : InstrPtr q = NULL;
3595 :
3596 55272 : if (r->nr < 0)
3597 0 : goto bailout;
3598 :
3599 55272 : q = newStmt(mb, batRef, replaceRef);
3600 55272 : if (q == NULL)
3601 0 : goto bailout;
3602 55272 : q = pushArgument(mb, q, r->nr);
3603 55272 : q = pushArgument(mb, q, id->nr);
3604 55272 : q = pushArgument(mb, q, val->nr);
3605 55272 : q = pushBit(mb, q, TRUE); /* forced */
3606 55272 : bool enabled = be->mvc->sa->eb.enabled;
3607 55272 : be->mvc->sa->eb.enabled = false;
3608 55272 : stmt *s = stmt_create(be->mvc->sa, st_replace);
3609 55272 : be->mvc->sa->eb.enabled = enabled;
3610 55272 : if(!s) {
3611 0 : freeInstruction(q);
3612 0 : goto bailout;
3613 : }
3614 55272 : s->op1 = r;
3615 55272 : s->op2 = id;
3616 55272 : s->op3 = val;
3617 55272 : s->nrcols = r->nrcols;
3618 55272 : s->key = r->key;
3619 55272 : s->nr = getDestVar(q);
3620 55272 : s->q = q;
3621 55272 : s->cand = r->cand;
3622 55272 : pushInstruction(mb, q);
3623 55272 : 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 41833 : stmt_table_clear(backend *be, sql_table *t, int restart_sequences)
3633 : {
3634 41833 : MalBlkPtr mb = be->mb;
3635 41833 : InstrPtr q = NULL;
3636 :
3637 41833 : 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 41831 : q = newStmt(mb, sqlRef, clear_tableRef);
3650 41831 : if (q == NULL)
3651 0 : goto bailout;
3652 41831 : q = pushSchema(mb, q, t);
3653 41831 : q = pushStr(mb, q, t->base.name);
3654 41831 : q = pushInt(mb, q, restart_sequences);
3655 41830 : pushInstruction(mb, q);
3656 : }
3657 41832 : stmt *s = stmt_create(be->mvc->sa, st_table_clear);
3658 :
3659 41832 : if(!s) {
3660 0 : goto bailout;
3661 : }
3662 41832 : s->op4.tval = t;
3663 41832 : s->nrcols = 0;
3664 41832 : s->nr = getDestVar(q);
3665 41832 : s->q = q;
3666 41832 : 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 39493 : stmt_exception(backend *be, stmt *cond, const char *errstr, int errcode)
3676 : {
3677 39493 : MalBlkPtr mb = be->mb;
3678 39493 : InstrPtr q = NULL;
3679 :
3680 39493 : if (cond->nr < 0)
3681 : return NULL;
3682 :
3683 : /* if(bit(l)) { error(r);} ==raising an exception */
3684 39493 : q = newStmt(mb, sqlRef, assertRef);
3685 39493 : if (q == NULL)
3686 0 : goto bailout;
3687 39493 : q = pushArgument(mb, q, cond->nr);
3688 39492 : q = pushStr(mb, q, errstr);
3689 39493 : bool enabled = be->mvc->sa->eb.enabled;
3690 39493 : be->mvc->sa->eb.enabled = false;
3691 39493 : stmt *s = stmt_create(be->mvc->sa, st_exception);
3692 39493 : be->mvc->sa->eb.enabled = enabled;
3693 39493 : if(!s) {
3694 0 : freeInstruction(q);
3695 0 : return NULL;
3696 : }
3697 39493 : assert(cond);
3698 39493 : s->op1 = cond;
3699 39493 : (void)errcode;
3700 39493 : s->nrcols = 0;
3701 39493 : s->q = q;
3702 39493 : s->nr = getDestVar(q);
3703 39493 : pushInstruction(mb, q);
3704 39493 : 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 14806 : tail_set_type(mvc *m, stmt *st, sql_subtype *t)
3716 : {
3717 39894 : for (;;) {
3718 39894 : switch (st->type) {
3719 3688 : case st_const:
3720 3688 : st = st->op2;
3721 3688 : continue;
3722 18008 : case st_alias:
3723 : case st_gen_group:
3724 : case st_order:
3725 18008 : st = st->op1;
3726 18008 : continue;
3727 0 : case st_list:
3728 0 : st = st->op4.lval->h->data;
3729 0 : continue;
3730 3392 : case st_join:
3731 : case st_join2:
3732 : case st_joinN:
3733 3392 : if (st->flag == cmp_project) {
3734 3392 : st = st->op2;
3735 3392 : 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 6726 : case st_atom:
3747 6726 : st->op4.aval = atom_set_type(m->sa, st->op4.aval, t);
3748 6726 : 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 51240 : stmt_convert(backend *be, stmt *v, stmt *sel, sql_subtype *f, sql_subtype *t)
3888 : {
3889 51240 : MalBlkPtr mb = be->mb;
3890 51240 : InstrPtr q = NULL;
3891 51240 : const char *convert = t->type->impl, *mod = calcRef;
3892 51240 : int pushed = (v->cand && v->cand == sel), no_candidates = 0;
3893 51240 : bool add_tz = false;
3894 : /* convert types and make sure they are rounded up correctly */
3895 :
3896 51240 : if (v->nr < 0)
3897 0 : goto bailout;
3898 :
3899 51240 : if (f->type->eclass != EC_EXTERNAL && t->type->eclass != EC_EXTERNAL &&
3900 : /* general cases */
3901 50882 : ((t->type->localtype == f->type->localtype && t->type->eclass == f->type->eclass &&
3902 50882 : !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 1768 : (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 44159 : (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 14806 : tail_set_type(be->mvc, v, t);
3909 14806 : return v;
3910 : }
3911 :
3912 : /* external types have sqlname convert functions,
3913 : these can generate errors (fromstr cannot) */
3914 36434 : if (t->type->eclass == EC_EXTERNAL)
3915 331 : convert = t->type->base.name;
3916 36103 : else if (t->type->eclass == EC_MONTH)
3917 : convert = "month_interval";
3918 36080 : else if (t->type->eclass == EC_SEC)
3919 100 : convert = "second_interval";
3920 :
3921 36434 : no_candidates = t->type->eclass == EC_EXTERNAL && strcmp(convert, "uuid") != 0; /* uuids conversions support candidate lists */
3922 :
3923 36434 : 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 36310 : if (v->nrcols == 0 && (!sel || sel->nrcols == 0)) { /* simple calc */
3935 8157 : q = newStmtArgs(mb, mod, convert, 13);
3936 8157 : if (q == NULL)
3937 0 : goto bailout;
3938 28174 : } 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 28132 : 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 28132 : q = newStmtArgs(mb, mod==calcRef?batcalcRef:batmtimeRef, convert, 13);
3960 28132 : 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 36472 : if (EC_VARCHAR(t->type->eclass) && !(trivial_string_conversion(f->type->eclass) && t->digits == 0)) {
3966 1852 : q = pushInt(mb, q, f->type->eclass);
3967 1852 : q = pushInt(mb, q, f->digits);
3968 1852 : q = pushInt(mb, q, f->scale);
3969 1852 : q = pushInt(mb, q, type_has_tz(f));
3970 34458 : } else if (f->type->eclass == EC_DEC) {
3971 : /* scale of the current decimal */
3972 1552 : q = pushInt(mb, q, f->scale);
3973 32906 : } 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 36310 : q = pushArgument(mb, q, v->nr);
3978 36310 : if (add_tz)
3979 : q = pushLng(mb, q, be->mvc->timezone);
3980 36310 : if (sel && !pushed && !v->cand) {
3981 3489 : q = pushArgument(mb, q, sel->nr);
3982 3489 : pushed = 1;
3983 32821 : } else if (v->nrcols > 0 && !no_candidates) {
3984 24643 : q = pushNilBat(mb, q);
3985 : }
3986 36310 : 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 3058 : q = pushInt(mb, q, t->digits);
3989 3058 : if (!EC_TEMP_FRAC(t->type->eclass))
3990 2719 : q = pushInt(mb, q, t->scale);
3991 : }
3992 : /* convert to string, give error on to large strings */
3993 36472 : if (EC_VARCHAR(t->type->eclass) && !(trivial_string_conversion(f->type->eclass) && t->digits == 0))
3994 1852 : q = pushInt(mb, q, t->digits);
3995 : /* convert a string to a time(stamp) with time zone */
3996 36310 : 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 36310 : 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 36310 : bool enabled = be->mvc->sa->eb.enabled;
4022 36310 : be->mvc->sa->eb.enabled = false;
4023 36310 : stmt *s = stmt_create(be->mvc->sa, st_convert);
4024 36310 : be->mvc->sa->eb.enabled = enabled;
4025 36310 : if(!s) {
4026 0 : freeInstruction(q);
4027 0 : goto bailout;
4028 : }
4029 36310 : s->op1 = v;
4030 36310 : s->nrcols = 0; /* function without arguments returns single value */
4031 36310 : s->key = v->key;
4032 36310 : s->nrcols = v->nrcols;
4033 36310 : s->aggr = v->aggr;
4034 36310 : s->op4.typeval = *t;
4035 36310 : s->nr = getDestVar(q);
4036 36310 : s->q = q;
4037 36310 : s->cand = pushed ? sel : NULL;
4038 36310 : pushInstruction(mb, q);
4039 36310 : 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 27057 : stmt_unop(backend *be, stmt *op1, stmt *sel, sql_subfunc *op)
4051 : {
4052 27057 : list *ops = sa_list(be->mvc->sa);
4053 27057 : list_append(ops, op1);
4054 27057 : stmt *r = stmt_Nop(be, stmt_list(be, ops), sel, op, NULL);
4055 27057 : if (r && !r->cand)
4056 27057 : r->cand = op1->cand;
4057 27057 : return r;
4058 : }
4059 :
4060 : stmt *
4061 47229 : stmt_binop(backend *be, stmt *op1, stmt *op2, stmt *sel, sql_subfunc *op)
4062 : {
4063 47229 : list *ops = sa_list(be->mvc->sa);
4064 47229 : list_append(ops, op1);
4065 47229 : list_append(ops, op2);
4066 47229 : stmt *r = stmt_Nop(be, stmt_list(be, ops), sel, op, NULL);
4067 47229 : if (r && !r->cand)
4068 47229 : r->cand = op1->cand?op1->cand:op2->cand;
4069 47229 : return r;
4070 : }
4071 :
4072 : #define LANG_INT_OR_MAL(l) ((l)==FUNC_LANG_INT || (l)==FUNC_LANG_MAL)
4073 :
4074 : stmt *
4075 219581 : stmt_Nop(backend *be, stmt *ops, stmt *sel, sql_subfunc *f, stmt* rows)
4076 : {
4077 219581 : MalBlkPtr mb = be->mb;
4078 219581 : InstrPtr q = NULL;
4079 219581 : const char *mod = sql_func_mod(f->func), *fimp = backend_function_imp(be, f->func);
4080 219581 : sql_subtype *tpe = NULL;
4081 219581 : int push_cands = 0, default_nargs;
4082 219581 : stmt *o = NULL, *card = NULL;
4083 :
4084 219581 : if (ops == NULL)
4085 0 : goto bailout;
4086 :
4087 219581 : 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 219480 : } else if (list_length(ops->op4.lval)) {
4092 217678 : o = ops->op4.lval->h->data;
4093 650087 : for (node *n = ops->op4.lval->h; n; n = n->next) {
4094 432409 : stmt *c = n->data;
4095 :
4096 432409 : if (c && o->nrcols < c->nrcols)
4097 432409 : o = c;
4098 : }
4099 : }
4100 :
4101 : /* handle nullif */
4102 219581 : if (list_length(ops->op4.lval) == 2 &&
4103 138071 : 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 219488 : if (backend_create_subfunc(be, f, ops->op4.lval) < 0)
4134 2 : goto bailout;
4135 219485 : mod = sql_func_mod(f->func);
4136 219484 : fimp = convertMultiplexFcn(backend_function_imp(be, f->func));
4137 219485 : push_cands = f->func->type == F_FUNC && can_push_cands(sel, mod, fimp);
4138 228492 : 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 219485 : 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 219485 : if (o && o->nrcols > 0 && f->func->type != F_LOADER && f->func->type != F_PROC) {
4145 139849 : sql_subtype *res = f->res->h->data;
4146 :
4147 139849 : q = newStmtArgs(mb, f->func->type == F_UNION ? batmalRef : malRef, multiplexRef, default_nargs);
4148 139849 : if (q == NULL)
4149 0 : goto bailout;
4150 139849 : if (rows)
4151 101 : q = pushArgument(mb, q, card->nr);
4152 139849 : q = pushStr(mb, q, mod);
4153 139849 : q = pushStr(mb, q, fimp);
4154 139849 : setVarType(mb, getArg(q, 0), newBatType(res->type->localtype));
4155 : } else {
4156 79636 : q = newStmtArgs(mb, mod, fimp, default_nargs);
4157 79637 : if (q == NULL)
4158 0 : goto bailout;
4159 :
4160 79637 : if (rows)
4161 0 : q = pushArgument(mb, q, card->nr);
4162 79637 : if (f->res && list_length(f->res)) {
4163 70630 : sql_subtype *res = f->res->h->data;
4164 :
4165 70630 : setVarType(mb, getArg(q, 0), res->type->localtype);
4166 : }
4167 : }
4168 219486 : 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 219486 : if (f->func->lang == FUNC_LANG_C) {
4178 35 : q = pushBit(mb, q, 0);
4179 219451 : } else if (f->func->lang == FUNC_LANG_CPP) {
4180 1 : q = pushBit(mb, q, 1);
4181 : }
4182 219486 : 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 219486 : if (f->func->type == F_UNION || (f->func->type == F_LOADER && f->res != NULL))
4188 2675 : q = table_func_create_result(mb, q, f->func, f->res);
4189 219486 : if (list_length(ops->op4.lval))
4190 217669 : tpe = tail_type(ops->op4.lval->h->data);
4191 :
4192 651878 : for (node *n = ops->op4.lval->h; n; n = n->next) {
4193 432392 : stmt *op = n->data;
4194 432392 : q = pushArgument(mb, q, op->nr);
4195 : }
4196 : /* push candidate lists if that's the case */
4197 219486 : if (push_cands) {
4198 76743 : for (node *n = ops->op4.lval->h; n; n = n->next) {
4199 50617 : stmt *op = n->data;
4200 :
4201 50617 : if (op->nrcols > 0) {
4202 28428 : if (op->cand && op->cand == sel) {
4203 3818 : q = pushNilBat(mb, q);
4204 : } else {
4205 24610 : q = pushArgument(mb, q, sel->nr);
4206 : }
4207 : }
4208 : }
4209 : }
4210 : /* special case for round function on decimals */
4211 219486 : 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 219486 : pushInstruction(mb, q);
4216 : }
4217 :
4218 219581 : stmt *s = stmt_create(be->mvc->sa, st_Nop);
4219 219581 : if(!s) {
4220 0 : goto bailout;
4221 : }
4222 219581 : s->op1 = ops;
4223 219581 : if (o) {
4224 217780 : s->nrcols = o->nrcols;
4225 217780 : s->key = o->key;
4226 217780 : s->aggr = o->aggr;
4227 : } else {
4228 1801 : s->nrcols = 0;
4229 1801 : s->key = 1;
4230 : }
4231 219581 : s->op4.funcval = f;
4232 219581 : s->nr = getDestVar(q);
4233 219581 : s->q = q;
4234 219581 : if (sel && push_cands && s->nrcols)
4235 24615 : 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 23 : stmt_direct_func(backend *be, InstrPtr q)
4246 : {
4247 23 : if (q) {
4248 23 : stmt *s = stmt_create(be->mvc->sa, st_func);
4249 23 : if(!s) {
4250 : return NULL;
4251 : }
4252 23 : s->flag = op_union;
4253 23 : s->nrcols = 3;
4254 23 : s->nr = getDestVar(q);
4255 23 : s->q = q;
4256 23 : 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 85138 : stmt_aggr(backend *be, stmt *op1, stmt *grp, stmt *ext, sql_subfunc *op, int reduce, int no_nil, int nil_if_empty)
4353 : {
4354 85138 : MalBlkPtr mb = be->mb;
4355 85138 : InstrPtr q = NULL;
4356 85138 : const char *mod, *aggrfunc;
4357 85138 : sql_subtype *res = op->res->h->data;
4358 85138 : int restype = res->type->localtype;
4359 85138 : bool complex_aggr = false;
4360 85138 : int *stmt_nr = NULL;
4361 85138 : int avg = 0;
4362 :
4363 85138 : if (op1->nr < 0)
4364 0 : goto bailout;
4365 85138 : if (backend_create_subfunc(be, op, NULL) < 0)
4366 0 : goto bailout;
4367 85138 : mod = sql_func_mod(op->func);
4368 85138 : aggrfunc = backend_function_imp(be, op->func);
4369 :
4370 85137 : if (LANG_INT_OR_MAL(op->func->lang)) {
4371 85090 : if (strcmp(aggrfunc, "avg") == 0)
4372 : avg = 1;
4373 83720 : if (avg || strcmp(aggrfunc, "sum") == 0 || strcmp(aggrfunc, "prod") == 0
4374 76451 : || strcmp(aggrfunc, "str_group_concat") == 0)
4375 : complex_aggr = true;
4376 85090 : if (restype == TYPE_dbl)
4377 1561 : avg = 0;
4378 : }
4379 :
4380 170274 : int argc = 1
4381 85137 : + 2 * avg
4382 85137 : + (LANG_EXT(op->func->lang) != 0)
4383 85137 : + 2 * (op->func->lang == FUNC_LANG_C || op->func->lang == FUNC_LANG_CPP)
4384 85137 : + (op->func->lang == FUNC_LANG_PY || op->func->lang == FUNC_LANG_R)
4385 85137 : + (op1->type != st_list ? 1 : list_length(op1->op4.lval))
4386 85137 : + (grp ? 4 : avg + 1);
4387 :
4388 85137 : if (grp) {
4389 6831 : char *aggrF = SA_NEW_ARRAY(be->mvc->sa, char, strlen(aggrfunc) + 4);
4390 6831 : if (!aggrF)
4391 0 : goto bailout;
4392 6831 : stpcpy(stpcpy(aggrF, "sub"), aggrfunc);
4393 6831 : aggrfunc = aggrF;
4394 6831 : if ((grp && grp->nr < 0) || (ext && ext->nr < 0))
4395 0 : goto bailout;
4396 :
4397 6831 : q = newStmtArgs(mb, mod, aggrfunc, argc);
4398 6831 : if (q == NULL)
4399 0 : goto bailout;
4400 6831 : setVarType(mb, getArg(q, 0), newBatType(restype));
4401 6831 : 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 78306 : q = newStmtArgs(mb, mod, aggrfunc, argc);
4407 78307 : if (q == NULL)
4408 0 : goto bailout;
4409 78307 : if (complex_aggr) {
4410 6720 : setVarType(mb, getArg(q, 0), restype);
4411 6720 : 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 85138 : if (LANG_EXT(op->func->lang))
4419 47 : q = pushPtr(mb, q, op->func);
4420 85138 : if (op->func->lang == FUNC_LANG_R ||
4421 85103 : 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 85138 : if (op1->type != st_list) {
4436 79267 : q = pushArgument(mb, q, op1->nr);
4437 : } else {
4438 5871 : int i;
4439 5871 : node *n;
4440 :
4441 12142 : for (i=0, n = op1->op4.lval->h; n; n = n->next, i++) {
4442 6271 : stmt *op = n->data;
4443 :
4444 6271 : if (stmt_nr)
4445 : q = pushArgument(mb, q, stmt_nr[i]);
4446 : else
4447 6271 : q = pushArgument(mb, q, op->nr);
4448 : }
4449 : }
4450 85138 : if (grp) {
4451 6831 : q = pushArgument(mb, q, grp->nr);
4452 6831 : q = pushArgument(mb, q, ext->nr);
4453 6831 : if (LANG_INT_OR_MAL(op->func->lang)) {
4454 6804 : if (avg) /* push nil candidates */
4455 96 : q = pushNilBat(mb, q);
4456 6804 : q = pushBit(mb, q, no_nil);
4457 : }
4458 78307 : } 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 76664 : } 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 76664 : } 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 85138 : bool enabled = be->mvc->sa->eb.enabled;
4468 85138 : be->mvc->sa->eb.enabled = false;
4469 85138 : stmt *s = stmt_create(be->mvc->sa, st_aggr);
4470 85138 : be->mvc->sa->eb.enabled = enabled;
4471 85138 : if(!s) {
4472 0 : freeInstruction(q);
4473 0 : goto bailout;
4474 : }
4475 85138 : s->op1 = op1;
4476 85138 : if (grp) {
4477 6831 : s->op2 = grp;
4478 6831 : s->op3 = ext;
4479 6831 : s->nrcols = 1;
4480 : } else {
4481 78307 : if (!reduce)
4482 0 : s->nrcols = 1;
4483 : }
4484 85138 : s->key = reduce;
4485 85138 : s->aggr = reduce;
4486 85138 : s->flag = no_nil;
4487 85138 : s->op4.funcval = op;
4488 85138 : s->nr = getDestVar(q);
4489 85138 : s->q = q;
4490 85138 : pushInstruction(mb, q);
4491 85138 : 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 5030944 : stmt_alias_(backend *be, stmt *op1, int label, const char *tname, const char *alias)
4501 : {
4502 5030944 : assert(label);
4503 5030944 : stmt *s = stmt_create(be->mvc->sa, st_alias);
4504 5030825 : if(!s) {
4505 : return NULL;
4506 : }
4507 5030825 : s->label = label;
4508 5030825 : s->op1 = op1;
4509 5030825 : s->nrcols = op1->nrcols;
4510 5030825 : s->key = op1->key;
4511 5030825 : s->aggr = op1->aggr;
4512 :
4513 5030825 : s->tname = tname;
4514 5030825 : s->cname = alias;
4515 5030825 : s->nr = op1->nr;
4516 5030825 : s->q = op1->q;
4517 5030825 : return s;
4518 : }
4519 :
4520 : stmt *
4521 4467822 : 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 4467822 : return stmt_alias_(be, op1, label, tname, alias);
4530 : }
4531 :
4532 : stmt *
4533 563145 : stmt_as(backend *be, stmt *s, stmt *org)
4534 : {
4535 563145 : assert(org->type == st_alias);
4536 563145 : return stmt_alias_(be, s, org->label, org->tname, org->cname);
4537 : }
4538 :
4539 : sql_subtype *
4540 1550548 : tail_type(stmt *st)
4541 : {
4542 8618672 : for (;;) {
4543 8618672 : switch (st->type) {
4544 36402 : case st_const:
4545 36402 : st = st->op2;
4546 36402 : continue;
4547 3182 : 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 3182 : 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 3898194 : 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 3898194 : st = st->op1;
4567 3898194 : continue;
4568 0 : case st_list:
4569 0 : st = st->op4.lval->h->data;
4570 0 : continue;
4571 907892 : case st_bat:
4572 907892 : 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 3133566 : if (st->flag == cmp_project) {
4584 3133528 : st = st->op2;
4585 3133528 : continue;
4586 : }
4587 : /* fall through */
4588 : case st_reorder:
4589 : case st_group:
4590 : case st_tid:
4591 : case st_mirror:
4592 15403 : return sql_bind_localtype("oid");
4593 31255 : case st_result:
4594 31255 : return &st->op4.typeval;
4595 0 : case st_table_clear:
4596 0 : return sql_bind_localtype("lng");
4597 156113 : case st_aggr:
4598 : case st_Nop: {
4599 156113 : list *res = st->op4.funcval->res;
4600 :
4601 156113 : if (res && list_length(res) == 1)
4602 156111 : return res->h->data;
4603 :
4604 : return NULL;
4605 : }
4606 150898 : case st_atom:
4607 150898 : return atom_type(st->op4.aval);
4608 280897 : case st_convert:
4609 : case st_temp:
4610 : case st_single:
4611 : case st_rs_column:
4612 280897 : return &st->op4.typeval;
4613 2295 : case st_var:
4614 2295 : if (st->op4.typeval.type)
4615 2295 : 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 6638 : stmt_has_null(stmt *s)
4630 : {
4631 20880 : 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 8191 : case st_alias:
4639 8191 : return stmt_has_null(s->op1);
4640 6051 : case st_join:
4641 6051 : return stmt_has_null(s->op2);
4642 4216 : case st_bat:
4643 4216 : return s->op4.cval->null;
4644 :
4645 2422 : default:
4646 2422 : 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 2653428 : column_name(allocator *sa, stmt *st)
4680 : {
4681 2653428 : if (!st->cname)
4682 0 : st->cname = _column_name(sa, st);
4683 2653428 : 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 2638082 : table_name(allocator *sa, stmt *st)
4754 : {
4755 2638082 : (void)sa;
4756 2638082 : return st->tname;
4757 : }
4758 :
4759 : const char *
4760 335770 : schema_name(allocator *sa, stmt *st)
4761 : {
4762 3099873 : switch (st->type) {
4763 1192768 : case st_const:
4764 : case st_semijoin:
4765 : case st_join:
4766 : case st_join2:
4767 : case st_joinN:
4768 1192768 : return schema_name(sa, st->op2);
4769 120414 : 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 120414 : if (st->op1)
4789 : return schema_name(sa, st->op1);
4790 : return NULL;
4791 1419635 : case st_alias:
4792 1419635 : return schema_name(sa, st->op1);
4793 200938 : case st_bat:
4794 200938 : 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 31406 : case st_list:
4802 31406 : if (list_length(st->op4.lval))
4803 31286 : return schema_name(sa, st->op4.lval->h->data);
4804 : return NULL;
4805 : default:
4806 : return NULL;
4807 : }
4808 : }
4809 :
4810 : stmt *
4811 1118 : stmt_cond(backend *be, stmt *cond, stmt *outer, int loop /* 0 if, 1 while */, int anti )
4812 : {
4813 1118 : MalBlkPtr mb = be->mb;
4814 1118 : InstrPtr q = NULL;
4815 :
4816 1118 : if (cond->nr < 0)
4817 0 : goto bailout;
4818 1118 : 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 1118 : if (!loop) { /* if */
4828 1101 : q = newAssignment(mb);
4829 1101 : if (q == NULL)
4830 0 : goto bailout;
4831 1101 : q->barrier = BARRIERsymbol;
4832 1101 : q = pushArgument(mb, q, cond->nr);
4833 : } else { /* while */
4834 17 : int c;
4835 :
4836 17 : if (outer->nr < 0)
4837 0 : goto bailout;
4838 : /* leave barrier */
4839 17 : q = newStmt(mb, calcRef, notRef);
4840 17 : if (q == NULL)
4841 0 : goto bailout;
4842 17 : q = pushArgument(mb, q, cond->nr);
4843 17 : c = getArg(q, 0);
4844 17 : pushInstruction(mb, q);
4845 :
4846 17 : q = newAssignment(mb);
4847 17 : if (q == NULL)
4848 0 : goto bailout;
4849 17 : getArg(q, 0) = outer->nr;
4850 17 : q->barrier = LEAVEsymbol;
4851 17 : q = pushArgument(mb, q, c);
4852 : }
4853 :
4854 1118 : bool enabled = be->mvc->sa->eb.enabled;
4855 1118 : be->mvc->sa->eb.enabled = false;
4856 1118 : stmt *s = stmt_create(be->mvc->sa, st_cond);
4857 1118 : be->mvc->sa->eb.enabled = enabled;
4858 1118 : if(!s) {
4859 0 : freeInstruction(q);
4860 0 : goto bailout;
4861 : }
4862 1118 : s->flag = be->mvc_var; /* keep the mvc_var of the outer context */
4863 1118 : s->loop = loop;
4864 1118 : s->op1 = cond;
4865 1118 : s->nr = getArg(q, 0);
4866 1118 : pushInstruction(mb, q);
4867 1118 : 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 1118 : stmt_control_end(backend *be, stmt *cond)
4877 : {
4878 1118 : MalBlkPtr mb = be->mb;
4879 1118 : InstrPtr q = NULL;
4880 :
4881 1118 : if (cond->nr < 0)
4882 0 : goto bailout;
4883 :
4884 1118 : if (cond->loop) { /* while */
4885 : /* redo barrier */
4886 17 : q = newAssignment(mb);
4887 17 : if (q == NULL)
4888 0 : goto bailout;
4889 17 : getArg(q, 0) = cond->nr;
4890 17 : q->argc = q->retc = 1;
4891 17 : q->barrier = REDOsymbol;
4892 17 : q = pushBit(mb, q, TRUE);
4893 : } else {
4894 1101 : q = newAssignment(mb);
4895 1101 : if (q == NULL)
4896 0 : goto bailout;
4897 1101 : getArg(q, 0) = cond->nr;
4898 1101 : q->argc = q->retc = 1;
4899 1101 : q->barrier = EXITsymbol;
4900 : }
4901 1118 : be->mvc_var = cond->flag; /* restore old mvc_var from before the barrier */
4902 1118 : bool enabled = be->mvc->sa->eb.enabled;
4903 1118 : be->mvc->sa->eb.enabled = false;
4904 1118 : stmt *s = stmt_create(be->mvc->sa, st_control_end);
4905 1118 : be->mvc->sa->eb.enabled = enabled;
4906 1118 : if(!s) {
4907 0 : freeInstruction(q);
4908 0 : goto bailout;
4909 : }
4910 1118 : s->op1 = cond;
4911 1118 : s->nr = getArg(q, 0);
4912 1118 : pushInstruction(mb, q);
4913 1118 : 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 206 : dump_cols(MalBlkPtr mb, list *l, InstrPtr q)
4924 : {
4925 206 : int i;
4926 206 : node *n;
4927 :
4928 206 : if (q == NULL)
4929 : return NULL;
4930 206 : q->retc = q->argc = 0;
4931 1651 : for (i = 0, n = l->h; n; n = n->next, i++) {
4932 1445 : stmt *c = n->data;
4933 :
4934 1445 : q = pushArgument(mb, q, c->nr);
4935 : }
4936 206 : if (q == NULL)
4937 : return NULL;
4938 206 : q->retc = q->argc;
4939 : /* Let's make it a proper assignment */
4940 1651 : for (i = 0, n = l->h; n; n = n->next, i++) {
4941 1445 : stmt *c = n->data;
4942 :
4943 1445 : q = pushArgument(mb, q, c->nr);
4944 : }
4945 : return q;
4946 : }
4947 :
4948 : stmt *
4949 658 : stmt_return(backend *be, stmt *val, int nr_declared_tables)
4950 : {
4951 658 : MalBlkPtr mb = be->mb;
4952 658 : InstrPtr q = NULL;
4953 :
4954 658 : if (val->nr < 0)
4955 0 : goto bailout;
4956 658 : int args = val->type == st_table ? 2 * list_length(val->op1->op4.lval) : 0;
4957 206 : if (args < MAXARG)
4958 : args = MAXARG;
4959 658 : q = newInstructionArgs(mb, NULL, NULL, args);
4960 658 : if (q == NULL)
4961 0 : goto bailout;
4962 658 : q->barrier= RETURNsymbol;
4963 658 : if (val->type == st_table) {
4964 206 : list *l = val->op1->op4.lval;
4965 :
4966 206 : q = dump_cols(mb, l, q);
4967 : } else {
4968 452 : getArg(q, 0) = getArg(getInstrPtr(mb, 0), 0);
4969 452 : q = pushArgument(mb, q, val->nr);
4970 : }
4971 :
4972 658 : bool enabled = be->mvc->sa->eb.enabled;
4973 658 : be->mvc->sa->eb.enabled = false;
4974 658 : stmt *s = stmt_create(be->mvc->sa, st_return);
4975 658 : be->mvc->sa->eb.enabled = enabled;
4976 658 : if(!s) {
4977 0 : freeInstruction(q);
4978 0 : goto bailout;
4979 : }
4980 658 : s->op1 = val;
4981 658 : s->flag = nr_declared_tables;
4982 658 : s->nr = getDestVar(q);
4983 658 : s->q = q;
4984 658 : pushInstruction(mb, q);
4985 658 : 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 1416 : stmt_assign(backend *be, const char *sname, const char *varname, stmt *val, int level)
4995 : {
4996 1416 : MalBlkPtr mb = be->mb;
4997 1416 : InstrPtr q = NULL;
4998 :
4999 1416 : if (val && val->nr < 0)
5000 0 : goto bailout;
5001 1416 : if (level != 0) {
5002 1037 : char *buf, levelstr[16];
5003 :
5004 1037 : if (!val) {
5005 : /* drop declared table */
5006 0 : assert(0);
5007 : }
5008 :
5009 1037 : assert(!sname);
5010 1037 : snprintf(levelstr, sizeof(levelstr), "%d", level);
5011 1037 : buf = SA_NEW_ARRAY(be->mvc->sa, char, strlen(levelstr) + strlen(varname) + 3);
5012 1037 : if (!buf)
5013 0 : goto bailout;
5014 1037 : stpcpy(stpcpy(stpcpy(stpcpy(buf, "A"), levelstr), "%"), varname); /* mangle variable name */
5015 1037 : q = newInstruction(mb, NULL, NULL);
5016 1037 : if (q == NULL) {
5017 0 : goto bailout;
5018 : }
5019 1037 : q->argc = q->retc = 0;
5020 1037 : q = pushArgumentId(mb, q, buf);
5021 1037 : pushInstruction(mb, q);
5022 1037 : q->retc++;
5023 : } else {
5024 379 : assert(sname); /* all global variables have a schema */
5025 379 : q = newStmt(mb, sqlRef, setVariableRef);
5026 379 : if (q == NULL)
5027 0 : goto bailout;
5028 379 : q = pushArgument(mb, q, be->mvc_var);
5029 379 : q = pushStr(mb, q, sname);
5030 379 : q = pushStr(mb, q, varname);
5031 379 : getArg(q, 0) = be->mvc_var = newTmpVariable(mb, TYPE_int);
5032 379 : pushInstruction(mb, q);
5033 379 : be->mvc_var = getDestVar(q);
5034 : }
5035 1416 : q = pushArgument(mb, q, val->nr);
5036 :
5037 1416 : bool enabled = be->mvc->sa->eb.enabled;
5038 1416 : be->mvc->sa->eb.enabled = false;
5039 1416 : stmt *s = stmt_create(be->mvc->sa, st_assign);
5040 1416 : be->mvc->sa->eb.enabled = enabled;
5041 1416 : if(!s) {
5042 0 : goto bailout;
5043 : }
5044 1416 : s->op2 = val;
5045 1416 : s->flag = (level << 1);
5046 1416 : s->q = q;
5047 1416 : s->nr = 1;
5048 1416 : 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 21386 : const_column(backend *be, stmt *val)
5058 : {
5059 21386 : sql_subtype *ct = tail_type(val);
5060 21385 : MalBlkPtr mb = be->mb;
5061 21385 : InstrPtr q = NULL;
5062 21385 : int tt = ct->type->localtype;
5063 :
5064 21385 : if (val->nr < 0)
5065 0 : goto bailout;
5066 21385 : q = newStmt(mb, batRef, singleRef);
5067 21386 : if (q == NULL)
5068 0 : goto bailout;
5069 21386 : setVarType(mb, getArg(q, 0), newBatType(tt));
5070 21386 : q = pushArgument(mb, q, val->nr);
5071 :
5072 21386 : bool enabled = be->mvc->sa->eb.enabled;
5073 21386 : be->mvc->sa->eb.enabled = false;
5074 21386 : stmt *s = stmt_create(be->mvc->sa, st_single);
5075 21386 : be->mvc->sa->eb.enabled = enabled;
5076 21386 : if(!s) {
5077 0 : freeInstruction(q);
5078 0 : goto bailout;
5079 : }
5080 21386 : s->op1 = val;
5081 21386 : s->op4.typeval = *ct;
5082 21386 : s->nrcols = 1;
5083 :
5084 21386 : s->tname = val->tname;
5085 21386 : s->cname = val->cname;
5086 21386 : s->nr = getDestVar(q);
5087 21386 : s->q = q;
5088 21386 : pushInstruction(mb, q);
5089 21386 : 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 1617539 : stmt_rename(backend *be, sql_exp *exp, stmt *s )
5150 : {
5151 1617539 : int label = exp_get_label(exp);
5152 1617543 : const char *name = exp_name(exp);
5153 1617538 : const char *rname = exp_relname(exp);
5154 1617534 : stmt *o = s;
5155 :
5156 1617534 : if (!name && exp_is_atom(exp))
5157 0 : name = sa_strdup(be->mvc->sa, "single_value");
5158 0 : assert(name);
5159 1617534 : s = stmt_alias(be, s, label, rname, name);
5160 1617517 : if (o->flag & OUTER_ZERO)
5161 521 : s->flag |= OUTER_ZERO;
5162 1617517 : return s;
5163 : }
|