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