Skip to content

File object_domain.h

File List > cubrid > src > object > object_domain.h

Go to the documentation of this file

/*
 * Copyright 2008 Search Solution Corporation
 * Copyright 2016 CUBRID Corporation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */


/*
 * object_domain.h: data type definitions
 */

#ifndef _OBJECT_DOMAIN_H_
#define _OBJECT_DOMAIN_H_

#ident "$Id$"

#include "config.h"
#include "dbtype_def.h"

#include <stdio.h>

#if defined (__cplusplus)
class JSON_VALIDATOR;
#endif

#define DOM_GET_ENUMERATION(dom) \
    ((dom)->enumeration)
#define DOM_GET_ENUM_ELEMENTS(dom) \
    ((dom)->enumeration.elements)
#define DOM_GET_ENUM_ELEMS_COUNT(dom) \
    ((dom)->enumeration.count)
#define DOM_GET_ENUM_ELEM(dom, idx) \
    ((dom)->enumeration.elements[idx - 1])

#define DOM_SET_ENUM_ELEMENTS(dom, elems) \
    ((dom)->enumeration.elements = (elems))
#define DOM_SET_ENUM_ELEMS_COUNT(dom, cnt) \
    ((dom)->enumeration.count = (cnt))
#define DOM_SET_ENUM(dom, elems, cnt) \
    do{\
    (dom)->enumeration.count = (cnt); \
    (dom)->enumeration.elements = (elems); \
      } while(0)
/*
 * TP_DOMAIN_SELF_REF is used as an argument
 * to tp_domain_construct so that the self_ref flag can be set
 */
#define TP_DOMAIN_SELF_REF -1

typedef enum
{
  /* normal mode, collation applies as other domain parameters */
  TP_DOMAIN_COLL_NORMAL = 0,
  /* only collation applies, the type and precision are not changed */
  TP_DOMAIN_COLL_ENFORCE = 1,
  /* type and precision are applied, collation is leaved intact */
  TP_DOMAIN_COLL_LEAVE = 2
} TP_DOMAIN_COLL_ACTION;

typedef struct tp_domain
{
  struct tp_domain *next;   /* next in the same domain list */
  struct tp_domain *next_list;  /* next domain list */
  const struct pr_type *type;

  int precision;
  int scale;

  struct db_object *class_mop;  /* swizzled class oid if on client */
  struct tp_domain *setdomain;  /* hierarchical domain for sets */

  DB_ENUMERATION enumeration;   /* enumeration values */

  OID class_oid;        /* Class OID if type is tp_Object */

  /* built-in reference number */
  int built_in_index;

  unsigned char codeset;    /* codeset if char */
  int collation_id;     /* collation identifier */

  TP_DOMAIN_COLL_ACTION collation_flag;

  unsigned self_ref:1;      /* object self reference */
  /*
   * merge this with self_ref when we get a chance to rebuild the whole
   * system
   */
  unsigned is_cached:1;     /* set when the domain has been cached */

  /* non-zero if this type can be parameterized */
  unsigned is_parameterized:1;

  unsigned is_desc:1;       /* desc order for index key_type */

  /* run-time flag used during domain comparison */
  unsigned is_visited:1;

  JSON_VALIDATOR *json_validator;   /* schema validator if type is json */
} TP_DOMAIN;

  /*
   * We probably should make this 0 rather than -1 so that we can more easily
   * represent precisions with unsigned integers.  Zero is not a valid
   * precision.
   */
#define TP_FLOATING_PRECISION_VALUE -1

/*
 * TP_ALLOC_CONTEXT
 *    This structure is used in places where the storage allocation of
 *    certain structures must be controlled.
 *
 */

typedef struct tp_alloc_context
{
  void *(*alloc_func) (int size, ...);  /* optional second argument */
  void *alloc_args;
  void (*free_func) (void *mem, ...);   /* optional second argument */
  void *free_args;
} TP_ALLOC_CONTEXT;

#define TP_ALLOC(con, size) \
  (*(con)->alloc_func)(size, (con)->alloc_args)

#define TP_FREE(con, mem) \
  (*(con)->free_func)(mem, (con)->free_args)

/*
 * BUILT IN DOMAINS
 */

