LCOV - code coverage report
Current view: top level - sql/backends/monet5 - sql_round_impl.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 257 612 42.0 %
Date: 2024-12-19 23:10:26 Functions: 34 85 40.0 %

          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             : #define dec_round_body          FUN(TYPE, dec_round_body)
      14             : #define dec_round_wrap          FUN(TYPE, dec_round_wrap)
      15             : #define bat_dec_round_wrap      FUN(TYPE, bat_dec_round_wrap)
      16             : #define bat_dec_round_wrap_cst  FUN(TYPE, bat_dec_round_wrap_cst)
      17             : #define bat_dec_round_wrap_nocst        FUN(TYPE, bat_dec_round_wrap_nocst)
      18             : #define round_body              FUN(TYPE, round_body)
      19             : #define round_wrap              FUN(TYPE, round_wrap)
      20             : #define bat_round_wrap          FUN(TYPE, bat_round_wrap)
      21             : #define bat_round_wrap_cst      FUN(TYPE, bat_round_wrap_cst)
      22             : #define bat_round_wrap_nocst    FUN(TYPE, bat_round_wrap_nocst)
      23             : #define nil_2dec                FUN(nil_2dec, TYPE)
      24             : #define str_2dec_body           FUN(str_2dec_body, TYPE)
      25             : #define str_2dec                FUN(str_2dec, TYPE)
      26             : #define batnil_2dec             FUN(batnil_2dec, TYPE)
      27             : #define batstr_2dec             FUN(batstr_2dec, TYPE)
      28             : #define dec2second_interval     FUN(TYPE, dec2second_interval)
      29             : #define batdec2second_interval  FUN(TYPE, batdec2second_interval)
      30             : 
      31             : static inline TYPE
      32          21 : dec_round_body(TYPE v, TYPE r)
      33             : {
      34          21 :         TYPE add = r >> 1;
      35             : 
      36          21 :         assert(!ISNIL(TYPE)(v));
      37             : 
      38          21 :         if (v < 0)
      39           4 :                 add = -add;
      40          21 :         v += add;
      41          21 :         return v / r;
      42             : }
      43             : 
      44             : str
      45          12 : dec_round_wrap(TYPE *res, const TYPE *v, const TYPE *r)
      46             : {
      47             :         /* basic sanity checks */
      48          12 :         assert(res && v && r);
      49             : 
      50          12 :         if (ISNIL(TYPE)(*r))
      51           0 :                 throw(MAL, "round", SQLSTATE(42000) "Argument 2 to round function cannot be null");
      52          12 :         if (*r <= 0)
      53           0 :                 throw(MAL, "round", SQLSTATE(42000) "Argument 2 to round function must be positive");
      54             : 
      55          12 :         *res = ISNIL(TYPE)(*v) ? NIL(TYPE) : dec_round_body(*v, *r);
      56          12 :         return MAL_SUCCEED;
      57             : }
      58             : 
      59             : str
      60           1 : bat_dec_round_wrap(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
      61             : {
      62           1 :         BAT *bn = NULL, *b = NULL, *bs = NULL;
      63           1 :         TYPE *restrict src, *restrict dst, x, r = *(TYPE *)getArgReference(stk, pci, 2);
      64           1 :         str msg = MAL_SUCCEED;
      65           1 :         bool nils = false, btsorted = false, btrevsorted = false;
      66           1 :         struct canditer ci1 = {0};
      67           1 :         oid off1;
      68           1 :         bat *res = getArgReference_bat(stk, pci, 0), *bid = getArgReference_bat(stk, pci, 1),
      69           1 :                 *sid1 = pci->argc == 4 ? getArgReference_bat(stk, pci, 3) : NULL;
      70           1 :         BATiter bi;
      71             : 
      72           1 :         (void) cntxt;
      73           1 :         (void) mb;
      74           1 :         if (ISNIL(TYPE)(r)) {
      75           0 :                 msg = createException(MAL, "round", SQLSTATE(42000) "Argument 2 to round function cannot be null");
      76           0 :                 goto bailout;
      77             :         }
      78           1 :         if (r <= 0) {
      79           0 :                 msg = createException(MAL, "round", SQLSTATE(42000) "Argument 2 to round function must be positive");
      80           0 :                 goto bailout;
      81             :         }
      82           1 :         if (!(b = BATdescriptor(*bid))) {
      83           0 :                 msg = createException(MAL, "round", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
      84           0 :                 goto bailout;
      85             :         }
      86           1 :         if (b->ttype != TPE(TYPE)) {
      87           0 :                 msg = createException(MAL, "round", SQLSTATE(42000) "Argument 1 must have a " STRING(TYPE) " tail");
      88           0 :                 goto bailout;
      89             :         }
      90           1 :         if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
      91           0 :                 msg = createException(MAL, "round", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
      92           0 :                 goto bailout;
      93             :         }
      94           1 :         canditer_init(&ci1, b, bs);
      95           1 :         if (!(bn = COLnew(ci1.hseq, TPE(TYPE), ci1.ncand, TRANSIENT))) {
      96           0 :                 msg = createException(MAL, "round", SQLSTATE(HY013) MAL_MALLOC_FAIL);
      97           0 :                 goto bailout;
      98             :         }
      99             : 
     100           1 :         off1 = b->hseqbase;
     101           1 :         bi = bat_iterator(b);
     102           1 :         src = (TYPE *) bi.base;
     103           1 :         dst = (TYPE *) Tloc(bn, 0);
     104           1 :         if (ci1.tpe == cand_dense) {
     105          10 :                 for (BUN i = 0; i < ci1.ncand; i++) {
     106           9 :                         oid p1 = (canditer_next_dense(&ci1) - off1);
     107           9 :                         x = src[p1];
     108             : 
     109           9 :                         if (ISNIL(TYPE)(x)) {
     110           0 :                                 dst[i] = NIL(TYPE);
     111           0 :                                 nils = true;
     112             :                         } else {
     113           9 :                                 dst[i] = dec_round_body(x, r);
     114             :                         }
     115             :                 }
     116             :         } else {
     117           0 :                 for (BUN i = 0; i < ci1.ncand; i++) {
     118           0 :                         oid p1 = (canditer_next(&ci1) - off1);
     119           0 :                         x = src[p1];
     120             : 
     121           0 :                         if (ISNIL(TYPE)(x)) {
     122           0 :                                 dst[i] = NIL(TYPE);
     123           0 :                                 nils = true;
     124             :                         } else {
     125           0 :                                 dst[i] = dec_round_body(x, r);
     126             :                         }
     127             :                 }
     128             :         }
     129           1 :         btsorted = bi.sorted;
     130           1 :         btrevsorted = bi.revsorted;
     131           1 :         bat_iterator_end(&bi);
     132           1 : bailout:
     133           1 :         finalize_ouput_copy_sorted_property(res, bn, msg, nils, ci1.ncand, btsorted, btrevsorted);
     134           1 :         unfix_inputs(2, b, bs);
     135           1 :         return msg;
     136             : }
     137             : 
     138             : str
     139           0 : bat_dec_round_wrap_cst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     140             : {
     141           0 :         BAT *bn = NULL, *b = NULL, *bs = NULL;
     142           0 :         TYPE *restrict src, *restrict dst, x = *(TYPE *)getArgReference(stk, pci, 1), r;
     143           0 :         str msg = MAL_SUCCEED;
     144           0 :         bool nils = false;
     145           0 :         struct canditer ci1 = {0};
     146           0 :         oid off1;
     147           0 :         bat *res = getArgReference_bat(stk, pci, 0), *bid = getArgReference_bat(stk, pci, 2),
     148           0 :                 *sid1 = pci->argc == 4 ? getArgReference_bat(stk, pci, 3) : NULL;
     149           0 :         BATiter bi;
     150             : 
     151           0 :         (void) cntxt;
     152           0 :         (void) mb;
     153           0 :         if (!(b = BATdescriptor(*bid))) {
     154           0 :                 msg = createException(MAL, "round", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     155           0 :                 goto bailout;
     156             :         }
     157           0 :         if (b->ttype != TPE(TYPE)) {
     158           0 :                 msg = createException(MAL, "round", SQLSTATE(42000) "Argument 1 must have a " STRING(TYPE) " tail");
     159           0 :                 goto bailout;
     160             :         }
     161           0 :         if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
     162           0 :                 msg = createException(MAL, "round", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     163           0 :                 goto bailout;
     164             :         }
     165           0 :         canditer_init(&ci1, b, bs);
     166           0 :         if (!(bn = COLnew(ci1.hseq, TPE(TYPE), ci1.ncand, TRANSIENT))) {
     167           0 :                 msg = createException(MAL, "round", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     168           0 :                 goto bailout;
     169             :         }
     170             : 
     171           0 :         off1 = b->hseqbase;
     172           0 :         bi = bat_iterator(b);
     173           0 :         src = (TYPE *) bi.base;
     174           0 :         dst = (TYPE *) Tloc(bn, 0);
     175           0 :         if (ci1.tpe == cand_dense) {
     176           0 :                 for (BUN i = 0; i < ci1.ncand; i++) {
     177           0 :                         oid p1 = (canditer_next_dense(&ci1) - off1);
     178           0 :                         r = src[p1];
     179             : 
     180           0 :                         if (ISNIL(TYPE)(r)) {
     181           0 :                                 msg = createException(MAL, "round", SQLSTATE(42000) "Argument 2 to round function cannot be null");
     182           0 :                                 goto bailout1;
     183           0 :                         } else if (r <= 0) {
     184           0 :                                 msg = createException(MAL, "round", SQLSTATE(42000) "Argument 2 to round function must be positive");
     185           0 :                                 goto bailout1;
     186           0 :                         } else if (ISNIL(TYPE)(x)) {
     187           0 :                                 dst[i] = NIL(TYPE);
     188           0 :                                 nils = true;
     189             :                         } else {
     190           0 :                                 dst[i] = dec_round_body(x, r);
     191             :                         }
     192             :                 }
     193             :         } else {
     194           0 :                 for (BUN i = 0; i < ci1.ncand; i++) {
     195           0 :                         oid p1 = (canditer_next(&ci1) - off1);
     196           0 :                         r = src[p1];
     197             : 
     198           0 :                         if (ISNIL(TYPE)(r)) {
     199           0 :                                 msg = createException(MAL, "round", SQLSTATE(42000) "Argument 2 to round function cannot be null");
     200           0 :                                 goto bailout1;
     201           0 :                         } else if (r <= 0) {
     202           0 :                                 msg = createException(MAL, "round", SQLSTATE(42000) "Argument 2 to round function must be positive");
     203           0 :                                 goto bailout1;
     204           0 :                         } else if (ISNIL(TYPE)(x)) {
     205           0 :                                 dst[i] = NIL(TYPE);
     206           0 :                                 nils = true;
     207             :                         } else {
     208           0 :                                 dst[i] = dec_round_body(x, r);
     209             :                         }
     210             :                 }
     211             :         }
     212           0 : bailout1:
     213           0 :         bat_iterator_end(&bi);
     214             : 
     215           0 : bailout:
     216           0 :         finalize_ouput_copy_sorted_property(res, bn, msg, nils, ci1.ncand, false, false/* don't propagate here*/);
     217           0 :         unfix_inputs(2, b, bs);
     218           0 :         return msg;
     219             : }
     220             : 
     221             : str
     222           0 : bat_dec_round_wrap_nocst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     223             : {
     224           0 :         BAT *bn = NULL, *left = NULL, *lefts = NULL, *right = NULL, *rights = NULL;
     225           0 :         TYPE *src1, *src2, *restrict dst, x, rr;
     226           0 :         str msg = MAL_SUCCEED;
     227           0 :         bool nils = false;
     228           0 :         struct canditer ci1 = {0}, ci2 = {0};
     229           0 :         oid off1, off2;
     230           0 :         bat *res = getArgReference_bat(stk, pci, 0), *l = getArgReference_bat(stk, pci, 1),
     231           0 :                 *r = getArgReference_bat(stk, pci, 2),
     232           0 :                 *sid1 = pci->argc == 5 ? getArgReference_bat(stk, pci, 3) : NULL,
     233           0 :                 *sid2 = pci->argc == 5 ? getArgReference_bat(stk, pci, 4) : NULL;
     234           0 :         BATiter lefti, righti;
     235             : 
     236           0 :         (void) cntxt;
     237           0 :         (void) mb;
     238           0 :         if (!(left = BATdescriptor(*l)) || !(right = BATdescriptor(*r))) {
     239           0 :                 msg = createException(MAL, "round", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     240           0 :                 goto bailout;
     241             :         }
     242           0 :         if (left->ttype != TPE(TYPE) || right->ttype != TPE(TYPE)) {
     243           0 :                 msg = createException(MAL, "round", SQLSTATE(42000) "Arguments must have a " STRING(TYPE) " tail");
     244           0 :                 goto bailout;
     245             :         }
     246           0 :         if ((sid1 && !is_bat_nil(*sid1) && !(lefts = BATdescriptor(*sid1))) || (sid2 && !is_bat_nil(*sid2) && !(rights = BATdescriptor(*sid2)))) {
     247           0 :                 msg = createException(MAL, "round", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     248           0 :                 goto bailout;
     249             :         }
     250           0 :         canditer_init(&ci1, left, lefts);
     251           0 :         canditer_init(&ci2, right, rights);
     252           0 :         if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq) {
     253           0 :                 msg = createException(MAL, "round", ILLEGAL_ARGUMENT " Requires bats of identical size");
     254           0 :                 goto bailout;
     255             :         }
     256           0 :         if (!(bn = COLnew(ci1.hseq, TPE(TYPE), ci1.ncand, TRANSIENT))) {
     257           0 :                 msg = createException(MAL, "round", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     258           0 :                 goto bailout;
     259             :         }
     260             : 
     261           0 :         off1 = left->hseqbase;
     262           0 :         off2 = right->hseqbase;
     263           0 :         lefti = bat_iterator(left);
     264           0 :         righti = bat_iterator(right);
     265           0 :         src1 = (TYPE *) lefti.base;
     266           0 :         src2 = (TYPE *) righti.base;
     267           0 :         dst = (TYPE *) Tloc(bn, 0);
     268           0 :         if (ci1.tpe == cand_dense && ci2.tpe == cand_dense) {
     269           0 :                 for (BUN i = 0; i < ci1.ncand; i++) {
     270           0 :                         oid p1 = (canditer_next_dense(&ci1) - off1), p2 = (canditer_next_dense(&ci2) - off2);
     271           0 :                         x = src1[p1];
     272           0 :                         rr = src2[p2];
     273             : 
     274           0 :                         if (ISNIL(TYPE)(rr)) {
     275           0 :                                 msg = createException(MAL, "round", SQLSTATE(42000) "Argument 2 to round function cannot be null");
     276           0 :                                 goto bailout1;
     277           0 :                         } else if (rr <= 0) {
     278           0 :                                 msg = createException(MAL, "round", SQLSTATE(42000) "Argument 2 to round function must be positive");
     279           0 :                                 goto bailout1;
     280           0 :                         } else if (ISNIL(TYPE)(x)) {
     281           0 :                                 dst[i] = NIL(TYPE);
     282           0 :                                 nils = true;
     283             :                         } else {
     284           0 :                                 dst[i] = dec_round_body(x, rr);
     285             :                         }
     286             :                 }
     287             :         } else {
     288           0 :                 for (BUN i = 0; i < ci1.ncand; i++) {
     289           0 :                         oid p1 = (canditer_next(&ci1) - off1), p2 = (canditer_next(&ci2) - off2);
     290           0 :                         x = src1[p1];
     291           0 :                         rr = src2[p2];
     292             : 
     293           0 :                         if (ISNIL(TYPE)(rr)) {
     294           0 :                                 msg = createException(MAL, "round", SQLSTATE(42000) "Argument 2 to round function cannot be null");
     295           0 :                                 goto bailout1;
     296           0 :                         } else if (rr <= 0) {
     297           0 :                                 msg = createException(MAL, "round", SQLSTATE(42000) "Argument 2 to round function must be positive");
     298           0 :                                 goto bailout1;
     299           0 :                         } else if (ISNIL(TYPE)(x)) {
     300           0 :                                 dst[i] = NIL(TYPE);
     301           0 :                                 nils = true;
     302             :                         } else {
     303           0 :                                 dst[i] = dec_round_body(x, rr);
     304             :                         }
     305             :                 }
     306             :         }
     307           0 : bailout1:
     308           0 :         bat_iterator_end(&lefti);
     309           0 :         bat_iterator_end(&righti);
     310             : 
     311           0 : bailout:
     312           0 :         finalize_ouput_copy_sorted_property(res, bn, msg, nils, ci1.ncand, false, false/* don't propagate here*/);
     313           0 :         unfix_inputs(4, left, lefts, right, rights);
     314           0 :         return msg;
     315             : }
     316             : 
     317             : static inline TYPE
     318       18692 : round_body(TYPE v, int d, int s, int r)
     319             : {
     320       18692 :         TYPE res = NIL(TYPE);
     321             : 
     322       18692 :         assert(!ISNIL(TYPE)(v));
     323             : 
     324       18692 :         if (r > 0 && r < s) {
     325       17817 :                 int dff = s - r;
     326       17817 :                 BIG rnd = scales[dff] >> 1;
     327       17817 :                 BIG lres;
     328       17817 :                 if (v > 0)
     329       17817 :                         lres = ((v + rnd) / scales[dff]) * scales[dff];
     330             :                 else
     331           0 :                         lres = ((v - rnd) / scales[dff]) * scales[dff];
     332           7 :                 res = (TYPE) lres;
     333         875 :         } else if (r <= 0 && -r > -s) {
     334          25 :                 int dff = -r + s;
     335          25 :                 if (dff > d) {
     336             :                         res = 0;
     337             :                 } else {
     338          21 :                         BIG rnd = scales[dff] >> 1;
     339          21 :                         BIG lres;
     340          21 :                         if (v > 0)
     341          13 :                                 lres = ((v + rnd) / scales[dff]) * scales[dff];
     342             :                         else
     343           8 :                                 lres = ((v - rnd) / scales[dff]) * scales[dff];
     344          11 :                         res = (TYPE) lres;
     345             :                 }
     346             :         } else {
     347             :                 res = v;
     348             :         }
     349       18692 :         return res;
     350             : }
     351             : 
     352             : str
     353          17 : round_wrap(TYPE *res, const TYPE *v, const bte *r, const int *d, const int *s)
     354             : {
     355             :         /* basic sanity checks */
     356          17 :         assert(res && v && r && d && s);
     357             : 
     358          17 :         *res = (ISNIL(TYPE)(*v) || is_bte_nil(*r)) ? NIL(TYPE) : round_body(*v, *d, *s, *r);
     359          17 :         return MAL_SUCCEED;
     360             : }
     361             : 
     362             : str
     363          28 : bat_round_wrap(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     364             : {
     365          28 :         BAT *bn = NULL, *b = NULL, *bs = NULL;
     366          28 :         TYPE *restrict src, *restrict dst, x;
     367          28 :         bte r = *getArgReference_bte(stk, pci, 2);
     368          84 :         int d = *getArgReference_int(stk, pci, pci->argc == 6 ? 4 : 3), s = *getArgReference_int(stk, pci, pci->argc == 6 ? 5 : 4);
     369          28 :         str msg = MAL_SUCCEED;
     370          28 :         bool nils = false, btsorted = false, btrevsorted = false;
     371          28 :         struct canditer ci1 = {0};
     372          28 :         oid off1;
     373          28 :         bat *res = getArgReference_bat(stk, pci, 0), *bid = getArgReference_bat(stk, pci, 1),
     374          28 :                 *sid1 = pci->argc == 6 ? getArgReference_bat(stk, pci, 3) : NULL;
     375          28 :         BATiter bi;
     376             : 
     377          28 :         (void) cntxt;
     378          28 :         (void) mb;
     379          28 :         if (!(b = BATdescriptor(*bid))) {
     380           0 :                 msg = createException(MAL, "round", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     381           0 :                 goto bailout;
     382             :         }
     383          28 :         if (b->ttype != TPE(TYPE)) {
     384           0 :                 msg = createException(MAL, "round", SQLSTATE(42000) "Argument 1 must have a " STRING(TYPE) " tail");
     385           0 :                 goto bailout;
     386             :         }
     387          28 :         if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
     388           0 :                 msg = createException(MAL, "round", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     389           0 :                 goto bailout;
     390             :         }
     391          28 :         canditer_init(&ci1, b, bs);
     392          28 :         if (!(bn = COLnew(ci1.hseq, TPE(TYPE), ci1.ncand, TRANSIENT))) {
     393           0 :                 msg = createException(MAL, "round", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     394           0 :                 goto bailout;
     395             :         }
     396             : 
     397          28 :         off1 = b->hseqbase;
     398          28 :         bi = bat_iterator(b);
     399          28 :         src = (TYPE *) bi.base;
     400          28 :         dst = (TYPE *) Tloc(bn, 0);
     401          28 :         if (ci1.tpe == cand_dense) {
     402       18688 :                 for (BUN i = 0; i < ci1.ncand; i++) {
     403       18660 :                         oid p1 = (canditer_next_dense(&ci1) - off1);
     404       18660 :                         x = src[p1];
     405             : 
     406       18660 :                         if (ISNIL(TYPE)(x) || is_bte_nil(r)) {
     407           4 :                                 dst[i] = NIL(TYPE);
     408           4 :                                 nils = true;
     409             :                         } else {
     410       18656 :                                 dst[i] = round_body(x, d, s, r);
     411             :                         }
     412             :                 }
     413             :         } else {
     414           0 :                 for (BUN i = 0; i < ci1.ncand; i++) {
     415           0 :                         oid p1 = (canditer_next(&ci1) - off1);
     416           0 :                         x = src[p1];
     417             : 
     418           0 :                         if (ISNIL(TYPE)(x) || is_bte_nil(r)) {
     419           0 :                                 dst[i] = NIL(TYPE);
     420           0 :                                 nils = true;
     421             :                         } else {
     422           0 :                                 dst[i] = round_body(x, d, s, r);
     423             :                         }
     424             :                 }
     425             :         }
     426          28 :         btsorted = bi.sorted;
     427          28 :         btrevsorted = bi.revsorted;
     428          28 :         bat_iterator_end(&bi);
     429             : 
     430          28 : bailout:
     431          28 :         finalize_ouput_copy_sorted_property(res, bn, msg, nils, ci1.ncand, btsorted, btrevsorted);
     432          28 :         unfix_inputs(2, b, bs);
     433          28 :         return msg;
     434             : }
     435             : 
     436             : str
     437           8 : bat_round_wrap_cst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     438             : {
     439           8 :         BAT *bn = NULL, *b = NULL, *bs = NULL;
     440           8 :         TYPE *restrict dst, x = *(TYPE *)getArgReference(stk, pci, 1);
     441           8 :         bte *restrict src, r;
     442          22 :         int d = *getArgReference_int(stk, pci, pci->argc == 6 ? 4 : 3), s = *getArgReference_int(stk, pci, pci->argc == 6 ? 5 : 4);
     443           8 :         str msg = MAL_SUCCEED;
     444           8 :         bool nils = false;
     445           8 :         struct canditer ci1 = {0};
     446           8 :         oid off1;
     447           8 :         bat *res = getArgReference_bat(stk, pci, 0), *bid = getArgReference_bat(stk, pci, 2),
     448           8 :                 *sid1 = pci->argc == 6 ? getArgReference_bat(stk, pci, 3) : NULL;
     449           8 :         BATiter bi;
     450             : 
     451           8 :         (void) cntxt;
     452           8 :         (void) mb;
     453           8 :         if (!(b = BATdescriptor(*bid))) {
     454           0 :                 msg = createException(MAL, "round", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     455           0 :                 goto bailout;
     456             :         }
     457           8 :         if (b->ttype != TYPE_bte) {
     458           0 :                 msg = createException(MAL, "round", SQLSTATE(42000) "Argument 2 must have a bte tail");
     459           0 :                 goto bailout;
     460             :         }
     461           8 :         if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
     462           0 :                 msg = createException(MAL, "round", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     463           0 :                 goto bailout;
     464             :         }
     465           8 :         canditer_init(&ci1, b, bs);
     466           8 :         if (!(bn = COLnew(ci1.hseq, TPE(TYPE), ci1.ncand, TRANSIENT))) {
     467           0 :                 msg = createException(MAL, "round", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     468           0 :                 goto bailout;
     469             :         }
     470             : 
     471           8 :         off1 = b->hseqbase;
     472           8 :         bi = bat_iterator(b);
     473           8 :         src = (bte *) bi.base;
     474           8 :         dst = (TYPE *) Tloc(bn, 0);
     475           8 :         if (ci1.tpe == cand_dense) {
     476          26 :                 for (BUN i = 0; i < ci1.ncand; i++) {
     477          18 :                         oid p1 = (canditer_next_dense(&ci1) - off1);
     478          18 :                         r = src[p1];
     479             : 
     480          18 :                         if (ISNIL(TYPE)(x) || is_bte_nil(r)) {
     481           0 :                                 dst[i] = NIL(TYPE);
     482           0 :                                 nils = true;
     483             :                         } else {
     484          18 :                                 dst[i] = round_body(x, d, s, r);
     485             :                         }
     486             :                 }
     487             :         } else {
     488           0 :                 for (BUN i = 0; i < ci1.ncand; i++) {
     489           0 :                         oid p1 = (canditer_next(&ci1) - off1);
     490           0 :                         r = src[p1];
     491             : 
     492           0 :                         if (ISNIL(TYPE)(x) || is_bte_nil(r)) {
     493           0 :                                 dst[i] = NIL(TYPE);
     494           0 :                                 nils = true;
     495             :                         } else {
     496           0 :                                 dst[i] = round_body(x, d, s, r);
     497             :                         }
     498             :                 }
     499             :         }
     500           8 :         bat_iterator_end(&bi);
     501             : 
     502           8 : bailout:
     503           8 :         finalize_ouput_copy_sorted_property(res, bn, msg, nils, ci1.ncand, false, false/* don't propagate here*/);
     504           8 :         unfix_inputs(2, b, bs);
     505           8 :         return msg;
     506             : }
     507             : 
     508             : str
     509           1 : bat_round_wrap_nocst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     510             : {
     511           1 :         BAT *bn = NULL, *left = NULL, *lefts = NULL, *right = NULL, *rights = NULL;
     512           1 :         TYPE *restrict dst, *src1, x;
     513           1 :         bte *src2, rr;
     514           3 :         int d = *getArgReference_int(stk, pci, pci->argc == 7 ? 5 : 3), s = *getArgReference_int(stk, pci, pci->argc == 7 ? 6 : 4);
     515           1 :         str msg = MAL_SUCCEED;
     516           1 :         bool nils = false;
     517           1 :         struct canditer ci1 = {0}, ci2 = {0};
     518           1 :         oid off1, off2;
     519           1 :         bat *res = getArgReference_bat(stk, pci, 0), *l = getArgReference_bat(stk, pci, 1),
     520           1 :                 *r = getArgReference_bat(stk, pci, 2),
     521           1 :                 *sid1 = pci->argc == 7 ? getArgReference_bat(stk, pci, 3) : NULL,
     522           1 :                 *sid2 = pci->argc == 7 ? getArgReference_bat(stk, pci, 4) : NULL;
     523           1 :         BATiter lefti, righti;
     524             : 
     525           1 :         (void) cntxt;
     526           1 :         (void) mb;
     527           1 :         if (!(left = BATdescriptor(*l)) || !(right = BATdescriptor(*r))) {
     528           0 :                 msg = createException(MAL, "round", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     529           0 :                 goto bailout;
     530             :         }
     531           1 :         if (left->ttype != TPE(TYPE)) {
     532           0 :                 msg = createException(MAL, "round", SQLSTATE(42000) "Argument 1 must have a " STRING(TYPE) " tail");
     533           0 :                 goto bailout;
     534             :         }
     535           1 :         if (right->ttype != TYPE_bte) {
     536           0 :                 msg = createException(MAL, "round", SQLSTATE(42000) "Argument 2 must have a bte tail");
     537           0 :                 goto bailout;
     538             :         }
     539           1 :         if ((sid1 && !is_bat_nil(*sid1) && !(lefts = BATdescriptor(*sid1))) || (sid2 && !is_bat_nil(*sid2) && !(rights = BATdescriptor(*sid2)))) {
     540           0 :                 msg = createException(MAL, "round", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     541           0 :                 goto bailout;
     542             :         }
     543           1 :         canditer_init(&ci1, left, lefts);
     544           1 :         canditer_init(&ci2, right, rights);
     545           1 :         if (ci2.ncand != ci1.ncand || ci1.hseq != ci2.hseq) {
     546           0 :                 msg = createException(MAL, "round", ILLEGAL_ARGUMENT " Requires bats of identical size");
     547           0 :                 goto bailout;
     548             :         }
     549           1 :         if (!(bn = COLnew(ci1.hseq, TPE(TYPE), ci1.ncand, TRANSIENT))) {
     550           0 :                 msg = createException(MAL, "round", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     551           0 :                 goto bailout;
     552             :         }
     553             : 
     554           1 :         off1 = left->hseqbase;
     555           1 :         off2 = right->hseqbase;
     556           1 :         lefti = bat_iterator(left);
     557           1 :         righti = bat_iterator(right);
     558           1 :         src1 = (TYPE *) lefti.base;
     559           1 :         src2 = (bte *) righti.base;
     560           1 :         dst = (TYPE *) Tloc(bn, 0);
     561           1 :         if (ci1.tpe == cand_dense && ci2.tpe == cand_dense) {
     562           2 :                 for (BUN i = 0; i < ci1.ncand; i++) {
     563           1 :                         oid p1 = (canditer_next_dense(&ci1) - off1), p2 = (canditer_next_dense(&ci2) - off2);
     564           1 :                         x = src1[p1];
     565           1 :                         rr = src2[p2];
     566             : 
     567           1 :                         if (ISNIL(TYPE)(x) || is_bte_nil(rr)) {
     568           0 :                                 dst[i] = NIL(TYPE);
     569           0 :                                 nils = true;
     570             :                         } else {
     571           1 :                                 dst[i] = round_body(x, d, s, rr);
     572             :                         }
     573             :                 }
     574             :         } else {
     575           0 :                 for (BUN i = 0; i < ci1.ncand; i++) {
     576           0 :                         oid p1 = (canditer_next(&ci1) - off1), p2 = (canditer_next(&ci2) - off2);
     577           0 :                         x = src1[p1];
     578           0 :                         rr = src2[p2];
     579             : 
     580           0 :                         if (ISNIL(TYPE)(x) || is_bte_nil(rr)) {
     581           0 :                                 dst[i] = NIL(TYPE);
     582           0 :                                 nils = true;
     583             :                         } else {
     584           0 :                                 dst[i] = round_body(x, d, s, rr);
     585             :                         }
     586             :                 }
     587             :         }
     588           1 :         bat_iterator_end(&lefti);
     589           1 :         bat_iterator_end(&righti);
     590             : 
     591           1 : bailout:
     592           1 :         finalize_ouput_copy_sorted_property(res, bn, msg, nils, ci1.ncand, false, false/* don't propagate here*/);
     593           1 :         unfix_inputs(4, left, lefts, right, rights);
     594           1 :         return msg;
     595             : }
     596             : 
     597             : str
     598           0 : nil_2dec(TYPE *res, const void *val, const int *d, const int *sc)
     599             : {
     600           0 :         (void) val;
     601           0 :         (void) d;
     602           0 :         (void) sc;
     603             : 
     604           0 :         *res = NIL(TYPE);
     605           0 :         return MAL_SUCCEED;
     606             : }
     607             : 
     608             : static inline str
     609         718 : str_2dec_body(TYPE *res, const char *val, const int d, const int sc)
     610             : {
     611         718 :         const char *s = val;
     612         718 :         int digits;
     613         718 :         int scale;
     614         718 :         BIG value;
     615             : 
     616         718 :         if (d < 0 || d >= (int) (sizeof(scales) / sizeof(scales[0])))
     617           0 :                 throw(SQL, STRING(TYPE), SQLSTATE(42000) "Decimal (%s) doesn't have format (%d.%d)", s, d, sc);
     618             : 
     619         718 :         int has_errors;
     620         718 :         value = 0;
     621             : 
     622             :         // s = strip_extra_zeros(s);
     623             : 
     624         718 :         value = decimal_from_str(s, &digits, &scale, &has_errors);
     625         718 :         if (has_errors)
     626          77 :                 throw(SQL, STRING(TYPE), SQLSTATE(42000) "Decimal (%s) doesn't have format (%d.%d)", s, d, sc);
     627             : 
     628             :         // handle situations where the de facto scale is different from the formal scale.
     629         641 :         if (scale < sc) {
     630             :                 /* the current scale is too small, increase it by adding 0's */
     631         464 :                 int dff = sc - scale;   /* CANNOT be 0! */
     632         464 :                 if (dff >= MAX_SCALE)
     633           0 :                         throw(SQL, STRING(TYPE), SQLSTATE(42000) "Rounding of decimal (%s) doesn't fit format (%d.%d)", s, d, sc);
     634             : 
     635         464 :                 value *= scales[dff];
     636         464 :                 scale += dff;
     637         464 :                 digits += dff;
     638         177 :         } else if (scale > sc) {
     639             :                 /* the current scale is too big, decrease it by correctly rounding */
     640             :                 /* we should round properly, and check for overflow (res >= 10^digits+scale) */
     641         126 :                 int dff = scale - sc;   /* CANNOT be 0 */
     642             : 
     643         126 :                 if (dff >= MAX_SCALE)
     644           0 :                         throw(SQL, STRING(TYPE), SQLSTATE(42000) "Rounding of decimal (%s) doesn't fit format (%d.%d)", s, d, sc);
     645             : 
     646         126 :                 BIG rnd = scales[dff] >> 1;
     647             : 
     648         126 :                 if (value > 0)
     649          89 :                         value += rnd;
     650             :                 else
     651          37 :                         value -= rnd;
     652         126 :                 value /= scales[dff];
     653         126 :                 scale -= dff;
     654         126 :                 digits -= dff;
     655         126 :                 if (value >= scales[d] || value <= -scales[d])
     656          14 :                         throw(SQL, STRING(TYPE), SQLSTATE(42000) "Rounding of decimal (%s) doesn't fit format (%d.%d)", s, d, sc);
     657             :         }
     658         627 :         if (value <= -scales[d] || value >= scales[d])
     659           2 :                 throw(SQL, STRING(TYPE), SQLSTATE(42000) "Decimal (%s) doesn't have format (%d.%d)", s, d, sc);
     660         626 :         *res = (TYPE) value;
     661         626 :         return MAL_SUCCEED;
     662             : }
     663             : 
     664             : str
     665         558 : str_2dec(TYPE *res, const str *val, const int *d, const int *sc)
     666             : {
     667         558 :         str v = *val;
     668             : 
     669         558 :         if (strNil(v)) {
     670           0 :                 *res = NIL(TYPE);
     671           0 :                 return MAL_SUCCEED;
     672             :         } else {
     673         558 :                 return str_2dec_body(res, v, *d, *sc);
     674             :         }
     675             : }
     676             : 
     677             : str
     678           0 : batnil_2dec(bat *res, const bat *bid, const int *d, const int *sc)
     679             : {
     680           0 :         BAT *b, *dst;
     681           0 :         BUN p, q;
     682             : 
     683           0 :         (void) d;
     684           0 :         (void) sc;
     685           0 :         if ((b = BATdescriptor(*bid)) == NULL) {
     686           0 :                 throw(SQL, "batcalc.nil_2dec_" STRING(TYPE), SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     687             :         }
     688           0 :         dst = COLnew(b->hseqbase, TPE(TYPE), BATcount(b), TRANSIENT);
     689           0 :         if (dst == NULL) {
     690           0 :                 BBPunfix(b->batCacheid);
     691           0 :                 throw(SQL, "sql.dec_" STRING(TYPE), SQLSTATE(HY013) MAL_MALLOC_FAIL);
     692             :         }
     693           0 :         const TYPE r = NIL(TYPE);
     694           0 :         BATloop(b, p, q) {
     695           0 :                 if (BUNappend(dst, &r, false) != GDK_SUCCEED) {
     696           0 :                         BBPunfix(b->batCacheid);
     697           0 :                         BBPreclaim(dst);
     698           0 :                         throw(SQL, "sql.dec_" STRING(TYPE), SQLSTATE(HY013) MAL_MALLOC_FAIL);
     699             :                 }
     700             :         }
     701           0 :         *res = dst->batCacheid;
     702           0 :         BBPkeepref(dst);
     703           0 :         BBPunfix(b->batCacheid);
     704           0 :         return MAL_SUCCEED;
     705             : }
     706             : 
     707             : str
     708          71 : batstr_2dec(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     709             : {
     710          71 :         str msg = MAL_SUCCEED;
     711          71 :         int d = *getArgReference_int(stk, pci, pci->argc == 5 ? 3 : 2), sk = *getArgReference_int(stk, pci, pci->argc == 5 ? 4 : 3);
     712          71 :         BAT *b = NULL, *s = NULL, *res = NULL;
     713          71 :         bat *r = getArgReference_bat(stk, pci, 0), *sid = pci->argc == 5 ? getArgReference_bat(stk, pci, 2) : NULL;
     714          71 :         BATiter bi;
     715          71 :         oid off;
     716          71 :         struct canditer ci = {0};
     717          71 :         TYPE *restrict ret;
     718          71 :         bool nils = false;
     719             : 
     720          71 :         (void) cntxt;
     721          71 :         (void) mb;
     722          71 :         if (!(b = BATdescriptor(*getArgReference_bat(stk, pci, 1)))) {
     723           0 :                 msg = createException(SQL, "sql.dec_" STRING(TYPE), SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     724           0 :                 goto bailout;
     725             :         }
     726          71 :         bi = bat_iterator(b);
     727          70 :         if (sid && !is_bat_nil(*sid) && (s = BATdescriptor(*sid)) == NULL) {
     728           0 :                 msg = createException(SQL, "sql.dec_" STRING(TYPE), SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     729           0 :                 goto bailout1;
     730             :         }
     731          70 :         off = b->hseqbase;
     732          70 :         canditer_init(&ci, b, s);
     733          71 :         if (!(res = COLnew(ci.hseq, TPE(TYPE), ci.ncand, TRANSIENT))) {
     734           0 :                 msg = createException(SQL, "sql.dec_" STRING(TYPE), SQLSTATE(HY013) MAL_MALLOC_FAIL);
     735           0 :                 goto bailout1;
     736             :         }
     737          70 :         ret = (TYPE*) Tloc(res, 0);
     738             : 
     739          70 :         if (ci.tpe == cand_dense) {
     740         230 :                 for (BUN i = 0; i < ci.ncand; i++) {
     741         160 :                         oid p = (canditer_next_dense(&ci) - off);
     742         160 :                         const char *next = BUNtail(bi, p);
     743             : 
     744         160 :                         if (strNil(next)) {
     745           0 :                                 ret[i] = NIL(TYPE);
     746           0 :                                 nils = true;
     747         160 :                         } else if ((msg = str_2dec_body(&(ret[i]), next, d, sk)))
     748           1 :                                 goto bailout1;
     749             :                 }
     750             :         } else {
     751           0 :                 for (BUN i = 0; i < ci.ncand; i++) {
     752           0 :                         oid p = (canditer_next(&ci) - off);
     753           0 :                         const char *next = BUNtail(bi, p);
     754             : 
     755           0 :                         if (strNil(next)) {
     756           0 :                                 ret[i] = NIL(TYPE);
     757           0 :                                 nils = true;
     758           0 :                         } else if ((msg = str_2dec_body(&(ret[i]), next, d, sk)))
     759           0 :                                 goto bailout1;
     760             :                 }
     761             :         }
     762           0 : bailout1:
     763          71 :         bat_iterator_end(&bi);
     764             : 
     765          71 : bailout:
     766          71 :         finalize_ouput_copy_sorted_property(r, res, msg, nils, ci.ncand, false, false/* don't propagate here*/);
     767          71 :         unfix_inputs(2, b, s);
     768          71 :         return msg;
     769             : }
     770             : 
     771             : str
     772           0 : dec2second_interval(lng *res, const int *sc, const TYPE *dec, const int *ek, const int *sk)
     773             : {
     774           0 :         BIG value = *dec;
     775           0 :         int scale = *sc;
     776             : 
     777           0 :         if (is_int_nil(scale))
     778           0 :                 throw(SQL, "calc.dec2second_interval", SQLSTATE(42000) "Scale cannot be NULL");
     779           0 :         if (scale < 0 || (size_t) scale >= sizeof(scales) / sizeof(scales[0]))
     780           0 :                 throw(SQL, "calc.dec2second_interval", SQLSTATE(42000) "Scale out of bounds");
     781             : 
     782           0 :         (void) ek;
     783           0 :         (void) sk;
     784           0 :         if (ISNIL(TYPE)(*dec)) {
     785           0 :                 value = lng_nil;
     786           0 :         } else if (scale < 3) {
     787           0 :                 int d = 3 - scale;
     788           0 :                 value *= scales[d];
     789           0 :         } else if (scale > 3) {
     790           0 :                 int d = scale - 3;
     791           0 :                 lng rnd = scales[d] >> 1;
     792             : 
     793           0 :                 value += rnd;
     794           0 :                 value /= scales[d];
     795             :         }
     796           0 :         *res = value;
     797           0 :         return MAL_SUCCEED;
     798             : }
     799             : 
     800             : str
     801           0 : batdec2second_interval(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     802             : {
     803           0 :         str msg = MAL_SUCCEED;
     804           0 :         int sc = *getArgReference_int(stk, pci, 1);
     805           0 :         BAT *b = NULL, *s = NULL, *res = NULL;
     806           0 :         bat *r = getArgReference_bat(stk, pci, 0), *sid = pci->argc == 6 ? getArgReference_bat(stk, pci, 3) : NULL;
     807           0 :         oid off;
     808           0 :         struct canditer ci = {0};
     809           0 :         TYPE *restrict src;
     810           0 :         BIG *restrict ret, multiplier = 1, divider = 1, offset = 0;
     811           0 :         bool nils = false;
     812           0 :         BATiter bi;
     813             : 
     814           0 :         (void) cntxt;
     815           0 :         (void) mb;
     816           0 :         if (is_int_nil(sc)) {
     817           0 :                 msg = createException(SQL, "batcalc.batdec2second_interval", SQLSTATE(42000) "Scale cannot be NULL");
     818           0 :                 goto bailout;
     819             :         }
     820           0 :         if (sc < 0 || (size_t) sc >= sizeof(scales) / sizeof(scales[0])) {
     821           0 :                 msg = createException(SQL, "batcalc.batdec2second_interval", SQLSTATE(42000) "Scale out of bounds");
     822           0 :                 goto bailout;
     823             :         }
     824           0 :         if (!(b = BATdescriptor(*getArgReference_bat(stk, pci, 2)))) {
     825           0 :                 msg = createException(SQL, "batcalc.batdec2second_interval", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     826           0 :                 goto bailout;
     827             :         }
     828           0 :         if (sid && !is_bat_nil(*sid) && (s = BATdescriptor(*sid)) == NULL) {
     829           0 :                 msg = createException(SQL, "batcalc.batdec2second_interval", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     830           0 :                 goto bailout;
     831             :         }
     832           0 :         off = b->hseqbase;
     833           0 :         canditer_init(&ci, b, s);
     834           0 :         if (!(res = COLnew(ci.hseq, TYPE_lng, ci.ncand, TRANSIENT))) {
     835           0 :                 msg = createException(SQL, "batcalc.batdec2second_interval", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     836           0 :                 goto bailout;
     837             :         }
     838           0 :         bi = bat_iterator(b);
     839           0 :         src = bi.base;
     840           0 :         ret = Tloc(res, 0);
     841             : 
     842           0 :         if (sc < 3) {
     843           0 :                 int d = 3 - sc;
     844           0 :                 multiplier = scales[d];
     845           0 :         } else if (sc > 3) {
     846           0 :                 int d = sc - 3;
     847           0 :                 lng rnd = scales[d] >> 1;
     848             : 
     849           0 :                 offset = rnd;
     850           0 :                 divider = scales[d];
     851             :         }
     852             : 
     853             :         /* the cast from decimal to interval is now deactivated. So adding the canditer_next_dense case is not worth */
     854           0 :         if (sc < 3) {
     855           0 :                 for (BUN i = 0 ; i < ci.ncand ; i++) {
     856           0 :                         oid p = (canditer_next(&ci) - off);
     857           0 :                         if (ISNIL(TYPE)(src[p])) {
     858           0 :                                 ret[i] = lng_nil;
     859           0 :                                 nils = true;
     860             :                         } else {
     861           0 :                                 BIG next = (BIG) src[p];
     862           0 :                                 next *= multiplier;
     863           0 :                                 ret[i] = next;
     864             :                         }
     865             :                 }
     866           0 :         } else if (sc > 3) {
     867           0 :                 for (BUN i = 0 ; i < ci.ncand ; i++) {
     868           0 :                         oid p = (canditer_next(&ci) - off);
     869           0 :                         if (ISNIL(TYPE)(src[p])) {
     870           0 :                                 ret[i] = lng_nil;
     871           0 :                                 nils = true;
     872             :                         } else {
     873           0 :                                 BIG next = (BIG) src[p];
     874           0 :                                 next += offset;
     875           0 :                                 next /= divider;
     876           0 :                                 ret[i] = next;
     877             :                         }
     878             :                 }
     879             :         } else {
     880           0 :                 for (BUN i = 0 ; i < ci.ncand ; i++) {
     881           0 :                         oid p = (canditer_next(&ci) - off);
     882           0 :                         if (ISNIL(TYPE)(src[p])) {
     883           0 :                                 ret[i] = lng_nil;
     884           0 :                                 nils = true;
     885             :                         } else {
     886           0 :                                 ret[i] = (BIG) src[p];
     887             :                         }
     888             :                 }
     889             :         }
     890           0 :         bat_iterator_end(&bi);
     891             : 
     892           0 : bailout:
     893           0 :         finalize_ouput_copy_sorted_property(r, res, msg, nils, ci.ncand, false, false/* don't propagate here*/);
     894           0 :         unfix_inputs(2, b, s);
     895           0 :         return msg;
     896             : }
     897             : 
     898             : #undef dec_round_body
     899             : #undef dec_round_wrap
     900             : #undef bat_dec_round_wrap
     901             : #undef bat_dec_round_wrap_cst
     902             : #undef bat_dec_round_wrap_nocst
     903             : #undef round_body
     904             : #undef round_wrap
     905             : #undef bat_round_wrap
     906             : #undef bat_round_wrap_cst
     907             : #undef bat_round_wrap_nocst
     908             : #undef nil_2dec
     909             : #undef str_2dec_body
     910             : #undef str_2dec
     911             : #undef batnil_2dec
     912             : #undef batstr_2dec
     913             : #undef dec2second_interval
     914             : #undef batdec2second_interval

Generated by: LCOV version 1.14