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 64462 : 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 64462 : BAT *b, *s = NULL, *bn;
265 :
266 64462 : if ((*li != 0 && *li != 1) ||
267 64462 : (*hi != 0 && *hi != 1) || (*anti != 0 && *anti != 1)) {
268 1 : throw(MAL, "algebra.select", ILLEGAL_ARGUMENT);
269 : }
270 :
271 64461 : if ((b = BATdescriptor(*bid)) == NULL) {
272 0 : throw(MAL, "algebra.select", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
273 : }
274 64462 : 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 64461 : derefStr(b, low);
279 64461 : derefStr(b, high);
280 :
281 64461 : bool nanti = *anti, nli = *li, nhi = *hi;
282 :
283 : /* here we don't need open ended parts with nil */
284 64461 : if (!nanti && *unknown) {
285 883 : const void *nilptr = ATOMnilptr(b->ttype);
286 883 : if (nilptr) {
287 883 : 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 883 : if (ATOMcmp(b->ttype, low, high) == 0 && ATOMcmp(b->ttype, high, nilptr) == 0) /* ugh sql nil != nil */
296 11 : nanti = true;
297 : }
298 63578 : } else if (!*unknown) {
299 60501 : const void *nilptr = ATOMnilptr(b->ttype);
300 120851 : if (nli && nhi && nilptr != NULL &&
301 60372 : ATOMcmp(b->ttype, low, nilptr) == 0 &&
302 24 : ATOMcmp(b->ttype, high, nilptr) == 0) {
303 : /* special case: equi-select for NIL */
304 64463 : high = NULL;
305 : }
306 : }
307 :
308 64463 : bn = BATselect(b, s, low, high, nli, nhi, nanti, false);
309 64458 : BBPunfix(b->batCacheid);
310 64453 : BBPreclaim(s);
311 64455 : if (bn == NULL)
312 0 : throw(MAL, "algebra.select", GDK_EXCEPTION);
313 64455 : *result = bn->batCacheid;
314 64455 : BBPkeepref(bn);
315 64455 : return MAL_SUCCEED;
316 : }
317 :
318 : static str
319 20752 : 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 20752 : return ALGselect2nil(result, bid, sid, low, high, li, hi, anti, &(bit){0});
323 : }
324 :
325 : static str
326 39750 : ALGselect1(bat *result, const bat *bid, const void *low, const void *high,
327 : const bit *li, const bit *hi, const bit *anti)
328 : {
329 39750 : 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 329762 : ALGthetaselect2(bat *result, const bat *bid, const bat *sid, const void *val,
341 : const char **op)
342 : {
343 329762 : BAT *b, *s = NULL, *bn;
344 :
345 329762 : if ((b = BATdescriptor(*bid)) == NULL) {
346 0 : throw(MAL, "algebra.thetaselect",
347 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
348 : }
349 329752 : 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 329740 : derefStr(b, val);
355 329740 : bn = BATthetaselect(b, s, val, *op);
356 329728 : BBPunfix(b->batCacheid);
357 329718 : BBPreclaim(s);
358 329691 : if (bn == NULL)
359 0 : throw(MAL, "algebra.select", GDK_EXCEPTION);
360 329691 : *result = bn->batCacheid;
361 329691 : BBPkeepref(bn);
362 329691 : 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 1583 : MT_lock_set(&b->theaplock);
571 1583 : bool bnonil = b->tnonil || b->ttype == TYPE_msk;
572 1583 : MT_lock_unset(&b->theaplock);
573 1583 : 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 1486 : *result = b->batCacheid;
591 1486 : BBPkeepref(b);
592 1486 : return MAL_SUCCEED;
593 : }
594 :
595 : static str
596 312665 : 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 312665 : BAT *left = NULL, *right = NULL, *right2 = NULL;
616 312665 : BAT *candleft = NULL, *candright = NULL;
617 312665 : BAT *result1 = NULL, *result2 = NULL, *result3 = NULL;
618 312665 : BUN est;
619 312665 : const char *err = SQLSTATE(HY002) RUNTIME_OBJECT_MISSING;
620 :
621 312665 : assert(r2id == NULL || rangefunc != NULL);
622 :
623 312665 : if ((left = BATdescriptor(*lid)) == NULL)
624 0 : goto fail;
625 312653 : if ((right = BATdescriptor(*rid)) == NULL)
626 0 : goto fail;
627 312643 : if (slid && !is_bat_nil(*slid) && (candleft = BATdescriptor(*slid)) == NULL)
628 0 : goto fail;
629 312644 : if (srid && !is_bat_nil(*srid)
630 0 : && (candright = BATdescriptor(*srid)) == NULL)
631 0 : goto fail;
632 312644 : 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 312644 : err = NULL; /* most likely error now is GDK_EXCEPTION */
639 :
640 312644 : if (thetafunc) {
641 16834 : assert(joinfunc == NULL);
642 16834 : assert(semifunc == NULL);
643 16834 : assert(markfunc == NULL);
644 16834 : assert(bandfunc == NULL);
645 16834 : assert(rangefunc == NULL);
646 16834 : assert(difffunc == NULL);
647 16834 : assert(interfunc == NULL);
648 16834 : if ((*thetafunc)
649 : (&result1, r2 ? &result2 : NULL, left, right, candleft, candright,
650 16834 : op, *nil_matches, est) != GDK_SUCCEED)
651 0 : goto fail;
652 295810 : } else if (joinfunc) {
653 194919 : assert(semifunc == NULL);
654 194919 : assert(markfunc == NULL);
655 194919 : assert(bandfunc == NULL);
656 194919 : assert(rangefunc == NULL);
657 194919 : assert(difffunc == NULL);
658 194919 : assert(interfunc == NULL);
659 194919 : if ((*joinfunc)
660 : (&result1, r2 ? &result2 : NULL, left, right, candleft, candright,
661 194919 : *nil_matches, est) != GDK_SUCCEED)
662 1 : goto fail;
663 100891 : } 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 100559 : } 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 90909 : } 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 90909 : } 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 90784 : } else if (difffunc) {
702 85329 : assert(r2 == NULL);
703 85329 : assert(interfunc == NULL);
704 85321 : if ((result1 = (*difffunc) (left, right, candleft, candright,
705 85329 : *nil_matches, *not_in, est)) == NULL)
706 0 : goto fail;
707 : } else {
708 5455 : assert(r2 == NULL);
709 5453 : if ((result1 = (*interfunc) (left, right, candleft, candright,
710 5455 : *nil_matches, *max_one, est)) == NULL)
711 1 : goto fail;
712 : }
713 312557 : *r1 = result1->batCacheid;
714 312557 : BBPkeepref(result1);
715 312439 : if (r2) {
716 179432 : *r2 = result2->batCacheid;
717 179432 : BBPkeepref(result2);
718 : }
719 312335 : if (r3) {
720 9650 : *r3 = result3->batCacheid;
721 9650 : BBPkeepref(result3);
722 : }
723 312330 : BBPunfix(left->batCacheid);
724 312402 : BBPunfix(right->batCacheid);
725 312473 : BBPreclaim(candleft);
726 312477 : 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 174245 : 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 174245 : 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 20045 : 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 20045 : 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 12537 : 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 12537 : 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 85330 : 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 85330 : 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 5455 : 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 5455 : 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 1217 : BBPreclaim(s);
982 1217 : BBPreclaim(g);
983 1217 : if (rc != GDK_SUCCEED)
984 0 : throw(MAL, "algebra.firstn", GDK_EXCEPTION);
985 1217 : *ret1 = bn->batCacheid;
986 1217 : 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 25475 : ALGcrossproduct(bat *l, bat *r, const bat *left, const bat *right,
1047 : const bat *slid, const bat *srid, const bit *max_one)
1048 : {
1049 25475 : BAT *L, *R, *bn1, *bn2 = NULL;
1050 25475 : BAT *sl = NULL, *sr = NULL;
1051 25475 : gdk_return ret;
1052 :
1053 25475 : L = BATdescriptor(*left);
1054 25474 : R = BATdescriptor(*right);
1055 25475 : 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 25475 : 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 26864 : ret = BATsubcross(&bn1, r ? &bn2 : NULL, L, R, sl, sr,
1071 25475 : max_one && !is_bit_nil(*max_one) && *max_one);
1072 25468 : BBPunfix(L->batCacheid);
1073 25472 : BBPunfix(R->batCacheid);
1074 25471 : BBPreclaim(sl);
1075 25471 : BBPreclaim(sr);
1076 25471 : if (ret != GDK_SUCCEED)
1077 77 : throw(MAL, "algebra.crossproduct", GDK_EXCEPTION);
1078 25394 : *l = bn1->batCacheid;
1079 25394 : BBPkeepref(bn1);
1080 25390 : if (r) {
1081 24008 : *r = bn2->batCacheid;
1082 24008 : 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 24086 : ALGcrossproduct2(bat *l, bat *r, const bat *left, const bat *right,
1095 : const bit *max_one)
1096 : {
1097 24086 : 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 1061574 : ALGprojection2(bat *result, const bat *lid, const bat *r1id, const bat *r2id)
1155 : {
1156 1061574 : BAT *l, *r1, *r2 = NULL, *bn;
1157 :
1158 1061574 : if ((l = BATdescriptor(*lid)) == NULL) {
1159 0 : throw(MAL, "algebra.projection",
1160 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1161 : }
1162 1061522 : if ((r1 = BATdescriptor(*r1id)) == NULL) {
1163 0 : BBPunfix(l->batCacheid);
1164 0 : throw(MAL, "algebra.projection",
1165 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1166 : }
1167 1061426 : 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 1061426 : bn = BATproject2(l, r1, r2);
1174 1061043 : BBPunfix(l->batCacheid);
1175 1061173 : BBPunfix(r1->batCacheid);
1176 1060916 : BBPreclaim(r2);
1177 1060928 : if (bn == NULL)
1178 0 : throw(MAL, "algebra.projection", GDK_EXCEPTION);
1179 1060928 : *result = bn->batCacheid;
1180 1060928 : BBPkeepref(bn);
1181 1060928 : return MAL_SUCCEED;
1182 : }
1183 :
1184 : str
1185 1061590 : ALGprojection(bat *result, const bat *lid, const bat *rid)
1186 : {
1187 1061590 : return ALGprojection2(result, lid, rid, NULL);
1188 : }
1189 :
1190 : static str
1191 19231 : 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 19231 : BAT *bn = NULL, *on = NULL, *gn = NULL;
1196 19231 : BAT *b = NULL, *o = NULL, *g = NULL;
1197 :
1198 19231 : if ((b = BATdescriptor(*bid)) == NULL)
1199 0 : throw(MAL, "algebra.sort", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1200 19231 : 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 19231 : 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 22729 : if (BATsort(result ? &bn : NULL,
1210 : norder ? &on : NULL,
1211 : ngroup ? &gn : NULL,
1212 19231 : 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 2837 : 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 2837 : 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 69414 : ALGcountCND_nil(lng *result, const bat *bid, const bat *cnd,
1304 : const bit *ignore_nils)
1305 : {
1306 69414 : BAT *b, *s = NULL;
1307 :
1308 69414 : if ((b = BATdescriptor(*bid)) == NULL) {
1309 0 : throw(MAL, "aggr.count", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1310 : }
1311 69414 : 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 69414 : if (b->ttype == TYPE_msk || mask_cand(b)) {
1316 30 : BATsum(result, TYPE_lng, b, s, *ignore_nils, false);
1317 69384 : } else if (*ignore_nils) {
1318 1723 : *result = (lng) BATcount_no_nil(b, s);
1319 : } else {
1320 67661 : struct canditer ci;
1321 67661 : canditer_init(&ci, b, s);
1322 67661 : *result = (lng) ci.ncand;
1323 : }
1324 69414 : BBPreclaim(s);
1325 69414 : BBPunfix(b->batCacheid);
1326 69414 : 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 67691 : ALGcount_bat(lng *result, const bat *bid)
1343 : {
1344 67691 : 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 17370 : ALGsubslice_lng(bat *ret, const bat *bid, const lng *start, const lng *end)
1408 : {
1409 17370 : BAT *b, *bn;
1410 17370 : BUN s, e;
1411 :
1412 17370 : if (*start < 0 || (*end < 0 && !is_lng_nil(*end)))
1413 0 : throw(MAL, "algebra.subslice", ILLEGAL_ARGUMENT);
1414 17370 : if ((b = BBPquickdesc(*bid)) == NULL)
1415 0 : throw(MAL, "algebra.subslice", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1416 17370 : s = (BUN) *start;
1417 17370 : if (s > BATcount(b))
1418 : s = BATcount(b);
1419 17370 : e = is_lng_nil(*end) ? BATcount(b) : (BUN) *end + 1;
1420 17370 : if (e > BATcount(b))
1421 : e = BATcount(b);
1422 17370 : if (e < s)
1423 : e = s;
1424 17370 : bn = BATdense(0, b->hseqbase + s, e - s);
1425 17370 : if (bn == NULL)
1426 0 : throw(MAL, "algebra.subslice", SQLSTATE(HY013) MAL_MALLOC_FAIL);
1427 17370 : *ret = bn->batCacheid;
1428 17370 : BBPkeepref(bn);
1429 17370 : 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 164295 : ALGprojecttail(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1555 : {
1556 164295 : bat *ret = getArgReference_bat(stk, pci, 0);
1557 164295 : bat bid = *getArgReference_bat(stk, pci, 1);
1558 164295 : const ValRecord *v = &stk->stk[getArg(pci, 2)];
1559 164295 : BAT *b, *bn;
1560 :
1561 164295 : (void) cntxt;
1562 164295 : (void) mb;
1563 164295 : if (isaBatType(getArgType(mb, pci, 2)))
1564 0 : throw(MAL, "algebra.project", "Scalar value expected");
1565 164295 : if ((b = BBPquickdesc(bid)) == NULL)
1566 0 : throw(MAL, "algebra.project", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1567 164277 : bn = BATconstant(b->hseqbase, v->vtype, VALptr(v), BATcount(b), TRANSIENT);
1568 164287 : if (bn == NULL) {
1569 0 : *ret = bat_nil;
1570 0 : throw(MAL, "algebra.project", SQLSTATE(HY013) MAL_MALLOC_FAIL);
1571 : }
1572 164287 : *ret = bn->batCacheid;
1573 164287 : BBPkeepref(bn);
1574 164287 : 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 308 : LIB_STARTUP_FUNC(init_algebra_mal)
1838 308 : { mal_module("algebra", NULL, algebra_init_funcs); }
|