LCOV - code coverage report
Current view: top level - sql/server - sql_atom.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 541 765 70.7 %
Date: 2024-12-20 20:06:10 Functions: 31 32 96.9 %

          Line data    Source code
       1             : /*
       2             :  * SPDX-License-Identifier: MPL-2.0
       3             :  *
       4             :  * This Source Code Form is subject to the terms of the Mozilla Public
       5             :  * License, v. 2.0.  If a copy of the MPL was not distributed with this
       6             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       7             :  *
       8             :  * Copyright 2024 MonetDB Foundation;
       9             :  * Copyright August 2008 - 2023 MonetDB B.V.;
      10             :  * Copyright 1997 - July 2008 CWI.
      11             :  */
      12             : 
      13             : #include "monetdb_config.h"
      14             : #include "sql_atom.h"
      15             : #include "sql_string.h"
      16             : #include "sql_decimal.h"
      17             : #include "gdk_time.h"
      18             : 
      19             : void
      20      350386 : atom_init( atom *a )
      21             : {
      22      350386 :         a->isnull = 1;
      23      350386 :         a->data.vtype = 0;
      24      350386 :         a->data.bat = false;
      25      350386 :         a->tpe.type = NULL;
      26      350386 : }
      27             : 
      28             : static atom *
      29     6900738 : atom_create( allocator *sa )
      30             : {
      31     6900738 :         atom *a = SA_NEW(sa, atom);
      32             : 
      33     6900570 :         if (!a)
      34             :                 return NULL;
      35     6900570 :         *a = (atom) {
      36             :                 .data = (ValRecord) {.vtype = TYPE_void,},
      37             :         };
      38     6900570 :         return a;
      39             : }
      40             : 
      41             : atom *
      42      260088 : atom_bool( allocator *sa, sql_subtype *tpe, bit val)
      43             : {
      44      260088 :         atom *a = atom_create(sa);
      45      260085 :         if(!a)
      46             :                 return NULL;
      47             : 
      48      260085 :         a->isnull = val == bit_nil?true:false;
      49      260085 :         a->tpe = *tpe;
      50      260085 :         a->data.vtype = tpe->type->localtype;
      51      260085 :         a->data.val.btval = val;
      52      260085 :         a->data.len = 0;
      53      260085 :         return a;
      54             : }
      55             : 
      56             : atom *
      57     2683498 : atom_int( allocator *sa, sql_subtype *tpe,
      58             : #ifdef HAVE_HGE
      59             :         hge val
      60             : #else
      61             :         lng val
      62             : #endif
      63             : )
      64             : {
      65     2683498 :         if (tpe->type->eclass == EC_FLT) {
      66           0 :                 return atom_float(sa, tpe, (dbl) val);
      67             :         } else {
      68     2683498 :                 atom *a = atom_create(sa);
      69     2683512 :                 if(!a)
      70             :                         return NULL;
      71             : 
      72     2683512 :                 a->isnull = 0;
      73     2683512 :                 a->tpe = *tpe;
      74     2683512 :                 a->data.vtype = tpe->type->localtype;
      75     2683512 :                 switch (ATOMstorage(a->data.vtype)) {
      76     1353712 :                 case TYPE_bte:
      77     1353712 :                         a->data.val.btval = (bte) val;
      78     1353712 :                         break;
      79      276472 :                 case TYPE_sht:
      80      276472 :                         a->data.val.shval = (sht) val;
      81      276472 :                         break;
      82      889895 :                 case TYPE_int:
      83      889895 :                         a->data.val.ival = (int) val;
      84      889895 :                         break;
      85           0 :                 case TYPE_oid:
      86           0 :                         a->data.val.oval = (oid) val;
      87           0 :                         break;
      88      163343 :                 case TYPE_lng:
      89      163343 :                         a->data.val.lval = (lng) val;
      90      163343 :                         break;
      91             : #ifdef HAVE_HGE
      92          90 :                 case TYPE_hge:
      93          90 :                         a->data.val.hval = val;
      94          90 :                         break;
      95             : #endif
      96             :                 default:
      97           0 :                         assert(0);
      98             :                 }
      99     2683512 :                 int bits = number_bits(val);
     100     2683165 :                 if (a->tpe.type->eclass == EC_NUM)
     101     2656951 :                         a->tpe.digits = bits;
     102     2683165 :                 a->data.len = 0;
     103     2683165 :                 return a;
     104             :         }
     105             : }
     106             : 
     107             : #ifdef HAVE_HGE
     108             : hge
     109             : #else
     110             : lng
     111             : #endif
     112        9566 : atom_get_int(atom *a)
     113             : {
     114             : #ifdef HAVE_HGE
     115        9566 :         hge r = 0;
     116             : #else
     117             :         lng r = 0;
     118             : #endif
     119             : 
     120        9566 :         if (a && !a->isnull) {
     121        9565 :                 switch (ATOMstorage(a->data.vtype)) {
     122        9276 :                 case TYPE_bte:
     123        9276 :                         r = a->data.val.btval;
     124        9276 :                         break;
     125           0 :                 case TYPE_sht:
     126           0 :                         r = a->data.val.shval;
     127           0 :                         break;
     128         289 :                 case TYPE_int:
     129         289 :                         r = a->data.val.ival;
     130         289 :                         break;
     131           0 :                 case TYPE_oid:
     132           0 :                         r = a->data.val.oval;
     133           0 :                         break;
     134           0 :                 case TYPE_lng:
     135           0 :                         r = a->data.val.lval;
     136           0 :                         break;
     137             : #ifdef HAVE_HGE
     138           0 :                 case TYPE_hge:
     139           0 :                         r = a->data.val.hval;
     140           0 :                         break;
     141             : #endif
     142             :                 }
     143             :         }
     144        9566 :         return r;
     145             : }
     146             : 
     147             : atom *
     148        8705 : atom_dec(allocator *sa, sql_subtype *tpe,
     149             : #ifdef HAVE_HGE
     150             :         hge val)
     151             : #else
     152             :         lng val)
     153             : #endif
     154             : {
     155        8705 :         return atom_int(sa, tpe, val);
     156             : }
     157             : 
     158             : atom *
     159     1625576 : atom_string(allocator *sa, sql_subtype *tpe, const char *val)
     160             : {
     161     1625576 :         atom *a = atom_create(sa);
     162     1625576 :         if(!a)
     163             :                 return NULL;
     164             : 
     165     1625576 :         a->isnull = 1;
     166     1625576 :         a->tpe = *tpe;
     167     1625576 :         a->data.val.sval = NULL;
     168     1625576 :         a->data.vtype = TYPE_str;
     169     1625576 :         a->data.len = 0;
     170     1625576 :         if (val) {
     171     1599919 :                 a->isnull = 0;
     172     1599919 :                 a->data.val.sval = (char*)val;
     173     1599919 :                 a->data.len = strlen(a->data.val.sval);
     174             :         }
     175             :         return a;
     176             : }
     177             : 
     178             : atom *
     179        2383 : atom_float(allocator *sa, sql_subtype *tpe, dbl val)
     180             : {
     181        2383 :         atom *a = atom_create(sa);
     182        2383 :         if(!a)
     183             :                 return NULL;
     184             : 
     185        2383 :         a->isnull = 0;
     186        2383 :         a->tpe = *tpe;
     187        2383 :         if (tpe->type->localtype == TYPE_dbl)
     188        2383 :                 a->data.val.dval = val;
     189             :         else {
     190           0 :                 assert((dbl) GDK_flt_min <= val && val <= (dbl) GDK_flt_max);
     191           0 :                 a->data.val.fval = (flt) val;
     192             :         }
     193        2383 :         a->data.vtype = tpe->type->localtype;
     194        2383 :         a->data.len = 0;
     195        2383 :         return a;
     196             : }
     197             : 
     198             : #ifdef HAVE_HGE
     199             : const hge scales[39] = {
     200             :         (hge) LL_CONSTANT(1),
     201             :         (hge) LL_CONSTANT(10),
     202             :         (hge) LL_CONSTANT(100),
     203             :         (hge) LL_CONSTANT(1000),
     204             :         (hge) LL_CONSTANT(10000),
     205             :         (hge) LL_CONSTANT(100000),
     206             :         (hge) LL_CONSTANT(1000000),
     207             :         (hge) LL_CONSTANT(10000000),
     208             :         (hge) LL_CONSTANT(100000000),
     209             :         (hge) LL_CONSTANT(1000000000),
     210             :         (hge) LL_CONSTANT(10000000000),
     211             :         (hge) LL_CONSTANT(100000000000),
     212             :         (hge) LL_CONSTANT(1000000000000),
     213             :         (hge) LL_CONSTANT(10000000000000),
     214             :         (hge) LL_CONSTANT(100000000000000),
     215             :         (hge) LL_CONSTANT(1000000000000000),
     216             :         (hge) LL_CONSTANT(10000000000000000),
     217             :         (hge) LL_CONSTANT(100000000000000000),
     218             :         (hge) LL_CONSTANT(1000000000000000000),
     219             :         (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(1),
     220             :         (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(10),
     221             :         (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(100),
     222             :         (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(1000),
     223             :         (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(10000),
     224             :         (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(100000),
     225             :         (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(1000000),
     226             :         (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(10000000),
     227             :         (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(100000000),
     228             :         (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(1000000000),
     229             :         (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(10000000000),
     230             :         (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(100000000000),
     231             :         (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(1000000000000),
     232             :         (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(10000000000000),
     233             :         (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(100000000000000),
     234             :         (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(1000000000000000),
     235             :         (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(10000000000000000),
     236             :         (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(100000000000000000),
     237             :         (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(1000000000000000000),
     238             :         (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(10000000000000000000U)
     239             : };
     240             : #else
     241             : const lng scales[19] = {
     242             :         LL_CONSTANT(1),
     243             :         LL_CONSTANT(10),
     244             :         LL_CONSTANT(100),
     245             :         LL_CONSTANT(1000),
     246             :         LL_CONSTANT(10000),
     247             :         LL_CONSTANT(100000),
     248             :         LL_CONSTANT(1000000),
     249             :         LL_CONSTANT(10000000),
     250             :         LL_CONSTANT(100000000),
     251             :         LL_CONSTANT(1000000000),
     252             :         LL_CONSTANT(10000000000),
     253             :         LL_CONSTANT(100000000000),
     254             :         LL_CONSTANT(1000000000000),
     255             :         LL_CONSTANT(10000000000000),
     256             :         LL_CONSTANT(100000000000000),
     257             :         LL_CONSTANT(1000000000000000),
     258             :         LL_CONSTANT(10000000000000000),
     259             :         LL_CONSTANT(100000000000000000),
     260             :         LL_CONSTANT(1000000000000000000)
     261             : };
     262             : #endif
     263             : 
     264             : atom *
     265      264351 : atom_general(allocator *sa, sql_subtype *tpe, const char *val, long tz_offset)
     266             : {
     267      264351 :         atom *a = atom_create(sa);
     268             : 
     269      264351 :         if(!a)
     270             :                 return NULL;
     271      264351 :         a->tpe = *tpe;
     272      264351 :         a->data.vtype = tpe->type->localtype;
     273      264351 :         assert(a->data.vtype >= 0);
     274             : 
     275      270360 :         if (!strNil(val)) {
     276        6009 :                 int type = a->data.vtype;
     277             : 
     278        6009 :                 if (type == TYPE_str) {
     279          10 :                         a->data.len = strLen(val);
     280          10 :                         a->data.val.sval = sa_alloc(sa, a->data.len);
     281          10 :                         memcpy(a->data.val.sval, val, a->data.len);
     282        5999 :                 } else if (type == TYPE_timestamp) {
     283         722 :                         if (sql_timestamp_fromstr(val, &a->data.val.lval, tz_offset/1000, tpe->type->eclass == EC_TIMESTAMP) < 0 ||
     284         677 :                                         (timestamp)a->data.val.lval == timestamp_nil)
     285             :                                         return NULL;
     286        5277 :                 } else if (type == TYPE_daytime) {
     287        2395 :                         if (sql_daytime_fromstr(val, &a->data.val.lval, tz_offset/1000, tpe->type->eclass == EC_TIME) < 0 ||
     288        2385 :                                         (daytime)a->data.val.lval == daytime_nil)
     289             :                                         return NULL;
     290             :                 } else {
     291        2882 :                         ptr p = NULL;
     292        2882 :                         ssize_t res = ATOMfromstr(type, &p, &a->data.len, val, false);
     293             : 
     294             :                         /* no result or nil means error (SQL has NULL not nil) */
     295        2882 :                         if (res < 0 || !p || ATOMcmp(type, p, ATOMnilptr(type)) == 0) {
     296          31 :                                 GDKfree(p);
     297          31 :                                 GDKclrerr();
     298          31 :                                 return NULL;
     299             :                         }
     300        2851 :                         VALset(&a->data, a->data.vtype, p);
     301        2851 :                         SA_VALcopy(sa, &a->data, &a->data);
     302        2851 :                         if (tpe->type->eclass == EC_TIME && tpe->digits <= 7) {
     303           0 :                                 unsigned int diff = 6-(tpe->digits-1);
     304             : 
     305           0 :                                 assert(diff < MAX_SCALE);
     306             : #ifdef HAVE_HGE
     307           0 :                                 hge d = scales[diff];
     308             : #else
     309             :                                 lng d = scales[diff];
     310             : #endif
     311             : 
     312           0 :                                 a->data.val.lval /= d;
     313           0 :                                 a->data.val.lval *= d;
     314             :                         }
     315        2851 :                         GDKfree(p);
     316             :                 }
     317             :         } else {
     318      258342 :                 VALset(&a->data, a->data.vtype, (ptr) ATOMnilptr(a->data.vtype));
     319      258342 :                 a->isnull = 1;
     320             :         }
     321             :         return a;
     322             : }
     323             : 
     324             : atom *
     325      268285 : atom_ptr( allocator *sa, sql_subtype *tpe, void *v)
     326             : {
     327      268285 :         atom *a = atom_create(sa);
     328      268285 :         if(!a)
     329             :                 return NULL;
     330      268285 :         a->tpe = *tpe;
     331      268285 :         a->isnull = 0;
     332      268285 :         a->data.vtype = TYPE_ptr;
     333      268285 :         VALset(&a->data, a->data.vtype, &v);
     334      268285 :         a->data.len = 0;
     335      268285 :         return a;
     336             : }
     337             : 
     338             : atom *
     339        1837 : atom_general_ptr( allocator *sa, sql_subtype *tpe, void *v)
     340             : {
     341        1837 :         atom *a = atom_create(sa);
     342        1837 :         if(!a)
     343             :                 return NULL;
     344        1837 :         a->tpe = *tpe;
     345        1837 :         a->data.vtype = tpe->type->localtype;
     346        1837 :         if (!ATOMextern(a->data.vtype)) {
     347        1771 :                 VALset(&a->data, a->data.vtype, v);
     348          66 :         } else if (a->data.vtype == TYPE_str) {
     349          52 :                 const char *p = (const char*) v;
     350          52 :                 a->data.len = strLen(p);
     351          52 :                 a->data.val.sval = sa_alloc(sa, a->data.len);
     352          52 :                 memcpy(a->data.val.sval, p, a->data.len);
     353             :         } else {
     354          14 :                 a->data.len = ATOMlen(a->data.vtype, v);
     355          14 :                 a->data.val.pval = sa_alloc(sa, a->data.len);
     356          14 :                 memcpy(a->data.val.pval, v, a->data.len);
     357             :         }
     358        1837 :         a->isnull = VALisnil(&a->data);
     359        1837 :         return a;
     360             : }
     361             : 
     362             : char *
     363           0 : atom2string(allocator *sa, atom *a)
     364             : {
     365           0 :         char buf[BUFSIZ], *p = NULL;
     366             : 
     367           0 :         if (a->isnull)
     368           0 :                 return sa_strdup(sa, "NULL");
     369           0 :         switch (a->data.vtype) {
     370             : #ifdef HAVE_HGE
     371           0 :         case TYPE_hge:
     372           0 :         {       char *_buf = buf;
     373           0 :                 size_t _bufsiz = BUFSIZ;
     374           0 :                 hgeToStr(&_buf, &_bufsiz, &a->data.val.hval, true);
     375           0 :                 break;
     376             :         }
     377             : #endif
     378           0 :         case TYPE_lng:
     379           0 :                 sprintf(buf, LLFMT, a->data.val.lval);
     380           0 :                 break;
     381           0 :         case TYPE_oid:
     382           0 :                 sprintf(buf, OIDFMT "@0", a->data.val.oval);
     383           0 :                 break;
     384           0 :         case TYPE_int:
     385           0 :                 sprintf(buf, "%d", a->data.val.ival);
     386           0 :                 break;
     387           0 :         case TYPE_sht:
     388           0 :                 sprintf(buf, "%d", a->data.val.shval);
     389           0 :                 break;
     390           0 :         case TYPE_bte:
     391           0 :                 sprintf(buf, "%d", a->data.val.btval);
     392           0 :                 break;
     393           0 :         case TYPE_bit:
     394           0 :                 if (a->data.val.btval)
     395           0 :                         return sa_strdup(sa, "true");
     396           0 :                 return sa_strdup(sa, "false");
     397           0 :         case TYPE_flt:
     398           0 :                 sprintf(buf, "%f", a->data.val.fval);
     399           0 :                 break;
     400           0 :         case TYPE_dbl:
     401           0 :                 sprintf(buf, "%f", a->data.val.dval);
     402           0 :                 break;
     403           0 :         case TYPE_str:
     404           0 :                 assert(a->data.val.sval);
     405           0 :                 return sa_strdup(sa, a->data.val.sval);
     406           0 :         default:
     407           0 :                 if ((p = ATOMformat(a->data.vtype, VALget(&a->data))) == NULL) {
     408           0 :                         snprintf(buf, BUFSIZ, "atom2string(TYPE_%d) not implemented", a->data.vtype);
     409             :                 } else {
     410           0 :                          char *r = sa_strdup(sa, p);
     411           0 :                          GDKfree(p);
     412           0 :                          return r;
     413             :                 }
     414             :         }
     415           0 :         return sa_strdup(sa, buf);
     416             : }
     417             : 
     418             : static inline char *
     419         156 : sql_escape_str(allocator *sa, const char *s)
     420             : {
     421         156 :         size_t l = strlen(s);
     422         156 :         char *res, *r = SA_NEW_ARRAY(sa, char, (l * 2) + 4);
     423             : 
     424         156 :         res = r;
     425         156 :         if (res) {
     426         156 :                 if (strchr(s, '\\') != NULL)
     427           1 :                         *r++ = 'R';
     428         156 :                 *r++ = '\'';
     429         462 :                 while (*s) {
     430         306 :                         if (*s == '\'') {
     431           2 :                                 *r++ = *s;
     432             :                         }
     433         306 :                         *r++ = *s++;
     434             :                 }
     435         156 :                 *r++ = '\'';
     436         156 :                 *r = '\0';
     437             :         }
     438         156 :         return res;
     439             : }
     440             : 
     441             : char *
     442         927 : atom2sql(allocator *sa, atom *a, int timezone)
     443             : {
     444         927 :         sql_class ec = a->tpe.type->eclass;
     445         927 :         char buf[BUFSIZ];
     446             : 
     447         927 :         if (a->data.vtype == TYPE_str && EC_INTERVAL(ec))
     448         927 :                 ec = EC_STRING;
     449         927 :         if (a->isnull)
     450             :                 return "NULL";
     451         927 :         switch (ec) {
     452         473 :         case EC_BIT:
     453         473 :                 assert( a->data.vtype == TYPE_bit);
     454         473 :                 if (a->data.val.btval)
     455         228 :                         return "true";
     456             :                 return "false";
     457         156 :         case EC_CHAR:
     458             :         case EC_STRING:
     459         156 :                 assert(a->data.vtype == TYPE_str && a->data.val.sval);
     460         156 :                 return sql_escape_str(sa, a->data.val.sval);
     461           2 :         case EC_BLOB: {
     462           2 :                 char *res;
     463           2 :                 blob *b = (blob*)a->data.val.pval;
     464           2 :                 size_t blobstr_size = b->nitems * 2 + 1;
     465             : 
     466           4 :                 if ((res = SA_NEW_ARRAY(sa, char, blobstr_size + 8))) {
     467           2 :                         char *tail = stpcpy(res, "blob '");
     468           2 :                         ssize_t blobstr_offset = BATatoms[TYPE_blob].atomToStr(&tail, &blobstr_size, b, true);
     469           2 :                         strcpy(res + blobstr_offset + 6, "'");
     470             :                 }
     471           2 :                 return res;
     472           4 :         } break;
     473           4 :         case EC_MONTH:
     474             :         case EC_SEC: {
     475           4 :                 lng v;
     476           4 :                 switch (a->data.vtype) {
     477           3 :                 case TYPE_lng:
     478           3 :                         v = a->data.val.lval;
     479           3 :                         break;
     480           1 :                 case TYPE_int:
     481           1 :                         v = a->data.val.ival;
     482           1 :                         break;
     483           0 :                 case TYPE_sht:
     484           0 :                         v = a->data.val.shval;
     485           0 :                         break;
     486           0 :                 case TYPE_bte:
     487           0 :                         v = a->data.val.btval;
     488           0 :                         break;
     489             :                 default:
     490             :                         v = 0;
     491             :                         break;
     492             :                 }
     493           4 :                 switch (a->tpe.digits) {
     494           0 :                 case 1:         /* year */
     495           0 :                         v /= 12;
     496           0 :                         break;
     497             :                 case 2:         /* year to month */
     498             :                 case 3:         /* month */
     499             :                         break;
     500           0 :                 case 4:         /* day */
     501           0 :                         v /= 60 * 60 * 24;
     502           0 :                         break;
     503           0 :                 case 5:         /* day to hour */
     504             :                 case 8:         /* hour */
     505           0 :                         v /= 60 * 60;
     506           0 :                         break;
     507           0 :                 case 6:         /* day to minute */
     508             :                 case 9:         /* hour to minute */
     509             :                 case 11:        /* minute */
     510           0 :                         v /= 60;
     511           0 :                         break;
     512             :                 case 7:         /* day to second */
     513             :                 case 10:        /* hour to second */
     514             :                 case 12:        /* minute to second */
     515             :                 case 13:        /* second */
     516             :                         break;
     517             :                 }
     518           4 :                 sprintf(buf, "interval '" LLFMT "' %s", ec == EC_MONTH ? v : v/1000, ec == EC_MONTH ? "month" : "second");
     519           4 :                 break;
     520             :         }
     521         259 :         case EC_NUM:
     522         259 :                 switch (a->data.vtype) {
     523             : #ifdef HAVE_HGE
     524           0 :                 case TYPE_hge:
     525           0 :                 {       char *_buf = buf;
     526           0 :                         size_t _bufsiz = BUFSIZ;
     527           0 :                         hgeToStr(&_buf, &_bufsiz, &a->data.val.hval, true);
     528           0 :                         break;
     529             :                 }
     530             : #endif
     531           0 :                 case TYPE_lng:
     532           0 :                         sprintf(buf, LLFMT, a->data.val.lval);
     533           0 :                         break;
     534           6 :                 case TYPE_int:
     535           6 :                         sprintf(buf, "%d", a->data.val.ival);
     536           6 :                         break;
     537          74 :                 case TYPE_sht:
     538          74 :                         sprintf(buf, "%d", a->data.val.shval);
     539          74 :                         break;
     540         179 :                 case TYPE_bte:
     541         179 :                         sprintf(buf, "%d", a->data.val.btval);
     542         179 :                         break;
     543             :                 default:
     544             :                         break;
     545             :                 }
     546             :                 break;
     547          24 :         case EC_DEC: {
     548             : #ifdef HAVE_HGE
     549          24 :                 hge v = 0;
     550             : #else
     551             :                 lng v = 0;
     552             : #endif
     553          24 :                 switch (a->data.vtype) {
     554             : #ifdef HAVE_HGE
     555           0 :                 case TYPE_hge: v = a->data.val.hval; break;
     556             : #endif
     557           1 :                 case TYPE_lng: v = a->data.val.lval; break;
     558          16 :                 case TYPE_int: v = a->data.val.ival; break;
     559           2 :                 case TYPE_sht: v = a->data.val.shval; break;
     560           5 :                 case TYPE_bte: v = a->data.val.btval; break;
     561             :                 default: break;
     562             :                 }
     563          24 :                 return decimal_to_str(sa, v, &a->tpe);
     564             :         }
     565           0 :         case EC_FLT:
     566           0 :                 if (a->data.vtype == TYPE_dbl)
     567           0 :                         sprintf(buf, "%f", a->data.val.dval);
     568             :                 else
     569           0 :                         sprintf(buf, "%f", a->data.val.fval);
     570             :                 break;
     571           9 :         case EC_TIME:
     572             :         case EC_TIME_TZ:
     573             :         case EC_DATE:
     574             :         case EC_TIMESTAMP:
     575             :         case EC_TIMESTAMP_TZ: {
     576           9 :                 char val1[64], sbuf[64], *val2 = sbuf, *res;
     577           9 :                 size_t len = sizeof(sbuf);
     578             : 
     579           9 :                 switch (ec) {
     580           3 :                 case EC_TIME:
     581             :                 case EC_TIME_TZ:
     582             :                 case EC_TIMESTAMP:
     583             :                 case EC_TIMESTAMP_TZ: {
     584           3 :                         char *n = stpcpy(val1, (ec == EC_TIME || ec == EC_TIME_TZ) ? "TIME" : "TIMESTAMP");
     585           3 :                         if (a->tpe.digits) {
     586           3 :                                 char str[16];
     587           3 :                                 sprintf(str, "%u", a->tpe.digits);
     588           3 :                                 n = stpcpy(stpcpy(stpcpy(n, " ("), str), ")");
     589             :                         }
     590           3 :                         if (ec == EC_TIME_TZ || ec == EC_TIMESTAMP_TZ)
     591           0 :                                 stpcpy(n, " WITH TIME ZONE");
     592             :                 } break;
     593           6 :                 case EC_DATE:
     594           6 :                         strcpy(val1, "DATE");
     595           6 :                 break;
     596             :                 default:
     597             :                         assert(0);
     598             :                 }
     599             : 
     600           9 :                 switch (ec) {
     601           2 :                 case EC_TIME:
     602             :                 case EC_TIME_TZ: {
     603           2 :                         daytime dt = a->data.val.lval;
     604           2 :                         unsigned int digits = a->tpe.digits ? a->tpe.digits - 1 : 0;
     605           2 :                         char *s = val2;
     606           2 :                         ssize_t lens;
     607             : 
     608           2 :                         if (ec == EC_TIME_TZ)
     609           0 :                                 dt = daytime_add_usec_modulo(dt, timezone * 1000);
     610           2 :                         if ((lens = daytime_precision_tostr(&s, &len, dt, (int) digits, true)) < 0)
     611           0 :                                 assert(0);
     612             : 
     613           2 :                         if (ec == EC_TIME_TZ) {
     614           0 :                                 lng timezone_hours = llabs(timezone / 60000);
     615           0 :                                 char *end = sbuf + sizeof(sbuf) - 1;
     616             : 
     617           0 :                                 s += lens;
     618           0 :                                 snprintf(s, end - s, "%c%02d:%02d", (timezone >= 0) ? '+' : '-', (int) (timezone_hours / 60), (int) (timezone_hours % 60));
     619             :                         }
     620           2 :                 } break;
     621           6 :                 case EC_DATE: {
     622           6 :                         date dt = a->data.val.ival;
     623           6 :                         if (date_tostr(&val2, &len, &dt, false) < 0)
     624           0 :                                 assert(0);
     625           6 :                 } break;
     626           1 :                 case EC_TIMESTAMP:
     627             :                 case EC_TIMESTAMP_TZ: {
     628           1 :                         timestamp ts = a->data.val.lval;
     629           1 :                         unsigned int digits = a->tpe.digits ? a->tpe.digits - 1 : 0;
     630           1 :                         char *s = val2;
     631           1 :                         size_t nlen;
     632           1 :                         ssize_t lens;
     633           1 :                         date days;
     634           1 :                         daytime usecs;
     635             : 
     636           1 :                         if (ec == EC_TIMESTAMP_TZ)
     637           0 :                                 ts = timestamp_add_usec(ts, timezone * 1000);
     638           1 :                         days = timestamp_date(ts);
     639           1 :                         if ((lens = date_tostr(&s, &len, &days, true)) < 0)
     640           0 :                                 assert(0);
     641             : 
     642           1 :                         s += lens;
     643           1 :                         *s++ = ' ';
     644           1 :                         nlen = len - lens - 1;
     645           1 :                         assert(nlen < len);
     646             : 
     647           1 :                         usecs = timestamp_daytime(ts);
     648           1 :                         if ((lens = daytime_precision_tostr(&s, &nlen, usecs, (int) digits, true)) < 0)
     649           0 :                                 assert(0);
     650             : 
     651           1 :                         if (ec == EC_TIMESTAMP_TZ) {
     652           0 :                                 lng timezone_hours = llabs(timezone / 60000);
     653           0 :                                 char *end = sbuf + sizeof(sbuf) - 1;
     654             : 
     655           0 :                                 s += lens;
     656           0 :                                 snprintf(s, end - s, "%c%02d:%02d", (timezone >= 0) ? '+' : '-', (int) (timezone_hours / 60), (int) (timezone_hours % 60));
     657             :                         }
     658           1 :                 } break;
     659             :                 default:
     660             :                         assert(0);
     661             :                 }
     662             : 
     663          18 :                 if ((res = SA_NEW_ARRAY(sa, char, strlen(val1) + strlen(val2) + 4)))
     664           9 :                         stpcpy(stpcpy(stpcpy(stpcpy(res, val1)," '"), val2), "'");
     665           9 :                 return res;
     666           0 :         } break;
     667           0 :         default:
     668           0 :                 snprintf(buf, BUFSIZ, "atom2sql(TYPE_%d) not implemented", a->data.vtype);
     669             :         }
     670         263 :         return sa_strdup(sa, buf);
     671             : }
     672             : 
     673             : sql_subtype *
     674    33708392 : atom_type(atom *a)
     675             : {
     676    33708392 :         return &a->tpe;
     677             : }
     678             : 
     679             : atom *
     680        7143 : atom_set_type(allocator *sa, atom *a, sql_subtype *t)
     681             : {
     682        7143 :         atom *na = atom_copy(sa, a);
     683        7143 :         na->tpe = *t;
     684        7143 :         return na;
     685             : }
     686             : 
     687             : unsigned int
     688           6 : atom_num_digits( atom *a )
     689             : {
     690             : #ifdef HAVE_HGE
     691           6 :         hge v = 0;
     692             : #else
     693             :         lng v = 0;
     694             : #endif
     695           6 :         unsigned int inlen = 1;
     696             : 
     697           6 :         switch (a->tpe.type->localtype) {
     698           5 :         case TYPE_bte:
     699           5 :                 v = a->data.val.btval;
     700           5 :                 break;
     701           0 :         case TYPE_sht:
     702           0 :                 v = a->data.val.shval;
     703           0 :                 break;
     704           1 :         case TYPE_int:
     705           1 :                 v = a->data.val.ival;
     706           1 :                 break;
     707           0 :         case TYPE_lng:
     708           0 :                 v = a->data.val.lval;
     709           0 :                 break;
     710             : #ifdef HAVE_HGE
     711           0 :         case TYPE_hge:
     712           0 :                 v = a->data.val.hval;
     713           0 :                 break;
     714             : #endif
     715             :         default:
     716             :                 return 64;
     717             :         }
     718             :         /* count the number of digits in the input */
     719          15 :         while (v /= 10)
     720           9 :                 inlen++;
     721             :         return inlen;
     722             : }
     723             : 
     724             : /* cast atom a to type tp (success returns not NULL, fail returns NULL) */
     725             : atom *
     726     2863233 : atom_cast(allocator *sa, atom *a, sql_subtype *tp)
     727             : {
     728     2863233 :         atom *na = NULL;
     729     2863233 :         sql_subtype *at = &a->tpe;
     730             : 
     731     2863233 :         if (subtype_cmp(at, tp) == 0) {
     732             :                 /* it may be a subtype, but still a different one */
     733     1287383 :                 if (at->type->base.id != tp->type->base.id ||
     734     1287383 :                         at->digits != tp->digits || at->scale != tp->scale) {
     735      117088 :                         na = atom_create(sa);
     736      117110 :                         SA_VALcopy(sa, &na->data, &a->data);
     737      117110 :                         na->data.vtype = tp->type->localtype;
     738      117110 :                         na->tpe = *tp;
     739      117110 :                         na->isnull = a->isnull;
     740      117110 :                         return na;
     741             :                 }
     742             :                 return a;
     743             :         }
     744     1575854 :         if (!a->isnull) {
     745             :                 /* need to do a cast, start simple is atom type a subtype of tp */
     746     1471050 :                 if ((at->type->eclass == tp->type->eclass ||
     747       32239 :                     (EC_VARCHAR(at->type->eclass) && EC_VARCHAR(tp->type->eclass))) &&
     748     1439977 :                     at->type->localtype == tp->type->localtype &&
     749      594142 :                    (EC_TEMP(tp->type->eclass) || !tp->digits|| at->digits <= tp->digits) &&
     750      593594 :                    (!tp->type->scale || at->scale == tp->scale)) {
     751      593490 :                         na = atom_create(sa);
     752      593490 :                         SA_VALcopy(sa, &na->data, &a->data);
     753      593490 :                         na->tpe = *tp;
     754      593490 :                         na->data.vtype = tp->type->localtype;
     755      593490 :                         return na;
     756             :                 }
     757      877560 :                 if (((at->type->eclass == EC_DEC ||
     758      872215 :                           at->type->eclass == EC_NUM) &&
     759      872215 :                          (tp->type->eclass == EC_DEC ||
     760       25619 :                           tp->type->eclass == EC_NUM ||
     761       23261 :                           tp->type->eclass == EC_FLT)) ||
     762       23261 :                         (EC_VARCHAR(at->type->eclass) &&
     763        4562 :                          (tp->type->eclass == EC_DATE ||
     764        4562 :                           EC_TEMP_NOFRAC(tp->type->eclass)))) {
     765      857165 :                         ValRecord v = { .vtype = tp->type->localtype };
     766      857165 :                         if (VARconvert(&v, &a->data, at->scale, tp->scale, tp->type->eclass == EC_DEC ? tp->digits : 0) != GDK_SUCCEED) {
     767          94 :                                 GDKclrerr();
     768          94 :                                 return NULL;
     769             :                         }
     770      857076 :                         na = atom_create(sa);
     771      857070 :                         na->tpe = *tp;
     772      857070 :                         na->isnull = 0;
     773      857070 :                         SA_VALcopy(sa, &na->data, &v);
     774      857071 :                         if (!v.bat && ATOMextern(v.vtype))
     775           0 :                                 GDKfree(v.val.pval);
     776      857071 :                         return na;
     777             :                 }
     778             :         } else {
     779      104804 :                 na = atom_create(sa);
     780      104804 :                 na->tpe = *tp;
     781      104804 :                 na->isnull = 1;
     782      104804 :                 na->data.vtype = tp->type->localtype;
     783      104804 :                 if (!VALset(&na->data, na->data.vtype, (ptr) ATOMnilptr(na->data.vtype)))
     784             :                         return NULL;
     785             :                 return na;
     786             :         }
     787             :         return NULL;
     788             : }
     789             : 
     790             : atom *
     791        6842 : atom_neg(allocator *sa, atom *a)
     792             : {
     793             : 
     794        6842 :         if (a->isnull)
     795             :                 return a;
     796        6842 :         ValRecord dst = { .vtype = a->data.vtype };
     797        6842 :         if (VARcalcnegate(&dst, &a->data) != GDK_SUCCEED) {
     798           0 :                 GDKclrerr();
     799           0 :                 return NULL;
     800             :         }
     801        6842 :         atom *res = atom_create(sa);
     802        6842 :         if (!res)
     803             :                 return NULL;
     804        6842 :         res->tpe = a->tpe;
     805        6842 :         res->data = dst;
     806        6842 :         return res;
     807             : }
     808             : 
     809             : atom *
     810         220 : atom_absolute(allocator *sa, atom *a)
     811             : {
     812             : 
     813         220 :         if (a->isnull)
     814             :                 return a;
     815         220 :         ValRecord dst = { .vtype = a->data.vtype };
     816         220 :         if (VARcalcabsolute(&dst, &a->data) != GDK_SUCCEED) {
     817           0 :                 GDKclrerr();
     818           0 :                 return NULL;
     819             :         }
     820         220 :         atom *res = atom_create(sa);
     821         220 :         if (!res)
     822             :                 return NULL;
     823         220 :         res->tpe = a->tpe;
     824         220 :         res->data = dst;
     825         220 :         return res;
     826             : }
     827             : 
     828             : int
     829     1585702 : atom_cmp(atom *a1, atom *a2)
     830             : {
     831     1585702 :         if (a1->isnull != a2->isnull)
     832             :                 return -1;
     833     1585691 :         if ( a1->isnull)
     834          33 :                 return !(a1->tpe.type->localtype == a2->tpe.type->localtype);
     835     1585658 :         if ( a1->tpe.type->localtype != a2->tpe.type->localtype) {
     836          48 :                 switch (ATOMstorage(a1->tpe.type->localtype)) {
     837           0 :                 case TYPE_bte:
     838           0 :                         switch (ATOMstorage(a2->tpe.type->localtype)) {
     839           0 :                         case TYPE_sht:
     840           0 :                                 return (a1->data.val.btval < a2->data.val.shval)?-1:
     841           0 :                                        (a1->data.val.btval > a2->data.val.shval)?1:0;
     842           0 :                         case TYPE_int:
     843           0 :                                 return (a1->data.val.btval < a2->data.val.ival)?-1:
     844           0 :                                        (a1->data.val.btval > a2->data.val.ival)?1:0;
     845           0 :                         case TYPE_lng:
     846           0 :                                 return (a1->data.val.btval < a2->data.val.lval)?-1:
     847           0 :                                        (a1->data.val.btval > a2->data.val.lval)?1:0;
     848             :         #ifdef HAVE_HGE
     849           0 :                         case TYPE_hge:
     850           0 :                                 return (a1->data.val.btval < a2->data.val.hval)?-1:
     851           0 :                                        (a1->data.val.btval > a2->data.val.hval)?1:0;
     852             :         #endif
     853             :                         }
     854             :                         return -1;
     855           0 :                 case TYPE_sht:
     856           0 :                         switch (ATOMstorage(a2->tpe.type->localtype)) {
     857           0 :                         case TYPE_bte:
     858           0 :                                 return (a1->data.val.shval < a2->data.val.btval)?-1:
     859           0 :                                        (a1->data.val.shval > a2->data.val.btval)?1:0;
     860           0 :                         case TYPE_int:
     861           0 :                                 return (a1->data.val.shval < a2->data.val.ival)?-1:
     862           0 :                                        (a1->data.val.shval > a2->data.val.ival)?1:0;
     863           0 :                         case TYPE_lng:
     864           0 :                                 return (a1->data.val.shval < a2->data.val.lval)?-1:
     865           0 :                                        (a1->data.val.shval > a2->data.val.lval)?1:0;
     866             :         #ifdef HAVE_HGE
     867           0 :                         case TYPE_hge:
     868           0 :                                 return (a1->data.val.shval < a2->data.val.hval)?-1:
     869           0 :                                        (a1->data.val.shval > a2->data.val.hval)?1:0;
     870             :         #endif
     871             :                         }
     872             :                         return -1;
     873           0 :                 case TYPE_int:
     874           0 :                         switch (ATOMstorage(a2->tpe.type->localtype)) {
     875           0 :                         case TYPE_bte:
     876           0 :                                 return (a1->data.val.ival < a2->data.val.btval)?-1:
     877           0 :                                        (a1->data.val.ival > a2->data.val.btval)?1:0;
     878           0 :                         case TYPE_sht:
     879           0 :                                 return (a1->data.val.ival < a2->data.val.shval)?-1:
     880           0 :                                        (a1->data.val.ival > a2->data.val.shval)?1:0;
     881           0 :                         case TYPE_lng:
     882           0 :                                 return (a1->data.val.ival < a2->data.val.lval)?-1:
     883           0 :                                        (a1->data.val.ival > a2->data.val.lval)?1:0;
     884             :         #ifdef HAVE_HGE
     885           0 :                         case TYPE_hge:
     886           0 :                                 return (a1->data.val.ival < a2->data.val.hval)?-1:
     887           0 :                                        (a1->data.val.ival > a2->data.val.hval)?1:0;
     888             :         #endif
     889             :                         }
     890             :                         return -1;
     891           0 :                 case TYPE_lng:
     892           0 :                         switch (ATOMstorage(a2->tpe.type->localtype)) {
     893           0 :                         case TYPE_bte:
     894           0 :                                 return (a1->data.val.lval < a2->data.val.btval)?-1:
     895           0 :                                        (a1->data.val.lval > a2->data.val.btval)?1:0;
     896           0 :                         case TYPE_sht:
     897           0 :                                 return (a1->data.val.lval < a2->data.val.shval)?-1:
     898           0 :                                        (a1->data.val.lval > a2->data.val.shval)?1:0;
     899           0 :                         case TYPE_int:
     900           0 :                                 return (a1->data.val.lval < a2->data.val.ival)?-1:
     901           0 :                                        (a1->data.val.lval > a2->data.val.ival)?1:0;
     902             :         #ifdef HAVE_HGE
     903           0 :                         case TYPE_hge:
     904           0 :                                 return (a1->data.val.lval < a2->data.val.hval)?-1:
     905           0 :                                        (a1->data.val.lval > a2->data.val.hval)?1:0;
     906             :         #endif
     907             :                         }
     908             :                         return -1;
     909             : #ifdef HAVE_HGE
     910           0 :                 case TYPE_hge:
     911           0 :                         switch (ATOMstorage(a2->tpe.type->localtype)) {
     912           0 :                         case TYPE_bte:
     913           0 :                                 return (a1->data.val.hval < a2->data.val.btval)?-1:
     914           0 :                                        (a1->data.val.hval > a2->data.val.btval)?1:0;
     915           0 :                         case TYPE_sht:
     916           0 :                                 return (a1->data.val.hval < a2->data.val.shval)?-1:
     917           0 :                                        (a1->data.val.hval > a2->data.val.shval)?1:0;
     918           0 :                         case TYPE_int:
     919           0 :                                 return (a1->data.val.hval < a2->data.val.ival)?-1:
     920           0 :                                        (a1->data.val.hval > a2->data.val.ival)?1:0;
     921           0 :                         case TYPE_lng:
     922           0 :                                 return (a1->data.val.hval < a2->data.val.lval)?-1:
     923           0 :                                        (a1->data.val.hval > a2->data.val.lval)?1:0;
     924             :                 }
     925             :                         return -1;
     926             : #endif
     927             :                 }
     928             :         }
     929     1585658 :         return VALcmp(&a1->data, &a2->data);
     930             : }
     931             : 
     932             : atom *
     933       34093 : atom_add(allocator *sa, atom *a1, atom *a2)
     934             : {
     935       34093 :         if ((!EC_COMPUTE(a1->tpe.type->eclass) && (a1->tpe.type->eclass != EC_DEC || a1->tpe.digits != a2->tpe.digits || a1->tpe.scale != a2->tpe.scale)) || a1->tpe.digits < a2->tpe.digits || a1->tpe.type->localtype != a2->tpe.type->localtype)
     936             :                 return NULL;
     937       32250 :         if (a1->tpe.type->localtype < a2->tpe.type->localtype ||
     938             :             (a1->tpe.type->localtype == a2->tpe.type->localtype &&
     939             :              a1->tpe.digits < a2->tpe.digits)) {
     940             :                 atom *t = a1;
     941             :                 a1 = a2;
     942             :                 a2 = t;
     943             :         }
     944       32250 :         if (a1->isnull || a2->isnull)
     945           0 :                 return atom_general(sa, &a1->tpe, NULL, 0);
     946       32250 :         ValRecord dst = { .vtype = a1->tpe.type->localtype };
     947       32250 :         if (VARcalcadd(&dst, &a1->data, &a2->data) != GDK_SUCCEED) {
     948          30 :                 GDKclrerr();
     949          30 :                 return NULL;
     950             :         }
     951       32220 :         atom *res = atom_create(sa);
     952       32220 :         if (!res)
     953             :                 return NULL;
     954       32220 :         res->tpe = a1->tpe;
     955       32220 :         res->data = dst;
     956       32220 :         return res;
     957             : }
     958             : 
     959             : atom *
     960       25165 : atom_sub(allocator *sa, atom *a1, atom *a2)
     961             : {
     962       25165 :         if (!EC_NUMBER(a1->tpe.type->eclass))
     963             :                 return NULL;
     964       25135 :         if (a1->tpe.type->localtype < a2->tpe.type->localtype ||
     965       25133 :                 (a1->tpe.type->localtype == a2->tpe.type->localtype && a1->tpe.digits < a2->tpe.digits)) {
     966          54 :                 atom *na1 = atom_cast(sa, a1, &a2->tpe);
     967             :                 /*
     968             :                 atom *t = a1;
     969             :                 a1 = a2;
     970             :                 a2 = t;
     971             :                 */
     972          54 :                 if (!na1)
     973             :                         return NULL;
     974             :                 a1 = na1;
     975             :         }
     976       25135 :         if (a1->isnull || a2->isnull)
     977           0 :                 return atom_general(sa, &a1->tpe, NULL, 0);
     978       25135 :         ValRecord dst = { .vtype = a1->tpe.type->localtype };
     979       25135 :         if (VARcalcsub(&dst, &a1->data, &a2->data) != GDK_SUCCEED) {
     980           2 :                 GDKclrerr();
     981           2 :                 return NULL;
     982             :         }
     983       25133 :         atom *res = atom_create(sa);
     984       25133 :         if (!res)
     985             :                 return NULL;
     986       25133 :         res->tpe = a1->tpe;
     987       25133 :         res->data = dst;
     988       25133 :         return res;
     989             : }
     990             : 
     991             : atom *
     992       17752 : atom_mul(allocator *sa, atom *a1, atom *a2)
     993             : {
     994       17752 :         if (!EC_NUMBER(a1->tpe.type->eclass))
     995             :                 return NULL;
     996       17752 :         if (!EC_INTERVAL(a1->tpe.type->eclass) && (a1->tpe.type->localtype < a2->tpe.type->localtype ||
     997         424 :                 (a1->tpe.type->localtype == a2->tpe.type->localtype && a1->tpe.digits < a2->tpe.digits))) {
     998             :                 atom *t = a1;
     999       17752 :                 a1 = a2;
    1000       17752 :                 a2 = t;
    1001             :         }
    1002       17752 :         if (a1->isnull || a2->isnull)
    1003           0 :                 return atom_general(sa, &a1->tpe, NULL, 0);
    1004       17752 :         ValRecord dst = { .vtype = a1->tpe.type->localtype };
    1005       17752 :         if (VARcalcmul(&dst, &a1->data, &a2->data) != GDK_SUCCEED) {
    1006         138 :                 GDKclrerr();
    1007         138 :                 return NULL;
    1008             :         }
    1009       17614 :         atom *res = atom_create(sa);
    1010       17614 :         if (!res)
    1011             :                 return NULL;
    1012       17614 :         res->tpe = a1->tpe;
    1013       17614 :         res->tpe.digits += a2->tpe.digits;
    1014       17614 :         res->data = dst;
    1015       17614 :         return res;
    1016             : }
    1017             : 
    1018             : atom *
    1019         602 : atom_div(allocator *sa, atom *a1, atom *a2)
    1020             : {
    1021         602 :         if (!EC_NUMBER(a1->tpe.type->eclass))
    1022             :                 return NULL;
    1023         602 :         if (a1->isnull || a2->isnull)
    1024           0 :                 return atom_general(sa, &a1->tpe, NULL, 0);
    1025         602 :         ValRecord dst = { .vtype = a1->tpe.type->localtype };
    1026         602 :         if (VARcalcdiv(&dst, &a1->data, &a2->data) != GDK_SUCCEED) {
    1027          28 :                 GDKclrerr();
    1028          28 :                 return NULL;
    1029             :         }
    1030         574 :         atom *res = atom_create(sa);
    1031         574 :         if (!res)
    1032             :                 return NULL;
    1033         574 :         res->tpe = a1->tpe;
    1034         574 :         res->data = dst;
    1035         574 :         return res;
    1036             : }
    1037             : 
    1038             : atom *
    1039       17511 : atom_inc(allocator *sa, atom *a)
    1040             : {
    1041       17511 :         if (a->isnull)
    1042             :                 return a;
    1043       17511 :         ValRecord dst = { .vtype = a->data.vtype };
    1044       17511 :         if (VARcalcincr(&dst, &a->data) != GDK_SUCCEED) {
    1045           0 :                 GDKclrerr();
    1046           0 :                 return NULL;
    1047             :         }
    1048       17511 :         atom *res = atom_create(sa);
    1049       17511 :         if (!res)
    1050             :                 return NULL;
    1051       17511 :         res->tpe = a->tpe;
    1052       17511 :         res->data = dst;
    1053       17511 :         return res;
    1054             : }
    1055             : 
    1056             : int
    1057       17555 : atom_is_zero(atom *a)
    1058             : {
    1059       17555 :         if (a->isnull || !ATOMlinear(a->tpe.type->localtype))
    1060             :                 return 0;
    1061       17555 :         switch (ATOMstorage(a->tpe.type->localtype)) {
    1062        9634 :         case TYPE_bte:
    1063        9634 :                 return a->data.val.btval == 0;
    1064        5468 :         case TYPE_sht:
    1065        5468 :                 return a->data.val.shval == 0;
    1066        2358 :         case TYPE_int:
    1067        2358 :                 return a->data.val.ival == 0;
    1068          42 :         case TYPE_lng:
    1069          42 :                 return a->data.val.lval == 0;
    1070             : #ifdef HAVE_HGE
    1071          12 :         case TYPE_hge:
    1072          12 :                 return a->data.val.hval == 0;
    1073             : #endif
    1074           0 :         case TYPE_flt:
    1075           0 :                 return a->data.val.fval == 0;
    1076          41 :         case TYPE_dbl:
    1077          41 :                 return a->data.val.dval == 0;
    1078             :         default:
    1079             :                 return 0;
    1080             :         }
    1081             : }
    1082             : 
    1083             : int
    1084       46903 : atom_is_true(atom *a)
    1085             : {
    1086       46903 :         if (a->isnull)
    1087             :                 return 0;
    1088       46667 :         switch (ATOMstorage(a->tpe.type->localtype)) {
    1089       46442 :         case TYPE_bte:
    1090       46442 :                 return a->data.val.btval != 0;
    1091           7 :         case TYPE_sht:
    1092           7 :                 return a->data.val.shval != 0;
    1093          98 :         case TYPE_int:
    1094          98 :                 return a->data.val.ival != 0;
    1095          28 :         case TYPE_lng:
    1096          28 :                 return a->data.val.lval != 0;
    1097             : #ifdef HAVE_HGE
    1098           0 :         case TYPE_hge:
    1099           0 :                 return a->data.val.hval != 0;
    1100             : #endif
    1101           0 :         case TYPE_flt:
    1102           0 :                 return a->data.val.fval != 0;
    1103           8 :         case TYPE_dbl:
    1104           8 :                 return a->data.val.dval != 0;
    1105             :         default:
    1106             :                 return 0;
    1107             :         }
    1108             : }
    1109             : 
    1110             : int
    1111       46334 : atom_is_false(atom *a)
    1112             : {
    1113       46334 :         if (a->isnull)
    1114             :                 return 0;
    1115       46242 :         switch (ATOMstorage(a->tpe.type->localtype)) {
    1116       46195 :         case TYPE_bte:
    1117       46195 :                 return a->data.val.btval == 0;
    1118           1 :         case TYPE_sht:
    1119           1 :                 return a->data.val.shval == 0;
    1120          20 :         case TYPE_int:
    1121          20 :                 return a->data.val.ival == 0;
    1122           3 :         case TYPE_lng:
    1123           3 :                 return a->data.val.lval == 0;
    1124             : #ifdef HAVE_HGE
    1125           0 :         case TYPE_hge:
    1126           0 :                 return a->data.val.hval == 0;
    1127             : #endif
    1128           0 :         case TYPE_flt:
    1129           0 :                 return a->data.val.fval == 0;
    1130           5 :         case TYPE_dbl:
    1131           5 :                 return a->data.val.dval == 0;
    1132             :         default:
    1133             :                 return 0;
    1134             :         }
    1135             : }
    1136             : 
    1137             : unsigned int
    1138     3323893 : atom_digits(atom *a)
    1139             : {
    1140     3323893 :         if (a->isnull || !ATOMlinear(a->tpe.type->localtype) ||
    1141     3323893 :                         (a->tpe.type->eclass != EC_DEC && a->tpe.type->eclass != EC_NUM))
    1142             :                 return 0;
    1143     3323893 :         if (a->tpe.type->eclass == EC_DEC) {
    1144        3462 :                 switch (ATOMstorage(a->tpe.type->localtype)) {
    1145           0 :                         case TYPE_bte:
    1146           0 :                                 return decimal_digits(a->data.val.btval);
    1147         130 :                         case TYPE_sht:
    1148         130 :                                 return decimal_digits(a->data.val.shval);
    1149         438 :                         case TYPE_int:
    1150         438 :                                 return decimal_digits(a->data.val.ival);
    1151        1946 :                         case TYPE_lng:
    1152        1946 :                                 return decimal_digits(a->data.val.lval);
    1153             : #ifdef HAVE_HGE
    1154         948 :                         case TYPE_hge:
    1155         948 :                                 return decimal_digits(a->data.val.hval);
    1156             : #endif
    1157             :                         default:
    1158             :                                 return 0;
    1159             :                 }
    1160             :         } else {
    1161     3320431 :                 switch (ATOMstorage(a->tpe.type->localtype)) {
    1162       45188 :                         case TYPE_bte:
    1163       45188 :                                 return number_bits(a->data.val.btval);
    1164      511555 :                         case TYPE_sht:
    1165      511555 :                                 return number_bits(a->data.val.shval);
    1166     2733649 :                         case TYPE_int:
    1167     2733649 :                                 return number_bits(a->data.val.ival);
    1168       29559 :                         case TYPE_lng:
    1169       29559 :                                 return number_bits(a->data.val.lval);
    1170             : #ifdef HAVE_HGE
    1171         480 :                         case TYPE_hge:
    1172         480 :                                 return number_bits(a->data.val.hval);
    1173             : #endif
    1174             :                         default:
    1175             :                                 return 0;
    1176             :                 }
    1177             :         }
    1178             : }
    1179             : 
    1180             : atom *
    1181       21957 : atom_zero_value(allocator *sa, sql_subtype* tpe)
    1182             : {
    1183       21957 :         void *ret = NULL;
    1184       21957 :         atom *res = NULL;
    1185       21957 :         int localtype = tpe->type->localtype;
    1186             : 
    1187       21957 :         bte bval = 0;
    1188       21957 :         sht sval = 0;
    1189       21957 :         int ival = 0;
    1190       21957 :         lng lval = 0;
    1191             : #ifdef HAVE_HGE
    1192       21957 :         hge hval = 0;
    1193             : #endif
    1194       21957 :         flt fval = 0;
    1195       21957 :         dbl dval = 0;
    1196             : 
    1197       21957 :         if (ATOMlinear(localtype)) {
    1198       21957 :                 switch (ATOMstorage(localtype)) {
    1199             :                 case TYPE_bte:
    1200        8021 :                         ret = &bval;
    1201        8021 :                         break;
    1202             :                 case TYPE_sht:
    1203        1039 :                         ret = &sval;
    1204        1039 :                         break;
    1205             :                 case TYPE_int:
    1206        9751 :                         ret = &ival;
    1207        9751 :                         break;
    1208             :                 case TYPE_lng:
    1209        3064 :                         ret = &lval;
    1210        3064 :                         break;
    1211             : #ifdef HAVE_HGE
    1212             :                 case TYPE_hge:
    1213           8 :                         ret = &hval;
    1214           8 :                         break;
    1215             : #endif
    1216             :                 case TYPE_flt:
    1217           6 :                         ret = &fval;
    1218           6 :                         break;
    1219             :                 case TYPE_dbl:
    1220             :                         ret = &dval;
    1221             :                         break;
    1222             :                 default: /* no support for strings and blobs zero value */
    1223             :                         break;
    1224             :                 }
    1225             :         }
    1226             : 
    1227       21889 :         if (ret != NULL) {
    1228       21957 :                 res = atom_create(sa);
    1229       21957 :                 res->tpe = *tpe;
    1230       21957 :                 res->isnull = 0;
    1231       21957 :                 res->data.vtype = localtype;
    1232       21957 :                 VALset(&res->data, res->data.vtype, ret);
    1233             :         }
    1234             : 
    1235       21957 :         return res;
    1236             : }
    1237             : 
    1238             : atom *
    1239         200 : atom_max_value(allocator *sa, sql_subtype *tpe)
    1240             : {
    1241         200 :         void *ret = NULL;
    1242         200 :         atom *res = NULL;
    1243         200 :         int localtype = tpe->type->localtype;
    1244             : 
    1245         200 :         bte bval = GDK_bte_max;
    1246         200 :         sht sval = GDK_sht_max;
    1247         200 :         int ival = GDK_int_max;
    1248         200 :         lng lval = GDK_lng_max;
    1249             : #ifdef HAVE_HGE
    1250         200 :         hge hval = GDK_hge_max;
    1251             : #endif
    1252         200 :         flt fval = GDK_flt_max;
    1253         200 :         dbl dval = GDK_dbl_max;
    1254             : 
    1255         200 :         if (ATOMlinear(localtype)) {
    1256         200 :                 switch (ATOMstorage(localtype)) {
    1257             :                 case TYPE_bte:
    1258          24 :                         ret = &bval;
    1259          24 :                         break;
    1260             :                 case TYPE_sht:
    1261           2 :                         ret = &sval;
    1262           2 :                         break;
    1263             :                 case TYPE_int:
    1264          74 :                         ret = &ival;
    1265          74 :                         break;
    1266             :                 case TYPE_lng:
    1267         100 :                         ret = &lval;
    1268         100 :                         break;
    1269             : #ifdef HAVE_HGE
    1270             :                 case TYPE_hge:
    1271           0 :                         ret = &hval;
    1272           0 :                         break;
    1273             : #endif
    1274             :                 case TYPE_flt:
    1275           0 :                         ret = &fval;
    1276           0 :                         break;
    1277             :                 case TYPE_dbl:
    1278             :                         ret = &dval;
    1279             :                         break;
    1280             :                 default: /* no support for strings and blobs zero value */
    1281             :                         break;
    1282             :                 }
    1283             :         }
    1284             : 
    1285         200 :         if (ret != NULL) {
    1286         200 :                 res = atom_create(sa);
    1287         200 :                 res->tpe = *tpe;
    1288         200 :                 res->isnull = 0;
    1289         200 :                 res->data.vtype = localtype;
    1290         200 :                 VALset(&res->data, res->data.vtype, ret);
    1291             :         }
    1292             : 
    1293         200 :         return res;
    1294             : }

Generated by: LCOV version 1.14