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 | |
11 | static BUN |
12 | op_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 | |
817 | static BAT * |
818 | BATcalcop_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 | |
862 | BAT * |
863 | BATcalcop(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 | |
919 | BAT * |
920 | BATcalcopcst(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 | |
961 | BAT * |
962 | BATcalccstop(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 | |
1003 | gdk_return |
1004 | VARcalcop(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 | |