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