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

Generated by: LCOV version 1.14