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