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