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