1/*
2 * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5 *
6 * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
7 */
8
9#include "monetdb_config.h"
10#include "sql_atom.h"
11#include "sql_string.h"
12#include "sql_decimal.h"
13#include "mtime.h"
14
15static int atom_debug = 0;
16
17void
18atom_init( atom *a )
19{
20 a->isnull = 1;
21 a->data.vtype = 0;
22 a->tpe.type = NULL;
23 a->d = 0;
24 a->varid = 0;
25}
26
27static atom *
28atom_create( sql_allocator *sa )
29{
30 atom *a;
31 a = SA_NEW(sa, atom);
32 if(!a)
33 return NULL;
34
35 a->data = (ValRecord) {.vtype = TYPE_void,};
36 a->d = dbl_nil;
37 a->varid = -1;
38 return a;
39}
40
41static ValPtr
42SA_VALcopy(sql_allocator *sa, ValPtr d, const ValRecord *s)
43{
44 if (sa == NULL)
45 return VALcopy(d, s);
46 if (!ATOMextern(s->vtype)) {
47 *d = *s;
48 } else if (s->val.pval == 0) {
49 d->val.pval = ATOMnil(s->vtype);
50 if (d->val.pval == NULL)
51 return NULL;
52 d->vtype = s->vtype;
53 } else if (s->vtype == TYPE_str) {
54 d->vtype = TYPE_str;
55 d->val.sval = sa_strdup(sa, s->val.sval);
56 if (d->val.sval == NULL)
57 return NULL;
58 d->len = strLen(d->val.sval);
59 } else {
60 ptr p = s->val.pval;
61
62 d->vtype = s->vtype;
63 d->len = ATOMlen(d->vtype, p);
64 d->val.pval = sa_alloc(sa, d->len);
65 if (d->val.pval == NULL)
66 return NULL;
67 memcpy(d->val.pval, p, d->len);
68 }
69 return d;
70}
71
72atom *
73atom_bool( sql_allocator *sa, sql_subtype *tpe, bit val)
74{
75 atom *a = atom_create(sa);
76 if(!a)
77 return NULL;
78
79 a->isnull = 0;
80 a->tpe = *tpe;
81 a->data.vtype = tpe->type->localtype;
82 a->data.val.btval = val;
83 a->data.len = 0;
84 return a;
85}
86
87atom *
88atom_int( sql_allocator *sa, sql_subtype *tpe,
89#ifdef HAVE_HGE
90 hge val
91#else
92 lng val
93#endif
94)
95{
96 if (tpe->type->eclass == EC_FLT) {
97 return atom_float(sa, tpe, (double) val);
98 } else {
99 atom *a = atom_create(sa);
100 if(!a)
101 return NULL;
102
103 a->isnull = 0;
104 a->tpe = *tpe;
105 a->data.vtype = tpe->type->localtype;
106 switch (ATOMstorage(a->data.vtype)) {
107 case TYPE_bte:
108 a->data.val.btval = (bte) val;
109 break;
110 case TYPE_sht:
111 a->data.val.shval = (sht) val;
112 break;
113 case TYPE_int:
114 a->data.val.ival = (int) val;
115 break;
116 case TYPE_oid:
117 a->data.val.oval = (oid) val;
118 break;
119 case TYPE_lng:
120 a->data.val.lval = (lng) val;
121 break;
122#ifdef HAVE_HGE
123 case TYPE_hge:
124 a->data.val.hval = val;
125 break;
126#endif
127 default:
128 fprintf(stderr, "atom_int %d\n", a->data.vtype);
129 assert(0);
130 }
131 a->d = (dbl) val;
132 a->data.len = 0;
133 if (atom_debug)
134 fprintf(stderr, "atom_int(%s,%.40g)\n", tpe->type->sqlname, (dbl)val);
135 return a;
136 }
137}
138
139#ifdef HAVE_HGE
140hge
141#else
142lng
143#endif
144atom_get_int(atom *a)
145{
146#ifdef HAVE_HGE
147 hge r = 0;
148#else
149 lng r = 0;
150#endif
151
152 if (!a->isnull) {
153 switch (ATOMstorage(a->data.vtype)) {
154 case TYPE_bte:
155 r = a->data.val.btval;
156 break;
157 case TYPE_sht:
158 r = a->data.val.shval;
159 break;
160 case TYPE_int:
161 r = a->data.val.ival;
162 break;
163 case TYPE_oid:
164 r = a->data.val.oval;
165 break;
166 case TYPE_lng:
167 r = a->data.val.lval;
168 break;
169#ifdef HAVE_HGE
170 case TYPE_hge:
171 r = a->data.val.hval;
172 break;
173#endif
174 }
175 }
176 return r;
177}
178
179
180atom *
181atom_dec(sql_allocator *sa, sql_subtype *tpe,
182#ifdef HAVE_HGE
183 hge val,
184#else
185 lng val,
186#endif
187 double dval)
188{
189 atom *a = atom_int(sa, tpe, val);
190 if (a)
191 a -> d = dval;
192 return a;
193}
194
195atom *
196atom_string(sql_allocator *sa, sql_subtype *tpe, const char *val)
197{
198 atom *a = atom_create(sa);
199 if(!a)
200 return NULL;
201
202 a->isnull = 1;
203 a->tpe = *tpe;
204 a->data.val.sval = NULL;
205 a->data.vtype = TYPE_str;
206 a->data.len = 0;
207 if (val) {
208 a->isnull = 0;
209 a->data.val.sval = (char*)val;
210 a->data.len = strlen(a->data.val.sval);
211 }
212
213 if (atom_debug)
214 fprintf(stderr, "atom_string(%s,%s)\n", tpe->type->sqlname, val);
215 return a;
216}
217
218atom *
219atom_float(sql_allocator *sa, sql_subtype *tpe, double val)
220{
221 atom *a = atom_create(sa);
222 if(!a)
223 return NULL;
224
225 a->isnull = 0;
226 a->tpe = *tpe;
227 if (tpe->type->localtype == TYPE_dbl)
228 a->data.val.dval = val;
229 else {
230 assert((dbl) GDK_flt_min <= val && val <= (dbl) GDK_flt_max);
231 a->data.val.fval = (flt) val;
232 }
233 a->data.vtype = tpe->type->localtype;
234 a->data.len = 0;
235 if (atom_debug)
236 fprintf(stderr, "atom_float(%s,%f)\n", tpe->type->sqlname, val);
237 return a;
238}
239
240#ifdef HAVE_HGE
241hge scales[39] = {
242 (hge) LL_CONSTANT(1),
243 (hge) LL_CONSTANT(10),
244 (hge) LL_CONSTANT(100),
245 (hge) LL_CONSTANT(1000),
246 (hge) LL_CONSTANT(10000),
247 (hge) LL_CONSTANT(100000),
248 (hge) LL_CONSTANT(1000000),
249 (hge) LL_CONSTANT(10000000),
250 (hge) LL_CONSTANT(100000000),
251 (hge) LL_CONSTANT(1000000000),
252 (hge) LL_CONSTANT(10000000000),
253 (hge) LL_CONSTANT(100000000000),
254 (hge) LL_CONSTANT(1000000000000),
255 (hge) LL_CONSTANT(10000000000000),
256 (hge) LL_CONSTANT(100000000000000),
257 (hge) LL_CONSTANT(1000000000000000),
258 (hge) LL_CONSTANT(10000000000000000),
259 (hge) LL_CONSTANT(100000000000000000),
260 (hge) LL_CONSTANT(1000000000000000000),
261 (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(1),
262 (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(10),
263 (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(100),
264 (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(1000),
265 (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(10000),
266 (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(100000),
267 (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(1000000),
268 (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(10000000),
269 (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(100000000),
270 (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(1000000000),
271 (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(10000000000),
272 (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(100000000000),
273 (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(1000000000000),
274 (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(10000000000000),
275 (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(100000000000000),
276 (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(1000000000000000),
277 (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(10000000000000000),
278 (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(100000000000000000),
279 (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(1000000000000000000),
280 (hge) LL_CONSTANT(10000000000000000000U) * LL_CONSTANT(10000000000000000000U)
281};
282#else
283lng scales[19] = {
284 LL_CONSTANT(1),
285 LL_CONSTANT(10),
286 LL_CONSTANT(100),
287 LL_CONSTANT(1000),
288 LL_CONSTANT(10000),
289 LL_CONSTANT(100000),
290 LL_CONSTANT(1000000),
291 LL_CONSTANT(10000000),
292 LL_CONSTANT(100000000),
293 LL_CONSTANT(1000000000),
294 LL_CONSTANT(10000000000),
295 LL_CONSTANT(100000000000),
296 LL_CONSTANT(1000000000000),
297 LL_CONSTANT(10000000000000),
298 LL_CONSTANT(100000000000000),
299 LL_CONSTANT(1000000000000000),
300 LL_CONSTANT(10000000000000000),
301 LL_CONSTANT(100000000000000000),
302 LL_CONSTANT(1000000000000000000)
303};
304#endif
305
306atom *
307atom_general(sql_allocator *sa, sql_subtype *tpe, const char *val)
308{
309 atom *a;
310 ptr p = NULL;
311
312 if (atom_debug)
313 fprintf(stderr, "atom_general(%s,%s)\n", tpe->type->sqlname, val);
314
315 if (tpe->type->localtype == TYPE_str)
316 return atom_string(sa, tpe, val);
317 a = atom_create(sa);
318 if(!a)
319 return NULL;
320 a->tpe = *tpe;
321 a->data.val.pval = NULL;
322 a->data.vtype = tpe->type->localtype;
323 a->data.len = 0;
324
325 assert(a->data.vtype >= 0);
326
327 if (!GDK_STRNIL(val)) {
328 int type = a->data.vtype;
329
330 a->isnull = 0;
331 if (ATOMstorage(type) == TYPE_str) {
332 a->isnull = 0;
333 a->data.val.sval = sa_strdup(sa, val);
334 a->data.len = strlen(a->data.val.sval);
335 } else {
336 ssize_t res = ATOMfromstr(type, &p, &a->data.len, val, false);
337
338 /* no result or nil means error (SQL has NULL not nil) */
339 if (res < 0 || !p || ATOMcmp(type, p, ATOMnilptr(type)) == 0) {
340 /*_DELETE(val);*/
341 if (p)
342 GDKfree(p);
343 return NULL;
344 }
345 VALset(&a->data, a->data.vtype, p);
346 SA_VALcopy(sa, &a->data, &a->data);
347 if (tpe->type->eclass == EC_TIME && tpe->digits <= 7) {
348 int diff = 6-(tpe->digits-1);
349#ifdef HAVE_HGE
350 hge d = scales[diff];
351#else
352 lng d = scales[diff];
353#endif
354
355 a->data.val.lval /= d;
356 a->data.val.lval *= d;
357 }
358 GDKfree(p);
359 /*_DELETE(val);*/
360 }
361 } else {
362 VALset(&a->data, a->data.vtype, (ptr) ATOMnilptr(a->data.vtype));
363 a->isnull = 1;
364 }
365 return a;
366}
367
368atom *
369atom_ptr( sql_allocator *sa, sql_subtype *tpe, void *v)
370{
371 atom *a = atom_create(sa);
372 if(!a)
373 return NULL;
374 a->tpe = *tpe;
375 a->isnull = 0;
376 a->data.vtype = TYPE_ptr;
377 VALset(&a->data, a->data.vtype, &v);
378 a->data.len = 0;
379 return a;
380}
381
382char *
383atom2string(sql_allocator *sa, atom *a)
384{
385 char buf[BUFSIZ], *p = NULL;
386 void *v;
387
388 if (a->isnull)
389 return sa_strdup(sa, "NULL");
390 switch (a->data.vtype) {
391#ifdef HAVE_HGE
392 case TYPE_hge:
393 { char *_buf = buf;
394 size_t _bufsiz = BUFSIZ;
395 hgeToStr(&_buf, &_bufsiz, &a->data.val.hval, true);
396 break;
397 }
398#endif
399 case TYPE_lng:
400 sprintf(buf, LLFMT, a->data.val.lval);
401 break;
402 case TYPE_oid:
403 sprintf(buf, OIDFMT "@0", a->data.val.oval);
404 break;
405 case TYPE_int:
406 sprintf(buf, "%d", a->data.val.ival);
407 break;
408 case TYPE_sht:
409 sprintf(buf, "%d", a->data.val.shval);
410 break;
411 case TYPE_bte:
412 sprintf(buf, "%d", a->data.val.btval);
413 break;
414 case TYPE_bit:
415 if (a->data.val.btval)
416 return sa_strdup(sa, "true");
417 return sa_strdup(sa, "false");
418 case TYPE_flt:
419 sprintf(buf, "%f", a->data.val.fval);
420 break;
421 case TYPE_dbl:
422 sprintf(buf, "%f", a->data.val.dval);
423 break;
424 case TYPE_str:
425 assert(a->data.val.sval);
426 return sa_strdup(sa, a->data.val.sval);
427 default:
428 v = &a->data.val.ival;
429 if (ATOMvarsized(a->data.vtype))
430 v = a->data.val.pval;
431 if ((p = ATOMformat(a->data.vtype, v)) == NULL) {
432 snprintf(buf, BUFSIZ, "atom2string(TYPE_%d) not implemented", a->data.vtype);
433 } else {
434 char *r = sa_strdup(sa, p);
435 _DELETE(p);
436 return r;
437 }
438 }
439 return sa_strdup(sa, buf);
440}
441
442char *
443atom2sql(atom *a)
444{
445 sql_class ec = a->tpe.type->eclass;
446 char buf[BUFSIZ];
447
448 if (a->data.vtype == TYPE_str && EC_INTERVAL(ec))
449 ec = EC_STRING;
450 if (a->isnull)
451 return _STRDUP("NULL");
452 switch (ec) {
453 case EC_BIT:
454 assert( a->data.vtype == TYPE_bit);
455 if (a->data.val.btval)
456 return _STRDUP("true");
457 return _STRDUP("false");
458 case EC_CHAR:
459 case EC_STRING:
460 assert(a->data.vtype == TYPE_str && a->data.val.sval);
461 sprintf(buf, "'%s'", a->data.val.sval);
462 break;
463 case EC_BLOB:
464 /* TODO atom to string */
465 break;
466 case EC_MONTH:
467 case EC_SEC: {
468 lng v;
469 switch (a->data.vtype) {
470 case TYPE_lng:
471 v = a->data.val.lval;
472 break;
473 case TYPE_int:
474 v = a->data.val.ival;
475 break;
476 case TYPE_sht:
477 v = a->data.val.shval;
478 break;
479 case TYPE_bte:
480 v = a->data.val.btval;
481 break;
482 default:
483 v = 0;
484 break;
485 }
486 switch (a->tpe.digits) {
487 case 1: /* year */
488 v /= 12;
489 break;
490 case 2: /* year to month */
491 case 3: /* month */
492 break;
493 case 4: /* day */
494 v /= 60 * 60 * 24;
495 break;
496 case 5: /* day to hour */
497 case 8: /* hour */
498 v /= 60 * 60;
499 break;
500 case 6: /* day to minute */
501 case 9: /* hour to minute */
502 case 11: /* minute */
503 v /= 60;
504 break;
505 case 7: /* day to second */
506 case 10: /* hour to second */
507 case 12: /* minute to second */
508 case 13: /* second */
509 break;
510 }
511 if (a->tpe.digits < 4) {
512 sprintf(buf, LLFMT, v);
513 } else {
514 lng sec = v/1000;
515 lng msec = v%1000;
516 sprintf(buf, LLFMT "." LLFMT, sec, msec);
517 }
518 break;
519 }
520 case EC_NUM:
521 switch (a->data.vtype) {
522#ifdef HAVE_HGE
523 case TYPE_hge:
524 { char *_buf = buf;
525 size_t _bufsiz = BUFSIZ;
526 hgeToStr(&_buf, &_bufsiz, &a->data.val.hval, true);
527 break;
528 }
529#endif
530 case TYPE_lng:
531 sprintf(buf, LLFMT, a->data.val.lval);
532 break;
533 case TYPE_int:
534 sprintf(buf, "%d", a->data.val.ival);
535 break;
536 case TYPE_sht:
537 sprintf(buf, "%d", a->data.val.shval);
538 break;
539 case TYPE_bte:
540 sprintf(buf, "%d", a->data.val.btval);
541 break;
542 default:
543 break;
544 }
545 break;
546 case EC_DEC: {
547#ifdef HAVE_HGE
548 hge v = 0;
549#else
550 lng v = 0;
551#endif
552 switch (a->data.vtype) {
553#ifdef HAVE_HGE
554 case TYPE_hge: v = a->data.val.hval; break;
555#endif
556 case TYPE_lng: v = a->data.val.lval; break;
557 case TYPE_int: v = a->data.val.ival; break;
558 case TYPE_sht: v = a->data.val.shval; break;
559 case TYPE_bte: v = a->data.val.btval; break;
560 default: break;
561 }
562 return decimal_to_str(v, &a->tpe);
563 }
564 case EC_FLT:
565 if (a->data.vtype == TYPE_dbl)
566 sprintf(buf, "%f", a->data.val.dval);
567 else
568 sprintf(buf, "%f", a->data.val.fval);
569 break;
570 case EC_TIME:
571 case EC_DATE:
572 case EC_TIMESTAMP:
573 if (a->data.vtype == TYPE_str) {
574 assert(a->data.val.sval);
575 sprintf(buf, "%s '%s'", a->tpe.type->sqlname, a->data.val.sval);
576 }
577 break;
578 default:
579 snprintf(buf, BUFSIZ, "atom2sql(TYPE_%d) not implemented", a->data.vtype);
580 }
581 return _STRDUP(buf);
582}
583
584sql_subtype *
585atom_type(atom *a)
586{
587 return &a->tpe;
588}
589
590atom *
591atom_dup(sql_allocator *sa, atom *a)
592{
593 atom *r = atom_create(sa);
594 if(!r)
595 return NULL;
596
597 *r = *a;
598 r->tpe = a->tpe;
599 if (!a->isnull)
600 SA_VALcopy(sa, &r->data, &a->data);
601 return r;
602}
603
604unsigned int
605atom_num_digits( atom *a )
606{
607#ifdef HAVE_HGE
608 hge v = 0;
609#else
610 lng v = 0;
611#endif
612 unsigned int inlen = 1;
613
614 switch(a->tpe.type->localtype) {
615 case TYPE_bte:
616 v = a->data.val.btval;
617 break;
618 case TYPE_sht:
619 v = a->data.val.shval;
620 break;
621 case TYPE_int:
622 v = a->data.val.ival;
623 break;
624 case TYPE_lng:
625 v = a->data.val.lval;
626 break;
627#ifdef HAVE_HGE
628 case TYPE_hge:
629 v = a->data.val.hval;
630 break;
631#endif
632 default:
633 return 64;
634 }
635 /* count the number of digits in the input */
636 while (v /= 10)
637 inlen++;
638 return inlen;
639}
640
641/* cast atom a to type tp (success == 1, fail == 0) */
642int
643atom_cast(sql_allocator *sa, atom *a, sql_subtype *tp)
644{
645 sql_subtype *at = &a->tpe;
646
647 if (!a->isnull) {
648 if (subtype_cmp(at, tp) == 0)
649 return 1;
650 /* need to do a cast, start simple is atom type a subtype of tp */
651 if ((at->type->eclass == tp->type->eclass ||
652 (EC_VARCHAR(at->type->eclass) && EC_VARCHAR(tp->type->eclass))) &&
653 at->type->localtype == tp->type->localtype &&
654 (EC_TEMP(tp->type->eclass) || !tp->digits|| at->digits <= tp->digits) &&
655 (!tp->type->scale || at->scale == tp->scale)) {
656 *at = *tp;
657 return 1;
658 }
659 if (at->type->eclass == EC_NUM && tp->type->eclass == EC_NUM &&
660 at->type->localtype <= tp->type->localtype) {
661 /* cast numerics */
662 switch( tp->type->localtype) {
663 case TYPE_bte:
664 if (at->type->localtype != TYPE_bte)
665 return 0;
666 break;
667 case TYPE_sht:
668 if (at->type->localtype == TYPE_bte)
669 a->data.val.shval = a->data.val.btval;
670 else if (at->type->localtype != TYPE_sht)
671 return 0;
672 break;
673 case TYPE_int:
674#if SIZEOF_OID == SIZEOF_INT
675 case TYPE_oid:
676#endif
677 if (at->type->localtype == TYPE_bte)
678 a->data.val.ival = a->data.val.btval;
679 else if (at->type->localtype == TYPE_sht)
680 a->data.val.ival = a->data.val.shval;
681 else if (at->type->localtype != TYPE_int)
682 return 0;
683 break;
684 case TYPE_lng:
685#if SIZEOF_OID == SIZEOF_LNG
686 case TYPE_oid:
687#endif
688 if (at->type->localtype == TYPE_bte)
689 a->data.val.lval = a->data.val.btval;
690 else if (at->type->localtype == TYPE_sht)
691 a->data.val.lval = a->data.val.shval;
692 else if (at->type->localtype == TYPE_int)
693 a->data.val.lval = a->data.val.ival;
694 else if (at->type->localtype != TYPE_lng)
695 return 0;
696 break;
697#ifdef HAVE_HGE
698 case TYPE_hge:
699 if (at->type->localtype == TYPE_bte)
700 a->data.val.hval = a->data.val.btval;
701 else if (at->type->localtype == TYPE_sht)
702 a->data.val.hval = a->data.val.shval;
703 else if (at->type->localtype == TYPE_int)
704 a->data.val.hval = a->data.val.ival;
705 else if (at->type->localtype == TYPE_lng)
706 a->data.val.hval = a->data.val.lval;
707 else if (at->type->localtype != TYPE_hge)
708 return 0;
709 break;
710#endif
711 default:
712 return 0;
713 }
714 a->tpe = *tp;
715 a->data.vtype = tp->type->localtype;
716 return 1;
717 }
718 if (at->type->eclass == EC_DEC && tp->type->eclass == EC_DEC &&
719 at->type->localtype <= tp->type->localtype &&
720 at->digits <= tp->digits /* &&
721 at->scale <= tp->scale*/) {
722#ifdef HAVE_HGE
723 hge mul = 1, div = 0, rnd = 0;
724#else
725 lng mul = 1, div = 0, rnd = 0;
726#endif
727 /* cast numerics */
728 switch( tp->type->localtype) {
729 case TYPE_bte:
730 if (at->type->localtype != TYPE_bte)
731 return 0;
732 break;
733 case TYPE_sht:
734 if (at->type->localtype == TYPE_bte)
735 a->data.val.shval = a->data.val.btval;
736 else if (at->type->localtype != TYPE_sht)
737 return 0;
738 break;
739 case TYPE_int:
740#if SIZEOF_OID == SIZEOF_INT
741 case TYPE_oid:
742#endif
743 if (at->type->localtype == TYPE_bte)
744 a->data.val.ival = a->data.val.btval;
745 else if (at->type->localtype == TYPE_sht)
746 a->data.val.ival = a->data.val.shval;
747 else if (at->type->localtype != TYPE_int)
748 return 0;
749 break;
750 case TYPE_lng:
751#if SIZEOF_OID == SIZEOF_LNG
752 case TYPE_oid:
753#endif
754 if (at->type->localtype == TYPE_bte)
755 a->data.val.lval = a->data.val.btval;
756 else if (at->type->localtype == TYPE_sht)
757 a->data.val.lval = a->data.val.shval;
758 else if (at->type->localtype == TYPE_int)
759 a->data.val.lval = a->data.val.ival;
760 else if (at->type->localtype != TYPE_lng)
761 return 0;
762 break;
763#ifdef HAVE_HGE
764 case TYPE_hge:
765 if (at->type->localtype == TYPE_bte)
766 a->data.val.hval = a->data.val.btval;
767 else if (at->type->localtype == TYPE_sht)
768 a->data.val.hval = a->data.val.shval;
769 else if (at->type->localtype == TYPE_int)
770 a->data.val.hval = a->data.val.ival;
771 else if (at->type->localtype == TYPE_lng)
772 a->data.val.hval = a->data.val.lval;
773 else if (at->type->localtype != TYPE_hge)
774 return 0;
775 break;
776#endif
777 default:
778 return 0;
779 }
780 /* fix scale */
781 if (tp->scale >= at->scale) {
782 mul = scales[tp->scale-at->scale];
783 } else {
784 /* only round when going to a lower scale */
785 mul = scales[at->scale-tp->scale];
786#ifndef TRUNCATE_NUMBERS
787 rnd = mul>>1;
788#endif
789 div = 1;
790 }
791 a->tpe = *tp;
792 a->data.vtype = tp->type->localtype;
793#ifdef HAVE_HGE
794 if (a->data.vtype == TYPE_hge) {
795 if (div) {
796 if (a->data.val.hval < 0)
797 a->data.val.hval -= rnd;
798 else
799 a->data.val.hval += rnd;
800 a->data.val.hval /= mul;
801 } else
802 a->data.val.hval *= mul;
803 } else if (a->data.vtype == TYPE_lng) {
804 if (!div && ((hge) GDK_lng_min > (hge) a->data.val.lval * mul || (hge) a->data.val.lval * mul > (hge) GDK_lng_max))
805 return 0;
806 if (div) {
807 if (a->data.val.lval < 0)
808 a->data.val.lval -= (lng)rnd;
809 else
810 a->data.val.lval += (lng)rnd;
811 a->data.val.lval /= (lng) mul;
812 } else
813 a->data.val.lval *= (lng) mul;
814 } else if (a->data.vtype == TYPE_int) {
815 if (!div && ((hge) GDK_int_min > (hge) a->data.val.ival * mul || (hge) a->data.val.ival * mul > (hge) GDK_int_max))
816 return 0;
817 if (div) {
818 if (a->data.val.ival < 0)
819 a->data.val.ival -= (int)rnd;
820 else
821 a->data.val.ival += (int)rnd;
822 a->data.val.ival /= (int) mul;
823 } else
824 a->data.val.ival *= (int) mul;
825 } else if (a->data.vtype == TYPE_sht) {
826 if (!div && ((hge) GDK_sht_min > (hge) a->data.val.shval * mul || (hge) a->data.val.shval * mul > (hge) GDK_sht_max))
827 return 0;
828 if (div) {
829 if (a->data.val.shval < 0)
830 a->data.val.shval -= (sht)rnd;
831 else
832 a->data.val.shval += (sht)rnd;
833 a->data.val.shval /= (sht) mul;
834 } else
835 a->data.val.shval *= (sht) mul;
836 } else if (a->data.vtype == TYPE_bte) {
837 if (!div && ((hge) GDK_bte_min > (hge) a->data.val.btval * mul || (hge) a->data.val.btval * mul > (hge) GDK_bte_max))
838 return 0;
839 if (div) {
840 if (a->data.val.btval < 0)
841 a->data.val.btval -= (bte)rnd;
842 else
843 a->data.val.btval += (bte)rnd;
844 a->data.val.btval /= (bte) mul;
845 } else
846 a->data.val.btval *= (bte) mul;
847 }
848#else
849 if (a->data.vtype == TYPE_lng) {
850 if (div) {
851 if (a->data.val.lval < 0)
852 a->data.val.lval -= rnd;
853 else
854 a->data.val.lval += rnd;
855 a->data.val.lval /= mul;
856 } else
857 a->data.val.lval *= mul;
858 } else if (a->data.vtype == TYPE_int) {
859 if (!div && ((lng) GDK_int_min > (lng) a->data.val.ival * mul || (lng) a->data.val.ival * mul > (lng) GDK_int_max))
860 return 0;
861 if (div) {
862 if (a->data.val.ival < 0)
863 a->data.val.ival -= (int)rnd;
864 else
865 a->data.val.ival += (int)rnd;
866 a->data.val.ival /= (int) mul;
867 } else
868 a->data.val.ival *= (int) mul;
869 } else if (a->data.vtype == TYPE_sht) {
870 if (!div && ((lng) GDK_sht_min > (lng) a->data.val.shval * mul || (lng) a->data.val.shval * mul > (lng) GDK_sht_max))
871 return 0;
872 if (div) {
873 if (a->data.val.shval < 0)
874 a->data.val.shval -= (sht)rnd;
875 else
876 a->data.val.shval += (sht)rnd;
877 a->data.val.shval /= (sht) mul;
878 } else
879 a->data.val.shval *= (sht) mul;
880 } else if (a->data.vtype == TYPE_bte) {
881 if (!div && ((lng) GDK_bte_min > (lng) a->data.val.btval * mul || (lng) a->data.val.btval * mul > (lng) GDK_bte_max))
882 return 0;
883 if (div) {
884 if (a->data.val.btval < 0)
885 a->data.val.btval -= (bte)rnd;
886 else
887 a->data.val.btval += (bte)rnd;
888 a->data.val.btval /= (bte) mul;
889 } else
890 a->data.val.btval *= (bte) mul;
891 }
892#endif
893 return 1;
894 }
895 /* truncating decimals */
896 if (at->type->eclass == EC_DEC && tp->type->eclass == EC_DEC &&
897 at->type->localtype >= tp->type->localtype &&
898 at->digits >= tp->digits &&
899 (at->digits - tp->digits) == (at->scale - tp->scale)) {
900#ifdef HAVE_HGE
901 hge mul = 1, rnd = 0, val = 0;
902#else
903 lng mul = 1, rnd = 0, val = 0;
904#endif
905
906 /* fix scale */
907
908 /* only round when going to a lower scale */
909 mul = scales[at->scale-tp->scale];
910#ifndef TRUNCATE_NUMBERS
911 rnd = mul>>1;
912#endif
913
914#ifdef HAVE_HGE
915 if (a->data.vtype == TYPE_hge) {
916 val = a->data.val.hval;
917 } else
918#endif
919 if (a->data.vtype == TYPE_lng) {
920 val = a->data.val.lval;
921 } else if (a->data.vtype == TYPE_int) {
922 val = a->data.val.ival;
923 } else if (a->data.vtype == TYPE_sht) {
924 val = a->data.val.shval;
925 } else if (a->data.vtype == TYPE_bte) {
926 val = a->data.val.btval;
927 }
928
929 if (val < 0)
930 val -= rnd;
931 else
932 val += rnd;
933 val /= mul;
934
935 a->tpe = *tp;
936 a->data.vtype = tp->type->localtype;
937#ifdef HAVE_HGE
938 if (a->data.vtype == TYPE_hge) {
939 a->data.val.hval = val;
940 } else if (a->data.vtype == TYPE_lng) {
941 if ( ((hge) GDK_lng_min > val || val > (hge) GDK_lng_max))
942 return 0;
943 a->data.val.lval = (lng) val;
944 } else if (a->data.vtype == TYPE_int) {
945 if ( ((hge) GDK_int_min > val || val > (hge) GDK_int_max))
946 return 0;
947 a->data.val.ival = (int) val;
948 } else if (a->data.vtype == TYPE_sht) {
949 if ( ((hge) GDK_sht_min > val || val > (hge) GDK_sht_max))
950 return 0;
951 a->data.val.shval = (sht) val;
952 } else if (a->data.vtype == TYPE_bte) {
953 if ( ((hge) GDK_bte_min > val || val > (hge) GDK_bte_max))
954 return 0;
955 a->data.val.btval = (bte) val;
956 }
957#else
958 if (a->data.vtype == TYPE_lng) {
959 a->data.val.lval = (lng) val;
960 } else if (a->data.vtype == TYPE_int) {
961 if ( ((lng) GDK_int_min > val || val > (lng) GDK_int_max))
962 return 0;
963 a->data.val.ival = (int) val;
964 } else if (a->data.vtype == TYPE_sht) {
965 if ( ((lng) GDK_sht_min > val || val > (lng) GDK_sht_max))
966 return 0;
967 a->data.val.shval = (sht) val;
968 } else if (a->data.vtype == TYPE_bte) {
969 if ( ((lng) GDK_bte_min > val || val > (lng) GDK_bte_max))
970 return 0;
971 a->data.val.btval = (bte) val;
972 }
973#endif
974 return 1;
975 }
976 if (at->type->eclass == EC_NUM && tp->type->eclass == EC_DEC &&
977 at->type->localtype <= tp->type->localtype &&
978 (at->digits <= tp->digits || atom_num_digits(a) <= tp->digits) &&
979 at->scale <= tp->scale) {
980#ifdef HAVE_HGE
981 hge mul = 1;
982#else
983 lng mul = 1;
984#endif
985 /* cast numerics */
986 switch( tp->type->localtype) {
987 case TYPE_bte:
988 if (at->type->localtype != TYPE_bte)
989 return 0;
990 break;
991 case TYPE_sht:
992 if (at->type->localtype == TYPE_bte)
993 a->data.val.shval = a->data.val.btval;
994 else if (at->type->localtype != TYPE_sht)
995 return 0;
996 break;
997 case TYPE_int:
998#if SIZEOF_OID == SIZEOF_INT
999 case TYPE_oid:
1000#endif
1001 if (at->type->localtype == TYPE_bte)
1002 a->data.val.ival = a->data.val.btval;
1003 else if (at->type->localtype == TYPE_sht)
1004 a->data.val.ival = a->data.val.shval;
1005 else if (at->type->localtype != TYPE_int)
1006 return 0;
1007 break;
1008 case TYPE_lng:
1009#if SIZEOF_OID == SIZEOF_LNG
1010 case TYPE_oid:
1011#endif
1012 if (at->type->localtype == TYPE_bte)
1013 a->data.val.lval = a->data.val.btval;
1014 else if (at->type->localtype == TYPE_sht)
1015 a->data.val.lval = a->data.val.shval;
1016 else if (at->type->localtype == TYPE_int)
1017 a->data.val.lval = a->data.val.ival;
1018 else if (at->type->localtype != TYPE_lng)
1019 return 0;
1020 break;
1021#ifdef HAVE_HGE
1022 case TYPE_hge:
1023 if (at->type->localtype == TYPE_bte)
1024 a->data.val.hval = a->data.val.btval;
1025 else if (at->type->localtype == TYPE_sht)
1026 a->data.val.hval = a->data.val.shval;
1027 else if (at->type->localtype == TYPE_int)
1028 a->data.val.hval = a->data.val.ival;
1029 else if (at->type->localtype == TYPE_lng)
1030 a->data.val.hval = a->data.val.lval;
1031 else if (at->type->localtype != TYPE_hge)
1032 return 0;
1033 break;
1034#endif
1035 default:
1036 return 0;
1037 }
1038 /* fix scale */
1039 mul = scales[tp->scale-at->scale];
1040 a->tpe = *tp;
1041 a->data.vtype = tp->type->localtype;
1042#ifdef HAVE_HGE
1043 if (a->data.vtype == TYPE_hge) {
1044 a->data.val.hval *= mul;
1045 }
1046 else if (a->data.vtype == TYPE_lng) {
1047 if ((hge) GDK_lng_min > (hge) a->data.val.lval * mul || (hge) a->data.val.lval * mul > (hge) GDK_lng_max)
1048 return 0;
1049 a->data.val.ival *= (int) mul;
1050 }
1051 else if (a->data.vtype == TYPE_int) {
1052 if ((hge) GDK_int_min > (hge) a->data.val.ival * mul || (hge) a->data.val.ival * mul > (hge) GDK_int_max)
1053 return 0;
1054 a->data.val.ival *= (int) mul;
1055 }
1056 else if (a->data.vtype == TYPE_sht) {
1057 if ((hge) GDK_sht_min > (hge) a->data.val.shval * mul || (hge) a->data.val.shval * mul > (hge) GDK_sht_max)
1058 return 0;
1059 a->data.val.shval *= (sht) mul;
1060 }
1061 else if (a->data.vtype == TYPE_bte) {
1062 if ((hge) GDK_bte_min > (hge) a->data.val.btval * mul || (hge) a->data.val.btval * mul > (hge) GDK_bte_max)
1063 return 0;
1064 a->data.val.btval *= (bte) mul;
1065 }
1066#else
1067 if (a->data.vtype == TYPE_lng) {
1068 a->data.val.lval *= mul;
1069 }
1070 else if (a->data.vtype == TYPE_int) {
1071 if ((lng) GDK_int_min > (lng) a->data.val.ival * mul || (lng) a->data.val.ival * mul > (lng) GDK_int_max)
1072 return 0;
1073 a->data.val.ival *= (int) mul;
1074 }
1075 else if (a->data.vtype == TYPE_sht) {
1076 if ((lng) GDK_sht_min > (lng) a->data.val.shval * mul || (lng) a->data.val.shval * mul > (lng) GDK_sht_max)
1077 return 0;
1078 a->data.val.shval *= (sht) mul;
1079 }
1080 else if (a->data.vtype == TYPE_bte) {
1081 if ((lng) GDK_bte_min > (lng) a->data.val.btval * mul || (lng) a->data.val.btval * mul > (lng) GDK_bte_max)
1082 return 0;
1083 a->data.val.btval *= (bte) mul;
1084 }
1085#endif
1086 return 1;
1087 }
1088 if ((at->type->eclass == EC_DEC ||
1089 at->type->eclass == EC_NUM) &&
1090 tp->type->eclass == EC_FLT) {
1091 if (is_dbl_nil(a->d)) {
1092 ptr p = &a->d;
1093 char *s;
1094#ifdef HAVE_HGE
1095 hge dec = 0;
1096#else
1097 lng dec = 0;
1098#endif
1099 size_t len = 0;
1100 ssize_t res = 0;
1101 /* cast decimals to doubles */
1102 switch( at->type->localtype) {
1103 case TYPE_bte:
1104 dec = a->data.val.btval;
1105 break;
1106 case TYPE_sht:
1107 dec = a->data.val.shval;
1108 break;
1109 case TYPE_int:
1110 dec = a->data.val.ival;
1111 break;
1112 case TYPE_lng:
1113 dec = a->data.val.lval;
1114 break;
1115#ifdef HAVE_HGE
1116 case TYPE_hge:
1117 dec = a->data.val.hval;
1118 break;
1119#endif
1120 default:
1121 return 0;
1122 }
1123 s = decimal_to_str(dec, at);
1124 len = sizeof(double);
1125 res = ATOMfromstr(TYPE_dbl, &p, &len, s, false);
1126 GDKfree(s);
1127 if (res < 0)
1128 return 0;
1129 }
1130 if (tp->type->localtype == TYPE_dbl)
1131 a->data.val.dval = a->d;
1132 else {
1133 if ((dbl) GDK_flt_min > a->d || a->d > (dbl) GDK_flt_max)
1134 return 0;
1135 a->data.val.fval = (flt) a->d;
1136 }
1137 a->tpe = *tp;
1138 a->data.vtype = tp->type->localtype;
1139 return 1;
1140 }
1141 if (at->type->eclass == EC_CHAR && tp->type->eclass == EC_DATE){
1142 int type = tp->type->localtype;
1143 ssize_t res = 0;
1144 ptr p = NULL;
1145
1146 a->data.len = 0;
1147 res = ATOMfromstr(type, &p, &a->data.len, a->data.val.sval, false);
1148 /* no result or nil means error (SQL has NULL not nil) */
1149 if (res < (ssize_t) strlen(a->data.val.sval) || !p ||
1150 ATOMcmp(type, p, ATOMnilptr(type)) == 0) {
1151 GDKfree(p);
1152 a->data.len = strlen(a->data.val.sval);
1153 return 0;
1154 }
1155 a->tpe = *tp;
1156 a->data.vtype = type;
1157 VALset(&a->data, a->data.vtype, p);
1158 SA_VALcopy(sa, &a->data, &a->data);
1159 GDKfree(p);
1160 return 1;
1161 }
1162 } else {
1163 a->tpe = *tp;
1164 a->data.vtype = tp->type->localtype;
1165 return VALset(&a->data, a->data.vtype, (ptr) ATOMnilptr(a->data.vtype)) != NULL;
1166 }
1167 return 0;
1168}
1169
1170int
1171atom_neg( atom *a )
1172{
1173 ValRecord dst;
1174 dst.vtype = a->data.vtype;
1175 if (VARcalcnegate(&dst, &a->data) != GDK_SUCCEED)
1176 return -1;
1177 a->data = dst;
1178 dst.vtype = TYPE_dbl;
1179 dst.val.dval = a->d;
1180 if (VARcalcnegate(&dst, &dst) != GDK_SUCCEED)
1181 return -1;
1182 a->d = dst.val.dval;
1183 return 0;
1184}
1185
1186int
1187atom_cmp(atom *a1, atom *a2)
1188{
1189 if ( a1->tpe.type->localtype != a2->tpe.type->localtype)
1190 return -1;
1191 if ( a1->isnull != a2->isnull)
1192 return -1;
1193 if ( a1->isnull)
1194 return 0;
1195 return VALcmp(&a1->data, &a2->data);
1196}
1197
1198atom *
1199atom_add(atom *a1, atom *a2)
1200{
1201 ValRecord dst;
1202
1203 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) {
1204 return NULL;
1205 }
1206 if (a1->tpe.type->localtype < a2->tpe.type->localtype ||
1207 (a1->tpe.type->localtype == a2->tpe.type->localtype &&
1208 a1->tpe.digits < a2->tpe.digits)) {
1209 atom *t = a1;
1210 a1 = a2;
1211 a2 = t;
1212 }
1213 dst.vtype = a1->tpe.type->localtype;
1214 if (VARcalcadd(&dst, &a1->data, &a2->data, 1) != GDK_SUCCEED)
1215 return NULL;
1216 a1->data = dst;
1217 dst.vtype = TYPE_dbl;
1218 if (a1->isnull || a2->isnull)
1219 a1->isnull = 1;
1220 if (VARconvert(&dst, &a1->data, 1) == GDK_SUCCEED)
1221 a1->d = dst.val.dval;
1222 return a1;
1223}
1224
1225atom *
1226atom_sub(atom *a1, atom *a2)
1227{
1228 ValRecord dst;
1229
1230 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) {
1231 return NULL;
1232 }
1233 if (a1->tpe.type->localtype < a2->tpe.type->localtype ||
1234 (a1->tpe.type->localtype == a2->tpe.type->localtype &&
1235 a1->tpe.digits < a2->tpe.digits))
1236 dst.vtype = a2->tpe.type->localtype;
1237 else
1238 dst.vtype = a1->tpe.type->localtype;
1239 if (VARcalcsub(&dst, &a1->data, &a2->data, 1) != GDK_SUCCEED)
1240 return NULL;
1241 if (a1->tpe.type->localtype < a2->tpe.type->localtype ||
1242 (a1->tpe.type->localtype == a2->tpe.type->localtype &&
1243 a1->tpe.digits < a2->tpe.digits))
1244 a1 = a2;
1245 a1->data = dst;
1246 dst.vtype = TYPE_dbl;
1247 if (a1->isnull || a2->isnull)
1248 a1->isnull = 1;
1249 if (VARconvert(&dst, &a1->data, 1) == GDK_SUCCEED)
1250 a1->d = dst.val.dval;
1251 return a1;
1252}
1253
1254atom *
1255atom_mul(atom *a1, atom *a2)
1256{
1257 ValRecord dst;
1258
1259 if (!EC_COMPUTE(a1->tpe.type->eclass))
1260 return NULL;
1261 if (a1->tpe.type->localtype == TYPE_dbl ||
1262 a2->tpe.type->localtype == TYPE_dbl) {
1263 ValRecord v1, v2;
1264 dst.vtype = v1.vtype = v2.vtype = TYPE_dbl;
1265 v1.val.dval = a1->d;
1266 v2.val.dval = a2->d;
1267 if (a1->isnull)
1268 return a1;
1269 if (a2->isnull)
1270 return a2;
1271 if (VARcalcmul(&dst, &v1, &v2, 1) != GDK_SUCCEED)
1272 return NULL;
1273 a1->data.vtype = TYPE_dbl;
1274 a1->d = a1->data.val.dval = dst.val.dval;
1275 return a1;
1276 }
1277 if (a1->tpe.type->localtype < a2->tpe.type->localtype ||
1278 (a1->tpe.type->localtype == a2->tpe.type->localtype &&
1279 a1->tpe.digits < a2->tpe.digits)) {
1280 atom *t = a1;
1281 a1 = a2;
1282 a2 = t;
1283 }
1284 if (a1->isnull || a2->isnull) {
1285 a1->isnull = 1;
1286 return a1;
1287 }
1288 dst.vtype = a1->tpe.type->localtype;
1289 if (VARcalcmul(&dst, &a1->data, &a2->data, 1) != GDK_SUCCEED)
1290 return NULL;
1291 a1->data = dst;
1292 dst.vtype = TYPE_dbl;
1293 if (VARconvert(&dst, &a1->data, 1) == GDK_SUCCEED)
1294 a1->d = dst.val.dval;
1295 a1->tpe.digits += a2->tpe.digits;
1296 return a1;
1297}
1298
1299int
1300atom_inc( atom *a )
1301{
1302 ValRecord dst;
1303
1304 if (a->isnull)
1305 return -1;
1306 dst.vtype = a->data.vtype;
1307 if (VARcalcincr(&dst, &a->data, 1) != GDK_SUCCEED)
1308 return -1;
1309 a->data = dst;
1310 dst.vtype = TYPE_dbl;
1311 if (VARconvert(&dst, &a->data, 1) == GDK_SUCCEED)
1312 a->d = dst.val.dval;
1313 return 0;
1314}
1315
1316int
1317atom_is_zero( atom *a )
1318{
1319 if (a->isnull)
1320 return 0;
1321 switch(a->tpe.type->localtype) {
1322 case TYPE_bte:
1323 return a->data.val.btval == 0;
1324 case TYPE_sht:
1325 return a->data.val.shval == 0;
1326 case TYPE_int:
1327 return a->data.val.ival == 0;
1328 case TYPE_lng:
1329 return a->data.val.lval == 0;
1330#ifdef HAVE_HGE
1331 case TYPE_hge:
1332 return a->data.val.hval == 0;
1333#endif
1334 case TYPE_flt:
1335 return a->data.val.fval == 0;
1336 case TYPE_dbl:
1337 return a->data.val.dval == 0;
1338 default:
1339 break;
1340 }
1341 return 0;
1342}
1343
1344int
1345atom_is_true( atom *a )
1346{
1347 if (a->isnull)
1348 return 0;
1349 switch(a->tpe.type->localtype) {
1350 case TYPE_bit:
1351 return a->data.val.btval != 0;
1352 case TYPE_bte:
1353 return a->data.val.btval != 0;
1354 case TYPE_sht:
1355 return a->data.val.shval != 0;
1356 case TYPE_int:
1357 return a->data.val.ival != 0;
1358 case TYPE_lng:
1359 return a->data.val.lval != 0;
1360#ifdef HAVE_HGE
1361 case TYPE_hge:
1362 return a->data.val.hval != 0;
1363#endif
1364 case TYPE_flt:
1365 return a->data.val.fval != 0;
1366 case TYPE_dbl:
1367 return a->data.val.dval != 0;
1368 default:
1369 break;
1370 }
1371 return 0;
1372}
1373
1374atom*
1375atom_zero_value(sql_allocator *sa, sql_subtype* tpe)
1376{
1377 void *ret = NULL;
1378 atom *res = NULL;
1379
1380#ifdef HAVE_HGE
1381 hge hval = 0;
1382#endif
1383 lng lval = 0;
1384 int ival = 0;
1385 sht sval = 0;
1386 bte bbval = 0;
1387 bit bval = 0;
1388 flt fval = 0;
1389 dbl dval = 0;
1390
1391 switch (tpe->type->eclass) {
1392 case EC_BIT:
1393 {
1394 ret = &bval;
1395 break;
1396 }
1397 case EC_POS:
1398 case EC_NUM:
1399 case EC_DEC:
1400 case EC_SEC:
1401 case EC_MONTH:
1402 switch (tpe->type->localtype) {
1403#ifdef HAVE_HGE
1404 case TYPE_hge:
1405 {
1406 ret = &hval;
1407 break;
1408 }
1409#endif
1410 case TYPE_lng:
1411 {
1412 ret = &lval;
1413 break;
1414 }
1415 case TYPE_int:
1416 {
1417 ret = &ival;
1418 break;
1419 }
1420 case TYPE_sht:
1421 {
1422 ret = &sval;
1423 break;
1424 }
1425 case TYPE_bte:
1426 {
1427 ret = &bbval;
1428 break;
1429 }
1430 default:
1431 break;
1432 }
1433 break;
1434 case EC_FLT:
1435 switch (tpe->type->localtype) {
1436 case TYPE_flt:
1437 {
1438 ret = &fval;
1439 break;
1440 }
1441 case TYPE_dbl:
1442 {
1443 ret = &dval;
1444 break;
1445 }
1446 default:
1447 break;
1448 }
1449 break;
1450 default:
1451 break;
1452 } //no support for strings and blobs zero value
1453
1454 if(ret != NULL) {
1455 res = atom_create(sa);
1456 res->tpe = *tpe;
1457 res->isnull = 0;
1458 res->data.vtype = tpe->type->localtype;
1459 VALset(&res->data, res->data.vtype, ret);
1460 }
1461
1462 return res;
1463}
1464