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 : #include "monetdb_config.h"
14 : #include "gdk.h"
15 : #include "gdk_private.h"
16 : #include "gdk_calc_private.h"
17 :
18 : /* ---------------------------------------------------------------------- */
19 : /* type conversion (cast) */
20 :
21 : /* a note on the return values from the internal conversion functions:
22 : *
23 : * the functions return the number of NIL values produced (or at
24 : * least, 0 if no NIL, and != 0 if there were any);
25 : * the return value is BUN_NONE if a message was generated
26 : * (e.g. overflow or timeout);
27 : * the return value is BUN_NONE + 1 if the types were not compatible;
28 : * the return value is BUN_NONE + 2 if inserting a value into a BAT
29 : * failed (only happens for conversion to str).
30 : */
31 :
32 : #ifdef HAVE_HGE
33 : static const hge scales[39] = {
34 : (hge) LL_CONSTANT(1),
35 : (hge) LL_CONSTANT(10),
36 : (hge) LL_CONSTANT(100),
37 : (hge) LL_CONSTANT(1000),
38 : (hge) LL_CONSTANT(10000),
39 : (hge) LL_CONSTANT(100000),
40 : (hge) LL_CONSTANT(1000000),
41 : (hge) LL_CONSTANT(10000000),
42 : (hge) LL_CONSTANT(100000000),
43 : (hge) LL_CONSTANT(1000000000),
44 : (hge) LL_CONSTANT(10000000000),
45 : (hge) LL_CONSTANT(100000000000),
46 : (hge) LL_CONSTANT(1000000000000),
47 : (hge) LL_CONSTANT(10000000000000),
48 : (hge) LL_CONSTANT(100000000000000),
49 : (hge) LL_CONSTANT(1000000000000000),
50 : (hge) LL_CONSTANT(10000000000000000),
51 : (hge) LL_CONSTANT(100000000000000000),
52 : (hge) LL_CONSTANT(1000000000000000000),
53 : (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(1),
54 : (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(10),
55 : (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(100),
56 : (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(1000),
57 : (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(10000),
58 : (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(100000),
59 : (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(1000000),
60 : (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(10000000),
61 : (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(100000000),
62 : (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(1000000000),
63 : (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(10000000000),
64 : (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(100000000000),
65 : (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(1000000000000),
66 : (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(10000000000000),
67 : (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(100000000000000),
68 : (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(1000000000000000),
69 : (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(10000000000000000),
70 : (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(100000000000000000),
71 : (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(1000000000000000000),
72 : (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(10000000000000000000U)
73 : };
74 : #else
75 : static const lng scales[19] = {
76 : LL_CONSTANT(1),
77 : LL_CONSTANT(10),
78 : LL_CONSTANT(100),
79 : LL_CONSTANT(1000),
80 : LL_CONSTANT(10000),
81 : LL_CONSTANT(100000),
82 : LL_CONSTANT(1000000),
83 : LL_CONSTANT(10000000),
84 : LL_CONSTANT(100000000),
85 : LL_CONSTANT(1000000000),
86 : LL_CONSTANT(10000000000),
87 : LL_CONSTANT(100000000000),
88 : LL_CONSTANT(1000000000000),
89 : LL_CONSTANT(10000000000000),
90 : LL_CONSTANT(100000000000000),
91 : LL_CONSTANT(1000000000000000),
92 : LL_CONSTANT(10000000000000000),
93 : LL_CONSTANT(100000000000000000),
94 : LL_CONSTANT(1000000000000000000)
95 : };
96 : #endif
97 :
98 : #define convertimpl_enlarge_float(TYPE1, TYPE2, MANT_DIG) \
99 : static BUN \
100 : convert_##TYPE1##_##TYPE2(const TYPE1 *src, TYPE2 *restrict dst, \
101 : struct canditer *restrict ci, \
102 : oid candoff, uint8_t scale1, bool *reduce) \
103 : { \
104 : BUN i, nils = 0; \
105 : TYPE1 v; \
106 : oid x; \
107 : const TYPE1 div = (TYPE1) scales[scale1]; \
108 : QryCtx *qry_ctx = MT_thread_get_qry_ctx(); \
109 : \
110 : *reduce = 8 * sizeof(TYPE1) > MANT_DIG; \
111 : if (ci->tpe == cand_dense) { \
112 : if (div == 1) { \
113 : TIMEOUT_LOOP_IDX(i, ci->ncand, qry_ctx) { \
114 : x = canditer_next_dense(ci) - candoff; \
115 : v = src[x]; \
116 : if (is_##TYPE1##_nil(v)) { \
117 : dst[i] = TYPE2##_nil; \
118 : nils++; \
119 : } else \
120 : dst[i] = (TYPE2) v; \
121 : } \
122 : } else { \
123 : TIMEOUT_LOOP_IDX(i, ci->ncand, qry_ctx) { \
124 : x = canditer_next_dense(ci) - candoff; \
125 : v = src[x]; \
126 : if (is_##TYPE1##_nil(v)) { \
127 : dst[i] = TYPE2##_nil; \
128 : nils++; \
129 : } else \
130 : dst[i] = (TYPE2) v / div; \
131 : } \
132 : } \
133 : } else { \
134 : TIMEOUT_LOOP_IDX(i, ci->ncand, qry_ctx) { \
135 : x = canditer_next(ci) - candoff; \
136 : v = src[x]; \
137 : if (is_##TYPE1##_nil(v)) { \
138 : dst[i] = TYPE2##_nil; \
139 : nils++; \
140 : } else \
141 : dst[i] = (TYPE2) v / div; \
142 : } \
143 : } \
144 : TIMEOUT_CHECK(qry_ctx, TIMEOUT_HANDLER(BUN_NONE, qry_ctx)); \
145 : return nils; \
146 : }
147 :
148 : #define CONV_OVERFLOW(TYPE1, TYPE2, value) \
149 : do { \
150 : GDKerror("22003!overflow in conversion of " \
151 : FMT##TYPE1 " to %s.\n", CST##TYPE1 (value), \
152 : TYPE2); \
153 : return BUN_NONE; \
154 : } while (0)
155 :
156 : #define CONV_OVERFLOW_PREC(TYPE1, TYPE2, value, scale, prec) \
157 : do { \
158 : if (prec > 0) \
159 : GDKerror("22003!overflow in conversion to " \
160 : "DECIMAL(%d,%d).\n", prec, scale); \
161 : else \
162 : GDKerror("22003!overflow in conversion of " \
163 : FMT##TYPE1 " to %s.\n", CST##TYPE1 (value), \
164 : TYPE2); \
165 : return BUN_NONE; \
166 : } while (0)
167 :
168 : #define convertimpl_oid_enlarge(TYPE1) \
169 : static BUN \
170 : convert_##TYPE1##_oid(const TYPE1 *src, oid *restrict dst, \
171 : struct canditer *restrict ci, \
172 : oid candoff, bool *reduce) \
173 : { \
174 : BUN i, nils = 0; \
175 : oid x; \
176 : QryCtx *qry_ctx = MT_thread_get_qry_ctx(); \
177 : \
178 : *reduce = false; \
179 : if (ci->tpe == cand_dense) { \
180 : TIMEOUT_LOOP_IDX(i, ci->ncand, qry_ctx) { \
181 : x = canditer_next_dense(ci) - candoff; \
182 : if (is_##TYPE1##_nil(src[x])) { \
183 : dst[i] = oid_nil; \
184 : nils++; \
185 : } else if (src[x] < 0) { \
186 : CONV_OVERFLOW(TYPE1, "oid", src[i]); \
187 : } else if (is_oid_nil((dst[i] = (oid) src[x]))) { \
188 : CONV_OVERFLOW(TYPE1, "oid", src[x]); \
189 : } \
190 : } \
191 : TIMEOUT_CHECK(qry_ctx, TIMEOUT_HANDLER(BUN_NONE, qry_ctx)); \
192 : } else { \
193 : TIMEOUT_LOOP_IDX(i, ci->ncand, qry_ctx) { \
194 : x = canditer_next(ci) - candoff; \
195 : if (is_##TYPE1##_nil(src[x])) { \
196 : dst[i] = oid_nil; \
197 : nils++; \
198 : } else if (src[x] < 0) { \
199 : CONV_OVERFLOW(TYPE1, "oid", src[x]); \
200 : } else if (is_oid_nil((dst[i] = (oid) src[x]))) { \
201 : CONV_OVERFLOW(TYPE1, "oid", src[x]); \
202 : } \
203 : } \
204 : TIMEOUT_CHECK(qry_ctx, TIMEOUT_HANDLER(BUN_NONE, qry_ctx)); \
205 : } \
206 : return nils; \
207 : }
208 :
209 : #define convertimpl_oid_reduce(TYPE1) \
210 : static BUN \
211 : convert_##TYPE1##_oid(const TYPE1 *src, oid *restrict dst, \
212 : struct canditer *restrict ci, \
213 : oid candoff, bool *reduce) \
214 : { \
215 : BUN i, nils = 0; \
216 : oid x; \
217 : QryCtx *qry_ctx = MT_thread_get_qry_ctx(); \
218 : \
219 : *reduce = false; \
220 : if (ci->tpe == cand_dense) { \
221 : TIMEOUT_LOOP_IDX(i, ci->ncand, qry_ctx) { \
222 : x = canditer_next_dense(ci) - candoff; \
223 : if (is_##TYPE1##_nil(src[x])) { \
224 : dst[i] = oid_nil; \
225 : nils++; \
226 : } else if (src[x] < 0 || \
227 : src[x] > (TYPE1) GDK_oid_max) { \
228 : CONV_OVERFLOW(TYPE1, "oid", src[x]); \
229 : } else if (is_oid_nil((dst[i] = (oid) src[x]))) { \
230 : CONV_OVERFLOW(TYPE1, "oid", src[x]); \
231 : } \
232 : } \
233 : TIMEOUT_CHECK(qry_ctx, TIMEOUT_HANDLER(BUN_NONE, qry_ctx)); \
234 : } else { \
235 : TIMEOUT_LOOP_IDX(i, ci->ncand, qry_ctx) { \
236 : x = canditer_next(ci) - candoff; \
237 : if (is_##TYPE1##_nil(src[x])) { \
238 : dst[i] = oid_nil; \
239 : nils++; \
240 : } else if (src[x] < 0 || \
241 : src[x] > (TYPE1) GDK_oid_max) { \
242 : CONV_OVERFLOW(TYPE1, "oid", src[x]); \
243 : } else if (is_oid_nil((dst[i] = (oid) src[x]))) { \
244 : CONV_OVERFLOW(TYPE1, "oid", src[x]); \
245 : } \
246 : } \
247 : TIMEOUT_CHECK(qry_ctx, TIMEOUT_HANDLER(BUN_NONE, qry_ctx)); \
248 : } \
249 : return nils; \
250 : }
251 :
252 : #define uint unsigned int
253 : #define usht uint16_t
254 : #define ubte uint8_t
255 :
256 : #ifdef TRUNCATE_NUMBERS
257 : #define DIVIDE(v, div, TYPE) ((v) / (div))
258 : #else
259 : #define DIVIDE(v, div, TYPE) ((v) < 0 ? -(TYPE) (((u##TYPE) -(v) + ((u##TYPE) (div) >> 1)) / (div)) : (TYPE) (((u##TYPE) (v) + ((u##TYPE) (div) >> 1)) / (div)))
260 : #endif
261 :
262 : #define convertimpl(TYPE1, TYPE2) \
263 : static BUN \
264 : convert_##TYPE1##_##TYPE2(const TYPE1 *restrict src, \
265 : TYPE2 *restrict dst, \
266 : struct canditer *restrict ci, \
267 : oid candoff, \
268 : uint8_t scale1, \
269 : uint8_t scale2, \
270 : uint8_t precision, \
271 : bool *reduce) \
272 : { \
273 : BUN i; \
274 : BUN nils = 0; \
275 : TYPE1 v; \
276 : oid x; \
277 : const TYPE1 div = (TYPE1) scales[scale1 > scale2 ? scale1 - scale2 : 0]; \
278 : const TYPE2 mul = (TYPE2) scales[scale2 > scale1 ? scale2 - scale1 : 0]; \
279 : const TYPE2 min = GDK_##TYPE2##_min / mul; \
280 : const TYPE2 max = GDK_##TYPE2##_max / mul; \
281 : const TYPE2 prec = (TYPE2) scales[precision] / mul; \
282 : QryCtx *qry_ctx = MT_thread_get_qry_ctx(); \
283 : \
284 : assert(div == 1 || mul == 1); \
285 : assert(div >= 1 && mul >= 1); \
286 : \
287 : *reduce = div > 1; \
288 : if (ci->tpe == cand_dense) { \
289 : if (div == 1 && mul == 1) { \
290 : TIMEOUT_LOOP_IDX(i, ci->ncand, qry_ctx) { \
291 : x = canditer_next_dense(ci) - candoff; \
292 : v = src[x]; \
293 : if (is_##TYPE1##_nil(v)) { \
294 : dst[i] = TYPE2##_nil; \
295 : nils++; \
296 : } else if (v < min || v > max || \
297 : (precision && \
298 : (v >= prec || v <= -prec))) { \
299 : CONV_OVERFLOW_PREC(TYPE1, #TYPE2, v, scale2, precision); \
300 : } else { \
301 : dst[i] = (TYPE2) v; \
302 : } \
303 : } \
304 : } else if (div == 1) { \
305 : TIMEOUT_LOOP_IDX(i, ci->ncand, qry_ctx) { \
306 : x = canditer_next_dense(ci) - candoff; \
307 : v = src[x]; \
308 : if (is_##TYPE1##_nil(v)) { \
309 : dst[i] = TYPE2##_nil; \
310 : nils++; \
311 : } else if (v < min || v > max || \
312 : (precision && \
313 : (v >= prec || v <= -prec))) { \
314 : CONV_OVERFLOW_PREC(TYPE1, #TYPE2, src[x], scale2, precision); \
315 : } else { \
316 : dst[i] = (TYPE2) v * mul; \
317 : } \
318 : } \
319 : } else { \
320 : /* mul == 1 */ \
321 : TIMEOUT_LOOP_IDX(i, ci->ncand, qry_ctx) { \
322 : x = canditer_next_dense(ci) - candoff; \
323 : v = src[x]; \
324 : if (is_##TYPE1##_nil(v)) { \
325 : dst[i] = TYPE2##_nil; \
326 : nils++; \
327 : } else { \
328 : v = DIVIDE(v, div, TYPE1); \
329 : if (v < min || v > max || \
330 : (precision && \
331 : (v >= prec || v <= -prec))) { \
332 : CONV_OVERFLOW_PREC(TYPE1, #TYPE2, src[x], scale2, precision); \
333 : } else { \
334 : dst[i] = (TYPE2) v; \
335 : } \
336 : } \
337 : } \
338 : } \
339 : } else { \
340 : TIMEOUT_LOOP_IDX(i, ci->ncand, qry_ctx) { \
341 : x = canditer_next(ci) - candoff; \
342 : v = src[x]; \
343 : if (is_##TYPE1##_nil(v)) { \
344 : dst[i] = TYPE2##_nil; \
345 : nils++; \
346 : } else { \
347 : v = DIVIDE(v, div, TYPE1); \
348 : if (v < min || v > max || \
349 : (precision && \
350 : (v >= prec || v <= -prec))) { \
351 : CONV_OVERFLOW_PREC(TYPE1, #TYPE2, src[x], scale2, precision); \
352 : } else { \
353 : dst[i] = (TYPE2) v * mul; \
354 : } \
355 : } \
356 : } \
357 : } \
358 : TIMEOUT_CHECK(qry_ctx, TIMEOUT_HANDLER(BUN_NONE, qry_ctx)); \
359 : return nils; \
360 : }
361 :
362 : /* Special version of the above for converting from floating point.
363 : * The final assignment rounds the value which can still come out to
364 : * the NIL representation, so we need to check for that. */
365 : #define convertimpl_reduce_float(TYPE1, TYPE2) \
366 : static BUN \
367 : convert_##TYPE1##_##TYPE2(const TYPE1 *src, TYPE2 *restrict dst, \
368 : struct canditer *restrict ci, \
369 : oid candoff, uint8_t scale2, uint8_t precision, \
370 : bool *reduce) \
371 : { \
372 : BUN i, nils = 0; \
373 : oid x; \
374 : TYPE1 v; \
375 : const TYPE2 mul = (TYPE2) scales[scale2]; \
376 : const TYPE2 min = GDK_##TYPE2##_min; \
377 : const TYPE2 max = GDK_##TYPE2##_max; \
378 : const TYPE2 prec = (TYPE2) scales[precision]; \
379 : QryCtx *qry_ctx = MT_thread_get_qry_ctx(); \
380 : \
381 : *reduce = true; \
382 : if (ci->tpe == cand_dense) { \
383 : TIMEOUT_LOOP_IDX(i, ci->ncand, qry_ctx) { \
384 : x = canditer_next_dense(ci) - candoff; \
385 : v = src[x]; \
386 : if (is_##TYPE1##_nil(v)) { \
387 : dst[i] = TYPE2##_nil; \
388 : nils++; \
389 : } else if (v < (TYPE1) min || v > (TYPE1) max) { \
390 : CONV_OVERFLOW_PREC(TYPE1, #TYPE2, v, scale2, precision); \
391 : } else { \
392 : ldouble m = (ldouble) v * mul; \
393 : dst[i] = (TYPE2) rounddbl(m); \
394 : if (is_##TYPE2##_nil(dst[i]) || \
395 : (precision && \
396 : (dst[i] >= prec || \
397 : dst[i] <= -prec))) \
398 : CONV_OVERFLOW_PREC(TYPE1, #TYPE2, v, scale2, precision); \
399 : } \
400 : } \
401 : TIMEOUT_CHECK(qry_ctx, TIMEOUT_HANDLER(BUN_NONE, qry_ctx)); \
402 : } else { \
403 : TIMEOUT_LOOP_IDX(i, ci->ncand, qry_ctx) { \
404 : x = canditer_next(ci) - candoff; \
405 : v = src[x]; \
406 : if (is_##TYPE1##_nil(v)) { \
407 : dst[i] = TYPE2##_nil; \
408 : nils++; \
409 : } else if (v < (TYPE1) min || v > (TYPE1) max) { \
410 : CONV_OVERFLOW_PREC(TYPE1, #TYPE2, v, scale2, precision); \
411 : } else { \
412 : ldouble m = (ldouble) v * mul; \
413 : dst[i] = (TYPE2) rounddbl(m); \
414 : if (is_##TYPE2##_nil(dst[i]) || \
415 : (precision && \
416 : (dst[i] >= prec || \
417 : dst[i] <= -prec))) \
418 : CONV_OVERFLOW_PREC(TYPE1, #TYPE2, v, scale2, precision); \
419 : } \
420 : } \
421 : TIMEOUT_CHECK(qry_ctx, TIMEOUT_HANDLER(BUN_NONE, qry_ctx)); \
422 : } \
423 : return nils; \
424 : }
425 :
426 : #define convert2bit_impl(TYPE) \
427 : static BUN \
428 : convert_##TYPE##_bit(const TYPE *src, bit *restrict dst, \
429 : struct canditer *restrict ci, \
430 : oid candoff, bool *reduce) \
431 : { \
432 : BUN i, nils = 0; \
433 : oid x; \
434 : QryCtx *qry_ctx = MT_thread_get_qry_ctx(); \
435 : \
436 : *reduce = true; \
437 : if (ci->tpe == cand_dense) { \
438 : TIMEOUT_LOOP_IDX(i, ci->ncand, qry_ctx) { \
439 : x = canditer_next_dense(ci) - candoff; \
440 : if (is_##TYPE##_nil(src[x])) { \
441 : dst[i] = bit_nil; \
442 : nils++; \
443 : } else \
444 : dst[i] = (bit) (src[x] != 0); \
445 : } \
446 : TIMEOUT_CHECK(qry_ctx, TIMEOUT_HANDLER(BUN_NONE, qry_ctx)); \
447 : } else { \
448 : TIMEOUT_LOOP_IDX(i, ci->ncand, qry_ctx) { \
449 : x = canditer_next(ci) - candoff; \
450 : if (is_##TYPE##_nil(src[x])) { \
451 : dst[i] = bit_nil; \
452 : nils++; \
453 : } else \
454 : dst[i] = (bit) (src[x] != 0); \
455 : } \
456 : TIMEOUT_CHECK(qry_ctx, TIMEOUT_HANDLER(BUN_NONE, qry_ctx)); \
457 : } \
458 : return nils; \
459 : }
460 :
461 : #define convertimpl_msk(TYPE) \
462 : static BUN \
463 : convert_##TYPE##_msk(const TYPE *src, uint32_t *restrict dst, \
464 : struct canditer *restrict ci, \
465 : oid candoff, bool *reduce) \
466 : { \
467 : BUN cnt = ci->ncand / 32; \
468 : BUN i, j; \
469 : uint32_t mask; \
470 : oid x; \
471 : QryCtx *qry_ctx = MT_thread_get_qry_ctx(); \
472 : \
473 : *reduce = true; \
474 : if (ci->tpe == cand_dense) { \
475 : TIMEOUT_LOOP_IDX(i, cnt, qry_ctx) { \
476 : mask = 0; \
477 : for (j = 0; j < 32; j++) { \
478 : x = canditer_next_dense(ci) - candoff; \
479 : mask |= (uint32_t) (!is_##TYPE##_nil(src[x]) && src[x] != 0) << j; \
480 : } \
481 : dst[i] = mask; \
482 : } \
483 : TIMEOUT_CHECK(qry_ctx, TIMEOUT_HANDLER(BUN_NONE, qry_ctx)); \
484 : cnt = ci->ncand % 32; \
485 : if (cnt > 0) { \
486 : mask = 0; \
487 : for (j = 0; j < cnt; j++) { \
488 : x = canditer_next_dense(ci) - candoff; \
489 : mask |= (uint32_t) (!is_##TYPE##_nil(src[x]) && src[x] != 0) << j; \
490 : } \
491 : dst[i] = mask; \
492 : } \
493 : } else { \
494 : TIMEOUT_LOOP_IDX(i, cnt, qry_ctx) { \
495 : mask = 0; \
496 : for (j = 0; j < 32; j++) { \
497 : x = canditer_next(ci) - candoff; \
498 : mask |= (uint32_t) (!is_##TYPE##_nil(src[x]) && src[x] != 0) << j; \
499 : } \
500 : dst[i] = mask; \
501 : } \
502 : TIMEOUT_CHECK(qry_ctx, TIMEOUT_HANDLER(BUN_NONE, qry_ctx)); \
503 : cnt = ci->ncand % 32; \
504 : if (cnt > 0) { \
505 : mask = 0; \
506 : for (j = 0; j < cnt; j++) { \
507 : x = canditer_next(ci) - candoff; \
508 : mask |= (uint32_t) (!is_##TYPE##_nil(src[x]) && src[x] != 0) << j; \
509 : } \
510 : dst[i] = mask; \
511 : } \
512 : } \
513 : return 0; \
514 : } \
515 : \
516 : static BUN \
517 : convert_msk_##TYPE(const uint32_t *src, TYPE *restrict dst, \
518 : struct canditer *restrict ci, \
519 : oid candoff, bool *reduce) \
520 : { \
521 : BUN nils = 0; \
522 : BUN k; \
523 : QryCtx *qry_ctx = MT_thread_get_qry_ctx(); \
524 : \
525 : *reduce = false; \
526 : if (ci->tpe == cand_dense) { \
527 : uint32_t mask; \
528 : BUN i = (ci->seq - candoff) / 32; \
529 : BUN cnt = (ci->seq + ci->ncand - candoff) / 32; \
530 : BUN first = (ci->seq - candoff) % 32; \
531 : BUN rem = (ci->seq + ci->ncand - candoff) % 32; \
532 : BUN j; \
533 : k = 0; \
534 : for (; i < cnt; i++) { \
535 : mask = src[i]; \
536 : for (j = first; j < 32; j++) { \
537 : dst[k] = (TYPE) ((mask & (1U << j)) != 0); \
538 : k++; \
539 : } \
540 : first = 0; \
541 : } \
542 : if (rem > first) { \
543 : mask = src[i]; \
544 : for (j = first; j < rem; j++) { \
545 : dst[k] = (TYPE) ((mask & (1U << j)) != 0); \
546 : k++; \
547 : } \
548 : } \
549 : } else { \
550 : TIMEOUT_LOOP_IDX(k, ci->ncand, qry_ctx) { \
551 : oid x = canditer_next(ci) - candoff; \
552 : dst[k] = (TYPE) ((src[x / 32] & (1U << (x % 32))) != 0); \
553 : } \
554 : TIMEOUT_CHECK(qry_ctx, TIMEOUT_HANDLER(BUN_NONE, qry_ctx)); \
555 : } \
556 : return nils; \
557 : }
558 :
559 701 : convertimpl(bte, bte)
560 4437249 : convertimpl(bte, sht)
561 5849942 : convertimpl(bte, int)
562 36 : convertimpl_oid_enlarge(bte)
563 9118365 : convertimpl(bte, lng)
564 : #ifdef HAVE_HGE
565 769489 : convertimpl(bte, hge)
566 : #endif
567 1018 : convertimpl_enlarge_float(bte, flt, FLT_MANT_DIG)
568 48166 : convertimpl_enlarge_float(bte, dbl, DBL_MANT_DIG)
569 :
570 56 : convertimpl(sht, bte)
571 308 : convertimpl(sht, sht)
572 5635318 : convertimpl(sht, int)
573 2 : convertimpl_oid_enlarge(sht)
574 12042197 : convertimpl(sht, lng)
575 : #ifdef HAVE_HGE
576 2338 : convertimpl(sht, hge)
577 : #endif
578 192 : convertimpl_enlarge_float(sht, flt, FLT_MANT_DIG)
579 3139 : convertimpl_enlarge_float(sht, dbl, DBL_MANT_DIG)
580 :
581 1445 : convertimpl(int, bte)
582 19499 : convertimpl(int, sht)
583 768 : convertimpl(int, int)
584 38 : convertimpl_oid_enlarge(int)
585 151891847 : convertimpl(int, lng)
586 : #ifdef HAVE_HGE
587 32353 : convertimpl(int, hge)
588 : #endif
589 3014061 : convertimpl_enlarge_float(int, flt, FLT_MANT_DIG)
590 81551 : convertimpl_enlarge_float(int, dbl, DBL_MANT_DIG)
591 :
592 164 : convertimpl(lng, bte)
593 129496 : convertimpl(lng, sht)
594 2067602 : convertimpl(lng, int)
595 : #if SIZEOF_OID == SIZEOF_LNG
596 9308 : convertimpl_oid_enlarge(lng)
597 : #else
598 : convertimpl_oid_reduce(lng)
599 : #endif
600 4560593 : convertimpl(lng, lng)
601 : #ifdef HAVE_HGE
602 11416110 : convertimpl(lng, hge)
603 : #endif
604 316 : convertimpl_enlarge_float(lng, flt, FLT_MANT_DIG)
605 282855 : convertimpl_enlarge_float(lng, dbl, DBL_MANT_DIG)
606 :
607 : #ifdef HAVE_HGE
608 59 : convertimpl(hge, bte)
609 59 : convertimpl(hge, sht)
610 8751 : convertimpl(hge, int)
611 0 : convertimpl_oid_reduce(hge)
612 46952 : convertimpl(hge, lng)
613 2388513 : convertimpl(hge, hge)
614 52 : convertimpl_enlarge_float(hge, flt, FLT_MANT_DIG)
615 216 : convertimpl_enlarge_float(hge, dbl, DBL_MANT_DIG)
616 : #endif
617 :
618 20 : convertimpl_reduce_float(flt, bte)
619 24 : convertimpl_reduce_float(flt, sht)
620 34 : convertimpl_reduce_float(flt, int)
621 0 : convertimpl_oid_reduce(flt)
622 272 : convertimpl_reduce_float(flt, lng)
623 : #ifdef HAVE_HGE
624 30 : convertimpl_reduce_float(flt, hge)
625 : #endif
626 38 : convertimpl_enlarge_float(flt, flt, 128)
627 7766460 : convertimpl_enlarge_float(flt, dbl, DBL_MANT_DIG)
628 :
629 139 : convertimpl_reduce_float(dbl, bte)
630 55 : convertimpl_reduce_float(dbl, sht)
631 750 : convertimpl_reduce_float(dbl, int)
632 0 : convertimpl_oid_reduce(dbl)
633 300496 : convertimpl_reduce_float(dbl, lng)
634 : #ifdef HAVE_HGE
635 130 : convertimpl_reduce_float(dbl, hge)
636 : #endif
637 : #undef rounddbl
638 : /* no rounding here */
639 : #define rounddbl(x) (x)
640 260 : convertimpl_reduce_float(dbl, flt)
641 0 : convertimpl_enlarge_float(dbl, dbl, 128)
642 :
643 1066758 : convert2bit_impl(bte)
644 83 : convert2bit_impl(sht)
645 420 : convert2bit_impl(int)
646 16444 : convert2bit_impl(lng)
647 : #ifdef HAVE_HGE
648 36 : convert2bit_impl(hge)
649 : #endif
650 34 : convert2bit_impl(flt)
651 74 : convert2bit_impl(dbl)
652 :
653 0 : convertimpl_msk(bte)
654 0 : convertimpl_msk(sht)
655 0 : convertimpl_msk(int)
656 0 : convertimpl_msk(lng)
657 : #ifdef HAVE_HGE
658 0 : convertimpl_msk(hge)
659 : #endif
660 0 : convertimpl_msk(flt)
661 0 : convertimpl_msk(dbl)
662 :
663 : static BUN
664 168 : convert_any_str(BATiter *bi, BAT *bn, struct canditer *restrict ci)
665 : {
666 168 : int tp = bi->type;
667 168 : oid candoff = bi->b->hseqbase;
668 168 : str dst = 0;
669 168 : size_t len = 0;
670 168 : BUN nils = 0;
671 168 : BUN i;
672 168 : const void *nil = ATOMnilptr(tp);
673 168 : const void *restrict src;
674 168 : ssize_t (*atomtostr)(str *, size_t *, const void *, bool) = BATatoms[tp].atomToStr;
675 168 : int (*atomcmp)(const void *, const void *) = ATOMcompare(tp);
676 168 : oid x;
677 :
678 168 : QryCtx *qry_ctx = MT_thread_get_qry_ctx();
679 :
680 168 : if (atomtostr == BATatoms[TYPE_str].atomToStr) {
681 : /* compatible with str, we just copy the value */
682 0 : assert(bi->type != TYPE_void);
683 0 : TIMEOUT_LOOP_IDX(i, ci->ncand, qry_ctx) {
684 0 : x = canditer_next(ci) - candoff;
685 0 : src = BUNtvar(*bi, x);
686 0 : if (strNil(src))
687 0 : nils++;
688 0 : if (tfastins_nocheckVAR(bn, i, src) != GDK_SUCCEED) {
689 0 : goto bailout;
690 : }
691 : }
692 168 : } else if (bi->b->tvheap) {
693 12 : assert(bi->type != TYPE_void);
694 82 : TIMEOUT_LOOP_IDX(i, ci->ncand, qry_ctx) {
695 46 : x = canditer_next(ci) - candoff;
696 46 : src = BUNtvar(*bi, x);
697 46 : if ((*atomcmp)(src, nil) == 0) {
698 6 : nils++;
699 6 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED) {
700 0 : goto bailout;
701 : }
702 : } else {
703 80 : if ((*atomtostr)(&dst, &len, src, false) < 0 ||
704 40 : tfastins_nocheckVAR(bn, i, dst) != GDK_SUCCEED) {
705 0 : goto bailout;
706 : }
707 : }
708 : }
709 156 : } else if (ATOMstorage(bi->type) == TYPE_msk) {
710 0 : TIMEOUT_LOOP_IDX(i, ci->ncand, qry_ctx) {
711 0 : const char *v;
712 0 : x = canditer_next(ci) - candoff;
713 0 : v = Tmskval(bi, x) ? "1" : "0";
714 0 : if (tfastins_nocheckVAR(bn, i, v) != GDK_SUCCEED)
715 0 : goto bailout;
716 : }
717 : } else {
718 1008590 : TIMEOUT_LOOP_IDX(i, ci->ncand, qry_ctx) {
719 1008062 : x = canditer_next(ci) - candoff;
720 1008062 : src = BUNtloc(*bi, x);
721 1008062 : if ((*atomcmp)(src, nil) == 0) {
722 4117 : nils++;
723 4117 : if (tfastins_nocheckVAR(bn, i, str_nil) != GDK_SUCCEED)
724 0 : goto bailout;
725 : } else {
726 1003945 : if ((*atomtostr)(&dst, &len, src, false) < 0)
727 0 : goto bailout;
728 1003945 : if (tfastins_nocheckVAR(bn, i, dst) != GDK_SUCCEED)
729 0 : goto bailout;
730 : }
731 : }
732 : }
733 168 : GDKfree(dst);
734 168 : TIMEOUT_CHECK(qry_ctx, TIMEOUT_HANDLER(BUN_NONE, qry_ctx));
735 168 : BATsetcount(bn, ci->ncand);
736 168 : return nils;
737 0 : bailout:
738 0 : GDKfree(dst);
739 0 : return BUN_NONE + 2;
740 : }
741 :
742 : static BUN
743 9 : convert_str_var(BATiter *bi, BAT *bn, struct canditer *restrict ci)
744 : {
745 9 : int tp = bn->ttype;
746 9 : oid candoff = bi->b->hseqbase;
747 9 : void *dst = 0;
748 9 : size_t len = 0;
749 9 : BUN nils = 0;
750 9 : BUN i;
751 9 : const void *nil = ATOMnilptr(tp);
752 9 : const char *restrict src;
753 9 : ssize_t (*atomfromstr)(const char *, size_t *, ptr *, bool) = BATatoms[tp].atomFromStr;
754 9 : oid x;
755 :
756 9 : QryCtx *qry_ctx = MT_thread_get_qry_ctx();
757 :
758 2034 : TIMEOUT_LOOP_IDX(i, ci->ncand, qry_ctx) {
759 2007 : x = canditer_next(ci) - candoff;
760 2007 : src = BUNtvar(*bi, x);
761 2007 : if (strNil(src)) {
762 0 : nils++;
763 0 : if (tfastins_nocheckVAR(bn, i, nil) != GDK_SUCCEED) {
764 0 : goto bailout;
765 : }
766 : } else {
767 2007 : ssize_t l;
768 2007 : if ((l = (*atomfromstr)(src, &len, &dst, false)) < 0 ||
769 4014 : l < (ssize_t) strlen(src) ||
770 2007 : tfastins_nocheckVAR(bn, i, dst) != GDK_SUCCEED) {
771 0 : goto bailout;
772 : }
773 : }
774 : }
775 9 : GDKfree(dst);
776 9 : TIMEOUT_CHECK(qry_ctx, TIMEOUT_HANDLER(BUN_NONE, qry_ctx));
777 9 : BATsetcount(bn, ci->ncand);
778 9 : return nils;
779 0 : bailout:
780 0 : GDKfree(dst);
781 0 : return BUN_NONE + 2;
782 : }
783 :
784 : static BUN
785 930 : convert_str_fix(BATiter *bi, int tp, void *restrict dst,
786 : struct canditer *restrict ci, oid candoff)
787 : {
788 930 : BUN nils = 0;
789 930 : const void *nil = ATOMnilptr(tp);
790 930 : size_t len = ATOMsize(tp);
791 930 : ssize_t l;
792 930 : ssize_t (*atomfromstr)(const char *, size_t *, ptr *, bool) = BATatoms[tp].atomFromStr;
793 930 : const char *s = NULL;
794 :
795 930 : QryCtx *qry_ctx = MT_thread_get_qry_ctx();
796 :
797 930 : if (ATOMstorage(tp) == TYPE_msk) {
798 0 : uint32_t mask = 0;
799 0 : uint32_t *d = dst;
800 0 : int j = 0;
801 0 : TIMEOUT_LOOP(ci->ncand, qry_ctx) {
802 0 : oid x = canditer_next(ci) - candoff;
803 0 : uint32_t v;
804 0 : s = BUNtvar(*bi, x);
805 0 : if (strcmp(s, "0") == 0)
806 : v = 0;
807 0 : else if (strcmp(s, "1") == 0)
808 : v = 1;
809 : else
810 0 : goto conversion_failed;
811 0 : mask |= v << j;
812 0 : if (++j == 32) {
813 0 : *d++ = mask;
814 0 : j = 0;
815 0 : mask = 0;
816 : }
817 : }
818 0 : TIMEOUT_CHECK(qry_ctx, TIMEOUT_HANDLER(BUN_NONE, qry_ctx));
819 0 : if (j > 0)
820 0 : *d = mask;
821 0 : return 0;
822 : }
823 :
824 930 : int (*atomcmp)(const void *, const void *) = ATOMcompare(tp);
825 260270 : TIMEOUT_LOOP(ci->ncand, qry_ctx) {
826 258426 : oid x = canditer_next(ci) - candoff;
827 254983 : const char *s = BUNtvar(*bi, x);
828 250607 : if (strNil(s)) {
829 5 : memcpy(dst, nil, len);
830 5 : nils++;
831 : } else {
832 250602 : void *d = dst;
833 250602 : if ((l = (*atomfromstr)(s, &len, &d, false)) < 0 ||
834 268546 : l < (ssize_t) strlen(s)) {
835 12 : goto conversion_failed;
836 : }
837 268544 : assert(len == ATOMsize(tp));
838 268544 : if (atomcmp(dst, nil) == 0)
839 0 : nils++;
840 : }
841 258414 : dst = (void *) ((char *) dst + len);
842 : }
843 918 : TIMEOUT_CHECK(qry_ctx, TIMEOUT_HANDLER(BUN_NONE, qry_ctx));
844 : return nils;
845 :
846 0 : conversion_failed:
847 0 : GDKclrerr();
848 12 : size_t sz = 0;
849 12 : char *bf = NULL;
850 :
851 12 : if (s) {
852 0 : sz = escapedStrlen(s, NULL, NULL, '\'');
853 0 : bf = GDKmalloc(sz + 1);
854 : }
855 12 : if (bf) {
856 0 : escapedStr(bf, s, sz + 1, NULL, NULL, '\'');
857 0 : GDKerror("22018!conversion of string "
858 : "'%s' to type %s failed.\n",
859 : bf, ATOMname(tp));
860 0 : GDKfree(bf);
861 : } else {
862 12 : GDKerror("22018!conversion of string "
863 : "to type %s failed.\n",
864 : ATOMname(tp));
865 : }
866 : return BUN_NONE;
867 : }
868 :
869 : static BUN
870 0 : convert_void_any(oid seq, BAT *bn,
871 : struct canditer *restrict ci,
872 : oid candoff, bool *reduce)
873 : {
874 0 : BUN nils = 0;
875 0 : BUN i;
876 0 : int tp = bn->ttype;
877 0 : void *restrict dst = Tloc(bn, 0);
878 0 : ssize_t (*atomtostr)(str *, size_t *, const void *, bool) = BATatoms[TYPE_oid].atomToStr;
879 0 : char *s = NULL;
880 0 : size_t len = 0;
881 0 : oid x;
882 :
883 0 : QryCtx *qry_ctx = MT_thread_get_qry_ctx();
884 :
885 0 : *reduce = false;
886 0 : assert(!is_oid_nil(seq));
887 :
888 0 : switch (ATOMbasetype(tp)) {
889 0 : case TYPE_bte:
890 0 : if (tp == TYPE_bit) {
891 0 : if (ci->ncand > 0) {
892 0 : x = canditer_next(ci) - candoff;
893 0 : ((bit *) dst)[0] = x + seq != 0;
894 : }
895 0 : TIMEOUT_LOOP_IDX(i, ci->ncand, qry_ctx) {
896 0 : ((bit *) dst)[i] = 1;
897 : }
898 : } else {
899 0 : TIMEOUT_LOOP_IDX(i, ci->ncand, qry_ctx) {
900 0 : x = canditer_next(ci) - candoff;
901 0 : if (seq + x > GDK_bte_max) {
902 0 : CONV_OVERFLOW(oid, "bte", seq + x);
903 : } else {
904 0 : ((bte *) dst)[i] = (bte) (seq + x);
905 : }
906 : }
907 : }
908 : break;
909 0 : case TYPE_sht:
910 0 : TIMEOUT_LOOP_IDX(i, ci->ncand, qry_ctx) {
911 0 : x = canditer_next(ci) - candoff;
912 0 : if (seq + x > GDK_sht_max) {
913 0 : CONV_OVERFLOW(oid, "sht", seq + x);
914 : } else {
915 0 : ((sht *) dst)[i] = (sht) (seq + x);
916 : }
917 : }
918 : break;
919 0 : case TYPE_int:
920 0 : TIMEOUT_LOOP_IDX(i, ci->ncand, qry_ctx) {
921 0 : x = canditer_next(ci) - candoff;
922 : #if SIZEOF_OID > SIZEOF_INT
923 0 : if (seq + x > GDK_int_max) {
924 0 : CONV_OVERFLOW(oid, "int", seq + x);
925 : } else
926 : #endif
927 0 : ((int *) dst)[i] = (int) (seq + x);
928 : }
929 : break;
930 0 : case TYPE_lng:
931 0 : TIMEOUT_LOOP_IDX(i, ci->ncand, qry_ctx) {
932 0 : x = canditer_next(ci) - candoff;
933 0 : ((lng *) dst)[i] = (lng) (seq + x);
934 : }
935 : break;
936 : #ifdef HAVE_HGE
937 0 : case TYPE_hge:
938 0 : TIMEOUT_LOOP_IDX(i, ci->ncand, qry_ctx) {
939 0 : x = canditer_next(ci) - candoff;
940 0 : ((hge *) dst)[i] = (hge) (seq + x);
941 : }
942 : break;
943 : #endif
944 0 : case TYPE_flt:
945 0 : TIMEOUT_LOOP_IDX(i, ci->ncand, qry_ctx) {
946 0 : x = canditer_next(ci) - candoff;
947 0 : ((flt *) dst)[i] = (flt) (seq + x);
948 : }
949 : break;
950 0 : case TYPE_dbl:
951 0 : TIMEOUT_LOOP_IDX(i, ci->ncand, qry_ctx) {
952 0 : x = canditer_next(ci) - candoff;
953 0 : ((dbl *) dst)[i] = (dbl) (seq + x);
954 : }
955 : break;
956 0 : case TYPE_str:
957 0 : TIMEOUT_LOOP_IDX(i, ci->ncand, qry_ctx) {
958 0 : x = canditer_next(ci) - candoff;
959 0 : if ((*atomtostr)(&s, &len, &(oid){seq + x}, false) < 0)
960 0 : goto bailout;
961 0 : if (tfastins_nocheckVAR(bn, i, s) != GDK_SUCCEED)
962 0 : goto bailout;
963 : }
964 0 : GDKfree(s);
965 0 : s = NULL;
966 0 : break;
967 : default:
968 : return BUN_NONE + 1;
969 : }
970 0 : TIMEOUT_CHECK(qry_ctx, TIMEOUT_HANDLER(BUN_NONE, qry_ctx));
971 :
972 0 : bn->theap->dirty = true;
973 0 : return nils;
974 :
975 0 : bailout:
976 0 : GDKfree(s);
977 0 : return BUN_NONE + 2;
978 : }
979 :
980 : static BUN
981 2006629 : convert_typeswitchloop(const void *src, int stp, void *restrict dst, int dtp,
982 : struct canditer *restrict ci,
983 : oid candoff, bool *reduce,
984 : uint8_t scale1, uint8_t scale2, uint8_t precision)
985 : {
986 2006629 : assert(stp == TYPE_flt || stp == TYPE_dbl || scale1 < (uint8_t) (sizeof(scales) / sizeof(scales[0])));
987 2006629 : assert(dtp == TYPE_flt || dtp == TYPE_dbl || scale2 < (uint8_t) (sizeof(scales) / sizeof(scales[0])));
988 4012998 : switch (ATOMbasetype(stp)) {
989 0 : case TYPE_msk:
990 0 : switch (ATOMbasetype(dtp)) {
991 : /* case TYPE_msk not needed: it is done with the help
992 : * of BATappend */
993 0 : case TYPE_bte:
994 0 : return convert_bte_msk(src, dst, ci, candoff,
995 : reduce);
996 0 : case TYPE_sht:
997 0 : return convert_sht_msk(src, dst, ci, candoff,
998 : reduce);
999 0 : case TYPE_int:
1000 0 : return convert_int_msk(src, dst, ci, candoff,
1001 : reduce);
1002 0 : case TYPE_lng:
1003 0 : return convert_lng_msk(src, dst, ci, candoff,
1004 : reduce);
1005 : #ifdef HAVE_HGE
1006 0 : case TYPE_hge:
1007 0 : return convert_hge_msk(src, dst, ci, candoff,
1008 : reduce);
1009 : #endif
1010 0 : case TYPE_flt:
1011 0 : return convert_flt_msk(src, dst, ci, candoff,
1012 : reduce);
1013 0 : case TYPE_dbl:
1014 0 : return convert_dbl_msk(src, dst, ci, candoff,
1015 : reduce);
1016 : default:
1017 : return BUN_NONE + 1;
1018 : }
1019 561261 : case TYPE_bte:
1020 1122441 : switch (ATOMbasetype(dtp)) {
1021 0 : case TYPE_msk:
1022 0 : return convert_msk_bte(src, dst, ci, candoff,
1023 : reduce);
1024 219 : case TYPE_bte:
1025 219 : if (dtp == TYPE_bit)
1026 72 : return convert_bte_bit(src, dst, ci,
1027 : candoff, reduce);
1028 147 : return convert_bte_bte(src, dst, ci, candoff,
1029 : scale1,
1030 : scale2,
1031 : precision, reduce);
1032 159112 : case TYPE_sht:
1033 159112 : return convert_bte_sht(src, dst, ci, candoff,
1034 : scale1,
1035 : scale2,
1036 : precision, reduce);
1037 368672 : case TYPE_int:
1038 : #if SIZEOF_OID == SIZEOF_INT
1039 : if (dtp == TYPE_oid)
1040 : return convert_bte_oid(src, dst, ci,
1041 : candoff,
1042 : reduce);
1043 : #endif
1044 368672 : return convert_bte_int(src, dst, ci, candoff,
1045 : scale1,
1046 : scale2,
1047 : precision, reduce);
1048 30072 : case TYPE_lng:
1049 : #if SIZEOF_OID == SIZEOF_LNG
1050 30072 : if (dtp == TYPE_oid)
1051 9 : return convert_bte_oid(src, dst, ci,
1052 : candoff,
1053 : reduce);
1054 : #endif
1055 30063 : return convert_bte_lng(src, dst, ci, candoff,
1056 : scale1,
1057 : scale2,
1058 : precision, reduce);
1059 : #ifdef HAVE_HGE
1060 1115 : case TYPE_hge:
1061 1115 : return convert_bte_hge(src, dst, ci, candoff,
1062 : scale1,
1063 : scale2,
1064 : precision, reduce);
1065 : #endif
1066 201 : case TYPE_flt:
1067 201 : return convert_bte_flt(src, dst, ci, candoff,
1068 : scale1,
1069 : reduce);
1070 1870 : case TYPE_dbl:
1071 1870 : return convert_bte_dbl(src, dst, ci, candoff,
1072 : scale1,
1073 : reduce);
1074 : default:
1075 : return BUN_NONE + 1;
1076 : }
1077 260197 : case TYPE_sht:
1078 520384 : switch (ATOMbasetype(dtp)) {
1079 0 : case TYPE_msk:
1080 0 : return convert_msk_sht(src, dst, ci, candoff,
1081 : reduce);
1082 19 : case TYPE_bte:
1083 19 : if (dtp == TYPE_bit)
1084 7 : return convert_sht_bit(src, dst, ci,
1085 : candoff, reduce);
1086 12 : return convert_sht_bte(src, dst, ci, candoff,
1087 : scale1,
1088 : scale2,
1089 : precision, reduce);
1090 76 : case TYPE_sht:
1091 76 : return convert_sht_sht(src, dst, ci, candoff,
1092 : scale1,
1093 : scale2,
1094 : precision, reduce);
1095 257212 : case TYPE_int:
1096 : #if SIZEOF_OID == SIZEOF_INT
1097 : if (dtp == TYPE_oid)
1098 : return convert_sht_oid(src, dst, ci,
1099 : candoff,
1100 : reduce);
1101 : #endif
1102 257212 : return convert_sht_int(src, dst, ci, candoff,
1103 : scale1,
1104 : scale2,
1105 : precision, reduce);
1106 1550 : case TYPE_lng:
1107 : #if SIZEOF_OID == SIZEOF_LNG
1108 1550 : if (dtp == TYPE_oid)
1109 2 : return convert_sht_oid(src, dst, ci,
1110 : candoff,
1111 : reduce);
1112 : #endif
1113 1548 : return convert_sht_lng(src, dst, ci, candoff,
1114 : scale1,
1115 : scale2,
1116 : precision, reduce);
1117 : #ifdef HAVE_HGE
1118 531 : case TYPE_hge:
1119 531 : return convert_sht_hge(src, dst, ci, candoff,
1120 : scale1,
1121 : scale2,
1122 : precision, reduce);
1123 : #endif
1124 41 : case TYPE_flt:
1125 41 : return convert_sht_flt(src, dst, ci, candoff,
1126 : scale1,
1127 : reduce);
1128 768 : case TYPE_dbl:
1129 768 : return convert_sht_dbl(src, dst, ci, candoff,
1130 : scale1,
1131 : reduce);
1132 : default:
1133 : return BUN_NONE + 1;
1134 : }
1135 1178709 : case TYPE_int:
1136 2357335 : switch (ATOMbasetype(dtp)) {
1137 0 : case TYPE_msk:
1138 0 : return convert_msk_int(src, dst, ci, candoff,
1139 : reduce);
1140 434 : case TYPE_bte:
1141 434 : if (dtp == TYPE_bit) {
1142 72 : return convert_int_bit(src, dst, ci,
1143 : candoff, reduce);
1144 : }
1145 362 : return convert_int_bte(src, dst, ci, candoff,
1146 : scale1,
1147 : scale2,
1148 : precision, reduce);
1149 2492 : case TYPE_sht:
1150 2492 : return convert_int_sht(src, dst, ci, candoff,
1151 : scale1,
1152 : scale2,
1153 : precision, reduce);
1154 194 : case TYPE_int:
1155 : #if SIZEOF_OID == SIZEOF_INT
1156 : if (dtp == TYPE_oid)
1157 : return convert_int_oid(src, dst, ci,
1158 : candoff,
1159 : reduce);
1160 : #endif
1161 194 : return convert_int_int(src, dst, ci, candoff,
1162 : scale1,
1163 : scale2,
1164 : precision, reduce);
1165 1157796 : case TYPE_lng:
1166 : #if SIZEOF_OID == SIZEOF_LNG
1167 1157796 : if (dtp == TYPE_oid)
1168 9 : return convert_int_oid(src, dst, ci,
1169 : candoff,
1170 : reduce);
1171 : #endif
1172 1157787 : return convert_int_lng(src, dst, ci, candoff,
1173 : scale1,
1174 : scale2,
1175 : precision, reduce);
1176 : #ifdef HAVE_HGE
1177 1725 : case TYPE_hge:
1178 1725 : return convert_int_hge(src, dst, ci, candoff,
1179 : scale1,
1180 : scale2,
1181 : precision, reduce);
1182 : #endif
1183 165 : case TYPE_flt:
1184 165 : return convert_int_flt(src, dst, ci, candoff,
1185 : scale1,
1186 : reduce);
1187 15902 : case TYPE_dbl:
1188 15902 : return convert_int_dbl(src, dst, ci, candoff,
1189 : scale1,
1190 : reduce);
1191 : default:
1192 : return BUN_NONE + 1;
1193 : }
1194 5347 : case TYPE_lng:
1195 10670 : switch (ATOMbasetype(dtp)) {
1196 0 : case TYPE_msk:
1197 0 : return convert_msk_lng(src, dst, ci, candoff,
1198 : reduce);
1199 40 : case TYPE_bte:
1200 40 : if (dtp == TYPE_bit) {
1201 10 : return convert_lng_bit(src, dst, ci,
1202 : candoff, reduce);
1203 : }
1204 30 : return convert_lng_bte(src, dst, ci, candoff,
1205 : scale1,
1206 : scale2,
1207 : precision, reduce);
1208 104 : case TYPE_sht:
1209 104 : return convert_lng_sht(src, dst, ci, candoff,
1210 : scale1,
1211 : scale2,
1212 : precision, reduce);
1213 2024 : case TYPE_int:
1214 : #if SIZEOF_OID == SIZEOF_INT
1215 : if (dtp == TYPE_oid)
1216 : return convert_lng_oid(src, dst, ci,
1217 : candoff,
1218 : reduce);
1219 : #endif
1220 2024 : return convert_lng_int(src, dst, ci, candoff,
1221 : scale1,
1222 : scale2,
1223 : precision, reduce);
1224 428 : case TYPE_lng:
1225 : #if SIZEOF_OID == SIZEOF_LNG
1226 428 : if (dtp == TYPE_oid)
1227 14 : return convert_lng_oid(src, dst, ci,
1228 : candoff,
1229 : reduce);
1230 : #endif
1231 414 : return convert_lng_lng(src, dst, ci, candoff,
1232 : scale1,
1233 : scale2,
1234 : precision, reduce);
1235 : #ifdef HAVE_HGE
1236 1234 : case TYPE_hge:
1237 1234 : return convert_lng_hge(src, dst, ci, candoff,
1238 : scale1,
1239 : scale2,
1240 : precision, reduce);
1241 : #endif
1242 40 : case TYPE_flt:
1243 40 : return convert_lng_flt(src, dst, ci, candoff,
1244 : scale1,
1245 : reduce);
1246 1477 : case TYPE_dbl:
1247 1477 : return convert_lng_dbl(src, dst, ci, candoff,
1248 : scale1,
1249 : reduce);
1250 : default:
1251 : return BUN_NONE + 1;
1252 : }
1253 : #ifdef HAVE_HGE
1254 791 : case TYPE_hge:
1255 1579 : switch (ATOMbasetype(dtp)) {
1256 0 : case TYPE_msk:
1257 0 : return convert_msk_hge(src, dst, ci, candoff,
1258 : reduce);
1259 14 : case TYPE_bte:
1260 14 : if (dtp == TYPE_bit) {
1261 3 : return convert_hge_bit(src, dst, ci,
1262 : candoff, reduce);
1263 : }
1264 11 : return convert_hge_bte(src, dst, ci, candoff,
1265 : scale1,
1266 : scale2,
1267 : precision, reduce);
1268 14 : case TYPE_sht:
1269 14 : return convert_hge_sht(src, dst, ci, candoff,
1270 : scale1,
1271 : scale2,
1272 : precision, reduce);
1273 109 : case TYPE_int:
1274 109 : return convert_hge_int(src, dst, ci, candoff,
1275 : scale1,
1276 : scale2,
1277 : precision, reduce);
1278 386 : case TYPE_lng:
1279 386 : return convert_hge_lng(src, dst, ci, candoff,
1280 : scale1,
1281 : scale2,
1282 : precision, reduce);
1283 228 : case TYPE_hge:
1284 228 : return convert_hge_hge(src, dst, ci, candoff,
1285 : scale1,
1286 : scale2,
1287 : precision, reduce);
1288 0 : case TYPE_oid:
1289 0 : return convert_hge_oid(src, dst, ci, candoff, reduce);
1290 4 : case TYPE_flt:
1291 4 : return convert_hge_flt(src, dst, ci, candoff,
1292 : scale1,
1293 : reduce);
1294 36 : case TYPE_dbl:
1295 36 : return convert_hge_dbl(src, dst, ci, candoff,
1296 : scale1,
1297 : reduce);
1298 : default:
1299 : return BUN_NONE + 1;
1300 : }
1301 : #endif
1302 153 : case TYPE_flt:
1303 303 : switch (ATOMbasetype(dtp)) {
1304 0 : case TYPE_msk:
1305 0 : return convert_msk_flt(src, dst, ci, candoff,
1306 : reduce);
1307 5 : case TYPE_bte:
1308 5 : if (dtp == TYPE_bit) {
1309 3 : return convert_flt_bit(src, dst, ci,
1310 : candoff, reduce);
1311 : }
1312 2 : return convert_flt_bte(src, dst, ci, candoff,
1313 : scale2,
1314 : precision, reduce);
1315 2 : case TYPE_sht:
1316 2 : return convert_flt_sht(src, dst, ci, candoff,
1317 : scale2,
1318 : precision, reduce);
1319 6 : case TYPE_int:
1320 : #if SIZEOF_OID == SIZEOF_INT
1321 : if (dtp == TYPE_oid)
1322 : return convert_flt_oid(src, dst, ci,
1323 : candoff,
1324 : reduce);
1325 : #endif
1326 6 : return convert_flt_int(src, dst, ci, candoff,
1327 : scale2,
1328 : precision, reduce);
1329 22 : case TYPE_lng:
1330 : #if SIZEOF_OID == SIZEOF_LNG
1331 22 : if (dtp == TYPE_oid)
1332 0 : return convert_flt_oid(src, dst, ci,
1333 : candoff,
1334 : reduce);
1335 : #endif
1336 22 : return convert_flt_lng(src, dst, ci, candoff,
1337 : scale2,
1338 : precision, reduce);
1339 : #ifdef HAVE_HGE
1340 2 : case TYPE_hge:
1341 2 : return convert_flt_hge(src, dst, ci, candoff,
1342 : scale2,
1343 : precision, reduce);
1344 : #endif
1345 4 : case TYPE_flt:
1346 4 : return convert_flt_flt(src, dst, ci, candoff,
1347 : 0,
1348 : reduce);
1349 112 : case TYPE_dbl:
1350 112 : return convert_flt_dbl(src, dst, ci, candoff,
1351 : 0,
1352 : reduce);
1353 : default:
1354 : return BUN_NONE + 1;
1355 : }
1356 171 : case TYPE_dbl:
1357 335 : switch (ATOMbasetype(dtp)) {
1358 0 : case TYPE_msk:
1359 0 : return convert_msk_dbl(src, dst, ci, candoff,
1360 : reduce);
1361 19 : case TYPE_bte:
1362 19 : if (dtp == TYPE_bit) {
1363 7 : return convert_dbl_bit(src, dst, ci,
1364 : candoff, reduce);
1365 : }
1366 12 : return convert_dbl_bte(src, dst, ci, candoff,
1367 : scale2,
1368 : precision, reduce);
1369 6 : case TYPE_sht:
1370 6 : return convert_dbl_sht(src, dst, ci, candoff,
1371 : scale2,
1372 : precision, reduce);
1373 39 : case TYPE_int:
1374 : #if SIZEOF_OID == SIZEOF_INT
1375 : if (dtp == TYPE_oid)
1376 : return convert_dbl_oid(src, dst, ci,
1377 : candoff,
1378 : reduce);
1379 : #endif
1380 39 : return convert_dbl_int(src, dst, ci, candoff,
1381 : scale2,
1382 : precision, reduce);
1383 49 : case TYPE_lng:
1384 : #if SIZEOF_OID == SIZEOF_LNG
1385 49 : if (dtp == TYPE_oid)
1386 0 : return convert_dbl_oid(src, dst, ci,
1387 : candoff,
1388 : reduce);
1389 : #endif
1390 49 : return convert_dbl_lng(src, dst, ci, candoff,
1391 : scale2,
1392 : precision, reduce);
1393 : #ifdef HAVE_HGE
1394 14 : case TYPE_hge:
1395 14 : return convert_dbl_hge(src, dst, ci, candoff,
1396 : scale2,
1397 : precision, reduce);
1398 : #endif
1399 44 : case TYPE_flt:
1400 44 : return convert_dbl_flt(src, dst, ci, candoff,
1401 : 0, 0, reduce);
1402 0 : case TYPE_dbl:
1403 0 : return convert_dbl_dbl(src, dst, ci, candoff,
1404 : 0,
1405 : reduce);
1406 : default:
1407 : return BUN_NONE + 1;
1408 : }
1409 : default:
1410 : return BUN_NONE + 1;
1411 : }
1412 : }
1413 :
1414 : BAT *
1415 50366 : BATconvert(BAT *b, BAT *s, int tp,
1416 : uint8_t scale1, uint8_t scale2, uint8_t precision)
1417 : {
1418 50366 : lng t0 = 0;
1419 50366 : BAT *bn;
1420 50366 : BUN nils = 0; /* in case no conversion defined */
1421 50366 : struct canditer ci;
1422 50366 : BUN cnt;
1423 : /* set reduce to true if there are (potentially) multiple
1424 : * (different) source values that map to the same destination
1425 : * value */
1426 50366 : bool reduce = false;
1427 :
1428 50366 : TRC_DEBUG_IF(ALGO) t0 = GDKusec();
1429 :
1430 50366 : BATcheck(b, NULL);
1431 50366 : if (tp == TYPE_void)
1432 0 : tp = TYPE_oid;
1433 :
1434 50366 : BATiter bi = bat_iterator(b);
1435 50362 : cnt = BATcount(b);
1436 50362 : canditer_init(&ci, b, s);
1437 50366 : if (ci.ncand == 0 || (bi.type == TYPE_void && is_oid_nil(b->tseqbase))) {
1438 10909 : bat_iterator_end(&bi);
1439 10909 : return BATconstant(ci.hseq, tp,
1440 : ATOMnilptr(tp), ci.ncand, TRANSIENT);
1441 : }
1442 :
1443 76710 : if (cnt == ci.ncand && tp != TYPE_bit &&
1444 75807 : ATOMbasetype(bi.type) == ATOMbasetype(tp) &&
1445 11 : (tp != TYPE_oid || bi.type == TYPE_oid) &&
1446 1584 : scale1 == 0 && scale2 == 0 && precision == 0 &&
1447 15 : (tp != TYPE_str ||
1448 15 : BATatoms[bi.type].atomToStr == BATatoms[TYPE_str].atomToStr)) {
1449 1389 : bn = COLcopy(b, tp, false, TRANSIENT);
1450 1389 : if (bn && s)
1451 18 : bn->hseqbase = s->hseqbase;
1452 1389 : bat_iterator_end(&bi);
1453 1389 : return bn;
1454 : }
1455 38068 : if (ATOMstorage(tp) == TYPE_ptr) {
1456 0 : GDKerror("type combination (convert(%s)->%s) "
1457 : "not supported.\n",
1458 : ATOMname(bi.type), ATOMname(tp));
1459 0 : bat_iterator_end(&bi);
1460 0 : return NULL;
1461 : }
1462 38068 : if (ATOMstorage(tp) == TYPE_msk) {
1463 0 : if (BATtdensebi(&bi)) {
1464 : /* dense to msk is easy: all values 1, except
1465 : * maybe the first */
1466 0 : bn = BATconstant(ci.hseq, tp, &(msk){1}, ci.ncand,
1467 : TRANSIENT);
1468 0 : if (bn && b->tseqbase == 0)
1469 0 : mskClr(bn, 0);
1470 0 : bat_iterator_end(&bi);
1471 0 : return bn;
1472 0 : } else if (bi.type == TYPE_void) {
1473 : /* void-nil to msk is easy: all values 0 */
1474 0 : bn = BATconstant(ci.hseq, tp, &(msk){0}, ci.ncand,
1475 : TRANSIENT);
1476 0 : bat_iterator_end(&bi);
1477 0 : return bn;
1478 : }
1479 : }
1480 :
1481 38068 : bn = COLnew(ci.hseq, tp, ci.ncand, TRANSIENT);
1482 38067 : if (bn == NULL) {
1483 0 : bat_iterator_end(&bi);
1484 0 : return NULL;
1485 : }
1486 :
1487 38067 : if (bi.type == TYPE_void)
1488 0 : nils = convert_void_any(b->tseqbase, bn,
1489 : &ci, b->hseqbase, &reduce);
1490 38067 : else if (tp == TYPE_str)
1491 168 : nils = convert_any_str(&bi, bn, &ci);
1492 37899 : else if (bi.type == TYPE_str) {
1493 939 : reduce = true;
1494 939 : if (ATOMvarsized(tp)) {
1495 9 : nils = convert_str_var(&bi, bn, &ci);
1496 : } else {
1497 930 : nils = convert_str_fix(&bi, tp, Tloc(bn, 0),
1498 : &ci, b->hseqbase);
1499 : }
1500 36960 : } else if (ATOMstorage(bi.type) == TYPE_msk &&
1501 0 : ATOMstorage(tp) == TYPE_msk) {
1502 0 : if (BATappend(bn, b, s, false) != GDK_SUCCEED)
1503 : nils = BUN_NONE + 2;
1504 : } else {
1505 36960 : nils = convert_typeswitchloop(bi.base, bi.type,
1506 36960 : Tloc(bn, 0), tp,
1507 : &ci, b->hseqbase, &reduce,
1508 : scale1, scale2, precision);
1509 : }
1510 :
1511 38065 : if (nils >= BUN_NONE) {
1512 16 : BBPunfix(bn->batCacheid);
1513 16 : if (nils == BUN_NONE + 1) {
1514 0 : GDKerror("type combination (convert(%s)->%s) "
1515 : "not supported.\n",
1516 : ATOMname(bi.type), ATOMname(tp));
1517 16 : } else if (nils == BUN_NONE + 2) {
1518 0 : GDKerror("could not insert value into BAT.\n");
1519 : }
1520 16 : bat_iterator_end(&bi);
1521 16 : return NULL;
1522 : }
1523 :
1524 38049 : BATsetcount(bn, ci.ncand);
1525 :
1526 38049 : bn->tnil = nils != 0;
1527 38049 : bn->tnonil = nils == 0;
1528 38049 : if ((bn->ttype != TYPE_str && bn->ttype != TYPE_bit && bi.type != TYPE_str) ||
1529 1235 : BATcount(bn) < 2) {
1530 37212 : bn->tsorted = nils == 0 && bi.sorted;
1531 69220 : bn->trevsorted = nils == 0 && bi.revsorted;
1532 : } else {
1533 837 : bn->tsorted = false;
1534 837 : bn->trevsorted = false;
1535 : }
1536 38049 : if (!reduce || BATcount(bn) < 2)
1537 60303 : bn->tkey = bi.key && nils <= 1;
1538 : else
1539 2039 : bn->tkey = false;
1540 :
1541 38049 : bat_iterator_end(&bi);
1542 38051 : TRC_DEBUG(ALGO, "b=" ALGOBATFMT ",s=" ALGOOPTBATFMT
1543 : " -> " ALGOOPTBATFMT " " LLFMT "usec\n",
1544 : ALGOBATPAR(b), ALGOOPTBATPAR(s),
1545 : ALGOOPTBATPAR(bn), GDKusec() - t0);
1546 :
1547 : return bn;
1548 : }
1549 :
1550 : gdk_return
1551 2251989 : VARconvert(ValPtr ret, const ValRecord *v,
1552 : uint8_t scale1, uint8_t scale2, uint8_t precision)
1553 : {
1554 2251989 : ptr p;
1555 2251989 : BUN nils = 0;
1556 2251989 : bool reduce;
1557 :
1558 2251989 : assert(!v->bat);
1559 2251989 : if (ret->vtype == TYPE_msk) {
1560 0 : ValRecord tmp = { .vtype = TYPE_bit };
1561 0 : if (VARconvert(&tmp, v, scale1, scale2, precision) != GDK_SUCCEED)
1562 0 : return GDK_FAIL;
1563 0 : if (is_bte_nil(tmp.val.btval)) {
1564 0 : GDKerror("22003!cannot convert nil to msk.\n");
1565 0 : nils = BUN_NONE;
1566 : }
1567 0 : ret->val.mval = tmp.val.btval;
1568 0 : ret->len = ATOMsize(TYPE_msk);
1569 2251989 : } else if (v->vtype == TYPE_msk) {
1570 0 : ValRecord tmp = { .vtype = TYPE_bit, .val.btval = v->val.mval };
1571 0 : if (VARconvert(ret, &tmp, scale1, scale2, precision) != GDK_SUCCEED)
1572 0 : return GDK_FAIL;
1573 2251989 : } else if (ret->vtype == TYPE_str) {
1574 32503 : if (v->vtype == TYPE_void ||
1575 593 : (*ATOMcompare(v->vtype))(VALptr(v),
1576 : ATOMnilptr(v->vtype)) == 0) {
1577 31413 : if (VALinit(ret, TYPE_str, str_nil) == NULL)
1578 : return GDK_FAIL;
1579 497 : } else if (BATatoms[v->vtype].atomToStr == BATatoms[TYPE_str].atomToStr) {
1580 2 : if (VALinit(ret, TYPE_str, v->val.sval) == NULL)
1581 : return GDK_FAIL;
1582 : } else {
1583 495 : ret->len = 0;
1584 495 : ret->val.sval = NULL;
1585 495 : if ((*BATatoms[v->vtype].atomToStr)(&ret->val.sval,
1586 : &ret->len,
1587 : VALptr(v),
1588 : false) < 0) {
1589 0 : GDKfree(ret->val.sval);
1590 0 : ret->val.sval = NULL;
1591 0 : ret->len = 0;
1592 0 : return GDK_FAIL;
1593 : }
1594 : }
1595 2220079 : } else if (ret->vtype == TYPE_void) {
1596 0 : if (ATOMcmp(v->vtype, VALptr(v), ATOMnilptr(v->vtype)) != 0) {
1597 0 : GDKerror("22003!cannot convert non-nil to void.\n");
1598 0 : return GDK_FAIL;
1599 : }
1600 0 : ret->val.oval = oid_nil;
1601 0 : ret->len = ATOMsize(TYPE_void);
1602 2220079 : } else if (v->vtype == TYPE_void) {
1603 246630 : if (VALinit(ret, ret->vtype, ATOMnilptr(ret->vtype)) == NULL)
1604 : return GDK_FAIL;
1605 1973449 : } else if (v->vtype == TYPE_str) {
1606 3763 : if (strNil(v->val.sval)) {
1607 23 : if (VALinit(ret, ret->vtype, ATOMnilptr(ret->vtype)) == NULL)
1608 : return GDK_FAIL;
1609 3740 : } else if (ATOMstorage(ret->vtype) == TYPE_ptr) {
1610 : nils = BUN_NONE + 1;
1611 : } else {
1612 3740 : ssize_t l;
1613 3740 : size_t len;
1614 :
1615 3740 : if (ATOMextern(ret->vtype)) {
1616 : /* let atomFromStr allocate memory
1617 : * which we later give away to ret */
1618 4 : p = NULL;
1619 4 : len = 0;
1620 : } else {
1621 : /* use the space provided by ret */
1622 3736 : p = VALget(ret);
1623 3736 : len = ATOMsize(ret->vtype);
1624 : }
1625 3740 : if ((l = (*BATatoms[ret->vtype].atomFromStr)(
1626 3740 : v->val.sval, &len, &p, false)) < 0 ||
1627 3447 : l < (ssize_t) strlen(v->val.sval)) {
1628 370 : if (ATOMextern(ret->vtype))
1629 0 : GDKfree(p);
1630 370 : GDKclrerr();
1631 370 : size_t sz = escapedStrlen(v->val.sval, NULL, NULL, '\'');
1632 370 : char *bf = GDKmalloc(sz + 1);
1633 370 : if (bf) {
1634 370 : escapedStr(bf, v->val.sval, sz + 1, NULL, NULL, '\'');
1635 370 : GDKerror("22018!conversion of string "
1636 : "'%s' to type %s failed.\n",
1637 : bf, ATOMname(ret->vtype));
1638 370 : GDKfree(bf);
1639 : } else {
1640 0 : GDKerror("22018!conversion of string "
1641 : "to type %s failed.\n",
1642 : ATOMname(ret->vtype));
1643 : }
1644 370 : return GDK_FAIL;
1645 : } else {
1646 : /* now give value obtained to ret */
1647 3370 : assert(ATOMextern(ret->vtype) ||
1648 : p == VALget(ret));
1649 3370 : ret->len = (int) len;
1650 3370 : if (ATOMextern(ret->vtype))
1651 4 : VALset(ret, ret->vtype, p);
1652 : }
1653 : }
1654 : } else {
1655 1969686 : nils = convert_typeswitchloop(VALptr(v), v->vtype,
1656 : VALget(ret), ret->vtype,
1657 1969686 : &(struct canditer){.tpe=cand_dense, .ncand=1},
1658 : 0, &reduce,
1659 : scale1, scale2, precision);
1660 1969685 : if (nils < BUN_NONE)
1661 1969631 : ret->len = ATOMlen(ret->vtype, VALptr(ret));
1662 : }
1663 1973056 : if (nils == BUN_NONE + 1) {
1664 1 : GDKerror("conversion from type %s to type %s "
1665 : "unsupported.\n",
1666 : ATOMname(v->vtype), ATOMname(ret->vtype));
1667 1 : return GDK_FAIL;
1668 : }
1669 2251617 : return nils == BUN_NONE ? GDK_FAIL : GDK_SUCCEED;
1670 : }
|