LCOV - code coverage report
Current view: top level - sql/backends/monet5 - sql_fround_impl.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 122 393 31.0 %
Date: 2021-10-13 02:24:04 Functions: 10 22 45.5 %

          Line data    Source code
       1             : /*
       2             :  * This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0.  If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       5             :  *
       6             :  * Copyright 1997 - July 2008 CWI, August 2008 - 2021 MonetDB B.V.
       7             :  */
       8             : 
       9             : #define dec_round_body          FUN(TYPE, dec_round_body)
      10             : #define dec_round_wrap          FUN(TYPE, dec_round_wrap)
      11             : #define bat_dec_round_wrap      FUN(TYPE, bat_dec_round_wrap)
      12             : #define bat_dec_round_wrap_cst  FUN(TYPE, bat_dec_round_wrap_cst)
      13             : #define bat_dec_round_wrap_nocst        FUN(TYPE, bat_dec_round_wrap_nocst)
      14             : #define round_body              FUN(TYPE, round_body)
      15             : #define round_wrap              FUN(TYPE, round_wrap)
      16             : #define bat_round_wrap          FUN(TYPE, bat_round_wrap)
      17             : #define bat_round_wrap_cst      FUN(TYPE, bat_round_wrap_cst)
      18             : #define bat_round_wrap_nocst    FUN(TYPE, bat_round_wrap_nocst)
      19             : #define trunc_wrap              FUN(TYPE, trunc_wrap)
      20             : 
      21             : static inline TYPE
      22          20 : dec_round_body(TYPE v, TYPE r)
      23             : {
      24          20 :         assert(!ISNIL(TYPE)(v));
      25             : 
      26          20 :         return v / r;
      27             : }
      28             : 
      29             : str
      30           4 : dec_round_wrap(TYPE *res, const TYPE *v, const TYPE *r)
      31             : {
      32             :         /* basic sanity checks */
      33           4 :         assert(res && v);
      34           4 :         TYPE rr = *r;
      35             : 
      36           4 :         if (ISNIL(TYPE)(rr))
      37           2 :                 throw(MAL, "round", SQLSTATE(42000) "Argument 2 to round function cannot be null");
      38           2 :         if (rr <= 0)
      39           0 :                 throw(MAL, "round", SQLSTATE(42000) "Argument 2 to round function must be positive");
      40           2 :         *res = ISNIL(TYPE)(*v) ? NIL(TYPE) : dec_round_body(*v, rr);
      41           2 :         if (isinf(*res))
      42           0 :                 throw(MAL, "round", SQLSTATE(22003) "Overflow in round");
      43             :         return MAL_SUCCEED;
      44             : }
      45             : 
      46             : str
      47           1 : bat_dec_round_wrap(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
      48             : {
      49             :         BAT *bn = NULL, *b = NULL, *bs = NULL;
      50             :         BUN q = 0;
      51           1 :         TYPE *restrict src, *restrict dst, x, r = *(TYPE *)getArgReference(stk, pci, 2);
      52             :         str msg = MAL_SUCCEED;
      53             :         bool nils = false;
      54           1 :         struct canditer ci1 = {0};
      55             :         oid off1;
      56           1 :         bat *res = getArgReference_bat(stk, pci, 0), *bid = getArgReference_bat(stk, pci, 1),
      57           1 :                 *sid1 = pci->argc == 4 ? getArgReference_bat(stk, pci, 3) : NULL;
      58             :         BATiter bi;
      59             : 
      60             :         (void) cntxt;
      61             :         (void) mb;
      62           1 :         if (ISNIL(TYPE)(r)) {
      63           0 :                 msg = createException(MAL, "round", SQLSTATE(42000) "Argument 2 to round function cannot be null");
      64           0 :                 goto bailout;
      65             :         }
      66           1 :         if (r <= 0) {
      67           0 :                 msg = createException(MAL, "round", SQLSTATE(42000) "Argument 2 to round function must be positive");
      68           0 :                 goto bailout;
      69             :         }
      70           1 :         if (!(b = BATdescriptor(*bid))) {
      71           0 :                 msg = createException(MAL, "round", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
      72           0 :                 goto bailout;
      73             :         }
      74           1 :         if (b->ttype != TPE(TYPE)) {
      75           0 :                 msg = createException(MAL, "round", SQLSTATE(42000) "Argument 1 must have a " STRING(TYPE) " tail");
      76           0 :                 goto bailout;
      77             :         }
      78           1 :         if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
      79           0 :                 msg = createException(MAL, "round", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
      80           0 :                 goto bailout;
      81             :         }
      82           1 :         q = canditer_init(&ci1, b, bs);
      83           1 :         if (!(bn = COLnew(ci1.hseq, TPE(TYPE), q, TRANSIENT))) {
      84           0 :                 msg = createException(MAL, "round", SQLSTATE(HY013) MAL_MALLOC_FAIL);
      85           0 :                 goto bailout;
      86             :         }
      87             : 
      88           1 :         off1 = b->hseqbase;
      89           1 :         bi = bat_iterator(b);
      90           1 :         src = (TYPE *) bi.base;
      91           1 :         dst = (TYPE *) Tloc(bn, 0);
      92           1 :         if (ci1.tpe == cand_dense) {
      93           6 :                 for (BUN i = 0; i < q; i++) {
      94           6 :                         oid p1 = (canditer_next_dense(&ci1) - off1);
      95           6 :                         x = src[p1];
      96             : 
      97           6 :                         if (ISNIL(TYPE)(x)) {
      98           0 :                                 dst[i] = NIL(TYPE);
      99             :                                 nils = true;
     100             :                         } else {
     101           6 :                                 dst[i] = dec_round_body(x, r);
     102           6 :                                 if (isinf(dst[i])) {
     103           1 :                                         msg = createException(MAL, "round", SQLSTATE(22003) "Overflow in round");
     104           1 :                                         goto bailout1;
     105             :                                 }
     106             :                         }
     107             :                 }
     108             :         } else {
     109           0 :                 for (BUN i = 0; i < q; i++) {
     110           0 :                         oid p1 = (canditer_next(&ci1) - off1);
     111           0 :                         x = src[p1];
     112             : 
     113           0 :                         if (ISNIL(TYPE)(x)) {
     114           0 :                                 dst[i] = NIL(TYPE);
     115             :                                 nils = true;
     116             :                         } else {
     117           0 :                                 dst[i] = dec_round_body(x, r);
     118           0 :                                 if (isinf(dst[i])) {
     119           0 :                                         msg = createException(MAL, "round", SQLSTATE(22003) "Overflow in round");
     120           0 :                                         goto bailout1;
     121             :                                 }
     122             :                         }
     123             :                 }
     124             :         }
     125           0 : bailout1:
     126           1 :         bat_iterator_end(&bi);
     127           1 : bailout:
     128           1 :         finalize_ouput_copy_sorted_property(res, bn, b, msg, nils, q, true);
     129           1 :         unfix_inputs(2, b, bs);
     130           1 :         return msg;
     131             : }
     132             : 
     133             : str
     134           2 : bat_dec_round_wrap_cst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     135             : {
     136             :         BAT *bn = NULL, *b = NULL, *bs = NULL;
     137             :         BUN q = 0;
     138           2 :         TYPE *restrict src, *restrict dst, x = *(TYPE *)getArgReference(stk, pci, 1), r;
     139             :         str msg = MAL_SUCCEED;
     140             :         bool nils = false;
     141           2 :         struct canditer ci1 = {0};
     142             :         oid off1;
     143           2 :         bat *res = getArgReference_bat(stk, pci, 0), *bid = getArgReference_bat(stk, pci, 2),
     144           2 :                 *sid1 = pci->argc == 4 ? getArgReference_bat(stk, pci, 3) : NULL;
     145             :         BATiter bi;
     146             : 
     147             :         (void) cntxt;
     148             :         (void) mb;
     149           2 :         if (!(b = BATdescriptor(*bid))) {
     150           0 :                 msg = createException(MAL, "round", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     151           0 :                 goto bailout;
     152             :         }
     153           2 :         if (b->ttype != TPE(TYPE)) {
     154           0 :                 msg = createException(MAL, "round", SQLSTATE(42000) "Argument 2 must have a " STRING(TYPE) " tail");
     155           0 :                 goto bailout;
     156             :         }
     157           2 :         if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
     158           0 :                 msg = createException(MAL, "round", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     159           0 :                 goto bailout;
     160             :         }
     161           2 :         q = canditer_init(&ci1, b, bs);
     162           2 :         if (!(bn = COLnew(ci1.hseq, TPE(TYPE), q, TRANSIENT))) {
     163           0 :                 msg = createException(MAL, "round", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     164           0 :                 goto bailout;
     165             :         }
     166             : 
     167           2 :         off1 = b->hseqbase;
     168           2 :         bi = bat_iterator(b);
     169           2 :         src = (TYPE *) bi.base;
     170           2 :         dst = (TYPE *) Tloc(bn, 0);
     171           2 :         if (ci1.tpe == cand_dense) {
     172          14 :                 for (BUN i = 0; i < q; i++) {
     173          13 :                         oid p1 = (canditer_next_dense(&ci1) - off1);
     174          13 :                         r = src[p1];
     175             : 
     176          13 :                         if (ISNIL(TYPE)(r)) {
     177           0 :                                 msg = createException(MAL, "round", SQLSTATE(42000) "Argument 2 to round function cannot be null");
     178           0 :                                 goto bailout1;
     179          13 :                         } else if (r <= 0) {
     180           1 :                                 msg = createException(MAL, "round", SQLSTATE(42000) "Argument 2 to round function must be positive");
     181           1 :                                 goto bailout1;
     182          12 :                         } else if (ISNIL(TYPE)(x)) {
     183           0 :                                 dst[i] = NIL(TYPE);
     184             :                                 nils = true;
     185             :                         } else {
     186          12 :                                 dst[i] = dec_round_body(x, r);
     187          12 :                                 if (isinf(dst[i])) {
     188           0 :                                         msg = createException(MAL, "round", SQLSTATE(22003) "Overflow in round");
     189           0 :                                         goto bailout1;
     190             :                                 }
     191             :                         }
     192             :                 }
     193             :         } else {
     194           0 :                 for (BUN i = 0; i < q; 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             :                                 nils = true;
     207             :                         } else {
     208           0 :                                 dst[i] = dec_round_body(x, r);
     209           0 :                                 if (isinf(dst[i])) {
     210           0 :                                         msg = createException(MAL, "round", SQLSTATE(22003) "Overflow in round");
     211           0 :                                         goto bailout1;
     212             :                                 }
     213             :                         }
     214             :                 }
     215             :         }
     216           0 : bailout1:
     217           2 :         bat_iterator_end(&bi);
     218             : 
     219           2 : bailout:
     220           2 :         finalize_ouput_copy_sorted_property(res, bn, b, msg, nils, q, false);
     221           2 :         unfix_inputs(2, b, bs);
     222           2 :         return msg;
     223             : }
     224             : 
     225             : str
     226           0 : bat_dec_round_wrap_nocst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     227             : {
     228             :         BAT *bn = NULL, *left = NULL, *lefts = NULL, *right = NULL, *rights = NULL;
     229             :         BUN q = 0;
     230             :         TYPE *src1, *src2, *restrict dst, x, rr;
     231             :         str msg = MAL_SUCCEED;
     232             :         bool nils = false;
     233           0 :         struct canditer ci1 = {0}, ci2 = {0};
     234             :         oid off1, off2;
     235           0 :         bat *res = getArgReference_bat(stk, pci, 0), *l = getArgReference_bat(stk, pci, 1),
     236           0 :                 *r = getArgReference_bat(stk, pci, 2),
     237           0 :                 *sid1 = pci->argc == 5 ? getArgReference_bat(stk, pci, 3) : NULL,
     238           0 :                 *sid2 = pci->argc == 5 ? getArgReference_bat(stk, pci, 4) : NULL;
     239             :         BATiter lefti, righti;
     240             : 
     241             :         (void) cntxt;
     242             :         (void) mb;
     243           0 :         if (!(left = BATdescriptor(*l)) || !(right = BATdescriptor(*r))) {
     244           0 :                 msg = createException(MAL, "round", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     245           0 :                 goto bailout;
     246             :         }
     247           0 :         if (left->ttype != TPE(TYPE) || right->ttype != TPE(TYPE)) {
     248           0 :                 msg = createException(MAL, "round", SQLSTATE(42000) "Arguments must have a " STRING(TYPE) " tail");
     249           0 :                 goto bailout;
     250             :         }
     251           0 :         if ((sid1 && !is_bat_nil(*sid1) && !(lefts = BATdescriptor(*sid1))) || (sid2 && !is_bat_nil(*sid2) && !(rights = BATdescriptor(*sid2)))) {
     252           0 :                 msg = createException(MAL, "round", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     253           0 :                 goto bailout;
     254             :         }
     255           0 :         q = canditer_init(&ci1, left, lefts);
     256           0 :         if (canditer_init(&ci2, right, rights) != q || ci1.hseq != ci2.hseq) {
     257           0 :                 msg = createException(MAL, "round", ILLEGAL_ARGUMENT " Requires bats of identical size");
     258           0 :                 goto bailout;
     259             :         }
     260           0 :         if (!(bn = COLnew(ci1.hseq, TPE(TYPE), q, TRANSIENT))) {
     261           0 :                 msg = createException(MAL, "round", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     262           0 :                 goto bailout;
     263             :         }
     264             : 
     265           0 :         off1 = left->hseqbase;
     266           0 :         off2 = right->hseqbase;
     267           0 :         lefti = bat_iterator(left);
     268           0 :         righti = bat_iterator(right);
     269           0 :         src1 = (TYPE *) lefti.base;
     270           0 :         src2 = (TYPE *) righti.base;
     271           0 :         dst = (TYPE *) Tloc(bn, 0);
     272           0 :         if (ci1.tpe == cand_dense && ci2.tpe == cand_dense) {
     273           0 :                 for (BUN i = 0; i < q; i++) {
     274           0 :                         oid p1 = (canditer_next_dense(&ci1) - off1), p2 = (canditer_next_dense(&ci2) - off2);
     275           0 :                         x = src1[p1];
     276           0 :                         rr = src2[p2];
     277             : 
     278           0 :                         if (ISNIL(TYPE)(rr)) {
     279           0 :                                 msg = createException(MAL, "round", SQLSTATE(42000) "Argument 2 to round function cannot be null");
     280           0 :                                 goto bailout1;
     281           0 :                         } else if (rr <= 0) {
     282           0 :                                 msg = createException(MAL, "round", SQLSTATE(42000) "Argument 2 to round function must be positive");
     283           0 :                                 goto bailout1;
     284           0 :                         } else if (ISNIL(TYPE)(x)) {
     285           0 :                                 dst[i] = NIL(TYPE);
     286             :                                 nils = true;
     287             :                         } else {
     288           0 :                                 dst[i] = dec_round_body(x, rr);
     289           0 :                                 if (isinf(dst[i])) {
     290           0 :                                         msg = createException(MAL, "round", SQLSTATE(22003) "Overflow in round");
     291           0 :                                         goto bailout1;
     292             :                                 }
     293             :                         }
     294             :                 }
     295             :         } else {
     296           0 :                 for (BUN i = 0; i < q; i++) {
     297           0 :                         oid p1 = (canditer_next(&ci1) - off1), p2 = (canditer_next(&ci2) - off2);
     298           0 :                         x = src1[p1];
     299           0 :                         rr = src2[p2];
     300             : 
     301           0 :                         if (ISNIL(TYPE)(rr)) {
     302           0 :                                 msg = createException(MAL, "round", SQLSTATE(42000) "Argument 2 to round function cannot be null");
     303           0 :                                 goto bailout1;
     304           0 :                         } else if (rr <= 0) {
     305           0 :                                 msg = createException(MAL, "round", SQLSTATE(42000) "Argument 2 to round function must be positive");
     306           0 :                                 goto bailout1;
     307           0 :                         } else if (ISNIL(TYPE)(x)) {
     308           0 :                                 dst[i] = NIL(TYPE);
     309             :                                 nils = true;
     310             :                         } else {
     311           0 :                                 dst[i] = dec_round_body(x, rr);
     312           0 :                                 if (isinf(dst[i])) {
     313           0 :                                         msg = createException(MAL, "round", SQLSTATE(22003) "Overflow in round");
     314           0 :                                         goto bailout1;
     315             :                                 }
     316             :                         }
     317             :                 }
     318             :         }
     319           0 : bailout1:
     320           0 :         bat_iterator_end(&lefti);
     321           0 :         bat_iterator_end(&righti);
     322             : 
     323           0 : bailout:
     324           0 :         finalize_ouput_copy_sorted_property(res, bn, left, msg, nils, q, false);
     325           0 :         unfix_inputs(4, left, lefts, right, rights);
     326           0 :         return msg;
     327             : }
     328             : 
     329             : static inline TYPE
     330          25 : round_body(TYPE v, int r)
     331             : {
     332             :         TYPE res = NIL(TYPE);
     333             : 
     334          25 :         assert(!ISNIL(TYPE)(v));
     335             : 
     336          25 :         if (r < 0) {
     337           0 :                 int d = -r;
     338           0 :                 TYPE rnd = (TYPE) (scales[d] >> 1);
     339             : 
     340           0 :                 res = (TYPE) (floor(((v + rnd) / ((TYPE) (scales[d])))) * scales[d]);
     341          25 :         } else if (r > 0) {
     342             :                 int d = r;
     343             : 
     344           8 :                 res = (TYPE) (floor(v * (TYPE) scales[d] + .5) / scales[d]);
     345             :         } else {
     346          17 :                 res = (TYPE) round(v);
     347             :         }
     348          25 :         return res;
     349             : }
     350             : 
     351             : str
     352           8 : round_wrap(TYPE *res, const TYPE *v, const bte *r)
     353             : {
     354             :         /* basic sanity checks */
     355           8 :         assert(res && v && r);
     356           8 :         bte rr = *r;
     357             : 
     358           8 :         if (is_bte_nil(rr) || (size_t) abs(rr) >= sizeof(scales) / sizeof(scales[0]))
     359           0 :                 throw(MAL, "round", SQLSTATE(42000) "Digits out of bounds");
     360           8 :         *res = (ISNIL(TYPE)(*v)) ? NIL(TYPE) : round_body(*v, rr);
     361           8 :         if (isinf(*res))
     362           2 :                 throw(MAL, "round", SQLSTATE(22003) "Overflow in round");
     363             :         return MAL_SUCCEED;
     364             : }
     365             : 
     366             : str
     367           6 : bat_round_wrap(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     368             : {
     369             :         BAT *bn = NULL, *b = NULL, *bs = NULL;
     370             :         BUN q = 0;
     371             :         TYPE *restrict src, *restrict dst, x;
     372           6 :         bte r = *getArgReference_bte(stk, pci, 2);
     373             :         str msg = MAL_SUCCEED;
     374             :         bool nils = false;
     375           6 :         struct canditer ci1 = {0};
     376             :         oid off1;
     377           6 :         bat *res = getArgReference_bat(stk, pci, 0), *bid = getArgReference_bat(stk, pci, 1),
     378           6 :                 *sid1 = pci->argc == 4 ? getArgReference_bat(stk, pci, 3) : NULL;
     379             :         BATiter bi;
     380             : 
     381             :         (void) cntxt;
     382             :         (void) mb;
     383           6 :         if (is_bte_nil(r) || (size_t) abs(r) >= sizeof(scales) / sizeof(scales[0])) {
     384           1 :                 msg = createException(MAL, "round", SQLSTATE(42000) "Digits out of bounds");
     385           1 :                 goto bailout;
     386             :         }
     387           5 :         if (!(b = BATdescriptor(*bid))) {
     388           0 :                 msg = createException(MAL, "round", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     389           0 :                 goto bailout;
     390             :         }
     391           5 :         if (b->ttype != TPE(TYPE)) {
     392           0 :                 msg = createException(MAL, "round", SQLSTATE(42000) "Argument 1 must have a " STRING(TYPE) " tail");
     393           0 :                 goto bailout;
     394             :         }
     395           5 :         if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
     396           0 :                 msg = createException(MAL, "round", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     397           0 :                 goto bailout;
     398             :         }
     399           5 :         q = canditer_init(&ci1, b, bs);
     400           5 :         if (!(bn = COLnew(ci1.hseq, TPE(TYPE), q, TRANSIENT))) {
     401           0 :                 msg = createException(MAL, "round", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     402           0 :                 goto bailout;
     403             :         }
     404             : 
     405           5 :         off1 = b->hseqbase;
     406           5 :         bi = bat_iterator(b);
     407           5 :         src = (TYPE *) bi.base;
     408           5 :         dst = (TYPE *) Tloc(bn, 0);
     409           5 :         if (ci1.tpe == cand_dense) {
     410          22 :                 for (BUN i = 0; i < q; i++) {
     411          17 :                         oid p1 = (canditer_next_dense(&ci1) - off1);
     412          17 :                         x = src[p1];
     413             : 
     414          17 :                         if (ISNIL(TYPE)(x)) {
     415           0 :                                 dst[i] = NIL(TYPE);
     416             :                                 nils = true;
     417             :                         } else {
     418          17 :                                 dst[i] = round_body(x, r);
     419          17 :                                 if (isinf(dst[i])) {
     420           0 :                                         msg = createException(MAL, "round", SQLSTATE(22003) "Overflow in round");
     421           0 :                                         goto bailout1;
     422             :                                 }
     423             :                         }
     424             :                 }
     425             :         } else {
     426           0 :                 for (BUN i = 0; i < q; i++) {
     427           0 :                         oid p1 = (canditer_next(&ci1) - off1);
     428           0 :                         x = src[p1];
     429             : 
     430           0 :                         if (ISNIL(TYPE)(x)) {
     431           0 :                                 dst[i] = NIL(TYPE);
     432             :                                 nils = true;
     433             :                         } else {
     434           0 :                                 dst[i] = round_body(x, r);
     435           0 :                                 if (isinf(dst[i])) {
     436           0 :                                         msg = createException(MAL, "round", SQLSTATE(22003) "Overflow in round");
     437           0 :                                         goto bailout1;
     438             :                                 }
     439             :                         }
     440             :                 }
     441             :         }
     442           0 : bailout1:
     443           5 :         bat_iterator_end(&bi);
     444           6 : bailout:
     445           6 :         finalize_ouput_copy_sorted_property(res, bn, b, msg, nils, q, true);
     446           6 :         unfix_inputs(2, b, bs);
     447           6 :         return msg;
     448             : }
     449             : 
     450             : str
     451           0 : bat_round_wrap_cst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     452             : {
     453             :         BAT *bn = NULL, *b = NULL, *bs = NULL;
     454             :         BUN q = 0;
     455           0 :         TYPE *restrict dst, x = *(TYPE *)getArgReference(stk, pci, 1);
     456             :         bte *restrict src, r;
     457             :         str msg = MAL_SUCCEED;
     458             :         bool nils = false;
     459           0 :         struct canditer ci1 = {0};
     460             :         oid off1;
     461           0 :         bat *res = getArgReference_bat(stk, pci, 0), *bid = getArgReference_bat(stk, pci, 2),
     462           0 :                 *sid1 = pci->argc == 4 ? getArgReference_bat(stk, pci, 3) : NULL;
     463             :         BATiter bi;
     464             : 
     465             :         (void) cntxt;
     466             :         (void) mb;
     467           0 :         if (!(b = BATdescriptor(*bid))) {
     468           0 :                 msg = createException(MAL, "round", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     469           0 :                 goto bailout;
     470             :         }
     471           0 :         if (b->ttype != TYPE_bte) {
     472           0 :                 msg = createException(MAL, "round", SQLSTATE(42000) "Argument 2 must have a bte tail");
     473           0 :                 goto bailout;
     474             :         }
     475           0 :         if (sid1 && !is_bat_nil(*sid1) && !(bs = BATdescriptor(*sid1))) {
     476           0 :                 msg = createException(MAL, "round", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     477           0 :                 goto bailout;
     478             :         }
     479           0 :         q = canditer_init(&ci1, b, bs);
     480           0 :         if (!(bn = COLnew(ci1.hseq, TPE(TYPE), q, TRANSIENT))) {
     481           0 :                 msg = createException(MAL, "round", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     482           0 :                 goto bailout;
     483             :         }
     484             : 
     485           0 :         off1 = b->hseqbase;
     486           0 :         bi = bat_iterator(b);
     487           0 :         src = (bte *) bi.base;
     488           0 :         dst = (TYPE *) Tloc(bn, 0);
     489           0 :         if (ci1.tpe == cand_dense) {
     490           0 :                 for (BUN i = 0; i < q; i++) {
     491           0 :                         oid p1 = (canditer_next_dense(&ci1) - off1);
     492           0 :                         r = src[p1];
     493             : 
     494           0 :                         if (is_bte_nil(r) || (size_t) abs(r) >= sizeof(scales) / sizeof(scales[0])) {
     495           0 :                                 msg = createException(MAL, "round", SQLSTATE(42000) "Digits out of bounds");
     496           0 :                                 goto bailout1;
     497           0 :                         } else if (ISNIL(TYPE)(x)) {
     498           0 :                                 dst[i] = NIL(TYPE);
     499             :                                 nils = true;
     500             :                         } else {
     501           0 :                                 dst[i] = round_body(x, r);
     502           0 :                                 if (isinf(dst[i])) {
     503           0 :                                         msg = createException(MAL, "round", SQLSTATE(22003) "Overflow in round");
     504           0 :                                         goto bailout1;
     505             :                                 }
     506             :                         }
     507             :                 }
     508             :         } else {
     509           0 :                 for (BUN i = 0; i < q; i++) {
     510           0 :                         oid p1 = (canditer_next(&ci1) - off1);
     511           0 :                         r = src[p1];
     512             : 
     513           0 :                         if (is_bte_nil(r) || (size_t) abs(r) >= sizeof(scales) / sizeof(scales[0])) {
     514           0 :                                 msg = createException(MAL, "round", SQLSTATE(42000) "Digits out of bounds");
     515           0 :                                 goto bailout1;
     516           0 :                         } else if (ISNIL(TYPE)(x)) {
     517           0 :                                 dst[i] = NIL(TYPE);
     518             :                                 nils = true;
     519             :                         } else {
     520           0 :                                 dst[i] = round_body(x, r);
     521           0 :                                 if (isinf(dst[i])) {
     522           0 :                                         msg = createException(MAL, "round", SQLSTATE(22003) "Overflow in round");
     523           0 :                                         goto bailout1;
     524             :                                 }
     525             :                         }
     526             :                 }
     527             :         }
     528           0 : bailout1:
     529           0 :         bat_iterator_end(&bi);
     530             : 
     531           0 : bailout:
     532           0 :         finalize_ouput_copy_sorted_property(res, bn, b, msg, nils, q, false);
     533           0 :         unfix_inputs(2, b, bs);
     534           0 :         return msg;
     535             : }
     536             : 
     537             : str
     538           0 : bat_round_wrap_nocst(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
     539             : {
     540             :         BAT *bn = NULL, *left = NULL, *lefts = NULL, *right = NULL, *rights = NULL;
     541             :         BUN q = 0;
     542             :         TYPE *src1, *restrict dst, x;
     543             :         bte *src2, rr;
     544             :         str msg = MAL_SUCCEED;
     545             :         bool nils = false;
     546           0 :         struct canditer ci1 = {0}, ci2 = {0};
     547             :         oid off1, off2;
     548           0 :         bat *res = getArgReference_bat(stk, pci, 0), *l = getArgReference_bat(stk, pci, 1),
     549           0 :                 *r = getArgReference_bat(stk, pci, 2),
     550           0 :                 *sid1 = pci->argc == 5 ? getArgReference_bat(stk, pci, 3) : NULL,
     551           0 :                 *sid2 = pci->argc == 5 ? getArgReference_bat(stk, pci, 4) : NULL;
     552             :         BATiter lefti, righti;
     553             : 
     554             :         (void) cntxt;
     555             :         (void) mb;
     556           0 :         if (!(left = BATdescriptor(*l)) || !(right = BATdescriptor(*r))) {
     557           0 :                 msg = createException(MAL, "round", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     558           0 :                 goto bailout;
     559             :         }
     560           0 :         if (left->ttype != TPE(TYPE)) {
     561           0 :                 msg = createException(MAL, "round", SQLSTATE(42000) "Argument 1 must have a " STRING(TYPE) " tail");
     562           0 :                 goto bailout;
     563             :         }
     564           0 :         if (right->ttype != TYPE_bte) {
     565           0 :                 msg = createException(MAL, "round", SQLSTATE(42000) "Argument 2 must have a bte tail");
     566           0 :                 goto bailout;
     567             :         }
     568           0 :         if ((sid1 && !is_bat_nil(*sid1) && !(lefts = BATdescriptor(*sid1))) || (sid2 && !is_bat_nil(*sid2) && !(rights = BATdescriptor(*sid2)))) {
     569           0 :                 msg = createException(MAL, "round", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
     570           0 :                 goto bailout;
     571             :         }
     572           0 :         q = canditer_init(&ci1, left, lefts);
     573           0 :         if (canditer_init(&ci2, right, rights) != q || ci1.hseq != ci2.hseq) {
     574           0 :                 msg = createException(MAL, "round", ILLEGAL_ARGUMENT " Requires bats of identical size");
     575           0 :                 goto bailout;
     576             :         }
     577           0 :         if (!(bn = COLnew(ci1.hseq, TPE(TYPE), q, TRANSIENT))) {
     578           0 :                 msg = createException(MAL, "round", SQLSTATE(HY013) MAL_MALLOC_FAIL);
     579           0 :                 goto bailout;
     580             :         }
     581             : 
     582           0 :         off1 = left->hseqbase;
     583           0 :         off2 = right->hseqbase;
     584           0 :         lefti = bat_iterator(left);
     585           0 :         righti = bat_iterator(right);
     586           0 :         src1 = (TYPE *) lefti.base;
     587           0 :         src2 = (bte *) righti.base;
     588           0 :         dst = (TYPE *) Tloc(bn, 0);
     589           0 :         if (ci1.tpe == cand_dense && ci2.tpe == cand_dense) {
     590           0 :                 for (BUN i = 0; i < q; i++) {
     591           0 :                         oid p1 = (canditer_next_dense(&ci1) - off1), p2 = (canditer_next_dense(&ci2) - off2);
     592           0 :                         x = src1[p1];
     593           0 :                         rr = src2[p2];
     594             : 
     595           0 :                         if (is_bte_nil(rr) || (size_t) abs(rr) >= sizeof(scales) / sizeof(scales[0])) {
     596           0 :                                 msg = createException(MAL, "round", SQLSTATE(42000) "Digits out of bounds");
     597           0 :                                 goto bailout1;
     598           0 :                         } else if (ISNIL(TYPE)(x)) {
     599           0 :                                 dst[i] = NIL(TYPE);
     600             :                                 nils = true;
     601             :                         } else {
     602           0 :                                 dst[i] = round_body(x, rr);
     603           0 :                                 if (isinf(dst[i])) {
     604           0 :                                         msg = createException(MAL, "round", SQLSTATE(22003) "Overflow in round");
     605           0 :                                         goto bailout1;
     606             :                                 }
     607             :                         }
     608             :                 }
     609             :         } else {
     610           0 :                 for (BUN i = 0; i < q; i++) {
     611           0 :                         oid p1 = (canditer_next(&ci1) - off1), p2 = (canditer_next(&ci2) - off2);
     612           0 :                         x = src1[p1];
     613           0 :                         rr = src2[p2];
     614             : 
     615           0 :                         if (is_bte_nil(rr) || (size_t) abs(rr) >= sizeof(scales) / sizeof(scales[0])) {
     616           0 :                                 msg = createException(MAL, "round", SQLSTATE(42000) "Digits out of bounds");
     617           0 :                                 goto bailout1;
     618           0 :                         } else if (ISNIL(TYPE)(x)) {
     619           0 :                                 dst[i] = NIL(TYPE);
     620             :                                 nils = true;
     621             :                         } else {
     622           0 :                                 dst[i] = round_body(x, rr);
     623           0 :                                 if (isinf(dst[i])) {
     624           0 :                                         msg = createException(MAL, "round", SQLSTATE(22003) "Overflow in round");
     625           0 :                                         goto bailout1;
     626             :                                 }
     627             :                         }
     628             :                 }
     629             :         }
     630           0 : bailout1:
     631           0 :         bat_iterator_end(&lefti);
     632           0 :         bat_iterator_end(&righti);
     633             : 
     634           0 : bailout:
     635           0 :         finalize_ouput_copy_sorted_property(res, bn, left, msg, nils, q, false);
     636           0 :         unfix_inputs(4, left, lefts, right, rights);
     637           0 :         return msg;
     638             : }
     639             : 
     640             : str
     641           4 : trunc_wrap(TYPE *res, const TYPE *v, const int *r)
     642             : {
     643           4 :         int rr = *r;
     644           4 :         if ((size_t) abs(rr) >= sizeof(scales) / sizeof(scales[0]))
     645           0 :                 throw(MAL, "trunc", SQLSTATE(42000) "Digits out of bounds");
     646             : 
     647             :         /* shortcut nil */
     648           4 :         if (ISNIL(TYPE)(*v)) {
     649           0 :                 *res = NIL(TYPE);
     650           4 :         } else if (rr < 0) {
     651           0 :                 int d = -rr;
     652           0 :                 *res = (TYPE) (trunc((*v) / ((TYPE) scales[d])) * scales[d]);
     653           4 :         } else if (rr > 0) {
     654             :                 int d = rr;
     655           3 :                 *res = (TYPE) (trunc(*v * (TYPE) scales[d]) / ((TYPE) scales[d]));
     656             :         } else {
     657           1 :                 *res = (TYPE) trunc(*v);
     658             :         }
     659             :         return MAL_SUCCEED;
     660             : }
     661             : 
     662             : #undef dec_round_body
     663             : #undef dec_round_wrap
     664             : #undef bat_dec_round_wrap
     665             : #undef bat_dec_round_wrap_cst
     666             : #undef bat_dec_round_wrap_nocst
     667             : #undef round_body
     668             : #undef round_wrap
     669             : #undef bat_round_wrap
     670             : #undef bat_round_wrap_cst
     671             : #undef bat_round_wrap_nocst
     672             : #undef trunc_wrap

Generated by: LCOV version 1.14