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 : /*
14 : * (c) Peter Boncz, Martin Kersten, Niels Nes, Sjoerd Mullender
15 : * BAT Algebra
16 : * This modules contains the most common algebraic BAT manipulation
17 : * commands. We call them algebra, because all operations take
18 : * values as parameters, and produce new result values, but
19 : * do not modify their parameters.
20 : *
21 : * Unlike the previous Monet versions, we reduce the number
22 : * of functions returning a BAT reference. This was previously needed
23 : * to simplify recursive bat-expression and manage reference counts.
24 : * In the current version we return only a BAT identifier when a new
25 : * bat is being created.
26 : *
27 : * All parameters to the modules are passed by reference.
28 : * In particular, this means that
29 : * string values are passed to the module layer as (str *)
30 : * and we have to de-reference them before entering the gdk library.
31 : * This calls for knowledge on the underlying BAT typs`s
32 : */
33 : #define derefStr(b, v) \
34 : do { \
35 : int _tpe= ATOMstorage((b)->ttype); \
36 : if (_tpe >= TYPE_str) { \
37 : if ((v) == 0 || *(str*) (v) == 0) \
38 : (v) = (str) str_nil; \
39 : else \
40 : (v) = *(str *) (v); \
41 : } \
42 : } while (0)
43 :
44 : #include "monetdb_config.h"
45 : #include "algebra.h"
46 :
47 : /*
48 : * Command Implementations in C
49 : * This module contains just a wrapper implementations; since all described
50 : * operations are part of the GDK kernel.
51 : *
52 : * BAT sum operation
53 : * The sum aggregate only works for int and float fields.
54 : * The routines below assumes that the caller knows what type
55 : * is large enough to prevent overflow.
56 : */
57 :
58 : static gdk_return
59 2377 : CMDgen_group(BAT **result, BAT *gids, BAT *cnts)
60 : {
61 2377 : BUN j;
62 2377 : BATiter gi = bat_iterator(gids);
63 2377 : BAT *r = COLnew(0, TYPE_oid, gi.count * 2, TRANSIENT);
64 :
65 2377 : if (r == NULL) {
66 0 : bat_iterator_end(&gi);
67 0 : return GDK_FAIL;
68 : }
69 2377 : BATiter ci = bat_iterator(cnts);
70 2377 : if (gi.type == TYPE_void) {
71 1041 : oid id = gi.tseq;
72 1041 : lng *cnt = (lng *) ci.base;
73 96149 : for (j = 0; j < gi.count; j++) {
74 95108 : lng i, sz = cnt[j];
75 190162 : for (i = 0; i < sz; i++) {
76 95054 : if (BUNappend(r, &id, false) != GDK_SUCCEED) {
77 0 : BBPreclaim(r);
78 0 : bat_iterator_end(&ci);
79 0 : bat_iterator_end(&gi);
80 0 : return GDK_FAIL;
81 : }
82 : }
83 95108 : id ++;
84 : }
85 : } else {
86 1336 : oid *id = (oid *) gi.base;
87 1336 : lng *cnt = (lng *) ci.base;
88 140457 : for (j = 0; j < gi.count; j++) {
89 139121 : lng i, sz = cnt[j];
90 274767 : for (i = 0; i < sz; i++) {
91 135646 : if (BUNappend(r, id, false) != GDK_SUCCEED) {
92 0 : BBPreclaim(r);
93 0 : bat_iterator_end(&ci);
94 0 : bat_iterator_end(&gi);
95 0 : return GDK_FAIL;
96 : }
97 : }
98 139121 : id ++;
99 : }
100 : }
101 2377 : bat_iterator_end(&ci);
102 2377 : r->tkey = false;
103 2377 : r->tseqbase = oid_nil;
104 2377 : r->tsorted = gi.sorted;
105 2377 : r->trevsorted = gi.revsorted;
106 2377 : r->tnonil = gi.nonil;
107 2377 : bat_iterator_end(&gi);
108 2377 : *result = r;
109 2377 : return GDK_SUCCEED;
110 : }
111 :
112 :
113 : static gdk_return
114 6 : slice(BAT **retval, BAT *b, lng start, lng end)
115 : {
116 : /* the internal BATslice requires exclusive end */
117 6 : if (start < 0) {
118 0 : GDKerror("start position of slice should >= 0\n");
119 0 : return GDK_FAIL;
120 : }
121 6 : if (is_lng_nil(end))
122 3 : end = BATcount(b);
123 :
124 6 : return (*retval = BATslice(b, (BUN) start, (BUN) end + 1)) ? GDK_SUCCEED : GDK_FAIL;
125 : }
126 :
127 : /*
128 : *
129 : * The remainder of this file contains the wrapper around the V4 code base
130 : * The BAT identifiers passed through this module may indicate
131 : * that the 'reverse' view applies. This should be taken into
132 : * account while resolving them.
133 : *
134 : * The sum aggregate only works for int and float fields.
135 : * The routines below assumes that the caller knows what type
136 : * is large enough to prevent overflow.
137 : */
138 :
139 : static str
140 655 : ALGminany_skipnil(ptr result, const bat *bid, const bit *skipnil)
141 : {
142 655 : BAT *b;
143 655 : ptr p;
144 655 : str msg = MAL_SUCCEED;
145 :
146 655 : if (result == NULL || (b = BATdescriptor(*bid)) == NULL)
147 0 : throw(MAL, "algebra.min", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
148 :
149 659 : if (!ATOMlinear(b->ttype)) {
150 0 : msg = createException(MAL, "algebra.min",
151 : "atom '%s' cannot be ordered linearly",
152 : ATOMname(b->ttype));
153 : } else {
154 659 : if (ATOMextern(b->ttype)) {
155 42 : *(ptr *) result = p = BATmin_skipnil(b, NULL, *skipnil);
156 : } else {
157 617 : p = BATmin_skipnil(b, result, *skipnil);
158 617 : if (p != result)
159 0 : msg = createException(MAL, "algebra.min",
160 : SQLSTATE(HY002) "INTERNAL ERROR");
161 : }
162 659 : if (msg == MAL_SUCCEED && p == NULL)
163 0 : msg = createException(MAL, "algebra.min", GDK_EXCEPTION);
164 : }
165 659 : BBPunfix(b->batCacheid);
166 659 : return msg;
167 : }
168 :
169 : static str
170 656 : ALGminany(ptr result, const bat *bid)
171 : {
172 656 : bit skipnil = TRUE;
173 656 : return ALGminany_skipnil(result, bid, &skipnil);
174 : }
175 :
176 : static str
177 554 : ALGmaxany_skipnil(ptr result, const bat *bid, const bit *skipnil)
178 : {
179 554 : BAT *b;
180 554 : ptr p;
181 554 : str msg = MAL_SUCCEED;
182 :
183 554 : if (result == NULL || (b = BATdescriptor(*bid)) == NULL)
184 0 : throw(MAL, "algebra.max", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
185 :
186 554 : if (!ATOMlinear(b->ttype)) {
187 0 : msg = createException(MAL, "algebra.max",
188 : "atom '%s' cannot be ordered linearly",
189 : ATOMname(b->ttype));
190 : } else {
191 554 : if (ATOMextern(b->ttype)) {
192 68 : *(ptr *) result = p = BATmax_skipnil(b, NULL, *skipnil);
193 : } else {
194 486 : p = BATmax_skipnil(b, result, *skipnil);
195 490 : if (p != result)
196 0 : msg = createException(MAL, "algebra.max",
197 : SQLSTATE(HY002) "INTERNAL ERROR");
198 : }
199 558 : if (msg == MAL_SUCCEED && p == NULL)
200 0 : msg = createException(MAL, "algebra.max", GDK_EXCEPTION);
201 : }
202 558 : BBPunfix(b->batCacheid);
203 558 : return msg;
204 : }
205 :
206 : static str
207 554 : ALGmaxany(ptr result, const bat *bid)
208 : {
209 554 : bit skipnil = TRUE;
210 554 : return ALGmaxany_skipnil(result, bid, &skipnil);
211 : }
212 :
213 : static str
214 2377 : ALGgroupby(bat *res, const bat *gids, const bat *cnts)
215 : {
216 2377 : BAT *bn, *g, *c;
217 :
218 2377 : g = BATdescriptor(*gids);
219 2377 : if (g == NULL) {
220 0 : throw(MAL, "algebra.groupby", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
221 : }
222 2377 : c = BATdescriptor(*cnts);
223 2377 : if (c == NULL) {
224 0 : BBPunfix(g->batCacheid);
225 0 : throw(MAL, "algebra.groupby", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
226 : }
227 2377 : if (CMDgen_group(&bn, g, c) != GDK_SUCCEED) {
228 0 : BBPunfix(g->batCacheid);
229 0 : BBPunfix(c->batCacheid);
230 0 : throw(MAL, "algebra.groupby", GDK_EXCEPTION);
231 : }
232 2377 : *res = bn->batCacheid;
233 2377 : BBPkeepref(bn);
234 2377 : BBPunfix(g->batCacheid);
235 2377 : BBPunfix(c->batCacheid);
236 2377 : return MAL_SUCCEED;
237 : }
238 :
239 : static str
240 1 : ALGcard(lng *result, const bat *bid)
241 : {
242 1 : BAT *b, *en;
243 :
244 1 : if ((b = BATdescriptor(*bid)) == NULL) {
245 0 : throw(MAL, "algebra.card", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
246 : }
247 1 : en = BATunique(b, NULL);
248 1 : BBPunfix(b->batCacheid);
249 1 : if (en == NULL) {
250 0 : throw(MAL, "algebra.card", GDK_EXCEPTION);
251 : }
252 1 : struct canditer ci;
253 1 : canditer_init(&ci, NULL, en);
254 1 : *result = (lng) ci.ncand;
255 1 : BBPunfix(en->batCacheid);
256 1 : return MAL_SUCCEED;
257 : }
258 :
259 : static str
260 128051 : ALGselect2nil(bat *result, const bat *bid, const bat *sid, const void *low,
261 : const void *high, const bit *li, const bit *hi, const bit *anti,
262 : const bit *unknown)
263 : {
264 128051 : BAT *b, *s = NULL, *bn;
265 :
266 128051 : if ((*li != 0 && *li != 1) ||
267 128051 : (*hi != 0 && *hi != 1) || (*anti != 0 && *anti != 1)) {
268 0 : throw(MAL, "algebra.select", ILLEGAL_ARGUMENT);
269 : }
270 :
271 128122 : if ((b = BATdescriptor(*bid)) == NULL) {
272 0 : throw(MAL, "algebra.select", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
273 : }
274 128816 : if (sid && !is_bat_nil(*sid) && (s = BATdescriptor(*sid)) == NULL) {
275 0 : BBPunfix(b->batCacheid);
276 0 : throw(MAL, "algebra.select", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
277 : }
278 128858 : derefStr(b, low);
279 128858 : derefStr(b, high);
280 :
281 128858 : bool nanti = *anti, nli = *li, nhi = *hi;
282 :
283 : /* here we don't need open ended parts with nil */
284 128858 : if (!nanti && *unknown) {
285 1375 : const void *nilptr = ATOMnilptr(b->ttype);
286 1375 : if (nilptr) {
287 1375 : if (nli && ATOMcmp(b->ttype, low, nilptr) == 0) {
288 21 : low = high;
289 21 : nli = false;
290 : }
291 1369 : if (nhi && ATOMcmp(b->ttype, high, nilptr) == 0) {
292 23 : high = low;
293 23 : nhi = false;
294 : }
295 1370 : if (ATOMcmp(b->ttype, low, high) == 0 && ATOMcmp(b->ttype, high, nilptr) == 0) /* ugh sql nil != nil */
296 13 : nanti = true;
297 : }
298 127483 : } else if (!*unknown) {
299 121232 : const void *nilptr = ATOMnilptr(b->ttype);
300 242233 : if (nli && nhi && nilptr != NULL &&
301 121258 : ATOMcmp(b->ttype, low, nilptr) == 0 &&
302 24 : ATOMcmp(b->ttype, high, nilptr) == 0) {
303 : /* special case: equi-select for NIL */
304 128625 : high = NULL;
305 : }
306 : }
307 :
308 128625 : bn = BATselect(b, s, low, high, nli, nhi, nanti, false);
309 127705 : BBPunfix(b->batCacheid);
310 128803 : BBPreclaim(s);
311 128655 : if (bn == NULL)
312 0 : throw(MAL, "algebra.select", GDK_EXCEPTION);
313 128655 : *result = bn->batCacheid;
314 128655 : BBPkeepref(bn);
315 128655 : return MAL_SUCCEED;
316 : }
317 :
318 : static str
319 40835 : ALGselect2(bat *result, const bat *bid, const bat *sid, const void *low,
320 : const void *high, const bit *li, const bit *hi, const bit *anti)
321 : {
322 40835 : return ALGselect2nil(result, bid, sid, low, high, li, hi, anti, &(bit){0});
323 : }
324 :
325 : static str
326 79947 : ALGselect1(bat *result, const bat *bid, const void *low, const void *high,
327 : const bit *li, const bit *hi, const bit *anti)
328 : {
329 79947 : return ALGselect2nil(result, bid, NULL, low, high, li, hi, anti, &(bit){0});
330 : }
331 :
332 : static str
333 311 : ALGselect1nil(bat *result, const bat *bid, const void *low, const void *high,
334 : const bit *li, const bit *hi, const bit *anti, const bit *unknown)
335 : {
336 311 : return ALGselect2nil(result, bid, NULL, low, high, li, hi, anti, unknown);
337 : }
338 :
339 : static str
340 431539 : ALGthetaselect2(bat *result, const bat *bid, const bat *sid, const void *val,
341 : const char **op)
342 : {
343 431539 : BAT *b, *s = NULL, *bn;
344 :
345 431539 : if ((b = BATdescriptor(*bid)) == NULL) {
346 0 : throw(MAL, "algebra.thetaselect",
347 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
348 : }
349 433620 : if (sid && !is_bat_nil(*sid) && (s = BATdescriptor(*sid)) == NULL) {
350 0 : BBPunfix(b->batCacheid);
351 0 : throw(MAL, "algebra.thetaselect",
352 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
353 : }
354 433787 : derefStr(b, val);
355 433787 : bn = BATthetaselect(b, s, val, *op);
356 431361 : BBPunfix(b->batCacheid);
357 433530 : BBPreclaim(s);
358 433559 : if (bn == NULL)
359 0 : throw(MAL, "algebra.select", GDK_EXCEPTION);
360 433559 : *result = bn->batCacheid;
361 433559 : BBPkeepref(bn);
362 433559 : return MAL_SUCCEED;
363 : }
364 :
365 : static str
366 337 : ALGmarkselect(bat *r1, bat *r2, const bat *gid, const bat *mid, const bat *pid, const bit *Any)
367 : {
368 337 : BAT *g = BATdescriptor(*gid); /* oid */
369 337 : BAT *m = BATdescriptor(*mid); /* bit, true: match, false: empty set, nil: nil on left */
370 337 : BAT *p = BATdescriptor(*pid); /* bit */
371 337 : BAT *res1 = NULL, *res2 = NULL;
372 337 : bit any = *Any; /* any or normal comparison semantics */
373 :
374 337 : if (!g || !m || !p) {
375 0 : if (g) BBPreclaim(g);
376 0 : if (m) BBPreclaim(m);
377 0 : if (p) BBPreclaim(p);
378 0 : throw(MAL, "algebra.markselect", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
379 : }
380 337 : BUN nr = BATcount(g), q = 0;
381 :
382 337 : if ((res1 = COLnew(0, TYPE_oid, nr, TRANSIENT)) == NULL || (res2 = COLnew(0, TYPE_bit, nr, TRANSIENT)) == NULL) {
383 : BBPreclaim(g);
384 0 : BBPreclaim(m);
385 0 : BBPreclaim(p);
386 0 : if (res1) BBPreclaim(res1);
387 0 : throw(MAL, "algebra.markselect", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
388 : }
389 337 : assert(g->tsorted);
390 337 : oid *ri1 = Tloc(res1, 0);
391 337 : bit *ri2 = Tloc(res2, 0);
392 337 : bit *mi = Tloc(m, 0);
393 337 : bit *pi = Tloc(p, 0);
394 337 : oid cur = oid_nil;
395 :
396 337 : if (g->ttype == TYPE_void) { /* void case ? */
397 25 : oid c = g->hseqbase;
398 100 : for (BUN n = 0; n < nr; n++, c++) {
399 75 : ri1[q] = c;
400 75 : ri2[q] = FALSE;
401 75 : if (pi[n] == TRUE && mi[n] == TRUE)
402 7 : ri2[q] = TRUE;
403 68 : else if ((mi[n] == bit_nil && pi[n] != bit_nil && !any) || (mi[n] != FALSE && pi[n] == bit_nil && any))
404 3 : ri2[q] = bit_nil;
405 75 : q++;
406 : }
407 : } else {
408 312 : oid *gi = Tloc(g, 0);
409 312 : oid c = g->hseqbase;
410 312 : if (nr)
411 312 : cur = gi[0];
412 : bit m = FALSE;
413 : bool has_nil = false;
414 332251 : for (BUN n = 0; n < nr; n++, c++) {
415 331939 : if (c && cur != gi[n]) {
416 57618 : ri1[q] = c-1;
417 57618 : ri2[q] = (m == TRUE)?TRUE:(has_nil)?bit_nil:FALSE;
418 57618 : q++;
419 57618 : cur = gi[n];
420 57618 : m = FALSE;
421 57618 : has_nil = false;
422 : }
423 331939 : if (m == TRUE)
424 191802 : continue;
425 :
426 140137 : if (pi[n] == TRUE && mi[n] == TRUE)
427 : m = TRUE;
428 133264 : else if ((mi[n] == bit_nil && pi[n] != bit_nil && !any) || (mi[n] != FALSE && pi[n] == bit_nil && any))
429 331939 : has_nil = true;
430 : }
431 312 : if (nr) {
432 312 : ri1[q] = c-1;
433 312 : ri2[q] = (m == TRUE)?TRUE:(has_nil)?bit_nil:FALSE;
434 : }
435 312 : q++;
436 : }
437 337 : BATsetcount(res1, q);
438 337 : BATsetcount(res2, q);
439 337 : res1->tsorted = true;
440 337 : res1->tkey = true;
441 337 : res1->trevsorted = false;
442 337 : res2->tsorted = false;
443 337 : res2->trevsorted = false;
444 337 : res1->tnil = false;
445 337 : res1->tnonil = true;
446 337 : res2->tnonil = false;
447 337 : res2->tkey = false;
448 :
449 337 : BBPreclaim(g);
450 337 : BBPreclaim(m);
451 337 : BBPreclaim(p);
452 :
453 337 : BBPkeepref(res1);
454 337 : BBPkeepref(res2);
455 337 : *r1 = res1->batCacheid;
456 337 : *r2 = res2->batCacheid;
457 337 : return MAL_SUCCEED;
458 : }
459 :
460 : static str
461 19 : ALGouterselect(bat *r1, bat *r2, const bat *gid, const bat *mid, const bat *pid, const bit *Any)
462 : {
463 19 : BAT *g = BATdescriptor(*gid); /* oid */
464 19 : BAT *m = BATdescriptor(*mid); /* bit, true: match, false: empty set, nil: nil on left */
465 19 : BAT *p = BATdescriptor(*pid); /* bit */
466 19 : BAT *res1 = NULL, *res2 = NULL;
467 19 : bit any = *Any; /* any or normal comparison semantics */
468 :
469 19 : if (!g || !m || !p) {
470 0 : if (g) BBPreclaim(g);
471 0 : if (m) BBPreclaim(m);
472 0 : if (p) BBPreclaim(p);
473 0 : throw(MAL, "algebra.outerselect", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
474 : }
475 19 : BUN nr = BATcount(g), q = 0;
476 :
477 19 : if ((res1 = COLnew(0, TYPE_oid, nr, TRANSIENT)) == NULL || (res2 = COLnew(0, TYPE_bit, nr, TRANSIENT)) == NULL) {
478 : BBPreclaim(g);
479 0 : BBPreclaim(m);
480 0 : BBPreclaim(p);
481 0 : if (res1) BBPreclaim(res1);
482 0 : throw(MAL, "algebra.outerselect", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
483 : }
484 19 : assert(g->tsorted);
485 19 : oid *ri1 = Tloc(res1, 0);
486 19 : bit *ri2 = Tloc(res2, 0);
487 19 : bit *mi = Tloc(m, 0);
488 19 : bit *pi = Tloc(p, 0);
489 19 : oid cur = oid_nil;
490 :
491 19 : if (g->ttype == TYPE_void) { /* void case ? */
492 6 : oid c = g->hseqbase;
493 71 : for (BUN n = 0; n < nr; n++, c++) {
494 65 : ri1[q] = c;
495 127 : ri2[q] = (any && (mi[n] == bit_nil || pi[n] == bit_nil))?bit_nil:(mi[n] == TRUE && pi[n] == TRUE)?TRUE:FALSE;
496 65 : q++;
497 : }
498 : } else {
499 13 : oid *gi = Tloc(g, 0);
500 13 : oid c = g->hseqbase;
501 13 : if (nr)
502 13 : cur = gi[0];
503 : bool used = false;
504 493 : for (BUN n = 0; n < nr; n++, c++) {
505 480 : if (c && cur != gi[n]) {
506 122 : if (!used) {
507 0 : ri1[q] = c-1;
508 0 : ri2[q] = false;
509 0 : q++;
510 : }
511 122 : used = false;
512 122 : cur = gi[n];
513 : }
514 480 : if (mi[n] == TRUE && pi[n] == TRUE) {
515 278 : ri1[q] = c;
516 278 : ri2[q] = TRUE;
517 278 : used = true;
518 278 : q++;
519 202 : } else if (mi[n] == FALSE) { /* empty */
520 40 : ri1[q] = c;
521 40 : ri2[q] = FALSE;
522 40 : used = true;
523 40 : q++;
524 162 : } else if (any && (mi[n] == bit_nil /* ie has nil */ || pi[n] == bit_nil)) {
525 0 : ri1[q] = c;
526 0 : ri2[q] = bit_nil;
527 0 : used = true;
528 0 : q++;
529 : }
530 : }
531 13 : if (nr && !used) {
532 0 : ri1[q] = c-1;
533 0 : ri2[q] = FALSE;
534 0 : q++;
535 : }
536 : }
537 19 : BATsetcount(res1, q);
538 19 : BATsetcount(res2, q);
539 19 : res1->tsorted = true;
540 19 : res1->tkey = true;
541 19 : res1->trevsorted = false;
542 19 : res2->tsorted = false;
543 19 : res2->trevsorted = false;
544 19 : res1->tnil = false;
545 19 : res1->tnonil = true;
546 19 : res2->tnonil = false;
547 19 : res2->tkey = false;
548 :
549 19 : BBPreclaim(g);
550 19 : BBPreclaim(m);
551 19 : BBPreclaim(p);
552 :
553 19 : BBPkeepref(res1);
554 19 : BBPkeepref(res2);
555 19 : *r1 = res1->batCacheid;
556 19 : *r2 = res2->batCacheid;
557 19 : return MAL_SUCCEED;
558 : }
559 :
560 :
561 : static str
562 1469 : ALGselectNotNil(bat *result, const bat *bid)
563 : {
564 1469 : BAT *b;
565 :
566 1469 : if ((b = BATdescriptor(*bid)) == NULL)
567 0 : throw(MAL, "algebra.selectNotNil",
568 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
569 :
570 1470 : MT_lock_set(&b->theaplock);
571 1470 : bool bnonil = b->tnonil || b->ttype == TYPE_msk;
572 1470 : MT_lock_unset(&b->theaplock);
573 1470 : if (!bnonil) {
574 71 : BAT *s;
575 71 : s = BATselect(b, NULL, ATOMnilptr(b->ttype), NULL, true, true, true, false);
576 71 : if (s) {
577 71 : BAT *bn = BATproject(s, b);
578 71 : BBPunfix(s->batCacheid);
579 71 : if (bn) {
580 71 : BBPunfix(b->batCacheid);
581 71 : *result = bn->batCacheid;
582 71 : BBPkeepref(bn);
583 71 : return MAL_SUCCEED;
584 : }
585 : }
586 0 : BBPunfix(b->batCacheid);
587 0 : throw(MAL, "algebra.selectNotNil", GDK_EXCEPTION);
588 : }
589 : /* just pass on the result */
590 1399 : *result = b->batCacheid;
591 1399 : BBPkeepref(b);
592 1399 : return MAL_SUCCEED;
593 : }
594 :
595 : static str
596 522761 : do_join(bat *r1, bat *r2, bat *r3, const bat *lid, const bat *rid, const bat *r2id, const bat *slid, const bat *srid, int op, const void *c1, const void *c2, bool li, bool hi, bool anti, bool symmetric, /* these two only for rangejoin */
597 : const bit *nil_matches, const bit *not_in, const bit *max_one,
598 : const lng *estimate,
599 : gdk_return (*joinfunc)(BAT **, BAT **, BAT *, BAT *, BAT *, BAT *,
600 : bool, BUN),
601 : gdk_return (*semifunc)(BAT **, BAT **, BAT *, BAT *, BAT *, BAT *,
602 : bool, bool, BUN),
603 : gdk_return (*markfunc)(BAT **, BAT **, BAT **,
604 : BAT *, BAT *, BAT *, BAT *, BUN),
605 : gdk_return (*thetafunc)(BAT **, BAT **, BAT *, BAT *, BAT *, BAT *,
606 : int, bool, BUN),
607 : gdk_return (*bandfunc)(BAT **, BAT **, BAT *, BAT *, BAT *, BAT *,
608 : const void *, const void *, bool, bool, BUN),
609 : gdk_return (*rangefunc)(BAT **, BAT **, BAT *, BAT *, BAT *,
610 : BAT *, BAT *, bool, bool, bool, bool, BUN),
611 : BAT * (*difffunc)(BAT *, BAT *, BAT *, BAT *, bool, bool, BUN),
612 : BAT * (*interfunc)(BAT *, BAT *, BAT *, BAT *, bool, bool, BUN),
613 : const char *funcname)
614 : {
615 522761 : BAT *left = NULL, *right = NULL, *right2 = NULL;
616 522761 : BAT *candleft = NULL, *candright = NULL;
617 522761 : BAT *result1 = NULL, *result2 = NULL, *result3 = NULL;
618 522761 : BUN est;
619 522761 : const char *err = SQLSTATE(HY002) RUNTIME_OBJECT_MISSING;
620 :
621 522761 : assert(r2id == NULL || rangefunc != NULL);
622 :
623 522761 : if ((left = BATdescriptor(*lid)) == NULL)
624 0 : goto fail;
625 528544 : if ((right = BATdescriptor(*rid)) == NULL)
626 0 : goto fail;
627 528622 : if (slid && !is_bat_nil(*slid) && (candleft = BATdescriptor(*slid)) == NULL)
628 0 : goto fail;
629 528625 : if (srid && !is_bat_nil(*srid)
630 0 : && (candright = BATdescriptor(*srid)) == NULL)
631 0 : goto fail;
632 528625 : if (estimate == NULL || *estimate < 0 || is_lng_nil(*estimate)
633 0 : || *estimate > (lng) BUN_MAX)
634 : est = BUN_NONE;
635 : else
636 0 : est = (BUN) *estimate;
637 :
638 528625 : err = NULL; /* most likely error now is GDK_EXCEPTION */
639 :
640 528625 : if (thetafunc) {
641 51160 : assert(joinfunc == NULL);
642 51160 : assert(semifunc == NULL);
643 51160 : assert(markfunc == NULL);
644 51160 : assert(bandfunc == NULL);
645 51160 : assert(rangefunc == NULL);
646 51160 : assert(difffunc == NULL);
647 51160 : assert(interfunc == NULL);
648 51160 : if ((*thetafunc)
649 : (&result1, r2 ? &result2 : NULL, left, right, candleft, candright,
650 51160 : op, *nil_matches, est) != GDK_SUCCEED)
651 0 : goto fail;
652 477465 : } else if (joinfunc) {
653 353779 : assert(semifunc == NULL);
654 353779 : assert(markfunc == NULL);
655 353779 : assert(bandfunc == NULL);
656 353779 : assert(rangefunc == NULL);
657 353779 : assert(difffunc == NULL);
658 353779 : assert(interfunc == NULL);
659 353779 : if ((*joinfunc)
660 : (&result1, r2 ? &result2 : NULL, left, right, candleft, candright,
661 353779 : *nil_matches, est) != GDK_SUCCEED)
662 1 : goto fail;
663 123686 : } else if (semifunc) {
664 206 : assert(markfunc == NULL);
665 206 : assert(bandfunc == NULL);
666 206 : assert(rangefunc == NULL);
667 206 : assert(difffunc == NULL);
668 206 : assert(interfunc == NULL);
669 206 : if ((*semifunc)
670 : (&result1, r2 ? &result2 : NULL, left, right, candleft, candright,
671 206 : *nil_matches, *max_one, est) != GDK_SUCCEED)
672 25 : goto fail;
673 123480 : } else if (markfunc) {
674 4283 : assert(bandfunc == NULL);
675 4283 : assert(rangefunc == NULL);
676 4283 : assert(difffunc == NULL);
677 4283 : assert(interfunc == NULL);
678 8564 : if ((*markfunc) (&result1, r2 ? &result2 : NULL, &result3,
679 : left, right, candleft, candright, est) != GDK_SUCCEED)
680 0 : goto fail;
681 119197 : } else if (bandfunc) {
682 0 : assert(rangefunc == NULL);
683 0 : assert(difffunc == NULL);
684 0 : assert(interfunc == NULL);
685 0 : if ((*bandfunc)
686 : (&result1, r2 ? &result2 : NULL, left, right, candleft, candright,
687 : c1, c2, li, hi, est) != GDK_SUCCEED)
688 0 : goto fail;
689 119197 : } else if (rangefunc) {
690 147 : assert(difffunc == NULL);
691 147 : assert(interfunc == NULL);
692 147 : if ((right2 = BATdescriptor(*r2id)) == NULL) {
693 0 : err = SQLSTATE(HY002) RUNTIME_OBJECT_MISSING;
694 0 : goto fail;
695 : }
696 172 : if ((*rangefunc)
697 : (&result1, r2 ? &result2 : NULL, left, right, right2, candleft,
698 : candright, li, hi, anti, symmetric, est) != GDK_SUCCEED)
699 0 : goto fail;
700 145 : BBPunfix(right2->batCacheid);
701 119050 : } else if (difffunc) {
702 110376 : assert(r2 == NULL);
703 110376 : assert(interfunc == NULL);
704 110277 : if ((result1 = (*difffunc) (left, right, candleft, candright,
705 110376 : *nil_matches, *not_in, est)) == NULL)
706 0 : goto fail;
707 : } else {
708 8674 : assert(r2 == NULL);
709 8671 : if ((result1 = (*interfunc) (left, right, candleft, candright,
710 8674 : *nil_matches, *max_one, est)) == NULL)
711 1 : goto fail;
712 : }
713 525571 : *r1 = result1->batCacheid;
714 525571 : BBPkeepref(result1);
715 526401 : if (r2) {
716 324191 : *r2 = result2->batCacheid;
717 324191 : BBPkeepref(result2);
718 : }
719 527524 : if (r3) {
720 4274 : *r3 = result3->batCacheid;
721 4274 : BBPkeepref(result3);
722 : }
723 527530 : BBPunfix(left->batCacheid);
724 528165 : BBPunfix(right->batCacheid);
725 528524 : BBPreclaim(candleft);
726 528543 : BBPreclaim(candright);
727 : return MAL_SUCCEED;
728 :
729 27 : fail:
730 27 : BBPreclaim(left);
731 27 : BBPreclaim(right);
732 27 : BBPreclaim(right2);
733 27 : BBPreclaim(candleft);
734 27 : BBPreclaim(candright);
735 27 : if (err == NULL)
736 27 : throw(MAL, funcname, GDK_EXCEPTION);
737 0 : throw(MAL, funcname, "%s", err);
738 : }
739 :
740 : static str
741 314021 : ALGjoin(bat *r1, bat *r2, const bat *lid, const bat *rid, const bat *slid,
742 : const bat *srid, const bit *nil_matches, const lng *estimate)
743 : {
744 314021 : return do_join(r1, r2, NULL, lid, rid, NULL, slid, srid, 0, NULL, NULL,
745 : false, false, false, false, nil_matches, NULL, NULL,
746 : estimate, BATjoin, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
747 : "algebra.join");
748 : }
749 :
750 : static str
751 36431 : ALGjoin1(bat *r1, const bat *lid, const bat *rid, const bat *slid,
752 : const bat *srid, const bit *nil_matches, const lng *estimate)
753 : {
754 36431 : return do_join(r1, NULL, NULL, lid, rid, NULL, slid, srid, 0, NULL, NULL,
755 : false, false, false, false, nil_matches, NULL, NULL,
756 : estimate, BATjoin, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
757 : "algebra.join");
758 : }
759 :
760 : static str
761 645 : ALGleftjoin(bat *r1, bat *r2, const bat *lid, const bat *rid, const bat *slid,
762 : const bat *srid, const bit *nil_matches, const lng *estimate)
763 : {
764 645 : return do_join(r1, r2, NULL, lid, rid, NULL, slid, srid, 0, NULL, NULL,
765 : false, false, false, false, nil_matches, NULL, NULL,
766 : estimate, BATleftjoin, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
767 : "algebra.leftjoin");
768 : }
769 :
770 : static str
771 0 : ALGleftjoin1(bat *r1, const bat *lid, const bat *rid, const bat *slid,
772 : const bat *srid, const bit *nil_matches, const lng *estimate)
773 : {
774 0 : return do_join(r1, NULL, NULL, lid, rid, NULL, slid, srid, 0, NULL, NULL,
775 : false, false, false, false, nil_matches, NULL, NULL,
776 : estimate, BATleftjoin, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
777 : "algebra.leftjoin");
778 : }
779 :
780 : static str
781 53 : ALGouterjoin(bat *r1, bat *r2, const bat *lid, const bat *rid, const bat *slid,
782 : const bat *srid, const bit *nil_matches, const bit *match_one,
783 : const lng *estimate)
784 : {
785 53 : return do_join(r1, r2, NULL, lid, rid, NULL, slid, srid, 0, NULL, NULL,
786 : false, false, false, false, nil_matches, NULL, match_one,
787 : estimate, NULL, BATouterjoin, NULL, NULL, NULL, NULL, NULL, NULL,
788 : "algebra.outerjoin");
789 : }
790 :
791 : static str
792 0 : ALGouterjoin1(bat *r1, const bat *lid, const bat *rid, const bat *slid,
793 : const bat *srid, const bit *nil_matches, const bit *match_one,
794 : const lng *estimate)
795 : {
796 0 : return do_join(r1, NULL, NULL, lid, rid, NULL, slid, srid, 0, NULL, NULL,
797 : false, false, false, false, nil_matches, NULL, match_one,
798 : estimate, NULL, BATouterjoin, NULL, NULL, NULL, NULL, NULL, NULL,
799 : "algebra.outerjoin");
800 : }
801 :
802 : static str
803 151 : ALGsemijoin(bat *r1, bat *r2, const bat *lid, const bat *rid, const bat *slid,
804 : const bat *srid, const bit *nil_matches, const bit *max_one,
805 : const lng *estimate)
806 : {
807 151 : return do_join(r1, r2, NULL, lid, rid, NULL, slid, srid, 0, NULL, NULL,
808 : false, false, false, false, nil_matches, NULL, max_one,
809 : estimate, NULL, BATsemijoin, NULL, NULL, NULL, NULL, NULL, NULL,
810 : "algebra.semijoin");
811 : }
812 :
813 : static str
814 4262 : ALGmark2join(bat *r1, bat *r3, const bat *lid, const bat *rid,
815 : const bat *slid, const bat *srid, const lng *estimate)
816 : {
817 4262 : return do_join(r1, NULL, r3, lid, rid, NULL, slid, srid, 0, NULL, NULL,
818 : false, false, false, false, NULL, NULL, NULL,
819 : estimate, NULL, NULL, BATmarkjoin, NULL, NULL, NULL, NULL, NULL,
820 : "algebra.markjoin");
821 : }
822 :
823 : static str
824 2 : ALGmark3join(bat *r1, bat *r2, bat *r3, const bat *lid, const bat *rid,
825 : const bat *slid, const bat *srid, const lng *estimate)
826 : {
827 2 : return do_join(r1, r2, r3, lid, rid, NULL, slid, srid, 0, NULL, NULL,
828 : false, false, false, false, NULL, NULL, NULL,
829 : estimate, NULL, NULL, BATmarkjoin, NULL, NULL, NULL, NULL, NULL,
830 : "algebra.markjoin");
831 : }
832 :
833 : static str
834 7613 : ALGthetajoin(bat *r1, bat *r2, const bat *lid, const bat *rid, const bat *slid,
835 : const bat *srid, const int *op, const bit *nil_matches,
836 : const lng *estimate)
837 : {
838 7613 : return do_join(r1, r2, NULL, lid, rid, NULL, slid, srid, *op, NULL, NULL,
839 : false, false, false, false, nil_matches, NULL, NULL,
840 : estimate, NULL, NULL, NULL, BATthetajoin, NULL, NULL, NULL, NULL,
841 : "algebra.thetajoin");
842 : }
843 :
844 : static str
845 41384 : ALGthetajoin1(bat *r1, const bat *lid, const bat *rid, const bat *slid,
846 : const bat *srid, const int *op, const bit *nil_matches,
847 : const lng *estimate)
848 : {
849 41384 : return do_join(r1, NULL, NULL, lid, rid, NULL, slid, srid, *op, NULL, NULL,
850 : false, false, false, false, nil_matches, NULL, NULL,
851 : estimate, NULL, NULL, NULL, BATthetajoin, NULL, NULL, NULL, NULL,
852 : "algebra.thetajoin");
853 : }
854 :
855 : static str
856 0 : ALGbandjoin(bat *r1, bat *r2, const bat *lid, const bat *rid, const bat *slid,
857 : const bat *srid, const void *c1, const void *c2, const bit *li,
858 : const bit *hi, const lng *estimate)
859 : {
860 0 : return do_join(r1, r2, NULL, lid, rid, NULL, slid, srid, 0, c1, c2,
861 0 : *li, *hi, false, false, NULL, NULL, NULL, estimate,
862 : NULL, NULL, NULL, NULL, BATbandjoin, NULL, NULL, NULL,
863 : "algebra.bandjoin");
864 : }
865 :
866 : static str
867 0 : ALGbandjoin1(bat *r1, const bat *lid, const bat *rid, const bat *slid,
868 : const bat *srid, const void *c1, const void *c2, const bit *li,
869 : const bit *hi, const lng *estimate)
870 : {
871 0 : return do_join(r1, NULL, NULL, lid, rid, NULL, slid, srid, 0, c1, c2,
872 0 : *li, *hi, false, false, NULL, NULL, NULL, estimate,
873 : NULL, NULL, NULL, NULL, BATbandjoin, NULL, NULL, NULL,
874 : "algebra.bandjoin");
875 : }
876 :
877 : static str
878 118 : ALGrangejoin(bat *r1, bat *r2, const bat *lid, const bat *rlid, const bat *rhid,
879 : const bat *slid, const bat *srid, const bit *li, const bit *hi,
880 : const bit *anti, const bit *symmetric, const lng *estimate)
881 : {
882 240 : return do_join(r1, r2, NULL, lid, rlid, rhid, slid, srid, 0, NULL, NULL,
883 118 : *li, *hi, *anti, *symmetric, NULL, NULL, NULL, estimate,
884 : NULL, NULL, NULL, NULL, NULL, BATrangejoin, NULL, NULL,
885 : "algebra.rangejoin");
886 : }
887 :
888 : static str
889 22 : ALGrangejoin1(bat *r1, const bat *lid, const bat *rlid, const bat *rhid,
890 : const bat *slid, const bat *srid, const bit *li, const bit *hi,
891 : const bit *anti, const bit *symmetric, const lng *estimate)
892 : {
893 47 : return do_join(r1, NULL, NULL, lid, rlid, rhid, slid, srid, 0, NULL, NULL,
894 22 : *li, *hi, *anti, *symmetric, NULL, NULL, NULL, estimate,
895 : NULL, NULL, NULL, NULL, NULL, BATrangejoin, NULL, NULL,
896 : "algebra.rangejoin");
897 : }
898 :
899 : static str
900 110257 : ALGdifference(bat *r1, const bat *lid, const bat *rid, const bat *slid,
901 : const bat *srid, const bit *nil_matches, const bit *not_in,
902 : const lng *estimate)
903 : {
904 110257 : return do_join(r1, NULL, NULL, lid, rid, NULL, slid, srid, 0, NULL, NULL,
905 : false, false, false, false, nil_matches, not_in, NULL,
906 : estimate, NULL, NULL, NULL, NULL, NULL, NULL, BATdiff, NULL,
907 : "algebra.difference");
908 : }
909 :
910 : static str
911 8669 : ALGintersect(bat *r1, const bat *lid, const bat *rid, const bat *slid,
912 : const bat *srid, const bit *nil_matches, const bit *max_one,
913 : const lng *estimate)
914 : {
915 8669 : return do_join(r1, NULL, NULL, lid, rid, NULL, slid, srid, 0, NULL, NULL,
916 : false, false, false, false, nil_matches, NULL, max_one,
917 : estimate, NULL, NULL, NULL, NULL, NULL, NULL, NULL, BATintersect,
918 : "algebra.intersect");
919 : }
920 :
921 : /* algebra.firstn(b:bat[:any],
922 : * [ s:bat[:oid],
923 : * [ g:bat[:oid], ] ]
924 : * n:lng,
925 : * asc:bit,
926 : * nilslast:bit,
927 : * distinct:bit)
928 : * returns :bat[:oid] [ , :bat[:oid] ]
929 : */
930 : static str
931 1568 : ALGfirstn(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
932 : {
933 1568 : bat *ret1, *ret2 = NULL;
934 1568 : bat bid, sid, gid;
935 1568 : BAT *b, *s = NULL, *g = NULL;
936 1568 : BAT *bn = NULL, *gn = NULL;
937 1568 : lng n;
938 1568 : bit asc, nilslast, distinct;
939 1568 : gdk_return rc;
940 :
941 1568 : (void) cntxt;
942 1568 : (void) mb;
943 :
944 1568 : assert(pci->retc == 1 || pci->retc == 2);
945 1568 : assert(pci->argc - pci->retc >= 5 && pci->argc - pci->retc <= 7);
946 :
947 1568 : n = *getArgReference_lng(stk, pci, pci->argc - 4);
948 1568 : if (n < 0)
949 0 : throw(MAL, "algebra.firstn", ILLEGAL_ARGUMENT);
950 1568 : if (n > (lng) BUN_MAX)
951 : n = BUN_MAX;
952 1568 : ret1 = getArgReference_bat(stk, pci, 0);
953 1568 : if (pci->retc == 2)
954 517 : ret2 = getArgReference_bat(stk, pci, 1);
955 1568 : bid = *getArgReference_bat(stk, pci, pci->retc);
956 1568 : if ((b = BATdescriptor(bid)) == NULL)
957 0 : throw(MAL, "algebra.firstn", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
958 1569 : if (pci->argc - pci->retc > 5) {
959 1570 : sid = *getArgReference_bat(stk, pci, pci->retc + 1);
960 1570 : if (!is_bat_nil(sid) && (s = BATdescriptor(sid)) == NULL) {
961 0 : BBPunfix(bid);
962 0 : throw(MAL, "algebra.firstn",
963 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
964 : }
965 1570 : if (pci->argc - pci->retc > 6) {
966 1570 : gid = *getArgReference_bat(stk, pci, pci->retc + 2);
967 1570 : if (!is_bat_nil(gid) && (g = BATdescriptor(gid)) == NULL) {
968 0 : BBPunfix(bid);
969 0 : BBPunfix(sid);
970 0 : throw(MAL, "algebra.firstn",
971 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
972 : }
973 : }
974 : }
975 1569 : asc = *getArgReference_bit(stk, pci, pci->argc - 3);
976 1569 : nilslast = *getArgReference_bit(stk, pci, pci->argc - 2);
977 1569 : distinct = *getArgReference_bit(stk, pci, pci->argc - 1);
978 2621 : rc = BATfirstn(&bn, ret2 ? &gn : NULL, b, s, g, (BUN) n, asc, nilslast,
979 : distinct);
980 1566 : BBPunfix(b->batCacheid);
981 1568 : BBPreclaim(s);
982 1568 : BBPreclaim(g);
983 1571 : if (rc != GDK_SUCCEED)
984 0 : throw(MAL, "algebra.firstn", GDK_EXCEPTION);
985 1571 : *ret1 = bn->batCacheid;
986 1571 : BBPkeepref(bn);
987 1563 : if (ret2) {
988 515 : *ret2 = gn->batCacheid;
989 515 : BBPkeepref(gn);
990 : }
991 : return MAL_SUCCEED;
992 : }
993 :
994 : static str
995 9 : ALGunary(bat *result, const bat *bid, BAT *(*func)(BAT *), const char *name)
996 : {
997 9 : BAT *b, *bn;
998 :
999 9 : if ((b = BATdescriptor(*bid)) == NULL) {
1000 0 : throw(MAL, name, SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1001 : }
1002 9 : bn = (*func) (b);
1003 9 : BBPunfix(b->batCacheid);
1004 9 : if (bn == NULL)
1005 0 : throw(MAL, name, GDK_EXCEPTION);
1006 9 : *result = bn->batCacheid;
1007 9 : BBPkeepref(bn);
1008 9 : return MAL_SUCCEED;
1009 : }
1010 :
1011 : static inline BAT *
1012 9 : BATwcopy(BAT *b)
1013 : {
1014 9 : return COLcopy(b, b->ttype, true, TRANSIENT);
1015 : }
1016 :
1017 : static str
1018 9 : ALGcopy(bat *result, const bat *bid)
1019 : {
1020 9 : return ALGunary(result, bid, BATwcopy, "algebra.copy");
1021 : }
1022 :
1023 : static str
1024 74 : ALGunique(bat *result, const bat *bid, const bat *sid)
1025 : {
1026 74 : BAT *b, *s = NULL, *bn = NULL;
1027 :
1028 74 : if ((b = BATdescriptor(*bid)) == NULL) {
1029 0 : throw(MAL, "algebra.unique", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1030 : }
1031 74 : if (sid && !is_bat_nil(*sid) && (s = BATdescriptor(*sid)) == NULL) {
1032 0 : BBPunfix(b->batCacheid);
1033 0 : throw(MAL, "algebra.unique", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1034 : }
1035 74 : bn = BATunique(b, s);
1036 74 : BBPunfix(b->batCacheid);
1037 74 : BBPreclaim(s);
1038 74 : if (bn == NULL)
1039 0 : throw(MAL, "algebra.unique", GDK_EXCEPTION);
1040 74 : *result = bn->batCacheid;
1041 74 : BBPkeepref(bn);
1042 74 : return MAL_SUCCEED;
1043 : }
1044 :
1045 : static str
1046 43526 : ALGcrossproduct(bat *l, bat *r, const bat *left, const bat *right,
1047 : const bat *slid, const bat *srid, const bit *max_one)
1048 : {
1049 43526 : BAT *L, *R, *bn1, *bn2 = NULL;
1050 43526 : BAT *sl = NULL, *sr = NULL;
1051 43526 : gdk_return ret;
1052 :
1053 43526 : L = BATdescriptor(*left);
1054 45014 : R = BATdescriptor(*right);
1055 45092 : if (L == NULL || R == NULL) {
1056 0 : BBPreclaim(L);
1057 0 : BBPreclaim(R);
1058 0 : throw(MAL, "algebra.crossproduct",
1059 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1060 : }
1061 45092 : if ((slid && !is_bat_nil(*slid) && (sl = BATdescriptor(*slid)) == NULL) ||
1062 0 : (srid && !is_bat_nil(*srid) && (sr = BATdescriptor(*srid)) == NULL)) {
1063 0 : BBPunfix(L->batCacheid);
1064 0 : BBPunfix(R->batCacheid);
1065 0 : BBPreclaim(sl);
1066 : /* sr == NULL, so no need to unfix */
1067 0 : throw(MAL, "algebra.crossproduct",
1068 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1069 : }
1070 46622 : ret = BATsubcross(&bn1, r ? &bn2 : NULL, L, R, sl, sr,
1071 45092 : max_one && !is_bit_nil(*max_one) && *max_one);
1072 44412 : BBPunfix(L->batCacheid);
1073 44996 : BBPunfix(R->batCacheid);
1074 45084 : BBPreclaim(sl);
1075 45088 : BBPreclaim(sr);
1076 45086 : if (ret != GDK_SUCCEED)
1077 62 : throw(MAL, "algebra.crossproduct", GDK_EXCEPTION);
1078 45024 : *l = bn1->batCacheid;
1079 45024 : BBPkeepref(bn1);
1080 44974 : if (r) {
1081 43461 : *r = bn2->batCacheid;
1082 43461 : BBPkeepref(bn2);
1083 : }
1084 : return MAL_SUCCEED;
1085 : }
1086 :
1087 : static str
1088 1479 : ALGcrossproduct1(bat *l, const bat *left, const bat *right, const bit *max_one)
1089 : {
1090 1479 : return ALGcrossproduct(l, NULL, left, right, NULL, NULL, max_one);
1091 : }
1092 :
1093 : static str
1094 42162 : ALGcrossproduct2(bat *l, bat *r, const bat *left, const bat *right,
1095 : const bit *max_one)
1096 : {
1097 42162 : return ALGcrossproduct(l, r, left, right, NULL, NULL, max_one);
1098 : }
1099 :
1100 : static str
1101 0 : ALGcrossproduct3(bat *l, bat *r, const bat *left, const bat *right,
1102 : const bat *sl, const bat *sr, const bit *max_one)
1103 : {
1104 0 : return ALGcrossproduct(l, r, left, right, sl, sr, max_one);
1105 : }
1106 :
1107 : static str
1108 0 : ALGcrossproduct4(bat *l, const bat *left, const bat *right, const bat *sl,
1109 : const bat *sr, const bit *max_one)
1110 : {
1111 0 : return ALGcrossproduct(l, NULL, left, right, sl, sr, max_one);
1112 : }
1113 :
1114 : static str
1115 366 : ALGoutercrossproduct3(bat *l, bat *r, const bat *left, const bat *right, const bat *slid, const bat *srid, const bit *max_one)
1116 : {
1117 366 : BAT *L, *R, *bn1, *bn2 = NULL;
1118 366 : BAT *sl = NULL, *sr = NULL;
1119 366 : gdk_return ret;
1120 :
1121 366 : L = BATdescriptor(*left);
1122 366 : R = BATdescriptor(*right);
1123 366 : if (L == NULL || R == NULL) {
1124 0 : BBPreclaim(L);
1125 0 : BBPreclaim(R);
1126 0 : throw(MAL, "algebra.crossproduct", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1127 : }
1128 366 : if ((slid && !is_bat_nil(*slid) && (sl = BATdescriptor(*slid)) == NULL) ||
1129 366 : (srid && !is_bat_nil(*srid) && (sr = BATdescriptor(*srid)) == NULL)) {
1130 0 : BBPunfix(L->batCacheid);
1131 0 : BBPunfix(R->batCacheid);
1132 0 : BBPreclaim(sl);
1133 : /* sr == NULL, so no need to unfix */
1134 0 : throw(MAL, "algebra.crossproduct", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1135 : }
1136 366 : ret = BAToutercross(&bn1, r ? &bn2 : NULL, L, R, sl, sr,
1137 366 : max_one && !is_bit_nil(*max_one) && *max_one);
1138 366 : BBPunfix(L->batCacheid);
1139 366 : BBPunfix(R->batCacheid);
1140 366 : BBPreclaim(sl);
1141 366 : BBPreclaim(sr);
1142 366 : if (ret != GDK_SUCCEED)
1143 0 : throw(MAL, "algebra.crossproduct", GDK_EXCEPTION);
1144 366 : *l = bn1->batCacheid;
1145 366 : BBPkeepref(bn1);
1146 366 : if (r) {
1147 366 : *r = bn2->batCacheid;
1148 366 : BBPkeepref(bn2);
1149 : }
1150 : return MAL_SUCCEED;
1151 : }
1152 :
1153 : static str
1154 1726371 : ALGprojection2(bat *result, const bat *lid, const bat *r1id, const bat *r2id)
1155 : {
1156 1726371 : BAT *l, *r1, *r2 = NULL, *bn;
1157 :
1158 1726371 : if ((l = BATdescriptor(*lid)) == NULL) {
1159 0 : throw(MAL, "algebra.projection",
1160 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1161 : }
1162 1738326 : if ((r1 = BATdescriptor(*r1id)) == NULL) {
1163 0 : BBPunfix(l->batCacheid);
1164 0 : throw(MAL, "algebra.projection",
1165 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1166 : }
1167 1737605 : if (r2id && !is_bat_nil(*r2id) && (r2 = BATdescriptor(*r2id)) == NULL) {
1168 0 : BBPunfix(l->batCacheid);
1169 0 : BBPunfix(r1->batCacheid);
1170 0 : throw(MAL, "algebra.projection",
1171 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1172 : }
1173 1737605 : bn = BATproject2(l, r1, r2);
1174 1718373 : BBPunfix(l->batCacheid);
1175 1734854 : BBPunfix(r1->batCacheid);
1176 1737562 : BBPreclaim(r2);
1177 1737727 : if (bn == NULL)
1178 0 : throw(MAL, "algebra.projection", GDK_EXCEPTION);
1179 1737727 : *result = bn->batCacheid;
1180 1737727 : BBPkeepref(bn);
1181 1737727 : return MAL_SUCCEED;
1182 : }
1183 :
1184 : str
1185 1728821 : ALGprojection(bat *result, const bat *lid, const bat *rid)
1186 : {
1187 1728821 : return ALGprojection2(result, lid, rid, NULL);
1188 : }
1189 :
1190 : static str
1191 23566 : ALGsort33(bat *result, bat *norder, bat *ngroup, const bat *bid,
1192 : const bat *order, const bat *group, const bit *reverse,
1193 : const bit *nilslast, const bit *stable)
1194 : {
1195 23566 : BAT *bn = NULL, *on = NULL, *gn = NULL;
1196 23566 : BAT *b = NULL, *o = NULL, *g = NULL;
1197 :
1198 23566 : if ((b = BATdescriptor(*bid)) == NULL)
1199 0 : throw(MAL, "algebra.sort", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1200 23567 : if (order && !is_bat_nil(*order) && (o = BATdescriptor(*order)) == NULL) {
1201 0 : BBPunfix(b->batCacheid);
1202 0 : throw(MAL, "algebra.sort", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1203 : }
1204 23567 : if (group &&!is_bat_nil(*group) && (g = BATdescriptor(*group)) == NULL) {
1205 0 : BBPreclaim(o);
1206 0 : BBPunfix(b->batCacheid);
1207 0 : throw(MAL, "algebra.sort", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1208 : }
1209 27122 : if (BATsort(result ? &bn : NULL,
1210 : norder ? &on : NULL,
1211 : ngroup ? &gn : NULL,
1212 23567 : b, o, g, *reverse, *nilslast, *stable) != GDK_SUCCEED) {
1213 0 : BBPreclaim(o);
1214 0 : BBPreclaim(g);
1215 0 : BBPunfix(b->batCacheid);
1216 0 : throw(MAL, "algebra.sort", GDK_EXCEPTION);
1217 : }
1218 23567 : BBPunfix(b->batCacheid);
1219 23567 : BBPreclaim(o);
1220 23567 : BBPreclaim(g);
1221 23567 : if (result) {
1222 23567 : *result = bn->batCacheid;
1223 23567 : BBPkeepref(bn);
1224 : }
1225 23567 : if (norder) {
1226 20012 : *norder = on->batCacheid;
1227 20012 : BBPkeepref(on);
1228 : }
1229 23567 : if (ngroup) {
1230 13491 : *ngroup = gn->batCacheid;
1231 13491 : BBPkeepref(gn);
1232 : }
1233 : return MAL_SUCCEED;
1234 : }
1235 :
1236 : static str
1237 4024 : ALGsort32(bat *result, bat *norder, const bat *bid, const bat *order,
1238 : const bat *group, const bit *reverse, const bit *nilslast,
1239 : const bit *stable)
1240 : {
1241 4024 : return ALGsort33(result, norder, NULL, bid, order, group, reverse, nilslast,
1242 : stable);
1243 : }
1244 :
1245 : static str
1246 1952 : ALGsort31(bat *result, const bat *bid, const bat *order, const bat *group,
1247 : const bit *reverse, const bit *nilslast, const bit *stable)
1248 : {
1249 1952 : return ALGsort33(result, NULL, NULL, bid, order, group, reverse, nilslast,
1250 : stable);
1251 : }
1252 :
1253 : static str
1254 0 : ALGsort23(bat *result, bat *norder, bat *ngroup, const bat *bid,
1255 : const bat *order, const bit *reverse, const bit *nilslast,
1256 : const bit *stable)
1257 : {
1258 0 : return ALGsort33(result, norder, ngroup, bid, order, NULL, reverse,
1259 : nilslast, stable);
1260 : }
1261 :
1262 : static str
1263 0 : ALGsort22(bat *result, bat *norder, const bat *bid, const bat *order,
1264 : const bit *reverse, const bit *nilslast, const bit *stable)
1265 : {
1266 0 : return ALGsort33(result, norder, NULL, bid, order, NULL, reverse, nilslast,
1267 : stable);
1268 : }
1269 :
1270 : static str
1271 0 : ALGsort21(bat *result, const bat *bid, const bat *order, const bit *reverse,
1272 : const bit *nilslast, const bit *stable)
1273 : {
1274 0 : return ALGsort33(result, NULL, NULL, bid, order, NULL, reverse, nilslast,
1275 : stable);
1276 : }
1277 :
1278 : static str
1279 6231 : ALGsort13(bat *result, bat *norder, bat *ngroup, const bat *bid,
1280 : const bit *reverse, const bit *nilslast, const bit *stable)
1281 : {
1282 6231 : return ALGsort33(result, norder, ngroup, bid, NULL, NULL, reverse, nilslast,
1283 : stable);
1284 : }
1285 :
1286 : static str
1287 2497 : ALGsort12(bat *result, bat *norder, const bat *bid, const bit *reverse,
1288 : const bit *nilslast, const bit *stable)
1289 : {
1290 2497 : return ALGsort33(result, norder, NULL, bid, NULL, NULL, reverse, nilslast,
1291 : stable);
1292 : }
1293 :
1294 : static str
1295 1603 : ALGsort11(bat *result, const bat *bid, const bit *reverse, const bit *nilslast,
1296 : const bit *stable)
1297 : {
1298 1603 : return ALGsort33(result, NULL, NULL, bid, NULL, NULL, reverse, nilslast,
1299 : stable);
1300 : }
1301 :
1302 : static str
1303 69745 : ALGcountCND_nil(lng *result, const bat *bid, const bat *cnd,
1304 : const bit *ignore_nils)
1305 : {
1306 69745 : BAT *b, *s = NULL;
1307 :
1308 69745 : if ((b = BATdescriptor(*bid)) == NULL) {
1309 0 : throw(MAL, "aggr.count", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1310 : }
1311 69974 : if (cnd && !is_bat_nil(*cnd) && (s = BATdescriptor(*cnd)) == NULL) {
1312 0 : BBPunfix(b->batCacheid);
1313 0 : throw(MAL, "aggr.count", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1314 : }
1315 69974 : if (b->ttype == TYPE_msk || mask_cand(b)) {
1316 30 : BATsum(result, TYPE_lng, b, s, *ignore_nils, false);
1317 69944 : } else if (*ignore_nils) {
1318 1769 : *result = (lng) BATcount_no_nil(b, s);
1319 : } else {
1320 68175 : struct canditer ci;
1321 68175 : canditer_init(&ci, b, s);
1322 68191 : *result = (lng) ci.ncand;
1323 : }
1324 69990 : BBPreclaim(s);
1325 69990 : BBPunfix(b->batCacheid);
1326 69990 : return MAL_SUCCEED;
1327 : }
1328 :
1329 : static str
1330 1769 : ALGcount_nil(lng *result, const bat *bid, const bit *ignore_nils)
1331 : {
1332 1769 : return ALGcountCND_nil(result, bid, NULL, ignore_nils);
1333 : }
1334 :
1335 : static str
1336 0 : ALGcountCND_bat(lng *result, const bat *bid, const bat *cnd)
1337 : {
1338 0 : return ALGcountCND_nil(result, bid, cnd, &(bit) { 0 });
1339 : }
1340 :
1341 : static str
1342 67978 : ALGcount_bat(lng *result, const bat *bid)
1343 : {
1344 67978 : return ALGcountCND_nil(result, bid, NULL, &(bit) { 0 });
1345 : }
1346 :
1347 : static str
1348 0 : ALGcountCND_no_nil(lng *result, const bat *bid, const bat *cnd)
1349 : {
1350 0 : return ALGcountCND_nil(result, bid, cnd, &(bit) { 1 });
1351 : }
1352 :
1353 : static str
1354 0 : ALGcount_no_nil(lng *result, const bat *bid)
1355 : {
1356 0 : return ALGcountCND_nil(result, bid, NULL, &(bit) { 1 });
1357 : }
1358 :
1359 : static str
1360 6 : ALGslice(bat *ret, const bat *bid, const lng *start, const lng *end)
1361 : {
1362 6 : BAT *b, *bn = NULL;
1363 :
1364 6 : if ((b = BATdescriptor(*bid)) == NULL) {
1365 0 : throw(MAL, "algebra.slice", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1366 : }
1367 6 : if (slice(&bn, b, *start, *end) == GDK_SUCCEED) {
1368 6 : *ret = bn->batCacheid;
1369 6 : BBPkeepref(bn);
1370 6 : BBPunfix(b->batCacheid);
1371 6 : return MAL_SUCCEED;
1372 : }
1373 0 : BBPunfix(b->batCacheid);
1374 0 : throw(MAL, "algebra.slice", GDK_EXCEPTION);
1375 : }
1376 :
1377 : static str
1378 1 : ALGslice_int(bat *ret, const bat *bid, const int *start, const int *end)
1379 : {
1380 1 : lng s = *start;
1381 1 : lng e = (is_int_nil(*end) ? lng_nil : *end);
1382 :
1383 1 : return ALGslice(ret, bid, &s, &e);
1384 : }
1385 :
1386 : static str
1387 0 : ALGslice_lng(bat *ret, const bat *bid, const lng *start, const lng *end)
1388 : {
1389 0 : lng s = *start;
1390 0 : lng e = *end;
1391 :
1392 0 : return ALGslice(ret, bid, &s, &e);
1393 : }
1394 :
1395 : /* carve out a slice based on the OIDs */
1396 : /* beware that BATs may have different OID bases */
1397 : static str
1398 5 : ALGslice_oid(bat *ret, const bat *bid, const oid *start, const oid *end)
1399 : {
1400 5 : lng s = (lng) (is_oid_nil(*start) ? 0 : (lng) *start);
1401 5 : lng e = (is_oid_nil(*end) ? lng_nil : (lng) *end);
1402 :
1403 5 : return ALGslice(ret, bid, &s, &e);
1404 : }
1405 :
1406 : static str
1407 17086 : ALGsubslice_lng(bat *ret, const bat *bid, const lng *start, const lng *end)
1408 : {
1409 17086 : BAT *b, *bn;
1410 17086 : BUN s, e;
1411 :
1412 17086 : if (*start < 0 || (*end < 0 && !is_lng_nil(*end)))
1413 0 : throw(MAL, "algebra.subslice", ILLEGAL_ARGUMENT);
1414 17086 : if ((b = BBPquickdesc(*bid)) == NULL)
1415 0 : throw(MAL, "algebra.subslice", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1416 17087 : s = (BUN) *start;
1417 17087 : if (s > BATcount(b))
1418 : s = BATcount(b);
1419 17087 : e = is_lng_nil(*end) ? BATcount(b) : (BUN) *end + 1;
1420 17087 : if (e > BATcount(b))
1421 : e = BATcount(b);
1422 17087 : if (e < s)
1423 : e = s;
1424 17087 : bn = BATdense(0, b->hseqbase + s, e - s);
1425 17088 : if (bn == NULL)
1426 0 : throw(MAL, "algebra.subslice", SQLSTATE(HY013) MAL_MALLOC_FAIL);
1427 17088 : *ret = bn->batCacheid;
1428 17088 : BBPkeepref(bn);
1429 17088 : return MAL_SUCCEED;
1430 : }
1431 :
1432 : /*
1433 : * BUN Get/Fetch
1434 : */
1435 :
1436 : static str
1437 88858 : doALGfetch(ptr ret, BAT *b, BUN pos)
1438 : {
1439 88858 : assert(pos <= BUN_MAX);
1440 88858 : BATiter bi = bat_iterator(b);
1441 88858 : if (ATOMextern(b->ttype)) {
1442 190 : ptr _src = BUNtail(bi, pos);
1443 190 : size_t _len = ATOMlen(b->ttype, _src);
1444 190 : ptr _dst = GDKmalloc(_len);
1445 190 : if (_dst == NULL) {
1446 0 : bat_iterator_end(&bi);
1447 0 : throw(MAL, "doAlgFetch", SQLSTATE(HY013) MAL_MALLOC_FAIL);
1448 : }
1449 190 : memcpy(_dst, _src, _len);
1450 190 : *(ptr *) ret = _dst;
1451 : } else {
1452 88668 : size_t _s = ATOMsize(ATOMtype(b->ttype));
1453 88668 : if (b->ttype == TYPE_void) {
1454 0 : *(oid *) ret = b->tseqbase;
1455 0 : if (!is_oid_nil(b->tseqbase))
1456 0 : *(oid *) ret += pos;
1457 88668 : } else if (_s == 4) {
1458 88581 : *(int *) ret = ((int *) bi.base)[pos];
1459 : } else if (_s == 1) {
1460 11 : *(bte *) ret = ((bte *) bi.base)[pos];
1461 : } else if (_s == 2) {
1462 1 : *(sht *) ret = ((sht *) bi.base)[pos];
1463 : } else if (_s == 8) {
1464 75 : *(lng *) ret = ((lng *) bi.base)[pos];
1465 : #ifdef HAVE_HGE
1466 : } else if (_s == 16) {
1467 0 : *(hge *) ret = ((hge *) bi.base)[pos];
1468 : #endif
1469 : } else {
1470 0 : memcpy(ret, (const char *) bi.base + (pos << bi.shift), _s);
1471 : }
1472 : }
1473 88858 : bat_iterator_end(&bi);
1474 88858 : return MAL_SUCCEED;
1475 : }
1476 :
1477 : static str
1478 88860 : ALGfetch(ptr ret, const bat *bid, const lng *pos)
1479 : {
1480 88860 : BAT *b;
1481 88860 : str msg;
1482 :
1483 88860 : if ((b = BATdescriptor(*bid)) == NULL) {
1484 0 : throw(MAL, "algebra.fetch", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1485 : }
1486 88860 : if (*pos < (lng) 0) {
1487 0 : BBPunfix(b->batCacheid);
1488 0 : throw(MAL, "algebra.fetch",
1489 : ILLEGAL_ARGUMENT ": row index to fetch must be non negative\n");
1490 : }
1491 88860 : if (BATcount(b) == 0) {
1492 2 : BBPunfix(b->batCacheid);
1493 2 : throw(MAL, "algebra.fetch",
1494 : ILLEGAL_ARGUMENT
1495 : ": cannot fetch a single row from an empty input\n");
1496 : }
1497 88858 : if (*pos >= (lng) BATcount(b)) {
1498 0 : BBPunfix(b->batCacheid);
1499 0 : throw(MAL, "algebra.fetch",
1500 : ILLEGAL_ARGUMENT ": row index to fetch is out of range\n");
1501 : }
1502 88858 : msg = doALGfetch(ret, b, (BUN) *pos);
1503 88858 : BBPunfix(b->batCacheid);
1504 88858 : return msg;
1505 : }
1506 :
1507 : str
1508 88860 : ALGfetchoid(ptr ret, const bat *bid, const oid *pos)
1509 : {
1510 88860 : lng o = *pos;
1511 :
1512 88860 : return ALGfetch(ret, bid, &o);
1513 : }
1514 :
1515 : static str
1516 0 : ALGexist(bit *ret, const bat *bid, const void *val)
1517 : {
1518 0 : BAT *b;
1519 0 : BUN q;
1520 :
1521 0 : if ((b = BATdescriptor(*bid)) == NULL) {
1522 0 : throw(MAL, "algebra.exist", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1523 : }
1524 0 : derefStr(b, val);
1525 0 : q = BUNfnd(b, val);
1526 0 : *ret = (q != BUN_NONE);
1527 0 : BBPunfix(b->batCacheid);
1528 0 : return MAL_SUCCEED;
1529 : }
1530 :
1531 : static str
1532 9 : ALGfind(oid *ret, const bat *bid, ptr val)
1533 : {
1534 9 : BAT *b;
1535 9 : BUN q;
1536 9 : str msg = MAL_SUCCEED;
1537 :
1538 9 : if ((b = BATdescriptor(*bid)) == NULL) {
1539 0 : throw(MAL, "algebra.find", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1540 : }
1541 9 : derefStr(b, val);
1542 9 : q = BUNfnd(b, val);
1543 :
1544 9 : if (q == BUN_NONE) {
1545 3 : *ret = oid_nil;
1546 : } else
1547 6 : *ret = (oid) q;
1548 9 : BBPunfix(b->batCacheid);
1549 9 : return msg;
1550 : }
1551 :
1552 :
1553 : static str
1554 205351 : ALGprojecttail(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1555 : {
1556 205351 : bat *ret = getArgReference_bat(stk, pci, 0);
1557 205351 : bat bid = *getArgReference_bat(stk, pci, 1);
1558 205351 : const ValRecord *v = &stk->stk[getArg(pci, 2)];
1559 205351 : BAT *b, *bn;
1560 :
1561 205351 : (void) cntxt;
1562 205351 : (void) mb;
1563 205351 : if (isaBatType(getArgType(mb, pci, 2)))
1564 0 : throw(MAL, "algebra.project", "Scalar value expected");
1565 205351 : if ((b = BBPquickdesc(bid)) == NULL)
1566 0 : throw(MAL, "algebra.project", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1567 205337 : bn = BATconstant(b->hseqbase, v->vtype, VALptr(v), BATcount(b), TRANSIENT);
1568 205471 : if (bn == NULL) {
1569 0 : *ret = bat_nil;
1570 0 : throw(MAL, "algebra.project", SQLSTATE(HY013) MAL_MALLOC_FAIL);
1571 : }
1572 205471 : *ret = bn->batCacheid;
1573 205471 : BBPkeepref(bn);
1574 205471 : return MAL_SUCCEED;
1575 : }
1576 :
1577 :
1578 : static str
1579 0 : ALGreuse(bat *ret, const bat *bid)
1580 : {
1581 0 : BAT *b, *bn;
1582 0 : if ((b = BATdescriptor(*bid)) == NULL)
1583 0 : throw(MAL, "algebra.reuse", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1584 :
1585 0 : if (!b->batTransient || b->batRestricted != BAT_WRITE) {
1586 0 : if (ATOMvarsized(b->ttype)) {
1587 0 : bn = BATwcopy(b);
1588 0 : if (bn == NULL) {
1589 0 : BBPunfix(b->batCacheid);
1590 0 : throw(MAL, "algebra.reuse", SQLSTATE(HY013) MAL_MALLOC_FAIL);
1591 : }
1592 : } else {
1593 0 : bn = COLnew(b->hseqbase, b->ttype, BATcount(b), TRANSIENT);
1594 0 : if (bn == NULL) {
1595 0 : BBPunfix(b->batCacheid);
1596 0 : throw(MAL, "algebra.reuse", SQLSTATE(HY013) MAL_MALLOC_FAIL);
1597 : }
1598 0 : BATsetcount(bn, BATcount(b));
1599 0 : bn->tsorted = false;
1600 0 : bn->trevsorted = false;
1601 0 : BATkey(bn, false);
1602 : }
1603 0 : *ret = bn->batCacheid;
1604 0 : BBPkeepref(bn);
1605 0 : BBPunfix(b->batCacheid);
1606 : } else
1607 0 : BBPkeepref(b);
1608 : return MAL_SUCCEED;
1609 : }
1610 :
1611 : /*
1612 : * BAT standard deviation
1613 : */
1614 : static str
1615 7 : ALGstdev(dbl *res, const bat *bid)
1616 : {
1617 7 : BAT *b;
1618 7 : dbl stdev;
1619 :
1620 7 : if ((b = BATdescriptor(*bid)) == NULL)
1621 0 : throw(MAL, "aggr.stdev", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1622 7 : stdev = BATcalcstdev_sample(NULL, b);
1623 7 : BBPunfix(b->batCacheid);
1624 7 : if (is_dbl_nil(stdev) && GDKerrbuf && GDKerrbuf[0])
1625 0 : throw(MAL, "aggr.stdev", GDK_EXCEPTION);
1626 7 : *res = stdev;
1627 7 : return MAL_SUCCEED;
1628 : }
1629 :
1630 : static str
1631 13 : ALGstdevp(dbl *res, const bat *bid)
1632 : {
1633 13 : BAT *b;
1634 13 : dbl stdev;
1635 :
1636 13 : if ((b = BATdescriptor(*bid)) == NULL)
1637 0 : throw(MAL, "aggr.stdevp", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1638 13 : stdev = BATcalcstdev_population(NULL, b);
1639 13 : BBPunfix(b->batCacheid);
1640 13 : if (is_dbl_nil(stdev) && GDKerrbuf && GDKerrbuf[0])
1641 1 : throw(MAL, "aggr.stdevp", GDK_EXCEPTION);
1642 12 : *res = stdev;
1643 12 : return MAL_SUCCEED;
1644 : }
1645 :
1646 : /*
1647 : * BAT variance
1648 : */
1649 : static str
1650 2 : ALGvariance(dbl *res, const bat *bid)
1651 : {
1652 2 : BAT *b;
1653 2 : dbl variance;
1654 :
1655 2 : if ((b = BATdescriptor(*bid)) == NULL)
1656 0 : throw(MAL, "aggr.variance", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1657 2 : variance = BATcalcvariance_sample(NULL, b);
1658 2 : BBPunfix(b->batCacheid);
1659 2 : if (is_dbl_nil(variance) && GDKerrbuf && GDKerrbuf[0])
1660 0 : throw(MAL, "aggr.variance", GDK_EXCEPTION);
1661 2 : *res = variance;
1662 2 : return MAL_SUCCEED;
1663 : }
1664 :
1665 : static str
1666 5 : ALGvariancep(dbl *res, const bat *bid)
1667 : {
1668 5 : BAT *b;
1669 5 : dbl variance;
1670 :
1671 5 : if ((b = BATdescriptor(*bid)) == NULL)
1672 0 : throw(MAL, "aggr.variancep", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1673 5 : variance = BATcalcvariance_population(NULL, b);
1674 5 : BBPunfix(b->batCacheid);
1675 5 : if (is_dbl_nil(variance) && GDKerrbuf && GDKerrbuf[0])
1676 1 : throw(MAL, "aggr.variancep", GDK_EXCEPTION);
1677 4 : *res = variance;
1678 4 : return MAL_SUCCEED;
1679 : }
1680 :
1681 : /*
1682 : * BAT covariance
1683 : */
1684 : static str
1685 5 : ALGcovariance(dbl *res, const bat *bid1, const bat *bid2)
1686 : {
1687 5 : BAT *b1, *b2;
1688 5 : dbl covariance;
1689 :
1690 5 : if ((b1 = BATdescriptor(*bid1)) == NULL)
1691 0 : throw(MAL, "aggr.covariance", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1692 5 : if ((b2 = BATdescriptor(*bid2)) == NULL) {
1693 0 : BBPunfix(b1->batCacheid);
1694 0 : throw(MAL, "aggr.covariance", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1695 : }
1696 :
1697 5 : covariance = BATcalccovariance_sample(b1, b2);
1698 5 : BBPunfix(b1->batCacheid);
1699 5 : BBPunfix(b2->batCacheid);
1700 4 : if (is_dbl_nil(covariance) && GDKerrbuf && GDKerrbuf[0])
1701 0 : throw(MAL, "aggr.covariance", GDK_EXCEPTION);
1702 4 : *res = covariance;
1703 4 : return MAL_SUCCEED;
1704 : }
1705 :
1706 : static str
1707 9 : ALGcovariancep(dbl *res, const bat *bid1, const bat *bid2)
1708 : {
1709 9 : BAT *b1, *b2;
1710 9 : dbl covariance;
1711 :
1712 9 : if ((b1 = BATdescriptor(*bid1)) == NULL)
1713 0 : throw(MAL, "aggr.covariancep", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1714 9 : if ((b2 = BATdescriptor(*bid2)) == NULL) {
1715 0 : BBPunfix(b1->batCacheid);
1716 0 : throw(MAL, "aggr.covariancep", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1717 : }
1718 :
1719 9 : covariance = BATcalccovariance_population(b1, b2);
1720 9 : BBPunfix(b1->batCacheid);
1721 9 : BBPunfix(b2->batCacheid);
1722 9 : if (is_dbl_nil(covariance) && GDKerrbuf && GDKerrbuf[0])
1723 1 : throw(MAL, "aggr.covariancep", GDK_EXCEPTION);
1724 8 : *res = covariance;
1725 8 : return MAL_SUCCEED;
1726 : }
1727 :
1728 : /*
1729 : * BAT correlation
1730 : */
1731 : static str
1732 19 : ALGcorr(dbl *res, const bat *bid1, const bat *bid2)
1733 : {
1734 19 : BAT *b1, *b2;
1735 19 : dbl covariance;
1736 :
1737 19 : if ((b1 = BATdescriptor(*bid1)) == NULL)
1738 0 : throw(MAL, "aggr.corr", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1739 19 : if ((b2 = BATdescriptor(*bid2)) == NULL) {
1740 0 : BBPunfix(b1->batCacheid);
1741 0 : throw(MAL, "aggr.corr", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1742 : }
1743 :
1744 19 : covariance = BATcalccorrelation(b1, b2);
1745 19 : BBPunfix(b1->batCacheid);
1746 19 : BBPunfix(b2->batCacheid);
1747 19 : if (is_dbl_nil(covariance) && GDKerrbuf && GDKerrbuf[0])
1748 1 : throw(MAL, "aggr.corr", GDK_EXCEPTION);
1749 18 : *res = covariance;
1750 18 : return MAL_SUCCEED;
1751 : }
1752 :
1753 : #include "mel.h"
1754 : mel_func algebra_init_funcs[] = {
1755 : command("algebra", "groupby", ALGgroupby, false, "Produces a new BAT with groups identified by the head column. The result contains tail times the head value, ie the tail contains the result group sizes.", args(1,3, batarg("",oid),batarg("gids",oid),batarg("cnts",lng))),
1756 : command("algebra", "find", ALGfind, false, "Returns the index position of a value. If no such BUN exists return OID-nil.", args(1,3, arg("",oid),batargany("b",1),argany("t",1))),
1757 : command("algebra", "fetch", ALGfetchoid, false, "Returns the value of the BUN at x-th position with 0 <= x < b.count", args(1,3, argany("",1),batargany("b",1),arg("x",oid))),
1758 : pattern("algebra", "project", ALGprojecttail, false, "Fill the tail with a constant", args(1,3, batargany("",2),batargany("b",1),argany("v",2))),
1759 : command("algebra", "projection", ALGprojection, false, "Project left input onto right input.", args(1,3, batargany("",1),batarg("left",oid),batargany("right",1))),
1760 : command("algebra", "projection", ALGprojection2, false, "Project left input onto right inputs which should be consecutive.", args(1,4, batargany("",1),batarg("left",oid),batargany("right1",1),batargany("right2",1))),
1761 : command("algebra", "copy", ALGcopy, false, "Returns physical copy of a BAT.", args(1,2, batargany("",1),batargany("b",1))),
1762 : command("algebra", "exist", ALGexist, false, "Returns whether 'val' occurs in b.", args(1,3, arg("",bit),batargany("b",1),argany("val",1))),
1763 : command("algebra", "select", ALGselect1, false, "Select all head values for which the tail value is in range.\nInput is a dense-headed BAT, output is a dense-headed BAT with in\nthe tail the head value of the input BAT for which the tail value\nis between the values low and high (inclusive if li respectively\nhi is set). The output BAT is sorted on the tail value. If low\nor high is nil, the boundary is not considered (effectively - and\n+ infinity). If anti is set, the result is the complement. Nil\nvalues in the tail are never matched, unless low=nil, high=nil,\nli=1, hi=1, anti=0. All non-nil values are returned if low=nil,\nhigh=nil, and li, hi are not both 1, or anti=1.\nNote that the output is suitable as second input for the other\nversion of this function.", args(1,7, batarg("",oid),batargany("b",1),argany("low",1),argany("high",1),arg("li",bit),arg("hi",bit),arg("anti",bit))),
1764 : command("algebra", "select", ALGselect2, false, "Select all head values of the first input BAT for which the tail value\nis in range and for which the head value occurs in the tail of the\nsecond input BAT.\nThe first input is a dense-headed BAT, the second input is a\ndense-headed BAT with sorted tail, output is a dense-headed BAT\nwith in the tail the head value of the input BAT for which the\ntail value is between the values low and high (inclusive if li\nrespectively hi is set). The output BAT is sorted on the tail\nvalue. If low or high is nil, the boundary is not considered\n(effectively - and + infinity). If anti is set, the result is the\ncomplement. Nil values in the tail are never matched, unless\nlow=nil, high=nil, li=1, hi=1, anti=0. All non-nil values are\nreturned if low=nil, high=nil, and li, hi are not both 1, or anti=1.\nNote that the output is suitable as second input for this\nfunction.", args(1,8, batarg("",oid),batargany("b",1),batarg("s",oid),argany("low",1),argany("high",1),arg("li",bit),arg("hi",bit),arg("anti",bit))),
1765 : command("algebra", "select", ALGselect1nil, false, "With unknown set, each nil != nil", args(1,8, batarg("",oid),batargany("b",1),argany("low",1),argany("high",1),arg("li",bit),arg("hi",bit),arg("anti",bit),arg("unknown",bit))),
1766 : command("algebra", "select", ALGselect2nil, false, "With unknown set, each nil != nil", args(1,9, batarg("",oid),batargany("b",1),batarg("s",oid),argany("low",1),argany("high",1),arg("li",bit),arg("hi",bit),arg("anti",bit),arg("unknown",bit))),
1767 : command("algebra", "thetaselect", ALGthetaselect2, false, "Select all head values of the first input BAT for which the tail value\nobeys the relation value OP VAL and for which the head value occurs in\nthe tail of the second input BAT.\nInput is a dense-headed BAT, output is a dense-headed BAT with in\nthe tail the head value of the input BAT for which the\nrelationship holds. The output BAT is sorted on the tail value.", args(1,5, batarg("",oid),batargany("b",1),batarg("s",oid),argany("val",1),arg("op",str))),
1768 : command("algebra", "markselect", ALGmarkselect, false, "Group on group-ids, return aggregated anyequal or allnotequal", args(2,6, batarg("",oid), batarg("", bit), batarg("gid",oid), batarg("m", bit), batarg("p", bit), arg("any", bit))),
1769 : command("algebra", "outerselect", ALGouterselect, false, "Per input lid return at least one row, if none of the predicates (p) hold, return a nil, else 'all' true cases.", args(2,6, batarg("",oid), batarg("", bit), batarg("lid", oid), batarg("rid", bit), batarg("predicate", bit), arg("any", bit))),
1770 : command("algebra", "selectNotNil", ALGselectNotNil, false, "Select all not-nil values", args(1,2, batargany("",1),batargany("b",1))),
1771 : command("algebra", "sort", ALGsort11, false, "Returns a copy of the BAT sorted on tail values.\nThe order is descending if the reverse bit is set.\nThis is a stable sort if the stable bit is set.", args(1,5, batargany("",1),batargany("b",1),arg("reverse",bit),arg("nilslast",bit),arg("stable",bit))),
1772 : command("algebra", "sort", ALGsort12, false, "Returns a copy of the BAT sorted on tail values and a BAT that\nspecifies how the input was reordered.\nThe order is descending if the reverse bit is set.\nThis is a stable sort if the stable bit is set.", args(2,6, batargany("",1),batarg("",oid),batargany("b",1),arg("reverse",bit),arg("nilslast",bit),arg("stable",bit))),
1773 : command("algebra", "sort", ALGsort13, false, "Returns a copy of the BAT sorted on tail values, a BAT that specifies\nhow the input was reordered, and a BAT with group information.\nThe order is descending if the reverse bit is set.\nThis is a stable sort if the stable bit is set.", args(3,7, batargany("",1),batarg("",oid),batarg("",oid),batargany("b",1),arg("reverse",bit),arg("nilslast",bit),arg("stable",bit))),
1774 : command("algebra", "sort", ALGsort21, false, "Returns a copy of the BAT sorted on tail values.\nThe order is descending if the reverse bit is set.\nThis is a stable sort if the stable bit is set.", args(1,6, batargany("",1),batargany("b",1),batarg("o",oid),arg("reverse",bit),arg("nilslast",bit),arg("stable",bit))),
1775 : command("algebra", "sort", ALGsort22, false, "Returns a copy of the BAT sorted on tail values and a BAT that\nspecifies how the input was reordered.\nThe order is descending if the reverse bit is set.\nThis is a stable sort if the stable bit is set.", args(2,7, batargany("",1),batarg("",oid),batargany("b",1),batarg("o",oid),arg("reverse",bit),arg("nilslast",bit),arg("stable",bit))),
1776 : command("algebra", "sort", ALGsort23, false, "Returns a copy of the BAT sorted on tail values, a BAT that specifies\nhow the input was reordered, and a BAT with group information.\nThe order is descending if the reverse bit is set.\nThis is a stable sort if the stable bit is set.", args(3,8, batargany("",1),batarg("",oid),batarg("",oid),batargany("b",1),batarg("o",oid),arg("reverse",bit),arg("nilslast",bit),arg("stable",bit))),
1777 : command("algebra", "sort", ALGsort31, false, "Returns a copy of the BAT sorted on tail values.\nThe order is descending if the reverse bit is set.\nThis is a stable sort if the stable bit is set.", args(1,7, batargany("",1),batargany("b",1),batarg("o",oid),batarg("g",oid),arg("reverse",bit),arg("nilslast",bit),arg("stable",bit))),
1778 : command("algebra", "sort", ALGsort32, false, "Returns a copy of the BAT sorted on tail values and a BAT that\nspecifies how the input was reordered.\nThe order is descending if the reverse bit is set.\nThis is a stable sort if the stable bit is set.", args(2,8, batargany("",1),batarg("",oid),batargany("b",1),batarg("o",oid),batarg("g",oid),arg("reverse",bit),arg("nilslast",bit),arg("stable",bit))),
1779 : command("algebra", "sort", ALGsort33, false, "Returns a copy of the BAT sorted on tail values, a BAT that specifies\nhow the input was reordered, and a BAT with group information.\nThe order is descending if the reverse bit is set.\nThis is a stable sort if the stable bit is set.", args(3,9, batargany("",1),batarg("",oid),batarg("",oid),batargany("b",1),batarg("o",oid),batarg("g",oid),arg("reverse",bit),arg("nilslast",bit),arg("stable",bit))),
1780 : command("algebra", "unique", ALGunique, false, "Select all unique values from the tail of the first input.\nInput is a dense-headed BAT, the second input is a\ndense-headed BAT with sorted tail, output is a dense-headed\nBAT with in the tail the head value of the input BAT that was\nselected. The output BAT is sorted on the tail value. The\nsecond input BAT is a list of candidates.", args(1,3, batarg("",oid),batargany("b",1),batarg("s",oid))),
1781 : command("algebra", "crossproduct", ALGcrossproduct2, false, "Returns 2 columns with all BUNs, consisting of the head-oids\nfrom 'left' and 'right' for which there are BUNs in 'left'\nand 'right' with equal tails", args(2,5, batarg("l",oid),batarg("r",oid),batargany("left",1),batargany("right",2),arg("max_one",bit))),
1782 : command("algebra", "crossproduct", ALGcrossproduct1, false, "Compute the cross product of both input bats; but only produce left output", args(1,4, batarg("",oid),batargany("left",1),batargany("right",2),arg("max_one",bit))),
1783 : command("algebra", "crossproduct", ALGcrossproduct3, false, "Compute the cross product of both input bats", args(2,7, batarg("l",oid),batarg("r",oid),batargany("left",1),batargany("right",2),batarg("sl",oid),batarg("sr",oid),arg("max_one",bit))),
1784 : command("algebra", "crossproduct", ALGcrossproduct4, false, "Compute the cross product of both input bats; but only produce left output", args(1,6, batarg("",oid),batargany("left",1),batargany("right",2),batarg("sl",oid),batarg("sr",oid),arg("max_one",bit))),
1785 : command("algebra", "outercrossproduct", ALGoutercrossproduct3, false, "Compute the outer cross product of both input bats", args(2,7, batarg("l",oid),batarg("r",oid),batargany("left",1),batargany("right",2),batarg("sl",oid),batarg("sr",oid),arg("max_one",bit))),
1786 : command("algebra", "join", ALGjoin, false, "Join", args(2,8, batarg("",oid),batarg("",oid),batargany("l",1),batargany("r",1),batarg("sl",oid),batarg("sr",oid),arg("nil_matches",bit),arg("estimate",lng))),
1787 : command("algebra", "join", ALGjoin1, false, "Join; only produce left output", args(1,7, batarg("",oid),batargany("l",1),batargany("r",1),batarg("sl",oid),batarg("sr",oid),arg("nil_matches",bit),arg("estimate",lng))),
1788 : command("algebra", "leftjoin", ALGleftjoin, false, "Left join with candidate lists", args(2,8, batarg("",oid),batarg("",oid),batargany("l",1),batargany("r",1),batarg("sl",oid),batarg("sr",oid),arg("nil_matches",bit),arg("estimate",lng))),
1789 : command("algebra", "leftjoin", ALGleftjoin1, false, "Left join with candidate lists; only produce left output", args(1,7, batarg("",oid),batargany("l",1),batargany("r",1),batarg("sl",oid),batarg("sr",oid),arg("nil_matches",bit),arg("estimate",lng))),
1790 : command("algebra", "outerjoin", ALGouterjoin, false, "Left outer join with candidate lists", args(2,9, batarg("",oid),batarg("",oid),batargany("l",1),batargany("r",1),batarg("sl",oid),batarg("sr",oid),arg("nil_matches",bit),arg("match_one",bit),arg("estimate",lng))),
1791 : command("algebra", "outerjoin", ALGouterjoin1, false, "Left outer join with candidate lists; only produce left output", args(1,8,batarg("",oid),batargany("l",1),batargany("r",1),batarg("sl",oid),batarg("sr",oid),arg("nil_matches",bit),arg("match_one",bit),arg("estimate",lng))),
1792 : command("algebra", "semijoin", ALGsemijoin, false, "Semi join with candidate lists", args(2,9, batarg("",oid),batarg("",oid),batargany("l",1),batargany("r",1),batarg("sl",oid),batarg("sr",oid),arg("nil_matches",bit),arg("max_one",bit),arg("estimate",lng))),
1793 : command("algebra", "markjoin", ALGmark2join, false, "Mark join with candidate lists", args(2,7, batarg("",oid),batarg("",bit),batargany("l",1),batargany("r",1),batarg("sl",oid),batarg("sr",oid),arg("estimate",lng))),
1794 : command("algebra", "markjoin", ALGmark3join, false, "Mark join with candidate lists", args(3,8, batarg("",oid),batarg("",oid),batarg("",bit),batargany("l",1),batargany("r",1),batarg("sl",oid),batarg("sr",oid),arg("estimate",lng))),
1795 : command("algebra", "thetajoin", ALGthetajoin, false, "Theta join with candidate lists", args(2,9, batarg("",oid),batarg("",oid),batargany("l",1),batargany("r",1),batarg("sl",oid),batarg("sr",oid),arg("op",int),arg("nil_matches",bit),arg("estimate",lng))),
1796 : command("algebra", "thetajoin", ALGthetajoin1, false, "Theta join with candidate lists; only produce left output", args(1,8, batarg("",oid),batargany("l",1),batargany("r",1),batarg("sl",oid),batarg("sr",oid),arg("op",int),arg("nil_matches",bit),arg("estimate",lng))),
1797 : command("algebra", "bandjoin", ALGbandjoin, false, "Band join: values in l and r match if r - c1 <[=] l <[=] r + c2", args(2,11, batarg("",oid),batarg("",oid),batargany("l",1),batargany("r",1),batarg("sl",oid),batarg("sr",oid),argany("c1",1),argany("c2",1),arg("li",bit),arg("hi",bit),arg("estimate",lng))),
1798 : command("algebra", "bandjoin", ALGbandjoin1, false, "Band join: values in l and r match if r - c1 <[=] l <[=] r + c2; only produce left output", args(1,10, batarg("",oid),batargany("l",1),batargany("r",1),batarg("sl",oid),batarg("sr",oid),argany("c1",1),argany("c2",1),arg("li",bit),arg("hi",bit),arg("estimate",lng))),
1799 : command("algebra", "rangejoin", ALGrangejoin, false, "Range join: values in l and r1/r2 match if r1 <[=] l <[=] r2", args(2,12, batarg("",oid),batarg("",oid),batargany("l",1),batargany("r1",1),batargany("r2",1),batarg("sl",oid),batarg("sr",oid),arg("li",bit),arg("hi",bit),arg("anti",bit),arg("symmetric",bit),arg("estimate",lng))),
1800 : command("algebra", "rangejoin", ALGrangejoin1, false, "Range join: values in l and r1/r2 match if r1 <[=] l <[=] r2; only produce left output", args(1,11,batarg("",oid),batargany("l",1),batargany("r1",1),batargany("r2",1),batarg("sl",oid),batarg("sr",oid),arg("li",bit),arg("hi",bit),arg("anti",bit),arg("symmetric",bit),arg("estimate",lng))),
1801 : command("algebra", "difference", ALGdifference, false, "Difference of l and r with candidate lists", args(1,8, batarg("",oid),batargany("l",1),batargany("r",1),batarg("sl",oid),batarg("sr",oid),arg("nil_matches",bit),arg("nil_clears",bit),arg("estimate",lng))),
1802 : command("algebra", "intersect", ALGintersect, false, "Intersection of l and r with candidate lists (i.e. half of semi-join)", args(1,8, batarg("",oid),batargany("l",1),batargany("r",1),batarg("sl",oid),batarg("sr",oid),arg("nil_matches",bit),arg("max_one",bit),arg("estimate",lng))),
1803 : pattern("algebra", "firstn", ALGfirstn, false, "Calculate first N values of B with candidate list S", args(1,8, batarg("",oid),batargany("b",0),batarg("s",oid),batarg("g",oid),arg("n",lng),arg("asc",bit),arg("nilslast",bit),arg("distinct",bit))),
1804 : pattern("algebra", "firstn", ALGfirstn, false, "Calculate first N values of B with candidate list S", args(2,9, batarg("",oid),batarg("",oid),batargany("b",0),batarg("s",oid),batarg("g",oid),arg("n",lng),arg("asc",bit),arg("nilslast",bit),arg("distinct",bit))),
1805 : command("algebra", "reuse", ALGreuse, false, "Reuse a temporary BAT if you can. Otherwise,\nallocate enough storage to accept result of an\noperation (not involving the heap)", args(1,2, batargany("",1),batargany("b",1))),
1806 : command("algebra", "slice", ALGslice_oid, false, "Return the slice based on head oid x till y (exclusive).", args(1,4, batargany("",1),batargany("b",1),arg("x",oid),arg("y",oid))),
1807 : command("algebra", "slice", ALGslice_int, false, "Return the slice with the BUNs at position x till y.", args(1,4, batargany("",1),batargany("b",1),arg("x",int),arg("y",int))),
1808 : command("algebra", "slice", ALGslice_lng, false, "Return the slice with the BUNs at position x till y.", args(1,4, batargany("",1),batargany("b",1),arg("x",lng),arg("y",lng))),
1809 : command("algebra", "subslice", ALGsubslice_lng, false, "Return the oids of the slice with the BUNs at position x till y.", args(1,4, batarg("",oid),batargany("b",1),arg("x",lng),arg("y",lng))),
1810 : command("aggr", "count", ALGcount_bat, false, "Return the current size (in number of elements) in a BAT.", args(1,2, arg("",lng),batargany("b",0))),
1811 : command("aggr", "count", ALGcount_nil, false, "Return the number of elements currently in a BAT ignores\nBUNs with nil-tail iff ignore_nils==TRUE.", args(1,3, arg("",lng),batargany("b",0),arg("ignore_nils",bit))),
1812 : command("aggr", "count_no_nil", ALGcount_no_nil, false, "Return the number of elements currently\nin a BAT ignoring BUNs with nil-tail", args(1,2, arg("",lng),batargany("b",2))),
1813 : command("aggr", "count", ALGcountCND_bat, false, "Return the current size (in number of elements) in a BAT.", args(1,3, arg("",lng),batargany("b",0),batarg("cnd",oid))),
1814 : command("aggr", "count", ALGcountCND_nil, false, "Return the number of elements currently in a BAT ignores\nBUNs with nil-tail iff ignore_nils==TRUE.", args(1,4, arg("",lng),batargany("b",0),batarg("cnd",oid),arg("ignore_nils",bit))),
1815 : command("aggr", "count_no_nil", ALGcountCND_no_nil, false, "Return the number of elements currently\nin a BAT ignoring BUNs with nil-tail", args(1,3, arg("",lng),batargany("b",2),batarg("cnd",oid))),
1816 : command("aggr", "cardinality", ALGcard, false, "Return the cardinality of the BAT tail values.", args(1,2, arg("",lng),batargany("b",2))),
1817 : command("aggr", "min", ALGminany, false, "Return the lowest tail value or nil.", args(1,2, argany("",2),batargany("b",2))),
1818 : command("aggr", "min", ALGminany_skipnil, false, "Return the lowest tail value or nil.", args(1,3, argany("",2),batargany("b",2),arg("skipnil",bit))),
1819 : command("aggr", "max", ALGmaxany, false, "Return the highest tail value or nil.", args(1,2, argany("",2),batargany("b",2))),
1820 : command("aggr", "max", ALGmaxany_skipnil, false, "Return the highest tail value or nil.", args(1,3, argany("",2),batargany("b",2),arg("skipnil",bit))),
1821 : command("aggr", "stdev", ALGstdev, false, "Gives the standard deviation of all tail values", args(1,2, arg("",dbl),batargany("b",2))),
1822 : command("aggr", "stdevp", ALGstdevp, false, "Gives the standard deviation of all tail values", args(1,2, arg("",dbl),batargany("b",2))),
1823 : command("aggr", "variance", ALGvariance, false, "Gives the variance of all tail values", args(1,2, arg("",dbl),batargany("b",2))),
1824 : command("aggr", "variancep", ALGvariancep, false, "Gives the variance of all tail values", args(1,2, arg("",dbl),batargany("b",2))),
1825 : command("aggr", "covariance", ALGcovariance, false, "Gives the covariance of all tail values", args(1,3, arg("",dbl),batargany("b1",2),batargany("b2",2))),
1826 : command("aggr", "covariancep", ALGcovariancep, false, "Gives the covariance of all tail values", args(1,3, arg("",dbl),batargany("b1",2),batargany("b2",2))),
1827 : command("aggr", "corr", ALGcorr, false, "Gives the correlation of all tail values", args(1,3, arg("",dbl),batargany("b1",2),batargany("b2",2))),
1828 : // sql
1829 : command("aggr", "exist", ALGexist, false, "", args(1,3, arg("",bit),batargany("b",2),argany("h",1))),
1830 : { .imp=NULL }
1831 : };
1832 : #include "mal_import.h"
1833 : #ifdef _MSC_VER
1834 : #undef read
1835 : #pragma section(".CRT$XCU",read)
1836 : #endif
1837 323 : LIB_STARTUP_FUNC(init_algebra_mal)
1838 323 : { mal_module("algebra", NULL, algebra_init_funcs); }
|