extern TP_DOMAIN tp_Null_domain;
extern TP_DOMAIN tp_Integer_domain;
extern TP_DOMAIN tp_Float_domain;
extern TP_DOMAIN tp_Double_domain;
extern TP_DOMAIN tp_String_domain;
extern TP_DOMAIN tp_Object_domain;
extern TP_DOMAIN tp_Set_domain;
extern TP_DOMAIN tp_Multiset_domain;
extern TP_DOMAIN tp_Sequence_domain;
extern TP_DOMAIN tp_Elo_domain;
extern TP_DOMAIN tp_Blob_domain;
extern TP_DOMAIN tp_Clob_domain;
extern TP_DOMAIN tp_Time_domain;
extern TP_DOMAIN tp_Utime_domain;
extern TP_DOMAIN tp_Date_domain;
extern TP_DOMAIN tp_Monetary_domain;
extern TP_DOMAIN tp_Variable_domain;
extern TP_DOMAIN tp_Substructure_domain;
extern TP_DOMAIN tp_Pointer_domain;
extern TP_DOMAIN tp_Error_domain;
extern TP_DOMAIN tp_Short_domain;
extern TP_DOMAIN tp_Vobj_domain;
extern TP_DOMAIN tp_Oid_domain;
extern TP_DOMAIN tp_Numeric_domain;
extern TP_DOMAIN tp_Char_domain;
extern TP_DOMAIN tp_Bit_domain;
extern TP_DOMAIN tp_VarBit_domain;
extern TP_DOMAIN tp_Midxkey_domain;
extern TP_DOMAIN tp_Enumeration_domain;
extern TP_DOMAIN tp_Json_domain;
extern TP_DOMAIN tp_Bigint_domain;

/*
 * TP_DOMAIN_STATUS
 *    This is used to defined a set of possible return codes
 *    for the domain comparison and checking functions.
 *    These don't set errors but rather rely on the higher level
 *    modules to set a more appropriate error.
 */

typedef enum tp_domain_status
{
  DOMAIN_COMPATIBLE = 0,    /* success */
  DOMAIN_INCOMPATIBLE,      /* can't be coerced */
  DOMAIN_OVERFLOW,      /* value out of range */
  DOMAIN_ERROR          /* an error has been set */
} TP_DOMAIN_STATUS;

/*
 * TP_MATCH
 *    This is used to describe the amount of "tolerance" to be exhibited by
 *    domain matching functions when looking for compatible domains.
 */
typedef enum tp_match
{
  TP_ANY_MATCH,         /* Any coercible domain matches. */
  TP_EXACT_MATCH,       /* Domain must match exactly.  */
  TP_STR_MATCH,         /* "String" domains match subject to length constraints and fixed/varying types, i.e.,
                 * a varying domain with precision n "matches" a fixed domain with precision m if n >=
                 * m. Only used in very special circumstances where we're trying to avoid copying
                 * strings. */

  TP_SET_MATCH
} TP_MATCH;

/*
 * TP_IS_SET_TYPE
 *    Macros for detecting the set types, saves a function call.
 */
/*
 * !!! DB_TYPE_VOBJ probably should be added to this macro as this
 * is now the behavior of pr_is_set_type() which we should try to
 * phase out in favor of the faster inline macro.  Unfortunately, there
 * are a number of usages of both TP_IS_SET_TYPE that may break if
 * we change the semantics.  Will have to think carefully about this
 */

#define TP_IS_SET_TYPE(typenum) \
  ((((typenum) == DB_TYPE_SET) || ((typenum) == DB_TYPE_MULTISET) || \
    ((typenum) == DB_TYPE_SEQUENCE)) ? true : false)

/*
 * TP_IS_BIT_TYPE
 *    Tests to see if the type id is one of the binary string types.
 */

#define TP_IS_BIT_TYPE(typeid) \
  (((typeid) == DB_TYPE_VARBIT) || ((typeid) == DB_TYPE_BIT))

/*
 * TP_IS_CHAR_TYPE
 *    Tests to see if a type is any one of the character types.
 */

