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) Martin Kersten, Sjoerd Mullender
15 : * Series generating module for integer, decimal, real, double, date and timestamps.
16 : */
17 :
18 : #include "monetdb_config.h"
19 : #include "generator.h"
20 : #include "gdk_time.h"
21 :
22 :
23 : #define IDENTITY(x) (x)
24 :
25 : /*
26 : * The noop simply means that we keep the properties for the generator object.
27 : */
28 : #define VLTnoop(TPE) \
29 : do { \
30 : TPE s; \
31 : s = pci->argc == 3 ? 1: *getArgReference_##TPE(stk,pci, 3); \
32 : zeroerror = (s == 0); \
33 : nullerr = is_##TPE##_nil(s); \
34 : } while (0)
35 :
36 : str
37 487 : VLTgenerator_noop(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
38 : {
39 487 : int nullerr= 0, zeroerror=0, tpe;
40 487 : (void) cntxt;
41 :
42 487 : switch( tpe = getArgType(mb,pci,1)){
43 343 : case TYPE_bte: VLTnoop(bte); break;
44 32 : case TYPE_sht: VLTnoop(sht); break;
45 37 : case TYPE_int: VLTnoop(int); break;
46 17 : case TYPE_lng: VLTnoop(lng); break;
47 : #ifdef HAVE_HGE
48 9 : case TYPE_hge: VLTnoop(hge); break;
49 : #endif
50 6 : case TYPE_flt: VLTnoop(flt); break;
51 10 : case TYPE_dbl: VLTnoop(dbl); break;
52 33 : default:
53 33 : if (tpe == TYPE_date) {
54 : /* with date, step is of SQL type "interval month or day",
55 : * i.e., MAL / C type "int" or "lng" */
56 4 : int steptpe = pci->argc==4 ? getArgType(mb,pci,3) : 0;
57 4 : if (steptpe == TYPE_int)
58 2 : VLTnoop(int);
59 : else /* default interval days */
60 2 : VLTnoop(lng);
61 29 : } else if (tpe == TYPE_timestamp) {
62 : /* with timestamp, step is of SQL type "interval seconds",
63 : * i.e., MAL / C type "lng" */
64 29 : VLTnoop(lng);
65 : } else {
66 0 : throw(MAL,"generator.noop", SQLSTATE(42000) "unknown data type %d", getArgType(mb,pci,1));
67 : }
68 : }
69 487 : if( zeroerror)
70 2 : throw(MAL,"generator.noop", SQLSTATE(42000) "Zero step size not allowed");
71 485 : if( nullerr)
72 2 : throw(MAL,"generator.noop", SQLSTATE(42000) "Null step size not allowed");
73 : return MAL_SUCCEED;
74 : }
75 :
76 : #define check_bte() ((void)0)
77 : #define check_sht() ((void)0)
78 : #if SIZEOF_BUN < SIZEOF_LNG
79 : #define check_int() \
80 : do { \
81 : if (cnt > (unsigned int) BUN_MAX) \
82 : throw(MAL, "generator.table", \
83 : SQLSTATE(42000) "Illegal generator range"); \
84 : } while (0)
85 : #else
86 : #define check_int() ((void)0)
87 : #endif
88 : #define check_lng() \
89 : do { \
90 : if (cnt > (ulng) BUN_MAX) \
91 : throw(MAL, "generator.table", \
92 : SQLSTATE(42000) "Illegal generator range"); \
93 : } while (0)
94 : #ifdef HAVE_HGE
95 : #define check_hge() \
96 : do { \
97 : if (cnt > (uhge) BUN_MAX) \
98 : throw(MAL, "generator.table", \
99 : SQLSTATE(42000) "Illegal generator range"); \
100 : } while (0)
101 : #endif
102 :
103 : #define VLTmaterialize(TPE, uTPE) \
104 : do { \
105 : TPE f, l, s; \
106 : uTPE cnt; \
107 : \
108 : f = *getArgReference_##TPE(stk, pci, 1); \
109 : l = *getArgReference_##TPE(stk, pci, 2); \
110 : if ( pci->argc == 3) \
111 : s = f <= l ? (TPE) 1 : (TPE) -1; \
112 : else \
113 : s = *getArgReference_##TPE(stk,pci, 3); \
114 : if (s == 0 || is_##TPE##_nil(f) || is_##TPE##_nil(l) || is_##TPE##_nil(s)) \
115 : throw(MAL, "generator.table", \
116 : SQLSTATE(42000) "Illegal generator range"); \
117 : if (f == l) { \
118 : cnt = 0; \
119 : } else if (f < l) { \
120 : /* cnt = l - f */ \
121 : if (s <= 0) \
122 : throw(MAL, "generator.table", \
123 : SQLSTATE(42000) "Illegal generator range"); \
124 : if (f >= 0 || l <= 0) { \
125 : /* no chance of any kind of overflow */ \
126 : cnt = l - f; \
127 : } else { \
128 : /* f < 0 && l > 0, do calculation is unsigned type */ \
129 : cnt = (uTPE) l + (uTPE) -f; \
130 : } \
131 : uTPE i = cnt / (uTPE) s; \
132 : if (i * (uTPE) s != cnt) \
133 : i++; \
134 : cnt = i; \
135 : } else { \
136 : /* l < f; cnt = f - l */ \
137 : if (s >= 0) \
138 : throw(MAL, "generator.table", \
139 : SQLSTATE(42000) "Illegal generator range"); \
140 : if (l >= 0 || f <= 0) { \
141 : /* no chance of any kind of overflow */ \
142 : cnt = f - l; \
143 : } else { \
144 : /* f > 0 && l < 0, do calculation is unsigned type */ \
145 : cnt = (uTPE) f + (uTPE) -l; \
146 : } \
147 : uTPE i = cnt / (uTPE) -s; \
148 : if (i * (uTPE) -s != cnt) \
149 : i++; \
150 : cnt = i; \
151 : } \
152 : check_##TPE(); \
153 : n = (BUN) cnt; \
154 : bn = COLnew(0, TYPE_##TPE, n, TRANSIENT); \
155 : if (bn == NULL) \
156 : throw(MAL, "generator.table", SQLSTATE(HY013) MAL_MALLOC_FAIL); \
157 : TPE *v = (TPE *) Tloc(bn, 0); \
158 : while (cnt > 0) { \
159 : *v++ = f; \
160 : f += s; \
161 : cnt--; \
162 : } \
163 : bn->tsorted = s > 0 || n <= 1; \
164 : bn->trevsorted = s < 0 || n <= 1; \
165 : } while (0)
166 :
167 : #define VLTmaterialize_flt(TPE) \
168 : do { \
169 : TPE *v, f, l, s; \
170 : f = *getArgReference_##TPE(stk, pci, 1); \
171 : l = *getArgReference_##TPE(stk, pci, 2); \
172 : if ( pci->argc == 3) \
173 : s = f<l? (TPE) 1: (TPE)-1; \
174 : else s = *getArgReference_##TPE(stk,pci, 3); \
175 : if (s == 0 || (s > 0 && f > l) || (s < 0 && f < l) || is_##TPE##_nil(f) || is_##TPE##_nil(l)) \
176 : throw(MAL, "generator.table", \
177 : SQLSTATE(42000) "Illegal generator range"); \
178 : n = (BUN) ((l - f) / s); \
179 : if ((TPE) (n * s + f) != l) \
180 : n++; \
181 : bn = COLnew(0, TYPE_##TPE, n, TRANSIENT); \
182 : if (bn == NULL) \
183 : throw(MAL, "generator.table", SQLSTATE(HY013) MAL_MALLOC_FAIL); \
184 : v = (TPE*) Tloc(bn, 0); \
185 : for (BUN c = 0; c < n; c++) \
186 : *v++ = (TPE) (f + c * s); \
187 : bn->tsorted = s > 0 || n <= 1; \
188 : bn->trevsorted = s < 0 || n <= 1; \
189 : } while (0)
190 :
191 : static str
192 455 : VLTgenerator_table_(BAT **result, Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
193 : {
194 455 : BAT *bn;
195 455 : int tpe;
196 455 : (void) cntxt;
197 455 : BUN n;
198 :
199 455 : *result = NULL;
200 455 : tpe = getArgType(mb, pci, 1);
201 455 : switch (tpe) {
202 328 : case TYPE_bte:
203 2825 : VLTmaterialize(bte, uint8_t);
204 313 : break;
205 32 : case TYPE_sht:
206 77668 : VLTmaterialize(sht, uint16_t);
207 29 : break;
208 36 : case TYPE_int:
209 118986496 : VLTmaterialize(int, unsigned);
210 33 : break;
211 15 : case TYPE_lng:
212 60 : VLTmaterialize(lng, ulng);
213 11 : break;
214 : #ifdef HAVE_HGE
215 9 : case TYPE_hge:
216 1384 : VLTmaterialize(hge, uhge);
217 9 : break;
218 : #endif
219 5 : case TYPE_flt:
220 28 : VLTmaterialize_flt(flt);
221 5 : break;
222 8 : case TYPE_dbl:
223 53 : VLTmaterialize_flt(dbl);
224 8 : break;
225 22 : default:
226 22 : if (tpe == TYPE_date && pci->argc == 3)
227 0 : throw(MAL,"generator.table", SQLSTATE(42000) "Date step missing");
228 2 : if (tpe == TYPE_date && getArgType(mb, pci, 3) == TYPE_int) { /* months */
229 1 : date *v,f,l;
230 1 : int s;
231 1 : ValRecord ret;
232 1 : if (VARcalccmp(&ret, &stk->stk[pci->argv[1]],
233 1 : &stk->stk[pci->argv[2]]) != GDK_SUCCEED)
234 0 : throw(MAL, "generator.table",
235 : SQLSTATE(42000) "Illegal generator expression range");
236 1 : f = *getArgReference_TYPE(stk, pci, 1, date);
237 1 : l = *getArgReference_TYPE(stk, pci, 2, date);
238 1 : s = *getArgReference_int(stk, pci, 3);
239 1 : if (s == 0 ||
240 1 : (s > 0 && ret.val.btval > 0) ||
241 0 : (s < 0 && ret.val.btval < 0) ||
242 1 : is_date_nil(f) || is_date_nil(l))
243 0 : throw(MAL, "generator.table",
244 : SQLSTATE(42000) "Illegal generator range");
245 1 : n = (BUN) (date_diff(l, f) / (s *28)); /* n maybe too large now */
246 1 : bn = COLnew(0, TYPE_date, n + 1, TRANSIENT);
247 1 : if (bn == NULL)
248 0 : throw(MAL, "generator.table", SQLSTATE(HY013) MAL_MALLOC_FAIL);
249 1 : v = (date *) Tloc(bn, 0);
250 1 : BUN c;
251 4 : for (c = 0; c < n && f < l; c++) {
252 3 : *v++ = f;
253 3 : f = date_add_month(f, s);
254 3 : if (is_date_nil(f)) {
255 0 : BBPreclaim(bn);
256 0 : throw(MAL, "generator.table", SQLSTATE(22003) "overflow in calculation");
257 : }
258 : }
259 1 : n = c;
260 1 : bn->tsorted = s > 0 || n <= 1;
261 1 : bn->trevsorted = s < 0 || n <= 1;
262 1 : } else if (tpe == TYPE_date) { /* days */
263 1 : date *v,f,l;
264 1 : lng s;
265 1 : ValRecord ret;
266 1 : if (VARcalccmp(&ret, &stk->stk[pci->argv[1]],
267 1 : &stk->stk[pci->argv[2]]) != GDK_SUCCEED)
268 0 : throw(MAL, "generator.table",
269 : SQLSTATE(42000) "Illegal generator expression range");
270 1 : f = *getArgReference_TYPE(stk, pci, 1, date);
271 1 : l = *getArgReference_TYPE(stk, pci, 2, date);
272 1 : s = *getArgReference_lng(stk, pci, 3);
273 1 : if (s == 0 ||
274 1 : (s > 0 && ret.val.btval > 0) ||
275 0 : (s < 0 && ret.val.btval < 0) ||
276 1 : is_date_nil(f) || is_date_nil(l))
277 0 : throw(MAL, "generator.table",
278 : SQLSTATE(42000) "Illegal generator range");
279 1 : s /= 24*60*60*1000;
280 : /* check if s is really in nr of days or usecs */
281 1 : n = (BUN) (date_diff(l, f) / s) + 1; /* n maybe too large now */
282 1 : bn = COLnew(0, TYPE_date, n + 1, TRANSIENT);
283 1 : if (bn == NULL)
284 0 : throw(MAL, "generator.table", SQLSTATE(HY013) MAL_MALLOC_FAIL);
285 1 : v = (date *) Tloc(bn, 0);
286 1 : BUN c;
287 3 : for (c = 0; c < n && f < l; c++) {
288 2 : *v++ = f;
289 2 : f = date_add_day(f, (int) s);
290 2 : if (is_date_nil(f)) {
291 0 : BBPreclaim(bn);
292 0 : throw(MAL, "generator.table", SQLSTATE(22003) "overflow in calculation");
293 : }
294 : }
295 1 : n = c;
296 1 : bn->tsorted = s > 0 || n <= 1;
297 1 : bn->trevsorted = s < 0 || n <= 1;
298 20 : } else if (tpe == TYPE_timestamp) {
299 20 : timestamp *v,f,l;
300 20 : lng s;
301 20 : ValRecord ret;
302 20 : if (VARcalccmp(&ret, &stk->stk[pci->argv[1]],
303 20 : &stk->stk[pci->argv[2]]) != GDK_SUCCEED)
304 0 : throw(MAL, "generator.table",
305 : SQLSTATE(42000) "Illegal generator expression range");
306 20 : f = *getArgReference_TYPE(stk, pci, 1, timestamp);
307 20 : l = *getArgReference_TYPE(stk, pci, 2, timestamp);
308 20 : if ( pci->argc == 3)
309 0 : throw(MAL,"generator.table", SQLSTATE(42000) "Timestamp step missing");
310 20 : s = *getArgReference_lng(stk, pci, 3);
311 20 : if (s == 0 ||
312 20 : (s > 0 && ret.val.btval > 0) ||
313 10 : (s < 0 && ret.val.btval < 0) ||
314 20 : is_timestamp_nil(f) || is_timestamp_nil(l))
315 0 : throw(MAL, "generator.table",
316 : SQLSTATE(42000) "Illegal generator range");
317 : /* casting one value to lng causes the whole
318 : * computation to be done as lng, reducing the
319 : * risk of overflow */
320 20 : s *= 1000; /* msec -> usec */
321 20 : n = (BUN) (timestamp_diff(l, f) / s);
322 20 : bn = COLnew(0, TYPE_timestamp, n + 1, TRANSIENT);
323 20 : if (bn == NULL)
324 0 : throw(MAL, "generator.table", SQLSTATE(HY013) MAL_MALLOC_FAIL);
325 20 : v = (timestamp *) Tloc(bn, 0);
326 166 : for (BUN c = 0; c < n; c++) {
327 146 : *v++ = f;
328 146 : f = timestamp_add_usec(f, s);
329 146 : if (is_timestamp_nil(f)) {
330 0 : BBPreclaim(bn);
331 0 : throw(MAL, "generator.table", SQLSTATE(22003) "overflow in calculation");
332 : }
333 : }
334 20 : if (f != l) {
335 11 : *v++ = f;
336 11 : n++;
337 : }
338 20 : bn->tsorted = s > 0 || n <= 1;
339 20 : bn->trevsorted = s < 0 || n <= 1;
340 : } else {
341 0 : throw(MAL, "generator.table", SQLSTATE(42000) "Unsupported type");
342 : }
343 : break;
344 : }
345 430 : BATsetcount(bn, n);
346 430 : bn->tkey = true;
347 430 : bn->tnil = false;
348 430 : bn->tnonil = true;
349 430 : *result = bn;
350 430 : return MAL_SUCCEED;
351 : }
352 :
353 : str
354 458 : VLTgenerator_table(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
355 : {
356 458 : str msg;
357 458 : BAT *bn = NULL;
358 :
359 458 : if ((msg = VLTgenerator_noop(cntxt, mb, stk, pci)) != MAL_SUCCEED)
360 : return msg;
361 :
362 455 : msg = VLTgenerator_table_(&bn, cntxt, mb, stk, pci);
363 455 : if( msg == MAL_SUCCEED){
364 430 : *getArgReference_bat(stk, pci, 0) = bn->batCacheid;
365 430 : BBPkeepref(bn);
366 : }
367 : return msg;
368 : }
369 :
370 : /*
371 : * Selection over the generator table does not require a materialization of the table
372 : * An optimizer can replace the subselect directly into a generator specific one.
373 : * The target to look for is generator.series(A1,A2,A3)
374 : * We need the generator parameters, which are injected to replace the target column
375 : */
376 : static InstrPtr
377 408 : findGeneratorDefinition(MalBlkPtr mb, InstrPtr pci, int target)
378 : {
379 408 : InstrPtr q, p = NULL;
380 408 : int i;
381 :
382 11492 : for (i = 1; i < mb->stop; i++) {
383 11492 : q = getInstrPtr(mb, i);
384 11492 : if (q->argv[0] == target && getModuleId(q) == generatorRef && (getFunctionId(q) == parametersRef || getFunctionId(q) == seriesRef))
385 11492 : p = q;
386 11492 : if (q == pci)
387 408 : return p;
388 : }
389 : return p;
390 : }
391 :
392 : #define calculate_range(TPE, TPE2) \
393 : do { \
394 : TPE f, l, s, low, hgh; \
395 : \
396 : f = * getArgReference_##TPE(stk, p, 1); \
397 : l = * getArgReference_##TPE(stk, p, 2); \
398 : if ( p->argc == 3) \
399 : s = f<l? (TPE) 1: (TPE)-1; \
400 : else s = * getArgReference_##TPE(stk, p, 3); \
401 : if (s == 0 || (s > 0 && f > l) || (s < 0 && f < l) || is_##TPE##_nil(f) || is_##TPE##_nil(l)) { \
402 : BBPreclaim(cand); \
403 : throw(MAL, "generator.select", \
404 : SQLSTATE(42000) "Illegal generator range"); \
405 : } \
406 : n = (BUN) (((TPE2) l - (TPE2) f) / (TPE2) s); \
407 : if ((TPE)(n * s + f) != l) \
408 : n++; \
409 : \
410 : low = * getArgReference_##TPE(stk, pci, i); \
411 : hgh = * getArgReference_##TPE(stk, pci, i + 1); \
412 : \
413 : if (!is_##TPE##_nil(low) && low == hgh) \
414 : hi = li; \
415 : if (is_##TPE##_nil(low) && is_##TPE##_nil(hgh)) { \
416 : if (li && hi && !anti) { \
417 : /* match NILs (of which there aren't */ \
418 : /* any) */ \
419 : o1 = o2 = 0; \
420 : } else { \
421 : /* match all non-NIL values, */ \
422 : /* i.e. everything */ \
423 : o1 = 0; \
424 : o2 = (oid) n; \
425 : } \
426 : } else if (s > 0) { \
427 : if (is_##TPE##_nil(low) || low < f) \
428 : o1 = 0; \
429 : else { \
430 : o1 = (oid) (((TPE2) low - (TPE2) f) / (TPE2) s); \
431 : if ((TPE) (f + o1 * s) < low || \
432 : (!li && (TPE) (f + o1 * s) == low)) \
433 : o1++; \
434 : } \
435 : if (is_##TPE##_nil(hgh)) \
436 : o2 = (oid) n; \
437 : else if (hgh < f) \
438 : o2 = 0; \
439 : else { \
440 : o2 = (oid) (((TPE2) hgh - (TPE2) f) / (TPE2) s); \
441 : if ((hi && (TPE) (f + o2 * s) == hgh) || \
442 : (TPE) (f + o2 * s) < hgh) \
443 : o2++; \
444 : } \
445 : } else { \
446 : if (is_##TPE##_nil(low)) \
447 : o2 = (oid) n; \
448 : else if (low > f) \
449 : o2 = 0; \
450 : else { \
451 : o2 = (oid) (((TPE2) low - (TPE2) f) / (TPE2) s); \
452 : if ((li && (TPE) (f + o2 * s) == low) || \
453 : (TPE) (f + o2 * s) > low) \
454 : o2++; \
455 : } \
456 : if (is_##TPE##_nil(hgh) || hgh > f) \
457 : o1 = 0; \
458 : else { \
459 : o1 = (oid) (((TPE2) hgh - (TPE2) f) / (TPE2) s); \
460 : if ((!hi && (TPE) (f + o1 * s) == hgh) || \
461 : (TPE) (f + o1 * s) > hgh) \
462 : o1++; \
463 : } \
464 : } \
465 : } while (0)
466 :
467 : str
468 0 : VLTgenerator_subselect(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
469 : {
470 0 : bit li, hi, anti;
471 0 : int i;
472 0 : oid o1, o2;
473 0 : BUN n = 0;
474 0 : BAT *bn, *cand = NULL;
475 0 : struct canditer ci = (struct canditer) {.tpe = cand_dense};
476 0 : InstrPtr p;
477 0 : int tpe;
478 :
479 0 : (void) cntxt;
480 0 : p = findGeneratorDefinition(mb, pci, pci->argv[1]);
481 0 : if (p == NULL)
482 0 : throw(MAL, "generator.select",
483 : SQLSTATE(42000) "Could not locate definition for object");
484 :
485 0 : if (pci->argc == 8) { /* candidate list included */
486 0 : bat candid = *getArgReference_bat(stk, pci, 2);
487 0 : if (candid) {
488 0 : cand = BATdescriptor(candid);
489 0 : if (cand == NULL)
490 0 : throw(MAL, "generator.select",
491 : SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
492 0 : canditer_init(&ci, NULL, cand);
493 : }
494 : i = 3;
495 : } else
496 : i = 2;
497 :
498 0 : li = * getArgReference_bit(stk, pci, i + 2);
499 0 : hi = * getArgReference_bit(stk, pci, i + 3);
500 0 : anti = * getArgReference_bit(stk, pci, i + 4);
501 :
502 0 : switch ( tpe = getArgType(mb, pci, i)) {
503 0 : case TYPE_bte: calculate_range(bte, sht); break;
504 0 : case TYPE_sht: calculate_range(sht, int); break;
505 0 : case TYPE_int: calculate_range(int, lng); break;
506 : #ifndef HAVE_HGE
507 : case TYPE_lng: calculate_range(lng, lng); break;
508 : #else
509 0 : case TYPE_lng: calculate_range(lng, hge); break;
510 0 : case TYPE_hge: calculate_range(hge, hge); break;
511 : #endif
512 0 : case TYPE_flt: calculate_range(flt, dbl); break;
513 0 : case TYPE_dbl: calculate_range(dbl, dbl); break;
514 0 : default:
515 0 : if (p->argc == 3) {
516 0 : BBPreclaim(cand);
517 0 : throw(MAL,"generator.table", SQLSTATE(42000) "Date step missing");
518 : }
519 0 : if (tpe == TYPE_date && getArgType(mb, p, 3) == TYPE_int) { /* months */
520 0 : date tsf,tsl;
521 0 : date tlow,thgh;
522 0 : int tss;
523 0 : oid *ol;
524 :
525 0 : tsf = *getArgReference_TYPE(stk, p, 1, date);
526 0 : tsl = *getArgReference_TYPE(stk, p, 2, date);
527 0 : tss = *getArgReference_int(stk, p, 3);
528 0 : if ( tss == 0 ||
529 0 : is_date_nil(tsf) || is_date_nil(tsl) ||
530 0 : (tss > 0 && tsf > tsl ) ||
531 0 : (tss < 0 && tsf < tsl )
532 : ) {
533 0 : BBPreclaim(cand);
534 0 : throw(MAL, "generator.select", SQLSTATE(42000) "Illegal generator range");
535 : }
536 :
537 0 : tlow = *getArgReference_TYPE(stk,pci,i, date);
538 0 : thgh = *getArgReference_TYPE(stk,pci,i+1, date);
539 :
540 0 : if (!is_date_nil(tlow) && tlow == thgh)
541 0 : hi = li;
542 0 : if( hi && !is_date_nil(thgh)) {
543 0 : thgh = date_add_month(thgh, 1);
544 0 : if (is_date_nil(thgh)) {
545 0 : BBPreclaim(cand);
546 0 : throw(MAL, "generator.select", SQLSTATE(22003) "overflow in calculation");
547 : }
548 : }
549 0 : if( !li && !is_date_nil(tlow)) {
550 0 : tlow = date_add_month(tlow, 1);
551 0 : if (is_date_nil(tlow)) {
552 0 : BBPreclaim(cand);
553 0 : throw(MAL, "generator.select", SQLSTATE(22003) "overflow in calculation");
554 : }
555 : }
556 :
557 0 : o2 = (BUN) (date_diff(tsl, tsf) / (tss*28));
558 0 : bn = COLnew(0, TYPE_oid, o2 + 1, TRANSIENT);
559 0 : if (bn == NULL) {
560 0 : BBPreclaim(cand);
561 0 : throw(MAL, "generator.select", SQLSTATE(HY013) MAL_MALLOC_FAIL);
562 : }
563 :
564 : // simply enumerate the sequence and filter it by predicate and candidate list
565 0 : ol = (oid *) Tloc(bn, 0);
566 0 : for (o1=0; o1 <= o2; o1++) {
567 0 : if(((is_date_nil(tlow) || tsf >= tlow) &&
568 0 : (is_date_nil(thgh) || tsf < thgh)) != anti ){
569 : /* could be improved when no candidate list is available into a void/void BAT */
570 0 : if( cand == NULL || canditer_contains(&ci, o1)) {
571 0 : *ol++ = o1;
572 0 : n++;
573 : }
574 : }
575 0 : tsf = date_add_month(tsf, tss);
576 0 : if (is_date_nil(tsf)) {
577 0 : BBPreclaim(cand);
578 0 : BBPreclaim(bn);
579 0 : throw(MAL, "generator.select", SQLSTATE(22003) "overflow in calculation");
580 : }
581 : }
582 0 : BBPreclaim(cand);
583 0 : BATsetcount(bn, n);
584 0 : bn->tsorted = true;
585 0 : bn->trevsorted = BATcount(bn) <= 1;
586 0 : bn->tkey = true;
587 0 : bn->tnil = false;
588 0 : bn->tnonil = true;
589 0 : * getArgReference_bat(stk, pci, 0) = bn->batCacheid;
590 0 : BBPkeepref(bn);
591 0 : return MAL_SUCCEED;
592 0 : } else if (tpe == TYPE_date) { /* days */
593 0 : date tsf,tsl;
594 0 : date tlow,thgh;
595 0 : lng tss;
596 0 : oid *ol;
597 :
598 0 : tsf = *getArgReference_TYPE(stk, p, 1, date);
599 0 : tsl = *getArgReference_TYPE(stk, p, 2, date);
600 0 : tss = *getArgReference_lng(stk, p, 3);
601 0 : if ( tss == 0 ||
602 0 : is_date_nil(tsf) || is_date_nil(tsl) ||
603 0 : (tss > 0 && tsf > tsl ) ||
604 0 : (tss < 0 && tsf < tsl )
605 : ) {
606 0 : BBPreclaim(cand);
607 0 : throw(MAL, "generator.select", SQLSTATE(42000) "Illegal generator range");
608 : }
609 0 : tss /= 24*60*60*1000;
610 :
611 0 : tlow = *getArgReference_TYPE(stk,pci,i, date);
612 0 : thgh = *getArgReference_TYPE(stk,pci,i+1, date);
613 :
614 0 : if (!is_date_nil(tlow) && tlow == thgh)
615 0 : hi = li;
616 0 : if( hi && !is_date_nil(thgh)) {
617 0 : thgh = date_add_month(thgh, 1);
618 0 : if (is_date_nil(thgh)) {
619 0 : BBPreclaim(cand);
620 0 : throw(MAL, "generator.select", SQLSTATE(22003) "overflow in calculation");
621 : }
622 : }
623 0 : if( !li && !is_date_nil(tlow)) {
624 0 : tlow = date_add_month(tlow, 1);
625 0 : if (is_date_nil(tlow)) {
626 0 : BBPreclaim(cand);
627 0 : throw(MAL, "generator.select", SQLSTATE(22003) "overflow in calculation");
628 : }
629 : }
630 :
631 0 : o2 = (BUN) (date_diff(tsl, tsf) / tss) + 1;
632 0 : bn = COLnew(0, TYPE_oid, o2 + 1, TRANSIENT);
633 0 : if (bn == NULL) {
634 0 : BBPreclaim(cand);
635 0 : throw(MAL, "generator.select", SQLSTATE(HY013) MAL_MALLOC_FAIL);
636 : }
637 :
638 : // simply enumerate the sequence and filter it by predicate and candidate list
639 0 : ol = (oid *) Tloc(bn, 0);
640 0 : for (o1=0; o1 <= o2; o1++) {
641 0 : if(((is_date_nil(tlow) || tsf >= tlow) &&
642 0 : (is_date_nil(thgh) || tsf < thgh)) != anti ){
643 : /* could be improved when no candidate list is available into a void/void BAT */
644 0 : if( cand == NULL || canditer_contains(&ci, o1)) {
645 0 : *ol++ = o1;
646 0 : n++;
647 : }
648 : }
649 0 : tsf = date_add_day(tsf, (int) tss);
650 0 : if (is_date_nil(tsf)) {
651 0 : BBPreclaim(cand);
652 0 : BBPreclaim(bn);
653 0 : throw(MAL, "generator.select", SQLSTATE(22003) "overflow in calculation");
654 : }
655 : }
656 0 : BBPreclaim(cand);
657 0 : BATsetcount(bn, n);
658 0 : bn->tsorted = true;
659 0 : bn->trevsorted = BATcount(bn) <= 1;
660 0 : bn->tkey = true;
661 0 : bn->tnil = false;
662 0 : bn->tnonil = true;
663 0 : * getArgReference_bat(stk, pci, 0) = bn->batCacheid;
664 0 : BBPkeepref(bn);
665 0 : return MAL_SUCCEED;
666 0 : } else if (tpe == TYPE_timestamp) {
667 0 : timestamp tsf,tsl;
668 0 : timestamp tlow,thgh;
669 0 : lng tss;
670 0 : oid *ol;
671 :
672 0 : tsf = *getArgReference_TYPE(stk, p, 1, timestamp);
673 0 : tsl = *getArgReference_TYPE(stk, p, 2, timestamp);
674 0 : if (p->argc == 3) {
675 0 : BBPreclaim(cand);
676 0 : throw(MAL,"generator.table", SQLSTATE(42000) "Timestamp step missing");
677 : }
678 0 : tss = *getArgReference_lng(stk, p, 3);
679 0 : if ( tss == 0 ||
680 0 : is_timestamp_nil(tsf) || is_timestamp_nil(tsl) ||
681 0 : (tss > 0 && tsf > tsl ) ||
682 0 : (tss < 0 && tsf < tsl )
683 : ) {
684 0 : BBPreclaim(cand);
685 0 : throw(MAL, "generator.select", SQLSTATE(42000) "Illegal generator range");
686 : }
687 :
688 0 : tlow = *getArgReference_TYPE(stk,pci,i, timestamp);
689 0 : thgh = *getArgReference_TYPE(stk,pci,i+1, timestamp);
690 :
691 0 : if (!is_timestamp_nil(tlow) && tlow == thgh)
692 0 : hi = li;
693 0 : if( hi && !is_timestamp_nil(thgh)) {
694 0 : thgh = timestamp_add_usec(thgh, 1);
695 0 : if (is_timestamp_nil(thgh)) {
696 0 : BBPreclaim(cand);
697 0 : throw(MAL, "generator.select", SQLSTATE(22003) "overflow in calculation");
698 : }
699 : }
700 0 : if( !li && !is_timestamp_nil(tlow)) {
701 0 : tlow = timestamp_add_usec(tlow, 1);
702 0 : if (is_timestamp_nil(tlow)) {
703 0 : BBPreclaim(cand);
704 0 : throw(MAL, "generator.select", SQLSTATE(22003) "overflow in calculation");
705 : }
706 : }
707 :
708 : /* casting one value to lng causes the whole
709 : * computation to be done as lng, reducing the
710 : * risk of overflow */
711 0 : tss *= 1000; /* msec -> usec */
712 0 : o2 = (BUN) (timestamp_diff(tsl, tsf) / tss);
713 0 : bn = COLnew(0, TYPE_oid, o2 + 1, TRANSIENT);
714 0 : if (bn == NULL) {
715 0 : BBPreclaim(cand);
716 0 : throw(MAL, "generator.select", SQLSTATE(HY013) MAL_MALLOC_FAIL);
717 : }
718 :
719 : // simply enumerate the sequence and filter it by predicate and candidate list
720 0 : ol = (oid *) Tloc(bn, 0);
721 0 : for (o1=0; o1 <= o2; o1++) {
722 0 : if(((is_timestamp_nil(tlow) || tsf >= tlow) &&
723 0 : (is_timestamp_nil(thgh) || tsf < thgh)) != anti ){
724 : /* could be improved when no candidate list is available into a void/void BAT */
725 0 : if( cand == NULL || canditer_contains(&ci, o1)) {
726 0 : *ol++ = o1;
727 0 : n++;
728 : }
729 : }
730 0 : tsf = timestamp_add_usec(tsf, tss);
731 0 : if (is_timestamp_nil(tsf)) {
732 0 : BBPreclaim(cand);
733 0 : BBPreclaim(bn);
734 0 : throw(MAL, "generator.select", SQLSTATE(22003) "overflow in calculation");
735 : }
736 : }
737 0 : BBPreclaim(cand);
738 0 : BATsetcount(bn, n);
739 0 : bn->tsorted = true;
740 0 : bn->trevsorted = BATcount(bn) <= 1;
741 0 : bn->tkey = true;
742 0 : bn->tnil = false;
743 0 : bn->tnonil = true;
744 0 : * getArgReference_bat(stk, pci, 0) = bn->batCacheid;
745 0 : BBPkeepref(bn);
746 0 : return MAL_SUCCEED;
747 : } else {
748 0 : BBPreclaim(cand);
749 0 : throw(MAL, "generator.select", SQLSTATE(42000) "Unsupported type in select");
750 : }
751 : }
752 0 : if (o1 > (oid) n)
753 : o1 = (oid) n;
754 0 : if (o2 > (oid) n)
755 : o2 = (oid) n;
756 0 : assert(o1 <= o2);
757 0 : assert(o2 - o1 <= (oid) n);
758 0 : if (anti && o1 == o2) {
759 0 : o1 = 0;
760 0 : o2 = (oid) n;
761 0 : anti = 0;
762 : }
763 0 : if (cand) {
764 0 : if (anti) {
765 0 : bn = canditer_slice2val(&ci, oid_nil, o1, o2, oid_nil);
766 : } else {
767 0 : bn = canditer_sliceval(&ci, o1, o2);
768 : }
769 0 : BBPunfix(cand->batCacheid);
770 0 : if (bn == NULL)
771 0 : throw(MAL, "generator.select",
772 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
773 : } else {
774 0 : if (anti) {
775 0 : oid o;
776 0 : oid *op;
777 :
778 0 : bn = COLnew(0, TYPE_oid, n - (o2 - o1), TRANSIENT);
779 0 : if (bn == NULL)
780 0 : throw(MAL, "generator.select",
781 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
782 0 : BATsetcount(bn, n - (o2 - o1));
783 0 : op = (oid *) Tloc(bn, 0);
784 0 : for (o = 0; o < o1; o++)
785 0 : *op++ = o;
786 0 : for (o = o2; o < (oid) n; o++)
787 0 : *op++ = o;
788 0 : bn->tnil = false;
789 0 : bn->tnonil = true;
790 0 : bn->tsorted = true;
791 0 : bn->trevsorted = BATcount(bn) <= 1;
792 0 : bn->tkey = true;
793 : } else {
794 0 : bn = BATdense(0, o1, (BUN) (o2 - o1));
795 0 : if (bn == NULL)
796 0 : throw(MAL, "generator.select",
797 : SQLSTATE(HY013) MAL_MALLOC_FAIL);
798 : }
799 : }
800 0 : * getArgReference_bat(stk, pci, 0) = bn->batCacheid;
801 0 : BBPkeepref(bn);
802 0 : return MAL_SUCCEED;
803 : }
804 :
805 : #define PREVVALUEbte(x) ((x) - 1)
806 : #define PREVVALUEsht(x) ((x) - 1)
807 : #define PREVVALUEint(x) ((x) - 1)
808 : #define PREVVALUElng(x) ((x) - 1)
809 : #ifdef HAVE_HGE
810 : #define PREVVALUEhge(x) ((x) - 1)
811 : #endif
812 : #define PREVVALUEoid(x) ((x) - 1)
813 : #define PREVVALUEflt(x) nextafterf((x), -GDK_flt_max)
814 : #define PREVVALUEdbl(x) nextafter((x), -GDK_dbl_max)
815 :
816 : #define NEXTVALUEbte(x) ((x) + 1)
817 : #define NEXTVALUEsht(x) ((x) + 1)
818 : #define NEXTVALUEint(x) ((x) + 1)
819 : #define NEXTVALUElng(x) ((x) + 1)
820 : #ifdef HAVE_HGE
821 : #define NEXTVALUEhge(x) ((x) + 1)
822 : #endif
823 : #define NEXTVALUEoid(x) ((x) + 1)
824 : #define NEXTVALUEflt(x) nextafterf((x), GDK_flt_max)
825 : #define NEXTVALUEdbl(x) nextafter((x), GDK_dbl_max)
826 :
827 : #define HGE_ABS(a) (((a) < 0) ? -(a) : (a))
828 :
829 : #define VLTthetasubselect(TPE,ABS) \
830 : do { \
831 : TPE f,l,s, low, hgh; \
832 : BUN j; oid *v; \
833 : bool nil_matches = false; \
834 : f = *getArgReference_##TPE(stk,p, 1); \
835 : l = *getArgReference_##TPE(stk,p, 2); \
836 : if ( p->argc == 3) \
837 : s = f<l? (TPE) 1: (TPE)-1; \
838 : else s = *getArgReference_##TPE(stk,p, 3); \
839 : if( s == 0 || (f<l && s < 0) || (f>l && s> 0)) { \
840 : BBPreclaim(cand); \
841 : throw(MAL,"generator.thetaselect", SQLSTATE(42000) "Illegal range"); \
842 : } \
843 : cap = (BUN)(ABS(l-f)/ABS(s)); \
844 : bn = COLnew(0, TYPE_oid, cap, TRANSIENT); \
845 : if( bn == NULL) { \
846 : BBPreclaim(cand); \
847 : throw(MAL,"generator.thetaselect", SQLSTATE(HY013) MAL_MALLOC_FAIL); \
848 : } \
849 : low= hgh = TPE##_nil; \
850 : v = (oid*) Tloc(bn,0); \
851 : if ( strcmp(oper,"<") == 0){ \
852 : hgh= *getArgReference_##TPE(stk,pci,3); \
853 : hgh = PREVVALUE##TPE(hgh); \
854 : } else if ( strcmp(oper,"<=") == 0){ \
855 : hgh= *getArgReference_##TPE(stk,pci,3); \
856 : } else if ( strcmp(oper,">") == 0){ \
857 : low= *getArgReference_##TPE(stk,pci,3); \
858 : low = NEXTVALUE##TPE(low); \
859 : } else if ( strcmp(oper,">=") == 0){ \
860 : low= *getArgReference_##TPE(stk,pci,3); \
861 : } else if (strcmp(oper, "!=") == 0 || strcmp(oper, "<>") == 0) { \
862 : hgh= low= *getArgReference_##TPE(stk,pci,3); \
863 : anti = true; \
864 : } else if (strcmp(oper, "==") == 0 || strcmp(oper, "=") == 0) { \
865 : hgh= low= *getArgReference_##TPE(stk,pci,3); \
866 : } else if (strcmp(oper, "ne") == 0) { \
867 : hgh= low= *getArgReference_##TPE(stk,pci,3); \
868 : anti = true; \
869 : nil_matches = true; \
870 : } else if (strcmp(oper, "eq") == 0) { \
871 : hgh= low= *getArgReference_##TPE(stk,pci,3); \
872 : nil_matches = true; \
873 : } else { \
874 : BBPreclaim(cand); \
875 : BBPreclaim(bn); \
876 : throw(MAL,"generator.thetaselect", SQLSTATE(42000) "Unknown operator"); \
877 : } \
878 : for(j=0;j<cap;j++, f+=s, o++) \
879 : if (nil_matches && is_##TPE##_nil(low) ? anti : \
880 : ((is_##TPE##_nil(low) || f >= low) && (is_##TPE##_nil(hgh) || f <= hgh)) != anti){ \
881 : if(cand == NULL || canditer_contains(&ci, o)) { \
882 : *v++ = o; \
883 : c++; \
884 : } \
885 : } \
886 : } while (0)
887 :
888 :
889 29 : str VLTgenerator_thetasubselect(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
890 : {
891 29 : bool anti = false;
892 29 : int tpe;
893 29 : bat cndid =0;
894 29 : BAT *cand = 0, *bn = NULL;
895 29 : struct canditer ci = (struct canditer) {.tpe = cand_dense};
896 29 : BUN cap,j, c = 0;
897 29 : oid o = 0;
898 29 : InstrPtr p;
899 29 : str oper;
900 :
901 29 : (void) cntxt;
902 29 : p = findGeneratorDefinition(mb,pci,pci->argv[1]);
903 29 : if( p == NULL)
904 0 : throw(MAL,"generator.thetaselect",SQLSTATE(42000) "Could not locate definition for object");
905 :
906 29 : assert(pci->argc == 5); // candidate list included
907 29 : cndid = *getArgReference_bat(stk,pci, 2);
908 29 : if( !is_bat_nil(cndid)){
909 2 : cand = BATdescriptor(cndid);
910 2 : if( cand == NULL)
911 0 : throw(MAL,"generator.select", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
912 2 : canditer_init(&ci, NULL, cand);
913 : }
914 29 : oper= *getArgReference_str(stk,pci,4);
915 :
916 : // check the step direction
917 :
918 29 : switch( tpe =getArgType(mb,pci,3)){
919 82 : case TYPE_bte: VLTthetasubselect(bte,abs);break;
920 0 : case TYPE_sht: VLTthetasubselect(sht,abs);break;
921 0 : case TYPE_int: VLTthetasubselect(int,abs);break;
922 12 : case TYPE_lng: VLTthetasubselect(lng,llabs);break;
923 : #ifdef HAVE_HGE
924 0 : case TYPE_hge: VLTthetasubselect(hge,HGE_ABS);break;
925 : #endif
926 6 : case TYPE_flt: VLTthetasubselect(flt,fabsf);break;
927 18 : case TYPE_dbl: VLTthetasubselect(dbl,fabs);break;
928 11 : default:
929 11 : if (tpe == TYPE_date && p->argc == 3) {
930 0 : BBPreclaim(cand);
931 0 : throw(MAL,"generator.table", SQLSTATE(42000) "Timestamp step missing");
932 : }
933 2 : if (tpe == TYPE_date && getArgType(mb, p, 3) == TYPE_int) { /* months */
934 1 : date f,l, val, low, hgh;
935 1 : int s;
936 1 : oid *v;
937 :
938 1 : f = *getArgReference_TYPE(stk,p, 1, date);
939 1 : l = *getArgReference_TYPE(stk,p, 2, date);
940 1 : s = *getArgReference_int(stk,p, 3);
941 1 : if ( s == 0 ||
942 1 : (s > 0 && f > l) ||
943 1 : (s < 0 && f < l)
944 : ) {
945 0 : BBPreclaim(cand);
946 0 : throw(MAL, "generator.select", SQLSTATE(42000) "Illegal generator range");
947 : }
948 :
949 1 : hgh = low = date_nil;
950 1 : if ( strcmp(oper,"<") == 0){
951 1 : hgh= *getArgReference_TYPE(stk,pci,3, date);
952 1 : hgh = date_add_month(hgh, -1);
953 1 : if (is_date_nil(hgh)) {
954 0 : BBPreclaim(cand);
955 0 : throw(MAL, "generator.select", SQLSTATE(22003) "overflow in calculation");
956 : }
957 : } else
958 0 : if ( strcmp(oper,"<=") == 0){
959 0 : hgh= *getArgReference_TYPE(stk,pci,3, date) ;
960 : } else
961 0 : if ( strcmp(oper,">") == 0){
962 0 : low= *getArgReference_TYPE(stk,pci,3, date);
963 0 : low = date_add_month(low, 1);
964 0 : if (is_date_nil(low)) {
965 0 : BBPreclaim(cand);
966 0 : throw(MAL, "generator.select", SQLSTATE(22003) "overflow in calculation");
967 : }
968 : } else
969 0 : if ( strcmp(oper,">=") == 0){
970 0 : low= *getArgReference_TYPE(stk,pci,3, date);
971 : } else
972 0 : if ( strcmp(oper,"!=") == 0 || strcmp(oper, "<>") == 0){
973 0 : hgh= low= *getArgReference_TYPE(stk,pci,3, date);
974 0 : anti = true;
975 : } else
976 0 : if ( strcmp(oper,"==") == 0 || strcmp(oper, "=") == 0){
977 0 : hgh= low= *getArgReference_TYPE(stk,pci,3, date);
978 : } else {
979 0 : BBPreclaim(cand);
980 0 : throw(MAL,"generator.thetaselect", SQLSTATE(42000) "Unknown operator");
981 : }
982 :
983 1 : cap = (BUN) (date_diff(l, f) / (s*28));
984 1 : bn = COLnew(0, TYPE_oid, cap, TRANSIENT);
985 1 : if( bn == NULL) {
986 0 : BBPreclaim(cand);
987 0 : throw(MAL,"generator.thetaselect", SQLSTATE(HY013) MAL_MALLOC_FAIL);
988 : }
989 1 : v = (oid*) Tloc(bn,0);
990 :
991 1 : val = f;
992 14 : for(j = 0; j< cap; j++, o++){
993 13 : if (((is_date_nil(low) || val >= low) &&
994 18 : (is_date_nil(hgh) || val <= hgh)) != anti){
995 5 : if(cand == NULL || canditer_contains(&ci, o)){
996 5 : *v++ = o;
997 5 : c++;
998 : }
999 : }
1000 13 : val = date_add_month(val, s);
1001 13 : if (is_date_nil(val)) {
1002 0 : BBPreclaim(cand);
1003 0 : BBPreclaim(bn);
1004 0 : throw(MAL, "generator.thetaselect", SQLSTATE(22003) "overflow in calculation");
1005 : }
1006 : }
1007 1 : } else if (tpe == TYPE_date) { /* days */
1008 1 : date f,l, val, low, hgh;
1009 1 : lng s;
1010 1 : oid *v;
1011 :
1012 1 : f = *getArgReference_TYPE(stk,p, 1, date);
1013 1 : l = *getArgReference_TYPE(stk,p, 2, date);
1014 1 : s = *getArgReference_lng(stk,p, 3);
1015 1 : if ( s == 0 ||
1016 1 : (s > 0 && f > l) ||
1017 1 : (s < 0 && f < l)
1018 : ) {
1019 0 : BBPreclaim(cand);
1020 0 : throw(MAL, "generator.select", SQLSTATE(42000) "Illegal generator range");
1021 : }
1022 1 : s /= 24*60*60*1000;
1023 :
1024 1 : hgh = low = date_nil;
1025 1 : if ( strcmp(oper,"<") == 0){
1026 1 : hgh= *getArgReference_TYPE(stk,pci,3, date);
1027 1 : hgh = date_add_day(hgh, -1);
1028 1 : if (is_date_nil(hgh)) {
1029 0 : BBPreclaim(cand);
1030 0 : throw(MAL, "generator.select", SQLSTATE(22003) "overflow in calculation");
1031 : }
1032 : } else
1033 0 : if ( strcmp(oper,"<=") == 0){
1034 0 : hgh= *getArgReference_TYPE(stk,pci,3, date) ;
1035 : } else
1036 0 : if ( strcmp(oper,">") == 0){
1037 0 : low= *getArgReference_TYPE(stk,pci,3, date);
1038 0 : low = date_add_month(low, 1);
1039 0 : if (is_date_nil(low)) {
1040 0 : BBPreclaim(cand);
1041 0 : throw(MAL, "generator.select", SQLSTATE(22003) "overflow in calculation");
1042 : }
1043 : } else
1044 0 : if ( strcmp(oper,">=") == 0){
1045 0 : low= *getArgReference_TYPE(stk,pci,3, date);
1046 : } else
1047 0 : if ( strcmp(oper,"!=") == 0 || strcmp(oper, "<>") == 0){
1048 0 : hgh= low= *getArgReference_TYPE(stk,pci,3, date);
1049 0 : anti = true;
1050 : } else
1051 0 : if ( strcmp(oper,"==") == 0 || strcmp(oper, "=") == 0){
1052 0 : hgh= low= *getArgReference_TYPE(stk,pci,3, date);
1053 : } else {
1054 0 : BBPreclaim(cand);
1055 0 : throw(MAL,"generator.thetaselect", SQLSTATE(42000) "Unknown operator");
1056 : }
1057 :
1058 1 : cap = (BUN) (date_diff(l, f) / s) + 1;
1059 1 : bn = COLnew(0, TYPE_oid, cap, TRANSIENT);
1060 1 : if( bn == NULL) {
1061 0 : BBPreclaim(cand);
1062 0 : throw(MAL,"generator.thetaselect", SQLSTATE(HY013) MAL_MALLOC_FAIL);
1063 : }
1064 1 : v = (oid*) Tloc(bn,0);
1065 :
1066 1 : val = f;
1067 26 : for(j = 0; j< cap; j++, o++){
1068 25 : if (((is_date_nil(low) || val >= low) &&
1069 36 : (is_date_nil(hgh) || val <= hgh)) != anti){
1070 11 : if(cand == NULL || canditer_contains(&ci, o)){
1071 11 : *v++ = o;
1072 11 : c++;
1073 : }
1074 : }
1075 25 : val = date_add_day(val, (int) s);
1076 25 : if (is_date_nil(val)) {
1077 0 : BBPreclaim(cand);
1078 0 : BBPreclaim(bn);
1079 0 : throw(MAL, "generator.thetaselect", SQLSTATE(22003) "overflow in calculation");
1080 : }
1081 : }
1082 9 : } else if ( tpe == TYPE_timestamp){
1083 9 : timestamp f,l, val, low, hgh;
1084 9 : lng s;
1085 9 : oid *v;
1086 :
1087 9 : f = *getArgReference_TYPE(stk,p, 1, timestamp);
1088 9 : l = *getArgReference_TYPE(stk,p, 2, timestamp);
1089 9 : if ( p->argc == 3) {
1090 0 : BBPreclaim(cand);
1091 0 : throw(MAL,"generator.table", SQLSTATE(42000) "Timestamp step missing");
1092 : }
1093 9 : s = *getArgReference_lng(stk,p, 3);
1094 9 : if ( s == 0 ||
1095 9 : (s > 0 && f > l) ||
1096 9 : (s < 0 && f < l)
1097 : ) {
1098 0 : BBPreclaim(cand);
1099 0 : throw(MAL, "generator.select", SQLSTATE(42000) "Illegal generator range");
1100 : }
1101 :
1102 9 : hgh = low = timestamp_nil;
1103 9 : if ( strcmp(oper,"<") == 0){
1104 5 : hgh= *getArgReference_TYPE(stk,pci,3, timestamp);
1105 5 : hgh = timestamp_add_usec(hgh, -1);
1106 5 : if (is_timestamp_nil(hgh)) {
1107 0 : BBPreclaim(cand);
1108 0 : throw(MAL, "generator.select", SQLSTATE(22003) "overflow in calculation");
1109 : }
1110 : } else
1111 4 : if ( strcmp(oper,"<=") == 0){
1112 0 : hgh= *getArgReference_TYPE(stk,pci,3, timestamp) ;
1113 : } else
1114 4 : if ( strcmp(oper,">") == 0){
1115 3 : low= *getArgReference_TYPE(stk,pci,3, timestamp);
1116 3 : low = timestamp_add_usec(low, 1);
1117 3 : if (is_timestamp_nil(low)) {
1118 0 : BBPreclaim(cand);
1119 0 : throw(MAL, "generator.select", SQLSTATE(22003) "overflow in calculation");
1120 : }
1121 : } else
1122 1 : if ( strcmp(oper,">=") == 0){
1123 0 : low= *getArgReference_TYPE(stk,pci,3, timestamp);
1124 : } else
1125 1 : if ( strcmp(oper,"!=") == 0 || strcmp(oper, "<>") == 0){
1126 0 : hgh= low= *getArgReference_TYPE(stk,pci,3, timestamp);
1127 0 : anti = true;
1128 : } else
1129 1 : if ( strcmp(oper,"==") == 0 || strcmp(oper, "=") == 0){
1130 1 : hgh= low= *getArgReference_TYPE(stk,pci,3, timestamp);
1131 : } else {
1132 0 : BBPreclaim(cand);
1133 0 : throw(MAL,"generator.thetaselect", SQLSTATE(42000) "Unknown operator");
1134 : }
1135 :
1136 9 : s *= 1000; /* msec -> usec */
1137 9 : cap = (BUN) (timestamp_diff(l, f) / s);
1138 9 : bn = COLnew(0, TYPE_oid, cap, TRANSIENT);
1139 9 : if( bn == NULL) {
1140 0 : BBPreclaim(cand);
1141 0 : throw(MAL,"generator.thetaselect", SQLSTATE(HY013) MAL_MALLOC_FAIL);
1142 : }
1143 9 : v = (oid*) Tloc(bn,0);
1144 :
1145 9 : val = f;
1146 85 : for(j = 0; j< cap; j++, o++){
1147 76 : if (((is_timestamp_nil(low) || val >= low) &&
1148 88 : (is_timestamp_nil(hgh) || val <= hgh)) != anti){
1149 34 : if(cand == NULL || canditer_contains(&ci, o)){
1150 31 : *v++ = o;
1151 31 : c++;
1152 : }
1153 : }
1154 76 : val = timestamp_add_usec(val, s);
1155 76 : if (is_timestamp_nil(val)) {
1156 0 : BBPreclaim(cand);
1157 0 : BBPreclaim(bn);
1158 0 : throw(MAL, "generator.thetaselect", SQLSTATE(22003) "overflow in calculation");
1159 : }
1160 : }
1161 : } else {
1162 0 : BBPreclaim(cand);
1163 0 : throw(MAL,"generator.thetaselect", SQLSTATE(42000) "Illegal generator arguments");
1164 : }
1165 : }
1166 :
1167 29 : if( cndid)
1168 29 : BBPunfix(cndid);
1169 29 : BATsetcount(bn,c);
1170 29 : bn->tsorted = true;
1171 29 : bn->trevsorted = false;
1172 29 : bn->tkey = true;
1173 29 : bn->tnil = false;
1174 29 : bn->tnonil = true;
1175 29 : *getArgReference_bat(stk,pci,0) = bn->batCacheid;
1176 29 : BBPkeepref(bn);
1177 29 : return MAL_SUCCEED;
1178 : }
1179 :
1180 : #define VLTprojection(TPE) \
1181 : do { \
1182 : TPE f,l,s, val; \
1183 : TPE *v; \
1184 : f = *getArgReference_##TPE(stk,p, 1); \
1185 : l = *getArgReference_##TPE(stk,p, 2); \
1186 : if ( p->argc == 3) \
1187 : s = f<l? (TPE) 1: (TPE)-1; \
1188 : else \
1189 : s = * getArgReference_##TPE(stk, p, 3); \
1190 : if ( s == 0 || (f> l && s>0) || (f<l && s < 0)) { \
1191 : BBPunfix(b->batCacheid); \
1192 : throw(MAL,"generator.projection", SQLSTATE(42000) "Illegal range"); \
1193 : } \
1194 : bn = COLnew(0, TYPE_##TPE, cnt, TRANSIENT); \
1195 : if( bn == NULL){ \
1196 : BBPunfix(b->batCacheid); \
1197 : throw(MAL,"generator.projection", SQLSTATE(HY013) MAL_MALLOC_FAIL); \
1198 : } \
1199 : v = (TPE*) Tloc(bn,0); \
1200 : for(; cnt-- > 0; o++){ \
1201 : val = f + ((TPE) (ol == NULL ? o : ol[o])) * s; \
1202 : if ( (s > 0 && (val < f || val >= l)) || (s < 0 && (val <= l || val > f))) \
1203 : continue; \
1204 : *v++ = val; \
1205 : c++; \
1206 : } \
1207 : } while (0)
1208 :
1209 375 : str VLTgenerator_projection(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1210 : {
1211 375 : int tpe;
1212 375 : bat *ret;
1213 375 : BAT *b, *bn = NULL;
1214 375 : BUN cnt, c = 0;
1215 375 : oid *ol = NULL, o= 0;
1216 375 : InstrPtr p;
1217 :
1218 375 : (void) cntxt;
1219 375 : p = findGeneratorDefinition(mb,pci,pci->argv[2]);
1220 :
1221 375 : ret = getArgReference_bat(stk,pci,0);
1222 375 : b = BATdescriptor(*getArgReference_bat(stk,pci,1));
1223 375 : if( b == NULL)
1224 0 : throw(MAL,"generator.projection", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1225 :
1226 : // if it does not exist we should fall back to the ordinary projection to try
1227 : // it might have been materialized already
1228 375 : if( p == NULL){
1229 0 : bn = BATdescriptor( *getArgReference_bat(stk,pci,2));
1230 0 : if( bn == NULL) {
1231 0 : BBPunfix(b->batCacheid);
1232 0 : throw(MAL,"generator.projection", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1233 : }
1234 0 : BAT *bp = BATproject(b, bn);
1235 0 : BBPunfix(b->batCacheid);
1236 0 : BBPunfix(bn->batCacheid);
1237 0 : if (bp == NULL)
1238 0 : throw(MAL, "generator.projection", GDK_EXCEPTION);
1239 0 : *ret = bp->batCacheid;
1240 0 : BBPkeepref(bp);
1241 0 : return MAL_SUCCEED;
1242 : }
1243 :
1244 375 : cnt = BATcount(b);
1245 375 : if ( b->ttype == TYPE_void)
1246 72 : o = b->tseqbase;
1247 : else
1248 303 : ol = (oid*) Tloc(b,0);
1249 :
1250 : /* the actual code to perform a projection over generators */
1251 375 : switch( tpe = getArgType(mb,p,1)){
1252 2690 : case TYPE_bte: VLTprojection(bte); break;
1253 999146 : case TYPE_sht: VLTprojection(sht); break;
1254 1149357 : case TYPE_int: VLTprojection(int); break;
1255 14 : case TYPE_lng: VLTprojection(lng); break;
1256 : #ifdef HAVE_HGE
1257 0 : case TYPE_hge: VLTprojection(hge); break;
1258 : #endif
1259 7 : case TYPE_flt: VLTprojection(flt); break;
1260 17 : case TYPE_dbl: VLTprojection(dbl); break;
1261 37 : default:
1262 37 : if (tpe == TYPE_date && p->argc == 3) {
1263 0 : BBPunfix(b->batCacheid);
1264 0 : throw(MAL,"generator.table", SQLSTATE(42000) "Timestamp step missing");
1265 : }
1266 2 : if (tpe == TYPE_date && getArgType(mb, p, 3) == TYPE_int) { /* months */
1267 1 : date f,l, val;
1268 1 : int s,t;
1269 1 : date *v;
1270 1 : f = *getArgReference_TYPE(stk,p, 1, date);
1271 1 : l = *getArgReference_TYPE(stk,p, 2, date);
1272 1 : s = *getArgReference_int(stk,p, 3);
1273 1 : if ( s == 0 ||
1274 1 : (s< 0 && f < l) ||
1275 1 : (s> 0 && l < f) ) {
1276 0 : BBPunfix(b->batCacheid);
1277 0 : throw(MAL,"generator.projection", SQLSTATE(42000) "Illegal range");
1278 : }
1279 :
1280 1 : bn = COLnew(0, TYPE_date, cnt, TRANSIENT);
1281 1 : if( bn == NULL){
1282 0 : BBPunfix(b->batCacheid);
1283 0 : throw(MAL,"generator.projection", SQLSTATE(HY013) MAL_MALLOC_FAIL);
1284 : }
1285 :
1286 1 : v = (date*) Tloc(bn,0);
1287 :
1288 6 : for(; cnt-- > 0; o++){
1289 5 : t = ((int) (ol == NULL ? o : ol[o])) * s;
1290 5 : val = date_add_month(f, t);
1291 5 : if (is_date_nil(val)) {
1292 0 : BBPunfix(b->batCacheid);
1293 0 : BBPreclaim(bn);
1294 0 : throw(MAL, "generator.projection", SQLSTATE(22003) "overflow in calculation");
1295 : }
1296 :
1297 5 : if ( is_date_nil(val))
1298 : continue;
1299 5 : if (s > 0 && (val < f || val >= l) )
1300 0 : continue;
1301 5 : if (s < 0 && (val <= l || val > f) )
1302 0 : continue;
1303 5 : *v++ = val;
1304 5 : c++;
1305 : }
1306 1 : } else if (tpe == TYPE_date) { /* days */
1307 1 : date f,l, val;
1308 1 : lng s,t;
1309 1 : date *v;
1310 1 : f = *getArgReference_TYPE(stk,p, 1, date);
1311 1 : l = *getArgReference_TYPE(stk,p, 2, date);
1312 1 : s = *getArgReference_lng(stk,p, 3);
1313 1 : if ( s == 0 ||
1314 1 : (s< 0 && f < l) ||
1315 1 : (s> 0 && l < f) ) {
1316 0 : BBPunfix(b->batCacheid);
1317 0 : throw(MAL,"generator.projection", SQLSTATE(42000) "Illegal range");
1318 : }
1319 1 : s /= 24*60*60*1000;
1320 :
1321 1 : bn = COLnew(0, TYPE_date, cnt, TRANSIENT);
1322 1 : if( bn == NULL){
1323 0 : BBPunfix(b->batCacheid);
1324 0 : throw(MAL,"generator.projection", SQLSTATE(HY013) MAL_MALLOC_FAIL);
1325 : }
1326 :
1327 1 : v = (date*) Tloc(bn,0);
1328 :
1329 12 : for(; cnt-- > 0; o++){
1330 11 : t = ((int) (ol == NULL ? o : ol[o])) * s;
1331 11 : val = date_add_day(f, (int) t);
1332 11 : if (is_date_nil(val)) {
1333 0 : BBPunfix(b->batCacheid);
1334 0 : BBPreclaim(bn);
1335 0 : throw(MAL, "generator.projection", SQLSTATE(22003) "overflow in calculation");
1336 : }
1337 :
1338 11 : if ( is_date_nil(val))
1339 : continue;
1340 11 : if (s > 0 && (val < f || val >= l) )
1341 0 : continue;
1342 11 : if (s < 0 && (val <= l || val > f) )
1343 0 : continue;
1344 11 : *v++ = val;
1345 11 : c++;
1346 : }
1347 35 : } else if ( tpe == TYPE_timestamp){
1348 35 : timestamp f,l, val;
1349 35 : lng s,t;
1350 35 : timestamp *v;
1351 35 : f = *getArgReference_TYPE(stk,p, 1, timestamp);
1352 35 : l = *getArgReference_TYPE(stk,p, 2, timestamp);
1353 35 : if ( p->argc == 3) {
1354 0 : BBPunfix(b->batCacheid);
1355 0 : throw(MAL,"generator.table", SQLSTATE(42000) "Timestamp step missing");
1356 : }
1357 35 : s = *getArgReference_lng(stk,p, 3);
1358 35 : if ( s == 0 ||
1359 35 : (s< 0 && f < l) ||
1360 35 : (s> 0 && l < f) ) {
1361 0 : BBPunfix(b->batCacheid);
1362 0 : throw(MAL,"generator.projection", SQLSTATE(42000) "Illegal range");
1363 : }
1364 :
1365 35 : s *= 1000; /* msec -> usec */
1366 35 : bn = COLnew(0, TYPE_timestamp, cnt, TRANSIENT);
1367 35 : if( bn == NULL){
1368 0 : BBPunfix(b->batCacheid);
1369 0 : throw(MAL,"generator.projection", SQLSTATE(HY013) MAL_MALLOC_FAIL);
1370 : }
1371 :
1372 35 : v = (timestamp*) Tloc(bn,0);
1373 :
1374 89 : for(; cnt-- > 0; o++){
1375 54 : t = ((lng) (ol == NULL ? o : ol[o])) * s;
1376 54 : val = timestamp_add_usec(f, t);
1377 54 : if (is_timestamp_nil(val)) {
1378 0 : BBPunfix(b->batCacheid);
1379 0 : BBPreclaim(bn);
1380 0 : throw(MAL, "generator.projection", SQLSTATE(22003) "overflow in calculation");
1381 : }
1382 :
1383 54 : if ( is_timestamp_nil(val))
1384 : continue;
1385 54 : if (s > 0 && (val < f || val >= l) )
1386 0 : continue;
1387 54 : if (s < 0 && (val <= l || val > f) )
1388 0 : continue;
1389 54 : *v++ = val;
1390 54 : c++;
1391 : }
1392 : }
1393 : }
1394 :
1395 : /* administrative wrapup of the projection */
1396 375 : BBPunfix(b->batCacheid);
1397 375 : if( bn){
1398 375 : BATsetcount(bn,c);
1399 375 : bn->tsorted = bn->trevsorted = false;
1400 375 : bn->tkey = false;
1401 375 : bn->tnil = false;
1402 375 : bn->tnonil = false;
1403 375 : *getArgReference_bat(stk,pci,0) = bn->batCacheid;
1404 375 : BBPkeepref(bn);
1405 : }
1406 : return MAL_SUCCEED;
1407 : }
1408 :
1409 : /* The operands of a join operation can either be defined on a generator */
1410 : #define VLTjoin(TPE, ABS) \
1411 : do { \
1412 : TPE f,l,s; TPE *v; BUN w; \
1413 : f = *getArgReference_##TPE(stk,p, 1); \
1414 : l = *getArgReference_##TPE(stk,p, 2); \
1415 : if ( p->argc == 3) \
1416 : s = f<l? (TPE) 1: (TPE)-1; \
1417 : else \
1418 : s = * getArgReference_##TPE(stk, p, 3); \
1419 : incr = s > 0; \
1420 : v = (TPE*) Tloc(b,0); \
1421 : if ( s == 0 || (f> l && s>0) || (f<l && s < 0)) { \
1422 : BBPunfix(bln->batCacheid); \
1423 : BBPunfix(brn->batCacheid); \
1424 : BBPreclaim(bl); \
1425 : BBPreclaim(br); \
1426 : throw(MAL,"generator.join", SQLSTATE(42000) "Illegal range"); \
1427 : } \
1428 : for( ; cnt >0; cnt--,o++,v++){ \
1429 : w = (BUN) (ABS(*v -f)/ABS(s)); \
1430 : if ( f + (TPE)(w * s) == *v ){ \
1431 : *ol++ = (oid) w; \
1432 : *or++ = o; \
1433 : c++; \
1434 : } \
1435 : } \
1436 : } while (0)
1437 :
1438 0 : str VLTgenerator_join(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1439 : {
1440 0 : BAT *b, *bl = NULL, *br = NULL, *bln = NULL, *brn= NULL;
1441 0 : BUN cnt,c =0;
1442 0 : oid o= 0, *ol, *or;
1443 0 : int tpe, incr=0, materialized = 0;
1444 0 : InstrPtr p = NULL, q = NULL;
1445 0 : str msg = MAL_SUCCEED;
1446 :
1447 0 : (void) cntxt;
1448 : // we assume at most one of the arguments to refer to the generator
1449 0 : p = findGeneratorDefinition(mb,pci,pci->argv[2]);
1450 0 : q = findGeneratorDefinition(mb,pci,pci->argv[3]);
1451 :
1452 0 : if (p == NULL && q == NULL) {
1453 0 : bl = BATdescriptor(*getArgReference_bat(stk, pci, 2));
1454 0 : br = BATdescriptor(*getArgReference_bat(stk, pci, 3));
1455 0 : if (bl == NULL || br == NULL) {
1456 0 : BBPreclaim(bl);
1457 0 : BBPreclaim(br);
1458 0 : throw(MAL,"generator.join", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1459 : }
1460 0 : gdk_return rc = BATjoin(&bln, &brn, bl, br, NULL, NULL, false, BUN_NONE);
1461 0 : BBPunfix(bl->batCacheid);
1462 0 : BBPunfix(br->batCacheid);
1463 0 : if (rc != GDK_SUCCEED)
1464 0 : throw(MAL,"generator.join", GDK_EXCEPTION);
1465 0 : *getArgReference_bat(stk, pci, 0) = bln->batCacheid;
1466 0 : *getArgReference_bat(stk, pci, 1) = brn->batCacheid;
1467 0 : BBPkeepref(bln);
1468 0 : BBPkeepref(brn);
1469 0 : return MAL_SUCCEED;
1470 : }
1471 :
1472 0 : if( p == NULL){
1473 0 : bl = BATdescriptor(*getArgReference_bat(stk,pci,2));
1474 0 : if( bl == NULL)
1475 0 : throw(MAL,"generator.join", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1476 : }
1477 0 : if ( q == NULL){
1478 : /* p != NULL, hence bl == NULL */
1479 0 : br = BATdescriptor(*getArgReference_bat(stk,pci,3));
1480 0 : if( br == NULL)
1481 0 : throw(MAL,"generator.join", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1482 : }
1483 :
1484 : // in case of both generators || getModuleId(q) == generatorRef)materialize the 'smallest' one first
1485 : // or implement more knowledge, postponed
1486 0 : if (p && q ){
1487 0 : msg = VLTgenerator_table_(&bl, cntxt, mb, stk, p);
1488 0 : if( msg || bl == NULL )
1489 0 : throw(MAL,"generator.join",SQLSTATE(42000) "Join over generator pairs not supported");
1490 : else
1491 : p = NULL;
1492 : materialized =1;
1493 : }
1494 :
1495 : // switch roles to have a single target bat[:oid,:any] designated
1496 : // by b and reference instruction p for the generator
1497 0 : b = q? bl : br;
1498 0 : p = q? q : p;
1499 0 : cnt = BATcount(b);
1500 0 : tpe = b->ttype;
1501 0 : o= b->hseqbase;
1502 :
1503 0 : bln = COLnew(0,TYPE_oid, cnt, TRANSIENT);
1504 0 : brn = COLnew(0,TYPE_oid, cnt, TRANSIENT);
1505 0 : if( bln == NULL || brn == NULL){
1506 0 : BBPreclaim(bln);
1507 0 : BBPreclaim(brn);
1508 0 : BBPreclaim(bl);
1509 0 : BBPreclaim(br);
1510 0 : throw(MAL,"generator.join", SQLSTATE(HY013) MAL_MALLOC_FAIL);
1511 : }
1512 0 : ol = (oid*) Tloc(bln,0);
1513 0 : or = (oid*) Tloc(brn,0);
1514 :
1515 : /* The actual join code for generators be injected here */
1516 0 : switch(tpe){
1517 0 : case TYPE_bte: VLTjoin(bte,abs); break;
1518 0 : case TYPE_sht: VLTjoin(sht,abs); break;
1519 0 : case TYPE_int: VLTjoin(int,abs); break;
1520 0 : case TYPE_lng: VLTjoin(lng,llabs); break;
1521 : #ifdef HAVE_HGE
1522 0 : case TYPE_hge: VLTjoin(hge,HGE_ABS); break;
1523 : #endif
1524 0 : case TYPE_flt: VLTjoin(flt,fabsf); break;
1525 0 : case TYPE_dbl: VLTjoin(dbl,fabs); break;
1526 0 : default:
1527 0 : if(tpe == TYPE_date || tpe == TYPE_timestamp){
1528 : // it is easier to produce the date or timestamp series
1529 : // then to estimate the possible index
1530 0 : }
1531 0 : BBPunfix(bln->batCacheid);
1532 0 : BBPunfix(brn->batCacheid);
1533 0 : BBPreclaim(bl);
1534 0 : BBPreclaim(br);
1535 0 : throw(MAL,"generator.join", SQLSTATE(42000) "Illegal type");
1536 : }
1537 :
1538 0 : BATsetcount(bln,c);
1539 0 : bln->tsorted = bln->trevsorted = false;
1540 0 : bln->tkey = false;
1541 0 : bln->tnil = false;
1542 0 : bln->tnonil = false;
1543 0 : bln->tsorted = incr || c <= 1;
1544 0 : bln->trevsorted = !incr || c <= 1;
1545 :
1546 0 : BATsetcount(brn,c);
1547 0 : brn->tsorted = brn->trevsorted = false;
1548 0 : brn->tkey = false;
1549 0 : brn->tnil = false;
1550 0 : brn->tnonil = false;
1551 0 : brn->tsorted = incr || c <= 1;
1552 0 : brn->trevsorted = !incr || c <= 1;
1553 0 : if( q){
1554 0 : *getArgReference_bat(stk,pci,0) = brn->batCacheid;
1555 0 : BBPkeepref(brn);
1556 0 : *getArgReference_bat(stk,pci,1) = bln->batCacheid;
1557 0 : BBPkeepref(bln);
1558 : } else {
1559 0 : *getArgReference_bat(stk,pci,0) = bln->batCacheid;
1560 0 : BBPkeepref(bln);
1561 0 : *getArgReference_bat(stk,pci,1) = brn->batCacheid;
1562 0 : BBPkeepref(brn);
1563 : }
1564 0 : if ( materialized){
1565 0 : BBPreclaim(bl);
1566 0 : bl = 0;
1567 : }
1568 0 : BBPreclaim(bl);
1569 0 : BBPreclaim(br);
1570 : return msg;
1571 : }
1572 :
1573 : #define VLTrangeExpand() \
1574 : do { \
1575 : limit+= cnt * (limit/(done?done:1)+1); \
1576 : if (BATextend(bln, limit) != GDK_SUCCEED) { \
1577 : BBPunfix(blow->batCacheid); \
1578 : BBPunfix(bhgh->batCacheid); \
1579 : BBPunfix(bln->batCacheid); \
1580 : BBPunfix(brn->batCacheid); \
1581 : throw(MAL,"generator.rangejoin", SQLSTATE(HY013) MAL_MALLOC_FAIL); \
1582 : } \
1583 : if (BATextend(brn, limit) != GDK_SUCCEED) { \
1584 : BBPunfix(blow->batCacheid); \
1585 : BBPunfix(bhgh->batCacheid); \
1586 : BBPunfix(bln->batCacheid); \
1587 : BBPunfix(brn->batCacheid); \
1588 : throw(MAL,"generator.rangejoin", SQLSTATE(HY013) MAL_MALLOC_FAIL); \
1589 : } \
1590 : ol = (oid*) Tloc(bln,0) + c; \
1591 : or = (oid*) Tloc(brn,0) + c; \
1592 : } while (0)
1593 :
1594 : /* The operands of a join operation can either be defined on a generator */
1595 : #define VLTrangejoin(TPE, ABS, FLOOR) \
1596 : do { \
1597 : TPE f,f1,l,s; TPE *vlow,*vhgh; BUN w; \
1598 : f = *getArgReference_##TPE(stk,p, 1); \
1599 : l = *getArgReference_##TPE(stk,p, 2); \
1600 : if ( p->argc == 3) \
1601 : s = f<l? (TPE) 1: (TPE)-1; \
1602 : else \
1603 : s = * getArgReference_##TPE(stk, p, 3); \
1604 : incr = s > 0; \
1605 : if ( s == 0 || (f> l && s>0) || (f<l && s < 0)) { \
1606 : BBPreclaim(bln); \
1607 : BBPreclaim(brn); \
1608 : BBPreclaim(blow); \
1609 : BBPreclaim(bhgh); \
1610 : throw(MAL,"generator.rangejoin", SQLSTATE(42000) "Illegal range"); \
1611 : } \
1612 : vlow = (TPE*) Tloc(blow,0); \
1613 : vhgh = (TPE*) Tloc(bhgh,0); \
1614 : for( ; cnt >0; cnt--, done++, o++,vlow++,vhgh++){ \
1615 : f1 = f + FLOOR(ABS(*vlow-f)/ABS(s)) * s; \
1616 : if ( f1 < *vlow ) \
1617 : f1+= s; \
1618 : w = (BUN) FLOOR(ABS(f1-f)/ABS(s)); \
1619 : for( ; (f1 > *vlow || (li && f1 == *vlow)) && (f1 < *vhgh || (ri && f1 == *vhgh)); f1 += s, w++){ \
1620 : if(c == limit) \
1621 : VLTrangeExpand(); \
1622 : *ol++ = (oid) w; \
1623 : *or++ = o; \
1624 : c++; \
1625 : } \
1626 : } \
1627 : } while (0)
1628 :
1629 4 : str VLTgenerator_rangejoin(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1630 : {
1631 4 : BAT *blow = NULL, *bhgh = NULL, *bln = NULL, *brn= NULL;
1632 4 : bit li,ri;
1633 4 : BUN limit, cnt, done=0, c =0;
1634 4 : oid o= 0, *ol, *or;
1635 4 : int tpe, incr=0;
1636 4 : InstrPtr p = NULL;
1637 4 : str msg = MAL_SUCCEED;
1638 :
1639 4 : (void) cntxt;
1640 : // the left join argument should be a generator
1641 4 : p = findGeneratorDefinition(mb,pci,pci->argv[2]);
1642 4 : if( p == NULL)
1643 0 : throw(MAL,"generator.rangejoin",SQLSTATE(42000) "Invalid arguments");
1644 :
1645 4 : blow = BATdescriptor(*getArgReference_bat(stk,pci,3));
1646 4 : if( blow == NULL)
1647 0 : throw(MAL,"generator.rangejoin", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1648 :
1649 4 : bhgh = BATdescriptor(*getArgReference_bat(stk,pci,4));
1650 4 : if( bhgh == NULL){
1651 0 : BBPunfix(blow->batCacheid);
1652 0 : throw(MAL,"generator.rangejoin", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1653 : }
1654 : /* ToDo handle cands ie arguments 5,6 */
1655 4 : li = *getArgReference_bit(stk,pci,7);
1656 4 : ri = *getArgReference_bit(stk,pci,8);
1657 4 : bit anti = *getArgReference_bit(stk,pci,9);
1658 4 : bit nil = *getArgReference_bit(stk,pci,10);
1659 4 : lng estimate = *getArgReference_lng(stk,pci,11);
1660 : /* ToDo handle anti, symmetric and estimate */
1661 4 : (void)anti;
1662 4 : (void)nil;
1663 4 : (void)estimate;
1664 :
1665 4 : cnt = BATcount(blow);
1666 4 : limit = 2 * cnt; //top off result before expansion
1667 4 : tpe = blow->ttype;
1668 4 : o= blow->hseqbase;
1669 :
1670 4 : bln = COLnew(0,TYPE_oid, limit, TRANSIENT);
1671 4 : brn = COLnew(0,TYPE_oid, limit, TRANSIENT);
1672 4 : if( bln == NULL || brn == NULL){
1673 0 : BBPreclaim(bln);
1674 0 : BBPreclaim(brn);
1675 0 : BBPreclaim(blow);
1676 0 : BBPreclaim(bhgh);
1677 0 : throw(MAL,"generator.rangejoin", SQLSTATE(HY013) MAL_MALLOC_FAIL);
1678 : }
1679 4 : ol = (oid*) Tloc(bln,0);
1680 4 : or = (oid*) Tloc(brn,0);
1681 :
1682 : /* The actual join code for generators be injected here */
1683 4 : switch(tpe){
1684 0 : case TYPE_bte: VLTrangejoin(bte,abs,IDENTITY); break;
1685 0 : case TYPE_sht: VLTrangejoin(sht,abs,IDENTITY); break;
1686 13 : case TYPE_int: VLTrangejoin(int,abs,IDENTITY); break;
1687 0 : case TYPE_lng: VLTrangejoin(lng,llabs,IDENTITY); break;
1688 : #ifdef HAVE_HGE
1689 0 : case TYPE_hge: VLTrangejoin(hge,HGE_ABS,IDENTITY); break;
1690 : #endif
1691 0 : case TYPE_flt: VLTrangejoin(flt,fabsf,floorf); break;
1692 0 : case TYPE_dbl: VLTrangejoin(dbl,fabs,floor); break;
1693 0 : default:
1694 0 : if( tpe == TYPE_date || tpe == TYPE_timestamp){
1695 : // it is easier to produce the date or timestamp series
1696 : // then to estimate the possible index
1697 0 : }
1698 0 : BBPreclaim(bln);
1699 0 : BBPreclaim(brn);
1700 0 : BBPreclaim(blow);
1701 0 : BBPreclaim(bhgh);
1702 0 : throw(MAL,"generator.rangejoin","Illegal type");
1703 : }
1704 :
1705 4 : BATsetcount(bln,c);
1706 4 : bln->tsorted = bln->trevsorted = false;
1707 4 : bln->tkey = false;
1708 4 : bln->tnil = false;
1709 4 : bln->tnonil = false;
1710 4 : bln->tsorted = incr || c <= 1;
1711 4 : bln->trevsorted = !incr || c <= 1;
1712 :
1713 4 : BATsetcount(brn,c);
1714 4 : brn->tsorted = brn->trevsorted = false;
1715 4 : brn->tkey = false;
1716 4 : brn->tnil = false;
1717 4 : brn->tnonil = false;
1718 4 : brn->tsorted = incr || c <= 1;
1719 4 : brn->trevsorted = !incr || c <= 1;
1720 4 : *getArgReference_bat(stk,pci,0) = bln->batCacheid;
1721 4 : BBPkeepref(bln);
1722 4 : *getArgReference_bat(stk,pci,1) = brn->batCacheid;
1723 4 : BBPkeepref(brn);
1724 4 : BBPreclaim(blow);
1725 4 : BBPreclaim(bhgh);
1726 4 : return msg;
1727 : }
1728 :
1729 : #include "mel.h"
1730 : static mel_func generator_init_funcs[] = {
1731 : pattern("generator", "series", VLTgenerator_table, false, "", args(1,3, batarg("",bte),arg("first",bte),arg("limit",bte))),
1732 : pattern("generator", "series", VLTgenerator_table, false, "", args(1,3, batarg("",sht),arg("first",sht),arg("limit",sht))),
1733 : pattern("generator", "series", VLTgenerator_table, false, "", args(1,3, batarg("",int),arg("first",int),arg("limit",int))),
1734 : pattern("generator", "series", VLTgenerator_table, false, "", args(1,3, batarg("",lng),arg("first",lng),arg("limit",lng))),
1735 : pattern("generator", "series", VLTgenerator_table, false, "", args(1,3, batarg("",flt),arg("first",flt),arg("limit",flt))),
1736 : pattern("generator", "series", VLTgenerator_table, false, "", args(1,3, batarg("",dbl),arg("first",dbl),arg("limit",dbl))),
1737 : pattern("generator", "series", VLTgenerator_table, false, "", args(1,4, batarg("",bte),arg("first",bte),arg("limit",bte),arg("step",bte))),
1738 : pattern("generator", "series", VLTgenerator_table, false, "", args(1,4, batarg("",sht),arg("first",sht),arg("limit",sht),arg("step",sht))),
1739 : pattern("generator", "series", VLTgenerator_table, false, "", args(1,4, batarg("",int),arg("first",int),arg("limit",int),arg("step",int))),
1740 : pattern("generator", "series", VLTgenerator_table, false, "", args(1,4, batarg("",lng),arg("first",lng),arg("limit",lng),arg("step",lng))),
1741 : pattern("generator", "series", VLTgenerator_table, false, "", args(1,4, batarg("",flt),arg("first",flt),arg("limit",flt),arg("step",flt))),
1742 : pattern("generator", "series", VLTgenerator_table, false, "Create and materialize a generator table", args(1,4, batarg("",dbl),arg("first",dbl),arg("limit",dbl),arg("step",dbl))),
1743 : pattern("generator", "series", VLTgenerator_table, false, "date generator with step size in months", args(1,4, batarg("",date),arg("first",date),arg("limit",date),arg("step",int))),
1744 : pattern("generator", "series", VLTgenerator_table, false, "date generator with step size in days", args(1,4, batarg("",date),arg("first",date),arg("limit",date),arg("step",lng))),
1745 : pattern("generator", "series", VLTgenerator_table, false, "", args(1,4, batarg("",timestamp),arg("first",timestamp),arg("limit",timestamp),arg("step",lng))),
1746 : pattern("generator", "parameters", VLTgenerator_noop, false, "", args(1,4, batarg("",bte),arg("first",bte),arg("limit",bte),arg("step",bte))),
1747 : pattern("generator", "parameters", VLTgenerator_noop, false, "", args(1,4, batarg("",sht),arg("first",sht),arg("limit",sht),arg("step",sht))),
1748 : pattern("generator", "parameters", VLTgenerator_noop, false, "", args(1,4, batarg("",int),arg("first",int),arg("limit",int),arg("step",int))),
1749 : pattern("generator", "parameters", VLTgenerator_noop, false, "", args(1,4, batarg("",lng),arg("first",lng),arg("limit",lng),arg("step",lng))),
1750 : pattern("generator", "parameters", VLTgenerator_noop, false, "", args(1,4, batarg("",flt),arg("first",flt),arg("limit",flt),arg("step",flt))),
1751 : pattern("generator", "parameters", VLTgenerator_noop, false, "", args(1,4, batarg("",dbl),arg("first",dbl),arg("limit",dbl),arg("step",dbl))),
1752 : pattern("generator", "parameters", VLTgenerator_noop, false, "Retain the table definition, but don't materialize (months)", args(1,4, batarg("",date),arg("first",date),arg("limit",date),arg("step",int))),
1753 : pattern("generator", "parameters", VLTgenerator_noop, false, "Retain the table definition, but don't materialize (days)", args(1,4, batarg("",date),arg("first",date),arg("limit",date),arg("step",lng))),
1754 : pattern("generator", "parameters", VLTgenerator_noop, false, "Retain the table definition, but don't materialize", args(1,4, batarg("",timestamp),arg("first",timestamp),arg("limit",timestamp),arg("step",lng))),
1755 : pattern("generator", "parameters", VLTgenerator_noop, false, "", args(1,3, batarg("",bte),arg("first",bte),arg("limit",bte))),
1756 : pattern("generator", "parameters", VLTgenerator_noop, false, "", args(1,3, batarg("",sht),arg("first",sht),arg("limit",sht))),
1757 : pattern("generator", "parameters", VLTgenerator_noop, false, "", args(1,3, batarg("",int),arg("first",int),arg("limit",int))),
1758 : pattern("generator", "parameters", VLTgenerator_noop, false, "", args(1,3, batarg("",lng),arg("first",lng),arg("limit",lng))),
1759 : pattern("generator", "parameters", VLTgenerator_noop, false, "", args(1,3, batarg("",flt),arg("first",flt),arg("limit",flt))),
1760 : pattern("generator", "parameters", VLTgenerator_noop, false, "", args(1,3, batarg("",dbl),arg("first",dbl),arg("limit",dbl))),
1761 : pattern("generator", "thetaselect", VLTgenerator_thetasubselect, false, "", args(1,5, batarg("",oid),batarg("b",bte),batarg("cnd",oid),arg("low",bte),arg("oper",str))),
1762 : pattern("generator", "thetaselect", VLTgenerator_thetasubselect, false, "", args(1,5, batarg("",oid),batarg("b",sht),batarg("cnd",oid),arg("low",sht),arg("oper",str))),
1763 : pattern("generator", "thetaselect", VLTgenerator_thetasubselect, false, "", args(1,5, batarg("",oid),batarg("b",int),batarg("cnd",oid),arg("low",int),arg("oper",str))),
1764 : pattern("generator", "thetaselect", VLTgenerator_thetasubselect, false, "", args(1,5, batarg("",oid),batarg("b",lng),batarg("cnd",oid),arg("low",lng),arg("oper",str))),
1765 : pattern("generator", "thetaselect", VLTgenerator_thetasubselect, false, "", args(1,5, batarg("",oid),batarg("b",flt),batarg("cnd",oid),arg("low",flt),arg("oper",str))),
1766 : pattern("generator", "thetaselect", VLTgenerator_thetasubselect, false, "", args(1,5, batarg("",oid),batarg("b",dbl),batarg("cnd",oid),arg("low",dbl),arg("oper",str))),
1767 : pattern("generator", "thetaselect", VLTgenerator_thetasubselect, false, "Overloaded selection routine", args(1,5, batarg("",oid),batarg("b",date),batarg("cnd",oid),arg("low",date),arg("oper",str))),
1768 : pattern("generator", "thetaselect", VLTgenerator_thetasubselect, false, "Overloaded selection routine", args(1,5, batarg("",oid),batarg("b",timestamp),batarg("cnd",oid),arg("low",timestamp),arg("oper",str))),
1769 : pattern("generator", "select", VLTgenerator_subselect, false, "", args(1,7, batarg("",oid),batarg("b",bte),arg("low",bte),arg("high",bte),arg("li",bit),arg("hi",bit),arg("anti",bit))),
1770 : pattern("generator", "select", VLTgenerator_subselect, false, "", args(1,7, batarg("",oid),batarg("b",sht),arg("low",sht),arg("high",sht),arg("li",bit),arg("hi",bit),arg("anti",bit))),
1771 : pattern("generator", "select", VLTgenerator_subselect, false, "", args(1,7, batarg("",oid),batarg("b",int),arg("low",int),arg("high",int),arg("li",bit),arg("hi",bit),arg("anti",bit))),
1772 : pattern("generator", "select", VLTgenerator_subselect, false, "", args(1,7, batarg("",oid),batarg("b",lng),arg("low",lng),arg("high",lng),arg("li",bit),arg("hi",bit),arg("anti",bit))),
1773 : pattern("generator", "select", VLTgenerator_subselect, false, "", args(1,7, batarg("",oid),batarg("b",flt),arg("low",flt),arg("high",flt),arg("li",bit),arg("hi",bit),arg("anti",bit))),
1774 : pattern("generator", "select", VLTgenerator_subselect, false, "", args(1,7, batarg("",oid),batarg("b",dbl),arg("low",dbl),arg("high",dbl),arg("li",bit),arg("hi",bit),arg("anti",bit))),
1775 : pattern("generator", "select", VLTgenerator_subselect, false, "", args(1,7, batarg("",oid),batarg("b",date),arg("low",date),arg("high",date),arg("li",bit),arg("hi",bit),arg("anti",bit))),
1776 : pattern("generator", "select", VLTgenerator_subselect, false, "Overloaded selection routine", args(1,7, batarg("",oid),batarg("b",timestamp),arg("low",timestamp),arg("high",timestamp),arg("li",bit),arg("hi",bit),arg("anti",bit))),
1777 : pattern("generator", "select", VLTgenerator_subselect, false, "", args(1,8, batarg("",oid),batarg("b",bte),batarg("cand",oid),arg("low",bte),arg("high",bte),arg("li",bit),arg("hi",bit),arg("anti",bit))),
1778 : pattern("generator", "select", VLTgenerator_subselect, false, "", args(1,8, batarg("",oid),batarg("b",sht),batarg("cand",oid),arg("low",sht),arg("high",sht),arg("li",bit),arg("hi",bit),arg("anti",bit))),
1779 : pattern("generator", "select", VLTgenerator_subselect, false, "", args(1,8, batarg("",oid),batarg("b",int),batarg("cand",oid),arg("low",int),arg("high",int),arg("li",bit),arg("hi",bit),arg("anti",bit))),
1780 : pattern("generator", "select", VLTgenerator_subselect, false, "", args(1,8, batarg("",oid),batarg("b",lng),batarg("cand",oid),arg("low",lng),arg("high",lng),arg("li",bit),arg("hi",bit),arg("anti",bit))),
1781 : pattern("generator", "select", VLTgenerator_subselect, false, "", args(1,8, batarg("",oid),batarg("b",flt),batarg("cand",oid),arg("low",flt),arg("high",flt),arg("li",bit),arg("hi",bit),arg("anti",bit))),
1782 : pattern("generator", "select", VLTgenerator_subselect, false, "", args(1,8, batarg("",oid),batarg("b",dbl),batarg("cand",oid),arg("low",dbl),arg("high",dbl),arg("li",bit),arg("hi",bit),arg("anti",bit))),
1783 : pattern("generator", "select", VLTgenerator_subselect, false, "", args(1,8, batarg("",oid),batarg("b",date),batarg("cand",oid),arg("low",date),arg("high",date),arg("li",bit),arg("hi",bit),arg("anti",bit))),
1784 : pattern("generator", "select", VLTgenerator_subselect, false, "Overloaded selection routine", args(1,8, batarg("",oid),batarg("b",timestamp),batarg("cand",oid),arg("low",timestamp),arg("high",timestamp),arg("li",bit),arg("hi",bit),arg("anti",bit))),
1785 : pattern("generator", "projection", VLTgenerator_projection, false, "", args(1,3, batarg("",bte),batarg("b",oid),batarg("cand",bte))),
1786 : pattern("generator", "projection", VLTgenerator_projection, false, "", args(1,3, batarg("",sht),batarg("b",oid),batarg("cand",sht))),
1787 : pattern("generator", "projection", VLTgenerator_projection, false, "", args(1,3, batarg("",int),batarg("b",oid),batarg("cand",int))),
1788 : pattern("generator", "projection", VLTgenerator_projection, false, "", args(1,3, batarg("",lng),batarg("b",oid),batarg("cand",lng))),
1789 : pattern("generator", "projection", VLTgenerator_projection, false, "", args(1,3, batarg("",flt),batarg("b",oid),batarg("cand",flt))),
1790 : pattern("generator", "projection", VLTgenerator_projection, false, "", args(1,3, batarg("",dbl),batarg("b",oid),batarg("cand",dbl))),
1791 : pattern("generator", "projection", VLTgenerator_projection, false, "", args(1,3, batarg("",date),batarg("b",oid),batarg("cand",date))),
1792 : pattern("generator", "projection", VLTgenerator_projection, false, "Overloaded projection operation", args(1,3, batarg("",timestamp),batarg("b",oid),batarg("cand",timestamp))),
1793 : pattern("generator", "join", VLTgenerator_join, false, "", args(2,4, batarg("l",oid),batarg("r",oid),batarg("b",bte),batarg("gen",bte))),
1794 : pattern("generator", "join", VLTgenerator_join, false, "", args(2,4, batarg("l",oid),batarg("r",oid),batarg("b",sht),batarg("gen",sht))),
1795 : pattern("generator", "join", VLTgenerator_join, false, "", args(2,4, batarg("l",oid),batarg("r",oid),batarg("b",int),batarg("gen",int))),
1796 : pattern("generator", "join", VLTgenerator_join, false, "", args(2,4, batarg("l",oid),batarg("r",oid),batarg("b",lng),batarg("gen",lng))),
1797 : pattern("generator", "join", VLTgenerator_join, false, "", args(2,4, batarg("l",oid),batarg("r",oid),batarg("b",flt),batarg("gen",flt))),
1798 : pattern("generator", "join", VLTgenerator_join, false, "Overloaded join operation", args(2,4, batarg("l",oid),batarg("r",oid),batarg("b",dbl),batarg("gen",dbl))),
1799 : pattern("generator", "rangejoin", VLTgenerator_rangejoin, false, "", args(2,12, batarg("l",oid),batarg("r",oid),batarg("gen",bte),batarg("low",bte),batarg("hgh",bte),batarg("lc",oid),batarg("rc",oid),arg("li",bit),arg("ri",bit),arg("anti",bit),arg("sym",bit),arg("est",lng))),
1800 : pattern("generator", "rangejoin", VLTgenerator_rangejoin, false, "", args(2,12, batarg("l",oid),batarg("r",oid),batarg("gen",sht),batarg("low",sht),batarg("hgh",sht),batarg("lc",oid),batarg("rc",oid),arg("li",bit),arg("ri",bit),arg("anti",bit),arg("sym",bit),arg("est",lng))),
1801 : pattern("generator", "rangejoin", VLTgenerator_rangejoin, false, "", args(2,12, batarg("l",oid),batarg("r",oid),batarg("gen",int),batarg("low",int),batarg("hgh",int),batarg("lc",oid),batarg("rc",oid),arg("li",bit),arg("ri",bit),arg("anti",bit),arg("sym",bit),arg("est",lng))),
1802 : pattern("generator", "rangejoin", VLTgenerator_rangejoin, false, "", args(2,12, batarg("l",oid),batarg("r",oid),batarg("gen",lng),batarg("low",lng),batarg("hgh",lng),batarg("lc",oid),batarg("rc",oid),arg("li",bit),arg("ri",bit),arg("anti",bit),arg("sym",bit),arg("est",lng))),
1803 : pattern("generator", "rangejoin", VLTgenerator_rangejoin, false, "", args(2,12, batarg("l",oid),batarg("r",oid),batarg("gen",flt),batarg("low",flt),batarg("hgh",flt),batarg("lc",oid),batarg("rc",oid),arg("li",bit),arg("ri",bit),arg("anti",bit),arg("sym",bit),arg("est",lng))),
1804 : pattern("generator", "rangejoin", VLTgenerator_rangejoin, false, "Overloaded range join operation", args(2,12, batarg("l",oid),batarg("r",oid),batarg("gen",dbl),batarg("low",dbl),batarg("hgh",dbl),batarg("lc",oid),batarg("rc",oid),arg("li",bit),arg("ri",bit),arg("anti",bit),arg("sym",bit),arg("est",lng))),
1805 : #ifdef HAVE_HGE
1806 : pattern("generator", "series", VLTgenerator_table, false, "", args(1,3, batarg("",hge),arg("first",hge),arg("limit",hge))),
1807 : pattern("generator", "series", VLTgenerator_table, false, "Create and materialize a generator table", args(1,4, batarg("",hge),arg("first",hge),arg("limit",hge),arg("step",hge))),
1808 : pattern("generator", "parameters", VLTgenerator_noop, false, "Retain the table definition, but don't materialize", args(1,4, batarg("",hge),arg("first",hge),arg("limit",hge),arg("step",hge))),
1809 : pattern("generator", "parameters", VLTgenerator_noop, false, "", args(1,3, batarg("",hge),arg("first",hge),arg("limit",hge))),
1810 : pattern("generator", "thetaselect", VLTgenerator_thetasubselect, false, "Overloaded selection routine", args(1,5, batarg("",oid),batarg("b",hge),batarg("cnd",oid),arg("low",hge),arg("oper",str))),
1811 : pattern("generator", "select", VLTgenerator_subselect, false, "Overloaded selection routine", args(1,7, batarg("",oid),batarg("b",hge),arg("low",hge),arg("high",hge),arg("li",bit),arg("hi",bit),arg("anti",bit))),
1812 : pattern("generator", "select", VLTgenerator_subselect, false, "Overloaded selection routine", args(1,8, batarg("",oid),batarg("b",hge),batarg("cand",oid),arg("low",hge),arg("high",hge),arg("li",bit),arg("hi",bit),arg("anti",bit))),
1813 : pattern("generator", "projection", VLTgenerator_projection, false, "Overloaded projection operation", args(1,3, batarg("",hge),batarg("b",oid),batarg("cand",hge))),
1814 : pattern("generator", "join", VLTgenerator_join, false, "Overloaded join operation", args(2,4, batarg("l",oid),batarg("r",oid),batarg("b",hge),batarg("gen",hge))),
1815 : #endif
1816 : { .imp=NULL }
1817 : };
1818 : #include "mal_import.h"
1819 : #ifdef _MSC_VER
1820 : #undef read
1821 : #pragma section(".CRT$XCU",read)
1822 : #endif
1823 340 : LIB_STARTUP_FUNC(init_generator_mal)
1824 340 : { mal_module("generator", NULL, generator_init_funcs); }
|