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 596 : ALGmaxany_skipnil(ptr result, const bat *bid, const bit *skipnil)
178 : {
179 596 : BAT *b;
180 596 : ptr p;
181 596 : str msg = MAL_SUCCEED;
182 :
183 596 : if (result == NULL || (b = BATdescriptor(*bid)) == NULL)
184 0 : throw(MAL, "algebra.max", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
185 :
186 596 : 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 596 : if (ATOMextern(b->ttype)) {
192 48 : *(ptr *) result = p = BATmax_skipnil(b, NULL, *skipnil);
193 : } else {
194 548 : p = BATmax_skipnil(b, result, *skipnil);
195 548 : if (p != result)
196 0 : msg = createException(MAL, "algebra.max",
197 : SQLSTATE(HY002) "INTERNAL ERROR");
198 : }
199 596 : if (msg == MAL_SUCCEED && p == NULL)
200 0 : msg = createException(MAL, "algebra.max", GDK_EXCEPTION);
201 : }
202 596 : BBPunfix(b->batCacheid);
203 596 : return msg;
204 : }
205 :
206 : static str
207 596 : ALGmaxany(ptr result, const bat *bid)
208 : {
209 596 : bit skipnil = TRUE;
210 596 : 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 67593 : 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 67593 : BAT *b, *s = NULL, *bn;
265 :
266 67593 : if ((*li != 0 && *li != 1) ||
267 67593 : (*hi != 0 && *hi != 1) || (*anti != 0 && *anti != 1)) {
268 0 : throw(MAL, "algebra.select", ILLEGAL_ARGUMENT);
269 : }
270 :
271 67593 : if ((b = BATdescriptor(*bid)) == NULL) {
272 0 : throw(MAL, "algebra.select", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
273 : }
274 67593 : 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 67592 : derefStr(b, low);
279 67592 : derefStr(b, high);
280 :
281 67592 : bool nanti = *anti, nli = *li, nhi = *hi;
282 :
283 : /* here we don't need open ended parts with nil */
284 67592 : 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 66709 : } else if (!*unknown) {
299 63628 : const void *nilptr = ATOMnilptr(b->ttype);
300 127105 : if (nli && nhi && nilptr != NULL &&
301 63499 : ATOMcmp(b->ttype, low, nilptr) == 0 &&
302 24 : ATOMcmp(b->ttype, high, nilptr) == 0) {
303 : /* special case: equi-select for NIL */
304 67594 : high = NULL;
305 : }
306 : }
307 :
308 67594 : bn = BATselect(b, s, low, high, nli, nhi, nanti, false);
309 67592 : BBPunfix(b->batCacheid);
310 67586 : BBPreclaim(s);
311 67587 : if (bn == NULL)
312 0 : throw(MAL, "algebra.select", GDK_EXCEPTION);
313 67587 : *result = bn->batCacheid;
314 67587 : BBPkeepref(bn);
315 67587 : 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 42879 : ALGselect1(bat *result, const bat *bid, const void *low, const void *high,
327 : const bit *li, const bit *hi, const bit *anti)
328 : {
329 42879 : 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 323539 : ALGthetaselect2(bat *result, const bat *bid, const bat *sid, const void *val,
341 : const char **op)
342 : {
343 323539 : BAT *b, *s = NULL, *bn;
344 :
345 323539 : if ((b = BATdescriptor(*bid)) == NULL) {
346 0 : throw(MAL, "algebra.thetaselect",
347 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
348 : }
349 323525 : 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 323505 : derefStr(b, val);
355 323505 : bn = BATthetaselect(b, s, val, *op);
356 323519 : BBPunfix(b->batCacheid);
357 323510 : BBPreclaim(s);
358 323513 : if (bn == NULL)
359 0 : throw(MAL, "algebra.select", GDK_EXCEPTION);
360 323513 : *result = bn->batCacheid;
361 323513 : BBPkeepref(bn);
362 323513 : 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 1540 : ALGselectNotNil(bat *result, const bat *bid)
563 : {
564 1540 : BAT *b;
565 :
566 1540 : if ((b = BATdescriptor(*bid)) == NULL)
567 0 : throw(MAL, "algebra.selectNotNil",
568 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
569 :
570 1540 : MT_lock_set(&b->theaplock);
571 1540 : bool bnonil = b->tnonil || b->ttype == TYPE_msk;
572 1540 : MT_lock_unset(&b->theaplock);
573 1540 : 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 1443 : *result = b->batCacheid;
591 1443 : BBPkeepref(b);
592 1443 : return MAL_SUCCEED;
593 : }
594 :
595 : static str
596 290705 : 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 290705 : BAT *left = NULL, *right = NULL, *right2 = NULL;
616 290705 : BAT *candleft = NULL, *candright = NULL;
617 290705 : BAT *result1 = NULL, *result2 = NULL, *result3 = NULL;
618 290705 : BUN est;
619 290705 : const char *err = SQLSTATE(HY002) RUNTIME_OBJECT_MISSING;
620 :
621 290705 : assert(r2id == NULL || rangefunc != NULL);
622 :
623 290705 : if ((left = BATdescriptor(*lid)) == NULL)
624 0 : goto fail;
625 290685 : if ((right = BATdescriptor(*rid)) == NULL)
626 0 : goto fail;
627 290687 : if (slid && !is_bat_nil(*slid) && (candleft = BATdescriptor(*slid)) == NULL)
628 0 : goto fail;
629 290687 : if (srid && !is_bat_nil(*srid)
630 0 : && (candright = BATdescriptor(*srid)) == NULL)
631 0 : goto fail;
632 290687 : 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 290687 : err = NULL; /* most likely error now is GDK_EXCEPTION */
639 :
640 290687 : if (thetafunc) {
641 16827 : assert(joinfunc == NULL);
642 16827 : assert(semifunc == NULL);
643 16827 : assert(markfunc == NULL);
644 16827 : assert(bandfunc == NULL);
645 16827 : assert(rangefunc == NULL);
646 16827 : assert(difffunc == NULL);
647 16827 : assert(interfunc == NULL);
648 16827 : if ((*thetafunc)
649 : (&result1, r2 ? &result2 : NULL, left, right, candleft, candright,
650 16827 : op, *nil_matches, est) != GDK_SUCCEED)
651 0 : goto fail;
652 273860 : } else if (joinfunc) {
653 193106 : assert(semifunc == NULL);
654 193106 : assert(markfunc == NULL);
655 193106 : assert(bandfunc == NULL);
656 193106 : assert(rangefunc == NULL);
657 193106 : assert(difffunc == NULL);
658 193106 : assert(interfunc == NULL);
659 193106 : if ((*joinfunc)
660 : (&result1, r2 ? &result2 : NULL, left, right, candleft, candright,
661 193106 : *nil_matches, est) != GDK_SUCCEED)
662 1 : goto fail;
663 80754 : } 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 80422 : } else if (markfunc) {
674 3318 : assert(bandfunc == NULL);
675 3318 : assert(rangefunc == NULL);
676 3318 : assert(difffunc == NULL);
677 3318 : assert(interfunc == NULL);
678 6631 : if ((*markfunc) (&result1, r2 ? &result2 : NULL, &result3,
679 : left, right, candleft, candright, est) != GDK_SUCCEED)
680 0 : goto fail;
681 77104 : } 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 77104 : } 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 76979 : } else if (difffunc) {
702 71239 : assert(r2 == NULL);
703 71239 : assert(interfunc == NULL);
704 71239 : if ((result1 = (*difffunc) (left, right, candleft, candright,
705 71239 : *nil_matches, *not_in, est)) == NULL)
706 0 : goto fail;
707 : } else {
708 5740 : assert(r2 == NULL);
709 5741 : if ((result1 = (*interfunc) (left, right, candleft, candright,
710 5740 : *nil_matches, *max_one, est)) == NULL)
711 1 : goto fail;
712 : }
713 290627 : *r1 = result1->batCacheid;
714 290627 : BBPkeepref(result1);
715 290601 : if (r2) {
716 173854 : *r2 = result2->batCacheid;
717 173854 : BBPkeepref(result2);
718 : }
719 290586 : if (r3) {
720 3318 : *r3 = result3->batCacheid;
721 3318 : BBPkeepref(result3);
722 : }
723 290586 : BBPunfix(left->batCacheid);
724 290591 : BBPunfix(right->batCacheid);
725 290603 : BBPreclaim(candleft);
726 290603 : 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 168567 : 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 168567 : 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 23906 : 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 23906 : 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 3313 : ALGmark2join(bat *r1, bat *r3, const bat *lid, const bat *rid,
815 : const bat *slid, const bat *srid, const lng *estimate)
816 : {
817 3313 : 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 4293 : 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 4293 : 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 71241 : 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 71241 : 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 5741 : 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 5741 : 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 1208 : ALGfirstn(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
932 : {
933 1208 : bat *ret1, *ret2 = NULL;
934 1208 : bat bid, sid, gid;
935 1208 : BAT *b, *s = NULL, *g = NULL;
936 1208 : BAT *bn = NULL, *gn = NULL;
937 1208 : lng n;
938 1208 : bit asc, nilslast, distinct;
939 1208 : gdk_return rc;
940 :
941 1208 : (void) cntxt;
942 1208 : (void) mb;
943 :
944 1208 : assert(pci->retc == 1 || pci->retc == 2);
945 1208 : assert(pci->argc - pci->retc >= 5 && pci->argc - pci->retc <= 7);
946 :
947 1208 : n = *getArgReference_lng(stk, pci, pci->argc - 4);
948 1208 : if (n < 0)
949 0 : throw(MAL, "algebra.firstn", ILLEGAL_ARGUMENT);
950 1208 : if (n > (lng) BUN_MAX)
951 : n = BUN_MAX;
952 1208 : ret1 = getArgReference_bat(stk, pci, 0);
953 1208 : if (pci->retc == 2)
954 458 : ret2 = getArgReference_bat(stk, pci, 1);
955 1208 : bid = *getArgReference_bat(stk, pci, pci->retc);
956 1208 : if ((b = BATdescriptor(bid)) == NULL)
957 0 : throw(MAL, "algebra.firstn", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
958 1208 : if (pci->argc - pci->retc > 5) {
959 1208 : sid = *getArgReference_bat(stk, pci, pci->retc + 1);
960 1208 : 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 1208 : if (pci->argc - pci->retc > 6) {
966 1208 : gid = *getArgReference_bat(stk, pci, pci->retc + 2);
967 1208 : 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 1208 : asc = *getArgReference_bit(stk, pci, pci->argc - 3);
976 1208 : nilslast = *getArgReference_bit(stk, pci, pci->argc - 2);
977 1208 : distinct = *getArgReference_bit(stk, pci, pci->argc - 1);
978 1958 : rc = BATfirstn(&bn, ret2 ? &gn : NULL, b, s, g, (BUN) n, asc, nilslast,
979 : distinct);
980 1208 : BBPunfix(b->batCacheid);
981 1208 : BBPreclaim(s);
982 1208 : BBPreclaim(g);
983 1208 : if (rc != GDK_SUCCEED)
984 0 : throw(MAL, "algebra.firstn", GDK_EXCEPTION);
985 1208 : *ret1 = bn->batCacheid;
986 1208 : BBPkeepref(bn);
987 1208 : if (ret2) {
988 458 : *ret2 = gn->batCacheid;
989 458 : 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 26514 : ALGcrossproduct(bat *l, bat *r, const bat *left, const bat *right,
1047 : const bat *slid, const bat *srid, const bit *max_one)
1048 : {
1049 26514 : BAT *L, *R, *bn1, *bn2 = NULL;
1050 26514 : BAT *sl = NULL, *sr = NULL;
1051 26514 : gdk_return ret;
1052 :
1053 26514 : L = BATdescriptor(*left);
1054 26514 : R = BATdescriptor(*right);
1055 26513 : 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 26513 : 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 27885 : ret = BATsubcross(&bn1, r ? &bn2 : NULL, L, R, sl, sr,
1071 26513 : max_one && !is_bit_nil(*max_one) && *max_one);
1072 26506 : BBPunfix(L->batCacheid);
1073 26508 : BBPunfix(R->batCacheid);
1074 26507 : BBPreclaim(sl);
1075 26507 : BBPreclaim(sr);
1076 26507 : if (ret != GDK_SUCCEED)
1077 78 : throw(MAL, "algebra.crossproduct", GDK_EXCEPTION);
1078 26429 : *l = bn1->batCacheid;
1079 26429 : BBPkeepref(bn1);
1080 26434 : if (r) {
1081 25070 : *r = bn2->batCacheid;
1082 25070 : BBPkeepref(bn2);
1083 : }
1084 : return MAL_SUCCEED;
1085 : }
1086 :
1087 : static str
1088 1372 : ALGcrossproduct1(bat *l, const bat *left, const bat *right, const bit *max_one)
1089 : {
1090 1372 : return ALGcrossproduct(l, NULL, left, right, NULL, NULL, max_one);
1091 : }
1092 :
1093 : static str
1094 25142 : ALGcrossproduct2(bat *l, bat *r, const bat *left, const bat *right,
1095 : const bit *max_one)
1096 : {
1097 25142 : 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 1085054 : ALGprojection2(bat *result, const bat *lid, const bat *r1id, const bat *r2id)
1155 : {
1156 1085054 : BAT *l, *r1, *r2 = NULL, *bn;
1157 :
1158 1085054 : if ((l = BATdescriptor(*lid)) == NULL) {
1159 0 : throw(MAL, "algebra.projection",
1160 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1161 : }
1162 1084991 : if ((r1 = BATdescriptor(*r1id)) == NULL) {
1163 0 : BBPunfix(l->batCacheid);
1164 0 : throw(MAL, "algebra.projection",
1165 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1166 : }
1167 1084881 : 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 1084881 : bn = BATproject2(l, r1, r2);
1174 1084403 : BBPunfix(l->batCacheid);
1175 1084882 : BBPunfix(r1->batCacheid);
1176 1084813 : BBPreclaim(r2);
1177 1084818 : if (bn == NULL)
1178 0 : throw(MAL, "algebra.projection", GDK_EXCEPTION);
1179 1084818 : *result = bn->batCacheid;
1180 1084818 : BBPkeepref(bn);
1181 1084818 : return MAL_SUCCEED;
1182 : }
1183 :
1184 : str
1185 1085053 : ALGprojection(bat *result, const bat *lid, const bat *rid)
1186 : {
1187 1085053 : return ALGprojection2(result, lid, rid, NULL);
1188 : }
1189 :
1190 : static str
1191 23804 : 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 23804 : BAT *bn = NULL, *on = NULL, *gn = NULL;
1196 23804 : BAT *b = NULL, *o = NULL, *g = NULL;
1197 :
1198 23804 : if ((b = BATdescriptor(*bid)) == NULL)
1199 0 : throw(MAL, "algebra.sort", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1200 23804 : 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 23804 : 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 27403 : if (BATsort(result ? &bn : NULL,
1210 : norder ? &on : NULL,
1211 : ngroup ? &gn : NULL,
1212 23804 : 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 23804 : BBPunfix(b->batCacheid);
1219 23804 : BBPreclaim(o);
1220 23804 : BBPreclaim(g);
1221 23804 : if (result) {
1222 23804 : *result = bn->batCacheid;
1223 23804 : BBPkeepref(bn);
1224 : }
1225 23804 : if (norder) {
1226 20205 : *norder = on->batCacheid;
1227 20205 : BBPkeepref(on);
1228 : }
1229 23804 : if (ngroup) {
1230 13509 : *ngroup = gn->batCacheid;
1231 13509 : BBPkeepref(gn);
1232 : }
1233 : return MAL_SUCCEED;
1234 : }
1235 :
1236 : static str
1237 4036 : 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 4036 : 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 6249 : ALGsort13(bat *result, bat *norder, bat *ngroup, const bat *bid,
1280 : const bit *reverse, const bit *nilslast, const bit *stable)
1281 : {
1282 6249 : return ALGsort33(result, norder, ngroup, bid, NULL, NULL, reverse, nilslast,
1283 : stable);
1284 : }
1285 :
1286 : static str
1287 2660 : ALGsort12(bat *result, bat *norder, const bat *bid, const bit *reverse,
1288 : const bit *nilslast, const bit *stable)
1289 : {
1290 2660 : 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 69623 : ALGcountCND_nil(lng *result, const bat *bid, const bat *cnd,
1304 : const bit *ignore_nils)
1305 : {
1306 69623 : BAT *b, *s = NULL;
1307 :
1308 69623 : if ((b = BATdescriptor(*bid)) == NULL) {
1309 0 : throw(MAL, "aggr.count", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1310 : }
1311 69621 : 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 69621 : if (b->ttype == TYPE_msk || mask_cand(b)) {
1316 30 : BATsum(result, TYPE_lng, b, s, *ignore_nils, false);
1317 69591 : } else if (*ignore_nils) {
1318 1723 : *result = (lng) BATcount_no_nil(b, s);
1319 : } else {
1320 67868 : struct canditer ci;
1321 67868 : canditer_init(&ci, b, s);
1322 67870 : *result = (lng) ci.ncand;
1323 : }
1324 69623 : BBPreclaim(s);
1325 69623 : BBPunfix(b->batCacheid);
1326 69623 : 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 67900 : ALGcount_bat(lng *result, const bat *bid)
1343 : {
1344 67900 : 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 17214 : ALGsubslice_lng(bat *ret, const bat *bid, const lng *start, const lng *end)
1408 : {
1409 17214 : BAT *b, *bn;
1410 17214 : BUN s, e;
1411 :
1412 17214 : if (*start < 0 || (*end < 0 && !is_lng_nil(*end)))
1413 0 : throw(MAL, "algebra.subslice", ILLEGAL_ARGUMENT);
1414 17214 : if ((b = BBPquickdesc(*bid)) == NULL)
1415 0 : throw(MAL, "algebra.subslice", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1416 17214 : s = (BUN) *start;
1417 17214 : if (s > BATcount(b))
1418 : s = BATcount(b);
1419 17214 : e = is_lng_nil(*end) ? BATcount(b) : (BUN) *end + 1;
1420 17214 : if (e > BATcount(b))
1421 : e = BATcount(b);
1422 17214 : if (e < s)
1423 : e = s;
1424 17214 : bn = BATdense(0, b->hseqbase + s, e - s);
1425 17214 : if (bn == NULL)
1426 0 : throw(MAL, "algebra.subslice", SQLSTATE(HY013) MAL_MALLOC_FAIL);
1427 17214 : *ret = bn->batCacheid;
1428 17214 : BBPkeepref(bn);
1429 17214 : 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 141887 : ALGprojecttail(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1555 : {
1556 141887 : bat *ret = getArgReference_bat(stk, pci, 0);
1557 141887 : bat bid = *getArgReference_bat(stk, pci, 1);
1558 141887 : const ValRecord *v = &stk->stk[getArg(pci, 2)];
1559 141887 : BAT *b, *bn;
1560 :
1561 141887 : (void) cntxt;
1562 141887 : (void) mb;
1563 141887 : if (isaBatType(getArgType(mb, pci, 2)))
1564 0 : throw(MAL, "algebra.project", "Scalar value expected");
1565 141887 : if ((b = BBPquickdesc(bid)) == NULL)
1566 0 : throw(MAL, "algebra.project", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1567 141885 : bn = BATconstant(b->hseqbase, v->vtype, VALptr(v), BATcount(b), TRANSIENT);
1568 141884 : if (bn == NULL) {
1569 0 : *ret = bat_nil;
1570 0 : throw(MAL, "algebra.project", SQLSTATE(HY013) MAL_MALLOC_FAIL);
1571 : }
1572 141884 : *ret = bn->batCacheid;
1573 141884 : BBPkeepref(bn);
1574 141884 : 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 323 : LIB_STARTUP_FUNC(init_algebra_mal)
1838 323 : { mal_module("algebra", NULL, algebra_init_funcs); }
|