#define TP_IS_CHAR_TYPE(typeid)           ((typeid) == DB_TYPE_VARCHAR || (typeid) == DB_TYPE_CHAR)
#define TP_IS_LOB_TYPE(typeid)            ((typeid) == DB_TYPE_BLOB || (typeid) == DB_TYPE_CLOB)
#define TP_IS_FIXED_LEN_CHAR_TYPE(typeid) ((typeid) == DB_TYPE_CHAR)
#define TP_IS_VAR_LEN_CHAR_TYPE(typeid)   ((typeid) == DB_TYPE_VARCHAR)

/*
 * TP_IS_CHAR_BIT_TYPE
 *    Tests to see if a type is one of the character or bit types.
 */

#define TP_IS_CHAR_BIT_TYPE(typeid) (TP_IS_CHAR_TYPE(typeid) \
                                     || TP_IS_BIT_TYPE(typeid))

#define TP_IS_STRING_TYPE(typeid) TP_IS_CHAR_BIT_TYPE((typeid))

#define TP_IS_NUMERIC_TYPE(typeid) \
  (((typeid) == DB_TYPE_INTEGER) || ((typeid) == DB_TYPE_FLOAT) \
   || ((typeid) == DB_TYPE_DOUBLE)  || ((typeid) == DB_TYPE_SMALLINT) \
   || ((typeid) == DB_TYPE_NUMERIC) || ((typeid) == DB_TYPE_MONETARY) \
   || ((typeid) == DB_TYPE_BIGINT))

#define TP_IS_DOUBLE_ALIGN_TYPE(typeid) \
  ((typeid) == DB_TYPE_DOUBLE || (typeid) == DB_TYPE_BIGINT)

#define TP_IS_DATE_WITH_TZ_TYPE(typeid) \
  (((typeid) == DB_TYPE_DATETIMELTZ) || ((typeid) == DB_TYPE_DATETIMETZ) \
   || ((typeid) == DB_TYPE_TIMESTAMPLTZ) \
   || ((typeid) == DB_TYPE_TIMESTAMPTZ))

#define TP_IS_DATE_TYPE(typeid) \
  (((typeid) == DB_TYPE_DATE) || ((typeid) == DB_TYPE_DATETIME) \
   || ((typeid) == DB_TYPE_TIMESTAMP) || TP_IS_DATE_WITH_TZ_TYPE (typeid))

#define TP_IS_DATE_OR_TIME_TYPE(typeid) \
  (((typeid) == DB_TYPE_TIME) || TP_IS_DATE_TYPE(typeid))

#define TP_IS_FLOATING_NUMBER_TYPE(typeid) \
  (((typeid) == DB_TYPE_FLOAT) || ((typeid) == DB_TYPE_DOUBLE) \
   || ((typeid) == DB_TYPE_NUMERIC) || ((typeid) == DB_TYPE_MONETARY))

#define TP_IS_DISCRETE_NUMBER_TYPE(typeid) \
  (((typeid) == DB_TYPE_INTEGER) || ((typeid) == DB_TYPE_SMALLINT) \
   || ((typeid) == DB_TYPE_BIGINT))

/*
 * Precision for non-parameterized predefined types
 *
 * SQL-3 says time and timestamp types should be parameterized.
 * Should Cubrid implement the standard then the corresponding time/timestamp
 * macros found here would be removed and placed in dbtype.h similar to
 * the numeric macros (DB_MAX_NUMERIC_PRECISION).
 */

#define TP_DOUBLE_MANTISA_BINARY_PRECISION  53
#define TP_DOUBLE_EXPONENT_BINARY_PRECISION 11
#define TP_DOUBLE_BINARY_PRECISION      TP_DOUBLE_MANTISA_BINARY_PRECISION

#define TP_DOUBLE_MANTISA_DECIMAL_PRECISION   16    /* 15.955 */
#define TP_DOUBLE_EXPONENT_DECIMAL_PRECISION  3 /* 3.311 */
#define TP_DOUBLE_DECIMAL_PRECISION     TP_DOUBLE_MANTISA_DECIMAL_PRECISION

/* add 4 for exponent and mantisa sign, decimal point and the exponent
 * introducer 'e' in a floating-point literal */
#define TP_DOUBLE_AS_CHAR_LENGTH \
    (4 + TP_DOUBLE_MANTISA_DECIMAL_PRECISION + \
    TP_DOUBLE_EXPONENT_DECIMAL_PRECISION)

