1/*
2 * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5 *
6 * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
7 */
8
9#include "monetdb_config.h"
10#include "gdk.h"
11#include <math.h>
12#include "mal_exception.h"
13#include "mal_interpreter.h"
14
15static str
16mythrow(enum malexception type, const char *fcn, const char *msg)
17{
18 char *errbuf = GDKerrbuf;
19 char *s;
20
21 if (errbuf && *errbuf) {
22 if (strncmp(errbuf, "!ERROR: ", 8) == 0)
23 errbuf += 8;
24 if (strchr(errbuf, '!') == errbuf + 5) {
25 s = createException(type, fcn, "%s", errbuf);
26 } else if ((s = strchr(errbuf, ':')) != NULL && s[1] == ' ') {
27 s = createException(type, fcn, "%s", s + 2);
28 } else {
29 s = createException(type, fcn, "%s", errbuf);
30 }
31 GDKclrerr();
32 return s;
33 }
34 return createException(type, fcn, "%s", msg);
35}
36
37static str
38CMDbatUNARY(MalStkPtr stk, InstrPtr pci,
39 BAT *(*batfunc)(BAT *, BAT *), const char *malfunc)
40{
41 bat *bid;
42 BAT *bn, *b, *s = NULL;
43
44 bid = getArgReference_bat(stk, pci, 1);
45 if ((b = BATdescriptor(*bid)) == NULL)
46 throw(MAL, malfunc, SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
47 if (pci->argc == 3) {
48 bat *sid = getArgReference_bat(stk, pci, 2);
49 if (*sid && (s = BATdescriptor(*sid)) == NULL) {
50 BBPunfix(b->batCacheid);
51 throw(MAL, malfunc, SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
52 }
53 }
54
55 bn = (*batfunc)(b, s);
56 BBPunfix(b->batCacheid);
57 if (s)
58 BBPunfix(s->batCacheid);
59 if (bn == NULL) {
60 return mythrow(MAL, malfunc, OPERATION_FAILED);
61 }
62 bid = getArgReference_bat(stk, pci, 0);
63 BBPkeepref(*bid = bn->batCacheid);
64 return MAL_SUCCEED;
65}
66
67static str
68CMDbatUNARY1(MalStkPtr stk, InstrPtr pci, bool abort_on_error,
69 BAT *(*batfunc)(BAT *, BAT *, bool), const char *malfunc)
70{
71 bat *bid;
72 BAT *bn, *b, *s = NULL;
73
74 bid = getArgReference_bat(stk, pci, 1);
75 if ((b = BATdescriptor(*bid)) == NULL)
76 throw(MAL, malfunc, SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
77 if (pci->argc == 3) {
78 bat *sid = getArgReference_bat(stk, pci, 2);
79 if (*sid && (s = BATdescriptor(*sid)) == NULL) {
80 BBPunfix(b->batCacheid);
81 throw(MAL, malfunc, SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
82 }
83 }
84
85 bn = (*batfunc)(b, s, abort_on_error);
86 BBPunfix(b->batCacheid);
87 if (s)
88 BBPunfix(s->batCacheid);
89 if (bn == NULL) {
90 return mythrow(MAL, malfunc, OPERATION_FAILED);
91 }
92 bid = getArgReference_bat(stk, pci, 0);
93 BBPkeepref(*bid = bn->batCacheid);
94 return MAL_SUCCEED;
95}
96
97mal_export str CMDbatISZERO(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
98
99str
100CMDbatISZERO(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
101{
102 (void) cntxt;
103 (void) mb;
104
105 return CMDbatUNARY(stk, pci, BATcalciszero, "batcalc.iszero");
106}
107
108mal_export str CMDbatISNIL(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
109
110str
111CMDbatISNIL(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
112{
113 (void) cntxt;
114 (void) mb;
115
116 return CMDbatUNARY(stk, pci, BATcalcisnil, "batcalc.isnil");
117}
118
119mal_export str CMDbatISNOTNIL(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
120
121str
122CMDbatISNOTNIL(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
123{
124 (void) cntxt;
125 (void) mb;
126
127 return CMDbatUNARY(stk, pci, BATcalcisnotnil, "batcalc.isnotnil");
128}
129
130mal_export str CMDbatNOT(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
131
132str
133CMDbatNOT(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
134{
135 (void) cntxt;
136 (void) mb;
137
138 return CMDbatUNARY(stk, pci, BATcalcnot, "batcalc.not");
139}
140
141mal_export str CMDbatABS(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
142
143str
144CMDbatABS(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
145{
146 (void) cntxt;
147 (void) mb;
148
149 return CMDbatUNARY(stk, pci, BATcalcabsolute, "batcalc.abs");
150}
151
152mal_export str CMDbatINCR(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
153
154str
155CMDbatINCR(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
156{
157 (void) cntxt;
158 (void) mb;
159
160 return CMDbatUNARY1(stk, pci, true, BATcalcincr, "batcalc.incr");
161}
162
163mal_export str CMDbatDECR(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
164
165str
166CMDbatDECR(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
167{
168 (void) cntxt;
169 (void) mb;
170
171 return CMDbatUNARY1(stk, pci, true, BATcalcdecr, "batcalc.decr");
172}
173
174mal_export str CMDbatNEG(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
175
176str
177CMDbatNEG(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
178{
179 (void) cntxt;
180 (void) mb;
181
182 return CMDbatUNARY(stk, pci, BATcalcnegate, "batcalc.neg");
183}
184
185mal_export str CMDbatSIGN(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
186
187str
188CMDbatSIGN(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
189{
190 (void) cntxt;
191 (void) mb;
192
193 return CMDbatUNARY(stk, pci, BATcalcsign, "batcalc.sign");
194}
195
196static int
197calctype(int tp1, int tp2)
198{
199 int tp1s = ATOMbasetype(tp1);
200 int tp2s = ATOMbasetype(tp2);
201 if (tp1s == TYPE_str && tp2s == TYPE_str)
202 return TYPE_str;
203 if (tp1s < TYPE_flt && tp2s < TYPE_flt) {
204 if (tp1s > tp2s)
205 return tp1;
206 if (tp1s < tp2s)
207 return tp2;
208 return MAX(tp1, tp2);
209 }
210 if (tp1s == TYPE_dbl || tp2s == TYPE_dbl)
211 return TYPE_dbl;
212 if (tp1s == TYPE_flt || tp2s == TYPE_flt)
213 return TYPE_flt;
214#ifdef HAVE_HGE
215 if (tp1s == TYPE_hge || tp2s == TYPE_hge)
216 return TYPE_hge;
217#endif
218 return TYPE_lng;
219}
220
221static int
222calctypeenlarge(int tp1, int tp2)
223{
224 tp1 = calctype(tp1, tp2);
225 switch (tp1) {
226 case TYPE_bte:
227 return TYPE_sht;
228 case TYPE_sht:
229 return TYPE_int;
230 case TYPE_int:
231 return TYPE_lng;
232#ifdef HAVE_HGE
233 case TYPE_lng:
234 return TYPE_hge;
235#endif
236 case TYPE_flt:
237 return TYPE_dbl;
238 default:
239 /* we shouldn't get here */
240 return tp1;
241 }
242}
243
244static int
245calcdivtype(int tp1, int tp2)
246{
247 /* if right hand side is floating point, the result is floating
248 * point, otherwise the result has the type of the left hand
249 * side */
250 tp1 = ATOMbasetype(tp1);
251 tp2 = ATOMbasetype(tp2);
252 if (tp1 == TYPE_dbl || tp2 == TYPE_dbl)
253 return TYPE_dbl;
254 if (tp1 == TYPE_flt || tp2 == TYPE_flt)
255 return TYPE_flt;
256 return tp1;
257}
258
259#if 0
260static int
261calcdivtypeflt(int tp1, int tp2)
262{
263 (void) tp1;
264 (void) tp2;
265 return TYPE_flt;
266}
267
268static int
269calcdivtypedbl(int tp1, int tp2)
270{
271 (void) tp1;
272 (void) tp2;
273 return TYPE_dbl;
274}
275#endif
276
277static int
278calcmodtype(int tp1, int tp2)
279{
280 tp1 = ATOMbasetype(tp1);
281 tp2 = ATOMbasetype(tp2);
282 assert(tp1 > 0 && tp1 < TYPE_str && tp1 != TYPE_bat && tp1 != TYPE_ptr);
283 assert(tp2 > 0 && tp2 < TYPE_str && tp2 != TYPE_bat && tp2 != TYPE_ptr);
284 if (tp1 == TYPE_dbl || tp2 == TYPE_dbl)
285 return TYPE_dbl;
286 if (tp1 == TYPE_flt || tp2 == TYPE_flt)
287 return TYPE_flt;
288 return MIN(tp1, tp2);
289}
290
291static str
292CMDbatBINARY2(MalBlkPtr mb, MalStkPtr stk, InstrPtr pci,
293 BAT *(*batfunc)(BAT *, BAT *, BAT *, int, bool),
294 BAT *(batfunc1)(BAT *, const ValRecord *, BAT *, int, bool),
295 BAT *(batfunc2)(const ValRecord *, BAT *, BAT *, int, bool),
296 int (*typefunc)(int, int),
297 bool abort_on_error, const char *malfunc)
298{
299 bat *bid;
300 BAT *bn, *b, *s = NULL;
301 int tp1, tp2, tp3;
302
303 tp1 = stk->stk[getArg(pci, 1)].vtype;
304 tp2 = stk->stk[getArg(pci, 2)].vtype;
305 tp3 = getArgType(mb, pci, 0);
306 assert(isaBatType(tp3));
307 tp3 = getBatType(tp3);
308 if (pci->argc == 4) {
309 bat *sid = getArgReference_bat(stk, pci, 3);
310 if (*sid && (s = BATdescriptor(*sid)) == NULL)
311 throw(MAL, malfunc, SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
312 }
313
314 if (tp1 == TYPE_bat || isaBatType(tp1)) {
315 BAT *b2 = NULL;
316 bid = getArgReference_bat(stk, pci, 1);
317 b = BATdescriptor(*bid);
318 if (b == NULL) {
319 if (s)
320 BBPunfix(s->batCacheid);
321 throw(MAL, malfunc, SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
322 }
323 if (tp2 == TYPE_bat || isaBatType(tp2)) {
324 bid = getArgReference_bat(stk, pci, 2);
325 b2 = BATdescriptor(*bid);
326 if (b2 == NULL) {
327 BBPunfix(b->batCacheid);
328 if (s)
329 BBPunfix(s->batCacheid);
330 throw(MAL, malfunc, SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
331 }
332 }
333 if (b2) {
334 if (tp3 == TYPE_any)
335 tp3 = (*typefunc)(b->ttype, b2->ttype);
336 bn = (*batfunc)(b, b2, s, tp3, abort_on_error);
337 BBPunfix(b2->batCacheid);
338 } else {
339 if (tp3 == TYPE_any)
340 tp3 = (*typefunc)(b->ttype, tp2);
341 bn = (*batfunc1)(b, &stk->stk[getArg(pci, 2)], s,
342 tp3, abort_on_error);
343 }
344 } else {
345 assert(tp1 != TYPE_bat && !isaBatType(tp1));
346 assert(tp2 == TYPE_bat || isaBatType(tp2));
347 bid = getArgReference_bat(stk, pci, 2);
348 b = BATdescriptor(*bid);
349 if (b == NULL) {
350 if (s)
351 BBPunfix(s->batCacheid);
352 throw(MAL, malfunc, SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
353 }
354 if (tp3 == TYPE_any)
355 tp3 = (*typefunc)(tp1, b->ttype);
356 bn = (*batfunc2)(&stk->stk[getArg(pci, 1)], b, s, tp3, abort_on_error);
357 }
358 BBPunfix(b->batCacheid);
359 if (bn == NULL) {
360 return mythrow(MAL, malfunc, OPERATION_FAILED);
361 }
362 bid = getArgReference_bat(stk, pci, 0);
363 BBPkeepref(*bid = bn->batCacheid);
364 return MAL_SUCCEED;
365}
366
367static str
368CMDbatBINARY1(MalStkPtr stk, InstrPtr pci,
369 BAT *(*batfunc)(BAT *, BAT *, BAT *, bool),
370 BAT *(*batfunc1)(BAT *, const ValRecord *, BAT *, bool),
371 BAT *(*batfunc2)(const ValRecord *, BAT *, BAT *, bool),
372 bool abort_on_error,
373 const char *malfunc)
374{
375 bat *bid;
376 BAT *bn, *b, *s = NULL;
377 int tp1, tp2, tp3;
378
379 assert(3 <= pci->argc && pci->argc <= 5);
380
381 tp1 = stk->stk[getArg(pci, 1)].vtype;
382 tp2 = stk->stk[getArg(pci, 2)].vtype;
383 if (pci->argc >= 4 && ((tp3 = stk->stk[getArg(pci, 3)].vtype) == TYPE_bat ||
384 isaBatType(tp3))) {
385 bat *sid = getArgReference_bat(stk, pci, 3);
386 if (*sid && (s = BATdescriptor(*sid)) == NULL)
387 throw(MAL, malfunc, SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
388 }
389 if (pci->argc >= 4 && stk->stk[getArg(pci, pci->argc - 1)].vtype == TYPE_bit)
390 abort_on_error = *getArgReference_bit(stk, pci, pci->argc - 1);
391
392 if (tp1 == TYPE_bat || isaBatType(tp1)) {
393 BAT *b2 = NULL;
394 bid = getArgReference_bat(stk, pci, 1);
395 b = BATdescriptor(*bid);
396 if (b == NULL) {
397 if (s)
398 BBPunfix(s->batCacheid);
399 throw(MAL, malfunc, SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
400 }
401 if (tp2 == TYPE_bat || isaBatType(tp2)) {
402 bid = getArgReference_bat(stk, pci, 2);
403 b2 = BATdescriptor(*bid);
404 if (b2 == NULL) {
405 BBPunfix(b->batCacheid);
406 if (s)
407 BBPunfix(s->batCacheid);
408 throw(MAL, malfunc, SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
409 }
410 }
411 if (b2) {
412 bn = (*batfunc)(b, b2, s, abort_on_error);
413 BBPunfix(b2->batCacheid);
414 } else {
415 bn = (*batfunc1)(b, &stk->stk[getArg(pci, 2)], s, abort_on_error);
416 }
417 } else {
418 assert(tp1 != TYPE_bat && !isaBatType(tp1));
419 assert(tp2 == TYPE_bat || isaBatType(tp2));
420 bid = getArgReference_bat(stk, pci, 2);
421 b = BATdescriptor(*bid);
422 if (b == NULL) {
423 if (s)
424 BBPunfix(s->batCacheid);
425 throw(MAL, malfunc, SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
426 }
427 bn = (*batfunc2)(&stk->stk[getArg(pci, 1)], b, s, abort_on_error);
428 }
429 BBPunfix(b->batCacheid);
430 if (s)
431 BBPunfix(s->batCacheid);
432 if (bn == NULL) {
433 return mythrow(MAL, malfunc, OPERATION_FAILED);
434 }
435 bid = getArgReference_bat(stk, pci, 0);
436 BBPkeepref(*bid = bn->batCacheid);
437 return MAL_SUCCEED;
438}
439
440static str
441CMDbatBINARY0(MalStkPtr stk, InstrPtr pci,
442 BAT *(*batfunc)(BAT *, BAT *, BAT *),
443 BAT *(*batfunc1)(BAT *, const ValRecord *, BAT *),
444 BAT *(*batfunc2)(const ValRecord *, BAT *, BAT *),
445 const char *malfunc)
446{
447 bat *bid;
448 BAT *bn, *b, *s = NULL;
449 int tp1, tp2;
450
451 tp1 = stk->stk[getArg(pci, 1)].vtype;
452 tp2 = stk->stk[getArg(pci, 2)].vtype;
453 if (pci->argc == 4) {
454 bat *sid = getArgReference_bat(stk, pci, 3);
455 if (*sid && (s = BATdescriptor(*sid)) == NULL)
456 throw(MAL, malfunc, SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
457 }
458
459 if (tp1 == TYPE_bat || isaBatType(tp1)) {
460 BAT *b2 = NULL;
461 bid = getArgReference_bat(stk, pci, 1);
462 b = BATdescriptor(*bid);
463 if (b == NULL) {
464 if (s)
465 BBPunfix(s->batCacheid);
466 throw(MAL, malfunc, SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
467 }
468 if (tp2 == TYPE_bat || isaBatType(tp2)) {
469 bid = getArgReference_bat(stk, pci, 2);
470 b2 = BATdescriptor(*bid);
471 if (b2 == NULL) {
472 BBPunfix(b->batCacheid);
473 if (s)
474 BBPunfix(s->batCacheid);
475 throw(MAL, malfunc, SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
476 }
477 }
478 if (b2) {
479 bn = (*batfunc)(b, b2, s);
480 BBPunfix(b2->batCacheid);
481 } else if (batfunc1 == NULL) {
482 BBPunfix(b->batCacheid);
483 if (s)
484 BBPunfix(s->batCacheid);
485 throw(MAL, malfunc, SQLSTATE(0A000) PROGRAM_NYI);
486 } else {
487 bn = (*batfunc1)(b, &stk->stk[getArg(pci, 2)], s);
488 }
489 } else if (batfunc2 == NULL) {
490 throw(MAL, malfunc, SQLSTATE(0A000) PROGRAM_NYI);
491 } else {
492 assert(tp1 != TYPE_bat && !isaBatType(tp1));
493 assert(tp2 == TYPE_bat || isaBatType(tp2));
494 bid = getArgReference_bat(stk, pci, 2);
495 b = BATdescriptor(*bid);
496 if (b == NULL) {
497 if (s)
498 BBPunfix(s->batCacheid);
499 throw(MAL, malfunc, SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
500 }
501 bn = (*batfunc2)(&stk->stk[getArg(pci, 1)], b, s);
502 }
503 BBPunfix(b->batCacheid);
504 if (s)
505 BBPunfix(s->batCacheid);
506 if (bn == NULL) {
507 return mythrow(MAL, malfunc, OPERATION_FAILED);
508 }
509 bid = getArgReference_bat(stk, pci, 0);
510 BBPkeepref(*bid = bn->batCacheid);
511 return MAL_SUCCEED;
512}
513
514mal_export str CMDbatMIN(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
515
516str
517CMDbatMIN(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
518{
519 (void) cntxt;
520 (void) mb;
521
522 return CMDbatBINARY0(stk, pci, BATcalcmin, BATcalcmincst, BATcalccstmin, "batcalc.min");
523}
524
525mal_export str CMDbatMIN_no_nil(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
526
527str
528CMDbatMIN_no_nil(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
529{
530 (void) cntxt;
531 (void) mb;
532
533 return CMDbatBINARY0(stk, pci, BATcalcmin_no_nil, BATcalcmincst_no_nil, BATcalccstmin_no_nil, "batcalc.min_no_nil");
534}
535
536mal_export str CMDbatMAX(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
537
538str
539CMDbatMAX(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
540{
541 (void) cntxt;
542 (void) mb;
543
544 return CMDbatBINARY0(stk, pci, BATcalcmax, BATcalcmaxcst, BATcalccstmax, "batcalc.max");
545}
546
547mal_export str CMDbatMAX_no_nil(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
548
549str
550CMDbatMAX_no_nil(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
551{
552 (void) cntxt;
553 (void) mb;
554
555 return CMDbatBINARY0(stk, pci, BATcalcmax_no_nil, BATcalcmaxcst_no_nil, BATcalccstmax_no_nil, "batcalc.max_no_nil");
556}
557
558mal_export str CMDbatADD(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
559
560str
561CMDbatADD(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
562{
563 (void) cntxt;
564
565 return CMDbatBINARY2(mb, stk, pci, BATcalcadd, BATcalcaddcst, BATcalccstadd,
566 calctype, 0, "batcalc.add_noerror");
567}
568
569mal_export str CMDbatADDsignal(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
570
571str
572CMDbatADDsignal(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
573{
574 (void) cntxt;
575
576 return CMDbatBINARY2(mb, stk, pci, BATcalcadd, BATcalcaddcst, BATcalccstadd,
577 calctype, 1, "batcalc.+");
578}
579
580mal_export str CMDbatADDenlarge(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
581
582str
583CMDbatADDenlarge(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
584{
585 (void) cntxt;
586
587 return CMDbatBINARY2(mb, stk, pci, BATcalcadd, BATcalcaddcst, BATcalccstadd,
588 calctypeenlarge, 1, "batcalc.add_enlarge");
589}
590
591mal_export str CMDbatSUB(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
592
593str
594CMDbatSUB(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
595{
596 (void) cntxt;
597
598 return CMDbatBINARY2(mb, stk, pci, BATcalcsub, BATcalcsubcst, BATcalccstsub,
599 calctype, 0, "batcalc.sub_noerror");
600}
601
602mal_export str CMDbatSUBsignal(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
603
604str
605CMDbatSUBsignal(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
606{
607 (void) cntxt;
608
609 return CMDbatBINARY2(mb, stk, pci, BATcalcsub, BATcalcsubcst, BATcalccstsub,
610 calctype, 1, "batcalc.-");
611}
612
613mal_export str CMDbatSUBenlarge(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
614
615str
616CMDbatSUBenlarge(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
617{
618 (void) cntxt;
619
620 return CMDbatBINARY2(mb, stk, pci, BATcalcsub, BATcalcsubcst, BATcalccstsub,
621 calctypeenlarge, 1, "batcalc.sub_enlarge");
622}
623
624mal_export str CMDbatMUL(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
625
626str
627CMDbatMUL(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
628{
629 (void) cntxt;
630
631 return CMDbatBINARY2(mb, stk, pci, BATcalcmul, BATcalcmulcst, BATcalccstmul,
632 calctype, 0, "batcalc.mul_noerror");
633}
634
635mal_export str CMDbatMULsignal(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
636
637str
638CMDbatMULsignal(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
639{
640 (void) cntxt;
641
642 return CMDbatBINARY2(mb, stk, pci, BATcalcmul, BATcalcmulcst, BATcalccstmul,
643 calctype, 1, "batcalc.*");
644}
645
646mal_export str CMDbatMULenlarge(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
647
648str
649CMDbatMULenlarge(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
650{
651 (void) cntxt;
652
653 return CMDbatBINARY2(mb, stk, pci, BATcalcmul, BATcalcmulcst, BATcalccstmul,
654 calctypeenlarge, 1, "batcalc.mul_enlarge");
655}
656
657mal_export str CMDbatDIV(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
658
659str
660CMDbatDIV(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
661{
662 (void) cntxt;
663
664 return CMDbatBINARY2(mb, stk, pci, BATcalcdiv, BATcalcdivcst, BATcalccstdiv,
665 calcdivtype, 0, "batcalc.div_noerror");
666}
667
668mal_export str CMDbatDIVsignal(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
669
670str
671CMDbatDIVsignal(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
672{
673 (void) cntxt;
674
675 return CMDbatBINARY2(mb, stk, pci, BATcalcdiv, BATcalcdivcst, BATcalccstdiv,
676 calcdivtype, 1, "batcalc./");
677}
678
679mal_export str CMDbatMOD(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
680
681str
682CMDbatMOD(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
683{
684 (void) cntxt;
685
686 return CMDbatBINARY2(mb, stk, pci, BATcalcmod, BATcalcmodcst, BATcalccstmod,
687 calcmodtype, 0, "batcalc.mod_noerror");
688}
689
690mal_export str CMDbatMODsignal(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
691
692str
693CMDbatMODsignal(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
694{
695 (void) cntxt;
696
697 return CMDbatBINARY2(mb, stk, pci, BATcalcmod, BATcalcmodcst, BATcalccstmod,
698 calcmodtype, 1, "batcalc.%");
699}
700
701mal_export str CMDbatXOR(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
702
703str
704CMDbatXOR(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
705{
706 (void) cntxt;
707 (void) mb;
708
709 return CMDbatBINARY0(stk, pci, BATcalcxor, BATcalcxorcst, BATcalccstxor,
710 "batcalc.xor");
711}
712
713mal_export str CMDbatOR(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
714
715str
716CMDbatOR(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
717{
718 (void) cntxt;
719 (void) mb;
720
721 return CMDbatBINARY0(stk, pci, BATcalcor, BATcalcorcst, BATcalccstor,
722 "batcalc.or");
723}
724
725mal_export str CMDbatAND(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
726
727str
728CMDbatAND(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
729{
730 (void) cntxt;
731 (void) mb;
732
733 return CMDbatBINARY0(stk, pci, BATcalcand, BATcalcandcst, BATcalccstand,
734 "batcalc.and");
735}
736
737mal_export str CMDbatLSH(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
738
739str
740CMDbatLSH(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
741{
742 (void) cntxt;
743 (void) mb;
744
745 return CMDbatBINARY1(stk, pci, BATcalclsh, BATcalclshcst, BATcalccstlsh,
746 false, "batcalc.lsh_noerror");
747}
748
749mal_export str CMDbatLSHsignal(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
750
751str
752CMDbatLSHsignal(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
753{
754 (void) cntxt;
755 (void) mb;
756
757 return CMDbatBINARY1(stk, pci, BATcalclsh, BATcalclshcst, BATcalccstlsh,
758 true, "batcalc.<<");
759}
760
761mal_export str CMDbatRSH(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
762
763str
764CMDbatRSH(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
765{
766 (void) cntxt;
767 (void) mb;
768
769 return CMDbatBINARY1(stk, pci, BATcalcrsh, BATcalcrshcst, BATcalccstrsh,
770 false, "batcalc.rsh_noerror");
771}
772
773mal_export str CMDbatRSHsignal(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
774
775str
776CMDbatRSHsignal(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
777{
778 (void) cntxt;
779 (void) mb;
780
781 return CMDbatBINARY1(stk, pci, BATcalcrsh, BATcalcrshcst, BATcalccstrsh,
782 true, "batcalc.>>");
783}
784
785mal_export str CMDbatLT(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
786
787str
788CMDbatLT(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
789{
790 (void) cntxt;
791 (void) mb;
792
793 return CMDbatBINARY0(stk, pci, BATcalclt, BATcalcltcst, BATcalccstlt,
794 "batcalc.<");
795}
796
797mal_export str CMDbatLE(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
798
799str
800CMDbatLE(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
801{
802 (void) cntxt;
803 (void) mb;
804
805 return CMDbatBINARY0(stk, pci, BATcalcle, BATcalclecst, BATcalccstle,
806 "batcalc.<=");
807}
808
809mal_export str CMDbatGT(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
810
811str
812CMDbatGT(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
813{
814 (void) cntxt;
815 (void) mb;
816
817 return CMDbatBINARY0(stk, pci, BATcalcgt, BATcalcgtcst, BATcalccstgt,
818 "batcalc.>");
819}
820
821mal_export str CMDbatGE(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
822
823str
824CMDbatGE(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
825{
826 (void) cntxt;
827 (void) mb;
828
829 return CMDbatBINARY0(stk, pci, BATcalcge, BATcalcgecst, BATcalccstge,
830 "batcalc.>=");
831}
832
833mal_export str CMDbatEQ(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
834
835str
836CMDbatEQ(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
837{
838 (void) cntxt;
839 (void) mb;
840
841 return CMDbatBINARY1(stk, pci, BATcalceq, BATcalceqcst, BATcalccsteq,
842 false, "batcalc.==");
843}
844
845mal_export str CMDbatNE(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
846
847str
848CMDbatNE(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
849{
850 (void) cntxt;
851 (void) mb;
852
853 return CMDbatBINARY1(stk, pci, BATcalcne, BATcalcnecst, BATcalccstne,
854 false, "batcalc.!=");
855}
856
857mal_export str CMDbatCMP(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
858
859str
860CMDbatCMP(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
861{
862 (void) cntxt;
863 (void) mb;
864
865 return CMDbatBINARY0(stk, pci, BATcalccmp, BATcalccmpcst, BATcalccstcmp,
866 "batcalc.cmp");
867}
868
869mal_export str CMDbatBETWEEN(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
870
871str
872CMDbatBETWEEN(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
873{
874 bat *bid;
875 BAT *bn, *b, *lo = NULL, *hi = NULL, *s = NULL;
876 int tp1, tp2, tp3;
877 int bc = 3; /* number of BAT arguments */
878 bool symmetric, linc, hinc, nils_false, anti;
879
880 (void) cntxt;
881 (void) mb;
882
883 tp1 = stk->stk[getArg(pci, 1)].vtype;
884 tp2 = stk->stk[getArg(pci, 2)].vtype;
885 tp3 = stk->stk[getArg(pci, 3)].vtype;
886 if (pci->argc > bc + 1 && isaBatType(getArgType(mb, pci, 4))) {
887 bat *sid = getArgReference_bat(stk, pci, 4);
888 if (*sid && (s = BATdescriptor(*sid)) == NULL)
889 throw(MAL, "batcalc.between", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
890 bc++;
891 }
892 symmetric = *getArgReference_bit(stk, pci, bc + 1);
893 linc = *getArgReference_bit(stk, pci, bc + 2);
894 hinc = *getArgReference_bit(stk, pci, bc + 3);
895 nils_false = *getArgReference_bit(stk, pci, bc + 4);
896 anti = *getArgReference_bit(stk, pci, bc + 5);
897
898 if (tp1 != TYPE_bat && !isaBatType(tp1)) {
899 if (s)
900 BBPunfix(s->batCacheid);
901 throw(MAL, "batcalc.between", ILLEGAL_ARGUMENT);
902 }
903 bid = getArgReference_bat(stk, pci, 1);
904 b = BATdescriptor(*bid);
905 if (b == NULL) {
906 if (s)
907 BBPunfix(s->batCacheid);
908 throw(MAL, "batcalc.between", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
909 }
910
911 if (tp2 == TYPE_bat || isaBatType(tp2)) {
912 bid = getArgReference_bat(stk, pci, 2);
913 lo = BATdescriptor(*bid);
914 if (lo == NULL) {
915 BBPunfix(b->batCacheid);
916 if (s)
917 BBPunfix(s->batCacheid);
918 throw(MAL, "batcalc.between", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
919 }
920 }
921 if (tp3 == TYPE_bat || isaBatType(tp3)) {
922 bid = getArgReference_bat(stk, pci, 3);
923 hi = BATdescriptor(*bid);
924 if (hi == NULL) {
925 BBPunfix(b->batCacheid);
926 if (lo)
927 BBPunfix(lo->batCacheid);
928 if (s)
929 BBPunfix(s->batCacheid);
930 throw(MAL, "batcalc.between", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
931 }
932 }
933 if (lo == NULL) {
934 if (hi == NULL) {
935 bn = BATcalcbetweencstcst(b, &stk->stk[getArg(pci, 2)],
936 &stk->stk[getArg(pci, 3)], s,
937 symmetric, linc, hinc, nils_false, anti);
938 } else {
939 bn = BATcalcbetweencstbat(b, &stk->stk[getArg(pci, 2)], hi, s,
940 symmetric, linc, hinc, nils_false, anti);
941 }
942 } else {
943 if (hi == NULL) {
944 bn = BATcalcbetweenbatcst(b, lo, &stk->stk[getArg(pci, 3)], s,
945 symmetric, linc, hinc, nils_false, anti);
946 } else {
947 bn = BATcalcbetween(b, lo, hi, s,
948 symmetric, linc, hinc, nils_false, anti);
949 }
950 }
951 BBPunfix(b->batCacheid);
952 if (lo)
953 BBPunfix(lo->batCacheid);
954 if (hi)
955 BBPunfix(hi->batCacheid);
956 if (s)
957 BBPunfix(s->batCacheid);
958 if (bn == NULL) {
959 return mythrow(MAL, "batcalc.between", OPERATION_FAILED);
960 }
961 bid = getArgReference_bat(stk, pci, 0);
962 BBPkeepref(*bid = bn->batCacheid);
963 return MAL_SUCCEED;
964}
965
966mal_export str CMDcalcavg(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
967
968str
969CMDcalcavg(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
970{
971 dbl avg;
972 BUN vals;
973 bat *bid;
974 BAT *b, *s = NULL;
975 gdk_return ret;
976 int scale = 0;
977
978 (void) cntxt;
979 (void) mb;
980
981 bid = getArgReference_bat(stk, pci, pci->retc + 0);
982 if ((b = BATdescriptor(*bid)) == NULL)
983 throw(MAL, "aggr.avg", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
984 if ((pci->argc == pci->retc + 2 &&
985 stk->stk[pci->argv[pci->retc + 1]].vtype == TYPE_bat) ||
986 pci->argc == pci->retc + 3) {
987 bat *sid = getArgReference_bat(stk, pci, pci->retc + 1);
988 if (*sid && (s = BATdescriptor(*sid)) == NULL) {
989 BBPunfix(b->batCacheid);
990 throw(MAL, "aggr.avg", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
991 }
992 }
993 if (pci->argc >= pci->retc + 2 &&
994 stk->stk[pci->argv[pci->argc - 1]].vtype == TYPE_int) {
995 scale = *getArgReference_int(stk, pci, pci->argc - 1);
996 }
997 ret = BATcalcavg(b, s, &avg, &vals, scale);
998 BBPunfix(b->batCacheid);
999 if (s)
1000 BBPunfix(s->batCacheid);
1001 if (ret != GDK_SUCCEED)
1002 return mythrow(MAL, "aggr.avg", OPERATION_FAILED);
1003 * getArgReference_dbl(stk, pci, 0) = avg;
1004 if (pci->retc == 2)
1005 * getArgReference_lng(stk, pci, 1) = vals;
1006 return MAL_SUCCEED;
1007}
1008
1009static str
1010CMDconvertbat(MalStkPtr stk, InstrPtr pci, int tp, bool abort_on_error)
1011{
1012 bat *bid;
1013 BAT *b, *bn, *s = NULL;
1014
1015 bid = getArgReference_bat(stk, pci, 1);
1016 if ((b = BATdescriptor(*bid)) == NULL)
1017 throw(MAL, "batcalc.convert", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1018 if (pci->argc == 3) {
1019 bat *sid = getArgReference_bat(stk, pci, 2);
1020 if (*sid && (s = BATdescriptor(*sid)) == NULL) {
1021 BBPunfix(b->batCacheid);
1022 throw(MAL, "batcalc.convert", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1023 }
1024 }
1025
1026 bn = BATconvert(b, s, tp, abort_on_error);
1027 BBPunfix(b->batCacheid);
1028 if (s)
1029 BBPunfix(s->batCacheid);
1030 if (bn == NULL) {
1031 char buf[20];
1032 snprintf(buf, sizeof(buf), "batcalc.%s", ATOMname(tp));
1033 return mythrow(MAL, buf, OPERATION_FAILED);
1034 }
1035 bid = getArgReference_bat(stk, pci, 0);
1036 BBPkeepref(*bid = bn->batCacheid);
1037 return MAL_SUCCEED;
1038}
1039
1040mal_export str CMDconvert_bit(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
1041mal_export str CMDconvertsignal_bit(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
1042
1043str
1044CMDconvert_bit(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1045{
1046 (void) cntxt;
1047 (void) mb;
1048
1049 return CMDconvertbat(stk, pci, TYPE_bit, 0);
1050}
1051
1052str
1053CMDconvertsignal_bit(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1054{
1055 (void) cntxt;
1056 (void) mb;
1057
1058 return CMDconvertbat(stk, pci, TYPE_bit, 1);
1059}
1060
1061mal_export str CMDconvert_bte(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
1062mal_export str CMDconvertsignal_bte(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
1063
1064str
1065CMDconvert_bte(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1066{
1067 (void) cntxt;
1068 (void) mb;
1069
1070 return CMDconvertbat(stk, pci, TYPE_bte, 0);
1071}
1072
1073str
1074CMDconvertsignal_bte(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1075{
1076 (void) cntxt;
1077 (void) mb;
1078
1079 return CMDconvertbat(stk, pci, TYPE_bte, 1);
1080}
1081
1082mal_export str CMDconvert_sht(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
1083mal_export str CMDconvertsignal_sht(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
1084
1085str
1086CMDconvert_sht(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1087{
1088 (void) cntxt;
1089 (void) mb;
1090
1091 return CMDconvertbat(stk, pci, TYPE_sht, 0);
1092}
1093
1094str
1095CMDconvertsignal_sht(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1096{
1097 (void) cntxt;
1098 (void) mb;
1099
1100 return CMDconvertbat(stk, pci, TYPE_sht, 1);
1101}
1102
1103mal_export str CMDconvert_int(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
1104mal_export str CMDconvertsignal_int(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
1105
1106str
1107CMDconvert_int(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1108{
1109 (void) cntxt;
1110 (void) mb;
1111
1112 return CMDconvertbat(stk, pci, TYPE_int, 0);
1113}
1114
1115str
1116CMDconvertsignal_int(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1117{
1118 (void) cntxt;
1119 (void) mb;
1120
1121 return CMDconvertbat(stk, pci, TYPE_int, 1);
1122}
1123
1124mal_export str CMDconvert_lng(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
1125mal_export str CMDconvertsignal_lng(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
1126
1127str
1128CMDconvert_lng(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1129{
1130 (void) cntxt;
1131 (void) mb;
1132
1133 return CMDconvertbat(stk, pci, TYPE_lng, 0);
1134}
1135
1136str
1137CMDconvertsignal_lng(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1138{
1139 (void) cntxt;
1140 (void) mb;
1141
1142 return CMDconvertbat(stk, pci, TYPE_lng, 1);
1143}
1144
1145#ifdef HAVE_HGE
1146mal_export str CMDconvert_hge(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
1147mal_export str CMDconvertsignal_hge(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
1148
1149str
1150CMDconvert_hge(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1151{
1152 (void) cntxt;
1153 (void) mb;
1154
1155 return CMDconvertbat(stk, pci, TYPE_hge, 0);
1156}
1157
1158str
1159CMDconvertsignal_hge(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1160{
1161 (void) cntxt;
1162 (void) mb;
1163
1164 return CMDconvertbat(stk, pci, TYPE_hge, 1);
1165}
1166#endif
1167
1168mal_export str CMDconvert_flt(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
1169mal_export str CMDconvertsignal_flt(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
1170
1171str
1172CMDconvert_flt(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1173{
1174 (void) cntxt;
1175 (void) mb;
1176
1177 return CMDconvertbat(stk, pci, TYPE_flt, 0);
1178}
1179
1180str
1181CMDconvertsignal_flt(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1182{
1183 (void) cntxt;
1184 (void) mb;
1185
1186 return CMDconvertbat(stk, pci, TYPE_flt, 1);
1187}
1188
1189mal_export str CMDconvert_dbl(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
1190mal_export str CMDconvertsignal_dbl(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
1191
1192str
1193CMDconvert_dbl(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1194{
1195 (void) cntxt;
1196 (void) mb;
1197
1198 return CMDconvertbat(stk, pci, TYPE_dbl, 0);
1199}
1200
1201str
1202CMDconvertsignal_dbl(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1203{
1204 (void) cntxt;
1205 (void) mb;
1206
1207 return CMDconvertbat(stk, pci, TYPE_dbl, 1);
1208}
1209
1210mal_export str CMDconvert_oid(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
1211mal_export str CMDconvertsignal_oid(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
1212
1213str
1214CMDconvert_oid(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1215{
1216 (void) cntxt;
1217 (void) mb;
1218
1219 return CMDconvertbat(stk, pci, TYPE_oid, 0);
1220}
1221
1222str
1223CMDconvertsignal_oid(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1224{
1225 (void) cntxt;
1226 (void) mb;
1227
1228 return CMDconvertbat(stk, pci, TYPE_oid, 1);
1229}
1230
1231mal_export str CMDconvert_str(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
1232mal_export str CMDconvertsignal_str(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
1233
1234str
1235CMDconvert_str(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1236{
1237 (void) cntxt;
1238 (void) mb;
1239
1240 return CMDconvertbat(stk, pci, TYPE_str, 0);
1241}
1242
1243str
1244CMDconvertsignal_str(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1245{
1246 (void) cntxt;
1247 (void) mb;
1248
1249 return CMDconvertbat(stk, pci, TYPE_str, 1);
1250}
1251
1252mal_export str CMDifthen(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci);
1253
1254str
1255CMDifthen(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1256{
1257 BAT *b = NULL, *b1 = NULL, *b2 = NULL, *bn;
1258 int tp0, tp1, tp2;
1259 bat *ret;
1260 BUN cnt = BUN_NONE;
1261
1262 (void) cntxt;
1263 (void) mb;
1264
1265 if (pci->argc != 4)
1266 throw(MAL, "batcalc.ifthen", "Operation not supported.");
1267
1268 ret = getArgReference_bat(stk, pci, 0);
1269 tp0 = stk->stk[getArg(pci, 1)].vtype;
1270 tp1 = stk->stk[getArg(pci, 2)].vtype;
1271 tp2 = stk->stk[getArg(pci, 3)].vtype;
1272 if (tp0 == TYPE_bat || isaBatType(tp0)) {
1273 b = BATdescriptor(* getArgReference_bat(stk, pci, 1));
1274 if (b == NULL)
1275 throw(MAL, "batcalc.ifthenelse", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1276 cnt = BATcount(b);
1277 }
1278 if (tp1 == TYPE_bat || isaBatType(tp1)) {
1279 b1 = BATdescriptor(* getArgReference_bat(stk, pci, 2));
1280 if (b1 == NULL) {
1281 if (b)
1282 BBPunfix(b->batCacheid);
1283 throw(MAL, "batcalc.ifthenelse", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1284 }
1285 if (cnt == BUN_NONE)
1286 cnt = BATcount(b1);
1287 else if (BATcount(b1) != cnt) {
1288 BBPunfix(b->batCacheid);
1289 throw(MAL, "batcalc.ifthenelse", ILLEGAL_ARGUMENT);
1290 }
1291 }
1292 if (tp2 == TYPE_bat || isaBatType(tp2)) {
1293 b2 = BATdescriptor(* getArgReference_bat(stk, pci, 3));
1294 if (b2 == NULL) {
1295 if (b)
1296 BBPunfix(b->batCacheid);
1297 if (b1)
1298 BBPunfix(b1->batCacheid);
1299 throw(MAL, "batcalc.ifthenelse", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1300 }
1301 if (cnt == BUN_NONE)
1302 cnt = BATcount(b2);
1303 else if (BATcount(b2) != cnt) {
1304 if (b)
1305 BBPunfix(b->batCacheid);
1306 if (b1)
1307 BBPunfix(b1->batCacheid);
1308 throw(MAL, "batcalc.ifthenelse", ILLEGAL_ARGUMENT);
1309 }
1310 }
1311 if (b == NULL && b1 == NULL && b2 == NULL) {
1312 /* at least one BAT required */
1313 throw(MAL, "batcalc.ifthenelse", ILLEGAL_ARGUMENT);
1314 }
1315 if (b != NULL) {
1316 if (b1 != NULL) {
1317 if (b2 != NULL) {
1318 bn = BATcalcifthenelse(b, b1, b2);
1319 } else {
1320 bn = BATcalcifthenelsecst(b, b1, &stk->stk[getArg(pci, 3)]);
1321 }
1322 } else {
1323 if (b2 != NULL) {
1324 bn = BATcalcifthencstelse(b, &stk->stk[getArg(pci, 2)], b2);
1325 } else {
1326 bn = BATcalcifthencstelsecst(b, &stk->stk[getArg(pci, 2)], &stk->stk[getArg(pci, 3)]);
1327 }
1328 }
1329 } else {
1330 bit v = *getArgReference_bit(stk, pci, 1);
1331 if (is_bit_nil(v)) {
1332 if (b1 != NULL)
1333 bn = BATconstant(b1->hseqbase, b1->ttype, ATOMnilptr(b1->ttype), BATcount(b1), TRANSIENT);
1334 else
1335 bn = BATconstant(b2->hseqbase, b2->ttype, ATOMnilptr(b2->ttype), BATcount(b2), TRANSIENT);
1336 } else if (v) {
1337 if (b1 != NULL)
1338 bn = COLcopy(b1, b1->ttype, false, TRANSIENT);
1339 else
1340 bn = BATconstant(b2->hseqbase, b2->ttype, VALptr(&stk->stk[getArg(pci, 2)]), BATcount(b2), TRANSIENT);
1341 } else {
1342 if (b2 != NULL)
1343 bn = COLcopy(b2, b2->ttype, false, TRANSIENT);
1344 else
1345 bn = BATconstant(b1->hseqbase, b1->ttype, VALptr(&stk->stk[getArg(pci, 3)]), BATcount(b1), TRANSIENT);
1346 }
1347 }
1348 if (b)
1349 BBPunfix(b->batCacheid);
1350 if (b1)
1351 BBPunfix(b1->batCacheid);
1352 if (b2)
1353 BBPunfix(b2->batCacheid);
1354 if (bn == NULL) {
1355 return mythrow(MAL, "batcalc.ifthenelse", OPERATION_FAILED);
1356 }
1357 BBPkeepref(*ret = bn->batCacheid);
1358 return MAL_SUCCEED;
1359}
1360