occupy fields on master for ob_gis_42x branch
This commit is contained in:
		
							
								
								
									
										21
									
								
								deps/oblib/src/common/object/ob_obj_type.h
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										21
									
								
								deps/oblib/src/common/object/ob_obj_type.h
									
									
									
									
										vendored
									
									
								
							@ -92,6 +92,7 @@ enum ObObjType
 | 
			
		||||
 | 
			
		||||
  ObUserDefinedSQLType = 49, // User defined type in SQL
 | 
			
		||||
  ObDecimalIntType     = 50, // decimal int type
 | 
			
		||||
  // ! occupy for ob_gis_42x: ObCollectionSQLType  = 51, // collection(varray and nested table) in SQL
 | 
			
		||||
  ObMaxType                 // invalid type, or count of obj type
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -125,6 +126,7 @@ enum ObObjOType
 | 
			
		||||
  ObOJsonType         = 24,
 | 
			
		||||
  ObOGeometryType     = 25,
 | 
			
		||||
  ObOUDTSqlType       = 26,
 | 
			
		||||
  // !occupy for ob_gis_42x: ObOCollectionSqlType  = 27,
 | 
			
		||||
  ObOMaxType          //invalid type, or count of ObObjOType
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -139,6 +141,16 @@ enum class ObGeoType
 | 
			
		||||
  MULTIPOLYGON = 6,
 | 
			
		||||
  GEOMETRYCOLLECTION = 7,
 | 
			
		||||
  GEOTYPEMAX = 31, // 5 bit for geometry type in column schema,set max 31
 | 
			
		||||
  // 3d geotype is not supported to define as subtype yet,
 | 
			
		||||
  // only use for inner type
 | 
			
		||||
  POINTZ = 1001,
 | 
			
		||||
  LINESTRINGZ = 1002,
 | 
			
		||||
  POLYGONZ = 1003,
 | 
			
		||||
  MULTIPOINTZ = 1004,
 | 
			
		||||
  MULTILINESTRINGZ = 1005,
 | 
			
		||||
  MULTIPOLYGONZ = 1006,
 | 
			
		||||
  GEOMETRYCOLLECTIONZ = 1007,
 | 
			
		||||
  GEO3DTYPEMAX = 1024,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//for cast/cmp map
 | 
			
		||||
@ -233,6 +245,7 @@ enum ObObjTypeClass
 | 
			
		||||
  ObGeometryTC      = 23, // geometry type class
 | 
			
		||||
  ObUserDefinedSQLTC = 24, // user defined type class in SQL
 | 
			
		||||
  ObDecimalIntTC     = 25, // decimal int class
 | 
			
		||||
  // ! occupy for ob_gis_42x: ObCollectionSQLTC = 26, // collection type class in SQL
 | 
			
		||||
  ObMaxTC,
 | 
			
		||||
  // invalid type classes are below, only used as the result of XXXX_type_promotion()
 | 
			
		||||
  // to indicate that the two obj can't be promoted to the same type.
 | 
			
		||||
@ -1073,14 +1086,20 @@ enum ObExtObjType
 | 
			
		||||
 | 
			
		||||