#define TP_MONETARY_MANTISA_PRECISION     TP_DOUBLE_MANTISA_DECIMAL_PRECISION
#define TP_MONETARY_EXPONENT_PRECISION    TP_DOUBLE_EXPONENT_DECIMAL_PRECISION
#define TP_MONETARY_PRECISION         TP_DOUBLE_DECIMAL_PRECISION
#define TP_MONETARY_AS_CHAR_LENGTH    TP_DOUBLE_AS_CHAR_LENGTH

#define TP_FLOAT_MANTISA_BINARY_PRECISION   24
#define TP_FLOAT_EXPONENT_BINARY_PRECISION  8
#define TP_FLOAT_BINARY_PRECISION       TP_FLOAT_MANTISA_BINARY_PRECISION

#define TP_FLOAT_MANTISA_DECIMAL_PRECISION    7 /* 7.225 */
#define TP_FLOAT_EXPONENT_DECIMAL_PRECISION   2 /* 2.408 */
#define TP_FLOAT_DECIMAL_PRECISION      TP_FLOAT_MANTISA_DECIMAL_PRECISION
#define TP_FLOAT_AS_CHAR_LENGTH \
    (4 + TP_FLOAT_MANTISA_DECIMAL_PRECISION + \
    TP_FLOAT_EXPONENT_DECIMAL_PRECISION)

#define TP_BIGINT_PRECISION       19
#define TP_BIGINT_SCALE           0
#define TP_BIGINT_AS_CHAR_LENGTH      20

#define TP_INTEGER_PRECISION          10
#define TP_INTEGER_AS_CHAR_LENGTH     11

#define TP_SMALLINT_PRECISION         5
#define TP_SMALLINT_AS_CHAR_LENGTH    6

#define TP_TIME_PRECISION         6
#define TP_TIME_AS_CHAR_LENGTH        11

#define TP_DATE_PRECISION         8
#define TP_DATE_AS_CHAR_LENGTH        10

#define TP_TIMESTAMP_PRECISION        14
#define TP_TIMESTAMP_AS_CHAR_LENGTH   22
#define TP_TIMESTAMPTZ_AS_CHAR_LENGTH   64

#define TP_DATETIME_PRECISION         17
#define TP_DATETIME_AS_CHAR_LENGTH    26
#define TP_DATETIMETZ_AS_CHAR_LENGTH    64

/* CHAR type and VARCHAR type are compatible with each other */
/* BIT type and VARBIT type are compatible with each other */
/* OID type and OBJECT type are compatible with each other */
/* Keys can come in with a type of DB_TYPE_OID, but the B+tree domain
   itself will always be a DB_TYPE_OBJECT. The comparison routines
   can handle OID and OBJECT as compatible type with each other . */
#define TP_ARE_COMPARABLE_KEY_TYPES(key1_type, key2_type) \
      (((key1_type) == (key2_type)) || \
      (((key1_type) == DB_TYPE_CHAR || (key1_type) == DB_TYPE_VARCHAR) && \
       ((key2_type) == DB_TYPE_CHAR || (key2_type) == DB_TYPE_VARCHAR)) || \
      (((key1_type) == DB_TYPE_BIT || (key1_type) == DB_TYPE_VARBIT) && \
       ((key2_type) == DB_TYPE_BIT || (key2_type) == DB_TYPE_VARBIT)) || \
      (((key1_type) == DB_TYPE_OID || (key1_type) == DB_TYPE_OBJECT) && \
       ((key2_type) == DB_TYPE_OID || (key2_type) == DB_TYPE_OBJECT)))

#define TP_DOMAIN_TYPE(dom) \
   ((dom) ? (dom)->type->id : DB_TYPE_NULL)

#define TP_TYPE_HAS_COLLATION(typeid) \
  (TP_IS_CHAR_TYPE(typeid) || (typeid) == DB_TYPE_ENUMERATION)

#define TP_DOMAIN_CODESET(dom) (((dom) ? (INTL_CODESET)(dom)->codeset : LANG_SYS_CODESET))
#define TP_DOMAIN_COLLATION(dom) \
    ((dom) ? (dom)->collation_id : LANG_SYS_COLLATION)
