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_subquery.h"
15 : #include "gdk_subquery.h"
16 :
17 : str
18 445 : zero_or_one_error(ptr ret, const bat *bid, const bit *err)
19 : {
20 445 : BAT *b;
21 445 : BUN c;
22 445 : size_t _s;
23 445 : BATiter bi;
24 445 : const void *p = NULL;
25 :
26 445 : if ((b = BATdescriptor(*bid)) == NULL)
27 0 : throw(SQL, "sql.zero_or_one", SQLSTATE(HY005) "Cannot access column descriptor");
28 445 : c = BATcount(b);
29 445 : if (c == 0) {
30 37 : bi = bat_iterator(NULL);
31 37 : p = ATOMnilptr(b->ttype);
32 408 : } else if (c == 1 || (c > 1 && *err == false)) {
33 388 : bi = bat_iterator(b);
34 388 : p = BUNtail(bi, 0);
35 : } else {
36 20 : BBPunfix(b->batCacheid);
37 20 : throw(SQL, "sql.zero_or_one", SQLSTATE(21000) "Cardinality violation, scalar value expected");
38 : }
39 425 : _s = ATOMsize(ATOMtype(b->ttype));
40 425 : if (b->ttype == TYPE_void)
41 0 : p = &oid_nil;
42 425 : if (ATOMextern(b->ttype)) {
43 312 : _s = ATOMlen(ATOMtype(b->ttype), p);
44 312 : *(ptr *) ret = GDKmalloc(_s);
45 312 : if (*(ptr *) ret == NULL) {
46 0 : bat_iterator_end(&bi);
47 0 : BBPunfix(b->batCacheid);
48 0 : throw(SQL, "sql.zero_or_one", SQLSTATE(HY013) MAL_MALLOC_FAIL);
49 : }
50 312 : memcpy(*(ptr *) ret, p, _s);
51 113 : } else if (b->ttype == TYPE_bat) {
52 0 : bat bid = *(bat *) p;
53 0 : if ((*(BAT **) ret = BATdescriptor(bid)) == NULL){
54 0 : bat_iterator_end(&bi);
55 0 : BBPunfix(b->batCacheid);
56 0 : throw(SQL, "sql.zero_or_one", SQLSTATE(HY005) "Cannot access column descriptor");
57 : }
58 113 : } else if (_s == 4) {
59 43 : *(int *) ret = *(int *) p;
60 : } else if (_s == 1) {
61 2 : *(bte *) ret = *(bte *) p;
62 : } else if (_s == 2) {
63 0 : *(sht *) ret = *(sht *) p;
64 : } else if (_s == 8) {
65 60 : *(lng *) ret = *(lng *) p;
66 : #ifdef HAVE_HGE
67 : } else if (_s == 16) {
68 8 : *(hge *) ret = *(hge *) p;
69 : #endif
70 : } else {
71 0 : memcpy(ret, p, _s);
72 : }
73 425 : bat_iterator_end(&bi);
74 425 : BBPunfix(b->batCacheid);
75 425 : return MAL_SUCCEED;
76 : }
77 :
78 : str
79 0 : zero_or_one_error_bat(ptr ret, const bat *bid, const bat *err)
80 : {
81 0 : bit t = FALSE;
82 0 : (void)err;
83 0 : return zero_or_one_error(ret, bid, &t);
84 : }
85 :
86 : str
87 445 : zero_or_one(ptr ret, const bat *bid)
88 : {
89 445 : bit t = TRUE;
90 445 : return zero_or_one_error(ret, bid, &t);
91 : }
92 :
93 : str
94 0 : SQLsubzero_or_one(bat *ret, const bat *bid, const bat *gid, const bat *eid, bit *no_nil)
95 : {
96 0 : gdk_return r;
97 0 : BAT *ng = NULL, *h = NULL, *g = NULL;
98 0 : lng max = 0;
99 :
100 0 : (void)no_nil;
101 0 : (void)eid;
102 :
103 0 : if (!(g = BATdescriptor(*gid)))
104 0 : throw(MAL, "sql.subzero_or_one", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
105 0 : r = BATgroup(&ng, NULL, &h, g, NULL, NULL, NULL, NULL);
106 0 : BBPunfix(g->batCacheid);
107 0 : if (r != GDK_SUCCEED)
108 0 : throw(MAL, "sql.subzero_or_one", GDK_EXCEPTION);
109 :
110 0 : BBPreclaim(ng);
111 0 : BATmax(h, &max);
112 0 : BBPunfix(h->batCacheid);
113 :
114 0 : if (max != lng_nil && max > 1)
115 0 : throw(SQL, "sql.subzero_or_one", SQLSTATE(M0M29) "zero_or_one: cardinality violation, scalar expression expected");
116 0 : BBPretain(*ret = *bid);
117 0 : return MAL_SUCCEED;
118 : }
119 :
120 : #define SQLall_imp(TPE) \
121 : do { \
122 : TPE val = TPE##_nil; \
123 : if (c > 0) { \
124 : TPE *restrict bp = (TPE*)bi.base; \
125 : if (c == 1 || (bi.sorted && bi.revsorted)) { \
126 : val = bp[0]; \
127 : } else { \
128 : for (; q < c; q++) { /* find first non nil */ \
129 : val = bp[q]; \
130 : if (!is_##TPE##_nil(val)) \
131 : break; \
132 : } \
133 : for (; q < c; q++) { \
134 : TPE pp = bp[q]; \
135 : if (val != pp && !is_##TPE##_nil(pp)) { /* values != and not nil */ \
136 : val = TPE##_nil; \
137 : break; \
138 : } \
139 : } \
140 : } \
141 : } \
142 : *(TPE *) ret = val; \
143 : } while (0)
144 :
145 : str
146 34 : SQLall(ptr ret, const bat *bid)
147 : {
148 34 : BAT *b;
149 34 : BUN c, q = 0;
150 :
151 34 : if ((b = BATdescriptor(*bid)) == NULL)
152 0 : throw(SQL, "sql.all", SQLSTATE(HY005) "Cannot access column descriptor");
153 :
154 34 : c = BATcount(b);
155 34 : if (b->ttype == TYPE_void) {
156 0 : oid p = oid_nil;
157 0 : memcpy(ret, &p, sizeof(oid));
158 : } else {
159 34 : BATiter bi = bat_iterator(b);
160 57 : switch (ATOMbasetype(bi.type)) {
161 13 : case TYPE_bte:
162 13 : SQLall_imp(bte);
163 13 : break;
164 1 : case TYPE_sht:
165 4 : SQLall_imp(sht);
166 1 : break;
167 5 : case TYPE_int:
168 10 : SQLall_imp(int);
169 5 : break;
170 9 : case TYPE_lng:
171 9 : SQLall_imp(lng);
172 9 : break;
173 : #ifdef HAVE_HGE
174 0 : case TYPE_hge:
175 0 : SQLall_imp(hge);
176 0 : break;
177 : #endif
178 0 : case TYPE_flt:
179 0 : SQLall_imp(flt);
180 0 : break;
181 0 : case TYPE_dbl:
182 0 : SQLall_imp(dbl);
183 0 : break;
184 6 : default: {
185 6 : int (*ocmp) (const void *, const void *) = ATOMcompare(bi.type);
186 6 : const void *n = ATOMnilptr(bi.type), *p = n;
187 6 : size_t s;
188 :
189 6 : if (c > 0) {
190 6 : if (c == 1 || (bi.sorted && bi.revsorted)) {
191 5 : p = BUNtail(bi, 0);
192 : } else {
193 1 : for (; q < c; q++) { /* find first non nil */
194 1 : p = BUNtail(bi, q);
195 1 : if (ocmp(n, p) != 0)
196 : break;
197 : }
198 2 : for (; q < c; q++) {
199 2 : const void *pp = BUNtail(bi, q);
200 2 : if (ocmp(p, pp) != 0 && ocmp(n, pp) != 0) { /* values != and not nil */
201 : p = n;
202 : break;
203 : }
204 : }
205 : }
206 : }
207 12 : s = ATOMlen(ATOMtype(bi.type), p);
208 6 : if (ATOMextern(bi.type)) {
209 5 : *(ptr *) ret = GDKmalloc(s);
210 5 : if (*(ptr *) ret == NULL) {
211 0 : bat_iterator_end(&bi);
212 0 : BBPunfix(b->batCacheid);
213 0 : throw(SQL, "sql.all", SQLSTATE(HY013) MAL_MALLOC_FAIL);
214 : }
215 5 : memcpy(*(ptr *)ret, p, s);
216 : } else
217 1 : memcpy(ret, p, s);
218 : }
219 : }
220 34 : bat_iterator_end(&bi);
221 : }
222 34 : BBPunfix(b->batCacheid);
223 34 : return MAL_SUCCEED;
224 : }
225 :
226 : str
227 38 : SQLall_grp(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
228 : {
229 38 : bat *ret = getArgReference_bat(stk, pci, 0);
230 38 : bat *lp = getArgReference_bat(stk, pci, 1);
231 38 : bat *gp = getArgReference_bat(stk, pci, 2);
232 38 : bat *gpe = getArgReference_bat(stk, pci, 3);
233 38 : bat *sp = pci->argc == 6 ? getArgReference_bat(stk, pci, 4) : NULL;
234 : //bit *no_nil = getArgReference_bit(stk, pci, pci->argc == 6 ? 5 : 4); no_nil argument is ignored
235 38 : BAT *l = NULL, *g = NULL, *e = NULL, *s = NULL, *res = NULL;
236 :
237 38 : (void)cntxt;
238 38 : (void)mb;
239 38 : l = BATdescriptor(*lp);
240 38 : g = BATdescriptor(*gp);
241 38 : e = BATdescriptor(*gpe);
242 38 : if (sp)
243 0 : s = BATdescriptor(*sp);
244 :
245 38 : if (!l || !g || !e || (sp && !s)) {
246 0 : BBPreclaim(l);
247 0 : BBPreclaim(g);
248 0 : BBPreclaim(e);
249 0 : BBPreclaim(s);
250 0 : throw(MAL, "sql.all =", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
251 : }
252 :
253 38 : res = BATall_grp(l, g, e, s);
254 :
255 38 : BBPunfix(l->batCacheid);
256 38 : BBPunfix(g->batCacheid);
257 38 : BBPunfix(e->batCacheid);
258 38 : BBPreclaim(s);
259 38 : if (res == NULL)
260 0 : throw(MAL, "sql.all =", GDK_EXCEPTION);
261 38 : *ret = res->batCacheid;
262 38 : BBPkeepref(res);
263 38 : return MAL_SUCCEED;
264 : }
265 :
266 : #define SQLnil_imp(TPE) \
267 : do { \
268 : TPE *restrict bp = (TPE*)bi.base; \
269 : for (BUN q = 0; q < o; q++) { \
270 : if (is_##TPE##_nil(bp[q])) { \
271 : *ret = TRUE; \
272 : break; \
273 : } \
274 : } \
275 : } while (0)
276 :
277 : str
278 93 : SQLnil(bit *ret, const bat *bid)
279 : {
280 93 : BAT *b;
281 :
282 93 : if ((b = BATdescriptor(*bid)) == NULL) {
283 0 : throw(SQL, "sql.nil", SQLSTATE(HY005) "Cannot access column descriptor");
284 : }
285 93 : *ret = FALSE;
286 93 : if (BATcount(b) == 0)
287 18 : *ret = bit_nil;
288 93 : if (BATcount(b) > 0) {
289 75 : BUN o = BATcount(b);
290 :
291 75 : BATiter bi = bat_iterator(b);
292 144 : switch (ATOMbasetype(bi.type)) {
293 19 : case TYPE_bte:
294 49 : SQLnil_imp(bte);
295 : break;
296 1 : case TYPE_sht:
297 2 : SQLnil_imp(sht);
298 : break;
299 41 : case TYPE_int:
300 3215 : SQLnil_imp(int);
301 : break;
302 6 : case TYPE_lng:
303 11 : SQLnil_imp(lng);
304 : break;
305 : #ifdef HAVE_HGE
306 2 : case TYPE_hge:
307 4 : SQLnil_imp(hge);
308 : break;
309 : #endif
310 0 : case TYPE_flt:
311 0 : SQLnil_imp(flt);
312 : break;
313 0 : case TYPE_dbl:
314 0 : SQLnil_imp(dbl);
315 : break;
316 6 : default: {
317 6 : int (*ocmp) (const void *, const void *) = ATOMcompare(bi.type);
318 6 : const void *restrict nilp = ATOMnilptr(bi.type);
319 :
320 13 : for (BUN q = 0; q < o; q++) {
321 8 : const void *restrict c = BUNtail(bi, q);
322 8 : if (ocmp(nilp, c) == 0) {
323 1 : *ret = TRUE;
324 1 : break;
325 : }
326 : }
327 : }
328 : }
329 75 : bat_iterator_end(&bi);
330 : }
331 93 : BBPunfix(b->batCacheid);
332 93 : return MAL_SUCCEED;
333 : }
334 :
335 : str
336 74 : SQLnil_grp(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
337 : {
338 74 : bat *ret = getArgReference_bat(stk, pci, 0);
339 74 : bat *lp = getArgReference_bat(stk, pci, 1);
340 74 : bat *gp = getArgReference_bat(stk, pci, 2);
341 74 : bat *gpe = getArgReference_bat(stk, pci, 3);
342 74 : bat *sp = pci->argc == 6 ? getArgReference_bat(stk, pci, 4) : NULL;
343 : //bit *no_nil = getArgReference_bit(stk, pci, pci->argc == 6 ? 5 : 4); no_nil argument is ignored
344 74 : BAT *l = NULL, *g = NULL, *e = NULL, *s = NULL, *res = NULL;
345 :
346 74 : (void)cntxt;
347 74 : (void)mb;
348 74 : l = BATdescriptor(*lp);
349 74 : g = BATdescriptor(*gp);
350 74 : e = BATdescriptor(*gpe);
351 74 : if (sp)
352 0 : s = BATdescriptor(*sp);
353 :
354 74 : if (!l || !g || !e || (sp && !s)) {
355 0 : BBPreclaim(l);
356 0 : BBPreclaim(g);
357 0 : BBPreclaim(e);
358 0 : BBPreclaim(s);
359 0 : throw(MAL, "sql.nil", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
360 : }
361 :
362 74 : res = BATnil_grp(l, g, e, s);
363 :
364 74 : BBPunfix(l->batCacheid);
365 74 : BBPunfix(g->batCacheid);
366 74 : BBPunfix(e->batCacheid);
367 74 : BBPreclaim(s);
368 74 : if (res == NULL)
369 0 : throw(MAL, "sql.nil", GDK_EXCEPTION);
370 74 : *ret = res->batCacheid;
371 74 : BBPkeepref(res);
372 74 : return MAL_SUCCEED;
373 : }
374 :
375 : static inline bit
376 184 : any_cmp(const bit cmp, const bit nl, const bit nr)
377 : {
378 184 : if (nr == bit_nil) /* empty -> FALSE */
379 : return FALSE;
380 155 : else if (cmp == TRUE)
381 : return TRUE;
382 90 : else if (nl == TRUE || nr == TRUE)
383 : return bit_nil;
384 : return FALSE;
385 : }
386 :
387 : #define ANY_ALL_CMP_BULK(FUNC, CMP, NL, NR) \
388 : do { \
389 : for (BUN i = 0 ; i < q ; i++) { \
390 : res_l[i] = FUNC(CMP, NL, NR); \
391 : has_nil |= is_bit_nil(res_l[i]); \
392 : } \
393 : } while (0);
394 :
395 : str
396 47 : SQLany_cmp(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
397 : {
398 47 : bat *ret = isaBatType(getArgType(mb, pci, 0)) ? getArgReference_bat(stk, pci, 0) : NULL;
399 47 : bat *cid = isaBatType(getArgType(mb, pci, 1)) ? getArgReference_bat(stk, pci, 1) : NULL;
400 47 : bat *nlid = isaBatType(getArgType(mb, pci, 2)) ? getArgReference_bat(stk, pci, 2) : NULL;
401 47 : bat *nrid = isaBatType(getArgType(mb, pci, 3)) ? getArgReference_bat(stk, pci, 3) : NULL;
402 47 : BAT *cmp = NULL, *nl = NULL, *nr = NULL, *res = NULL;
403 47 : str msg = MAL_SUCCEED;
404 47 : BUN q = 0;
405 47 : bit *restrict res_l = NULL, *cmp_l = NULL, *nl_l = NULL, *nr_l = NULL, cmp_at = FALSE, nl_at = FALSE, nr_at = FALSE, has_nil = 0;
406 47 : BATiter cmpi, nli, nri;
407 :
408 47 : (void) cntxt;
409 47 : if (cid && (cmp = BATdescriptor(*cid)) == NULL) {
410 0 : msg = createException(SQL, "sql.any_cmp", SQLSTATE(HY005) "Cannot access column descriptor");
411 0 : goto bailout;
412 : }
413 47 : if (nlid && (nl = BATdescriptor(*nlid)) == NULL) {
414 0 : msg = createException(SQL, "sql.any_cmp", SQLSTATE(HY005) "Cannot access column descriptor");
415 0 : goto bailout;
416 : }
417 47 : if (nrid && (nr = BATdescriptor(*nrid)) == NULL) {
418 0 : msg = createException(SQL, "sql.any_cmp", SQLSTATE(HY005) "Cannot access column descriptor");
419 0 : goto bailout;
420 : }
421 47 : cmpi = bat_iterator(cmp);
422 47 : nli = bat_iterator(nl);
423 47 : nri = bat_iterator(nr);
424 47 : if (cmp)
425 47 : cmp_l = (bit *) cmpi.base;
426 : else
427 0 : cmp_at = *getArgReference_bit(stk, pci, 1);
428 47 : if (nl)
429 32 : nl_l = (bit *) nli.base;
430 : else
431 15 : nl_at = *getArgReference_bit(stk, pci, 2);
432 47 : if (nr)
433 47 : nr_l = (bit *) nri.base;
434 : else
435 0 : nr_at = *getArgReference_bit(stk, pci, 3);
436 :
437 47 : if (cmp || nl || nr) {
438 47 : q = cmp ? cmpi.count : nl ? nli.count : nri.count;
439 47 : if (!(res = COLnew(cmp ? cmp->hseqbase : nl ? nl->hseqbase : nr->hseqbase, TYPE_bit, q, TRANSIENT))) {
440 0 : msg = createException(SQL, "sql.any_cmp", SQLSTATE(HY013) MAL_MALLOC_FAIL);
441 0 : goto bailout1;
442 : }
443 47 : res_l = (bit *) Tloc(res, 0);
444 : }
445 :
446 47 : if (!cmp && !nl && !nr) {
447 0 : bit *b = getArgReference_bit(stk, pci, 0);
448 0 : *b = any_cmp(cmp_at, nl_at, nr_at);
449 47 : } else if (cmp && !nl && !nr) {
450 0 : ANY_ALL_CMP_BULK(any_cmp, cmp_l[i], nl_at, nr_at);
451 47 : } else if (!cmp && nl && !nr) {
452 0 : ANY_ALL_CMP_BULK(any_cmp, cmp_at, nl_l[i], nr_at);
453 47 : } else if (!cmp && !nl && nr) {
454 0 : ANY_ALL_CMP_BULK(any_cmp, cmp_at, nl_at, nr_l[i]);
455 47 : } else if (!cmp && nl && nr) {
456 0 : ANY_ALL_CMP_BULK(any_cmp, cmp_at, nl_l[i], nr_l[i]);
457 47 : } else if (cmp && !nl && nr) {
458 35 : ANY_ALL_CMP_BULK(any_cmp, cmp_l[i], nl_at, nr_l[i]);
459 32 : } else if (cmp && nl && !nr) {
460 0 : ANY_ALL_CMP_BULK(any_cmp, cmp_l[i], nl_l[i], nr_at);
461 : } else {
462 196 : ANY_ALL_CMP_BULK(any_cmp, cmp_l[i], nl_l[i], nr_l[i]);
463 : }
464 :
465 47 : if (res) {
466 47 : BATsetcount(res, q);
467 47 : res->tkey = BATcount(res) <= 1;
468 47 : res->tsorted = BATcount(res) <= 1;
469 47 : res->trevsorted = BATcount(res) <= 1;
470 47 : res->tnil = has_nil;
471 47 : res->tnonil = !has_nil;
472 : }
473 0 : bailout1:
474 47 : bat_iterator_end(&cmpi);
475 47 : bat_iterator_end(&nli);
476 47 : bat_iterator_end(&nri);
477 :
478 47 : bailout:
479 47 : if (res && !msg) {
480 47 : *ret = res->batCacheid;
481 47 : BBPkeepref(res);
482 0 : } else if (res)
483 0 : BBPreclaim(res);
484 47 : BBPreclaim(cmp);
485 47 : BBPreclaim(nl);
486 47 : BBPreclaim(nr);
487 47 : return msg;
488 : }
489 :
490 : static inline bit
491 802 : all_cmp(const bit cmp, const bit nl, const bit nr)
492 : {
493 802 : if (nr == bit_nil) /* empty -> TRUE */
494 : return TRUE;
495 481 : else if (cmp == FALSE || (cmp == bit_nil && !nl && !nr))
496 : return FALSE;
497 182 : else if (nl == TRUE || nr == TRUE)
498 : return bit_nil;
499 : else
500 75 : return cmp;
501 : return TRUE;
502 : }
503 :
504 : str
505 116 : SQLall_cmp(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
506 : {
507 116 : bat *ret = isaBatType(getArgType(mb, pci, 0)) ? getArgReference_bat(stk, pci, 0) : NULL;
508 116 : bat *cid = isaBatType(getArgType(mb, pci, 1)) ? getArgReference_bat(stk, pci, 1) : NULL;
509 116 : bat *nlid = isaBatType(getArgType(mb, pci, 2)) ? getArgReference_bat(stk, pci, 2) : NULL;
510 116 : bat *nrid = isaBatType(getArgType(mb, pci, 3)) ? getArgReference_bat(stk, pci, 3) : NULL;
511 116 : BAT *cmp = NULL, *nl = NULL, *nr = NULL, *res = NULL;
512 116 : str msg = MAL_SUCCEED;
513 116 : BUN q = 0;
514 116 : bit *restrict res_l = NULL, *cmp_l = NULL, *nl_l = NULL, *nr_l = NULL, cmp_at = FALSE, nl_at = FALSE, nr_at = FALSE, has_nil = 0;
515 116 : BATiter cmpi, nli, nri;
516 :
517 116 : (void) cntxt;
518 116 : if (cid && (cmp = BATdescriptor(*cid)) == NULL) {
519 0 : msg = createException(SQL, "sql.all_cmp", SQLSTATE(HY005) "Cannot access column descriptor");
520 0 : goto bailout;
521 : }
522 116 : if (nlid && (nl = BATdescriptor(*nlid)) == NULL) {
523 0 : msg = createException(SQL, "sql.all_cmp", SQLSTATE(HY005) "Cannot access column descriptor");
524 0 : goto bailout;
525 : }
526 116 : if (nrid && (nr = BATdescriptor(*nrid)) == NULL) {
527 0 : msg = createException(SQL, "sql.all_cmp", SQLSTATE(HY005) "Cannot access column descriptor");
528 0 : goto bailout;
529 : }
530 116 : cmpi = bat_iterator(cmp);
531 116 : nli = bat_iterator(nl);
532 116 : nri = bat_iterator(nr);
533 116 : if (cmp)
534 116 : cmp_l = (bit *) cmpi.base;
535 : else
536 0 : cmp_at = *getArgReference_bit(stk, pci, 1);
537 116 : if (nl)
538 79 : nl_l = (bit *) nli.base;
539 : else
540 37 : nl_at = *getArgReference_bit(stk, pci, 2);
541 116 : if (nr)
542 116 : nr_l = (bit *) nri.base;
543 : else
544 0 : nr_at = *getArgReference_bit(stk, pci, 3);
545 :
546 116 : if (cmp || nl || nr) {
547 116 : q = cmp ? cmpi.count : nl ? nli.count : nri.count;
548 116 : if (!(res = COLnew(cmp ? cmp->hseqbase : nl ? nl->hseqbase : nr->hseqbase, TYPE_bit, q, TRANSIENT))) {
549 0 : msg = createException(SQL, "sql.all_cmp", SQLSTATE(HY013) MAL_MALLOC_FAIL);
550 0 : goto bailout1;
551 : }
552 116 : res_l = (bit *) Tloc(res, 0);
553 : }
554 :
555 116 : if (!cmp && !nl && !nr) {
556 0 : bit *b = getArgReference_bit(stk, pci, 0);
557 0 : *b = all_cmp(cmp_at, nl_at, nr_at);
558 116 : } else if (cmp && !nl && !nr) {
559 0 : ANY_ALL_CMP_BULK(all_cmp, cmp_l[i], nl_at, nr_at);
560 116 : } else if (!cmp && nl && !nr) {
561 0 : ANY_ALL_CMP_BULK(all_cmp, cmp_at, nl_l[i], nr_at);
562 116 : } else if (!cmp && !nl && nr) {
563 0 : ANY_ALL_CMP_BULK(all_cmp, cmp_at, nl_at, nr_l[i]);
564 116 : } else if (!cmp && nl && nr) {
565 0 : ANY_ALL_CMP_BULK(all_cmp, cmp_at, nl_l[i], nr_l[i]);
566 116 : } else if (cmp && !nl && nr) {
567 88 : ANY_ALL_CMP_BULK(all_cmp, cmp_l[i], nl_at, nr_l[i]);
568 79 : } else if (cmp && nl && !nr) {
569 0 : ANY_ALL_CMP_BULK(all_cmp, cmp_l[i], nl_l[i], nr_at);
570 : } else {
571 830 : ANY_ALL_CMP_BULK(all_cmp, cmp_l[i], nl_l[i], nr_l[i]);
572 : }
573 :
574 116 : if (res) {
575 116 : BATsetcount(res, q);
576 116 : res->tkey = BATcount(res) <= 1;
577 116 : res->tsorted = BATcount(res) <= 1;
578 116 : res->trevsorted = BATcount(res) <= 1;
579 116 : res->tnil = has_nil;
580 116 : res->tnonil = !has_nil;
581 : }
582 0 : bailout1:
583 116 : bat_iterator_end(&cmpi);
584 116 : bat_iterator_end(&nli);
585 116 : bat_iterator_end(&nri);
586 :
587 116 : bailout:
588 116 : if (res && !msg) {
589 116 : *ret = res->batCacheid;
590 116 : BBPkeepref(res);
591 0 : } else if (res)
592 0 : BBPreclaim(res);
593 116 : BBPreclaim(cmp);
594 116 : BBPreclaim(nl);
595 116 : BBPreclaim(nr);
596 116 : return msg;
597 : }
598 :
599 : #define SQLanyequal_or_not_imp_single(TPE, OUTPUT) \
600 : do { \
601 : TPE *rp = (TPE*)ri.base, *lp = (TPE*)li.base, p = lp[0]; \
602 : for (BUN q = 0; q < o; q++) { \
603 : TPE c = rp[q]; \
604 : if (is_##TPE##_nil(c)) { \
605 : *ret = bit_nil; \
606 : } else if (p == c) { \
607 : *ret = OUTPUT; \
608 : break; \
609 : } \
610 : } \
611 : } while (0)
612 :
613 : #define SQLanyequal_or_not_imp_multi(TPE, CMP) \
614 : do { \
615 : TPE *rp = (TPE*)ri.base, *lp = (TPE*)li.base; \
616 : for (BUN q = 0; q < o; q++) { \
617 : TPE c = rp[q], d = lp[q]; \
618 : res_l[q] = (is_##TPE##_nil(c) || is_##TPE##_nil(d)) ? bit_nil : c CMP d; \
619 : } \
620 : } while (0)
621 :
622 : str
623 18 : SQLanyequal(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
624 : {
625 18 : bat *bret = isaBatType(getArgType(mb, pci, 0)) ? getArgReference_bat(stk, pci, 0) : NULL;
626 18 : bat *bid1 = getArgReference_bat(stk, pci, 1);
627 18 : bat *bid2 = getArgReference_bat(stk, pci, 2);
628 18 : BAT *res = NULL, *l = NULL, *r = NULL;
629 18 : str msg = MAL_SUCCEED;
630 18 : BUN o = 0;
631 18 : BATiter li, ri;
632 :
633 18 : (void) cntxt;
634 18 : if ((l = BATdescriptor(*bid1)) == NULL) {
635 0 : msg = createException(SQL, "sql.any =", SQLSTATE(HY005) "Cannot access column descriptor");
636 0 : goto bailout;
637 : }
638 18 : if ((r = BATdescriptor(*bid2)) == NULL) {
639 0 : msg = createException(SQL, "sql.any =", SQLSTATE(HY005) "Cannot access column descriptor");
640 0 : goto bailout;
641 : }
642 18 : if (l->ttype != r->ttype) {
643 0 : msg = createException(SQL, "sql.any =", SQLSTATE(42000) "sql.any = requires both arguments of the same type");
644 0 : goto bailout;
645 : }
646 :
647 18 : o = BATcount(r);
648 18 : ri = bat_iterator(r);
649 18 : li = bat_iterator(l);
650 18 : if (bret) {
651 0 : if (!(res = COLnew(r->hseqbase, TYPE_bit, o, TRANSIENT))) {
652 0 : msg = createException(SQL, "sql.any =", SQLSTATE(HY013) MAL_MALLOC_FAIL);
653 0 : goto bailout1;
654 : }
655 0 : bit *restrict res_l = (bit*) Tloc(res, 0);
656 :
657 0 : switch (ATOMbasetype(li.type)) {
658 0 : case TYPE_bte:
659 0 : SQLanyequal_or_not_imp_multi(bte, ==);
660 : break;
661 0 : case TYPE_sht:
662 0 : SQLanyequal_or_not_imp_multi(sht, ==);
663 : break;
664 0 : case TYPE_int:
665 0 : SQLanyequal_or_not_imp_multi(int, ==);
666 : break;
667 0 : case TYPE_lng:
668 0 : SQLanyequal_or_not_imp_multi(lng, ==);
669 : break;
670 : #ifdef HAVE_HGE
671 0 : case TYPE_hge:
672 0 : SQLanyequal_or_not_imp_multi(hge, ==);
673 : break;
674 : #endif
675 0 : case TYPE_flt:
676 0 : SQLanyequal_or_not_imp_multi(flt, ==);
677 : break;
678 0 : case TYPE_dbl:
679 0 : SQLanyequal_or_not_imp_multi(dbl, ==);
680 : break;
681 0 : default: {
682 0 : int (*ocmp) (const void *, const void *) = ATOMcompare(li.type);
683 0 : const void *nilp = ATOMnilptr(li.type);
684 :
685 0 : for (BUN q = 0; q < o; q++) {
686 0 : const void *c = BUNtail(ri, q), *d = BUNtail(li, q);
687 0 : res_l[q] = ocmp(nilp, c) == 0 || ocmp(nilp, d) == 0 ? bit_nil : ocmp(c, d) == 0;
688 : }
689 : }
690 : }
691 :
692 0 : BATsetcount(res, o);
693 0 : res->tkey = BATcount(res) <= 1;
694 0 : res->tsorted = BATcount(res) <= 1;
695 0 : res->trevsorted = BATcount(res) <= 1;
696 0 : res->tnil = li.nil || ri.nil;
697 0 : res->tnonil = li.nonil && ri.nonil;
698 : } else {
699 18 : bit *ret = getArgReference_bit(stk, pci, 0);
700 :
701 18 : *ret = FALSE;
702 18 : if (o > 0) {
703 36 : switch (ATOMbasetype(li.type)) {
704 2 : case TYPE_bte:
705 3 : SQLanyequal_or_not_imp_single(bte, TRUE);
706 : break;
707 0 : case TYPE_sht:
708 0 : SQLanyequal_or_not_imp_single(sht, TRUE);
709 : break;
710 1 : case TYPE_int:
711 1 : SQLanyequal_or_not_imp_single(int, TRUE);
712 : break;
713 0 : case TYPE_lng:
714 0 : SQLanyequal_or_not_imp_single(lng, TRUE);
715 : break;
716 : #ifdef HAVE_HGE
717 0 : case TYPE_hge:
718 0 : SQLanyequal_or_not_imp_single(hge, TRUE);
719 : break;
720 : #endif
721 0 : case TYPE_flt:
722 0 : SQLanyequal_or_not_imp_single(flt, TRUE);
723 : break;
724 1 : case TYPE_dbl:
725 2 : SQLanyequal_or_not_imp_single(dbl, TRUE);
726 : break;
727 14 : default: {
728 14 : int (*ocmp) (const void *, const void *) = ATOMcompare(li.type);
729 14 : const void *nilp = ATOMnilptr(li.type);
730 14 : const void *p = BUNtail(li, 0);
731 :
732 40 : for (BUN q = 0; q < o; q++) {
733 30 : const void *c = BUNtail(ri, q);
734 30 : if (ocmp(nilp, c) == 0)
735 0 : *ret = bit_nil;
736 30 : else if (ocmp(p, c) == 0) {
737 4 : *ret = TRUE;
738 4 : break;
739 : }
740 : }
741 : }
742 : }
743 : }
744 : }
745 10 : bailout1:
746 18 : bat_iterator_end(&li);
747 18 : bat_iterator_end(&ri);
748 :
749 18 : bailout:
750 18 : if (res && !msg) {
751 0 : *bret = res->batCacheid;
752 0 : BBPkeepref(res);
753 18 : } else if (res)
754 0 : BBPreclaim(res);
755 18 : BBPreclaim(l);
756 18 : BBPreclaim(r);
757 18 : return msg;
758 : }
759 :
760 : str
761 0 : SQLanyequal_grp(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
762 : {
763 0 : bat *ret = getArgReference_bat(stk, pci, 0);
764 0 : bat *lp = getArgReference_bat(stk, pci, 1);
765 0 : bat *rp = getArgReference_bat(stk, pci, 2);
766 0 : bat *gp = getArgReference_bat(stk, pci, 3);
767 0 : bat *gpe = getArgReference_bat(stk, pci, 4);
768 0 : bat *sp = pci->argc == 7 ? getArgReference_bat(stk, pci, 5) : NULL;
769 : //bit *no_nil = getArgReference_bit(stk, pci, pci->argc - 1); no_nil argument is ignored
770 0 : BAT *l = NULL, *r = NULL, *g = NULL, *e = NULL, *s = NULL, *res = NULL;
771 :
772 0 : (void)cntxt;
773 0 : (void)mb;
774 0 : l = BATdescriptor(*lp);
775 0 : r = BATdescriptor(*rp);
776 0 : g = BATdescriptor(*gp);
777 0 : e = BATdescriptor(*gpe);
778 0 : if (sp)
779 0 : s = BATdescriptor(*sp);
780 :
781 0 : if (!l || !r || !g || !e || (sp && !s)) {
782 0 : BBPreclaim(l);
783 0 : BBPreclaim(r);
784 0 : BBPreclaim(g);
785 0 : BBPreclaim(e);
786 0 : BBPreclaim(s);
787 0 : throw(MAL, "sql.any =", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
788 : }
789 0 : if (l->ttype != r->ttype) {
790 0 : BBPunfix(l->batCacheid);
791 0 : BBPunfix(r->batCacheid);
792 0 : BBPunfix(g->batCacheid);
793 0 : BBPunfix(e->batCacheid);
794 0 : BBPreclaim(s);
795 0 : throw(MAL, "sql.any =", SQLSTATE(42000) "sql.any = requires both arguments of the same type");
796 : }
797 :
798 0 : res = BATanyequal_grp(l, r, g, e, s);
799 :
800 0 : BBPunfix(l->batCacheid);
801 0 : BBPunfix(r->batCacheid);
802 0 : BBPunfix(g->batCacheid);
803 0 : BBPunfix(e->batCacheid);
804 0 : BBPreclaim(s);
805 0 : if (res == NULL)
806 0 : throw(MAL, "sql.any =", GDK_EXCEPTION);
807 0 : *ret = res->batCacheid;
808 0 : BBPkeepref(res);
809 0 : return MAL_SUCCEED;
810 : }
811 :
812 : str
813 0 : SQLanyequal_grp2(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
814 : {
815 0 : bat *ret = getArgReference_bat(stk, pci, 0);
816 0 : bat *lp = getArgReference_bat(stk, pci, 1);
817 0 : bat *rp = getArgReference_bat(stk, pci, 2);
818 0 : bat *ip = getArgReference_bat(stk, pci, 3);
819 0 : bat *gp = getArgReference_bat(stk, pci, 4);
820 0 : bat *gpe = getArgReference_bat(stk, pci, 5);
821 0 : bat *sp = pci->argc == 8 ? getArgReference_bat(stk, pci, 6) : NULL;
822 : //bit *no_nil = getArgReference_bit(stk, pci, pci->argc == 8 ? 7 : 6); no_nil argument is ignored
823 0 : BAT *l = NULL, *r = NULL, *rid = NULL, *g = NULL, *e = NULL, *s = NULL, *res = NULL;
824 0 : (void)cntxt;
825 0 : (void)mb;
826 :
827 0 : l = BATdescriptor(*lp);
828 0 : r = BATdescriptor(*rp);
829 0 : rid = BATdescriptor(*ip);
830 0 : g = BATdescriptor(*gp);
831 0 : e = BATdescriptor(*gpe);
832 0 : if (sp)
833 0 : s = BATdescriptor(*sp);
834 :
835 0 : if (!l || !r || !rid || !g || !e || (sp && !s)) {
836 0 : BBPreclaim(l);
837 0 : BBPreclaim(r);
838 0 : BBPreclaim(rid);
839 0 : BBPreclaim(g);
840 0 : BBPreclaim(e);
841 0 : BBPreclaim(s);
842 0 : throw(MAL, "sql.any =", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
843 : }
844 0 : if (l->ttype != r->ttype) {
845 0 : BBPunfix(l->batCacheid);
846 0 : BBPunfix(r->batCacheid);
847 0 : BBPunfix(rid->batCacheid);
848 0 : BBPunfix(g->batCacheid);
849 0 : BBPunfix(e->batCacheid);
850 0 : BBPreclaim(s);
851 0 : throw(MAL, "sql.any =", SQLSTATE(42000) "sql.any = requires both arguments of the same type");
852 : }
853 :
854 0 : res = BATanyequal_grp2(l, r, rid, g, e, s);
855 :
856 0 : BBPunfix(l->batCacheid);
857 0 : BBPunfix(r->batCacheid);
858 0 : BBPunfix(rid->batCacheid);
859 0 : BBPunfix(g->batCacheid);
860 0 : BBPunfix(e->batCacheid);
861 0 : BBPreclaim(s);
862 0 : if (res == NULL)
863 0 : throw(MAL, "sql.any =", GDK_EXCEPTION);
864 0 : *ret = res->batCacheid;
865 0 : BBPkeepref(res);
866 0 : return MAL_SUCCEED;
867 : }
868 :
869 : str
870 5 : SQLallnotequal(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
871 : {
872 5 : bat *bret = isaBatType(getArgType(mb, pci, 0)) ? getArgReference_bat(stk, pci, 0) : NULL;
873 5 : bat *bid1 = getArgReference_bat(stk, pci, 1);
874 5 : bat *bid2 = getArgReference_bat(stk, pci, 2);
875 5 : BAT *res = NULL, *l = NULL, *r = NULL;
876 5 : str msg = MAL_SUCCEED;
877 5 : BUN o = 0;
878 5 : BATiter li, ri;
879 :
880 5 : (void) cntxt;
881 5 : if ((l = BATdescriptor(*bid1)) == NULL) {
882 0 : msg = createException(SQL, "sql.all <>", SQLSTATE(HY005) "Cannot access column descriptor");
883 0 : goto bailout;
884 : }
885 5 : if ((r = BATdescriptor(*bid2)) == NULL) {
886 0 : msg = createException(SQL, "sql.all <>", SQLSTATE(HY005) "Cannot access column descriptor");
887 0 : goto bailout;
888 : }
889 5 : if (l->ttype != r->ttype) {
890 0 : msg = createException(SQL, "sql.all <>", SQLSTATE(42000) "sql.all <> requires both arguments of the same type");
891 0 : goto bailout;
892 : }
893 :
894 5 : o = BATcount(r);
895 5 : ri = bat_iterator(r);
896 5 : li = bat_iterator(l);
897 5 : if (bret) {
898 0 : if (!(res = COLnew(r->hseqbase, TYPE_bit, o, TRANSIENT))) {
899 0 : msg = createException(SQL, "sql.all <>", SQLSTATE(HY013) MAL_MALLOC_FAIL);
900 0 : goto bailout1;
901 : }
902 0 : bit *restrict res_l = (bit*) Tloc(res, 0);
903 :
904 0 : switch (ATOMbasetype(li.type)) {
905 0 : case TYPE_bte:
906 0 : SQLanyequal_or_not_imp_multi(bte, !=);
907 : break;
908 0 : case TYPE_sht:
909 0 : SQLanyequal_or_not_imp_multi(sht, !=);
910 : break;
911 0 : case TYPE_int:
912 0 : SQLanyequal_or_not_imp_multi(int, !=);
913 : break;
914 0 : case TYPE_lng:
915 0 : SQLanyequal_or_not_imp_multi(lng, !=);
916 : break;
917 : #ifdef HAVE_HGE
918 0 : case TYPE_hge:
919 0 : SQLanyequal_or_not_imp_multi(hge, !=);
920 : break;
921 : #endif
922 0 : case TYPE_flt:
923 0 : SQLanyequal_or_not_imp_multi(flt, !=);
924 : break;
925 0 : case TYPE_dbl:
926 0 : SQLanyequal_or_not_imp_multi(dbl, !=);
927 : break;
928 0 : default: {
929 0 : int (*ocmp) (const void *, const void *) = ATOMcompare(li.type);
930 0 : const void *nilp = ATOMnilptr(li.type);
931 :
932 0 : for (BUN q = 0; q < o; q++) {
933 0 : const void *c = BUNtail(ri, q), *d = BUNtail(li, q);
934 0 : res_l[q] = ocmp(nilp, c) == 0 || ocmp(nilp, d) == 0 ? bit_nil : ocmp(c, d) != 0;
935 : }
936 : }
937 : }
938 :
939 0 : BATsetcount(res, o);
940 0 : res->tkey = BATcount(res) <= 1;
941 0 : res->tsorted = BATcount(res) <= 1;
942 0 : res->trevsorted = BATcount(res) <= 1;
943 0 : res->tnil = li.nil || ri.nil;
944 0 : res->tnonil = li.nonil && ri.nonil;
945 : } else {
946 5 : bit *ret = getArgReference_bit(stk, pci, 0);
947 :
948 5 : *ret = TRUE;
949 5 : if (o > 0) {
950 10 : switch (ATOMbasetype(li.type)) {
951 1 : case TYPE_bte:
952 3 : SQLanyequal_or_not_imp_single(bte, FALSE);
953 : break;
954 1 : case TYPE_sht:
955 2 : SQLanyequal_or_not_imp_single(sht, FALSE);
956 : break;
957 2 : case TYPE_int:
958 5 : SQLanyequal_or_not_imp_single(int, FALSE);
959 : break;
960 0 : case TYPE_lng:
961 0 : SQLanyequal_or_not_imp_single(lng, FALSE);
962 : break;
963 : #ifdef HAVE_HGE
964 0 : case TYPE_hge:
965 0 : SQLanyequal_or_not_imp_single(hge, FALSE);
966 : break;
967 : #endif
968 0 : case TYPE_flt:
969 0 : SQLanyequal_or_not_imp_single(flt, FALSE);
970 : break;
971 1 : case TYPE_dbl:
972 2 : SQLanyequal_or_not_imp_single(dbl, FALSE);
973 : break;
974 0 : default: {
975 0 : int (*ocmp) (const void *, const void *) = ATOMcompare(li.type);
976 0 : const void *nilp = ATOMnilptr(li.type);
977 0 : const void *p = BUNtail(li, 0);
978 :
979 0 : for (BUN q = 0; q < o; q++) {
980 0 : const void *c = BUNtail(ri, q);
981 0 : if (ocmp(nilp, c) == 0)
982 0 : *ret = bit_nil;
983 0 : else if (ocmp(p, c) == 0) {
984 0 : *ret = FALSE;
985 0 : break;
986 : }
987 : }
988 : }
989 : }
990 : }
991 : }
992 0 : bailout1:
993 5 : bat_iterator_end(&li);
994 5 : bat_iterator_end(&ri);
995 :
996 5 : bailout:
997 5 : if (res && !msg) {
998 0 : *bret = res->batCacheid;
999 0 : BBPkeepref(res);
1000 5 : } else if (res)
1001 0 : BBPreclaim(res);
1002 5 : BBPreclaim(l);
1003 5 : BBPreclaim(r);
1004 5 : return msg;
1005 : }
1006 :
1007 : str
1008 0 : SQLallnotequal_grp(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1009 : {
1010 0 : bat *ret = getArgReference_bat(stk, pci, 0);
1011 0 : bat *lp = getArgReference_bat(stk, pci, 1);
1012 0 : bat *rp = getArgReference_bat(stk, pci, 2);
1013 0 : bat *gp = getArgReference_bat(stk, pci, 3);
1014 0 : bat *gpe = getArgReference_bat(stk, pci, 4);
1015 0 : bat *sp = pci->argc == 7 ? getArgReference_bat(stk, pci, 5) : NULL;
1016 : //bit *no_nil = getArgReference_bit(stk, pci, pci->argc == 7 ? 6 : 5); no_nil argument is ignored
1017 0 : BAT *l = NULL, *r = NULL, *g = NULL, *e = NULL, *s = NULL, *res = NULL;
1018 :
1019 0 : (void)cntxt;
1020 0 : (void)mb;
1021 0 : l = BATdescriptor(*lp);
1022 0 : r = BATdescriptor(*rp);
1023 0 : g = BATdescriptor(*gp);
1024 0 : e = BATdescriptor(*gpe);
1025 0 : if (sp)
1026 0 : s = BATdescriptor(*sp);
1027 :
1028 0 : if (!l || !r || !g || !e || (sp && !s)) {
1029 0 : BBPreclaim(l);
1030 0 : BBPreclaim(r);
1031 0 : BBPreclaim(g);
1032 0 : BBPreclaim(e);
1033 0 : BBPreclaim(s);
1034 0 : throw(MAL, "sql.all <>", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1035 : }
1036 0 : if (l->ttype != r->ttype) {
1037 0 : BBPunfix(l->batCacheid);
1038 0 : BBPunfix(r->batCacheid);
1039 0 : BBPunfix(g->batCacheid);
1040 0 : BBPunfix(e->batCacheid);
1041 0 : BBPreclaim(s);
1042 0 : throw(MAL, "sql.all <>", SQLSTATE(42000) "sql.all <> requires both arguments of the same type");
1043 : }
1044 :
1045 0 : res = BATallnotequal_grp(l, r, g, e, s);
1046 :
1047 0 : BBPunfix(l->batCacheid);
1048 0 : BBPunfix(r->batCacheid);
1049 0 : BBPunfix(g->batCacheid);
1050 0 : BBPunfix(e->batCacheid);
1051 0 : BBPreclaim(s);
1052 0 : if (res == NULL)
1053 0 : throw(MAL, "sql.all <>", GDK_EXCEPTION);
1054 0 : *ret = res->batCacheid;
1055 0 : BBPkeepref(res);
1056 0 : return MAL_SUCCEED;
1057 : }
1058 :
1059 : str
1060 0 : SQLallnotequal_grp2(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1061 : {
1062 0 : bat *ret = getArgReference_bat(stk, pci, 0);
1063 0 : bat *lp = getArgReference_bat(stk, pci, 1);
1064 0 : bat *rp = getArgReference_bat(stk, pci, 2);
1065 0 : bat *ip = getArgReference_bat(stk, pci, 3);
1066 0 : bat *gp = getArgReference_bat(stk, pci, 4);
1067 0 : bat *gpe = getArgReference_bat(stk, pci, 5);
1068 0 : bat *sp = pci->argc == 8 ? getArgReference_bat(stk, pci, 6) : NULL;
1069 : //bit *no_nil = getArgReference_bit(stk, pci, pci->argc == 8 ? 7 : 6); no_nil argument is ignored
1070 0 : BAT *l = NULL, *r = NULL, *rid = NULL, *g = NULL, *e = NULL, *s = NULL, *res = NULL;
1071 :
1072 0 : (void)cntxt;
1073 0 : (void)mb;
1074 :
1075 0 : l = BATdescriptor(*lp);
1076 0 : r = BATdescriptor(*rp);
1077 0 : rid = BATdescriptor(*ip);
1078 0 : g = BATdescriptor(*gp);
1079 0 : e = BATdescriptor(*gpe);
1080 0 : if (sp)
1081 0 : s = BATdescriptor(*sp);
1082 :
1083 0 : if (!l || !r || !rid || !g || !e || (sp && !s)) {
1084 0 : BBPreclaim(l);
1085 0 : BBPreclaim(r);
1086 0 : BBPreclaim(rid);
1087 0 : BBPreclaim(g);
1088 0 : BBPreclaim(e);
1089 0 : BBPreclaim(s);
1090 0 : throw(MAL, "sql.all <>", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1091 : }
1092 0 : if (l->ttype != r->ttype) {
1093 0 : BBPunfix(l->batCacheid);
1094 0 : BBPunfix(r->batCacheid);
1095 0 : BBPunfix(rid->batCacheid);
1096 0 : BBPunfix(g->batCacheid);
1097 0 : BBPunfix(e->batCacheid);
1098 0 : BBPreclaim(s);
1099 0 : throw(MAL, "sql.all <>", SQLSTATE(42000) "sql.all <> requires both arguments of the same type");
1100 : }
1101 :
1102 0 : res = BATallnotequal_grp2(l, r, rid, g, e, s);
1103 :
1104 0 : BBPunfix(l->batCacheid);
1105 0 : BBPunfix(r->batCacheid);
1106 0 : BBPunfix(rid->batCacheid);
1107 0 : BBPunfix(g->batCacheid);
1108 0 : BBPunfix(e->batCacheid);
1109 0 : BBPreclaim(s);
1110 0 : if (res == NULL)
1111 0 : throw(MAL, "sql.all <>", GDK_EXCEPTION);
1112 0 : *ret = res->batCacheid;
1113 0 : BBPkeepref(res);
1114 0 : return MAL_SUCCEED;
1115 : }
1116 :
1117 : str
1118 5 : SQLexist(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1119 : {
1120 5 : BAT *b = NULL, *r = NULL;
1121 5 : bit count = TRUE;
1122 :
1123 5 : (void)cntxt;
1124 5 : if (isaBatType(getArgType(mb, pci, 1))) {
1125 5 : bat *bid = getArgReference_bat(stk, pci, 1);
1126 5 : if (!(b = BBPquickdesc(*bid)))
1127 0 : throw(SQL, "aggr.exist", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1128 5 : count = BATcount(b) != 0;
1129 : }
1130 5 : if (isaBatType(getArgType(mb, pci, 0))) {
1131 0 : bat *res = getArgReference_bat(stk, pci, 0);
1132 0 : if (!(r = BATconstant(b ? b->hseqbase : 0, TYPE_bit, &count, b ? BATcount(b) : 1, TRANSIENT)))
1133 0 : throw(SQL, "aggr.exist", SQLSTATE(HY013) MAL_MALLOC_FAIL);
1134 0 : *res = r->batCacheid;
1135 0 : BBPkeepref(r);
1136 : } else {
1137 5 : bit *res = getArgReference_bit(stk, pci, 0);
1138 5 : *res = count;
1139 : }
1140 :
1141 : return MAL_SUCCEED;
1142 : }
1143 :
1144 : str
1145 0 : SQLsubexist(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1146 : {
1147 0 : bat *ret = getArgReference_bat(stk, pci, 0);
1148 0 : bat *bp = getArgReference_bat(stk, pci, 1);
1149 0 : bat *gp = getArgReference_bat(stk, pci, 2);
1150 0 : bat *gpe = getArgReference_bat(stk, pci, 3);
1151 0 : bat *sp = pci->argc == 6 ? getArgReference_bat(stk, pci, 4) : NULL;
1152 : //bit *no_nil = getArgReference_bit(stk, pci, pci->argc == 6 ? 5 : 4); no_nil argument is ignored
1153 0 : BAT *b = NULL, *g = NULL, *e = NULL, *s = NULL, *res = NULL;
1154 :
1155 0 : (void)cntxt;
1156 0 : (void)mb;
1157 0 : b = BATdescriptor(*bp);
1158 0 : g = BATdescriptor(*gp);
1159 0 : e = BATdescriptor(*gpe);
1160 0 : if (sp)
1161 0 : s = BATdescriptor(*sp);
1162 :
1163 0 : if (!b || !g || !e || (sp && !s)) {
1164 0 : BBPreclaim(b);
1165 0 : BBPreclaim(g);
1166 0 : BBPreclaim(e);
1167 0 : BBPreclaim(s);
1168 0 : throw(MAL, "sql.subexist", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1169 : }
1170 :
1171 0 : res = BATsubexist(b, g, e, s);
1172 :
1173 0 : BBPunfix(b->batCacheid);
1174 0 : BBPunfix(g->batCacheid);
1175 0 : BBPunfix(e->batCacheid);
1176 0 : BBPreclaim(s);
1177 0 : if (res == NULL)
1178 0 : throw(MAL, "sql.subexist", GDK_EXCEPTION);
1179 0 : *ret = res->batCacheid;
1180 0 : BBPkeepref(res);
1181 0 : return MAL_SUCCEED;
1182 : }
1183 :
1184 : str
1185 0 : SQLnot_exist(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1186 : {
1187 0 : BAT *b = NULL, *r = NULL;
1188 0 : bit count = FALSE;
1189 :
1190 0 : (void)cntxt;
1191 0 : if (isaBatType(getArgType(mb, pci, 1))) {
1192 0 : bat *bid = getArgReference_bat(stk, pci, 1);
1193 0 : if (!(b = BBPquickdesc(*bid)))
1194 0 : throw(SQL, "aggr.not_exist", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1195 0 : count = BATcount(b) == 0;
1196 : }
1197 0 : if (isaBatType(getArgType(mb, pci, 0))) {
1198 0 : bat *res = getArgReference_bat(stk, pci, 0);
1199 0 : if (!(r = BATconstant(b ? b->hseqbase : 0, TYPE_bit, &count, b ? BATcount(b) : 1, TRANSIENT)))
1200 0 : throw(SQL, "aggr.not_exist", SQLSTATE(HY013) MAL_MALLOC_FAIL);
1201 0 : *res = r->batCacheid;
1202 0 : BBPkeepref(r);
1203 : } else {
1204 0 : bit *res = getArgReference_bit(stk, pci, 0);
1205 0 : *res = count;
1206 : }
1207 :
1208 : return MAL_SUCCEED;
1209 : }
1210 :
1211 : str
1212 0 : SQLsubnot_exist(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1213 : {
1214 0 : bat *ret = getArgReference_bat(stk, pci, 0);
1215 0 : bat *bp = getArgReference_bat(stk, pci, 1);
1216 0 : bat *gp = getArgReference_bat(stk, pci, 2);
1217 0 : bat *gpe = getArgReference_bat(stk, pci, 3);
1218 0 : bat *sp = pci->argc == 6 ? getArgReference_bat(stk, pci, 4) : NULL;
1219 : //bit *no_nil = getArgReference_bit(stk, pci, pci->argc == 6 ? 5 : 4); no_nil argument is ignored
1220 0 : BAT *b = NULL, *g = NULL, *e = NULL, *s = NULL, *res = NULL;
1221 :
1222 0 : (void)cntxt;
1223 0 : (void)mb;
1224 0 : b = BATdescriptor(*bp);
1225 0 : g = BATdescriptor(*gp);
1226 0 : e = BATdescriptor(*gpe);
1227 0 : if (sp)
1228 0 : s = BATdescriptor(*sp);
1229 :
1230 0 : if (!b || !g || !e || (sp && !s)) {
1231 0 : BBPreclaim(b);
1232 0 : BBPreclaim(g);
1233 0 : BBPreclaim(e);
1234 0 : BBPreclaim(s);
1235 0 : throw(MAL, "sql.subnot_exist", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1236 : }
1237 :
1238 0 : res = BATsubnot_exist(b, g, e, s);
1239 :
1240 0 : BBPunfix(b->batCacheid);
1241 0 : BBPunfix(g->batCacheid);
1242 0 : BBPunfix(e->batCacheid);
1243 0 : BBPreclaim(s);
1244 0 : if (res == NULL)
1245 0 : throw(MAL, "sql.subnot_exist", GDK_EXCEPTION);
1246 0 : *ret = res->batCacheid;
1247 0 : BBPkeepref(res);
1248 0 : return MAL_SUCCEED;
1249 : }
|