CUBRID Engine  latest
object_domain.c
Go to the documentation of this file.
1 /*
2  * Copyright 2008 Search Solution Corporation
3  * Copyright 2016 CUBRID Corporation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 /*
20  * object_domain.c: type, domain and value operations.
21  * This module primarily defines support for domain structures.
22  */
23 
24 #ident "$Id$"
25 
26 
27 #include "config.h"
28 
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <float.h>
33 #include <math.h>
34 #include <errno.h>
35 #include <assert.h>
36 
37 #include "area_alloc.h"
38 #include "object_domain.h"
39 #include "object_primitive.h"
40 #include "object_representation.h"
41 #include "numeric_opfunc.h"
42 #include "tz_support.h"
43 #include "db_date.h"
44 #include "mprec.h"
45 #include "porting_inline.hpp"
46 #include "set_object.h"
47 #include "string_opfunc.h"
48 #include "tz_support.h"
49 #include "chartype.h"
50 #include "db_json.hpp"
51 
52 #if !defined (SERVER_MODE)
53 #include "work_space.h"
54 #include "virtual_object.h"
55 #include "schema_manager.h"
56 #include "locator_cl.h"
57 #include "object_template.h"
58 #include "dbi.h"
59 #endif /* !defined (SERVER_MODE) */
60 
61 #include "dbtype.h"
62 #include "error_manager.h"
63 
64 #if defined (SUPPRESS_STRLEN_WARNING)
65 #define strlen(s1) ((int) strlen(s1))
66 #endif /* defined (SUPPRESS_STRLEN_WARNING) */
67 
68 /*
69  * used by versant_driver to avoid doing foolish things
70  * like au_fetch_instance on DB_TYPE_OBJECT values that
71  * contain versant (not CUBRID) mops.
72  */
73 
74 #define ARE_COMPARABLE(typ1, typ2) \
75  ((typ1 == typ2) || \
76  (QSTR_IS_CHAR(typ1) && QSTR_IS_CHAR(typ2)) || \
77  (QSTR_IS_NATIONAL_CHAR(typ1) && QSTR_IS_NATIONAL_CHAR(typ2)))
78 
79 #define DBL_MAX_DIGITS ((int)ceil(DBL_MAX_EXP * log10((double) FLT_RADIX)))
80 
81 #define TP_NEAR_MATCH(t1, t2) \
82  (((t1) == (t2)) || \
83  ((t1) == DB_TYPE_CHAR && (t2) == DB_TYPE_VARCHAR) || \
84  ((t1) == DB_TYPE_VARCHAR && (t2) == DB_TYPE_CHAR) || \
85  ((t1) == DB_TYPE_NCHAR && (t2) == DB_TYPE_VARNCHAR) || \
86  ((t1) == DB_TYPE_VARNCHAR && (t2) == DB_TYPE_VARCHAR) || \
87  ((t1) == DB_TYPE_BIT && (t2) == DB_TYPE_VARBIT) || \
88  ((t1) == DB_TYPE_VARBIT && (t2) == DB_TYPE_BIT))
89 
90 #define TP_NUM_MIDXKEY_DOMAIN_LIST (10)
91 
92 #define DB_DATETIMETZ_INITIALIZER { {0, 0}, 0 }
93 
94 typedef enum tp_coersion_mode
95 {
100 
101 /*
102  * These are arranged to get relative types for symmetrical
103  * coercion selection. The absolute position is not critical.
104  * If two types are mutually coercible, the more general
105  * should appear later. Eg. Float should appear after integer.
106  */
107 
108 static const DB_TYPE db_type_rank[] = { DB_TYPE_NULL,
116  DB_TYPE_SET,
119  DB_TYPE_TIME,
120  DB_TYPE_DATE,
127  DB_TYPE_OID,
128  DB_TYPE_VOBJ,
130  DB_TYPE_CHAR,
134  DB_TYPE_BIT,
136  DB_TYPE_ELO,
137  DB_TYPE_BLOB,
138  DB_TYPE_CLOB,
140  DB_TYPE_SUB,
144  (DB_TYPE) (DB_TYPE_LAST + 1)
145 };
146 
148 static bool tp_Initialized = false;
149 
150 extern unsigned int db_on_server;
151 
152 
153 /*
154  * Shorthand to initialize a bunch of fields without duplication.
155  * Initializes the fields from precision to the end.
156  */
157 #define DOMAIN_INIT \
158  0, /* precision */ \
159  0, /* scale */ \
160  NULL, /* class */ \
161  NULL, /* set domain */ \
162  {NULL, 0, 0}, /* enumeration */ \
163  {-1, -1, -1}, /* class OID */ \
164  1, /* built_in_index (set in tp_init) */ \
165  0, /* codeset */ \
166  0, /* collation id */ \
167  TP_DOMAIN_COLL_NORMAL, /* collation flag */ \
168  0, /* self_ref */ \
169  1, /* is_cached */ \
170  0, /* is_parameterized */ \
171  false, /* is_desc */ \
172  0, /* is_visited */ \
173  NULL /* json_validator */ \
174 
175 /* Same as above, but leaves off the prec and scale, and sets the codeset */
176 #define DOMAIN_INIT2(codeset, coll) \
177  NULL, /* class */ \
178  NULL, /* set domain */ \
179  {NULL, 0, 0}, /* enumeration */ \
180  {-1, -1, -1}, /* class OID */ \
181  1, /* built_in_index (set in tp_init) */ \
182  (codeset), /* codeset */ \
183  (coll), /* collation id */ \
184  TP_DOMAIN_COLL_NORMAL, /* collation flag */ \
185  0, /* self_ref */ \
186  1, /* is_cached */ \
187  1, /* is_parameterized */ \
188  false, /* is_desc */ \
189  0, /* is_visited */ \
190  NULL /* json_validator */ \
191  /*
192  * Same as DOMAIN_INIT but it sets the is_parameterized flag.
193  * Used for things that don't have a precision but which are parameterized in
194  * other ways.
195  */
196 #define DOMAIN_INIT3 \
197  0, /* precision */ \
198  0, /* scale */ \
199  NULL, /* class */ \
200  NULL, /* set domain */ \
201  {NULL, 0, 0}, /* enumeration */ \
202  {-1, -1, -1}, /* class OID */ \
203  1, /* built_in_index (set in tp_init) */ \
204  0, /* codeset */ \
205  0, /* collation id */ \
206  TP_DOMAIN_COLL_NORMAL, /* collation flag */ \
207  0, /* self_ref */ \
208  1, /* is_cached */ \
209  1, /* is_parameterized */ \
210  false, /* is_desc */ \
211  0, /* is_visited */ \
212  NULL /* json_validator */ \
213 
214 /* Same as DOMAIN_INIT but set the prec and scale. */
215 #define DOMAIN_INIT4(prec, scale) \
216  (prec), /* precision */ \
217  (scale), /* scale */ \
218  NULL, /* class */ \
219  NULL, /* set domain */ \
220  {NULL, 0, 0}, /* enumeration */ \
221  {-1, -1, -1}, /* class OID */ \
222  1, /* built_in_index (set in tp_init) */ \
223  0, /* codeset */ \
224  0, /* collation id */ \
225  TP_DOMAIN_COLL_NORMAL, /* collation flag */ \
226  0, /* self_ref */ \
227  1, /* is_cached */ \
228  0, /* is_parameterized */ \
229  false, /* is_desc */ \
230  0, /* is_visited */ \
231  NULL /* json_validator */ \
232 
239 
241 
244 };
245 
248 
250 
252 
255  {NULL, NULL, &tp_Midxkey, DOMAIN_INIT3},
256  {NULL, NULL, &tp_Midxkey, DOMAIN_INIT3},
257  {NULL, NULL, &tp_Midxkey, DOMAIN_INIT3},
258  {NULL, NULL, &tp_Midxkey, DOMAIN_INIT3},
259  {NULL, NULL, &tp_Midxkey, DOMAIN_INIT3},
260  {NULL, NULL, &tp_Midxkey, DOMAIN_INIT3},
261  {NULL, NULL, &tp_Midxkey, DOMAIN_INIT3},
262  {NULL, NULL, &tp_Midxkey, DOMAIN_INIT3},
263  {NULL, NULL, &tp_Midxkey, DOMAIN_INIT3}
264 };
265 TP_DOMAIN tp_Elo_domain = { NULL, NULL, &tp_Elo, DOMAIN_INIT }; /* todo: remove me */
273 
276 };
277 
280 };
281 
284 };
285 
287 
293 
296 };
297 
299  DOMAIN_INIT2 (0, 0)
300 };
301 
304 };
305 
308 };
309 
312 };
313 
316 };
317 
320 };
321 
324 };
325 
326 /* These must be in DB_TYPE order */
327 static TP_DOMAIN *tp_Domains[] = {
334  &tp_Set_domain,
337  &tp_Elo_domain,
348  &tp_Oid_domain, /* does this make sense? shouldn't we share tp_Object_domain */
349  &tp_Null_domain, /* current position of DB_TYPE_DB_VALUE */
351  &tp_Bit_domain,
356  &tp_Null_domain, /* result set */
357  &tp_Midxkey_domain_list_heads[0],
361 
362  /* beginning of some "padding" built-in domains that can be used as expansion space when new primitive data types are
363  * added. */
379 
380  /* beginning of the built-in, complex domains */
381 
382 
383  /* end of built-in domain marker */
384  NULL
385 };
386 
387 /*
388  * Lists for MIDXKEY domain cache.
389  * They are hashed by the length of setdomain to decrease congestion on
390  * the list (See the function tp_domain_get_list). tp_Midxkey_domain should
391  * be located on the head of tp_Midxkey_domains[0] because it is one of
392  * built-in domains and is used to make XASL.
393  */
395  &tp_Midxkey_domain_list_heads[0],
396  &tp_Midxkey_domain_list_heads[1],
397  &tp_Midxkey_domain_list_heads[2],
398  &tp_Midxkey_domain_list_heads[3],
399  &tp_Midxkey_domain_list_heads[4],
400  &tp_Midxkey_domain_list_heads[5],
401  &tp_Midxkey_domain_list_heads[6],
402  &tp_Midxkey_domain_list_heads[7],
403  &tp_Midxkey_domain_list_heads[8],
404  &tp_Midxkey_domain_list_heads[9],
405 
406  /* end of built-in domain marker */
407  NULL
408 };
409 
413  NULL
414 };
415 
420 };
421 
426 };
427 
432 };
433 
438 };
439 
444 };
445 
450 };
451 
456  NULL
457 };
458 
459 static TP_DOMAIN *tp_Char_conv[] = {
463  NULL
464 };
465 
470  NULL
471 };
472 
477  NULL
478 };
479 
480 static TP_DOMAIN *tp_Bit_conv[] = {
482 };
483 
486 };
487 
488 static TP_DOMAIN *tp_Set_conv[] = {
490 };
491 
494 };
495 
498 };
499 
500 /*
501  * tp_Domain_conversion_matrix
502  * This is the matrix of conversion rules. It is used primarily
503  * in the coercion of sets.
504  */
505 
507  NULL, /* DB_TYPE_NULL */
512  NULL, /* DB_TYPE_OBJECT */
513  tp_Set_conv,
516  NULL, /* DB_TYPE_ELO */
517  NULL, /* DB_TYPE_TIME */
518  NULL, /* DB_TYPE_TIMESTAMP */
519  NULL, /* DB_TYPE_DATE */
521  NULL, /* DB_TYPE_VARIABLE */
522  NULL, /* DB_TYPE_SUBSTRUCTURE */
523  NULL, /* DB_TYPE_POINTER */
524  NULL, /* DB_TYPE_ERROR */
526  NULL, /* DB_TYPE_VOBJ */
527  NULL, /* DB_TYPE_OID */
528  NULL, /* DB_TYPE_DB_VALUE */
529  tp_Numeric_conv, /* DB_TYPE_NUMERIC */
530  tp_Bit_conv, /* DB_TYPE_BIT */
531  tp_VarBit_conv, /* DB_TYPE_VARBIT */
532  tp_Char_conv, /* DB_TYPE_CHAR */
533  tp_NChar_conv, /* DB_TYPE_NCHAR */
534  tp_VarNChar_conv, /* DB_TYPE_VARNCHAR */
535  NULL, /* DB_TYPE_RESULTSET */
536  NULL, /* DB_TYPE_MIDXKEY */
537  NULL, /* DB_TYPE_TABLE */
538  tp_Bigint_conv, /* DB_TYPE_BIGINT */
539  NULL, /* DB_TYPE_DATETIME */
540  NULL, /* DB_TYPE_BLOB */
541  NULL, /* DB_TYPE_CLOB */
542  NULL, /* DB_TYPE_ENUMERATION */
543  NULL, /* DB_TYPE_TIMESTAMPTZ */
544  NULL, /* DB_TYPE_TIMESTAMPLTZ */
545  NULL, /* DB_TYPE_DATETIMETZ */
546  NULL, /* DB_TYPE_DATETIMELTZ */
547  NULL /* DB_TYPE_JSON */
548 };
549 
550 #if defined (SERVER_MODE)
551 /* lock for domain list cache */
552 static pthread_mutex_t tp_domain_cache_lock = PTHREAD_MUTEX_INITIALIZER;
553 #endif /* SERVER_MODE */
554 
555 static int tp_domain_size_internal (const TP_DOMAIN * domain);
556 static void tp_value_slam_domain (DB_VALUE * value, const DB_DOMAIN * domain);
557 static TP_DOMAIN *tp_is_domain_cached (TP_DOMAIN * dlist, TP_DOMAIN * transient, TP_MATCH exact, TP_DOMAIN ** ins_pos);
558 #if !defined (SERVER_MODE)
559 static void tp_swizzle_oid (TP_DOMAIN * domain);
560 #endif /* SERVER_MODE */
561 static int tp_domain_check_class (TP_DOMAIN * domain, int *change);
562 static const TP_DOMAIN *tp_domain_find_compatible (const TP_DOMAIN * src, const TP_DOMAIN * dest);
563 #if defined(ENABLE_UNUSED_FUNCTION)
564 static int tp_null_terminate (const DB_VALUE * src, char **strp, int str_len, bool * do_alloc);
565 #endif
566 static int tp_atotime (const DB_VALUE * src, DB_TIME * temp);
567 static int tp_atodate (const DB_VALUE * src, DB_DATE * temp);
568 static int tp_atoutime (const DB_VALUE * src, DB_UTIME * temp);
569 static int tp_atotimestamptz (const DB_VALUE * src, DB_TIMESTAMPTZ * temp);
570 static int tp_atoudatetime (const DB_VALUE * src, DB_DATETIME * temp);
571 static int tp_atodatetimetz (const DB_VALUE * src, DB_DATETIMETZ * temp);
572 static int tp_atonumeric (const DB_VALUE * src, DB_VALUE * temp);
573 static int tp_atof (const DB_VALUE * src, double *num_value, DB_DATA_STATUS * data_stat);
574 static int tp_atobi (const DB_VALUE * src, DB_BIGINT * num_value, DB_DATA_STATUS * data_stat);
575 #if defined(ENABLE_UNUSED_FUNCTION)
576 static char *tp_itoa (int value, char *string, int radix);
577 #endif
578 static char *tp_ltoa (DB_BIGINT value, char *string, int radix);
579 static void format_floating_point (char *new_string, char *rve, int ndigits, int decpt, int sign);
580 static void tp_ftoa (DB_VALUE const *src, DB_VALUE * result);
581 static void tp_dtoa (DB_VALUE const *src, DB_VALUE * result);
582 static int bfmt_print (int bfmt, const DB_VALUE * the_db_bit, char *string, int max_size);
583 static TP_DOMAIN_STATUS tp_value_cast_internal (const DB_VALUE * src, DB_VALUE * dest, const TP_DOMAIN * desired_domain,
584  TP_COERCION_MODE coercion_mode, bool do_domain_select,
585  bool preserve_domain);
586 static DB_VALUE_COMPARE_RESULT oidcmp (OID * oid1, OID * oid2);
587 static int tp_domain_match_internal (const TP_DOMAIN * dom1, const TP_DOMAIN * dom2, TP_MATCH exact, bool match_order);
588 #if defined(CUBRID_DEBUG)
589 static void fprint_domain (FILE * fp, TP_DOMAIN * domain);
590 #endif
593 
594 static int tp_enumeration_match (const DB_ENUMERATION * db_enum1, const DB_ENUMERATION * db_enum2);
595 static int tp_digit_number_str_to_bi (const char *start, const char *end, INTL_CODESET codeset, bool is_negative,
596  DB_BIGINT * num_value, DB_DATA_STATUS * data_stat);
597 static int tp_hex_str_to_bi (const char *start, const char *end, INTL_CODESET codeset, bool is_negative,
598  DB_BIGINT * num_value, DB_DATA_STATUS * data_stat);
599 static int tp_scientific_str_to_bi (const char *start, const char *end, INTL_CODESET codeset, bool is_negative,
600  DB_BIGINT * num_value, DB_DATA_STATUS * data_stat);
601 static DB_BIGINT tp_ubi_to_bi_with_args (UINT64 ubi, bool is_negative, bool truncated, bool round,
602  DB_DATA_STATUS * data_stat);
603 
604 static UINT64 tp_ubi_times_ten (UINT64 ubi, bool * truncated);
605 
606 /*
607  * tp_init - Global initialization for this module.
608  * return: NO_ERROR or error code
609  */
610 int
611 tp_init (void)
612 {
613  TP_DOMAIN *d;
614  int i;
615 
616  if (tp_Initialized)
617  {
618  assert (tp_Domain_area != NULL);
619  return NO_ERROR;
620  }
621 
622  /* create our allocation area */
623  tp_Domain_area = area_create ("Domains", sizeof (TP_DOMAIN), 1024);
624  if (tp_Domain_area == NULL)
625  {
626  assert (er_errid () != NO_ERROR);
627  return er_errid ();
628  }
629 
630  /*
631  * Make sure the next pointer on all the built-in domains is clear.
632  * Also make sure the built-in domain numbers are assigned consistently.
633  * Assign the builtin indexes starting from 1 so we can use zero to mean
634  * that the domain isn't built-in.
635  */
636  for (i = 0; tp_Domains[i] != NULL; i++)
637  {
638  d = tp_Domains[i];
639  d->next_list = NULL;
640  d->class_mop = NULL;
641  d->self_ref = 0;
642  d->setdomain = NULL;
643  DOM_SET_ENUM (d, NULL, 0);
644  d->class_oid.volid = d->class_oid.pageid = d->class_oid.slotid = -1;
645  d->is_cached = 1;
646  d->built_in_index = i + 1;
647  d->is_desc = false;
648 
649  /* ! need to be adding this to the corresponding list */
650  }
651 
652  /* tp_Midxkey_domains[0] was already initialized by the above codes. */
653  for (i = 1; tp_Midxkey_domains[i] != NULL; i++)
654  {
655  d = tp_Midxkey_domains[i];
656  d->next_list = NULL;
657  d->class_mop = NULL;
658  d->self_ref = 0;
659  d->setdomain = NULL;
660  DOM_SET_ENUM (d, NULL, 0);
661  d->class_oid.volid = d->class_oid.pageid = d->class_oid.slotid = -1;
662  d->is_cached = 1;
663  d->built_in_index = tp_Midxkey_domains[0]->built_in_index;
664  d->is_desc = false;
665  }
666 
667  tp_Initialized = true;
668 
669  return NO_ERROR;
670 }
671 
672 /*
673  * tp_apply_sys_charset - applies system charset to string domains
674  * return: none
675  */
676 void
678 {
679  if (tp_Domain_area == NULL)
680  {
681  return;
682  }
683 
684  /* update string domains with current codeset */
685  tp_String_domain.codeset = LANG_SYS_CODESET;
686  tp_Char_domain.codeset = LANG_SYS_CODESET;
687  tp_NChar_domain.codeset = LANG_SYS_CODESET;
688  tp_VarNChar_domain.codeset = LANG_SYS_CODESET;
689  tp_Enumeration_domain.codeset = LANG_SYS_CODESET;
690 
691  tp_String_domain.collation_id = LANG_SYS_COLLATION;
692  tp_Char_domain.collation_id = LANG_SYS_COLLATION;
693  tp_NChar_domain.collation_id = LANG_SYS_COLLATION;
694  tp_VarNChar_domain.collation_id = LANG_SYS_COLLATION;
695  tp_Enumeration_domain.collation_id = LANG_SYS_COLLATION;
696 }
697 
698 /*
699  * tp_final - Global shutdown for this module.
700  * return: none
701  * Note:
702  * Frees all the cached domains. It isn't absolutely necessary
703  * that we do this since area_final() will destroy the areas but when
704  * leak statistics are enabled, it will dump a bunch of messages
705  * about dangling domain allocations.
706  */
707 void
708 tp_final (void)
709 {
710  TP_DOMAIN *dlist, *d, *next, *prev;
711  int i;
712 
713  if (!tp_Initialized)
714  {
715  assert (tp_Domain_area == NULL);
716  return;
717  }
718 
719  /*
720  * Make sure the next pointer on all the built-in domains is clear.
721  * Also make sure the built-in domain numbers are assigned consistently.
722  */
723  for (i = 0; tp_Domains[i] != NULL; i++)
724  {
725  dlist = tp_Domains[i];
726  /*
727  * The first element in the domain array is always a built-in, there
728  * can potentially be other built-ins in the list mixed in with
729  * allocated domains.
730  */
731  for (d = dlist->next_list, prev = dlist, next = NULL; d != NULL; d = next)
732  {
733  next = d->next_list;
734  if (d->built_in_index)
735  {
736  prev = d;
737  }
738  else
739  {
740  prev->next_list = next;
741 
742  /*
743  * Make sure to turn off the cache bit or else tp_domain_free
744  * will ignore the request.
745  */
746  d->is_cached = 0;
747  tp_domain_free (d);
748  }
749  }
750  }
751 
752  /*
753  * tp_Midxkey_domains[0] was cleared by the above for-loop.
754  * It holds a pointer of tp_Midxkey_domain_list_heads[0] on its head.
755  * The pointer is also stored on tp_Domains[DB_TYPE_MIDXKEY].
756  */
757  for (i = 1; tp_Midxkey_domains[i] != NULL; i++)
758  {
759  dlist = tp_Midxkey_domains[i];
760 
761  for (d = dlist->next_list, prev = dlist, next = NULL; d != NULL; d = next)
762  {
763  next = d->next_list;
764  if (d->built_in_index)
765  {
766  prev = d;
767  }
768  else
769  {
770  prev->next_list = next;
771 
772  d->is_cached = 0;
773  tp_domain_free (d);
774  }
775  }
776  }
777 
778  if (tp_Domain_area != NULL)
779  {
780  area_destroy (tp_Domain_area);
781  tp_Domain_area = NULL;
782  }
783 
784  tp_Initialized = false;
785 }
786 
787 /*
788  * tp_domain_clear_enumeration () - free memory allocated for an enumeration type
789  * return : void
790  * enumeration (in/out): enumeration
791  */
792 void
794 {
795  int i = 0;
796 
797  if (enumeration == NULL || enumeration->count == 0)
798  {
799  return;
800  }
801 
802  for (i = 0; i < enumeration->count; i++)
803  {
804  if (DB_GET_ENUM_ELEM_STRING (&enumeration->elements[i]) != NULL)
805  {
806  free_and_init (DB_GET_ENUM_ELEM_STRING (&enumeration->elements[i]));
807  }
808  }
809 
810  free_and_init (enumeration->elements);
811 }
812 
813 /*
814  * tp_enumeration_match () check if two enumerations match
815  * return : 1 if the two enums match, 0 otherwise
816  * db_enum1 (in):
817  * db_enum2 (in);
818  */
819 static int
820 tp_enumeration_match (const DB_ENUMERATION * db_enum1, const DB_ENUMERATION * db_enum2)
821 {
822  int i;
823  DB_ENUM_ELEMENT *enum1 = NULL, *enum2 = NULL;
824 
825  if (db_enum1 == db_enum2)
826  {
827  return 1;
828  }
829 
830  if (db_enum1 == NULL || db_enum2 == NULL)
831  {
832  return 0;
833  }
834 
835  if (db_enum1->count != db_enum2->count)
836  {
837  return 0;
838  }
839  if (db_enum1->collation_id != db_enum2->collation_id)
840  {
841  return 0;
842  }
843 
844  for (i = 0; i < db_enum1->count; i++)
845  {
846  enum1 = &db_enum1->elements[i];
847  enum2 = &db_enum2->elements[i];
848 
850  {
851  return 0;
852  }
853 
854  /*
855  * memcmp is used here because it is necessary for domains like
856  * ENUM('a', 'b') COLLATE utf8_en_ci and
857  * ENUM('A', 'B') COLLATE utf8_en_ci to be regarded as different
858  * domains, despite their common case-insensitive collation.
859  * Thus, collation-based comparison is not correct here.
860  */
861  if (memcmp (DB_GET_ENUM_ELEM_STRING (enum1), DB_GET_ENUM_ELEM_STRING (enum2),
862  DB_GET_ENUM_ELEM_STRING_SIZE (enum1)) != 0)
863  {
864  return 0;
865  }
866  }
867 
868  return 1;
869 }
870 
871 /*
872  * tp_get_fixed_precision - return the fixed precision of the given type.
873  * return: the fixed precision for the fixed types, otherwise -1.
874  * domain_type(in): The type of the domain
875  */
876 int
878 {
879  int precision;
880 
881  switch (domain_type)
882  {
883  case DB_TYPE_INTEGER:
884  precision = DB_INTEGER_PRECISION;
885  break;
886  case DB_TYPE_SHORT:
887  precision = DB_SHORT_PRECISION;
888  break;
889  case DB_TYPE_BIGINT:
890  precision = DB_BIGINT_PRECISION;
891  break;
892  case DB_TYPE_FLOAT:
893  precision = DB_FLOAT_DECIMAL_PRECISION;
894  break;
895  case DB_TYPE_DOUBLE:
896  precision = DB_DOUBLE_DECIMAL_PRECISION;
897  break;
898  case DB_TYPE_DATE:
899  precision = DB_DATE_PRECISION;
900  break;
901  case DB_TYPE_TIME:
902  precision = DB_TIME_PRECISION;
903  break;
904  case DB_TYPE_TIMESTAMP:
906  precision = DB_TIMESTAMP_PRECISION;
907  break;
908  case DB_TYPE_TIMESTAMPTZ:
909  precision = DB_TIMESTAMPTZ_PRECISION;
910  break;
911  case DB_TYPE_DATETIME:
912  case DB_TYPE_DATETIMELTZ:
913  precision = DB_DATETIME_PRECISION;
914  break;
915  case DB_TYPE_DATETIMETZ:
916  precision = DB_DATETIMETZ_PRECISION;
917  break;
918  case DB_TYPE_MONETARY:
919  precision = DB_MONETARY_DECIMAL_PRECISION;
920  break;
921  default:
922  precision = DB_DEFAULT_PRECISION;
923  break;
924  }
925 
926  return precision;
927 }
928 
929 /*
930  * tp_domain_free - free a hierarchical domain structure.
931  * return: none
932  * dom(out): domain to free
933  * Note:
934  * This routine can be called for a transient or cached domain. If
935  * the domain has been cached, the request is ignored.
936  * Note that you can only call this on the root of a domain hierarchy,
937  * you are not allowed to grab pointers into the middle of a hierarchical
938  * domain and free that.
939  */
940 void
942 {
943  TP_DOMAIN *d, *next;
944 
945  if (dom != NULL && !dom->is_cached)
946  {
947  /* NULL things that might be problems for garbage collection */
948  dom->class_mop = NULL;
949 
950  if (dom->type->id == DB_TYPE_JSON && dom->json_validator != NULL)
951  {
953  }
954 
955  /*
956  * sub-domains are always completely owned by their root domain,
957  * they cannot be cached anywhere else.
958  */
959  for (d = dom->setdomain, next = NULL; d != NULL; d = next)
960  {
961  next = d->next;
962  tp_domain_free (d);
963  }
964 
965  if (dom->type->id == DB_TYPE_ENUMERATION)
966  {
968  }
969 
970  (void) area_free (tp_Domain_area, dom);
971  }
972 }
973 
974 /*
975  * tp_domain_init - initializes a domain structure to contain reasonable "default"
976  * values.
977  * return: none
978  * domain(out): domain structure to initialize
979  * type_id(in): basic type of the domain
980  * Note:
981  * Used by tp_domain_new and also in some other places
982  * where we need to quickly synthesize some transient domain structures.
983  */
984 void
985 tp_domain_init (TP_DOMAIN * domain, DB_TYPE type_id)
986 {
987  assert (type_id <= DB_TYPE_LAST);
988 
989  domain->next = NULL;
990  domain->next_list = NULL;
991  domain->type = pr_type_from_id (type_id);
992  domain->precision = 0;
993  domain->scale = 0;
994  domain->class_mop = NULL;
995  domain->self_ref = 0;
996  domain->setdomain = NULL;
997  domain->json_validator = NULL;
998  DOM_SET_ENUM (domain, NULL, 0);
999  OID_SET_NULL (&domain->class_oid);
1000 
1002  if (TP_TYPE_HAS_COLLATION (type_id))
1003  {
1004  domain->codeset = LANG_SYS_CODESET;
1005  domain->collation_id = LANG_SYS_COLLATION;
1006  if (type_id == DB_TYPE_ENUMERATION)
1007  {
1009  }
1010  }
1011  else if (TP_IS_BIT_TYPE (type_id))
1012  {
1013  domain->codeset = INTL_CODESET_RAW_BITS;
1014  domain->collation_id = 0;
1015  }
1016  else
1017  {
1018  domain->codeset = 0;
1019  domain->collation_id = 0;
1020  }
1021  domain->is_cached = 0;
1022  domain->built_in_index = 0;
1023 
1024  /* use the built-in domain template to see if we're parameterized or not */
1025  domain->is_parameterized = tp_Domains[type_id]->is_parameterized;
1026 
1027  domain->is_desc = 0;
1028 }
1029 
1030 /*
1031  * tp_domain_new - returns a new initialized transient domain.
1032  * return: new transient domain
1033  * type(in): type id
1034  * Note:
1035  * It is intended for use in places where domains are being created
1036  * incrementally for eventual passing to tp_domain_cache.
1037  * Only the type id is passed here since that is the only common
1038  * piece of information shared by all domains.
1039  * The contents of the domain can be filled in by the caller assuming
1040  * they obey the rules.
1041  */
1042 TP_DOMAIN *
1044 {
1045  TP_DOMAIN *new_dm;
1046 
1047  new_dm = (TP_DOMAIN *) area_alloc (tp_Domain_area);
1048  if (new_dm != NULL)
1049  {
1050  tp_domain_init (new_dm, type);
1051  }
1052 
1053  return new_dm;
1054 }
1055 
1056 
1057 /*
1058  * tp_domain_construct - create a transient domain object with type, class,
1059  * precision, scale and setdomain.
1060  * return:
1061  * domain_type(in): The basic type of the domain
1062  * class_obj(in): The class of the domain (for DB_TYPE_OBJECT)
1063  * precision(in): The precision of the domain
1064  * scale(in): The class of the domain
1065  * setdomain(in): The setdomain of the domain
1066  * Note:
1067  * Used in a few places, callers must be aware that there may be more
1068  * initializations to do since not all of the domain parameters are
1069  * arguments to this function.
1070  *
1071  * The setdomain must also be a transient domain list.
1072  */
1073 TP_DOMAIN *
1074 tp_domain_construct (DB_TYPE domain_type, DB_OBJECT * class_obj, int precision, int scale, TP_DOMAIN * setdomain)
1075 {
1076  TP_DOMAIN *new_dm;
1077  int fixed_precision;
1078 
1079  new_dm = tp_domain_new (domain_type);
1080  if (new_dm)
1081  {
1082  fixed_precision = tp_get_fixed_precision (domain_type);
1083  if (fixed_precision != DB_DEFAULT_PRECISION)
1084  {
1085 #if !defined (NDEBUG)
1086  if (precision != fixed_precision)
1087  {
1088  assert (false);
1089  }
1090 #endif
1091  precision = fixed_precision;
1092  }
1093 
1094  new_dm->precision = precision;
1095  new_dm->scale = scale;
1096  new_dm->setdomain = setdomain;
1097  new_dm->json_validator = NULL;
1098 
1099 #if !defined (NDEBUG)
1100  if (domain_type == DB_TYPE_MIDXKEY)
1101  {
1102  assert ((new_dm->setdomain && new_dm->precision == tp_domain_size (new_dm->setdomain))
1103  || (new_dm->setdomain == NULL && new_dm->precision == 0));
1104 
1105  {
1106  TP_DOMAIN *d;
1107  for (d = new_dm->setdomain; d != NULL; d = d->next)
1108  {
1109  assert (d->is_cached == 0);
1110  }
1111  }
1112  }
1113 #endif /* NDEBUG */
1114 
1115  if (class_obj == (DB_OBJECT *) TP_DOMAIN_SELF_REF)
1116  {
1117  new_dm->class_mop = NULL;
1118  new_dm->self_ref = 1;
1119  }
1120  else
1121  {
1122  new_dm->class_mop = class_obj;
1123  new_dm->self_ref = 0;
1124  /*
1125  * For compatibility on the server side, class objects must have
1126  * the oid in the domain match the oid in the class object.
1127  */
1128  if (class_obj)
1129  {
1130 #if defined (SERVER_MODE)
1131  assert_release (false);
1132 #else /* !defined (SERVER_MODE) */
1133  new_dm->class_oid = class_obj->oid_info.oid;
1134 #endif /* !SERVER_MODE */
1135  }
1136  }
1137 
1138  /*
1139  * have to leave the class OID uninitialized because we don't know how
1140  * to get an OID out of a DB_OBJECT on the server.
1141  * That shouldn't matter since the server side unpackers will use
1142  * tp_domain_new and set the domain fields directly.
1143  */
1144  }
1145  return new_dm;
1146 }
1147 
1148 /*
1149  * tp_domain_copy_enumeration () - copy an enumeration
1150  * return: error code or NO_ERROR
1151  * dest (in/out): destination enumeration
1152  * src (in) : source enumeration
1153  */
1154 int
1156 {
1157  int error = NO_ERROR, i;
1158  DB_ENUM_ELEMENT *dest_elem = NULL, *src_elem = NULL;
1159  char *dest_str = NULL;
1160 
1161  if (src == NULL)
1162  {
1163  assert (false);
1164  return ER_FAILED;
1165  }
1166 
1167  if (dest == NULL)
1168  {
1169  assert (false);
1170  return ER_FAILED;
1171  }
1172 
1173  dest->collation_id = src->collation_id;
1174  dest->count = 0;
1175  dest->elements = NULL;
1176  if (src->count == 0 && src->elements == NULL)
1177  {
1178  /* nothing else to do */
1179  return NO_ERROR;
1180  }
1181 
1182  /* validate source enumeration */
1183  if (src->count == 0 && src->elements != NULL)
1184  {
1185  assert (false);
1186  return ER_FAILED;
1187  }
1188  else if (src->count != 0 && src->elements == NULL)
1189  {
1190  assert (false);
1191  return ER_FAILED;
1192  }
1193 
1194  dest->count = src->count;
1195 
1196  dest->elements = (DB_ENUM_ELEMENT *) malloc (src->count * sizeof (DB_ENUM_ELEMENT));
1197  if (dest->elements == NULL)
1198  {
1200  return ER_FAILED;
1201  }
1202 
1203  for (i = 0; i < src->count; i++)
1204  {
1205  src_elem = &src->elements[i];
1206  dest_elem = &dest->elements[i];
1207 
1208  DB_SET_ENUM_ELEM_SHORT (dest_elem, DB_GET_ENUM_ELEM_SHORT (src_elem));
1209 
1210  if (DB_GET_ENUM_ELEM_STRING (src_elem) != NULL)
1211  {
1212  dest_str = (char *) malloc (DB_GET_ENUM_ELEM_STRING_SIZE (src_elem) + 1);
1213  if (dest_str == NULL)
1214  {
1216  (size_t) (DB_GET_ENUM_ELEM_STRING_SIZE (src_elem) + 1));
1217  error = ER_OUT_OF_VIRTUAL_MEMORY;
1218  goto error_return;
1219  }
1220  memcpy (dest_str, DB_GET_ENUM_ELEM_STRING (src_elem), DB_GET_ENUM_ELEM_STRING_SIZE (src_elem));
1221  dest_str[DB_GET_ENUM_ELEM_STRING_SIZE (src_elem)] = 0;
1222  DB_SET_ENUM_ELEM_STRING (dest_elem, dest_str);
1224  }
1225  else
1226  {
1227  DB_SET_ENUM_ELEM_STRING (dest_elem, NULL);
1228  }
1229  DB_SET_ENUM_ELEM_CODESET (dest_elem, DB_GET_ENUM_ELEM_CODESET (src_elem));
1230  }
1231 
1232  return NO_ERROR;
1233 
1234 error_return:
1235  if (dest->elements != NULL)
1236  {
1237  for (--i; i >= 0; i--)
1238  {
1239  if (DB_GET_ENUM_ELEM_STRING (&dest->elements[i]) != NULL)
1240  {
1242  }
1243  }
1244  free_and_init (dest->elements);
1245  }
1246 
1247  return error;
1248 }
1249 
1250 /*
1251  * tp_domain_copy - copy a hierarcical domain structure
1252  * return: new domain
1253  * dom(in): domain to copy
1254  * check_cache(in): if set, return cached instance
1255  * Note:
1256  * If the domain was cached, we simply return a handle to the cached
1257  * domain, otherwise we make a full structure copy.
1258  * This should only be used in a few places in the schema manager which
1259  * maintains separate copies of all the attribute domains during
1260  * flattening. Could be converted to used cached domains perhaps.
1261  * But the "self referencing" domain is the problem.
1262  *
1263  * New functionality: If the check_cache parameter is false, we make
1264  * a NEW copy of the parameter domain whether it is cached or not. This
1265  * is used for updating fields of a cached domain. We don't want to
1266  * update a domain that has already been cached because multiple structures
1267  * may be pointing to it.
1268  */
1269 TP_DOMAIN *
1270 tp_domain_copy (const TP_DOMAIN * domain, bool check_cache)
1271 {
1272  TP_DOMAIN *new_domain, *first, *last;
1273  const TP_DOMAIN *d;
1274 
1275  if (check_cache && domain->is_cached)
1276  {
1277  return (TP_DOMAIN *) domain;
1278  }
1279 
1280  first = NULL;
1281  if (domain != NULL)
1282  {
1283  last = NULL;
1284 
1285  for (d = domain; d != NULL; d = d->next)
1286  {
1287  new_domain = tp_domain_new (TP_DOMAIN_TYPE (d));
1288  if (new_domain == NULL)
1289  {
1290  goto error;
1291  }
1292  else
1293  {
1294  /* copy over the domain parameters */
1295  new_domain->class_mop = d->class_mop;
1296  new_domain->class_oid = d->class_oid;
1297  new_domain->precision = d->precision;
1298  new_domain->scale = d->scale;
1299  new_domain->codeset = d->codeset;
1300  new_domain->collation_id = d->collation_id;
1301  new_domain->self_ref = d->self_ref;
1302  new_domain->is_parameterized = d->is_parameterized;
1303  new_domain->is_desc = d->is_desc;
1304  new_domain->json_validator = NULL;
1305 
1306  if (d->type->id == DB_TYPE_JSON)
1307  {
1308  if (d->json_validator != NULL)
1309  {
1311  }
1312  }
1313 
1314  if (d->type->id == DB_TYPE_ENUMERATION)
1315  {
1316  int error;
1318  if (error != NO_ERROR)
1319  {
1320  goto error;
1321  }
1322  }
1323 
1324  if (d->setdomain != NULL)
1325  {
1326  new_domain->setdomain = tp_domain_copy (d->setdomain, true);
1327  if (new_domain->setdomain == NULL)
1328  {
1329  goto error;
1330  }
1331  }
1332 
1333  if (first == NULL)
1334  {
1335  first = new_domain;
1336  }
1337  else
1338  {
1339  last->next = new_domain;
1340  }
1341  last = new_domain;
1342  }
1343  }
1344  }
1345 
1346  return first;
1347 
1348 error:
1349  for (d = first; d != NULL; d = d->next)
1350  {
1352  }
1353  return NULL;
1354 }
1355 
1356 
1357 /*
1358  * tp_domain_size_internal - count the number of domains in a domain list
1359  * return: number of domains in a domain list
1360  * domain(in): a domain list
1361  */
1362 static int
1364 {
1365  int size = 0;
1366 
1367  while (domain)
1368  {
1369  ++size;
1370  domain = domain->next;
1371  }
1372 
1373  return size;
1374 }
1375 
1376 /*
1377  * tp_domain_size - count the number of domains in a domain list
1378  * return: number of domains in a domain list
1379  * domain(in): domain
1380  */
1381 int
1382 tp_domain_size (const TP_DOMAIN * domain)
1383 {
1384  return tp_domain_size_internal (domain);
1385 }
1386 
1387 /*
1388  * tp_setdomain_size - count the number of domains in a setdomain list
1389  * return: number of domains in a setdomain list
1390  * domain(in): domain
1391  */
1392 int
1394 {
1395  if (TP_DOMAIN_TYPE (domain) == DB_TYPE_MIDXKEY)
1396  {
1397  assert ((domain->setdomain && domain->precision == tp_domain_size (domain->setdomain))
1398  || (domain->setdomain == NULL && domain->precision == 0));
1399  return domain->precision;
1400  }
1401  else
1402  {
1403  return tp_domain_size_internal (domain->setdomain);
1404  }
1405 }
1406 
1407 /*
1408  * tp_value_slam_domain - alter the domain of an existing DB_VALUE
1409  * return: nothing
1410  * value(out): value whose domain is to be altered
1411  * domain(in): domain descriptor
1412  * Note:
1413  * used usually in a context like tp_value_cast where we know that we
1414  * have a perfectly good fixed-length string that we want tocast as a varchar.
1415  *
1416  * This is a dangerous function and should not be exported to users. use
1417  * only if you know exactly what you're doing!!!!
1418  */
1419 static void
1420 tp_value_slam_domain (DB_VALUE * value, const DB_DOMAIN * domain)
1421 {
1422  switch (TP_DOMAIN_TYPE (domain))
1423  {
1424  case DB_TYPE_CHAR:
1425  case DB_TYPE_VARCHAR:
1426  case DB_TYPE_NCHAR:
1427  case DB_TYPE_VARNCHAR:
1428  if (domain->collation_flag == TP_DOMAIN_COLL_ENFORCE)
1429  {
1431  /* don't apply precision and type */
1432  break;
1433  }
1434  if (domain->collation_flag == TP_DOMAIN_COLL_NORMAL)
1435  {
1437  }
1438  /* FALLTHRU */
1439  case DB_TYPE_BIT:
1440  case DB_TYPE_VARBIT:
1441  value->domain.char_info.type = TP_DOMAIN_TYPE (domain);
1442  value->domain.char_info.length = domain->precision;
1443  break;
1444 
1445  case DB_TYPE_NUMERIC:
1446  value->domain.numeric_info.type = TP_DOMAIN_TYPE (domain);
1447  value->domain.numeric_info.precision = domain->precision;
1448  value->domain.numeric_info.scale = domain->scale;
1449  break;
1450 
1451  default:
1452  value->domain.general_info.type = TP_DOMAIN_TYPE (domain);
1453  break;
1454  }
1455 }
1456 
1457 /*
1458  * tp_domain_match - examins two domains to see if they are logically same
1459  * return: non-zero if the domains are the same
1460  * dom1(in): first domain
1461  * dom2(in): second domain
1462  * exact(in): how tolerant we are of mismatches
1463  */
1464 int
1465 tp_domain_match (const TP_DOMAIN * dom1, const TP_DOMAIN * dom2, TP_MATCH exact)
1466 {
1467  return tp_domain_match_internal (dom1, dom2, exact, true);
1468 }
1469 
1470 /*
1471  * tp_domain_match_ignore_order - examins two domains to see if they are logically same
1472  * return: non-zero if the domains are the same
1473  * dom1(in): first domain
1474  * dom2(in): second domain
1475  * exact(in): how tolerant we are of mismatches
1476  */
1477 int
1478 tp_domain_match_ignore_order (const TP_DOMAIN * dom1, const TP_DOMAIN * dom2, TP_MATCH exact)
1479 {
1480  return tp_domain_match_internal (dom1, dom2, exact, false);
1481 }
1482 
1483 /*
1484  * tp_domain_match_internal - examins two domains to see if they are logically same
1485  * return: non-zero if the domains are the same
1486  * dom1(in): first domain
1487  * dom2(in): second domain
1488  * exact(in): how tolerant we are of mismatches
1489  * match_order(in): check for asc/desc
1490  */
1491 static int
1492 tp_domain_match_internal (const TP_DOMAIN * dom1, const TP_DOMAIN * dom2, TP_MATCH exact, bool match_order)
1493 {
1494  int match = 0;
1495 
1496  if (dom1 == NULL || dom2 == NULL)
1497  {
1498  return 0;
1499  }
1500 
1501  /* in the case where their both cached */
1502  if (dom1 == dom2)
1503  {
1504  return 1;
1505  }
1506 
1507  if ((TP_DOMAIN_TYPE (dom1) != TP_DOMAIN_TYPE (dom2))
1508  && (exact != TP_STR_MATCH || !TP_NEAR_MATCH (TP_DOMAIN_TYPE (dom1), TP_DOMAIN_TYPE (dom2))))
1509  {
1510  return 0;
1511  }
1512 
1513  /*
1514  * At this point, either dom1 and dom2 have exactly the same type, or
1515  * exact_match is TP_STR_MATCH and dom1 and dom2 are a char/varchar
1516  * (nchar/varnchar, bit/varbit) pair.
1517  */
1518 
1519  /* check for asc/desc */
1520  if (TP_DOMAIN_TYPE (dom1) == TP_DOMAIN_TYPE (dom2) && tp_valid_indextype (TP_DOMAIN_TYPE (dom1))
1521  && match_order == true && dom1->is_desc != dom2->is_desc)
1522  {
1523  return 0;
1524  }
1525 
1526  /* could use the new is_parameterized flag to avoid the switch ? */
1527 
1528  switch (TP_DOMAIN_TYPE (dom1))
1529  {
1530 
1531  case DB_TYPE_NULL:
1532  case DB_TYPE_INTEGER:
1533  case DB_TYPE_BIGINT:
1534  case DB_TYPE_FLOAT:
1535  case DB_TYPE_DOUBLE:
1536  case DB_TYPE_BLOB:
1537  case DB_TYPE_CLOB:
1538  case DB_TYPE_TIME:
1539  case DB_TYPE_TIMESTAMP:
1540  case DB_TYPE_TIMESTAMPTZ:
1541  case DB_TYPE_TIMESTAMPLTZ:
1542  case DB_TYPE_DATETIME:
1543  case DB_TYPE_DATETIMETZ:
1544  case DB_TYPE_DATETIMELTZ:
1545  case DB_TYPE_DATE:
1546  case DB_TYPE_MONETARY:
1547  case DB_TYPE_SHORT:
1548  /*
1549  * these domains have no parameters, they match if the types are the
1550  * same.
1551  */
1552  match = 1;
1553  break;
1554 
1555  case DB_TYPE_JSON:
1556  match = (int) db_json_are_validators_equal (dom1->json_validator, dom2->json_validator);
1557  break;
1558 
1559  case DB_TYPE_VOBJ:
1560  case DB_TYPE_OBJECT:
1561  case DB_TYPE_SUB:
1562 
1563 #if defined (SERVER_MODE)
1564  match = OID_EQ (&dom1->class_oid, &dom2->class_oid);
1565 #else /* !defined (SERVER_MODE) */
1566  /*
1567  * if "exact" is zero, we should be checking the subclass hierarchy of
1568  * dom1 to see id dom2 is in it !
1569  */
1570 
1571  /* Always prefer comparison of MOPs */
1572  if (dom1->class_mop != NULL && dom2->class_mop != NULL)
1573  {
1574  match = (dom1->class_mop == dom2->class_mop);
1575  }
1576  else if (dom1->class_mop == NULL && dom2->class_mop == NULL)
1577  {
1578  match = OID_EQ (&dom1->class_oid, &dom2->class_oid);
1579  }
1580  else
1581  {
1582  /*
1583  * We have a mixture of OID & MOPS, it probably isn't necessary to
1584  * be this general but try to avoid assuming the class OIDs have
1585  * been set when there is a MOP present.
1586  */
1587  if (dom1->class_mop == NULL)
1588  {
1589  match = OID_EQ (&dom1->class_oid, WS_OID (dom2->class_mop));
1590  }
1591  else
1592  {
1593  match = OID_EQ (WS_OID (dom1->class_mop), &dom2->class_oid);
1594  }
1595  }
1596 #endif /* defined (SERVER_MODE) */
1597 
1598  if (match == 0 && exact == TP_SET_MATCH && dom1->class_mop == NULL && OID_ISNULL (&dom1->class_oid))
1599  {
1600  match = 1;
1601  }
1602  break;
1603 
1604  case DB_TYPE_VARIABLE:
1605  case DB_TYPE_SET:
1606  case DB_TYPE_MULTISET:
1607  case DB_TYPE_SEQUENCE:
1608 #if 1
1609  /* >>>>> NEED MORE CONSIDERATION <<<<< do not check order must be rollback with tp_domain_add() */
1610  if (dom1->setdomain == dom2->setdomain)
1611  {
1612  match = 1;
1613  }
1614  else
1615  {
1616  int dsize;
1617 
1618  /* don't bother comparing the lists unless the sizes are the same */
1619  dsize = tp_domain_size (dom1->setdomain);
1620  if (dsize == tp_domain_size (dom2->setdomain))
1621  {
1622  /* handle the simple single domain case quickly */
1623  if (dsize == 1)
1624  {
1625  match = tp_domain_match (dom1->setdomain, dom2->setdomain, exact);
1626  }
1627  else
1628  {
1629  TP_DOMAIN *d1, *d2;
1630 
1631  match = 1;
1632  for (d1 = dom1->setdomain, d2 = dom2->setdomain; d1 != NULL && d2 != NULL;
1633  d1 = d1->next, d2 = d2->next)
1634  {
1635  if (!tp_domain_match (d1, d2, exact))
1636  {
1637  match = 0;
1638  break; /* immediately exit for loop */
1639  }
1640  }
1641  }
1642  }
1643  }
1644 #else /* 0 */
1645  if (dom1->setdomain == dom2->setdomain)
1646  {
1647  match = 1;
1648  }
1649  else
1650  {
1651  int dsize;
1652 
1653  /* don't bother comparing the lists unless the sizes are the same */
1654  dsize = tp_domain_size (dom1->setdomain);
1655  if (dsize == tp_domain_size (dom2->setdomain))
1656  {
1657 
1658  /* handle the simple single domain case quickly */
1659  if (dsize == 1)
1660  {
1661  match = tp_domain_match (dom1->setdomain, dom2->setdomain, exact);
1662  }
1663  else
1664  {
1665  TP_DOMAIN *d1, *d2;
1666 
1667  /* clear the visited flag in the second subdomain list */
1668  for (d2 = dom2->setdomain; d2 != NULL; d2 = d2->next)
1669  {
1670  d2->is_visited = 0;
1671  }
1672 
1673  match = 1;
1674  for (d1 = dom1->setdomain; d1 != NULL && match; d1 = d1->next)
1675  {
1676  for (d2 = dom2->setdomain; d2 != NULL; d2 = d2->next)
1677  {
1678  if (!d2->is_visited && tp_domain_match (d1, d2, exact))
1679  {
1680  break;
1681  }
1682  }
1683  /* did we find the domain in the other list ? */
1684  if (d2 != NULL)
1685  {
1686  d2->is_visited = 1;
1687  }
1688  else
1689  {
1690  match = 0;
1691  }
1692  }
1693  }
1694  }
1695  }
1696 #endif /* 1 */
1697  break;
1698 
1699  case DB_TYPE_MIDXKEY:
1700  if (dom1->setdomain == dom2->setdomain)
1701  {
1702  match = 1;
1703  }
1704  else
1705  {
1706  int i, dsize1, dsize2;
1707  TP_DOMAIN *element_dom1;
1708  TP_DOMAIN *element_dom2;
1709 
1710  dsize1 = tp_domain_size (dom1->setdomain);
1711  dsize2 = tp_domain_size (dom2->setdomain);
1712 
1713  if (dsize1 == dsize2)
1714  {
1715  match = 1;
1716  element_dom1 = dom1->setdomain;
1717  element_dom2 = dom2->setdomain;
1718 
1719  for (i = 0; i < dsize1; i++)
1720  {
1721  match = tp_domain_match (element_dom1, element_dom2, exact);
1722  if (match == 0)
1723  {
1724  break;
1725  }
1726  element_dom1 = element_dom1->next;
1727  element_dom2 = element_dom2->next;
1728  }
1729  }
1730  }
1731  break;
1732 
1733  case DB_TYPE_VARCHAR:
1734  if (dom1->collation_id != dom2->collation_id)
1735  {
1736  match = 0;
1737  break;
1738  }
1739  /* fall through */
1740  case DB_TYPE_VARBIT:
1741  if (exact == TP_EXACT_MATCH || exact == TP_SET_MATCH)
1742  {
1743  match = dom1->precision == dom2->precision;
1744  }
1745  else if (exact == TP_STR_MATCH)
1746  {
1747  /*
1748  * Allow the match if the precisions would allow us to reuse the
1749  * string without modification.
1750  */
1751  match = (dom1->precision >= dom2->precision);
1752  }
1753  else
1754  {
1755  /*
1756  * Allow matches regardless of precision, let the actual length of the
1757  * value determine if it can be assigned. This is important for
1758  * literal strings as their precision will be the maximum but they
1759  * can still be assigned to domains with a smaller precision
1760  * provided the actual value is within the destination domain
1761  * tolerance.
1762  */
1763  match = 1;
1764  }
1765  break;
1766 
1767  case DB_TYPE_CHAR:
1768  if (dom1->collation_id != dom2->collation_id)
1769  {
1770  match = 0;
1771  break;
1772  }
1773  /* fall through */
1774  case DB_TYPE_BIT:
1775  /*
1776  * Unlike varchar, we have to be a little tighter on domain matches for
1777  * fixed width char. Not as much of a problem since these won't be
1778  * used for literal strings.
1779  */
1780  if (exact == TP_EXACT_MATCH || exact == TP_STR_MATCH || exact == TP_SET_MATCH)
1781  {
1782  match = (dom1->precision == dom2->precision);
1783  }
1784  else
1785  {
1786  /* Recognize a precision of TP_FLOATING_PRECISION_VALUE to indicate a precision whose coercability must be
1787  * determined by examing the value. This is used primarily by db_coerce() since it must pick a reasonable
1788  * CHAR domain for the representation of a literal string. Accept zero here too since it seems to creep into
1789  * domains sometimes. */
1790  match = (dom2->precision == 0 || dom2->precision == TP_FLOATING_PRECISION_VALUE
1791  || dom1->precision >= dom2->precision);
1792  }
1793  break;
1794 
1795  case DB_TYPE_NCHAR:
1796  if (exact == TP_EXACT_MATCH || exact == TP_STR_MATCH || exact == TP_SET_MATCH)
1797  {
1798  match = ((dom1->precision == dom2->precision) && (dom1->collation_id == dom2->collation_id));
1799  }
1800  else
1801  {
1802  /*
1803  * see discussion of special domain precision values in the
1804  * DB_TYPE_CHAR case above.
1805  */
1806  match = ((dom1->collation_id == dom2->collation_id)
1807  && (dom2->precision == 0 || dom2->precision == TP_FLOATING_PRECISION_VALUE
1808  || dom1->precision >= dom2->precision));
1809  }
1810 
1811  break;
1812 
1813  case DB_TYPE_VARNCHAR:
1814  if (exact == TP_EXACT_MATCH || exact == TP_STR_MATCH || exact == TP_SET_MATCH)
1815  {
1816  match = ((dom1->precision == dom2->precision) && (dom1->collation_id == dom2->collation_id));
1817  }
1818  else
1819  {
1820  /* see notes above under the DB_TYPE_VARCHAR clause */
1821  match = dom1->collation_id == dom2->collation_id;
1822  }
1823  break;
1824 
1825  case DB_TYPE_NUMERIC:
1826  /*
1827  * note that we never allow inexact matches here because the
1828  * mr_setmem_numeric function is not currently able to perform the
1829  * deferred coercion.
1830  */
1831  match = ((dom1->precision == dom2->precision) && (dom1->scale == dom2->scale));
1832  break;
1833 
1834  case DB_TYPE_POINTER:
1835  case DB_TYPE_ERROR:
1836  case DB_TYPE_OID:
1837  case DB_TYPE_DB_VALUE:
1838  /*
1839  * These are internal domains, they shouldn't be seen, in case they are,
1840  * just let them match without parameters.
1841  */
1842  match = 1;
1843  break;
1844 
1845  case DB_TYPE_ENUMERATION:
1847  break;
1848 
1849  case DB_TYPE_RESULTSET:
1850  case DB_TYPE_TABLE:
1851  break;
1852  case DB_TYPE_ELO:
1853  assert (false);
1854  break;
1855  /* don't have a default so we make sure to add clauses for all types */
1856  }
1857 
1858 #if !defined (NDEBUG)
1859  if (match && TP_TYPE_HAS_COLLATION (TP_DOMAIN_TYPE (dom1)))
1860  {
1861  assert (dom1->codeset == dom2->codeset);
1862  }
1863 #endif
1864 
1865  return match;
1866 }
1867 
1868 /*
1869  * tp_domain_get_list_ptr - get the pointer of the head of domain list
1870  * return: pointer of the head of the list
1871  * type(in): type of value
1872  * setdomain(in): used to find appropriate list of MIDXKEY
1873  */
1876 {
1877  int list_index;
1878 
1879  if (type == DB_TYPE_MIDXKEY)
1880  {
1881  list_index = tp_domain_size (setdomain);
1882  list_index %= TP_NUM_MIDXKEY_DOMAIN_LIST;
1883  return &(tp_Midxkey_domains[list_index]);
1884  }
1885  else
1886  {
1887  return &(tp_Domains[type]);
1888  }
1889 }
1890 
1891 /*
1892  * tp_domain_get_list - get the head of domain list
1893  * return: the head of the list
1894  * type(in): type of value
1895  * setdomain(in): used to find appropriate list of MIDXKEY
1896  */
1899 {
1900  TP_DOMAIN **dlist;
1901 
1902  dlist = tp_domain_get_list_ptr (type, setdomain);
1903  return *dlist;
1904 }
1905 
1906 /*
1907  * tp_is_domain_cached - find matching domain from domain list
1908  * return: matched domain
1909  * dlist(in): domain list
1910  * transient(in): transient domain
1911  * exact(in): matching level
1912  * ins_pos(out): domain found
1913  * Note:
1914  * DB_TYPE_VARCHAR, DB_TYPE_VARBIT, DB_TYPE_VARNCHAR : precision's desc order
1915  * others: precision's asc order
1916  */
1917 static TP_DOMAIN *
1918 tp_is_domain_cached (TP_DOMAIN * dlist, TP_DOMAIN * transient, TP_MATCH exact, TP_DOMAIN ** ins_pos)
1919 {
1920  TP_DOMAIN *domain = dlist;
1921  int match = 0;
1922 
1923  /* in the case where their both cached */
1924  if (domain == transient)
1925  {
1926  return domain;
1927  }
1928 
1929  if ((TP_DOMAIN_TYPE (domain) != TP_DOMAIN_TYPE (transient))
1930  && (exact != TP_STR_MATCH || !TP_NEAR_MATCH (TP_DOMAIN_TYPE (domain), TP_DOMAIN_TYPE (transient))))
1931  {
1932  return NULL;
1933  }
1934 
1935  *ins_pos = domain;
1936 
1937  /*
1938  * At this point, either domain and transient have exactly the same type, or
1939  * exact_match is TP_STR_MATCH and domain and transient are a char/varchar
1940  * (nchar/varnchar, bit/varbit) pair.
1941  */
1942 
1943  /* could use the new is_parameterized flag to avoid the switch ? */
1944  switch (TP_DOMAIN_TYPE (domain))
1945  {
1946 
1947  case DB_TYPE_NULL:
1948  case DB_TYPE_INTEGER:
1949  case DB_TYPE_BIGINT:
1950  case DB_TYPE_FLOAT:
1951  case DB_TYPE_DOUBLE:
1952  case DB_TYPE_BLOB:
1953  case DB_TYPE_CLOB:
1954  case DB_TYPE_TIME:
1955  case DB_TYPE_TIMESTAMP:
1956  case DB_TYPE_TIMESTAMPLTZ:
1957  case DB_TYPE_TIMESTAMPTZ:
1958  case DB_TYPE_DATETIME:
1959  case DB_TYPE_DATETIMELTZ:
1960  case DB_TYPE_DATETIMETZ:
1961  case DB_TYPE_DATE:
1962  case DB_TYPE_MONETARY:
1963  case DB_TYPE_SHORT:
1964  /*
1965  * these domains have no parameters, they match if asc/desc are the
1966  * same
1967  */
1968  while (domain)
1969  {
1970  if (domain->is_desc == transient->is_desc)
1971  {
1972  match = 1;
1973  break;
1974  }
1975 
1976  *ins_pos = domain;
1977  domain = domain->next_list;
1978  }
1979  break;
1980 
1981  case DB_TYPE_VOBJ:
1982  case DB_TYPE_OBJECT:
1983  case DB_TYPE_SUB:
1984 
1985 #if defined (SERVER_MODE)
1986  /* not match for these types on server... fall through. */
1987 #else /* !defined (SERVER_MODE) */
1988 
1989  while (domain)
1990  {
1991  /*
1992  * if "exact" is zero, we should be checking the subclass hierarchy
1993  * of domain to see id transient is in it !
1994  */
1995 
1996  /* Always prefer comparison of MOPs */
1997  if (domain->class_mop != NULL && transient->class_mop != NULL)
1998  {
1999  match = (domain->class_mop == transient->class_mop);
2000  }
2001  else if (domain->class_mop == NULL && transient->class_mop == NULL)
2002  {
2003  match = OID_EQ (&domain->class_oid, &transient->class_oid);
2004  }
2005  else
2006  {
2007  /*
2008  * We have a mixture of OID & MOPS, it probably isn't necessary
2009  * to be this general but try to avoid assuming the class OIDs
2010  * have been set when there is a MOP present.
2011  */
2012  if (domain->class_mop != NULL)
2013  {
2014  match = OID_EQ (WS_OID (domain->class_mop), &transient->class_oid);
2015  }
2016  }
2017 
2018  if (match == 0 && exact == TP_SET_MATCH && domain->class_mop == NULL && OID_ISNULL (&domain->class_oid))
2019  {
2020  /* check for asc/desc */
2021  if (domain->is_desc == transient->is_desc)
2022  {
2023  match = 1;
2024  }
2025  }
2026 
2027  if (match)
2028  {
2029  break;
2030  }
2031 
2032  *ins_pos = domain;
2033  domain = domain->next_list;
2034  }
2035 #endif /* !defined (SERVER_MODE) */
2036  break;
2037 
2038  case DB_TYPE_VARIABLE:
2039  case DB_TYPE_SET:
2040  case DB_TYPE_MULTISET:
2041  case DB_TYPE_SEQUENCE:
2042  {
2043  int dsize2;
2044 
2045  dsize2 = tp_domain_size (transient->setdomain);
2046  while (domain)
2047  {
2048 #if 1
2049  /* >>>>> NEED MORE CONSIDERATION <<<<< do not check order must be rollback with tp_domain_add() */
2050  if (domain->setdomain == transient->setdomain)
2051  {
2052  match = 1;
2053  }
2054  else
2055  {
2056  int dsize1;
2057 
2058  /*
2059  * don't bother comparing the lists unless the sizes are the
2060  * same
2061  */
2062  dsize1 = tp_domain_size (domain->setdomain);
2063  if (dsize1 > dsize2)
2064  {
2065  break;
2066  }
2067 
2068  if (dsize1 == dsize2)
2069  {
2070 
2071  /* handle the simple single domain case quickly */
2072  if (dsize1 == 1)
2073  {
2074  match = tp_domain_match (domain->setdomain, transient->setdomain, exact);
2075  }
2076  else
2077  {
2078  TP_DOMAIN *d1, *d2;
2079 
2080  match = 1;
2081  for (d1 = domain->setdomain, d2 = transient->setdomain; d1 != NULL && d2 != NULL;
2082  d1 = d1->next, d2 = d2->next)
2083  {
2084  if (!tp_domain_match (d1, d2, exact))
2085  {
2086  match = 0;
2087  break; /* immediately exit for loop */
2088  }
2089  } /* for */
2090  }
2091  } /* if (dsize1 == dsize2) */
2092  }
2093 #else /* #if 1 */
2094  if (domain->setdomain == transient->setdomain)
2095  {
2096  match = 1;
2097  }
2098  else
2099  {
2100  int dsize;
2101 
2102  /*
2103  * don't bother comparing the lists unless the sizes are the
2104  * same
2105  */
2106  dsize = tp_domain_size (domain->setdomain);
2107  if (dsize == tp_domain_size (transient->setdomain))
2108  {
2109 
2110  /* handle the simple single domain case quickly */
2111  if (dsize == 1)
2112  {
2113  match = tp_domain_match (domain->setdomain, transient->setdomain, exact);
2114  }
2115  else
2116  {
2117  TP_DOMAIN *d1, *d2;
2118 
2119  /* clear the visited flag of second subdomain list */
2120  for (d2 = transient->setdomain; d2 != NULL; d2 = d2->next)
2121  {
2122  d2->is_visited = 0;
2123  }
2124 
2125  match = 1;
2126  for (d1 = domain->setdomain; d1 != NULL && match; d1 = d1->next)
2127  {
2128  for (d2 = transient->setdomain; d2 != NULL; d2 = d2->next)
2129  {
2130  if (!d2->is_visited && tp_domain_match (d1, d2, exact))
2131  {
2132  break;
2133  }
2134  }
2135  /* did we find the domain in the other list ? */
2136  if (d2 != NULL)
2137  {
2138  d2->is_visited = 1;
2139  }
2140  else
2141  {
2142  match = 0;
2143  }
2144  }
2145  }
2146  }
2147  }
2148 #endif /* #if 1 */
2149 
2150  if (match)
2151  {
2152  break;
2153  }
2154 
2155  *ins_pos = domain;
2156  domain = domain->next_list;
2157  }
2158  }
2159  break;
2160 
2161  case DB_TYPE_MIDXKEY:
2162  {
2163  int dsize2;
2164 
2165  dsize2 = tp_setdomain_size (transient);
2166  while (domain)
2167  {
2168  if (domain->setdomain == transient->setdomain)
2169  {
2170  match = 1;
2171  }
2172  else
2173  {
2174  int i, dsize1;
2175  TP_DOMAIN *element_dom1;
2176  TP_DOMAIN *element_dom2;
2177 
2178  dsize1 = tp_setdomain_size (domain);
2179  if (dsize1 > dsize2)
2180  {
2181  break;
2182  }
2183 
2184  if (dsize1 == dsize2)
2185  {
2186  match = 1;
2187  element_dom1 = domain->setdomain;
2188  element_dom2 = transient->setdomain;
2189 
2190  for (i = 0; i < dsize1; i++)
2191  {
2192  match = tp_domain_match (element_dom1, element_dom2, exact);
2193  if (match == 0)
2194  {
2195  break;
2196  }
2197 
2198  element_dom1 = element_dom1->next;
2199  element_dom2 = element_dom2->next;
2200  }
2201  }
2202  }
2203  if (match)
2204  {
2205  break;
2206  }
2207 
2208  *ins_pos = domain;
2209  domain = domain->next_list;
2210  }
2211  }
2212  break;
2213 
2214  case DB_TYPE_JSON:
2215  while (domain)
2216  {
2217  match = (int) db_json_are_validators_equal (transient->json_validator, domain->json_validator);
2218 
2219  if (match)
2220  {
2221  break;
2222  }
2223  *ins_pos = domain;
2224  domain = domain->next_list;
2225  }
2226  break;
2227 
2228  case DB_TYPE_VARCHAR:
2229  while (domain)
2230  {
2231  if (exact == TP_EXACT_MATCH || exact == TP_SET_MATCH)
2232  {
2233  /* check for descending order */
2234  if (domain->precision < transient->precision)
2235  {
2236  break;
2237  }
2238 
2239  match = ((domain->precision == transient->precision) && (domain->collation_id == transient->collation_id)
2240  && (domain->is_desc == transient->is_desc)
2241  && (domain->collation_flag == transient->collation_flag));
2242  }
2243  else if (exact == TP_STR_MATCH)
2244  {
2245  /*
2246  * Allow the match if the precisions would allow us to reuse the
2247  * string without modification.
2248  */
2249  match = ((domain->precision >= transient->precision) && (domain->collation_id == transient->collation_id)
2250  && (domain->is_desc == transient->is_desc)
2251  && (domain->collation_flag == transient->collation_flag));
2252  }
2253  else
2254  {
2255  /*
2256  * Allow matches regardless of precision, let the actual length
2257  * of the value determine if it can be assigned. This is
2258  * important for literal strings as their precision will be the
2259  * maximum but they can still be assigned to domains with a
2260  * smaller precision provided the actual value is within the
2261  * destination domain tolerance.
2262  */
2263  match = ((domain->collation_id == transient->collation_id) && (domain->is_desc == transient->is_desc)
2264  && (domain->collation_flag == transient->collation_flag));
2265  }
2266 
2267  if (match)
2268  {
2269  assert (domain->codeset == transient->codeset);
2270  break;
2271  }
2272 
2273  *ins_pos = domain;
2274  domain = domain->next_list;
2275  }
2276  break;
2277 
2278  case DB_TYPE_VARBIT:
2279  while (domain)
2280  {
2281  if (exact == TP_EXACT_MATCH || exact == TP_SET_MATCH)
2282  {
2283  /* check for descending order */
2284  if (domain->precision < transient->precision)
2285  {
2286  break;
2287  }
2288 
2289  match = ((domain->precision == transient->precision) && (domain->is_desc == transient->is_desc));
2290  }
2291  else if (exact == TP_STR_MATCH)
2292  {
2293  /*
2294  * Allow the match if the precisions would allow us to reuse the
2295  * string without modification.
2296  */
2297  match = ((domain->precision >= transient->precision) && (domain->is_desc == transient->is_desc));
2298  }
2299  else
2300  {
2301  /*
2302  * Allow matches regardless of precision, let the actual length
2303  * of the value determine if it can be assigned. This is
2304  * important for literal strings as their precision will be the
2305  * maximum but they can still be assigned to domains with a
2306  * smaller precision provided the actual value is within the
2307  * destination domain tolerance.
2308  */
2309  match = (domain->is_desc == transient->is_desc);
2310  }
2311 
2312  if (match)
2313  {
2314  break;
2315  }
2316 
2317  *ins_pos = domain;
2318  domain = domain->next_list;
2319  }
2320  break;
2321 
2322  case DB_TYPE_BIT:
2323  while (domain)
2324  {
2325  /*
2326  * Unlike varchar, we have to be a little tighter on domain matches
2327  * for fixed width char. Not as much of a problem since these won't
2328  * be used for literal strings.
2329  */
2330  if (exact == TP_EXACT_MATCH || exact == TP_STR_MATCH || exact == TP_SET_MATCH)
2331  {
2332  if (domain->precision > transient->precision)
2333  {
2334  break;
2335  }
2336 
2337  match = ((domain->precision == transient->precision) && (domain->is_desc == transient->is_desc));
2338  }
2339  else
2340  {
2341  /*
2342  * Recognize a precision of TP_FLOATING_PRECISION_VALUE to
2343  * indicate a precision whose coercability must be determined
2344  * by examing the value. This is used primarily by db_coerce()
2345  * since it must pick a reasonable CHAR domain for the
2346  * representation of a literal string.
2347  * Accept zero here too since it seems to creep into domains
2348  * sometimes.
2349  */
2350  match =
2351  ((transient->precision == 0 || transient->precision == TP_FLOATING_PRECISION_VALUE
2352  || domain->precision >= transient->precision) && (domain->is_desc == transient->is_desc));
2353  }
2354 
2355  if (match)
2356  {
2357  break;
2358  }
2359 
2360  *ins_pos = domain;
2361  domain = domain->next_list;
2362  }
2363  break;
2364 
2365  case DB_TYPE_CHAR:
2366  case DB_TYPE_NCHAR:
2367  while (domain)
2368  {
2369  if (exact == TP_EXACT_MATCH || exact == TP_STR_MATCH || exact == TP_SET_MATCH)
2370  {
2371  if (domain->precision > transient->precision)
2372  {
2373  break;
2374  }
2375 
2376  match = ((domain->precision == transient->precision) && (domain->collation_id == transient->collation_id)
2377  && (domain->is_desc == transient->is_desc)
2378  && (domain->collation_flag == transient->collation_flag));
2379  }
2380  else
2381  {
2382  /*
2383  * see discussion of special domain precision values
2384  * in the DB_TYPE_CHAR case above.
2385  */
2386  match = ((domain->collation_id == transient->collation_id)
2387  && (transient->precision == 0 || (transient->precision == TP_FLOATING_PRECISION_VALUE)
2388  || domain->precision >= transient->precision)
2389  && (domain->is_desc == transient->is_desc)
2390  && (domain->collation_flag == transient->collation_flag));
2391  }
2392 
2393  if (match)
2394  {
2395  assert (domain->codeset == transient->codeset);
2396  break;
2397  }
2398 
2399  *ins_pos = domain;
2400  domain = domain->next_list;
2401  }
2402 
2403  break;
2404 
2405  case DB_TYPE_VARNCHAR:
2406  while (domain)
2407  {
2408  if (exact == TP_EXACT_MATCH || exact == TP_STR_MATCH || exact == TP_SET_MATCH)
2409  {
2410  /* check for descending order */
2411  if (domain->precision < transient->precision)
2412  {
2413  break;
2414  }
2415 
2416  match = ((domain->precision == transient->precision) && (domain->collation_id == transient->collation_id)
2417  && (domain->is_desc == transient->is_desc)
2418  && (domain->collation_flag == transient->collation_flag));
2419  }
2420  else
2421  {
2422  /* see notes above under the DB_TYPE_VARCHAR clause */
2423  match = ((domain->collation_id == transient->collation_id) && (domain->is_desc == transient->is_desc)
2424  && (domain->collation_flag == transient->collation_flag));
2425  }
2426 
2427  if (match)
2428  {
2429  assert (domain->codeset == transient->codeset);
2430  break;
2431  }
2432 
2433  *ins_pos = domain;
2434  domain = domain->next_list;
2435  }
2436  break;
2437 
2438  case DB_TYPE_NUMERIC:
2439  /*
2440  * The first domain is a default domain for numeric type,
2441  * actually NUMERIC(15,0). We try to match it first.
2442  */
2443  if (transient->precision == domain->precision && transient->scale == domain->scale
2444  && transient->is_desc == domain->is_desc)
2445  {
2446  match = 1;
2447  break;
2448  }
2449 
2450  domain = domain->next_list;
2451  while (domain)
2452  {
2453  /*
2454  * The other domains for numeric values are sorted
2455  * by descending order of precision and scale.
2456  */
2457  if ((domain->precision < transient->precision)
2458  || ((domain->precision == transient->precision) && (domain->scale < transient->scale)))
2459  {
2460  break;
2461  }
2462 
2463  /*
2464  * note that we never allow inexact matches here because
2465  * the mr_setmem_numeric function is not currently able
2466  * to perform the deferred coercion.
2467  */
2468  match = ((domain->precision == transient->precision) && (domain->scale == transient->scale)
2469  && (domain->is_desc == transient->is_desc));
2470  if (match)
2471  {
2472  break;
2473  }
2474 
2475  *ins_pos = domain;
2476  domain = domain->next_list;
2477  }
2478  break;
2479 
2480  case DB_TYPE_POINTER:
2481  case DB_TYPE_ERROR:
2482  case DB_TYPE_OID:
2483  case DB_TYPE_DB_VALUE:
2484  /*
2485  * These are internal domains, they shouldn't be seen, in case they are,
2486  * just let them match without parameters.
2487  */
2488 
2489  while (domain)
2490  {
2491  if (domain->is_desc == transient->is_desc)
2492  {
2493  match = 1;
2494  break;
2495  }
2496 
2497  *ins_pos = domain;
2498  domain = domain->next_list;
2499  }
2500  break;
2501 
2502  case DB_TYPE_ENUMERATION:
2503  while (domain != NULL)
2504  {
2505  if (tp_enumeration_match (&DOM_GET_ENUMERATION (domain), &DOM_GET_ENUMERATION (transient)) != 0)
2506  {
2507  match = 1;
2508  break;
2509  }
2510  domain = domain->next_list;
2511  }
2512  break;
2513 
2514  case DB_TYPE_RESULTSET:
2515  case DB_TYPE_TABLE:
2516  break;
2517  case DB_TYPE_ELO:
2518  assert (false);
2519  break;
2520  /* don't have a default so we make sure to add clauses for all types */
2521  }
2522 
2523  return (match ? domain : NULL);
2524 }
2525 
2526 #if !defined (SERVER_MODE)
2527 /*
2528  * tp_swizzle_oid - swizzle oid of a domain class recursively
2529  * return: void
2530  * domain(in): domain to swizzle
2531  * Note:
2532  * If the code caching the domain was written for the server, we will
2533  * only have the OID of the class here if this is an object domain. If
2534  * the domain table is being shared by the client and server (e.g. in
2535  * standalone mode), it is important that we "swizzle" the OID into
2536  * a corresponding workspace MOP during the cache. This ensures that we
2537  * never get an object domain entered into the client's domain table that
2538  * doesn't have a real DB_OBJECT pointer for the domain class. There is
2539  * a lot of code that expects this to be the case.
2540  */
2541 static void
2543 {
2544  TP_DOMAIN *d;
2545  DB_TYPE type;
2546 
2547  type = TP_DOMAIN_TYPE (domain);
2548 
2549  if ((type == DB_TYPE_OBJECT || type == DB_TYPE_OID || type == DB_TYPE_VOBJ) && domain->class_mop == NULL
2550  && !OID_ISNULL (&domain->class_oid))
2551  {
2552  /* swizzle the pointer if we're on the client */
2553  domain->class_mop = ws_mop (&domain->class_oid, NULL);
2554  }
2555  else if (TP_IS_SET_TYPE (type))
2556  {
2557  for (d = domain->setdomain; d != NULL; d = d->next)
2558  {
2559  tp_swizzle_oid (d);
2560  }
2561  }
2562 }
2563 #endif /* !SERVER_MODE */
2564 
2565 /*
2566  * tp_domain_find_noparam - get domain for give type
2567  * return: domain
2568  * type(in): domain type
2569  * is_desc(in): desc order for index key_type
2570  */
2571 TP_DOMAIN *
2572 tp_domain_find_noparam (DB_TYPE type, bool is_desc)
2573 {
2574  TP_DOMAIN *dom;
2575 
2576  /* tp_domain_find_with_no_param */
2577  /* type : DB_TYPE_NULL DB_TYPE_INTEGER DB_TYPE_FLOAT DB_TYPE_DOUBLE DB_TYPE_ELO DB_TYPE_TIME DB_TYPE_BLOB
2578  * DB_TYPE_CLOB DB_TYPE_TIMESTAMP DB_TYPE_DATE DB_TYPE_DATETIME DB_TYPE_MONETARY DB_TYPE_SHORT DB_TYPE_BIGINT
2579  * DB_TYPE_TIMESTAMPTZ DB_TYPE_TIMESTAMPLTZ DB_TYPE_DATETIMETZ DB_TYPE_DATETIMELTZ */
2580 
2581  for (dom = tp_domain_get_list (type, NULL); dom != NULL; dom = dom->next_list)
2582  {
2583  if (dom->is_desc == is_desc)
2584  {
2585  break; /* found */
2586  }
2587  }
2588 
2589  return dom;
2590 }
2591 
2592 /*
2593  * tp_domain_find_numeric - find domain for given type, precision and scale
2594  * return: domain that matches
2595  * type(in): DB_TYPE
2596  * precision(in): precision
2597  * scale(in): scale
2598  * is_desc(in): desc order for index key_type
2599  */
2600 TP_DOMAIN *
2601 tp_domain_find_numeric (DB_TYPE type, int precision, int scale, bool is_desc)
2602 {
2603  TP_DOMAIN *dom;
2604 
2605  /* tp_domain_find_with_precision_scale */
2606  /* type : DB_TYPE_NUMERIC */
2607  assert (type == DB_TYPE_NUMERIC);
2608 
2609  /*
2610  * The first domain is a default domain for numeric type,
2611  * actually NUMERIC(15,0). We try to match it first.
2612  */
2613  dom = tp_domain_get_list (type, NULL);
2614  if (precision == dom->precision && scale == dom->scale && is_desc == dom->is_desc)
2615  {
2616  return dom;
2617  }
2618 
2619  /* search the list for a domain that matches */
2620  for (dom = dom->next_list; dom != NULL; dom = dom->next_list)
2621  {
2622  if ((precision > dom->precision) || ((precision == dom->precision) && (scale > dom->scale)))
2623  {
2624  return NULL; /* not exist */
2625  }
2626 
2627  /* we MUST perform exact matches here */
2628  if (dom->precision == precision && dom->scale == scale && dom->is_desc == is_desc)
2629  {
2630  break; /* found */
2631  }
2632  }
2633 
2634  return dom;
2635 }
2636 
2637 /*
2638  * tp_domain_find_charbit - find domain for given codeset and precision
2639  * return: domain that matches
2640  * type(in): DB_TYPE
2641  * codeset(in): code set
2642  * collation_id(in): collation id
2643  * precision(in): precision
2644  * is_desc(in): desc order for index key_type
2645  */
2646 TP_DOMAIN *
2647 tp_domain_find_charbit (DB_TYPE type, int codeset, int collation_id, unsigned char collation_flag, int precision,
2648  bool is_desc)
2649 {
2650  TP_DOMAIN *dom;
2651 
2652  /* tp_domain_find_with_codeset_precision */
2653  /*
2654  * type : DB_TYPE_NCHAR DB_TYPE_VARNCHAR
2655  * DB_TYPE_CHAR DB_TYPE_VARCHAR
2656  * DB_TYPE_BIT DB_TYPE_VARBIT
2657  */
2658  assert (type == DB_TYPE_CHAR || type == DB_TYPE_VARCHAR || type == DB_TYPE_NCHAR || type == DB_TYPE_VARNCHAR
2659  || type == DB_TYPE_BIT || type == DB_TYPE_VARBIT);
2660 
2661  if (type == DB_TYPE_VARCHAR || type == DB_TYPE_VARNCHAR || type == DB_TYPE_VARBIT)
2662  {
2663  /* search the list for a domain that matches */
2664  for (dom = tp_domain_get_list (type, NULL); dom != NULL; dom = dom->next_list)
2665  {
2666  /* Variable character/bit is sorted in descending order of precision. */
2667  if (precision > dom->precision)
2668  {
2669  return NULL; /* not exist */
2670  }
2671 
2672  /* we MUST perform exact matches here */
2673  if (dom->precision == precision && dom->is_desc == is_desc)
2674  {
2675  if (type == DB_TYPE_VARBIT)
2676  {
2677  break; /* found */
2678  }
2679  else if (dom->collation_id == collation_id && dom->collation_flag == collation_flag)
2680  {
2681  /* codeset should be the same if collations are equal */
2682  assert (dom->codeset == codeset);
2683  break;
2684  }
2685  }
2686  }
2687  }
2688  else
2689  {
2690  /* search the list for a domain that matches */
2691  for (dom = tp_domain_get_list (type, NULL); dom != NULL; dom = dom->next_list)
2692  {
2693  /* Fixed character/bit is sorted in ascending order of precision. */
2694  if (precision < dom->precision)
2695  {
2696  return NULL; /* not exist */
2697  }
2698 
2699  /* we MUST perform exact matches here */
2700  if (dom->precision == precision && dom->is_desc == is_desc)
2701  {
2702  if (type == DB_TYPE_BIT)
2703  {
2704  break; /* found */
2705  }
2706  else if (dom->collation_id == collation_id && dom->collation_flag == collation_flag)
2707  {
2708  /* codeset should be the same if collations are equal */
2709  assert (dom->codeset == codeset);
2710  break;
2711  }
2712  }
2713  }
2714  }
2715 
2716  return dom;
2717 }
2718 
2719 /*
2720  * tp_domain_find_object - find domain for given class OID and class
2721  * return: domain that matches
2722  * type(in): DB_TYPE
2723  * class_oid(in): class oid
2724  * class_mop(in): class structure
2725  * is_desc(in): desc order for index key_type
2726  */
2727 TP_DOMAIN *
2728 tp_domain_find_object (DB_TYPE type, OID * class_oid, struct db_object * class_mop, bool is_desc)
2729 {
2730  TP_DOMAIN *dom;
2731 
2732  /* tp_domain_find_with_classinfo */
2733 
2734  /* search the list for a domain that matches */
2735  for (dom = tp_domain_get_list (type, NULL); dom != NULL; dom = dom->next_list)
2736  {
2737  /* we MUST perform exact matches here */
2738 
2739  /* Always prefer comparison of MOPs */
2740  if (dom->class_mop != NULL && class_mop != NULL)
2741  {
2742  if (dom->class_mop == class_mop && dom->is_desc == is_desc)
2743  {
2744  break; /* found */
2745  }
2746  }
2747  else if (dom->class_mop == NULL && class_mop == NULL)
2748  {
2749  if (OID_EQ (&dom->class_oid, class_oid) && dom->is_desc == is_desc)
2750  {
2751  break; /* found */
2752  }
2753  }
2754  else
2755  {
2756 #if defined (SERVER_MODE)
2757  assert_release (false);
2758 #else /* defined (SERVER_MODE) */
2759  /*
2760  * We have a mixture of OID & MOPS, it probably isn't necessary to be
2761  * this general but try to avoid assuming the class OIDs have been set
2762  * when there is a MOP present.
2763  */
2764  if (dom->class_mop == NULL)
2765  {
2766  if (OID_EQ (&dom->class_oid, WS_OID (class_mop)) && dom->is_desc == is_desc)
2767  {
2768  break; /* found */
2769  }
2770  }
2771  else
2772  {
2773  if (OID_EQ (WS_OID (dom->class_mop), class_oid) && dom->is_desc == is_desc)
2774  {
2775  break; /* found */
2776  }
2777  }
2778 #endif /* defined (SERVER_MODE) */
2779  }
2780  }
2781 
2782  return dom;
2783 }
2784 
2785 /*
2786  * tp_domain_find_set - find domain that matches for given set domain
2787  * return: domain that matches
2788  * type(in): DB_TYPE
2789  * setdomain(in): set domain
2790  * is_desc(in): desc order for index key_type
2791  */
2792 TP_DOMAIN *
2793 tp_domain_find_set (DB_TYPE type, TP_DOMAIN * setdomain, bool is_desc)
2794 {
2795  TP_DOMAIN *dom;
2796  int dsize;
2797  int src_dsize;
2798 
2799  src_dsize = tp_domain_size (setdomain);
2800 
2801  /* search the list for a domain that matches */
2802  for (dom = tp_domain_get_list (type, setdomain); dom != NULL; dom = dom->next_list)
2803  {
2804  /* we MUST perform exact matches here */
2805  if (dom->setdomain == setdomain)
2806  {
2807  break;
2808  }
2809 
2810  if (dom->is_desc == is_desc)
2811  {
2812  /* don't bother comparing the lists unless the sizes are the same */
2813  dsize = tp_setdomain_size (dom);
2814  if (dsize == src_dsize)
2815  {
2816  /* handle the simple single domain case quickly */
2817  if (dsize == 1)
2818  {
2819  if (tp_domain_match (dom->setdomain, setdomain, TP_EXACT_MATCH))
2820  {
2821  break;
2822  }
2823  }
2824  else
2825  {
2826  TP_DOMAIN *d1, *d2;
2827  int match, i;
2828 
2829  if (type == DB_TYPE_SEQUENCE || type == DB_TYPE_MIDXKEY)
2830  {
2831  if (dsize == src_dsize)
2832  {
2833  match = 1;
2834  d1 = dom->setdomain;
2835  d2 = setdomain;
2836 
2837  for (i = 0; i < dsize; i++)
2838  {
2839  match = tp_domain_match (d1, d2, TP_EXACT_MATCH);
2840  if (match == 0)
2841  {
2842  break;
2843  }
2844  d1 = d1->next;
2845  d2 = d2->next;
2846  }
2847  if (match == 1)
2848  {
2849  break;
2850  }
2851  }
2852  }
2853  else
2854  {
2855  /* clear the visited flag in the second subdomain list */
2856  for (d2 = setdomain; d2 != NULL; d2 = d2->next)
2857  {
2858  d2->is_visited = 0;
2859  }
2860 
2861  match = 1;
2862  for (d1 = dom->setdomain; d1 != NULL && match; d1 = d1->next)
2863  {
2864  for (d2 = setdomain; d2 != NULL; d2 = d2->next)
2865  {
2866  if (!d2->is_visited && tp_domain_match (d1, d2, TP_EXACT_MATCH))
2867  {
2868  break;
2869  }
2870  }
2871  /* did we find the domain in the other list ? */
2872  if (d2 != NULL)
2873  {
2874  d2->is_visited = 1;
2875  }
2876  else
2877  {
2878  match = 0;
2879  }
2880  }
2881 
2882  if (match == 1)
2883  {
2884  break;
2885  }
2886  }
2887  }
2888  }
2889  }
2890  }
2891 
2892  return dom;
2893 }
2894 
2895 /*
2896  * tp_domain_find_enumeration () - Find a chached domain with this enumeration
2897  * enumeration(in): enumeration to look for
2898  * is_desc(in): true if desc, false if asc (for only index key)
2899  */
2900 TP_DOMAIN *
2901 tp_domain_find_enumeration (const DB_ENUMERATION * enumeration, bool is_desc)
2902 {
2903  TP_DOMAIN *dom = NULL;
2904 
2905  /* search the list for a domain that matches */
2906  for (dom = tp_domain_get_list (DB_TYPE_ENUMERATION, NULL); dom != NULL; dom = dom->next_list)
2907  {
2908  if (dom->is_desc == is_desc && tp_enumeration_match (&DOM_GET_ENUMERATION (dom), enumeration))
2909  {
2910  return dom;
2911  }
2912  }
2913 
2914  return NULL;
2915 }
2916 
2917 /*
2918  * tp_domain_cache - caches a transient domain
2919  * return: cached domain
2920  * transient(in/out): transient domain
2921  * Note:
2922  * If the domain has already been cached, it is located and returned.
2923  * Otherwise, a new domain is cached and returned.
2924  * In either case, the transient domain may be freed so you should never
2925  * depend on it being valid after this function returns.
2926  *
2927  * Note that if a new domain is added to the list, it is always appended
2928  * to the end. It is vital that the deafult "built-in" domain be
2929  * at the head of the domain lists in tp_Domains.
2930  */
2931 TP_DOMAIN *
2933 {
2934  TP_DOMAIN *domain, **dlist;
2935  TP_DOMAIN *ins_pos = NULL;
2936 #if defined (SERVER_MODE)
2937  int rv;
2938 #endif /* SERVER_MODE */
2939 
2940  /* guard against a bad transient domain */
2941  if (transient == NULL || transient->type == NULL)
2942  {
2943  return NULL;
2944  }
2945 
2946  /* return this domain if its already cached */
2947  if (transient->is_cached)
2948  {
2949  return transient;
2950  }
2951 
2952 #if !defined (SERVER_MODE)
2953  /* see comments for tp_swizzle_oid */
2954  tp_swizzle_oid (transient);
2955 #endif /* !SERVER_MODE */
2956 
2957  /*
2958  * first search stage: NO LOCK
2959  */
2960  /* locate the root of the cache list for domains of this type */
2961  dlist = tp_domain_get_list_ptr (TP_DOMAIN_TYPE (transient), transient->setdomain);
2962 
2963  /* search the list for a domain that matches */
2964  if (*dlist != NULL)
2965  {
2966  ins_pos = NULL;
2967  domain = tp_is_domain_cached (*dlist, transient, TP_EXACT_MATCH, &ins_pos);
2968  if (domain != NULL)
2969  {
2970  /*
2971  * We found one in the cache, free the supplied domain and return
2972  * the cached one
2973  */
2974  tp_domain_free (transient);
2975  return domain;
2976  }
2977  }
2978 
2979  /*
2980  * second search stage: LOCK
2981  */
2982 #if defined (SERVER_MODE)
2983  rv = pthread_mutex_lock (&tp_domain_cache_lock); /* LOCK */
2984 
2985  /* locate the root of the cache list for domains of this type */
2986  dlist = tp_domain_get_list_ptr (TP_DOMAIN_TYPE (transient), transient->setdomain);
2987 
2988  /* search the list for a domain that matches */
2989  if (*dlist != NULL)
2990  {
2991  ins_pos = NULL;
2992  domain = tp_is_domain_cached (*dlist, transient, TP_EXACT_MATCH, &ins_pos);
2993  if (domain != NULL)
2994  {
2995  /*
2996  * We found one in the cache, free the supplied domain and return
2997  * the cached one
2998  */
2999  tp_domain_free (transient);
3000  pthread_mutex_unlock (&tp_domain_cache_lock);
3001  return domain;
3002  }
3003  }
3004 #endif /* SERVER_MODE */
3005 
3006  /*
3007  * We couldn't find one, install the transient domain that was passed in.
3008  * Since by far the most common domain match is going to be the built-in
3009  * domain at the head of the list, append new domains to the end of the
3010  * list as they are encountered.
3011  */
3012  transient->is_cached = 1;
3013 
3014  if (*dlist)
3015  {
3016  if (ins_pos)
3017  {
3018  TP_DOMAIN *tmp;
3019 
3020  tmp = ins_pos->next_list;
3021  ins_pos->next_list = transient;
3022  transient->next_list = tmp;
3023  }
3024  }
3025  else
3026  {
3027  *dlist = transient;
3028  }
3029 
3030  domain = transient;
3031 
3032 #if defined (SERVER_MODE)
3033  pthread_mutex_unlock (&tp_domain_cache_lock);
3034 #endif /* SERVER_MODE */
3035 
3036  return domain;
3037 }
3038 
3039 /*
3040  * tp_domain_resolve - Find a domain object that matches the type, class,
3041  * precision, scale and setdomain.
3042  * return: domain found
3043  * domain_type(in): The basic type of the domain
3044  * class_obj(in): The class of the domain (for DB_TYPE_OBJECT)
3045  * precision(in): The precision of the domain
3046  * scale(in): The class of the domain
3047  * setdomain(in): The setdomain of the domain
3048  * collation(in): The collation of domain
3049  * Note:
3050  * Current implementation just creates a new one then returns it.
3051  */
3052 TP_DOMAIN *
3053 tp_domain_resolve (DB_TYPE domain_type, DB_OBJECT * class_obj, int precision, int scale, TP_DOMAIN * setdomain,
3054  int collation)
3055 {
3056  TP_DOMAIN *d;
3057 
3058  d = tp_domain_new (domain_type);
3059  if (d != NULL)
3060  {
3061  d->precision = precision;
3062  d->scale = scale;
3063  d->class_mop = class_obj;
3064  d->setdomain = setdomain;
3065  if (TP_TYPE_HAS_COLLATION (domain_type))
3066  {
3067  LANG_COLLATION *lc;
3068  d->collation_id = collation;
3069 
3070  lc = lang_get_collation (collation);
3071  d->codeset = lc->codeset;
3072  }
3073 
3074  d = tp_domain_cache (d);
3075  }
3076 
3077  return d;
3078 }
3079 
3080 /*
3081  * tp_domain_resolve_default - returns the built-in "default" domain for a
3082  * given primitive type
3083  * return: cached domain
3084  * type(in): type id
3085  * Note:
3086  * This is used only in special cases where we need to get quickly to
3087  * a built-in domain without worrying about domain parameters.
3088  * Note that this relies on the fact that the built-in domain is at
3089  * the head of our domain lists.
3090  */
3091 TP_DOMAIN *
3093 {
3094  if (type >= sizeof (tp_Domains) / sizeof (tp_Domains[0]))
3095  {
3096  assert_release (false);
3097  return NULL;
3098  }
3099 
3100  return tp_Domains[type];
3101 }
3102 
3103 /*
3104  * tp_domain_resolve_default_w_coll -
3105  *
3106  * return: cached domain
3107  * type(in): type id
3108  * coll_id(in): collation
3109  * coll_flag(in): collation flag
3110  * Note:
3111  * It returns a special domain having the desired collation and collation
3112  * mode flag. Use this in context of type inference for argument coercion
3113  */
3114 TP_DOMAIN *
3116 {
3117  TP_DOMAIN *default_dom;
3118  TP_DOMAIN *resolved_dom;
3119 
3120  default_dom = tp_domain_resolve_default (type);
3121 
3122  if (TP_TYPE_HAS_COLLATION (type) && coll_flag != TP_DOMAIN_COLL_NORMAL)
3123  {
3124  resolved_dom = tp_domain_copy (default_dom, false);
3125 
3126  if (coll_flag == TP_DOMAIN_COLL_ENFORCE)
3127  {
3128  LANG_COLLATION *lc = lang_get_collation (coll_id);
3129 
3130  resolved_dom->collation_id = coll_id;
3131  resolved_dom->codeset = lc->codeset;
3132  }
3133  else
3134  {
3135  assert (coll_flag == TP_DOMAIN_COLL_LEAVE);
3136  }
3137 
3138  resolved_dom->collation_flag = coll_flag;
3139 
3140  resolved_dom = tp_domain_cache (resolved_dom);
3141  }
3142  else
3143  {
3144  resolved_dom = default_dom;
3145  }
3146 
3147  return resolved_dom;
3148 }
3149 
3150 
3151 /*
3152  * tp_domain_resolve_value - Find a domain object that describes the type info
3153  * in the DB_VALUE.
3154  * return: domain found
3155  * val(in): A DB_VALUE for which we need to obtain a domain
3156  * dbuf(out): if not NULL, founded domain initialized on dbuf
3157  */
3158 TP_DOMAIN *
3160 {
3161  TP_DOMAIN *domain;
3162  DB_TYPE value_type;
3163 
3164  domain = NULL;
3165  value_type = DB_VALUE_DOMAIN_TYPE (val);
3166 
3167  if (TP_IS_SET_TYPE (value_type))
3168  {
3169  DB_SET *set;
3170  /*
3171  * For sets, just return the domain attached to the set since it
3172  * will already have been cached.
3173  */
3174  set = db_get_set (val);
3175  if (set != NULL)
3176  {
3177  domain = set_get_domain (set);
3178  /* handle case of incomplete set domain: build full domain */
3179  if (domain->setdomain == NULL || tp_domain_check (domain, val, TP_EXACT_MATCH) != DOMAIN_COMPATIBLE)
3180  {
3181  if (domain->is_cached)
3182  {
3183  domain = tp_domain_new (value_type);
3184  }
3185 
3186  if (domain != NULL)
3187  {
3188  int err_status;
3189 
3190  err_status = setobj_build_domain_from_col (set->set, &(domain->setdomain));
3191  if (err_status != NO_ERROR && !domain->is_cached)
3192  {
3193  tp_domain_free (domain);
3194  domain = NULL;
3195  }
3196  else
3197  {
3198  /* cache this new domain */
3199  domain = tp_domain_cache (domain);
3200  }
3201  }
3202  }
3203  }
3204  else
3205  {
3206  /* we need to synthesize a wildcard set domain for this value */
3207  domain = tp_domain_resolve_default (value_type);
3208  }
3209  }
3210  else if (value_type == DB_TYPE_MIDXKEY)
3211  {
3212  DB_MIDXKEY *midxkey;
3213 
3214  /* For midxkey type, return the domain attached to the value */
3215  midxkey = db_get_midxkey (val);
3216  if (midxkey != NULL)
3217  {
3218  domain = midxkey->domain;
3219  }
3220  else
3221  {
3222  assert (DB_VALUE_TYPE (val) == DB_TYPE_NULL);
3223  domain = tp_domain_resolve_default (value_type);
3224  }
3225  }
3226  else
3227  {
3228  switch (value_type)
3229  {
3230  case DB_TYPE_NULL:
3231  case DB_TYPE_INTEGER:
3232  case DB_TYPE_BIGINT:
3233  case DB_TYPE_FLOAT:
3234  case DB_TYPE_DOUBLE:
3235  case DB_TYPE_BLOB:
3236  case DB_TYPE_CLOB:
3237  case DB_TYPE_TIME:
3238  case DB_TYPE_TIMESTAMP:
3239  case DB_TYPE_TIMESTAMPTZ:
3240  case DB_TYPE_TIMESTAMPLTZ:
3241  case DB_TYPE_DATE:
3242  case DB_TYPE_DATETIME:
3243  case DB_TYPE_DATETIMETZ:
3244  case DB_TYPE_DATETIMELTZ:
3245  case DB_TYPE_MONETARY:
3246  case DB_TYPE_SHORT:
3247  /* domains without parameters, return the built-in domain */
3248  domain = tp_domain_resolve_default (value_type);
3249  break;
3250 
3251  case DB_TYPE_OBJECT:
3252  {
3253 #if !defined (SERVER_MODE)
3254  DB_OBJECT *mop;
3255 
3256  domain = &tp_Object_domain;
3257  mop = db_get_object (val);
3258  if ((mop == NULL) || (WS_IS_DELETED (mop)))
3259  {
3260  /* just let the oid thing stand?, this is a NULL anyway */
3261  }
3262  else
3263  {
3264  /* this is a virtual mop */
3265  if (WS_ISVID (mop))
3266  {
3267  domain = &tp_Vobj_domain;
3268  }
3269  }
3270 #else
3271  /* We don't have mops on server */
3272  assert (false);
3273 #endif
3274  }
3275  break;
3276 
3277  case DB_TYPE_OID:
3278  domain = &tp_Object_domain;
3279  break;
3280 
3281  case DB_TYPE_CHAR:
3282  case DB_TYPE_VARCHAR: /* new name for DB_TYPE_STRING */
3283  case DB_TYPE_BIT:
3284  case DB_TYPE_VARBIT:
3285  case DB_TYPE_NCHAR:
3286  case DB_TYPE_VARNCHAR:
3287  /* must find one with a matching precision */
3288  if (dbuf == NULL)
3289  {
3290  domain = tp_domain_new (value_type);
3291  if (domain == NULL)
3292  {
3293  return NULL;
3294  }
3295  }
3296  else
3297  {
3298  domain = dbuf;
3299  tp_domain_init (domain, value_type);
3300  }
3301  domain->codeset = db_get_string_codeset (val);
3302  domain->collation_id = db_get_string_collation (val);
3303  domain->precision = db_value_precision (val);
3304 
3305  /*
3306  * Convert references to the "floating" precisions to actual
3307  * precisions. This may not be necessary or desirable?
3308  * Zero seems to pop up occasionally in DB_VALUE precisions, until
3309  * this is fixed, treat it as the floater for the variable width
3310  * types.
3311  */
3312  if (TP_DOMAIN_TYPE (domain) == DB_TYPE_VARCHAR)
3313  {
3314  if (domain->precision == 0 || domain->precision == TP_FLOATING_PRECISION_VALUE
3315  || domain->precision > DB_MAX_VARCHAR_PRECISION)
3316  {
3318  }
3319  }
3320  else if (TP_DOMAIN_TYPE (domain) == DB_TYPE_VARBIT)
3321  {
3322  if (domain->precision == 0 || domain->precision == TP_FLOATING_PRECISION_VALUE
3323  || domain->precision > DB_MAX_VARBIT_PRECISION)
3324  {
3326  }
3327  }
3328  else if (value_type == DB_TYPE_VARNCHAR)
3329  {
3330  if (domain->precision == 0 || domain->precision == TP_FLOATING_PRECISION_VALUE
3331  || domain->precision >= DB_MAX_VARNCHAR_PRECISION)
3332  {
3334  }
3335  }
3336 
3337  if (dbuf == NULL)
3338  {
3339  domain = tp_domain_cache (domain);
3340  }
3341  break;
3342  case DB_TYPE_ENUMERATION:
3343  /*
3344  * We have no choice but to return the default enumeration domain
3345  * because we cannot construct the domain from a DB_VALUE
3346  */
3347  domain = tp_domain_resolve_default (value_type);
3348  break;
3349  case DB_TYPE_NUMERIC:
3350  /* must find one with a matching precision and scale */
3351  if (dbuf == NULL)
3352  {
3353  domain = tp_domain_new (value_type);
3354  if (domain == NULL)
3355  {
3356  return NULL;
3357  }
3358  }
3359  else
3360  {
3361  domain = dbuf;
3362  tp_domain_init (dbuf, value_type);
3363  }
3364  domain->precision = db_value_precision (val);
3365  domain->scale = db_value_scale (val);
3366 
3367  /*
3368  * Hack, precision seems to be commonly -1 DB_VALUES, turn this into
3369  * the default "maximum" precision.
3370  * This may not be necessary any more.
3371  */
3372  if (domain->precision == -1)
3373  {
3375  }
3376 
3377  if (domain->scale == -1)
3378  {
3379  domain->scale = DB_DEFAULT_NUMERIC_SCALE;
3380  }
3381 
3382  if (dbuf == NULL)
3383  {
3384  domain = tp_domain_cache (domain);
3385  }
3386  break;
3387 
3388  case DB_TYPE_POINTER:
3389  case DB_TYPE_ERROR:
3390  case DB_TYPE_VOBJ:
3391  case DB_TYPE_SUB:
3392  case DB_TYPE_VARIABLE:
3393  case DB_TYPE_DB_VALUE:
3394  /*
3395  * These are internal domains, they shouldn't be seen, in case they
3396  * are, match to a built-in
3397  */
3398  domain = tp_domain_resolve_default (value_type);
3399  break;
3400 
3401  case DB_TYPE_JSON:
3402  if (dbuf == NULL)
3403  {
3404  domain = tp_domain_new (value_type);
3405  if (domain == NULL)
3406  {
3407  return NULL;
3408  }
3409  }
3410  else
3411  {
3412  domain = dbuf;
3413  tp_domain_init (domain, value_type);
3414  }
3415 
3416  if (db_get_json_schema (val) != NULL)
3417  {
3418  int error_code;
3419 
3420  error_code = db_json_load_validator (db_get_json_schema (val), domain->json_validator);
3421  if (error_code != NO_ERROR)
3422  {
3423  assert (false);
3424  tp_domain_free (domain);
3425  return NULL;
3426  }
3427  }
3428  else
3429  {
3430  domain->json_validator = NULL;
3431  }
3432 
3433  if (dbuf == NULL)
3434  {
3435  domain = tp_domain_cache (domain);
3436  }
3437  break;
3438 
3439  /*
3440  * things handled in logic outside the switch, shuts up compiler
3441  * warnings
3442  */
3443  case DB_TYPE_SET:
3444  case DB_TYPE_MULTISET:
3445  case DB_TYPE_SEQUENCE:
3446  case DB_TYPE_MIDXKEY:
3447  break;
3448  case DB_TYPE_RESULTSET:
3449  case DB_TYPE_TABLE:
3450  break;
3451  case DB_TYPE_ELO:
3452  assert (false);
3453  break;
3454  }
3455  }
3456 
3457  return domain;
3458 }
3459 
3460 #if defined(ENABLE_UNUSED_FUNCTION)
3461 /*
3462  * tp_create_domain_resolve_value - adjust domain of a DB_VALUE with respect to
3463  * the primitive value of the value
3464  * return: domain
3465  * val(in): DB_VALUE
3466  * domain(in): domain
3467  * Note: val->domain changes
3468  */
3469 TP_DOMAIN *
3470 tp_create_domain_resolve_value (DB_VALUE * val, TP_DOMAIN * domain)
3471 {
3472  DB_TYPE value_type;
3473 
3474  value_type = DB_VALUE_DOMAIN_TYPE (val);
3475 
3476  switch (value_type)
3477  {
3478  case DB_TYPE_INTEGER:
3479  case DB_TYPE_BIGINT:
3480  case DB_TYPE_FLOAT:
3481  case DB_TYPE_DOUBLE:
3482  case DB_TYPE_TIME:
3483  case DB_TYPE_TIMESTAMP:
3484  case DB_TYPE_DATE:
3485  case DB_TYPE_DATETIME:
3486  case DB_TYPE_MONETARY:
3487  case DB_TYPE_SHORT:
3488  case DB_TYPE_OBJECT:
3489  case DB_TYPE_OID:
3490  break;
3491 
3492  case DB_TYPE_CHAR:
3493  case DB_TYPE_BIT:
3494  case DB_TYPE_NCHAR:
3495  case DB_TYPE_VARCHAR: /* new name for DB_TYPE_STRING */
3496  case DB_TYPE_VARBIT:
3497  case DB_TYPE_VARNCHAR:
3499  {
3500  /* Check for floating precision. */
3501  val->domain.char_info.length = domain->precision;
3502  }
3503  else
3504  {
3505  if (domain->precision == TP_FLOATING_PRECISION_VALUE)
3506  {
3507  ; /* nop */
3508  }
3509  else
3510  {
3511  if (db_value_precision (val) > domain->precision)
3512  {
3513  val->domain.char_info.length = domain->precision;
3514  }
3515  }
3516  }
3517  break;
3518 
3519  case DB_TYPE_NUMERIC:
3520  break;
3521 
3522  case DB_TYPE_NULL: /* for midxkey elements */
3523  break;
3524 
3525  default:
3526  return NULL;
3527  }
3528 
3529  /* if(domain) return tp_domain_cache(domain); */
3530  return domain;
3531 }
3532 #endif /* ENABLE_UNUSED_FUNCTION */
3533 
3534 /*
3535  * tp_domain_add - Adds a domain structure to a domain list if it doesn't
3536  * already exist.
3537  * return: error code
3538  * dlist(in/out): domain list
3539  * domain(in): domain structure
3540  * Note:
3541  * This routine should only be used to construct a transient domain.
3542  * Note that there are no error messages if a duplicate isn't added.
3543  */
3544 int
3545 tp_domain_add (TP_DOMAIN ** dlist, TP_DOMAIN * domain)
3546 {
3547  int error = NO_ERROR;
3548  TP_DOMAIN *d, *found, *last;
3549  DB_TYPE type_id;
3550 
3551  last = NULL;
3552  type_id = TP_DOMAIN_TYPE (domain);
3553 
3554  for (d = *dlist, found = NULL; d != NULL && found == NULL; d = d->next)
3555  {
3556 #if 1
3557  /* >>>>> NEED MORE CONSIDERATION <<<<< do not check duplication must be rollback with tp_domain_match() */
3558 #else /* 0 */
3559  if (TP_DOMAIN_TYPE (d) == type_id)
3560  {
3561  switch (type_id)
3562  {
3563  case DB_TYPE_INTEGER:
3564  case DB_TYPE_BIGINT:
3565  case DB_TYPE_FLOAT:
3566  case DB_TYPE_DOUBLE:
3567  case DB_TYPE_BLOB:
3568  case DB_TYPE_CLOB:
3569  case DB_TYPE_TIME:
3570  case DB_TYPE_TIMESTAMP:
3571  case DB_TYPE_TIMESTAMPTZ:
3572  case DB_TYPE_TIMESTAMPLTZ:
3573  case DB_TYPE_DATE:
3574  case DB_TYPE_DATETIME:
3575  case DB_TYPE_DATETIMETZ:
3576  case DB_TYPE_DATETIMELTZ:
3577  case DB_TYPE_MONETARY:
3578  case DB_TYPE_SUB:
3579  case DB_TYPE_POINTER:
3580  case DB_TYPE_ERROR:
3581  case DB_TYPE_SHORT:
3582  case DB_TYPE_VOBJ:
3583  case DB_TYPE_OID:
3584  case DB_TYPE_NULL:
3585  case DB_TYPE_VARIABLE:
3586  case DB_TYPE_SET:
3587  case DB_TYPE_MULTISET:
3588  case DB_TYPE_SEQUENCE:
3589  case DB_TYPE_DB_VALUE:
3590  case DB_TYPE_VARCHAR:
3591  case DB_TYPE_VARNCHAR:
3592  case DB_TYPE_VARBIT:
3593  found = d;
3594  break;
3595 
3596  case DB_TYPE_NUMERIC:
3597  if ((d->precision == domain->precision) && (d->scale == domain->scale))
3598  {
3599  found = d;
3600  }
3601  break;
3602 
3603  case DB_TYPE_CHAR:
3604  case DB_TYPE_NCHAR:
3605  case DB_TYPE_BIT:
3606  /*
3607  * PR) 1.deficient character related with CHAR & VARCHAR in set.
3608  * ==> distinguishing VARCHAR from CHAR.
3609  * 2. core dumped & deficient character related with
3610  * CONST CHAR & CHAR in set.
3611  * ==> In case of CHAR,NCHAR,BIT, cosidering precision.
3612  */
3613  if (d->precision == domain->precision)
3614  {
3615  found = d;
3616  }
3617  break;
3618 
3619  case DB_TYPE_OBJECT:
3620  if (d->class_mop == domain->class_mop)
3621  {
3622  found = d;
3623  }
3624  break;
3625 
3626  default:
3627  break;
3628  }
3629  }
3630 #endif /* 1 */
3631 
3632  last = d;
3633  }
3634 
3635  if (found == NULL)
3636  {
3637  if (last == NULL)
3638  {
3639  *dlist = domain;
3640  }
3641  else
3642  {
3643  last->next = domain;
3644  }
3645  }
3646  else
3647  {
3648  /* the domain already existed, free the supplied domain */
3649  tp_domain_free (domain);
3650  }
3651 
3652  return error;
3653 }
3654 
3655 #if !defined (SERVER_MODE)
3656 /*
3657  * tp_domain_attach - concatenate two domains
3658  * return: concatenated domain
3659  * dlist(out): domain 1
3660  * domain(in): domain 2
3661  */
3662 int
3664 {
3665  int error = NO_ERROR;
3666  TP_DOMAIN *d;
3667 
3668  d = *dlist;
3669 
3670  if (*dlist == NULL)
3671  {
3672  *dlist = domain;
3673  }
3674  else
3675  {
3676  while (d->next)
3677  d = d->next;
3678 
3679  d->next = domain;
3680  }
3681 
3682  return error;
3683 }
3684 
3685 /*
3686  * tp_domain_drop - Removes a domain from a list if it was found.
3687  * return: non-zero if domain was dropped
3688  * dlist(in/out): domain list
3689  * domain(in/out): domain class
3690  * Note:
3691  * This routine should only be used to modify a transient domain.
3692  */
3693 int
3694 tp_domain_drop (TP_DOMAIN ** dlist, TP_DOMAIN * domain)
3695 {
3696  TP_DOMAIN *d, *found, *prev;
3697  int dropped = 0;
3698  DB_TYPE type_id;
3699 
3700  type_id = TP_DOMAIN_TYPE (domain);
3701  for (d = *dlist, prev = NULL, found = NULL; d != NULL && found == NULL; d = d->next)
3702  {
3703  if (TP_DOMAIN_TYPE (d) == type_id)
3704  {
3705  switch (type_id)
3706  {
3707  case DB_TYPE_INTEGER:
3708  case DB_TYPE_BIGINT:
3709  case DB_TYPE_FLOAT:
3710  case DB_TYPE_DOUBLE:
3711  case DB_TYPE_BLOB:
3712  case DB_TYPE_CLOB:
3713  case DB_TYPE_TIME:
3714  case DB_TYPE_TIMESTAMP:
3715  case DB_TYPE_TIMESTAMPLTZ:
3716  case DB_TYPE_TIMESTAMPTZ:
3717  case DB_TYPE_DATE:
3718  case DB_TYPE_DATETIME:
3719  case DB_TYPE_DATETIMELTZ:
3720  case DB_TYPE_DATETIMETZ:
3721  case DB_TYPE_MONETARY:
3722  case DB_TYPE_SUB:
3723  case DB_TYPE_POINTER:
3724  case DB_TYPE_ERROR:
3725  case DB_TYPE_SHORT:
3726  case DB_TYPE_VOBJ:
3727  case DB_TYPE_OID:
3728  case DB_TYPE_NULL:
3729  case DB_TYPE_VARIABLE:
3730  case DB_TYPE_SET:
3731  case DB_TYPE_MULTISET:
3732  case DB_TYPE_SEQUENCE:
3733  case DB_TYPE_DB_VALUE:
3734  case DB_TYPE_VARCHAR:
3735  case DB_TYPE_VARNCHAR:
3736  case DB_TYPE_VARBIT:
3737  found = d;
3738  break;
3739 
3740  case DB_TYPE_NUMERIC:
3741  if (d->precision == domain->precision && d->scale == domain->scale)
3742  {
3743  found = d;
3744  }
3745  break;
3746 
3747  case DB_TYPE_CHAR:
3748  case DB_TYPE_NCHAR:
3749  case DB_TYPE_BIT:
3750  /* 1.deficient character related with CHAR & VARCHAR in set. ==> distinguishing VARCHAR from CHAR. 2.
3751  * core dumped & deficient character related with CONST CHAR & CHAR in set. ==> In case of
3752  * CHAR,NCHAR,BIT, cosidering precision. */
3753  if (d->precision == domain->precision)
3754  {
3755  found = d;
3756  }
3757  break;
3758 
3759  case DB_TYPE_OBJECT:
3760  if (d->class_mop == domain->class_mop)
3761  {
3762  found = d;
3763  }
3764  break;
3765 
3766  default:
3767  break;
3768  }
3769  }
3770 
3771  if (found == NULL)
3772  {
3773  prev = d;
3774  }
3775  }
3776 
3777  if (found != NULL)
3778  {
3779  if (prev == NULL)
3780  {
3781  *dlist = found->next;
3782  }
3783  else
3784  {
3785  prev->next = found->next;
3786  }
3787 
3788  found->next = NULL;
3789  tp_domain_free (found);
3790 
3791  dropped = 1;
3792  }
3793 
3794  return dropped;
3795 }
3796 #endif /* !SERVER_MODE */
3797 
3798 
3799 /*
3800  * tp_domain_check_class - Work function for tp_domain_filter_list and
3801  * sm_filter_domain.
3802  * return: error code
3803  * domain(in): domain to examine
3804  * change(out): non-zero if the domain was modified
3805  * Note:
3806  * Check the class in a domain and if it was deleted, downgrade the
3807  * domain to "object".
3808  */
3809 static int
3810 tp_domain_check_class (TP_DOMAIN * domain, int *change)
3811 {
3812  int error = NO_ERROR;
3813 #if !defined (SERVER_MODE)
3814  int status;
3815 #endif /* !SERVER_MODE */
3816 
3817  if (change != NULL)
3818  {
3819  *change = 0;
3820  }
3821 
3822 #if !defined (SERVER_MODE)
3823  if (!db_on_server)
3824  {
3825  if (domain != NULL && domain->type == tp_Type_object && domain->class_mop != NULL)
3826  {
3827  /* check for deletion of the domain class, assume just one for now */
3829 
3830  if (status == LC_DOESNOT_EXIST)
3831  {
3832  WS_SET_DELETED (domain->class_mop);
3833  domain->class_mop = NULL;
3834  if (change != NULL)
3835  {
3836  *change = 1;
3837  }
3838  }
3839  else if (status == LC_ERROR)
3840  {
3841  ASSERT_ERROR ();
3842  error = er_errid ();
3843  }
3844  }
3845  }
3846 #endif /* !SERVER_MODE */
3847 
3848  return error;
3849 }
3850 
3851 
3852 /*
3853  * tp_domain_filter_list - filter out any domain references to classes that
3854  * have been deleted or are otherwise invalid from domain list
3855  * return: error code
3856  * dlist(in): domain list
3857  * list_changes(out) : non-zero if changes were made
3858  * Note:
3859  * The semantic for deleted classes is that the domain reverts
3860  * to the root "object" domain, thereby allowing all object references.
3861  * This could become more sophisticated but not without a lot of extra
3862  * bookkeeping in the database. If a domain is downgraded to "object",
3863  * be sure to remove it from the list entirely if there is already an
3864  * "object" domain present.
3865  */
3866 int
3867 tp_domain_filter_list (TP_DOMAIN * dlist, int *list_changes)
3868 {
3869  TP_DOMAIN *d, *prev, *next;
3870  int has_object, changes, set_changes, domain_change;
3871  int error;
3872 
3873  has_object = changes = 0;
3874  if (list_changes != NULL)
3875  {
3876  *list_changes = 0;
3877  }
3878 
3879  for (d = dlist, prev = NULL, next = NULL; d != NULL; d = next)
3880  {
3881  next = d->next;
3882  error = tp_domain_check_class (d, &domain_change);
3883  if (error != NO_ERROR)
3884  {
3885  return error;
3886  }
3887 
3888  if (domain_change)
3889  {
3890  /* domain reverted to "object" */
3891  if (!has_object)
3892  {
3893  has_object = 1;
3894  prev = d;
3895  }
3896  else
3897  {
3898  /*
3899  * redundant "object" domain, remove, prev can't be NULL here,
3900  * will always have at least one domain structure at the head of
3901  * the list
3902  */
3903  prev->next = next;
3904  d->next = NULL;
3905  tp_domain_free (d);
3906  changes |= 1;
3907  }
3908  }
3909  else
3910  {
3911  /* domain is still valid, see if its "object" */
3912  if (d->type == tp_Type_object && d->class_mop == NULL)
3913  {
3914  has_object = 1;
3915  }
3916  else if (pr_is_set_type (TP_DOMAIN_TYPE (d)) && d->setdomain != NULL)
3917  {
3918  /* recurse on set domain list */
3919  error = tp_domain_filter_list (d->setdomain, &set_changes);
3920  if (error != NO_ERROR)
3921  {
3922  return error;
3923  }
3924 
3925  changes |= set_changes;
3926  }
3927  prev = d;
3928  }
3929  }
3930 
3931  if (list_changes != NULL)
3932  {
3933  *list_changes = changes;
3934  }
3935 
3936  return NO_ERROR;
3937 }
3938 
3939 /*
3940  * tp_domain_name - generate a printed representation for the given domain.
3941  * return: non-zero if buffer overflow, -1 for error
3942  * domain(in): domain structure
3943  * buffer(out): output buffer
3944  * maxlen(in): maximum length of buffer
3945  */
3946 int
3947 tp_domain_name (const TP_DOMAIN * domain, char *buffer, int maxlen)
3948 {
3949  /*
3950  * need to get more sophisticated here, do full name decomposition and
3951  * check maxlen
3952  */
3953  strncpy (buffer, domain->type->name, maxlen);
3954  buffer[maxlen - 1] = '\0';
3955  return (0);
3956 }
3957 
3958 /*
3959  * tp_value_domain_name - generates printed representation of the domain for a
3960  * given DB_VALUE.
3961  * return: non-zero if buffer overflow, -1 if error
3962  * value(in): value to examine
3963  * buffer(out): output buffer
3964  * maxlen(in): maximum length of buffer
3965  */
3966 int
3967 tp_value_domain_name (const DB_VALUE * value, char *buffer, int maxlen)
3968 {
3969  /* need to get more sophisticated here */
3970 
3971  strncpy (buffer, pr_type_name (DB_VALUE_TYPE (value)), maxlen);
3972  buffer[maxlen - 1] = '\0';
3973  return (0);
3974 }
3975 
3976 /*
3977  * tp_domain_find_compatible - two domains are compatible for the purposes of
3978  * assignment of values.
3979  * return: non-zero if domains are compatible
3980  * src(in): domain we're wanting to assign
3981  * dest(in): domain we're trying to go into
3982  * Note:
3983  * Domains are compatible if they are equal.
3984  * Further, domain 1 is compatible with domain 2 if domain 2 is more
3985  * general.
3986  *
3987  * This will not properly detect of the domains are compatible due
3988  * to a proper subclass superclass relationship between object domains.
3989  * It will only check to see if the class matches exactly.
3990  *
3991  * This is the function used to test to see if a particular set domain
3992  * is "within" another set domain during assignment of set values to
3993  * attributes. src in this case will be the domain of the set we were
3994  * given and dest will be the domain of the attribute.
3995  * All of the sub-domains in src must also be found in dest.
3996  *
3997  * This is somewhat different than tp_domain_match because the comparison
3998  * of set domains is more of an "is it a subset" operation rather than
3999  * an "is it equal to" operation.
4000  */
4001 static const TP_DOMAIN *
4002 tp_domain_find_compatible (const TP_DOMAIN * src, const TP_DOMAIN * dest)
4003 {
4004  const TP_DOMAIN *d, *found;
4005 
4006  found = NULL;
4007 
4008  /*
4009  * If we have a hierarchical domain, perform a lenient "superset" comparison
4010  * rather than an exact match.
4011  */
4013  {
4014  for (d = dest; d != NULL && found == NULL; d = d->next)
4015  {
4016  if (TP_DOMAIN_TYPE (src) == TP_DOMAIN_TYPE (d) && tp_domain_compatible (src->setdomain, dest->setdomain))
4017  {
4018  found = d;
4019  }
4020  }
4021  }
4022  else
4023  {
4024 
4025  for (d = dest; d != NULL && found == NULL; d = d->next)
4026  {
4027  if (tp_domain_match ((TP_DOMAIN *) src, (TP_DOMAIN *) d, TP_EXACT_MATCH))
4028  {
4029  /* exact match flag is on */
4030  found = d;
4031  }
4032  }
4033 
4034  }
4035 
4036  return found;
4037 }
4038 
4039 /*
4040  * tp_domain_compatible - check compatibility of src domain w.r.t dest
4041  * return: 1 if compatible, 0 otherwise
4042  * src(in): src domain
4043  * dest(in): dest domain
4044  */
4045 int
4046 tp_domain_compatible (const TP_DOMAIN * src, const TP_DOMAIN * dest)
4047 {
4048  const TP_DOMAIN *d;
4049  int equal = 0;
4050 
4051  if (src != NULL && dest != NULL)
4052  {
4053  equal = 1;
4054  if (src != dest)
4055  {
4056  /*
4057  * for every domain in src, make sure we have a compatible one in
4058  * dest
4059  */
4060  for (d = src; equal && d != NULL; d = d->next)
4061  {
4062  if (tp_domain_find_compatible (d, dest) == NULL)
4063  {
4064  equal = 0;
4065  }
4066  }
4067  }
4068  }
4069 
4070  return equal;
4071 }
4072 
4073 
4074 /*
4075  * tp_domain_select - select a domain from a list of possible domains that is
4076  * the exact match (or closest, depending on the value of exact_match) to the
4077  * supplied value.
4078  * return: domain
4079  * domain_list(in): list of possible domains
4080  * value(in): value of interest
4081  * allow_coercion(in): non-zero if coercion will be allowed
4082  * exact_match(in): controls tolerance permitted during match
4083  * Note:
4084  * This operation is used for basic domain compatibility checking
4085  * as well as value coercion.
4086  * If the allow_coercion flag is on, the tp_Domain_conversion_matrix
4087  * will be consulted to find an appropriate domain in the case
4088  * where there is no exact match.
4089  * If an appropriate domain could not be found, NULL is returned.
4090  *
4091  * This is known not to work correctly for nested set domains. In order
4092  * for the best domain to be selected, we must recursively check the
4093  * complete set domains here.
4094  *
4095  * The exact_match flag determines if we allow "tolerance" matches when
4096  * checking domains for attributes. See commentary in tp_domain_match
4097  * for more information.
4098  */
4099 TP_DOMAIN *
4100 tp_domain_select (const TP_DOMAIN * domain_list, const DB_VALUE * value, int allow_coercion, TP_MATCH exact_match)
4101 {
4102  TP_DOMAIN *best = NULL, *d = NULL;
4103  TP_DOMAIN **others = NULL;
4104  DB_TYPE vtype;
4105  int i;
4106 
4107  DB_VALUE temp;
4108  db_make_null (&temp);
4109 
4110  best = NULL;
4111 
4112  bool ti = true;
4113  static bool ignore_trailing_space = prm_get_bool_value (PRM_ID_IGNORE_TRAILING_SPACE);
4114 
4115  /*
4116  * NULL values are allowed in any domain, a NULL domain means that any value
4117  * is allowed, return the first thing on the list.
4118  */
4119  if (value == NULL || domain_list == NULL || (vtype = DB_VALUE_TYPE (value)) == DB_TYPE_NULL)
4120  {
4121  return (TP_DOMAIN *) domain_list;
4122  }
4123 
4124 
4125  if (vtype == DB_TYPE_OID)
4126  {
4127  if (db_on_server)
4128  {
4129  /*
4130  * On the server, just make sure that we have any object domain in
4131  * the list.
4132  */
4133  for (d = (TP_DOMAIN *) domain_list; d != NULL && best == NULL; d = d->next)
4134  {
4135  if (TP_DOMAIN_TYPE (d) == DB_TYPE_OBJECT)
4136  {
4137  best = d;
4138  }
4139  }
4140  }
4141 #if !defined (SERVER_MODE)
4142  else
4143  {
4144  /*
4145  * On the client, swizzle to an object and fall in to the next
4146  * clause
4147  */
4148  OID *oid;
4149  DB_OBJECT *mop;
4150 
4151  oid = (OID *) db_get_oid (value);
4152  if (oid)
4153  {
4154  if (OID_ISNULL (oid))
4155  {
4156  /* this is the same as the NULL case above */
4157  return (TP_DOMAIN *) domain_list;
4158  }
4159  else
4160  {
4161  mop = ws_mop (oid, NULL);
4162  db_make_object (&temp, mop);
4163  /*
4164  * we don't have to worry about clearing this since its an
4165  * object
4166  */
4167  value = (const DB_VALUE *) &temp;
4168  vtype = DB_TYPE_OBJECT;
4169  }
4170  }
4171  }
4172 #endif /* !SERVER_MODE */
4173  }
4174 
4175  /*
4176  * Handling of object domains is more complex than just comparing the
4177  * types and parameters. We have to see if the instance's class is
4178  * somewhere in the subclass hierarchy of the domain class.
4179  * This can't be done on the server yet though presumably we could
4180  * implement something like this using OID chasing.
4181  */
4182 
4183  if (vtype == DB_TYPE_OBJECT)
4184  {
4185  if (db_on_server)
4186  {
4187  /*
4188  * we really shouldn't get here but if we do, handle it like the
4189  * OID case above, just return the first object domain that we find.
4190  */
4191  for (d = (TP_DOMAIN *) domain_list; d != NULL && best == NULL; d = d->next)
4192  {
4193  if (TP_DOMAIN_TYPE (d) == DB_TYPE_OBJECT)
4194  {
4195  best = d;
4196  }
4197  }
4198  return best;
4199  }
4200 #if !defined (SERVER_MODE)
4201  else
4202  {
4203  /*
4204  * On the client, check to see if the instance is within the subclass
4205  * hierarchy of the object domains. If there are more than one
4206  * acceptable domains, we just pick the first one.
4207  */
4208  DB_OBJECT *obj = db_get_object (value);
4209 
4210  for (d = (TP_DOMAIN *) domain_list; d != NULL && best == NULL; d = d->next)
4211  {
4212  if (TP_DOMAIN_TYPE (d) == DB_TYPE_OBJECT && sm_check_object_domain (d, obj))
4213  {
4214  best = d;
4215  }
4216  }
4217  }
4218 #endif /* !SERVER_MODE */
4219  }
4220 
4221 #if !defined (SERVER_MODE)
4222  else if (vtype == DB_TYPE_POINTER)
4223  {
4224  /*
4225  * This is necessary in order to correctly choose an object domain from
4226  * the domain list when doing an insert nested inside a heterogeneous
4227  * set, e.g.:
4228  * create class foo (a int);
4229  * create class bar (b set_of(string, integer, foo));
4230  * insert into bar (b) values ({insert into foo values (1)});
4231  */
4232  DB_OTMPL *val_tmpl;
4233 
4234  val_tmpl = (DB_OTMPL *) db_get_pointer (value);
4235  if (val_tmpl)
4236  {
4237  for (d = (TP_DOMAIN *) domain_list; d != NULL && best == NULL; d = d->next)
4238  {
4239  if (TP_DOMAIN_TYPE (d) == DB_TYPE_OBJECT && sm_check_class_domain (d, val_tmpl->classobj))
4240  {
4241  best = d;
4242  }
4243  }
4244  }
4245  }
4246 #endif /* !SERVER_MODE */
4247 
4248  else if (TP_IS_SET_TYPE (vtype))
4249  {
4250  /*
4251  * Now that we cache set domains, there might be a faster way to do
4252  * this !
4253  */
4254  DB_SET *set;
4255 
4256  set = db_get_set (value);
4257  for (d = (TP_DOMAIN *) domain_list; d != NULL && best == NULL; d = d->next)
4258  {
4259  if (TP_DOMAIN_TYPE (d) == vtype)
4260  {
4261  if (set_check_domain (set, d) == DOMAIN_COMPATIBLE)
4262  {
4263  best = d;
4264  }
4265  }
4266  }
4267  }
4268  else if (vtype == DB_TYPE_ENUMERATION)
4269  {
4270  int val_idx, dom_size, val_size;
4271  const char *dom_str = NULL, *val_str = NULL;
4272 
4273  if (db_get_enum_short (value) == 0 && db_get_enum_string (value) != NULL)
4274  {
4275  /* An enumeration should be NULL or should at least have an index */
4276  assert (false);
4278  return NULL;
4279  }
4280 
4281  val_idx = db_get_enum_short (value);
4282 
4283  val_str = db_get_enum_string (value);
4284  val_size = db_get_enum_string_size (value);
4285 
4286  for (d = (TP_DOMAIN *) domain_list; d != NULL && best == NULL; d = d->next)
4287  {
4289  {
4290  continue;
4291  }
4292 
4293  if (val_idx == 0)
4294  {
4295  /* this is an invalid enum value so any domain matches */
4296  best = d;
4297  break;
4298  }
4299  if (DOM_GET_ENUM_ELEMS_COUNT (d) == 0 && best == NULL)
4300  {
4301  /* this is the default enum domain and we haven't found any matching domain yet. This is our best
4302  * candidate so far */
4303  best = d;
4304  continue;
4305  }
4306  if (DOM_GET_ENUM_ELEMS_COUNT (d) < val_idx)
4307  {
4308  continue;
4309  }
4310  if (val_str == NULL)
4311  {
4312  /* The enumeration string value is not specified. This means that the domain we have so far is the best
4313  * match because there is no way of deciding between other domains based only on the short value */
4314  best = d;
4315  break;
4316  }
4317 
4318  if (db_get_enum_collation (value) != d->collation_id)
4319  {
4320  continue;
4321  }
4322 
4323  dom_str = DB_GET_ENUM_ELEM_STRING (&DOM_GET_ENUM_ELEM (d, val_idx));
4324  dom_size = DB_GET_ENUM_ELEM_STRING_SIZE (&DOM_GET_ENUM_ELEM (d, val_idx));
4325 
4326  /* We have already checked that val_str is not null */
4327  if (dom_str == NULL)
4328  {
4329  assert (false);
4331  return NULL;
4332  }
4333 
4334  if (!ignore_trailing_space)
4335  {
4336  ti = (d->type->id == DB_TYPE_CHAR || d->type->id == DB_TYPE_NCHAR);
4337  }
4338  if (QSTR_COMPARE (d->collation_id, (const unsigned char *) dom_str, dom_size,
4339  (const unsigned char *) val_str, val_size, ti) == 0)
4340  {
4341  if (best == NULL)
4342  {
4343  best = d;
4344  }
4345  else if (DOM_GET_ENUM_ELEMS_COUNT (best) < DOM_GET_ENUM_ELEMS_COUNT (d))
4346  {
4347  /* The best match is the domain that has the largest element count. We're not interested in the value
4348  * of the exact_match argument since we cannot find an exact enumeration match based on a DB_VALUE */
4349  best = d;
4350  }
4351  }
4352  }
4353  }
4354  else
4355  {
4356  /*
4357  * synthesize a domain for the value and look for a match.
4358  * Could we be doing this for the set values too ?
4359  * Hack, since this will be used only for comparison purposes,
4360  * don't go through the overhead of caching the domain every time,
4361  * especially for numeric types. This will be a lot simpler if we
4362  * store the domain
4363  * pointer directly in the DB_VALUE.
4364  */
4365  TP_DOMAIN temp_domain, *val_domain;
4366 
4367  val_domain = tp_domain_resolve_value ((DB_VALUE *) value, &temp_domain);
4368 
4369  for (d = (TP_DOMAIN *) domain_list; d != NULL && best == NULL; d = d->next)
4370  {
4371  /* hack, try allowing "tolerance" matches of the domain ! */
4372  if (tp_domain_match (d, val_domain, exact_match))
4373  {
4374  best = d;
4375  }
4376  }
4377  }
4378 
4379  if (best == NULL && allow_coercion)
4380  {
4381  others = tp_Domain_conversion_matrix[vtype];
4382  if (others != NULL)
4383  {
4384  for (i = 0; others[i] != NULL && best == NULL; i++)
4385  {
4386  for (d = (TP_DOMAIN *) domain_list; d != NULL && best == NULL; d = d->next)
4387  {
4388  if (d->type == others[i]->type)
4389  {
4390  best = d;
4391  }
4392  }
4393  }
4394  }
4395  }
4396 
4397  return best;
4398 }
4399 
4400 #if !defined (SERVER_MODE)
4401 /*
4402  * tp_domain_select_type - similar to tp_domain_select except that it does not
4403  * require the existance of an actual DB_VALUE containing a proposed value.
4404  * return: best domain from the list, NULL if none
4405  * domain_list(in): domain lis t
4406  * type(in): basic data type
4407  * class(in): class if type == DB_TYPE_OBJECT
4408  * allow_coercion(in): flag to enable coercions
4409  * Note:
4410  * this cannot be used for checking set domains.
4411  */
4412 TP_DOMAIN *
4413 tp_domain_select_type (const TP_DOMAIN * domain_list, DB_TYPE type, DB_OBJECT * class_mop, int allow_coercion)
4414 {
4415  const TP_DOMAIN *best, *d;
4416  TP_DOMAIN **others;
4417  int i;
4418 
4419  /*
4420  * NULL values are allowed in any domain, a NULL domain means that any value
4421  * is allowed, return the first thing on the list
4422  */
4423  if (type == DB_TYPE_NULL || domain_list == NULL)
4424  {
4425  best = domain_list;
4426  }
4427  else
4428  {
4429  best = NULL;
4430  /*
4431  * loop through the domain elements looking for one the fits,
4432  * rather than make type comparisons for each element in the loop,
4433  * do them out here and duplicate the loop
4434  */
4435 
4436  if (type == DB_TYPE_OBJECT)
4437  {
4438  for (d = domain_list; d != NULL && best == NULL; d = d->next)
4439  {
4440  if (TP_DOMAIN_TYPE (d) == DB_TYPE_OBJECT && sm_check_class_domain ((TP_DOMAIN *) d, class_mop))
4441  {
4442  best = d;
4443  }
4444  }
4445  }
4446  else if (TP_IS_SET_TYPE (type))
4447  {
4448  for (d = domain_list; d != NULL && best == NULL; d = d->next)
4449  {
4450  if (TP_DOMAIN_TYPE (d) == type)
4451  {
4452  /* can't check the actual set domain here, assume its ok */
4453  best = d;
4454  }
4455  }
4456  }
4457  else
4458  {
4459  for (d = domain_list; d != NULL && best == NULL; d = d->next)
4460  {
4461  if (TP_DOMAIN_TYPE (d) == type || TP_DOMAIN_TYPE (d) == DB_TYPE_VARIABLE)
4462  {
4463  best = d;
4464  }
4465  }
4466  }
4467 
4468  if (best == NULL && allow_coercion)
4469  {
4470  others = tp_Domain_conversion_matrix[type];
4471  if (others != NULL)
4472  {
4473  /*
4474  * loop through the allowable conversions until we find
4475  * one that appears in the supplied domain list, the
4476  * array is ordered in terms of priority,
4477  * THIS WILL NOT WORK CORRECTLY FOR NESTED SETS
4478  */
4479  for (i = 0; others[i] != NULL && best == NULL; i++)
4480  {
4481  for (d = domain_list; d != NULL && best == NULL; d = d->next)
4482  {
4483  if (d->type == others[i]->type)
4484  {
4485  best = d;
4486  }
4487  }
4488  }
4489  }
4490  }
4491  }
4492 
4493  return ((TP_DOMAIN *) best);
4494 }
4495 #endif /* !SERVER_MODE */
4496 
4497 
4498 /*
4499  * tp_domain_check - does basic validation of a value against a domain.
4500  * return: domain status
4501  * domain(in): destination domain
4502  * value(in): value to look at
4503  * exact_match(in): controls the tolerance permitted for the match
4504  * Note:
4505  * It does NOT do coercion. If the intention is to perform coercion,
4506  * them tp_domain_select should be used.
4507  * Exact match is used to request a deferred coercion of values that
4508  * are within "tolerance" of the destination domain. This is currently
4509  * only specified for assignment of attribute values and will be
4510  * recognized only by those types whose "setmem" and "writeval" functions
4511  * are able to perform delayed coercion. Examples are the CHAR types
4512  * which will do truncation or blank padding as the values are being
4513  * assigned. See commentary in tp_domain_match for more information.
4514  */
4516 tp_domain_check (const TP_DOMAIN * domain, const DB_VALUE * value, TP_MATCH exact_match)
4517 {
4518  TP_DOMAIN_STATUS status;
4519  TP_DOMAIN *d;
4520 
4521  if (domain == NULL)
4522  {
4523  status = DOMAIN_COMPATIBLE;
4524  }
4525  else
4526  {
4527  d = tp_domain_select (domain, value, 0, exact_match);
4528  if (d == NULL)
4529  {
4530  status = DOMAIN_INCOMPATIBLE;
4531  }
4532  else
4533  {
4534  status = DOMAIN_COMPATIBLE;
4535  }
4536  }
4537 
4538  return status;
4539 }
4540 
4541 /*
4542  * COERCION
4543  */
4544 
4545 
4546 /*
4547  * tp_can_steal_string - check if the string currently held in "val" can be
4548  * safely reused
4549  * WITHOUT copying.
4550  * return: error code
4551  * val(in): source (and destination) value
4552  * desired_domain(in): desired domain for coerced value
4553  * Note:
4554  * Basically, this holds if
4555  * 1. the dest precision is "floating", or
4556  * 2. the dest type is varying and the length of the string is less
4557  * than or equal to the dest precision, or
4558  * 3. the dest type is fixed and the length of the string is exactly
4559  * equal to the dest precision.
4560  * Since the desired domain is often a varying char, this wins often.
4561  */
4562 int
4563 tp_can_steal_string (const DB_VALUE * val, const DB_DOMAIN * desired_domain)
4564 {
4565  DB_TYPE original_type, desired_type;
4566  int original_length, original_size, desired_precision;
4567 
4568  original_type = DB_VALUE_DOMAIN_TYPE (val);
4569  if (!TP_IS_CHAR_BIT_TYPE (original_type))
4570  {
4571  return 0;
4572  }
4573 
4574  original_length = db_get_string_length (val);
4575  original_size = db_get_string_size (val);
4576  desired_type = TP_DOMAIN_TYPE (desired_domain);
4577  desired_precision = desired_domain->precision;
4578 
4579  /* this condition covers both the cases when string conversion is needed, and when byte reinterpretation will be
4580  * performed (destination charset = BINARY) */
4581  if (original_size > desired_precision)
4582  {
4583  return 0;
4584  }
4585 
4586  if (TP_IS_CHAR_TYPE (original_type) && TP_IS_CHAR_TYPE (TP_DOMAIN_TYPE (desired_domain)))
4587  {
4588  if (desired_domain->collation_flag != TP_DOMAIN_COLL_LEAVE
4589  && db_get_string_collation (val) != TP_DOMAIN_COLLATION (desired_domain)
4591  {
4592  return 0;
4593  }
4594 
4595  if (desired_domain->collation_flag != TP_DOMAIN_COLL_LEAVE
4596  && !INTL_CAN_STEAL_CS (db_get_string_codeset (val), TP_DOMAIN_CODESET (desired_domain)))
4597  {
4598  return 0;
4599  }
4600  }
4601 
4602  if (desired_domain->collation_flag == TP_DOMAIN_COLL_ENFORCE)
4603  {
4604  return 1;
4605  }
4606 
4607  if (desired_precision == TP_FLOATING_PRECISION_VALUE)
4608  {
4609  desired_precision = original_length;
4610  }
4611 
4612  switch (desired_type)
4613  {
4614  case DB_TYPE_CHAR:
4615  return (desired_precision == original_length
4616  && (original_type == DB_TYPE_CHAR || original_type == DB_TYPE_VARCHAR)
4617  && DB_GET_COMPRESSED_STRING (val) == NULL);
4618  case DB_TYPE_VARCHAR:
4619  return (desired_precision >= original_length
4620  && (original_type == DB_TYPE_CHAR || original_type == DB_TYPE_VARCHAR));
4621  case DB_TYPE_NCHAR:
4622  return (desired_precision == original_length
4623  && (original_type == DB_TYPE_NCHAR || original_type == DB_TYPE_VARNCHAR)
4624  && DB_GET_COMPRESSED_STRING (val) == NULL);
4625  case DB_TYPE_VARNCHAR:
4626  return (desired_precision >= original_length
4627  && (original_type == DB_TYPE_NCHAR || original_type == DB_TYPE_VARNCHAR));
4628  case DB_TYPE_BIT:
4629  return (desired_precision == original_length
4630  && (original_type == DB_TYPE_BIT || original_type == DB_TYPE_VARBIT));
4631  case DB_TYPE_VARBIT:
4632  return (desired_precision >= original_length
4633  && (original_type == DB_TYPE_BIT || original_type == DB_TYPE_VARBIT));
4634  default:
4635  return 0;
4636  }
4637 }
4638 
4639 #if defined(ENABLE_UNUSED_FUNCTION)
4640 /*
4641  * tp_null_terminate - NULL terminate the given DB_VALUE string.
4642  * return: NO_ERROR or error code
4643  * src(in): string to null terminate
4644  * strp(out): pointer for output
4645  * str_len(in): length of 'str'
4646  * do_alloc(out): set true if allocation occurred
4647  * Note:
4648  * Don't call this unless src is a string db_value.
4649  */
4650 static int
4651 tp_null_terminate (const DB_VALUE * src, char **strp, int str_len, bool * do_alloc)
4652 {
4653  char *str;
4654  int str_size;
4655 
4656  *do_alloc = false; /* init */
4657 
4658  str = db_get_string (src);
4659  if (str == NULL)
4660  {
4661  return ER_FAILED;
4662  }
4663 
4664  str_size = db_get_string_size (src);
4665 
4666  if (str[str_size] == '\0')
4667  {
4668  /* already NULL terminated */
4669  *strp = str;
4670 
4671  return NO_ERROR;
4672  }
4673 
4674  if (str_size >= str_len)
4675  {
4676  *strp = (char *) malloc (str_size + 1);
4677  if (*strp == NULL)
4678  {
4679  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1, (size_t) (str_size + 1));
4680  return ER_OUT_OF_VIRTUAL_MEMORY;
4681  }
4682 
4683  *do_alloc = true; /* mark as alloced */
4684  }
4685 
4686  memcpy (*strp, str, str_size);
4687  (*strp)[str_size] = '\0';
4688 
4689  return NO_ERROR;
4690 }
4691 #endif /* ENABLE_UNUSED_FUNCTION */
4692 
4693 /*
4694  * tp_atotime - coerce a string to a time
4695  * return: NO_ERROR or error code
4696  * src(in): string DB_VALUE
4697  * temp(out): time container
4698  * Note:
4699  * Accepts strings that are not null terminated. Don't call this unless
4700  * src is a string db_value.
4701  */
4702 static int
4703 tp_atotime (const DB_VALUE * src, DB_TIME * temp)
4704 {
4705  int milisec;
4706  const char *strp = db_get_string (src);
4707  int str_len = db_get_string_size (src);
4708  int status = NO_ERROR;
4709 
4710  if (db_date_parse_time (strp, str_len, temp, &milisec) != NO_ERROR)
4711  {
4712  status = ER_FAILED;
4713  }
4714 
4715  return status;
4716 }
4717 
4718 /*
4719  * tp_atodate - coerce a string to a date
4720  * return: NO_ERROR or error code
4721  * src(in): string DB_VALUE
4722  * temp(out): date container
4723  * Note:
4724  * Accepts strings that are not null terminated. Don't call this unless
4725  * src is a string db_value.
4726  */
4727 static int
4728 tp_atodate (const DB_VALUE * src, DB_DATE * temp)
4729 {
4730  const char *strp = db_get_string (src);
4731  int str_len = db_get_string_size (src);
4732  int status = NO_ERROR;
4733 
4734  if (db_date_parse_date (strp, str_len, temp) != NO_ERROR)
4735  {
4736  status = ER_FAILED;
4737  }
4738 
4739  return status;
4740 }
4741 
4742 /*
4743  * tp_atoutime - coerce a string to a utime.
4744  * return: NO_ERROR or error code
4745  * src(in): string DB_VALUE
4746  * temp(out): utime container
4747  * Note:
4748  * Accepts strings that are not null terminated. Don't call this unless
4749  * src is a string db_value.
4750  */
4751 static int
4752 tp_atoutime (const DB_VALUE * src, DB_UTIME * temp)
4753 {
4754  const char *strp = db_get_string (src);
4755  int str_len = db_get_string_size (src);
4756  int status = NO_ERROR;
4757 
4758  if (db_date_parse_utime (strp, str_len, temp) != NO_ERROR)
4759  {
4760  status = ER_FAILED;
4761  }
4762 
4763  return status;
4764 }
4765 
4766 /*
4767  * tp_atotimestamptz - coerce a string to a timestamp with time zone.
4768  * return: NO_ERROR or error code
4769  * src(in): string DB_VALUE
4770  * temp(out): timestamp with TZ info container
4771  * Note:
4772  * Accepts strings that are not null terminated. Don't call this unless
4773  * src is a string db_value.
4774  */
4775 static int
4777 {
4778  const char *strp = db_get_string (src);
4779  int str_len = db_get_string_size (src);
4780  int status = NO_ERROR;
4781  bool dummy_has_zone;
4782 
4783  if (db_string_to_timestamptz_ex (strp, str_len, temp, &dummy_has_zone, true) != NO_ERROR)
4784  {
4785  status = ER_FAILED;
4786  }
4787 
4788  return status;
4789 }
4790 
4791 /*
4792  * tp_atoudatetime - coerce a string to a datetime.
4793  * return: NO_ERROR or error code
4794  * src(in): string DB_VALUE
4795  * temp(out): datetime container
4796  * Note:
4797  * Accepts strings that are not null terminated. Don't call this unless
4798  * src is a string db_value.
4799  */
4800 static int
4801 tp_atoudatetime (const DB_VALUE * src, DB_DATETIME * temp)
4802 {
4803  const char *strp = db_get_string (src);
4804  int str_len = db_get_string_size (src);
4805  int status = NO_ERROR;
4806 
4807  if (db_date_parse_datetime (strp, str_len, temp) != NO_ERROR)
4808  {
4809  status = ER_FAILED;
4810  }
4811 
4812  return status;
4813 }
4814 
4815 /*
4816  * tp_atoudatetimetz - coerce a string to a datetime with time zone.
4817  * return: NO_ERROR or error code
4818  * src(in): string DB_VALUE
4819  * temp(out): datetime with time zone container
4820  * Note:
4821  * Accepts strings that are not null terminated. Don't call this unless
4822  * src is a string db_value.
4823  */
4824 static int
4826 {
4827  const char *strp = db_get_string (src);
4828  int str_len = db_get_string_size (src);
4829  int status = NO_ERROR;
4830  bool dummy_has_zone;
4831 
4832  if (db_string_to_datetimetz_ex (strp, str_len, temp, &dummy_has_zone) != NO_ERROR)
4833  {
4834  status = ER_FAILED;
4835  }
4836 
4837  return status;
4838 }
4839 
4840 /*
4841  * tp_atonumeric - Coerce a string to a numeric.
4842  * return: NO_ERROR or error code
4843  * src(in): string DB_VALUE
4844  * temp(out): numeirc container
4845  * Note:
4846  * Accepts strings that are not null terminated. Don't call this unless
4847  * src is a string db_value.
4848  */
4849 static int
4850 tp_atonumeric (const DB_VALUE * src, DB_VALUE * temp)
4851 {
4852  const char *strp;
4853  int status = NO_ERROR;
4854  int str_len;
4855 
4856  strp = db_get_string (src);
4857  if (strp == NULL)
4858  {
4859  return ER_FAILED;
4860  }
4861 
4862  str_len = db_get_string_size (src);
4863 
4864  if (numeric_coerce_string_to_num (strp, str_len, db_get_string_codeset (src), temp) != NO_ERROR)
4865  {
4866  status = ER_FAILED;
4867  }
4868 
4869  return status;
4870 }
4871 
4872 /*
4873  * tp_atof - Coerce a string to a double.
4874  * return: NO_ERROR or error code.
4875  * src(in): string DB_VALUE
4876  * num_value(out): float container
4877  * data_stat(out): if overflow is detected, this is set to
4878  * DATA_STATUS_TRUNCATED. If there exists some characters
4879  * that are not numeric codes or spaces then it is set to
4880  * DATA_STATUS_NOT_CONSUMED.
4881  * Note:
4882  * Accepts strings that are not null terminated. Don't call this unless
4883  * src is a string db_value.
4884  */
4885 static int
4886 tp_atof (const DB_VALUE * src, double *num_value, DB_DATA_STATUS * data_stat)
4887 {
4888  char str[NUM_BUF_SIZE];
4889  const char *strp = NULL;
4890  bool do_alloc = false;
4891  double d;
4892  const char *p, *end;
4893  int status = NO_ERROR;
4894  unsigned int size;
4895  INTL_CODESET codeset;
4896 
4897  *data_stat = DATA_STATUS_OK;
4898 
4899  p = db_get_string (src);
4900  size = db_get_string_size (src);
4901  codeset = db_get_string_codeset (src);
4902  end = p + size - 1;
4903 
4904  if (size > 0 && *end)
4905  {
4906  while (p <= end && char_isspace (*p))
4907  {
4908  p++;
4909  }
4910 
4911  while (p < end && char_isspace (*end))
4912  {
4913  end--;
4914  }
4915 
4916  char *strp_tmp = NULL;
4917  size = CAST_BUFLEN (end - p) + 1;
4918 
4919  if (size > sizeof (str) - 1)
4920  {
4921  strp_tmp = (char *) malloc (size + 1);
4922  if (strp_tmp == NULL)
4923  {
4924  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1, (size_t) (size + 1));
4925  return ER_OUT_OF_VIRTUAL_MEMORY;
4926  }
4927  do_alloc = true;
4928  }
4929  else
4930  {
4931  strp_tmp = str;
4932  }
4933 
4934  if (size)
4935  {
4936  memcpy (strp_tmp, p, size);
4937  }
4938  strp_tmp[size] = '\0';
4939 
4940  strp = strp_tmp;
4941  }
4942  else
4943  {
4944  strp = p;
4945  }
4946 
4947  /* don't use atof() which cannot detect the error. */
4948  errno = 0;
4949  char *end_ptr = NULL;
4950  d = string_to_double (strp, &end_ptr);
4951 
4952  if (errno == ERANGE)
4953  {
4954  if (d != 0)
4955  {
4956  /* overflow */
4957  *data_stat = DATA_STATUS_TRUNCATED;
4958  }
4959  /* d == 0 is underflow, we don't have an error for this */
4960  }
4961 
4962  /* ignore trailing spaces */
4963  end_ptr = (char *) intl_skip_spaces (end_ptr, NULL, codeset);
4964  if (*end_ptr) /* all input does not consumed */
4965  {
4966  *data_stat = DATA_STATUS_NOT_CONSUMED;
4967  }
4968  *num_value = d;
4969 
4970  if (do_alloc)
4971  {
4972  free_and_init (strp);
4973  }
4974 
4975  return status;
4976 }
4977 
4978 /*
4979  * tp_atobi - Coerce a string to a bigint.
4980  * return: NO_ERROR or error code
4981  * src(in): string DB_VALUE
4982  * num_value(out): bigint container
4983  * data_stat(out): if overflow is detected, this is set to
4984  * DATA_STATUS_TRUNCATED
4985  * Note:
4986  * Accepts strings that are not null terminated. Don't call this unless
4987  * src is a string db_value.
4988  * If string contains decimal part, performs rounding.
4989  *
4990  */
4991 static int
4992 tp_atobi (const DB_VALUE * src, DB_BIGINT * num_value, DB_DATA_STATUS * data_stat)
4993 {
4994  const char *strp = db_get_string (src);
4995  const char *stre = NULL;
4996  const char *p = NULL, *old_p = NULL;
4997  int status = NO_ERROR;
4998  bool is_negative = false;
4999  INTL_CODESET codeset = db_get_string_codeset (src);
5000  bool is_hex = false, is_scientific = false;
5001  bool has_leading_zero = false;
5002 
5003  if (strp == NULL)
5004  {
5005  return ER_FAILED;
5006  }
5007 
5008  stre = strp + db_get_string_size (src);
5009 
5010  /* skip leading spaces */
5011  while (strp != stre && char_isspace (*strp))
5012  {
5013  strp++;
5014  }
5015 
5016  /* read sign if any */
5017  if (strp != stre && (*strp == '-' || *strp == '+'))
5018  {
5019  is_negative = (*strp == '-');
5020  strp++;
5021  }
5022  else
5023  {
5024  is_negative = false;
5025  }
5026 
5027  /* 0x or 0X */
5028  if (strp != stre && *strp == '0' && (strp + 1) != stre && (*(strp + 1) == 'x' || *(strp + 1) == 'X'))
5029  {
5030  is_hex = true;
5031  strp += 2;
5032  }
5033 
5034  /* skip leading zeros */
5035  while (strp != stre && *strp == '0')
5036  {
5037  strp++;
5038 
5039  if (!has_leading_zero)
5040  {
5041  has_leading_zero = true;
5042  }
5043  }
5044 
5045  if (!is_hex)
5046  {
5047  /* check whether is scientific format */
5048  p = strp;
5049 
5050  /* check first part */
5051  while (p != stre && char_isdigit (*p))
5052  {
5053  ++p;
5054  }
5055 
5056  if (p != stre && *p == '.')
5057  {
5058  ++p;
5059 
5060  while (p != stre && char_isdigit (*p))
5061  {
5062  ++p;
5063  }
5064  }
5065 
5066  /* no first part */
5067  if (!has_leading_zero && p == strp)
5068  {
5069  return ER_FAILED;
5070  }
5071 
5072  /* skip trailing white spaces of first part */
5073  p = (char *) intl_skip_spaces (p, stre, codeset);
5074 
5075  /* check exponent part */
5076  if (p != stre)
5077  {
5078  if (*p == 'e' || *p == 'E')
5079  {
5080  ++p;
5081 
5082  /* check second part */
5083  if (p != stre && (*p == '+' || *p == '-'))
5084  {
5085  ++p;
5086  }
5087 
5088  old_p = p;
5089  while (p != stre && char_isdigit (*p))
5090  {
5091  ++p;
5092  }
5093 
5094  if (p == old_p)
5095  {
5096  return ER_FAILED;
5097  }
5098 
5099  /* skip trailing white spaces of second part */
5100  p = (char *) intl_skip_spaces (p, stre, codeset);
5101  if (p == stre)
5102  {
5103  is_scientific = true;
5104  }
5105  }
5106  else
5107  {
5108  return ER_FAILED;
5109  }
5110  }
5111  }
5112 
5113  /* convert to bigint */
5114  if (is_hex)
5115  {
5116  status = tp_hex_str_to_bi (strp, stre, codeset, is_negative, num_value, data_stat);
5117  }
5118  else if (is_scientific)
5119  {
5120  status = tp_scientific_str_to_bi (strp, stre, codeset, is_negative, num_value, data_stat);
5121  }
5122  else
5123  {
5124  status = tp_digit_number_str_to_bi (strp, stre, codeset, is_negative, num_value, data_stat);
5125  }
5126 
5127  return status;
5128 }
5129 
5130 #if defined(ENABLE_UNUSED_FUNCTION)
5131 /*
5132  * tp_itoa - int to string representation for given radix
5133  * return: string pointer (given or malloc'd)
5134  * value(in): int value
5135  * string(in/out): dest buffer or NULL
5136  * radix(in): int value between 2 and 36
5137  */
5138 static char *
5139 tp_itoa (int value, char *string, int radix)
5140 {
5141  char tmp[33];
5142  char *tp = tmp;
5143  int i;
5144  unsigned v;
5145  int sign;
5146  char *sp;
5147 
5148  if (radix > 36 || radix <= 1)
5149  {
5150  return 0;
5151  }
5152 
5153  sign = (radix == 10 && value < 0);
5154 
5155  if (sign)
5156  {
5157  v = -value;
5158  }
5159  else
5160  {
5161  v = (unsigned) value;
5162  }
5163 
5164  while (v || tp == tmp)
5165  {
5166  i = v % radix;
5167  v = v / radix;
5168  if (i < 10)
5169  {
5170  *tp++ = i + '0';
5171  }
5172  else
5173  {
5174  *tp++ = i + 'a' - 10;
5175  }
5176  }
5177 
5178  if (string == NULL)
5179  {
5180  string = (char *) malloc ((tp - tmp) + sign + 1);
5181  if (string == NULL)
5182  {
5183  return string;
5184  }
5185  }
5186  sp = string;
5187 
5188  if (sign)
5189  {
5190  *sp++ = '-';
5191  }
5192  while (tp > tmp)
5193  {
5194  *sp++ = *--tp;
5195  }
5196  *sp = '\0';
5197  return string;
5198 }
5199 #endif /* ENABLE_UNUSED_FUNCTION */
5200 
5201 /*
5202  * tp_ltoa - bigint to string representation for given radix
5203  * return: string pointer (given or malloc'd)
5204  * value(in): bigint value
5205  * string(in/out): dest buffer or NULL
5206  * radix(in): int value between 2 and 36
5207  */
5208 static char *
5209 tp_ltoa (DB_BIGINT value, char *string, int radix)
5210 {
5211  char tmp[33];
5212  char *tp = tmp;
5213  int i;
5214  UINT64 v;
5215  int sign;
5216  char *sp;
5217 
5218  if (radix > 36 || radix <= 1)
5219  {
5220  return 0;
5221  }
5222 
5223  sign = (radix == 10 && value < 0);
5224 
5225  if (sign)
5226  {
5227  v = -value;
5228  }
5229  else
5230  {
5231  v = (UINT64) value;
5232  }
5233 
5234  while (v || tp == tmp)
5235  {
5236  i = v % radix;
5237  v = v / radix;
5238  if (i < 10)
5239  {
5240  *tp++ = i + '0';
5241  }
5242  else
5243  {
5244  *tp++ = i + 'a' - 10;
5245  }
5246  }
5247 
5248  if (string == NULL)
5249  {
5250  string = (char *) malloc ((tp - tmp) + sign + 1);
5251  if (string == NULL)
5252  {
5253  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1, (size_t) ((tp - tmp) + sign + 1));
5254  return NULL;
5255  }
5256  }
5257  sp = string;
5258 
5259  if (sign)
5260  {
5261  *sp++ = '-';
5262  }
5263  while (tp > tmp)
5264  {
5265  *sp++ = *--tp;
5266  }
5267  *sp = '\0';
5268 
5269  return string;
5270 }
5271 
5272 /*
5273  * format_floating_point() - formats a digits sequence and an integer exponent
5274  * for a floating-point number (from dtoa) to the
5275  * printable representation
5276  *
5277  * return:
5278  * new_string(out): the sequence of decimal digits for the floating-point
5279  * number mantisa, to be reformated into a character
5280  * sequence for a printable floating point number.
5281  * the buffer is assumed to be large enought for the
5282  * printable sequence
5283  * rve(out): end of sequence of digits
5284  * ndigits(in): floating number precision to be used for printing
5285  * decpt(in): decimal point position in the digits sequence
5286  * (similar to the exponent)
5287  * sign(in): sign of the floating-point number
5288  */
5289 static void
5290 format_floating_point (char *new_string, char *rve, int ndigits, int decpt, int sign)
5291 {
5292  assert (new_string && rve);
5293 
5294  if (decpt != 9999)
5295  {
5296  if (ndigits >= decpt && decpt > -4) /* as in the C 2005 standard for printf conversion specification */
5297  {
5298  /* print as a fractional number */
5299  if (decpt > rve - new_string)
5300  {
5301  /* append with zeros until the decimal point is encountered */
5302  while (new_string + decpt > rve)
5303  {
5304  *rve++ = '0';
5305  }
5306  *rve = '\0';
5307  /* no decimal point needed */
5308  }
5309  else if (decpt <= 0)
5310  {
5311  /* prepend zeroes until the decimal point is encountered */
5312  /* if decpt is -3, insert 3 zeroes between the decimal point and first non-zero digit */
5313  size_t n_left_pad = +2 - decpt;
5314 
5315  char *p = new_string + n_left_pad;
5316 
5317  rve += n_left_pad;
5318  do
5319  {
5320  *rve = *(rve - n_left_pad);
5321  rve--;
5322  }
5323  while (rve != p);
5324 
5325  *rve = *(rve - n_left_pad);
5326 
5327  p--;
5328  while (p != new_string + 1)
5329  {
5330  *p-- = '0';
5331  }
5332  *p-- = '.';
5333  *p = '0';
5334  }
5335  else if (decpt != rve - new_string)
5336  {
5337  /* insert decimal point within the digits sequence at position indicated by decpt */
5338  rve++;
5339 
5340  while (rve != new_string + decpt)
5341  {
5342  *rve = *(rve - 1);
5343  rve--;
5344  }
5345  *rve = '.';
5346  }
5347  }
5348  else
5349  {
5350  /* print as mantisa followed by exponent */
5351  if (rve > new_string + 1)
5352  {
5353  /* insert the decimal point before the second digit, if any */
5354  char *p = rve;
5355 
5356  while (p != new_string)
5357  {
5358  *p = *(p - 1);
5359  p--;
5360  }
5361 
5362  p[1] = '.';
5363  rve++;
5364  }
5365  *rve++ = 'e';
5366 
5367  decpt--; /* convert from 0.432e12 to 4.32e11 */
5368  if (decpt < 0)
5369  {
5370  *rve++ = '-';
5371  decpt = -decpt;
5372  }
5373  else
5374  {
5375  *rve++ = '+';
5376  }
5377 
5378  if (decpt > 99)
5379  {
5380  *rve++ = '0' + decpt / 100;
5381  *rve++ = '0' + decpt % 100 / 10;
5382  *rve++ = '0' + decpt % 10;
5383  }
5384  else if (decpt > 9)
5385  {
5386  *rve++ = '0' + decpt / 10;
5387  *rve++ = '0' + decpt % 10;
5388  }
5389  else
5390  *rve++ = '0' + decpt;
5391 
5392  *rve = '\0';
5393  }
5394  }
5395 
5396  /* prepend '-' sign if number is negative */
5397  if (sign)
5398  {
5399  char ch = *new_string;
5400 
5401  rve = new_string + 1;
5402 
5403  while (*rve)
5404  {
5405  /* swap(ch, *rve); */
5406  ch ^= *rve;
5407  *rve = ch ^ *rve;
5408  ch ^= *rve++;
5409  }
5410 
5411  /* swap(ch, *rve); */
5412  ch ^= *rve;
5413  *rve = ch ^ *rve;
5414  ch ^= *rve++;
5415 
5416  rve[0] = '\0';
5417  *new_string = '-';
5418  }
5419 }
5420 
5421 /*
5422  * tp_ftoa() - convert a float DB_VALUE to a string DB_VALUE.
5423  * Only the decimal representation is preserved by
5424  * by the conversion, in order to avoid printing
5425  * inexact digits. This means that if the number is
5426  * read back from string into a float, the binary
5427  * representation for the float might be different
5428  * than the original, but the printed number shall
5429  * always be the same.
5430  *
5431  * return:
5432  * src(in): float DB_VALUE to be converted to string
5433  * result(in/out): string DB_VALUE of the desired [VAR][N]CHAR
5434  * domain type and null value, that receives
5435  * the string resulting from conversion.
5436  */
5437 void
5438 tp_ftoa (DB_VALUE const *src, DB_VALUE * result)
5439 {
5440  /* dtoa() appears to ignore the requested number of digits... */
5441  const int ndigits = TP_FLOAT_MANTISA_DECIMAL_PRECISION;
5442  char *str_float, *rve;
5443  int decpt, sign;
5444 
5445  assert (DB_VALUE_TYPE (src) == DB_TYPE_FLOAT);
5446  assert (DB_VALUE_TYPE (result) == DB_TYPE_NULL);
5447 
5448  rve = str_float = (char *) db_private_alloc (NULL, TP_FLOAT_AS_CHAR_LENGTH + 1);
5449  if (str_float == NULL)
5450  {
5451  db_make_null (result);
5452  return;
5453  }
5454 
5455  /* _dtoa just returns the digits sequence and the exponent as for a number in the form 0.4321344e+14 */
5456  _dtoa (db_get_float (src), 0, ndigits, &decpt, &sign, &rve, str_float, 1);
5457 
5458  /* rounding should also be performed here */
5459  str_float[ndigits] = '\0'; /* _dtoa() disregards ndigits */
5460 
5461  format_floating_point (str_float, str_float + strlen (str_float), ndigits, decpt, sign);
5462 
5463  switch (DB_VALUE_DOMAIN_TYPE (result))
5464  {
5465  case DB_TYPE_CHAR:
5466  db_make_char (result, DB_VALUE_PRECISION (result), str_float, strlen (str_float), db_get_string_codeset (result),
5467  db_get_string_collation (result));
5468  result->need_clear = true;
5469  break;
5470 
5471  case DB_TYPE_NCHAR:
5472  db_make_nchar (result, DB_VALUE_PRECISION (result), str_float, strlen (str_float), db_get_string_codeset (result),
5473  db_get_string_collation (result));
5474  result->need_clear = true;
5475  break;
5476 
5477  case DB_TYPE_VARCHAR:
5478  db_make_varchar (result, DB_VALUE_PRECISION (result), str_float, strlen (str_float),
5479  db_get_string_codeset (result), db_get_string_collation (result));
5480  result->need_clear = true;
5481  break;
5482 
5483  case DB_TYPE_VARNCHAR:
5484  db_make_varnchar (result, DB_VALUE_PRECISION (result), str_float, strlen (str_float),
5485  db_get_string_codeset (result), db_get_string_collation (result));
5486  result->need_clear = true;
5487  break;
5488 
5489  default:
5490  db_private_free_and_init (NULL, str_float);
5492  pr_type_name (DB_VALUE_DOMAIN_TYPE (result)));
5493  db_make_null (result);
5494  break;
5495  }
5496 }
5497 
5498 /*
5499  * tp_dtoa(): converts a double DB_VALUE to a string DB_VALUE.
5500  * Only as many digits as can be computed exactly are
5501  * written in the resulting string.
5502  *
5503  * return:
5504  * src(in): double DB_VALUE to be converted to string
5505  * result(in/out): string DB_VALUE of the desired [VAR][N]CHAR domain
5506  * type and null value, to receive the converted float
5507  */
5508 void
5509 tp_dtoa (DB_VALUE const *src, DB_VALUE * result)
5510 {
5511  /* dtoa() appears to ignore the requested number of digits... */
5512  const int ndigits = TP_DOUBLE_MANTISA_DECIMAL_PRECISION;
5513  char *str_double, *rve;
5514  int decpt, sign;
5515 
5516  assert (DB_VALUE_TYPE (src) == DB_TYPE_DOUBLE);
5517  assert (DB_VALUE_TYPE (result) == DB_TYPE_NULL);
5518 
5519  rve = str_double = (char *) db_private_alloc (NULL, TP_DOUBLE_AS_CHAR_LENGTH + 1);
5520  if (str_double == NULL)
5521  {
5522  db_make_null (result);
5523  return;
5524  }
5525 
5526  _dtoa (db_get_double (src), 0, ndigits, &decpt, &sign, &rve, str_double, 0);
5527  /* rounding should also be performed here */
5528  str_double[ndigits] = '\0'; /* _dtoa() disregards ndigits */
5529 
5530  format_floating_point (str_double, str_double + strlen (str_double), ndigits, decpt, sign);
5531 
5532  switch (DB_VALUE_DOMAIN_TYPE (result))
5533  {
5534  case DB_TYPE_CHAR:
5535  db_make_char (result, DB_VALUE_PRECISION (result), str_double, strlen (str_double),
5536  db_get_string_codeset (result), db_get_string_collation (result));
5537  result->need_clear = true;
5538  break;
5539 
5540  case DB_TYPE_NCHAR:
5541  db_make_nchar (result, DB_VALUE_PRECISION (result), str_double, strlen (str_double),
5542  db_get_string_codeset (result), db_get_string_collation (result));
5543  result->need_clear = true;
5544  break;
5545 
5546  case DB_TYPE_VARCHAR:
5547  db_make_varchar (result, DB_VALUE_PRECISION (result), str_double, strlen (str_double),
5548  db_get_string_codeset (result), db_get_string_collation (result));
5549  result->need_clear = true;
5550  break;
5551 
5552  case DB_TYPE_VARNCHAR:
5553  db_make_varnchar (result, DB_VALUE_PRECISION (result), str_double, strlen (str_double),
5554  db_get_string_codeset (result), db_get_string_collation (result));
5555  result->need_clear = true;
5556  break;
5557 
5558  default:
5559  db_private_free_and_init (NULL, str_double);
5561  pr_type_name (DB_VALUE_DOMAIN_TYPE (result)));
5562  db_make_null (result);
5563  break;
5564  }
5565 }
5566 
5567 /*
5568  * tp_enumeration_to_varchar - Get the value of an enumeration as a varchar.
5569  * return: error code or NO_ERROR
5570  * src(in): enumeration
5571  * result(in/out): varchar
5572  * Note:
5573  * The string value of the varchar value is not a copy of the enumeration
5574  * value, it just points to it
5575  */
5576 int
5578 {
5579  int error = NO_ERROR;
5580 
5581  if (src == NULL || result == NULL)
5582  {
5583  assert (false);
5584  return ER_FAILED;
5585  }
5586 
5587  if (db_get_enum_string (src) == NULL)
5588  {
5590  }
5591  else
5592  {
5595  }
5596 
5597  return error;
5598 }
5599 
5600 #define BITS_IN_BYTE 8
5601 #define HEX_IN_BYTE 2
5602 #define BITS_IN_HEX 4
5603 
5604 #define BYTE_COUNT(bit_cnt) (((bit_cnt)+BITS_IN_BYTE-1)/BITS_IN_BYTE)
5605 #define BYTE_COUNT_HEX(bit_cnt) (((bit_cnt)+BITS_IN_HEX-1)/BITS_IN_HEX)
5606 
5607 /*
5608  * bfmt_print - Change the given string to a representation of the given
5609  * bit string value in the given format.
5610  * return: NO_ERROR or -1 if max_size is too small
5611  * bfmt(in): 0: for binary representation or 1: for hex representation
5612  * the_db_bit(in): DB_VALUE
5613  * string(out): output buffer
5614  * max_size(in): size of output buffer
5615  */
5616 static int
5617 bfmt_print (int bfmt, const DB_VALUE * the_db_bit, char *string, int max_size)
5618 {
5619  int length = 0;
5620  int string_index = 0;
5621  int byte_index;
5622  int bit_index;
5623  const char *bstring;
5624  int error = NO_ERROR;
5625  static const char digits[16] = {
5626  '0', '1', '2', '3', '4', '5', '6', '7',
5627  '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
5628  };
5629 
5630  /* Get the buffer and the length from the_db_bit */
5631  bstring = db_get_bit (the_db_bit, &length);
5632 
5633  switch (bfmt)
5634  {
5635  case 0: /* BIT_STRING_BINARY */
5636  if (length + 1 > max_size)
5637  {
5638  error = -1;
5639  }
5640  else
5641  {
5642  for (byte_index = 0; byte_index < BYTE_COUNT (length); byte_index++)
5643  {
5644  for (bit_index = 7; bit_index >= 0 && string_index < length; bit_index--)
5645  {
5646  *string = digits[((bstring[byte_index] >> bit_index) & 0x1)];
5647  string++;
5648  string_index++;
5649  }
5650  }
5651  *string = '\0';
5652  }
5653  break;
5654 
5655  case 1: /* BIT_STRING_HEX */
5656  if (BYTE_COUNT_HEX (length) + 1 > max_size)
5657  {
5658  error = -1;
5659  }
5660  else
5661  {
5662  for (byte_index = 0; byte_index < BYTE_COUNT (length); byte_index++)
5663  {
5664  *string = digits[((bstring[byte_index] >> BITS_IN_HEX) & 0x0f)];
5665  string++;
5666  string_index++;
5667  if (string_index < BYTE_COUNT_HEX (length))
5668  {
5669  *string = digits[((bstring[byte_index] & 0x0f))];
5670  string++;
5671  string_index++;
5672  }
5673  }
5674  *string = '\0';
5675  }
5676  break;
5677 
5678  default:
5679  break;
5680  }
5681 
5682  return error;
5683 }
5684 
5685 
5686 #define ROUND(x) ((x) > 0 ? ((x) + .5) : ((x) - .5))
5687 #define SECONDS_IN_A_DAY (long)(86400) /* 24L * 60L * 60L */
5688 #define TP_IS_CHAR_STRING(db_val_type) \
5689  (db_val_type == DB_TYPE_CHAR || db_val_type == DB_TYPE_VARCHAR || \
5690  db_val_type == DB_TYPE_NCHAR || db_val_type == DB_TYPE_VARNCHAR)
5691 
5692 #define TP_IS_LOB(db_val_type) \
5693  (db_val_type == DB_TYPE_BLOB || db_val_type == DB_TYPE_CLOB)
5694 
5695 #define TP_IS_DATETIME_TYPE(db_val_type) TP_IS_DATE_OR_TIME_TYPE (db_val_type)
5696 
5697 #define TP_IMPLICIT_COERCION_NOT_ALLOWED(src_type, dest_type) \
5698  ((TP_IS_CHAR_STRING(src_type) && !(TP_IS_CHAR_STRING(dest_type) || \
5699  TP_IS_DATETIME_TYPE(dest_type) || \
5700  TP_IS_NUMERIC_TYPE(dest_type) || \
5701  dest_type == DB_TYPE_ENUMERATION)) ||\
5702  (!TP_IS_CHAR_STRING(src_type) && src_type != DB_TYPE_ENUMERATION && \
5703  TP_IS_CHAR_STRING(dest_type)) || \
5704  (TP_IS_LOB(src_type) || TP_IS_LOB(dest_type)))
5705 
5706 /*
5707  * tp_value_string_to_double - Coerce a string to a double.
5708  * return: NO_ERROR, ER_OUT_OF_VIRTUAL_MEMORY or ER_FAILED.
5709  * src(in): string DB_VALUE
5710  * result(in/out): float container
5711  * Note:
5712  * Accepts strings that are not null terminated.
5713  */
5714 int
5716 {
5717  DB_DATA_STATUS data_stat;
5718  double dbl;
5719  int ret;
5720  DB_TYPE type = DB_VALUE_TYPE (value);
5721 
5722  if (!TP_IS_CHAR_STRING (type))
5723  {
5724  db_make_double (result, 0);
5725  return ER_FAILED;
5726  }
5727 
5728  ret = tp_atof (value, &dbl, &data_stat);
5729  if (ret != NO_ERROR)
5730  {
5731  db_make_double (result, 0);
5732  }
5733  else
5734  {
5735  db_make_double (result, dbl);
5736  }
5737 
5738  return ret;
5739 }
5740 
5741 static void
5742 make_desired_string_db_value (DB_TYPE desired_type, const TP_DOMAIN * desired_domain, const char *new_string,
5743  DB_VALUE * target, TP_DOMAIN_STATUS * status, DB_DATA_STATUS * data_stat)
5744 {
5745  DB_VALUE temp;
5746 
5747  assert (desired_domain->collation_flag == TP_DOMAIN_COLL_NORMAL
5748  || desired_domain->collation_flag == TP_DOMAIN_COLL_LEAVE);
5749 
5750  *status = DOMAIN_COMPATIBLE;
5751  switch (desired_type)
5752  {
5753  case DB_TYPE_CHAR:
5754  db_make_char (&temp, desired_domain->precision, new_string, strlen (new_string),
5755  TP_DOMAIN_CODESET (desired_domain), TP_DOMAIN_COLLATION (desired_domain));
5756  break;
5757  case DB_TYPE_NCHAR:
5758  db_make_nchar (&temp, desired_domain->precision, new_string, strlen (new_string),
5759  TP_DOMAIN_CODESET (desired_domain), TP_DOMAIN_COLLATION (desired_domain));
5760  break;
5761  case DB_TYPE_VARCHAR:
5762  db_make_varchar (&temp, desired_domain->precision, new_string, strlen (new_string),
5763  TP_DOMAIN_CODESET (desired_domain), TP_DOMAIN_COLLATION (desired_domain));
5764  break;
5765  case DB_TYPE_VARNCHAR:
5766  db_make_varnchar (&temp, desired_domain->precision, new_string, strlen (new_string),
5767  TP_DOMAIN_CODESET (desired_domain), TP_DOMAIN_COLLATION (desired_domain));
5768  break;
5769  default: /* Can't get here. This just quiets the compiler */
5770  break;
5771  }
5772 
5773  temp.need_clear = true;
5774  if (db_char_string_coerce (&temp, target, data_stat) != NO_ERROR)
5775  {
5776  *status = DOMAIN_INCOMPATIBLE;
5777  }
5778  else
5779  {
5780  *status = DOMAIN_COMPATIBLE;
5781  }
5782  pr_clear_value (&temp);
5783 }
5784 
5785 /*
5786  * tp_value_coerce - Coerce a value into one of another domain.
5787  * return: TP_DOMAIN_STATUS
5788  * src(in): source value
5789  * dest(out): destination value
5790  * desired_domain(in): destination domain
5791  */
5793 tp_value_coerce (const DB_VALUE * src, DB_VALUE * dest, const TP_DOMAIN * desired_domain)
5794 {
5795  return tp_value_cast (src, dest, desired_domain, true);
5796 }
5797 
5798 /*
5799  * tp_value_coerce_strict () - convert a value to desired domain without loss
5800  * of precision
5801  * return : error code or NO_ERROR
5802  * src (in) : source value
5803  * dest (out) : destination value
5804  * desired_domain (in) : destination domain
5805  */
5806 int
5807 tp_value_coerce_strict (const DB_VALUE * src, DB_VALUE * dest, const TP_DOMAIN * desired_domain)
5808 {
5809  DB_TYPE desired_type, original_type;
5810  int err = NO_ERROR;
5811  DB_VALUE temp, *target;
5812 
5813  /* A NULL src is allowed but destination remains NULL, not desired_domain */
5814  if (src == NULL || (original_type = DB_VALUE_TYPE (src)) == DB_TYPE_NULL)
5815  {
5816  db_make_null (dest);
5817  return err;
5818  }
5819 
5820  if (desired_domain == NULL)
5821  {
5822  db_make_null (dest);
5823  return ER_FAILED;
5824  }
5825 
5826  desired_type = TP_DOMAIN_TYPE (desired_domain);
5827 
5828  if (!TP_IS_NUMERIC_TYPE (desired_type) && !TP_IS_DATETIME_TYPE (desired_type))
5829  {
5830  db_make_null (dest);
5831  return ER_FAILED;
5832  }
5833 
5834  if (desired_type == original_type)
5835  {
5836  if (src != dest)
5837  {
5838  pr_clone_value ((DB_VALUE *) src, dest);
5839  return NO_ERROR;
5840  }
5841  }
5842 
5843  /*
5844  * If src == dest, coerce into a temporary variable and
5845  * handle the conversion before returning.
5846  */
5847  if (src == dest)
5848  {
5849  target = &temp;
5850  }
5851  else
5852  {
5853  target = dest;
5854  }
5855 
5856  /*
5857  * Initialize the destination domain, important for the
5858  * nm_ coercion functions which take domain information inside the
5859  * destination db value.
5860  */
5861  db_value_domain_init (target, desired_type, desired_domain->precision, desired_domain->scale);
5862 
5863  switch (desired_type)
5864  {
5865  case DB_TYPE_SHORT:
5866  switch (original_type)
5867  {
5868  case DB_TYPE_MONETARY:
5869  {
5870  double i = 0;
5871  const double val = db_get_monetary (src)->amount;
5872  if (OR_CHECK_SHORT_OVERFLOW (val))
5873  {
5874  err = ER_FAILED;
5875  break;
5876  }
5877  if (modf (val, &i) != 0)
5878  {
5879  err = ER_FAILED;
5880  break;
5881  }
5882  db_make_short (target, (short) i);
5883  break;
5884  }
5885  case DB_TYPE_INTEGER:
5886  if (OR_CHECK_SHORT_OVERFLOW (db_get_int (src)))
5887  {
5888  err = ER_FAILED;
5889  break;
5890  }
5891  db_make_short (target, (short) db_get_int (src));
5892  break;
5893  case DB_TYPE_BIGINT:
5895  {
5896  err = ER_FAILED;
5897  break;
5898  }
5899  db_make_short (target, (short) db_get_bigint (src));
5900  break;
5901  case DB_TYPE_FLOAT:
5902  {
5903  float i = 0;
5904  const float val = db_get_float (src);
5905  if (OR_CHECK_SHORT_OVERFLOW (val))
5906  {
5907  err = ER_FAILED;
5908  break;
5909  }
5910  if (modff (val, &i) != 0)
5911  {
5912  err = ER_FAILED;
5913  break;
5914  }
5915  db_make_short (target, (short) i);
5916  break;
5917  }
5918  case DB_TYPE_DOUBLE:
5919  {
5920  double i = 0;
5921  const double val = db_get_double (src);
5922  if (OR_CHECK_SHORT_OVERFLOW (val))
5923  {
5924  err = ER_FAILED;
5925  break;
5926  }
5927  if (modf (val, &i) != 0)
5928  {
5929  err = ER_FAILED;
5930  break;
5931  }
5932  db_make_short (target, (short) i);
5933  break;
5934  }
5935  case DB_TYPE_NUMERIC:
5936  err = numeric_db_value_coerce_from_num_strict ((DB_VALUE *) src, target);
5937  break;
5938  case DB_TYPE_CHAR:
5939  case DB_TYPE_VARCHAR:
5940  case DB_TYPE_NCHAR:
5941  case DB_TYPE_VARNCHAR:
5942  {
5943  double num_value = 0.0, i = 0.0;
5944  DB_DATA_STATUS data_stat = DATA_STATUS_OK;
5945  if (tp_atof (src, &num_value, &data_stat) != NO_ERROR)
5946  {
5947  err = ER_FAILED;
5948  break;
5949  }
5950  if (data_stat != DATA_STATUS_OK || OR_CHECK_SHORT_OVERFLOW (num_value))
5951  {
5952  err = ER_FAILED;
5953  break;
5954  }
5955  if (modf (num_value, &i) != 0)
5956  {
5957  err = ER_FAILED;
5958  break;
5959  }
5960  db_make_short (target, (short) i);
5961  break;
5962  }
5963  default:
5964  err = ER_FAILED;
5965  break;
5966  }
5967  break;
5968 
5969  case DB_TYPE_INTEGER:
5970  switch (original_type)
5971  {
5972  case DB_TYPE_SHORT:
5973  db_make_int (target, (int) db_get_short (src));
5974  err = NO_ERROR;
5975  break;
5976  case DB_TYPE_MONETARY:
5977  {
5978  double i = 0;
5979  const double val = db_get_monetary (src)->amount;
5980  if (OR_CHECK_INT_OVERFLOW (val))
5981  {
5982  err = ER_FAILED;
5983  break;
5984  }
5985  if (modf (val, &i) != 0)
5986  {
5987  err = ER_FAILED;
5988  break;
5989  }
5990  db_make_int (target, (int) i);
5991  break;
5992  }
5993  case DB_TYPE_BIGINT:
5995  {
5996  err = ER_FAILED;
5997  break;
5998  }
5999  db_make_int (target, (int) db_get_bigint (src));
6000  break;
6001  case DB_TYPE_FLOAT:
6002  {
6003  float i = 0;
6004  const float val = db_get_float (src);
6005  if (OR_CHECK_INT_OVERFLOW (val))
6006  {
6007  err = ER_FAILED;
6008  break;
6009  }
6010  if (modff (val, &i) != 0)
6011  {
6012  err = ER_FAILED;
6013  break;
6014  }
6015  db_make_int (target, (int) i);
6016  break;
6017  }
6018  case DB_TYPE_DOUBLE:
6019  {
6020  double i = 0;
6021  const double val = db_get_double (src);
6022  if (OR_CHECK_INT_OVERFLOW (val))
6023  {
6024  err = ER_FAILED;
6025  break;
6026  }
6027  if (modf (val, &i) != 0)
6028  {
6029  err = ER_FAILED;
6030  break;
6031  }
6032  db_make_int (target, (int) i);
6033  break;
6034  }
6035  case DB_TYPE_NUMERIC:
6036  err = numeric_db_value_coerce_from_num_strict ((DB_VALUE *) src, target);
6037  break;
6038  case DB_TYPE_CHAR:
6039  case DB_TYPE_VARCHAR:
6040  case DB_TYPE_NCHAR:
6041  case DB_TYPE_VARNCHAR:
6042  {
6043  double num_value = 0.0, i = 0.0;
6044  DB_DATA_STATUS data_stat = DATA_STATUS_OK;
6045  if (tp_atof (src, &num_value, &data_stat) != NO_ERROR)
6046  {
6047  err = ER_FAILED;
6048  break;
6049  }
6050  if (data_stat != DATA_STATUS_OK || OR_CHECK_INT_OVERFLOW (num_value))
6051  {
6052  err = ER_FAILED;
6053  break;
6054  }
6055  if (modf (num_value, &i) != 0)
6056  {
6057  err = ER_FAILED;
6058  break;
6059  }
6060  db_make_int (target, (int) i);
6061  break;
6062  }
6063  default:
6064  err = ER_FAILED;
6065  break;
6066  }
6067  break;
6068 
6069  case DB_TYPE_BIGINT:
6070  switch (original_type)
6071  {
6072  case DB_TYPE_SHORT:
6073  db_make_bigint (target, db_get_short (src));
6074  break;
6075  case DB_TYPE_INTEGER:
6076  db_make_bigint (target, db_get_int (src));
6077  break;
6078  case DB_TYPE_MONETARY:
6079  {
6080  double i = 0;
6081  const double val = db_get_monetary (src)->amount;
6082  if (OR_CHECK_BIGINT_OVERFLOW (val))
6083  {
6084  err = ER_FAILED;
6085  break;
6086  }
6087  if (modf (val, &i) != 0)
6088  {
6089  err = ER_FAILED;
6090  break;
6091  }
6092  db_make_bigint (target, (DB_BIGINT) i);
6093  break;
6094  }
6095  break;
6096  case DB_TYPE_FLOAT:
6097  {
6098  float i = 0;
6099  const float val = db_get_float (src);
6100  if (OR_CHECK_BIGINT_OVERFLOW (val))
6101  {
6102  err = ER_FAILED;
6103  break;
6104  }
6105  if (modff (val, &i) != 0)
6106  {
6107  err = ER_FAILED;
6108  break;
6109  }
6110  db_make_bigint (target, (DB_BIGINT) i);
6111  break;
6112  }
6113  case DB_TYPE_DOUBLE:
6114  {
6115  double i = 0;
6116  const double val = db_get_double (src);
6117  if (OR_CHECK_BIGINT_OVERFLOW (val))
6118  {
6119  err = ER_FAILED;
6120  break;
6121  }
6122  if (modf (val, &i) != 0)
6123  {
6124  err = ER_FAILED;
6125  break;
6126  }
6127  db_make_bigint (target, (DB_BIGINT) i);
6128  break;
6129  }
6130  case DB_TYPE_NUMERIC:
6131  err = numeric_db_value_coerce_from_num_strict ((DB_VALUE *) src, target);
6132  break;
6133  case DB_TYPE_CHAR:
6134  case DB_TYPE_VARCHAR:
6135  case DB_TYPE_NCHAR:
6136  case DB_TYPE_VARNCHAR:
6137  {
6138  double num_value = 0.0, i = 0.0;
6139  DB_DATA_STATUS data_stat = DATA_STATUS_OK;
6140  if (tp_atof (src, &num_value, &data_stat) != NO_ERROR)
6141  {
6142  err = ER_FAILED;
6143  break;
6144  }
6145  if (data_stat != DATA_STATUS_OK || OR_CHECK_BIGINT_OVERFLOW (num_value))
6146  {
6147  err = ER_FAILED;
6148  break;
6149  }
6150  if (modf (num_value, &i) != 0)
6151  {
6152  err = ER_FAILED;
6153  break;
6154  }
6155  db_make_bigint (target, (DB_BIGINT) i);
6156  break;
6157  }
6158  default:
6159  err = ER_FAILED;
6160  break;
6161  }
6162  break;
6163 
6164  case DB_TYPE_FLOAT:
6165  switch (original_type)
6166  {
6167  case DB_TYPE_SHORT:
6168  db_make_float (target, (float) db_get_short (src));
6169  break;
6170  case DB_TYPE_INTEGER:
6171  db_make_float (target, (float) db_get_int (src));
6172  break;
6173  case DB_TYPE_BIGINT:
6174  db_make_float (target, (float) db_get_bigint (src));
6175  break;
6176  case DB_TYPE_NUMERIC:
6177  err = numeric_db_value_coerce_from_num_strict ((DB_VALUE *) src, target);
6178  break;
6179  case DB_TYPE_CHAR:
6180  case DB_TYPE_VARCHAR:
6181  case DB_TYPE_NCHAR:
6182  case DB_TYPE_VARNCHAR:
6183  {
6184  double num_value = 0.0;
6185  DB_DATA_STATUS data_stat = DATA_STATUS_OK;
6186 
6187  if (tp_atof (src, &num_value, &data_stat) != NO_ERROR)
6188  {
6189  err = ER_FAILED;
6190  break;
6191  }
6192 
6193  if (data_stat != DATA_STATUS_OK || OR_CHECK_FLOAT_OVERFLOW (num_value))
6194  {
6195  err = ER_FAILED;
6196  break;
6197  }
6198  db_make_float (target, (float) num_value);
6199  break;
6200  }
6201  default:
6202  err = ER_FAILED;
6203  break;
6204  }
6205  break;
6206 
6207  case DB_TYPE_DOUBLE:
6208  switch (original_type)
6209  {
6210  case DB_TYPE_SHORT:
6211  db_make_double (target, (double) db_get_short (src));
6212  break;
6213  case DB_TYPE_INTEGER:
6214  db_make_double (target, (double) db_get_int (src));
6215  break;
6216  case DB_TYPE_BIGINT:
6217  db_make_double (target, (double) db_get_bigint (src));
6218  break;
6219  case DB_TYPE_FLOAT:
6220  db_make_double (target, (double) db_get_float (src));
6221  break;
6222  case DB_TYPE_MONETARY:
6223  db_make_double (target, db_get_monetary (src)->amount);
6224  break;
6225  case DB_TYPE_NUMERIC:
6226  err = numeric_db_value_coerce_from_num_strict ((DB_VALUE *) src, target);
6227  break;
6228  case DB_TYPE_CHAR:
6229  case DB_TYPE_VARCHAR:
6230  case DB_TYPE_NCHAR:
6231  case DB_TYPE_VARNCHAR:
6232  {
6233  DB_DATA_STATUS data_stat = DATA_STATUS_OK;
6234  double num_value = 0.0;
6235  if (tp_atof (src, &num_value, &data_stat) != NO_ERROR)
6236  {
6237  err = ER_FAILED;
6238  break;
6239  }
6240  if (data_stat != DATA_STATUS_OK)
6241  {
6242  err = ER_FAILED;
6243  break;
6244  }
6245  db_make_double (target, num_value);
6246  break;
6247  }
6248  default:
6249  err = ER_FAILED;
6250  break;
6251  }
6252  break;
6253 
6254  case DB_TYPE_NUMERIC:
6255  switch (original_type)
6256  {
6257  case DB_TYPE_CHAR:
6258  case DB_TYPE_VARCHAR:
6259  case DB_TYPE_NCHAR:
6260  case DB_TYPE_VARNCHAR:
6261  {
6262  if (tp_atonumeric (src, target) != NO_ERROR)
6263  {
6264  err = ER_FAILED;
6265  }
6266  break;
6267  }
6268  case DB_TYPE_SHORT:
6269  case DB_TYPE_INTEGER:
6270  case DB_TYPE_BIGINT:
6271  case DB_TYPE_NUMERIC:
6272  {
6273  DB_DATA_STATUS data_stat = DATA_STATUS_OK;
6274  err = numeric_db_value_coerce_to_num ((DB_VALUE *) src, target, &data_stat);
6275  if (data_stat != DATA_STATUS_OK)
6276  {
6277  err = ER_FAILED;
6278  break;
6279  }
6280  break;
6281  }
6282  default:
6283  err = ER_FAILED;
6284  break;
6285  }
6286  break;
6287 
6288  case DB_TYPE_MONETARY:
6289  switch (original_type)
6290  {
6291  case DB_TYPE_SHORT:
6292  db_make_monetary (target, DB_CURRENCY_DEFAULT, (double) db_get_short (src));
6293  break;
6294  case DB_TYPE_INTEGER:
6295  db_make_monetary (target, DB_CURRENCY_DEFAULT, (double) db_get_int (src));
6296  break;
6297  case DB_TYPE_BIGINT:
6298  db_make_monetary (target, DB_CURRENCY_DEFAULT, (double) db_get_bigint (src));
6299  break;
6300  case DB_TYPE_FLOAT:
6301  db_make_monetary (target, DB_CURRENCY_DEFAULT, (double) db_get_float (src));
6302  break;
6303  case DB_TYPE_DOUBLE:
6305  break;
6306  case DB_TYPE_NUMERIC:
6307  err = numeric_db_value_coerce_from_num_strict ((DB_VALUE *) src, target);
6308  break;
6309  case DB_TYPE_CHAR:
6310  case DB_TYPE_VARCHAR:
6311  case DB_TYPE_NCHAR:
6312  case DB_TYPE_VARNCHAR:
6313  {
6314  double num_value = 0.0;
6315  DB_DATA_STATUS data_stat = DATA_STATUS_OK;
6316  if (tp_atof (src, &num_value, &data_stat) != NO_ERROR)
6317  {
6318  err = ER_FAILED;
6319  break;
6320  }
6321  if (data_stat == DATA_STATUS_TRUNCATED || data_stat == DATA_STATUS_NOT_CONSUMED)
6322  {
6323  err = ER_FAILED;
6324  break;
6325  }
6326  db_make_monetary (target, DB_CURRENCY_DEFAULT, num_value);
6327  break;
6328  }
6329  default:
6330  err = ER_FAILED;
6331  break;
6332  }
6333  break;
6334 
6335  case DB_TYPE_TIME:
6336  switch (original_type)
6337  {
6338  case DB_TYPE_CHAR:
6339  case DB_TYPE_VARCHAR:
6340  case DB_TYPE_NCHAR:
6341  case DB_TYPE_VARNCHAR:
6342  {
6343  DB_TIME time = 0;
6344  if (tp_atotime (src, &time) != NO_ERROR)
6345  {
6346  err = ER_FAILED;
6347  break;
6348  }
6349  db_value_put_encoded_time (target, &time);
6350  break;
6351  }
6352  default:
6353  err = ER_FAILED;
6354  break;
6355  }
6356  break;
6357 
6358  case DB_TYPE_DATE:
6359  switch (original_type)
6360  {
6361  case DB_TYPE_CHAR:
6362  case DB_TYPE_VARCHAR:
6363  case DB_TYPE_NCHAR:
6364  case DB_TYPE_VARNCHAR:
6365  {
6366  DB_DATE date = 0;
6367 
6368  if (tp_atodate (src, &date) != NO_ERROR)
6369  {
6370  err = ER_FAILED;
6371  break;
6372  }
6373  db_value_put_encoded_date (target, &date);
6374  break;
6375  }
6376  case DB_TYPE_DATETIME:
6377  {
6378  DB_DATETIME *src_dt = NULL;
6379 
6380  src_dt = db_get_datetime (src);
6381  if (src_dt->time != 0)
6382  {
6383  /* only "downcast" if time is 0 */
6384  err = ER_FAILED;
6385  break;
6386  }
6387  db_value_put_encoded_date (target, (DB_DATE *) (&src_dt->date));
6388  break;
6389  }
6390  case DB_TYPE_DATETIMELTZ:
6391  case DB_TYPE_DATETIMETZ:
6392  {
6393  DB_DATETIME *utc_dt_p;
6394  DB_DATETIMETZ *dt_tz_p;
6395  DB_DATETIME local_dt;
6396  TZ_ID tz_id;
6397 
6398  /* DATETIMELTZ and DATETIMETZ store in UTC, convert to session */
6399  if (original_type == DB_TYPE_DATETIMELTZ)
6400  {
6401  utc_dt_p = db_get_datetime (src);
6402  if (tz_create_session_tzid_for_datetime (utc_dt_p, true, &tz_id) != NO_ERROR)
6403  {
6404  err = ER_FAILED;
6405  break;
6406  }
6407  }
6408  else
6409  {
6410  dt_tz_p = db_get_datetimetz (src);
6411  utc_dt_p = &dt_tz_p->datetime;
6412  tz_id = dt_tz_p->tz_id;
6413  }
6414 
6415  if (tz_utc_datetimetz_to_local (utc_dt_p, &tz_id, &local_dt) != NO_ERROR)
6416  {
6417  err = ER_FAILED;
6418  break;
6419  }
6420 
6421  if (local_dt.time != 0)
6422  {
6423  /* only "downcast" if time is 0 */
6424  err = ER_FAILED;
6425  break;
6426  }
6427 
6428  db_value_put_encoded_date (target, (DB_DATE *) (&local_dt.date));
6429  break;
6430  }
6431  case DB_TYPE_TIMESTAMP:
6432  case DB_TYPE_TIMESTAMPLTZ:
6433  {
6434  DB_DATE date = 0;
6435  DB_TIME time = 0;
6436  DB_TIMESTAMP *ts = NULL;
6437 
6438  ts = db_get_timestamp (src);
6439  (void) db_timestamp_decode_ses (ts, &date, &time);
6440  if (time != 0)
6441  {
6442  /* only "downcast" if time is 0 */
6443  err = ER_FAILED;
6444  break;
6445  }
6446  db_value_put_encoded_date (target, &date);
6447  break;
6448  }
6449  case DB_TYPE_TIMESTAMPTZ:
6450  {
6451  DB_DATE date = 0;
6452  DB_TIME time = 0;
6453  DB_TIMESTAMPTZ *ts_tz = NULL;
6454 
6455  ts_tz = db_get_timestamptz (src);
6456  err = db_timestamp_decode_w_tz_id (&ts_tz->timestamp, &ts_tz->tz_id, &date, &time);
6457  if (err != NO_ERROR || time != 0)
6458  {
6459  /* only "downcast" if time is 0 */
6460  err = ER_FAILED;
6461  break;
6462  }
6463  db_value_put_encoded_date (target, &date);
6464  break;
6465  }
6466  default:
6467  err = ER_FAILED;
6468  break;
6469  }
6470  break;
6471 
6472  case DB_TYPE_DATETIME:
6473  switch (original_type)
6474  {
6475  case DB_TYPE_DATE:
6476  {
6477  DB_DATETIME datetime = { 0, 0 };
6478  datetime.date = *db_get_date (src);
6479  datetime.time = 0;
6480  db_make_datetime (target, &datetime);
6481  break;
6482  }
6483  case DB_TYPE_DATETIMETZ:
6484  {
6485  DB_DATETIMETZ *dt_tz = db_get_datetimetz (src);
6486  db_make_datetime (target, &dt_tz->datetime);
6487  break;
6488  }
6489  case DB_TYPE_DATETIMELTZ:
6490  {
6491  DB_DATETIME *dt = db_get_datetime (src);
6492  db_make_datetime (target, dt);
6493  break;
6494  }
6495  case DB_TYPE_VARCHAR:
6496  case DB_TYPE_CHAR:
6497  case DB_TYPE_NCHAR:
6498  case DB_TYPE_VARNCHAR:
6499  {
6500  DB_DATETIME datetime = { 0, 0 };
6501  if (tp_atoudatetime (src, &datetime) != NO_ERROR)
6502  {
6503  err = ER_FAILED;
6504  break;
6505  }
6506  db_make_datetime (target, &datetime);
6507  break;
6508  }
6509  case DB_TYPE_TIMESTAMP:
6510  case DB_TYPE_TIMESTAMPLTZ:
6511  {
6512  DB_DATETIME datetime = { 0, 0 };
6513  DB_TIMESTAMP *utime = db_get_timestamp (src);
6514  DB_DATE date;
6515  DB_TIME time;
6516 
6517  if (db_timestamp_decode_ses (utime, &date, &time) != NO_ERROR)
6518  {
6519  err = ER_FAILED;
6520  break;
6521  }
6522  datetime.time = time * 1000;
6523  datetime.date = date;
6524  db_make_datetime (target, &datetime);
6525  break;
6526  }
6527  case DB_TYPE_TIMESTAMPTZ:
6528  {
6529  DB_DATETIME datetime = { 0, 0 };
6530  DB_DATE date;
6531  DB_TIME time;
6532  DB_TIMESTAMPTZ *ts_tz = db_get_timestamptz (src);
6533 
6534  if (db_timestamp_decode_w_tz_id (&ts_tz->timestamp, &ts_tz->tz_id, &date, &time) != NO_ERROR)
6535  {
6536  err = ER_FAILED;
6537  break;
6538  }
6539 
6540  datetime.time = time * 1000;
6541  datetime.date = date;
6542  db_make_datetime (target, &datetime);
6543  break;
6544  }
6545  default:
6546  err = ER_FAILED;
6547  break;
6548  }
6549  break;
6550 
6551  case DB_TYPE_DATETIMETZ:
6552  switch (original_type)
6553  {
6554  case DB_TYPE_DATE:
6555  case DB_TYPE_DATETIME:
6556  {
6558 
6559  if (original_type == DB_TYPE_DATE)
6560  {
6561  dt_tz.datetime.date = *db_get_date (src);
6562  dt_tz.datetime.time = 0;
6563  }
6564  else
6565  {
6566  dt_tz.datetime = *db_get_datetime (src);
6567  }
6568 
6569  err = tz_create_datetimetz_from_ses (&(dt_tz.datetime), &dt_tz);
6570  if (err == NO_ERROR)
6571  {
6572  db_make_datetimetz (target, &dt_tz);
6573  }
6574  break;
6575  }
6576 
6577  case DB_TYPE_DATETIMELTZ:
6578  {
6580  DB_DATETIME *dt = db_get_datetime (src);
6581 
6582  dt_tz.datetime = *dt;
6583  err = tz_create_session_tzid_for_datetime (dt, false, &dt_tz.tz_id);
6584  if (err == NO_ERROR)
6585  {
6586  db_make_datetimetz (target, &dt_tz);
6587  }
6588  break;
6589  }
6590  case DB_TYPE_VARCHAR:
6591  case DB_TYPE_CHAR:
6592  case DB_TYPE_NCHAR:
6593  case DB_TYPE_VARNCHAR:
6594  {
6596 
6597  if (tp_atodatetimetz (src, &dt_tz) != NO_ERROR)
6598  {
6599  err = ER_FAILED;
6600  break;
6601  }
6602 
6603  db_make_datetimetz (target, &dt_tz);
6604  }
6605  break;
6606  case DB_TYPE_TIMESTAMP:
6607  case DB_TYPE_TIMESTAMPLTZ:
6608  {
6610  DB_TIMESTAMP *utime = db_get_timestamp (src);
6611  DB_DATE date;
6612  DB_TIME time;
6613 
6614  /* convert DT to TS in UTC reference */
6615  db_timestamp_decode_utc (utime, &date, &time);
6616  dt_tz.datetime.date = date;
6617  dt_tz.datetime.time = time * 1000;
6618  err = tz_create_session_tzid_for_datetime (&dt_tz.datetime, true, &(dt_tz.tz_id));
6619  if (err == NO_ERROR)
6620  {
6621  db_make_datetimetz (target, &dt_tz);
6622  }
6623  break;
6624  }
6625  case DB_TYPE_TIMESTAMPTZ:
6626  {
6628  DB_TIMESTAMPTZ *ts_tz = db_get_timestamptz (src);
6629  DB_DATE date;
6630  DB_TIME time;
6631 
6632  (void) db_timestamp_decode_utc (&ts_tz->timestamp, &date, &time);
6633  dt_tz.datetime.time = time * 1000;
6634  dt_tz.datetime.date = date;
6635  dt_tz.tz_id = ts_tz->tz_id;
6636  db_make_datetimetz (target, &dt_tz);
6637  break;
6638  }
6639  default:
6640  err = ER_FAILED;
6641  break;
6642  }
6643  break;
6644 
6645  case DB_TYPE_DATETIMELTZ:
6646  switch (original_type)
6647  {
6648  case DB_TYPE_DATE:
6649  case DB_TYPE_DATETIME:
6650  {
6651  DB_DATETIME datetime;
6652  DB_DATETIMETZ dt_tz;
6653 
6654  if (original_type == DB_TYPE_DATE)
6655  {
6656  datetime.date = *db_get_date (src);
6657  datetime.time = 0;
6658  }
6659  else
6660  {
6661  datetime = *db_get_datetime (src);
6662  }
6663 
6664  err = tz_create_datetimetz_from_ses (&datetime, &dt_tz);
6665  if (err != NO_ERROR)
6666  {
6667  err = ER_FAILED;
6668  break;
6669  }
6670 
6671  db_make_datetimeltz (target, &dt_tz.datetime);
6672  break;
6673  }
6674  case DB_TYPE_DATETIMETZ:
6675  {
6676  DB_DATETIMETZ *dt_tz = db_get_datetimetz (src);
6677 
6678  /* copy datetime (UTC) */
6679  db_make_datetimeltz (target, &dt_tz->datetime);
6680  break;
6681  }
6682  case DB_TYPE_VARCHAR:
6683  case DB_TYPE_CHAR:
6684  case DB_TYPE_NCHAR:
6685  case DB_TYPE_VARNCHAR:
6686  {
6688 
6689  if (tp_atodatetimetz (src, &dt_tz) != NO_ERROR)
6690  {
6691  err = ER_FAILED;
6692  break;
6693  }
6694  db_make_datetimeltz (target, &dt_tz.datetime);
6695  break;
6696  }
6697  case DB_TYPE_TIMESTAMP:
6698  case DB_TYPE_TIMESTAMPLTZ:
6699  {
6700  DB_DATETIME datetime = { 0, 0 };
6701  DB_TIMESTAMP *utime = db_get_timestamp (src);
6702  DB_DATE date;
6703  DB_TIME time;
6704 
6705  (void) db_timestamp_decode_utc (utime, &date, &time);
6706  datetime.time = time * 1000;
6707  datetime.date = date;
6708  db_make_datetimeltz (target, &datetime);
6709  break;
6710  }
6711  case DB_TYPE_TIMESTAMPTZ:
6712  {
6713  DB_DATETIME datetime = { 0, 0 };
6714  DB_TIMESTAMPTZ *ts_tz = db_get_timestamptz (src);
6715  DB_DATE date;
6716  DB_TIME time;
6717 
6718  (void) db_timestamp_decode_utc (&ts_tz->timestamp, &date, &time);
6719  datetime.time = time * 1000;
6720  datetime.date = date;
6721  db_make_datetimeltz (target, &datetime);
6722  break;
6723  }
6724  default:
6725  err = ER_FAILED;
6726  break;
6727  }
6728  break;
6729 
6730  case DB_TYPE_TIMESTAMP:
6731  switch (original_type)
6732  {
6733  case DB_TYPE_VARCHAR:
6734  case DB_TYPE_CHAR:
6735  case DB_TYPE_NCHAR:
6736  case DB_TYPE_VARNCHAR:
6737  {
6738  DB_TIMESTAMP ts = 0;
6739 
6740  if (tp_atoutime (src, &ts) != NO_ERROR)
6741  {
6742  err = ER_FAILED;
6743  break;
6744  }
6745  db_make_timestamp (target, ts);
6746  break;
6747  }
6748  case DB_TYPE_DATETIME:
6749  {
6750  DB_DATETIME dt = *db_get_datetime (src);
6751  DB_DATE date = dt.date;
6752  DB_TIME time = dt.time / 1000;
6753  DB_TIMESTAMP ts = 0;
6754 
6755  if (db_timestamp_encode_ses (&date, &time, &ts, NULL) != NO_ERROR)
6756  {
6757  err = ER_FAILED;
6758  break;
6759  }
6760  db_make_timestamp (target, ts);
6761  break;
6762  }
6763  case DB_TYPE_DATETIMELTZ:
6764  {
6765  DB_DATETIME dt = *db_get_datetime (src);
6766  DB_DATE date = dt.date;
6767  DB_TIME time = dt.time / 1000;
6768  DB_TIMESTAMP ts = 0;
6769 
6770  if (db_timestamp_encode_utc (&date, &time, &ts) != NO_ERROR)
6771  {
6772  err = ER_FAILED;
6773  break;
6774  }
6775  db_make_timestamp (target, ts);
6776  break;
6777  }
6778 
6779  case DB_TYPE_DATETIMETZ:
6780  {
6781  DB_DATETIMETZ *dt_tz = db_get_datetimetz (src);
6782  DB_DATE date = dt_tz->datetime.date;
6783  DB_TIME time = dt_tz->datetime.time / 1000;
6784  DB_TIMESTAMP ts = 0;
6785 
6786  if (db_timestamp_encode_utc (&date, &time, &ts) != NO_ERROR)
6787  {
6788  err = ER_FAILED;
6789  break;
6790  }
6791  db_make_timestamp (target, ts);
6792  break;
6793  }
6794 
6795  case DB_TYPE_DATE:
6796  {
6797  DB_TIME tm = 0;
6798  DB_DATE date = *db_get_date (src);
6799  DB_TIMESTAMP ts = 0;
6800 
6801  db_time_encode (&tm, 0, 0, 0);
6802  if (db_timestamp_encode_ses (&date, &tm, &ts, NULL) != NO_ERROR)
6803  {
6804  err = ER_FAILED;
6805  break;
6806  }
6807  db_make_timestamp (target, ts);
6808  break;
6809  }
6810 
6811  case DB_TYPE_TIMESTAMPTZ:
6812  {
6813  DB_TIMESTAMPTZ *ts_tz = db_get_timestamptz (src);
6814 
6815  /* copy timestamp value (UTC) */
6816  db_make_timestamp (target, ts_tz->timestamp);
6817  break;
6818  }
6819 
6820  case DB_TYPE_TIMESTAMPLTZ:
6821  {
6822  DB_TIMESTAMP *ts = db_get_timestamp (src);
6823 
6824  /* copy timestamp value (UTC) */
6825  db_make_timestamp (target, *ts);
6826  break;
6827  }
6828 
6829  default:
6830  err = ER_FAILED;
6831  break;
6832  }
6833  break;
6834 
6835  case DB_TYPE_TIMESTAMPLTZ:
6836  switch (original_type)
6837  {
6838  case DB_TYPE_VARCHAR:
6839  case DB_TYPE_CHAR:
6840  case DB_TYPE_NCHAR:
6841  case DB_TYPE_VARNCHAR:
6842  {
6843  DB_TIMESTAMPTZ ts_tz = { 0, 0 };
6844 
6845  if (tp_atotimestamptz (src, &ts_tz) != NO_ERROR)
6846  {
6847  err = ER_FAILED;
6848  break;
6849  }
6850  db_make_timestampltz (target, ts_tz.timestamp);
6851  break;
6852  }
6853  case DB_TYPE_DATETIME:
6854  {
6855  DB_DATETIME dt = *db_get_datetime (src);
6856  DB_DATE date = dt.date;
6857  DB_TIME time = dt.time / 1000;
6858  DB_TIMESTAMP ts = 0;
6859 
6860  if (db_timestamp_encode_ses (&date, &time, &ts, NULL) != NO_ERROR)
6861  {
6862  err = ER_FAILED;
6863  break;
6864  }
6865  db_make_timestampltz (target, ts);
6866  break;
6867  }
6868  case DB_TYPE_DATETIMELTZ:
6869  {
6870  DB_DATETIME dt = *db_get_datetime (src);
6871  DB_DATE date = dt.date;
6872  DB_TIME time = dt.time / 1000;
6873  DB_TIMESTAMP ts = 0;
6874 
6875  if (db_timestamp_encode_utc (&date, &time, &ts) != NO_ERROR)
6876  {
6877  err = ER_FAILED;
6878  break;
6879  }
6880  db_make_timestampltz (target, ts);
6881  break;
6882  }
6883 
6884  case DB_TYPE_DATETIMETZ:
6885  {
6886  DB_DATETIMETZ *dt_tz = db_get_datetimetz (src);
6887  DB_DATE date = dt_tz->datetime.date;
6888  DB_TIME time = dt_tz->datetime.time / 1000;
6889  DB_TIMESTAMP ts = 0;
6890 
6891  if (db_timestamp_encode_utc (&date, &time, &ts) != NO_ERROR)
6892  {
6893  err = ER_FAILED;
6894  break;
6895  }
6896  db_make_timestampltz (target, ts);
6897  break;
6898  }
6899 
6900  case DB_TYPE_DATE:
6901  {
6902  DB_TIME tm = 0;
6903  DB_DATE date = *db_get_date (src);
6904  DB_TIMESTAMP ts = 0;
6905 
6906  db_time_encode (&tm, 0, 0, 0);
6907  if (db_timestamp_encode_ses (&date, &tm, &ts, NULL) != NO_ERROR)
6908  {
6909  err = ER_FAILED;
6910  break;
6911  }
6912  db_make_timestampltz (target, ts);
6913  break;
6914  }
6915 
6916  case DB_TYPE_TIMESTAMP:
6917  {
6918  DB_TIMESTAMP *ts = db_get_timestamp (src);
6919 
6920  /* copy val timestamp value (UTC) */
6921  db_make_timestampltz (target, *ts);
6922  break;
6923  }
6924 
6925  case DB_TYPE_TIMESTAMPTZ:
6926  {
6927  DB_TIMESTAMPTZ *ts_tz = db_get_timestamptz (src);
6928 
6929  /* copy val timestamp value (UTC) */
6930  db_make_timestampltz (target, ts_tz->timestamp);
6931  break;
6932  }
6933 
6934  default:
6935  err = ER_FAILED;
6936  break;
6937  }
6938  break;
6939 
6940  case DB_TYPE_TIMESTAMPTZ:
6941  switch (original_type)
6942  {
6943  case DB_TYPE_VARCHAR:
6944  case DB_TYPE_CHAR:
6945  case DB_TYPE_NCHAR:
6946  case DB_TYPE_VARNCHAR:
6947  {
6948  DB_TIMESTAMPTZ ts_tz = { 0, 0 };
6949 
6950  if (tp_atotimestamptz (src, &ts_tz) != NO_ERROR)
6951  {
6952  err = ER_FAILED;
6953  break;
6954  }
6955  db_make_timestamptz (target, &ts_tz);
6956  break;
6957  }
6958  case DB_TYPE_DATETIME:
6959  {
6960  DB_TIMESTAMPTZ ts_tz = { 0, 0 };
6961  DB_DATETIME dt = *db_get_datetime (src);
6962  DB_DATE date = dt.date;
6963  DB_TIME time = dt.time / 1000;
6964 
6965  if (db_timestamp_encode_ses (&date, &time, &ts_tz.timestamp, &ts_tz.tz_id) != NO_ERROR)
6966  {
6967  err = ER_FAILED;
6968  break;
6969  }
6970  db_make_timestamptz (target, &ts_tz);
6971  break;
6972  }
6973 
6974  case DB_TYPE_DATETIMELTZ:
6975  {
6976  DB_TIMESTAMPTZ ts_tz = { 0, 0 };
6977  DB_DATETIME dt = *db_get_datetime (src);
6978  DB_DATE date = dt.date;
6979  DB_TIME time = dt.time / 1000;
6980 
6981  if (db_timestamp_encode_utc (&date, &time, &ts_tz.timestamp) != NO_ERROR)
6982  {
6983  err = ER_FAILED;
6984  break;
6985  }
6986  ts_tz.tz_id = *tz_get_utc_tz_id ();
6987  db_make_timestamptz (target, &ts_tz);
6988  break;
6989  }
6990 
6991  case DB_TYPE_DATETIMETZ:
6992  {
6993  DB_TIMESTAMPTZ ts_tz = { 0, 0 };
6994  DB_DATETIMETZ *dt_tz = db_get_datetimetz (src);
6995  DB_DATE date = dt_tz->datetime.date;
6996  DB_TIME time = dt_tz->datetime.time / 1000;
6997 
6998  if (db_timestamp_encode_utc (&date, &time, &ts_tz.timestamp) != NO_ERROR)
6999  {
7000  err = ER_FAILED;
7001  break;
7002  }
7003  ts_tz.tz_id = dt_tz->tz_id;
7004  db_make_timestamptz (target, &ts_tz);
7005  break;
7006  }
7007 
7008  case DB_TYPE_DATE:
7009  {
7010  DB_TIMESTAMPTZ ts_tz = { 0, 0 };
7011  DB_TIME tm = 0;
7012  DB_DATE date = *db_get_date (src);
7013 
7014  db_time_encode (&tm, 0, 0, 0);
7015  if (db_timestamp_encode_ses (&date, &tm, &ts_tz.timestamp, &ts_tz.tz_id) != NO_ERROR)
7016  {
7017  err = ER_FAILED;
7018  break;
7019  }
7020  db_make_timestamptz (target, &ts_tz);
7021  break;
7022  }
7023 
7024  case DB_TYPE_TIMESTAMP:
7025  case DB_TYPE_TIMESTAMPLTZ:
7026  {
7027  DB_TIMESTAMPTZ ts_tz = { 0, 0 };
7028 
7029  ts_tz.timestamp = *db_get_timestamp (src);
7030 
7031  err = tz_create_session_tzid_for_timestamp (&(ts_tz.timestamp), &(ts_tz.tz_id));
7032 
7033  if (err != NO_ERROR)
7034  {
7035  err = ER_FAILED;
7036  break;
7037  }
7038  db_make_timestamptz (target, &ts_tz);
7039  break;
7040  }
7041 
7042  default:
7043  err = ER_FAILED;
7044  break;
7045  }
7046  break;
7047  default:
7048  err = ER_FAILED;
7049  break;
7050  }
7051 
7052  if (err == ER_FAILED)
7053  {
7054  /* the above code might have set an error message but we don't want to propagate it in this context */
7055  er_clear ();
7056  }
7057 
7058  return err;
7059 }
7060 
7061 /*
7062  * tp_value_coerce_internal - Coerce a value into one of another domain.
7063  * return: error code
7064  * src(in): source value
7065  * dest(out): destination value
7066  * desired_domain(in): destination domain
7067  * coercion_mode(in): flag for the coercion mode
7068  * do_domain_select(in): flag for select appropriate domain from
7069  * 'desired_domain'
7070  * preserve_domain(in): flag to preserve dest's domain
7071  */
7072 static TP_DOMAIN_STATUS
7073 tp_value_cast_internal (const DB_VALUE * src, DB_VALUE * dest, const TP_DOMAIN * desired_domain,
7074  const TP_COERCION_MODE coercion_mode, bool do_domain_select, bool preserve_domain)
7075 {
7076  DB_TYPE desired_type, original_type;
7077  int err;
7078  TP_DOMAIN_STATUS status;
7079  TP_DOMAIN *best, *p_tmp_desired_domain;
7080  TP_DOMAIN tmp_desired_domain;
7081  const DB_MONETARY *v_money;
7082  DB_UTIME v_utime;
7083  DB_TIMESTAMPTZ v_timestamptz;
7084  DB_DATETIME v_datetime;
7085  DB_DATETIMETZ v_datetimetz;
7086  DB_TIME v_time;
7087  DB_DATE v_date;
7088  DB_DATA_STATUS data_stat;
7089  DB_VALUE temp, *target;
7090  int hour, minute, second, millisecond;
7091  int year, month, day;
7092  TZ_ID ses_tz_id;
7093 
7094  bool ti = true;
7095  static bool ignore_trailing_space = prm_get_bool_value (PRM_ID_IGNORE_TRAILING_SPACE);
7096 
7097  DB_VALUE src_replacement;
7098 
7099  db_make_null (&src_replacement);
7100 
7101  err = NO_ERROR;
7102  status = DOMAIN_COMPATIBLE;
7103 
7104  if (desired_domain == NULL)
7105  {
7106  db_make_null (dest);
7107  return DOMAIN_INCOMPATIBLE;
7108  }
7109 
7110  /* If more than one destination domain, select the most appropriate */
7111  if (do_domain_select)
7112  {
7113  if (desired_domain->next != NULL)
7114  {
7115  best = tp_domain_select (desired_domain, src, 1, TP_ANY_MATCH);
7116  if (best != NULL)
7117  {
7118  desired_domain = best;
7119  }
7120  }
7121  }
7122  desired_type = TP_DOMAIN_TYPE (desired_domain);
7123 
7124  /* A NULL src is allowed but destination remains NULL, not desired_domain */
7125  if (src == NULL || (original_type = DB_VALUE_TYPE (src)) == DB_TYPE_NULL)
7126  {
7127  if (preserve_domain)
7128  {
7129  db_value_domain_init (dest, desired_type, desired_domain->precision, desired_domain->scale);
7130  db_value_put_null (dest);
7131  }
7132  else
7133  {
7134  db_make_null (dest);
7135  }
7136  return status;
7137  }
7138 
7139  if (desired_type != original_type && original_type == DB_TYPE_JSON)
7140  {
7141  /* TODO this is very hackish,
7142  * we really need to split this function up
7143  */
7144  DB_JSON_TYPE json_type = db_json_get_type (db_get_json_document (src));
7145  JSON_DOC *src_doc = db_get_json_document (src);
7146  bool use_replacement = true;
7147 
7148  switch (json_type)
7149  {
7150  case DB_JSON_DOUBLE:
7151  db_make_double (&src_replacement, db_json_get_double_from_document (src_doc));
7152  break;
7153  case DB_JSON_INT:
7154  db_make_int (&src_replacement, db_json_get_int_from_document (src_doc));
7155  break;
7156  case DB_JSON_BIGINT:
7157  db_make_bigint (&src_replacement, db_json_get_bigint_from_document (src_doc));
7158  break;
7159  case DB_JSON_BOOL:
7160  switch (desired_type)
7161  {
7162  case DB_TYPE_CHAR:
7163  case DB_TYPE_VARCHAR:
7164  case DB_TYPE_NCHAR:
7165  case DB_TYPE_VARNCHAR:
7166  db_make_string (&src_replacement, db_json_get_bool_as_str_from_document (src_doc));
7167  src_replacement.need_clear = true;
7168  break;
7169  default:
7170  db_make_int (&src_replacement, db_json_get_bool_from_document (src_doc) ? 1 : 0);
7171  }
7172  break;
7173  case DB_JSON_STRING:
7174  db_make_string_copy (&src_replacement, db_json_get_string_from_document (src_doc));
7175  break;
7176  default:
7177  use_replacement = false;
7178  /* do nothing */
7179  break;
7180  }
7181 
7182  if (use_replacement)
7183  {
7184  if (src == dest)
7185  {
7186  // if src is equal to dest then JSON_DOC can be deleted after required information was extracted from it
7187  pr_clear_value (dest);
7188  }
7189 
7190  original_type = DB_VALUE_TYPE (&src_replacement);
7191  src = &src_replacement;
7192  }
7193  }
7194 
7195  if (desired_type == original_type)
7196  {
7197  /*
7198  * If there is an easy to check exact match on a non-parameterized
7199  * domain, just do a simple clone of the value.
7200  */
7201  if (!desired_domain->is_parameterized)
7202  {
7203  if (src != dest)
7204  {
7205  pr_clone_value ((DB_VALUE *) src, dest);
7206  pr_clear_value (&src_replacement);
7207  }
7208  return status;
7209  }
7210  else
7211  { /* is parameterized domain */
7212  switch (desired_type)
7213  {
7214  case DB_TYPE_NUMERIC:
7215  if (desired_domain->precision == DB_VALUE_PRECISION (src)
7216  && desired_domain->scale == DB_VALUE_SCALE (src))
7217  {
7218  if (src != dest)
7219  {
7220  pr_clone_value ((DB_VALUE *) src, dest);
7221  }
7222  return (status);
7223  }
7224  break;
7225  case DB_TYPE_OID:
7226  if (src != dest)
7227  {
7228  pr_clone_value ((DB_VALUE *) src, dest);
7229  }
7230  return (status);
7231  case DB_TYPE_JSON:
7232  if (desired_domain->json_validator != NULL
7233  && db_json_validate_doc (desired_domain->json_validator, src->data.json.document) != NO_ERROR)
7234  {
7235  pr_clear_value (&src_replacement);
7236  ASSERT_ERROR ();
7237  return DOMAIN_ERROR;
7238  }
7239  if (src != dest)
7240  {
7241  pr_clone_value (src, dest);
7242  }
7243  pr_clear_value (&src_replacement);
7244  return (status);
7245  default:
7246  /* pr_is_string_type(desired_type) - NEED MORE CONSIDERATION */
7247  break;
7248  }
7249  }
7250  }
7251 
7252  /*
7253  * If the coercion_mode is TP_IMPLICIT_COERCION, check to see if the original
7254  * type can be implicitly coerced to the desired_type.
7255  *
7256  * (Note: This macro only picks up only coercions that are not allowed
7257  * implicitly but are allowed explicitly.)
7258  */
7259  if (coercion_mode == TP_IMPLICIT_COERCION)
7260  {
7261  if (TP_IMPLICIT_COERCION_NOT_ALLOWED (original_type, desired_type))
7262  {
7263  if (preserve_domain)
7264  {
7265  db_value_domain_init (dest, desired_type, desired_domain->precision, desired_domain->scale);
7266  db_value_put_null (dest);
7267  }
7268  else
7269  {
7270  db_make_null (dest);
7271  }
7272 
7273  pr_clear_value (&src_replacement);
7274  return DOMAIN_INCOMPATIBLE;
7275  }
7276  }
7277 
7278  /*
7279  * If src == dest, coerce into a temporary variable and
7280  * handle the conversion before returning.
7281  */
7282  if (src == dest)
7283  {
7284  target = &temp;
7285  }
7286  else
7287  {
7288  target = dest;
7289  }
7290 
7291  /*
7292  * Initialize the destination domain, important for the
7293  * nm_ coercion functions thich take domain information inside the
7294  * destination db value.
7295  */
7296  db_value_domain_init (target, desired_type, desired_domain->precision, desired_domain->scale);
7297 
7298  if (TP_IS_CHAR_TYPE (desired_type))
7299  {
7300  if (desired_domain->collation_flag == TP_DOMAIN_COLL_ENFORCE)
7301  {
7302  if (TP_IS_CHAR_TYPE (original_type))
7303  {
7304  db_string_put_cs_and_collation (target, TP_DOMAIN_CODESET (desired_domain),
7305  TP_DOMAIN_COLLATION (desired_domain));
7306 
7307  /* create a domain from source value */
7308  p_tmp_desired_domain = tp_domain_resolve_value ((DB_VALUE *) src, &tmp_desired_domain);
7309  p_tmp_desired_domain->codeset = TP_DOMAIN_CODESET (desired_domain);
7310  p_tmp_desired_domain->collation_id = TP_DOMAIN_COLLATION (desired_domain);
7311 
7312  desired_domain = p_tmp_desired_domain;
7313  }
7314  else if (TP_IS_SET_TYPE (original_type))
7315  {
7316  TP_DOMAIN *curr_set_dom;
7317  TP_DOMAIN *elem_dom;
7318  TP_DOMAIN *new_elem_dom;
7319  TP_DOMAIN *save_elem_dom_next;
7320 
7321  /* source value already exists, we expect that a collection domain already exists and is cached */
7322  curr_set_dom = tp_domain_resolve_value ((DB_VALUE *) src, NULL);
7323  elem_dom = curr_set_dom->setdomain;
7324  curr_set_dom->setdomain = NULL;
7325 
7326  /* copy only parent collection domain */
7327  p_tmp_desired_domain = tp_domain_copy (curr_set_dom, false);
7328  curr_set_dom->setdomain = elem_dom;
7329  while (elem_dom != NULL)
7330  {
7331  /* create a new domain from this */
7332  save_elem_dom_next = elem_dom->next;
7333  elem_dom->next = NULL;
7334  new_elem_dom = tp_domain_copy (elem_dom, false);
7335  elem_dom->next = save_elem_dom_next;
7336 
7337  if (TP_IS_CHAR_TYPE (TP_DOMAIN_TYPE (elem_dom)))
7338  {
7339  /* for string domains overwrite collation */
7340  new_elem_dom->collation_id = TP_DOMAIN_COLLATION (desired_domain);
7341  new_elem_dom->codeset = TP_DOMAIN_CODESET (desired_domain);
7342  }
7343 
7344  tp_domain_add (&(p_tmp_desired_domain->setdomain), new_elem_dom);
7345  elem_dom = elem_dom->next;
7346  }
7347 
7348  desired_domain = p_tmp_desired_domain;
7349  }
7350  else
7351  {
7352  /* ENUM values are included here (cannot be HV) */
7353  /* source value does not have collation, we leave it as it is */
7354  if (src != dest)
7355  {
7356  pr_clone_value ((DB_VALUE *) src, dest);
7357  }
7358 
7359  pr_clear_value (&src_replacement);
7360  return DOMAIN_COMPATIBLE;
7361  }
7362  desired_type = TP_DOMAIN_TYPE (desired_domain);
7363  }
7364  else if (desired_domain->collation_flag == TP_DOMAIN_COLL_NORMAL)
7365  {
7366  db_string_put_cs_and_collation (target, TP_DOMAIN_CODESET (desired_domain),
7367  TP_DOMAIN_COLLATION (desired_domain));
7368  }
7369  else
7370  {
7371  assert (desired_domain->collation_flag == TP_DOMAIN_COLL_LEAVE);
7372  if (TP_IS_CHAR_TYPE (original_type))
7373  {
7375  }
7376  }
7377  }
7378 
7379  switch (desired_type)
7380  {
7381  case DB_TYPE_SHORT:
7382  switch (original_type)
7383  {
7384  case DB_TYPE_MONETARY:
7385  v_money = db_get_monetary (src);
7386  if (OR_CHECK_SHORT_OVERFLOW (v_money->amount))
7387  {
7388  status = DOMAIN_OVERFLOW;
7389  }
7390  else
7391  {
7392  db_make_short (target, (short) ROUND (v_money->amount));
7393  }
7394  break;
7395  case DB_TYPE_INTEGER:
7396  if (OR_CHECK_SHORT_OVERFLOW (db_get_int (src)))
7397  {
7398  status = DOMAIN_OVERFLOW;
7399  }
7400  else
7401  {
7402  db_make_short (target, db_get_int (src));
7403  }
7404  break;
7405  case DB_TYPE_BIGINT:
7407  {
7408  status = DOMAIN_OVERFLOW;
7409  }
7410  else
7411  {
7412  db_make_short (target, (short) db_get_bigint (src));
7413  }
7414  break;
7415  case DB_TYPE_FLOAT:
7417  {
7418  status = DOMAIN_OVERFLOW;
7419  }
7420  else
7421  {
7422  db_make_short (target, (short) ROUND (db_get_float (src)));
7423  }
7424  break;
7425  case DB_TYPE_DOUBLE:
7427  {
7428  status = DOMAIN_OVERFLOW;
7429  }
7430  else
7431  {
7432  db_make_short (target, (short) ROUND (db_get_double (src)));
7433  }
7434  break;
7435  case DB_TYPE_NUMERIC:
7436  status = (TP_DOMAIN_STATUS) numeric_db_value_coerce_from_num ((DB_VALUE *) src, target, &data_stat);
7437  if (status != NO_ERROR)
7438  {
7439  status = DOMAIN_OVERFLOW;
7440  }
7441  break;
7442  case DB_TYPE_CHAR:
7443  case DB_TYPE_VARCHAR:
7444  case DB_TYPE_NCHAR:
7445  case DB_TYPE_VARNCHAR:
7446  {
7447  double num_value = 0.0;
7448 
7449  if (tp_atof (src, &num_value, &data_stat) != NO_ERROR || data_stat == DATA_STATUS_NOT_CONSUMED)
7450  {
7451  if (er_errid () != NO_ERROR) /* i.e, malloc failure */
7452  {
7453  status = DOMAIN_ERROR;
7454  }
7455  else
7456  {
7457  status = DOMAIN_INCOMPATIBLE; /* conversion error */
7458  }
7459  break;
7460  }
7461 
7462  if (data_stat == DATA_STATUS_TRUNCATED || OR_CHECK_SHORT_OVERFLOW (num_value))
7463  {
7464  status = DOMAIN_OVERFLOW;
7465  }
7466  else
7467  {
7468  db_make_short (target, (short) ROUND (num_value));
7469  }
7470  break;
7471  }
7472  case DB_TYPE_ENUMERATION:
7473  db_make_short (target, db_get_enum_short (src));
7474  break;
7475  default:
7476  status = DOMAIN_INCOMPATIBLE;
7477  break;
7478  }
7479  break;
7480 
7481  case DB_TYPE_INTEGER:
7482  switch (original_type)
7483  {
7484  case DB_TYPE_SHORT:
7485  db_make_int (target, db_get_short (src));
7486  break;
7487  case DB_TYPE_BIGINT:
7489  {
7490  status = DOMAIN_OVERFLOW;
7491  }
7492  else
7493  {
7494  db_make_int (target, (int) db_get_bigint (src));
7495  }
7496  break;
7497  case DB_TYPE_MONETARY:
7498  v_money = db_get_monetary (src);
7499  if (OR_CHECK_INT_OVERFLOW (v_money->amount))
7500  {
7501  status = DOMAIN_OVERFLOW;
7502  }
7503  else
7504  {
7505  db_make_int (target, (int) ROUND (v_money->amount));
7506  }
7507  break;
7508  case DB_TYPE_FLOAT:
7509  {
7510  int tmp_int;
7511  float tmp_float;
7512 
7513  if (OR_CHECK_INT_OVERFLOW (db_get_float (src)))
7514  {
7515  status = DOMAIN_OVERFLOW;
7516  }
7517  else
7518  {
7519  tmp_float = db_get_float (src);
7520  tmp_int = (int) ROUND (tmp_float);
7521 
7522 #if defined(AIX)
7523  /* in AIX, float/double to int will not overflow, make it the same as linux. */
7524  if (tmp_float == (float) DB_INT32_MAX)
7525  {
7526  tmp_int = DB_INT32_MIN;
7527  }
7528 #endif
7529 
7530  if (OR_CHECK_ASSIGN_OVERFLOW (tmp_int, tmp_float))
7531  {
7532  status = DOMAIN_OVERFLOW;
7533  }
7534  else
7535  {
7536  db_make_int (target, tmp_int);
7537  }
7538  }
7539  }
7540  break;
7541  case DB_TYPE_DOUBLE:
7543  {
7544  status = DOMAIN_OVERFLOW;
7545  }
7546  else
7547  {
7548  db_make_int (target, (int) ROUND (db_get_double (src)));
7549  }
7550  break;
7551  case DB_TYPE_NUMERIC:
7552  status = (TP_DOMAIN_STATUS) numeric_db_value_coerce_from_num ((DB_VALUE *) src, target, &data_stat);
7553  if (status != NO_ERROR)
7554  {
7555  status = DOMAIN_OVERFLOW;
7556  }
7557  break;
7558  case DB_TYPE_CHAR:
7559  case DB_TYPE_VARCHAR:
7560  case DB_TYPE_NCHAR:
7561  case DB_TYPE_VARNCHAR:
7562  {
7563  double num_value = 0.0;
7564 
7565  if (tp_atof (src, &num_value, &data_stat) != NO_ERROR || data_stat == DATA_STATUS_NOT_CONSUMED)
7566  {
7567  if (er_errid () != NO_ERROR) /* i.e, malloc failure */
7568  {
7569  status = DOMAIN_ERROR;
7570  }
7571  else
7572  {
7573  status = DOMAIN_INCOMPATIBLE; /* conversion error */
7574  }
7575  break;
7576  }
7577 
7578  if (data_stat == DATA_STATUS_TRUNCATED || OR_CHECK_INT_OVERFLOW (num_value))
7579  {
7580  status = DOMAIN_OVERFLOW;
7581  }
7582  else
7583  {
7584  db_make_int (target, (int) ROUND (num_value));
7585  }
7586  break;
7587  }
7588  case DB_TYPE_ENUMERATION:
7589  db_make_int (target, db_get_enum_short (src));
7590  break;
7591  default:
7592  status = DOMAIN_INCOMPATIBLE;
7593  break;
7594  }
7595  break;
7596 
7597  case DB_TYPE_BIGINT:
7598  switch (original_type)
7599  {
7600  case DB_TYPE_SHORT:
7601  db_make_bigint (target, db_get_short (src));
7602  break;
7603  case DB_TYPE_INTEGER:
7604  db_make_bigint (target, db_get_int (src));
7605  break;
7606  case DB_TYPE_MONETARY:
7607  {
7608  DB_BIGINT tmp_bi;
7609 
7610  v_money = db_get_monetary (src);
7611  if (OR_CHECK_BIGINT_OVERFLOW (v_money->amount))
7612  {
7613  status = DOMAIN_OVERFLOW;
7614  }
7615  else
7616  {
7617  tmp_bi = (DB_BIGINT) ROUND (v_money->amount);
7618  if (OR_CHECK_ASSIGN_OVERFLOW (tmp_bi, v_money->amount))
7619  {
7620  status = DOMAIN_OVERFLOW;
7621  }
7622  else
7623  {
7624  db_make_bigint (target, tmp_bi);
7625  }
7626  }
7627  }
7628  break;
7629  case DB_TYPE_FLOAT:
7630  {
7631  float tmp_float;
7632  DB_BIGINT tmp_bi;
7633 
7635  {
7636  status = DOMAIN_OVERFLOW;
7637  }
7638  else
7639  {
7640  tmp_float = db_get_float (src);
7641  tmp_bi = (DB_BIGINT) ROUND (tmp_float);
7642 
7643 #if defined(AIX)
7644  /* in AIX, float/double to int64 will not overflow, make it the same as linux. */
7645  if (tmp_float == (float) DB_BIGINT_MAX)
7646  {
7647  tmp_bi = DB_BIGINT_MIN;
7648  }
7649 #endif
7650  if (OR_CHECK_ASSIGN_OVERFLOW (tmp_bi, tmp_float))
7651  {
7652  status = DOMAIN_OVERFLOW;
7653  }
7654  else
7655  {
7656  db_make_bigint (target, tmp_bi);
7657  }
7658  }
7659  }
7660  break;
7661  case DB_TYPE_DOUBLE:
7662  {
7663  double tmp_double;
7664  DB_BIGINT tmp_bi;
7665 
7667  {
7668  status = DOMAIN_OVERFLOW;
7669  }
7670  else
7671  {
7672  tmp_double = db_get_double (src);
7673  tmp_bi = (DB_BIGINT) ROUND (tmp_double);
7674 
7675 #if defined(AIX)
7676  /* in AIX, float/double to int64 will not overflow, make it the same as linux. */
7677  if (tmp_double == (double) DB_BIGINT_MAX)
7678  {
7679  tmp_bi = DB_BIGINT_MIN;
7680  }
7681 #endif
7682  if (OR_CHECK_ASSIGN_OVERFLOW (tmp_bi, tmp_double))
7683  {
7684  status = DOMAIN_OVERFLOW;
7685  }
7686  else
7687  {
7688  db_make_bigint (target, tmp_bi);
7689  }
7690  }
7691  }
7692  break;
7693  case DB_TYPE_NUMERIC:
7694  status = (TP_DOMAIN_STATUS) numeric_db_value_coerce_from_num ((DB_VALUE *) src, target, &data_stat);
7695  if (status != NO_ERROR)
7696  {
7697  status = DOMAIN_OVERFLOW;
7698  }
7699  break;
7700  case DB_TYPE_CHAR:
7701  case DB_TYPE_VARCHAR:
7702  case DB_TYPE_NCHAR:
7703  case DB_TYPE_VARNCHAR:
7704  {
7705  DB_BIGINT num_value = 0;
7706 
7707  if (tp_atobi (src, &num_value, &data_stat) != NO_ERROR)
7708  {
7709  if (er_errid () != NO_ERROR) /* i.e, malloc failure */
7710  {
7711  status = DOMAIN_ERROR;
7712  }
7713  else
7714  {
7715  status = DOMAIN_INCOMPATIBLE; /* conversion error */
7716  }
7717  break;
7718  }
7719 
7720  if (data_stat == DATA_STATUS_TRUNCATED)
7721  {
7722  status = DOMAIN_OVERFLOW;
7723  break;
7724  }
7725  db_make_bigint (target, num_value);
7726  break;
7727  }
7728  case DB_TYPE_ENUMERATION:
7729  db_make_bigint (target, db_get_enum_short (src));
7730  break;
7731  default:
7732  status = DOMAIN_INCOMPATIBLE;
7733  break;
7734  }
7735  break;
7736 
7737  case DB_TYPE_FLOAT:
7738  switch (original_type)
7739  {
7740  case DB_TYPE_SHORT:
7741  db_make_float (target, (float) db_get_short (src));
7742  break;
7743  case DB_TYPE_INTEGER:
7744  db_make_float (target, (float) db_get_int (src));
7745  break;
7746  case DB_TYPE_BIGINT:
7747  db_make_float (target, (float) db_get_bigint (src));
7748  break;
7749  case DB_TYPE_DOUBLE:
7751  {
7752  status = DOMAIN_OVERFLOW;
7753  }
7754  else
7755  {
7756  db_make_float (target, (float) db_get_double (src));
7757  }
7758  break;
7759  case DB_TYPE_MONETARY:
7760  v_money = db_get_monetary (src);
7761  if (OR_CHECK_FLOAT_OVERFLOW (v_money->amount))
7762  {
7763  status = DOMAIN_OVERFLOW;
7764  }
7765  else
7766  {
7767  db_make_float (target, (float) v_money->amount);
7768  }
7769  break;
7770  case DB_TYPE_NUMERIC:
7771  status = (TP_DOMAIN_STATUS) numeric_db_value_coerce_from_num ((DB_VALUE *) src, target, &data_stat);
7772  if (status != NO_ERROR)
7773  {
7774  status = DOMAIN_OVERFLOW;
7775  }
7776  break;
7777  case DB_TYPE_CHAR:
7778  case DB_TYPE_VARCHAR:
7779  case DB_TYPE_NCHAR:
7780  case DB_TYPE_VARNCHAR:
7781  {
7782  double num_value = 0.0;
7783 
7784  if (tp_atof (src, &num_value, &data_stat) != NO_ERROR || data_stat == DATA_STATUS_NOT_CONSUMED)
7785  {
7786  if (er_errid () != NO_ERROR) /* i.e, malloc failure */
7787  {
7788  status = DOMAIN_ERROR;
7789  }
7790  else
7791  {
7792  status = DOMAIN_INCOMPATIBLE; /* conversion error */
7793  }
7794  break;
7795  }
7796 
7797  if (data_stat == DATA_STATUS_TRUNCATED || OR_CHECK_FLOAT_OVERFLOW (num_value))
7798  {
7799  status = DOMAIN_OVERFLOW;
7800  }
7801  else
7802  {
7803  db_make_float (target, (float) num_value);
7804  }
7805  break;
7806  }
7807  case DB_TYPE_ENUMERATION:
7808  db_make_float (target, (float) db_get_enum_short (src));
7809  break;
7810  default:
7811  status = DOMAIN_INCOMPATIBLE;
7812  break;
7813  }
7814  break;
7815 
7816  case DB_TYPE_DOUBLE:
7817  switch (original_type)
7818  {
7819  case DB_TYPE_SHORT:
7820  db_make_double (target, (double) db_get_short (src));
7821  break;
7822  case DB_TYPE_INTEGER:
7823  db_make_double (target, (double) db_get_int (src));
7824  break;
7825  case DB_TYPE_BIGINT:
7826  db_make_double (target, (double) db_get_bigint (src));
7827  break;
7828  case DB_TYPE_FLOAT:
7829  db_make_double (target, (double) db_get_float (src));
7830  break;
7831  case DB_TYPE_MONETARY:
7832  v_money = db_get_monetary (src);
7833  db_make_double (target, (double) v_money->amount);
7834  break;
7835  case DB_TYPE_NUMERIC:
7836  status = (TP_DOMAIN_STATUS) numeric_db_value_coerce_from_num ((DB_VALUE *) src, target, &data_stat);
7837  if (status != NO_ERROR)
7838  {
7839  status = DOMAIN_OVERFLOW;
7840  }
7841  break;
7842  case DB_TYPE_CHAR:
7843  case DB_TYPE_VARCHAR:
7844  case DB_TYPE_NCHAR:
7845  case DB_TYPE_VARNCHAR:
7846  {
7847  double num_value = 0.0;
7848 
7849  if (tp_atof (src, &num_value, &data_stat) != NO_ERROR || data_stat == DATA_STATUS_NOT_CONSUMED)
7850  {
7851  if (er_errid () != NO_ERROR) /* i.e, malloc failure */
7852  {
7853  status = DOMAIN_ERROR;
7854  }
7855  else
7856  {
7857  status = DOMAIN_INCOMPATIBLE; /* conversion error */
7858  }
7859  break;
7860  }
7861 
7862  if (data_stat == DATA_STATUS_TRUNCATED)
7863  {
7864  status = DOMAIN_OVERFLOW;
7865  }
7866  else
7867  {
7868  db_make_double (target, num_value);
7869  }
7870 
7871  break;
7872  }
7873  case DB_TYPE_ENUMERATION:
7874  db_make_double (target, (double) db_get_enum_short (src));
7875  break;
7876  default:
7877  status = DOMAIN_INCOMPATIBLE;
7878  break;
7879  }
7880  break;
7881 
7882  case DB_TYPE_NUMERIC:
7883  /*
7884  * Numeric-to-numeric coercion will be handled in the nm_ module.
7885  * The desired precision & scale is communicated through the destination
7886  * value.
7887  */
7888  switch (original_type)
7889  {
7890  case DB_TYPE_CHAR:
7891  case DB_TYPE_VARCHAR:
7892  case DB_TYPE_NCHAR:
7893  case DB_TYPE_VARNCHAR:
7894  {
7895  DB_VALUE temp;
7896 
7897  if (tp_atonumeric (src, &temp) != NO_ERROR)
7898  {
7899  if (er_errid () != NO_ERROR)
7900  {
7901  status = DOMAIN_ERROR;
7902  }
7903  else
7904  {
7905  status = DOMAIN_INCOMPATIBLE;
7906  }
7907  }
7908  else
7909  {
7910  status = tp_value_coerce (&temp, target, desired_domain);
7911  }
7912  break;
7913  }
7914  default:
7915  {
7916  int error_code = numeric_db_value_coerce_to_num ((DB_VALUE *) src, target, &data_stat);
7917 
7918  if (error_code == ER_IT_DATA_OVERFLOW || data_stat == DATA_STATUS_TRUNCATED)
7919  {
7920  status = DOMAIN_OVERFLOW;
7921  }
7922  else if (error_code != NO_ERROR)
7923  {
7924  status = DOMAIN_INCOMPATIBLE;
7925  }
7926  else
7927  {
7928  status = DOMAIN_COMPATIBLE;
7929  }
7930  }
7931  break;
7932  }
7933  break;
7934 
7935  case DB_TYPE_MONETARY:
7936  switch (original_type)
7937  {
7938  case DB_TYPE_SHORT:
7939  db_make_monetary (target, DB_CURRENCY_DEFAULT, (double) db_get_short (src));
7940  break;
7941  case DB_TYPE_INTEGER:
7942  db_make_monetary (target, DB_CURRENCY_DEFAULT, (double) db_get_int (src));
7943  break;
7944  case DB_TYPE_BIGINT:
7945  db_make_monetary (target, DB_CURRENCY_DEFAULT, (double) db_get_bigint (src));
7946  break;
7947  case DB_TYPE_FLOAT:
7948  db_make_monetary (target, DB_CURRENCY_DEFAULT, (double) db_get_float (src));
7949  break;
7950  case DB_TYPE_DOUBLE:
7952  break;
7953  case DB_TYPE_NUMERIC:
7954  status = (TP_DOMAIN_STATUS) numeric_db_value_coerce_from_num ((DB_VALUE *) src, target, &data_stat);
7955  if (status != NO_ERROR)
7956  {
7957  status = DOMAIN_OVERFLOW;
7958  }
7959  break;
7960  case DB_TYPE_CHAR:
7961  case DB_TYPE_VARCHAR:
7962  case DB_TYPE_NCHAR:
7963  case DB_TYPE_VARNCHAR:
7964  {
7965  double num_value = 0.0;
7966 
7967  if (tp_atof (src, &num_value, &data_stat) != NO_ERROR || data_stat == DATA_STATUS_NOT_CONSUMED)
7968  {
7969  if (er_errid () != NO_ERROR) /* i.e, malloc failure */
7970  {
7971  status = DOMAIN_ERROR;
7972  }
7973  else
7974  {
7975  status = DOMAIN_INCOMPATIBLE; /* conversion error */
7976  }
7977  break;
7978  }
7979 
7980  if (data_stat == DATA_STATUS_TRUNCATED)
7981  {
7982  status = DOMAIN_OVERFLOW;
7983  }
7984  else
7985  {
7986  db_make_monetary (target, DB_CURRENCY_DEFAULT, num_value);
7987  }
7988  break;
7989  }
7990  case DB_TYPE_ENUMERATION:
7992  break;
7993  default:
7994  status = DOMAIN_INCOMPATIBLE;
7995  break;
7996  }
7997  break;
7998 
7999  case DB_TYPE_TIMESTAMP:
8000  switch (original_type)
8001  {
8002  case DB_TYPE_VARCHAR:
8003  case DB_TYPE_CHAR:
8004  case DB_TYPE_NCHAR:
8005  case DB_TYPE_VARNCHAR:
8006  if (tp_atoutime (src, &v_utime) != NO_ERROR)
8007  {
8008  status = DOMAIN_ERROR;
8009  }
8010  else
8011  {
8012  db_make_timestamp (target, v_utime);
8013  }
8014  break;
8015 
8016  case DB_TYPE_ENUMERATION:
8017  {
8018  DB_VALUE varchar_val;
8019  if (tp_enumeration_to_varchar (src, &varchar_val) != NO_ERROR)
8020  {
8021  status = DOMAIN_ERROR;
8022  break;
8023  }
8024  status =
8025  tp_value_cast_internal (&varchar_val, target, desired_domain, coercion_mode, do_domain_select, false);
8026  break;
8027  }
8028 
8029  case DB_TYPE_DATETIME:
8030  case DB_TYPE_DATE:
8031  {
8032  if (original_type == DB_TYPE_DATE)
8033  {
8034  v_date = *db_get_date (src);
8035  db_time_encode (&v_time, 0, 0, 0);
8036  }
8037  else
8038  {
8039  v_datetime = *db_get_datetime (src);
8040  v_date = v_datetime.date;
8041  v_time = v_datetime.time / 1000;
8042  }
8043 
8044  if (db_timestamp_encode_ses (&v_date, &v_time, &v_utime, NULL) == NO_ERROR)
8045  {
8046  db_make_timestamp (target, v_utime);
8047  }
8048  else
8049  {
8050  status = DOMAIN_OVERFLOW;
8051  }
8052  break;
8053  }
8054 
8055  case DB_TYPE_DATETIMELTZ:
8056  v_datetime = *db_get_datetime (src);
8057  v_date = v_datetime.date;
8058  v_time = v_datetime.time / 1000;
8059 
8060  if (db_timestamp_encode_utc (&v_date, &v_time, &v_utime) == NO_ERROR)
8061  {
8062  db_make_timestamp (target, v_utime);
8063  }
8064  else
8065  {
8066  status = DOMAIN_OVERFLOW;
8067  }
8068  break;
8069 
8070  case DB_TYPE_DATETIMETZ:
8071  v_datetimetz = *db_get_datetimetz (src);
8072  v_date = v_datetimetz.datetime.date;
8073  v_time = v_datetimetz.datetime.time / 1000;
8074 
8075  if (db_timestamp_encode_utc (&v_date, &v_time, &v_utime) == NO_ERROR)
8076  {
8077  db_make_timestamp (target, v_utime);
8078  }
8079  else
8080  {
8081  status = DOMAIN_OVERFLOW;
8082  }
8083  break;
8084 
8085  case DB_TYPE_TIMESTAMPLTZ:
8086  /* copy timestamp (UTC) */
8087  db_make_timestamp (target, *db_get_timestamp (src));
8088  break;
8089 
8090  case DB_TYPE_TIMESTAMPTZ:
8091  v_timestamptz = *db_get_timestamptz (src);
8092  /* copy timestamp (UTC) */
8093  db_make_timestamp (target, v_timestamptz.timestamp);
8094  break;
8095 
8096  default:
8097  status = tp_value_coerce ((DB_VALUE *) src, target, &tp_Integer_domain);
8098  if (status == DOMAIN_COMPATIBLE)
8099  {
8100  int tmpint;
8101  tmpint = db_get_int (target);
8102  if (tmpint >= 0)
8103  {
8104  db_make_timestamp (target, (DB_UTIME) tmpint);
8105  }
8106  else
8107  {
8108  status = DOMAIN_INCOMPATIBLE;
8109  }
8110  }
8111  break;
8112  }
8113  break;
8114 
8115  case DB_TYPE_TIMESTAMPTZ:
8116  switch (original_type)
8117  {
8118  case DB_TYPE_VARCHAR:
8119  case DB_TYPE_CHAR:
8120  case DB_TYPE_NCHAR:
8121  case DB_TYPE_VARNCHAR:
8122  if (tp_atotimestamptz (src, &v_timestamptz) != NO_ERROR)
8123  {
8124  status = DOMAIN_ERROR;
8125  }
8126  else
8127  {
8128  db_make_timestamptz (target, &v_timestamptz);
8129  }
8130  break;
8131 
8132  case DB_TYPE_ENUMERATION:
8133  {
8134  DB_VALUE varchar_val;
8135  if (tp_enumeration_to_varchar (src, &varchar_val) != NO_ERROR)
8136  {
8137  status = DOMAIN_ERROR;
8138  break;
8139  }
8140  status =
8141  tp_value_cast_internal (&varchar_val, target, desired_domain, coercion_mode, do_domain_select, false);
8142  break;
8143  }
8144 
8145  case DB_TYPE_DATETIME:
8146  case DB_TYPE_DATE:
8147  /* convert from session to UTC */
8148  if (original_type == DB_TYPE_DATETIME)
8149  {
8150  v_datetime = *db_get_datetime (src);
8151  v_date = v_datetime.date;
8152  v_time = v_datetime.time / 1000;
8153  }
8154  else
8155  {
8156  assert (original_type == DB_TYPE_DATE);
8157  v_date = *db_get_date (src);
8158  v_time = 0;
8159  }
8160 
8161  if (db_timestamp_encode_ses (&v_date, &v_time, &v_timestamptz.timestamp, &v_timestamptz.tz_id) != NO_ERROR)
8162  {
8163  status = DOMAIN_ERROR;
8164  }
8165  else
8166  {
8167  db_make_timestamptz (target, &v_timestamptz);
8168  }
8169  break;
8170 
8171  case DB_TYPE_DATETIMELTZ:
8172  v_datetime = *db_get_datetime (src);
8173  v_date = v_datetime.date;
8174  v_time = v_datetime.time / 1000;
8175 
8176  /* encode DT as UTC and the TZ of session */
8177  if (db_timestamp_encode_utc (&v_date, &v_time, &v_timestamptz.timestamp) != NO_ERROR)
8178  {
8179  status = DOMAIN_ERROR;
8180  break;
8181  }
8182  if (tz_create_session_tzid_for_datetime (&v_datetime, true, &(v_timestamptz.tz_id)) != NO_ERROR)
8183  {
8184  status = DOMAIN_ERROR;
8185  }
8186  else
8187  {
8188  db_make_timestamptz (target, &v_timestamptz);
8189  }
8190  break;
8191 
8192  case DB_TYPE_DATETIMETZ:
8193  v_datetimetz = *db_get_datetimetz (src);
8194  v_date = v_datetimetz.datetime.date;
8195  v_time = v_datetimetz.datetime.time / 1000;
8196 
8197  /* encode TS to DT (UTC) and copy TZ from DT_TZ */
8198  if (db_timestamp_encode_utc (&v_date, &v_time, &v_timestamptz.timestamp) == NO_ERROR)
8199  {
8200  v_timestamptz.tz_id = v_datetimetz.tz_id;
8201  db_make_timestamptz (target, &v_timestamptz);
8202  }
8203  else
8204  {
8205  status = DOMAIN_OVERFLOW;
8206  }
8207  break;
8208 
8209  case DB_TYPE_TIMESTAMP:
8210  case DB_TYPE_TIMESTAMPLTZ:
8211  /* copy TS value and create TZ_ID for system TZ */
8212  v_timestamptz.timestamp = *db_get_timestamp (src);
8213 
8214  if (tz_create_session_tzid_for_timestamp (&v_timestamptz.timestamp, &(v_timestamptz.tz_id)) != NO_ERROR)
8215  {
8216  status = DOMAIN_ERROR;
8217  break;
8218  }
8219 
8220  db_make_timestamptz (target, &v_timestamptz);
8221  break;
8222 
8223  default:
8224  status = tp_value_coerce ((DB_VALUE *) src, target, &tp_Integer_domain);
8225  if (status == DOMAIN_COMPATIBLE)
8226  {
8227  int tmpint;
8228 
8229  tmpint = db_get_int (target);
8230  if (tmpint < 0)
8231  {
8232  status = DOMAIN_INCOMPATIBLE;
8233  break;
8234  }
8235  v_timestamptz.timestamp = (DB_UTIME) tmpint;
8236 
8237  if (tz_create_session_tzid_for_timestamp (&v_timestamptz.timestamp, &v_timestamptz.tz_id) != NO_ERROR)
8238  {
8239  status = DOMAIN_INCOMPATIBLE;
8240  break;
8241  }
8242 
8243  db_make_timestamptz (target, &v_timestamptz);
8244  }
8245  break;
8246  }
8247  break;
8248 
8249  case DB_TYPE_TIMESTAMPLTZ:
8250  switch (original_type)
8251  {
8252  case DB_TYPE_VARCHAR:
8253  case DB_TYPE_CHAR:
8254  case DB_TYPE_NCHAR:
8255  case DB_TYPE_VARNCHAR:
8256  /* read as DATETIMETZ */
8257  if (tp_atotimestamptz (src, &v_timestamptz) != NO_ERROR)
8258  {
8259  status = DOMAIN_ERROR;
8260  break;
8261  }
8262  else
8263  {
8264  db_make_timestampltz (target, v_timestamptz.timestamp);
8265  }
8266  break;
8267 
8268  case DB_TYPE_ENUMERATION:
8269  {
8270  DB_VALUE varchar_val;
8271  if (tp_enumeration_to_varchar (src, &varchar_val) != NO_ERROR)
8272  {
8273  status = DOMAIN_ERROR;
8274  break;
8275  }
8276  status =
8277  tp_value_cast_internal (&varchar_val, target, desired_domain, coercion_mode, do_domain_select, false);
8278  break;
8279  }
8280 
8281  case DB_TYPE_DATETIME:
8282  case DB_TYPE_DATE:
8283  {
8284  if (original_type == DB_TYPE_DATETIME)
8285  {
8286  v_datetime = *db_get_datetime (src);
8287  v_date = v_datetime.date;
8288  v_time = v_datetime.time / 1000;
8289  }
8290  else
8291  {
8292  assert (original_type == DB_TYPE_DATE);
8293  v_date = *db_get_date (src);
8294  v_time = 0;
8295  }
8296 
8297  if (db_timestamp_encode_ses (&v_date, &v_time, &v_utime, NULL) != NO_ERROR)
8298  {
8299  status = DOMAIN_OVERFLOW;
8300  break;
8301  }
8302 
8303  db_make_timestampltz (target, v_utime);
8304  }
8305  break;
8306 
8307  case DB_TYPE_DATETIMELTZ:
8308  case DB_TYPE_DATETIMETZ:
8309  if (original_type == DB_TYPE_DATETIMELTZ)
8310  {
8311  v_datetime = *db_get_datetime (src);
8312  v_date = v_datetime.date;
8313  v_time = v_datetime.time / 1000;
8314  }
8315  else
8316  {
8317  assert (original_type == DB_TYPE_DATETIMETZ);
8318  v_datetimetz = *db_get_datetimetz (src);
8319  v_date = v_datetimetz.datetime.date;
8320  v_time = v_datetimetz.datetime.time / 1000;
8321  }
8322 
8323  /* both values are in UTC */
8324  if (db_timestamp_encode_utc (&v_date, &v_time, &v_utime) == NO_ERROR)
8325  {
8326  db_make_timestampltz (target, v_utime);
8327  }
8328  else
8329  {
8330  status = DOMAIN_OVERFLOW;
8331  }
8332  break;
8333 
8334  case DB_TYPE_TIMESTAMP:
8335  /* original value stored in UTC, copy it */
8336  db_make_timestampltz (target, *db_get_timestamp (src));
8337  break;
8338 
8339  case DB_TYPE_TIMESTAMPTZ:
8340  v_timestamptz = *db_get_timestamptz (src);
8341  /* original value stored in UTC, copy it */
8342  db_make_timestampltz (target, v_timestamptz.timestamp);
8343  break;
8344 
8345  default:
8346  status = tp_value_coerce ((DB_VALUE *) src, target, &tp_Integer_domain);
8347  if (status == DOMAIN_COMPATIBLE)
8348  {
8349  int tmpint;
8350  tmpint = db_get_int (target);
8351  if (tmpint >= 0)
8352  {
8353  db_make_timestampltz (target, (DB_UTIME) tmpint);
8354  }
8355  else
8356  {
8357  status = DOMAIN_INCOMPATIBLE;
8358  }
8359  }
8360  break;
8361  }
8362  break;
8363 
8364  case DB_TYPE_DATETIME:
8365  switch (original_type)
8366  {
8367  case DB_TYPE_VARCHAR:
8368  case DB_TYPE_CHAR:
8369  case DB_TYPE_NCHAR:
8370  case DB_TYPE_VARNCHAR:
8371  if (tp_atoudatetime (src, &v_datetime) != NO_ERROR)
8372  {
8373  status = DOMAIN_ERROR;
8374  }
8375  else
8376  {
8377  db_make_datetime (target, &v_datetime);
8378  }
8379  break;
8380 
8381  case DB_TYPE_ENUMERATION:
8382  {
8383  DB_VALUE varchar_val;
8384  if (tp_enumeration_to_varchar (src, &varchar_val) != NO_ERROR)
8385  {
8386  status = DOMAIN_ERROR;
8387  break;
8388  }
8389  status =
8390  tp_value_cast_internal (&varchar_val, target, desired_domain, coercion_mode, do_domain_select, false);
8391  break;
8392  }
8393 
8394  case DB_TYPE_TIMESTAMP:
8395  case DB_TYPE_TIMESTAMPLTZ:
8396  v_utime = *db_get_timestamp (src);
8397  if (db_timestamp_decode_ses (&v_utime, &v_date, &v_time) != NO_ERROR)
8398  {
8399  status = DOMAIN_ERROR;
8400  break;
8401  }
8402  v_datetime.date = v_date;
8403  v_datetime.time = v_time * 1000;
8404  db_make_datetime (target, &v_datetime);
8405  break;
8406 
8407  case DB_TYPE_TIMESTAMPTZ:
8408  v_timestamptz = *db_get_timestamptz (src);
8409  if (db_timestamp_decode_w_tz_id (&v_timestamptz.timestamp, &v_timestamptz.tz_id, &v_date, &v_time) !=
8410  NO_ERROR)
8411  {
8412  status = DOMAIN_ERROR;
8413  break;
8414  }
8415  v_datetime.date = v_date;
8416  v_datetime.time = v_time * 1000;
8417  db_make_datetime (target, &v_datetime);
8418  break;
8419 
8420  case DB_TYPE_DATE:
8421  v_datetime.date = *db_get_date (src);
8422  v_datetime.time = 0;
8423  db_make_datetime (target, &v_datetime);
8424  break;
8425 
8426  case DB_TYPE_DATETIMELTZ:
8427  {
8428  DB_DATETIME utc_dt;
8429 
8430  /* DATETIMELTZ store in UTC, DATETIME in session TZ */
8431  utc_dt = *db_get_datetime (src);
8432  if (tz_datetimeltz_to_local (&utc_dt, &v_datetime) != NO_ERROR)
8433  {
8434  status = DOMAIN_ERROR;
8435  break;
8436  }
8437 
8438  db_make_datetime (target, &v_datetime);
8439  }
8440  break;
8441 
8442  case DB_TYPE_DATETIMETZ:
8443  /* DATETIMETZ store in UTC, DATETIME in session TZ */
8444  v_datetimetz = *db_get_datetimetz (src);
8445  if (tz_utc_datetimetz_to_local (&v_datetimetz.datetime, &v_datetimetz.tz_id, &v_datetime) == NO_ERROR)
8446  {
8447  db_make_datetime (target, &v_datetime);
8448  }
8449  else
8450  {
8451  status = DOMAIN_ERROR;
8452  }
8453  break;
8454 
8455  default:
8456  status = DOMAIN_INCOMPATIBLE;
8457  break;
8458  }
8459  break;
8460 
8461  case DB_TYPE_DATETIMELTZ:
8462  switch (original_type)
8463  {
8464  case DB_TYPE_VARCHAR:
8465  case DB_TYPE_CHAR:
8466  case DB_TYPE_NCHAR:
8467  case DB_TYPE_VARNCHAR:
8468  if (tp_atodatetimetz (src, &v_datetimetz) != NO_ERROR)
8469  {
8470  status = DOMAIN_ERROR;
8471  }
8472  else
8473  {
8474  db_make_datetimeltz (target, &v_datetimetz.datetime);
8475  }
8476  break;
8477 
8478  case DB_TYPE_ENUMERATION:
8479  {
8480  DB_VALUE varchar_val;
8481  if (tp_enumeration_to_varchar (src, &varchar_val) != NO_ERROR)
8482  {
8483  status = DOMAIN_ERROR;
8484  break;
8485  }
8486  status =
8487  tp_value_cast_internal (&varchar_val, target, desired_domain, coercion_mode, do_domain_select, false);
8488  break;
8489  }
8490 
8491  case DB_TYPE_TIMESTAMP:
8492  case DB_TYPE_TIMESTAMPLTZ:
8493  v_utime = *db_get_timestamp (src);
8494 
8495  (void) db_timestamp_decode_utc (&v_utime, &v_date, &v_time);
8496  v_datetime.time = v_time * 1000;
8497  v_datetime.date = v_date;
8498  db_make_datetimeltz (target, &v_datetime);
8499  break;
8500 
8501  case DB_TYPE_TIMESTAMPTZ:
8502  v_timestamptz = *db_get_timestamptz (src);
8503  (void) db_timestamp_decode_utc (&v_timestamptz.timestamp, &v_date, &v_time);
8504  v_datetime.time = v_time * 1000;
8505  v_datetime.date = v_date;
8506  db_make_datetimeltz (target, &v_datetime);
8507  break;
8508 
8509  case DB_TYPE_DATE:
8510  case DB_TYPE_DATETIME:
8511  if (original_type == DB_TYPE_DATE)
8512  {
8513  v_datetime.date = *db_get_date (src);
8514  v_datetime.time = 0;
8515  }
8516  else
8517  {
8518  v_datetime = *db_get_datetime (src);
8519  }
8520 
8521  if (tz_create_datetimetz_from_ses (&v_datetime, &v_datetimetz) != NO_ERROR)
8522  {
8523  status = DOMAIN_ERROR;
8524  break;
8525  }
8526  db_make_datetimeltz (target, &v_datetimetz.datetime);
8527  break;
8528 
8529  case DB_TYPE_DATETIMETZ:
8530  /* copy (UTC) */
8531  v_datetimetz = *db_get_datetimetz (src);
8532  db_make_datetimeltz (target, &v_datetimetz.datetime);
8533  break;
8534 
8535  case DB_TYPE_TIME:
8536  status = DOMAIN_INCOMPATIBLE;
8537  break;
8538 
8539  default:
8540  status = DOMAIN_INCOMPATIBLE;
8541  break;
8542  }
8543  break;
8544 
8545  case DB_TYPE_DATETIMETZ:
8546  switch (original_type)
8547  {
8548  case DB_TYPE_VARCHAR:
8549  case DB_TYPE_CHAR:
8550  case DB_TYPE_NCHAR:
8551  case DB_TYPE_VARNCHAR:
8552  {
8553  if (tp_atodatetimetz (src, &v_datetimetz) != NO_ERROR)
8554  {
8555  status = DOMAIN_ERROR;
8556  break;
8557  }
8558 
8559  db_make_datetimetz (target, &v_datetimetz);
8560  }
8561 
8562  break;
8563 
8564  case DB_TYPE_ENUMERATION:
8565  {
8566  DB_VALUE varchar_val;
8567  if (tp_enumeration_to_varchar (src, &varchar_val) != NO_ERROR)
8568  {
8569  status = DOMAIN_ERROR;
8570  break;
8571  }
8572  status =
8573  tp_value_cast_internal (&varchar_val, target, desired_domain, coercion_mode, do_domain_select, false);
8574  break;
8575  }
8576 
8577  case DB_TYPE_TIMESTAMP:
8578  case DB_TYPE_TIMESTAMPLTZ:
8579  {
8580  v_utime = *db_get_timestamp (src);
8581  db_timestamp_decode_utc (&v_utime, &v_date, &v_time);
8582  v_datetimetz.datetime.time = v_time * 1000;
8583  v_datetimetz.datetime.date = v_date;
8584 
8585  if (tz_create_session_tzid_for_datetime (&v_datetimetz.datetime, true, &v_datetimetz.tz_id) != NO_ERROR)
8586  {
8587  status = DOMAIN_ERROR;
8588  break;
8589  }
8590 
8591  db_make_datetimetz (target, &v_datetimetz);
8592  }
8593  break;
8594 
8595  case DB_TYPE_TIMESTAMPTZ:
8596  v_timestamptz = *db_get_timestamptz (src);
8597  (void) db_timestamp_decode_utc (&v_timestamptz.timestamp, &v_date, &v_time);
8598  v_datetimetz.datetime.time = v_time * 1000;
8599  v_datetimetz.datetime.date = v_date;
8600  v_datetimetz.tz_id = v_timestamptz.tz_id;
8601  db_make_datetimetz (target, &v_datetimetz);
8602  break;
8603 
8604  case DB_TYPE_DATE:
8605  v_datetime.date = *db_get_date (src);
8606  v_datetime.time = 0;
8607 
8608  if (tz_create_datetimetz_from_ses (&v_datetime, &v_datetimetz) != NO_ERROR)
8609  {
8610  status = DOMAIN_ERROR;
8611  break;
8612  }
8613  db_make_datetimetz (target, &v_datetimetz);
8614  break;
8615 
8616  case DB_TYPE_DATETIME:
8617  if (tz_create_datetimetz_from_ses (db_get_datetime (src), &v_datetimetz) != NO_ERROR)
8618  {
8619  status = DOMAIN_ERROR;
8620  break;
8621  }
8622  db_make_datetimetz (target, &v_datetimetz);
8623  break;
8624 
8625  case DB_TYPE_DATETIMELTZ:
8626  v_datetimetz.datetime = *db_get_datetime (src);
8627  if (tz_create_session_tzid_for_datetime (&v_datetimetz.datetime, true, &v_datetimetz.tz_id) != NO_ERROR)
8628  {
8629  status = DOMAIN_ERROR;
8630  break;
8631  }
8632  db_make_datetimetz (target, &v_datetimetz);
8633  break;
8634 
8635  case DB_TYPE_TIME:
8636  status = DOMAIN_INCOMPATIBLE;
8637  break;
8638 
8639  default:
8640  status = DOMAIN_INCOMPATIBLE;
8641  break;
8642  }
8643  break;
8644 
8645  case DB_TYPE_DATE:
8646  switch (original_type)
8647  {
8648  case DB_TYPE_VARCHAR:
8649  case DB_TYPE_CHAR:
8650  case DB_TYPE_NCHAR:
8651  case DB_TYPE_VARNCHAR:
8652  if (tp_atodate (src, &v_date) == NO_ERROR)
8653  {
8654  db_date_decode (&v_date, &month, &day, &year);
8655  }
8656  else
8657  {
8658  status = DOMAIN_ERROR;
8659  break;
8660  }
8661 
8662  if (db_make_date (target, month, day, year) != NO_ERROR)
8663  {
8664  status = DOMAIN_ERROR;
8665  }
8666  break;
8667 
8668  case DB_TYPE_ENUMERATION:
8669  {
8670  DB_VALUE varchar_val;
8671  if (tp_enumeration_to_varchar (src, &varchar_val) != NO_ERROR)
8672  {
8673  status = DOMAIN_ERROR;
8674  break;
8675  }
8676  status =
8677  tp_value_cast_internal (&varchar_val, target, desired_domain, coercion_mode, do_domain_select, false);
8678  break;
8679  }
8680 
8681  case DB_TYPE_TIMESTAMP:
8682  case DB_TYPE_TIMESTAMPLTZ:
8683  (void) db_timestamp_decode_ses (db_get_timestamp (src), &v_date, NULL);
8684  db_date_decode (&v_date, &month, &day, &year);
8685  db_make_date (target, month, day, year);
8686  break;
8687 
8688  case DB_TYPE_TIMESTAMPTZ:
8689  v_timestamptz = *db_get_timestamptz (src);
8690  if (db_timestamp_decode_w_tz_id (&v_timestamptz.timestamp, &v_timestamptz.tz_id, &v_date, NULL) != NO_ERROR)
8691  {
8692  status = DOMAIN_ERROR;
8693  break;
8694  }
8695  db_date_decode (&v_date, &month, &day, &year);
8696  db_make_date (target, month, day, year);
8697  break;
8698 
8699  case DB_TYPE_DATETIME:
8700  db_datetime_decode ((DB_DATETIME *) db_get_datetime (src), &month, &day, &year, &hour, &minute, &second,
8701  &millisecond);
8702  db_make_date (target, month, day, year);
8703  break;
8704 
8705  case DB_TYPE_DATETIMELTZ:
8706  case DB_TYPE_DATETIMETZ:
8707  {
8708  DB_DATETIME *utc_dt_p;
8709  DB_DATETIMETZ *dt_tz_p;
8710  TZ_ID tz_id;
8711 
8712  /* DATETIMELTZ and DATETIMETZ store in UTC, convert to session */
8713  if (original_type == DB_TYPE_DATETIMELTZ)
8714  {
8715  utc_dt_p = db_get_datetime (src);
8716  if (tz_create_session_tzid_for_datetime (utc_dt_p, true, &tz_id) != NO_ERROR)
8717  {
8718  status = DOMAIN_ERROR;
8719  break;
8720  }
8721  }
8722  else
8723  {
8724  dt_tz_p = db_get_datetimetz (src);
8725  utc_dt_p = &dt_tz_p->datetime;
8726  tz_id = dt_tz_p->tz_id;
8727  }
8728 
8729  if (tz_utc_datetimetz_to_local (utc_dt_p, &tz_id, &v_datetime) != NO_ERROR)
8730  {
8731  status = DOMAIN_ERROR;
8732  break;
8733  }
8734 
8735  db_datetime_decode (&v_datetime, &month, &day, &year, &hour, &minute, &second, &millisecond);
8736 
8737  db_make_date (target, month, day, year);
8738  break;
8739  }
8740 
8741  default:
8742  status = DOMAIN_INCOMPATIBLE;
8743  break;
8744  }
8745  break;
8746 
8747  case DB_TYPE_TIME:
8748  switch (original_type)
8749  {
8750  case DB_TYPE_TIMESTAMP:
8751  case DB_TYPE_TIMESTAMPLTZ:
8752  if (db_timestamp_decode_ses (db_get_timestamp (src), NULL, &v_time) != NO_ERROR)
8753  {
8754  status = DOMAIN_ERROR;
8755  break;
8756  }
8757  db_value_put_encoded_time (target, &v_time);
8758  break;
8759 
8760  case DB_TYPE_TIMESTAMPTZ:
8761  /* convert TS from UTC to value TZ */
8762  v_timestamptz = *db_get_timestamptz (src);
8763  if (db_timestamp_decode_w_tz_id (&v_timestamptz.timestamp, &v_timestamptz.tz_id, NULL, &v_time) != NO_ERROR)
8764  {
8765  status = DOMAIN_ERROR;
8766  break;
8767  }
8768  db_value_put_encoded_time (target, &v_time);
8769  break;
8770  case DB_TYPE_DATETIME:
8771  db_datetime_decode ((DB_DATETIME *) db_get_datetime (src), &month, &day, &year, &hour, &minute, &second,
8772  &millisecond);
8773  db_make_time (target, hour, minute, second);
8774  break;
8775  case DB_TYPE_DATETIMELTZ:
8776  {
8777  DB_DATETIME dt_local;
8778 
8779  v_datetime = *db_get_datetime (src);
8780 
8781  if (tz_datetimeltz_to_local (&v_datetime, &dt_local) != NO_ERROR)
8782  {
8783  status = DOMAIN_ERROR;
8784  break;
8785  }
8786 
8787  db_datetime_decode (&dt_local, &month, &day, &year, &hour, &minute, &second, &millisecond);
8788  db_make_time (target, hour, minute, second);
8789  break;
8790  }
8791  case DB_TYPE_DATETIMETZ:
8792  {
8793  DB_DATETIME dt_local;
8794 
8795  v_datetimetz = *db_get_datetimetz (src);
8796  if (tz_utc_datetimetz_to_local (&v_datetimetz.datetime, &v_datetimetz.tz_id, &dt_local) != NO_ERROR)
8797  {
8798  status = DOMAIN_ERROR;
8799  break;
8800  }
8801  db_datetime_decode (&dt_local, &month, &day, &year, &hour, &minute, &second, &millisecond);
8802  db_make_time (target, hour, minute, second);
8803  break;
8804  }
8805  case DB_TYPE_SHORT:
8806  v_time = db_get_short (src) % SECONDS_IN_A_DAY;
8807  db_time_decode (&v_time, &hour, &minute, &second);
8808  db_make_time (target, hour, minute, second);
8809  break;
8810  case DB_TYPE_INTEGER:
8811  v_time = db_get_int (src) % SECONDS_IN_A_DAY;
8812  db_time_decode (&v_time, &hour, &minute, &second);
8813  db_make_time (target, hour, minute, second);
8814  break;
8815  case DB_TYPE_BIGINT:
8816  v_time = db_get_bigint (src) % SECONDS_IN_A_DAY;
8817  db_time_decode (&v_time, &hour, &minute, &second);
8818  db_make_time (target, hour, minute, second);
8819  break;
8820  case DB_TYPE_MONETARY:
8821  v_money = db_get_monetary (src);
8822  if (OR_CHECK_INT_OVERFLOW (v_money->amount))
8823  {
8824  status = DOMAIN_OVERFLOW;
8825  }
8826  else
8827  {
8828  v_time = (int) ROUND (v_money->amount) % SECONDS_IN_A_DAY;
8829  db_time_decode (&v_time, &hour, &minute, &second);
8830  db_make_time (target, hour, minute, second);
8831  }
8832  break;
8833  case DB_TYPE_FLOAT:
8834  {
8835  float ftmp = db_get_float (src);
8836  if (OR_CHECK_INT_OVERFLOW (ftmp))
8837  {
8838  status = DOMAIN_OVERFLOW;
8839  }
8840  else
8841  {
8842  v_time = ((int) ROUND (ftmp)) % SECONDS_IN_A_DAY;
8843  db_time_decode (&v_time, &hour, &minute, &second);
8844  db_make_time (target, hour, minute, second);
8845  }
8846  break;
8847  }
8848  case DB_TYPE_DOUBLE:
8849  {
8850  double dtmp = db_get_double (src);
8851  if (OR_CHECK_INT_OVERFLOW (dtmp))
8852  {
8853  status = DOMAIN_OVERFLOW;
8854  }
8855  else
8856  {
8857  v_time = ((int) ROUND (dtmp)) % SECONDS_IN_A_DAY;
8858  db_time_decode (&v_time, &hour, &minute, &second);
8859  db_make_time (target, hour, minute, second);
8860  }
8861  break;
8862  }
8863  case DB_TYPE_VARCHAR:
8864  case DB_TYPE_CHAR:
8865  case DB_TYPE_NCHAR:
8866  case DB_TYPE_VARNCHAR:
8867  if (tp_atotime (src, &v_time) == NO_ERROR)
8868  {
8869  db_time_decode (&v_time, &hour, &minute, &second);
8870  }
8871  else
8872  {
8873  status = DOMAIN_ERROR;
8874  break;
8875  }
8876 
8877  if (db_make_time (target, hour, minute, second) != NO_ERROR)
8878  {
8879  status = DOMAIN_ERROR;
8880  }
8881  break;
8882  case DB_TYPE_ENUMERATION:
8883  {
8884  DB_VALUE varchar_val;
8885  if (tp_enumeration_to_varchar (src, &varchar_val) != NO_ERROR)
8886  {
8887  status = DOMAIN_ERROR;
8888  break;
8889  }
8890  status =
8891  tp_value_cast_internal (&varchar_val, target, desired_domain, coercion_mode, do_domain_select, false);
8892  break;
8893  }
8894  default:
8895  status = DOMAIN_INCOMPATIBLE;
8896  break;
8897  }
8898  break;
8899 
8900 #if !defined (SERVER_MODE)
8901  case DB_TYPE_OBJECT:
8902  {
8903  DB_OBJECT *v_obj = NULL;
8904  int is_vclass = 0;
8905 
8906  /* Make sure the domains are compatible. Coerce view objects to real objects. */
8907  switch (original_type)
8908  {
8909  case DB_TYPE_OBJECT:
8910  if (!sm_coerce_object_domain ((TP_DOMAIN *) desired_domain, db_get_object (src), &v_obj))
8911  {
8912  status = DOMAIN_INCOMPATIBLE;
8913  }
8914  break;
8915  case DB_TYPE_POINTER:
8916  if (!sm_check_class_domain ((TP_DOMAIN *) desired_domain, ((DB_OTMPL *) db_get_pointer (src))->classobj))
8917  {
8918  status = DOMAIN_INCOMPATIBLE;
8919  break;
8920  }
8921  db_make_pointer (target, db_get_pointer (src));
8922  break;
8923  case DB_TYPE_OID:
8924  vid_oid_to_object (src, &v_obj);
8925  break;
8926 
8927  case DB_TYPE_VOBJ:
8928  vid_vobj_to_object (src, &v_obj);
8929  is_vclass = db_is_vclass (desired_domain->class_mop);
8930  if (is_vclass < 0)
8931  {
8932  status = DOMAIN_ERROR;
8933  break;
8934  }
8935  if (!is_vclass)
8936  {
8937  v_obj = db_real_instance (v_obj);
8938  }
8939  break;
8940 
8941  default:
8942  status = DOMAIN_INCOMPATIBLE;
8943  }
8944  if (original_type != DB_TYPE_POINTER)
8945  {
8946  /* check we got an object in a proper class */
8947  if (v_obj && desired_domain->class_mop)
8948  {
8949  DB_OBJECT *obj_class;
8950 
8951  obj_class = db_get_class (v_obj);
8952  if (obj_class == desired_domain->class_mop)
8953  {
8954  /* everything is fine */
8955  }
8956  else if (db_is_subclass (obj_class, desired_domain->class_mop) > 0)
8957  {
8958  /* everything is also ok */
8959  }
8960  else
8961  {
8962  is_vclass = db_is_vclass (desired_domain->class_mop);
8963  if (is_vclass < 0)
8964  {
8965  status = DOMAIN_ERROR;
8966  break;
8967  }
8968  if (is_vclass)
8969  {
8970  /*
8971  * This should still be an error, and the above
8972  * code should have constructed a virtual mop.
8973  * I'm not sure the rest of the code is consistent
8974  * in this regard.
8975  */
8976  }
8977  else
8978  {
8979  status = DOMAIN_INCOMPATIBLE;
8980  }
8981  }
8982  }
8983  db_make_object (target, v_obj);
8984  }
8985  }
8986  break;
8987 #endif /* !SERVER_MODE */
8988 
8989  case DB_TYPE_SET:
8990  case DB_TYPE_MULTISET:
8991  case DB_TYPE_SEQUENCE:
8992  if (!TP_IS_SET_TYPE (original_type))
8993  {
8994  status = DOMAIN_INCOMPATIBLE;
8995  }
8996  else
8997  {
8998  SETREF *setref;
8999 
9000  setref = db_get_set (src);
9001  if (setref)
9002  {
9003  TP_DOMAIN *set_domain;
9004 
9005  set_domain = setobj_domain (setref->set);
9006  if (src == dest && tp_domain_compatible (set_domain, desired_domain))
9007  {
9008  /*
9009  * We know that this is a "coerce-in-place" operation, and
9010  * we know that no coercion is necessary, so do nothing: we
9011  * can use the exact same set without any conversion.
9012  * Setting "src" to NULL prevents the wrapup code from
9013  * clearing the set; that's important since we haven't made
9014  * a copy.
9015  */
9016  setobj_put_domain (setref->set, (TP_DOMAIN *) desired_domain);
9017  src = NULL;
9018  }
9019  else
9020  {
9021  if (tp_domain_compatible (set_domain, desired_domain))
9022  {
9023  /*
9024  * Well, we can't use the exact same set, but we don't
9025  * have to do the whole hairy coerce thing either: we
9026  * can just make a copy and then take the more general
9027  * domain. setobj_put_domain() guards against null
9028  * pointers, there's no need to check first.
9029  */
9030  setref = set_copy (setref);
9031  if (setref)
9032  {
9033  setobj_put_domain (setref->set, (TP_DOMAIN *) desired_domain);
9034  }
9035  }
9036  else
9037  {
9038  /*
9039  * Well, now we have to use the whole hairy coercion
9040  * thing. Too bad...
9041  *
9042  * This case will crop up when someone tries to cast a
9043  * "set of int" as a "set of float", for example.
9044  */
9045  setref =
9046  set_coerce (setref, (TP_DOMAIN *) desired_domain, (coercion_mode == TP_IMPLICIT_COERCION));
9047  }
9048 
9049  if (setref == NULL)
9050  {
9051  assert (er_errid () != NO_ERROR);
9052  err = er_errid ();
9053  }
9054  else if (desired_type == DB_TYPE_SET)
9055  {
9056  err = db_make_set (target, setref);
9057  }
9058  else if (desired_type == DB_TYPE_MULTISET)
9059  {
9060  err = db_make_multiset (target, setref);
9061  }
9062  else
9063  {
9064  err = db_make_sequence (target, setref);
9065  }
9066  }
9067  if (!setref || err < 0)
9068  {
9069  status = DOMAIN_INCOMPATIBLE;
9070  }
9071  }
9072  }
9073  break;
9074 
9075  case DB_TYPE_VOBJ:
9076  if (original_type == DB_TYPE_VOBJ)
9077  {
9078  SETREF *setref;
9079  /*
9080  * We should try and convert the view of the src to match
9081  * the view of the desired_domain. However, the desired
9082  * domain generally does not contain this information.
9083  * We will detect domain incompatibly later on assignment,
9084  * so we treat casting any DB_TYPE_VOBJ to DB_TYPE_VOBJ
9085  * as success.
9086  */
9087  status = DOMAIN_COMPATIBLE;
9088  setref = db_get_set (src);
9089  if (src != dest || !setref)
9090  {
9091  pr_clone_value ((DB_VALUE *) src, target);
9092  }
9093  else
9094  {
9095  /*
9096  * this is a "coerce-in-place", and no coercion is necessary,
9097  * so do nothing: use the same vobj without any conversion. set
9098  * "src" to NULL to prevent the wrapup code from clearing dest.
9099  */
9100  setobj_put_domain (setref->set, (TP_DOMAIN *) desired_domain);
9101  src = NULL;
9102  }
9103  }
9104  else
9105 #if !defined (SERVER_MODE)
9106  if (original_type == DB_TYPE_OBJECT)
9107  {
9108  if (vid_object_to_vobj (db_get_object (src), target) < 0)
9109  {
9110  status = DOMAIN_INCOMPATIBLE;
9111  }
9112  else
9113  {
9114  status = DOMAIN_COMPATIBLE;
9115  }
9116  break;
9117  }
9118  else
9119 #endif /* !SERVER_MODE */
9120  if (original_type == DB_TYPE_OID || original_type == DB_TYPE_OBJECT)
9121  {
9122  DB_VALUE view_oid;
9123  DB_VALUE class_oid;
9124  DB_VALUE keys;
9125  OID nulloid;
9126  DB_SEQ *seq;
9127 
9128  OID_SET_NULL (&nulloid);
9129  db_make_oid (&class_oid, &nulloid);
9130  db_make_oid (&view_oid, &nulloid);
9131  seq = db_seq_create (NULL, NULL, 3);
9132  keys = *src;
9133 
9134  /*
9135  * if we are on the server, and get a DB_TYPE_OBJECT,
9136  * then its only possible representation is a DB_TYPE_OID,
9137  * and it may be treated that way. However, this should
9138  * not really be a case that can happen. It may still
9139  * for historical reasons, so is not falgged as an error.
9140  * On the client, a worskapce based scheme must be used,
9141  * which is just above in a conditional compiled section.
9142  */
9143 
9144  if ((db_seq_put (seq, 0, &view_oid) != NO_ERROR) || (db_seq_put (seq, 1, &class_oid) != NO_ERROR)
9145  || (db_seq_put (seq, 2, &keys) != NO_ERROR))
9146  {
9147  status = DOMAIN_INCOMPATIBLE;
9148  }
9149  else
9150  {
9151  db_make_sequence (target, seq);
9153  status = DOMAIN_COMPATIBLE;
9154  }
9155  }
9156  else
9157  {
9158  status = DOMAIN_INCOMPATIBLE;
9159  }
9160  break;
9161 
9162  case DB_TYPE_BIT:
9163  case DB_TYPE_VARBIT:
9164  switch (original_type)
9165  {
9166  case DB_TYPE_VARCHAR:
9167  case DB_TYPE_CHAR:
9168  case DB_TYPE_NCHAR:
9169  case DB_TYPE_VARNCHAR:
9170  {
9171  DB_VALUE temp;
9172  char *bit_char_string;
9173  int src_size = db_get_string_size (src);
9174  int dst_size = (src_size + 1) / 2;
9175 
9176  bit_char_string = (char *) db_private_alloc (NULL, dst_size + 1);
9177  if (bit_char_string)
9178  {
9179  if (qstr_hex_to_bin (bit_char_string, dst_size, db_get_string (src), src_size) != src_size)
9180  {
9181  status = DOMAIN_ERROR;
9182  db_private_free_and_init (NULL, bit_char_string);
9183  }
9184  else
9185  {
9186  db_make_bit (&temp, TP_FLOATING_PRECISION_VALUE, bit_char_string, src_size * 4);
9187  temp.need_clear = true;
9188  if (db_bit_string_coerce (&temp, target, &data_stat) != NO_ERROR)
9189  {
9190  status = DOMAIN_INCOMPATIBLE;
9191  }
9192  else if (data_stat == DATA_STATUS_TRUNCATED && coercion_mode != TP_FORCE_COERCION &&
9194  || coercion_mode == TP_IMPLICIT_COERCION))
9195  {
9196  status = DOMAIN_OVERFLOW;
9197  pr_clear_value (target);
9198  }
9199  else
9200  {
9201  status = DOMAIN_COMPATIBLE;
9202  }
9203  pr_clear_value (&temp);
9204  }
9205  }
9206  else
9207  {
9208  /* Couldn't allocate space for bit_char_string */
9209  status = DOMAIN_INCOMPATIBLE;
9210  }
9211  }
9212  break;
9213 
9214  case DB_TYPE_ENUMERATION:
9215  {
9216  DB_VALUE varchar_val;
9217 
9218  if (tp_enumeration_to_varchar (src, &varchar_val) != NO_ERROR)
9219  {
9220  status = DOMAIN_ERROR;
9221  break;
9222  }
9223  status =
9224  tp_value_cast_internal (&varchar_val, target, desired_domain, coercion_mode, do_domain_select, false);
9225  }
9226  break;
9227 
9228  case DB_TYPE_BLOB:
9229  {
9230  DB_VALUE tmpval;
9231 
9232  db_make_null (&tmpval);
9233 
9234  err = db_blob_to_bit (src, NULL, &tmpval);
9235  if (err == NO_ERROR)
9236  {
9237  err = tp_value_cast_internal (&tmpval, target, desired_domain, coercion_mode, do_domain_select, false);
9238  }
9239  (void) pr_clear_value (&tmpval);
9240  }
9241  break;
9242 
9243  default:
9244  if (src == dest && tp_can_steal_string (src, desired_domain))
9245  {
9246  tp_value_slam_domain (dest, desired_domain);
9247  /*
9248  * Set "src" to NULL to prevent the wrapup code from undoing
9249  * our work; since we haven't actually made a copy, we don't
9250  * want to clear the original.
9251  */
9252  src = NULL;
9253  }
9254  else if (db_bit_string_coerce (src, target, &data_stat) != NO_ERROR)
9255  {
9256  status = DOMAIN_INCOMPATIBLE;
9257  }
9258  else if (data_stat == DATA_STATUS_TRUNCATED && coercion_mode != TP_FORCE_COERCION &&
9260  || coercion_mode == TP_IMPLICIT_COERCION))
9261  {
9262  status = DOMAIN_OVERFLOW;
9263  pr_clear_value (target);
9264  }
9265  else
9266  {
9267  status = DOMAIN_COMPATIBLE;
9268  }
9269  break;
9270  }
9271  break;
9272 
9273  case DB_TYPE_VARCHAR:
9274  case DB_TYPE_CHAR:
9275  case DB_TYPE_NCHAR:
9276  case DB_TYPE_VARNCHAR:
9277  switch (original_type)
9278  {
9279  case DB_TYPE_VARCHAR:
9280  case DB_TYPE_CHAR:
9281  case DB_TYPE_NCHAR:
9282  case DB_TYPE_VARNCHAR:
9283  if (src == dest && tp_can_steal_string (src, desired_domain))
9284  {
9285  tp_value_slam_domain (dest, desired_domain);
9286  /*
9287  * Set "src" to NULL to prevent the wrapup code from undoing
9288  * our work; since we haven't actually made a copy, we don't
9289  * want to clear the original.
9290  */
9291  src = NULL;
9292  }
9293  else if (db_char_string_coerce (src, target, &data_stat) != NO_ERROR)
9294  {
9295  status = DOMAIN_INCOMPATIBLE;
9296  }
9297  else if (data_stat == DATA_STATUS_TRUNCATED && coercion_mode != TP_FORCE_COERCION &&
9299  || coercion_mode == TP_IMPLICIT_COERCION))
9300  {
9301  status = DOMAIN_OVERFLOW;
9302  pr_clear_value (target);
9303  }
9304  else if (desired_domain->collation_flag != TP_DOMAIN_COLL_LEAVE)
9305  {
9306  db_string_put_cs_and_collation (target, TP_DOMAIN_CODESET (desired_domain),
9307  TP_DOMAIN_COLLATION (desired_domain));
9308  status = DOMAIN_COMPATIBLE;
9309  }
9310  break;
9311 
9312  case DB_TYPE_ENUMERATION:
9313  {
9314  DB_VALUE varchar_val;
9315 
9316  if (desired_type == DB_TYPE_NCHAR || desired_type == DB_TYPE_VARNCHAR)
9317  {
9318  status = DOMAIN_INCOMPATIBLE;
9319  }
9320  else if (tp_enumeration_to_varchar (src, &varchar_val) != NO_ERROR)
9321  {
9322  status = DOMAIN_ERROR;
9323  }
9324  else
9325  {
9326  status =
9327  tp_value_cast_internal (&varchar_val, target, desired_domain, coercion_mode, do_domain_select, false);
9328  }
9329  }
9330  break;
9331 
9332  case DB_TYPE_BIGINT:
9333  case DB_TYPE_INTEGER:
9334  case DB_TYPE_SMALLINT:
9335  {
9336  int max_size = TP_BIGINT_PRECISION + 2 + 1;
9337  char *new_string;
9338  DB_BIGINT num;
9339 
9340  new_string = (char *) db_private_alloc (NULL, max_size);
9341  if (!new_string)
9342  {
9343  status = DOMAIN_ERROR;
9344  break;
9345  }
9346 
9347  if (original_type == DB_TYPE_BIGINT)
9348  {
9349  num = db_get_bigint (src);
9350  }
9351  else if (original_type == DB_TYPE_INTEGER)
9352  {
9353  num = (DB_BIGINT) db_get_int (src);
9354  }
9355  else /* DB_TYPE_SHORT */
9356  {
9357  num = (DB_BIGINT) db_get_short (src);
9358  }
9359 
9360  if (tp_ltoa (num, new_string, 10))
9361  {
9363  && db_value_precision (target) < (int) strlen (new_string))
9364  {
9365  status = DOMAIN_OVERFLOW;
9366  db_private_free_and_init (NULL, new_string);
9367  }
9368  else
9369  {
9370  make_desired_string_db_value (desired_type, desired_domain, new_string, target, &status,
9371  &data_stat);
9372  }
9373  }
9374  else
9375  {
9376  status = DOMAIN_ERROR;
9377  db_private_free_and_init (NULL, new_string);
9378  }
9379  }
9380  break;
9381 
9382  case DB_TYPE_DOUBLE:
9383  case DB_TYPE_FLOAT:
9384  {
9385  if (original_type == DB_TYPE_FLOAT)
9386  {
9387  tp_ftoa (src, target);
9388  }
9389  else
9390  {
9391  tp_dtoa (src, target);
9392  }
9393 
9394  if (DB_IS_NULL (target))
9395  {
9397  {
9398  /* no way to report "out of memory" from tp_value_cast_internal() ?? */
9399  status = DOMAIN_ERROR;
9400  }
9401  else
9402  {
9403  status = DOMAIN_INCOMPATIBLE;
9404  }
9405  }
9406  else if (DB_VALUE_PRECISION (target) != TP_FLOATING_PRECISION_VALUE
9407  && (db_get_string_length (target) > DB_VALUE_PRECISION (target)))
9408  {
9409  status = DOMAIN_OVERFLOW;
9410  pr_clear_value (target);
9411  }
9412  }
9413  break;
9414 
9415  case DB_TYPE_NUMERIC:
9416  {
9417  char str_buf[NUMERIC_MAX_STRING_SIZE];
9418  char *new_string;
9419  int max_size;
9420 
9421  numeric_db_value_print (src, str_buf);
9422 
9423  max_size = strlen (str_buf) + 1;
9424  new_string = (char *) db_private_alloc (NULL, max_size);
9425  if (new_string == NULL)
9426  {
9427  status = DOMAIN_ERROR;
9428  break;
9429  }
9430 
9431  strcpy (new_string, str_buf);
9432 
9434  && db_value_precision (target) < max_size - 1)
9435  {
9436  status = DOMAIN_OVERFLOW;
9437  db_private_free_and_init (NULL, new_string);
9438  }
9439  else
9440  {
9441  make_desired_string_db_value (desired_type, desired_domain, new_string, target, &status, &data_stat);
9442  }
9443  }
9444  break;
9445 
9446  case DB_TYPE_MONETARY:
9447  {
9448  /* monetary symbol = 3 sign = 1 dot = 1 fraction digits = 2 NUL terminator = 1 */
9449  int max_size = DBL_MAX_DIGITS + 3 + 1 + 1 + 2 + 1;
9450  char *new_string;
9451  char *p;
9452 
9453  new_string = (char *) db_private_alloc (NULL, max_size);
9454  if (!new_string)
9455  {
9456  status = DOMAIN_ERROR;
9457  break;
9458  }
9459 
9460  snprintf (new_string, max_size - 1, "%s%.*f", lang_currency_symbol (db_get_monetary (src)->type), 2,
9461  db_get_monetary (src)->amount);
9462  new_string[max_size - 1] = '\0';
9463 
9464  p = new_string + strlen (new_string);
9465  for (--p; p >= new_string && *p == '0'; p--)
9466  { /* remove trailing zeros */
9467  *p = '\0';
9468  }
9469  if (*p == '.') /* remove point */
9470  {
9471  *p = '\0';
9472  }
9473 
9475  && db_value_precision (target) < (int) strlen (new_string))
9476  {
9477  status = DOMAIN_OVERFLOW;
9478  db_private_free_and_init (NULL, new_string);
9479  }
9480  else
9481  {
9482  make_desired_string_db_value (desired_type, desired_domain, new_string, target, &status, &data_stat);
9483  }
9484  }
9485  break;
9486 
9487  case DB_TYPE_DATE:
9488  case DB_TYPE_TIME:
9489  case DB_TYPE_TIMESTAMP:
9490  case DB_TYPE_TIMESTAMPTZ:
9491  case DB_TYPE_TIMESTAMPLTZ:
9492  case DB_TYPE_DATETIME:
9493  case DB_TYPE_DATETIMETZ:
9494  case DB_TYPE_DATETIMELTZ:
9495  {
9496  int max_size = DATETIMETZ_BUF_SIZE;
9497  char *new_string;
9498 
9499  new_string = (char *) db_private_alloc (NULL, max_size);
9500  if (!new_string)
9501  {
9502  status = DOMAIN_ERROR;
9503  break;
9504  }
9505 
9506  err = NO_ERROR;
9507 
9508  switch (original_type)
9509  {
9510  case DB_TYPE_DATE:
9511  db_date_to_string (new_string, max_size, (DB_DATE *) db_get_date (src));
9512  break;
9513  case DB_TYPE_TIME:
9514  db_time_to_string (new_string, max_size, (DB_TIME *) db_get_time (src));
9515  break;
9516  case DB_TYPE_TIMESTAMP:
9517  db_timestamp_to_string (new_string, max_size, (DB_TIMESTAMP *) db_get_timestamp (src));
9518  break;
9519  case DB_TYPE_TIMESTAMPLTZ:
9520  v_utime = *db_get_timestamp (src);
9521  err = tz_create_session_tzid_for_timestamp (&v_utime, &ses_tz_id);
9522  if (err != NO_ERROR)
9523  {
9524  break;
9525  }
9526  db_timestamptz_to_string (new_string, max_size, &v_utime, &ses_tz_id);
9527  break;
9528  case DB_TYPE_TIMESTAMPTZ:
9529  v_timestamptz = *db_get_timestamptz (src);
9530  db_timestamptz_to_string (new_string, max_size, &v_timestamptz.timestamp, &v_timestamptz.tz_id);
9531  break;
9532  case DB_TYPE_DATETIMELTZ:
9533  v_datetime = *db_get_datetime (src);
9534  err = tz_create_session_tzid_for_datetime (&v_datetime, true, &ses_tz_id);
9535  if (err != NO_ERROR)
9536  {
9537  break;
9538  }
9539  db_datetimetz_to_string (new_string, max_size, &v_datetime, &ses_tz_id);
9540  break;
9541  case DB_TYPE_DATETIMETZ:
9542  v_datetimetz = *db_get_datetimetz (src);
9543  db_datetimetz_to_string (new_string, max_size, &v_datetimetz.datetime, &v_datetimetz.tz_id);
9544  break;
9545  case DB_TYPE_DATETIME:
9546  default:
9547  db_datetime_to_string (new_string, max_size, (DB_DATETIME *) db_get_datetime (src));
9548  break;
9549  }
9550 
9551  if (err != NO_ERROR)
9552  {
9553  status = DOMAIN_ERROR;
9554  break;
9555  }
9556 
9558  && db_value_precision (target) < (int) strlen (new_string))
9559  {
9560  status = DOMAIN_OVERFLOW;
9561  db_private_free_and_init (NULL, new_string);
9562  }
9563  else
9564  {
9565  make_desired_string_db_value (desired_type, desired_domain, new_string, target, &status, &data_stat);
9566  }
9567  }
9568  break;
9569 
9570  case DB_TYPE_BIT:
9571  case DB_TYPE_VARBIT:
9572  {
9573  int max_size;
9574  char *new_string;
9575  int convert_error;
9576 
9577  max_size = ((db_get_string_length (src) + 3) / 4) + 1;
9578  new_string = (char *) db_private_alloc (NULL, max_size);
9579  if (!new_string)
9580  {
9581  status = DOMAIN_ERROR;
9582  break;
9583  }
9584 
9585  convert_error = bfmt_print (1 /* BIT_STRING_HEX */ , src,
9586  new_string, max_size);
9587 
9588  if (convert_error == NO_ERROR)
9589  {
9591  && (db_value_precision (target) < (int) strlen (new_string)))
9592  {
9593  status = DOMAIN_OVERFLOW;
9594  db_private_free_and_init (NULL, new_string);
9595  }
9596  else
9597  {
9598  make_desired_string_db_value (desired_type, desired_domain, new_string, target, &status,
9599  &data_stat);
9600  }
9601  }
9602  else if (convert_error == -1)
9603  {
9604  status = DOMAIN_OVERFLOW;
9605  db_private_free_and_init (NULL, new_string);
9606  }
9607  else
9608  {
9609  status = DOMAIN_ERROR;
9610  db_private_free_and_init (NULL, new_string);
9611  }
9612  }
9613  break;
9614 
9615  case DB_TYPE_CLOB:
9616  switch (desired_type)
9617  {
9618  case DB_TYPE_NCHAR:
9619  case DB_TYPE_VARNCHAR:
9620  status = DOMAIN_INCOMPATIBLE;
9621  break;
9622  default:
9623  {
9624  DB_VALUE tmpval;
9625  DB_VALUE cs;
9626 
9627  db_make_null (&tmpval);
9628  /* convert directly from CLOB into charset of desired domain string */
9629  db_make_int (&cs, desired_domain->codeset);
9630  err = db_clob_to_char (src, &cs, &tmpval);
9631  if (err == NO_ERROR)
9632  {
9633  err =
9634  tp_value_cast_internal (&tmpval, dest, desired_domain, coercion_mode, do_domain_select, false);
9635  }
9636 
9637  pr_clear_value (&tmpval);
9638  }
9639  break;
9640  }
9641  break;
9642 
9643  case DB_TYPE_JSON:
9644  {
9645  char *json_str;
9646  int len;
9647 
9649  len = strlen (json_str);
9650 
9651  if (db_value_precision (target) != TP_FLOATING_PRECISION_VALUE && db_value_precision (target) < len)
9652  {
9653  status = DOMAIN_OVERFLOW;
9654  db_private_free_and_init (NULL, json_str);
9655  }
9656  else
9657  {
9658  make_desired_string_db_value (desired_type, desired_domain, json_str, target, &status, &data_stat);
9659  target->need_clear = true;
9660  }
9661  }
9662  break;
9663 
9664  default:
9665  status = DOMAIN_INCOMPATIBLE;
9666  break;
9667  }
9668  break;
9669 
9670  case DB_TYPE_BLOB:
9671  switch (original_type)
9672  {
9673  case DB_TYPE_BLOB:
9674  err = db_value_clone ((DB_VALUE *) src, target);
9675  break;
9676  case DB_TYPE_BIT:
9677  case DB_TYPE_VARBIT:
9678  err = db_bit_to_blob (src, target);
9679  break;
9680  case DB_TYPE_CHAR:
9681  case DB_TYPE_VARCHAR:
9682  case DB_TYPE_NCHAR:
9683  case DB_TYPE_VARNCHAR:
9684  err = db_char_to_blob (src, target);
9685  break;
9686  case DB_TYPE_ENUMERATION:
9687  {
9688  DB_VALUE varchar_val;
9689 
9690  if (tp_enumeration_to_varchar (src, &varchar_val) != NO_ERROR)
9691  {
9692  status = DOMAIN_ERROR;
9693  break;
9694  }
9695  status =
9696  tp_value_cast_internal (&varchar_val, target, desired_domain, coercion_mode, do_domain_select, false);
9697  }
9698  break;
9699  default:
9700  status = DOMAIN_INCOMPATIBLE;
9701  break;
9702  }
9703  break;
9704 
9705  case DB_TYPE_CLOB:
9706  switch (original_type)
9707  {
9708  case DB_TYPE_CLOB:
9709  err = db_value_clone ((DB_VALUE *) src, target);
9710  break;
9711  case DB_TYPE_CHAR:
9712  case DB_TYPE_VARCHAR:
9713  err = db_char_to_clob (src, target);
9714  break;
9715  case DB_TYPE_ENUMERATION:
9716  {
9717  DB_VALUE varchar_val;
9718  if (tp_enumeration_to_varchar (src, &varchar_val) != NO_ERROR)
9719  {
9720  status = DOMAIN_ERROR;
9721  break;
9722  }
9723  status =
9724  tp_value_cast_internal (&varchar_val, target, desired_domain, coercion_mode, do_domain_select, false);
9725  break;
9726  }
9727  default:
9728  status = DOMAIN_INCOMPATIBLE;
9729  break;
9730  }
9731  break;
9732 
9733  case DB_TYPE_ENUMERATION:
9734  {
9735  unsigned short val_idx = 0;
9736  int val_str_size = 0;
9737  const char *val_str = NULL;
9738  bool exit = false, alloc_string = true;
9739  DB_VALUE conv_val;
9740 
9741  db_make_null (&conv_val);
9742 
9743  if (src->domain.general_info.is_null)
9744  {
9745  db_make_null (target);
9746  break;
9747  }
9748 
9749  switch (original_type)
9750  {
9751  case DB_TYPE_SHORT:
9752  val_idx = (unsigned short) db_get_short (src);
9753  break;
9754  case DB_TYPE_INTEGER:
9755  if (OR_CHECK_USHRT_OVERFLOW (db_get_int (src)))
9756  {
9757  status = DOMAIN_INCOMPATIBLE;
9758  }
9759  else
9760  {
9761  val_idx = (unsigned short) db_get_int (src);
9762  }
9763  break;
9764  case DB_TYPE_BIGINT:
9766  {
9767  status = DOMAIN_INCOMPATIBLE;
9768  }
9769  else
9770  {
9771  val_idx = (unsigned short) db_get_bigint (src);
9772  }
9773  break;
9774  case DB_TYPE_FLOAT:
9775  if (OR_CHECK_USHRT_OVERFLOW (floor (db_get_float (src))))
9776  {
9777  status = DOMAIN_INCOMPATIBLE;
9778  }
9779  else
9780  {
9781  val_idx = (unsigned short) floor (db_get_float (src));
9782  }
9783  break;
9784  case DB_TYPE_DOUBLE:
9785  if (OR_CHECK_USHRT_OVERFLOW (floor (db_get_double (src))))
9786  {
9787  status = DOMAIN_INCOMPATIBLE;
9788  }
9789  else
9790  {
9791  val_idx = (unsigned short) floor (db_get_double (src));
9792  }
9793  break;
9794  case DB_TYPE_NUMERIC:
9795  {
9796  DB_VALUE val;
9798 
9799  db_make_double (&val, 0);
9800  err = numeric_db_value_coerce_from_num ((DB_VALUE *) src, &val, &stat);
9801  if (err != NO_ERROR)
9802  {
9803  status = DOMAIN_ERROR;
9804  }
9805  else
9806  {
9807  if (OR_CHECK_USHRT_OVERFLOW (floor (db_get_double (&val))))
9808  {
9809  status = DOMAIN_INCOMPATIBLE;
9810  }
9811  else
9812  {
9813  val_idx = (unsigned short) floor (db_get_double (&val));
9814  }
9815  }
9816  break;
9817  }
9818  case DB_TYPE_MONETARY:
9819  v_money = db_get_monetary (src);
9820  if (OR_CHECK_USHRT_OVERFLOW (floor (v_money->amount)))
9821  {
9822  status = DOMAIN_INCOMPATIBLE;
9823  }
9824  else
9825  {
9826  val_idx = (unsigned short) floor (v_money->amount);
9827  }
9828  break;
9829  case DB_TYPE_TIMESTAMP:
9830  case DB_TYPE_TIMESTAMPLTZ:
9831  case DB_TYPE_TIMESTAMPTZ:
9832  case DB_TYPE_DATETIME:
9833  case DB_TYPE_DATETIMETZ:
9834  case DB_TYPE_DATETIMELTZ:
9835  case DB_TYPE_DATE:
9836  case DB_TYPE_TIME:
9837  case DB_TYPE_BIT:
9838  case DB_TYPE_VARBIT:
9839  case DB_TYPE_BLOB:
9840  case DB_TYPE_CLOB:
9841  {
9842  status =
9843  tp_value_cast_internal (src, &conv_val, tp_domain_resolve_default (DB_TYPE_STRING), coercion_mode,
9844  do_domain_select, false);
9845  if (status == DOMAIN_COMPATIBLE)
9846  {
9847  val_str = db_get_string (&conv_val);
9848  val_str_size = db_get_string_size (&conv_val);
9849  }
9850  }
9851  break;
9852  case DB_TYPE_CHAR:
9853  case DB_TYPE_VARCHAR:
9854  if (db_get_string_codeset (src) != TP_DOMAIN_CODESET (desired_domain))
9855  {
9856  DB_DATA_STATUS data_status = DATA_STATUS_OK;
9857 
9858  if (TP_DOMAIN_CODESET (desired_domain) == INTL_CODESET_RAW_BYTES)
9859  {
9860  /* avoid data truncation when converting to binary charset */
9861  db_value_domain_init (&conv_val, DB_VALUE_TYPE (src), db_get_string_size (src), 0);
9862  }
9863  else
9864  {
9865  db_value_domain_init (&conv_val, DB_VALUE_TYPE (src), DB_VALUE_PRECISION (src), 0);
9866  }
9867 
9868  db_string_put_cs_and_collation (&conv_val, TP_DOMAIN_CODESET (desired_domain),
9869  TP_DOMAIN_COLLATION (desired_domain));
9870 
9871  if (db_char_string_coerce (src, &conv_val, &data_status) != NO_ERROR || data_status != DATA_STATUS_OK)
9872  {
9873  status = DOMAIN_ERROR;
9874  pr_clear_value (&conv_val);
9875  }
9876  else
9877  {
9878  val_str = db_get_string (&conv_val);
9879  val_str_size = db_get_string_size (&conv_val);
9880  }
9881  }
9882  else
9883  {
9884  val_str = db_get_string (src);
9885  val_str_size = db_get_string_size (src);
9886  }
9887  break;
9888  case DB_TYPE_ENUMERATION:
9889  if (DOM_GET_ENUM_ELEMS_COUNT (desired_domain) == 0)
9890  {
9891  pr_clone_value (src, target);
9892  exit = true;
9893  break;
9894  }
9895  val_str = db_get_enum_string (src);
9896  val_str_size = db_get_enum_string_size (src);
9897  if (val_str == NULL)
9898  {
9899  /* src has a short value or a string value or both. We prefer to use the string value when matching
9900  * against the desired domain but, if this is not set, we will use the value index */
9901  val_idx = db_get_enum_short (src);
9902  }
9903  else
9904  {
9905  if (db_get_enum_codeset (src) != TP_DOMAIN_CODESET (desired_domain))
9906  {
9907  /* first convert charset of the original value to charset of destination domain */
9908  DB_VALUE tmp;
9909  DB_DATA_STATUS data_status = DATA_STATUS_OK;
9910 
9911  /* charset conversion can handle only CHAR/VARCHAR DB_VALUEs, create a STRING value with max
9912  * precision (so that no truncation occurs) from the ENUM source string */
9913  db_make_varchar (&tmp, DB_MAX_STRING_LENGTH, val_str, val_str_size, db_get_enum_codeset (src),
9914  db_get_enum_collation (src));
9915 
9916  /* initialize destination value of conversion */
9918  db_string_put_cs_and_collation (&conv_val, TP_DOMAIN_CODESET (desired_domain),
9919  TP_DOMAIN_COLLATION (desired_domain));
9920 
9921  if (db_char_string_coerce (&tmp, &conv_val, &data_status) != NO_ERROR
9922  || data_status != DATA_STATUS_OK)
9923  {
9924  status = DOMAIN_ERROR;
9925  pr_clear_value (&conv_val);
9926  val_str = NULL;
9927  val_idx = 0;
9928  }
9929  else
9930  {
9931  val_str = db_get_string (&conv_val);
9932  val_str_size = db_get_string_size (&conv_val);
9933  }
9934  pr_clear_value (&tmp);
9935  }
9936  }
9937  break;
9938  default:
9939  status = DOMAIN_INCOMPATIBLE;
9940  break;
9941  }
9942 
9943  if (exit)
9944  {
9945  break;
9946  }
9947 
9948  if (status == DOMAIN_COMPATIBLE)
9949  {
9950  if (val_str != NULL)
9951  {
9952  /* We have to search through the elements of the desired domain to find the index for val_str. */
9953  int i, size;
9954  DB_ENUM_ELEMENT *db_enum = NULL;
9955  int elem_count = DOM_GET_ENUM_ELEMS_COUNT (desired_domain);
9956 
9957  for (i = 1; i <= elem_count; i++)
9958  {
9959  db_enum = &DOM_GET_ENUM_ELEM (desired_domain, i);
9960  size = DB_GET_ENUM_ELEM_STRING_SIZE (db_enum);
9961 
9962  if (!ignore_trailing_space)
9963  {
9964  ti = (desired_domain->type->id == DB_TYPE_CHAR || desired_domain->type->id == DB_TYPE_NCHAR);
9965  }
9966 
9967  /* use collation from the PT_TYPE_ENUMERATION */
9968  if (QSTR_COMPARE (desired_domain->collation_id, (const unsigned char *) val_str, val_str_size,
9969  (const unsigned char *) DB_GET_ENUM_ELEM_STRING (db_enum), size, ti) == 0)
9970  {
9971  break;
9972  }
9973  }
9974 
9975  val_idx = i;
9976  if (i > elem_count)
9977  {
9978  if (val_str[0] == 0)
9979  {
9980  /* The source value is string with length 0 and can be matched with enum "special error value"
9981  * if it's not a valid ENUM value */
9982  db_make_enumeration (target, 0, NULL, 0, TP_DOMAIN_CODESET (desired_domain),
9983  TP_DOMAIN_COLLATION (desired_domain));
9984  break;
9985  }
9986  else
9987  {
9988  status = DOMAIN_INCOMPATIBLE;
9989  }
9990  }
9991  }
9992  else
9993  {
9994  /* We have the index, we need to get the actual string value from the desired domain */
9995  if (val_idx > DOM_GET_ENUM_ELEMS_COUNT (desired_domain))
9996  {
9997  status = DOMAIN_INCOMPATIBLE;
9998  }
9999  else if (val_idx == 0)
10000  {
10001  /* ENUM Special error value */
10002  db_make_enumeration (target, 0, NULL, 0, TP_DOMAIN_CODESET (desired_domain),
10003  TP_DOMAIN_COLLATION (desired_domain));
10004  break;
10005  }
10006  else
10007  {
10008  val_str_size = DB_GET_ENUM_ELEM_STRING_SIZE (&DOM_GET_ENUM_ELEM (desired_domain, val_idx));
10009  val_str = DB_GET_ENUM_ELEM_STRING (&DOM_GET_ENUM_ELEM (desired_domain, val_idx));
10010  }
10011  }
10012 
10013  if (status == DOMAIN_COMPATIBLE)
10014  {
10015  const char *enum_str;
10016 
10017  assert (val_str != NULL);
10018 
10019  if (!DB_IS_NULL (&conv_val))
10020  {
10021  /* if charset conversion, than use the converted value buffer to avoid an additional copy */
10022  alloc_string = false;
10023  conv_val.need_clear = false;
10024  }
10025 
10026  if (alloc_string)
10027  {
10028  char *enum_str_tmp = (char *) db_private_alloc (NULL, val_str_size + 1);
10029  if (enum_str_tmp == NULL)
10030  {
10031  status = DOMAIN_ERROR;
10032  pr_clear_value (&conv_val);
10033  break;
10034  }
10035  else
10036  {
10037  memcpy (enum_str_tmp, val_str, val_str_size);
10038  enum_str_tmp[val_str_size] = 0;
10039  }
10040 
10041  enum_str = enum_str_tmp;
10042  }
10043  else
10044  {
10045  enum_str = val_str;
10046  }
10047 
10048  db_make_enumeration (target, val_idx, enum_str, val_str_size, TP_DOMAIN_CODESET (desired_domain),
10049  TP_DOMAIN_COLLATION (desired_domain));
10050  target->need_clear = true;
10051  }
10052  }
10053  pr_clear_value (&conv_val);
10054  }
10055  break;
10056  case DB_TYPE_JSON:
10057  {
10058  JSON_DOC *doc = NULL;
10059 
10060  switch (original_type)
10061  {
10062  case DB_TYPE_CHAR:
10063  case DB_TYPE_VARCHAR:
10064  case DB_TYPE_NCHAR:
10065  case DB_TYPE_VARNCHAR:
10066  {
10067  DB_VALUE utf8_str;
10068  const DB_VALUE *json_str_val = &utf8_str;
10069  int error_code = db_json_copy_and_convert_to_utf8 (src, &utf8_str, &json_str_val);
10070  if (error_code != NO_ERROR)
10071  {
10072  ASSERT_ERROR ();
10073  status = DOMAIN_ERROR;
10074  break;
10075  }
10076 
10077  unsigned int str_size = db_get_string_size (json_str_val);
10078  const char *original_str = db_get_string (json_str_val);
10079 
10080  error_code = db_json_get_json_from_str (original_str, doc, str_size);
10081  if (error_code != NO_ERROR)
10082  {
10083  pr_clear_value (&utf8_str);
10084  assert (doc == NULL);
10085  status = DOMAIN_ERROR;
10086  break;
10087  }
10088 
10089  if (desired_domain->json_validator
10090  && db_json_validate_doc (desired_domain->json_validator, doc) != NO_ERROR)
10091  {
10092  ASSERT_ERROR ();
10093  pr_clear_value (&utf8_str);
10094  db_json_delete_doc (doc);
10095  status = DOMAIN_ERROR;
10096  break;
10097  }
10098  pr_clear_value (&utf8_str);
10099  }
10100  break;
10101  case DB_TYPE_SHORT:
10102  doc = db_json_allocate_doc ();
10103  db_json_set_int_to_doc (doc, db_get_short (src));
10104  break;
10105  case DB_TYPE_INTEGER:
10106  doc = db_json_allocate_doc ();
10107  db_json_set_int_to_doc (doc, db_get_int (src));
10108  break;
10109  case DB_TYPE_BIGINT:
10110  doc = db_json_allocate_doc ();
10112  break;
10113  case DB_TYPE_DOUBLE:
10114  doc = db_json_allocate_doc ();
10116  break;
10117  case DB_TYPE_FLOAT:
10118  case DB_TYPE_NUMERIC:
10119  {
10120  DB_VALUE double_value;
10121 
10122  doc = db_json_allocate_doc ();
10123  db_value_coerce (src, &double_value, db_type_to_db_domain (DB_TYPE_DOUBLE));
10124  db_json_set_double_to_doc (doc, db_get_double (&double_value));
10125  pr_clear_value (&double_value);
10126  }
10127  break;
10128  default:
10129  status = DOMAIN_INCOMPATIBLE;
10130  break;
10131  }
10132 
10133  if (status == DOMAIN_COMPATIBLE)
10134  {
10135  db_make_json (target, doc, true);
10136  }
10137  else
10138  {
10139  if (doc != NULL)
10140  {
10141  db_json_delete_doc (doc);
10142  }
10143  }
10144  }
10145  break;
10146  default:
10147  status = DOMAIN_INCOMPATIBLE;
10148  break;
10149  }
10150 
10151  if (err < 0)
10152  {
10153  status = DOMAIN_ERROR;
10154  }
10155 
10156  if (status != DOMAIN_COMPATIBLE)
10157  {
10158  if (src != dest)
10159  {
10160 #if 0 /* TODO - */
10161  pr_clear_value (dest);
10162 #endif
10163 
10164  /* make sure this doesn't have any partial results */
10165  if (preserve_domain)
10166  {
10167  db_value_domain_init (dest, desired_type, desired_domain->precision, desired_domain->scale);
10168  db_value_put_null (dest);
10169  }
10170  else
10171  {
10172  db_make_null (dest);
10173  }
10174  }
10175  }
10176  else if (src == dest)
10177  {
10178  /* coercsion successful, transfer the value if src == dest */
10179  pr_clear_value (dest);
10180  *dest = temp;
10181  }
10182 
10183  pr_clear_value (&src_replacement);
10184 
10185  return status;
10186 }
10187 
10188 /*
10189  * tp_value_cast - Coerce a value into one of another domain.
10190  * return: TP_DOMAIN_STATUS
10191  * src(in): src DB_VALUE
10192  * dest(out): dest DB_VALUE
10193  * desired_domain(in):
10194  * implicit_coercion(in): flag for the coercion is implicit
10195  * Note:
10196  * This function does select domain from desired_domain
10197  */
10199 tp_value_cast (const DB_VALUE * src, DB_VALUE * dest, const TP_DOMAIN * desired_domain, bool implicit_coercion)
10200 {
10202 
10203  mode = (implicit_coercion ? TP_IMPLICIT_COERCION : TP_EXPLICIT_COERCION);
10204  return tp_value_cast_internal (src, dest, desired_domain, mode, true, false);
10205 }
10206 
10208 tp_value_cast_force (const DB_VALUE * src, DB_VALUE * dest, const TP_DOMAIN * desired_domain, bool implicit_coercion)
10209 {
10211 
10212  mode = TP_FORCE_COERCION;
10213  return tp_value_cast_internal (src, dest, desired_domain, mode, true, false);
10214 }
10215 
10216 /*
10217  * tp_value_cast_preserve_domain - Coerce a value into one of another domain.
10218  * return: TP_DOMAIN_STATUS
10219  * src(in): src DB_VALUE
10220  * dest(out): dest DB_VALUE
10221  * desired_domain(in):
10222  * implicit_coercion(in): flag for the coercion is implicit
10223  * preserve_domain(in): flag to preserve dest's domain
10224  * Note:
10225  * This function dose not change the domain type of dest to a DB_NULL_TYPE.
10226  */
10228 tp_value_cast_preserve_domain (const DB_VALUE * src, DB_VALUE * dest, const TP_DOMAIN * desired_domain,
10229  bool implicit_coercion, bool preserve_domain)
10230 {
10232 
10233  mode = (implicit_coercion ? TP_IMPLICIT_COERCION : TP_EXPLICIT_COERCION);
10234  return tp_value_cast_internal (src, dest, desired_domain, mode, true, true);
10235 }
10236 
10237 /*
10238  * tp_value_cast_no_domain_select - Coerce a value into one of another domain.
10239  * return: TP_DOMAIN_STATUS
10240  * src(in): src DB_VALUE
10241  * dest(out): dest DB_VALUE
10242  * desired_domain(in):
10243  * implicit_coercion(in): flag for the coercion is implicit
10244  * Note:
10245  * This function does not select domain from desired_domain
10246  */
10248 tp_value_cast_no_domain_select (const DB_VALUE * src, DB_VALUE * dest, const TP_DOMAIN * desired_domain,
10249  bool implicit_coercion)
10250 {
10252 
10253  mode = (implicit_coercion ? TP_IMPLICIT_COERCION : TP_EXPLICIT_COERCION);
10254  return tp_value_cast_internal (src, dest, desired_domain, mode, false, false);
10255 }
10256 
10257 /*
10258  * tp_value_change_coll_and_codeset () - change the collation and codeset of a
10259  * value
10260  * returns: cast operation result
10261  * src(in): source DB_VALUE
10262  * dest(in): destination DB_VALUE where src will be copied/adjusted to
10263  * coll_id(in): destination collation id
10264  * codeset(in): destination codeset
10265  */
10267 tp_value_change_coll_and_codeset (DB_VALUE * src, DB_VALUE * dest, int coll_id, int codeset)
10268 {
10269  TP_DOMAIN *temp_domain;
10270 
10271  assert (src != NULL && dest != NULL);
10273 
10274  if (db_get_string_collation (src) == coll_id && db_get_string_codeset (src) == codeset)
10275  {
10276  /* early exit scenario */
10277  return DOMAIN_COMPATIBLE;
10278  }
10279 
10280  /* create new domain and adjust collation and codeset */
10281  temp_domain = tp_domain_resolve_value (src, NULL);
10282  if (temp_domain != NULL && temp_domain->is_cached)
10283  {
10284  temp_domain = tp_domain_copy (temp_domain, false);
10285  }
10286  if (temp_domain == NULL)
10287  {
10288  /* not exactly a relevant error code, but should serve it's purpose */
10289  assert (false);
10290  return DOMAIN_ERROR;
10291  }
10292 
10293  temp_domain->collation_id = coll_id;
10294  temp_domain->codeset = codeset;
10295 
10296  /* cache domain */
10297  temp_domain = tp_domain_cache (temp_domain);
10298 
10299  /* cast the value */
10300  return tp_value_cast (src, dest, temp_domain, true);
10301 }
10302 
10303 /*
10304  * VALUE COMPARISON
10305  */
10306 
10307 /*
10308  * oidcmp - Compares two OIDs and returns a DB_ style status code.
10309  * return: DB_ comparison status code
10310  * oid1(in): first oid
10311  * oid2(in): second oid
10312  * Note:
10313  * The underlying oid_compare should be using these so we can avoid
10314  * an extra level of indirection.
10315  */
10317 oidcmp (OID * oid1, OID * oid2)
10318 {
10319  DB_VALUE_COMPARE_RESULT status;
10320  int c;
10321 
10322  c = oid_compare (oid1, oid2);
10323  if (c < 0)
10324  {
10325  status = DB_LT;
10326  }
10327  else if (c > 0)
10328  {
10329  status = DB_GT;
10330  }
10331  else
10332  {
10333  status = DB_EQ;
10334  }
10335 
10336  return status;
10337 }
10338 
10339 /*
10340  * tp_more_general_type - compares two type with respect to generality
10341  * return: 0 if same type,
10342  * <0 if type1 less general then type2,
10343  * >0 otherwise
10344  * type1(in): first type
10345  * type2(in): second type
10346  */
10347 int
10348 tp_more_general_type (const DB_TYPE type1, const DB_TYPE type2)
10349 {
10350  static int rank[DB_TYPE_LAST + 1];
10351  static int rank_init = 0;
10352  int i;
10353 
10354  if (type1 == type2)
10355  {
10356  return 0;
10357  }
10358  if ((unsigned) type1 > DB_TYPE_LAST)
10359  {
10360 #if defined (CUBRID_DEBUG)
10361  printf ("tp_more_general_type: DB type 1 out of range: %d\n", type1);
10362 #endif /* CUBRID_DEBUG */
10363  return 0;
10364  }
10365  if ((unsigned) type2 > DB_TYPE_LAST)
10366  {
10367 #if defined (CUBRID_DEBUG)
10368  printf ("tp_more_general_type: DB type 2 out of range: %d\n", type2);
10369 #endif /* CUBRID_DEBUG */
10370  return 0;
10371  }
10372  if (!rank_init)
10373  {
10374  /* set up rank so we can do fast table lookup */
10375  for (i = 0; i <= DB_TYPE_LAST; i++)
10376  {
10377  rank[i] = 0;
10378  }
10379  for (i = 0; db_type_rank[i] < (DB_TYPE_LAST + 1); i++)
10380  {
10381  rank[db_type_rank[i]] = i;
10382  }
10383  rank_init = 1;
10384  }
10385 
10386  return rank[type1] - rank[type2];
10387 }
10388 
10389 /*
10390  * tp_set_compare - compare two collection
10391  * return: zero if equal, <0 if less, >0 if greater
10392  * value1(in): first collection value
10393  * value2(in): second collection value
10394  * do_coercion(in): coercion flag
10395  * total_order(in): total order flag
10396  * Note:
10397  * If the total_order flag is set, it will return one of DB_LT, DB_GT, or
10398  * SB_SUBSET, DB_SUPERSET, or DB_EQ, it will not return DB_UNK.
10399  */
10401 tp_set_compare (const DB_VALUE * value1, const DB_VALUE * value2, int do_coercion, int total_order)
10402 {
10403  DB_VALUE temp;
10404  int coercion;
10405  DB_VALUE *v1, *v2;
10406  DB_TYPE vtype1, vtype2;
10407  DB_SET *s1, *s2;
10410 
10411  coercion = 0;
10412  if (DB_IS_NULL (value1))
10413  {
10414  if (DB_IS_NULL (value2))
10415  {
10416  result = (total_order ? DB_EQ : DB_UNK);
10417  }
10418  else
10419  {
10420  result = (total_order ? DB_LT : DB_UNK);
10421  }
10422  }
10423  else if (DB_IS_NULL (value2))
10424  {
10425  result = (total_order ? DB_GT : DB_UNK);
10426  }
10427  else
10428  {
10429  v1 = (DB_VALUE *) value1;
10430  v2 = (DB_VALUE *) value2;
10431 
10432  vtype1 = DB_VALUE_DOMAIN_TYPE (v1);
10433  vtype2 = DB_VALUE_DOMAIN_TYPE (v2);
10434  if (vtype1 != DB_TYPE_SET && vtype1 != DB_TYPE_MULTISET && vtype1 != DB_TYPE_SEQUENCE)
10435  {
10436  return DB_NE;
10437  }
10438 
10439  if (vtype2 != DB_TYPE_SET && vtype2 != DB_TYPE_MULTISET && vtype2 != DB_TYPE_SEQUENCE)
10440  {
10441  return DB_NE;
10442  }
10443 
10444  if (vtype1 != vtype2)
10445  {
10446  if (!do_coercion)
10447  {
10448  /* types are not comparable */
10449  return DB_NE;
10450  }
10451  else
10452  {
10453  db_make_null (&temp);
10454  coercion = 1;
10455  if (tp_more_general_type (vtype1, vtype2) > 0)
10456  {
10457  /* vtype1 is more general, coerce value 2 */
10458  status = tp_value_coerce (v2, &temp, tp_domain_resolve_default (vtype1));
10459  if (status != DOMAIN_COMPATIBLE)
10460  {
10461  /*
10462  * This is arguably an error condition
10463  * but Not Equal is as close as we can come
10464  * to reporting it.
10465  */
10466  pr_clear_value (&temp);
10467  return DB_NE;
10468  }
10469  else
10470  {
10471  v2 = &temp;
10472  vtype2 = DB_VALUE_TYPE (v2);
10473  }
10474  }
10475  else
10476  {
10477  /* coerce value1 to value2's type */
10478  status = tp_value_coerce (v1, &temp, tp_domain_resolve_default (vtype2));
10479  if (status != DOMAIN_COMPATIBLE)
10480  {
10481  /*
10482  * This is arguably an error condition
10483  * but Not Equal is as close as we can come
10484  * to reporting it.
10485  */
10486  pr_clear_value (&temp);
10487  return DB_NE;
10488  }
10489  else
10490  {
10491  v1 = &temp;
10492  vtype1 = DB_VALUE_TYPE (v1);
10493  }
10494  }
10495  }
10496  }
10497  /* Here, we have two collections of the same type */
10498 
10499  s1 = db_get_set (v1);
10500  s2 = db_get_set (v2);
10501 
10502  /*
10503  * there may ba a call for set_compare returning a total
10504  * ordering some day.
10505  */
10506  if (s1 && s2)
10507  {
10508  result = set_compare (s1, s2, do_coercion);
10509  }
10510  else
10511  {
10512  result = DB_UNK;
10513  }
10514 
10515  if (coercion)
10516  {
10517  pr_clear_value (&temp);
10518  }
10519  }
10520 
10521  return result;
10522 }
10523 
10524 /*
10525  * tp_value_compare - calls tp_value_compare_with_error, but does not log error
10526  * return: zero if equal, <0 if less, >0 if greater
10527  * value1(in): first value
10528  * value2(in): second value
10529  * do_coercion(in): coercion flag
10530  * total_order(in): total order flag
10531  */
10533 tp_value_compare (const DB_VALUE * value1, const DB_VALUE * value2, int allow_coercion, int total_order)
10534 {
10535  return tp_value_compare_with_error (value1, value2, allow_coercion, total_order, NULL);
10536 }
10537 
10538 /*
10539  * tp_value_compare_with_error - compares two values
10540  * return: zero if equal, <0 if less, >0 if greater
10541  * value1(in): first value
10542  * value2(in): second value
10543  * do_coercion(in): coercion flag
10544  * total_order(in): total order flag
10545  * can_compare(out): set if values are comparable
10546  * Note:
10547  * There is some implicit conversion going on here, not sure if this
10548  * is a good idea because it gives the impression that these have
10549  * compatible domains.
10550  *
10551  * If the total_order flag is set, it will return one of DB_LT, DB_GT, or
10552  * DB_EQ, it will not return DB_UNK. For the purposes of the total
10553  * ordering, two NULL values are DB_EQ and if only one value is NULL, that
10554  * value is less than the non-null value.
10555  *
10556  * If "can_compare" is not null, in the event of incomparable values an
10557  * error will be logged and the boolean that is pointed by "can_compare"
10558  * will be set to false.
10559  */
10561 tp_value_compare_with_error (const DB_VALUE * value1, const DB_VALUE * value2, int do_coercion, int total_order,
10562  bool * can_compare)
10563 {
10564  DB_VALUE temp1, temp2, tmp_char_conv;
10565  int coercion, char_conv;
10566  DB_VALUE *v1, *v2;
10567  DB_TYPE vtype1, vtype2;
10568 #if !defined (SERVER_MODE)
10569  DB_OBJECT *mop;
10570  DB_IDENTIFIER *oid1, *oid2;
10571 #endif /* !defined (SERVER_MODE) */
10572  bool use_collation_of_v1 = false;
10573  bool use_collation_of_v2 = false;
10576 
10577  coercion = 0;
10578  char_conv = 0;
10579 
10580  if (can_compare != NULL)
10581  {
10582  *can_compare = true;
10583  }
10584 
10585  if (DB_IS_NULL (value1))
10586  {
10587  if (DB_IS_NULL (value2))
10588  {
10589  result = (total_order ? DB_EQ : DB_UNK);
10590  }
10591  else
10592  {
10593  result = (total_order ? DB_LT : DB_UNK);
10594  }
10595  }
10596  else if (DB_IS_NULL (value2))
10597  {
10598  result = (total_order ? DB_GT : DB_UNK);
10599  }
10600  else
10601  {
10602  int common_coll = -1;
10603  v1 = (DB_VALUE *) value1;
10604  v2 = (DB_VALUE *) value2;
10605 
10606  vtype1 = DB_VALUE_DOMAIN_TYPE (v1);
10607  vtype2 = DB_VALUE_DOMAIN_TYPE (v2);
10608 
10609  /*
10610  * Hack, DB_TYPE_OID & DB_TYPE_OBJECT are logically the same domain
10611  * although their physical representations are different.
10612  * If we see a pair of those, handle it up front before we
10613  * fall in and try to perform coercion. Avoid "coercion" between
10614  * OIDs and OBJECTs because we usually try to keep OIDs unswizzled
10615  * as long as possible.
10616  */
10617  if (vtype1 != vtype2)
10618  {
10619 #if defined (SERVER_MODE)
10620  if (vtype1 == DB_TYPE_OBJECT || vtype2 == DB_TYPE_OBJECT)
10621  {
10622  assert_release (false);
10623  return DB_UNK;
10624  }
10625 #else /* !defined (SERVER_MODE) */
10626  if (vtype1 == DB_TYPE_OBJECT)
10627  {
10628  if (vtype2 == DB_TYPE_OID)
10629  {
10630  mop = db_get_object (v1);
10631  oid1 = mop ? WS_OID (mop) : NULL;
10632  oid2 = db_get_oid (v2);
10633  if (oid1 && oid2)
10634  {
10635  return oidcmp (oid1, oid2);
10636  }
10637  else
10638  {
10639  return DB_UNK;
10640  }
10641  }
10642  }
10643  else if (vtype2 == DB_TYPE_OBJECT)
10644  {
10645  if (vtype1 == DB_TYPE_OID)
10646  {
10647  oid1 = db_get_oid (v1);
10648  mop = db_get_object (v2);
10649  oid2 = mop ? WS_OID (mop) : NULL;
10650 
10651  if (oid1 && oid2)
10652  {
10653  return oidcmp (oid1, oid2);
10654  }
10655  else
10656  {
10657  return DB_UNK;
10658  }
10659  }
10660  }
10661 #endif /* !defined (SERVER_MODE) */
10662 
10663  /*
10664  * If value types aren't exact, try coercion.
10665  * May need to be using the domain returned by
10666  * tp_domain_resolve_value here ?
10667  */
10668  if (do_coercion && !ARE_COMPARABLE (vtype1, vtype2))
10669  {
10670  db_make_null (&temp1);
10671  db_make_null (&temp2);
10672  coercion = 1;
10673 
10674  if (TP_IS_CHAR_TYPE (vtype1) && TP_IS_NUMERIC_TYPE (vtype2))
10675  {
10676  /* coerce v1 to double */
10677  status = tp_value_coerce (v1, &temp1, tp_domain_resolve_default (DB_TYPE_DOUBLE));
10678  if (status == DOMAIN_COMPATIBLE)
10679  {
10680  v1 = &temp1;
10681  vtype1 = DB_VALUE_TYPE (v1);
10682 
10683  if (vtype2 != DB_TYPE_DOUBLE)
10684  {
10685  status = tp_value_coerce (v2, &temp2, tp_domain_resolve_default (DB_TYPE_DOUBLE));
10686 
10687  if (status == DOMAIN_COMPATIBLE)
10688  {
10689  v2 = &temp2;
10690  vtype2 = DB_VALUE_TYPE (v2);
10691  }
10692  }
10693  }
10694  }
10695  else if (TP_IS_NUMERIC_TYPE (vtype1) && TP_IS_CHAR_TYPE (vtype2))
10696  {
10697  /* coerce v2 to double */
10698  status = tp_value_coerce (v2, &temp2, tp_domain_resolve_default (DB_TYPE_DOUBLE));
10699  if (status == DOMAIN_COMPATIBLE)
10700  {
10701  v2 = &temp2;
10702  vtype2 = DB_VALUE_TYPE (v2);
10703 
10704  if (vtype1 != DB_TYPE_DOUBLE)
10705  {
10706  status = tp_value_coerce (v1, &temp1, tp_domain_resolve_default (DB_TYPE_DOUBLE));
10707 
10708  if (status == DOMAIN_COMPATIBLE)
10709  {
10710  v1 = &temp1;
10711  vtype1 = DB_VALUE_TYPE (v1);
10712  }
10713  }
10714  }
10715  }
10716  else if (TP_IS_CHAR_TYPE (vtype1) && TP_IS_DATE_OR_TIME_TYPE (vtype2))
10717  {
10718  /* vtype2 is the date or time type, coerce value 1 */
10719  TP_DOMAIN *d2 = tp_domain_resolve_default (vtype2);
10720  status = tp_value_coerce (v1, &temp1, d2);
10721  if (status == DOMAIN_COMPATIBLE)
10722  {
10723  v1 = &temp1;
10724  vtype1 = DB_VALUE_TYPE (v1);
10725  }
10726  }
10727  else if (TP_IS_DATE_OR_TIME_TYPE (vtype1) && TP_IS_CHAR_TYPE (vtype2))
10728  {
10729  /* vtype1 is the date or time type, coerce value 2 */
10731  status = tp_value_coerce (v2, &temp2, d1);
10732  if (status == DOMAIN_COMPATIBLE)
10733  {
10734  v2 = &temp2;
10735  vtype2 = DB_VALUE_TYPE (v2);
10736  }
10737  }
10738  else if (tp_more_general_type (vtype1, vtype2) > 0)
10739  {
10740  /* vtype1 is more general, coerce value 2 */
10742 
10743  if (TP_TYPE_HAS_COLLATION (vtype2) && TP_IS_CHAR_TYPE (vtype1))
10744  {
10745  /* create a new domain with type of v1 */
10746  d1 = tp_domain_copy (d1, false);
10747  if (TP_IS_CHAR_TYPE (vtype2))
10748  {
10749  /* keep the codeset and collation from original value v2 */
10750  d1->codeset = db_get_string_codeset (v2);
10752  }
10753  else
10754  {
10755  /* v2 is ENUM, and is coerced to string this should happend when the other operand is a HV;
10756  * in this case we remember to use collation and charset from ENUM (v2) */
10757  use_collation_of_v2 = true;
10758  d1->codeset = db_get_enum_codeset (v2);
10760  common_coll = d1->collation_id;
10761  }
10762 
10763  d1 = tp_domain_cache (d1);
10764  }
10765 
10766  status = tp_value_coerce (v2, &temp2, d1);
10767  if (status != DOMAIN_COMPATIBLE)
10768  {
10769  /*
10770  * This is arguably an error condition
10771  * but Not Equal is as close as we can come
10772  * to reporting it.
10773  */
10774 
10775  // WARNING: forget any error for coercion.
10776  er_clear ();
10777  }
10778  else
10779  {
10780  v2 = &temp2;
10781  vtype2 = DB_VALUE_TYPE (v2);
10782  }
10783  }
10784  else
10785  {
10786  /* coerce value1 to value2's type */
10787  TP_DOMAIN *d2 = tp_domain_resolve_default (vtype2);
10788 
10789  if (TP_TYPE_HAS_COLLATION (vtype1) && TP_IS_CHAR_TYPE (vtype2))
10790  {
10791  /* create a new domain with type of v2 */
10792  d2 = tp_domain_copy (d2, false);
10793  if (TP_IS_CHAR_TYPE (vtype1))
10794  {
10795  /* keep the codeset and collation from original value v1 */
10796  d2->codeset = db_get_string_codeset (v1);
10798  }
10799  else
10800  {
10801  /* v1 is ENUM, and is coerced to string this should happend when the other operand is a HV;
10802  * in this case we remember to use collation and charset from ENUM (v1) */
10803  use_collation_of_v1 = true;
10804  d2->codeset = db_get_enum_codeset (v1);
10806  common_coll = d2->collation_id;
10807  }
10808 
10809  d2 = tp_domain_cache (d2);
10810  }
10811 
10812  status = tp_value_coerce (v1, &temp1, d2);
10813  if (status != DOMAIN_COMPATIBLE)
10814  {
10815  /*
10816  * This is arguably an error condition
10817  * but Not Equal is as close as we can come
10818  * to reporting it.
10819  */
10820 
10821  // WARNING: forget any error for coercion.
10822  er_clear ();
10823  }
10824  else
10825  {
10826  v1 = &temp1;
10827  vtype1 = DB_VALUE_TYPE (v1);
10828  }
10829  }
10830  }
10831  }
10832 
10833  if (!ARE_COMPARABLE (vtype1, vtype2))
10834  {
10835  /*
10836  * Default result for mismatched types.
10837  * Not correct but will be consistent.
10838  */
10839  if (tp_more_general_type (vtype1, vtype2) > 0)
10840  {
10841  result = DB_GT;
10842  }
10843  else
10844  {
10845  result = DB_LT;
10846  }
10847 
10848  /* set incompatibility flag */
10849  if (can_compare != NULL)
10850  {
10851  *can_compare = false;
10852 
10854  pr_type_name (vtype2));
10855  }
10856  }
10857  else
10858  {
10859  PR_TYPE *pr_type;
10860 
10861  pr_type = pr_type_from_id (vtype1);
10862  assert (pr_type != NULL);
10863 
10864  if (pr_type)
10865  {
10866  /* Either both arguments are enums, or both are not. If one is enum and one is not, it means that
10867  * tp_value_cast_internal failed somewhere */
10868  assert ((vtype1 == DB_TYPE_ENUMERATION && vtype1 == vtype2)
10869  || (vtype1 != DB_TYPE_ENUMERATION && vtype2 != DB_TYPE_ENUMERATION));
10870 
10871  if (!TP_IS_CHAR_TYPE (vtype1))
10872  {
10873  common_coll = 0;
10874  }
10875  else if (db_get_string_collation (v1) == db_get_string_collation (v2))
10876  {
10877  common_coll = db_get_string_collation (v1);
10878  }
10879  else if (TP_IS_CHAR_TYPE (vtype1) && (use_collation_of_v1 || use_collation_of_v2))
10880  {
10881  INTL_CODESET codeset;
10882  DB_DATA_STATUS data_status;
10883  int error_status;
10884 
10885  db_make_null (&tmp_char_conv);
10886  char_conv = 1;
10887 
10888  if (use_collation_of_v1)
10889  {
10890  assert (!use_collation_of_v2);
10891  common_coll = db_get_string_collation (v1);
10892  }
10893  else
10894  {
10895  assert (use_collation_of_v2 == true);
10896  common_coll = db_get_string_collation (v2);
10897  }
10898 
10899  codeset = lang_get_collation (common_coll)->codeset;
10900 
10901  if (db_get_string_codeset (v1) != codeset)
10902  {
10903  db_value_domain_init (&tmp_char_conv, vtype1, DB_VALUE_PRECISION (v1), 0);
10904 
10905  db_string_put_cs_and_collation (&tmp_char_conv, codeset, common_coll);
10906  error_status = db_char_string_coerce (v1, &tmp_char_conv, &data_status);
10907 
10908  if (error_status != NO_ERROR)
10909  {
10910  pr_clear_value (&tmp_char_conv);
10911  if (coercion)
10912  {
10913  pr_clear_value (&temp1);
10914  pr_clear_value (&temp2);
10915  }
10916  return DB_UNK;
10917  }
10918 
10919  assert (data_status == DATA_STATUS_OK);
10920 
10921  v1 = &tmp_char_conv;
10922  }
10923  else if (db_get_string_codeset (v2) != codeset)
10924  {
10925  db_value_domain_init (&tmp_char_conv, vtype2, DB_VALUE_PRECISION (v2), 0);
10926 
10927  db_string_put_cs_and_collation (&tmp_char_conv, codeset, common_coll);
10928  error_status = db_char_string_coerce (v2, &tmp_char_conv, &data_status);
10929 
10930  if (error_status != NO_ERROR)
10931  {
10932  pr_clear_value (&tmp_char_conv);
10933  if (coercion)
10934  {
10935  pr_clear_value (&temp1);
10936  pr_clear_value (&temp2);
10937  }
10938  return DB_UNK;
10939  }
10940 
10941  assert (data_status == DATA_STATUS_OK);
10942 
10943  v2 = &tmp_char_conv;
10944  }
10945  }
10946  else if (TP_IS_CHAR_TYPE (vtype1) && db_get_string_codeset (v1) == db_get_string_codeset (v2))
10947  {
10949  }
10950 
10951  if (common_coll == -1)
10952  {
10953  result = DB_UNK;
10955  if (can_compare != NULL)
10956  {
10957  *can_compare = false;
10958  }
10959  }
10960  else
10961  {
10962  result = pr_type->cmpval (v1, v2, do_coercion, total_order, NULL, common_coll);
10963  }
10964 
10965  if (result == DB_UNK)
10966  {
10967  /* safe guard */
10968  if (pr_type->id == DB_TYPE_MIDXKEY)
10969  {
10971  assert (false);
10972  }
10973  }
10974  }
10975  else
10976  {
10978  result = DB_UNK;
10979  }
10980  }
10981 
10982  if (coercion)
10983  {
10984  pr_clear_value (&temp1);
10985  pr_clear_value (&temp2);
10986  }
10987  if (char_conv)
10988  {
10989  pr_clear_value (&tmp_char_conv);
10990  }
10991  }
10992 
10993  return result;
10994 }
10995 
10996 /*
10997  * tp_value_equal - compares the contents of two DB_VALUE structures and
10998  * determines if they are equal
10999  * return: non-zero if the values are equal
11000  * value1(in): first value
11001  * value2(in): second value
11002  * do_coercion(): coercion flag
11003  * Note:
11004  * determines if they are equal. This is a boolean comparison, you
11005  * cannot use this for sorting.
11006  *
11007  * This used to be fully implemented, since this got a lot more complicated
11008  * with the introduction of parameterized types, and it is doubtfull that
11009  * it saved much in performance anyway, it has been reimplemented to simply
11010  * call tp_value_compare. The old function is commented out below in case
11011  * this causes problems. After awhile, it can be removed.
11012  *
11013  */
11014 int
11015 tp_value_equal (const DB_VALUE * value1, const DB_VALUE * value2, int do_coercion)
11016 {
11017  return tp_value_compare (value1, value2, do_coercion, 0) == DB_EQ;
11018 }
11019 
11020 /*
11021  * DOMAIN INFO FUNCTIONS
11022  */
11023 
11024 
11025 /*
11026  * tp_domain_disk_size - Calculate the disk size necessary to store a value
11027  * for a particular domain.
11028  * return: disk size in bytes. -1 if this is a variable width domain or
11029  * floating precision in fixed domain.
11030  * domain(in): domain to consider
11031  * Note:
11032  * This is here because it takes a domain handle.
11033  * Since this is going to get called a lot, we might want to just add
11034  * this to the TP_DOMAIN structure and calculate it internally when
11035  * it is cached.
11036  */
11037 int
11039 {
11040  if (domain->type->is_always_variable ())
11041  {
11042  return -1;
11043  }
11044 
11045  if ((domain->type->get_id () == DB_TYPE_CHAR || domain->type->get_id () == DB_TYPE_NCHAR
11046  || domain->type->get_id () == DB_TYPE_BIT) && domain->precision == TP_FLOATING_PRECISION_VALUE)
11047  {
11048  return -1;
11049  }
11050 
11052 
11053  return domain->type->get_disk_size_of_mem (NULL, domain);
11054 }
11055 
11056 
11057 /*
11058  * tp_domain_memory_size - Calculates the "instance memory" size required
11059  * to hold a value for a particular domain.
11060  * return: bytes size
11061  * domain(in): domain to consider
11062  */
11063 int
11065 {
11066  if ((domain->type->get_id () == DB_TYPE_CHAR || domain->type->get_id () == DB_TYPE_NCHAR
11067  || domain->type->get_id () == DB_TYPE_BIT) && domain->precision == TP_FLOATING_PRECISION_VALUE)
11068  {
11069  return -1;
11070  }
11071 
11072  return domain->type->get_mem_size_of_mem (NULL, domain);
11073 }
11074 
11075 /*
11076  * tp_init_value_domain - initializes the domain information in a DB_VALUE to
11077  * correspond to the information from a TP_DOMAIN structure.
11078  * return: none
11079  * domain(out): domain information
11080  * value(in): value to initialize
11081  * Note:
11082  * Used primarily by the value unpacking functions.
11083  * It uses the "initval" type function. This needs to be changed
11084  * to take a full domain rather than just precision/scale but the
11085  * currently behavior will work for now.
11086  *
11087  * Think about the need for "initval" all it really does is call
11088  * db_value_domain_init() with the supplied arguments.
11089  */
11090 void
11092 {
11093  if (domain == NULL)
11094  {
11095  /* shouldn't happen ? */
11097  }
11098  else
11099  {
11100  domain->type->initval (value, domain->precision, domain->scale);
11101  }
11102 }
11103 
11104 
11105 /*
11106  * tp_check_value_size - check a particular variable sized value (e.g.
11107  * varchar, char, bit) against a destination domain.
11108  * return: domain status (ok or overflow)
11109  * domain(in): target domain
11110  * value(in): value to be assigned
11111  * Note:
11112  * It is assumed that basic domain compatibility has already been
11113  * performed and that the supplied domain will match with what is
11114  * in the value.
11115  * This is used primarily for character data that is allowed to fit
11116  * within a domain if the byte size is within tolerance.
11117  */
11120 {
11121  TP_DOMAIN_STATUS status;
11122  int src_precision, src_length;
11123  DB_TYPE dbtype;
11124  const char *src;
11125 
11126  status = DOMAIN_COMPATIBLE;
11127 
11128  /* if target domain is "floating", its always ok */
11129  if (domain->precision != TP_FLOATING_PRECISION_VALUE)
11130  {
11131 
11132  dbtype = TP_DOMAIN_TYPE (domain);
11133  switch (dbtype)
11134  {
11135  case DB_TYPE_CHAR:
11136  case DB_TYPE_NCHAR:
11137  case DB_TYPE_BIT:
11138  /*
11139  * The compatibility will be determined by the precision.
11140  * A floating precision is determined by the length of the string
11141  * value.
11142  */
11143  src = db_get_string (value);
11144  if (src != NULL)
11145  {
11146  src_precision = db_value_precision (value);
11147  if (!TP_IS_BIT_TYPE (dbtype))
11148  {
11149  src_length = db_get_string_length (value);
11150  assert (src_length >= 0);
11151  }
11152  else
11153  {
11154  src_length = db_get_string_size (value);
11155  }
11156 
11157  /* Check for floating precision. */
11158  if (src_precision == TP_FLOATING_PRECISION_VALUE)
11159  {
11160  src_precision = src_length;
11161  }
11162 
11163  if (src_precision > domain->precision)
11164  {
11165  status = DOMAIN_OVERFLOW;
11166  }
11167  }
11168  break;
11169 
11170  case DB_TYPE_VARCHAR:
11171  case DB_TYPE_VARNCHAR:
11172  case DB_TYPE_VARBIT:
11173  /*
11174  * The compatibility of the value is always determined by the
11175  * actual length of the value, not the destination precision.
11176  */
11177  src = db_get_string (value);
11178  if (src != NULL)
11179  {
11180  if (!TP_IS_BIT_TYPE (dbtype))
11181  {
11182  src_length = db_get_string_length (value);
11183  assert (src_length >= 0);
11184  }
11185  else
11186  {
11187  src_length = db_get_string_size (value);
11188  }
11189 
11190  /*
11191  * Work backwards from the source length into a minimum precision.
11192  * This feels like it should be a nice packed utility
11193  * function somewhere.
11194  */
11195  src_precision = src_length;
11196 
11197  if (src_precision > domain->precision)
11198  {
11199  status = DOMAIN_OVERFLOW;
11200  }
11201  }
11202  break;
11203 
11204  default:
11205  /*
11206  * None of the other types require this form of value dependent domain
11207  * precision checking.
11208  */
11209  break;
11210  }
11211  }
11212 
11213  return status;
11214 }
11215 
11216 #if defined(CUBRID_DEBUG)
11217 /*
11218  * fprint_domain - print information of a domain
11219  * return: void
11220  * fp(out): FILE pointer
11221  * domain(in): domain to print
11222  */
11223 static void
11224 fprint_domain (FILE * fp, TP_DOMAIN * domain)
11225 {
11226  TP_DOMAIN *d;
11227 
11228  for (d = domain; d != NULL; d = d->next)
11229  {
11230 
11231  switch (TP_DOMAIN_TYPE (d))
11232  {
11233 
11234  case DB_TYPE_OBJECT:
11235  case DB_TYPE_OID:
11236  case DB_TYPE_SUB:
11237  if (TP_DOMAIN_TYPE (d) == DB_TYPE_SUB)
11238  {
11239  fprintf (fp, "sub(");
11240  }
11241 #if !defined (SERVER_MODE)
11242  if (d->class_mop != NULL)
11243  {
11244  fprintf (fp, "%s", db_get_class_name (d->class_mop));
11245  }
11246  else if (OID_ISNULL (&d->class_oid))
11247  {
11248  fprintf (fp, "object");
11249  }
11250  else
11251 #endif /* !SERVER_MODE */
11252  {
11253  fprintf (fp, "object(%d,%d,%d)", d->class_oid.volid, d->class_oid.pageid, d->class_oid.slotid);
11254  }
11255  if (TP_DOMAIN_TYPE (d) == DB_TYPE_SUB)
11256  {
11257  fprintf (fp, ")");
11258  }
11259  break;
11260 
11261  case DB_TYPE_VARIABLE:
11262  fprintf (fp, "union(");
11263  fprint_domain (fp, d->setdomain);
11264  fprintf (fp, ")");
11265  break;
11266 
11267  case DB_TYPE_SET:
11268  fprintf (fp, "set(");
11269  fprint_domain (fp, d->setdomain);
11270  fprintf (fp, ")");
11271  break;
11272  case DB_TYPE_MULTISET:
11273  fprintf (fp, "multiset(");
11274  fprint_domain (fp, d->setdomain);
11275  fprintf (fp, ")");
11276  break;
11277  case DB_TYPE_SEQUENCE:
11278  fprintf (fp, "sequence(");
11279  fprint_domain (fp, d->setdomain);
11280  fprintf (fp, ")");
11281  break;
11282 
11283  case DB_TYPE_BIT:
11284  case DB_TYPE_VARBIT:
11285  fprintf (fp, "%s(%d)", d->type->name, d->precision);
11286  break;
11287 
11288  case DB_TYPE_CHAR:
11289  case DB_TYPE_VARCHAR:
11290  fprintf (fp, "%s(%d) collate %s", d->type->name, d->precision, lang_get_collation_name (d->collation_id));
11291  break;
11292 
11293  case DB_TYPE_NCHAR:
11294  case DB_TYPE_VARNCHAR:
11295  fprintf (fp, "%s(%d) NATIONAL collate %s", d->type->name, d->precision,
11297  break;
11298 
11299  case DB_TYPE_NUMERIC:
11300  fprintf (fp, "%s(%d,%d)", d->type->name, d->precision, d->scale);
11301  break;
11302 
11303  default:
11304  fprintf (fp, "%s", d->type->name);
11305  break;
11306  }
11307 
11308  if (d->next != NULL)
11309  {
11310  fprintf (fp, ",");
11311  }
11312  }
11313 }
11314 
11315 /*
11316  * tp_dump_domain - fprint_domain to stdout
11317  * return: void
11318  * domain(in): domain to print
11319  */
11320 void
11321 tp_dump_domain (TP_DOMAIN * domain)
11322 {
11323  fprint_domain (stdout, domain);
11324  fprintf (stdout, "\n");
11325 }
11326 
11327 /*
11328  * tp_domain_print - fprint_domain to stdout
11329  * return: void
11330  * domain(in): domain to print
11331  */
11332 void
11333 tp_domain_print (TP_DOMAIN * domain)
11334 {
11335  fprint_domain (stdout, domain);
11336 }
11337 
11338 /*
11339  * tp_domain_fprint - fprint_domain to stdout
11340  * return: void
11341  * fp(out): FILE pointer
11342  * domain(in): domain to print
11343  */
11344 void
11345 tp_domain_fprint (FILE * fp, TP_DOMAIN * domain)
11346 {
11347  fprint_domain (fp, domain);
11348 }
11349 #endif
11350 
11351 /*
11352  * tp_valid_indextype - check for valid index type
11353  * return: 1 if type is a valid index type, 0 otherwise.
11354  * type(in): a database type constant
11355  */
11356 int
11358 {
11359  switch (type)
11360  {
11361  case DB_TYPE_INTEGER:
11362  case DB_TYPE_FLOAT:
11363  case DB_TYPE_DOUBLE:
11364  case DB_TYPE_STRING:
11365  case DB_TYPE_OBJECT:
11366  case DB_TYPE_TIME:
11367  case DB_TYPE_TIMESTAMP:
11368  case DB_TYPE_TIMESTAMPTZ:
11369  case DB_TYPE_TIMESTAMPLTZ:
11370  case DB_TYPE_DATETIME:
11371  case DB_TYPE_DATETIMETZ:
11372  case DB_TYPE_DATETIMELTZ:
11373  case DB_TYPE_DATE:
11374  case DB_TYPE_MONETARY:
11375  case DB_TYPE_SHORT:
11376  case DB_TYPE_BIGINT:
11377  case DB_TYPE_OID:
11378  case DB_TYPE_NUMERIC:
11379  case DB_TYPE_BIT:
11380  case DB_TYPE_VARBIT:
11381  case DB_TYPE_CHAR:
11382  case DB_TYPE_NCHAR:
11383  case DB_TYPE_VARNCHAR:
11384  case DB_TYPE_ENUMERATION:
11385  return 1;
11386  default:
11387  return 0;
11388  }
11389 }
11390 
11391 
11392 /*
11393  * tp_domain_references_objects - check if domain is an object domain or a
11394  * collection domain that might include objects.
11395  * return: int (true or false)
11396  * dom(in): the domain to be inspected
11397  */
11398 bool
11400 {
11401  switch (TP_DOMAIN_TYPE (dom))
11402  {
11403  case DB_TYPE_OBJECT:
11404  case DB_TYPE_OID:
11405  case DB_TYPE_VOBJ:
11406  return true;
11407  case DB_TYPE_SET:
11408  case DB_TYPE_MULTISET:
11409  case DB_TYPE_SEQUENCE:
11410  dom = dom->setdomain;
11411  if (dom)
11412  {
11413  /*
11414  * If domains are specified, we can assume that the upper levels
11415  * have enforced the rule that no value in the collection has a
11416  * domain that isn't included in this list. If this list has no
11417  * object domain, then no collection with this domain can include
11418  * an object reference.
11419  */
11420  for (; dom; dom = dom->next)
11421  {
11422  if (tp_domain_references_objects (dom))
11423  {
11424  return true;
11425  }
11426  }
11427 
11428  return false;
11429  }
11430  else
11431  {
11432  /*
11433  * We've got hold of one of our fabulous "collection of anything"
11434  * attributes. We've got no choice but to assume that it might
11435  * have objects in it.
11436  */
11437  return true;
11438  }
11439  default:
11440  return false;
11441  }
11442 }
11443 
11444 /*
11445  * tp_value_auto_cast - Cast a value into one of another domain, returning an
11446  * error only
11447  * return: TP_DOMAIN_STATUS
11448  * src(in): src DB_VALUE
11449  * dest(out): dest DB_VALUE
11450  * desired_domain(in): destion domain
11451  *
11452  * Note : this function is used at execution stage, by operators performing
11453  * late binding on Host Variables; the automatic cast is a replacement
11454  * for implicit cast performed at type-checking for operators that do
11455  * not require late binding.
11456  */
11458 tp_value_auto_cast (const DB_VALUE * src, DB_VALUE * dest, const TP_DOMAIN * desired_domain)
11459 {
11460  TP_DOMAIN_STATUS status;
11461 
11462  status = tp_value_cast (src, dest, desired_domain, false);
11463  if (status != DOMAIN_COMPATIBLE)
11464  {
11466  {
11467  status = DOMAIN_COMPATIBLE;
11468  pr_clear_value (dest);
11469  db_make_null (dest);
11470  er_clear ();
11471  }
11472  }
11473 
11474  return status;
11475 }
11476 
11477 /*
11478  * tp_value_str_auto_cast_to_number () - checks if the original value
11479  * is of type string, and cast it to a DOUBLE type domain.
11480  * return: error code.
11481  * src(in): source DB_VALUE
11482  * dest(out): destination DB_VALUE
11483  * val_type(in/out): db type of value; modified if the cast is performed
11484  *
11485  * Note : this is a helper function used by arithmetic functions to accept
11486  * string arguments.
11487  */
11488 int
11490 {
11491  TP_DOMAIN *cast_dom = NULL;
11492  TP_DOMAIN_STATUS dom_status;
11493  int er_status = NO_ERROR;
11494 
11495  assert (src != NULL);
11496  assert (dest != NULL);
11497  assert (val_type != NULL);
11498  assert (TP_IS_CHAR_TYPE (*val_type));
11499  assert (src != dest);
11500 
11501  db_make_null (dest);
11502 
11503  /* cast string to DOUBLE */
11505  if (cast_dom == NULL)
11506  {
11507  return ER_FAILED;
11508  }
11509 
11510  dom_status = tp_value_auto_cast (src, dest, cast_dom);
11511  if (dom_status != DOMAIN_COMPATIBLE)
11512  {
11513  er_status = tp_domain_status_er_set (dom_status, ARG_FILE_LINE, src, cast_dom);
11514 
11515  pr_clear_value (dest);
11516  return er_status;
11517  }
11518 
11519  *val_type = DB_VALUE_DOMAIN_TYPE (dest);
11520 
11521  return NO_ERROR;
11522 }
11523 
11524 /*
11525  * tp_infer_common_domain () -
11526  * return:
11527  *
11528  * arg1(in):
11529  * arg2(in):
11530  *
11531  * Note :
11532  */
11533 TP_DOMAIN *
11535 {
11536  TP_DOMAIN *target_domain;
11537  DB_TYPE arg1_type, arg2_type, common_type;
11538  bool need_to_domain_update = false;
11539 
11540  assert (arg1 && arg2);
11541 
11542  arg1_type = arg1->type->id;
11543  arg2_type = arg2->type->id;
11544 
11545  if (arg1_type == arg2_type)
11546  {
11547  common_type = arg1_type;
11548  target_domain = tp_domain_copy (arg1, false);
11549  need_to_domain_update = true;
11550  }
11551  else if (arg1_type == DB_TYPE_NULL)
11552  {
11553  common_type = arg2_type;
11554  target_domain = tp_domain_copy (arg2, false);
11555  }
11556  else if (arg2_type == DB_TYPE_NULL)
11557  {
11558  common_type = arg1_type;
11559  target_domain = tp_domain_copy (arg1, false);
11560  }
11561  else if ((TP_IS_BIT_TYPE (arg1_type) && TP_IS_BIT_TYPE (arg2_type))
11562  || (TP_IS_CHAR_TYPE (arg1_type) && TP_IS_CHAR_TYPE (arg2_type))
11563  || (TP_IS_DATE_TYPE (arg1_type) && TP_IS_DATE_TYPE (arg2_type))
11564  || (TP_IS_SET_TYPE (arg1_type) && TP_IS_SET_TYPE (arg2_type))
11565  || (TP_IS_NUMERIC_TYPE (arg1_type) && TP_IS_NUMERIC_TYPE (arg2_type)))
11566  {
11567  if (tp_more_general_type (arg1_type, arg2_type) > 0)
11568  {
11569  common_type = arg1_type;
11570  target_domain = tp_domain_copy (arg1, false);
11571  }
11572  else
11573  {
11574  common_type = arg2_type;
11575  target_domain = tp_domain_copy (arg2, false);
11576  }
11577  need_to_domain_update = true;
11578  }
11579  else
11580  {
11581  common_type = DB_TYPE_VARCHAR;
11582  target_domain = db_type_to_db_domain (common_type);
11583  }
11584 
11585  if (need_to_domain_update)
11586  {
11587  int arg1_prec, arg2_prec, arg1_scale, arg2_scale;
11588 
11589  arg1_prec = arg1->precision;
11590  arg1_scale = arg1->scale;
11591 
11592  arg2_prec = arg2->precision;
11593  arg2_scale = arg2->scale;
11594 
11595  if (arg1_prec == TP_FLOATING_PRECISION_VALUE || arg2_prec == TP_FLOATING_PRECISION_VALUE)
11596  {
11597  target_domain->precision = TP_FLOATING_PRECISION_VALUE;
11598  target_domain->scale = 0;
11599  }
11600  else if (common_type == DB_TYPE_NUMERIC)
11601  {
11602  int integral_digits1, integral_digits2;
11603 
11604  integral_digits1 = arg1_prec - arg1_scale;
11605  integral_digits2 = arg2_prec - arg2_scale;
11606  target_domain->scale = MAX (arg1_scale, arg2_scale);
11607  target_domain->precision = (target_domain->scale + MAX (integral_digits1, integral_digits2));
11608  target_domain->precision = MIN (target_domain->precision, DB_MAX_NUMERIC_PRECISION);
11609  }
11610  else
11611  {
11612  target_domain->precision = MAX (arg1_prec, arg2_prec);
11613  target_domain->scale = 0;
11614  }
11615  }
11616 
11617  target_domain = tp_domain_cache (target_domain);
11618  return target_domain;
11619 }
11620 
11621 /*
11622  * tp_domain_status_er_set () -
11623  * return:
11624  *
11625  * Note :
11626  */
11627 int
11628 tp_domain_status_er_set (TP_DOMAIN_STATUS status, const char *file_name, const int line_no, const DB_VALUE * src,
11629  const TP_DOMAIN * domain)
11630 {
11631  int error = NO_ERROR;
11632 
11633  assert (src != NULL);
11634  assert (domain != NULL);
11635 
11636  /* prefer to change error code; hide internal errors from users view */
11637  if (status == DOMAIN_ERROR)
11638  {
11639 #if 0 /* TODO */
11640  assert (er_errid () != NO_ERROR);
11641 #endif
11642  error = er_errid ();
11643 
11644  if (error == ER_JSON_INVALID_JSON)
11645  {
11646  // We keep invalid json errors that happend during cast since they are more descriptive
11647  return error;
11648  }
11649 
11650  if (error == ER_IT_DATA_OVERFLOW)
11651  {
11652  status = DOMAIN_OVERFLOW;
11653  }
11654  else
11655  {
11656  status = DOMAIN_INCOMPATIBLE;
11657  }
11658  }
11659 
11660  assert (status != DOMAIN_ERROR);
11661 
11662  switch (status)
11663  {
11664  case DOMAIN_INCOMPATIBLE:
11665  error = ER_TP_CANT_COERCE;
11666  er_set (ER_ERROR_SEVERITY, file_name, line_no, error, 2, pr_type_name (DB_VALUE_DOMAIN_TYPE (src)),
11667  pr_type_name (TP_DOMAIN_TYPE (domain)));
11668  break;
11669 
11670  case DOMAIN_OVERFLOW:
11671  error = ER_IT_DATA_OVERFLOW;
11672  er_set (ER_ERROR_SEVERITY, file_name, line_no, error, 1, pr_type_name (TP_DOMAIN_TYPE (domain)));
11673  break;
11674 
11675  case DOMAIN_ERROR:
11676  assert (false); /* is impossible */
11677  break;
11678 
11679  default:
11680  assert (false); /* is impossible */
11681  break;
11682  }
11683 
11684  return error;
11685 }
11686 
11687 /*
11688  * tp_digit_number_str_to_bi - Coerce a digit number string to a bigint.
11689  * return: NO_ERROR or error code
11690  * start(in): string start pos
11691  * end(in): string end pos
11692  * codeset(in):
11693  * is_negative(in):
11694  * num_value(out): bigint container
11695  * data_stat(out): if overflow is detected, this is set to
11696  * DATA_STATUS_TRUNCATED
11697  */
11698 int
11699 tp_digit_number_str_to_bi (const char *start, const char *end, INTL_CODESET codeset, bool is_negative,
11700  DB_BIGINT * num_value, DB_DATA_STATUS * data_stat)
11701 {
11702  char str[64] = { 0 };
11703  const char *p = NULL;
11704  const char *strp = NULL, *stre = NULL;
11705  size_t n_digits = 0;
11706  DB_BIGINT bigint = 0;
11707  bool round = false;
11708  bool truncated = false;
11709 
11710  assert (start != NULL && end != NULL && num_value != NULL && data_stat != NULL);
11711 
11712  strp = start;
11713  stre = end;
11714 
11715  /* count number of significant digits */
11716  p = strp;
11717 
11718  while (p != stre && char_isdigit (*p))
11719  {
11720  p++;
11721  }
11722 
11723  n_digits = p - strp;
11724  if (n_digits > 62)
11725  {
11726  /* more than 62 significant digits in the input number (63 chars with sign) */
11727  truncated = true;
11728  }
11729 
11730  /* skip decimal point and the digits after, keep the round flag */
11731  if (p != stre && *p == '.')
11732  {
11733  p++;
11734 
11735  if (p != stre)
11736  {
11737  if (char_isdigit (*p))
11738  {
11739  if (*p >= '5')
11740  {
11741  round = true;
11742  }
11743 
11744  /* skip all digits after decimal point */
11745  do
11746  {
11747  p++;
11748  }
11749  while (p != stre && char_isdigit (*p));
11750  }
11751  }
11752  }
11753 
11754  /* skip trailing whitespace characters */
11755  p = (char *) intl_skip_spaces (p, stre, codeset);
11756 
11757  if (p != stre)
11758  {
11759  /* trailing characters in string */
11760  return ER_FAILED;
11761  }
11762 
11763  if (truncated)
11764  {
11765  *data_stat = DATA_STATUS_TRUNCATED;
11766  if (is_negative)
11767  {
11768  bigint = DB_BIGINT_MIN;
11769  }
11770  else
11771  {
11772  bigint = DB_BIGINT_MAX;
11773  }
11774  }
11775  else
11776  {
11777  /* Copy the number to str, excluding leading spaces and '0's and trailing spaces. Anything other than leading and
11778  * trailing spaces already resulted in an error. */
11779  if (is_negative)
11780  {
11781  str[0] = '-';
11782  strncpy (str + 1, strp, n_digits);
11783  str[n_digits + 1] = '\0';
11784  strp = str;
11785  }
11786  else
11787  {
11788  strp = strncpy (str, strp, n_digits);
11789  str[n_digits] = '\0';
11790  }
11791 
11792  errno = 0;
11793  bigint = strtoll (strp, NULL, 10);
11794 
11795  if (errno == ERANGE)
11796  {
11797  *data_stat = DATA_STATUS_TRUNCATED;
11798  }
11799  else
11800  {
11801  *data_stat = DATA_STATUS_OK;
11802  }
11803 
11804  /* round number if a '5' or greater digit was found after the decimal point */
11805  if (round)
11806  {
11807  if (is_negative)
11808  {
11809  if (bigint > DB_BIGINT_MIN)
11810  {
11811  bigint--;
11812  }
11813  else
11814  {
11815  *data_stat = DATA_STATUS_TRUNCATED;
11816  }
11817  }
11818  else
11819  {
11820  if (bigint < DB_BIGINT_MAX)
11821  {
11822  bigint++;
11823  }
11824  else
11825  {
11826  *data_stat = DATA_STATUS_TRUNCATED;
11827  }
11828  }
11829  }
11830  }
11831 
11832  *num_value = bigint;
11833 
11834  return NO_ERROR;
11835 }
11836 
11837 /*
11838  * tp_hex_str_to_bi - Coerce a hex string to a bigint.
11839  * return: NO_ERROR or error code
11840  * start(in): string start pos
11841  * end(in): string end pos
11842  * codeset(in):
11843  * is_negative(in):
11844  * num_value(out): bigint container
11845  * data_stat(out): if overflow is detected, this is set to
11846  * DATA_STATUS_TRUNCATED
11847  */
11848 int
11849 tp_hex_str_to_bi (const char *start, const char *end, INTL_CODESET codeset, bool is_negative, DB_BIGINT * num_value,
11850  DB_DATA_STATUS * data_stat)
11851 {
11852 #define HIGHEST_4BITS_OF_UBI 0xF000000000000000
11853 
11854  int error = NO_ERROR;
11855  const char *p = NULL;
11856  UINT64 ubi = 0;
11857  unsigned int tmp_ui = 0;
11858  bool round = false;
11859  bool truncated = false;
11860 
11861  assert (start != NULL && end != NULL && num_value != NULL && data_stat != NULL);
11862 
11863  *data_stat = DATA_STATUS_OK;
11864 
11865  /* convert */
11866  p = start;
11867  while (p != end)
11868  {
11869  /* convert chars one by one */
11870  if (char_isdigit (*p))
11871  {
11872  tmp_ui = *p - '0';
11873  }
11874  else if (*p >= 'a' && *p <= 'f')
11875  {
11876  tmp_ui = *p - 'a' + 10;
11877  }
11878  else if (*p >= 'A' && *p <= 'F')
11879  {
11880  tmp_ui = *p - 'A' + 10;
11881  }
11882  else if (*p == '.')
11883  {
11884  if (++p != end)
11885  {
11886  if (char_isxdigit (*p))
11887  {
11888  if (*p >= '0' && *p < '8')
11889  {
11890  round = false;
11891  }
11892  else
11893  {
11894  round = true;
11895  }
11896 
11897  /* check the rest chars */
11898  while (++p != end && char_isxdigit (*p))
11899  ;
11900 
11901  /* skip trailing whitespace characters */
11902  p = (char *) intl_skip_spaces (p, end, codeset);
11903  if (p != end)
11904  {
11905  error = ER_FAILED;
11906  goto end;
11907  }
11908  }
11909  else
11910  {
11911  /* skip trailing whitespace characters */
11912  p = (char *) intl_skip_spaces (p, end, codeset);
11913  if (p != end)
11914  {
11915  error = ER_FAILED;
11916  goto end;
11917  }
11918  }
11919  }
11920 
11921  break;
11922  }
11923  else
11924  {
11925  /* skip trailing whitespace characters */
11926  p = (char *) intl_skip_spaces (p, end, codeset);
11927  if (p != end)
11928  {
11929  error = ER_FAILED;
11930  goto end;
11931  }
11932 
11933  break;
11934  }
11935 
11936  if (ubi & HIGHEST_4BITS_OF_UBI)
11937  {
11938  truncated = true;
11939  break;
11940  }
11941 
11942  ubi = ubi << 4;
11943 
11944  /* never overflow */
11945  ubi += tmp_ui;
11946 
11947  ++p;
11948  }
11949 
11950  *num_value = tp_ubi_to_bi_with_args (ubi, is_negative, truncated, round, data_stat);
11951 
11952 end:
11953 
11954  return error;
11955 
11956 #undef HIGHEST_4BITS_OF_UBI
11957 }
11958 
11959 /*
11960  * tp_scientific_str_to_bi - Coerce a scientific string to a bigint.
11961  * return: NO_ERROR or error code
11962  * start(in): string start pos
11963  * end(in): string end pos
11964  * codeset(in):
11965  * is_negative(in):
11966  * num_value(out): bigint container
11967  * data_stat(out): if overflow is detected, this is set to
11968  * DATA_STATUS_TRUNCATED
11969  *
11970  * NOTE: format check has been done by caller already
11971  * see tp_atobi
11972  */
11973 int
11974 tp_scientific_str_to_bi (const char *start, const char *end, INTL_CODESET codeset, bool is_negative,
11975  DB_BIGINT * num_value, DB_DATA_STATUS * data_stat)
11976 {
11977  int error = NO_ERROR;
11978  UINT64 ubi = 0;
11979  bool truncated = false;
11980  bool round = false;
11981  const char *p = NULL;
11982  const char *base_int_start = NULL, *base_int_end = NULL;
11983  const char *base_float_start = NULL, *base_float_end = NULL;
11984  const char *exp_start = NULL, *exp_end = NULL;
11985  bool is_exp_negative = false;
11986  int exp = 0; /* at most 308 */
11987 
11988  assert (start != NULL && end != NULL && num_value != NULL && data_stat != NULL);
11989 
11990  *data_stat = DATA_STATUS_OK;
11991 
11992  base_int_start = start;
11993  p = base_int_start;
11994  while (p != end && char_isdigit (*p))
11995  {
11996  ++p;
11997  }
11998 
11999  base_int_end = p;
12000 
12001  /* no int part */
12002  if (base_int_start == base_int_end)
12003  {
12004  base_int_start = NULL;
12005  base_int_end = NULL;
12006  }
12007 
12008  if (p != end && *p == '.')
12009  {
12010  ++p;
12011  if (p != end)
12012  {
12013  base_float_start = p;
12014  while (p != end && char_isdigit (*p))
12015  {
12016  ++p;
12017  }
12018 
12019  base_float_end = p;
12020 
12021  /* no float part */
12022  if (base_float_start == base_float_end)
12023  {
12024  base_float_start = NULL;
12025  base_float_end = NULL;
12026  }
12027  }
12028  }
12029 
12030  /* this is an error */
12031  if (base_int_start == NULL && base_float_start == NULL)
12032  {
12033  error = ER_FAILED;
12034  goto end;
12035  }
12036 
12037  if (p != end && (*p == 'e' || *p == 'E'))
12038  {
12039  ++p;
12040  if (p != end)
12041  {
12042  if (*p == '-')
12043  {
12044  is_exp_negative = true;
12045  ++p;
12046  }
12047  else if (*p == '+')
12048  {
12049  ++p;
12050  }
12051 
12052  exp_start = p;
12053  while (p != end && char_isdigit (*p))
12054  {
12055  ++p;
12056  }
12057 
12058  exp_end = p;
12059 
12060  /* no exp part */
12061  if (exp_start == exp_end)
12062  {
12063  error = ER_FAILED;
12064  goto end;
12065  }
12066  }
12067  }
12068 
12069  if (exp_start == NULL)
12070  {
12071  error = ER_FAILED;
12072  goto end;
12073  }
12074 
12075  /* start to calculate */
12076 
12077  /* exponent */
12078  p = exp_start;
12079  while (p != exp_end)
12080  {
12081  exp = exp * 10 + (*p - '0');
12082  if (exp > 308)
12083  {
12084  error = ER_FAILED;
12085  goto end;
12086  }
12087 
12088  ++p;
12089  }
12090 
12091  if (is_exp_negative)
12092  {
12093  exp = -exp;
12094  }
12095 
12096  /* calculate int part */
12097  if (base_int_start != NULL)
12098  {
12099  assert (base_int_end != NULL);
12100 
12101  if (exp < 0)
12102  {
12103  if (base_int_end - base_int_start >= -exp)
12104  {
12105  base_int_end += exp;
12106  }
12107  else
12108  {
12109  base_int_end = base_int_start - 1;
12110  }
12111  }
12112 
12113  p = base_int_start;
12114  while (p < base_int_end)
12115  {
12116  ubi = tp_ubi_times_ten (ubi, &truncated);
12117  if (truncated)
12118  {
12119  break;
12120  }
12121 
12122  /* never overflow */
12123  ubi = ubi + *p - '0';
12124 
12125  ++p;
12126  }
12127 
12128  /* need round ? */
12129  if (exp < 0 && base_int_end >= base_int_start && *base_int_end >= '5')
12130  {
12131  round = true;
12132  }
12133  }
12134 
12135  /* calculate float part */
12136  if (!truncated)
12137  {
12138  if (exp > 0)
12139  {
12140  if (base_float_start != NULL)
12141  {
12142  assert (base_float_end != NULL);
12143 
12144  p = base_float_start;
12145  while (p != base_float_end && exp > 0)
12146  {
12147  ubi = tp_ubi_times_ten (ubi, &truncated);
12148  if (truncated)
12149  {
12150  break;
12151  }
12152 
12153  /* never overflow */
12154  ubi = ubi + *p - '0';
12155 
12156  ++p;
12157  --exp;
12158  }
12159 
12160  /* need round ? */
12161  if (p != base_float_end && *p >= '5')
12162  {
12163  round = true;
12164  }
12165  }
12166 
12167  /* exp */
12168  if (!truncated)
12169  {
12170  while (exp > 0)
12171  {
12172  ubi = tp_ubi_times_ten (ubi, &truncated);
12173  if (truncated)
12174  {
12175  break;
12176  }
12177 
12178  --exp;
12179  }
12180  }
12181  }
12182  else if (exp == 0 && base_float_start != NULL && *base_float_start >= '5')
12183  {
12184  round = true;
12185  }
12186  }
12187 
12188 
12189  *num_value = tp_ubi_to_bi_with_args (ubi, is_negative, truncated, round, data_stat);
12190 
12191 end:
12192 
12193  return error;
12194 }
12195 
12196 /*
12197  * tp_ubi_to_bi_with_args -
12198  * return: bigint
12199  * ubi(in): unsigned bigint
12200  * is_negative(in):
12201  * truncated(in):
12202  * round(in):
12203  * data_stat(out): if overflow is detected, this is set to
12204  * DATA_STATUS_TRUNCATED
12205  *
12206  * NOTE: This is an internal function for convert string to bigint
12207  */
12208 DB_BIGINT
12209 tp_ubi_to_bi_with_args (UINT64 ubi, bool is_negative, bool truncated, bool round, DB_DATA_STATUS * data_stat)
12210 {
12211 #define HIGHEST_BIT_OF_UINT64 0x8000000000000000
12212 
12213  DB_BIGINT bigint = 0;
12214 
12215  assert (data_stat != NULL);
12216 
12217  if (!truncated)
12218  {
12219  if (is_negative)
12220  {
12221  if (ubi == HIGHEST_BIT_OF_UINT64)
12222  {
12223  bigint = DB_BIGINT_MIN;
12224  }
12225  else if (ubi & HIGHEST_BIT_OF_UINT64)
12226  {
12227  truncated = true;
12228  }
12229  else
12230  {
12231  bigint = (DB_BIGINT) ubi;
12232  bigint = -bigint;
12233  }
12234  }
12235  else
12236  {
12237  if (ubi & HIGHEST_BIT_OF_UINT64)
12238  {
12239  truncated = true;
12240  }
12241  else
12242  {
12243  bigint = (DB_BIGINT) ubi;
12244  }
12245  }
12246  }
12247 
12248  if (truncated)
12249  {
12250  *data_stat = DATA_STATUS_TRUNCATED;
12251  if (is_negative)
12252  {
12253  bigint = DB_BIGINT_MIN;
12254  }
12255  else
12256  {
12257  bigint = DB_BIGINT_MAX;
12258  }
12259  }
12260  else if (round)
12261  {
12262  if (is_negative)
12263  {
12264  if (bigint > DB_BIGINT_MIN)
12265  {
12266  --bigint;
12267  }
12268  else
12269  {
12270  *data_stat = DATA_STATUS_TRUNCATED;
12271  bigint = DB_BIGINT_MIN;
12272  }
12273  }
12274  else
12275  {
12276  if (bigint < DB_BIGINT_MAX)
12277  {
12278  ++bigint;
12279  }
12280  else
12281  {
12282  *data_stat = DATA_STATUS_TRUNCATED;
12283  bigint = DB_BIGINT_MAX;
12284  }
12285  }
12286  }
12287 
12288  return bigint;
12289 
12290 #undef HIGHEST_BIT_OF_UINT64
12291 }
12292 
12293 /*
12294  * tp_ubi_times_ten -
12295  * return: bigint
12296  * ubi(in): unsigned bigint
12297  * truncated(in/out): set to true if truncated
12298  *
12299  */
12300 UINT64
12301 tp_ubi_times_ten (UINT64 ubi, bool * truncated)
12302 {
12303 #define HIGHEST_3BITS_OF_UBI 0xE000000000000000
12304 
12305  UINT64 tmp_ubi = 0;
12306 
12307  assert (truncated != NULL);
12308 
12309  if (ubi & HIGHEST_3BITS_OF_UBI)
12310  {
12311  *truncated = true;
12312 
12313  goto end;
12314  }
12315 
12316  /* ubi*10 = ubi*8 + ubi*2 = ubi<<3 + ubi<<1 */
12317  tmp_ubi = ubi << 3;
12318  ubi = (ubi << 1) + tmp_ubi;
12319  if (ubi < tmp_ubi)
12320  {
12321  *truncated = true;
12322 
12323  goto end;
12324  }
12325 
12326 end:
12327 
12328  return ubi;
12329 
12330 #undef HIGHEST_3BITS_OF_UBI
12331 }
PR_TYPE tp_Multiset
TP_DOMAIN tp_String_domain
unsigned int TZ_ID
Definition: dbtype_def.h:756
DB_C_FLOAT db_get_float(const DB_VALUE *value)
int char_isspace(int c)
Definition: chartype.c:109
static int tp_atoutime(const DB_VALUE *src, DB_UTIME *temp)
static void format_floating_point(char *new_string, char *rve, int ndigits, int decpt, int sign)
struct db_domain_info::char_info char_info
static TP_DOMAIN * tp_Monetary_conv[]
#define BYTE_COUNT(bit_cnt)
#define TP_IS_DATE_OR_TIME_TYPE(typeid)
bool tp_domain_references_objects(const TP_DOMAIN *dom)
TP_DOMAIN_STATUS tp_value_coerce(const DB_VALUE *src, DB_VALUE *dest, const TP_DOMAIN *desired_domain)
int tp_domain_disk_size(TP_DOMAIN *domain)
static int tp_domain_size_internal(const TP_DOMAIN *domain)
int db_make_json(DB_VALUE *value, JSON_DOC *json_document, bool need_clear)
#define DB_DATETIMETZ_PRECISION
Definition: dbtype_def.h:613
int db_make_datetime(DB_VALUE *value, const DB_DATETIME *datetime)
TP_DOMAIN tp_Datetimeltz_domain
#define ER_TP_CANT_COERCE
Definition: error_code.h:250
#define WS_IS_DELETED(mop)
Definition: work_space.h:284
TP_DOMAIN tp_Substructure_domain
int sm_check_object_domain(TP_DOMAIN *domain, MOP object)
int db_value_coerce(const DB_VALUE *src, DB_VALUE *dest, const DB_DOMAIN *desired_domain)
Definition: db_macro.c:1779
#define NO_ERROR
Definition: error_code.h:46
PR_TYPE tp_Bigint
static int bfmt_print(int bfmt, const DB_VALUE *the_db_bit, char *string, int max_size)
PR_TYPE tp_Datetime
int built_in_index
Definition: object_domain.h:89
PR_TYPE tp_Utime
TP_DOMAIN_STATUS tp_value_change_coll_and_codeset(DB_VALUE *src, DB_VALUE *dest, int coll_id, int codeset)
#define DB_GET_ENUM_ELEM_STRING(elem)
Definition: dbtype.h:103
int db_value_put_null(DB_VALUE *value)
Definition: db_macro.c:122
TP_DOMAIN tp_Blob_domain
const char * lang_currency_symbol(DB_CURRENCY curr)
#define __attribute__(X)
Definition: porting.h:36
DB_COLLECTION * db_get_set(const DB_VALUE *value)
int db_value_scale(const DB_VALUE *value)
#define LANG_SYS_COLLATION
PR_TYPE tp_Monetary
#define TP_NUM_MIDXKEY_DOMAIN_LIST
Definition: object_domain.c:90
void tp_domain_init(TP_DOMAIN *domain, DB_TYPE type_id)
TP_DOMAIN tp_Error_domain
static TP_DOMAIN * tp_is_domain_cached(TP_DOMAIN *dlist, TP_DOMAIN *transient, TP_MATCH exact, TP_DOMAIN **ins_pos)
TP_DOMAIN_STATUS tp_domain_check(const TP_DOMAIN *domain, const DB_VALUE *value, TP_MATCH exact_match)
DB_MIDXKEY * db_get_midxkey(const DB_VALUE *value)
bool db_json_are_validators_equal(JSON_VALIDATOR *val1, JSON_VALIDATOR *val2)
Definition: db_json.cpp:2401
int db_timestamptz_to_string(char *buf, int bufsize, DB_TIMESTAMP *utime, const TZ_ID *tz_id)
Definition: db_date.c:4090
TP_DOMAIN * tp_domain_resolve_default_w_coll(DB_TYPE type, int coll_id, TP_DOMAIN_COLL_ACTION coll_flag)
#define DB_SET_ENUM_ELEM_STRING(elem, str)
Definition: dbtype.h:116
static char * tp_ltoa(DB_BIGINT value, char *string, int radix)
DB_VALUE_COMPARE_RESULT tp_value_compare(const DB_VALUE *value1, const DB_VALUE *value2, int allow_coercion, int total_order)
TP_DOMAIN tp_Variable_domain
static void tp_ftoa(DB_VALUE const *src, DB_VALUE *result)
double db_json_get_double_from_document(const JSON_DOC *doc)
Definition: db_json.cpp:2537
#define ASSERT_ERROR()
int tp_domain_compatible(const TP_DOMAIN *src, const TP_DOMAIN *dest)
const char * db_get_class_name(DB_OBJECT *class_)
Definition: db_info.c:608
TP_DOMAIN tp_Short_domain
int tp_get_fixed_precision(DB_TYPE domain_type)
MOP ws_mop(const OID *oid, MOP class_mop)
Definition: work_space.c:614
#define OR_CHECK_BIGINT_OVERFLOW(i)
unsigned self_ref
Definition: object_domain.h:96
#define HIGHEST_4BITS_OF_UBI
TP_DOMAIN * tp_domain_select(const TP_DOMAIN *domain_list, const DB_VALUE *value, int allow_coercion, TP_MATCH exact_match)
int tp_value_domain_name(const DB_VALUE *value, char *buffer, int maxlen)
unsigned char codeset
Definition: object_domain.h:91
DB_OBJECT * db_real_instance(DB_OBJECT *obj)
Definition: db_virt.c:247
void area_destroy(AREA *area)
Definition: area_alloc.c:247
TP_DOMAIN tp_Timestamptz_domain
DB_SET * db_seq_create(MOP classop, const char *name, int size)
Definition: db_set.c:252
DB_CONST_C_BIT db_get_bit(const DB_VALUE *value, int *length)
#define TP_IS_SET_TYPE(typenum)
int tp_init(void)
JSON_DOC * db_get_json_document(const DB_VALUE *value)
#define DB_MAX_STRING_LENGTH
Definition: dbtype_def.h:516
static TP_DOMAIN * tp_VarBit_conv[]
static int tp_atodate(const DB_VALUE *src, DB_DATE *temp)
int db_bit_string_coerce(const DB_VALUE *src_string, DB_VALUE *dest_string, DB_DATA_STATUS *data_status)
PR_TYPE tp_Clob
int db_date_to_string(char *buf, int bufsize, DB_DATE *date)
Definition: db_date.c:3953
struct tp_domain * next_list
Definition: object_domain.h:75
#define ER_JSON_INVALID_JSON
Definition: error_code.h:1546
int db_make_bigint(DB_VALUE *value, const DB_BIGINT num)
int db_get_int(const DB_VALUE *value)
int db_date_parse_datetime(char const *str, int str_len, DB_DATETIME *datetime)
Definition: db_date.c:3423
DB_TIMESTAMP timestamp
Definition: dbtype_def.h:766
#define LC_DOESNOT_EXIST
int db_is_vclass(DB_OBJECT *op)
Definition: db_virt.c:681
PR_TYPE tp_Numeric
int tp_more_general_type(const DB_TYPE type1, const DB_TYPE type2)
DB_TYPE
Definition: dbtype_def.h:670
int tp_value_equal(const DB_VALUE *value1, const DB_VALUE *value2, int do_coercion)
#define LANG_IS_COERCIBLE_COLL(c)
unsigned short count
Definition: dbtype_def.h:1033
int tz_create_datetimetz_from_ses(const DB_DATETIME *dt, DB_DATETIMETZ *dt_tz)
Definition: tz_support.c:1493
DB_C_DOUBLE db_get_double(const DB_VALUE *value)
#define ER_FAILED
Definition: error_code.h:47
int db_char_to_blob(const DB_VALUE *src_value, DB_VALUE *result_value)
int tp_domain_copy_enumeration(DB_ENUMERATION *dest, const DB_ENUMERATION *src)
int db_make_varchar(DB_VALUE *value, const int max_char_length, DB_CONST_C_CHAR str, const int char_str_byte_size, const int codeset, const int collation_id)
int db_seq_put(DB_SET *set, int index, DB_VALUE *value)
Definition: db_set.c:745
int db_datetime_decode(const DB_DATETIME *datetime, int *month, int *day, int *year, int *hour, int *minute, int *second, int *millisecond)
Definition: db_date.c:4574
#define DB_GET_COMPRESSED_STRING(v)
Definition: dbtype.h:89
int db_get_string_collation(const DB_VALUE *value)
#define ALWAYS_INLINE
DB_COLLECTION * set_copy(DB_COLLECTION *set)
Definition: set_object.c:2473
#define DB_DATETIMETZ_INITIALIZER
Definition: object_domain.c:92
int tp_domain_drop(TP_DOMAIN **dlist, TP_DOMAIN *domain)
void initval(DB_VALUE *value, int precision, int scale) const
struct tp_domain * setdomain
Definition: object_domain.h:82
int sm_check_class_domain(TP_DOMAIN *domain, MOP class_)
#define pthread_mutex_unlock(a)
Definition: area_alloc.c:51
int db_timestamp_encode_ses(const DB_DATE *date, const DB_TIME *timeval, DB_TIMESTAMP *utime, TZ_ID *dest_tz_id)
Definition: db_date.c:597
#define LC_ERROR
int db_value_clone(DB_VALUE *src, DB_VALUE *dest)
Definition: db_macro.c:1564
TP_DOMAIN_STATUS tp_value_auto_cast(const DB_VALUE *src, DB_VALUE *dest, const TP_DOMAIN *desired_domain)
DB_VALUE_COMPARE_RESULT tp_value_compare_with_error(const DB_VALUE *value1, const DB_VALUE *value2, int do_coercion, int total_order, bool *can_compare)
static TP_DOMAIN_STATUS tp_value_cast_internal(const DB_VALUE *src, DB_VALUE *dest, const TP_DOMAIN *desired_domain, TP_COERCION_MODE coercion_mode, bool do_domain_select, bool preserve_domain)
TP_DOMAIN * tp_domain_select_type(const TP_DOMAIN *domain_list, DB_TYPE type, DB_OBJECT *class_mop, int allow_coercion)
const TZ_ID * tz_get_utc_tz_id(void)
Definition: tz_support.c:816
int db_get_enum_codeset(const DB_VALUE *value)
struct setobj * set
Definition: db_set.h:43
TP_DOMAIN * tp_domain_find_enumeration(const DB_ENUMERATION *enumeration, bool is_desc)
int db_get_enum_string_size(const DB_VALUE *value)
static TP_DOMAIN * tp_Bigint_conv[]
#define assert_release(e)
Definition: error_manager.h:96
#define DOMAIN_INIT2(codeset, coll)
int db_make_object(DB_VALUE *value, DB_C_OBJECT *obj)
int db_make_pointer(DB_VALUE *value, DB_C_POINTER ptr)
#define DB_TIME_PRECISION
Definition: dbtype_def.h:598
PR_TYPE tp_Datetimeltz
static TP_DOMAIN * tp_Integer_conv[]
void db_json_set_double_to_doc(JSON_DOC *doc, double d)
Definition: db_json.cpp:3104
static void tp_dtoa(DB_VALUE const *src, DB_VALUE *result)
DB_VALUE_COMPARE_RESULT cmpval(const DB_VALUE *value, const DB_VALUE *value2, int do_coercion, int total_order, int *start_colp, int collation) const
TP_DOMAIN tp_Midxkey_domain_list_heads[TP_NUM_MIDXKEY_DOMAIN_LIST]
unsigned int db_on_server
int vid_oid_to_object(const DB_VALUE *value, DB_OBJECT **mop)
#define TP_FLOAT_MANTISA_DECIMAL_PRECISION
void setobj_put_domain(COL *set, TP_DOMAIN *domain)
Definition: set_object.c:6193
#define DB_SET_ENUM_ELEM_SHORT(elem, sv)
Definition: dbtype.h:114
#define WS_ISVID(mop)
Definition: work_space.h:288
int db_make_date(DB_VALUE *value, const int month, const int day, const int year)
#define OID_SET_NULL(oidp)
Definition: oid.h:85
DB_DATETIMETZ * db_get_datetimetz(const DB_VALUE *value)
int tp_value_coerce_strict(const DB_VALUE *src, DB_VALUE *dest, const TP_DOMAIN *desired_domain)
int db_make_datetimeltz(DB_VALUE *value, const DB_DATETIME *datetime)
unsigned is_cached
static TP_DOMAIN * tp_Domains[]
TP_DOMAIN tp_Object_domain
TP_DOMAIN * tp_domain_resolve_value(const DB_VALUE *val, TP_DOMAIN *dbuf)
static DB_VALUE_COMPARE_RESULT oidcmp(OID *oid1, OID *oid2)
static int tp_domain_match_internal(const TP_DOMAIN *dom1, const TP_DOMAIN *dom2, TP_MATCH exact, bool match_order)
#define SECONDS_IN_A_DAY
int db_make_sequence(DB_VALUE *value, DB_C_SET *set)
#define TP_IS_STRING_TYPE(typeid)
int vid_object_to_vobj(const DB_OBJECT *obj, DB_VALUE *vobj)
TP_DOMAIN * tp_domain_copy(const TP_DOMAIN *domain, bool check_cache)
static int tp_domain_check_class(TP_DOMAIN *domain, int *change)
int db_string_to_timestamptz_ex(const char *str, int str_len, DB_TIMESTAMPTZ *ts_tz, bool *has_zone, bool is_cast)
Definition: db_date.c:3820
TP_DOMAIN * tp_domain_find_charbit(DB_TYPE type, int codeset, int collation_id, unsigned char collation_flag, int precision, bool is_desc)
PR_TYPE tp_Integer
int numeric_db_value_coerce_to_num(DB_VALUE *src, DB_VALUE *dest, DB_DATA_STATUS *data_status)
TP_DOMAIN tp_Integer_domain
int er_errid(void)
#define TP_NEAR_MATCH(t1, t2)
Definition: object_domain.c:81
int db_is_subclass(MOP classmop, MOP supermop)
Definition: db_info.c:445
TP_DOMAIN ** tp_Domain_conversion_matrix[]
static int tp_atobi(const DB_VALUE *src, DB_BIGINT *num_value, DB_DATA_STATUS *data_stat)
const char * name
PR_TYPE tp_Oid
#define DB_VALUE_PRECISION(value)
Definition: dbtype.h:73
TP_DOMAIN tp_Null_domain
PR_TYPE tp_Time
enum tp_domain_status TP_DOMAIN_STATUS
#define DB_SHORT_PRECISION
Definition: dbtype_def.h:586
DB_TYPE get_id() const
PR_TYPE tp_Char
PR_TYPE * tp_Type_object
int setobj_build_domain_from_col(COL *col, TP_DOMAIN **set_domain)
Definition: set_object.c:6315
TP_DOMAIN tp_Utime_domain
TP_DOMAIN tp_Json_domain
TP_DOMAIN * tp_domain_find_set(DB_TYPE type, TP_DOMAIN *setdomain, bool is_desc)
#define DB_DEFAULT_NUMERIC_SCALE
Definition: dbtype_def.h:567
AREA * area_create(const char *name, size_t element_size, size_t alloc_count)
Definition: area_alloc.c:146
#define HIGHEST_3BITS_OF_UBI
int get_mem_size_of_mem(const void *mem, const tp_domain *domain=NULL) const
DB_DOMAIN_INFO domain
Definition: dbtype_def.h:1082
PR_TYPE tp_Pointer
#define DB_VALUE_SCALE(value)
Definition: dbtype.h:74
int tp_setdomain_size(const TP_DOMAIN *domain)
int db_datetimetz_to_string(char *buf, int bufsize, DB_DATETIME *dt, const TZ_ID *tz_id)
Definition: db_date.c:4302
#define DB_DATETIME_DECIMAL_SCALE
Definition: dbtype_def.h:616
#define DB_FLOAT_DECIMAL_PRECISION
Definition: dbtype_def.h:589
#define TP_DOUBLE_MANTISA_DECIMAL_PRECISION
#define TP_DOUBLE_AS_CHAR_LENGTH
#define TP_IS_DATETIME_TYPE(db_val_type)
static TP_DOMAIN * tp_NChar_conv[]
static TP_DOMAIN * tp_Float_conv[]
PR_TYPE tp_Blob
#define DATETIMETZ_BUF_SIZE
Definition: string_opfunc.h:95
DB_TIMESTAMPTZ * db_get_timestamptz(const DB_VALUE *value)
TP_DOMAIN tp_Double_domain
int db_make_short(DB_VALUE *value, const DB_C_SHORT num)
int db_timestamp_to_string(char *buf, int bufsize, DB_TIMESTAMP *utime)
Definition: db_date.c:4054
const char * lang_get_collation_name(const int coll_id)
TP_DOMAIN_STATUS tp_value_cast_preserve_domain(const DB_VALUE *src, DB_VALUE *dest, const TP_DOMAIN *desired_domain, bool implicit_coercion, bool preserve_domain)
int db_make_string(DB_VALUE *value, DB_CONST_C_CHAR str)
TP_DOMAIN tp_VarNChar_domain
DB_MONETARY * db_get_monetary(const DB_VALUE *value)
static INLINE TP_DOMAIN ** tp_domain_get_list_ptr(DB_TYPE type, TP_DOMAIN *setdomain) __attribute__((ALWAYS_INLINE))
bool pr_is_set_type(DB_TYPE type)
TP_DOMAIN tp_Datetime_domain
DB_DATA data
Definition: dbtype_def.h:1083
int char_isxdigit(int c)
Definition: chartype.c:85
DB_JSON json
Definition: dbtype_def.h:1073
unsigned int DB_TIMESTAMP
Definition: dbtype_def.h:759
unsigned is_parameterized
PR_TYPE * pr_type_from_id(DB_TYPE id)
PR_TYPE tp_Timestampltz
#define DB_MAX_VARBIT_PRECISION
Definition: dbtype_def.h:552
DB_COLLECTION * set_coerce(DB_COLLECTION *set, TP_DOMAIN *domain, bool implicit_coercion)
Definition: set_object.c:3645
TP_DOMAIN * tp_domain_resolve_default(DB_TYPE type)
PR_TYPE tp_Sequence
#define ER_MR_NULL_DOMAIN
Definition: error_code.h:1168
void er_set(int severity, const char *file_name, const int line_no, int err_id, int num_args,...)
Definition: db_set.h:35
INTL_CODESET codeset
LANG_COLLATION * lang_get_collation(const int coll_id)
PR_TYPE tp_Vobj
#define TP_FLOAT_AS_CHAR_LENGTH
int db_make_enumeration(DB_VALUE *value, unsigned short index, DB_CONST_C_CHAR str, int size, unsigned char codeset, const int collation_id)
int db_value_put_encoded_time(DB_VALUE *value, const DB_TIME *time)
Definition: db_macro.c:1357
#define DB_MAX_VARCHAR_PRECISION
Definition: dbtype_def.h:536
int tp_domain_match(const TP_DOMAIN *dom1, const TP_DOMAIN *dom2, TP_MATCH exact)
#define DB_MAX_NUMERIC_PRECISION
Definition: dbtype_def.h:522
JSON_VALIDATOR * db_json_copy_validator(JSON_VALIDATOR *validator)
Definition: db_json.cpp:2382
TP_DOMAIN tp_Vobj_domain
#define DB_INT32_MIN
Definition: dbtype_def.h:632
static TP_DOMAIN * tp_Double_conv[]
#define assert(x)
#define DB_DATETIME_PRECISION
Definition: dbtype_def.h:610
int db_make_monetary(DB_VALUE *value, const DB_CURRENCY type, const double amount)
#define DOMAIN_INIT4(prec, scale)
static int tp_atoudatetime(const DB_VALUE *src, DB_DATETIME *temp)
int tz_create_session_tzid_for_datetime(const DB_DATETIME *src_dt, bool src_is_utc, TZ_ID *tz_id)
Definition: tz_support.c:1037
#define DB_SET_ENUM_ELEM_STRING_SIZE(elem, sz)
Definition: dbtype.h:119
int qstr_hex_to_bin(char *dest, int dest_size, const char *src, int src_size)
int db_string_to_datetimetz_ex(const char *str, int str_len, DB_DATETIMETZ *dt_tz, bool *has_zone)
Definition: db_date.c:4455
#define DB_DOUBLE_DECIMAL_PRECISION
Definition: dbtype_def.h:592
int db_make_set(DB_VALUE *value, DB_C_SET *set)
struct db_domain_info::numeric_info numeric_info
TP_DOMAIN tp_Bigint_domain
int db_make_multiset(DB_VALUE *value, DB_C_SET *set)
static const TP_DOMAIN * tp_domain_find_compatible(const TP_DOMAIN *src, const TP_DOMAIN *dest)
#define ER_GENERIC_ERROR
Definition: error_code.h:49
#define STATIC_INLINE
TP_DOMAIN * tp_infer_common_domain(TP_DOMAIN *arg1, TP_DOMAIN *arg2)
int db_timestamp_encode_utc(const DB_DATE *date, const DB_TIME *timeval, DB_TIMESTAMP *utime)
Definition: db_date.c:635
int tp_domain_status_er_set(TP_DOMAIN_STATUS status, const char *file_name, const int line_no, const DB_VALUE *src, const TP_DOMAIN *domain)
TP_DOMAIN_COLL_ACTION
Definition: object_domain.h:62
struct db_object * class_mop
Definition: work_space.h:121
#define ER_IT_DATA_OVERFLOW
Definition: error_code.h:505
#define TP_DOMAIN_SELF_REF
Definition: object_domain.h:60
#define ER_OUT_OF_VIRTUAL_MEMORY
Definition: error_code.h:50
const char * intl_skip_spaces(const char *str, const char *str_end, const INTL_CODESET codeset)
int tp_domain_name(const TP_DOMAIN *domain, char *buffer, int maxlen)
#define DOM_GET_ENUMERATION(dom)
Definition: object_domain.h:38
#define INTL_CAN_STEAL_CS(cs_from, cs_to)
Definition: intl_support.h:87
PR_TYPE tp_Null
int tp_domain_size(const TP_DOMAIN *domain)
#define OR_CHECK_SHORT_OVERFLOW(i)
int db_time_encode(DB_TIME *timeval, int hour, int minute, int second)
Definition: db_date.c:370
#define DB_INTEGER_PRECISION
Definition: dbtype_def.h:580
unsigned is_desc
TP_DOMAIN * setobj_domain(COL *set)
Definition: set_object.c:6175
int db_json_get_json_from_str(const char *json_raw, JSON_DOC *&doc, size_t json_raw_length)
Definition: db_json.cpp:1608
void tp_init_value_domain(TP_DOMAIN *domain, DB_VALUE *value)
JSON_DOC * document
Definition: dbtype_def.h:1040
DB_DATETIME datetime
Definition: dbtype_def.h:783
int numeric_db_value_coerce_from_num(DB_VALUE *src, DB_VALUE *dest, DB_DATA_STATUS *data_status)
#define DB_VALUE_DOMAIN_TYPE(value)
Definition: dbtype.h:70
int tp_value_string_to_double(const DB_VALUE *value, DB_VALUE *result)
#define DB_INT32_MAX
Definition: dbtype_def.h:633
PR_TYPE tp_NChar
#define _dtoa
Definition: mprec.h:362
void tp_final(void)
#define DOM_GET_ENUM_ELEM(dom, idx)
Definition: object_domain.h:44
PR_TYPE tp_Short
#define TP_DOMAIN_COLLATION(dom)
static TP_DOMAIN * tp_Set_conv[]
#define TP_IS_NUMERIC_TYPE(typeid)
bool is_always_variable() const
TP_DOMAIN tp_Set_domain
static enum scanner_mode mode
#define DOM_GET_ENUM_ELEMS_COUNT(dom)
Definition: object_domain.h:42
static DB_BIGINT tp_ubi_to_bi_with_args(UINT64 ubi, bool is_negative, bool truncated, bool round, DB_DATA_STATUS *data_stat)
#define OR_CHECK_INT_OVERFLOW(i)
static void tp_value_slam_domain(DB_VALUE *value, const DB_DOMAIN *domain)
int db_json_get_int_from_document(const JSON_DOC *doc)
Definition: db_json.cpp:2525
std::int64_t db_json_get_bigint_from_document(const JSON_DOC *doc)
Definition: db_json.cpp:2531
#define db_get_json_schema(v)
Definition: dbtype.h:148
void db_json_delete_doc(JSON_DOC *&doc)
Definition: db_json.cpp:2355
static TP_DOMAIN * tp_Char_conv[]
DB_OBJECT * db_get_object(const DB_VALUE *value)
int db_make_timestamptz(DB_VALUE *value, const DB_C_TIMESTAMPTZ *ts_tz_val)
#define OID_EQ(oidp1, oidp2)
Definition: oid.h:92
static TP_DOMAIN * tp_Midxkey_domains[TP_NUM_MIDXKEY_DOMAIN_LIST+1]
VID_OID oid_info
Definition: work_space.h:120
int db_string_put_cs_and_collation(DB_VALUE *value, const int codeset, const int collation_id)
Definition: db_macro.c:4164
static int tp_enumeration_match(const DB_ENUMERATION *db_enum1, const DB_ENUMERATION *db_enum2)
TP_DOMAIN_STATUS tp_value_cast(const DB_VALUE *src, DB_VALUE *dest, const TP_DOMAIN *desired_domain, bool implicit_coercion)
PR_TYPE tp_Float
int db_char_string_coerce(const DB_VALUE *src_string, DB_VALUE *dest_string, DB_DATA_STATUS *data_status)
TP_DOMAIN tp_Pointer_domain
#define TP_DOMAIN_TYPE(dom)
static int rv
Definition: area_alloc.c:52
void db_json_set_bigint_to_doc(JSON_DOC *doc, std::int64_t i)
Definition: db_json.cpp:3116
static int tp_atonumeric(const DB_VALUE *src, DB_VALUE *temp)
#define WS_SET_DELETED(mop)
Definition: work_space.h:286
int char_isdigit(int c)
Definition: chartype.c:73
static TP_DOMAIN * tp_String_conv[]
#define NULL
Definition: freelistheap.h:34
static TP_DOMAIN * tp_VarNChar_conv[]
OID oid
Definition: work_space.h:65
TP_DOMAIN tp_Oid_domain
unsigned short db_get_enum_short(const DB_VALUE *value)
int tp_valid_indextype(DB_TYPE type)
int db_date_parse_time(char const *str, int str_len, DB_TIME *time, int *millisecond)
Definition: db_date.c:2933
#define NUMERIC_MAX_STRING_SIZE
int db_blob_to_bit(const DB_VALUE *src_value, const DB_VALUE *length_value, DB_VALUE *result_value)
PR_TYPE tp_Set
TP_DOMAIN * tp_domain_find_noparam(DB_TYPE type, bool is_desc)
struct pr_type * type
Definition: object_domain.h:76
TP_DOMAIN tp_Time_domain
int tz_datetimeltz_to_local(const DB_DATETIME *dt_ltz, DB_DATETIME *dt_local)
Definition: tz_support.c:1628
DB_OBJECT * db_get_class(MOP obj)
Definition: db_info.c:589
PR_TYPE tp_VarBit
const char * pr_type_name(DB_TYPE id)
#define DBL_MAX_DIGITS
Definition: object_domain.c:79
TP_DOMAIN tp_Elo_domain
static UINT64 tp_ubi_times_ten(UINT64 ubi, bool *truncated)
TP_DOMAIN * tp_domain_cache(TP_DOMAIN *transient)
#define err(fd,...)
Definition: porting.h:431
#define db_private_free_and_init(thrd, ptr)
Definition: memory_alloc.h:141
int db_value_put_encoded_date(DB_VALUE *value, const DB_DATE *date)
Definition: db_macro.c:1383
int db_timestamp_decode_w_tz_id(const DB_TIMESTAMP *utime, const TZ_ID *tz_id, DB_DATE *date, DB_TIME *timeval)
Definition: db_date.c:902
#define TP_BIGINT_PRECISION
TP_DOMAIN_STATUS tp_value_cast_no_domain_select(const DB_VALUE *src, DB_VALUE *dest, const TP_DOMAIN *desired_domain, bool implicit_coercion)
TP_DOMAIN tp_Date_domain
DB_VALUE_COMPARE_RESULT set_compare(DB_COLLECTION *set1, DB_COLLECTION *set2, int do_coercion)
Definition: set_object.c:3411
PR_TYPE tp_Substructure
#define NUM_BUF_SIZE
Definition: string_opfunc.h:88
int db_date_parse_date(char const *str, int str_len, DB_DATE *date)
Definition: db_date.c:3481
PR_TYPE tp_Variable
static int tp_digit_number_str_to_bi(const char *start, const char *end, INTL_CODESET codeset, bool is_negative, DB_BIGINT *num_value, DB_DATA_STATUS *data_stat)
int numeric_db_value_coerce_from_num_strict(DB_VALUE *src, DB_VALUE *dest)
#define db_private_alloc(thrd, size)
Definition: memory_alloc.h:227
#define CONST_CAST(dest_type, expr)
Definition: porting.h:1060
#define TP_IMPLICIT_COERCION_NOT_ALLOWED(src_type, dest_type)
int tp_domain_add(TP_DOMAIN **dlist, TP_DOMAIN *domain)
TP_DOMAIN tp_Clob_domain
need_clear_type need_clear
Definition: dbtype_def.h:1084
#define DB_TIMESTAMP_PRECISION
Definition: dbtype_def.h:604
static int tp_atotimestamptz(const DB_VALUE *src, DB_TIMESTAMPTZ *temp)
int pr_clear_value(DB_VALUE *value)
int db_timestamp_decode_ses(const DB_TIMESTAMP *utime, DB_DATE *date, DB_TIME *timeval)
Definition: db_date.c:764
DB_BIGINT db_get_bigint(const DB_VALUE *value)
#define DB_MONETARY_DECIMAL_PRECISION
Definition: dbtype_def.h:595
DB_JSON_TYPE db_json_get_type(const JSON_DOC *doc)
Definition: db_json.cpp:2519
#define DB_BIGINT_PRECISION
Definition: dbtype_def.h:577
int vid_vobj_to_object(const DB_VALUE *vobj, DB_OBJECT **mop)
int db_time_to_string(char *buf, int bufsize, DB_TIME *time)
Definition: db_date.c:3994
DB_DOMAIN * db_type_to_db_domain(const DB_TYPE type)
Definition: db_macro.c:1710
#define DB_DEFAULT_NUMERIC_PRECISION
Definition: dbtype_def.h:564
int db_json_copy_and_convert_to_utf8(const DB_VALUE *src_dbval, DB_VALUE *dest_dbval, const DB_VALUE **json_str_dbval)
int db_make_time(DB_VALUE *value, const int hour, const int minute, const int second)
int db_datetime_to_string(char *buf, int bufsize, DB_DATETIME *datetime)
Definition: db_date.c:4225
#define DB_DEFAULT_SCALE
Definition: dbtype_def.h:561
TP_DOMAIN_STATUS tp_check_value_size(TP_DOMAIN *domain, DB_VALUE *value)
int db_make_datetimetz(DB_VALUE *value, const DB_DATETIMETZ *datetimetz)
TP_DOMAIN tp_Float_domain
PR_TYPE tp_Midxkey
struct db_domain_info::general_info general_info
int64_t DB_BIGINT
Definition: dbtype_def.h:751
#define d1
TP_DOMAIN tp_Numeric_domain
#define ROUND(x)
int db_clob_to_char(const DB_VALUE *src_value, const DB_VALUE *codeset_value, DB_VALUE *result_value)
void tp_apply_sys_charset(void)
enum tp_match TP_MATCH
#define CAST_BUFLEN
Definition: porting.h:471
DB_ENUMERATION enumeration
Definition: object_domain.h:84
DB_CONST_C_CHAR db_get_enum_string(const DB_VALUE *value)
#define TP_IS_CHAR_TYPE(typeid)
TP_DOMAIN_COLL_ACTION collation_flag
Definition: object_domain.h:94
static void error(const char *msg)
Definition: gencat.c:331
TP_DOMAIN * set_get_domain(DB_COLLECTION *set)
Definition: set_object.c:3319
int db_make_float(DB_VALUE *value, const DB_C_FLOAT num)
unsigned is_visited
#define DB_DEFAULT_PRECISION
Definition: dbtype_def.h:558
PR_TYPE tp_Bit
#define DB_GET_ENUM_ELEM_STRING_SIZE(elem)
Definition: dbtype.h:105
TP_DOMAIN * tp_domain_construct(DB_TYPE domain_type, DB_OBJECT *class_obj, int precision, int scale, TP_DOMAIN *setdomain)
TP_DOMAIN tp_Char_domain
#define BITS_IN_HEX
#define BYTE_COUNT_HEX(bit_cnt)
#define TP_TYPE_HAS_COLLATION(typeid)
char * numeric_db_value_print(const DB_VALUE *val, char *buf)
#define OR_CHECK_FLOAT_OVERFLOW(i)
int tz_utc_datetimetz_to_local(const DB_DATETIME *dt_utc, const TZ_ID *tz_id, DB_DATETIME *dt_local)
Definition: tz_support.c:1571
int locator_does_exist_object(MOP mop, DB_FETCH_MODE purpose)
Definition: locator_cl.c:3242
static void tp_swizzle_oid(TP_DOMAIN *domain)
TP_DOMAIN tp_Timestampltz_domain
#define ARG_FILE_LINE
Definition: error_manager.h:44
PR_TYPE tp_String
void db_json_set_int_to_doc(JSON_DOC *doc, int i)
Definition: db_json.cpp:3110
#define DB_BIGINT_MAX
Definition: dbtype_def.h:640
int pr_clone_value(const DB_VALUE *src, DB_VALUE *dest)
OID * db_get_oid(const DB_VALUE *value)
const char * db_json_get_string_from_document(const JSON_DOC *doc)
Definition: db_json.cpp:2543
#define WS_OID(mop)
Definition: work_space.h:293
unsigned int DB_TIME
Definition: dbtype_def.h:754
TP_DOMAIN * tp_domain_find_numeric(DB_TYPE type, int precision, int scale, bool is_desc)
unsigned int DB_DATE
Definition: dbtype_def.h:771
#define DB_BIGINT_MIN
Definition: dbtype_def.h:641
DB_DATA_STATUS
TP_DOMAIN_STATUS set_check_domain(DB_COLLECTION *set, TP_DOMAIN *domain)
Definition: set_object.c:3604
PR_TYPE tp_Double
#define DB_SET_ENUM_ELEM_CODESET(elem, cs)
Definition: dbtype.h:111
PR_TYPE tp_Date
#define free_and_init(ptr)
Definition: memory_alloc.h:147
int sm_coerce_object_domain(TP_DOMAIN *domain, MOP object, MOP *dest_object)
#define DOMAIN_INIT3
#define strlen(s1)
Definition: intl_support.c:43
int db_make_timestampltz(DB_VALUE *value, const DB_C_TIMESTAMP ts_val)
DB_DATE * db_get_date(const DB_VALUE *value)
int oid_compare(const void *a, const void *b)
Definition: oid.c:243
DB_ENUM_ELEMENT * elements
Definition: dbtype_def.h:1031
TP_DOMAIN tp_Bit_domain
#define HIGHEST_BIT_OF_UINT64
#define DB_DATE_PRECISION
Definition: dbtype_def.h:601
int db_value_precision(const DB_VALUE *value)
TP_DOMAIN tp_Datetimetz_domain
DB_DOMAIN * domain
Definition: dbtype_def.h:865
PR_TYPE tp_Json
int db_make_string_copy(DB_VALUE *value, DB_CONST_C_CHAR str)
unsigned int date
Definition: dbtype_def.h:776
void db_json_delete_validator(JSON_VALIDATOR *&validator)
Definition: db_json.cpp:2394
TP_DOMAIN tp_Monetary_domain
int tp_domain_filter_list(TP_DOMAIN *dlist, int *list_changes)
int db_json_validate_doc(JSON_VALIDATOR *validator, JSON_DOC *doc)
Definition: db_json.cpp:2388
enum intl_codeset INTL_CODESET
Definition: intl_support.h:190
static bool tp_Initialized
PR_TYPE tp_Timestamptz
PR_TYPE tp_Object
void * area_alloc(AREA *area)
Definition: area_alloc.c:360
TP_DOMAIN tp_Enumeration_domain
bool prm_get_bool_value(PARAM_ID prm_id)
JSON_VALIDATOR * json_validator
int db_json_load_validator(const char *json_schema_raw, JSON_VALIDATOR *&validator)
Definition: db_json.cpp:2362
DB_TIMESTAMP * db_get_timestamp(const DB_VALUE *value)
PR_TYPE tp_Datetimetz
int db_get_string_size(const DB_VALUE *value)
DB_C_SHORT db_get_short(const DB_VALUE *value)
tp_coersion_mode
Definition: object_domain.c:94
PR_TYPE tp_VarNChar
void er_clear(void)
void tp_domain_clear_enumeration(DB_ENUMERATION *enumeration)
static int tp_atotime(const DB_VALUE *src, DB_TIME *temp)
#define TP_IS_DATE_TYPE(typeid)
int area_free(AREA *area, void *ptr)
Definition: area_alloc.c:514
PR_TYPE tp_Elo
static int tp_atodatetimetz(const DB_VALUE *src, DB_DATETIMETZ *temp)
void db_timestamp_decode_utc(const DB_TIMESTAMP *utime, DB_DATE *date, DB_TIME *timeval)
Definition: db_date.c:781
int db_make_varnchar(DB_VALUE *value, const int max_nchar_length, DB_CONST_C_NCHAR str, const int nchar_str_byte_size, const int codeset, const int collation_id)
#define TP_FLOATING_PRECISION_VALUE
#define ER_QSTR_INCOMPATIBLE_COLLATIONS
Definition: error_code.h:1472
int tp_enumeration_to_varchar(const DB_VALUE *src, DB_VALUE *result)
#define DB_VALUE_TYPE(value)
Definition: dbtype.h:72
#define ARE_COMPARABLE(typ1, typ2)
Definition: object_domain.c:74
#define DB_CURRENCY_DEFAULT
Definition: dbtype.h:46
int db_get_enum_collation(const DB_VALUE *value)
int i
Definition: dynamic_load.c:954
static const DB_TYPE db_type_rank[]
int db_make_null(DB_VALUE *value)
#define DB_TIMESTAMPTZ_PRECISION
Definition: dbtype_def.h:607
DB_TYPE id
int tp_value_str_auto_cast_to_number(DB_VALUE *src, DB_VALUE *dest, DB_TYPE *val_type)
static TP_DOMAIN * tp_Sequence_conv[]
#define DB_IS_NULL(value)
Definition: dbtype.h:63
struct tp_domain * next
Definition: object_domain.h:74
#define INLINE
static TP_DOMAIN * tp_Bit_conv[]
int db_make_double(DB_VALUE *value, const DB_C_DOUBLE num)
int tp_can_steal_string(const DB_VALUE *val, const DB_DOMAIN *desired_domain)
TP_DOMAIN * tp_domain_resolve(DB_TYPE domain_type, DB_OBJECT *class_obj, int precision, int scale, TP_DOMAIN *setdomain, int collation)
void db_date_decode(const DB_DATE *date, int *monthp, int *dayp, int *yearp)
Definition: db_date.c:338
TP_DOMAIN tp_Sequence_domain
DB_DATETIME * db_get_datetime(const DB_VALUE *value)
int db_char_to_clob(const DB_VALUE *src_value, DB_VALUE *result_value)
#define pthread_mutex_lock(a)
Definition: area_alloc.c:50
#define DB_MAX_VARNCHAR_PRECISION
Definition: dbtype_def.h:546
static int tp_scientific_str_to_bi(const char *start, const char *end, INTL_CODESET codeset, bool is_negative, DB_BIGINT *num_value, DB_DATA_STATUS *data_stat)
int db_make_timestamp(DB_VALUE *value, const DB_C_TIMESTAMP timeval)
int db_make_int(DB_VALUE *value, const int num)
int db_get_string_length(const DB_VALUE *value)
PR_TYPE tp_Error
struct db_object * class_mop
Definition: object_domain.h:81
#define LANG_RT_COMMON_COLL(c1, c2, coll)
int db_make_oid(DB_VALUE *value, const OID *oid)
int db_make_char(DB_VALUE *value, const int char_length, DB_CONST_C_CHAR str, const int char_str_byte_size, const int codeset, const int collation_id)
AREA * tp_Domain_area
#define OID_ISNULL(oidp)
Definition: oid.h:81
int tp_domain_attach(TP_DOMAIN **dlist, TP_DOMAIN *domain)
#define db_date_parse_utime
Definition: tz_support.h:31
DB_TIMESTAMP DB_UTIME
Definition: dbtype_def.h:761
static INLINE TP_DOMAIN * tp_domain_get_list(DB_TYPE type, TP_DOMAIN *setdomain) __attribute__((ALWAYS_INLINE))
#define LANG_SYS_CODESET
#define TP_DOMAIN_CODESET(dom)
int tp_domain_match_ignore_order(const TP_DOMAIN *dom1, const TP_DOMAIN *dom2, TP_MATCH exact)
#define OR_CHECK_ASSIGN_OVERFLOW(dest, src)
int collation_id
Definition: object_domain.h:92
int get_disk_size_of_mem(const void *mem, const tp_domain *domain=NULL) const
DB_TIME * db_get_time(const DB_VALUE *value)
PR_TYPE tp_Enumeration
int numeric_coerce_string_to_num(const char *astring, int astring_length, INTL_CODESET codeset, DB_VALUE *result)
void db_time_decode(DB_TIME *timeval, int *hourp, int *minutep, int *secondp)
Definition: db_date.c:432
#define DB_GET_ENUM_ELEM_CODESET(elem)
Definition: dbtype.h:108
DB_VALUE_COMPARE_RESULT
Definition: dbtype_def.h:199
int tz_create_session_tzid_for_timestamp(const DB_UTIME *src_ts, TZ_ID *tz_id)
Definition: tz_support.c:1068
DB_C_POINTER db_get_pointer(const DB_VALUE *value)
enum tp_coersion_mode TP_COERCION_MODE
#define TP_IS_BIT_TYPE(typeid)
#define DOM_SET_ENUM(dom, elems, cnt)
Definition: object_domain.h:51
static TP_DOMAIN * tp_Multiset_conv[]
#define string_to_double(str, end_ptr)
Definition: porting.h:972
TP_DOMAIN * tp_domain_new(DB_TYPE type)
static int tp_hex_str_to_bi(const char *start, const char *end, INTL_CODESET codeset, bool is_negative, DB_BIGINT *num_value, DB_DATA_STATUS *data_stat)
double amount
Definition: dbtype_def.h:831
#define TP_IS_CHAR_STRING(db_val_type)
TP_DOMAIN_STATUS tp_value_cast_force(const DB_VALUE *src, DB_VALUE *dest, const TP_DOMAIN *desired_domain, bool implicit_coercion)
bool db_json_get_bool_from_document(const JSON_DOC *doc)
Definition: db_json.cpp:2555
char * db_json_get_bool_as_str_from_document(const JSON_DOC *doc)
Definition: db_json.cpp:2549
int db_make_bit(DB_VALUE *value, const int bit_length, DB_CONST_C_BIT bit_str, const int bit_str_bit_size)
int db_get_string_codeset(const DB_VALUE *value)
TP_DOMAIN tp_Multiset_domain
#define TP_IS_CHAR_BIT_TYPE(typeid)
const char ** p
Definition: dynamic_load.c:945
JSON_DOC * db_json_allocate_doc()
Definition: db_json.cpp:2332
DB_VALUE_COMPARE_RESULT tp_set_compare(const DB_VALUE *value1, const DB_VALUE *value2, int do_coercion, int total_order)
void tp_domain_free(TP_DOMAIN *dom)
DB_CONST_C_CHAR db_get_string(const DB_VALUE *value)
TP_DOMAIN tp_NChar_domain
TP_DOMAIN * tp_domain_find_object(DB_TYPE type, OID *class_oid, struct db_object *class_mop, bool is_desc)
int db_bit_to_blob(const DB_VALUE *src_value, DB_VALUE *result_value)
unsigned int time
Definition: dbtype_def.h:777
#define QSTR_COMPARE(id, string1, size1, string2, size2, ti)
Definition: string_opfunc.h:66
int db_make_nchar(DB_VALUE *value, const int nchar_length, DB_CONST_C_NCHAR str, const int nchar_str_byte_size, const int codeset, const int collation_id)
static TP_DOMAIN * tp_Short_conv[]
#define DOMAIN_INIT
static void make_desired_string_db_value(DB_TYPE desired_type, const TP_DOMAIN *desired_domain, const char *new_string, DB_VALUE *target, TP_DOMAIN_STATUS *status, DB_DATA_STATUS *data_stat)
int tp_domain_memory_size(TP_DOMAIN *domain)
#define OR_CHECK_USHRT_OVERFLOW(i)
static TP_DOMAIN * tp_Numeric_conv[]
#define DB_GET_ENUM_ELEM_SHORT(elem)
Definition: dbtype.h:99
static int tp_atof(const DB_VALUE *src, double *num_value, DB_DATA_STATUS *data_stat)
TP_DOMAIN tp_VarBit_domain
int db_value_domain_init(DB_VALUE *value, const DB_TYPE type, const int precision, const int scale)
Definition: db_macro.c:153
int db_value_alter_type(DB_VALUE *value, const DB_TYPE type)
Definition: db_macro.c:1225
char * db_json_get_raw_json_body_from_document(const JSON_DOC *doc)
Definition: db_json.cpp:1357