#define TP_DOMAIN_COLLATION_FLAG(dom) \
  ((dom) ? (dom)->collation_flag: TP_DOMAIN_COLL_NORMAL)

#define TP_TYPE_NOT_SUPPORT_COVERING(typeid) \
   ((typeid) == DB_TYPE_TIMESTAMPTZ || (typeid) == DB_TYPE_DATETIMETZ)


/*
 * FUNCTIONS
 */
#ifdef __cplusplus
extern "C"
{
#endif

/* called during workspace initialization */

  extern void tp_area_init (void);

/* Domain support functions */

  extern int tp_init (void);
  extern void tp_apply_sys_charset (void);
  extern void tp_final (void);
  extern TP_DOMAIN *tp_domain_resolve (DB_TYPE domain_type, DB_OBJECT * class_obj, int precision, int scale,
                       TP_DOMAIN * setdomain, int collation);
  extern TP_DOMAIN *tp_domain_resolve_default (DB_TYPE type);
  extern TP_DOMAIN *tp_domain_resolve_default_w_coll (DB_TYPE type, int coll_id, TP_DOMAIN_COLL_ACTION coll_flag);

  extern void tp_domain_init (TP_DOMAIN * domain, DB_TYPE type_id);
  extern void tp_domain_free (TP_DOMAIN * dom);
  extern TP_DOMAIN *tp_domain_new (DB_TYPE type);
  extern int tp_domain_copy_enumeration (DB_ENUMERATION * dest, const DB_ENUMERATION * src);
  extern TP_DOMAIN *tp_domain_copy (const TP_DOMAIN * dom, bool check_cache);
  extern TP_DOMAIN *tp_domain_construct (DB_TYPE domain_type, DB_OBJECT * class_obj, int precision, int scale,
                     TP_DOMAIN * setdomain);

  extern void tp_init_value_domain (TP_DOMAIN * domain, DB_VALUE * value);

  extern TP_DOMAIN *tp_domain_cache (TP_DOMAIN * domain);

  extern int tp_domain_add (TP_DOMAIN ** dlist, TP_DOMAIN * domain);

  extern int tp_domain_drop (TP_DOMAIN ** dlist, TP_DOMAIN * domain);

  extern int tp_domain_filter_list (TP_DOMAIN * dlist, int *list_changes);

  extern int tp_domain_size (const TP_DOMAIN * domain);

  extern int tp_setdomain_size (const TP_DOMAIN * domain);

  extern int tp_domain_match (const TP_DOMAIN * dom1, const TP_DOMAIN * dom2, TP_MATCH exact);
  extern int tp_domain_match_ignore_order (const TP_DOMAIN * dom1, const TP_DOMAIN * dom2, TP_MATCH exact);
  extern int tp_domain_compatible (const TP_DOMAIN * dom1, const TP_DOMAIN * dom2);

  extern TP_DOMAIN *tp_domain_select (const TP_DOMAIN * domain_list, const DB_VALUE * value, int allow_coercion,
                      TP_MATCH exact_match);

#if !defined (SERVER_MODE)
  extern TP_DOMAIN *tp_domain_select_type (const TP_DOMAIN * domain_list, DB_TYPE type, DB_OBJECT * class_mop,
                       int allow_coercion);
#endif

  extern TP_DOMAIN_STATUS tp_domain_check (const TP_DOMAIN * domain, const DB_VALUE * value, TP_MATCH exact_match);
  TP_DOMAIN *tp_domain_find_noparam (DB_TYPE type, bool is_desc);
  TP_DOMAIN *tp_domain_find_numeric (DB_TYPE type, int precision, int scale, bool is_desc);
  TP_DOMAIN *tp_domain_find_charbit (DB_TYPE type, int codeset, int collation_id, unsigned char collation_flag,
                     int precision, bool is_desc);
  TP_DOMAIN *tp_domain_find_object (DB_TYPE type, OID * class_oid, struct db_object *class_, bool is_desc);
  TP_DOMAIN *tp_domain_find_set (DB_TYPE type, TP_DOMAIN * setdomain, bool is_desc);
  TP_DOMAIN *tp_domain_find_enumeration (const DB_ENUMERATION * enumeration, bool is_desc);
  TP_DOMAIN *tp_domain_resolve_value (const DB_VALUE * val, TP_DOMAIN * dbuf);
#if defined(ENABLE_UNUSED_FUNCTION)
  TP_DOMAIN *tp_create_domain_resolve_value (DB_VALUE * val, TP_DOMAIN * domain);
#endif              /* ENABLE_UNUSED_FUNCTION */
  int tp_can_steal_string (const DB_VALUE * val, const DB_DOMAIN * desired_domain);
  bool tp_domain_references_objects (const TP_DOMAIN * dom);

  int tp_get_fixed_precision (DB_TYPE domain_type);

/* value functions */

  extern TP_DOMAIN_STATUS tp_value_coerce (const DB_VALUE * src, DB_VALUE * dest, const TP_DOMAIN * desired_domain);
  extern int tp_value_coerce_strict (const DB_VALUE * src, DB_VALUE * dest, const TP_DOMAIN * desired_domain);

  extern TP_DOMAIN_STATUS tp_value_cast (const DB_VALUE * src, DB_VALUE * dest, const TP_DOMAIN * desired_domain,
                     bool implicit_coercion);

  extern TP_DOMAIN_STATUS tp_value_cast_force (const DB_VALUE * src, DB_VALUE * dest,
                           const TP_DOMAIN * desired_domain, bool implicit_coercion);

  extern 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);

  extern 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_STATUS tp_value_change_coll_and_codeset (DB_VALUE * src, DB_VALUE * dest, int coll_id, int codeset);

  extern int tp_value_equal (const DB_VALUE * value1, const DB_VALUE * value2, int allow_coercion);

  extern int tp_more_general_type (const DB_TYPE type1, const DB_TYPE type2);

  extern DB_VALUE_COMPARE_RESULT tp_value_compare (const DB_VALUE * value1, const DB_VALUE * value2, int allow_coercion,
                           int total_order);

  extern DB_VALUE_COMPARE_RESULT tp_value_compare_with_error (const DB_VALUE * value1, const DB_VALUE * value2,
                                  int allow_coercion, int total_order, bool * can_compare);

  extern DB_VALUE_COMPARE_RESULT tp_set_compare (const DB_VALUE * value1, const DB_VALUE * value2, int allow_coercion,
                         int total_order);