enum ObUDTType
 | 
			
		||||
{
 | 
			
		||||
  T_OBJ_NOT_SUPPORTED = 0,
 | 
			
		||||
  T_OBJ_XML = 300001,
 | 
			
		||||
  T_OBJ_SDO_POINT = 300027,
 | 
			
		||||
  T_OBJ_SDO_GEOMETRY = 300028,
 | 
			
		||||
  T_OBJ_SDO_ELEMINFO_ARRAY = 300029,
 | 
			
		||||
  T_OBJ_SDO_ORDINATE_ARRAY = 300030,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// reserved sub schema id for system defined types
 | 
			
		||||
enum ObSystemUDTSqlType
 | 
			
		||||
{
 | 
			
		||||
  ObXMLSqlType = 0,
 | 
			
		||||
  ObMaxSystemUDTSqlType = 16
 | 
			
		||||
  ObMaxSystemUDTSqlType = 16, // used not supported cases;
 | 
			
		||||
  ObInvalidSqlType = 17 // only used when subschema id not set, like the creation of col ref rawexpr
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
OB_INLINE bool is_valid_obj_type(const ObObjType type)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										1
									
								
								deps/oblib/src/lib/CMakeLists.txt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								deps/oblib/src/lib/CMakeLists.txt
									
									
									
									
										vendored
									
									
								
							@ -174,6 +174,7 @@ ob_set_subtarget(oblib_lib common_mixed
 | 
			
		||||
  wide_integer/ob_wide_integer.cpp
 | 
			
		||||
  wide_integer/ob_wide_integer_cmp_funcs.cpp
 | 
			
		||||
  wide_integer/ob_wide_integer_str_funcs.cpp
 | 
			
		||||
  udt/ob_udt_type.cpp
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
ob_set_subtarget(oblib_lib lock
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										5
									
								
								deps/oblib/src/lib/ob_errno.h
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								deps/oblib/src/lib/ob_errno.h
									
									
									
									
										vendored
									
									
								
							@ -364,6 +364,11 @@ constexpr int OB_ERR_INVALID_OPTION_KEY = -7286;
 | 
			
		||||
constexpr int OB_ERR_INVALID_OPTION_VALUE = -7287;
 | 
			
		||||
constexpr int OB_ERR_INVALID_GEOMETRY_TYPE = -7288;
 | 
			
		||||
constexpr int OB_ERR_FTS_MUST_HAVE_TEXT_COL = -7289;
 | 
			
		||||
constexpr int OB_ERR_INVALID_GTYPE_IN_SDO_GEROMETRY = -7291;
 | 
			
		||||
constexpr int OB_ERR_INVALID_NULL_SDO_GEOMETRY = -7294;
 | 
			
		||||
constexpr int OB_ERR_INVALID_DATA_IN_SDO_ELEM_INFO_ARRAY = -7295;
 | 
			
		||||
constexpr int OB_ERR_INVALID_DATA_IN_SDO_ORDINATE_ARRAY = -7296;
 | 
			
		||||
constexpr int OB_ERR_VALUE_NOT_ALLOWED = -7297;
 | 
			
		||||
constexpr int OB_ERR_DUP_DEF_NAMESPACE = -7420;
 | 
			
		||||
constexpr int OB_ERR_PARSE_XQUERY_EXPR = -7422;
 | 
			
		||||
constexpr int OB_ERR_TOO_MANY_PREFIX_DECLARE = -7424;
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										393
									
								
								deps/oblib/src/lib/udt/ob_udt_type.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										393
									
								
								deps/oblib/src/lib/udt/ob_udt_type.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,393 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright (c) 2021 OceanBase
 | 
			
		||||
 * OceanBase CE is licensed under Mulan PubL v2.
 | 
			
		||||
 * You can use this software according to the terms and conditions of the Mulan PubL v2.
 | 
			
		||||
 * You may obtain a copy of Mulan PubL v2 at:
 | 
			
		||||
 *          http://license.coscl.org.cn/MulanPubL-2.0
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 | 
			
		||||
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 | 
			
		||||
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 | 
			
		||||
 * See the Mulan PubL v2 for more details.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#define USING_LOG_PREFIX LIB
 | 
			
		||||
#include "ob_udt_type.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
namespace oceanbase {
 | 
			
		||||
namespace common {
 | 
			
		||||
 | 
			
		||||
int ObSqlUDT::init_null_bitmap()
 | 
			
		||||
{
 | 
			
		||||
  int ret = OB_SUCCESS;
 | 
			
		||||
  uint32_t offset = get_null_bitmap_len(udt_meta_.attribute_cnt_);
 | 
			
		||||
  uint32_t data_offset = offset + sizeof(int32_t) * udt_meta_.attribute_cnt_;
 | 
			
		||||
  MEMSET(udt_data_.ptr(), 0, data_offset);
 | 
			
		||||
  udt_data_.set_length(data_offset);
 | 
			
		||||
  if (OB_FAIL(set_attribute_offset(0, data_offset))) {
 | 
			
		||||
    LOG_WARN("update attribute offset failed", K(ret), K(udt_meta_.attribute_cnt_), K(offset));
 | 
			
		||||
  }
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int ObSqlUDT::access_attribute(uint32_t index, ObString &attr_value, bool is_varray_element)
 | 
			
		||||
{
 | 
			
		||||
  int ret = OB_SUCCESS;
 | 
			
		||||
  uint32_t attribute_cnt = 0;
 | 
			
		||||
  if (udt_data_.empty()) {
 | 
			
		||||
    ret = OB_ERR_UNEXPECTED;
 | 
			
		||||
    LOG_WARN("udt data is null", K(ret), K(index));
 | 
			
		||||
  } else if (FALSE_IT(attribute_cnt = is_varray_element ? get_varray_element_count() : udt_meta_.attribute_cnt_)) {
 | 
			
		||||
  } else if (FALSE_IT(attribute_cnt += (!is_varray_element) ? 1 : 0)) {
 | 
			
		||||
  } else if (index >= attribute_cnt) {
 | 
			
		||||
    ret = OB_ERR_UNEXPECTED;
 | 
			
		||||
    LOG_WARN("invalid attribute index", K(ret), K(index), K(attribute_cnt));
 | 
			
		||||
  } else {
 | 
			
		||||
    uint32_t null_bitmap_offset = get_null_bitmap_len(attribute_cnt);
 | 
			
		||||
    int32_t offset = get_attr_offset(index, null_bitmap_offset, is_varray_element);
 | 
			
		||||
    uint32_t attr_len = 0;
 | 
			
		||||
    if (offset > udt_data_.length()) {
 | 
			
		||||
      ret = OB_ERR_UNEXPECTED;
 | 
			
		||||
      LOG_WARN("invalid udt data", K(ret), K(index), K(udt_data_.length()), K(offset), K(attribute_cnt));
 | 
			
		||||
    } else if (index == (attribute_cnt - 1)) {
 | 
			
		||||
      // last attribute
 | 
			
		||||
      attr_len = udt_data_.length() -  offset;
 | 
			
		||||
    } else {
 | 
			
		||||
      int32_t next_offset = get_attr_offset(index + 1, null_bitmap_offset, is_varray_element);
 | 
			
		||||
      if (next_offset > udt_data_.length() || next_offset < offset) {
 | 
			
		||||
        ret = OB_ERR_UNEXPECTED;
 | 
			
		||||
        LOG_WARN("invalid udt data", K(ret), K(index), K(udt_data_.length()), K(offset), K(next_offset), K(attribute_cnt));
 | 
			
		||||
      } else {
 | 
			
		||||
        attr_len = next_offset - offset;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (OB_FAIL(ret)) {
 | 
			
		||||
    } else if (attr_len == 0) {
 | 
			
		||||
      attr_value.reset();
 | 
			
		||||
    } else if (offset + attr_len > udt_data_.length()) {
 | 
			
		||||
      ret = OB_ERR_UNEXPECTED;
 | 
			
		||||
      LOG_WARN("udt attribute is out range", K(ret), K(index), K(attribute_cnt), K(attr_len), K(offset), K(udt_data_.length()));
 | 
			
		||||
    } else {
 | 
			
		||||
      attr_value.assign_ptr(udt_data_.ptr() + offset, attr_len);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t ObSqlUDT::get_offset_array_len(uint32_t count)
 | 
			
		||||
{
 | 
			
		||||
  uint32_t len = count * sizeof(uint32_t); // offset is 4bytes currently
 | 
			
		||||
  return len;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t ObSqlUDT::get_varray_element_count()
 | 
			
		||||
{
 | 
			
		||||
  uint32_t length = 0;
 | 
			
		||||
  if (udt_data_.empty() || udt_data_.length() < sizeof(uint32_t)) {
 | 
			
		||||
  } else {
 | 
			
		||||
    length = *(reinterpret_cast<uint32_t *>(udt_data_.ptr()));
 | 
			
		||||
  }
 | 
			
		||||
  return length;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int ObSqlUDT::set_null_bitmap_pos(char *bitmap_start, uint32_t bitmap_len, uint32_t pos)
 | 
			
		||||
{
 | 
			
		||||
  // remove ?
 | 
			
		||||
  int ret = OB_SUCCESS;
 | 
			
		||||
  uint32 index = pos / 8;
 | 
			
		||||
  uint32 byte_index = pos % 8;
 | 
			
		||||
  if (index >= bitmap_len) {
 | 
			
		||||
    ret = OB_ERR_UNEXPECTED;
 | 
			
		||||
    LOG_WARN("udt bitmap overflow", K(ret), K(index), K(bitmap_len), K(pos));
 | 
			
		||||
  } else {
 | 
			
		||||
    bitmap_start[index] |= (1 << byte_index);
 | 
			
		||||
  }
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int ObSqlUDT::append_attribute(uint32_t index, const ObString &attr_value)
 | 
			
		||||
{
 | 
			
		||||
  int ret = OB_SUCCESS;
 | 
			
		||||
  if (index >= udt_meta_.attribute_cnt_) {
 | 
			
		||||
    ret = OB_ERR_UNEXPECTED;
 | 
			
		||||
    LOG_WARN("invalid attribute index", K(ret), K(index), K(udt_meta_.attribute_cnt_));
 | 
			
		||||
  } else if (udt_data_.empty()) {
 | 
			
		||||
    ret = OB_ERR_UNEXPECTED;
 | 
			
		||||
    LOG_WARN("udt data is null", K(ret), K(index), K(udt_meta_.attribute_cnt_));
 | 
			
		||||
  } else if (OB_FAIL(set_null_bitmap(index, attr_value.empty()))) {
 | 
			
		||||
    LOG_WARN("set null bitmap failed", K(ret), K(index));
 | 
			
		||||
  } else {
 | 
			
		||||
    uint32_t null_bitmap_offset = get_null_bitmap_len(udt_meta_.attribute_cnt_);
 | 
			
		||||
    int32_t offset = get_attr_offset(index, null_bitmap_offset);
 | 
			
		||||
    uint32_t attr_len = attr_value.length();
 | 
			
		||||
    if (offset != udt_data_.length()) {
 | 
			
		||||
      ret = OB_ERR_UNEXPECTED;
 | 
			
		||||
      LOG_WARN("append udt attribute failed", K(ret), K(index), K(udt_meta_.attribute_cnt_),
 | 
			
		||||
                                              K(attr_len), K(offset), K(udt_data_.length()),
 | 
			
		||||
                                              K(udt_data_.size()));
 | 
			
		||||
    } else if (offset + attr_len > udt_data_.size()) {
 | 
			
		||||
      ret = OB_ERR_UNEXPECTED;
 | 
			
		||||
      LOG_WARN("udt attribute is out range", K(ret), K(index), K(udt_meta_.attribute_cnt_),
 | 
			
		||||
                                              K(attr_len), K(offset), K(udt_data_.length()),
 | 
			
		||||
                                              K(udt_data_.size()));
 | 
			
		||||
    } else {
 | 
			
		||||
      udt_data_.write(attr_value.ptr(), attr_len);
 | 
			
		||||
      if (index < udt_meta_.attribute_cnt_ - 1) {
 | 
			
		||||
        set_attribute_offset(index + 1, offset + attr_len);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int ObSqlUDT::get_null_bitmap_pos(const char *bitmap_start, uint32_t bitmap_len, uint32_t pos, bool &is_set)
 | 
			
		||||
{
 | 
			
		||||
  int ret = OB_SUCCESS;
 | 
			
		||||
  is_set = false;
 | 
			
		||||
  uint32 index = pos / 8;
 | 
			
		||||
  uint32 byte_pos = pos % 8;
 | 
			
		||||
  if (index >= bitmap_len) {
 | 
			
		||||
    ret = OB_ERR_UNEXPECTED;
 | 
			
		||||
    LOG_WARN("udt bitmap overflow", K(ret), K(index), K(bitmap_len), K(pos));
 | 
			
		||||
  } else {
 | 
			
		||||
    is_set = bitmap_start[index] & (1 << pos);
 | 
			
		||||
  }
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int ObSqlUDT::set_attribute_offset(uint32_t index, int32_t offset)
 | 
			
		||||
{
 | 
			
		||||
  int ret = OB_SUCCESS;
 | 
			
		||||
  uint32_t null_bitmap_offset = get_null_bitmap_len(udt_meta_.attribute_cnt_);
 | 
			
		||||
  uint32_t pos = null_bitmap_offset + (sizeof(int32_t) * index);
 | 
			
		||||
  if (pos >= udt_data_.length()) {
 | 
			
		||||
    ret = OB_ERR_UNEXPECTED;
 | 
			
		||||
    LOG_WARN("udt attribute is out range", K(ret), K(index), K(null_bitmap_offset), K(offset), K(udt_data_.length()));
 | 
			
		||||
  } else {
 | 
			
		||||
    reinterpret_cast<int32_t *>(udt_data_.ptr() + null_bitmap_offset)[index] = offset;
 | 
			
		||||
  }
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int ObSqlUDT::set_null_bitmap(uint32_t index, bool is_null)
 | 
			
		||||
{
 | 
			
		||||
  int ret = OB_SUCCESS;
 | 
			
		||||
  uint32_t null_bitmap_len = get_null_bitmap_len(udt_meta_.attribute_cnt_);
 | 
			
		||||
  uint32_t byte_pos = static_cast<uint32_t>((index) / 8);
 | 
			
		||||
  uint32_t bit_pos  = static_cast<uint32_t>((index) % 8);
 | 
			
		||||
  if (byte_pos >= null_bitmap_len) {
 | 
			
		||||
    ret = OB_ERR_UNEXPECTED;
 | 
			
		||||
    LOG_WARN("udt null bitmap is out range", K(ret), K(index), K(udt_meta_.attribute_cnt_), K(null_bitmap_len));
 | 
			
		||||
  } else if (udt_data_.empty()) {
 | 
			
		||||
    ret = OB_ERR_UNEXPECTED;
 | 
			
		||||
    LOG_WARN("udt data is null", K(ret), K(index), K(udt_meta_.attribute_cnt_));
 | 
			
		||||
  } else {
 | 
			
		||||
    char *bitmap = udt_data_.ptr();
 | 
			
		||||
    if (is_null) {
 | 
			
		||||
      bitmap[byte_pos] |= static_cast<char>(1 << bit_pos);
 | 
			
		||||
    } else {
 | 
			
		||||
      bitmap[byte_pos] &= ~static_cast<char>(1 << bit_pos);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// implement udt meta serialization
 | 
			
		||||
// Notice: no deep copy in ObSqlUDTMeta serialzie/desrialize,
 | 
			
		||||
// deep copy is done when subschema mapping serialzie/desriazlied
 | 
			
		||||
int ObSqlUDTMeta::deep_copy(ObIAllocator &allocator, ObSqlUDTMeta *&dst) const
 | 
			
		||||
{
 | 
			
		||||
  int ret = OB_SUCCESS;
 | 
			
		||||
  ObSqlUDTMeta *new_udt_meta = NULL;
 | 
			
		||||
  ObSqlUDTAttrMeta *copy_child_attrs_meta = NULL;
 | 
			
		||||
  ObSqlUDTAttrMeta *copy_leaf_attrs_meta = NULL;
 | 
			
		||||
  char *copy_udt_name = NULL;
 | 
			
		||||
 | 
			
		||||
  new_udt_meta = reinterpret_cast<ObSqlUDTMeta *>(allocator.alloc(sizeof(ObSqlUDTMeta)));
 | 
			
		||||
  if (OB_ISNULL(new_udt_meta)) {
 | 
			
		||||
    ret = OB_ALLOCATE_MEMORY_FAILED;
 | 
			
		||||
    LOG_WARN("failed to allocate memory", K(ret), K(sizeof(ObSqlUDTMeta)));
 | 
			
		||||
  } else {
 | 
			
		||||
    *new_udt_meta = *this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (OB_FAIL(ret)) { // memory free when allocator reset/destory
 | 
			
		||||
  } else if (udt_name_len_ == 0) {
 | 
			
		||||
    ret = OB_ERR_UNEXPECTED;
 | 
			
		||||
    LOG_WARN("copy udt meta without name", K(ret), K(*this));
 | 
			
		||||
  } else if (FALSE_IT(copy_udt_name = reinterpret_cast<char *>(allocator.alloc(udt_name_len_)))) {
 | 
			
		||||
  } else if (OB_ISNULL(copy_udt_name)) {
 | 
			
		||||
    ret = OB_ALLOCATE_MEMORY_FAILED;
 | 
			
		||||
    LOG_WARN("failed to allocate memory for udt name", K(ret), K(udt_name_len_));
 | 
			
		||||
  } else {
 | 
			
		||||
    MEMCPY(copy_udt_name, udt_name_, udt_name_len_);
 | 
			
		||||
    new_udt_meta->udt_name_ = copy_udt_name;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  uint32_t child_attrs_size = sizeof(ObSqlUDTAttrMeta) * child_attr_cnt_;
 | 
			
		||||
  if (OB_FAIL(ret)) {
 | 
			
		||||
  } else if (child_attr_cnt_ == 0) {
 | 
			
		||||
    new_udt_meta->child_attrs_meta_ = NULL;
 | 
			
		||||
  } else if (FALSE_IT(copy_child_attrs_meta = reinterpret_cast<ObSqlUDTAttrMeta *>(
 | 
			
		||||
                                                  allocator.alloc(child_attrs_size)))) {
 | 
			
		||||
  } else if (OB_ISNULL(copy_child_attrs_meta)) {
 | 
			
		||||
    ret = OB_ALLOCATE_MEMORY_FAILED;
 | 
			
		||||
    LOG_WARN("failed to allocate memory for child attrs", K(ret), K(child_attrs_size));
 | 
			
		||||
  } else {
 | 
			
		||||
    MEMCPY(copy_child_attrs_meta, child_attrs_meta_, child_attrs_size);
 | 
			
		||||
    new_udt_meta->child_attrs_meta_ = copy_child_attrs_meta;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  uint32_t leaf_attrs_size = sizeof(ObSqlUDTAttrMeta) * leaf_attr_cnt_;
 | 
			
		||||
  if (OB_FAIL(ret)) {
 | 
			
		||||
  } else if (leaf_attr_cnt_ == 0) {
 | 
			
		||||
    new_udt_meta->leaf_attrs_meta_ = NULL;
 | 
			
		||||
  } else if (FALSE_IT(copy_leaf_attrs_meta = reinterpret_cast<ObSqlUDTAttrMeta *>(
 | 
			
		||||
                                                  allocator.alloc(leaf_attrs_size)))) {
 | 
			
		||||
  } else if (OB_ISNULL(copy_leaf_attrs_meta)) {
 | 
			
		||||
    ret = OB_ALLOCATE_MEMORY_FAILED;
 | 
			
		||||
    LOG_WARN("failed to allocate memory for leaf attrs", K(ret), K(leaf_attrs_size));
 | 
			
		||||
  } else {
 | 
			
		||||
    MEMCPY(copy_leaf_attrs_meta, leaf_attrs_meta_, leaf_attrs_size);
 | 
			
		||||
    new_udt_meta->leaf_attrs_meta_ = copy_leaf_attrs_meta;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (OB_SUCC(ret)) {
 | 
			
		||||
    dst = new_udt_meta;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
OB_DEF_SERIALIZE(ObSqlUDTMeta)
 | 
			
		||||
{
 | 
			
		||||
  int ret = OB_SUCCESS;
 | 
			
		||||
  LST_DO_CODE(OB_UNIS_ENCODE,
 | 
			
		||||
              attribute_cnt_,
 | 
			
		||||
              fixed_attr_cnt_,
 | 
			
		||||
              fixed_offset_,
 | 
			
		||||
              pl_type_,
 | 
			
		||||
              udt_id_,
 | 
			
		||||
              child_attr_cnt_,
 | 
			
		||||
              leaf_attr_cnt_,
 | 
			
		||||
              nested_udt_number_,
 | 
			
		||||
              varray_capacity_,
 | 
			
		||||
              udt_name_len_);
 | 
			
		||||
  if (OB_FAIL(ret)) {
 | 
			
		||||
  } else if (udt_name_len_ <= 0 || OB_ISNULL(udt_name_)) {
 | 
			
		||||
    ret = OB_ERR_UNEXPECTED;
 | 
			
		||||
    LOG_WARN("invalid udt name length for serialize", K(ret), K(*this));
 | 
			
		||||
  } else {
 | 
			
		||||
    MEMCPY(buf + pos, udt_name_, udt_name_len_);
 | 
			
		||||
    pos += udt_name_len_;
 | 
			
		||||
  }
 | 
			
		||||
  if (OB_SUCC(ret)) {
 | 
			
		||||
    if (child_attr_cnt_ > 0) {
 | 
			
		||||
      MEMCPY(buf + pos, reinterpret_cast<char *>(child_attrs_meta_), sizeof(ObSqlUDTAttrMeta) * child_attr_cnt_);
 | 
			
		||||
      pos += sizeof(ObSqlUDTAttrMeta) * child_attr_cnt_;
 | 
			
		||||
    }
 | 
			
		||||
    if (leaf_attr_cnt_ > 0) {
 | 
			
		||||
      MEMCPY(buf + pos, reinterpret_cast<char *>(leaf_attrs_meta_), sizeof(ObSqlUDTAttrMeta) * leaf_attr_cnt_);
 | 
			
		||||
      pos += sizeof(ObSqlUDTAttrMeta) * leaf_attr_cnt_;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
OB_DEF_DESERIALIZE(ObSqlUDTMeta)
 | 
			
		||||
{
 | 
			
		||||
  int ret = OB_SUCCESS;
 | 
			
		||||
  LST_DO_CODE(OB_UNIS_DECODE,
 | 
			
		||||
              attribute_cnt_,
 | 
			
		||||
              fixed_attr_cnt_,
 | 
			
		||||
              fixed_offset_,
 | 
			
		||||
              pl_type_,
 | 
			
		||||
              udt_id_,
 | 
			
		||||
              child_attr_cnt_,
 | 
			
		||||
              leaf_attr_cnt_,
 | 
			
		||||
              nested_udt_number_,
 | 
			
		||||
              varray_capacity_,
 | 
			
		||||
              udt_name_len_);
 | 
			
		||||
  if (OB_FAIL(ret)) {
 | 
			
		||||
  } else if (udt_name_len_ <= 0 || pos >= data_len) {
 | 
			
		||||
    ret = OB_DESERIALIZE_ERROR;
 | 
			
		||||
    LOG_WARN("invalid udt name length for deseriazlie", K(ret), K(*this), K(pos), K(data_len));
 | 
			
		||||
  } else {
 | 
			
		||||
    udt_name_ = buf + pos;
 | 
			
		||||
    pos += udt_name_len_;
 | 
			
		||||
  }
 | 
			
		||||
  // need copy data after deserialize, since metas are from buffer
 | 
			
		||||
  int64_t child_attrs_length = sizeof(ObSqlUDTAttrMeta) * child_attr_cnt_;
 | 
			
		||||
  int64_t leaf_attrs_length = sizeof(ObSqlUDTAttrMeta) * leaf_attr_cnt_;
 | 
			
		||||
  if (OB_FAIL(ret)) {
 | 
			
		||||
  } else if (child_attr_cnt_ == 0) { // no child attrs
 | 
			
		||||
  } else if (child_attr_cnt_ < 0 || pos + child_attrs_length > data_len) {
 | 
			
		||||
    ret = OB_DESERIALIZE_ERROR;
 | 
			
		||||
    LOG_WARN("invalid udt child attrs for deseriazlie", K(ret), K(*this), K(pos), K(data_len));
 | 
			
		||||
  } else {
 | 
			
		||||
    child_attrs_meta_ = reinterpret_cast<ObSqlUDTAttrMeta *>(const_cast<char *>(buf + pos));
 | 
			
		||||
    pos += child_attrs_length;
 | 
			
		||||
  }
 | 
			
		||||
  if (OB_FAIL(ret)) {
 | 
			
		||||
  } else if (leaf_attr_cnt_ == 0) { // no leaf attrs
 | 
			
		||||
  } else if (leaf_attr_cnt_ < 0 && pos + leaf_attrs_length > data_len) {
 | 
			
		||||
    ret = OB_DESERIALIZE_ERROR;
 | 
			
		||||
    LOG_WARN("invalid udt child attrs for deseriazlie", K(ret), K(*this), K(pos), K(data_len));
 | 
			
		||||
  } else {
 | 
			
		||||
    leaf_attrs_meta_ = reinterpret_cast<ObSqlUDTAttrMeta *>(const_cast<char *>(buf + pos));
 | 
			
		||||
    pos += leaf_attrs_length;
 | 
			
		||||
  }
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// serialize size cannot return error code
 | 
			
		||||
OB_DEF_SERIALIZE_SIZE(ObSqlUDTMeta)
 | 
			
		||||
{
 | 
			
		||||
  int64_t len = 0;
 | 
			
		||||
  LST_DO_CODE(OB_UNIS_ADD_LEN,
 | 
			
		||||
              attribute_cnt_,
 | 
			
		||||
              fixed_attr_cnt_,
 | 
			
		||||
              fixed_offset_,
 | 
			
		||||
              pl_type_,
 | 
			
		||||
              udt_id_,
 | 
			
		||||
              child_attr_cnt_,
 | 
			
		||||
              leaf_attr_cnt_,
 | 
			
		||||
              nested_udt_number_,
 | 
			
		||||
              varray_capacity_,
 | 
			
		||||
              udt_name_len_);
 | 
			
		||||
  len += udt_name_len_;
 | 
			
		||||
  len += sizeof(ObSqlUDTAttrMeta) * child_attr_cnt_;
 | 
			
		||||
  len += sizeof(ObSqlUDTAttrMeta) * leaf_attr_cnt_;
 | 
			
		||||
  return len;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int ob_get_reserved_udt_meta(uint16_t subschema_id, ObSqlUDTMeta &udt_meta)
 | 
			
		||||
{
 | 
			
		||||
  int ret = OB_SUCCESS;
 | 
			
		||||
  if (subschema_id == ObXMLSqlType) {
 | 
			
		||||
    udt_meta.reset();
 | 
			
		||||
    udt_meta.udt_id_ = T_OBJ_XML;
 | 
			
		||||
    udt_meta.udt_name_ = "XMLTYPE";
 | 
			
		||||
    udt_meta.udt_name_len_ = strlen("XMLTYPE");
 | 
			
		||||
  } else {
 | 
			
		||||
    ret = OB_NOT_SUPPORTED;
 | 
			
		||||
    LOG_WARN("unsupported reserved subschema id", K(ret), K(subschema_id));
 | 
			
		||||
  }
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int ob_get_reserved_subschema(uint64_t udt_id, uint16_t &subschema_id)
 | 
			
		||||
{
 | 
			
		||||
  int ret = OB_SUCCESS;
 | 
			
		||||
  if (udt_id == T_OBJ_XML) {
 | 
			
		||||
    subschema_id = ObXMLSqlType;
 | 
			
		||||
  } else {
 | 
			
		||||
    ret = OB_NOT_SUPPORTED;
 | 
			
		||||
    LOG_WARN("unsupported udt id", K(ret), K(udt_id));
 | 
			
		||||
  }
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace common
 | 
			
		||||
} // namespace oceanbase
 | 
			
		||||
							
								
								
									
										227
									
								
								deps/oblib/src/lib/udt/ob_udt_type.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										227
									
								
								deps/oblib/src/lib/udt/ob_udt_type.h
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,227 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright (c) 2021 OceanBase
 | 
			
		||||
 * OceanBase CE is licensed under Mulan PubL v2.
 | 
			
		||||
 * You can use this software according to the terms and conditions of the Mulan PubL v2.
 | 
			
		||||
 * You may obtain a copy of Mulan PubL v2 at:
 | 
			
		||||
 *          http://license.coscl.org.cn/MulanPubL-2.0
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 | 
			
		||||
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 | 
			
		||||
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 | 
			
		||||
 * See the Mulan PubL v2 for more details.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef OCEANBASE_OB_SQL_UDT_TYPE_
 | 
			
		||||
#define OCEANBASE_OB_SQL_UDT_TYPE_
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include "common/object/ob_object.h"
 | 
			
		||||
#include "lib/string/ob_string.h"
 | 
			
		||||
#include "lib/oblog/ob_log_module.h"
 | 
			
		||||
#include "common/ob_field.h"
 | 
			
		||||
 | 
			
		||||
namespace oceanbase {
 | 
			
		||||
namespace common {
 | 
			
		||||
 | 
			
		||||
// build udt meta from ObUDTTypeInfo (flatten_leaf_attrs_meta)
 | 
			
		||||
//   1. get all dependent udt schema recursively to build a flattern ObSqlUDTAttrMeta array, assing order sequentially
 | 
			
		||||
//   2. sort array built in 1 by type and length order (fix len), by type only (var len)
 | 
			
		||||
// encoding from pl extend to sql udt
 | 
			
		||||
//   1 build an leaf object point array, in define order, from pl extend
 | 
			
		||||
//   2 use order in flatten_leaf_attrs_meta to mapping to a new leaf object
 | 
			
		||||
//   3 encoding new object point array in 2 sequentially
 | 
			
		||||
// decoding from sql udt to pl extend (need schema guard?)
 | 
			
		||||
//   1 build an leaf object point array, in sorted order, from sql udt
 | 
			
		||||
//   2 use order in flatten_leaf_attrs_meta to remapping to a new leaf object
 | 
			
		||||
//   3 use toplevel_attrs_meta? to build pl extend (looks like a constructor)
 | 
			
		||||
// sql udt to string
 | 
			
		||||
//   1 same as from sql udt to pl extend
 | 
			
		||||
//   2 use root ObSqlUDTMeta to print udt name, to_string top level elements recursively (toplevel_attrs_meta)
 | 
			
		||||
 | 
			
		||||
const uint32_t nested_udt_bitmap_index = 0; // the first attribute in sql udt is always nest udt bitmap
 | 
			
		||||
 | 
			
		||||
typedef struct ObSqlUDTAttrMeta
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
  int32_t order_; // only used in flattern leaf attrs meta;
 | 
			
		||||
  ObObjMeta type_info_;
 | 
			
		||||
  // may need udt id ?
 | 
			
		||||
  bool is_same(ObSqlUDTAttrMeta &other) {
 | 
			
		||||
    bool is_same = (order_ == other.order_);
 | 
			
		||||
    if (is_same) {
 | 
			
		||||
      if ((type_info_.is_user_defined_sql_type()
 | 
			
		||||
      // || type_info_.is_collection_sql_type()
 | 
			
		||||
      )) {
 | 
			
		||||
        is_same = (type_info_.get_type() == other.type_info_.get_type()
 | 
			
		||||
                   && type_info_.get_scale() == other.type_info_.get_scale());
 | 
			
		||||
      } else {
 | 
			
		||||
        is_same = (type_info_ == other.type_info_);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return is_same;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  TO_STRING_KV(K_(order), K_(type_info));
 | 
			
		||||
} ObSqlUDTAttrMeta;
 | 
			
		||||
 | 
			
		||||
typedef struct ObSqlUDTMeta
 | 
			
		||||
{
 | 
			
		||||
  OB_UNIS_VERSION(1);
 | 
			
		||||
public:
 | 
			
		||||
  void set_name(ObString &name)
 | 
			
		||||
  {
 | 
			
		||||
    udt_name_ = name.ptr();
 | 
			
		||||
    udt_name_len_ = name.length();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool is_same(const ObSqlUDTMeta &other) // test only remove later
 | 
			
		||||
  {
 | 
			
		||||
    bool is_same = (attribute_cnt_ == other.attribute_cnt_
 | 
			
		||||
                    && fixed_attr_cnt_ == other.fixed_attr_cnt_
 | 
			
		||||
                    && fixed_offset_ == other.fixed_offset_
 | 
			
		||||
                    && pl_type_ == other.pl_type_
 | 
			
		||||
                    && udt_id_ == other.udt_id_
 | 
			
		||||
                    && child_attr_cnt_ == other.child_attr_cnt_
 | 
			
		||||
                    && leaf_attr_cnt_ == other.leaf_attr_cnt_
 | 
			
		||||
                    && udt_name_len_ == other.udt_name_len_
 | 
			
		||||
                    && strncmp(udt_name_, other.udt_name_, udt_name_len_) == 0
 | 
			
		||||
                    && nested_udt_number_ == other.nested_udt_number_
 | 
			
		||||
                    && varray_capacity_ == other.varray_capacity_);
 | 
			
		||||
    if (is_same) {
 | 
			
		||||
      for (int32_t i = 0; is_same && i < child_attr_cnt_; i++) {
 | 
			
		||||
        is_same = child_attrs_meta_[i].is_same(other.child_attrs_meta_[i]);
 | 
			
		||||
      }
 | 
			
		||||
      for (int32_t i = 0; is_same && i < leaf_attr_cnt_; i++) {
 | 
			
		||||
        is_same = leaf_attrs_meta_[i].is_same(other.leaf_attrs_meta_[i]);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return is_same;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void reset()
 | 
			
		||||
  {
 | 
			
		||||
    attribute_cnt_ = 0;
 | 
			
		||||
    fixed_attr_cnt_ = 0;
 | 
			
		||||
    fixed_offset_ = 0;
 | 
			
		||||
    pl_type_ = 0;
 | 
			
		||||
    udt_id_ = 0;
 | 
			
		||||
    child_attr_cnt_ = 0;
 | 
			
		||||
    leaf_attr_cnt_ = 0;
 | 
			
		||||
    udt_name_len_ = 0;
 | 
			
		||||
    udt_name_ = NULL;
 | 
			
		||||
    nested_udt_number_ = 0;
 | 
			
		||||
    varray_capacity_ = 0;
 | 
			
		||||
    child_attrs_meta_ = NULL;
 | 
			
		||||
    leaf_attrs_meta_ = NULL;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  int deep_copy(ObIAllocator &allocator, ObSqlUDTMeta *&dst) const;
 | 
			
		||||
 | 
			
		||||
  TO_STRING_KV(K_(attribute_cnt),
 | 
			
		||||
               K_(fixed_attr_cnt),
 | 
			
		||||
               K_(fixed_offset),
 | 
			
		||||
               K_(pl_type),
 | 
			
		||||
               K_(udt_id),
 | 
			
		||||
               K_(child_attr_cnt),
 | 
			
		||||
               K_(leaf_attr_cnt),
 | 
			
		||||
               K(ObString(udt_name_len_, udt_name_)),
 | 
			
		||||
               K_(nested_udt_number),
 | 
			
		||||
               K_(varray_capacity),
 | 
			
		||||
               KP_(child_attrs_meta),
 | 
			
		||||
               KP_(leaf_attrs_meta));
 | 
			
		||||
 | 
			
		||||
  uint32_t attribute_cnt_; // leaf-level attributes count of object type
 | 
			
		||||
  uint32_t fixed_attr_cnt_; // fixed size attributes count of object type
 | 
			
		||||
  int32_t fixed_offset_;     // offset of fixed attributes
 | 
			
		||||
 | 
			
		||||
  // new elements for discuss
 | 
			
		||||
  int32_t pl_type_; // record/varary
 | 
			
		||||
  uint64_t udt_id_;  // orignal udt id in schema
 | 
			
		||||
 | 
			
		||||
  uint32_t child_attr_cnt_; // top level attributes number for restore
 | 
			
		||||
  // leaf attributes number for encoding, the same with attribute_cnt_ ? remove later
 | 
			
		||||
  uint32_t leaf_attr_cnt_; // remove this or attribute_cnt_;
 | 
			
		||||
 | 
			
		||||
  size_t udt_name_len_;
 | 
			
		||||
  const char *udt_name_;
 | 
			
		||||
 | 
			
		||||
  uint32_t nested_udt_number_; // for nested_udt_bitmap
 | 
			
		||||
  uint32_t varray_capacity_;
 | 
			
		||||
  // bool is_nullable
 | 
			
		||||
 | 
			
		||||
  // int64_t rowsize_; ? expr_object_construct use this to verify pl handler size
 | 
			
		||||
 | 
			
		||||
  ObSqlUDTAttrMeta* child_attrs_meta_;  // in attrs define order
 | 
			
		||||
 | 
			
		||||
  // flattern(encoding) order, fix length attrs first, varray length attrs laster
 | 
			
		||||
  // sorted by type, length
 | 
			
		||||
  ObSqlUDTAttrMeta* leaf_attrs_meta_;
 | 
			
		||||
} ObSqlUDTMeta;
 | 
			
		||||
 | 
			
		||||
class ObSqlUDT
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
  ObSqlUDT(common::ObIAllocator *allocator = NULL)
 | 
			
		||||
      : allocator_(allocator),
 | 
			
		||||
        udt_meta_(),
 | 
			
		||||
        udt_data_()
 | 
			
		||||
  {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  virtual ~ObSqlUDT() {}
 | 
			
		||||
 | 
			
		||||
  void set_data(const ObString data) { udt_data_ = data; }
 | 
			
		||||
  int init_null_bitmap();
 | 
			
		||||
  int set_null_bitmap(uint32_t index, bool is_null);
 | 
			
		||||
  int set_attribute_offset(uint32_t index, int32_t offset);
 | 
			
		||||
  int append_attribute(uint32_t index, const ObString &attr_value);
 | 
			
		||||
  static inline uint32_t get_null_bitmap_len(uint32_t attr_cnt) { return (attr_cnt + 7) / 8; }
 | 
			
		||||
  void set_udt_meta(const ObSqlUDTMeta &udt_meta) {
 | 
			
		||||
    udt_meta_ = udt_meta;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ObSqlUDTMeta &get_udt_meta() { return udt_meta_; }
 | 
			
		||||
 | 
			
		||||
  // int update_attribute();
 | 
			
		||||
 | 
			
		||||
  int access_attribute(uint32_t index, ObString &attr_value, bool is_varray_element = false);
 | 
			
		||||
 | 
			
		||||
  int get_null_bitmap(ObString &null_bitmap);
 | 
			
		||||
 | 
			
		||||
  uint32_t get_varray_element_count();
 | 
			
		||||
  static uint32_t get_offset_array_len(uint32_t count);
 | 
			
		||||
  static int set_null_bitmap_pos(char *bitmap_start, uint32_t bitmap_len, uint32_t pos);
 | 
			
		||||
  static int get_null_bitmap_pos(const char *bitmap_start, uint32_t bitmap_len, uint32_t pos, bool &is_set);
 | 
			
		||||
 | 
			
		||||
  TO_STRING_KV(KP_(allocator), K_(udt_meta), K_(udt_data));
 | 
			
		||||
 | 
			
		||||
/* data */
 | 
			
		||||
private:
 | 
			
		||||
 | 
			
		||||
  inline int32_t get_attr_offset(uint32_t index, uint32_t null_bitmap_offset, bool is_varray_element = false) {
 | 
			
		||||
 | 
			
		||||
    int32_t count_offset = is_varray_element ? sizeof(uint32) : 0;
 | 
			
		||||
    return reinterpret_cast<int32_t *>(udt_data_.ptr() + null_bitmap_offset + count_offset)[index];
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  common::ObIAllocator *allocator_;
 | 
			
		||||
 | 
			
		||||
  ObSqlUDTMeta udt_meta_;
 | 
			
		||||
  ObString udt_data_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
inline bool ob_is_reserved_subschema_id(uint16_t subschema_id)
 | 
			
		||||
{
 | 
			
		||||
  return subschema_id < ObMaxSystemUDTSqlType;
 | 
			
		||||
}
 | 
			
		||||
inline bool ob_is_reserved_udt_id(uint64_t udt_id)
 | 
			
		||||
{
 | 
			
		||||
  return udt_id == T_OBJ_XML;
 | 
			
		||||
}
 | 
			
		||||
int ob_get_reserved_udt_meta(uint16_t subschema_id, ObSqlUDTMeta &udt_meta);
 | 
			
		||||
int ob_get_reserved_subschema(uint64_t udt_id, uint16_t &subschema_id);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
} // namespace common
 | 
			
		||||
} // namespace oceanbase
 | 
			
		||||
#endif // OCEANBASE_OB_SQL_UDT_TYPE_
 | 
			
		||||
@ -816,6 +816,27 @@ typedef enum ObItemType
 | 
			
		||||
  T_FUN_SYS_INSERTCHILDXML = 1708,
 | 
			
		||||
  T_FUN_SYS_DELETEXML = 1709,
 | 
			
		||||
  T_FUN_SYS_XMLSEQUENCE = 1710,
 | 
			
		||||
  T_FUN_SYS_PRIV_SQL_UDT_CONSTRUCT = 1711,  // add only for udt default constructor in sql
 | 
			
		||||
  T_FUN_SYS_PRIV_SQL_UDT_ATTR_ACCESS = 1712,  // add only for sql udt access attribute in sql
 | 
			
		||||
  T_FUN_SYS_PRIV_ST_NUMINTERIORRINGS = 1713,
 | 
			
		||||
  T_FUN_SYS_PRIV_ST_ISCOLLECTION = 1714,
 | 
			
		||||
  T_FUN_SYS_PRIV_ST_EQUALS = 1715,
 | 
			
		||||
  T_FUN_SYS_PRIV_ST_TOUCHES = 1716,
 | 
			
		||||
  T_FUN_SYS_PRIV_ST_MAKEENVELOPE = 1717,
 | 
			
		||||
  T_FUN_SYS_PRIV_ST_CLIPBYBOX2D = 1718,
 | 
			
		||||
  T_FUN_SYS_PRIV_ST_POINTONSURFACE = 1719,
 | 
			
		||||
  T_FUN_SYS_PRIV_ST_GEOMETRYTYPE = 1720,
 | 
			
		||||
  T_FUN_SYS_ST_CROSSES = 1721,
 | 
			
		||||
  T_FUN_SYS_ST_OVERLAPS = 1722,
 | 
			
		||||
  T_FUN_SYS_ST_UNION = 1723,
 | 
			
		||||
  T_FUN_SYS_ST_LENGTH = 1724,
 | 
			
		||||
  T_FUN_SYS_ST_DIFFERENCE = 1725,
 | 
			
		||||
  T_FUN_SYS_ST_ASMVT = 1726,
 | 
			
		||||
  T_FUN_SYS_ST_ASGEOJSON = 1727,
 | 
			
		||||
  T_FUN_SYS_ST_CENTROID = 1728,
 | 
			
		||||
  T_FUN_SYS_ST_SYMDIFFERENCE = 1729,
 | 
			
		||||
  T_FUN_SYS_PRIV_ST_ASMVTGEOM = 1730,
 | 
			
		||||
  T_FUN_SYS_PRIV_ST_MAKE_VALID = 1731,
 | 
			
		||||
  ///< @note add new oracle only function type before this line
 | 
			
		||||
 | 
			
		||||
  T_FUN_SYS_TABLET_AUTOINC_NEXTVAL = 1801, // add only for heap table
 | 
			
		||||
@ -2346,7 +2367,11 @@ typedef enum ObContextType {
 | 
			
		||||
    || ((op) == T_FUN_SYS_ST_WITHIN) \
 | 
			
		||||
    || ((op) == T_FUN_SYS_ST_DWITHIN) \
 | 
			
		||||
    || ((op) == T_FUN_SYS_ST_INTERSECTS) \
 | 
			
		||||
    || ((op) == T_FUN_SYS_ST_COVERS)) \
 | 
			
		||||
    || ((op) == T_FUN_SYS_ST_COVERS) \
 | 
			
		||||
    || ((op) == T_FUN_SYS_PRIV_ST_EQUALS) \
 | 
			
		||||
    || ((op) == T_FUN_SYS_PRIV_ST_TOUCHES) \
 | 
			
		||||
    || ((op) == T_FUN_SYS_ST_CROSSES) \
 | 
			
		||||
    || ((op) == T_FUN_SYS_ST_OVERLAPS)) \
 | 
			
		||||
 | 
			
		||||
//in oracle mode, only lists exprs can accept bool(tinyint) param
 | 
			
		||||
#define ALLOW_BOOL_INPUT(op) \
 | 
			
		||||
@ -2429,6 +2454,7 @@ extern const char *get_type_name(int type);
 | 
			
		||||
                         (op) == T_FUN_ORA_JSON_ARRAYAGG || (op) == T_FUN_ORA_JSON_OBJECTAGG ||\
 | 
			
		||||
                         (op) == T_FUN_GROUP_ID || \
 | 
			
		||||
                         (op) == T_FUN_ORA_XMLAGG || \
 | 
			
		||||
                         (op) == T_FUN_SYS_ST_ASMVT || \
 | 
			
		||||
                         ((op) >= T_FUN_SYS_BIT_AND && (op) <= T_FUN_SYS_BIT_XOR))
 | 
			
		||||
#define MAYBE_ROW_OP(op) ((op) >= T_OP_EQ && (op) <= T_OP_NE)
 | 
			
		||||
#define IS_PSEUDO_COLUMN_TYPE(op) \
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										31
									
								
								src/share/inner_table/sys_package/sdo_geometry.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								src/share/inner_table/sys_package/sdo_geometry.sql
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,31 @@
 | 
			
		||||
#type_name:sdo_geometry
 | 
			
		||||
#package_name:sdo_geometry
 | 
			
		||||
CREATE OR REPLACE TYPE SDO_POINT_TYPE OID '300027' IS OBJECT (
 | 
			
		||||
 X NUMBER,
 | 
			
		||||
 Y NUMBER,
 | 
			
		||||
 Z NUMBER
 | 
			
		||||
 );
 | 
			
		||||
//
 | 
			
		||||
CREATE OR REPLACE TYPE SDO_ELEM_INFO_ARRAY OID '300029' AS VARRAY (1048576) of NUMBER;
 | 
			
		||||
//
 | 
			
		||||
CREATE OR REPLACE TYPE SDO_ORDINATE_ARRAY OID '300030' AS VARRAY (1048576) of NUMBER;
 | 
			
		||||
//
 | 
			
		||||
CREATE OR REPLACE TYPE SDO_GEOMETRY OID '300028' IS OBJECT (
 | 
			
		||||
 SDO_GTYPE NUMBER,
 | 
			
		||||
 SDO_SRID NUMBER,
 | 
			
		||||
 SDO_POINT SDO_POINT_TYPE,
 | 
			
		||||
 SDO_ELEM_INFO SDO_ELEM_INFO_ARRAY,
 | 
			
		||||
 SDO_ORDINATES SDO_ORDINATE_ARRAY,
 | 
			
		||||
 -- extraction functions
 | 
			
		||||
 MEMBER FUNCTION GET_WKB RETURN BLOB DETERMINISTIC,
 | 
			
		||||
 MEMBER FUNCTION GET_WKT RETURN CLOB DETERMINISTIC,
 | 
			
		||||
 MEMBER FUNCTION Get_GType RETURN NUMBER DETERMINISTIC,
 | 
			
		||||
 MEMBER FUNCTION ST_CoordDim RETURN NUMBER DETERMINISTIC,
 | 
			
		||||
 MEMBER FUNCTION Get_Dims RETURN NUMBER DETERMINISTIC,
 | 
			
		||||
 MEMBER FUNCTION ST_IsValid RETURN NUMBER DETERMINISTIC,
 | 
			
		||||
 MEMBER FUNCTION Get_GeoJson RETURN CLOB DETERMINISTIC,
 | 
			
		||||
 CONSTRUCTOR FUNCTION SDO_GEOMETRY(wkb IN BLOB, srid IN NUMBER DEFAULT NULL) RETURN SELF AS RESULT DETERMINISTIC,
 | 
			
		||||
 CONSTRUCTOR FUNCTION SDO_GEOMETRY(wkt IN CLOB, srid IN NUMBER DEFAULT NULL) RETURN SELF AS RESULT DETERMINISTIC,
 | 
			
		||||
 CONSTRUCTOR FUNCTION SDO_GEOMETRY(wkt IN VARCHAR2, srid IN NUMBER DEFAULT NULL) RETURN SELF AS RESULT DETERMINISTIC
 | 
			
		||||
);
 | 
			
		||||
//
 | 
			
		||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							@ -1940,6 +1940,14 @@ DEFINE_ORACLE_ERROR_EXT_DEP(OB_ERR_INVALID_OPTION_KEY, -7286, ER_INVALID_OPTION_
 | 
			
		||||
DEFINE_ORACLE_ERROR_EXT_DEP(OB_ERR_INVALID_OPTION_VALUE, -7287, ER_INVALID_OPTION_VALUE, "22023", "Invalid value for option in function.", "Invalid value \'%.192s\' for option \'%.192s\' in function \'%.192s\'.", 600, "Invalid value for option in function.", "Invalid value \'%.192s\' for option \'%.192s\' in function \'%.192s\'.");
 | 
			
		||||
DEFINE_ORACLE_ERROR_EXT_DEP(OB_ERR_INVALID_GEOMETRY_TYPE, -7288, ER_UNEXPECTED_GEOMETRY_TYPE, "22S01", "Unknown WKB type.", "Unknown WKB type(%d)! Full WKB type number was (%d).", 600, "Unknown WKB type.", "Unknown WKB type(%d)! Full WKB type number was (%d).");
 | 
			
		||||
DEFINE_ORACLE_ERROR_EXT_DEP(OB_ERR_FTS_MUST_HAVE_TEXT_COL, -7289, ER_BAD_FT_COLUMN, "42000", "A FTS index may only contain a text type column.", "A FTS index may only contain a text type column.", 600, "A FTS index may only contain a text type column.", "A FTS index may only contain a text type column.");
 | 
			
		||||
DEFINE_ORACLE_ERROR(OB_ERR_DIMENSION_NUMBER_IS_OUT_OF_RANGE, -7290, -1, "HY000", "dimension number is out of range", 13000, "dimension number is out of range");
 | 
			
		||||
DEFINE_ORACLE_ERROR_DEP(OB_ERR_INVALID_GTYPE_IN_SDO_GEROMETRY, -7291, -1, "HY000", "Invalid Gtype in the SDO_GEOMETRY object", 13028, "Invalid Gtype in the SDO_GEOMETRY object");
 | 
			
		||||
DEFINE_ORACLE_ERROR(OB_ERR_INVALID_SRID_IN_SDO_GEOMETRY, -7292, -1, "HY000", "Invalid SRID in the SDO_GEOMETRY object", 13029, "Invalid SRID in the SDO_GEOMETRY object");
 | 
			
		||||
DEFINE_ORACLE_ERROR(OB_ERR_INVALID_GTYPE_FOR_POINT_OBJECT, -7293, -1, "HY000", "Invalid Gtype in the SDO_GEOMETRY object for point object", 13031, "Invalid Gtype in the SDO_GEOMETRY object for point object");
 | 
			
		||||
DEFINE_ORACLE_ERROR_DEP(OB_ERR_INVALID_NULL_SDO_GEOMETRY, -7294, -1, "HY000", "Invalid NULL  SDO_GEOMETRY object", 13032, "Invalid NULL  SDO_GEOMETRY object");
 | 
			
		||||
DEFINE_ORACLE_ERROR_DEP(OB_ERR_INVALID_DATA_IN_SDO_ELEM_INFO_ARRAY, -7295, -1, "HY000", "Invalid data in the SDO_ELEM_INFO_ARRAY in SDO_GEOMETRY object", 13033, "Invalid data in the SDO_ELEM_INFO_ARRAY in SDO_GEOMETRY object");
 | 
			
		||||
DEFINE_ORACLE_ERROR_DEP(OB_ERR_INVALID_DATA_IN_SDO_ORDINATE_ARRAY, -7296, -1, "HY000", "Invalid data in the SDO_ORDINATE_ARRAY in SDO_GEOMETRY object", 13034, "Invalid data in the SDO_ORDINATE_ARRAY in SDO_GEOMETRY object");
 | 
			
		||||
DEFINE_ORACLE_ERROR_DEP(OB_ERR_VALUE_NOT_ALLOWED, -7297, -1, "HY000", "value not allowed", 24323, "value not allowed");
 | 
			
		||||
DEFINE_ORACLE_ERROR_EXT(OB_ERR_INVALID_XML_DATATYPE, -7402, -1, "22000", "Invalid data type for the operation", "inconsistent datatypes: expected %s got %s", 932, "inconsistent datatypes", "inconsistent datatypes: expected %s got %s");
 | 
			
		||||
DEFINE_ORACLE_ERROR(OB_ERR_XML_MISSING_COMMA, -7403, -1, "42000", "missing comma", 917, "missing comma");
 | 
			
		||||
DEFINE_ORACLE_ERROR(OB_ERR_INVALID_XPATH_EXPRESSION, -7404, ER_UNKNOWN_ERROR, "42000", "invalid xpath expression", 31013, "invalid xpath expression");
 | 
			
		||||
@ -1970,6 +1978,7 @@ DEFINE_ORACLE_ERROR(OB_ERR_XQUERY_UNSUPPORTED, -7428, -1, "42000", "unsupported
 | 
			
		||||
DEFINE_ORACLE_ERROR(OB_ERR_INVALID_XML_CHILD_NAME, -7429, -1, "42000", "The document being inserted does not conform to specified child name", 31056, "The document being inserted does not conform to specified child name");
 | 
			
		||||
DEFINE_ORACLE_ERROR(OB_ERR_XML_NOT_SUPPORT_OPERATION, -7430, -1, "42000", "XML node '' (type=%s) does not support this operation", 31195, "XML node '' (type=%s) does not support this operation");
 | 
			
		||||
DEFINE_ORACLE_ERROR(OB_ERR_JSON_FUN_UNSUPPORTED_TYPE, -7431, -1, "HY000", "Input to JSON generation function has unsupported data type", 40654, "Input to JSON generation function has unsupported data type");
 | 
			
		||||
DEFINE_ORACLE_ERROR(OB_ERR_COMPARE_VARRAY_LOB_ATTR, -7432, -1, "42000", "cannot compare VARRAY or LOB attributes of an object type", 22901, "cannot compare VARRAY or LOB attributes of an object type");
 | 
			
		||||
 | 
			
		||||
////////////////////////////////////////////////////////////////
 | 
			
		||||
// !!! Fatal errors and the client should close the connection, -8000 ~ -8999
 | 
			
		||||
 | 
			
		||||
@ -1434,6 +1434,9 @@ constexpr int OB_TABLET_GC_LOCK_CONFLICT = -7120;
 | 
			
		||||
constexpr int OB_SEQUENCE_NOT_MATCH = -7121;
 | 
			
		||||
constexpr int OB_SEQUENCE_TOO_SMALL = -7122;
 | 
			
		||||
constexpr int OB_TRANSFER_CANNOT_START = -7123;
 | 
			
		||||
constexpr int OB_ERR_DIMENSION_NUMBER_IS_OUT_OF_RANGE = -7290;
 | 
			
		||||
constexpr int OB_ERR_INVALID_SRID_IN_SDO_GEOMETRY = -7292;
 | 
			
		||||
constexpr int OB_ERR_INVALID_GTYPE_FOR_POINT_OBJECT = -7293;
 | 
			
		||||
constexpr int OB_ERR_INVALID_XML_DATATYPE = -7402;
 | 
			
		||||
constexpr int OB_ERR_XML_MISSING_COMMA = -7403;
 | 
			
		||||
constexpr int OB_ERR_INVALID_XPATH_EXPRESSION = -7404;
 | 
			
		||||
@ -1459,6 +1462,7 @@ constexpr int OB_ERR_XQUERY_UNSUPPORTED = -7428;
 | 
			
		||||
constexpr int OB_ERR_INVALID_XML_CHILD_NAME = -7429;
 | 
			
		||||
constexpr int OB_ERR_XML_NOT_SUPPORT_OPERATION = -7430;
 | 
			
		||||
constexpr int OB_ERR_JSON_FUN_UNSUPPORTED_TYPE = -7431;
 | 
			
		||||
constexpr int OB_ERR_COMPARE_VARRAY_LOB_ATTR = -7432;
 | 
			
		||||
constexpr int OB_SERVER_IS_INIT = -8001;
 | 
			
		||||
constexpr int OB_SERVER_IS_STOPPING = -8002;
 | 
			
		||||
constexpr int OB_PACKET_CHECKSUM_ERROR = -8003;
 | 
			
		||||
@ -3571,6 +3575,14 @@ constexpr int OB_ERR_INVALID_DATE_MSG_FMT_V2 = -4219;
 | 
			
		||||
#define OB_ERR_INVALID_OPTION_VALUE__USER_ERROR_MSG "Invalid value \'%.192s\' for option \'%.192s\' in function \'%.192s\'."
 | 
			
		||||
#define OB_ERR_INVALID_GEOMETRY_TYPE__USER_ERROR_MSG "Unknown WKB type(%d)! Full WKB type number was (%d)."
 | 
			
		||||
#define OB_ERR_FTS_MUST_HAVE_TEXT_COL__USER_ERROR_MSG "A FTS index may only contain a text type column."
 | 
			
		||||
#define OB_ERR_DIMENSION_NUMBER_IS_OUT_OF_RANGE__USER_ERROR_MSG "dimension number is out of range"
 | 
			
		||||
#define OB_ERR_INVALID_GTYPE_IN_SDO_GEROMETRY__USER_ERROR_MSG "Invalid Gtype in the SDO_GEOMETRY object"
 | 
			
		||||
#define OB_ERR_INVALID_SRID_IN_SDO_GEOMETRY__USER_ERROR_MSG "Invalid SRID in the SDO_GEOMETRY object"
 | 
			
		||||
#define OB_ERR_INVALID_GTYPE_FOR_POINT_OBJECT__USER_ERROR_MSG "Invalid Gtype in the SDO_GEOMETRY object for point object"
 | 
			
		||||
#define OB_ERR_INVALID_NULL_SDO_GEOMETRY__USER_ERROR_MSG "Invalid NULL  SDO_GEOMETRY object"
 | 
			
		||||
#define OB_ERR_INVALID_DATA_IN_SDO_ELEM_INFO_ARRAY__USER_ERROR_MSG "Invalid data in the SDO_ELEM_INFO_ARRAY in SDO_GEOMETRY object"
 | 
			
		||||
#define OB_ERR_INVALID_DATA_IN_SDO_ORDINATE_ARRAY__USER_ERROR_MSG "Invalid data in the SDO_ORDINATE_ARRAY in SDO_GEOMETRY object"
 | 
			
		||||
#define OB_ERR_VALUE_NOT_ALLOWED__USER_ERROR_MSG "value not allowed"
 | 
			
		||||
#define OB_ERR_INVALID_XML_DATATYPE__USER_ERROR_MSG "inconsistent datatypes: expected %s got %s"
 | 
			
		||||
#define OB_ERR_XML_MISSING_COMMA__USER_ERROR_MSG "missing comma"
 | 
			
		||||
#define OB_ERR_INVALID_XPATH_EXPRESSION__USER_ERROR_MSG "invalid xpath expression"
 | 
			
		||||
@ -3601,6 +3613,7 @@ constexpr int OB_ERR_INVALID_DATE_MSG_FMT_V2 = -4219;
 | 
			
		||||
#define OB_ERR_INVALID_XML_CHILD_NAME__USER_ERROR_MSG "The document being inserted does not conform to specified child name"
 | 
			
		||||
#define OB_ERR_XML_NOT_SUPPORT_OPERATION__USER_ERROR_MSG "XML node '' (type=%s) does not support this operation"
 | 
			
		||||
#define OB_ERR_JSON_FUN_UNSUPPORTED_TYPE__USER_ERROR_MSG "Input to JSON generation function has unsupported data type"
 | 
			
		||||
#define OB_ERR_COMPARE_VARRAY_LOB_ATTR__USER_ERROR_MSG "cannot compare VARRAY or LOB attributes of an object type"
 | 
			
		||||
#define OB_SERVER_IS_INIT__USER_ERROR_MSG "Server is initializing"
 | 
			
		||||
#define OB_SERVER_IS_STOPPING__USER_ERROR_MSG "Server is stopping"
 | 
			
		||||
#define OB_PACKET_CHECKSUM_ERROR__USER_ERROR_MSG "Packet checksum error"
 | 
			
		||||
@ -5737,6 +5750,14 @@ constexpr int OB_ERR_INVALID_DATE_MSG_FMT_V2 = -4219;
 | 
			
		||||
#define OB_ERR_INVALID_OPTION_VALUE__ORA_USER_ERROR_MSG "ORA-00600: Invalid value \'%.192s\' for option \'%.192s\' in function \'%.192s\'."
 | 
			
		||||
#define OB_ERR_INVALID_GEOMETRY_TYPE__ORA_USER_ERROR_MSG "ORA-00600: Unknown WKB type(%d)! Full WKB type number was (%d)."
 | 
			
		||||
#define OB_ERR_FTS_MUST_HAVE_TEXT_COL__ORA_USER_ERROR_MSG "ORA-00600: A FTS index may only contain a text type column."
 | 
			
		||||
#define OB_ERR_DIMENSION_NUMBER_IS_OUT_OF_RANGE__ORA_USER_ERROR_MSG "ORA-13000: dimension number is out of range"
 | 
			
		||||
#define OB_ERR_INVALID_GTYPE_IN_SDO_GEROMETRY__ORA_USER_ERROR_MSG "ORA-13028: Invalid Gtype in the SDO_GEOMETRY object"
 | 
			
		||||
#define OB_ERR_INVALID_SRID_IN_SDO_GEOMETRY__ORA_USER_ERROR_MSG "ORA-13029: Invalid SRID in the SDO_GEOMETRY object"
 | 
			
		||||
#define OB_ERR_INVALID_GTYPE_FOR_POINT_OBJECT__ORA_USER_ERROR_MSG "ORA-13031: Invalid Gtype in the SDO_GEOMETRY object for point object"
 | 
			
		||||
#define OB_ERR_INVALID_NULL_SDO_GEOMETRY__ORA_USER_ERROR_MSG "ORA-13032: Invalid NULL  SDO_GEOMETRY object"
 | 
			
		||||
#define OB_ERR_INVALID_DATA_IN_SDO_ELEM_INFO_ARRAY__ORA_USER_ERROR_MSG "ORA-13033: Invalid data in the SDO_ELEM_INFO_ARRAY in SDO_GEOMETRY object"
 | 
			
		||||
#define OB_ERR_INVALID_DATA_IN_SDO_ORDINATE_ARRAY__ORA_USER_ERROR_MSG "ORA-13034: Invalid data in the SDO_ORDINATE_ARRAY in SDO_GEOMETRY object"
 | 
			
		||||
#define OB_ERR_VALUE_NOT_ALLOWED__ORA_USER_ERROR_MSG "ORA-24323: value not allowed"
 | 
			
		||||
#define OB_ERR_INVALID_XML_DATATYPE__ORA_USER_ERROR_MSG "ORA-00932: inconsistent datatypes: expected %s got %s"
 | 
			
		||||
#define OB_ERR_XML_MISSING_COMMA__ORA_USER_ERROR_MSG "ORA-00917: missing comma"
 | 
			
		||||
#define OB_ERR_INVALID_XPATH_EXPRESSION__ORA_USER_ERROR_MSG "ORA-31013: invalid xpath expression"
 | 
			
		||||
@ -5767,6 +5788,7 @@ constexpr int OB_ERR_INVALID_DATE_MSG_FMT_V2 = -4219;
 | 
			
		||||
#define OB_ERR_INVALID_XML_CHILD_NAME__ORA_USER_ERROR_MSG "ORA-31056: The document being inserted does not conform to specified child name"
 | 
			
		||||
#define OB_ERR_XML_NOT_SUPPORT_OPERATION__ORA_USER_ERROR_MSG "ORA-31195: XML node '' (type=%s) does not support this operation"
 | 
			
		||||
#define OB_ERR_JSON_FUN_UNSUPPORTED_TYPE__ORA_USER_ERROR_MSG "ORA-40654: Input to JSON generation function has unsupported data type"
 | 
			
		||||
#define OB_ERR_COMPARE_VARRAY_LOB_ATTR__ORA_USER_ERROR_MSG "ORA-22901: cannot compare VARRAY or LOB attributes of an object type"
 | 
			
		||||
#define OB_SERVER_IS_INIT__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -8001, Server is initializing"
 | 
			
		||||
#define OB_SERVER_IS_STOPPING__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -8002, Server is stopping"
 | 
			
		||||
#define OB_PACKET_CHECKSUM_ERROR__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -8003, Packet checksum error"
 | 
			
		||||
@ -6149,7 +6171,7 @@ constexpr int OB_ERR_INVALID_DATE_MSG_FMT_V2 = -4219;
 | 
			
		||||
#define OB_ERR_DATA_TOO_LONG_MSG_FMT_V2__ORA_USER_ERROR_MSG "ORA-12899: value too large for column %.*s (actual: %ld, maximum: %ld)"
 | 
			
		||||
#define OB_ERR_INVALID_DATE_MSG_FMT_V2__ORA_USER_ERROR_MSG "ORA-01861: Incorrect datetime value for column '%.*s' at row %ld"
 | 
			
		||||
 | 
			
		||||
extern int g_all_ob_errnos[2162];
 | 
			
		||||
extern int g_all_ob_errnos[2171];
 | 
			
		||||
 | 
			
		||||
  const char *ob_error_name(const int oberr);
 | 
			
		||||
  const char* ob_error_cause(const int oberr);
 | 
			
		||||
 | 
			
		||||
@ -128,6 +128,7 @@ ob_set_subtarget(ob_sql engine
 | 
			
		||||
  engine/user_defined_function/ob_user_defined_function.cpp
 | 
			
		||||
  engine/window_function/ob_window_function_op.cpp
 | 
			
		||||
  engine/opt_statistics/ob_optimizer_stats_gathering_op.cpp
 | 
			
		||||
  engine/ob_subschema_ctx.cpp
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
ob_set_subtarget(ob_sql engine_aggregate
 | 
			
		||||
 | 
			
		||||
@ -132,7 +132,8 @@ ObPhysicalPlan::ObPhysicalPlan(MemoryContext &mem_context /* = CURRENT_CONTEXT *
 | 
			
		||||
    enable_append_(false),
 | 
			
		||||
    append_table_id_(0),
 | 
			
		||||
    logical_plan_(),
 | 
			
		||||
    is_enable_px_fast_reclaim_(false)
 | 
			
		||||
    is_enable_px_fast_reclaim_(false),
 | 
			
		||||
    subschema_ctx_(allocator_)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -227,6 +228,7 @@ void ObPhysicalPlan::reset()
 | 
			
		||||
  need_record_plan_info_ = false;
 | 
			
		||||
  logical_plan_.reset();
 | 
			
		||||
  is_enable_px_fast_reclaim_ = false;
 | 
			
		||||
  subschema_ctx_.reset();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ObPhysicalPlan::destroy()
 | 
			
		||||
@ -238,6 +240,7 @@ void ObPhysicalPlan::destroy()
 | 
			
		||||
  expr_op_factory_.destroy();
 | 
			
		||||
  stat_.expected_worker_map_.destroy();
 | 
			
		||||
  stat_.minimal_worker_map_.destroy();
 | 
			
		||||
  subschema_ctx_.destroy();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int ObPhysicalPlan::copy_common_info(ObPhysicalPlan &src)
 | 
			
		||||
@ -778,7 +781,8 @@ OB_SERIALIZE_MEMBER(ObPhysicalPlan,
 | 
			
		||||
                    append_table_id_,
 | 
			
		||||
                    is_enable_px_fast_reclaim_,
 | 
			
		||||
                    gtt_session_scope_ids_,
 | 
			
		||||
                    gtt_trans_scope_ids_);
 | 
			
		||||
                    gtt_trans_scope_ids_,
 | 
			
		||||
                    subschema_ctx_);
 | 
			
		||||
 | 
			
		||||
int ObPhysicalPlan::set_table_locations(const ObTablePartitionInfoArray &infos,
 | 
			
		||||
                                        ObSchemaGetterGuard &schema_guard)
 | 
			
		||||
 | 
			
		||||
@ -31,6 +31,7 @@
 | 
			
		||||
#include "storage/tx/ob_clog_encrypt_info.h"
 | 
			
		||||
#include "storage/tx/ob_trans_define.h"
 | 
			
		||||
#include "sql/monitor/ob_plan_info_manager.h"
 | 
			
		||||
#include "sql/engine/ob_subschema_ctx.h"
 | 
			
		||||
 | 
			
		||||
namespace oceanbase
 | 
			
		||||
{
 | 
			
		||||
@ -659,6 +660,7 @@ public:
 | 
			
		||||
  ObLogicalPlanRawData logical_plan_;
 | 
			
		||||
  // for detector manager
 | 
			
		||||
  bool is_enable_px_fast_reclaim_;
 | 
			
		||||
  ObSubSchemaCtx subschema_ctx_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
inline void ObPhysicalPlan::set_affected_last_insert_id(bool affected_last_insert_id)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										407
									
								
								src/sql/engine/ob_subschema_ctx.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										407
									
								
								src/sql/engine/ob_subschema_ctx.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,407 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright (c) 2021 OceanBase
 | 
			
		||||
 * OceanBase CE is licensed under Mulan PubL v2.
 | 
			
		||||
 * You can use this software according to the terms and conditions of the Mulan PubL v2.
 | 
			
		||||
 * You may obtain a copy of Mulan PubL v2 at:
 | 
			
		||||
 *          http://license.coscl.org.cn/MulanPubL-2.0
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 | 
			
		||||
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 | 
			
		||||
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 | 
			
		||||
 * See the Mulan PubL v2 for more details.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#define USING_LOG_PREFIX SQL_ENG
 | 
			
		||||
#include "sql/engine/ob_subschema_ctx.h"
 | 
			
		||||
#include "deps/oblib/src/lib/udt/ob_udt_type.h"
 | 
			
		||||
#include "src/share/rc/ob_tenant_base.h"
 | 
			
		||||
 | 
			
		||||
namespace oceanbase
 | 
			
		||||
{
 | 
			
		||||
using namespace common;
 | 
			
		||||
using namespace share;
 | 
			
		||||
using namespace transaction;
 | 
			
		||||
namespace sql
 | 
			
		||||
{
 | 
			
		||||
// implement of subschema mapping
 | 
			
		||||
 | 
			
		||||
// Add New de/serialize functions for schema value when new subschema types are added.
 | 
			
		||||
// Signature is identify of subschema value, using for reverse search of subschema id
 | 
			
		||||
// for sql udt, signature is original udt id
 | 
			
		||||
#define DEF_SUBSCHEMA_ENTRY(SUBSCHEMATYPE)         \
 | 
			
		||||
  {                                                \
 | 
			
		||||
    subschema_value_serialize<SUBSCHEMATYPE>,      \
 | 
			
		||||
    subschema_value_deserialize<SUBSCHEMATYPE>,    \
 | 
			
		||||
    subschema_value_serialize_size<SUBSCHEMATYPE>, \
 | 
			
		||||
    subschema_value_get_signature<SUBSCHEMATYPE>,  \
 | 
			
		||||
    subschema_value_deep_copy<SUBSCHEMATYPE>,      \
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
template<>
 | 
			
		||||
int subschema_value_serialize<OB_SUBSCHEMA_UDT_TYPE>(void *value, char* buf, const int64_t buf_len, int64_t& pos)
 | 
			
		||||
{
 | 
			
		||||
  int ret = OB_SUCCESS;
 | 
			
		||||
  if (OB_ISNULL(value)) {
 | 
			
		||||
    ret = OB_ERR_UNEXPECTED;
 | 
			
		||||
    LOG_WARN("null sql udt value for seriazlie", K(ret), K(OB_SUBSCHEMA_UDT_TYPE));
 | 
			
		||||
  } else {
 | 
			
		||||
    const ObSqlUDTMeta* udt_meta = reinterpret_cast<ObSqlUDTMeta *>(value);
 | 
			
		||||
    if (OB_FAIL(udt_meta->serialize(buf, buf_len, pos))) {
 | 
			
		||||
      LOG_WARN("failed to do sql udt meta seriazlie", K(ret), K(*udt_meta));
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <>
 | 
			
		||||
int subschema_value_deserialize<OB_SUBSCHEMA_UDT_TYPE>(void *value, const char* buf, const int64_t data_len, int64_t& pos)
 | 
			
		||||
{
 | 
			
		||||
  int ret = OB_SUCCESS;
 | 
			
		||||
  if (OB_ISNULL(value)) {
 | 
			
		||||
    ret = OB_ERR_UNEXPECTED;
 | 
			
		||||
    LOG_WARN("null sql udt value for deseriazlie", K(ret), K(OB_SUBSCHEMA_UDT_TYPE));
 | 
			
		||||
  } else {
 | 
			
		||||
    ObSqlUDTMeta* udt_meta = reinterpret_cast<ObSqlUDTMeta *>(value);
 | 
			
		||||
    if (OB_FAIL(udt_meta->deserialize(buf, data_len, pos))) {
 | 
			
		||||
      LOG_WARN("failed to do sql udt meta deseriazlie", K(ret), KP(buf), K(data_len));
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <>
 | 
			
		||||
int64_t subschema_value_serialize_size<OB_SUBSCHEMA_UDT_TYPE>(void *value)
 | 
			
		||||
{
 | 
			
		||||
  int ret = OB_SUCCESS;
 | 
			
		||||
  int64_t len = 0;
 | 
			
		||||
  if (OB_ISNULL(value)) {
 | 
			
		||||
  } else {
 | 
			
		||||
    ObSqlUDTMeta* udt_meta = reinterpret_cast<ObSqlUDTMeta *>(value);
 | 
			
		||||
    len += udt_meta->get_serialize_size();
 | 
			
		||||
  }
 | 
			
		||||
  return len;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <>
 | 
			
		||||
int subschema_value_get_signature<OB_SUBSCHEMA_UDT_TYPE>(void *value, uint64_t &signature)
 | 
			
		||||
{
 | 
			
		||||
  int ret = OB_SUCCESS;
 | 
			
		||||
  signature = 0;
 | 
			
		||||
  if (OB_ISNULL(value)) {
 | 
			
		||||
    ret = OB_ERR_UNEXPECTED;
 | 
			
		||||
    LOG_WARN("null subschema value", K(ret), K(OB_SUBSCHEMA_UDT_TYPE));
 | 
			
		||||
  } else {
 | 
			
		||||
    const ObSqlUDTMeta* udt_meta = reinterpret_cast<ObSqlUDTMeta *>(value);
 | 
			
		||||
    signature = udt_meta->udt_id_;
 | 
			
		||||
  }
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <>
 | 
			
		||||
int subschema_value_deep_copy<OB_SUBSCHEMA_UDT_TYPE>(const void *src_value, void *&dst_value, ObIAllocator &allocator)
 | 
			
		||||
{
 | 
			
		||||
  int ret = OB_SUCCESS;
 | 
			
		||||
  if (OB_ISNULL(src_value)) {
 | 
			
		||||
    ret = OB_ERR_UNEXPECTED;
 | 
			
		||||
    LOG_WARN("null subschema value for deep copy", K(ret), K(OB_SUBSCHEMA_UDT_TYPE));
 | 
			
		||||
  } else {
 | 
			
		||||
    const ObSqlUDTMeta* udt_meta = reinterpret_cast<const ObSqlUDTMeta *>(src_value);
 | 
			
		||||
    ObSqlUDTMeta* copy_meta = NULL;
 | 
			
		||||
    if (OB_FAIL(udt_meta->deep_copy(allocator, copy_meta))) {
 | 
			
		||||
      LOG_WARN("failed to deep copy udt meta", K(ret), K(OB_SUBSCHEMA_UDT_TYPE));
 | 
			
		||||
    } else if (OB_ISNULL(copy_meta)) {
 | 
			
		||||
      ret = OB_ERR_UNEXPECTED;
 | 
			
		||||
      LOG_WARN("deep copy udt meta result is null", K(ret), K(OB_SUBSCHEMA_UDT_TYPE));
 | 
			
		||||
    } else {
 | 
			
		||||
      dst_value = static_cast<void *>(copy_meta);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ObSubSchemaFuncs SUBSCHEMA_FUNCS[OB_SUBSCHEMA_MAX_TYPE] =
 | 
			
		||||
{
 | 
			
		||||
  DEF_SUBSCHEMA_ENTRY(OB_SUBSCHEMA_UDT_TYPE),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
int ObSubSchemaValue::deep_copy_value(const void *src_value, ObIAllocator &allocator)
 | 
			
		||||
{
 | 
			
		||||
  int ret = OB_SUCCESS;
 | 
			
		||||
  if (OB_ISNULL(src_value)) {
 | 
			
		||||
    ret = OB_ERR_UNEXPECTED;
 | 
			
		||||
    LOG_WARN("null value for deep copy subschema value", K(ret));
 | 
			
		||||
  } else if (OB_FAIL(SUBSCHEMA_FUNCS[type_].deep_copy(src_value, value_, allocator))) {
 | 
			
		||||
    LOG_WARN("failed deep copy subschema value", K(ret), K(*this), KP(src_value));
 | 
			
		||||
  }
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Implementation of de/serialize of ObSubschemaValue
 | 
			
		||||
OB_DEF_SERIALIZE(ObSubSchemaValue)
 | 
			
		||||
{
 | 
			
		||||
  int ret = OB_SUCCESS;
 | 
			
		||||
  LST_DO_CODE(OB_UNIS_ENCODE,
 | 
			
		||||
              type_,
 | 
			
		||||
              signature_);
 | 
			
		||||
  if (OB_FAIL(ret)) {
 | 
			
		||||
    LOG_WARN("fail to serialize subschema type info", K(ret), K(type_), K(signature_));
 | 
			
		||||
  } else if (OB_FAIL(SUBSCHEMA_FUNCS[type_].value_serialize(value_, buf, buf_len, pos))) {
 | 
			
		||||
    LOG_WARN("fail to serialize subschema data", K(ret), K(type_), K(signature_));
 | 
			
		||||
  }
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
OB_DEF_DESERIALIZE(ObSubSchemaValue)
 | 
			
		||||
{
 | 
			
		||||
  int ret = OB_SUCCESS;
 | 
			
		||||
  LST_DO_CODE(OB_UNIS_DECODE,
 | 
			
		||||
              type_,
 | 
			
		||||
              signature_);
 | 
			
		||||
  if (OB_FAIL(ret)) {
 | 
			
		||||
    LOG_WARN("fail to deserialize subschema type info", K(ret), K(type_), K(signature_));
 | 
			
		||||
  } else if (OB_FAIL(SUBSCHEMA_FUNCS[type_].value_deserialize(value_, buf, data_len, pos))) {
 | 
			
		||||
    LOG_WARN("fail to deserialize subschema data", K(ret), K(type_), K(signature_));
 | 
			
		||||
  }
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// serialize size cannot return error code
 | 
			
		||||
OB_DEF_SERIALIZE_SIZE(ObSubSchemaValue)
 | 
			
		||||
{
 | 
			
		||||
  int64_t len = 0;
 | 
			
		||||
  LST_DO_CODE(OB_UNIS_ADD_LEN,
 | 
			
		||||
              type_,
 | 
			
		||||
              signature_);
 | 
			
		||||
  len += SUBSCHEMA_FUNCS[type_].get_value_serialize_size(value_);
 | 
			
		||||
  return len;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Implementation of de/serialize of ObSubschemaValue of ObSubSchemaCtx
 | 
			
		||||
OB_DEF_SERIALIZE(ObSubSchemaCtx)
 | 
			
		||||
{
 | 
			
		||||
  int ret = OB_SUCCESS;
 | 
			
		||||
  if (!is_inited_ || subschema_map_.empty()) { // do nothing
 | 
			
		||||
  } else { // subschema count more then zero
 | 
			
		||||
    uint32_t subschema_count = subschema_map_.size();
 | 
			
		||||
    OB_UNIS_ENCODE(subschema_count);
 | 
			
		||||
    OB_UNIS_ENCODE(used_subschema_id_);
 | 
			
		||||
    if (OB_FAIL(ret)) {
 | 
			
		||||
      LOG_WARN("fail to serialize subschema ctx", K(ret));
 | 
			
		||||
    } else {
 | 
			
		||||
      ObSubSchemaMap::const_iterator iter = subschema_map_.begin();
 | 
			
		||||
      while (OB_SUCC(ret) && iter != subschema_map_.end()) {
 | 
			
		||||
        OB_UNIS_ENCODE(iter->first);
 | 
			
		||||
        OB_UNIS_ENCODE(iter->second);
 | 
			
		||||
        iter++;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
OB_DEF_DESERIALIZE(ObSubSchemaCtx)
 | 
			
		||||
{
 | 
			
		||||
  int ret = OB_SUCCESS;
 | 
			
		||||
  uint32_t subschema_count = 0;
 | 
			
		||||
  OB_UNIS_DECODE(subschema_count);
 | 
			
		||||
  if (OB_FAIL(ret)) {
 | 
			
		||||
  } else if (subschema_count > 0) {
 | 
			
		||||
    if (!is_inited_ && OB_FAIL(init())) {
 | 
			
		||||
      LOG_WARN("fail to init subschema ctx", K(ret));
 | 
			
		||||
    } else {
 | 
			
		||||
      OB_UNIS_DECODE(used_subschema_id_);
 | 
			
		||||
      if (OB_FAIL(ret)) {
 | 
			
		||||
        LOG_WARN("fail to deserialize subschema ctx", K(ret));
 | 
			
		||||
      } else {
 | 
			
		||||
        for (int64_t i = 0; OB_SUCC(ret) && i < subschema_count; i++) {
 | 
			
		||||
          uint64_t subschema_id = 0;
 | 
			
		||||
          ObSubSchemaValue value;
 | 
			
		||||
          ObSqlUDTMeta udt_meta;
 | 
			
		||||
          value.value_ = &udt_meta;
 | 
			
		||||
          OB_UNIS_DECODE(subschema_id);
 | 
			
		||||
          OB_UNIS_DECODE(value);
 | 
			
		||||
          if (OB_FAIL(ret)) { // copy value from buffer to local memory
 | 
			
		||||
          } else if (OB_FAIL(value.deep_copy_value(value.value_, allocator_))) {
 | 
			
		||||
            LOG_WARN("deep copy value failed", K(ret), K(subschema_id), K(value));
 | 
			
		||||
          } else if (OB_FAIL(set_subschema(subschema_id, value))) {
 | 
			
		||||
             LOG_WARN("fail to set subschema", K(ret), K(subschema_id), K(value));
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// serialize size cannot return error code
 | 
			
		||||
OB_DEF_SERIALIZE_SIZE(ObSubSchemaCtx)
 | 
			
		||||
{
 | 
			
		||||
  int64_t len = 0;
 | 
			
		||||
  if (!is_inited_ || subschema_map_.empty()) { // do nothing
 | 
			
		||||
  } else { // subschema count more then zero
 | 
			
		||||
    uint32_t subschema_count = subschema_map_.size();
 | 
			
		||||
    OB_UNIS_ADD_LEN(subschema_count);
 | 
			
		||||
    OB_UNIS_ADD_LEN(used_subschema_id_);
 | 
			
		||||
    ObSubSchemaMap::const_iterator iter = subschema_map_.begin();
 | 
			
		||||
    while (iter != subschema_map_.end()) {
 | 
			
		||||
      OB_UNIS_ADD_LEN(iter->first);
 | 
			
		||||
      OB_UNIS_ADD_LEN(iter->second);
 | 
			
		||||
      iter++;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return len;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int ObSubSchemaCtx::assgin(const ObSubSchemaCtx &other)
 | 
			
		||||
{
 | 
			
		||||
  int ret = OB_SUCCESS;
 | 
			
		||||
  if (!other.is_inited() || other.get_subschema_count() == 0) {
 | 
			
		||||
    // no subschema, do nothing
 | 
			
		||||
  } else if (is_inited() && get_subschema_count() > 0) {
 | 
			
		||||
    reset();
 | 
			
		||||
    LOG_INFO("subschema context reset due to assgin other", K(*this), K(lbt()));
 | 
			
		||||
  }
 | 
			
		||||
  if (!is_inited() && OB_FAIL(init())) {
 | 
			
		||||
    LOG_WARN("fail to init subschema ctx", K(ret));
 | 
			
		||||
  } else {
 | 
			
		||||
    ObSubSchemaMap::const_iterator iter = other.get_subschema_map().begin();
 | 
			
		||||
    while (OB_SUCC(ret) && iter != other.get_subschema_map().end()) {
 | 
			
		||||
      uint64_t subschema_id = iter->first;
 | 
			
		||||
      ObSubSchemaValue value = iter->second;
 | 
			
		||||
      if (OB_FAIL(value.deep_copy_value(iter->second.value_, allocator_))) {
 | 
			
		||||
        LOG_WARN("deep copy value failed", K(ret), K(subschema_id), K(value));
 | 
			
		||||
      } else if (OB_FAIL(set_subschema(subschema_id, value))) {
 | 
			
		||||
        LOG_WARN("fail to set subschema", K(ret), K(subschema_id), K(value));
 | 
			
		||||
      }
 | 
			
		||||
      iter++;
 | 
			
		||||
    }
 | 
			
		||||
    used_subschema_id_ = other.used_subschema_id_;
 | 
			
		||||
  }
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int ObSubSchemaCtx::init()
 | 
			
		||||
{
 | 
			
		||||
  int ret = OB_SUCCESS;
 | 
			
		||||
  if (is_inited_) {
 | 
			
		||||
    ret = OB_ERR_UNEXPECTED;
 | 
			
		||||
    LOG_WARN("sub schema ctx already inited", K(ret), K(*this));
 | 
			
		||||
  } else if (OB_FAIL(subschema_map_.create(SUBSCHEMA_BUCKET_NUM,
 | 
			
		||||
                                    "SubSchemaHash",
 | 
			
		||||
                                    "SubSchemaHash",
 | 
			
		||||
                                    MTL_ID()))) {
 | 
			
		||||
    LOG_WARN("fail to create subschema map", K(ret));
 | 
			
		||||
  } else if (OB_FAIL(subschema_reverse_map_.create(SUBSCHEMA_BUCKET_NUM,
 | 
			
		||||
                                    "SubSchemaRev",
 | 
			
		||||
                                    "SubSchemaRev",
 | 
			
		||||
                                    MTL_ID()))) {
 | 
			
		||||
    LOG_WARN("fail to create subschema map", K(ret));
 | 
			
		||||
  } else {
 | 
			
		||||
    is_inited_ = true;
 | 
			
		||||
    used_subschema_id_ = MAX_NON_RESERVED_SUBSCHEMA_ID;
 | 
			
		||||
  }
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ObSubSchemaCtx::reset() {
 | 
			
		||||
  // content in subschema value is alloc from plan object allocator? need a new allocator?
 | 
			
		||||
  if (is_inited_) {
 | 
			
		||||
    subschema_map_.destroy();
 | 
			
		||||
    subschema_reverse_map_.destroy();
 | 
			
		||||
    is_inited_ = false;
 | 
			
		||||
    used_subschema_id_ = MAX_NON_RESERVED_SUBSCHEMA_ID;
 | 
			
		||||
    reserved_ = 0;
 | 
			
		||||
    fields_ = NULL;
 | 
			
		||||
    LOG_INFO("subschema ctx reset", KP(this), KP(this), K(lbt()));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t ObSubSchemaCtx::get_subschema_count() const
 | 
			
		||||
{
 | 
			
		||||
  uint32_t subschema_count = 0;
 | 
			
		||||
  if (!is_inited_) {
 | 
			
		||||
  } else {
 | 
			
		||||
    subschema_count = subschema_map_.size();
 | 
			
		||||
  }
 | 
			
		||||
  return subschema_count;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int ObSubSchemaCtx::get_new_subschema_id(uint16_t &subschema_id)
 | 
			
		||||
{
 | 
			
		||||
  int ret = OB_SUCCESS;
 | 
			
		||||
  subschema_id = used_subschema_id_++;
 | 
			
		||||
  if (used_subschema_id_ == UINT16_MAX) {
 | 
			
		||||
    ret = OB_ERR_UNEXPECTED;
 | 
			
		||||
    SQL_ENG_LOG(WARN, "more then 64K different subschema", K(ret), K(subschema_id), K(lbt()));
 | 
			
		||||
  } else {
 | 
			
		||||
    SQL_ENG_LOG(INFO, "new subschema id", KP(this), K(subschema_id), K(lbt()));
 | 
			
		||||
  }
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
int ObSubSchemaCtx::get_subschema_id_from_fields(uint64_t udt_id, uint16_t &subschema_id)
 | 
			
		||||
{
 | 
			
		||||
  int ret = OB_SUCCESS;
 | 
			
		||||
  subschema_id = ObInvalidSqlType;
 | 
			
		||||
  bool is_found = false;
 | 
			
		||||
  if (OB_NOT_NULL(fields_)) {
 | 
			
		||||
    for (uint32_t i = 0; is_found == false && OB_SUCC(ret) && i < fields_->count(); i++) {
 | 
			
		||||
      if ((fields_->at(i).type_.is_user_defined_sql_type()
 | 
			
		||||
            // || fields_->at(i).type_.is_collection_sql_type()
 | 
			
		||||
          )
 | 
			
		||||
          && fields_->at(i).accuracy_.get_accuracy() == udt_id) {
 | 
			
		||||
        subschema_id = fields_->at(i).type_.get_udt_subschema_id();
 | 
			
		||||
        is_found = true;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int ObSubSchemaCtx::set_subschema(uint16_t subschema_id, ObSubSchemaValue &value)
 | 
			
		||||
{
 | 
			
		||||
  int ret = OB_SUCCESS;
 | 
			
		||||
  uint64_t key = subschema_id;
 | 
			
		||||
  ObSubSchemaValue tmp_value;
 | 
			
		||||
  if (OB_FAIL(subschema_map_.get_refactored(key, tmp_value))) {
 | 
			
		||||
    if (OB_HASH_NOT_EXIST != ret) {
 | 
			
		||||
      LOG_WARN("failed to get subschema", K(ret), K(key), K(tmp_value), K(value));
 | 
			
		||||
    } else { // not exist
 | 
			
		||||
      ret = OB_SUCCESS;
 | 
			
		||||
      ObSubSchemaReverseKey rev_key(value.type_, value.signature_);
 | 
			
		||||
      LOG_INFO("add new subschema", K(ret), K(subschema_id), K(value));
 | 
			
		||||
      if (OB_FAIL(subschema_map_.set_refactored(key, value))) {
 | 
			
		||||
        LOG_WARN("set subschema map failed", K(ret), K(subschema_id));
 | 
			
		||||
      } else if (OB_FAIL(subschema_reverse_map_.set_refactored(rev_key, key))) {
 | 
			
		||||
        LOG_WARN("set subschema map failed", K(ret), K(rev_key));
 | 
			
		||||
        int tmp_ret = subschema_map_.erase_refactored(subschema_id);
 | 
			
		||||
        if (tmp_ret != OB_SUCCESS) {
 | 
			
		||||
          LOG_WARN("erase subschema map failed", K(ret), K(tmp_ret), K(subschema_id));
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  } else {
 | 
			
		||||
    ret = OB_ERR_UNEXPECTED;
 | 
			
		||||
    LOG_WARN("subschema id already exist", KP(this), K(ret), K(subschema_id), K(value));
 | 
			
		||||
  }
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int ObSubSchemaCtx::get_subschema(uint16_t subschema_id, ObSubSchemaValue &value) const
 | 
			
		||||
{
 | 
			
		||||
  uint64_t key = subschema_id;
 | 
			
		||||
  return subschema_map_.get_refactored(key, value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int ObSubSchemaCtx::get_subschema_id(uint64_t value_signature,
 | 
			
		||||
                                     ObSubSchemaType type,
 | 
			
		||||
                                     uint16_t &subschema_id) const
 | 
			
		||||
{
 | 
			
		||||
  ObSubSchemaReverseKey rev_key(type, value_signature);
 | 
			
		||||
  uint64_t value = ObMaxSystemUDTSqlType; // init invalid subschema value
 | 
			
		||||
  int ret = subschema_reverse_map_.get_refactored(rev_key, value);
 | 
			
		||||
  subschema_id = value;
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} //sql
 | 
			
		||||
} //oceanbase
 | 
			
		||||
							
								
								
									
										157
									
								
								src/sql/engine/ob_subschema_ctx.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										157
									
								
								src/sql/engine/ob_subschema_ctx.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,157 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright (c) 2021 OceanBase
 | 
			
		||||
 * OceanBase CE is licensed under Mulan PubL v2.
 | 
			
		||||
 * You can use this software according to the terms and conditions of the Mulan PubL v2.
 | 
			
		||||
 * You may obtain a copy of Mulan PubL v2 at:
 | 
			
		||||
 *          http://license.coscl.org.cn/MulanPubL-2.0
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 | 
			
		||||
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 | 
			
		||||
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 | 
			
		||||
 * See the Mulan PubL v2 for more details.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef OCEANBASE_SQL_OB_SUBSCHEMA_CTX_H
 | 
			
		||||
#define OCEANBASE_SQL_OB_SUBSCHEMA_CTX_H
 | 
			
		||||
 | 
			
		||||
#include "lib/oblog/ob_log_module.h"
 | 
			
		||||
#include "common/ob_field.h"
 | 
			
		||||
 | 
			
		||||
namespace oceanbase
 | 
			
		||||
{
 | 
			
		||||
namespace sql
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
// implement of subschema mapping
 | 
			
		||||
enum ObSubSchemaType {
 | 
			
		||||
  OB_SUBSCHEMA_UDT_TYPE = 0,
 | 
			
		||||
  OB_SUBSCHEMA_MAX_TYPE
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// key must be subschema (uint16_t)
 | 
			
		||||
// signature for value (refer to value serialize)
 | 
			
		||||
 | 
			
		||||
class ObSubSchemaValue
 | 
			
		||||
{
 | 
			
		||||
OB_UNIS_VERSION(1);
 | 
			
		||||
public:
 | 
			
		||||
  ObSubSchemaValue() : type_(OB_SUBSCHEMA_MAX_TYPE), signature_(0), value_(NULL) {}
 | 
			
		||||
  ~ObSubSchemaValue() {}
 | 
			
		||||
  int deep_copy_value(const void *src_value, ObIAllocator &allocator);
 | 
			
		||||
  TO_STRING_KV(K_(type), K_(signature), KP_(value));
 | 
			
		||||
public:
 | 
			
		||||
  ObSubSchemaType type_;
 | 
			
		||||
  uint64_t signature_;
 | 
			
		||||
  void *value_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef int (*ob_subschema_value_serialize)(void *value, char* buf, const int64_t buf_len, int64_t& pos);
 | 
			
		||||
typedef int (*ob_subschema_value_deserialize)(void *value, const char* buf, const int64_t data_len, int64_t& pos);
 | 
			
		||||
typedef int64_t (*ob_subschema_value_serialize_size)(void *value);
 | 
			
		||||
typedef int (*ob_subschema_value_get_signature)(void *value, uint64_t &signature);
 | 
			
		||||
 | 
			
		||||
typedef int (*ob_subschema_value_deep_copy)(const void *src_value, void *&dst_value, ObIAllocator &allocator);
 | 
			
		||||
 | 
			
		||||
struct ObSubSchemaFuncs
 | 
			
		||||
{
 | 
			
		||||
  ob_subschema_value_serialize value_serialize;
 | 
			
		||||
  ob_subschema_value_deserialize value_deserialize;
 | 
			
		||||
  ob_subschema_value_serialize_size get_value_serialize_size;
 | 
			
		||||
  ob_subschema_value_get_signature get_signature;
 | 
			
		||||
 | 
			
		||||
  ob_subschema_value_deep_copy deep_copy;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <ObSubSchemaType type>
 | 
			
		||||
    int subschema_value_serialize(void *value, char* buf, const int64_t buf_len, int64_t& pos);
 | 
			
		||||
template <ObSubSchemaType type>
 | 
			
		||||
    int subschema_value_deserialize(void *value, const char* buf, const int64_t data_len, int64_t& pos);
 | 
			
		||||
template <ObSubSchemaType type> int64_t subschema_value_serialize_size(void *value);
 | 
			
		||||
template <ObSubSchemaType type>
 | 
			
		||||
    int subschema_value_get_signature(void *value, uint64_t &signature);
 | 
			
		||||
template <ObSubSchemaType type>
 | 
			
		||||
    int subschema_value_deep_copy(const void *src_value, void *&dst_value, ObIAllocator &allocator);
 | 
			
		||||
 | 
			
		||||
class ObSubSchemaReverseKey
 | 
			
		||||
{
 | 
			
		||||
  public:
 | 
			
		||||
  ObSubSchemaReverseKey() : type_(OB_SUBSCHEMA_MAX_TYPE), signature_(0) {}
 | 
			
		||||
  ObSubSchemaReverseKey(ObSubSchemaType type, uint64_t signature) : type_(type), signature_(signature) {}
 | 
			
		||||
  ~ObSubSchemaReverseKey() {}
 | 
			
		||||
 | 
			
		||||
  uint64_t hash() const
 | 
			
		||||
  {
 | 
			
		||||
    return signature_ + static_cast<uint64_t>(type_);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  int hash(uint64_t &res) const
 | 
			
		||||
  {
 | 
			
		||||
    res = hash();
 | 
			
		||||
    return OB_SUCCESS;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool operator==(const ObSubSchemaReverseKey &other) const
 | 
			
		||||
  {
 | 
			
		||||
    return (other.type_ == this->type_
 | 
			
		||||
            && other.signature_ == this->signature_);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  TO_STRING_KV(K_(type), K_(signature));
 | 
			
		||||
  ObSubSchemaType type_;
 | 
			
		||||
  uint64_t signature_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class ObSubSchemaCtx
 | 
			
		||||
{
 | 
			
		||||
OB_UNIS_VERSION(1);
 | 
			
		||||
  typedef common::hash::ObHashMap<uint64_t, ObSubSchemaValue, common::hash::NoPthreadDefendMode> ObSubSchemaMap;
 | 
			
		||||
  // reverse map is used for confilict check and reverse search, reverse key is a signature from value;
 | 
			
		||||
  typedef common::hash::ObHashMap<ObSubSchemaReverseKey, uint64_t, common::hash::NoPthreadDefendMode> ObSubSchemaReverseMap;
 | 
			
		||||
  static const uint16_t MAX_NON_RESERVED_SUBSCHEMA_ID = ObInvalidSqlType + 1;
 | 
			
		||||
  static const uint32_t SUBSCHEMA_BUCKET_NUM = 64;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
  ObSubSchemaCtx(ObIAllocator &allocator) :
 | 
			
		||||
    is_inited_(false), used_subschema_id_(MAX_NON_RESERVED_SUBSCHEMA_ID),
 | 
			
		||||
    reserved_(0), fields_(NULL), allocator_(allocator) {}
 | 
			
		||||
 | 
			
		||||
  ~ObSubSchemaCtx() { reset(); }
 | 
			
		||||
 | 
			
		||||
  int init();
 | 
			
		||||
  bool is_inited() const { return is_inited_; }
 | 
			
		||||
  void reset();
 | 
			
		||||
  void destroy() { reset(); }
 | 
			
		||||
  int assgin(const ObSubSchemaCtx &other);
 | 
			
		||||
 | 
			
		||||
  uint32_t get_subschema_count() const;
 | 
			
		||||
 | 
			
		||||
  int get_new_subschema_id(uint16_t &subschema_id);
 | 
			
		||||
  int get_subschema_id_from_fields(uint64_t udt_id, uint16_t &subschema_id);
 | 
			
		||||
 | 
			
		||||
  int set_subschema(uint16_t subschema_id, ObSubSchemaValue &value);
 | 
			
		||||
  int get_subschema(uint16_t subschema_id, ObSubSchemaValue &value) const;
 | 
			
		||||
  ObSubSchemaMap &get_subschema_map() { return subschema_map_; }
 | 
			
		||||
  const ObSubSchemaMap &get_subschema_map() const { return subschema_map_; }
 | 
			
		||||
 | 
			
		||||
  int get_subschema_id(uint64_t value_signature, ObSubSchemaType type, uint16_t &subschema_id) const;
 | 
			
		||||
 | 
			
		||||
  void set_fields(const common::ObIArray<common::ObField> *fields) { fields_ = fields; }
 | 
			
		||||
  ObIAllocator &get_allocator() { return allocator_; }
 | 
			
		||||
 | 
			
		||||
  TO_STRING_KV(K_(is_inited), K_(used_subschema_id),
 | 
			
		||||
               K(subschema_map_.size()), K(subschema_reverse_map_.size()));
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
  bool is_inited_;
 | 
			
		||||
  uint16_t used_subschema_id_;
 | 
			
		||||
  uint32_t reserved_;
 | 
			
		||||
  const common::ObIArray<common::ObField> *fields_; // resultset fields, no need to serialize
 | 
			
		||||
 | 
			
		||||
  ObIAllocator &allocator_;
 | 
			
		||||
  ObSubSchemaMap subschema_map_; // subschema id mapping to subschema (e.g. udt meta)
 | 
			
		||||
  ObSubSchemaReverseMap subschema_reverse_map_; // subschema type+signature (e.g. udt_id) mapping to subschema id
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
#endif //OCEANBASE_SQL_OB_SUBSCHEMA_CTX_H
 | 
			
		||||
@ -132,6 +132,7 @@ struct ObParamInfo
 | 
			
		||||
  bool is_oracle_empty_string_;
 | 
			
		||||
  common::ObCollationType col_type_;
 | 
			
		||||
  common::ObPrecision precision_;
 | 
			
		||||
  uint64_t udt_id_;
 | 
			
		||||
 | 
			
		||||
  OB_UNIS_VERSION_V(1);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user