LCOV - code coverage report
Current view: top level - gdk - gdk_calc_convert.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 400 617 64.8 %
Date: 2024-04-26 00:35:57 Functions: 64 84 76.2 %

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

Generated by: LCOV version 1.14