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 722 : ALGminany_skipnil(ptr result, const bat *bid, const bit *skipnil)
141 : {
142 722 : BAT *b;
143 722 : ptr p;
144 722 : str msg = MAL_SUCCEED;
145 :
146 722 : if (result == NULL || (b = BATdescriptor(*bid)) == NULL)
147 0 : throw(MAL, "algebra.min", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
148 :
149 722 : 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 722 : if (ATOMextern(b->ttype)) {
155 34 : *(ptr *) result = p = BATmin_skipnil(b, NULL, *skipnil);
156 : } else {
157 688 : p = BATmin_skipnil(b, result, *skipnil);
158 688 : if (p != result)
159 0 : msg = createException(MAL, "algebra.min",
160 : SQLSTATE(HY002) "INTERNAL ERROR");
161 : }
162 722 : if (msg == MAL_SUCCEED && p == NULL)
163 0 : msg = createException(MAL, "algebra.min", GDK_EXCEPTION);
164 : }
165 722 : BBPunfix(b->batCacheid);
166 722 : return msg;
167 : }
168 :
169 : static str
170 722 : ALGminany(ptr result, const bat *bid)
171 : {
172 722 : bit skipnil = TRUE;
173 722 : return ALGminany_skipnil(result, bid, &skipnil);
174 : }
175 :
176 : static str
177 480 : ALGmaxany_skipnil(ptr result, const bat *bid, const bit *skipnil)
178 : {
179 480 : BAT *b;
180 480 : ptr p;
181 480 : str msg = MAL_SUCCEED;
182 :
183 480 : if (result == NULL || (b = BATdescriptor(*bid)) == NULL)
184 0 : throw(MAL, "algebra.max", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
185 :
186 480 : 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 480 : if (ATOMextern(b->ttype)) {
192 48 : *(ptr *) result = p = BATmax_skipnil(b, NULL, *skipnil);
193 : } else {
194 432 : p = BATmax_skipnil(b, result, *skipnil);
195 432 : if (p != result)
196 0 : msg = createException(MAL, "algebra.max",
197 : SQLSTATE(HY002) "INTERNAL ERROR");
198 : }
199 480 : if (msg == MAL_SUCCEED && p == NULL)
200 0 : msg = createException(MAL, "algebra.max", GDK_EXCEPTION);
201 : }
202 480 : BBPunfix(b->batCacheid);
203 480 : return msg;
204 : }
205 :
206 : static str
207 480 : ALGmaxany(ptr result, const bat *bid)
208 : {
209 480 : bit skipnil = TRUE;
210 480 : 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 69440 : 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 69440 : BAT *b, *s = NULL, *bn;
265 :
266 69440 : if ((*li != 0 && *li != 1) ||
267 69440 : (*hi != 0 && *hi != 1) || (*anti != 0 && *anti != 1)) {
268 0 : throw(MAL, "algebra.select", ILLEGAL_ARGUMENT);
269 : }
270 :
271 69440 : if ((b = BATdescriptor(*bid)) == NULL) {
272 0 : throw(MAL, "algebra.select", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
273 : }
274 69438 : 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 69439 : derefStr(b, low);
279 69439 : derefStr(b, high);
280 :
281 69439 : bool nanti = *anti, nli = *li, nhi = *hi;
282 :
283 : /* here we don't need open ended parts with nil */
284 69439 : if (!nanti && *unknown) {
285 882 : const void *nilptr = ATOMnilptr(b->ttype);
286 882 : if (nilptr) {
287 882 : if (nli && ATOMcmp(b->ttype, low, nilptr) == 0) {
288 16 : low = high;
289 16 : nli = false;
290 : }
291 883 : if (nhi && ATOMcmp(b->ttype, high, nilptr) == 0) {
292 18 : high = low;
293 18 : nhi = false;
294 : }
295 882 : if (ATOMcmp(b->ttype, low, high) == 0 && ATOMcmp(b->ttype, high, nilptr) == 0) /* ugh sql nil != nil */
296 11 : nanti = true;
297 : }
298 68557 : } else if (!*unknown) {
299 65476 : const void *nilptr = ATOMnilptr(b->ttype);
300 130800 : if (nli && nhi && nilptr != NULL &&
301 65347 : ATOMcmp(b->ttype, low, nilptr) == 0 &&
302 24 : ATOMcmp(b->ttype, high, nilptr) == 0) {
303 : /* special case: equi-select for NIL */
304 69441 : high = NULL;
305 : }
306 : }
307 :
308 69441 : bn = BATselect(b, s, low, high, nli, nhi, nanti, false);
309 69437 : BBPunfix(b->batCacheid);
310 69424 : BBPreclaim(s);
311 69425 : if (bn == NULL)
312 0 : throw(MAL, "algebra.select", GDK_EXCEPTION);
313 69425 : *result = bn->batCacheid;
314 69425 : BBPkeepref(bn);
315 69425 : return MAL_SUCCEED;
316 : }
317 :
318 : static str
319 20753 : 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 20753 : return ALGselect2nil(result, bid, sid, low, high, li, hi, anti, &(bit){0});
323 : }
324 :
325 : static str
326 44726 : ALGselect1(bat *result, const bat *bid, const void *low, const void *high,
327 : const bit *li, const bit *hi, const bit *anti)
328 : {
329 44726 : return ALGselect2nil(result, bid, NULL, low, high, li, hi, anti, &(bit){0});
330 : }
331 :
332 : static str
333 272 : 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 272 : return ALGselect2nil(result, bid, NULL, low, high, li, hi, anti, unknown);
337 : }
338 :
339 : static str
340 360599 : ALGthetaselect2(bat *result, const bat *bid, const bat *sid, const void *val,
341 : const char **op)
342 : {
343 360599 : BAT *b, *s = NULL, *bn;
344 :
345 360599 : if ((b = BATdescriptor(*bid)) == NULL) {
346 0 : throw(MAL, "algebra.thetaselect",
347 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
348 : }
349 360587 : 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 360585 : derefStr(b, val);
355 360585 : bn = BATthetaselect(b, s, val, *op);
356 360579 : BBPunfix(b->batCacheid);
357 360545 : BBPreclaim(s);
358 360523 : if (bn == NULL)
359 0 : throw(MAL, "algebra.select", GDK_EXCEPTION);
360 360523 : *result = bn->batCacheid;
361 360523 : BBPkeepref(bn);
362 360523 : 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 1587 : ALGselectNotNil(bat *result, const bat *bid)
563 : {
564 1587 : BAT *b;
565 :
566 1587 : if ((b = BATdescriptor(*bid)) == NULL)
567 0 : throw(MAL, "algebra.selectNotNil",
568 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
569 :
570 1587 : MT_lock_set(&b->theaplock);
571 1587 : bool bnonil = b->tnonil || b->ttype == TYPE_msk;
572 1587 : MT_lock_unset(&b->theaplock);
573 1587 : if (!bnonil) {
574 97 : BAT *s;
575 97 : s = BATselect(b, NULL, ATOMnilptr(b->ttype), NULL, true, true, true, false);
576 97 : if (s) {
577 97 : BAT *bn = BATproject(s, b);
578 97 : BBPunfix(s->batCacheid);
579 97 : if (bn) {
580 97 : BBPunfix(b->batCacheid);
581 97 : *result = bn->batCacheid;
582 97 : BBPkeepref(bn);
583 97 : 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 1490 : *result = b->batCacheid;
591 1490 : BBPkeepref(b);
592 1490 : return MAL_SUCCEED;
593 : }
594 :
595 : static str
596 342191 : 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 342191 : BAT *left = NULL, *right = NULL, *right2 = NULL;
616 342191 : BAT *candleft = NULL, *candright = NULL;
617 342191 : BAT *result1 = NULL, *result2 = NULL, *result3 = NULL;
618 342191 : BUN est;
619 342191 : const char *err = SQLSTATE(HY002) RUNTIME_OBJECT_MISSING;
620 :
621 342191 : assert(r2id == NULL || rangefunc != NULL);
622 :
623 342191 : if ((left = BATdescriptor(*lid)) == NULL)
624 0 : goto fail;
625 342178 : if ((right = BATdescriptor(*rid)) == NULL)
626 0 : goto fail;
627 342174 : if (slid && !is_bat_nil(*slid) && (candleft = BATdescriptor(*slid)) == NULL)
628 0 : goto fail;
629 342174 : if (srid && !is_bat_nil(*srid)
630 0 : && (candright = BATdescriptor(*srid)) == NULL)
631 0 : goto fail;
632 342174 : 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 342174 : err = NULL; /* most likely error now is GDK_EXCEPTION */
639 :
640 342174 : if (thetafunc) {
641 16833 : assert(joinfunc == NULL);
642 16833 : assert(semifunc == NULL);
643 16833 : assert(markfunc == NULL);
644 16833 : assert(bandfunc == NULL);
645 16833 : assert(rangefunc == NULL);
646 16833 : assert(difffunc == NULL);
647 16833 : assert(interfunc == NULL);
648 16833 : if ((*thetafunc)
649 : (&result1, r2 ? &result2 : NULL, left, right, candleft, candright,
650 16833 : op, *nil_matches, est) != GDK_SUCCEED)
651 0 : goto fail;
652 325341 : } else if (joinfunc) {
653 217281 : assert(semifunc == NULL);
654 217281 : assert(markfunc == NULL);
655 217281 : assert(bandfunc == NULL);
656 217281 : assert(rangefunc == NULL);
657 217281 : assert(difffunc == NULL);
658 217281 : assert(interfunc == NULL);
659 217281 : if ((*joinfunc)
660 : (&result1, r2 ? &result2 : NULL, left, right, candleft, candright,
661 217281 : *nil_matches, est) != GDK_SUCCEED)
662 1 : goto fail;
663 108060 : } 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 107728 : } else if (markfunc) {
674 9650 : assert(bandfunc == NULL);
675 9650 : assert(rangefunc == NULL);
676 9650 : assert(difffunc == NULL);
677 9650 : assert(interfunc == NULL);
678 19295 : if ((*markfunc) (&result1, r2 ? &result2 : NULL, &result3,
679 : left, right, candleft, candright, est) != GDK_SUCCEED)
680 0 : goto fail;
681 98078 : } 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 98078 : } else if (rangefunc) {
690 125 : assert(difffunc == NULL);
691 125 : assert(interfunc == NULL);
692 125 : if ((right2 = BATdescriptor(*r2id)) == NULL) {
693 0 : err = SQLSTATE(HY002) RUNTIME_OBJECT_MISSING;
694 0 : goto fail;
695 : }
696 148 : 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 125 : BBPunfix(right2->batCacheid);
701 97953 : } else if (difffunc) {
702 92023 : assert(r2 == NULL);
703 92023 : assert(interfunc == NULL);
704 92026 : if ((result1 = (*difffunc) (left, right, candleft, candright,
705 92023 : *nil_matches, *not_in, est)) == NULL)
706 0 : goto fail;
707 : } else {
708 5930 : assert(r2 == NULL);
709 5930 : if ((result1 = (*interfunc) (left, right, candleft, candright,
710 5930 : *nil_matches, *max_one, est)) == NULL)
711 1 : goto fail;
712 : }
713 342088 : *r1 = result1->batCacheid;
714 342088 : BBPkeepref(result1);
715 341962 : if (r2) {
716 195409 : *r2 = result2->batCacheid;
717 195409 : BBPkeepref(result2);
718 : }
719 341834 : if (r3) {
720 9646 : *r3 = result3->batCacheid;
721 9646 : BBPkeepref(result3);
722 : }
723 341832 : BBPunfix(left->batCacheid);
724 341938 : BBPunfix(right->batCacheid);
725 341999 : BBPreclaim(candleft);
726 342001 : 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 190211 : 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 190211 : 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 26436 : 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 26436 : 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 123 : 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 123 : 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 9645 : ALGmark2join(bat *r1, bat *r3, const bat *lid, const bat *rid,
815 : const bat *slid, const bat *srid, const lng *estimate)
816 : {
817 9645 : 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 4299 : 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 4299 : 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 12538 : 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 12538 : 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 102 : 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 204 : return do_join(r1, r2, NULL, lid, rlid, rhid, slid, srid, 0, NULL, NULL,
883 102 : *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 23 : 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 46 : return do_join(r1, NULL, NULL, lid, rlid, rhid, slid, srid, 0, NULL, NULL,
894 23 : *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 92029 : 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 92029 : 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 5930 : 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 5930 : 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 1217 : ALGfirstn(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
932 : {
933 1217 : bat *ret1, *ret2 = NULL;
934 1217 : bat bid, sid, gid;
935 1217 : BAT *b, *s = NULL, *g = NULL;
936 1217 : BAT *bn = NULL, *gn = NULL;
937 1217 : lng n;
938 1217 : bit asc, nilslast, distinct;
939 1217 : gdk_return rc;
940 :
941 1217 : (void) cntxt;
942 1217 : (void) mb;
943 :
944 1217 : assert(pci->retc == 1 || pci->retc == 2);
945 1217 : assert(pci->argc - pci->retc >= 5 && pci->argc - pci->retc <= 7);
946 :
947 1217 : n = *getArgReference_lng(stk, pci, pci->argc - 4);
948 1217 : if (n < 0)
949 0 : throw(MAL, "algebra.firstn", ILLEGAL_ARGUMENT);
950 1217 : if (n > (lng) BUN_MAX)
951 : n = BUN_MAX;
952 1217 : ret1 = getArgReference_bat(stk, pci, 0);
953 1217 : if (pci->retc == 2)
954 462 : ret2 = getArgReference_bat(stk, pci, 1);
955 1217 : bid = *getArgReference_bat(stk, pci, pci->retc);
956 1217 : if ((b = BATdescriptor(bid)) == NULL)
957 0 : throw(MAL, "algebra.firstn", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
958 1217 : if (pci->argc - pci->retc > 5) {
959 1217 : sid = *getArgReference_bat(stk, pci, pci->retc + 1);
960 1217 : 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 1217 : if (pci->argc - pci->retc > 6) {
966 1217 : gid = *getArgReference_bat(stk, pci, pci->retc + 2);
967 1217 : 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 1217 : asc = *getArgReference_bit(stk, pci, pci->argc - 3);
976 1217 : nilslast = *getArgReference_bit(stk, pci, pci->argc - 2);
977 1217 : distinct = *getArgReference_bit(stk, pci, pci->argc - 1);
978 1972 : rc = BATfirstn(&bn, ret2 ? &gn : NULL, b, s, g, (BUN) n, asc, nilslast,
979 : distinct);
980 1217 : BBPunfix(b->batCacheid);
981 1215 : BBPreclaim(s);
982 1215 : BBPreclaim(g);
983 1215 : if (rc != GDK_SUCCEED)
984 0 : throw(MAL, "algebra.firstn", GDK_EXCEPTION);
985 1215 : *ret1 = bn->batCacheid;
986 1215 : BBPkeepref(bn);
987 1217 : if (ret2) {
988 462 : *ret2 = gn->batCacheid;
989 462 : 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 26751 : ALGcrossproduct(bat *l, bat *r, const bat *left, const bat *right,
1047 : const bat *slid, const bat *srid, const bit *max_one)
1048 : {
1049 26751 : BAT *L, *R, *bn1, *bn2 = NULL;
1050 26751 : BAT *sl = NULL, *sr = NULL;
1051 26751 : gdk_return ret;
1052 :
1053 26751 : L = BATdescriptor(*left);
1054 26752 : R = BATdescriptor(*right);
1055 26753 : 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 26753 : 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 28142 : ret = BATsubcross(&bn1, r ? &bn2 : NULL, L, R, sl, sr,
1071 26753 : max_one && !is_bit_nil(*max_one) && *max_one);
1072 26749 : BBPunfix(L->batCacheid);
1073 26745 : BBPunfix(R->batCacheid);
1074 26750 : BBPreclaim(sl);
1075 26750 : BBPreclaim(sr);
1076 26750 : if (ret != GDK_SUCCEED)
1077 77 : throw(MAL, "algebra.crossproduct", GDK_EXCEPTION);
1078 26673 : *l = bn1->batCacheid;
1079 26673 : BBPkeepref(bn1);
1080 26663 : if (r) {
1081 25281 : *r = bn2->batCacheid;
1082 25281 : BBPkeepref(bn2);
1083 : }
1084 : return MAL_SUCCEED;
1085 : }
1086 :
1087 : static str
1088 1389 : ALGcrossproduct1(bat *l, const bat *left, const bat *right, const bit *max_one)
1089 : {
1090 1389 : return ALGcrossproduct(l, NULL, left, right, NULL, NULL, max_one);
1091 : }
1092 :
1093 : static str
1094 25363 : ALGcrossproduct2(bat *l, bat *r, const bat *left, const bat *right,
1095 : const bit *max_one)
1096 : {
1097 25363 : 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 1192654 : ALGprojection2(bat *result, const bat *lid, const bat *r1id, const bat *r2id)
1155 : {
1156 1192654 : BAT *l, *r1, *r2 = NULL, *bn;
1157 :
1158 1192654 : if ((l = BATdescriptor(*lid)) == NULL) {
1159 0 : throw(MAL, "algebra.projection",
1160 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1161 : }
1162 1192598 : if ((r1 = BATdescriptor(*r1id)) == NULL) {
1163 0 : BBPunfix(l->batCacheid);
1164 0 : throw(MAL, "algebra.projection",
1165 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1166 : }
1167 1192503 : 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 1192503 : bn = BATproject2(l, r1, r2);
1174 1192044 : BBPunfix(l->batCacheid);
1175 1192180 : BBPunfix(r1->batCacheid);
1176 1191959 : BBPreclaim(r2);
1177 1191968 : if (bn == NULL)
1178 0 : throw(MAL, "algebra.projection", GDK_EXCEPTION);
1179 1191968 : *result = bn->batCacheid;
1180 1191968 : BBPkeepref(bn);
1181 1191968 : return MAL_SUCCEED;
1182 : }
1183 :
1184 : str
1185 1192660 : ALGprojection(bat *result, const bat *lid, const bat *rid)
1186 : {
1187 1192660 : return ALGprojection2(result, lid, rid, NULL);
1188 : }
1189 :
1190 : static str
1191 23994 : 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 23994 : BAT *bn = NULL, *on = NULL, *gn = NULL;
1196 23994 : BAT *b = NULL, *o = NULL, *g = NULL;
1197 :
1198 23994 : if ((b = BATdescriptor(*bid)) == NULL)
1199 0 : throw(MAL, "algebra.sort", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1200 23994 : 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 23994 : 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 27593 : if (BATsort(result ? &bn : NULL,
1210 : norder ? &on : NULL,
1211 : ngroup ? &gn : NULL,
1212 23994 : 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 23994 : BBPunfix(b->batCacheid);
1219 23994 : BBPreclaim(o);
1220 23994 : BBPreclaim(g);
1221 23994 : if (result) {
1222 23994 : *result = bn->batCacheid;
1223 23994 : BBPkeepref(bn);
1224 : }
1225 23994 : if (norder) {
1226 20395 : *norder = on->batCacheid;
1227 20395 : BBPkeepref(on);
1228 : }
1229 23994 : if (ngroup) {
1230 13572 : *ngroup = gn->batCacheid;
1231 13572 : BBPkeepref(gn);
1232 : }
1233 : return MAL_SUCCEED;
1234 : }
1235 :
1236 : static str
1237 4099 : 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 4099 : return ALGsort33(result, norder, NULL, bid, order, group, reverse, nilslast,
1242 : stable);
1243 : }
1244 :
1245 : static str
1246 1958 : ALGsort31(bat *result, const bat *bid, const bat *order, const bat *group,
1247 : const bit *reverse, const bit *nilslast, const bit *stable)
1248 : {
1249 1958 : 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 6312 : ALGsort13(bat *result, bat *norder, bat *ngroup, const bat *bid,
1280 : const bit *reverse, const bit *nilslast, const bit *stable)
1281 : {
1282 6312 : return ALGsort33(result, norder, ngroup, bid, NULL, NULL, reverse, nilslast,
1283 : stable);
1284 : }
1285 :
1286 : static str
1287 2724 : ALGsort12(bat *result, bat *norder, const bat *bid, const bit *reverse,
1288 : const bit *nilslast, const bit *stable)
1289 : {
1290 2724 : return ALGsort33(result, norder, NULL, bid, NULL, NULL, reverse, nilslast,
1291 : stable);
1292 : }
1293 :
1294 : static str
1295 1641 : ALGsort11(bat *result, const bat *bid, const bit *reverse, const bit *nilslast,
1296 : const bit *stable)
1297 : {
1298 1641 : return ALGsort33(result, NULL, NULL, bid, NULL, NULL, reverse, nilslast,
1299 : stable);
1300 : }
1301 :
1302 : static str
1303 69713 : ALGcountCND_nil(lng *result, const bat *bid, const bat *cnd,
1304 : const bit *ignore_nils)
1305 : {
1306 69713 : BAT *b, *s = NULL;
1307 :
1308 69713 : if ((b = BATdescriptor(*bid)) == NULL) {
1309 0 : throw(MAL, "aggr.count", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1310 : }
1311 69713 : 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 69713 : if (b->ttype == TYPE_msk || mask_cand(b)) {
1316 30 : BATsum(result, TYPE_lng, b, s, *ignore_nils, false);
1317 69683 : } else if (*ignore_nils) {
1318 1723 : *result = (lng) BATcount_no_nil(b, s);
1319 : } else {
1320 67960 : struct canditer ci;
1321 67960 : canditer_init(&ci, b, s);
1322 67960 : *result = (lng) ci.ncand;
1323 : }
1324 69713 : BBPreclaim(s);
1325 69713 : BBPunfix(b->batCacheid);
1326 69713 : return MAL_SUCCEED;
1327 : }
1328 :
1329 : static str
1330 1723 : ALGcount_nil(lng *result, const bat *bid, const bit *ignore_nils)
1331 : {
1332 1723 : 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 67990 : ALGcount_bat(lng *result, const bat *bid)
1343 : {
1344 67990 : 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 17251 : ALGsubslice_lng(bat *ret, const bat *bid, const lng *start, const lng *end)
1408 : {
1409 17251 : BAT *b, *bn;
1410 17251 : BUN s, e;
1411 :
1412 17251 : if (*start < 0 || (*end < 0 && !is_lng_nil(*end)))
1413 0 : throw(MAL, "algebra.subslice", ILLEGAL_ARGUMENT);
1414 17251 : if ((b = BBPquickdesc(*bid)) == NULL)
1415 0 : throw(MAL, "algebra.subslice", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1416 17251 : s = (BUN) *start;
1417 17251 : if (s > BATcount(b))
1418 : s = BATcount(b);
1419 17251 : e = is_lng_nil(*end) ? BATcount(b) : (BUN) *end + 1;
1420 17251 : if (e > BATcount(b))
1421 : e = BATcount(b);
1422 17251 : if (e < s)
1423 : e = s;
1424 17251 : bn = BATdense(0, b->hseqbase + s, e - s);
1425 17251 : if (bn == NULL)
1426 0 : throw(MAL, "algebra.subslice", SQLSTATE(HY013) MAL_MALLOC_FAIL);
1427 17251 : *ret = bn->batCacheid;
1428 17251 : BBPkeepref(bn);
1429 17251 : 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 178246 : ALGprojecttail(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1555 : {
1556 178246 : bat *ret = getArgReference_bat(stk, pci, 0);
1557 178246 : bat bid = *getArgReference_bat(stk, pci, 1);
1558 178246 : const ValRecord *v = &stk->stk[getArg(pci, 2)];
1559 178246 : BAT *b, *bn;
1560 :
1561 178246 : (void) cntxt;
1562 178246 : (void) mb;
1563 178246 : if (isaBatType(getArgType(mb, pci, 2)))
1564 0 : throw(MAL, "algebra.project", "Scalar value expected");
1565 178246 : if ((b = BBPquickdesc(bid)) == NULL)
1566 0 : throw(MAL, "algebra.project", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1567 178233 : bn = BATconstant(b->hseqbase, v->vtype, VALptr(v), BATcount(b), TRANSIENT);
1568 178238 : if (bn == NULL) {
1569 0 : *ret = bat_nil;
1570 0 : throw(MAL, "algebra.project", SQLSTATE(HY013) MAL_MALLOC_FAIL);
1571 : }
1572 178238 : *ret = bn->batCacheid;
1573 178238 : BBPkeepref(bn);
1574 178238 : 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 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 324 : LIB_STARTUP_FUNC(init_algebra_mal)
1838 324 : { mal_module("algebra", NULL, algebra_init_funcs); }
|