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