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

Generated by: LCOV version 1.14