1 | /* |
2 | * This Source Code Form is subject to the terms of the Mozilla Public |
3 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
5 | * |
6 | * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V. |
7 | */ |
8 | |
9 | #include "monetdb_config.h" |
10 | #include "sql_subquery.h" |
11 | |
12 | str |
13 | zero_or_one_error(ptr ret, const bat *bid, const bit *err) |
14 | { |
15 | BAT *b; |
16 | BUN c; |
17 | size_t _s; |
18 | const void *p; |
19 | |
20 | if ((b = BATdescriptor(*bid)) == NULL) { |
21 | throw(SQL, "sql.zero_or_one" , SQLSTATE(HY005) "Cannot access column descriptor" ); |
22 | } |
23 | c = BATcount(b); |
24 | if (c == 0) { |
25 | p = ATOMnilptr(b->ttype); |
26 | } else if (c == 1 || (c > 1 && *err == false)) { |
27 | BATiter bi = bat_iterator(b); |
28 | p = BUNtail(bi, 0); |
29 | } else { |
30 | p = NULL; |
31 | BBPunfix(b->batCacheid); |
32 | throw(SQL, "sql.zero_or_one" , SQLSTATE(21000) "Cardinality violation, scalar value expected" ); |
33 | } |
34 | _s = ATOMsize(ATOMtype(b->ttype)); |
35 | if (b->ttype == TYPE_void) |
36 | p = &oid_nil; |
37 | if (ATOMextern(b->ttype)) { |
38 | _s = ATOMlen(ATOMtype(b->ttype), p); |
39 | *(ptr *) ret = GDKmalloc(_s); |
40 | if (*(ptr *) ret == NULL) { |
41 | BBPunfix(b->batCacheid); |
42 | throw(SQL, "sql.zero_or_one" , SQLSTATE(HY001) MAL_MALLOC_FAIL); |
43 | } |
44 | memcpy(*(ptr *) ret, p, _s); |
45 | } else if (b->ttype == TYPE_bat) { |
46 | bat bid = *(bat *) p; |
47 | if ((*(BAT **) ret = BATdescriptor(bid)) == NULL){ |
48 | BBPunfix(b->batCacheid); |
49 | throw(SQL, "sql.zero_or_one" , SQLSTATE(HY005) "Cannot access column descriptor" ); |
50 | } |
51 | } else if (_s == 4) { |
52 | *(int *) ret = *(int *) p; |
53 | } else if (_s == 1) { |
54 | *(bte *) ret = *(bte *) p; |
55 | } else if (_s == 2) { |
56 | *(sht *) ret = *(sht *) p; |
57 | } else if (_s == 8) { |
58 | *(lng *) ret = *(lng *) p; |
59 | #ifdef HAVE_HGE |
60 | } else if (_s == 16) { |
61 | *(hge *) ret = *(hge *) p; |
62 | #endif |
63 | } else { |
64 | memcpy(ret, p, _s); |
65 | } |
66 | BBPunfix(b->batCacheid); |
67 | return MAL_SUCCEED; |
68 | } |
69 | |
70 | str |
71 | zero_or_one_error_bat(ptr ret, const bat *bid, const bat *err) |
72 | { |
73 | bit t = FALSE; |
74 | (void)err; |
75 | return zero_or_one_error(ret, bid, &t); |
76 | } |
77 | |
78 | str |
79 | zero_or_one(ptr ret, const bat *bid) |
80 | { |
81 | bit t = TRUE; |
82 | return zero_or_one_error(ret, bid, &t); |
83 | } |
84 | |
85 | str |
86 | SQLsubzero_or_one(bat *ret, const bat *bid, const bat *gid, const bat *eid, bit *no_nil) |
87 | { |
88 | gdk_return r; |
89 | BAT *ng = NULL, *h = NULL, *g, *b; |
90 | |
91 | (void)no_nil; |
92 | (void)eid; |
93 | |
94 | g = gid ? BATdescriptor(*gid) : NULL; |
95 | if (g == NULL) { |
96 | if (g) |
97 | BBPunfix(g->batCacheid); |
98 | throw(MAL, "sql.subzero_or_one" , SQLSTATE(HY002) RUNTIME_OBJECT_MISSING); |
99 | } |
100 | |
101 | if ((r = BATgroup(&ng, NULL, &h, g, NULL, NULL, NULL, NULL)) == GDK_SUCCEED) { |
102 | lng max = 0; |
103 | |
104 | if (ng) |
105 | BBPunfix(ng->batCacheid); |
106 | BATmax(h, &max); |
107 | BBPunfix(h->batCacheid); |
108 | if (max != lng_nil && max > 1) |
109 | throw(SQL, "sql.subzero_or_one" , SQLSTATE(M0M29) "zero_or_one: cardinality violation, scalar expression expected" ); |
110 | } |
111 | BBPunfix(g->batCacheid); |
112 | if (r == GDK_SUCCEED) { |
113 | b = bid ? BATdescriptor(*bid) : NULL; |
114 | BBPkeepref(*ret = b->batCacheid); |
115 | } |
116 | return MAL_SUCCEED; |
117 | } |
118 | |
119 | str |
120 | SQLall(ptr ret, const bat *bid) |
121 | { |
122 | BAT *b; |
123 | BUN c, _s; |
124 | const void *p; |
125 | |
126 | if ((b = BATdescriptor(*bid)) == NULL) { |
127 | throw(SQL, "sql.all" , SQLSTATE(HY005) "Cannot access column descriptor" ); |
128 | } |
129 | c = BATcount(b); |
130 | if (c == 0) { |
131 | p = ATOMnilptr(b->ttype); |
132 | } else if (c == 1 || (b->tsorted && b->trevsorted)) { |
133 | BATiter bi = bat_iterator(b); |
134 | p = BUNtail(bi, 0); |
135 | } else if (b->ttype == TYPE_void && is_oid_nil(b->tseqbase)) { |
136 | p = ATOMnilptr(b->ttype); |
137 | } else { |
138 | BUN q, r; |
139 | int (*ocmp) (const void *, const void *); |
140 | const void *n = ATOMnilptr(b->ttype); |
141 | BATiter bi = bat_iterator(b); |
142 | r = BUNlast(b); |
143 | ocmp = ATOMcompare(b->ttype); |
144 | for (q = 0; q < r; q++) { /* find first non nil */ |
145 | p = BUNtail(bi, q); |
146 | if (ocmp(n, p) != 0) |
147 | break; |
148 | } |
149 | for (; q < r; q++) { |
150 | const void *c = BUNtail(bi, q); |
151 | if (ocmp(p, c) != 0) { /* values != */ |
152 | if (ocmp(n, c) != 0) { /* and not nil */ |
153 | p = n; |
154 | break; |
155 | } |
156 | } |
157 | } |
158 | } |
159 | _s = ATOMsize(ATOMtype(b->ttype)); |
160 | if (b->ttype == TYPE_void) |
161 | p = &oid_nil; |
162 | if (ATOMextern(b->ttype)) { |
163 | _s = ATOMlen(ATOMtype(b->ttype), p); |
164 | *(ptr *) ret = GDKmalloc(_s); |
165 | if (*(ptr *) ret == NULL) { |
166 | BBPunfix(b->batCacheid); |
167 | throw(SQL, "sql.all" , SQLSTATE(HY001) MAL_MALLOC_FAIL); |
168 | } |
169 | memcpy(*(ptr *) ret, p, _s); |
170 | } else if (b->ttype == TYPE_bat) { |
171 | bat bid = *(bat *) p; |
172 | if ((*(BAT **) ret = BATdescriptor(bid)) == NULL) { |
173 | BBPunfix(b->batCacheid); |
174 | throw(SQL, "sql.all" , SQLSTATE(HY005) "Cannot access column descriptor" ); |
175 | } |
176 | } else if (_s == 4) { |
177 | *(int *) ret = *(int *) p; |
178 | } else if (_s == 1) { |
179 | *(bte *) ret = *(bte *) p; |
180 | } else if (_s == 2) { |
181 | *(sht *) ret = *(sht *) p; |
182 | } else if (_s == 8) { |
183 | *(lng *) ret = *(lng *) p; |
184 | #ifdef HAVE_HGE |
185 | } else if (_s == 16) { |
186 | *(hge *) ret = *(hge *) p; |
187 | #endif |
188 | } else { |
189 | memcpy(ret, p, _s); |
190 | } |
191 | BBPunfix(b->batCacheid); |
192 | return MAL_SUCCEED; |
193 | } |
194 | |
195 | str |
196 | SQLall_grp(bat *ret, const bat *bid, const bat *gp, const bat *gpe, bit *no_nil) |
197 | { |
198 | BAT *l, *g, *e, *res; |
199 | BATiter li; |
200 | ssize_t p, *pos = NULL; |
201 | int error = 0, has_nil = 0; |
202 | int (*ocmp) (const void *, const void *); |
203 | const void *nilp; |
204 | |
205 | (void)no_nil; |
206 | if ((l = BATdescriptor(*bid)) == NULL) { |
207 | throw(SQL, "sql.all =" , SQLSTATE(HY005) "Cannot access column descriptor" ); |
208 | } |
209 | if ((g = BATdescriptor(*gp)) == NULL) { |
210 | BBPunfix(l->batCacheid); |
211 | throw(SQL, "sql.all =" , SQLSTATE(HY005) "Cannot access column descriptor" ); |
212 | } |
213 | if ((e = BATdescriptor(*gpe)) == NULL) { |
214 | BBPunfix(l->batCacheid); |
215 | BBPunfix(g->batCacheid); |
216 | throw(SQL, "sql.all =" , SQLSTATE(HY005) "Cannot access column descriptor" ); |
217 | } |
218 | li = bat_iterator(l); |
219 | nilp = ATOMnilptr(l->ttype); |
220 | ocmp = ATOMcompare(l->ttype); |
221 | if (BATcount(g) > 0) { |
222 | BUN q, o, s, offset = 0; |
223 | BATiter gi = bat_iterator(g); |
224 | |
225 | if ((pos = GDKmalloc(sizeof(BUN)*BATcount(e))) == NULL) { |
226 | BBPunfix(l->batCacheid); |
227 | BBPunfix(g->batCacheid); |
228 | BBPunfix(e->batCacheid); |
229 | throw(SQL, "sql.all =" , SQLSTATE(HY001) MAL_MALLOC_FAIL); |
230 | } |
231 | for (s = 0; s < BATcount(e); s++) |
232 | pos[s] = -1; |
233 | |
234 | offset = g->hseqbase - l->hseqbase; |
235 | o = BUNlast(g); |
236 | for (q = offset, s = 0; s < o; q++, s++) { |
237 | oid id = *(oid*)BUNtail(gi, s); |
238 | if (pos[id] == -2) |
239 | continue; |
240 | else if (pos[id] == -1) { |
241 | const void *lv = BUNtail(li, q); |
242 | if (ocmp(nilp, lv) != 0) /* not nil */ |
243 | pos[id] = q; |
244 | } else { |
245 | const void *lv = BUNtail(li, q); |
246 | const void *rv = BUNtail(li, pos[id]); |
247 | |
248 | if (ocmp(lv, rv) != 0) /* values are different */ |
249 | if (ocmp(nilp, rv) != 0) /* and not nil */ |
250 | pos[id] = -2; |
251 | } |
252 | } |
253 | } |
254 | |
255 | if ((res = COLnew(e->hseqbase, l->ttype, BATcount(e), TRANSIENT)) == NULL) { |
256 | BBPunfix(l->batCacheid); |
257 | BBPunfix(g->batCacheid); |
258 | BBPunfix(e->batCacheid); |
259 | GDKfree(pos); |
260 | throw(SQL, "sql.all =" , SQLSTATE(HY001) MAL_MALLOC_FAIL); |
261 | } |
262 | |
263 | for (p = 0; p < (ssize_t)BATcount(e) && !error; p++) { |
264 | const void *v = nilp; |
265 | if (pos[p] >= 0) { |
266 | v = BUNtail(li, pos[p]); |
267 | if (ocmp(v, nilp) == 0) |
268 | has_nil = 1; |
269 | } else |
270 | has_nil = 1; |
271 | if (BUNappend(res, v, false) != GDK_SUCCEED) |
272 | error = 1; |
273 | } |
274 | GDKfree(pos); |
275 | if (error) |
276 | throw(SQL, "sql.all =" , SQLSTATE(HY005) "all append failed" ); |
277 | |
278 | res->hseqbase = g->hseqbase; |
279 | res->tnil = (has_nil)?1:0; |
280 | res->tnonil = (has_nil)?0:1; |
281 | res->tsorted = res->trevsorted = 0; |
282 | res->tkey = 0; |
283 | BBPunfix(l->batCacheid); |
284 | BBPunfix(g->batCacheid); |
285 | BBPunfix(e->batCacheid); |
286 | BBPkeepref(*ret = res->batCacheid); |
287 | return MAL_SUCCEED; |
288 | } |
289 | |
290 | str |
291 | SQLnil(bit *ret, const bat *bid) |
292 | { |
293 | BAT *b; |
294 | |
295 | if ((b = BATdescriptor(*bid)) == NULL) { |
296 | throw(SQL, "sql.nil" , SQLSTATE(HY005) "Cannot access column descriptor" ); |
297 | } |
298 | *ret = FALSE; |
299 | if (BATcount(b) == 0) |
300 | *ret = bit_nil; |
301 | if (BATcount(b) > 0) { |
302 | BUN q, o; |
303 | int (*ocmp) (const void *, const void *); |
304 | BATiter bi = bat_iterator(b); |
305 | const void *nilp = ATOMnilptr(b->ttype); |
306 | |
307 | o = BUNlast(b); |
308 | ocmp = ATOMcompare(b->ttype); |
309 | for (q = 0; q < o; q++) { |
310 | const void *c = BUNtail(bi, q); |
311 | if (ocmp(nilp, c) == 0) { |
312 | *ret = TRUE; |
313 | break; |
314 | } |
315 | } |
316 | } |
317 | BBPunfix(b->batCacheid); |
318 | return MAL_SUCCEED; |
319 | } |
320 | |
321 | str |
322 | SQLnil_grp(bat *ret, const bat *bid, const bat *gp, const bat *gpe, bit *no_nil) |
323 | { |
324 | BAT *l, *g, *e, *res; |
325 | bit F = FALSE; |
326 | BUN offset = 0; |
327 | |
328 | (void)no_nil; |
329 | if ((l = BATdescriptor(*bid)) == NULL) { |
330 | throw(SQL, "sql.any =" , SQLSTATE(HY005) "Cannot access column descriptor" ); |
331 | } |
332 | if ((g = BATdescriptor(*gp)) == NULL) { |
333 | BBPunfix(l->batCacheid); |
334 | throw(SQL, "sql.any =" , SQLSTATE(HY005) "Cannot access column descriptor" ); |
335 | } |
336 | if ((e = BATdescriptor(*gpe)) == NULL) { |
337 | BBPunfix(l->batCacheid); |
338 | BBPunfix(g->batCacheid); |
339 | throw(SQL, "sql.any =" , SQLSTATE(HY005) "Cannot access column descriptor" ); |
340 | } |
341 | if ((res = BATconstant(0, TYPE_bit, &F, BATcount(e), TRANSIENT)) == NULL) { |
342 | BBPunfix(l->batCacheid); |
343 | BBPunfix(g->batCacheid); |
344 | BBPunfix(e->batCacheid); |
345 | throw(SQL, "sql.any =" , SQLSTATE(HY001) MAL_MALLOC_FAIL); |
346 | } |
347 | BAThseqbase(res, e->hseqbase); |
348 | offset = g->hseqbase - l->hseqbase; |
349 | if (BATcount(g) > 0) { |
350 | BUN q, o, s; |
351 | int (*ocmp) (const void *, const void *); |
352 | BATiter li = bat_iterator(l); |
353 | BATiter gi = bat_iterator(g); |
354 | BATiter rt = bat_iterator(res); |
355 | |
356 | bit *ret = BUNtail(rt, 0); |
357 | const void *nilp = ATOMnilptr(l->ttype); |
358 | |
359 | o = BUNlast(g); |
360 | ocmp = ATOMcompare(l->ttype); |
361 | for (q = offset, s = 0; s < o; q++, s++) { |
362 | const void *lv = BUNtail(li, q); |
363 | oid id = *(oid*)BUNtail(gi, s); |
364 | |
365 | if (ret[id] != TRUE) { |
366 | if (ocmp(lv, nilp) == 0) { |
367 | ret[id] = TRUE; |
368 | } |
369 | } |
370 | } |
371 | } |
372 | res->hseqbase = g->hseqbase; |
373 | res->tnil = 0; |
374 | res->tnonil = 1; |
375 | res->tsorted = res->trevsorted = 0; |
376 | res->tkey = 0; |
377 | BBPunfix(l->batCacheid); |
378 | BBPunfix(g->batCacheid); |
379 | BBPunfix(e->batCacheid); |
380 | BBPkeepref(*ret = res->batCacheid); |
381 | return MAL_SUCCEED; |
382 | } |
383 | |
384 | str |
385 | SQLany_cmp(bit *ret, const bit *cmp, const bit *nl, const bit *nr) |
386 | { |
387 | *ret = FALSE; |
388 | if (*nr == bit_nil) /* empty -> FALSE */ |
389 | *ret = FALSE; |
390 | else if (*cmp == TRUE) |
391 | *ret = TRUE; |
392 | else if (*nl == TRUE || *nr == TRUE) |
393 | *ret = bit_nil; |
394 | return MAL_SUCCEED; |
395 | } |
396 | |
397 | str |
398 | SQLall_cmp(bit *ret, const bit *cmp, const bit *nl, const bit *nr) |
399 | { |
400 | *ret = TRUE; |
401 | if (*nr == bit_nil) /* empty -> TRUE */ |
402 | *ret = TRUE; |
403 | else if (*cmp == FALSE || (*cmp == bit_nil && !*nl && !*nr)) |
404 | *ret = FALSE; |
405 | else if (*nl == TRUE || *nr == TRUE) |
406 | *ret = bit_nil; |
407 | else |
408 | *ret = *cmp; |
409 | return MAL_SUCCEED; |
410 | } |
411 | |
412 | str |
413 | SQLanyequal(bit *ret, const bat *bid1, const bat *bid2) |
414 | { |
415 | BAT *l, *r; |
416 | const void *p; |
417 | |
418 | if ((l = BATdescriptor(*bid1)) == NULL) { |
419 | throw(SQL, "sql.any =" , SQLSTATE(HY005) "Cannot access column descriptor" ); |
420 | } |
421 | if ((r = BATdescriptor(*bid2)) == NULL) { |
422 | BBPunfix(l->batCacheid); |
423 | throw(SQL, "sql.any =" , SQLSTATE(HY005) "Cannot access column descriptor" ); |
424 | } |
425 | *ret = FALSE; |
426 | if (BATcount(r) > 0) { |
427 | BUN q, o; |
428 | int (*ocmp) (const void *, const void *); |
429 | BATiter li = bat_iterator(l); |
430 | BATiter ri = bat_iterator(r); |
431 | const void *nilp = ATOMnilptr(l->ttype); |
432 | |
433 | o = BUNlast(r); |
434 | p = BUNtail(li, 0); |
435 | ocmp = ATOMcompare(l->ttype); |
436 | for (q = 0; q < o; q++) { |
437 | const void *c = BUNtail(ri, q); |
438 | if (ocmp(nilp, c) == 0) |
439 | *ret = bit_nil; |
440 | else if (ocmp(p, c) == 0) { |
441 | *ret = TRUE; |
442 | break; |
443 | } |
444 | } |
445 | } |
446 | BBPunfix(l->batCacheid); |
447 | BBPunfix(r->batCacheid); |
448 | return MAL_SUCCEED; |
449 | } |
450 | |
451 | str |
452 | SQLanyequal_grp(bat *ret, const bat *bid1, const bat *bid2, const bat *gp, const bat *gpe, bit *no_nil) |
453 | { |
454 | BAT *l, *r, *g, *e, *res; |
455 | bit F = FALSE, hasnil = 0; |
456 | BUN offset = 0; |
457 | |
458 | (void)no_nil; |
459 | if ((l = BATdescriptor(*bid1)) == NULL) { |
460 | throw(SQL, "sql.any =" , SQLSTATE(HY005) "Cannot access column descriptor" ); |
461 | } |
462 | if ((r = BATdescriptor(*bid2)) == NULL) { |
463 | BBPunfix(l->batCacheid); |
464 | throw(SQL, "sql.any =" , SQLSTATE(HY005) "Cannot access column descriptor" ); |
465 | } |
466 | if ((g = BATdescriptor(*gp)) == NULL) { |
467 | BBPunfix(l->batCacheid); |
468 | BBPunfix(r->batCacheid); |
469 | throw(SQL, "sql.any =" , SQLSTATE(HY005) "Cannot access column descriptor" ); |
470 | } |
471 | if ((e = BATdescriptor(*gpe)) == NULL) { |
472 | BBPunfix(l->batCacheid); |
473 | BBPunfix(r->batCacheid); |
474 | BBPunfix(g->batCacheid); |
475 | throw(SQL, "sql.any =" , SQLSTATE(HY005) "Cannot access column descriptor" ); |
476 | } |
477 | if ((res = BATconstant(0, TYPE_bit, &F, BATcount(e), TRANSIENT)) == NULL) { |
478 | BBPunfix(l->batCacheid); |
479 | BBPunfix(r->batCacheid); |
480 | BBPunfix(g->batCacheid); |
481 | BBPunfix(e->batCacheid); |
482 | throw(SQL, "sql.any =" , SQLSTATE(HY001) MAL_MALLOC_FAIL); |
483 | } |
484 | BAThseqbase(res, e->hseqbase); |
485 | assert(BATcount(l) == BATcount(r)); |
486 | offset = g->hseqbase - l->hseqbase; |
487 | if (BATcount(g) > 0) { |
488 | BUN q, o, s; |
489 | int (*ocmp) (const void *, const void *); |
490 | BATiter li = bat_iterator(l); |
491 | BATiter ri = bat_iterator(r); |
492 | BATiter gi = bat_iterator(g); |
493 | BATiter rt = bat_iterator(res); |
494 | |
495 | bit *ret = BUNtail(rt, 0); |
496 | const void *nilp = ATOMnilptr(l->ttype); |
497 | |
498 | o = BUNlast(g); |
499 | ocmp = ATOMcompare(l->ttype); |
500 | for (q = offset, s = 0; s < o; q++, s++) { |
501 | const void *lv = BUNtail(li, q); |
502 | const void *rv = BUNtail(ri, q); |
503 | oid id = *(oid*)BUNtail(gi, s); |
504 | |
505 | if (ret[id] != TRUE) { |
506 | if (ocmp(lv, nilp) == 0 || ocmp(rv, nilp) == 0) { |
507 | ret[id] = bit_nil; |
508 | hasnil = 1; |
509 | } else if (ocmp(lv, rv) == 0) |
510 | ret[id] = TRUE; |
511 | } |
512 | } |
513 | } |
514 | res->hseqbase = g->hseqbase; |
515 | res->tnil = hasnil != 0; |
516 | res->tnonil = hasnil == 0; |
517 | res->tsorted = res->trevsorted = 0; |
518 | res->tkey = 0; |
519 | BBPunfix(l->batCacheid); |
520 | BBPunfix(r->batCacheid); |
521 | BBPunfix(g->batCacheid); |
522 | BBPunfix(e->batCacheid); |
523 | BBPkeepref(*ret = res->batCacheid); |
524 | return MAL_SUCCEED; |
525 | } |
526 | |
527 | str |
528 | SQLanyequal_grp2(bat *ret, const bat *bid1, const bat *bid2, const bat *Rid, const bat *gp, const bat *gpe, bit *no_nil) |
529 | { |
530 | BAT *l, *r, *rid, *g, *e, *res; |
531 | bit F = FALSE, hasnil = 0; |
532 | BUN offset = 0; |
533 | |
534 | (void)no_nil; |
535 | if ((l = BATdescriptor(*bid1)) == NULL) { |
536 | throw(SQL, "sql.any =" , SQLSTATE(HY005) "Cannot access column descriptor" ); |
537 | } |
538 | if ((r = BATdescriptor(*bid2)) == NULL) { |
539 | BBPunfix(l->batCacheid); |
540 | throw(SQL, "sql.any =" , SQLSTATE(HY005) "Cannot access column descriptor" ); |
541 | } |
542 | if ((rid = BATdescriptor(*Rid)) == NULL) { |
543 | BBPunfix(l->batCacheid); |
544 | BBPunfix(r->batCacheid); |
545 | throw(SQL, "sql.any =" , SQLSTATE(HY005) "Cannot access column descriptor" ); |
546 | } |
547 | if ((g = BATdescriptor(*gp)) == NULL) { |
548 | BBPunfix(l->batCacheid); |
549 | BBPunfix(r->batCacheid); |
550 | BBPunfix(rid->batCacheid); |
551 | throw(SQL, "sql.any =" , SQLSTATE(HY005) "Cannot access column descriptor" ); |
552 | } |
553 | if ((e = BATdescriptor(*gpe)) == NULL) { |
554 | BBPunfix(l->batCacheid); |
555 | BBPunfix(r->batCacheid); |
556 | BBPunfix(rid->batCacheid); |
557 | BBPunfix(g->batCacheid); |
558 | throw(SQL, "sql.any =" , SQLSTATE(HY005) "Cannot access column descriptor" ); |
559 | } |
560 | if ((res = BATconstant(0, TYPE_bit, &F, BATcount(e), TRANSIENT)) == NULL) { |
561 | BBPunfix(l->batCacheid); |
562 | BBPunfix(r->batCacheid); |
563 | BBPunfix(rid->batCacheid); |
564 | BBPunfix(g->batCacheid); |
565 | BBPunfix(e->batCacheid); |
566 | throw(SQL, "sql.any =" , SQLSTATE(HY001) MAL_MALLOC_FAIL); |
567 | } |
568 | BAThseqbase(res, e->hseqbase); |
569 | assert(BATcount(l) == BATcount(r)); |
570 | offset = g->hseqbase - l->hseqbase; |
571 | if (BATcount(g) > 0) { |
572 | BUN q, o, s; |
573 | int (*ocmp) (const void *, const void *); |
574 | BATiter li = bat_iterator(l); |
575 | BATiter ri = bat_iterator(r); |
576 | BATiter ii = bat_iterator(rid); |
577 | BATiter gi = bat_iterator(g); |
578 | BATiter rt = bat_iterator(res); |
579 | |
580 | bit *ret = BUNtail(rt, 0); |
581 | const void *nilp = ATOMnilptr(l->ttype); |
582 | |
583 | o = BUNlast(g); |
584 | ocmp = ATOMcompare(l->ttype); |
585 | for (q = offset, s = 0; s < o; q++, s++) { |
586 | const void *lv = BUNtail(li, q); |
587 | const void *rv = BUNtail(ri, q); |
588 | const oid rid = *(oid*)BUNtail(ii, q); |
589 | oid id = *(oid*)BUNtail(gi, s); |
590 | |
591 | if (ret[id] != TRUE) { |
592 | if (rid == oid_nil) { /* empty */ |
593 | ret[id] = FALSE; |
594 | } else if (ocmp(lv, nilp) == 0 || ocmp(rv, nilp) == 0) { |
595 | ret[id] = bit_nil; |
596 | hasnil = 1; |
597 | } else if (ocmp(lv, rv) == 0) |
598 | ret[id] = TRUE; |
599 | } |
600 | } |
601 | } |
602 | res->hseqbase = g->hseqbase; |
603 | res->tnil = hasnil != 0; |
604 | res->tnonil = hasnil == 0; |
605 | res->tsorted = res->trevsorted = 0; |
606 | res->tkey = 0; |
607 | BBPunfix(l->batCacheid); |
608 | BBPunfix(r->batCacheid); |
609 | BBPunfix(g->batCacheid); |
610 | BBPunfix(e->batCacheid); |
611 | BBPkeepref(*ret = res->batCacheid); |
612 | return MAL_SUCCEED; |
613 | } |
614 | |
615 | str |
616 | SQLallnotequal(bit *ret, const bat *bid1, const bat *bid2) |
617 | { |
618 | BAT *l, *r; |
619 | const void *p; |
620 | |
621 | if ((l = BATdescriptor(*bid1)) == NULL) { |
622 | throw(SQL, "sql.all <>" , SQLSTATE(HY005) "Cannot access column descriptor" ); |
623 | } |
624 | if ((r = BATdescriptor(*bid2)) == NULL) { |
625 | BBPunfix(l->batCacheid); |
626 | throw(SQL, "sql.all <>" , SQLSTATE(HY005) "Cannot access column descriptor" ); |
627 | } |
628 | *ret = TRUE; |
629 | if (BATcount(r) > 0) { |
630 | BUN q, o; |
631 | int (*ocmp) (const void *, const void *); |
632 | BATiter li = bat_iterator(l); |
633 | BATiter ri = bat_iterator(r); |
634 | const void *nilp = ATOMnilptr(l->ttype); |
635 | |
636 | o = BUNlast(r); |
637 | p = BUNtail(li, 0); |
638 | ocmp = ATOMcompare(l->ttype); |
639 | for (q = 0; q < o; q++) { |
640 | const void *c = BUNtail(ri, q); |
641 | if (ocmp(nilp, c) == 0) |
642 | *ret = bit_nil; |
643 | else if (ocmp(p, c) == 0) { |
644 | *ret = FALSE; |
645 | break; |
646 | } |
647 | } |
648 | } |
649 | BBPunfix(l->batCacheid); |
650 | BBPunfix(r->batCacheid); |
651 | return MAL_SUCCEED; |
652 | } |
653 | |
654 | str |
655 | SQLallnotequal_grp(bat *ret, const bat *bid1, const bat *bid2, const bat *gp, const bat *gpe, bit *no_nil) |
656 | { |
657 | BAT *l, *r, *g, *e, *res; |
658 | bit T = TRUE, hasnil = 0; |
659 | BUN offset = 0; |
660 | |
661 | (void)no_nil; |
662 | if ((l = BATdescriptor(*bid1)) == NULL) { |
663 | throw(SQL, "sql.all <>" , SQLSTATE(HY005) "Cannot access column descriptor" ); |
664 | } |
665 | if ((r = BATdescriptor(*bid2)) == NULL) { |
666 | BBPunfix(l->batCacheid); |
667 | throw(SQL, "sql.all <>" , SQLSTATE(HY005) "Cannot access column descriptor" ); |
668 | } |
669 | if ((g = BATdescriptor(*gp)) == NULL) { |
670 | BBPunfix(l->batCacheid); |
671 | BBPunfix(r->batCacheid); |
672 | throw(SQL, "sql.all <>" , SQLSTATE(HY005) "Cannot access column descriptor" ); |
673 | } |
674 | if ((e = BATdescriptor(*gpe)) == NULL) { |
675 | BBPunfix(l->batCacheid); |
676 | BBPunfix(r->batCacheid); |
677 | BBPunfix(g->batCacheid); |
678 | throw(SQL, "sql.all <>" , SQLSTATE(HY005) "Cannot access column descriptor" ); |
679 | } |
680 | if ((res = BATconstant(0, TYPE_bit, &T, BATcount(e), TRANSIENT)) == NULL) { |
681 | BBPunfix(l->batCacheid); |
682 | BBPunfix(r->batCacheid); |
683 | BBPunfix(g->batCacheid); |
684 | BBPunfix(e->batCacheid); |
685 | throw(SQL, "sql.all <>" , SQLSTATE(HY001) MAL_MALLOC_FAIL); |
686 | } |
687 | BAThseqbase(res, e->hseqbase); |
688 | assert(BATcount(l) == BATcount(r)); |
689 | offset = g->hseqbase - l->hseqbase; |
690 | if (BATcount(g) > 0) { |
691 | BUN q, o, s; |
692 | int (*ocmp) (const void *, const void *); |
693 | BATiter li = bat_iterator(l); |
694 | BATiter ri = bat_iterator(r); |
695 | BATiter gi = bat_iterator(g); |
696 | BATiter rt = bat_iterator(res); |
697 | |
698 | bit *ret = BUNtail(rt, 0); |
699 | const void *nilp = ATOMnilptr(l->ttype); |
700 | |
701 | o = BUNlast(g); |
702 | ocmp = ATOMcompare(l->ttype); |
703 | for (q = offset, s = 0; s < o; q++, s++) { |
704 | const void *lv = BUNtail(li, q); |
705 | const void *rv = BUNtail(ri, q); |
706 | oid id = *(oid*)BUNtail(gi, s); |
707 | |
708 | if (ret[id] != FALSE) { |
709 | if (ocmp(lv, nilp) == 0 || ocmp(rv, nilp) == 0) { |
710 | ret[id] = bit_nil; |
711 | hasnil = 1; |
712 | } else if (ocmp(lv, rv) == 0) |
713 | ret[id] = FALSE; |
714 | } |
715 | } |
716 | } |
717 | res->hseqbase = g->hseqbase; |
718 | res->tnil = hasnil != 0; |
719 | res->tnonil = hasnil == 0; |
720 | res->tsorted = res->trevsorted = 0; |
721 | res->tkey = 0; |
722 | BBPunfix(l->batCacheid); |
723 | BBPunfix(r->batCacheid); |
724 | BBPunfix(g->batCacheid); |
725 | BBPunfix(e->batCacheid); |
726 | BBPkeepref(*ret = res->batCacheid); |
727 | return MAL_SUCCEED; |
728 | } |
729 | |
730 | str |
731 | SQLallnotequal_grp2(bat *ret, const bat *bid1, const bat *bid2, const bat *Rid, const bat *gp, const bat *gpe, bit *no_nil) |
732 | { |
733 | BAT *l, *r, *rid, *g, *e, *res; |
734 | bit T = TRUE, hasnil = 0; |
735 | BUN offset = 0; |
736 | |
737 | (void)no_nil; |
738 | if ((l = BATdescriptor(*bid1)) == NULL) { |
739 | throw(SQL, "sql.all <>" , SQLSTATE(HY005) "Cannot access column descriptor" ); |
740 | } |
741 | if ((r = BATdescriptor(*bid2)) == NULL) { |
742 | BBPunfix(l->batCacheid); |
743 | throw(SQL, "sql.all <>" , SQLSTATE(HY005) "Cannot access column descriptor" ); |
744 | } |
745 | if ((rid = BATdescriptor(*Rid)) == NULL) { |
746 | BBPunfix(l->batCacheid); |
747 | BBPunfix(r->batCacheid); |
748 | throw(SQL, "sql.any =" , SQLSTATE(HY005) "Cannot access column descriptor" ); |
749 | } |
750 | if ((g = BATdescriptor(*gp)) == NULL) { |
751 | BBPunfix(l->batCacheid); |
752 | BBPunfix(r->batCacheid); |
753 | BBPunfix(rid->batCacheid); |
754 | throw(SQL, "sql.all <>" , SQLSTATE(HY005) "Cannot access column descriptor" ); |
755 | } |
756 | if ((e = BATdescriptor(*gpe)) == NULL) { |
757 | BBPunfix(l->batCacheid); |
758 | BBPunfix(r->batCacheid); |
759 | BBPunfix(rid->batCacheid); |
760 | BBPunfix(g->batCacheid); |
761 | throw(SQL, "sql.all <>" , SQLSTATE(HY005) "Cannot access column descriptor" ); |
762 | } |
763 | if ((res = BATconstant(0, TYPE_bit, &T, BATcount(e), TRANSIENT)) == NULL) { |
764 | BBPunfix(l->batCacheid); |
765 | BBPunfix(r->batCacheid); |
766 | BBPunfix(rid->batCacheid); |
767 | BBPunfix(g->batCacheid); |
768 | BBPunfix(e->batCacheid); |
769 | throw(SQL, "sql.all <>" , SQLSTATE(HY001) MAL_MALLOC_FAIL); |
770 | } |
771 | BAThseqbase(res, e->hseqbase); |
772 | assert(BATcount(l) == BATcount(r)); |
773 | offset = g->hseqbase - l->hseqbase; |
774 | if (BATcount(g) > 0) { |
775 | BUN q, o, s; |
776 | int (*ocmp) (const void *, const void *); |
777 | BATiter li = bat_iterator(l); |
778 | BATiter ri = bat_iterator(r); |
779 | BATiter ii = bat_iterator(rid); |
780 | BATiter gi = bat_iterator(g); |
781 | BATiter rt = bat_iterator(res); |
782 | |
783 | bit *ret = BUNtail(rt, 0); |
784 | const void *nilp = ATOMnilptr(l->ttype); |
785 | |
786 | o = BUNlast(g); |
787 | ocmp = ATOMcompare(l->ttype); |
788 | for (q = offset, s = 0; s < o; q++, s++) { |
789 | const void *lv = BUNtail(li, q); |
790 | const void *rv = BUNtail(ri, q); |
791 | const oid rid = *(oid*)BUNtail(ii, q); |
792 | oid id = *(oid*)BUNtail(gi, s); |
793 | |
794 | if (ret[id] != FALSE) { |
795 | if (rid == oid_nil) { /* empty */ |
796 | ret[id] = TRUE; |
797 | } else if (ocmp(lv, nilp) == 0 || ocmp(rv, nilp) == 0) { |
798 | ret[id] = bit_nil; |
799 | hasnil = 1; |
800 | } else if (ocmp(lv, rv) == 0) |
801 | ret[id] = FALSE; |
802 | } |
803 | } |
804 | } |
805 | res->hseqbase = g->hseqbase; |
806 | res->tnil = hasnil != 0; |
807 | res->tnonil = hasnil == 0; |
808 | res->tsorted = res->trevsorted = 0; |
809 | res->tkey = 0; |
810 | BBPunfix(l->batCacheid); |
811 | BBPunfix(r->batCacheid); |
812 | BBPunfix(g->batCacheid); |
813 | BBPunfix(e->batCacheid); |
814 | BBPkeepref(*ret = res->batCacheid); |
815 | return MAL_SUCCEED; |
816 | } |
817 | |
818 | str |
819 | SQLexist_val(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) |
820 | { |
821 | bit *res = getArgReference_bit(stk, pci, 0); |
822 | ptr v = getArgReference(stk, pci, 1); |
823 | int mtype = getArgType(mb, pci, 1); |
824 | |
825 | (void)cntxt; |
826 | if ((mtype == TYPE_bat || mtype > GDKatomcnt)) { |
827 | BAT *b = BATdescriptor(*(bat *)v); |
828 | |
829 | if (b) |
830 | *res = BATcount(b) != 0; |
831 | else |
832 | throw(SQL, "aggr.exist" , SQLSTATE(HY005) "Cannot access column descriptor" ); |
833 | } else if (ATOMcmp(mtype, v, ATOMnilptr(mtype)) != 0) |
834 | *res = TRUE; |
835 | else |
836 | *res = FALSE; |
837 | return MAL_SUCCEED; |
838 | } |
839 | |
840 | str |
841 | SQLexist(bit *res, bat *id) |
842 | { |
843 | BAT *b; |
844 | |
845 | if ((b = BATdescriptor(*id)) == NULL) |
846 | throw(SQL, "aggr.exist" , SQLSTATE(HY005) "Cannot access column descriptor" ); |
847 | *res = BATcount(b) != 0; |
848 | BBPunfix(b->batCacheid); |
849 | return MAL_SUCCEED; |
850 | } |
851 | |
852 | str |
853 | SQLsubexist(bat *ret, const bat *bp, const bat *gp, const bat *gpe, bit *no_nil) |
854 | { |
855 | BAT *b, *g, *e, *res; |
856 | bit T = TRUE; |
857 | BUN offset = 0; |
858 | |
859 | (void)no_nil; |
860 | if ((b = BATdescriptor(*bp)) == NULL) { |
861 | throw(SQL, "aggr.subexist" , SQLSTATE(HY005) "Cannot access column descriptor" ); |
862 | } |
863 | if ((g = BATdescriptor(*gp)) == NULL) { |
864 | BBPunfix(b->batCacheid); |
865 | throw(SQL, "aggr.subexist" , SQLSTATE(HY005) "Cannot access column descriptor" ); |
866 | } |
867 | if ((e = BATdescriptor(*gpe)) == NULL) { |
868 | BBPunfix(b->batCacheid); |
869 | BBPunfix(g->batCacheid); |
870 | throw(SQL, "aggr.subexist" , SQLSTATE(HY005) "Cannot access column descriptor" ); |
871 | } |
872 | if ((res = BATconstant(0, TYPE_bit, &T, BATcount(e), TRANSIENT)) == NULL) { |
873 | BBPunfix(b->batCacheid); |
874 | BBPunfix(g->batCacheid); |
875 | BBPunfix(e->batCacheid); |
876 | throw(SQL, "aggr.subexist" , SQLSTATE(HY001) MAL_MALLOC_FAIL); |
877 | } |
878 | BAThseqbase(res, e->hseqbase); |
879 | offset = g->hseqbase - b->hseqbase; |
880 | if (BATcount(g) > 0) { |
881 | BUN q, o, s; |
882 | int (*ocmp) (const void *, const void *); |
883 | BATiter bi = bat_iterator(b); |
884 | BATiter gi = bat_iterator(g); |
885 | BATiter rt = bat_iterator(res); |
886 | |
887 | bit *ret = BUNtail(rt, 0); |
888 | const void *nilp = ATOMnilptr(b->ttype); |
889 | |
890 | o = BUNlast(g); |
891 | ocmp = ATOMcompare(b->ttype); |
892 | for (q = offset, s = 0; s < o; q++, s++) { |
893 | const void *bv = BUNtail(bi, q); |
894 | oid id = *(oid*)BUNtail(gi, s); |
895 | |
896 | if (ret[id] == TRUE) { |
897 | if (ocmp(bv, nilp) == 0) { |
898 | ret[id] = FALSE; |
899 | } |
900 | } |
901 | } |
902 | } |
903 | res->hseqbase = g->hseqbase; |
904 | res->tnil = 0; |
905 | res->tnonil = 1; |
906 | res->tsorted = res->trevsorted = 0; |
907 | res->tkey = 0; |
908 | BBPunfix(b->batCacheid); |
909 | BBPunfix(g->batCacheid); |
910 | BBPunfix(e->batCacheid); |
911 | BBPkeepref(*ret = res->batCacheid); |
912 | return MAL_SUCCEED; |
913 | } |
914 | |
915 | str |
916 | SQLnot_exist_val(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) |
917 | { |
918 | bit *res = getArgReference_bit(stk, pci, 0); |
919 | ptr v = getArgReference(stk, pci, 1); |
920 | int mtype = getArgType(mb, pci, 1); |
921 | |
922 | (void)cntxt; |
923 | if ((mtype == TYPE_bat || mtype > GDKatomcnt)) { |
924 | BAT *b = BATdescriptor(*(bat *)v); |
925 | |
926 | if (b) |
927 | *res = BATcount(b) == 0; |
928 | else |
929 | throw(SQL, "aggr.not_exist" , SQLSTATE(HY005) "Cannot access column descriptor" ); |
930 | } else |
931 | *res = FALSE; |
932 | return MAL_SUCCEED; |
933 | } |
934 | |
935 | str |
936 | SQLnot_exist(bit *res, bat *id) |
937 | { |
938 | BAT *b; |
939 | |
940 | if ((b = BATdescriptor(*id)) == NULL) |
941 | throw(SQL, "aggr.not_exist" , SQLSTATE(HY005) "Cannot access column descriptor" ); |
942 | *res = BATcount(b) == 0; |
943 | BBPunfix(b->batCacheid); |
944 | return MAL_SUCCEED; |
945 | } |
946 | |
947 | str |
948 | SQLsubnot_exist(bat *ret, const bat *bp, const bat *gp, const bat *gpe, bit *no_nil) |
949 | { |
950 | BAT *b, *g, *e, *res; |
951 | bit F = FALSE, hasnil = 0; |
952 | BUN offset = 0; |
953 | |
954 | (void)no_nil; |
955 | if ((b = BATdescriptor(*bp)) == NULL) { |
956 | throw(SQL, "aggr.subnot_exist" , SQLSTATE(HY005) "Cannot access column descriptor" ); |
957 | } |
958 | if ((g = BATdescriptor(*gp)) == NULL) { |
959 | BBPunfix(b->batCacheid); |
960 | throw(SQL, "aggr.subnot_exist" , SQLSTATE(HY005) "Cannot access column descriptor" ); |
961 | } |
962 | if ((e = BATdescriptor(*gpe)) == NULL) { |
963 | BBPunfix(b->batCacheid); |
964 | BBPunfix(g->batCacheid); |
965 | throw(SQL, "aggr.subnot_exist" , SQLSTATE(HY005) "Cannot access column descriptor" ); |
966 | } |
967 | if ((res = BATconstant(0, TYPE_bit, &F, BATcount(e), TRANSIENT)) == NULL) { |
968 | BBPunfix(b->batCacheid); |
969 | BBPunfix(g->batCacheid); |
970 | BBPunfix(e->batCacheid); |
971 | throw(SQL, "aggr.subnot_exist" , SQLSTATE(HY001) MAL_MALLOC_FAIL); |
972 | } |
973 | BAThseqbase(res, e->hseqbase); |
974 | offset = g->hseqbase - b->hseqbase; |
975 | if (BATcount(g) > 0) { |
976 | BUN q, o, s; |
977 | int (*ocmp) (const void *, const void *); |
978 | BATiter bi = bat_iterator(b); |
979 | BATiter gi = bat_iterator(g); |
980 | BATiter rt = bat_iterator(res); |
981 | |
982 | bit *ret = BUNtail(rt, 0); |
983 | const void *nilp = ATOMnilptr(b->ttype); |
984 | |
985 | o = BUNlast(g); |
986 | ocmp = ATOMcompare(b->ttype); |
987 | for (q = offset, s = 0; s < o; q++, s++) { |
988 | const void *bv = BUNtail(bi, q); |
989 | oid id = *(oid*)BUNtail(gi, s); |
990 | |
991 | if (ret[id] != TRUE) { |
992 | if (ocmp(bv, nilp) == 0) { |
993 | ret[id] = bit_nil; |
994 | hasnil = 1; |
995 | } |
996 | } |
997 | } |
998 | } |
999 | res->hseqbase = g->hseqbase; |
1000 | res->tnil = hasnil != 0; |
1001 | res->tnonil = hasnil == 0; |
1002 | res->tsorted = res->trevsorted = 0; |
1003 | res->tkey = 0; |
1004 | BBPunfix(b->batCacheid); |
1005 | BBPunfix(g->batCacheid); |
1006 | BBPunfix(e->batCacheid); |
1007 | BBPkeepref(*ret = res->batCacheid); |
1008 | return MAL_SUCCEED; |
1009 | } |
1010 | |