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