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