LCOV - code coverage report
Current view: top level - gdk - gdk_calc_convert.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 410 631 65.0 %
Date: 2024-04-25 20:03:45 Functions: 65 84 77.4 %

          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             : }

Generated by: LCOV version 1.14