LCOV - code coverage report
Current view: top level - sql/server - sql_atom.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 563 762 73.9 %
Date: 2024-04-26 00:35:57 Functions: 30 32 93.8 %

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

Generated by: LCOV version 1.14