/* printed representations */

  extern int tp_domain_name (const TP_DOMAIN * domain, char *buffer, int maxlen);
  extern int tp_value_domain_name (const DB_VALUE * value, char *buffer, int maxlen);

/* misc info */

  extern int tp_domain_disk_size (TP_DOMAIN * domain);
  extern int tp_domain_memory_size (TP_DOMAIN * domain);
  extern TP_DOMAIN_STATUS tp_check_value_size (TP_DOMAIN * domain, DB_VALUE * value);

  extern int tp_valid_indextype (DB_TYPE type);
#if defined(CUBRID_DEBUG)
  extern void tp_dump_domain (TP_DOMAIN * domain);
  extern void tp_domain_print (TP_DOMAIN * domain);
  extern void tp_domain_fprint (FILE * fp, TP_DOMAIN * domain);
#endif
  extern int tp_domain_attach (TP_DOMAIN ** dlist, TP_DOMAIN * domain);

  extern TP_DOMAIN_STATUS tp_value_auto_cast_with_precision_check (const DB_VALUE * src, DB_VALUE * dest,
                                   const TP_DOMAIN * desired_domain);
  extern TP_DOMAIN_STATUS tp_value_auto_cast (const DB_VALUE * src, DB_VALUE * dest, const TP_DOMAIN * desired_domain);
  extern int tp_value_str_auto_cast_to_number (DB_VALUE * src, DB_VALUE * dest, DB_TYPE * val_type);
  extern TP_DOMAIN *tp_infer_common_domain (TP_DOMAIN * arg1, TP_DOMAIN * arg2);
  extern int tp_value_string_to_double (const DB_VALUE * value, DB_VALUE * result);
  extern void tp_domain_clear_enumeration (DB_ENUMERATION * enumeration);
  extern int tp_enumeration_to_varchar (const DB_VALUE * src, DB_VALUE * result);
  extern 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);
#ifdef __cplusplus
}
#endif
#endif              /* _OBJECT_DOMAIN_H_ */