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 18072 : convertMultiplexMod(const char *mod, const char *op)
31 : {
32 18072 : if (strcmp(op, "=") == 0)
33 0 : return "calc";
34 : return mod;
35 : }
36 :
37 : static const char *
38 328035 : convertMultiplexFcn(const char *op)
39 : {
40 328035 : if (strcmp(op, "=") == 0)
41 52447 : return "==";
42 : return op;
43 : }
44 :
45 : static InstrPtr
46 17996 : multiplex2(MalBlkPtr mb, const char *mod, const char *name, int o1, int o2, int rtype)
47 : {
48 17996 : InstrPtr q = NULL;
49 :
50 17996 : q = newStmt(mb, malRef, multiplexRef);
51 17996 : if (q == NULL)
52 : return NULL;
53 17996 : setVarType(mb, getArg(q, 0), newBatType(rtype));
54 17996 : q = pushStr(mb, q, convertMultiplexMod(mod, name));
55 17996 : q = pushStr(mb, q, convertMultiplexFcn(name));
56 17996 : q = pushArgument(mb, q, o1);
57 17996 : q = pushArgument(mb, q, o2);
58 17996 : pushInstruction(mb, q);
59 17996 : return q;
60 : }
61 :
62 : static InstrPtr
63 51665 : dump_1(MalBlkPtr mb, const char *mod, const char *name, stmt *o1)
64 : {
65 51665 : InstrPtr q = NULL;
66 :
67 51665 : if (o1 == NULL || o1->nr < 0)
68 : return NULL;
69 51665 : q = newStmt(mb, mod, name);
70 51665 : q = pushArgument(mb, q, o1->nr);
71 51665 : pushInstruction(mb, q);
72 51665 : return q;
73 : }
74 :
75 : static InstrPtr
76 181365 : dump_2(MalBlkPtr mb, const char *mod, const char *name, stmt *o1, stmt *o2)
77 : {
78 181365 : InstrPtr q = NULL;
79 :
80 181365 : if (o1 == NULL || o2 == NULL || o1->nr < 0 || o2->nr < 0)
81 : return NULL;
82 181365 : q = newStmt(mb, mod, name);
83 181365 : q = pushArgument(mb, q, o1->nr);
84 181365 : q = pushArgument(mb, q, o2->nr);
85 181365 : pushInstruction(mb, q);
86 181365 : return q;
87 : }
88 :
89 : InstrPtr
90 346 : pushPtr(MalBlkPtr mb, InstrPtr q, ptr val)
91 : {
92 346 : int _t;
93 346 : ValRecord cst;
94 :
95 346 : if (q == NULL || mb->errors)
96 : return q;
97 346 : cst.vtype= TYPE_ptr;
98 346 : cst.val.pval = val;
99 346 : cst.len = 0;
100 346 : _t = defConstant(mb, TYPE_ptr, &cst);
101 346 : if( _t >= 0)
102 346 : return pushArgument(mb, q, _t);
103 : return q;
104 : }
105 :
106 : static InstrPtr
107 2250854 : pushSchema(MalBlkPtr mb, InstrPtr q, sql_table *t)
108 : {
109 2250854 : if (t->s)
110 2250854 : 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 19926 : stmt_atom_string_nil(backend *be)
138 : {
139 19926 : sql_subtype t;
140 :
141 19926 : sql_find_subtype(&t, "varchar", 0, 0);
142 19926 : return stmt_atom(be, atom_string(be->mvc->sa, &t, NULL));
143 : }
144 :
145 : stmt *
146 6075 : stmt_atom_int(backend *be, int i)
147 : {
148 6075 : sql_subtype t;
149 :
150 6075 : sql_find_subtype(&t, "int", 32, 0);
151 6075 : return stmt_atom(be, atom_int(be->mvc->sa, &t, i));
152 : }
153 :
154 : stmt *
155 117703 : stmt_atom_lng(backend *be, lng i)
156 : {
157 117703 : sql_subtype t;
158 :
159 117703 : sql_find_subtype(&t, "bigint", 64, 0);
160 117724 : 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 43132 : stmt_bool(backend *be, int b)
174 : {
175 43132 : sql_subtype t;
176 :
177 43132 : sql_find_subtype(&t, "boolean", 0, 0);
178 :
179 43132 : if (b == bit_nil) {
180 0 : return stmt_atom(be, atom_bool(be->mvc->sa, &t, bit_nil));
181 43132 : } else if (b) {
182 42003 : 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 18353567 : stmt_create(allocator *sa, st_type type)
190 : {
191 18353567 : stmt *s = SA_NEW(sa, stmt);
192 :
193 18353208 : if (!s)
194 : return NULL;
195 18353208 : *s = (stmt) {
196 : .type = type,
197 : };
198 18353208 : return s;
199 : }
200 :
201 : stmt *
202 28178 : stmt_group(backend *be, stmt *s, stmt *grp, stmt *ext, stmt *cnt, int done)
203 : {
204 28178 : MalBlkPtr mb = be->mb;
205 28178 : InstrPtr q = NULL;
206 :
207 28178 : if (s == NULL || s->nr < 0)
208 0 : goto bailout;
209 28178 : if (grp && (grp->nr < 0 || ext->nr < 0 || cnt->nr < 0))
210 0 : goto bailout;
211 :
212 49953 : q = newStmt(mb, groupRef, done ? grp ? subgroupdoneRef : groupdoneRef : grp ? subgroupRef : groupRef);
213 28178 : if (q == NULL)
214 0 : goto bailout;
215 :
216 : /* output variables extent and hist */
217 28178 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
218 28178 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
219 28178 : q = pushArgument(mb, q, s->nr);
220 28178 : if (grp)
221 6403 : q = pushArgument(mb, q, grp->nr);
222 :
223 28178 : bool enabled = be->mvc->sa->eb.enabled;
224 28178 : be->mvc->sa->eb.enabled = false;
225 28178 : stmt *ns = stmt_create(be->mvc->sa, st_group);
226 28178 : be->mvc->sa->eb.enabled = enabled;
227 28178 : if (ns == NULL) {
228 0 : freeInstruction(q);
229 0 : goto bailout;
230 : }
231 :
232 28178 : ns->op1 = s;
233 :
234 28178 : if (grp) {
235 6403 : ns->op2 = grp;
236 6403 : ns->op3 = ext;
237 6403 : ns->op4.stval = cnt;
238 : }
239 28178 : ns->nrcols = s->nrcols;
240 28178 : ns->key = 0;
241 28178 : ns->q = q;
242 28178 : ns->nr = getDestVar(q);
243 28178 : pushInstruction(mb, q);
244 28178 : 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 6 : stmt_none(backend *be)
293 : {
294 6 : 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 2780 : stmt_var(backend *be, sql_alias *sname, const char *varname, sql_subtype *t, int declare, int level)
359 : {
360 2780 : MalBlkPtr mb = be->mb;
361 2780 : InstrPtr q = NULL;
362 2780 : char *buf;
363 :
364 2780 : 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 2349 : } else if (!declare) {
376 1959 : char levelstr[16];
377 :
378 1959 : assert(!sname);
379 1959 : snprintf(levelstr, sizeof(levelstr), "%d", level);
380 1959 : buf = SA_NEW_ARRAY(be->mvc->sa, char, strlen(levelstr) + strlen(varname) + 3);
381 1959 : if (!buf)
382 1 : goto bailout;
383 1959 : stpcpy(stpcpy(stpcpy(stpcpy(buf, "A"), levelstr), "%"), varname); /* mangle variable name */
384 1959 : q = newAssignment(mb);
385 1959 : if (q == NULL)
386 1 : goto bailout;
387 1958 : q = pushArgumentId(mb, q, buf);
388 : } else {
389 390 : int tt = t->type->localtype;
390 390 : char levelstr[16];
391 :
392 390 : assert(!sname);
393 390 : snprintf(levelstr, sizeof(levelstr), "%d", level);
394 390 : buf = SA_NEW_ARRAY(be->mvc->sa, char, strlen(levelstr) + strlen(varname) + 3);
395 390 : if (!buf)
396 0 : goto bailout;
397 390 : stpcpy(stpcpy(stpcpy(stpcpy(buf, "A"), levelstr), "%"), varname); /* mangle variable name */
398 :
399 390 : 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 390 : q->retc++;
407 : }
408 2779 : bool enabled = be->mvc->sa->eb.enabled;
409 2779 : be->mvc->sa->eb.enabled = false;
410 2779 : stmt *s = stmt_create(be->mvc->sa, st_var);
411 2779 : be->mvc->sa->eb.enabled = enabled;
412 2779 : if (s == NULL) {
413 0 : freeInstruction(q);
414 0 : goto bailout;
415 : }
416 :
417 2779 : if (t)
418 2779 : s->subtype = *t;
419 : else
420 0 : s->subtype.type = NULL;
421 2779 : s->flag = declare + (level << 1);
422 2779 : s->key = 1;
423 2779 : s->q = q;
424 2779 : s->nr = getDestVar(q);
425 2779 : pushInstruction(mb, q);
426 2779 : 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 690 : stmt_table(backend *be, stmt *cols, int temp)
506 : {
507 690 : MalBlkPtr mb = be->mb;
508 :
509 690 : if (cols == NULL || cols->nr < 0)
510 0 : goto bailout;
511 :
512 690 : stmt *s = stmt_create(be->mvc->sa, st_table);
513 :
514 690 : if (s == NULL)
515 0 : goto bailout;
516 :
517 690 : 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 690 : s->op1 = cols;
529 690 : s->flag = temp;
530 690 : s->nr = cols->nr;
531 690 : s->nrcols = cols->nrcols;
532 690 : 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 223114 : stmt_temp(backend *be, sql_subtype *t)
542 : {
543 223114 : int tt = t->type->localtype;
544 223114 : MalBlkPtr mb = be->mb;
545 223114 : InstrPtr q = newStmt(mb, batRef, newRef);
546 :
547 224073 : if (q == NULL)
548 0 : goto bailout;
549 224073 : setVarType(mb, getArg(q, 0), newBatType(tt));
550 224073 : q = pushType(mb, q, tt);
551 223936 : bool enabled = be->mvc->sa->eb.enabled;
552 223936 : be->mvc->sa->eb.enabled = false;
553 223936 : stmt *s = stmt_create(be->mvc->sa, st_temp);
554 223846 : be->mvc->sa->eb.enabled = enabled;
555 :
556 223846 : if (s == NULL) {
557 0 : freeInstruction(q);
558 0 : goto bailout;
559 : }
560 223846 : s->subtype = *t;
561 223846 : s->nrcols = 1;
562 223846 : s->q = q;
563 223846 : s->nr = getDestVar(q);
564 223846 : pushInstruction(mb, q);
565 223846 : 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 557 : stmt_blackbox_result(backend *be, InstrPtr q, int retnr, sql_subtype *t)
575 : {
576 557 : if (q == NULL)
577 : return NULL;
578 557 : stmt *s = stmt_create(be->mvc->sa, st_result);
579 557 : if (s == NULL)
580 : return NULL;
581 557 : s->subtype = *t;
582 557 : s->nrcols = 2;
583 557 : s->q = q;
584 557 : s->nr = getArg(q, retnr);
585 557 : s->flag = retnr;
586 557 : return s;
587 : }
588 :
589 :
590 : stmt *
591 205485 : stmt_tid(backend *be, sql_table *t, int partition)
592 : {
593 205485 : int tt = TYPE_oid;
594 205485 : MalBlkPtr mb = be->mb;
595 205485 : InstrPtr q;
596 :
597 205485 : 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 205469 : q = newStmt(mb, sqlRef, tidRef);
612 205629 : if (q == NULL)
613 0 : goto bailout;
614 205629 : setVarType(mb, getArg(q, 0), newBatType(tt));
615 205629 : q = pushArgument(mb, q, be->mvc_var);
616 205628 : q = pushSchema(mb, q, t);
617 205603 : q = pushStr(mb, q, t->base.name);
618 205618 : if (t && isTable(t) && partition) {
619 77060 : sql_trans *tr = be->mvc->session->tr;
620 77060 : sqlstore *store = tr->store;
621 77060 : BUN rows = (BUN) store->storage_api.count_del(tr, t, CNT_RDONLY);
622 77060 : setRowCnt(mb,getArg(q,0),rows);
623 : }
624 :
625 205618 : bool enabled = be->mvc->sa->eb.enabled;
626 205618 : be->mvc->sa->eb.enabled = false;
627 205618 : stmt *s = stmt_create(be->mvc->sa, st_tid);
628 205493 : be->mvc->sa->eb.enabled = enabled;
629 205493 : if (s == NULL) {
630 0 : freeInstruction(q);
631 0 : goto bailout;
632 : }
633 :
634 205493 : s->tname = table_alias(be->mvc->sa, t, NULL);
635 205443 : s->partition = partition;
636 205443 : s->op4.tval = t;
637 205443 : s->nrcols = 1;
638 205443 : s->nr = getDestVar(q);
639 205443 : s->q = q;
640 205443 : pushInstruction(mb, q);
641 205443 : 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 1011951 : find_real_column(backend *be, sql_column *c)
651 : {
652 1011951 : 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 1011951 : stmt_bat(backend *be, sql_column *c, sql_alias *tname, int access, int partition)
665 : {
666 1011951 : int tt = c->type.type->localtype;
667 1011951 : MalBlkPtr mb = be->mb;
668 1011951 : InstrPtr q;
669 :
670 1011951 : c = find_real_column(be, c);
671 :
672 1011974 : if (access == RD_EXT)
673 176 : partition = 0;
674 :
675 : /* for read access tid.project(col) */
676 1011974 : 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 1011951 : q = newStmtArgs(mb, sqlRef, bindRef, 9);
694 1012011 : if (q == NULL)
695 0 : goto bailout;
696 1012011 : if (c->storage_type && access != RD_EXT) {
697 422 : sql_trans *tr = be->mvc->session->tr;
698 422 : sqlstore *store = tr->store;
699 422 : BAT *b = store->storage_api.bind_col(tr, c, QUICK);
700 422 : if (!b) {
701 0 : freeInstruction(q);
702 0 : goto bailout;
703 : }
704 422 : tt = b->ttype;
705 : }
706 1011835 : if (access == RD_UPD_ID) {
707 491739 : q = pushReturn(mb, q, newTmpVariable(mb, newBatType(tt)));
708 : } else {
709 520272 : setVarType(mb, getArg(q, 0), newBatType(tt));
710 : }
711 1012010 : q = pushArgument(mb, q, be->mvc_var);
712 1011992 : q = pushSchema(mb, q, c->t);
713 1011994 : q = pushArgument(mb, q, getStrConstant(mb,c->t->base.name));
714 1011982 : q = pushArgument(mb, q, getStrConstant(mb,c->base.name));
715 1011970 : q = pushArgument(mb, q, getIntConstant(mb,access));
716 :
717 1011936 : if (access == RD_UPD_ID) {
718 491715 : setVarType(mb, getArg(q, 1), newBatType(tt));
719 : }
720 1011936 : if (partition) {
721 560923 : sql_trans *tr = be->mvc->session->tr;
722 560923 : sqlstore *store = tr->store;
723 :
724 560923 : if (c && isTable(c->t)) {
725 560915 : BUN rows = (BUN) store->storage_api.count_del(tr, c->t, CNT_RDONLY);
726 561008 : setRowCnt(mb,getArg(q,0),rows);
727 : }
728 : }
729 :
730 1012029 : bool enabled = be->mvc->sa->eb.enabled;
731 1012029 : be->mvc->sa->eb.enabled = false;
732 1012029 : stmt *s = stmt_create(be->mvc->sa, st_bat);
733 1012008 : be->mvc->sa->eb.enabled = enabled;
734 1012008 : if (s == NULL) {
735 0 : freeInstruction(q);
736 0 : goto bailout;
737 : }
738 :
739 1012008 : s->partition = partition;
740 1012008 : s->op4.cval = c;
741 1012008 : s->nrcols = 1;
742 1012008 : s->flag = access;
743 1012008 : s->nr = getDestVar(q);
744 1012008 : s->q = q;
745 1012008 : s->tname = tname;
746 1012008 : s->cname = c->base.name;
747 1012008 : pushInstruction(mb, q);
748 1012008 : 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 706398 : stmt_append_col(backend *be, sql_column *c, stmt *offset, stmt *b, int *mvc_var_update, int fake)
819 : {
820 706398 : MalBlkPtr mb = be->mb;
821 706398 : InstrPtr q = NULL;
822 :
823 706398 : if (b == NULL || b->nr < 0)
824 0 : goto bailout;
825 :
826 706398 : 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 706375 : } else if (!fake) { /* fake append */
845 706375 : if (offset == NULL || offset->nr < 0)
846 0 : goto bailout;
847 706375 : q = newStmt(mb, sqlRef, appendRef);
848 706921 : if (q == NULL)
849 0 : goto bailout;
850 706921 : q = pushArgument(mb, q, be->mvc_var);
851 706918 : int tmpvar = newTmpVariable(mb, TYPE_int);
852 706911 : getArg(q, 0) = tmpvar;
853 706911 : if (mvc_var_update != NULL)
854 706911 : *mvc_var_update = tmpvar;
855 706911 : q = pushSchema(mb, q, c->t);
856 706903 : q = pushStr(mb, q, c->t->base.name);
857 706923 : if (c->column_type != column_plain)
858 185 : q = pushInt(mb, q, c->base.id);
859 : else
860 706738 : q = pushStr(mb, q, c->base.name);
861 706783 : q = pushArgument(mb, q, offset->nr);
862 : /* also the offsets */
863 706811 : assert(offset->q->retc == 2);
864 706811 : q = pushArgument(mb, q, getArg(offset->q, 1));
865 706821 : q = pushArgument(mb, q, b->nr);
866 706814 : if (mvc_var_update != NULL)
867 706814 : *mvc_var_update = getDestVar(q);
868 : } else {
869 : return b;
870 : }
871 706837 : bool enabled = be->mvc->sa->eb.enabled;
872 706837 : be->mvc->sa->eb.enabled = false;
873 706837 : stmt *s = stmt_create(be->mvc->sa, st_append_col);
874 706650 : be->mvc->sa->eb.enabled = enabled;
875 :
876 706650 : if (s == NULL) {
877 0 : freeInstruction(q);
878 0 : goto bailout;
879 : }
880 706650 : s->op1 = b;
881 706650 : s->op2 = offset;
882 706650 : s->op4.cval = c;
883 706650 : s->q = q;
884 706650 : s->nr = getDestVar(q);
885 706650 : pushInstruction(mb, q);
886 706650 : 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 3259 : stmt_update_col(backend *be, sql_column *c, stmt *tids, stmt *upd)
943 : {
944 3259 : MalBlkPtr mb = be->mb;
945 3259 : InstrPtr q = NULL;
946 :
947 3259 : if (tids == NULL || upd == NULL || tids->nr < 0 || upd->nr < 0)
948 0 : goto bailout;
949 :
950 3260 : 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 3258 : q = newStmt(mb, sqlRef, updateRef);
961 3258 : if (q == NULL)
962 0 : goto bailout;
963 3258 : q = pushArgument(mb, q, be->mvc_var);
964 3258 : getArg(q, 0) = be->mvc_var = newTmpVariable(mb, TYPE_int);
965 3258 : q = pushSchema(mb, q, c->t);
966 3258 : q = pushStr(mb, q, c->t->base.name);
967 3258 : q = pushStr(mb, q, c->base.name);
968 3258 : q = pushArgument(mb, q, tids->nr);
969 3258 : q = pushArgument(mb, q, upd->nr);
970 3258 : be->mvc_var = getDestVar(q);
971 : }
972 3259 : bool enabled = be->mvc->sa->eb.enabled;
973 3259 : be->mvc->sa->eb.enabled = false;
974 3259 : stmt *s = stmt_create(be->mvc->sa, st_update_col);
975 3259 : be->mvc->sa->eb.enabled = enabled;
976 :
977 3259 : if (s == NULL) {
978 0 : freeInstruction(q);
979 0 : goto bailout;
980 : }
981 3259 : s->op1 = tids;
982 3259 : s->op2 = upd;
983 3259 : s->op4.cval = c;
984 3259 : s->q = q;
985 3259 : s->nr = getDestVar(q);
986 3259 : pushInstruction(mb, q);
987 3259 : 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 127617 : stmt_const(backend *be, stmt *s, stmt *val)
1091 : {
1092 127617 : InstrPtr q = NULL;
1093 127617 : MalBlkPtr mb = be->mb;
1094 :
1095 127617 : if (s == NULL)
1096 0 : goto bailout;
1097 127617 : if (val)
1098 127617 : q = dump_2(mb, algebraRef, projectRef, s, val);
1099 : else
1100 0 : q = dump_1(mb, algebraRef, projectRef, s);
1101 127617 : if (q) {
1102 127617 : stmt *ns = stmt_create(be->mvc->sa, st_const);
1103 127617 : if (ns == NULL) {
1104 0 : goto bailout;
1105 : }
1106 :
1107 127617 : ns->op1 = s;
1108 127617 : ns->op2 = val;
1109 127617 : ns->nrcols = s->nrcols;
1110 127617 : ns->key = s->key;
1111 127617 : ns->aggr = s->aggr;
1112 127617 : ns->q = q;
1113 127617 : ns->nr = getDestVar(q);
1114 127617 : ns->tname = val->tname;
1115 127617 : ns->cname = val->cname;
1116 127617 : 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 51665 : stmt_mirror(backend *be, stmt *s)
1158 : {
1159 51665 : MalBlkPtr mb = be->mb;
1160 :
1161 51665 : if (s == NULL)
1162 0 : goto bailout;
1163 :
1164 51665 : InstrPtr q = dump_1(mb, batRef, mirrorRef, s);
1165 :
1166 51665 : if (q) {
1167 51665 : stmt *ns = stmt_create(be->mvc->sa, st_mirror);
1168 51665 : if (ns == NULL) {
1169 0 : goto bailout;
1170 : }
1171 :
1172 51665 : ns->op1 = s;
1173 51665 : ns->nrcols = 2;
1174 51665 : ns->key = s->key;
1175 51665 : ns->aggr = s->aggr;
1176 51665 : ns->q = q;
1177 51665 : ns->nr = getDestVar(q);
1178 51665 : 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 330164 : stmt_result(backend *be, stmt *s, int nr)
1189 : {
1190 330164 : stmt *ns;
1191 :
1192 330164 : if (s == NULL)
1193 : return NULL;
1194 :
1195 330164 : if (s->type == st_join && s->flag == cmp_joined) {
1196 5562 : if (nr)
1197 2324 : return s->op2;
1198 3238 : return s->op1;
1199 : }
1200 :
1201 324602 : if (s->op1->nr < 0)
1202 : return NULL;
1203 :
1204 324602 : ns = stmt_create(be->mvc->sa, st_result);
1205 324602 : if(!ns) {
1206 : return NULL;
1207 : }
1208 324602 : if (s->op1->type == st_join && s->op1->flag == cmp_joined) {
1209 0 : assert(0);
1210 324602 : } else if (nr) {
1211 186292 : int v = getArg(s->q, nr);
1212 :
1213 186292 : assert(s->q->retc > nr);
1214 186292 : ns->nr = v;
1215 : } else {
1216 138310 : ns->nr = s->nr;
1217 : }
1218 324602 : ns->op1 = s;
1219 324602 : if (!nr && (s->type == st_order || s->type == st_reorder))
1220 26283 : ns->subtype = *tail_type(s->op1);
1221 186292 : else if (nr && ((s->type == st_join && s->flag == MARKJOIN) || (s->type == st_uselect2 && s->flag == MARKJOIN)))
1222 2986 : ns->subtype = *sql_bind_localtype("bit");
1223 : else
1224 295333 : ns->subtype = *sql_bind_localtype("oid");
1225 324602 : ns->flag = nr;
1226 324602 : ns->nrcols = s->nrcols;
1227 324602 : ns->key = s->key;
1228 324602 : ns->aggr = s->aggr;
1229 324602 : return ns;
1230 : }
1231 :
1232 :
1233 : /* limit maybe atom nil */
1234 : stmt *
1235 17659 : 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 17659 : MalBlkPtr mb = be->mb;
1238 17659 : InstrPtr q = NULL;
1239 17659 : int l, g, c;
1240 :
1241 17659 : if (col == NULL || offset == NULL || limit == NULL || col->nr < 0 || offset->nr < 0 || limit->nr < 0)
1242 0 : goto bailout;
1243 17659 : if (piv && (piv->nr < 0 || (gid && gid->nr < 0)))
1244 0 : goto bailout;
1245 :
1246 17659 : c = (col) ? col->nr : 0;
1247 17659 : g = (gid) ? gid->nr : 0;
1248 :
1249 : /* first insert single value into a bat */
1250 17659 : 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 17659 : 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 17067 : int len;
1333 :
1334 17067 : q = newStmt(mb, calcRef, plusRef);
1335 17088 : if (q == NULL)
1336 0 : goto bailout;
1337 17088 : q = pushArgument(mb, q, offset->nr);
1338 17088 : q = pushArgument(mb, q, limit->nr);
1339 17088 : len = getDestVar(q);
1340 17088 : pushInstruction(mb, q);
1341 :
1342 : /* since both arguments of algebra.subslice are
1343 : inclusive correct the LIMIT value by
1344 : subtracting 1 */
1345 17087 : q = newStmt(mb, calcRef, minusRef);
1346 17089 : if (q == NULL)
1347 0 : goto bailout;
1348 17089 : q = pushArgument(mb, q, len);
1349 17089 : q = pushInt(mb, q, 1);
1350 17088 : len = getDestVar(q);
1351 17088 : pushInstruction(mb, q);
1352 :
1353 17088 : q = newStmt(mb, algebraRef, subsliceRef);
1354 17089 : if (q == NULL)
1355 0 : goto bailout;
1356 17089 : q = pushArgument(mb, q, c);
1357 17089 : q = pushArgument(mb, q, offset->nr);
1358 17089 : q = pushArgument(mb, q, len);
1359 17087 : l = getDestVar(q);
1360 17087 : pushInstruction(mb, q);
1361 : }
1362 : /* retrieve the single values again */
1363 17679 : 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 35048 : stmt *ns = stmt_create(be->mvc->sa, piv?st_limit2:st_limit);
1374 17679 : if (ns == NULL) {
1375 0 : goto bailout;
1376 : }
1377 :
1378 17679 : ns->op1 = col;
1379 17679 : ns->op2 = offset;
1380 17679 : ns->op3 = limit;
1381 17679 : ns->nrcols = col->nrcols;
1382 17679 : ns->key = col->key;
1383 17679 : ns->aggr = col->aggr;
1384 17679 : ns->q = q;
1385 17679 : ns->nr = l;
1386 17679 : 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 12984 : stmt_order(backend *be, stmt *s, int direction, int nullslast)
1449 : {
1450 12984 : MalBlkPtr mb = be->mb;
1451 12984 : InstrPtr q = NULL;
1452 :
1453 12984 : if (s == NULL || s->nr < 0)
1454 0 : goto bailout;
1455 12984 : q = newStmt(mb, algebraRef, sortRef);
1456 12984 : if (q == NULL)
1457 0 : goto bailout;
1458 : /* both ordered result and oid's order en subgroups */
1459 12984 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
1460 12984 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
1461 12984 : q = pushArgument(mb, q, s->nr);
1462 12984 : q = pushBit(mb, q, !direction);
1463 12984 : q = pushBit(mb, q, nullslast);
1464 12984 : q = pushBit(mb, q, FALSE);
1465 :
1466 12984 : bool enabled = be->mvc->sa->eb.enabled;
1467 12984 : be->mvc->sa->eb.enabled = false;
1468 12984 : stmt *ns = stmt_create(be->mvc->sa, st_order);
1469 12984 : be->mvc->sa->eb.enabled = enabled;
1470 12984 : if (ns == NULL) {
1471 0 : freeInstruction(q);
1472 0 : goto bailout;
1473 : }
1474 :
1475 12984 : ns->op1 = s;
1476 12984 : ns->flag = direction;
1477 12984 : ns->nrcols = s->nrcols;
1478 12984 : ns->key = s->key;
1479 12984 : ns->aggr = s->aggr;
1480 12984 : ns->q = q;
1481 12984 : ns->nr = getDestVar(q);
1482 12984 : pushInstruction(mb, q);
1483 12984 : 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 13824 : stmt_reorder(backend *be, stmt *s, int direction, int nullslast, stmt *orderby_ids, stmt *orderby_grp)
1493 : {
1494 13824 : MalBlkPtr mb = be->mb;
1495 13824 : InstrPtr q = NULL;
1496 :
1497 13824 : 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 13824 : q = newStmtArgs(mb, algebraRef, sortRef, 9);
1500 13824 : if (q == NULL)
1501 0 : goto bailout;
1502 : /* both ordered result and oid's order en subgroups */
1503 13824 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
1504 13824 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
1505 13824 : q = pushArgument(mb, q, s->nr);
1506 13824 : q = pushArgument(mb, q, orderby_ids->nr);
1507 13824 : q = pushArgument(mb, q, orderby_grp->nr);
1508 13824 : q = pushBit(mb, q, !direction);
1509 13824 : q = pushBit(mb, q, nullslast);
1510 13824 : q = pushBit(mb, q, FALSE);
1511 :
1512 13824 : bool enabled = be->mvc->sa->eb.enabled;
1513 13824 : be->mvc->sa->eb.enabled = false;
1514 13824 : stmt *ns = stmt_create(be->mvc->sa, st_reorder);
1515 13824 : be->mvc->sa->eb.enabled = enabled;
1516 13824 : if (ns == NULL) {
1517 0 : freeInstruction(q);
1518 0 : goto bailout;
1519 : }
1520 :
1521 13824 : ns->op1 = s;
1522 13824 : ns->op2 = orderby_ids;
1523 13824 : ns->op3 = orderby_grp;
1524 13824 : ns->flag = direction;
1525 13824 : ns->nrcols = s->nrcols;
1526 13824 : ns->key = s->key;
1527 13824 : ns->aggr = s->aggr;
1528 13824 : ns->nr = getDestVar(q);
1529 13824 : ns->q = q;
1530 13824 : pushInstruction(mb, q);
1531 13824 : 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 3539400 : stmt_atom(backend *be, atom *a)
1541 : {
1542 : /* TODO handle tuples of values for composite types */
1543 3539400 : MalBlkPtr mb = be->mb;
1544 :
1545 3539400 : if (a == NULL)
1546 0 : goto bailout;
1547 :
1548 3539400 : InstrPtr q = EC_TEMP_FRAC(atom_type(a)->type->eclass) ? newStmt(mb, calcRef, atom_type(a)->type->d.impl) : newAssignment(mb);
1549 :
1550 3540159 : if (q == NULL)
1551 0 : goto bailout;
1552 3540159 : if (atom_null(a)) {
1553 158106 : q = pushNil(mb, q, atom_type(a)->type->localtype);
1554 : } else {
1555 3382053 : int k;
1556 3382053 : if ((k = constantAtom(be, mb, a)) == -1) {
1557 0 : freeInstruction(q);
1558 0 : goto bailout;
1559 : }
1560 3381587 : q = pushArgument(mb, q, k);
1561 : }
1562 : /* digits of the result timestamp/daytime */
1563 3539735 : if (EC_TEMP_FRAC(atom_type(a)->type->eclass))
1564 47397 : q = pushInt(mb, q, atom_type(a)->digits);
1565 3540103 : bool enabled = be->mvc->sa->eb.enabled;
1566 3540103 : be->mvc->sa->eb.enabled = false;
1567 3540103 : stmt *s = stmt_create(be->mvc->sa, st_atom);
1568 3539185 : be->mvc->sa->eb.enabled = enabled;
1569 3539185 : if (s == NULL) {
1570 0 : freeInstruction(q);
1571 0 : goto bailout;
1572 : }
1573 :
1574 3539185 : s->op4.aval = a;
1575 3539185 : s->key = 1; /* values are also unique */
1576 3539185 : s->q = q;
1577 3539185 : s->nr = getDestVar(q);
1578 3539185 : pushInstruction(mb, q);
1579 3539185 : 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 4117 : stmt_genselect(backend *be, stmt *lops, stmt *rops, sql_subfunc *f, stmt *sub, int anti)
1589 : {
1590 4117 : MalBlkPtr mb = be->mb;
1591 4117 : InstrPtr q = NULL;
1592 4117 : const char *mod, *op;
1593 4117 : node *n;
1594 4117 : int k;
1595 :
1596 4117 : if (lops == NULL || rops == NULL)
1597 0 : goto bailout;
1598 :
1599 4117 : if (backend_create_subfunc(be, f, NULL) < 0)
1600 0 : goto bailout;
1601 4117 : op = backend_function_imp(be, f->func);
1602 4117 : mod = sql_func_mod(f->func);
1603 :
1604 4117 : 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 4062 : node *n;
1644 :
1645 4062 : op = sa_strconcat(be->mvc->sa, op, selectRef);
1646 4062 : q = newStmtArgs(mb, mod, convertMultiplexFcn(op), 9);
1647 4062 : 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 4062 : 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 4062 : if (f->func->lang == FUNC_LANG_R || f->func->lang >= FUNC_LANG_PY)
1655 0 : q = pushStr(mb, q, f->func->query);
1656 :
1657 8124 : for (n = lops->op4.lval->h; n; n = n->next) {
1658 4062 : stmt *op = n->data;
1659 :
1660 4062 : q = pushArgument(mb, q, op->nr);
1661 : }
1662 : /* candidate lists */
1663 4062 : if (sub)
1664 3994 : q = pushArgument(mb, q, sub->nr);
1665 : else
1666 68 : q = pushNilBat(mb, q);
1667 :
1668 15995 : for (n = rops->op4.lval->h; n; n = n->next) {
1669 11933 : stmt *op = n->data;
1670 :
1671 11933 : q = pushArgument(mb, q, op->nr);
1672 : }
1673 :
1674 4062 : q = pushBit(mb, q, anti);
1675 : }
1676 :
1677 4117 : bool enabled = be->mvc->sa->eb.enabled;
1678 4117 : be->mvc->sa->eb.enabled = false;
1679 4117 : stmt *s = stmt_create(be->mvc->sa, st_uselect);
1680 4117 : be->mvc->sa->eb.enabled = enabled;
1681 4117 : if (s == NULL) {
1682 0 : freeInstruction(q);
1683 0 : goto bailout;
1684 : }
1685 :
1686 4117 : s->op1 = lops;
1687 4117 : s->op2 = rops;
1688 4117 : s->op3 = sub;
1689 4117 : s->key = lops->nrcols == 0 && rops->nrcols == 0;
1690 4117 : s->flag = cmp_filter;
1691 4117 : s->nrcols = lops->nrcols;
1692 4117 : s->nr = getDestVar(q);
1693 4117 : s->q = q;
1694 4117 : s->cand = sub;
1695 4117 : pushInstruction(mb, q);
1696 4117 : 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 204568 : stmt_uselect(backend *be, stmt *op1, stmt *op2, comp_type cmptype, stmt *sub, int anti, int is_semantics)
1706 : {
1707 204568 : MalBlkPtr mb = be->mb;
1708 204568 : InstrPtr q = NULL;
1709 204568 : int l, r;
1710 204568 : stmt *sel = sub;
1711 :
1712 204568 : if (op1 == NULL || op2 == NULL || op1->nr < 0 || op2->nr < 0 || (sub && sub->nr < 0))
1713 0 : goto bailout;
1714 204568 : l = op1->nr;
1715 204568 : r = op2->nr;
1716 :
1717 204568 : 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 204568 : if (op2->nrcols >= 1) {
1727 17996 : bit need_not = FALSE;
1728 17996 : const char *mod = calcRef;
1729 17996 : const char *op = "=";
1730 17996 : int k;
1731 :
1732 17996 : switch (cmptype) {
1733 : case cmp_equal:
1734 : op = "=";
1735 : break;
1736 : case cmp_notequal:
1737 17996 : 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 28405 : if ((q = multiplex2(mb, mod, convertMultiplexFcn(op), l, r, TYPE_bit)) == NULL)
1756 0 : goto bailout;
1757 17996 : 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 17996 : if (is_semantics)
1770 2998 : q = pushBit(mb, q, TRUE);
1771 17996 : k = getDestVar(q);
1772 :
1773 17996 : q = newStmtArgs(mb, algebraRef, selectRef, 9);
1774 17996 : if (q == NULL)
1775 0 : goto bailout;
1776 17996 : q = pushArgument(mb, q, k);
1777 17996 : if (sub)
1778 4362 : q = pushArgument(mb, q, sub->nr);
1779 17996 : q = pushBit(mb, q, !need_not);
1780 17996 : q = pushBit(mb, q, !need_not);
1781 17996 : q = pushBit(mb, q, TRUE);
1782 17996 : q = pushBit(mb, q, TRUE);
1783 17996 : q = pushBit(mb, q, anti);
1784 17996 : k = getDestVar(q);
1785 : } else {
1786 186572 : assert (cmptype != cmp_filter);
1787 186572 : q = newStmt(mb, algebraRef, thetaselectRef);
1788 186586 : if (q == NULL)
1789 0 : goto bailout;
1790 186586 : q = pushArgument(mb, q, l);
1791 186584 : if (sub && !op1->cand) {
1792 112690 : q = pushArgument(mb, q, sub->nr);
1793 : } else {
1794 2631 : assert(!sub || op1->cand == sub);
1795 73894 : q = pushNilBat(mb, q);
1796 73894 : sub = NULL;
1797 : }
1798 186586 : q = pushArgument(mb, q, r);
1799 186573 : switch (cmptype) {
1800 168374 : case cmp_equal:
1801 168374 : if (is_semantics)
1802 35060 : q = pushStr(mb, q, anti?"ne":"eq");
1803 : else
1804 296612 : q = pushStr(mb, q, anti?"!=":"==");
1805 : break;
1806 15124 : case cmp_notequal:
1807 15124 : if (is_semantics)
1808 153 : q = pushStr(mb, q, anti?"eq":"ne");
1809 : else
1810 30090 : 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 204578 : bool enabled = be->mvc->sa->eb.enabled;
1834 204578 : be->mvc->sa->eb.enabled = false;
1835 204578 : stmt *s = stmt_create(be->mvc->sa, st_uselect);
1836 204574 : be->mvc->sa->eb.enabled = enabled;
1837 204574 : if (s == NULL) {
1838 0 : freeInstruction(q);
1839 0 : goto bailout;
1840 : }
1841 :
1842 204574 : s->op1 = op1;
1843 204574 : s->op2 = op2;
1844 204574 : s->op3 = sub;
1845 204574 : s->flag = cmptype;
1846 204574 : s->key = op1->nrcols == 0 && op2->nrcols == 0;
1847 204574 : s->nrcols = op1->nrcols;
1848 204574 : s->nr = getDestVar(q);
1849 204574 : s->q = q;
1850 204574 : s->cand = sub;
1851 204574 : pushInstruction(mb, q);
1852 204580 : 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 2541 : stmt_markjoin(backend *be, stmt *l, stmt *r, bool final)
2154 : {
2155 2541 : MalBlkPtr mb = be->mb;
2156 2541 : InstrPtr q;
2157 :
2158 2541 : q = newStmtArgs(mb, algebraRef, markjoinRef, 8);
2159 2541 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
2160 2541 : if (!final)
2161 5 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
2162 2541 : q = pushArgument(mb, q, l->nr); /* left ids */
2163 2541 : q = pushArgument(mb, q, r->nr); /* mark info mask */
2164 2541 : q = pushNilBat(mb, q);
2165 2541 : q = pushNilBat(mb, q);
2166 2541 : q = pushNil(mb, q, TYPE_lng);
2167 2541 : pushInstruction(mb, q);
2168 :
2169 2541 : if (!q)
2170 : return NULL;
2171 2541 : stmt *s = stmt_create(be->mvc->sa, st_join);
2172 2541 : if (s == NULL) {
2173 0 : freeInstruction(q);
2174 0 : return NULL;
2175 : }
2176 :
2177 2541 : s->op1 = l;
2178 2541 : s->op2 = r;
2179 2541 : s->flag = MARKJOIN;
2180 2541 : s->key = 0;
2181 2541 : s->nrcols = l->nrcols;
2182 2541 : s->nr = getDestVar(q);
2183 2541 : s->q = q;
2184 2541 : 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 51348 : stmt_tunion(backend *be, stmt *op1, stmt *op2)
2219 : {
2220 51348 : InstrPtr q = NULL;
2221 51348 : MalBlkPtr mb = be->mb;
2222 :
2223 51348 : q = dump_2(mb, batRef, mergecandRef, op1, op2);
2224 51348 : if (q) {
2225 51348 : stmt *s = stmt_create(be->mvc->sa, st_tunion);
2226 51348 : if (s == NULL) {
2227 : return NULL;
2228 : }
2229 :
2230 51348 : s->op1 = op1;
2231 51348 : s->op2 = op2;
2232 51348 : s->nrcols = op1->nrcols;
2233 51348 : s->key = op1->key;
2234 51348 : s->aggr = op1->aggr;
2235 51348 : s->nr = getDestVar(q);
2236 51348 : s->q = q;
2237 51348 : 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 44989 : stmt_tdiff(backend *be, stmt *op1, stmt *op2, stmt *lcand)
2247 : {
2248 44989 : InstrPtr q = NULL;
2249 44989 : MalBlkPtr mb = be->mb;
2250 :
2251 44989 : if (op1 == NULL || op2 == NULL || op1->nr < 0 || op2->nr < 0)
2252 0 : goto bailout;
2253 44989 : q = newStmt(mb, algebraRef, differenceRef);
2254 44989 : if (q == NULL)
2255 0 : goto bailout;
2256 44989 : q = pushArgument(mb, q, op1->nr); /* left */
2257 44989 : q = pushArgument(mb, q, op2->nr); /* right */
2258 44989 : if (lcand)
2259 0 : q = pushArgument(mb, q, lcand->nr); /* left */
2260 : else
2261 44989 : q = pushNilBat(mb, q); /* left candidate */
2262 44989 : q = pushNilBat(mb, q); /* right candidate */
2263 44989 : q = pushBit(mb, q, FALSE); /* nil matches */
2264 44989 : q = pushBit(mb, q, FALSE); /* do not clear nils */
2265 44989 : q = pushNil(mb, q, TYPE_lng); /* estimate */
2266 :
2267 44989 : bool enabled = be->mvc->sa->eb.enabled;
2268 44989 : be->mvc->sa->eb.enabled = false;
2269 44989 : stmt *s = stmt_create(be->mvc->sa, st_tdiff);
2270 44989 : be->mvc->sa->eb.enabled = enabled;
2271 44989 : if (s == NULL) {
2272 0 : freeInstruction(q);
2273 0 : goto bailout;
2274 : }
2275 :
2276 44989 : s->op1 = op1;
2277 44989 : s->op2 = op2;
2278 44989 : s->nrcols = op1->nrcols;
2279 44989 : s->key = op1->key;
2280 44989 : s->aggr = op1->aggr;
2281 44989 : s->nr = getDestVar(q);
2282 44989 : s->q = q;
2283 44989 : pushInstruction(mb, q);
2284 44989 : 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 2115 : stmt_tinter(backend *be, stmt *op1, stmt *op2, bool single)
2341 : {
2342 2115 : InstrPtr q = NULL;
2343 2115 : MalBlkPtr mb = be->mb;
2344 :
2345 2115 : if (op1 == NULL || op2 == NULL || op1->nr < 0 || op2->nr < 0)
2346 0 : goto bailout;
2347 2115 : q = newStmt(mb, algebraRef, intersectRef);
2348 2115 : if (q == NULL)
2349 0 : goto bailout;
2350 2115 : q = pushArgument(mb, q, op1->nr); /* left */
2351 2115 : q = pushArgument(mb, q, op2->nr); /* right */
2352 2115 : q = pushNilBat(mb, q); /* left candidate */
2353 2115 : q = pushNilBat(mb, q); /* right candidate */
2354 2115 : q = pushBit(mb, q, FALSE); /* nil matches */
2355 2115 : q = pushBit(mb, q, single?TRUE:FALSE); /* max_one */
2356 2115 : q = pushNil(mb, q, TYPE_lng); /* estimate */
2357 :
2358 2115 : bool enabled = be->mvc->sa->eb.enabled;
2359 2115 : be->mvc->sa->eb.enabled = false;
2360 2115 : stmt *s = stmt_create(be->mvc->sa, st_tinter);
2361 2115 : be->mvc->sa->eb.enabled = enabled;
2362 2115 : if (s == NULL) {
2363 0 : freeInstruction(q);
2364 0 : goto bailout;
2365 : }
2366 :
2367 2115 : s->op1 = op1;
2368 2115 : s->op2 = op2;
2369 2115 : s->nrcols = op1->nrcols;
2370 2115 : s->key = op1->key;
2371 2115 : s->aggr = op1->aggr;
2372 2115 : s->nr = getDestVar(q);
2373 2115 : s->q = q;
2374 2115 : pushInstruction(mb, q);
2375 2115 : 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 95223 : 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 95223 : MalBlkPtr mb = be->mb;
2387 95223 : InstrPtr q = NULL;
2388 95223 : const char *sjt = inner?joinRef:outerjoinRef;
2389 :
2390 95223 : (void)anti;
2391 95223 : (void)inner;
2392 :
2393 95223 : if (need_left) {
2394 653 : cmptype = cmp_equal;
2395 653 : sjt = leftjoinRef;
2396 : }
2397 95223 : if (op1 == NULL || op2 == NULL || op1->nr < 0 || op2->nr < 0)
2398 0 : goto bailout;
2399 :
2400 95223 : assert (!single || cmptype == cmp_all);
2401 :
2402 95223 : switch (cmptype) {
2403 77295 : case cmp_equal:
2404 77295 : q = newStmtArgs(mb, algebraRef, sjt, 9);
2405 77295 : if (q == NULL)
2406 0 : goto bailout;
2407 77295 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
2408 77295 : q = pushArgument(mb, q, op1->nr);
2409 77295 : q = pushArgument(mb, q, op2->nr);
2410 77295 : if (!lcand)
2411 76192 : q = pushNilBat(mb, q);
2412 : else
2413 1103 : q = pushArgument(mb, q, lcand->nr);
2414 77295 : if (!rcand)
2415 77295 : q = pushNilBat(mb, q);
2416 : else
2417 0 : q = pushArgument(mb, q, rcand->nr);
2418 77295 : q = pushBit(mb, q, is_semantics?TRUE:FALSE);
2419 77295 : if (!inner)
2420 76 : q = pushBit(mb, q, FALSE); /* not match_one */
2421 77295 : q = pushNil(mb, q, TYPE_lng);
2422 77295 : pushInstruction(mb, q);
2423 77295 : 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 12075 : case cmp_all: /* aka cross table */
2480 12510 : q = newStmt(mb, algebraRef, inner?crossRef:outercrossRef);
2481 12075 : if (q == NULL)
2482 0 : goto bailout;
2483 12075 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
2484 12075 : q = pushArgument(mb, q, op1->nr);
2485 12075 : q = pushArgument(mb, q, op2->nr);
2486 12075 : if (!inner) {
2487 435 : q = pushNilBat(mb, q);
2488 435 : q = pushNilBat(mb, q);
2489 : }
2490 12075 : q = pushBit(mb, q, single?TRUE:FALSE); /* max_one */
2491 12075 : assert(!lcand && !rcand);
2492 12075 : pushInstruction(mb, q);
2493 12075 : break;
2494 3238 : case cmp_joined:
2495 3238 : q = op1->q;
2496 3238 : if (q == NULL)
2497 0 : goto bailout;
2498 : break;
2499 0 : default:
2500 0 : TRC_ERROR(SQL_EXECUTION, "Impossible action\n");
2501 : }
2502 :
2503 95223 : stmt *s = stmt_create(be->mvc->sa, st_join);
2504 95223 : if (s == NULL) {
2505 0 : goto bailout;
2506 : }
2507 :
2508 95223 : s->op1 = op1;
2509 95223 : s->op2 = op2;
2510 95223 : s->flag = cmptype;
2511 95223 : s->key = 0;
2512 95223 : s->nrcols = 2;
2513 95223 : s->nr = getDestVar(q);
2514 95223 : s->q = q;
2515 95223 : 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 90974 : stmt_join(backend *be, stmt *l, stmt *r, int anti, comp_type cmptype, int need_left, int is_semantics, bool single)
2525 : {
2526 90974 : return stmt_join_cand(be, l, r, NULL, NULL, anti, cmptype, need_left, is_semantics, single, true);
2527 : }
2528 :
2529 : stmt *
2530 1469 : stmt_semijoin(backend *be, stmt *op1, stmt *op2, stmt *lcand, stmt *rcand, int is_semantics, bool single)
2531 : {
2532 1469 : MalBlkPtr mb = be->mb;
2533 1469 : InstrPtr q = NULL;
2534 :
2535 1469 : if (op1 == NULL || op2 == NULL || op1->nr < 0 || op2->nr < 0)
2536 0 : goto bailout;
2537 :
2538 1469 : if (single) {
2539 284 : q = newStmtArgs(mb, algebraRef, semijoinRef, 9);
2540 284 : q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
2541 : } else
2542 1185 : q = newStmt(mb, algebraRef, intersectRef);
2543 1469 : if (q == NULL)
2544 0 : goto bailout;
2545 1469 : q = pushArgument(mb, q, op1->nr);
2546 1469 : q = pushArgument(mb, q, op2->nr);
2547 1469 : if (lcand)
2548 1182 : q = pushArgument(mb, q, lcand->nr);
2549 : else
2550 287 : q = pushNilBat(mb, q);
2551 1469 : if (rcand)
2552 0 : q = pushArgument(mb, q, rcand->nr);
2553 : else
2554 1469 : q = pushNilBat(mb, q);
2555 1469 : q = pushBit(mb, q, is_semantics?TRUE:FALSE);
2556 1469 : q = pushBit(mb, q, single?TRUE:FALSE); /* max_one */
2557 1469 : q = pushNil(mb, q, TYPE_lng);
2558 :
2559 1469 : bool enabled = be->mvc->sa->eb.enabled;
2560 1469 : be->mvc->sa->eb.enabled = false;
2561 1469 : stmt *s = stmt_create(be->mvc->sa, st_semijoin);
2562 1469 : be->mvc->sa->eb.enabled = enabled;
2563 1469 : if (s == NULL) {
2564 0 : freeInstruction(q);
2565 0 : goto bailout;
2566 : }
2567 :
2568 1469 : s->op1 = op1;
2569 1469 : s->op2 = op2;
2570 1469 : s->flag = cmp_equal;
2571 1469 : s->key = 0;
2572 1469 : s->nrcols = 1;
2573 1469 : if (single)
2574 284 : s->nrcols = 2;
2575 1469 : s->nr = getDestVar(q);
2576 1469 : s->q = q;
2577 1469 : pushInstruction(mb, q);
2578 1469 : 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 3565501 : stmt_project_join(backend *be, stmt *op1, stmt *op2, bool delta)
2588 : {
2589 3565501 : MalBlkPtr mb = be->mb;
2590 3565501 : InstrPtr q = NULL;
2591 :
2592 3565501 : if (op1 == NULL || op2 == NULL || op1->nr < 0 || op2->nr < 0)
2593 : return NULL;
2594 : /* delta bat */
2595 3565501 : if (delta) {
2596 494582 : int uval = getArg(op2->q, 1);
2597 :
2598 494582 : q = newStmt(mb, sqlRef, deltaRef);
2599 494611 : q = pushArgument(mb, q, op1->nr);
2600 494611 : q = pushArgument(mb, q, op2->nr);
2601 494611 : q = pushArgument(mb, q, uval);
2602 : } else {
2603 : /* projections, ie left is void headed */
2604 3070919 : q = newStmt(mb, algebraRef, projectionRef);
2605 3070955 : q = pushArgument(mb, q, op1->nr);
2606 3070948 : q = pushArgument(mb, q, op2->nr);
2607 : }
2608 3565560 : pushInstruction(mb, q);
2609 3565560 : return q;
2610 : }
2611 :
2612 : static list *
2613 62 : unnest_stmt(stmt *o)
2614 : {
2615 156 : while (o->type == st_alias)
2616 94 : o = o->op1;
2617 62 : assert(o && o->type == st_list);
2618 62 : return o->op4.lval;
2619 : }
2620 :
2621 : static stmt *
2622 0 : stmt_nest2(backend *be, stmt *op1, stmt *op2, fstmt call)
2623 : {
2624 0 : list *ops1 = unnest_stmt(op1);
2625 0 : list *ops2 = unnest_stmt(op2);
2626 0 : list *nops = sa_list(be->mvc->sa);
2627 0 : sql_subtype *st = tail_type(op2);
2628 0 : bool propagate = !st->multiset && st->type->composite;
2629 0 : for(node *n = ops1->h, *m = ops2->h; n && m; n = n->next, m = m->next) {
2630 0 : stmt *i1 = n->data;
2631 0 : stmt *i2 = m->data;
2632 0 : stmt *i = i2;
2633 0 : if (propagate || (st->multiset && n == ops1->t)) {
2634 0 : stmt *oi = i;
2635 0 : i = call(be, i1, oi);
2636 0 : i->nested = oi->nested;
2637 0 : i->subtype = *tail_type(oi);
2638 0 : i->tname = oi->tname;
2639 0 : i->cname = oi->cname;
2640 0 : i->label = oi->label;
2641 : }
2642 0 : append(nops, i);
2643 : }
2644 0 : stmt *s = stmt_list(be, nops);
2645 0 : if (s == NULL)
2646 : return NULL;
2647 0 : s->nested = true;
2648 0 : s->subtype = *st;
2649 0 : s->tname = op2->tname;
2650 0 : s->cname = op2->cname;
2651 0 : s->label = op2->label;
2652 0 : if (op2->type == st_alias)
2653 0 : return stmt_alias(be, s, op2->label, op2->tname, op2->cname);
2654 : return s;
2655 : }
2656 :
2657 : static stmt *
2658 0 : stmt_nest1(backend *be, stmt *op1, stmt *op2, fstmt call)
2659 : {
2660 0 : assert(op1->nested);
2661 0 : list *ops = unnest_stmt(op1);
2662 0 : list *nops = sa_list(be->mvc->sa);
2663 0 : sql_subtype *st = tail_type(op1);
2664 0 : bool propagate = !st->multiset && st->type->composite;
2665 0 : for(node *n = ops->h; n; n = n->next) {
2666 0 : stmt *i = n->data;
2667 0 : if (propagate || (st->multiset && n == ops->t)) {
2668 0 : stmt *oi = i;
2669 0 : i = call(be, oi, op2);
2670 0 : i->nested = oi->nested;
2671 0 : i->subtype = *tail_type(oi);
2672 0 : i->tname = oi->tname;
2673 0 : i->cname = oi->cname;
2674 0 : i->label = oi->label;
2675 : }
2676 0 : append(nops, i);
2677 : }
2678 0 : stmt *s = stmt_list(be, nops);
2679 0 : if (s == NULL)
2680 : return NULL;
2681 0 : s->nested = true;
2682 0 : s->subtype = *st;
2683 0 : s->tname = op1->tname;
2684 0 : s->cname = op1->cname;
2685 0 : s->label = op1->label;
2686 0 : if (op1->type == st_alias)
2687 0 : return stmt_alias(be, s, op1->label, op1->tname, op1->cname);
2688 : return s;
2689 : }
2690 :
2691 : stmt *
2692 36 : stmt_nest(backend *be, stmt *op1, stmt *op2, fstmt call)
2693 : {
2694 36 : if (!op2)
2695 0 : op2 = op1;
2696 36 : if (op1->nested && op2->nested)
2697 0 : return stmt_nest2(be, op1, op2, call);
2698 36 : if (op1->nested && !op2->nested)
2699 0 : return stmt_nest1(be, op1, op2, call);
2700 36 : assert(op2->nested);
2701 36 : list *ops = unnest_stmt(op2);
2702 36 : list *nops = sa_list(be->mvc->sa);
2703 36 : sql_subtype *st = tail_type(op2);
2704 36 : bool propagate = !st->multiset && st->type->composite;
2705 172 : for(node *n = ops->h; n; n = n->next) {
2706 136 : stmt *i = n->data;
2707 136 : if (propagate || (st->multiset && n == ops->t)) {
2708 82 : stmt *oi = i;
2709 82 : i = call(be, op1, oi);
2710 82 : i->nested = oi->nested;
2711 82 : i->subtype = *tail_type(oi);
2712 82 : i->tname = oi->tname;
2713 82 : i->cname = oi->cname;
2714 82 : i->label = oi->label;
2715 : }
2716 136 : append(nops, i);
2717 : }
2718 36 : stmt *s = stmt_list(be, nops);
2719 36 : if (s == NULL)
2720 : return NULL;
2721 36 : s->nested = true;
2722 36 : s->subtype = *st;
2723 36 : s->tname = op2->tname;
2724 36 : s->cname = op2->cname;
2725 36 : s->label = op2->label;
2726 36 : if (op2->type == st_alias)
2727 32 : return stmt_alias(be, s, op2->label, op2->tname, op2->cname);
2728 : return s;
2729 : }
2730 :
2731 : stmt *
2732 3080247 : stmt_project(backend *be, stmt *op1, stmt *op2)
2733 : {
2734 3080247 : if (op1 == NULL || op2 == NULL)
2735 : return NULL;
2736 3080247 : if (!op2->nrcols)
2737 9287 : return stmt_const(be, op1, op2);
2738 3070960 : if (op2->nested)
2739 36 : return stmt_nest(be, op1, op2, &stmt_project);
2740 3070924 : InstrPtr q = stmt_project_join(be, op1, op2, false);
2741 3070953 : if (q) {
2742 3070953 : stmt *s = stmt_create(be->mvc->sa, st_join);
2743 3070931 : if (s == NULL) {
2744 : return NULL;
2745 : }
2746 :
2747 3070931 : s->op1 = op1;
2748 3070931 : s->op2 = op2;
2749 3070931 : s->flag = cmp_project;
2750 3070931 : s->key = 0;
2751 3070931 : s->nrcols = MAX(op1->nrcols,op2->nrcols);
2752 3070931 : s->nr = getDestVar(q);
2753 3070931 : s->q = q;
2754 3070931 : s->tname = op2->tname;
2755 3070931 : s->cname = op2->cname;
2756 3070931 : s->label = op2->label;
2757 3070931 : 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 494582 : stmt_project_delta(backend *be, stmt *col, stmt *upd)
2766 : {
2767 494582 : InstrPtr q = stmt_project_join(be, col, upd, true);
2768 494610 : if (q) {
2769 494610 : stmt *s = stmt_create(be->mvc->sa, st_join);
2770 494603 : if (s == NULL) {
2771 : return NULL;
2772 : }
2773 :
2774 494603 : s->op1 = col;
2775 494603 : s->op2 = upd;
2776 494603 : s->flag = cmp_project;
2777 494603 : s->key = 0;
2778 494603 : s->nrcols = 2;
2779 494603 : s->nr = getDestVar(q);
2780 494603 : s->q = q;
2781 494603 : s->tname = col->tname;
2782 494603 : s->cname = col->cname;
2783 494603 : 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 26023 : stmt_rs_column(backend *be, stmt *rs, int i, sql_subtype *tpe)
3013 : {
3014 26023 : InstrPtr q = NULL;
3015 :
3016 26023 : if (rs == NULL || rs->nr < 0)
3017 : return NULL;
3018 26023 : q = rs->q;
3019 26023 : if (q) {
3020 25615 : stmt *s = stmt_create(be->mvc->sa, st_rs_column);
3021 25615 : if (s == NULL) {
3022 : return NULL;
3023 : }
3024 :
3025 25615 : s->op1 = rs;
3026 25615 : s->subtype = *tpe;
3027 25615 : s->flag = i;
3028 25615 : s->nrcols = 1;
3029 25615 : s->key = 0;
3030 25615 : s->q = q;
3031 25615 : s->nr = getArg(q, s->flag);
3032 25615 : 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 291655 : stmt_catalog(backend *be, int type, stmt *args)
3269 : {
3270 291655 : MalBlkPtr mb = be->mb;
3271 291655 : InstrPtr q = NULL;
3272 291655 : node *n;
3273 :
3274 291655 : if (args == NULL || args->nr < 0)
3275 0 : goto bailout;
3276 :
3277 : /* cast them into properly named operations */
3278 291655 : const char *ref;
3279 291655 : 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 1100 : case ddl_create_schema: ref = create_schemaRef; break;
3284 193 : case ddl_drop_schema: ref = drop_schemaRef; break;
3285 10242 : case ddl_create_table: ref = create_tableRef; break;
3286 22911 : case ddl_create_view: ref = create_viewRef; break;
3287 3753 : 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 944 : case ddl_create_type: ref = create_typeRef; break;
3292 36 : 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 18907 : case ddl_grant: ref = grantRef; break;
3296 15 : case ddl_revoke: ref = revokeRef; break;
3297 101527 : case ddl_grant_func: ref = grant_functionRef; break;
3298 1 : case ddl_revoke_func: ref = revoke_functionRef; break;
3299 362 : 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 688 : case ddl_drop_function: ref = drop_functionRef; break;
3307 124150 : case ddl_create_function: ref = create_functionRef; break;
3308 349 : 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 2350 : 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 358 : 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 291655 : q = newStmtArgs(mb, sqlcatalogRef, ref, list_length(args->op4.lval) + 1);
3324 291656 : if (q == NULL)
3325 0 : goto bailout;
3326 : // pass all arguments as before
3327 1743271 : for (n = args->op4.lval->h; n; n = n->next) {
3328 1451615 : stmt *c = n->data;
3329 :
3330 1451615 : q = pushArgument(mb, q, c->nr);
3331 : }
3332 :
3333 291656 : bool enabled = be->mvc->sa->eb.enabled;
3334 291656 : be->mvc->sa->eb.enabled = false;
3335 291656 : stmt *s = stmt_create(be->mvc->sa, st_catalog);
3336 291656 : be->mvc->sa->eb.enabled = enabled;
3337 291656 : if(!s) {
3338 0 : freeInstruction(q);
3339 0 : goto bailout;
3340 : }
3341 291656 : s->op1 = args;
3342 291656 : s->flag = type;
3343 291656 : s->q = q;
3344 291656 : s->nr = getDestVar(q);
3345 291656 : pushInstruction(mb, q);
3346 291656 : 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 1996050 : stmt_set_nrcols(stmt *s)
3356 : {
3357 1996050 : unsigned nrcols = 0;
3358 1996050 : int key = 1;
3359 1996050 : node *n;
3360 1996050 : list *l = s->op4.lval;
3361 :
3362 1996050 : assert(s->type == st_list);
3363 9481111 : for (n = l->h; n; n = n->next) {
3364 7485061 : stmt *f = n->data;
3365 :
3366 7485061 : if (!f)
3367 0 : continue;
3368 7485061 : if (f->nrcols > nrcols)
3369 : nrcols = f->nrcols;
3370 7485061 : key &= f->key;
3371 7485061 : s->nr = f->nr;
3372 : }
3373 1996050 : s->nrcols = nrcols;
3374 1996050 : s->key = key;
3375 1996050 : }
3376 :
3377 : stmt *
3378 1581748 : stmt_list(backend *be, list *l)
3379 : {
3380 1581748 : if (l == NULL)
3381 : return NULL;
3382 1581748 : stmt *s = stmt_create(be->mvc->sa, st_list);
3383 1581782 : if(!s) {
3384 : return NULL;
3385 : }
3386 1581782 : s->op4.lval = l;
3387 1581782 : stmt_set_nrcols(s);
3388 1581782 : return s;
3389 : }
3390 :
3391 : static InstrPtr
3392 68610 : 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 68610 : if (list_empty(l))
3395 : return instrlist;
3396 354148 : for (node *n = l->h; n; n = n->next) {
3397 285539 : stmt *c = n->data;
3398 285539 : sql_subtype *t = tail_type(c);
3399 285545 : bool virt = (!c->q && c->type == st_alias && !c->op1 && c->multiset);
3400 285545 : if (!c->nested && c->virt)
3401 0 : continue;
3402 :
3403 285545 : sql_alias *tname = table_name(sql->sa, c);
3404 285547 : const char *_empty = "";
3405 285547 : const char *tn = (tname) ? tname->name : _empty;
3406 : //const char *sn = (sname) ? sname : _empty;
3407 276514 : const char *sn = (tname && tname->parent) ? tname->parent->name : _empty;
3408 285547 : const char *cn = column_name(sql->sa, c);
3409 285541 : const char *ntn = sql_escape_ident(sql->ta, tn);
3410 285541 : const char *nsn = sql_escape_ident(sql->ta, sn);
3411 285555 : size_t fqtnl;
3412 :
3413 285555 : if (ntn && nsn && (fqtnl = strlen(ntn) + 1 + strlen(nsn) + 1) ){
3414 285555 : char *fqtn = SA_NEW_ARRAY(sql->ta, char, fqtnl);
3415 285557 : if (fqtn == NULL)
3416 : return NULL;
3417 285557 : snprintf(fqtn, fqtnl, "%s.%s", nsn, ntn);
3418 285557 : tblPtr = pushStr(mb, tblPtr, fqtn);
3419 285537 : nmePtr = pushStr(mb, nmePtr, cn);
3420 285534 : tpePtr = pushStr(mb, tpePtr, (t->type->localtype == TYPE_void ? "char" : t->type->base.name));
3421 285548 : lenPtr = pushInt(mb, lenPtr, t->digits);
3422 285536 : scalePtr = pushInt(mb, scalePtr, t->scale);
3423 285537 : if (virt || c->nested) {
3424 13 : multisetPtr = pushInt(mb, multisetPtr, c->subtype.multiset + ((virt || c->nested)?4:0));
3425 13 : InstrPtr q = newStmt(mb, batRef, newRef);
3426 :
3427 13 : if (q == NULL)
3428 : return NULL;
3429 13 : setVarType(mb, getArg(q, 0), newBatType(TYPE_void));
3430 13 : q = pushType(mb, q, TYPE_void);
3431 13 : pushInstruction(mb, q);
3432 13 : instrlist = pushArgument(mb, instrlist, getArg(q, 0));
3433 :
3434 13 : instrlist = nested_dump_header(sql, mb, instrlist, tblPtr, nmePtr, tpePtr, lenPtr, scalePtr, multisetPtr, unnest_stmt(c));
3435 13 : if (!instrlist)
3436 : return NULL;
3437 : } else {
3438 285524 : multisetPtr = pushInt(mb, multisetPtr, 0);
3439 285518 : instrlist = pushArgument(mb, instrlist,c->nr);
3440 : }
3441 : } else {
3442 : return NULL;
3443 : }
3444 : }
3445 : return instrlist;
3446 : }
3447 :
3448 : static int
3449 68594 : nested_len(list *l)
3450 : {
3451 68594 : int nr = 0;
3452 68594 : if (list_empty(l))
3453 : return 0;
3454 354153 : for(node *n = l->h; n; n = n->next) {
3455 285547 : stmt *s = n->data;
3456 285547 : if (s->nested)
3457 13 : nr += nested_len(unnest_stmt(s)) + 1;
3458 : else
3459 285534 : nr++;
3460 : }
3461 : return nr;
3462 : }
3463 :
3464 : static InstrPtr
3465 68582 : dump_header(mvc *sql, MalBlkPtr mb, list *l)
3466 : {
3467 : // gather the meta information
3468 68582 : int tblId, nmeId, tpeId, lenId, scaleId, multisetId;
3469 68582 : int args;
3470 68582 : InstrPtr list;
3471 68582 : InstrPtr tblPtr, nmePtr, tpePtr, lenPtr, scalePtr, multisetPtr;
3472 :
3473 68582 : args = 1 + nested_len(l);
3474 :
3475 68596 : list = newInstructionArgs(mb,sqlRef, resultSetRef, args + 6);
3476 68591 : if(!list)
3477 : return NULL;
3478 :
3479 68591 : getArg(list,0) = newTmpVariable(mb,TYPE_int);
3480 68589 : meta(tblPtr, tblId, TYPE_str, args);
3481 68596 : meta(nmePtr, nmeId, TYPE_str, args);
3482 68597 : meta(tpePtr, tpeId, TYPE_str, args);
3483 68597 : meta(lenPtr, lenId, TYPE_int, args);
3484 68597 : meta(scalePtr, scaleId, TYPE_int, args);
3485 68597 : meta(multisetPtr, multisetId, TYPE_int, args);
3486 68597 : if(tblPtr == NULL || nmePtr == NULL || tpePtr == NULL || lenPtr == NULL || scalePtr == NULL || multisetPtr == NULL)
3487 : return NULL;
3488 68597 : list = nested_dump_header(sql, mb, list, tblPtr, nmePtr, tpePtr, lenPtr, scalePtr, multisetPtr, l);
3489 68595 : sa_reset(sql->ta);
3490 68574 : if (list)
3491 68574 : pushInstruction(mb, list);
3492 : return list;
3493 : }
3494 :
3495 : int
3496 128978 : stmt_output(backend *be, stmt *lst)
3497 : {
3498 128978 : MalBlkPtr mb = be->mb;
3499 128978 : InstrPtr q = NULL;
3500 128978 : list *l = lst->op4.lval;
3501 128978 : int cnt = list_length(l), ok = 0;
3502 129054 : node *n = l->h;
3503 129054 : stmt *first = n->data;
3504 :
3505 : /* single value result, has a fast exit */
3506 129054 : if (cnt == 1 && first->nrcols <= 0 ){
3507 60428 : stmt *c = n->data;
3508 60428 : sql_subtype *t = tail_type(c);
3509 60440 : sql_alias *tname = table_name(be->mvc->sa, c);
3510 60394 : const char *_empty = "";
3511 60394 : const char *tn = (tname) ? tname->name : _empty;
3512 59968 : const char *sn = (tname && tname->parent) ? tname->parent->name : _empty;
3513 60394 : const char *cn = column_name(be->mvc->sa, c);
3514 60385 : const char *ntn = sql_escape_ident(be->mvc->ta, tn);
3515 60497 : const char *nsn = sql_escape_ident(be->mvc->ta, sn);
3516 :
3517 60506 : if (ntn && nsn) {
3518 60506 : size_t fqtnl = strlen(ntn) + 1 + strlen(nsn) + 1;
3519 60506 : char *fqtn = SA_NEW_ARRAY(be->mvc->ta, char, fqtnl);
3520 60505 : if (fqtn == NULL)
3521 : return -1;
3522 60505 : ok = 1;
3523 60505 : snprintf(fqtn, fqtnl, "%s.%s", nsn, ntn);
3524 :
3525 60505 : q = newStmt(mb, sqlRef, resultSetRef);
3526 60506 : if (q == NULL)
3527 : return -1;
3528 60506 : getArg(q,0) = newTmpVariable(mb,TYPE_int);
3529 60507 : q = pushStr(mb, q, fqtn);
3530 60505 : q = pushStr(mb, q, cn);
3531 60507 : q = pushStr(mb, q, t->type->localtype == TYPE_void ? "char" : t->type->base.name);
3532 60506 : q = pushInt(mb, q, t->digits);
3533 60497 : q = pushInt(mb, q, t->scale);
3534 60506 : q = pushInt(mb, q, t->type->eclass);
3535 60502 : q = pushInt(mb, q, t->multiset);
3536 60494 : q = pushArgument(mb, q, c->nr);
3537 60510 : pushInstruction(mb, q);
3538 : }
3539 60500 : sa_reset(be->mvc->ta);
3540 60490 : if (!ok)
3541 : return -1;
3542 : } else {
3543 68626 : if ((q = dump_header(be->mvc, mb, l)) == NULL)
3544 : return -1;
3545 : }
3546 : return 0;
3547 : }
3548 :
3549 : int
3550 149571 : stmt_affected_rows(backend *be, int lastnr)
3551 : {
3552 149571 : MalBlkPtr mb = be->mb;
3553 149571 : InstrPtr q = NULL;
3554 :
3555 149571 : q = newStmt(mb, sqlRef, affectedRowsRef);
3556 149817 : if (q == NULL)
3557 : return -1;
3558 149817 : q = pushArgument(mb, q, be->mvc_var);
3559 149815 : getArg(q, 0) = be->mvc_var = newTmpVariable(mb, TYPE_int);
3560 149817 : q = pushArgument(mb, q, lastnr);
3561 149819 : pushInstruction(mb, q);
3562 149827 : be->mvc_var = getDestVar(q);
3563 149827 : return 0;
3564 : }
3565 :
3566 : stmt *
3567 178079 : stmt_append(backend *be, stmt *c, stmt *a)
3568 : {
3569 178079 : MalBlkPtr mb = be->mb;
3570 178079 : InstrPtr q = NULL;
3571 :
3572 178079 : if (c == NULL || a == NULL || c->nr < 0 || a->nr < 0)
3573 0 : goto bailout;
3574 178079 : if (c->nested)
3575 0 : return stmt_nest(be, c, a, &stmt_append);
3576 178079 : q = newStmt(mb, batRef, appendRef);
3577 178079 : if (q == NULL)
3578 0 : goto bailout;
3579 178079 : q = pushArgument(mb, q, c->nr);
3580 178079 : q = pushArgument(mb, q, a->nr);
3581 178079 : q = pushBit(mb, q, TRUE);
3582 178079 : bool enabled = be->mvc->sa->eb.enabled;
3583 178079 : be->mvc->sa->eb.enabled = false;
3584 178079 : stmt *s = stmt_create(be->mvc->sa, st_append);
3585 178079 : be->mvc->sa->eb.enabled = enabled;
3586 178079 : if(!s) {
3587 0 : freeInstruction(q);
3588 0 : goto bailout;
3589 : }
3590 178079 : s->op1 = c;
3591 178079 : s->op2 = a;
3592 178079 : s->nrcols = c->nrcols;
3593 178079 : s->key = c->key;
3594 178079 : s->nr = getDestVar(q);
3595 178079 : s->q = q;
3596 178079 : pushInstruction(mb, q);
3597 178079 : 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 137888 : stmt_append_bulk(backend *be, stmt *c, list *l)
3607 : {
3608 137888 : MalBlkPtr mb = be->mb;
3609 137888 : InstrPtr q = NULL;
3610 137888 : bool needs_columns = false;
3611 137888 : bool ms = false;
3612 :
3613 137888 : 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 890712 : for (node *n = l->h; n; n = n->next) {
3619 752824 : stmt *t = n->data;
3620 752824 : needs_columns |= t->nrcols > 0;
3621 : }
3622 137888 : 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 137888 : q = newStmtArgs(mb, batRef, appendBulkRef, list_length(l) + 3 + (ms?1:0));
3633 138221 : if (q == NULL)
3634 0 : goto bailout;
3635 138221 : q = pushArgument(mb, q, c->nr);
3636 138219 : q = pushBit(mb, q, TRUE);
3637 138108 : if (ms)
3638 16 : q = pushBit(mb, q, TRUE);
3639 890995 : for (node *n = l->h ; n ; n = n->next) {
3640 752857 : stmt *a = n->data;
3641 752857 : q = pushArgument(mb, q, a->nr);
3642 : }
3643 138138 : bool enabled = be->mvc->sa->eb.enabled;
3644 138138 : be->mvc->sa->eb.enabled = false;
3645 138138 : stmt *s = stmt_create(be->mvc->sa, st_append_bulk);
3646 137971 : be->mvc->sa->eb.enabled = enabled;
3647 137971 : if(!s) {
3648 0 : freeInstruction(q);
3649 0 : goto bailout;
3650 : }
3651 137971 : s->op1 = c;
3652 137971 : s->op4.lval = l;
3653 137971 : s->nrcols = c->nrcols;
3654 137971 : s->key = c->key;
3655 137971 : s->nr = getDestVar(q);
3656 137971 : s->q = q;
3657 137971 : pushInstruction(mb, q);
3658 137971 : 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 106528 : stmt_claim(backend *be, sql_table *t, stmt *cnt)
3740 : {
3741 106528 : MalBlkPtr mb = be->mb;
3742 106528 : InstrPtr q = NULL;
3743 :
3744 106528 : if (!t || cnt->nr < 0)
3745 0 : goto bailout;
3746 106528 : assert(t->s); /* declared table */
3747 106528 : q = newStmtArgs(mb, sqlRef, claimRef, 6);
3748 106588 : if (q == NULL)
3749 0 : goto bailout;
3750 : /* returns offset or offsets */
3751 106588 : q = pushReturn(mb, q, newTmpVariable(mb, newBatType(TYPE_oid)));
3752 106579 : q = pushArgument(mb, q, be->mvc_var);
3753 106574 : q = pushSchema(mb, q, t);
3754 106547 : q = pushStr(mb, q, t->base.name);
3755 106567 : q = pushArgument(mb, q, cnt->nr);
3756 106570 : bool enabled = be->mvc->sa->eb.enabled;
3757 106570 : be->mvc->sa->eb.enabled = false;
3758 106570 : stmt *s = stmt_create(be->mvc->sa, st_claim);
3759 106518 : be->mvc->sa->eb.enabled = enabled;
3760 106518 : if(!s) {
3761 0 : freeInstruction(q);
3762 0 : goto bailout;
3763 : }
3764 106518 : s->op1 = cnt;
3765 106518 : s->op4.tval = t;
3766 106518 : s->nr = getDestVar(q);
3767 106518 : s->q = q;
3768 106518 : pushInstruction(mb, q);
3769 106518 : 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 149578 : stmt_add_dependency_change(backend *be, sql_table *t, stmt *cnt)
3779 : {
3780 149578 : MalBlkPtr mb = be->mb;
3781 149578 : InstrPtr q = NULL;
3782 :
3783 149578 : if (!t || cnt->nr < 0)
3784 0 : goto bailout;
3785 149578 : q = newStmtArgs(mb, sqlRef, dependRef, 4);
3786 150056 : if (q == NULL)
3787 0 : goto bailout;
3788 150056 : q = pushSchema(mb, q, t);
3789 150048 : q = pushStr(mb, q, t->base.name);
3790 150057 : q = pushArgument(mb, q, cnt->nr);
3791 150060 : pushInstruction(mb, q);
3792 150060 : 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 14936 : stmt_add_column_predicate(backend *be, sql_column *c)
3801 : {
3802 14936 : MalBlkPtr mb = be->mb;
3803 14936 : InstrPtr q = NULL;
3804 :
3805 14936 : if (!c)
3806 0 : goto bailout;
3807 14936 : q = newStmtArgs(mb, sqlRef, predicateRef, 4);
3808 14980 : if (q == NULL)
3809 0 : goto bailout;
3810 14980 : q = pushSchema(mb, q, c->t);
3811 14978 : q = pushStr(mb, q, c->t->base.name);
3812 14978 : q = pushStr(mb, q, c->base.name);
3813 14980 : pushInstruction(mb, q);
3814 14980 : 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 55832 : stmt_replace(backend *be, stmt *r, stmt *id, stmt *val)
3823 : {
3824 55832 : MalBlkPtr mb = be->mb;
3825 55832 : InstrPtr q = NULL;
3826 :
3827 55832 : if (r->nr < 0)
3828 0 : goto bailout;
3829 :
3830 55832 : q = newStmt(mb, batRef, replaceRef);
3831 55832 : if (q == NULL)
3832 0 : goto bailout;
3833 55832 : q = pushArgument(mb, q, r->nr);
3834 55832 : q = pushArgument(mb, q, id->nr);
3835 55832 : q = pushArgument(mb, q, val->nr);
3836 55832 : q = pushBit(mb, q, TRUE); /* forced */
3837 55832 : bool enabled = be->mvc->sa->eb.enabled;
3838 55832 : be->mvc->sa->eb.enabled = false;
3839 55832 : stmt *s = stmt_create(be->mvc->sa, st_replace);
3840 55832 : be->mvc->sa->eb.enabled = enabled;
3841 55832 : if(!s) {
3842 0 : freeInstruction(q);
3843 0 : goto bailout;
3844 : }
3845 55832 : s->op1 = r;
3846 55832 : s->op2 = id;
3847 55832 : s->op3 = val;
3848 55832 : s->nrcols = r->nrcols;
3849 55832 : s->key = r->key;
3850 55832 : s->nr = getDestVar(q);
3851 55832 : s->q = q;
3852 55832 : s->cand = r->cand;
3853 55832 : pushInstruction(mb, q);
3854 55832 : 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 41425 : stmt_table_clear(backend *be, sql_table *t, int restart_sequences)
3864 : {
3865 41425 : MalBlkPtr mb = be->mb;
3866 41425 : InstrPtr q = NULL;
3867 :
3868 41425 : 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 41423 : q = newStmt(mb, sqlRef, clear_tableRef);
3881 41825 : if (q == NULL)
3882 0 : goto bailout;
3883 41825 : q = pushSchema(mb, q, t);
3884 41816 : q = pushStr(mb, q, t->base.name);
3885 41776 : q = pushInt(mb, q, restart_sequences);
3886 41751 : pushInstruction(mb, q);
3887 : }
3888 41767 : stmt *s = stmt_create(be->mvc->sa, st_table_clear);
3889 :
3890 41673 : if(!s) {
3891 0 : goto bailout;
3892 : }
3893 41673 : s->op4.tval = t;
3894 41673 : s->nrcols = 0;
3895 41673 : s->nr = getDestVar(q);
3896 41673 : s->q = q;
3897 41673 : 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 39659 : stmt_exception(backend *be, stmt *cond, const char *errstr, int errcode)
3907 : {
3908 39659 : MalBlkPtr mb = be->mb;
3909 39659 : InstrPtr q = NULL;
3910 :
3911 39659 : if (cond->nr < 0)
3912 : return NULL;
3913 :
3914 : /* if(bit(l)) { error(r);} ==raising an exception */
3915 39659 : q = newStmt(mb, sqlRef, assertRef);
3916 39702 : if (q == NULL)
3917 0 : goto bailout;
3918 39702 : q = pushArgument(mb, q, cond->nr);
3919 39702 : q = pushStr(mb, q, errstr);
3920 39702 : bool enabled = be->mvc->sa->eb.enabled;
3921 39702 : be->mvc->sa->eb.enabled = false;
3922 39702 : stmt *s = stmt_create(be->mvc->sa, st_exception);
3923 39701 : be->mvc->sa->eb.enabled = enabled;
3924 39701 : if(!s) {
3925 0 : freeInstruction(q);
3926 0 : return NULL;
3927 : }
3928 39701 : assert(cond);
3929 39701 : s->op1 = cond;
3930 39701 : (void)errcode;
3931 39701 : s->nrcols = 0;
3932 39701 : s->q = q;
3933 39701 : s->nr = getDestVar(q);
3934 39701 : pushInstruction(mb, q);
3935 39701 : 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 18024 : tail_set_type(mvc *m, stmt *st, sql_subtype *t)
3947 : {
3948 44557 : for (;;) {
3949 44557 : switch (st->type) {
3950 3689 : case st_const:
3951 3689 : st = st->op2;
3952 3689 : continue;
3953 18749 : case st_alias:
3954 : case st_gen_group:
3955 : case st_order:
3956 18749 : st = st->op1;
3957 18749 : continue;
3958 0 : case st_list:
3959 0 : st = st->op4.lval->h->data;
3960 0 : continue;
3961 4095 : case st_join:
3962 : case st_join2:
3963 : case st_joinN:
3964 4095 : if (st->flag == cmp_project) {
3965 4095 : st = st->op2;
3966 4095 : 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 9193 : case st_atom:
3978 9193 : st->op4.aval = atom_set_type(m->sa, st->op4.aval, t);
3979 9193 : 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 106 : composite_type_resultsize(sql_subtype *t)
4119 : {
4120 106 : int nr = 0;
4121 :
4122 106 : if (t->multiset)
4123 27 : nr += 2 + (t->multiset == MS_ARRAY);
4124 106 : if (t->type->composite) {
4125 117 : for (node *n = t->type->d.fields->h; n; n = n->next) {
4126 79 : sql_arg *a = n->data;
4127 79 : nr += composite_type_resultsize(&a->type);
4128 : }
4129 : } else {
4130 68 : nr++;
4131 : }
4132 106 : 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 106 : composite_type_result(backend *be, InstrPtr q, sql_subtype *t, result_subtype *tps)
4143 : {
4144 106 : int i = 0;
4145 106 : if (t->multiset || t->type->composite) {
4146 51 : if (t->type->composite) {
4147 117 : for (node *n = t->type->d.fields->h; n; n = n->next) {
4148 79 : sql_arg *a = n->data;
4149 79 : int r = 0;
4150 79 : if ((r = composite_type_result(be, q, &a->type, tps+i)) < 0)
4151 : return -1;
4152 79 : i += r;
4153 : }
4154 : } else {
4155 13 : q = pushReturn(be->mb, q, newTmpVariable(be->mb, newBatType(t->type->localtype)));
4156 13 : tps[i].st = *t;
4157 13 : tps[i++].multiset = false;
4158 : }
4159 51 : if (t->multiset) { /* msid */
4160 27 : q = pushReturn(be->mb, q, newTmpVariable(be->mb, newBatType(TYPE_int)));
4161 27 : tps[i].st = *sql_bind_localtype("int");
4162 27 : tps[i++].multiset = true;
4163 : }
4164 51 : if (t->multiset == MS_ARRAY) { /* msnr */
4165 27 : q = pushReturn(be->mb, q, newTmpVariable(be->mb, newBatType(TYPE_int)));
4166 27 : tps[i].st = *sql_bind_localtype("int");
4167 27 : tps[i++].multiset = false;
4168 : }
4169 : /* end with the rowid */
4170 51 : if (t->multiset) { /* id col : rowid */
4171 27 : q = pushReturn(be->mb, q, newTmpVariable(be->mb, newBatType(TYPE_int)));
4172 27 : tps[i].st = *sql_bind_localtype("int");
4173 27 : tps[i++].multiset = true;
4174 : }
4175 : } else {
4176 55 : q = pushReturn(be->mb, q, newTmpVariable(be->mb, newBatType(t->type->localtype)));
4177 55 : tps[i].st = *t;
4178 55 : 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 27 : result_list(backend *be, InstrPtr q, int cur, result_subtype *tps, int nrcols)
4235 : {
4236 27 : list *r = sa_list(be->mvc->sa);
4237 176 : for(int i = cur; i < nrcols; i++) {
4238 149 : stmt *br = stmt_blackbox_result(be, q, i, &tps[i].st);
4239 149 : append(r, br);
4240 149 : if (tps[i].multiset)
4241 54 : br->multiset = true;
4242 : }
4243 27 : return stmt_list(be, r);
4244 : }
4245 :
4246 : static stmt *
4247 7 : stmt_from_json(backend *be, stmt *v, stmt *sel, sql_subtype *t)
4248 : {
4249 7 : (void)sel;
4250 7 : int nrcols = composite_type_resultsize(t);
4251 7 : result_subtype *tps = SA_NEW_ARRAY(be->mvc->sa, result_subtype, nrcols);
4252 :
4253 7 : InstrPtr q = newStmtArgs(be->mb, "sql", "from_json", nrcols + 2);
4254 7 : if (q == NULL)
4255 0 : goto bailout;
4256 :
4257 7 : q->retc = q->argc = 0;
4258 7 : if (composite_type_result(be, q, t, tps) < 0) {
4259 0 : freeInstruction(q);
4260 0 : goto bailout;
4261 : }
4262 :
4263 7 : q = pushArgument(be->mb, q, v->nr);
4264 7 : q = pushPtr(be->mb, q, t);
4265 :
4266 7 : bool enabled = be->mvc->sa->eb.enabled;
4267 7 : be->mvc->sa->eb.enabled = false;
4268 7 : stmt *s = stmt_create(be->mvc->sa, st_convert);
4269 7 : be->mvc->sa->eb.enabled = enabled;
4270 7 : if(!s) {
4271 0 : freeInstruction(q);
4272 0 : goto bailout;
4273 : }
4274 7 : s->op1 = v;
4275 7 : s->nrcols = 2;
4276 7 : s->key = v->key;
4277 7 : s->aggr = v->aggr;
4278 7 : s->subtype = *t;
4279 7 : s->nr = getDestVar(q);
4280 7 : s->q = q;
4281 : //s->cand = pushed ? sel : NULL;
4282 7 : pushInstruction(be->mb, q);
4283 7 : s = result_list(be, s->q, 0, tps, nrcols);
4284 7 : s->subtype = *t;
4285 7 : s->nested = true;
4286 7 : s->multiset = t->multiset;
4287 7 : 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 20 : stmt_from_varchar(backend *be, stmt *v, stmt *sel, sql_subtype *t)
4296 : {
4297 20 : (void)sel;
4298 20 : int nrcols = composite_type_resultsize(t);
4299 20 : result_subtype *tps = SA_NEW_ARRAY(be->mvc->sa, result_subtype, nrcols);
4300 :
4301 20 : InstrPtr q = newStmtArgs(be->mb, "sql", "from_varchar", nrcols + 2);
4302 20 : if (q == NULL)
4303 0 : goto bailout;
4304 :
4305 20 : q->retc = q->argc = 0;
4306 20 : if (composite_type_result(be, q, t, tps) < 0) {
4307 0 : freeInstruction(q);
4308 0 : goto bailout;
4309 : }
4310 :
4311 20 : q = pushArgument(be->mb, q, v->nr);
4312 20 : q = pushPtr(be->mb, q, t);
4313 :
4314 20 : bool enabled = be->mvc->sa->eb.enabled;
4315 20 : be->mvc->sa->eb.enabled = false;
4316 20 : stmt *s = stmt_create(be->mvc->sa, st_convert);
4317 20 : be->mvc->sa->eb.enabled = enabled;
4318 20 : if(!s) {
4319 0 : freeInstruction(q);
4320 0 : goto bailout;
4321 : }
4322 20 : s->op1 = v;
4323 20 : s->nrcols = 2;
4324 20 : s->key = v->key;
4325 20 : s->aggr = v->aggr;
4326 20 : s->subtype = *t;
4327 20 : s->nr = getDestVar(q);
4328 20 : s->q = q;
4329 : //s->cand = pushed ? sel : NULL;
4330 20 : pushInstruction(be->mb, q);
4331 20 : s = result_list(be, s->q, 0, tps, nrcols);
4332 20 : s->subtype = *t;
4333 20 : s->nested = true;
4334 20 : s->multiset = t->multiset;
4335 20 : 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 55220 : stmt_convert(backend *be, stmt *v, stmt *sel, sql_subtype *f, sql_subtype *t)
4344 : {
4345 55220 : MalBlkPtr mb = be->mb;
4346 55220 : InstrPtr q = NULL;
4347 55220 : const char *convert = t->type->d.impl, *mod = calcRef;
4348 55220 : int pushed = (v->cand && v->cand == sel), no_candidates = 0;
4349 55220 : bool add_tz = false;
4350 : /* convert types and make sure they are rounded up correctly */
4351 :
4352 55220 : if (v->nr < 0)
4353 0 : goto bailout;
4354 :
4355 55220 : if (f->type->eclass == EC_EXTERNAL && t->type->composite && strcmp(f->type->base.name, "json") == 0)
4356 7 : return stmt_from_json(be, v, sel, t);
4357 55213 : 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 55213 : if (EC_VARCHAR(f->type->eclass) && (t->type->composite || t->multiset))
4360 20 : return stmt_from_varchar(be, v, sel, t);
4361 55193 : if (f->type == t->type && t->multiset && v->subtype.multiset)
4362 : return v;
4363 55192 : if (f->type->eclass != EC_EXTERNAL && t->type->eclass != EC_EXTERNAL &&
4364 : /* general cases */
4365 54817 : ((t->type->localtype == f->type->localtype && t->type->eclass == f->type->eclass &&
4366 54817 : !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 45074 : (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 11133 : (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 18024 : tail_set_type(be->mvc, v, t);
4373 18024 : return v;
4374 : }
4375 :
4376 : /* external types have sqlname convert functions,
4377 : these can generate errors (fromstr cannot) */
4378 37168 : if (t->type->eclass == EC_EXTERNAL)
4379 347 : convert = t->type->base.name;
4380 36821 : else if (t->type->eclass == EC_MONTH)
4381 : convert = "month_interval";
4382 36771 : else if (t->type->eclass == EC_SEC)
4383 194 : convert = "second_interval";
4384 :
4385 37168 : no_candidates = t->type->eclass == EC_EXTERNAL && strcmp(convert, "uuid") != 0; /* uuids conversions support candidate lists */
4386 :
4387 37168 : 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 37044 : if (v->nrcols == 0 && (!sel || sel->nrcols == 0)) { /* simple calc */
4399 8481 : q = newStmtArgs(mb, mod, convert, 13);
4400 8481 : if (q == NULL)
4401 0 : goto bailout;
4402 28584 : } 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 28542 : 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 28542 : q = newStmtArgs(mb, mod==calcRef?batcalcRef:batmtimeRef, convert, 13);
4424 28542 : 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 37210 : if (EC_VARCHAR(t->type->eclass) && !(trivial_string_conversion(f->type->eclass) && t->digits == 0)) {
4430 1925 : q = pushInt(mb, q, f->type->eclass);
4431 1925 : q = pushInt(mb, q, f->digits);
4432 1925 : q = pushInt(mb, q, f->scale);
4433 1925 : q = pushInt(mb, q, type_has_tz(f));
4434 35119 : } else if (f->type->eclass == EC_DEC) {
4435 : /* scale of the current decimal */
4436 1566 : q = pushInt(mb, q, f->scale);
4437 33553 : } 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 37044 : q = pushArgument(mb, q, v->nr);
4442 37044 : if (add_tz)
4443 : q = pushLng(mb, q, be->mvc->timezone);
4444 37044 : if (sel && !pushed && !v->cand) {
4445 3578 : q = pushArgument(mb, q, sel->nr);
4446 3578 : pushed = 1;
4447 33466 : } else if (v->nrcols > 0 && !no_candidates) {
4448 24964 : q = pushNilBat(mb, q);
4449 : }
4450 37043 : 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 37209 : if (EC_VARCHAR(t->type->eclass) && !(trivial_string_conversion(f->type->eclass) && t->digits == 0))
4458 1925 : q = pushInt(mb, q, t->digits);
4459 : /* convert a string to a time(stamp) with time zone */
4460 37043 : 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 37043 : 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 37043 : bool enabled = be->mvc->sa->eb.enabled;
4486 37043 : be->mvc->sa->eb.enabled = false;
4487 37043 : stmt *s = stmt_create(be->mvc->sa, st_convert);
4488 37043 : be->mvc->sa->eb.enabled = enabled;
4489 37043 : if(!s) {
4490 0 : freeInstruction(q);
4491 0 : goto bailout;
4492 : }
4493 37043 : s->op1 = v;
4494 37043 : s->nrcols = 0; /* function without arguments returns single value */
4495 37043 : s->key = v->key;
4496 37043 : s->nrcols = v->nrcols;
4497 37043 : s->aggr = v->aggr;
4498 37043 : s->subtype = *t;
4499 37043 : s->nr = getDestVar(q);
4500 37043 : s->q = q;
4501 37043 : s->cand = pushed ? sel : NULL;
4502 37043 : pushInstruction(mb, q);
4503 37044 : 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 27197 : stmt_unop(backend *be, stmt *op1, stmt *sel, sql_subfunc *op)
4515 : {
4516 27197 : list *ops = sa_list(be->mvc->sa);
4517 27218 : list_append(ops, op1);
4518 27234 : stmt *r = stmt_Nop(be, stmt_list(be, ops), sel, op, NULL);
4519 27237 : if (r && !r->cand)
4520 27237 : r->cand = op1->cand;
4521 27237 : return r;
4522 : }
4523 :
4524 : stmt *
4525 47493 : stmt_binop(backend *be, stmt *op1, stmt *op2, stmt *sel, sql_subfunc *op)
4526 : {
4527 47493 : list *ops = sa_list(be->mvc->sa);
4528 47497 : list_append(ops, op1);
4529 47501 : list_append(ops, op2);
4530 47501 : stmt *r = stmt_Nop(be, stmt_list(be, ops), sel, op, NULL);
4531 47502 : if (r && !r->cand)
4532 47502 : r->cand = op1->cand?op1->cand:op2->cand;
4533 47502 : return r;
4534 : }
4535 :
4536 : #define LANG_INT_OR_MAL(l) ((l)==FUNC_LANG_INT || (l)==FUNC_LANG_MAL)
4537 :
4538 : stmt *
4539 287872 : stmt_Nop(backend *be, stmt *ops, stmt *sel, sql_subfunc *f, stmt* rows)
4540 : {
4541 287872 : MalBlkPtr mb = be->mb;
4542 287872 : InstrPtr q = NULL;
4543 287872 : const char *mod = sql_func_mod(f->func), *fimp = backend_function_imp(be, f->func);
4544 287955 : sql_subtype *tpe = NULL;
4545 287955 : int push_cands = 0, default_nargs;
4546 287955 : stmt *o = NULL, *card = NULL;
4547 :
4548 287955 : if (ops == NULL)
4549 0 : goto bailout;
4550 :
4551 287955 : 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 287850 : } else if (list_length(ops->op4.lval)) {
4556 285951 : o = ops->op4.lval->h->data;
4557 821950 : for (node *n = ops->op4.lval->h; n; n = n->next) {
4558 535999 : stmt *c = n->data;
4559 :
4560 535999 : if (c && o->nrcols < c->nrcols)
4561 535999 : o = c;
4562 : }
4563 : }
4564 :
4565 : /* handle nullif */
4566 287948 : if (list_length(ops->op4.lval) == 2 &&
4567 172769 : 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 287826 : if (backend_create_subfunc(be, f, ops->op4.lval) < 0)
4598 2 : goto bailout;
4599 287870 : mod = sql_func_mod(f->func);
4600 287930 : fimp = convertMultiplexFcn(backend_function_imp(be, f->func));
4601 287905 : push_cands = f->func->type == F_FUNC && can_push_cands(sel, mod, fimp);
4602 329734 : 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 287889 : 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 287889 : if (o && o->nrcols > 0 && f->func->type != F_LOADER && f->func->type != F_PROC) {
4609 174729 : sql_subtype *res = f->res->h->data;
4610 :
4611 349442 : q = newStmtArgs(mb, f->func->type == F_UNION ? batmalRef : malRef, multiplexRef, default_nargs);
4612 174729 : if (q == NULL)
4613 0 : goto bailout;
4614 174729 : if (rows)
4615 105 : q = pushArgument(mb, q, card->nr);
4616 174729 : q = pushStr(mb, q, mod);
4617 174729 : q = pushStr(mb, q, fimp);
4618 174729 : setVarType(mb, getArg(q, 0), newBatType(res->type->localtype));
4619 : } else {
4620 113160 : q = newStmtArgs(mb, mod, fimp, default_nargs);
4621 113223 : if (q == NULL)
4622 0 : goto bailout;
4623 :
4624 113223 : if (rows)
4625 0 : q = pushArgument(mb, q, card->nr);
4626 113225 : if (f->res && list_length(f->res)) {
4627 71374 : sql_subtype *res = f->res->h->data;
4628 :
4629 71374 : setVarType(mb, getArg(q, 0), res->type->localtype);
4630 : }
4631 : }
4632 287954 : 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 287954 : if (f->func->lang == FUNC_LANG_C) {
4642 35 : q = pushBit(mb, q, 0);
4643 287919 : } else if (f->func->lang == FUNC_LANG_CPP) {
4644 1 : q = pushBit(mb, q, 1);
4645 : }
4646 287954 : 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 287954 : if (f->func->type == F_UNION || (f->func->type == F_LOADER && f->res != NULL))
4652 2787 : q = table_func_create_result(mb, q, f->func, f->res);
4653 287954 : if (list_length(ops->op4.lval))
4654 286067 : tpe = tail_type(ops->op4.lval->h->data);
4655 :
4656 824111 : for (node *n = ops->op4.lval->h; n; n = n->next) {
4657 536161 : stmt *op = n->data;
4658 536161 : q = pushArgument(mb, q, op->nr);
4659 : }
4660 : /* push candidate lists if that's the case */
4661 287950 : if (push_cands) {
4662 178404 : for (node *n = ops->op4.lval->h; n; n = n->next) {
4663 118396 : stmt *op = n->data;
4664 :
4665 118396 : if (op->nrcols > 0) {
4666 78132 : if (op->cand && op->cand == sel) {
4667 35479 : q = pushNilBat(mb, q);
4668 : } else {
4669 42653 : q = pushArgument(mb, q, sel->nr);
4670 : }
4671 : }
4672 : }
4673 : }
4674 : /* special case for round function on decimals */
4675 287950 : 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 287950 : pushInstruction(mb, q);
4680 : }
4681 :
4682 288047 : stmt *s = stmt_create(be->mvc->sa, st_Nop);
4683 288046 : if(!s) {
4684 0 : goto bailout;
4685 : }
4686 288046 : s->op1 = ops;
4687 288046 : if (o) {
4688 286177 : s->nrcols = o->nrcols;
4689 286177 : s->key = o->key;
4690 286177 : s->aggr = o->aggr;
4691 : } else {
4692 1869 : s->nrcols = 0;
4693 1869 : s->key = 1;
4694 : }
4695 288046 : s->op4.funcval = f;
4696 288046 : s->nr = getDestVar(q);
4697 288046 : s->q = q;
4698 288046 : if (sel && push_cands && s->nrcols)
4699 58487 : 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 85489 : stmt_aggr(backend *be, stmt *op1, stmt *grp, stmt *ext, sql_subfunc *op, int reduce, int no_nil, int nil_if_empty)
4819 : {
4820 85489 : MalBlkPtr mb = be->mb;
4821 85489 : InstrPtr q = NULL;
4822 85489 : const char *mod, *aggrfunc;
4823 85489 : sql_subtype *res = op->res->h->data;
4824 85489 : int restype = res->type->localtype;
4825 85489 : bool complex_aggr = false;
4826 85489 : int *stmt_nr = NULL;
4827 85489 : int avg = 0;
4828 :
4829 85489 : if (op1->nr < 0)
4830 0 : goto bailout;
4831 85489 : if (backend_create_subfunc(be, op, NULL) < 0)
4832 0 : goto bailout;
4833 85710 : mod = sql_func_mod(op->func);
4834 85486 : aggrfunc = backend_function_imp(be, op->func);
4835 :
4836 85646 : if (LANG_INT_OR_MAL(op->func->lang)) {
4837 85523 : if (strcmp(aggrfunc, "avg") == 0)
4838 : avg = 1;
4839 84150 : if (avg || strcmp(aggrfunc, "sum") == 0 || strcmp(aggrfunc, "prod") == 0
4840 77036 : || strcmp(aggrfunc, "str_group_concat") == 0)
4841 : complex_aggr = true;
4842 85523 : if (restype == TYPE_dbl)
4843 1564 : avg = 0;
4844 : }
4845 :
4846 171292 : int argc = 1
4847 85646 : + 2 * avg
4848 85646 : + (LANG_EXT(op->func->lang) != 0)
4849 85646 : + 2 * (op->func->lang == FUNC_LANG_C || op->func->lang == FUNC_LANG_CPP)
4850 85646 : + (op->func->lang == FUNC_LANG_PY || op->func->lang == FUNC_LANG_R)
4851 85646 : + (op1->type != st_list ? 1 : list_length(op1->op4.lval))
4852 85646 : + (grp ? 4 : avg + 1);
4853 :
4854 85646 : if (grp) {
4855 6726 : char *aggrF = SA_NEW_ARRAY(be->mvc->sa, char, strlen(aggrfunc) + 4);
4856 6726 : if (!aggrF)
4857 0 : goto bailout;
4858 6726 : stpcpy(stpcpy(aggrF, "sub"), aggrfunc);
4859 6726 : aggrfunc = aggrF;
4860 6726 : if ((grp && grp->nr < 0) || (ext && ext->nr < 0))
4861 0 : goto bailout;
4862 :
4863 6726 : q = newStmtArgs(mb, mod, aggrfunc, argc);
4864 6726 : if (q == NULL)
4865 0 : goto bailout;
4866 6726 : setVarType(mb, getArg(q, 0), newBatType(restype));
4867 6726 : 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 78920 : q = newStmtArgs(mb, mod, aggrfunc, argc);
4873 79180 : if (q == NULL)
4874 0 : goto bailout;
4875 79180 : if (complex_aggr) {
4876 6783 : setVarType(mb, getArg(q, 0), restype);
4877 6783 : 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 85906 : if (LANG_EXT(op->func->lang))
4885 47 : q = pushPtr(mb, q, op->func);
4886 85910 : if (op->func->lang == FUNC_LANG_R ||
4887 85875 : 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 85909 : if (op1->type != st_list) {
4902 80129 : q = pushArgument(mb, q, op1->nr);
4903 : } else {
4904 5780 : int i;
4905 5780 : node *n;
4906 :
4907 11982 : for (i=0, n = op1->op4.lval->h; n; n = n->next, i++) {
4908 6201 : stmt *op = n->data;
4909 :
4910 6201 : if (stmt_nr)
4911 : q = pushArgument(mb, q, stmt_nr[i]);
4912 : else
4913 6201 : q = pushArgument(mb, q, op->nr);
4914 : }
4915 : }
4916 85908 : if (grp) {
4917 6726 : q = pushArgument(mb, q, grp->nr);
4918 6726 : q = pushArgument(mb, q, ext->nr);
4919 6726 : if (LANG_INT_OR_MAL(op->func->lang)) {
4920 6699 : if (avg) /* push nil candidates */
4921 96 : q = pushNilBat(mb, q);
4922 6699 : q = pushBit(mb, q, no_nil);
4923 : }
4924 79182 : } 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 77541 : } 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 77541 : } 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 85908 : bool enabled = be->mvc->sa->eb.enabled;
4934 85908 : be->mvc->sa->eb.enabled = false;
4935 85908 : stmt *s = stmt_create(be->mvc->sa, st_aggr);
4936 85894 : be->mvc->sa->eb.enabled = enabled;
4937 85894 : if(!s) {
4938 0 : freeInstruction(q);
4939 0 : goto bailout;
4940 : }
4941 85894 : s->op1 = op1;
4942 85894 : if (grp) {
4943 6726 : s->op2 = grp;
4944 6726 : s->op3 = ext;
4945 6726 : s->nrcols = 1;
4946 : } else {
4947 79168 : if (!reduce)
4948 0 : s->nrcols = 1;
4949 : }
4950 85894 : s->key = reduce;
4951 85894 : s->aggr = reduce;
4952 85894 : s->flag = no_nil;
4953 85894 : s->op4.funcval = op;
4954 85894 : s->nr = getDestVar(q);
4955 85894 : s->q = q;
4956 85894 : pushInstruction(mb, q);
4957 85894 : 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 5144466 : stmt_alias_(backend *be, stmt *op1, int label, sql_alias *tname, const char *alias)
4967 : {
4968 5144466 : assert(label);
4969 5144466 : stmt *s = stmt_create(be->mvc->sa, st_alias);
4970 5145303 : if(!s) {
4971 : return NULL;
4972 : }
4973 5145303 : s->label = label;
4974 5145303 : s->op1 = op1;
4975 5145303 : s->nrcols = op1->nrcols;
4976 5145303 : s->key = op1->key;
4977 5145303 : s->aggr = op1->aggr;
4978 5145303 : s->multiset = op1->multiset;
4979 5145303 : s->nested = op1->nested;
4980 5145303 : s->virt = op1->virt;
4981 5145303 : s->subtype = op1->subtype;
4982 :
4983 5145303 : s->tname = tname;
4984 5145303 : s->cname = alias;
4985 5145303 : s->nr = op1->nr;
4986 5145303 : s->q = op1->q;
4987 5145303 : return s;
4988 : }
4989 :
4990 : stmt *
4991 4562428 : 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 4562428 : return stmt_alias_(be, op1, label, tname, alias);
5000 : }
5001 :
5002 : stmt *
5003 582146 : stmt_as(backend *be, stmt *s, stmt *org)
5004 : {
5005 582146 : assert(org->type == st_alias);
5006 582146 : return stmt_alias_(be, s, org->label, org->tname, org->cname);
5007 : }
5008 :
5009 : sql_subtype *
5010 1659565 : tail_type(stmt *st)
5011 : {
5012 1659565 : if (st->subtype.type)
5013 82165 : return &st->subtype;
5014 8639404 : for (;;) {
5015 8639404 : switch (st->type) {
5016 37114 : case st_const:
5017 37114 : st = st->op2;
5018 37114 : continue;
5019 3365 : 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 3365 : 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 3368583 : case st_alias:
5033 3368583 : 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 3848306 : st = st->op1;
5042 3848306 : continue;
5043 0 : case st_list:
5044 0 : st = st->op4.lval->t->data;
5045 0 : continue;
5046 934087 : case st_bat:
5047 934087 : 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 3176602 : if (st->flag == cmp_project) {
5059 3176584 : st = st->op2;
5060 3176584 : continue;
5061 : }
5062 : /* fall through */
5063 : case st_reorder:
5064 : case st_group:
5065 : case st_tid:
5066 : case st_mirror:
5067 14582 : return sql_bind_localtype("oid");
5068 3222 : case st_result:
5069 3222 : return &st->subtype;
5070 0 : case st_table_clear:
5071 0 : return sql_bind_localtype("lng");
5072 171194 : case st_aggr:
5073 : case st_Nop: {
5074 171194 : list *res = st->op4.funcval->res;
5075 :
5076 171194 : if (res && list_length(res) == 1)
5077 171194 : return res->h->data;
5078 :
5079 : return NULL;
5080 : }
5081 191815 : case st_atom:
5082 191815 : return atom_type(st->op4.aval);
5083 255973 : case st_convert:
5084 : case st_temp:
5085 : case st_single:
5086 : case st_rs_column:
5087 255973 : 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 6727 : stmt_has_null(stmt *s)
5105 : {
5106 21155 : 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 8252 : case st_alias:
5114 8252 : return stmt_has_null(s->op1);
5115 6176 : case st_join:
5116 6176 : return stmt_has_null(s->op2);
5117 4276 : case st_bat:
5118 4276 : return s->op4.cval->null;
5119 :
5120 2451 : default:
5121 2451 : 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 2687127 : column_name(allocator *sa, stmt *st)
5155 : {
5156 2687127 : if (!st->cname)
5157 0 : st->cname = _column_name(sa, st);
5158 2687127 : 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 2671804 : table_name(allocator *sa, stmt *st)
5229 : {
5230 2671804 : (void)sa;
5231 2671804 : return st->tname;
5232 : }
5233 :
5234 : stmt *
5235 1120 : stmt_cond(backend *be, stmt *cond, stmt *outer, int loop /* 0 if, 1 while */, int anti )
5236 : {
5237 1120 : MalBlkPtr mb = be->mb;
5238 1120 : InstrPtr q = NULL;
5239 :
5240 1120 : if (cond->nr < 0)
5241 0 : goto bailout;
5242 1120 : if (anti) {
5243 25 : sql_subtype *bt = sql_bind_localtype("bit");
5244 25 : sql_subfunc *not = sql_bind_func(be->mvc, "sys", "not", bt, NULL, F_FUNC, true, true);
5245 25 : sql_subfunc *or = sql_bind_func(be->mvc, "sys", "or", bt, bt, F_FUNC, true, true);
5246 25 : sql_subfunc *isnull = sql_bind_func(be->mvc, "sys", "isnull", bt, NULL, F_FUNC, true, true);
5247 25 : cond = stmt_binop(be,
5248 : stmt_unop(be, cond, NULL, not),
5249 : stmt_unop(be, cond, NULL, isnull), NULL, or);
5250 : }
5251 1120 : if (!loop) { /* if */
5252 1103 : q = newAssignment(mb);
5253 1103 : if (q == NULL)
5254 0 : goto bailout;
5255 1103 : q->barrier = BARRIERsymbol;
5256 1103 : 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 1120 : bool enabled = be->mvc->sa->eb.enabled;
5279 1120 : be->mvc->sa->eb.enabled = false;
5280 1120 : stmt *s = stmt_create(be->mvc->sa, st_cond);
5281 1120 : be->mvc->sa->eb.enabled = enabled;
5282 1120 : if(!s) {
5283 0 : freeInstruction(q);
5284 0 : goto bailout;
5285 : }
5286 1120 : s->flag = be->mvc_var; /* keep the mvc_var of the outer context */
5287 1120 : s->loop = loop;
5288 1120 : s->op1 = cond;
5289 1120 : s->nr = getArg(q, 0);
5290 1120 : pushInstruction(mb, q);
5291 1120 : 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 1120 : stmt_control_end(backend *be, stmt *cond)
5301 : {
5302 1120 : MalBlkPtr mb = be->mb;
5303 1120 : InstrPtr q = NULL;
5304 :
5305 1120 : if (cond->nr < 0)
5306 0 : goto bailout;
5307 :
5308 1120 : 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 1103 : q = newAssignment(mb);
5319 1103 : if (q == NULL)
5320 0 : goto bailout;
5321 1103 : getArg(q, 0) = cond->nr;
5322 1103 : q->argc = q->retc = 1;
5323 1103 : q->barrier = EXITsymbol;
5324 : }
5325 1120 : be->mvc_var = cond->flag; /* restore old mvc_var from before the barrier */
5326 1120 : bool enabled = be->mvc->sa->eb.enabled;
5327 1120 : be->mvc->sa->eb.enabled = false;
5328 1120 : stmt *s = stmt_create(be->mvc->sa, st_control_end);
5329 1120 : be->mvc->sa->eb.enabled = enabled;
5330 1120 : if(!s) {
5331 0 : freeInstruction(q);
5332 0 : goto bailout;
5333 : }
5334 1120 : s->op1 = cond;
5335 1120 : s->nr = getArg(q, 0);
5336 1120 : pushInstruction(mb, q);
5337 1120 : 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 664 : stmt_return(backend *be, stmt *val, int nr_declared_tables)
5374 : {
5375 664 : MalBlkPtr mb = be->mb;
5376 664 : InstrPtr q = NULL;
5377 :
5378 664 : if (val->nr < 0)
5379 0 : goto bailout;
5380 664 : int args = val->type == st_table ? 2 * list_length(val->op1->op4.lval) : 0;
5381 208 : if (args < MAXARG)
5382 : args = MAXARG;
5383 664 : q = newInstructionArgs(mb, NULL, NULL, args);
5384 664 : if (q == NULL)
5385 0 : goto bailout;
5386 664 : q->barrier= RETURNsymbol;
5387 664 : 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 456 : getArg(q, 0) = getArg(getInstrPtr(mb, 0), 0);
5393 456 : q = pushArgument(mb, q, val->nr);
5394 : }
5395 :
5396 664 : bool enabled = be->mvc->sa->eb.enabled;
5397 664 : be->mvc->sa->eb.enabled = false;
5398 664 : stmt *s = stmt_create(be->mvc->sa, st_return);
5399 664 : be->mvc->sa->eb.enabled = enabled;
5400 664 : if(!s) {
5401 0 : freeInstruction(q);
5402 0 : goto bailout;
5403 : }
5404 664 : s->op1 = val;
5405 664 : s->flag = nr_declared_tables;
5406 664 : s->nr = getDestVar(q);
5407 664 : s->q = q;
5408 664 : pushInstruction(mb, q);
5409 664 : 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 1039 : char *buf, levelstr[16];
5427 :
5428 1039 : if (!val) {
5429 : /* drop declared table */
5430 0 : assert(0);
5431 : }
5432 :
5433 1039 : assert(!sname);
5434 1039 : snprintf(levelstr, sizeof(levelstr), "%d", level);
5435 1039 : buf = SA_NEW_ARRAY(be->mvc->sa, char, strlen(levelstr) + strlen(varname) + 3);
5436 1039 : if (!buf)
5437 0 : goto bailout;
5438 1039 : stpcpy(stpcpy(stpcpy(stpcpy(buf, "A"), levelstr), "%"), varname); /* mangle variable name */
5439 1039 : 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 383 : assert(sname); /* all global variables have a schema */
5449 383 : 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 1423 : bool enabled = be->mvc->sa->eb.enabled;
5462 1423 : be->mvc->sa->eb.enabled = false;
5463 1423 : stmt *s = stmt_create(be->mvc->sa, st_assign);
5464 1423 : be->mvc->sa->eb.enabled = enabled;
5465 1423 : if(!s) {
5466 0 : goto bailout;
5467 : }
5468 1423 : s->op2 = val;
5469 1423 : s->flag = (level << 1);
5470 1423 : s->q = q;
5471 1423 : s->nr = 1;
5472 1423 : 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 26580 : const_column(backend *be, stmt *val)
5482 : {
5483 26580 : sql_subtype *ct = tail_type(val);
5484 26580 : MalBlkPtr mb = be->mb;
5485 26580 : InstrPtr q = NULL;
5486 26580 : int tt = ct->type->localtype;
5487 :
5488 26580 : if (val->nr < 0)
5489 0 : goto bailout;
5490 26580 : q = newStmt(mb, batRef, singleRef);
5491 26580 : if (q == NULL)
5492 0 : goto bailout;
5493 26580 : setVarType(mb, getArg(q, 0), newBatType(tt));
5494 26580 : q = pushArgument(mb, q, val->nr);
5495 :
5496 26580 : bool enabled = be->mvc->sa->eb.enabled;
5497 26580 : be->mvc->sa->eb.enabled = false;
5498 26580 : stmt *s = stmt_create(be->mvc->sa, st_single);
5499 26580 : be->mvc->sa->eb.enabled = enabled;
5500 26580 : if(!s) {
5501 0 : freeInstruction(q);
5502 0 : goto bailout;
5503 : }
5504 26580 : s->op1 = val;
5505 26580 : s->subtype = *ct;
5506 26580 : s->nrcols = 1;
5507 :
5508 26580 : s->tname = val->tname;
5509 26580 : s->cname = val->cname;
5510 26580 : s->nr = getDestVar(q);
5511 26580 : s->q = q;
5512 26580 : pushInstruction(mb, q);
5513 26580 : 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 1674855 : stmt_rename(backend *be, sql_exp *exp, stmt *s )
5574 : {
5575 1674855 : int label = exp_get_label(exp);
5576 1674816 : const char *name = exp_name(exp);
5577 1675099 : sql_alias *rname = exp_relname(exp);
5578 1674787 : stmt *o = s;
5579 :
5580 1674787 : if (!name && exp_is_atom(exp))
5581 0 : name = sa_strdup(be->mvc->sa, "single_value");
5582 0 : assert(name);
5583 1674787 : s = stmt_alias(be, s, label, rname, name);
5584 1675372 : if (o->flag & OUTER_ZERO)
5585 521 : s->flag |= OUTER_ZERO;
5586 1675372 : return s;
5587 : }
|