1/*
2 * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5 *
6 * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
7 */
8
9/* this file is included multiple times by gdk_calc.c */
10
11static BUN
12op_typeswitchloop(const void *lft, int tp1, int incr1, const char *hp1, int wd1,
13 const void *rgt, int tp2, int incr2, const char *hp2, int wd2,
14 TPE *restrict dst, BUN cnt,
15 struct canditer *restrict ci, oid candoff,
16 bool nonil,
17#ifdef NIL_MATCHES_FLAG
18 bool nil_matches,
19#endif
20 const char *func)
21{
22 BUN nils = 0;
23 BUN i, j, k = 0;
24 const void *restrict nil;
25 int (*atomcmp)(const void *, const void *);
26 oid x = canditer_next(ci) - candoff;
27
28 switch (tp1) {
29 case TYPE_void: {
30 assert(incr1 == 1);
31 assert(tp2 == TYPE_oid || incr2 == 1); /* if void, incr2==1 */
32 oid v = lft ? * (const oid *) lft : oid_nil;
33 do {
34 TPE res;
35 while (k < x) {
36 dst[k++] = TPE_nil;
37 nils++;
38 }
39 if (is_oid_nil(v) || tp2 == TYPE_void) {
40 res = is_oid_nil(v) || is_oid_nil(* (const oid *) rgt) ?
41#ifdef NIL_MATCHES_FLAG
42 nil_matches ? OP(is_oid_nil(v), is_oid_nil(* (const oid *) rgt)) :
43#endif
44 TPE_nil :
45 OP(v, * (const oid *) rgt);
46 dst[k] = res;
47 nils += is_TPE_nil(res);
48 } else {
49 j = x * incr2;
50 if (is_oid_nil(((const oid *) rgt)[j])) {
51#ifdef NIL_MATCHES_FLAG
52 if (nil_matches) {
53 dst[k] = OP(false, true);
54 } else
55#endif
56 {
57 nils++;
58 dst[k] = TPE_nil;
59 }
60 } else {
61 dst[k] = OP(v + k, ((const oid *) rgt)[j]);
62 }
63 }
64 k++;
65 x = canditer_next(ci);
66 if (is_oid_nil(x))
67 break;
68 x -= candoff;
69 } while (k < cnt);
70 while (k < cnt) {
71 dst[k++] = TPE_nil;
72 nils++;
73 }
74 break;
75 }
76 case TYPE_bit:
77 if (tp2 != TYPE_bit)
78 goto unsupported;
79 if (nonil)
80 BINARY_3TYPE_FUNC_nonil(bit, bit, TPE, OP);
81#ifdef NIL_MATCHES_FLAG
82 else if (nil_matches)
83 BINARY_3TYPE_FUNC_nilmatch(bit, bit, TPE, OP);
84#endif
85 else
86 BINARY_3TYPE_FUNC(bit, bit, TPE, OP);
87 break;
88 case TYPE_bte:
89 switch (tp2) {
90 case TYPE_bte:
91 btebte:
92 if (nonil)
93 BINARY_3TYPE_FUNC_nonil(bte, bte, TPE, OP);
94#ifdef NIL_MATCHES_FLAG
95 else if (nil_matches)
96 BINARY_3TYPE_FUNC_nilmatch(bte, bte, TPE, OP);
97#endif
98 else
99 BINARY_3TYPE_FUNC(bte, bte, TPE, OP);
100 break;
101 case TYPE_sht:
102 if (nonil)
103 BINARY_3TYPE_FUNC_nonil(bte, sht, TPE, OP);
104#ifdef NIL_MATCHES_FLAG
105 else if (nil_matches)
106 BINARY_3TYPE_FUNC_nilmatch(bte, sht, TPE, OP);
107#endif
108 else
109 BINARY_3TYPE_FUNC(bte, sht, TPE, OP);
110 break;
111 case TYPE_int:
112 if (nonil)
113 BINARY_3TYPE_FUNC_nonil(bte, int, TPE, OP);
114#ifdef NIL_MATCHES_FLAG
115 else if (nil_matches)
116 BINARY_3TYPE_FUNC_nilmatch(bte, int, TPE, OP);
117#endif
118 else
119 BINARY_3TYPE_FUNC(bte, int, TPE, OP);
120 break;
121 case TYPE_lng:
122 if (nonil)
123 BINARY_3TYPE_FUNC_nonil(bte, lng, TPE, OP);
124#ifdef NIL_MATCHES_FLAG
125 else if (nil_matches)
126 BINARY_3TYPE_FUNC_nilmatch(bte, lng, TPE, OP);
127#endif
128 else
129 BINARY_3TYPE_FUNC(bte, lng, TPE, OP);
130 break;
131#ifdef HAVE_HGE
132 case TYPE_hge:
133 if (nonil)
134 BINARY_3TYPE_FUNC_nonil(bte, hge, TPE, OP);
135#ifdef NIL_MATCHES_FLAG
136 else if (nil_matches)
137 BINARY_3TYPE_FUNC_nilmatch(bte, hge, TPE, OP);
138#endif
139 else
140 BINARY_3TYPE_FUNC(bte, hge, TPE, OP);
141 break;
142#endif
143 case TYPE_flt:
144 if (nonil)
145 BINARY_3TYPE_FUNC_nonil(bte, flt, TPE, OP);
146#ifdef NIL_MATCHES_FLAG
147 else if (nil_matches)
148 BINARY_3TYPE_FUNC_nilmatch(bte, flt, TPE, OP);
149#endif
150 else
151 BINARY_3TYPE_FUNC(bte, flt, TPE, OP);
152 break;
153 case TYPE_dbl:
154 if (nonil)
155 BINARY_3TYPE_FUNC_nonil(bte, dbl, TPE, OP);
156#ifdef NIL_MATCHES_FLAG
157 else if (nil_matches)
158 BINARY_3TYPE_FUNC_nilmatch(bte, dbl, TPE, OP);
159#endif
160 else
161 BINARY_3TYPE_FUNC(bte, dbl, TPE, OP);
162 break;
163 default:
164 goto unsupported;
165 }
166 break;
167 case TYPE_sht:
168 switch (tp2) {
169 case TYPE_bte:
170 if (nonil)
171 BINARY_3TYPE_FUNC_nonil(sht, bte, TPE, OP);
172#ifdef NIL_MATCHES_FLAG
173 else if (nil_matches)
174 BINARY_3TYPE_FUNC_nilmatch(sht, bte, TPE, OP);
175#endif
176 else
177 BINARY_3TYPE_FUNC(sht, bte, TPE, OP);
178 break;
179 case TYPE_sht:
180 shtsht:
181 if (nonil)
182 BINARY_3TYPE_FUNC_nonil(sht, sht, TPE, OP);
183#ifdef NIL_MATCHES_FLAG
184 else if (nil_matches)
185 BINARY_3TYPE_FUNC_nilmatch(sht, sht, TPE, OP);
186#endif
187 else
188 BINARY_3TYPE_FUNC(sht, sht, TPE, OP);
189 break;
190 case TYPE_int:
191 if (nonil)
192 BINARY_3TYPE_FUNC_nonil(sht, int, TPE, OP);
193#ifdef NIL_MATCHES_FLAG
194 else if (nil_matches)
195 BINARY_3TYPE_FUNC_nilmatch(sht, int, TPE, OP);
196#endif
197 else
198 BINARY_3TYPE_FUNC(sht, int, TPE, OP);
199 break;
200 case TYPE_lng:
201 if (nonil)
202 BINARY_3TYPE_FUNC_nonil(sht, lng, TPE, OP);
203#ifdef NIL_MATCHES_FLAG
204 else if (nil_matches)
205 BINARY_3TYPE_FUNC_nilmatch(sht, lng, TPE, OP);
206#endif
207 else
208 BINARY_3TYPE_FUNC(sht, lng, TPE, OP);
209 break;
210#ifdef HAVE_HGE
211 case TYPE_hge:
212 if (nonil)
213 BINARY_3TYPE_FUNC_nonil(sht, hge, TPE, OP);
214#ifdef NIL_MATCHES_FLAG
215 else if (nil_matches)
216 BINARY_3TYPE_FUNC_nilmatch(sht, hge, TPE, OP);
217#endif
218 else
219 BINARY_3TYPE_FUNC(sht, hge, TPE, OP);
220 break;
221#endif
222 case TYPE_flt:
223 if (nonil)
224 BINARY_3TYPE_FUNC_nonil(sht, flt, TPE, OP);
225#ifdef NIL_MATCHES_FLAG
226 else if (nil_matches)
227 BINARY_3TYPE_FUNC_nilmatch(sht, flt, TPE, OP);
228#endif
229 else
230 BINARY_3TYPE_FUNC(sht, flt, TPE, OP);
231 break;
232 case TYPE_dbl:
233 if (nonil)
234 BINARY_3TYPE_FUNC_nonil(sht, dbl, TPE, OP);
235#ifdef NIL_MATCHES_FLAG
236 else if (nil_matches)
237 BINARY_3TYPE_FUNC_nilmatch(sht, dbl, TPE, OP);
238#endif
239 else
240 BINARY_3TYPE_FUNC(sht, dbl, TPE, OP);
241 break;
242 default:
243 goto unsupported;
244 }
245 break;
246 case TYPE_int:
247 switch (tp2) {
248 case TYPE_bte:
249 if (nonil)
250 BINARY_3TYPE_FUNC_nonil(int, bte, TPE, OP);
251#ifdef NIL_MATCHES_FLAG
252 else if (nil_matches)
253 BINARY_3TYPE_FUNC_nilmatch(int, bte, TPE, OP);
254#endif
255 else
256 BINARY_3TYPE_FUNC(int, bte, TPE, OP);
257 break;
258 case TYPE_sht:
259 if (nonil)
260 BINARY_3TYPE_FUNC_nonil(int, sht, TPE, OP);
261#ifdef NIL_MATCHES_FLAG
262 else if (nil_matches)
263 BINARY_3TYPE_FUNC_nilmatch(int, sht, TPE, OP);
264#endif
265 else
266 BINARY_3TYPE_FUNC(int, sht, TPE, OP);
267 break;
268 case TYPE_int:
269 intint:
270 if (nonil)
271 BINARY_3TYPE_FUNC_nonil(int, int, TPE, OP);
272#ifdef NIL_MATCHES_FLAG
273 else if (nil_matches)
274 BINARY_3TYPE_FUNC_nilmatch(int, int, TPE, OP);
275#endif
276 else
277 BINARY_3TYPE_FUNC(int, int, TPE, OP);
278 break;
279 case TYPE_lng:
280 if (nonil)
281 BINARY_3TYPE_FUNC_nonil(int, lng, TPE, OP);
282#ifdef NIL_MATCHES_FLAG
283 else if (nil_matches)
284 BINARY_3TYPE_FUNC_nilmatch(int, lng, TPE, OP);
285#endif
286 else
287 BINARY_3TYPE_FUNC(int, lng, TPE, OP);
288 break;
289#ifdef HAVE_HGE
290 case TYPE_hge:
291 if (nonil)
292 BINARY_3TYPE_FUNC_nonil(int, hge, TPE, OP);
293#ifdef NIL_MATCHES_FLAG
294 else if (nil_matches)
295 BINARY_3TYPE_FUNC_nilmatch(int, hge, TPE, OP);
296#endif
297 else
298 BINARY_3TYPE_FUNC(int, hge, TPE, OP);
299 break;
300#endif
301 case TYPE_flt:
302 if (nonil)
303 BINARY_3TYPE_FUNC_nonil(int, flt, TPE, OP);
304#ifdef NIL_MATCHES_FLAG
305 else if (nil_matches)
306 BINARY_3TYPE_FUNC_nilmatch(int, flt, TPE, OP);
307#endif
308 else
309 BINARY_3TYPE_FUNC(int, flt, TPE, OP);
310 break;
311 case TYPE_dbl:
312 if (nonil)
313 BINARY_3TYPE_FUNC_nonil(int, dbl, TPE, OP);
314#ifdef NIL_MATCHES_FLAG
315 else if (nil_matches)
316 BINARY_3TYPE_FUNC_nilmatch(int, dbl, TPE, OP);
317#endif
318 else
319 BINARY_3TYPE_FUNC(int, dbl, TPE, OP);
320 break;
321 default:
322 goto unsupported;
323 }
324 break;
325 case TYPE_lng:
326 switch (tp2) {
327 case TYPE_bte:
328 if (nonil)
329 BINARY_3TYPE_FUNC_nonil(lng, bte, TPE, OP);
330#ifdef NIL_MATCHES_FLAG
331 else if (nil_matches)
332 BINARY_3TYPE_FUNC_nilmatch(lng, bte, TPE, OP);
333#endif
334 else
335 BINARY_3TYPE_FUNC(lng, bte, TPE, OP);
336 break;
337 case TYPE_sht:
338 if (nonil)
339 BINARY_3TYPE_FUNC_nonil(lng, sht, TPE, OP);
340#ifdef NIL_MATCHES_FLAG
341 else if (nil_matches)
342 BINARY_3TYPE_FUNC_nilmatch(lng, sht, TPE, OP);
343#endif
344 else
345 BINARY_3TYPE_FUNC(lng, sht, TPE, OP);
346 break;
347 case TYPE_int:
348 if (nonil)
349 BINARY_3TYPE_FUNC_nonil(lng, int, TPE, OP);
350#ifdef NIL_MATCHES_FLAG
351 else if (nil_matches)
352 BINARY_3TYPE_FUNC_nilmatch(lng, int, TPE, OP);
353#endif
354 else
355 BINARY_3TYPE_FUNC(lng, int, TPE, OP);
356 break;
357 case TYPE_lng:
358 lnglng:
359 if (nonil)
360 BINARY_3TYPE_FUNC_nonil(lng, lng, TPE, OP);
361#ifdef NIL_MATCHES_FLAG
362 else if (nil_matches)
363 BINARY_3TYPE_FUNC_nilmatch(lng, lng, TPE, OP);
364#endif
365 else
366 BINARY_3TYPE_FUNC(lng, lng, TPE, OP);
367 break;
368#ifdef HAVE_HGE
369 case TYPE_hge:
370 if (nonil)
371 BINARY_3TYPE_FUNC_nonil(lng, hge, TPE, OP);
372#ifdef NIL_MATCHES_FLAG
373 else if (nil_matches)
374 BINARY_3TYPE_FUNC_nilmatch(lng, hge, TPE, OP);
375#endif
376 else
377 BINARY_3TYPE_FUNC(lng, hge, TPE, OP);
378 break;
379#endif
380 case TYPE_flt:
381 if (nonil)
382 BINARY_3TYPE_FUNC_nonil(lng, flt, TPE, OP);
383#ifdef NIL_MATCHES_FLAG
384 else if (nil_matches)
385 BINARY_3TYPE_FUNC_nilmatch(lng, flt, TPE, OP);
386#endif
387 else
388 BINARY_3TYPE_FUNC(lng, flt, TPE, OP);
389 break;
390 case TYPE_dbl:
391 if (nonil)
392 BINARY_3TYPE_FUNC_nonil(lng, dbl, TPE, OP);
393#ifdef NIL_MATCHES_FLAG
394 else if (nil_matches)
395 BINARY_3TYPE_FUNC_nilmatch(lng, dbl, TPE, OP);
396#endif
397 else
398 BINARY_3TYPE_FUNC(lng, dbl, TPE, OP);
399 break;
400 default:
401 goto unsupported;
402 }
403 break;
404#ifdef HAVE_HGE
405 case TYPE_hge:
406 switch (tp2) {
407 case TYPE_bte:
408 if (nonil)
409 BINARY_3TYPE_FUNC_nonil(hge, bte, TPE, OP);
410#ifdef NIL_MATCHES_FLAG
411 else if (nil_matches)
412 BINARY_3TYPE_FUNC_nilmatch(hge, bte, TPE, OP);
413#endif
414 else
415 BINARY_3TYPE_FUNC(hge, bte, TPE, OP);
416 break;
417 case TYPE_sht:
418 if (nonil)
419 BINARY_3TYPE_FUNC_nonil(hge, sht, TPE, OP);
420#ifdef NIL_MATCHES_FLAG
421 else if (nil_matches)
422 BINARY_3TYPE_FUNC_nilmatch(hge, sht, TPE, OP);
423#endif
424 else
425 BINARY_3TYPE_FUNC(hge, sht, TPE, OP);
426 break;
427 case TYPE_int:
428 if (nonil)
429 BINARY_3TYPE_FUNC_nonil(hge, int, TPE, OP);
430#ifdef NIL_MATCHES_FLAG
431 else if (nil_matches)
432 BINARY_3TYPE_FUNC_nilmatch(hge, int, TPE, OP);
433#endif
434 else
435 BINARY_3TYPE_FUNC(hge, int, TPE, OP);
436 break;
437 case TYPE_lng:
438 if (nonil)
439 BINARY_3TYPE_FUNC_nonil(hge, lng, TPE, OP);
440#ifdef NIL_MATCHES_FLAG
441 else if (nil_matches)
442 BINARY_3TYPE_FUNC_nilmatch(hge, lng, TPE, OP);
443#endif
444 else
445 BINARY_3TYPE_FUNC(hge, lng, TPE, OP);
446 break;
447 case TYPE_hge:
448 hgehge:
449 if (nonil)
450 BINARY_3TYPE_FUNC_nonil(hge, hge, TPE, OP);
451#ifdef NIL_MATCHES_FLAG
452 else if (nil_matches)
453 BINARY_3TYPE_FUNC_nilmatch(hge, hge, TPE, OP);
454#endif
455 else
456 BINARY_3TYPE_FUNC(hge, hge, TPE, OP);
457 break;
458 case TYPE_flt:
459 if (nonil)
460 BINARY_3TYPE_FUNC_nonil(hge, flt, TPE, OP);
461#ifdef NIL_MATCHES_FLAG
462 else if (nil_matches)
463 BINARY_3TYPE_FUNC_nilmatch(hge, flt, TPE, OP);
464#endif
465 else
466 BINARY_3TYPE_FUNC(hge, flt, TPE, OP);
467 break;
468 case TYPE_dbl:
469 if (nonil)
470 BINARY_3TYPE_FUNC_nonil(hge, dbl, TPE, OP);
471#ifdef NIL_MATCHES_FLAG
472 else if (nil_matches)
473 BINARY_3TYPE_FUNC_nilmatch(hge, dbl, TPE, OP);
474#endif
475 else
476 BINARY_3TYPE_FUNC(hge, dbl, TPE, OP);
477 break;
478 default:
479 goto unsupported;
480 }
481 break;
482#endif
483 case TYPE_flt:
484 switch (tp2) {
485 case TYPE_bte:
486 if (nonil)
487 BINARY_3TYPE_FUNC_nonil(flt, bte, TPE, OP);
488#ifdef NIL_MATCHES_FLAG
489 else if (nil_matches)
490 BINARY_3TYPE_FUNC_nilmatch(flt, bte, TPE, OP);
491#endif
492 else
493 BINARY_3TYPE_FUNC(flt, bte, TPE, OP);
494 break;
495 case TYPE_sht:
496 if (nonil)
497 BINARY_3TYPE_FUNC_nonil(flt, sht, TPE, OP);
498#ifdef NIL_MATCHES_FLAG
499 else if (nil_matches)
500 BINARY_3TYPE_FUNC_nilmatch(flt, sht, TPE, OP);
501#endif
502 else
503 BINARY_3TYPE_FUNC(flt, sht, TPE, OP);
504 break;
505 case TYPE_int:
506 if (nonil)
507 BINARY_3TYPE_FUNC_nonil(flt, int, TPE, OP);
508#ifdef NIL_MATCHES_FLAG
509 else if (nil_matches)
510 BINARY_3TYPE_FUNC_nilmatch(flt, int, TPE, OP);
511#endif
512 else
513 BINARY_3TYPE_FUNC(flt, int, TPE, OP);
514 break;
515 case TYPE_lng:
516 if (nonil)
517 BINARY_3TYPE_FUNC_nonil(flt, lng, TPE, OP);
518#ifdef NIL_MATCHES_FLAG
519 else if (nil_matches)
520 BINARY_3TYPE_FUNC_nilmatch(flt, lng, TPE, OP);
521#endif
522 else
523 BINARY_3TYPE_FUNC(flt, lng, TPE, OP);
524 break;
525#ifdef HAVE_HGE
526 case TYPE_hge:
527 if (nonil)
528 BINARY_3TYPE_FUNC_nonil(flt, hge, TPE, OP);
529#ifdef NIL_MATCHES_FLAG
530 else if (nil_matches)
531 BINARY_3TYPE_FUNC_nilmatch(flt, hge, TPE, OP);
532#endif
533 else
534 BINARY_3TYPE_FUNC(flt, hge, TPE, OP);
535 break;
536#endif
537 case TYPE_flt:
538 fltflt:
539 if (nonil)
540 BINARY_3TYPE_FUNC_nonil(flt, flt, TPE, OP);
541#ifdef NIL_MATCHES_FLAG
542 else if (nil_matches)
543 BINARY_3TYPE_FUNC_nilmatch(flt, flt, TPE, OP);
544#endif
545 else
546 BINARY_3TYPE_FUNC(flt, flt, TPE, OP);
547 break;
548 case TYPE_dbl:
549 if (nonil)
550 BINARY_3TYPE_FUNC_nonil(flt, dbl, TPE, OP);
551#ifdef NIL_MATCHES_FLAG
552 else if (nil_matches)
553 BINARY_3TYPE_FUNC_nilmatch(flt, dbl, TPE, OP);
554#endif
555 else
556 BINARY_3TYPE_FUNC(flt, dbl, TPE, OP);
557 break;
558 default:
559 goto unsupported;
560 }
561 break;
562 case TYPE_dbl:
563 switch (tp2) {
564 case TYPE_bte:
565 if (nonil)
566 BINARY_3TYPE_FUNC_nonil(dbl, bte, TPE, OP);
567#ifdef NIL_MATCHES_FLAG
568 else if (nil_matches)
569 BINARY_3TYPE_FUNC_nilmatch(dbl, bte, TPE, OP);
570#endif
571 else
572 BINARY_3TYPE_FUNC(dbl, bte, TPE, OP);
573 break;
574 case TYPE_sht:
575 if (nonil)
576 BINARY_3TYPE_FUNC_nonil(dbl, sht, TPE, OP);
577#ifdef NIL_MATCHES_FLAG
578 else if (nil_matches)
579 BINARY_3TYPE_FUNC_nilmatch(dbl, sht, TPE, OP);
580#endif
581 else
582 BINARY_3TYPE_FUNC(dbl, sht, TPE, OP);
583 break;
584 case TYPE_int:
585 if (nonil)
586 BINARY_3TYPE_FUNC_nonil(dbl, int, TPE, OP);
587#ifdef NIL_MATCHES_FLAG
588 else if (nil_matches)
589 BINARY_3TYPE_FUNC_nilmatch(dbl, int, TPE, OP);
590#endif
591 else
592 BINARY_3TYPE_FUNC(dbl, int, TPE, OP);
593 break;
594 case TYPE_lng:
595 if (nonil)
596 BINARY_3TYPE_FUNC_nonil(dbl, lng, TPE, OP);
597#ifdef NIL_MATCHES_FLAG
598 else if (nil_matches)
599 BINARY_3TYPE_FUNC_nilmatch(dbl, lng, TPE, OP);
600#endif
601 else
602 BINARY_3TYPE_FUNC(dbl, lng, TPE, OP);
603 break;
604#ifdef HAVE_HGE
605 case TYPE_hge:
606 if (nonil)
607 BINARY_3TYPE_FUNC_nonil(dbl, hge, TPE, OP);
608#ifdef NIL_MATCHES_FLAG
609 else if (nil_matches)
610 BINARY_3TYPE_FUNC_nilmatch(dbl, hge, TPE, OP);
611#endif
612 else
613 BINARY_3TYPE_FUNC(dbl, hge, TPE, OP);
614 break;
615#endif
616 case TYPE_flt:
617 if (nonil)
618 BINARY_3TYPE_FUNC_nonil(dbl, flt, TPE, OP);
619#ifdef NIL_MATCHES_FLAG
620 else if (nil_matches)
621 BINARY_3TYPE_FUNC_nilmatch(dbl, flt, TPE, OP);
622#endif
623 else
624 BINARY_3TYPE_FUNC(dbl, flt, TPE, OP);
625 break;
626 case TYPE_dbl:
627 dbldbl:
628 if (nonil)
629 BINARY_3TYPE_FUNC_nonil(dbl, dbl, TPE, OP);
630#ifdef NIL_MATCHES_FLAG
631 else if (nil_matches)
632 BINARY_3TYPE_FUNC_nilmatch(dbl, dbl, TPE, OP);
633#endif
634 else
635 BINARY_3TYPE_FUNC(dbl, dbl, TPE, OP);
636 break;
637 default:
638 goto unsupported;
639 }
640 break;
641 case TYPE_oid:
642 if (tp2 == TYPE_void) {
643 oid v = * (const oid *) rgt;
644 do {
645 while (k < x) {
646 dst[k++] = TPE_nil;
647 nils++;
648 }
649 i = x * incr1;
650 if (is_oid_nil(v)) {
651#ifdef NIL_MATCHES_FLAG
652 if (nil_matches) {
653 dst[k] = OP(is_oid_nil(((const oid *) lft)[i]), true);
654 } else
655#endif
656 {
657 dst[k] = TPE_nil;
658 nils++;
659 }
660 } else {
661 if (is_oid_nil(((const oid *) lft)[i])) {
662#ifdef NIL_MATCHES_FLAG
663 if (nil_matches) {
664 dst[k] = OP(true, false);
665 } else
666#endif
667 {
668 nils++;
669 dst[k] = TPE_nil;
670 }
671 } else {
672 dst[k] = OP(((const oid *) lft)[i], v);
673 }
674 }
675 k++;
676 x = canditer_next(ci);
677 if (is_oid_nil(x))
678 break;
679 x -= candoff;
680 } while (k < cnt);
681 while (k < cnt) {
682 dst[k++] = TPE_nil;
683 nils++;
684 }
685 } else if (tp2 == TYPE_oid) {
686 if (nonil)
687 BINARY_3TYPE_FUNC_nonil(oid, oid, TPE, OP);
688#ifdef NIL_MATCHES_FLAG
689 else if (nil_matches)
690 BINARY_3TYPE_FUNC_nilmatch(oid, oid, TPE, OP);
691#endif
692 else
693 BINARY_3TYPE_FUNC(oid, oid, TPE, OP);
694 } else {
695 goto unsupported;
696 }
697 break;
698 case TYPE_str:
699 if (tp1 != tp2)
700 goto unsupported;
701 do {
702 while (k < x) {
703 dst[k++] = TPE_nil;
704 nils++;
705 }
706 i = x * incr1;
707 j = x * incr2;
708 const char *s1, *s2;
709 s1 = hp1 ? hp1 + VarHeapVal(lft, i, wd1) : (const char *) lft;
710 s2 = hp2 ? hp2 + VarHeapVal(rgt, j, wd2) : (const char *) rgt;
711 if (s1 == NULL || strcmp(s1, str_nil) == 0 ||
712 s2 == NULL || strcmp(s2, str_nil) == 0) {
713#ifdef NIL_MATCHES_FLAG
714 if (nil_matches) {
715 dst[k] = OP(s1 == NULL || strcmp(s1, str_nil) == 0,
716 s2 == NULL || strcmp(s2, str_nil) == 0);
717 } else
718#endif
719 {
720 nils++;
721 dst[k] = TPE_nil;
722 }
723 } else {
724 int x = strcmp(s1, s2);
725 dst[k] = OP(x, 0);
726 }
727 k++;
728 x = canditer_next(ci);
729 if (is_oid_nil(x))
730 break;
731 x -= candoff;
732 } while (k < cnt);
733 while (k < cnt) {
734 dst[k++] = TPE_nil;
735 nils++;
736 }
737 break;
738 default:
739 if (tp1 != tp2 ||
740 !ATOMlinear(tp1) ||
741 (atomcmp = ATOMcompare(tp1)) == NULL)
742 goto unsupported;
743 /* a bit of a hack: for inherited types, use
744 * type-expanded version if comparison function is
745 * equal to the inherited-from comparison function,
746 * and yes, we jump right into the middle of a switch,
747 * but that is legal (although not encouraged) C */
748 if (atomcmp == ATOMcompare(TYPE_bte))
749 goto btebte;
750 if (atomcmp == ATOMcompare(TYPE_sht))
751 goto shtsht;
752 if (atomcmp == ATOMcompare(TYPE_int))
753 goto intint;
754 if (atomcmp == ATOMcompare(TYPE_lng))
755 goto lnglng;
756#ifdef HAVE_HGE
757 if (atomcmp == ATOMcompare(TYPE_hge))
758 goto hgehge;
759#endif
760 if (atomcmp == ATOMcompare(TYPE_flt))
761 goto fltflt;
762 if (atomcmp == ATOMcompare(TYPE_dbl))
763 goto dbldbl;
764 nil = ATOMnilptr(tp1);
765 do {
766 while (k < x) {
767 dst[k++] = TPE_nil;
768 nils++;
769 }
770 i = x * incr1;
771 j = x * incr2;
772 const void *p1, *p2;
773 p1 = hp1
774 ? (const void *) (hp1 + VarHeapVal(lft, i, wd1))
775 : (const void *) ((const char *) lft + i * wd1);
776 p2 = hp2
777 ? (const void *) (hp2 + VarHeapVal(rgt, j, wd2))
778 : (const void *) ((const char *) rgt + j * wd2);
779 if (p1 == NULL || p2 == NULL ||
780 (*atomcmp)(p1, nil) == 0 ||
781 (*atomcmp)(p2, nil) == 0) {
782#ifdef NIL_MATCHES_FLAG
783 if (nil_matches) {
784 dst[k] = OP(p1 == NULL || (*atomcmp)(p1, nil) == 0,
785 p2 == NULL || (*atomcmp)(p2, nil) == 0);
786 } else
787#endif
788 {
789 nils++;
790 dst[k] = TPE_nil;
791 }
792 } else {
793 int x = (*atomcmp)(p1, p2);
794 dst[k] = OP(x, 0);
795 }
796 k++;
797 x = canditer_next(ci);
798 if (is_oid_nil(x))
799 break;
800 x -= candoff;
801 } while (k < cnt);
802 while (k < cnt) {
803 dst[k++] = TPE_nil;
804 nils++;
805 }
806 break;
807 }
808
809 return nils;
810
811 unsupported:
812 GDKerror("%s: bad input types %s,%s.\n", func,
813 ATOMname(tp1), ATOMname(tp2));
814 return BUN_NONE;
815}
816
817static BAT *
818BATcalcop_intern(const void *lft, int tp1, int incr1, const char *hp1, int wd1,
819 const void *rgt, int tp2, int incr2, const char *hp2, int wd2,
820 BUN cnt, struct canditer *restrict ci,
821 oid candoff, bool nonil, oid seqbase,
822#ifdef NIL_MATCHES_FLAG
823 bool nil_matches,
824#endif
825 const char *func)
826{
827 BAT *bn;
828 BUN nils = 0;
829 TPE *restrict dst;
830
831 bn = COLnew(seqbase, TYPE_TPE, cnt, TRANSIENT);
832 if (bn == NULL)
833 return NULL;
834
835 dst = (TPE *) Tloc(bn, 0);
836
837 nils = op_typeswitchloop(lft, tp1, incr1, hp1, wd1,
838 rgt, tp2, incr2, hp2, wd2,
839 dst, cnt, ci, candoff,
840 nonil,
841#ifdef NIL_MATCHES_FLAG
842 nil_matches,
843#endif
844 func);
845
846 if (nils == BUN_NONE) {
847 BBPunfix(bn->batCacheid);
848 return NULL;
849 }
850
851 BATsetcount(bn, cnt);
852
853 bn->tsorted = cnt <= 1 || nils == cnt;
854 bn->trevsorted = cnt <= 1 || nils == cnt;
855 bn->tkey = cnt <= 1;
856 bn->tnil = nils != 0;
857 bn->tnonil = nils == 0;
858
859 return bn;
860}
861
862BAT *
863BATcalcop(BAT *b1, BAT *b2, BAT *s
864#ifdef NIL_MATCHES_FLAG
865 , bool nil_matches
866#endif
867 )
868{
869 BAT *bn;
870 struct canditer ci;
871 BUN cnt, ncand;
872
873 BATcheck(b1, __func__, NULL);
874 BATcheck(b2, __func__, NULL);
875
876 if (checkbats(b1, b2, __func__) != GDK_SUCCEED)
877 return NULL;
878
879 cnt = BATcount(b1);
880 ncand = canditer_init(&ci, b1, s);
881 if (ncand == 0)
882 return BATconstant(b1->hseqbase, TYPE_TPE,
883 ATOMnilptr(TYPE_TPE), cnt, TRANSIENT);
884
885 if (BATtvoid(b1) && BATtvoid(b2) && cnt == ncand) {
886 TPE res;
887
888 if (is_oid_nil(b1->tseqbase) || is_oid_nil(b2->tseqbase))
889 res = TPE_nil;
890 else
891 res = OP(b1->tseqbase, b2->tseqbase);
892
893 return BATconstant(b1->hseqbase, TYPE_TPE, &res, cnt, TRANSIENT);
894 }
895
896 bn = BATcalcop_intern(b1->ttype == TYPE_void ? (const void *) &b1->tseqbase : (const void *) Tloc(b1, 0),
897 ATOMtype(b1->ttype) == TYPE_oid ? b1->ttype : ATOMbasetype(b1->ttype),
898 1,
899 b1->tvheap ? b1->tvheap->base : NULL,
900 b1->twidth,
901 b2->ttype == TYPE_void ? (const void *) &b2->tseqbase : (const void *) Tloc(b2, 0),
902 ATOMtype(b2->ttype) == TYPE_oid ? b2->ttype : ATOMbasetype(b2->ttype),
903 1,
904 b2->tvheap ? b2->tvheap->base : NULL,
905 b2->twidth,
906 cnt,
907 &ci,
908 b1->hseqbase,
909 cnt == ncand && b1->tnonil && b2->tnonil,
910 b1->hseqbase,
911#ifdef NIL_MATCHES_FLAG
912 nil_matches,
913#endif
914 __func__);
915
916 return bn;
917}
918
919BAT *
920BATcalcopcst(BAT *b, const ValRecord *v, BAT *s
921#ifdef NIL_MATCHES_FLAG
922 , bool nil_matches
923#endif
924 )
925{
926 BAT *bn;
927 struct canditer ci;
928 BUN cnt, ncand;
929
930 BATcheck(b, __func__, NULL);
931
932 cnt = BATcount(b);
933 ncand = canditer_init(&ci, b, s);
934 if (ncand == 0)
935 return BATconstant(b->hseqbase, TYPE_TPE,
936 ATOMnilptr(TYPE_TPE), cnt, TRANSIENT);
937
938 bn = BATcalcop_intern(b->ttype == TYPE_void ? (const void *) &b->tseqbase : (const void *) Tloc(b, 0),
939 ATOMtype(b->ttype) == TYPE_oid ? b->ttype : ATOMbasetype(b->ttype),
940 1,
941 b->tvheap ? b->tvheap->base : NULL,
942 b->twidth,
943 VALptr(v),
944 ATOMtype(v->vtype) == TYPE_oid ? v->vtype : ATOMbasetype(v->vtype),
945 0,
946 NULL,
947 0,
948 cnt,
949 &ci,
950 b->hseqbase,
951 cnt == ncand && b->tnonil && ATOMcmp(v->vtype, VALptr(v), ATOMnilptr(v->vtype)) != 0,
952 b->hseqbase,
953#ifdef NIL_MATCHES_FLAG
954 nil_matches,
955#endif
956 __func__);
957
958 return bn;
959}
960
961BAT *
962BATcalccstop(const ValRecord *v, BAT *b, BAT *s
963#ifdef NIL_MATCHES_FLAG
964 , bool nil_matches
965#endif
966 )
967{
968 BAT *bn;
969 struct canditer ci;
970 BUN cnt, ncand;
971
972 BATcheck(b, __func__, NULL);
973
974 cnt = BATcount(b);
975 ncand = canditer_init(&ci, b, s);
976 if (ncand == 0)
977 return BATconstant(b->hseqbase, TYPE_TPE,
978 ATOMnilptr(TYPE_TPE), cnt, TRANSIENT);
979
980 bn = BATcalcop_intern(VALptr(v),
981 ATOMtype(v->vtype) == TYPE_oid ? v->vtype : ATOMbasetype(v->vtype),
982 0,
983 NULL,
984 0,
985 b->ttype == TYPE_void ? (const void *) &b->tseqbase : (const void *) Tloc(b, 0),
986 ATOMtype(b->ttype) == TYPE_oid ? b->ttype : ATOMbasetype(b->ttype),
987 1,
988 b->tvheap ? b->tvheap->base : NULL,
989 b->twidth,
990 cnt,
991 &ci,
992 b->hseqbase,
993 cnt == ncand && b->tnonil && ATOMcmp(v->vtype, VALptr(v), ATOMnilptr(v->vtype)) != 0,
994 b->hseqbase,
995#ifdef NIL_MATCHES_FLAG
996 nil_matches,
997#endif
998 __func__);
999
1000 return bn;
1001}
1002
1003gdk_return
1004VARcalcop(ValPtr ret, const ValRecord *lft, const ValRecord *rgt
1005#ifdef NIL_MATCHES_FLAG
1006 , bool nil_matches
1007#endif
1008 )
1009{
1010 ret->vtype = TYPE_TPE;
1011 if (op_typeswitchloop(VALptr(lft),
1012 ATOMtype(lft->vtype) == TYPE_oid ? lft->vtype : ATOMbasetype(lft->vtype),
1013 0,
1014 NULL,
1015 0,
1016 VALptr(rgt),
1017 ATOMtype(rgt->vtype) == TYPE_oid ? rgt->vtype : ATOMbasetype(rgt->vtype),
1018 0,
1019 NULL,
1020 0,
1021 VALget(ret),
1022 1,
1023 &(struct canditer){.tpe=cand_dense, .ncand=1},
1024 0,
1025 false,
1026#ifdef NIL_MATCHES_FLAG
1027 nil_matches,
1028#endif
1029 __func__) == BUN_NONE)
1030 return GDK_FAIL;
1031 return GDK_SUCCEED;
1032}
1033