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 2388 : CMDgen_group(BAT **result, BAT *gids, BAT *cnts)
60 : {
61 2388 : BUN j;
62 2388 : BATiter gi = bat_iterator(gids);
63 2388 : BAT *r = COLnew(0, TYPE_oid, gi.count * 2, TRANSIENT);
64 :
65 2388 : if (r == NULL) {
66 0 : bat_iterator_end(&gi);
67 0 : return GDK_FAIL;
68 : }
69 2388 : BATiter ci = bat_iterator(cnts);
70 2388 : if (gi.type == TYPE_void) {
71 1049 : oid id = gi.tseq;
72 1049 : lng *cnt = (lng *) ci.base;
73 96195 : for (j = 0; j < gi.count; j++) {
74 95146 : lng i, sz = cnt[j];
75 190236 : for (i = 0; i < sz; i++) {
76 95090 : 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 95146 : id ++;
84 : }
85 : } else {
86 1339 : oid *id = (oid *) gi.base;
87 1339 : lng *cnt = (lng *) ci.base;
88 140494 : for (j = 0; j < gi.count; j++) {
89 139155 : lng i, sz = cnt[j];
90 274814 : for (i = 0; i < sz; i++) {
91 135659 : 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 139155 : id ++;
99 : }
100 : }
101 2388 : bat_iterator_end(&ci);
102 2388 : r->tkey = false;
103 2388 : r->tseqbase = oid_nil;
104 2388 : r->tsorted = gi.sorted;
105 2388 : r->trevsorted = gi.revsorted;
106 2388 : r->tnonil = gi.nonil;
107 2388 : bat_iterator_end(&gi);
108 2388 : *result = r;
109 2388 : 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 771 : ALGminany_skipnil(ptr result, const bat *bid, const bit *skipnil)
141 : {
142 771 : BAT *b;
143 771 : ptr p;
144 771 : str msg = MAL_SUCCEED;
145 :
146 771 : if (result == NULL || (b = BATdescriptor(*bid)) == NULL)
147 0 : throw(MAL, "algebra.min", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
148 :
149 774 : 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 774 : if (ATOMextern(b->ttype)) {
155 42 : *(ptr *) result = p = BATmin_skipnil(b, NULL, *skipnil);
156 : } else {
157 732 : p = BATmin_skipnil(b, result, *skipnil);
158 732 : if (p != result)
159 0 : msg = createException(MAL, "algebra.min",
160 : SQLSTATE(HY002) "INTERNAL ERROR");
161 : }
162 774 : if (msg == MAL_SUCCEED && p == NULL)
163 0 : msg = createException(MAL, "algebra.min", GDK_EXCEPTION);
164 : }
165 774 : BBPunfix(b->batCacheid);
166 774 : return msg;
167 : }
168 :
169 : static str
170 771 : ALGminany(ptr result, const bat *bid)
171 : {
172 771 : bit skipnil = TRUE;
173 771 : return ALGminany_skipnil(result, bid, &skipnil);
174 : }
175 :
176 : static str
177 545 : ALGmaxany_skipnil(ptr result, const bat *bid, const bit *skipnil)
178 : {
179 545 : BAT *b;
180 545 : ptr p;
181 545 : str msg = MAL_SUCCEED;
182 :
183 545 : if (result == NULL || (b = BATdescriptor(*bid)) == NULL)
184 0 : throw(MAL, "algebra.max", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
185 :
186 545 : 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 545 : if (ATOMextern(b->ttype)) {
192 68 : *(ptr *) result = p = BATmax_skipnil(b, NULL, *skipnil);
193 : } else {
194 477 : p = BATmax_skipnil(b, result, *skipnil);
195 477 : if (p != result)
196 0 : msg = createException(MAL, "algebra.max",
197 : SQLSTATE(HY002) "INTERNAL ERROR");
198 : }
199 545 : if (msg == MAL_SUCCEED && p == NULL)
200 0 : msg = createException(MAL, "algebra.max", GDK_EXCEPTION);
201 : }
202 545 : BBPunfix(b->batCacheid);
203 545 : return msg;
204 : }
205 :
206 : static str
207 545 : ALGmaxany(ptr result, const bat *bid)
208 : {
209 545 : bit skipnil = TRUE;
210 545 : return ALGmaxany_skipnil(result, bid, &skipnil);
211 : }
212 :
213 : static str
214 2388 : ALGgroupby(bat *res, const bat *gids, const bat *cnts)
215 : {
216 2388 : BAT *bn, *g, *c;
217 :
218 2388 : g = BATdescriptor(*gids);
219 2388 : if (g == NULL) {
220 0 : throw(MAL, "algebra.groupby", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
221 : }
222 2388 : c = BATdescriptor(*cnts);
223 2388 : if (c == NULL) {
224 0 : BBPunfix(g->batCacheid);
225 0 : throw(MAL, "algebra.groupby", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
226 : }
227 2388 : 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 2388 : *res = bn->batCacheid;
233 2388 : BBPkeepref(bn);
234 2388 : BBPunfix(g->batCacheid);
235 2388 : BBPunfix(c->batCacheid);
236 2388 : 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 124628 : 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 124628 : BAT *b, *s = NULL, *bn;
265 :
266 124628 : if ((*li != 0 && *li != 1) ||
267 124628 : (*hi != 0 && *hi != 1) || (*anti != 0 && *anti != 1)) {
268 0 : throw(MAL, "algebra.select", ILLEGAL_ARGUMENT);
269 : }
270 :
271 124769 : if ((b = BATdescriptor(*bid)) == NULL) {
272 0 : throw(MAL, "algebra.select", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
273 : }
274 125495 : 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 125516 : derefStr(b, low);
279 125516 : derefStr(b, high);
280 :
281 125516 : bool nanti = *anti, nli = *li, nhi = *hi;
282 :
283 : /* here we don't need open ended parts with nil */
284 125516 : if (!nanti && *unknown) {
285 1376 : const void *nilptr = ATOMnilptr(b->ttype);
286 1376 : if (nilptr) {
287 1376 : if (nli && ATOMcmp(b->ttype, low, nilptr) == 0) {
288 22 : low = high;
289 22 : nli = false;
290 : }
291 1375 : if (nhi && ATOMcmp(b->ttype, high, nilptr) == 0) {
292 24 : high = low;
293 24 : nhi = false;
294 : }
295 1376 : if (ATOMcmp(b->ttype, low, high) == 0 && ATOMcmp(b->ttype, high, nilptr) == 0) /* ugh sql nil != nil */
296 14 : nanti = true;
297 : }
298 124140 : } else if (!*unknown) {
299 118021 : const void *nilptr = ATOMnilptr(b->ttype);
300 235505 : if (nli && nhi && nilptr != NULL &&
301 117976 : ATOMcmp(b->ttype, low, nilptr) == 0 &&
302 24 : ATOMcmp(b->ttype, high, nilptr) == 0) {
303 : /* special case: equi-select for NIL */
304 125050 : high = NULL;
305 : }
306 : }
307 :
308 125050 : bn = BATselect(b, s, low, high, nli, nhi, nanti, false);
309 124303 : BBPunfix(b->batCacheid);
310 125368 : BBPreclaim(s);
311 125381 : if (bn == NULL)
312 0 : throw(MAL, "algebra.select", GDK_EXCEPTION);
313 125381 : *result = bn->batCacheid;
314 125381 : BBPkeepref(bn);
315 125381 : return MAL_SUCCEED;
316 : }
317 :
318 : static str
319 40805 : 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 40805 : return ALGselect2nil(result, bid, sid, low, high, li, hi, anti, &(bit){0});
323 : }
324 :
325 : static str
326 76567 : ALGselect1(bat *result, const bat *bid, const void *low, const void *high,
327 : const bit *li, const bit *hi, const bit *anti)
328 : {
329 76567 : return ALGselect2nil(result, bid, NULL, low, high, li, hi, anti, &(bit){0});
330 : }
331 :
332 : static str
333 310 : 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 310 : return ALGselect2nil(result, bid, NULL, low, high, li, hi, anti, unknown);
337 : }
338 :
339 : static str
340 469693 : ALGthetaselect2(bat *result, const bat *bid, const bat *sid, const void *val,
341 : const char **op)
342 : {
343 469693 : BAT *b, *s = NULL, *bn;
344 :
345 469693 : if ((b = BATdescriptor(*bid)) == NULL) {
346 0 : throw(MAL, "algebra.thetaselect",
347 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
348 : }
349 472209 : 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 472295 : derefStr(b, val);
355 472295 : bn = BATthetaselect(b, s, val, *op);
356 469747 : BBPunfix(b->batCacheid);
357 471913 : BBPreclaim(s);
358 471780 : if (bn == NULL)
359 0 : throw(MAL, "algebra.select", GDK_EXCEPTION);
360 471780 : *result = bn->batCacheid;
361 471780 : BBPkeepref(bn);
362 471780 : return MAL_SUCCEED;
363 : }
364 :
365 : static str
366 396 : ALGmarkselect(bat *r1, bat *r2, const bat *gid, const bat *mid, const bat *pid, const bit *Any)
367 : {
368 396 : BAT *g = BATdescriptor(*gid); /* oid */
369 396 : BAT *m = BATdescriptor(*mid); /* bit, true: match, false: empty set, nil: nil on left */
370 396 : BAT *p = BATdescriptor(*pid); /* bit */
371 396 : BAT *res1 = NULL, *res2 = NULL;
372 396 : bit any = *Any; /* any or normal comparison semantics */
373 :
374 396 : 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 396 : BUN nr = BATcount(g), q = 0;
381 :
382 396 : 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 396 : assert(g->tsorted);
390 396 : oid *ri1 = Tloc(res1, 0);
391 396 : bit *ri2 = Tloc(res2, 0);
392 396 : bit *mi = Tloc(m, 0);
393 396 : bit *pi = Tloc(p, 0);
394 396 : oid cur = oid_nil;
395 :
396 396 : if (g->ttype == TYPE_void) { /* void case ? */
397 31 : oid c = g->hseqbase;
398 127 : for (BUN n = 0; n < nr; n++, c++) {
399 96 : ri1[q] = c;
400 96 : ri2[q] = FALSE;
401 96 : if (pi[n] == TRUE && mi[n] == TRUE)
402 7 : ri2[q] = TRUE;
403 89 : else if ((mi[n] == bit_nil && pi[n] != bit_nil && !any) || (mi[n] != FALSE && pi[n] == bit_nil && any))
404 7 : ri2[q] = bit_nil;
405 96 : q++;
406 : }
407 : } else {
408 365 : oid *gi = Tloc(g, 0);
409 365 : oid c = g->hseqbase;
410 365 : if (nr)
411 365 : cur = gi[0];
412 : bit m = FALSE;
413 : bool has_nil = false;
414 332661 : for (BUN n = 0; n < nr; n++, c++) {
415 332296 : if (c && cur != gi[n]) {
416 57735 : ri1[q] = c-1;
417 57735 : ri2[q] = (m == TRUE)?TRUE:(has_nil)?bit_nil:FALSE;
418 57735 : q++;
419 57735 : cur = gi[n];
420 57735 : m = FALSE;
421 57735 : has_nil = false;
422 : }
423 332296 : if (m == TRUE)
424 191843 : continue;
425 :
426 140453 : if (pi[n] == TRUE && mi[n] == TRUE)
427 : m = TRUE;
428 133526 : else if ((mi[n] == bit_nil && pi[n] != bit_nil && !any) || (mi[n] != FALSE && pi[n] == bit_nil && any))
429 332296 : has_nil = true;
430 : }
431 365 : if (nr) {
432 365 : ri1[q] = c-1;
433 365 : ri2[q] = (m == TRUE)?TRUE:(has_nil)?bit_nil:FALSE;
434 : }
435 365 : q++;
436 : }
437 396 : BATsetcount(res1, q);
438 396 : BATsetcount(res2, q);
439 396 : res1->tsorted = true;
440 396 : res1->tkey = true;
441 396 : res1->trevsorted = false;
442 396 : res2->tsorted = false;
443 396 : res2->trevsorted = false;
444 396 : res1->tnil = false;
445 396 : res1->tnonil = true;
446 396 : res2->tnonil = false;
447 396 : res2->tkey = false;
448 :
449 396 : BBPreclaim(g);
450 396 : BBPreclaim(m);
451 396 : BBPreclaim(p);
452 :
453 396 : BBPkeepref(res1);
454 396 : BBPkeepref(res2);
455 396 : *r1 = res1->batCacheid;
456 396 : *r2 = res2->batCacheid;
457 396 : return MAL_SUCCEED;
458 : }
459 :
460 : static str
461 38 : ALGouterselect(bat *r1, bat *r2, const bat *gid, const bat *mid, const bat *pid, const bit *Any)
462 : {
463 38 : BAT *g = BATdescriptor(*gid); /* oid */
464 38 : BAT *m = BATdescriptor(*mid); /* bit, true: match, false: empty set, nil: nil on left */
465 38 : BAT *p = BATdescriptor(*pid); /* bit */
466 38 : BAT *res1 = NULL, *res2 = NULL;
467 38 : bit any = *Any; /* any or normal comparison semantics */
468 :
469 38 : 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 38 : BUN nr = BATcount(g), q = 0;
476 :
477 38 : 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 38 : assert(g->tsorted);
485 38 : oid *ri1 = Tloc(res1, 0);
486 38 : bit *ri2 = Tloc(res2, 0);
487 38 : bit *mi = Tloc(m, 0);
488 38 : bit *pi = Tloc(p, 0);
489 38 : oid cur = oid_nil;
490 :
491 38 : if (g->ttype == TYPE_void) { /* void case ? */
492 12 : oid c = g->hseqbase;
493 101 : for (BUN n = 0; n < nr; n++, c++) {
494 89 : ri1[q] = c;
495 161 : ri2[q] = (any && (mi[n] == bit_nil || pi[n] == bit_nil))?bit_nil:(mi[n] == TRUE && pi[n] == TRUE)?TRUE:FALSE;
496 89 : q++;
497 : }
498 : } else {
499 26 : oid *gi = Tloc(g, 0);
500 26 : oid c = g->hseqbase;
501 26 : if (nr)
502 26 : cur = gi[0];
503 : bool used = false;
504 602 : for (BUN n = 0; n < nr; n++, c++) {
505 576 : if (c && cur != gi[n]) {
506 159 : if (!used) {
507 3 : ri1[q] = c-1;
508 3 : ri2[q] = false;
509 3 : q++;
510 : }
511 159 : used = false;
512 159 : cur = gi[n];
513 : }
514 576 : if (mi[n] == TRUE && pi[n] == TRUE) {
515 322 : ri1[q] = c;
516 322 : ri2[q] = TRUE;
517 322 : used = true;
518 322 : q++;
519 254 : } else if (mi[n] == FALSE) { /* empty */
520 55 : ri1[q] = c;
521 55 : ri2[q] = FALSE;
522 55 : used = true;
523 55 : q++;
524 199 : } else if (any && (mi[n] == bit_nil /* ie has nil */ || pi[n] == bit_nil)) {
525 6 : ri1[q] = c;
526 6 : ri2[q] = bit_nil;
527 6 : used = true;
528 6 : q++;
529 : }
530 : }
531 26 : if (nr && !used) {
532 1 : ri1[q] = c-1;
533 1 : ri2[q] = FALSE;
534 1 : q++;
535 : }
536 : }
537 38 : BATsetcount(res1, q);
538 38 : BATsetcount(res2, q);
539 38 : res1->tsorted = true;
540 38 : res1->tkey = true;
541 38 : res1->trevsorted = false;
542 38 : res2->tsorted = false;
543 38 : res2->trevsorted = false;
544 38 : res1->tnil = false;
545 38 : res1->tnonil = true;
546 38 : res2->tnonil = false;
547 38 : res2->tkey = false;
548 :
549 38 : BBPreclaim(g);
550 38 : BBPreclaim(m);
551 38 : BBPreclaim(p);
552 :
553 38 : BBPkeepref(res1);
554 38 : BBPkeepref(res2);
555 38 : *r1 = res1->batCacheid;
556 38 : *r2 = res2->batCacheid;
557 38 : return MAL_SUCCEED;
558 : }
559 :
560 :
561 : static str
562 1583 : ALGselectNotNil(bat *result, const bat *bid)
563 : {
564 1583 : BAT *b;
565 :
566 1583 : if ((b = BATdescriptor(*bid)) == NULL)
567 0 : throw(MAL, "algebra.selectNotNil",
568 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
569 :
570 1584 : MT_lock_set(&b->theaplock);
571 1584 : bool bnonil = b->tnonil || b->ttype == TYPE_msk;
572 1584 : MT_lock_unset(&b->theaplock);
573 1584 : if (!bnonil) {
574 123 : BAT *s;
575 123 : s = BATselect(b, NULL, ATOMnilptr(b->ttype), NULL, true, true, true, false);
576 123 : if (s) {
577 123 : BAT *bn = BATproject(s, b);
578 123 : BBPunfix(s->batCacheid);
579 123 : if (bn) {
580 123 : BBPunfix(b->batCacheid);
581 123 : *result = bn->batCacheid;
582 123 : BBPkeepref(bn);
583 123 : 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 1461 : *result = b->batCacheid;
591 1461 : BBPkeepref(b);
592 1461 : return MAL_SUCCEED;
593 : }
594 :
595 : static str
596 589231 : 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 589231 : BAT *left = NULL, *right = NULL, *right2 = NULL;
616 589231 : BAT *candleft = NULL, *candright = NULL;
617 589231 : BAT *result1 = NULL, *result2 = NULL, *result3 = NULL;
618 589231 : BUN est;
619 589231 : const char *err = SQLSTATE(HY002) RUNTIME_OBJECT_MISSING;
620 :
621 589231 : assert(r2id == NULL || rangefunc != NULL);
622 :
623 589231 : if ((left = BATdescriptor(*lid)) == NULL)
624 0 : goto fail;
625 595660 : if ((right = BATdescriptor(*rid)) == NULL)
626 0 : goto fail;
627 595684 : if (slid && !is_bat_nil(*slid) && (candleft = BATdescriptor(*slid)) == NULL)
628 0 : goto fail;
629 595690 : if (srid && !is_bat_nil(*srid)
630 0 : && (candright = BATdescriptor(*srid)) == NULL)
631 0 : goto fail;
632 595690 : 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 595690 : err = NULL; /* most likely error now is GDK_EXCEPTION */
639 :
640 595690 : if (thetafunc) {
641 51301 : assert(joinfunc == NULL);
642 51301 : assert(semifunc == NULL);
643 51301 : assert(markfunc == NULL);
644 51301 : assert(bandfunc == NULL);
645 51301 : assert(rangefunc == NULL);
646 51301 : assert(difffunc == NULL);
647 51301 : assert(interfunc == NULL);
648 51301 : if ((*thetafunc)
649 : (&result1, r2 ? &result2 : NULL, left, right, candleft, candright,
650 51301 : op, *nil_matches, est) != GDK_SUCCEED)
651 0 : goto fail;
652 544389 : } else if (joinfunc) {
653 367624 : assert(semifunc == NULL);
654 367624 : assert(markfunc == NULL);
655 367624 : assert(bandfunc == NULL);
656 367624 : assert(rangefunc == NULL);
657 367624 : assert(difffunc == NULL);
658 367624 : assert(interfunc == NULL);
659 367624 : if ((*joinfunc)
660 : (&result1, r2 ? &result2 : NULL, left, right, candleft, candright,
661 367624 : *nil_matches, est) != GDK_SUCCEED)
662 1 : goto fail;
663 176765 : } else if (semifunc) {
664 332 : assert(markfunc == NULL);
665 332 : assert(bandfunc == NULL);
666 332 : assert(rangefunc == NULL);
667 332 : assert(difffunc == NULL);
668 332 : assert(interfunc == NULL);
669 332 : if ((*semifunc)
670 : (&result1, r2 ? &result2 : NULL, left, right, candleft, candright,
671 332 : *nil_matches, *max_one, est) != GDK_SUCCEED)
672 42 : goto fail;
673 176433 : } else if (markfunc) {
674 19127 : assert(bandfunc == NULL);
675 19127 : assert(rangefunc == NULL);
676 19127 : assert(difffunc == NULL);
677 19127 : assert(interfunc == NULL);
678 38248 : if ((*markfunc) (&result1, r2 ? &result2 : NULL, &result3,
679 : left, right, candleft, candright, est) != GDK_SUCCEED)
680 0 : goto fail;
681 157306 : } 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 157306 : } 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 157159 : } else if (difffunc) {
702 148531 : assert(r2 == NULL);
703 148531 : assert(interfunc == NULL);
704 148081 : if ((result1 = (*difffunc) (left, right, candleft, candright,
705 148531 : *nil_matches, *not_in, est)) == NULL)
706 0 : goto fail;
707 : } else {
708 8628 : assert(r2 == NULL);
709 8606 : if ((result1 = (*interfunc) (left, right, candleft, candright,
710 8628 : *nil_matches, *max_one, est)) == NULL)
711 1 : goto fail;
712 : }
713 591555 : *r1 = result1->batCacheid;
714 591555 : BBPkeepref(result1);
715 593187 : if (r2) {
716 344018 : *r2 = result2->batCacheid;
717 344018 : BBPkeepref(result2);
718 : }
719 593617 : if (r3) {
720 19061 : *r3 = result3->batCacheid;
721 19061 : BBPkeepref(result3);
722 : }
723 593655 : BBPunfix(left->batCacheid);
724 595053 : BBPunfix(right->batCacheid);
725 595379 : BBPreclaim(candleft);
726 595235 : BBPreclaim(candright);
727 : return MAL_SUCCEED;
728 :
729 44 : fail:
730 44 : BBPreclaim(left);
731 44 : BBPreclaim(right);
732 44 : BBPreclaim(right2);
733 44 : BBPreclaim(candleft);
734 44 : BBPreclaim(candright);
735 44 : if (err == NULL)
736 44 : throw(MAL, funcname, GDK_EXCEPTION);
737 0 : throw(MAL, funcname, "%s", err);
738 : }
739 :
740 : static str
741 333336 : 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 333336 : 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 30702 : 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 30702 : 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 120 : 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 120 : 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 209 : 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 209 : 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 19025 : ALGmark2join(bat *r1, bat *r3, const bat *lid, const bat *rid,
815 : const bat *slid, const bat *srid, const lng *estimate)
816 : {
817 19025 : 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 5 : 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 5 : 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 7663 : 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 7663 : 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 41372 : 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 41372 : 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 115 : 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 237 : return do_join(r1, r2, NULL, lid, rlid, rhid, slid, srid, 0, NULL, NULL,
883 115 : *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 24 : 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 49 : return do_join(r1, NULL, NULL, lid, rlid, rhid, slid, srid, 0, NULL, NULL,
894 24 : *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 148441 : 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 148441 : 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 8625 : 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 8625 : 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 1611 : ALGfirstn(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
932 : {
933 1611 : bat *ret1, *ret2 = NULL;
934 1611 : bat bid, sid, gid;
935 1611 : BAT *b, *s = NULL, *g = NULL;
936 1611 : BAT *bn = NULL, *gn = NULL;
937 1611 : lng n;
938 1611 : bit asc, nilslast, distinct;
939 1611 : gdk_return rc;
940 :
941 1611 : (void) cntxt;
942 1611 : (void) mb;
943 :
944 1611 : assert(pci->retc == 1 || pci->retc == 2);
945 1611 : assert(pci->argc - pci->retc >= 5 && pci->argc - pci->retc <= 7);
946 :
947 1611 : n = *getArgReference_lng(stk, pci, pci->argc - 4);
948 1611 : if (n < 0)
949 0 : throw(MAL, "algebra.firstn", ILLEGAL_ARGUMENT);
950 1611 : if (n > (lng) BUN_MAX)
951 : n = BUN_MAX;
952 1611 : ret1 = getArgReference_bat(stk, pci, 0);
953 1611 : if (pci->retc == 2)
954 526 : ret2 = getArgReference_bat(stk, pci, 1);
955 1611 : bid = *getArgReference_bat(stk, pci, pci->retc);
956 1611 : if ((b = BATdescriptor(bid)) == NULL)
957 0 : throw(MAL, "algebra.firstn", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
958 1613 : if (pci->argc - pci->retc > 5) {
959 1613 : sid = *getArgReference_bat(stk, pci, pci->retc + 1);
960 1613 : 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 1613 : if (pci->argc - pci->retc > 6) {
966 1613 : gid = *getArgReference_bat(stk, pci, pci->retc + 2);
967 1613 : 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 1613 : asc = *getArgReference_bit(stk, pci, pci->argc - 3);
976 1613 : nilslast = *getArgReference_bit(stk, pci, pci->argc - 2);
977 1613 : distinct = *getArgReference_bit(stk, pci, pci->argc - 1);
978 2699 : rc = BATfirstn(&bn, ret2 ? &gn : NULL, b, s, g, (BUN) n, asc, nilslast,
979 : distinct);
980 1610 : BBPunfix(b->batCacheid);
981 1612 : BBPreclaim(s);
982 1606 : BBPreclaim(g);
983 1610 : if (rc != GDK_SUCCEED)
984 0 : throw(MAL, "algebra.firstn", GDK_EXCEPTION);
985 1610 : *ret1 = bn->batCacheid;
986 1610 : BBPkeepref(bn);
987 1616 : if (ret2) {
988 527 : *ret2 = gn->batCacheid;
989 527 : 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 43377 : ALGcrossproduct(bat *l, bat *r, const bat *left, const bat *right,
1047 : const bat *slid, const bat *srid, const bit *max_one)
1048 : {
1049 43377 : BAT *L, *R, *bn1, *bn2 = NULL;
1050 43377 : BAT *sl = NULL, *sr = NULL;
1051 43377 : gdk_return ret;
1052 :
1053 43377 : L = BATdescriptor(*left);
1054 44848 : R = BATdescriptor(*right);
1055 44938 : 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 44938 : 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 46691 : ret = BATsubcross(&bn1, r ? &bn2 : NULL, L, R, sl, sr,
1071 44938 : max_one && !is_bit_nil(*max_one) && *max_one);
1072 44083 : BBPunfix(L->batCacheid);
1073 44802 : BBPunfix(R->batCacheid);
1074 44937 : BBPreclaim(sl);
1075 44937 : BBPreclaim(sr);
1076 44936 : if (ret != GDK_SUCCEED)
1077 86 : throw(MAL, "algebra.crossproduct", GDK_EXCEPTION);
1078 44850 : *l = bn1->batCacheid;
1079 44850 : BBPkeepref(bn1);
1080 44788 : if (r) {
1081 43049 : *r = bn2->batCacheid;
1082 43049 : BBPkeepref(bn2);
1083 : }
1084 : return MAL_SUCCEED;
1085 : }
1086 :
1087 : static str
1088 1686 : ALGcrossproduct1(bat *l, const bat *left, const bat *right, const bit *max_one)
1089 : {
1090 1686 : return ALGcrossproduct(l, NULL, left, right, NULL, NULL, max_one);
1091 : }
1092 :
1093 : static str
1094 41742 : ALGcrossproduct2(bat *l, bat *r, const bat *left, const bat *right,
1095 : const bit *max_one)
1096 : {
1097 41742 : 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 425 : ALGoutercrossproduct3(bat *l, bat *r, const bat *left, const bat *right, const bat *slid, const bat *srid, const bit *max_one)
1116 : {
1117 425 : BAT *L, *R, *bn1, *bn2 = NULL;
1118 425 : BAT *sl = NULL, *sr = NULL;
1119 425 : gdk_return ret;
1120 :
1121 425 : L = BATdescriptor(*left);
1122 425 : R = BATdescriptor(*right);
1123 425 : 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 425 : if ((slid && !is_bat_nil(*slid) && (sl = BATdescriptor(*slid)) == NULL) ||
1129 425 : (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 425 : ret = BAToutercross(&bn1, r ? &bn2 : NULL, L, R, sl, sr,
1137 425 : max_one && !is_bit_nil(*max_one) && *max_one);
1138 425 : BBPunfix(L->batCacheid);
1139 425 : BBPunfix(R->batCacheid);
1140 425 : BBPreclaim(sl);
1141 425 : BBPreclaim(sr);
1142 425 : if (ret != GDK_SUCCEED)
1143 0 : throw(MAL, "algebra.crossproduct", GDK_EXCEPTION);
1144 425 : *l = bn1->batCacheid;
1145 425 : BBPkeepref(bn1);
1146 425 : if (r) {
1147 425 : *r = bn2->batCacheid;
1148 425 : BBPkeepref(bn2);
1149 : }
1150 : return MAL_SUCCEED;
1151 : }
1152 :
1153 : static str
1154 1762883 : ALGprojection2(bat *result, const bat *lid, const bat *r1id, const bat *r2id)
1155 : {
1156 1762883 : BAT *l, *r1, *r2 = NULL, *bn;
1157 :
1158 1762883 : if ((l = BATdescriptor(*lid)) == NULL) {
1159 0 : throw(MAL, "algebra.projection",
1160 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1161 : }
1162 1775175 : if ((r1 = BATdescriptor(*r1id)) == NULL) {
1163 0 : BBPunfix(l->batCacheid);
1164 0 : throw(MAL, "algebra.projection",
1165 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1166 : }
1167 1774047 : 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 1774047 : bn = BATproject2(l, r1, r2);
1174 1746858 : BBPunfix(l->batCacheid);
1175 1772890 : BBPunfix(r1->batCacheid);
1176 1773331 : BBPreclaim(r2);
1177 1772421 : if (bn == NULL)
1178 0 : throw(MAL, "algebra.projection", GDK_EXCEPTION);
1179 1772421 : *result = bn->batCacheid;
1180 1772421 : BBPkeepref(bn);
1181 1772421 : return MAL_SUCCEED;
1182 : }
1183 :
1184 : str
1185 1764543 : ALGprojection(bat *result, const bat *lid, const bat *rid)
1186 : {
1187 1764543 : return ALGprojection2(result, lid, rid, NULL);
1188 : }
1189 :
1190 : static str
1191 19230 : 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 19230 : BAT *bn = NULL, *on = NULL, *gn = NULL;
1196 19230 : BAT *b = NULL, *o = NULL, *g = NULL;
1197 :
1198 19230 : if ((b = BATdescriptor(*bid)) == NULL)
1199 0 : throw(MAL, "algebra.sort", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1200 19230 : 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 19230 : 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 22728 : if (BATsort(result ? &bn : NULL,
1210 : norder ? &on : NULL,
1211 : ngroup ? &gn : NULL,
1212 19230 : 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 19231 : BBPunfix(b->batCacheid);
1219 19231 : BBPreclaim(o);
1220 19231 : BBPreclaim(g);
1221 19231 : if (result) {
1222 19231 : *result = bn->batCacheid;
1223 19231 : BBPkeepref(bn);
1224 : }
1225 19231 : if (norder) {
1226 15733 : *norder = on->batCacheid;
1227 15733 : BBPkeepref(on);
1228 : }
1229 19231 : if (ngroup) {
1230 10852 : *ngroup = gn->batCacheid;
1231 10852 : BBPkeepref(gn);
1232 : }
1233 : return MAL_SUCCEED;
1234 : }
1235 :
1236 : static str
1237 2836 : 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 2836 : return ALGsort33(result, norder, NULL, bid, order, group, reverse, nilslast,
1242 : stable);
1243 : }
1244 :
1245 : static str
1246 1916 : ALGsort31(bat *result, const bat *bid, const bat *order, const bat *group,
1247 : const bit *reverse, const bit *nilslast, const bit *stable)
1248 : {
1249 1916 : 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 5008 : ALGsort13(bat *result, bat *norder, bat *ngroup, const bat *bid,
1280 : const bit *reverse, const bit *nilslast, const bit *stable)
1281 : {
1282 5008 : return ALGsort33(result, norder, ngroup, bid, NULL, NULL, reverse, nilslast,
1283 : stable);
1284 : }
1285 :
1286 : static str
1287 2044 : ALGsort12(bat *result, bat *norder, const bat *bid, const bit *reverse,
1288 : const bit *nilslast, const bit *stable)
1289 : {
1290 2044 : return ALGsort33(result, norder, NULL, bid, NULL, NULL, reverse, nilslast,
1291 : stable);
1292 : }
1293 :
1294 : static str
1295 1582 : ALGsort11(bat *result, const bat *bid, const bit *reverse, const bit *nilslast,
1296 : const bit *stable)
1297 : {
1298 1582 : return ALGsort33(result, NULL, NULL, bid, NULL, NULL, reverse, nilslast,
1299 : stable);
1300 : }
1301 :
1302 : static str
1303 69869 : ALGcountCND_nil(lng *result, const bat *bid, const bat *cnd,
1304 : const bit *ignore_nils)
1305 : {
1306 69869 : BAT *b, *s = NULL;
1307 :
1308 69869 : if ((b = BATdescriptor(*bid)) == NULL) {
1309 0 : throw(MAL, "aggr.count", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1310 : }
1311 70070 : 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 70070 : if (b->ttype == TYPE_msk || mask_cand(b)) {
1316 30 : BATsum(result, TYPE_lng, b, s, *ignore_nils, false);
1317 70040 : } else if (*ignore_nils) {
1318 1770 : *result = (lng) BATcount_no_nil(b, s);
1319 : } else {
1320 68270 : struct canditer ci;
1321 68270 : canditer_init(&ci, b, s);
1322 68266 : *result = (lng) ci.ncand;
1323 : }
1324 70066 : BBPreclaim(s);
1325 70066 : BBPunfix(b->batCacheid);
1326 70066 : 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 68104 : ALGcount_bat(lng *result, const bat *bid)
1343 : {
1344 68104 : 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 17233 : ALGsubslice_lng(bat *ret, const bat *bid, const lng *start, const lng *end)
1408 : {
1409 17233 : BAT *b, *bn;
1410 17233 : BUN s, e;
1411 :
1412 17233 : if (*start < 0 || (*end < 0 && !is_lng_nil(*end)))
1413 0 : throw(MAL, "algebra.subslice", ILLEGAL_ARGUMENT);
1414 17233 : if ((b = BBPquickdesc(*bid)) == NULL)
1415 0 : throw(MAL, "algebra.subslice", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1416 17233 : s = (BUN) *start;
1417 17233 : if (s > BATcount(b))
1418 : s = BATcount(b);
1419 17233 : e = is_lng_nil(*end) ? BATcount(b) : (BUN) *end + 1;
1420 17233 : if (e > BATcount(b))
1421 : e = BATcount(b);
1422 17233 : if (e < s)
1423 : e = s;
1424 17233 : bn = BATdense(0, b->hseqbase + s, e - s);
1425 17231 : if (bn == NULL)
1426 0 : throw(MAL, "algebra.subslice", SQLSTATE(HY013) MAL_MALLOC_FAIL);
1427 17231 : *ret = bn->batCacheid;
1428 17231 : BBPkeepref(bn);
1429 17231 : return MAL_SUCCEED;
1430 : }
1431 :
1432 : /*
1433 : * BUN Get/Fetch
1434 : */
1435 :
1436 : static str
1437 185168 : doALGfetch(ptr ret, BAT *b, BUN pos)
1438 : {
1439 185168 : assert(pos <= BUN_MAX);
1440 185168 : BATiter bi = bat_iterator(b);
1441 185168 : if (ATOMextern(b->ttype)) {
1442 176 : ptr _src = BUNtail(bi, pos);
1443 176 : size_t _len = ATOMlen(b->ttype, _src);
1444 176 : ptr _dst = GDKmalloc(_len);
1445 176 : if (_dst == NULL) {
1446 0 : bat_iterator_end(&bi);
1447 0 : throw(MAL, "doAlgFetch", SQLSTATE(HY013) MAL_MALLOC_FAIL);
1448 : }
1449 176 : memcpy(_dst, _src, _len);
1450 176 : *(ptr *) ret = _dst;
1451 : } else {
1452 184992 : size_t _s = ATOMsize(ATOMtype(b->ttype));
1453 184992 : 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 184992 : } else if (_s == 4) {
1458 184905 : *(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 185168 : bat_iterator_end(&bi);
1474 185168 : return MAL_SUCCEED;
1475 : }
1476 :
1477 : static str
1478 185170 : ALGfetch(ptr ret, const bat *bid, const lng *pos)
1479 : {
1480 185170 : BAT *b;
1481 185170 : str msg;
1482 :
1483 185170 : if ((b = BATdescriptor(*bid)) == NULL) {
1484 0 : throw(MAL, "algebra.fetch", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1485 : }
1486 185170 : 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 185170 : 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 185168 : 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 185168 : msg = doALGfetch(ret, b, (BUN) *pos);
1503 185168 : BBPunfix(b->batCacheid);
1504 185168 : return msg;
1505 : }
1506 :
1507 : str
1508 185170 : ALGfetchoid(ptr ret, const bat *bid, const oid *pos)
1509 : {
1510 185170 : lng o = *pos;
1511 :
1512 185170 : 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 270588 : ALGprojecttail(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1555 : {
1556 270588 : bat *ret = getArgReference_bat(stk, pci, 0);
1557 270588 : bat bid = *getArgReference_bat(stk, pci, 1);
1558 270588 : const ValRecord *v = &stk->stk[getArg(pci, 2)];
1559 270588 : BAT *b, *bn;
1560 :
1561 270588 : (void) cntxt;
1562 270588 : (void) mb;
1563 270588 : if (isaBatType(getArgType(mb, pci, 2)))
1564 0 : throw(MAL, "algebra.project", "Scalar value expected");
1565 270588 : if ((b = BBPquickdesc(bid)) == NULL)
1566 0 : throw(MAL, "algebra.project", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1567 270492 : bn = BATconstant(b->hseqbase, v->vtype, VALptr(v), BATcount(b), TRANSIENT);
1568 270717 : if (bn == NULL) {
1569 0 : *ret = bat_nil;
1570 0 : throw(MAL, "algebra.project", SQLSTATE(HY013) MAL_MALLOC_FAIL);
1571 : }
1572 270717 : *ret = bn->batCacheid;
1573 270717 : BBPkeepref(bn);
1574 270717 : 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 5 : if (is_dbl_nil(covariance) && GDKerrbuf && GDKerrbuf[0])
1701 0 : throw(MAL, "aggr.covariance", GDK_EXCEPTION);
1702 5 : *res = covariance;
1703 5 : return MAL_SUCCEED;
1704 : }
1705 :
1706 : static str
1707 8 : ALGcovariancep(dbl *res, const bat *bid1, const bat *bid2)
1708 : {
1709 8 : BAT *b1, *b2;
1710 8 : dbl covariance;
1711 :
1712 8 : 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 8 : 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 308 : LIB_STARTUP_FUNC(init_algebra_mal)
1838 308 : { mal_module("algebra", NULL, algebra_init_funcs); }
|