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