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