LCOV - code coverage report
Current view: top level - sql/server - sql_atom.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 543 737 73.7 %
Date: 2024-04-25 20:03:45 Functions: 29 31 93.5 %

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

Generated by: LCOV version 1.14