[FEAT MERGE][CP] 425 sql exec + enum set type refactoring CP 435
Co-authored-by: hezuojiao <hezuojiao@gmail.com>
This commit is contained in:
parent
e17fa92572
commit
92016c007e
1
deps/oblib/src/lib/CMakeLists.txt
vendored
1
deps/oblib/src/lib/CMakeLists.txt
vendored
@ -249,6 +249,7 @@ ob_set_subtarget(oblib_lib common_mixed
|
||||
xml/ob_binary_aggregate.cpp
|
||||
locale/ob_locale_type.cc
|
||||
locale/ob_locale.cpp
|
||||
enumset/ob_enum_set_meta.cpp
|
||||
)
|
||||
|
||||
ob_set_subtarget(oblib_lib lock
|
||||
|
179
deps/oblib/src/lib/enumset/ob_enum_set_meta.cpp
vendored
Normal file
179
deps/oblib/src/lib/enumset/ob_enum_set_meta.cpp
vendored
Normal file
@ -0,0 +1,179 @@
|
||||
/**
|
||||
* 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_enum_set_meta.h"
|
||||
#include "lib/container/ob_array_helper.h"
|
||||
#include "share/ob_define.h"
|
||||
|
||||
|
||||
namespace oceanbase {
|
||||
namespace common {
|
||||
|
||||
bool ObEnumSetMeta::is_same(const ObObjMeta &obj_meta, const ObStrValues &str_value) const
|
||||
{
|
||||
bool is_same_meta = true;
|
||||
if (OB_LIKELY(!is_valid())) {
|
||||
is_same_meta = false;
|
||||
} else if (obj_meta != obj_meta_) {
|
||||
is_same_meta = false;
|
||||
} else if (str_value.count() != str_values_->count()) {
|
||||
is_same_meta = false;
|
||||
} else {
|
||||
for (int64_t i = 0; is_same_meta && i < str_value.count(); ++i) {
|
||||
const ObString &str1 = str_value.at(i);
|
||||
const ObString &str2 = str_values_->at(i);
|
||||
if (str1.length() != str2.length()) {
|
||||
is_same_meta = false;
|
||||
} else {
|
||||
is_same_meta = (0 == MEMCMP(str1.ptr(), str2.ptr(), str1.length()));
|
||||
}
|
||||
}
|
||||
}
|
||||
return is_same_meta;
|
||||
}
|
||||
|
||||
bool ObEnumSetMeta::is_same(const ObEnumSetMeta &other) const
|
||||
{
|
||||
bool is_same_meta = true;
|
||||
if (this == &other) {
|
||||
is_same_meta = true;
|
||||
} else if (other.is_valid()) {
|
||||
is_same_meta = is_same(other.get_obj_meta(), *other.get_str_values());
|
||||
}
|
||||
return is_same_meta;
|
||||
}
|
||||
|
||||
uint64_t ObEnumSetMeta::hash() const
|
||||
{
|
||||
uint64_t hash_val = 0;
|
||||
if (is_valid()) {
|
||||
const uint64_t subschema_id = obj_meta_.get_subschema_id();
|
||||
hash_val = obj_meta_.is_set() ? subschema_id : ~subschema_id;
|
||||
for (int64_t i = 0; i < str_values_->count(); ++i) {
|
||||
hash_val = str_values_->at(i).hash(hash_val);
|
||||
}
|
||||
}
|
||||
return hash_val;
|
||||
}
|
||||
|
||||
int ObEnumSetMeta::deep_copy(ObIAllocator &allocator, ObEnumSetMeta *&dst) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
void *mem = NULL;
|
||||
const int64_t mem_size = sizeof(ObEnumSetMeta) + sizeof(ObFixedArray<ObString, ObIAllocator>);
|
||||
ObEnumSetMeta *meta = NULL;
|
||||
ObFixedArray<ObString, ObIAllocator> *str_values = NULL;
|
||||
if (OB_UNLIKELY(!is_valid())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("src meta is invalid", K(ret), KPC(this));
|
||||
} else if (OB_ISNULL(mem = allocator.alloc(mem_size))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("failed to alloc udt meta", K(ret), K(mem_size));
|
||||
} else {
|
||||
meta = new(mem)ObEnumSetMeta();
|
||||
void *array_ptr = static_cast<char*>(mem) + sizeof(ObEnumSetMeta);
|
||||
str_values = new(array_ptr) ObFixedArray<ObString, ObIAllocator>(allocator);
|
||||
if (OB_FAIL(str_values->init(str_values_->count()))) {
|
||||
LOG_WARN("fail to init array", K(ret));
|
||||
} else {
|
||||
// deep copy string
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < str_values_->count(); ++i) {
|
||||
ObString dst_str;
|
||||
if (OB_FAIL(ob_write_string(allocator, str_values_->at(i), dst_str))) {
|
||||
LOG_WARN("fail to deep copying string", K(ret));
|
||||
} else if (OB_FAIL(str_values->push_back(dst_str))) {
|
||||
LOG_WARN("push_back failed", K(ret));
|
||||
// free memory avoid memory leak
|
||||
for (int64_t j = 0; j < str_values->count(); ++j) {
|
||||
allocator.free(str_values->at(j).ptr());
|
||||
}
|
||||
allocator.free(dst_str.ptr());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
allocator.free(mem);
|
||||
mem = NULL;
|
||||
} else {
|
||||
meta->obj_meta_.set_meta(obj_meta_);
|
||||
meta->str_values_ = str_values;
|
||||
dst = meta;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static_assert(ObEnumSetMeta::MetaState::UNINITIALIZED == SCALE_UNKNOWN_YET,
|
||||
"make sure the value of uninitialized state always be equal to scale unkown yet");
|
||||
|
||||
OB_DEF_SERIALIZE(ObEnumSetMeta)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_UNLIKELY(!is_valid())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("src meta is invalid", K(ret), KPC(this));
|
||||
} else {
|
||||
OB_UNIS_ENCODE(obj_meta_);
|
||||
OB_UNIS_ENCODE_ARRAY(str_values_->get_data(), str_values_->count());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
OB_DEF_DESERIALIZE(ObEnumSetMeta)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
int64_t count = 0;
|
||||
OB_UNIS_DECODE(obj_meta_);
|
||||
OB_UNIS_DECODE(count);
|
||||
const int64_t array_size = sizeof(ObArrayHelper<ObString>); // for array container
|
||||
const int64_t strings_size = count * sizeof(ObString); // for string data
|
||||
void *mem = NULL;
|
||||
if (OB_ISNULL(allocator_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("allocator is need for deserialize", K(ret), K(lbt()));
|
||||
} else if (OB_UNLIKELY(0 == count)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("string values count is zero", K(ret));
|
||||
} else if (OB_ISNULL(mem = allocator_->alloc(strings_size + array_size))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("fail to allocate mem", K(ret), K(strings_size), K(array_size));
|
||||
} else if (FALSE_IT(MEMSET(mem, 0, strings_size + array_size))) {
|
||||
} else {
|
||||
ObArrayHelper<ObString> *array_helper = new(mem)(ObArrayHelper<ObString>);
|
||||
ObString *strings = reinterpret_cast<ObString*>(static_cast<char*>(mem) + array_size);
|
||||
OB_UNIS_DECODE_ARRAY(strings, count);
|
||||
if (OB_SUCC(ret)) {
|
||||
array_helper->init(count, strings, count);
|
||||
str_values_ = array_helper;
|
||||
}
|
||||
}
|
||||
if (OB_FAIL(ret) && OB_NOT_NULL(mem)) {
|
||||
allocator_->free(mem);
|
||||
str_values_ = NULL;
|
||||
mem = NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
OB_DEF_SERIALIZE_SIZE(ObEnumSetMeta)
|
||||
{
|
||||
int64_t len = 0;
|
||||
if (is_valid()) {
|
||||
OB_UNIS_ADD_LEN(obj_meta_);
|
||||
OB_UNIS_ADD_LEN_ARRAY(str_values_->get_data(), str_values_->count());
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
} // namespace common
|
||||
} // namespace oceanbase
|
102
deps/oblib/src/lib/enumset/ob_enum_set_meta.h
vendored
Normal file
102
deps/oblib/src/lib/enumset/ob_enum_set_meta.h
vendored
Normal file
@ -0,0 +1,102 @@
|
||||
/**
|
||||
* 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_ENUM_SET_EMTA_TYPE_
|
||||
#define OCEANBASE_OB_ENUM_SET_EMTA_TYPE_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "common/object/ob_object.h"
|
||||
#include "lib/container/ob_array_helper.h"
|
||||
#include "lib/string/ob_string.h"
|
||||
#include "share/ob_cluster_version.h"
|
||||
|
||||
namespace oceanbase {
|
||||
namespace common {
|
||||
|
||||
/**
|
||||
* The struct ObEnumSetMeta is primarily used to store complex meta-information about
|
||||
* `enum` and `set` types. It contains `obj_meta` to save `cs_type` and array `str_values` that
|
||||
* encapsulates the set of string representations associated with the enumerated type values.
|
||||
* It is intended to be stored within `ObSubSchemaCtx` and is utilized during the execution phase
|
||||
* to retrieve the extended type info about enum/set type.
|
||||
*/
|
||||
struct ObEnumSetMeta
|
||||
{
|
||||
OB_UNIS_VERSION(1);
|
||||
|
||||
private:
|
||||
typedef ObIArray<common::ObString> ObStrValues;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Since the `scale` field within the `ObExprResType` of the enum/set type is not used, we use
|
||||
* this field to save the meta state.
|
||||
*/
|
||||
enum MetaState
|
||||
{
|
||||
UNINITIALIZED = -1, // meta has not been saved, -1(SCALE_UNKNOWN_YET) as the default value
|
||||
SKIP = 0, // used in pl, compilation and running are separated, so skip this scenario
|
||||
READY = 1, // meta has been saved in `ObSubSchemaCtx`
|
||||
MAX_STATE
|
||||
};
|
||||
|
||||
public:
|
||||
ObEnumSetMeta(common::ObIAllocator *alloc = NULL) : obj_meta_(), str_values_(NULL),
|
||||
allocator_(alloc) {}
|
||||
ObEnumSetMeta(ObObjMeta obj_meta, const ObStrValues *str_value) :
|
||||
obj_meta_(obj_meta), str_values_(str_value), allocator_(NULL) {}
|
||||
inline bool is_valid() const
|
||||
{
|
||||
return obj_meta_.is_enum_or_set() && NULL != str_values_ && !str_values_->empty();
|
||||
}
|
||||
bool is_same(const ObObjMeta &obj_meta, const ObStrValues &str_value) const;
|
||||
bool is_same(const ObEnumSetMeta &other) const;
|
||||
uint64_t hash() const;
|
||||
int hash(uint64_t &res) const
|
||||
{
|
||||
res = hash();
|
||||
return common::OB_SUCCESS;
|
||||
}
|
||||
inline bool operator ==(const ObEnumSetMeta &other) const { return is_same(other); }
|
||||
inline bool operator !=(const ObEnumSetMeta &other) const { return !this->operator==(other); }
|
||||
int deep_copy(ObIAllocator &allocator, ObEnumSetMeta *&dst) const;
|
||||
void destroy()
|
||||
{
|
||||
if (OB_NOT_NULL(allocator_) && OB_NOT_NULL(str_values_)) {
|
||||
allocator_->free(const_cast<ObStrValues *>(str_values_));
|
||||
allocator_ = NULL;
|
||||
}
|
||||
}
|
||||
inline uint64_t get_signature() const { return udt_id_; }
|
||||
inline const common::ObObjMeta &get_obj_meta() const { return obj_meta_; }
|
||||
inline ObObjType get_type() const { return obj_meta_.get_type(); }
|
||||
inline ObCollationType get_collation_type() const { return obj_meta_.get_collation_type(); }
|
||||
inline ObCollationLevel get_collation_level() const { return obj_meta_.get_collation_level(); }
|
||||
inline const ObStrValues *get_str_values() const { return str_values_; }
|
||||
|
||||
TO_STRING_KV(K_(obj_meta), KP_(str_values), KP_(allocator));
|
||||
|
||||
private:
|
||||
common::ObObjMeta obj_meta_; // original type obj meta
|
||||
union
|
||||
{
|
||||
const ObStrValues *str_values_; // pointer to extended type info
|
||||
uint64_t udt_id_;
|
||||
};
|
||||
common::ObIAllocator *allocator_; // used for deserialize only
|
||||
};
|
||||
|
||||
|
||||
} // namespace common
|
||||
} // namespace oceanbase
|
||||
#endif // OCEANBASE_OB_ENUM_SET_EMTA_TYPE_
|
9
deps/oblib/src/lib/rc/context.cpp
vendored
9
deps/oblib/src/lib/rc/context.cpp
vendored
@ -56,5 +56,14 @@ MemoryContext &MemoryContext::root()
|
||||
return root;
|
||||
}
|
||||
|
||||
int64_t MemoryContext::tree_mem_hold()
|
||||
{
|
||||
int64_t total = 0;
|
||||
if (OB_LIKELY(ref_context_ != nullptr)) {
|
||||
total = ref_context_->tree_mem_hold();
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
} // end of namespace lib
|
||||
} // end of namespace oceanbase
|
||||
|
16
deps/oblib/src/lib/rc/context.h
vendored
16
deps/oblib/src/lib/rc/context.h
vendored
@ -67,7 +67,6 @@ namespace lib
|
||||
CONTEXT_P(condition, lib::ContextSource::CREATE, \
|
||||
lib::DynamicInfo(), __VA_ARGS__, &static_info)
|
||||
|
||||
|
||||
using std::nullptr_t;
|
||||
using lib::ObMemAttr;
|
||||
class Flow;
|
||||
@ -286,6 +285,7 @@ public:
|
||||
__MemoryContext__ *ref_context() const
|
||||
{ return ref_context_; }
|
||||
bool check_magic_code() const { return MAGIC_CODE == magic_code_; }
|
||||
int64_t tree_mem_hold();
|
||||
static MemoryContext &root();
|
||||
private:
|
||||
int64_t magic_code_;
|
||||
@ -606,6 +606,20 @@ public:
|
||||
destory_context(ref_context);
|
||||
}
|
||||
}
|
||||
int64_t tree_mem_hold()
|
||||
{
|
||||
int64_t total = 0;
|
||||
if (!tree_node_.with_lock_) {
|
||||
TreeNode *child_node = tree_node_.child_;
|
||||
while (child_node != nullptr) {
|
||||
__MemoryContext__ *child = node2context(child_node);
|
||||
total += child->tree_mem_hold();
|
||||
child_node = child_node->next_;
|
||||
}
|
||||
total += hold();
|
||||
}
|
||||
return total;
|
||||
}
|
||||
public:
|
||||
int64_t magic_code_;
|
||||
int64_t seq_id_;
|
||||
|
3
deps/oblib/src/lib/udt/ob_collection_type.h
vendored
3
deps/oblib/src/lib/udt/ob_collection_type.h
vendored
@ -75,6 +75,8 @@ public:
|
||||
ObSqlCollectionInfo(ObIAllocator &allocator)
|
||||
: allocator_(allocator), name_len_(0),
|
||||
name_def_(nullptr), collection_meta_(nullptr) {}
|
||||
ObSqlCollectionInfo(common::ObIAllocator *allocator)
|
||||
: ObSqlCollectionInfo(*allocator) {}
|
||||
virtual ~ObSqlCollectionInfo() {}
|
||||
void set_name(ObString &name)
|
||||
{
|
||||
@ -89,6 +91,7 @@ public:
|
||||
}
|
||||
|
||||
ObString get_def_string() const {return ObString(name_len_, name_def_);}
|
||||
int64_t get_signature() const { return get_def_string().hash(); }
|
||||
int get_child_def_string(ObString &child_def) const;
|
||||
int deep_copy(ObIAllocator &allocator, ObSqlCollectionInfo *&dst) const;
|
||||
int create_meta_info_by_name(const std::string &name, ObCollectionTypeBase *&meta_info, uint8_t &arr_depth);
|
||||
|
5
deps/oblib/src/lib/udt/ob_udt_type.h
vendored
5
deps/oblib/src/lib/udt/ob_udt_type.h
vendored
@ -65,6 +65,10 @@ typedef struct ObSqlUDTMeta
|
||||
{
|
||||
OB_UNIS_VERSION(1);
|
||||
public:
|
||||
ObSqlUDTMeta(common::ObIAllocator *alloc = NULL)
|
||||
{
|
||||
reset();
|
||||
}
|
||||
void set_name(ObString &name)
|
||||
{
|
||||
udt_name_ = name.ptr();
|
||||
@ -114,6 +118,7 @@ public:
|
||||
|
||||
int deep_copy(ObIAllocator &allocator, ObSqlUDTMeta *&dst) const;
|
||||
|
||||
inline uint64_t get_signature() const { return udt_id_; }
|
||||
TO_STRING_KV(K_(attribute_cnt),
|
||||
K_(fixed_attr_cnt),
|
||||
K_(fixed_offset),
|
||||
|
@ -151,6 +151,7 @@ public:
|
||||
void set_collation_level(common::ObCollationLevel cs_level);
|
||||
void set_collation_type(common::ObCollationType cs_type);
|
||||
void set_accuracy(const common::ObAccuracy &accuracy);
|
||||
void set_collation(const common::ObObjMeta &meta_type);
|
||||
void set_result_flag(const uint32_t flag);
|
||||
void set_scale(const int16_t scale);
|
||||
void set_precision(const int16_t precision);
|
||||
@ -163,6 +164,12 @@ public:
|
||||
|
||||
virtual int64_t get_children_count() const;
|
||||
virtual int get_children(ExprArray &jit_exprs) const;
|
||||
// used for record meta state for enum/set types
|
||||
void mark_enum_set_with_subschema();
|
||||
void mark_enum_set_skip_build_subschema();
|
||||
void reset_enum_set_meta_state();
|
||||
bool is_enum_set_with_subschema() const;
|
||||
bool skip_build_subschema_for_enumset() const;
|
||||
|
||||
TO_STRING_KV(K_(type), K_(expr_class));
|
||||
|
||||
@ -275,6 +282,10 @@ inline void ObIRawExpr::set_accuracy(const common::ObAccuracy &accuracy)
|
||||
{
|
||||
result_type_.set_accuracy(accuracy);
|
||||
}
|
||||
inline void ObIRawExpr::set_collation(const common::ObObjMeta &meta_type)
|
||||
{
|
||||
result_type_.set_collation(meta_type);
|
||||
}
|
||||
inline void ObIRawExpr::set_result_flag(const uint32_t flag)
|
||||
{
|
||||
result_type_.set_result_flag(flag);
|
||||
@ -327,6 +338,29 @@ inline int ObIRawExpr::accept(Visitor __attribute__ ((unused)) &v) const
|
||||
return common::OB_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
inline void ObIRawExpr::mark_enum_set_with_subschema()
|
||||
{
|
||||
result_type_.mark_enum_set_with_subschema();
|
||||
}
|
||||
|
||||
inline void ObIRawExpr::mark_enum_set_skip_build_subschema()
|
||||
{
|
||||
result_type_.set_scale(ObEnumSetMeta::MetaState::SKIP);
|
||||
}
|
||||
|
||||
inline void ObIRawExpr::reset_enum_set_meta_state() { result_type_.reset_enum_set_meta_state(); }
|
||||
|
||||
inline bool ObIRawExpr::is_enum_set_with_subschema() const
|
||||
{
|
||||
return result_type_.is_enum_set_with_subschema();
|
||||
}
|
||||
|
||||
inline bool ObIRawExpr::skip_build_subschema_for_enumset() const
|
||||
{
|
||||
return result_type_.get_scale() == ObEnumSetMeta::MetaState::SKIP ||
|
||||
result_type_.get_scale() == ObEnumSetMeta::MetaState::READY;
|
||||
}
|
||||
|
||||
} // expr
|
||||
} // jit
|
||||
} // oceanbase
|
||||
|
@ -682,6 +682,8 @@ int ObInnerSQLConnection::do_query(sqlclient::ObIExecutor &executor, ObInnerSQLR
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
WITH_CONTEXT(res.mem_context_) {
|
||||
// are there no restrictions on internal SQL such as refresh schema?
|
||||
// MEM_TRACKER_GUARD(CURRENT_CONTEXT);
|
||||
// restore有自己的inner_sql_connection,sql_modifier不为null
|
||||
bool is_restore = NULL != sql_modifier_;
|
||||
res.sql_ctx().is_restore_ = is_restore;
|
||||
|
@ -2708,8 +2708,8 @@ int ObCleanSequenceCacheP::process()
|
||||
if (OB_ISNULL(GCTX.schema_service_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("schema service is null", K(ret));
|
||||
} else if (OB_FAIL(sequence_cache.remove(MTL_ID(), sequence_id))) {
|
||||
LOG_WARN("remove sequence item from sequence cache failed", K(ret), K(sequence_id));
|
||||
} else if (OB_FAIL(sequence_cache.remove(MTL_ID(), sequence_id, result_))) {
|
||||
LOG_WARN("remove sequence item from sequence cache failed", K(ret), K(sequence_id), K(result_));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "observer/ob_server.h"
|
||||
#include "storage/memtable/ob_lock_wait_mgr.h"
|
||||
#include "sql/session/ob_sql_session_info.h"
|
||||
#include "sql/executor/ob_memory_tracker.h"
|
||||
|
||||
using namespace oceanbase;
|
||||
using namespace oceanbase::lib;
|
||||
@ -350,6 +351,7 @@ void ObThWorker::worker(int64_t &tenant_id, int64_t &req_recv_timestamp, int32_t
|
||||
.set_properties(lib::USE_TL_PAGE_OPTIONAL)
|
||||
.set_ablock_size(lib::INTACT_MIDDLE_AOBJECT_SIZE);
|
||||
CREATE_WITH_TEMP_CONTEXT(param) {
|
||||
MEM_TRACKER_GUARD(CURRENT_CONTEXT);
|
||||
const uint64_t owner_id =
|
||||
(!is_virtual_tenant_id(tenant_->id()) || is_virtual_tenant_for_memory(tenant_->id())) ?
|
||||
tenant_->id() : OB_SERVER_TENANT_ID;
|
||||
@ -473,7 +475,8 @@ int ObThWorker::check_status()
|
||||
}
|
||||
|
||||
if (OB_SUCC(ret)) {
|
||||
if (is_timeout()) {
|
||||
if (OB_UNLIKELY((OB_SUCCESS != (ret = CHECK_MEM_STATUS())))) {
|
||||
} else if (is_timeout()) {
|
||||
ret = OB_TIMEOUT;
|
||||
} else {
|
||||
if (WS_OUT_OF_THROTTLE == check_wait()) {
|
||||
|
@ -2592,6 +2592,8 @@ int ObPLResolver::build_record_type_by_table_schema(ObSchemaGetterGuard &schema_
|
||||
if (column_schema.is_enum_or_set()) {
|
||||
OZ (pl_type.set_type_info(column_schema.get_extended_type_info()));
|
||||
}
|
||||
data_type.set_collation_level(
|
||||
ObRawExprUtils::get_column_collation_level(column_schema.get_data_type()));
|
||||
OX (pl_type.set_data_type(data_type));
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
@ -10269,7 +10271,7 @@ int ObPLResolver::resolve_expr(const ParseNode *node,
|
||||
}
|
||||
} else if (need_cast) {
|
||||
bool need_wrap = false;
|
||||
OZ (ObRawExprUtils::need_wrap_to_string(expr->get_result_type().get_type(),
|
||||
OZ (ObRawExprUtils::need_wrap_to_string(expr->get_result_type(),
|
||||
data_type->get_obj_type(),
|
||||
true,
|
||||
need_wrap));
|
||||
@ -13886,6 +13888,7 @@ int ObPLResolver::make_var_from_access(const ObIArray<ObObjAccessIdx> &access_id
|
||||
OZ (c_expr->add_flag(IS_DYNAMIC_PARAM));
|
||||
if (OB_SUCC(ret) && ob_is_enum_or_set_type(res_type.get_type())) {
|
||||
c_expr->add_flag(IS_ENUM_OR_SET);
|
||||
c_expr->mark_enum_set_skip_build_subschema();
|
||||
}
|
||||
OZ (c_expr->extract_info());
|
||||
OX (expr = c_expr);
|
||||
@ -14080,6 +14083,10 @@ int ObPLResolver::convert_pltype_to_restype(ObIAllocator &alloc,
|
||||
result_type->set_collation_type(data_type->get_collation_type());
|
||||
result_type->set_collation_level(data_type->get_collation_level());
|
||||
result_type->set_scale(data_type->get_scale());
|
||||
} else if (ob_is_enumset_tc(result_type->get_type())) {
|
||||
result_type->set_collation_type(data_type->get_collation_type());
|
||||
result_type->set_collation_level(data_type->get_collation_level());
|
||||
result_type->set_accuracy(data_type->get_accuracy());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -261,7 +261,7 @@ public:
|
||||
// Notice:
|
||||
// 1. all lobs created by this class should be temp lobs
|
||||
// 2. if has_lob_header_ is false, the text result should be 4.0 compatible
|
||||
int init(const int64_t res_len, ObIAllocator *allocator = NULL);
|
||||
virtual int init(const int64_t res_len, ObIAllocator *allocator = NULL);
|
||||
int init(const int64_t res_len, ObString &res_buffer);
|
||||
|
||||
// copy existent loc to result
|
||||
|
@ -12530,6 +12530,28 @@ int ObTTLResponseArg::assign(const ObTTLResponseArg &other)
|
||||
return ret;
|
||||
}
|
||||
|
||||
OB_SERIALIZE_MEMBER(ObSeqCleanCacheRes, inited_, with_prefetch_node_, cache_node_, prefetch_node_);
|
||||
|
||||
ObSeqCleanCacheRes::ObSeqCleanCacheRes()
|
||||
: inited_(false), with_prefetch_node_(false), cache_node_(), prefetch_node_()
|
||||
{
|
||||
}
|
||||
|
||||
int ObSeqCleanCacheRes::assign(const ObSeqCleanCacheRes &other)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (this == &other) {
|
||||
} else if (OB_FAIL(cache_node_.assign(other.cache_node_))) {
|
||||
LOG_WARN("fail to assign cache node", K(ret));
|
||||
} else if (OB_FAIL(prefetch_node_.assign(other.prefetch_node_))) {
|
||||
LOG_WARN("fail to assign prefetch node", K(ret));
|
||||
} else {
|
||||
inited_ = other.inited_;
|
||||
with_prefetch_node_ = other.with_prefetch_node_;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
OB_SERIALIZE_MEMBER(ObTTLRequestArg, cmd_code_, trigger_type_, task_id_, tenant_id_);
|
||||
|
||||
int ObTTLRequestArg::assign(const ObTTLRequestArg &other)
|
||||
|
@ -92,6 +92,7 @@
|
||||
#endif
|
||||
#include "storage/tablelock/ob_table_lock_common.h" //ObTableLockPriority
|
||||
#include "storage/mview/ob_major_mv_merge_info.h" //ObMajorMVMergeInfo
|
||||
#include "share/sequence/ob_sequence_cache.h" // ObSeqCleanCacheRes
|
||||
|
||||
namespace oceanbase
|
||||
{
|
||||
@ -12773,6 +12774,22 @@ public:
|
||||
uint8_t task_status_;
|
||||
int err_code_;
|
||||
};
|
||||
|
||||
struct ObSeqCleanCacheRes final {
|
||||
OB_UNIS_VERSION(1);
|
||||
|
||||
public:
|
||||
ObSeqCleanCacheRes();
|
||||
int assign(const ObSeqCleanCacheRes &other);
|
||||
TO_STRING_KV(K_(inited), K_(with_prefetch_node), K_(cache_node), K_(prefetch_node));
|
||||
|
||||
public:
|
||||
bool inited_;
|
||||
bool with_prefetch_node_;
|
||||
share::SequenceCacheNode cache_node_;
|
||||
share::SequenceCacheNode prefetch_node_;
|
||||
};
|
||||
|
||||
struct ObAdminUnlockMemberListOpArg final
|
||||
{
|
||||
OB_UNIS_VERSION(1);
|
||||
|
@ -242,7 +242,7 @@ public:
|
||||
#endif
|
||||
RPC_S(PR5 remote_write_ddl_inc_commit_log, OB_REMOTE_WRITE_DDL_INC_COMMIT_LOG, (obrpc::ObRpcRemoteWriteDDLIncCommitLogArg), ObRpcRemoteWriteDDLIncCommitLogRes);
|
||||
RPC_S(PR5 check_ls_can_offline, OB_CHECK_LS_CAN_OFFLINE, (obrpc::ObCheckLSCanOfflineArg));
|
||||
RPC_S(PR5 clean_sequence_cache, obrpc::OB_CLEAN_SEQUENCE_CACHE, (obrpc::UInt64));
|
||||
RPC_S(PR5 clean_sequence_cache, obrpc::OB_CLEAN_SEQUENCE_CACHE, (obrpc::UInt64), obrpc::ObSeqCleanCacheRes);
|
||||
RPC_S(PR5 register_tx_data, OB_REGISTER_TX_DATA, (ObRegisterTxDataArg), ObRegisterTxDataResult);
|
||||
RPC_S(PR5 query_ls_is_valid_member, OB_QUERY_LS_IS_VALID_MEMBER, (ObQueryLSIsValidMemberRequest),
|
||||
ObQueryLSIsValidMemberResponse);
|
||||
|
@ -35,6 +35,8 @@
|
||||
#include "sql/engine/expr/ob_expr_sql_udt_utils.h"
|
||||
#include "sql/engine/expr/ob_array_expr_utils.h"
|
||||
#include "sql/engine/expr/ob_array_cast.h"
|
||||
#include "sql/engine/expr/ob_expr_json_func_helper.h"
|
||||
#include "sql/engine/expr/ob_expr_type_to_str.h"
|
||||
#include "sql/engine/ob_exec_context.h"
|
||||
#include "lib/charset/ob_charset.h"
|
||||
#include "lib/geo/ob_geometry_cast.h"
|
||||
@ -6811,6 +6813,74 @@ static int bit_geometry(const ObObjType expect_type, ObObjCastParams ¶ms,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool is_enum_set_with_subschema(const ObObj &in)
|
||||
{
|
||||
return in.get_scale() == ObEnumSetMeta::MetaState::READY;
|
||||
}
|
||||
|
||||
static OB_INLINE int common_enumset_string(const ObObj &in,
|
||||
ObObjCastParams ¶ms,
|
||||
ObTextStringResult &text_result)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
const ObEnumSetMeta *meta = NULL;
|
||||
const ObObjType in_type = in.get_type();
|
||||
if (0 == in.get_uint64()) {
|
||||
// empty string, do nothing
|
||||
} else {
|
||||
const uint16_t subschema_id = in.get_meta().get_subschema_id();
|
||||
if (OB_ISNULL(params.exec_ctx_)) {
|
||||
ret = OB_ERR_UNDEFINED;
|
||||
LOG_WARN("exec ctx is null", K(ret));
|
||||
} else if (OB_FAIL(params.exec_ctx_->get_enumset_meta_by_subschema_id(subschema_id, meta))) {
|
||||
LOG_WARN("failed to get udt meta", K(ret), K(subschema_id));
|
||||
} else if (OB_ISNULL(meta) || OB_ISNULL(meta->get_str_values())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("fail to get meta", K(ret));
|
||||
} else if (ObEnumType == in_type) {
|
||||
ret = ObExprEnumToStr::inner_to_str(in.get_uint64(), *meta->get_str_values(), text_result);
|
||||
} else if (ObSetType == in_type) {
|
||||
ret = ObExprSetToStr::inner_to_str(in.get_collation_type(), in.get_uint64(),
|
||||
*meta->get_str_values(), text_result);
|
||||
} else {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected expr type", K(ret), K(in_type));
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int enumset_enumset(const ObExpectType &expect_type, ObObjCastParams ¶ms,
|
||||
const ObObj &in, ObObj &out)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (!is_enum_set_with_subschema(in)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected cast", K(ret), K(in));
|
||||
} else if (OB_UNLIKELY(ObEnumSetTC != in.get_type_class()
|
||||
|| ObEnumSetTC != ob_obj_type_class(expect_type.get_type()))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_ERROR("invalid input type", K(ret), K(in), K(expect_type));
|
||||
} else {
|
||||
ObTextStringResult text_result(ObVarcharType, false, params.allocator_v2_);
|
||||
ObString es_str;
|
||||
ObObj temp_obj;
|
||||
if (OB_FAIL(common_enumset_string(in, params, text_result))) {
|
||||
LOG_WARN("common_enumset_string failed", K(ret), K(in));
|
||||
} else if (FALSE_IT(text_result.get_result_buffer(es_str))) {
|
||||
} else if (FALSE_IT(temp_obj.set_varchar(es_str))) {
|
||||
} else if (expect_type.get_type() == ObEnumType &&
|
||||
OB_FAIL(string_enum(expect_type, params, temp_obj, out))) {
|
||||
LOG_WARN("common_string_datetime failed", K(ret), K(es_str));
|
||||
} else if (expect_type.get_type() == ObSetType &&
|
||||
OB_FAIL(string_set(expect_type, params, temp_obj, out))) {
|
||||
LOG_WARN("common_string_datetime failed", K(ret), K(es_str));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// enum -> XXX
|
||||
/*//来自同一个enum 列的obj转换使用应该使用该接口,来自不同enum列的转换使用enumsetinner_enum
|
||||
@ -6991,8 +7061,8 @@ ObCastEnumOrSetFunc OB_CAST_ENUM_OR_SET[ObMaxTC][2] =
|
||||
},
|
||||
{
|
||||
/*enumset tc -> enum_or_set*/
|
||||
cast_not_expected_enum_set,/*enum*/
|
||||
cast_not_expected_enum_set,/*set*/
|
||||
enumset_enumset,/*enum*/
|
||||
enumset_enumset,/*set*/
|
||||
},
|
||||
{
|
||||
/*enumset_inner tc -> enum_or_set*/
|
||||
@ -7165,6 +7235,84 @@ static int enumset_number(const ObObjType expect_type, ObObjCastParams ¶ms,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int enumset_datetime(const ObObjType expect_type, ObObjCastParams ¶ms,
|
||||
const ObObj &in, ObObj &out, const ObCastMode cast_mode)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (!is_enum_set_with_subschema(in)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected cast", K(ret), K(in));
|
||||
} else if (OB_UNLIKELY(ObEnumSetTC != in.get_type_class()
|
||||
|| ObDateTimeTC != ob_obj_type_class(expect_type))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_ERROR("invalid input type", K(ret), K(in), K(expect_type));
|
||||
} else {
|
||||
ObTextStringResult text_result(ObVarcharType, false, params.allocator_v2_);
|
||||
ObString es_str;
|
||||
ObObj temp_obj;
|
||||
if (OB_FAIL(common_enumset_string(in, params, text_result))) {
|
||||
LOG_WARN("common_enumset_string failed", K(ret), K(in));
|
||||
} else if (FALSE_IT(text_result.get_result_buffer(es_str))) {
|
||||
} else if (FALSE_IT(temp_obj.set_varchar(es_str))) {
|
||||
} else if (OB_FAIL(string_datetime(expect_type, params, temp_obj, out, cast_mode))) {
|
||||
LOG_WARN("common_string_datetime failed", K(ret), K(es_str));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int enumset_date(const ObObjType expect_type, ObObjCastParams ¶ms,
|
||||
const ObObj &in, ObObj &out, const ObCastMode cast_mode)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (!is_enum_set_with_subschema(in)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected cast", K(ret), K(in));
|
||||
} else if (OB_UNLIKELY(ObEnumSetTC != in.get_type_class()
|
||||
|| ObDateTC != ob_obj_type_class(expect_type))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_ERROR("invalid input type", K(ret), K(in), K(expect_type));
|
||||
} else {
|
||||
ObTextStringResult text_result(ObVarcharType, false, params.allocator_v2_);
|
||||
ObString es_str;
|
||||
ObObj temp_obj;
|
||||
if (OB_FAIL(common_enumset_string(in, params, text_result))) {
|
||||
LOG_WARN("common_enumset_string failed", K(ret), K(in));
|
||||
} else if (FALSE_IT(text_result.get_result_buffer(es_str))) {
|
||||
} else if (FALSE_IT(temp_obj.set_varchar(es_str))) {
|
||||
} else if (OB_FAIL(string_date(expect_type, params, temp_obj, out, cast_mode))) {
|
||||
LOG_WARN("common_string_datetime failed", K(ret), K(es_str));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int enumset_time(const ObObjType expect_type, ObObjCastParams ¶ms,
|
||||
const ObObj &in, ObObj &out, const ObCastMode cast_mode)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (!is_enum_set_with_subschema(in)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected cast", K(ret), K(in));
|
||||
} else if (OB_UNLIKELY(ObEnumSetTC != in.get_type_class()
|
||||
|| ObTimeTC != ob_obj_type_class(expect_type))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_ERROR("invalid input type", K(ret), K(in), K(expect_type));
|
||||
} else {
|
||||
ObTextStringResult text_result(ObVarcharType, false, params.allocator_v2_);
|
||||
ObString es_str;
|
||||
ObObj temp_obj;
|
||||
if (OB_FAIL(common_enumset_string(in, params, text_result))) {
|
||||
LOG_WARN("common_enumset_string failed", K(ret), K(in));
|
||||
} else if (FALSE_IT(text_result.get_result_buffer(es_str))) {
|
||||
} else if (FALSE_IT(temp_obj.set_varchar(es_str))) {
|
||||
} else if (OB_FAIL(string_time(expect_type, params, temp_obj, out, cast_mode))) {
|
||||
LOG_WARN("common_string_datetime failed", K(ret), K(es_str));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int enumset_year(const ObObjType expect_type, ObObjCastParams ¶ms,
|
||||
const ObObj &in, ObObj &out, const ObCastMode cast_mode)
|
||||
{
|
||||
@ -7182,6 +7330,63 @@ static int enumset_year(const ObObjType expect_type, ObObjCastParams ¶ms,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int enumset_string(const ObObjType expect_type, ObObjCastParams ¶ms,
|
||||
const ObObj &in, ObObj &out, const ObCastMode cast_mode)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObLength res_length = -1;
|
||||
if (!is_enum_set_with_subschema(in)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected cast", K(ret), K(in));
|
||||
} else if (OB_UNLIKELY(ObEnumSetTC != in.get_type_class()
|
||||
|| ObStringTC != ob_obj_type_class(expect_type))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_ERROR("invalid input type", K(ret), K(in), K(expect_type));
|
||||
} else {
|
||||
ObTextStringResult text_result(expect_type, false, params.allocator_v2_);
|
||||
if (OB_FAIL(common_enumset_string(in, params, text_result))) {
|
||||
LOG_WARN("common_enumset_string failed", K(ret), K(in));
|
||||
} else {
|
||||
ObString es_str;
|
||||
text_result.get_result_buffer(es_str);
|
||||
out.set_string(expect_type, es_str);
|
||||
if (OB_SUCC(ret)) {
|
||||
res_length = static_cast<ObLength>(out.get_string_len());
|
||||
out.set_collation_type(params.dest_collation_);
|
||||
}
|
||||
}
|
||||
}
|
||||
SET_RES_ACCURACY_STRING(expect_type, DEFAULT_PRECISION_FOR_STRING, res_length);
|
||||
UNUSED(cast_mode);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int enumset_text(const ObObjType expect_type, ObObjCastParams ¶ms,
|
||||
const ObObj &in, ObObj &out, const ObCastMode cast_mode)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (!is_enum_set_with_subschema(in)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected cast", K(ret), K(in));
|
||||
} else if (OB_UNLIKELY(ObEnumSetTC != in.get_type_class()
|
||||
|| ObTextTC != ob_obj_type_class(expect_type))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_ERROR("invalid input type", K(ret), K(in), K(expect_type));
|
||||
} else {
|
||||
ObTextStringResult text_result(ObVarcharType, false, params.allocator_v2_);
|
||||
ObString es_str;
|
||||
ObObj temp_obj;
|
||||
if (OB_FAIL(common_enumset_string(in, params, text_result))) {
|
||||
LOG_WARN("common_enumset_string failed", K(ret), K(in));
|
||||
} else if (FALSE_IT(text_result.get_result_buffer(es_str))) {
|
||||
} else if (FALSE_IT(temp_obj.set_varchar(es_str))) {
|
||||
} else if (OB_FAIL(string_text(expect_type, params, temp_obj, out, cast_mode))) {
|
||||
LOG_WARN("common_string_datetime failed", K(ret), K(es_str));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int enumset_bit(const ObObjType expect_type, ObObjCastParams ¶ms,
|
||||
const ObObj &in, ObObj &out, const ObCastMode cast_mode)
|
||||
{
|
||||
@ -7202,6 +7407,59 @@ static int enumset_bit(const ObObjType expect_type, ObObjCastParams ¶ms,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int enumset_lob(const ObObjType expect_type, ObObjCastParams ¶ms,
|
||||
const ObObj &in, ObObj &out, const ObCastMode cast_mode)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (!is_enum_set_with_subschema(in)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected cast", K(ret), K(in));
|
||||
} else if (OB_UNLIKELY(ObEnumSetTC != in.get_type_class()
|
||||
|| ObLobTC != ob_obj_type_class(expect_type))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_ERROR("invalid input type", K(ret), K(in), K(expect_type));
|
||||
} else {
|
||||
ObTextStringResult text_result(ObVarcharType, false, params.allocator_v2_);
|
||||
ObString es_str;
|
||||
ObObj temp_obj;
|
||||
if (OB_FAIL(common_enumset_string(in, params, text_result))) {
|
||||
LOG_WARN("common_enumset_string failed", K(ret), K(in));
|
||||
} else if (FALSE_IT(text_result.get_result_buffer(es_str))) {
|
||||
} else if (FALSE_IT(temp_obj.set_varchar(es_str))) {
|
||||
} else if (OB_FAIL(string_lob(expect_type, params, temp_obj, out, cast_mode))) {
|
||||
LOG_WARN("common_string_datetime failed", K(ret), K(es_str));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int enumset_json(const ObObjType expect_type, ObObjCastParams ¶ms,
|
||||
const ObObj &in, ObObj &out, const ObCastMode cast_mode)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (!is_enum_set_with_subschema(in)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected cast", K(ret), K(in));
|
||||
} else if (OB_UNLIKELY(ObEnumSetTC != in.get_type_class()
|
||||
|| ObJsonTC != ob_obj_type_class(expect_type))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_ERROR("invalid input type", K(ret), K(in), K(expect_type));
|
||||
} else {
|
||||
ObTextStringResult text_result(ObVarcharType, false, params.allocator_v2_);
|
||||
ObString es_str;
|
||||
ObObj temp_obj;
|
||||
if (OB_FAIL(common_enumset_string(in, params, text_result))) {
|
||||
LOG_WARN("common_enumset_string failed", K(ret), K(in));
|
||||
} else if (FALSE_IT(text_result.get_result_buffer(es_str))) {
|
||||
} else if (FALSE_IT(temp_obj.set_varchar(es_str))) {
|
||||
} else if (OB_FAIL(string_json(expect_type, params, temp_obj, out, cast_mode))) {
|
||||
LOG_WARN("common_string_datetime failed", K(ret), K(es_str));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int get_uint64_from_enumset_inner(const ObObj &in, ObObj &out)
|
||||
{
|
||||
@ -11305,14 +11563,14 @@ ObObjCastFunc OB_OBJ_CAST[ObMaxTC][ObMaxTC] =
|
||||
enumset_float,/*float*/
|
||||
enumset_double,/*double*/
|
||||
enumset_number,/*number*/
|
||||
cast_not_expected,/*datetime*/
|
||||
cast_not_expected,/*date*/
|
||||
cast_not_expected,/*time*/
|
||||
enumset_datetime,/*datetime*/
|
||||
enumset_date,/*date*/
|
||||
enumset_time,/*time*/
|
||||
enumset_year,/*year*/
|
||||
cast_not_expected,/*string*/
|
||||
enumset_string,/*string*/
|
||||
cast_not_support,/*extend*/
|
||||
cast_not_support,/*unknown*/
|
||||
cast_not_expected,/*text*/
|
||||
enumset_text,/*text*/
|
||||
enumset_bit,/*bit*/
|
||||
cast_not_expected,/*enumset*/
|
||||
cast_not_expected,/*enumset_inner*/
|
||||
@ -11320,9 +11578,9 @@ ObObjCastFunc OB_OBJ_CAST[ObMaxTC][ObMaxTC] =
|
||||
cast_inconsistent_types,/*raw*/
|
||||
cast_not_expected,/*interval*/
|
||||
cast_not_expected,/*rowid*/
|
||||
cast_not_expected,/*lob*/
|
||||
cast_not_expected,/*json*/
|
||||
cast_not_expected,/*geometry*/
|
||||
enumset_lob,/*lob*/
|
||||
enumset_json,/*json*/
|
||||
cast_not_support,/*geometry*/
|
||||
cast_not_expected,/*udt*/
|
||||
enumset_decimalint,/*decimalint*/
|
||||
cast_not_support,/*collection*/
|
||||
|
@ -420,6 +420,11 @@ DEF_BOOL(_optimizer_sortmerge_join_enabled, OB_TENANT_PARAMETER, "True",
|
||||
DEF_BOOL(_nested_loop_join_enabled, OB_TENANT_PARAMETER, "True",
|
||||
"enable/disable nested loop join",
|
||||
ObParameterAttr(Section::TENANT, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE));
|
||||
//
|
||||
DEF_BOOL(_enable_enum_set_subschema, OB_TENANT_PARAMETER, "True",
|
||||
"Specifies whether to enable the enum/set extended type info is stored as subschema "
|
||||
"and to activate the related new type cast logic behavior.",
|
||||
ObParameterAttr(Section::TENANT, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE));
|
||||
|
||||
// tenant memtable consumption related
|
||||
DEF_INT(memstore_limit_percentage, OB_CLUSTER_PARAMETER, "0", "[0, 100)",
|
||||
@ -2285,3 +2290,6 @@ ERRSIM_DEF_STR(errsim_rebuild_addr, OB_CLUSTER_PARAMETER, "",
|
||||
DEF_BOOL(_enable_adaptive_auto_dop, OB_CLUSTER_PARAMETER, "False",
|
||||
"Enable or disable adaptive auto dop feature.",
|
||||
ObParameterAttr(Section::OBSERVER, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE));
|
||||
DEF_INT(query_memory_limit_percentage, OB_TENANT_PARAMETER, "50", "[0,100]",
|
||||
"the percentage of tenant memory that can be used by a single SQL. The default value is 50. Range: [0,100]",
|
||||
ObParameterAttr(Section::OBSERVER, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE));
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "observer/ob_server_struct.h"
|
||||
#include "observer/ob_srv_network_frame.h"
|
||||
#include "share/ob_autoincrement_service.h"
|
||||
#include "observer/ob_sql_client_decorator.h"
|
||||
|
||||
namespace oceanbase
|
||||
{
|
||||
@ -146,7 +147,44 @@ int ObSequenceSqlService::get_sequence_sync_value(const uint64_t tenant_id,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObSequenceSqlService::clean_sequence_cache(uint64_t tenant_id, uint64_t sequence_id)
|
||||
int ObSequenceSqlService::get_lastest_local_cache(ObFixedArray<SequenceCacheNode, common::ObIAllocator> &prefetch_nodes,
|
||||
const SequenceCacheNode &target_cache_node,
|
||||
const ObNumber &inner_next_value,
|
||||
ObSeqCleanCacheRes &cache_res,
|
||||
ObIAllocator &allocator)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObNumber temp_diff;
|
||||
ObNumber tmp_inner_value;
|
||||
if (OB_FAIL(tmp_inner_value.from(inner_next_value, allocator))) {
|
||||
LOG_WARN("fail to init tmp_inner_vale", K(ret));
|
||||
}
|
||||
for (int i = 0; OB_SUCC(ret) && i < prefetch_nodes.count(); i++) {
|
||||
const SequenceCacheNode &node = prefetch_nodes.at(i);
|
||||
if (OB_FAIL(node.end().sub(node.start(), temp_diff, allocator))) {
|
||||
LOG_WARN("fail calc sub", K(ret), K(node));
|
||||
} else {
|
||||
if ((temp_diff >= static_cast<int64_t>(0) && node.start() >= target_cache_node.end())
|
||||
|| (temp_diff < static_cast<int64_t>(0) && node.start() <= target_cache_node.end())) {
|
||||
if (OB_FAIL(tmp_inner_value.sub(temp_diff, tmp_inner_value, allocator))) {
|
||||
LOG_WARN("fail calc sub", K(ret), K(tmp_inner_value), K(temp_diff));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) && tmp_inner_value == target_cache_node.end()) {
|
||||
if (OB_FAIL(cache_res.cache_node_.assign(target_cache_node))) {
|
||||
LOG_WARN("faul to assign cache_node");
|
||||
}
|
||||
cache_res.inited_ = true;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObSequenceSqlService::clean_sequence_cache(uint64_t tenant_id, uint64_t sequence_id,
|
||||
ObNumber &inner_next_value,
|
||||
ObSeqCleanCacheRes &cache_res,
|
||||
ObIAllocator &allocator)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObSEArray<ObAddr, 8> server_list;
|
||||
@ -162,22 +200,142 @@ int ObSequenceSqlService::clean_sequence_cache(uint64_t tenant_id, uint64_t sequ
|
||||
} else if (OB_FAIL(srv_rpc_proxy.init(GCTX.net_frame_->get_req_transport(), GCTX.self_addr()))) {
|
||||
LOG_WARN("fail to init srv rpc proxy", KR(ret));
|
||||
} else {
|
||||
ObSeqCleanCacheRes temp_cache_res;
|
||||
ObNumber min_diff;
|
||||
ObNumber temp_diff;
|
||||
SequenceCacheNode target_cache_node;
|
||||
ObFixedArray<SequenceCacheNode, common::ObIAllocator> prefetch_nodes(allocator);
|
||||
if (OB_FAIL(prefetch_nodes.init(server_list.count()))) {
|
||||
LOG_WARN("fail to init prefetch_nodes", K(ret));
|
||||
} else if (OB_FAIL(min_diff.from(INT64_MAX, allocator))) {
|
||||
LOG_WARN("fail to init min_diff", K(ret));
|
||||
}
|
||||
for (int i = 0; OB_SUCC(ret) && i < server_list.count(); ++i) {
|
||||
temp_cache_res.inited_ = false;
|
||||
const uint64_t timeout = THIS_WORKER.get_timeout_remain();
|
||||
if (OB_FAIL(srv_rpc_proxy
|
||||
.to(server_list.at(i))
|
||||
.by(tenant_id)
|
||||
.timeout(timeout)
|
||||
.clean_sequence_cache(sequence_id))) {
|
||||
.clean_sequence_cache(sequence_id, temp_cache_res))) {
|
||||
if (is_timeout_err(ret) || is_server_down_error(ret)) {
|
||||
LOG_WARN("rpc call time out, ignore the error", "server", server_list.at(i),
|
||||
K(tenant_id), K(sequence_id), K(ret));
|
||||
ret = OB_SUCCESS;
|
||||
} else if (ret == OB_NOT_SUPPORTED) {
|
||||
// The new and old rpc are incompatible. The old rpc may not return results, but the cache
|
||||
// will be cleared.
|
||||
LOG_WARN("During upgrade, new and old rpc are incompatible, ignore the error",
|
||||
"server", server_list.at(i), K(tenant_id), K(sequence_id), K(ret));
|
||||
ret = OB_SUCCESS;
|
||||
} else {
|
||||
LOG_WARN("clean sequnece cache failed", K(ret), K(sequence_id), K(server_list.at(i)));
|
||||
}
|
||||
} else if (!temp_cache_res.inited_) {
|
||||
// do nothing
|
||||
} else if (temp_cache_res.with_prefetch_node_
|
||||
&& OB_FAIL(prefetch_nodes.push_back(temp_cache_res.prefetch_node_))) {
|
||||
LOG_WARN("fail to push back prefetch cache node", K(ret));
|
||||
} else if (OB_FAIL(
|
||||
inner_next_value.sub(temp_cache_res.cache_node_.end(), temp_diff, allocator))) {
|
||||
LOG_WARN("fail calc sub", K(ret), K(inner_next_value), K(temp_cache_res));
|
||||
} else if (temp_diff.abs() < min_diff) {
|
||||
if (OB_FAIL(min_diff.from(temp_diff.abs(), allocator))) {
|
||||
LOG_WARN("fail to set min_diff", K(ret));
|
||||
} else if (OB_FAIL(target_cache_node.assign(temp_cache_res.cache_node_))) {
|
||||
LOG_WARN("fail to assign cache node", K(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)
|
||||
&& OB_FAIL(get_lastest_local_cache(prefetch_nodes, target_cache_node, inner_next_value,
|
||||
cache_res, allocator))) {
|
||||
LOG_WARN("fail to get lastest local cache", K(ret));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObSequenceSqlService::clean_and_write_back_cache(common::ObISQLClient *sql_client,
|
||||
const ObSequenceSchema &sequence_schema,
|
||||
bool &need_write_back, ObIAllocator &allocator)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
uint64_t sequence_id = sequence_schema.get_sequence_id();
|
||||
uint64_t tenant_id = sequence_schema.get_tenant_id();
|
||||
const uint64_t exec_tenant_id = ObSchemaUtils::get_exec_tenant_id(tenant_id);
|
||||
const char *tname = OB_ALL_SEQUENCE_VALUE_TNAME;
|
||||
ObSqlString sql;
|
||||
|
||||
ObNumber inner_next_value; // default to zero
|
||||
ObSeqCleanCacheRes cache_res;
|
||||
ObSQLClientRetryWeak sql_client_retry_weak(sql_client, exec_tenant_id, OB_ALL_SEQUENCE_VALUE_TID);
|
||||
if (OB_SUCC(ret)) {
|
||||
SMART_VAR(ObMySQLProxy::MySQLResult, res)
|
||||
{
|
||||
common::sqlclient::ObMySQLResult *result = NULL;
|
||||
ObNumber tmp;
|
||||
if (OB_FAIL(sql.assign_fmt("SELECT NEXT_VALUE FROM %s "
|
||||
"WHERE SEQUENCE_ID = %lu FOR UPDATE",
|
||||
tname, sequence_id))) {
|
||||
STORAGE_LOG(WARN, "fail format sql", K(ret));
|
||||
} else if (OB_FAIL(sql_client_retry_weak.read(res, exec_tenant_id, sql.ptr()))) {
|
||||
LOG_WARN("fail to execute sql", K(sql), K(ret));
|
||||
} else if (NULL == (result = res.get_result())) {
|
||||
ret = OB_ENTRY_NOT_EXIST;
|
||||
LOG_WARN("can't find sequence", K(tname), K(exec_tenant_id), K(sequence_id));
|
||||
} else if (OB_SUCCESS != (ret = result->next())) {
|
||||
if (OB_ITER_END == ret) {
|
||||
need_write_back = false;
|
||||
ret = OB_SUCCESS;
|
||||
LOG_WARN("get no line from all_sequence_value", K(ret));
|
||||
} else {
|
||||
LOG_WARN("fail get next row", K(ret), K(tname), K(exec_tenant_id), K(sequence_id));
|
||||
}
|
||||
} else {
|
||||
EXTRACT_NUMBER_FIELD_MYSQL(*result, NEXT_VALUE, tmp);
|
||||
if (OB_FAIL(ret)) {
|
||||
LOG_WARN("fail get NEXT_VALUE", K(ret));
|
||||
} else if (OB_FAIL(inner_next_value.from(tmp, allocator))) {
|
||||
LOG_WARN("fail deep copy next_val", K(tmp), K(ret));
|
||||
} else if (OB_ITER_END != (ret = result->next())) {
|
||||
LOG_WARN("expected OB_ITER_END", K(ret));
|
||||
ret = (OB_SUCCESS == ret ? OB_ERR_UNEXPECTED : ret);
|
||||
} else {
|
||||
ret = OB_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ObNumber write_val;
|
||||
if (OB_FAIL(ret) || !need_write_back) {
|
||||
// do nothing
|
||||
} else if (OB_FAIL(clean_sequence_cache(tenant_id, sequence_id, inner_next_value, cache_res,
|
||||
allocator))) {
|
||||
LOG_WARN("clean sequence cache failed", K(ret));
|
||||
} else if (!cache_res.inited_) {
|
||||
// do nothing
|
||||
} else if (OB_FAIL(cache_res.cache_node_.start().add(sequence_schema.get_increment_by(),
|
||||
write_val, allocator))) {
|
||||
LOG_WARN("fail calc new_start", K(ret), K(inner_next_value), K(cache_res));
|
||||
} else if (write_val != inner_next_value) {
|
||||
int64_t affected_rows = 0;
|
||||
bool is_standby = false;
|
||||
if (OB_FAIL(sql.assign_fmt("UPDATE %s SET next_value = %s "
|
||||
"WHERE SEQUENCE_ID = %lu",
|
||||
tname, write_val.format(), sequence_id))) {
|
||||
LOG_WARN("format update sql fail", K(ret));
|
||||
} else if (OB_FAIL(ObShareUtil::table_check_if_tenant_role_is_standby(exec_tenant_id, is_standby))) {
|
||||
LOG_WARN("fail to execute table_check_if_tenant_role_is_standby", KR(ret), K(exec_tenant_id));
|
||||
} else if (is_standby && OB_SYS_TENANT_ID != exec_tenant_id) {
|
||||
ret = OB_OP_NOT_ALLOW;
|
||||
LOG_WARN("can't write sys table now", K(ret), K(exec_tenant_id));
|
||||
} else if (OB_FAIL(sql_client->write(exec_tenant_id, sql.ptr(), affected_rows))) {
|
||||
LOG_WARN("fail to execute sql", K(sql), K(ret));
|
||||
} else if (!is_single_row(affected_rows)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected value", K(affected_rows), K(sql), K(ret));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -187,6 +345,7 @@ int ObSequenceSqlService::replace_sequence(const ObSequenceSchema &sequence_sche
|
||||
common::ObISQLClient *sql_client,
|
||||
bool alter_start_with,
|
||||
bool need_clean_cache,
|
||||
bool need_write_back,
|
||||
const common::ObString *ddl_stmt_str)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
@ -266,14 +425,22 @@ int ObSequenceSqlService::replace_sequence(const ObSequenceSchema &sequence_sche
|
||||
K(ret));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
if (alter_start_with && OB_FAIL(alter_sequence_start_with(sequence_schema, *sql_client))) {
|
||||
ObNumber inner_next_value; // default to zero
|
||||
ObSeqCleanCacheRes cache_res;
|
||||
if (OB_FAIL(ret)) {
|
||||
// do nothing
|
||||
} else if (alter_start_with) {
|
||||
if (OB_FAIL(alter_sequence_start_with(sequence_schema, *sql_client))) {
|
||||
LOG_WARN("alter sequence for start with failed", K(ret));
|
||||
} else if (need_clean_cache && OB_FAIL(clean_sequence_cache(tenant_id, sequence_id))) {
|
||||
} else if (OB_FAIL(clean_sequence_cache(tenant_id, sequence_id, inner_next_value, cache_res,
|
||||
allocator))) {
|
||||
LOG_WARN("clean sequence cache failed", K(ret));
|
||||
}
|
||||
} else if (need_clean_cache
|
||||
&& OB_FAIL(clean_and_write_back_cache(sql_client, sequence_schema, need_write_back,
|
||||
allocator))) {
|
||||
LOG_WARN("fail to clean and write back cache", K(ret));
|
||||
}
|
||||
|
||||
// log operation
|
||||
if (OB_SUCC(ret)) {
|
||||
ObSchemaOperation opt;
|
||||
|
@ -15,6 +15,9 @@
|
||||
|
||||
#include "ob_ddl_sql_service.h"
|
||||
#include "lib/number/ob_number_v2.h"
|
||||
#include "share/ob_rpc_struct.h"
|
||||
|
||||
using namespace oceanbase::common::number;
|
||||
|
||||
namespace oceanbase
|
||||
{
|
||||
@ -45,6 +48,7 @@ public:
|
||||
common::ObISQLClient *sql_client,
|
||||
bool alter_start_with,
|
||||
bool need_clean_cache,
|
||||
bool need_write_back,
|
||||
const common::ObString *ddl_stmt_str = NULL);
|
||||
virtual int delete_sequence(const uint64_t tenant_id,
|
||||
const uint64_t database_id,
|
||||
@ -64,8 +68,10 @@ public:
|
||||
common::ObISQLClient &sql_client,
|
||||
ObIAllocator &allocator,
|
||||
common::number::ObNumber &next_value);
|
||||
int clean_sequence_cache(uint64_t tenant_id, uint64_t sequence_id);
|
||||
private:
|
||||
int clean_and_write_back_cache(common::ObISQLClient *sql_client,
|
||||
const ObSequenceSchema &sequence_schema, bool &need_write_back,
|
||||
ObIAllocator &allocator);
|
||||
int add_sequence(common::ObISQLClient &sql_client, const ObSequenceSchema &sequence_schema,
|
||||
const bool only_history, const uint64_t *old_sequence_id);
|
||||
int add_sequence_to_value_table(const uint64_t tenant_id,
|
||||
@ -74,6 +80,13 @@ private:
|
||||
const uint64_t new_sequence_id,
|
||||
common::ObISQLClient &sql_client,
|
||||
ObIAllocator &allocator);
|
||||
int clean_sequence_cache(uint64_t tenant_id, uint64_t sequence_id, ObNumber &inner_next_value,
|
||||
obrpc::ObSeqCleanCacheRes &cache_res, ObIAllocator &allocator);
|
||||
|
||||
int get_lastest_local_cache(ObFixedArray<SequenceCacheNode, common::ObIAllocator> &prefetch_nodes,
|
||||
const SequenceCacheNode &target_cache_node, const ObNumber &inner_next_value,
|
||||
obrpc::ObSeqCleanCacheRes &cache_res, ObIAllocator &allocator);
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObSequenceSqlService);
|
||||
};
|
||||
|
@ -17,12 +17,59 @@
|
||||
#include "share/schema/ob_schema_struct.h"
|
||||
#include "lib/worker.h"
|
||||
#include "share/ob_errno.h"
|
||||
#include "share/ob_rpc_struct.h"
|
||||
|
||||
using namespace oceanbase::common;
|
||||
using namespace oceanbase::common::number;
|
||||
using namespace oceanbase::share;
|
||||
using namespace oceanbase::share::schema;
|
||||
|
||||
OB_DEF_SERIALIZE(SequenceCacheNode)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
OB_UNIS_ENCODE(start_);
|
||||
OB_UNIS_ENCODE(end_);
|
||||
return ret;
|
||||
}
|
||||
|
||||
OB_DEF_DESERIALIZE(SequenceCacheNode)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
share::ObSequenceValue start;
|
||||
share::ObSequenceValue end;
|
||||
OB_UNIS_DECODE(start);
|
||||
OB_UNIS_DECODE(end);
|
||||
// deep copy is needed to ensure that the memory of start and end will not be reclaimed
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_FAIL(start_.assign(start))) {
|
||||
LOG_WARN("fail to assign start", K(ret));
|
||||
} else if (OB_FAIL(end_.assign(end))) {
|
||||
LOG_WARN("fail to assign end", K(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
OB_DEF_SERIALIZE_SIZE(SequenceCacheNode)
|
||||
{
|
||||
int64_t len = 0;
|
||||
OB_UNIS_ADD_LEN(start_);
|
||||
OB_UNIS_ADD_LEN(end_);
|
||||
return len;
|
||||
}
|
||||
|
||||
int SequenceCacheNode::assign(const SequenceCacheNode &other)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (this == &other) {
|
||||
} else if (OB_FAIL(start_.assign(other.start_))) {
|
||||
LOG_WARN("fail to assign start", K(ret));
|
||||
} else if (OB_FAIL(end_.assign(other.end_))) {
|
||||
LOG_WARN("fail to assign end", K(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
ObSequenceCache::ObSequenceCache()
|
||||
: inited_(false),
|
||||
cache_mutex_(common::ObLatchIds::SEQUENCE_CACHE_LOCK)
|
||||
@ -260,8 +307,10 @@ int ObSequenceCache::refill_sequence_cache(const ObSequenceSchema &schema,
|
||||
need_refetch = false;
|
||||
if (OB_FAIL(dml_proxy_.next_batch(schema.get_tenant_id(),
|
||||
schema.get_sequence_id(),
|
||||
schema.get_schema_version(),
|
||||
schema.get_sequence_option(),
|
||||
next_range))) {
|
||||
next_range,
|
||||
cache))) {
|
||||
LOG_WARN("fail get next sequence batch", K(schema), K(ret));
|
||||
} else {
|
||||
// 判断是否需要重取,确保取得的值够一次 increment
|
||||
@ -324,13 +373,16 @@ int ObSequenceCache::refill_sequence_cache(const ObSequenceSchema &schema,
|
||||
|
||||
|
||||
int ObSequenceCache::prefetch_sequence_cache(const ObSequenceSchema &schema,
|
||||
ObSequenceCacheItem &cache)
|
||||
ObSequenceCacheItem &cache,
|
||||
ObSequenceCacheItem &old_cache)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_FAIL(dml_proxy_.prefetch_next_batch(schema.get_tenant_id(),
|
||||
schema.get_sequence_id(),
|
||||
schema.get_schema_version(),
|
||||
schema.get_sequence_option(),
|
||||
cache.prefetch_node_))) {
|
||||
cache.prefetch_node_,
|
||||
old_cache))) {
|
||||
LOG_WARN("fail get next sequence batch", K(schema), K(ret));
|
||||
} else {
|
||||
cache.last_refresh_ts_ = ObTimeUtility::current_time();
|
||||
@ -362,26 +414,44 @@ int ObSequenceCache::get_item(CacheItemKey &key, ObSequenceCacheItem *&item)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObSequenceCache::del_item(CacheItemKey &key)
|
||||
int ObSequenceCache::del_item(uint64_t tenant_id, CacheItemKey &key, obrpc::ObSeqCleanCacheRes &cache_res)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
|
||||
// LOG_INFO("XXXX: del item", K(key));
|
||||
// auto func = [&] (CacheItemKey &mykey, ObSequenceCacheItem *value) {
|
||||
// LOG_INFO("XXXX: list items in cache", K(mykey), K(*value));
|
||||
// return true;
|
||||
// };
|
||||
// sequence_cache_.map(func);
|
||||
|
||||
if (OB_ENTRY_EXIST == (ret = sequence_cache_.contains_key(key))) {
|
||||
lib::ObMutexGuard guard(cache_mutex_); // 加锁再次确认,避免并发加入新节点
|
||||
if (OB_ENTRY_EXIST == (ret = sequence_cache_.contains_key(key))) {
|
||||
if (OB_FAIL(sequence_cache_.del(key))) {
|
||||
LOG_WARN("del sequence cache failed", K(ret));
|
||||
ObSequenceCacheItem *item = nullptr;
|
||||
uint64_t compat_version = 0;
|
||||
if (OB_FAIL(sequence_cache_.get(key, item))) {
|
||||
// no cache, do nothing
|
||||
} else if (OB_FAIL(sequence_cache_.del(key))) {
|
||||
LOG_WARN("del sequence cache failed", K(ret));
|
||||
} else if (FAILEDx(GET_MIN_DATA_VERSION(tenant_id, compat_version))) {
|
||||
LOG_WARN("fail to get data version", KR(ret), K(tenant_id));
|
||||
} else if ((compat_version >= MOCK_DATA_VERSION_4_2_5_0
|
||||
&& compat_version < DATA_VERSION_4_3_0_0)
|
||||
|| compat_version >= DATA_VERSION_4_3_5_0) {
|
||||
lib::ObMutexGuard guard(item->alloc_mutex_);
|
||||
if (OB_FAIL(ret) || item->last_refresh_ts_ <= SequenceCacheStatus::INITED) {
|
||||
// do nothing
|
||||
} else if (OB_FAIL(cache_res.cache_node_.set_start(item->last_number()))) {
|
||||
LOG_WARN("fail to set cache value", K(ret));
|
||||
} else if (OB_FAIL(cache_res.cache_node_.set_end(item->curr_node_.end()))) {
|
||||
LOG_WARN("fail to set cache end", K(ret));
|
||||
} else if (item->with_prefetch_node_
|
||||
&& OB_FAIL(cache_res.prefetch_node_.assign(item->prefetch_node_))) {
|
||||
LOG_WARN("fail to assign prefetch node", K(ret));
|
||||
} else {
|
||||
item->last_refresh_ts_ = SequenceCacheStatus::DELETED;
|
||||
cache_res.inited_ = true;
|
||||
cache_res.with_prefetch_node_ = item->with_prefetch_node_;
|
||||
}
|
||||
} else {
|
||||
LOG_INFO("fail check if key in cache", K(ret), K(key));
|
||||
}
|
||||
if (nullptr != item) {
|
||||
sequence_cache_.revert(item);
|
||||
}
|
||||
}
|
||||
return (ret == OB_ENTRY_NOT_EXIST) ? OB_SUCCESS : ret;
|
||||
}
|
||||
@ -409,98 +479,104 @@ int ObSequenceCache::nextval(const ObSequenceSchema &schema,
|
||||
} else if (OB_ISNULL(item)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
} else {
|
||||
lib::ObMutexGuard guard(item->alloc_mutex_);
|
||||
/* refill_sequence_cache 期间禁止调度器挂起 query */
|
||||
lib::DisableSchedInterGuard sched_guard;
|
||||
{
|
||||
LOG_DEBUG("nextval", K(schema));
|
||||
lib::ObMutexGuard guard(item->fetch_);
|
||||
item->alloc_mutex_.lock();
|
||||
if (item->last_refresh_ts_ == SequenceCacheStatus::DELETED) {
|
||||
ret = OB_AUTOINC_CACHE_NOT_EQUAL;
|
||||
LOG_WARN("cache has been cleared", K(ret), K(*item));
|
||||
} else {
|
||||
/* refill_sequence_cache 期间禁止调度器挂起 query */
|
||||
lib::DisableSchedInterGuard sched_guard;
|
||||
{
|
||||
LOG_DEBUG("nextval", K(schema));
|
||||
|
||||
// step 1. 从 cache 中获取下一个值
|
||||
ret = move_next(schema, *item, allocator, nextval);
|
||||
// step 1. 从 cache 中获取下一个值
|
||||
ret = move_next(schema, *item, allocator, nextval);
|
||||
|
||||
// setp 2. cache 中的值已经使用完,需要重填 cache
|
||||
// 注意:预取功能正常的情况下,不会走到这个分支
|
||||
if (OB_SIZE_OVERFLOW == ret) {
|
||||
LOG_INFO("no more avaliable value in current cache, try refill cache", K(*item), K(ret));
|
||||
if (OB_FAIL(refill_sequence_cache(schema, allocator, *item))) {
|
||||
LOG_WARN("fail refill sequence cache", K(*item), K(ret));
|
||||
} else if (OB_FAIL(move_next(schema, *item, allocator, nextval))) {
|
||||
LOG_WARN("fail move next", K(*item), K(ret));
|
||||
}
|
||||
// setp 2. cache 中的值已经使用完,需要重填 cache
|
||||
// 注意:预取功能正常的情况下,不会走到这个分支
|
||||
if (OB_SIZE_OVERFLOW == ret) {
|
||||
ret = OB_ERR_SEQ_VALUE_EXCEED_LIMIT;
|
||||
if (schema.get_increment_by() < static_cast<int64_t>(0)) {
|
||||
LOG_USER_ERROR(OB_ERR_SEQ_VALUE_EXCEED_LIMIT, "MINVALUE");
|
||||
} else if (schema.get_increment_by() > static_cast<int64_t>(0)) {
|
||||
LOG_USER_ERROR(OB_ERR_SEQ_VALUE_EXCEED_LIMIT, "MAXVALUE");
|
||||
LOG_INFO("no more avaliable value in current cache, try refill cache", K(*item), K(ret));
|
||||
if (OB_FAIL(refill_sequence_cache(schema, allocator, *item))) {
|
||||
LOG_WARN("fail refill sequence cache", K(*item), K(ret));
|
||||
} else if (OB_FAIL(move_next(schema, *item, allocator, nextval))) {
|
||||
LOG_WARN("fail move next", K(*item), K(ret));
|
||||
}
|
||||
if (OB_SIZE_OVERFLOW == ret) {
|
||||
ret = OB_ERR_SEQ_VALUE_EXCEED_LIMIT;
|
||||
if (schema.get_increment_by() < static_cast<int64_t>(0)) {
|
||||
LOG_USER_ERROR(OB_ERR_SEQ_VALUE_EXCEED_LIMIT, "MINVALUE");
|
||||
} else if (schema.get_increment_by() > static_cast<int64_t>(0)) {
|
||||
LOG_USER_ERROR(OB_ERR_SEQ_VALUE_EXCEED_LIMIT, "MAXVALUE");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// step 3. 尝试预取
|
||||
if (OB_SUCC(ret) &&
|
||||
!item->prefetching_ &&
|
||||
schema.get_cache_size() > static_cast<int64_t>(1) && /* cache size = 1 时禁止 prefetch */
|
||||
schema.get_order_flag() == false /* 有 order 时禁止 prefetch */) {
|
||||
if (OB_UNLIKELY(!item->with_prefetch_node_)) {
|
||||
//const int64_t rest = std::abs(item->curr_node_.end() - item->curr_node_.start());
|
||||
//const int64_t full = std::abs(schema.get_increment_by() * schema.get_cache_size());
|
||||
ObNumber rest;
|
||||
ObNumber full;
|
||||
ObNumberCalc calc(item->curr_node_.end(), allocator);
|
||||
// 拍脑袋的值,表示使用了 1/2 的值后就开始预取
|
||||
static const int64_t PREFETCH_OP_THRESHOLD = 2;
|
||||
//
|
||||
// const int64_t rest = std::abs(item->curr_node_.end_ - item->curr_node_.start_) * PREFETCH_OP_THRESHOLD;
|
||||
// const int64_t full = std::abs(schema.get_increment_by() * schema.get_cache_size());
|
||||
// if (rest < full) {
|
||||
// enable prefetch
|
||||
// }
|
||||
//
|
||||
if (OB_FAIL(calc.sub(item->curr_node_.start()).mul(PREFETCH_OP_THRESHOLD).get_result(rest))) {
|
||||
LOG_WARN("fail do number sub", K(ret));
|
||||
} else if (OB_FAIL(schema.get_increment_by().mul(schema.get_cache_size(), full, allocator))) {
|
||||
LOG_WARN("fail do number multiply", K(ret));
|
||||
} else if (rest.abs() <= full.abs()) {
|
||||
item->prefetching_ = true;
|
||||
need_prefetch = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// step 3. 尝试预取
|
||||
if (OB_SUCC(ret) &&
|
||||
!item->prefetching_ &&
|
||||
schema.get_cache_size() > static_cast<int64_t>(1) && /* cache size = 1 时禁止 prefetch */
|
||||
schema.get_order_flag() == false /* 有 order 时禁止 prefetch */) {
|
||||
if (OB_UNLIKELY(!item->with_prefetch_node_)) {
|
||||
//const int64_t rest = std::abs(item->curr_node_.end() - item->curr_node_.start());
|
||||
//const int64_t full = std::abs(schema.get_increment_by() * schema.get_cache_size());
|
||||
ObNumber rest;
|
||||
ObNumber full;
|
||||
ObNumberCalc calc(item->curr_node_.end(), allocator);
|
||||
// 拍脑袋的值,表示使用了 1/2 的值后就开始预取
|
||||
static const int64_t PREFETCH_OP_THRESHOLD = 2;
|
||||
//
|
||||
// const int64_t rest = std::abs(item->curr_node_.end_ - item->curr_node_.start_) * PREFETCH_OP_THRESHOLD;
|
||||
// const int64_t full = std::abs(schema.get_increment_by() * schema.get_cache_size());
|
||||
// if (rest < full) {
|
||||
// enable prefetch
|
||||
// }
|
||||
//
|
||||
if (OB_FAIL(calc.sub(item->curr_node_.start()).mul(PREFETCH_OP_THRESHOLD).get_result(rest))) {
|
||||
LOG_WARN("fail do number sub", K(ret));
|
||||
} else if (OB_FAIL(schema.get_increment_by().mul(schema.get_cache_size(), full, allocator))) {
|
||||
LOG_WARN("fail do number multiply", K(ret));
|
||||
} else if (rest.abs() <= full.abs()) {
|
||||
item->prefetching_ = true;
|
||||
need_prefetch = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (OB_SUCC(ret) && need_prefetch) {
|
||||
ObSequenceCacheItem mock_item;
|
||||
if (OB_FAIL(prefetch_sequence_cache(schema, mock_item))) {
|
||||
int prefetch_err = ret;
|
||||
ret = OB_SUCCESS;
|
||||
LOG_WARN("fail refill sequence cache. ignore prefrech error", K(prefetch_err), K(ret));
|
||||
} else {
|
||||
LOG_INFO("dump item", K(mock_item), K(*item));
|
||||
if (item->with_prefetch_node_) {
|
||||
LOG_INFO("new item has been fetched by other, ignore");
|
||||
if (OB_SUCC(ret) && need_prefetch) {
|
||||
ObSequenceCacheItem mock_item;
|
||||
if (OB_FAIL(prefetch_sequence_cache(schema, mock_item, *item))) {
|
||||
int prefetch_err = ret;
|
||||
ret = OB_SUCCESS;
|
||||
LOG_WARN("fail refill sequence cache. ignore prefrech error", K(prefetch_err), K(ret));
|
||||
} else {
|
||||
item->last_refresh_ts_ = mock_item.last_refresh_ts_;
|
||||
item->with_prefetch_node_ = true;
|
||||
if (OB_FAIL(item->prefetch_node_.set_start(mock_item.prefetch_node_.start()))) {
|
||||
LOG_WARN("fail set start for pretch node", K(ret));
|
||||
} else if (OB_FAIL(item->prefetch_node_.set_end(mock_item.prefetch_node_.end()))) {
|
||||
LOG_WARN("fail set end for pretch node", K(ret));
|
||||
LOG_INFO("dump item", K(mock_item), K(*item));
|
||||
if (item->with_prefetch_node_) {
|
||||
LOG_INFO("new item has been fetched by other, ignore");
|
||||
} else {
|
||||
item->last_refresh_ts_ = mock_item.last_refresh_ts_;
|
||||
item->with_prefetch_node_ = true;
|
||||
if (OB_FAIL(item->prefetch_node_.set_start(mock_item.prefetch_node_.start()))) {
|
||||
LOG_WARN("fail set start for pretch node", K(ret));
|
||||
} else if (OB_FAIL(item->prefetch_node_.set_end(mock_item.prefetch_node_.end()))) {
|
||||
LOG_WARN("fail set end for pretch node", K(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
item->prefetching_ = false;
|
||||
}
|
||||
item->prefetching_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (nullptr != item) {
|
||||
item->alloc_mutex_.unlock();
|
||||
sequence_cache_.revert(item);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObSequenceCache::remove(uint64_t tenant_id, uint64_t sequence_id)
|
||||
int ObSequenceCache::remove(uint64_t tenant_id, uint64_t sequence_id, obrpc::ObSeqCleanCacheRes &cache_res)
|
||||
{
|
||||
CacheItemKey key(tenant_id, sequence_id);
|
||||
return del_item(key);
|
||||
return del_item(tenant_id, key, cache_res);
|
||||
}
|
||||
|
@ -26,6 +26,10 @@ namespace common
|
||||
class ObMySQLProxy;
|
||||
class ObMySQLTransaction;
|
||||
}
|
||||
namespace obrpc
|
||||
{
|
||||
struct ObSeqCleanCacheRes;
|
||||
}
|
||||
namespace share
|
||||
{
|
||||
namespace schema
|
||||
@ -37,10 +41,12 @@ class ObMultiVersionSchemaService;
|
||||
|
||||
struct SequenceCacheNode
|
||||
{
|
||||
OB_UNIS_VERSION(1);
|
||||
public:
|
||||
SequenceCacheNode()
|
||||
: start_(), end_()
|
||||
{}
|
||||
|
||||
int assign(const SequenceCacheNode &other);
|
||||
void reset()
|
||||
{
|
||||
}
|
||||
@ -95,6 +101,12 @@ public:
|
||||
uint64_t key_;
|
||||
};
|
||||
|
||||
enum SequenceCacheStatus
|
||||
{
|
||||
DELETED,
|
||||
INITED
|
||||
};
|
||||
|
||||
struct ObSequenceCacheItem : public common::LinkHashValue<CacheItemKey>
|
||||
{
|
||||
public:
|
||||
@ -102,8 +114,9 @@ public:
|
||||
: prefetching_(false),
|
||||
with_prefetch_node_(false),
|
||||
base_on_last_number_(false),
|
||||
last_refresh_ts_(0),
|
||||
last_refresh_ts_(INITED),
|
||||
alloc_mutex_(common::ObLatchIds::SEQUENCE_VALUE_ALLOC_LOCK),
|
||||
fetch_(common::ObLatchIds::SEQUENCE_VALUE_FETCH_LOCK),
|
||||
last_number_()
|
||||
{}
|
||||
int combine_prefetch_node()
|
||||
@ -140,6 +153,7 @@ public:
|
||||
// 记录上次取得的值,用于 cycle 模式下判断下次取值是否需要加上 increment_by
|
||||
int64_t last_refresh_ts_;
|
||||
lib::ObMutex alloc_mutex_;
|
||||
lib::ObMutex fetch_;
|
||||
private:
|
||||
ObSequenceValue last_number_;
|
||||
public:
|
||||
@ -167,15 +181,17 @@ public:
|
||||
int nextval(const share::schema::ObSequenceSchema &schema,
|
||||
common::ObIAllocator &allocator, // 用于各种临时计算
|
||||
ObSequenceValue &nextval);
|
||||
int remove(uint64_t tenant_id, uint64_t sequence_id);
|
||||
int remove(uint64_t tenant_id, uint64_t sequence_id, obrpc::ObSeqCleanCacheRes &cache_res);
|
||||
|
||||
private:
|
||||
/* functions */
|
||||
int get_item(CacheItemKey &key, ObSequenceCacheItem *&item);
|
||||
|
||||
int del_item(CacheItemKey &key);
|
||||
int del_item(uint64_t tenant_id, CacheItemKey &key, obrpc::ObSeqCleanCacheRes &cache_res);
|
||||
|
||||
int prefetch_sequence_cache(const schema::ObSequenceSchema &schema,
|
||||
ObSequenceCacheItem &cache);
|
||||
ObSequenceCacheItem &cache,
|
||||
ObSequenceCacheItem &old_cache);
|
||||
int find_sequence_cache(const schema::ObSequenceSchema &schema,
|
||||
ObSequenceCacheItem &cache);
|
||||
int move_next(const schema::ObSequenceSchema &schema,
|
||||
|
@ -252,15 +252,15 @@ int ObSequenceDDLProxy::alter_sequence(
|
||||
const ObSequenceOption &opt_old = cur_sequence_schema->get_sequence_option();
|
||||
bool alter_start_with = opt_bitset.has_member(ObSequenceArg::START_WITH) ||
|
||||
opt_bitset.has_member(ObSequenceArg::RESTART);
|
||||
bool need_clean_cache = opt_bitset.has_member(ObSequenceArg::START_WITH) ||
|
||||
opt_bitset.has_member(ObSequenceArg::RESTART) ||
|
||||
(opt_bitset.has_member(ObSequenceArg::INCREMENT_BY)
|
||||
&& opt_old.get_cache_size() <= static_cast<int64_t>(1)) ||
|
||||
(opt_bitset.has_member(ObSequenceArg::ORDER) && !opt_old.get_order_flag());
|
||||
// Only in nocache mode, when the step is not changed, there is no need to clear the cache
|
||||
bool need_clean_cache = !(opt_old.get_cache_size() <= static_cast<int64_t>(1)
|
||||
&& !opt_bitset.has_member(ObSequenceArg::INCREMENT_BY));
|
||||
// in noorder cycle mode, cannot decide to write back which cache
|
||||
bool need_write_back = !(opt_old.get_cycle_flag() && !opt_old.get_order_flag());
|
||||
seq_schema.set_sequence_id(sequence_id);
|
||||
seq_schema.set_schema_version(new_schema_version);
|
||||
if (OB_FAIL(schema_service->get_sequence_sql_service().replace_sequence(
|
||||
seq_schema, false, &trans, alter_start_with, need_clean_cache, ddl_stmt_str))) {
|
||||
if (OB_FAIL(schema_service->get_sequence_sql_service().replace_sequence(seq_schema,
|
||||
false, &trans, alter_start_with, need_clean_cache, need_write_back, ddl_stmt_str))) {
|
||||
LOG_WARN("alter sequence info failed", K(seq_schema.get_sequence_name()), K(ret));
|
||||
} else {
|
||||
LOG_INFO("alter sequence", K(lbt()), K(seq_schema));
|
||||
@ -378,7 +378,7 @@ int ObSequenceDDLProxy::rename_sequence(share::schema::ObSequenceSchema &seq_sch
|
||||
} else {
|
||||
seq_schema.set_schema_version(new_schema_version);
|
||||
if (OB_FAIL(schema_service->get_sequence_sql_service().replace_sequence(
|
||||
seq_schema, true, &trans, false, false, ddl_stmt_str))) {
|
||||
seq_schema, true, &trans, false, false, false, ddl_stmt_str))) {
|
||||
LOG_WARN("rename sequence info failed", K(ret), K(seq_schema.get_sequence_name()));
|
||||
} else {
|
||||
LOG_INFO("rename sequence", K(lbt()), K(seq_schema));
|
||||
|
@ -97,8 +97,10 @@ int ObSequenceDMLProxy::set_pre_op_timeout(common::ObTimeoutCtx &ctx)
|
||||
int ObSequenceDMLProxy::next_batch(
|
||||
const uint64_t tenant_id,
|
||||
const uint64_t sequence_id,
|
||||
const int64_t schema_version,
|
||||
const share::ObSequenceOption &option,
|
||||
SequenceCacheNode &cache_range)
|
||||
SequenceCacheNode &cache_range,
|
||||
ObSequenceCacheItem &old_cache)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
const char *tname = OB_ALL_SEQUENCE_VALUE_TNAME;
|
||||
@ -127,6 +129,7 @@ int ObSequenceDMLProxy::next_batch(
|
||||
cache_size.shadow_copy(option.get_cache_size());
|
||||
}
|
||||
|
||||
old_cache.alloc_mutex_.unlock();
|
||||
if (OB_FAIL(ret)) {
|
||||
// pass
|
||||
} else if (!inited_) {
|
||||
@ -187,6 +190,31 @@ int ObSequenceDMLProxy::next_batch(
|
||||
}
|
||||
}
|
||||
|
||||
old_cache.alloc_mutex_.lock();
|
||||
if (OB_SUCC(ret)) {
|
||||
SMART_VAR(ObMySQLProxy::MySQLResult, res)
|
||||
{
|
||||
ObSqlString sql;
|
||||
ObMySQLResult *result = NULL;
|
||||
int64_t curr_version = OB_INVALID_VERSION;
|
||||
if (OB_FAIL(sql.assign_fmt("SELECT schema_version "
|
||||
"FROM %s WHERE sequence_id=%lu",
|
||||
OB_ALL_SEQUENCE_OBJECT_TNAME, sequence_id))) {
|
||||
LOG_WARN("fail to assign sql", KR(ret), K(tenant_id), K(sequence_id));
|
||||
} else if (OB_FAIL(sql_client->read(res, tenant_id, sql.ptr()))) {
|
||||
LOG_WARN("fail to read", KR(ret), K(tenant_id), K(sql));
|
||||
} else if (NULL == (result = res.get_result())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("fail to get sql result", K(ret));
|
||||
} else if (OB_FAIL((*result).get_int("schema_version", curr_version))) {
|
||||
LOG_WARN("fail to get schema_version", K(ret), K(tenant_id), K(sql));
|
||||
} else if (schema_version != curr_version) {
|
||||
ret = OB_AUTOINC_CACHE_NOT_EQUAL;
|
||||
LOG_WARN("schema is not up to date, need retry", K(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (OB_SUCC(ret) && need_init_sequence_value_table) {
|
||||
// 首次从 all_sequence_object 表读取数据时,需要先向
|
||||
// all_sequence_object 表中插入一行初始数据
|
||||
@ -306,16 +334,21 @@ int ObSequenceDMLProxy::next_batch(
|
||||
}
|
||||
|
||||
if (OB_SUCC(ret)) {
|
||||
OZ(cache_range.set_start(cache_inclusive_start));
|
||||
OZ(cache_range.set_end(cache_exclusive_end));
|
||||
LOG_INFO("get next sequence batch success",
|
||||
K(tenant_id),
|
||||
K(sequence_id),
|
||||
"cache_inclusive_start", cache_inclusive_start.format(),
|
||||
"cache_exclusive_end", cache_exclusive_end.format(),
|
||||
"increment_by", increment_by.format(),
|
||||
"cache_size", cache_size.format(),
|
||||
K(ret));
|
||||
if (OB_UNLIKELY(increment_by > static_cast<int64_t>(0) && cache_inclusive_start > max_value)
|
||||
|| OB_UNLIKELY(increment_by < static_cast<int64_t>(0) && cache_inclusive_start < min_value)) {
|
||||
ret = OB_AUTOINC_CACHE_NOT_EQUAL;
|
||||
} else {
|
||||
OZ(cache_range.set_start(cache_inclusive_start));
|
||||
OZ(cache_range.set_end(cache_exclusive_end));
|
||||
LOG_INFO("get next sequence batch success",
|
||||
K(tenant_id),
|
||||
K(sequence_id),
|
||||
"cache_inclusive_start", cache_inclusive_start.format(),
|
||||
"cache_exclusive_end", cache_exclusive_end.format(),
|
||||
"increment_by", increment_by.format(),
|
||||
"cache_size", cache_size.format(),
|
||||
K(ret));
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -324,8 +357,10 @@ int ObSequenceDMLProxy::next_batch(
|
||||
int ObSequenceDMLProxy::prefetch_next_batch(
|
||||
const uint64_t tenant_id,
|
||||
const uint64_t sequence_id,
|
||||
const int64_t schema_version,
|
||||
const share::ObSequenceOption &option,
|
||||
SequenceCacheNode &cache_range)
|
||||
SequenceCacheNode &cache_range,
|
||||
ObSequenceCacheItem &old_cache)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
// set timeout for prefetch
|
||||
@ -334,8 +369,10 @@ int ObSequenceDMLProxy::prefetch_next_batch(
|
||||
LOG_WARN("failed to set timeout", K(ret));
|
||||
} else if (OB_FAIL(next_batch(tenant_id,
|
||||
sequence_id,
|
||||
schema_version,
|
||||
option,
|
||||
cache_range))) {
|
||||
cache_range,
|
||||
old_cache))) {
|
||||
LOG_WARN("fail prefetch sequence batch",
|
||||
K(tenant_id), K(sequence_id), K(option), K(ret));
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
#include "lib/ob_define.h"
|
||||
#include "lib/utility/ob_macro_utils.h"
|
||||
#include "lib/lock/ob_mutex.h"
|
||||
|
||||
namespace oceanbase
|
||||
{
|
||||
@ -34,6 +35,7 @@ namespace share
|
||||
{
|
||||
class ObSequenceOption;
|
||||
struct SequenceCacheNode;
|
||||
struct ObSequenceCacheItem;
|
||||
namespace schema
|
||||
{
|
||||
class ObSchemaGetterGuard;
|
||||
@ -58,17 +60,21 @@ public:
|
||||
*/
|
||||
int next_batch(const uint64_t tenant_id,
|
||||
const uint64_t sequence_id,
|
||||
const int64_t schema_version,
|
||||
const share::ObSequenceOption &option,
|
||||
SequenceCacheNode &cache_range);
|
||||
SequenceCacheNode &cache_range,
|
||||
ObSequenceCacheItem &old_cache);
|
||||
int prefetch_next_batch(
|
||||
const uint64_t tenant_id,
|
||||
const uint64_t sequence_id,
|
||||
const int64_t schema_version,
|
||||
const share::ObSequenceOption &option,
|
||||
SequenceCacheNode &cache_range);
|
||||
SequenceCacheNode &cache_range,
|
||||
ObSequenceCacheItem &old_cache);
|
||||
private:
|
||||
/* functions */
|
||||
int set_pre_op_timeout(common::ObTimeoutCtx &ctx);
|
||||
int init_sequence_value_table(
|
||||
static int init_sequence_value_table(
|
||||
common::ObMySQLTransaction &trans,
|
||||
common::ObSQLClientRetryWeak &sql_client_retry_weak,
|
||||
common::ObIAllocator &allocator,
|
||||
|
@ -129,4 +129,3 @@ int ObSequenceOption::assign(const share::ObSequenceOption &from)
|
||||
flag_ = from.flag_;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1000,6 +1000,8 @@ ob_set_subtarget(ob_sql executor
|
||||
executor/ob_task_runner_notifier_service.cpp
|
||||
executor/ob_task_spliter.cpp
|
||||
executor/ob_task_spliter_factory.cpp
|
||||
executor/ob_memory_tracker.cpp
|
||||
executor/ob_memory_tracker_wrapper.cpp
|
||||
)
|
||||
|
||||
ob_set_subtarget(ob_sql monitor
|
||||
|
@ -980,7 +980,7 @@ int ObStaticEngineCG::generate_spec_final(ObLogicalOperator &op, ObOpSpec &spec)
|
||||
}
|
||||
}
|
||||
|
||||
if (PHY_NESTED_LOOP_CONNECT_BY == spec.type_
|
||||
if (PHY_CONNECT_BY == spec.type_
|
||||
|| PHY_NESTED_LOOP_CONNECT_BY_WITH_INDEX == spec.type_) {
|
||||
FOREACH_CNT_X(e, spec.calc_exprs_, OB_SUCC(ret)) {
|
||||
if (T_OP_PRIOR == (*e)->type_) {
|
||||
@ -5824,15 +5824,15 @@ int ObStaticEngineCG::construct_hash_elements_for_connect_by(ObLogJoin &op, ObNL
|
||||
} else if (OB_ISNULL(left_op = op.get_child(0)) || OB_ISNULL(right_op = op.get_child(1))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("child op is null", K(ret));
|
||||
} else if (OB_FAIL(spec.hash_key_exprs_.init(op.get_other_join_conditions().count()))) {
|
||||
} else if (OB_FAIL(spec.hash_key_exprs_.init(op.get_equal_join_conditions().count()))) {
|
||||
LOG_WARN("failed to init hash key exprs", K(ret));
|
||||
} else if (OB_FAIL(spec.hash_probe_exprs_.init(op.get_other_join_conditions().count()))) {
|
||||
} else if (OB_FAIL(spec.hash_probe_exprs_.init(op.get_equal_join_conditions().count()))) {
|
||||
LOG_WARN("failed to init hash probe exprs", K(ret));
|
||||
} else {
|
||||
const ObRelIds &left_table_set = left_op->get_table_set();
|
||||
const ObRelIds &right_table_set = right_op->get_table_set();
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < op.get_other_join_conditions().count(); i++) {
|
||||
ObRawExpr *other_cond = op.get_other_join_conditions().at(i);
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < op.get_equal_join_conditions().count(); i++) {
|
||||
ObRawExpr *other_cond = op.get_equal_join_conditions().at(i);
|
||||
if (OB_ISNULL(other_cond)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("other condition is null", K(ret));
|
||||
@ -5882,7 +5882,11 @@ int ObStaticEngineCG::generate_spec(ObLogJoin &op, ObNLConnectBySpec &spec, cons
|
||||
int ret = OB_SUCCESS;
|
||||
UNUSED(in_root_job);
|
||||
const ObIArray<ObRawExpr*> &other_join_conds = op.get_other_join_conditions();
|
||||
if (OB_FAIL(generate_param_spec(op.get_nl_params(), spec.rescan_params_))) {
|
||||
if (HASH_JOIN == op.get_join_algo()
|
||||
&& OB_FAIL(append(const_cast<ObIArray<ObRawExpr *> &>(other_join_conds),
|
||||
op.get_equal_join_conditions()))) {
|
||||
LOG_WARN("fail to push back hash join conditions", K(ret));
|
||||
} else if (OB_FAIL(generate_param_spec(op.get_nl_params(), spec.rescan_params_))) {
|
||||
LOG_WARN("failed to generate parameter", K(ret));
|
||||
} else if (OB_FAIL(generate_pump_exprs(op, spec))) {
|
||||
LOG_WARN("failed to generate pump exprs", K(ret));
|
||||
@ -5890,7 +5894,8 @@ int ObStaticEngineCG::generate_spec(ObLogJoin &op, ObNLConnectBySpec &spec, cons
|
||||
LOG_WARN("failed to init join conditions", K(ret));
|
||||
} else if (OB_FAIL(generate_rt_exprs(other_join_conds, spec.cond_exprs_))) {
|
||||
LOG_WARN("failed to generate condition rt exprs", K(ret));
|
||||
} else if (OB_FAIL(construct_hash_elements_for_connect_by(op, spec))) {
|
||||
} else if (HASH_JOIN == op.get_join_algo()
|
||||
&& OB_FAIL(construct_hash_elements_for_connect_by(op, spec))) {
|
||||
LOG_WARN("construct_hash_elements_for_connect_by failed", K(ret));
|
||||
}
|
||||
return ret;
|
||||
@ -9131,7 +9136,7 @@ int ObStaticEngineCG::get_phy_op_type(ObLogicalOperator &log_op,
|
||||
? PHY_NESTED_LOOP_JOIN
|
||||
: (op.get_nl_params().count() > 0
|
||||
? PHY_NESTED_LOOP_CONNECT_BY_WITH_INDEX
|
||||
: PHY_NESTED_LOOP_CONNECT_BY);
|
||||
: PHY_CONNECT_BY);
|
||||
break;
|
||||
}
|
||||
case MERGE_JOIN: {
|
||||
@ -9152,11 +9157,15 @@ int ObStaticEngineCG::get_phy_op_type(ObLogicalOperator &log_op,
|
||||
}
|
||||
case HASH_JOIN: {
|
||||
int tmp_ret = OB_SUCCESS;
|
||||
tmp_ret = OB_E(EventTable::EN_DISABLE_VEC_HASH_JOIN) OB_SUCCESS;
|
||||
if (OB_SUCCESS == tmp_ret && use_rich_format) {
|
||||
type = PHY_VEC_HASH_JOIN;
|
||||
if (CONNECT_BY_JOIN == op.get_join_type()) {
|
||||
type = PHY_CONNECT_BY;
|
||||
} else {
|
||||
type = PHY_HASH_JOIN;
|
||||
tmp_ret = OB_E(EventTable::EN_DISABLE_VEC_HASH_JOIN) OB_SUCCESS;
|
||||
if (OB_SUCCESS == tmp_ret && use_rich_format) {
|
||||
type = PHY_VEC_HASH_JOIN;
|
||||
} else {
|
||||
type = PHY_HASH_JOIN;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -330,6 +330,16 @@ int ObStaticEngineExprCG::cg_expr_basic(const ObIArray<ObRawExpr *> &raw_exprs)
|
||||
if (ob_is_bit_tc(result_meta.get_type())) {
|
||||
rt_expr->obj_meta_.set_scale(rt_expr->datum_meta_.length_semantics_);
|
||||
}
|
||||
if (OB_SUCC(ret) && ob_is_enumset_tc(result_meta.get_type())) {
|
||||
ObObjMeta org_obj_meta;
|
||||
if (OB_FAIL(ObRawExprUtils::extract_enum_set_collation(raw_expr->get_result_type(),
|
||||
op_cg_ctx_.session_,
|
||||
org_obj_meta))) {
|
||||
LOG_WARN("fail to extract enum set cs type", K(ret));
|
||||
} else {
|
||||
rt_expr->datum_meta_.cs_type_ = org_obj_meta.get_collation_type();
|
||||
}
|
||||
}
|
||||
// init max_length_
|
||||
rt_expr->max_length_ = raw_expr->get_result_type().get_length();
|
||||
// init obj_datum_map_
|
||||
|
@ -40,6 +40,8 @@
|
||||
#include "sql/engine/expr/ob_expr_xml_func_helper.h"
|
||||
#include "pl/ob_pl.h"
|
||||
#include "pl/ob_pl_user_type.h"
|
||||
#include "lib/enumset/ob_enum_set_meta.h"
|
||||
#include "sql/engine/expr/ob_expr_type_to_str.h"
|
||||
#ifdef OB_BUILD_ORACLE_PL
|
||||
#include "pl/sys_package/ob_sdo_geometry.h"
|
||||
#endif
|
||||
@ -2032,6 +2034,42 @@ static int common_string_lob(const ObExpr &expr,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int get_enumset_meta(sql::ObEvalCtx &ctx, const ObObjMeta &obj_meta, const ObEnumSetMeta *&meta) {
|
||||
int ret = OB_SUCCESS;
|
||||
const uint16_t subschema_id = obj_meta.get_subschema_id();
|
||||
if (OB_FAIL(ctx.exec_ctx_.get_enumset_meta_by_subschema_id(subschema_id, meta))) {
|
||||
LOG_WARN("failed to get udt meta", K(ret), K(subschema_id));
|
||||
} else if (OB_ISNULL(meta) || OB_UNLIKELY(!meta->is_valid())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("fail to get meta", K(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static OB_INLINE int common_enumset_string(const ObExpr &enumset_expr,
|
||||
const uint64_t in_val,
|
||||
ObEvalCtx &ctx,
|
||||
ObTextStringResult &text_result)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
const ObEnumSetMeta *meta = NULL;
|
||||
const ObObjType in_type = enumset_expr.datum_meta_.type_;
|
||||
if (0 == in_val) {
|
||||
// empty string, do nothing
|
||||
} else if (OB_FAIL(get_enumset_meta(ctx, enumset_expr.obj_meta_, meta))) {
|
||||
LOG_WARN("fail to get enumset meta", K(ret));
|
||||
} else if (ObEnumType == in_type) {
|
||||
ret = ObExprEnumToStr::inner_to_str(in_val, *meta->get_str_values(), text_result);
|
||||
} else if (ObSetType == in_type) {
|
||||
ret = ObExprSetToStr::inner_to_str(enumset_expr.datum_meta_.cs_type_, in_val,
|
||||
*meta->get_str_values(), text_result);
|
||||
} else {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected expr type", K(ret), K(in_type));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int get_text_full_data(const sql::ObExpr &expr,
|
||||
sql::ObEvalCtx &ctx,
|
||||
ObIAllocator *allocator,
|
||||
@ -3939,12 +3977,12 @@ CAST_FUNC_NAME(string, decimalint)
|
||||
}
|
||||
|
||||
static int common_string_json(const ObExpr &expr,
|
||||
const ObObjType in_type,
|
||||
const ObString &in_str,
|
||||
ObEvalCtx &ctx,
|
||||
ObDatum &res_datum)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObObjType in_type = expr.args_[0]->datum_meta_.type_;
|
||||
ObObjType out_type = ObLongTextType;
|
||||
ObCollationType in_cs_type = expr.args_[0]->datum_meta_.cs_type_;
|
||||
ObCollationType out_cs_type = expr.datum_meta_.cs_type_;
|
||||
@ -3971,7 +4009,8 @@ static int common_string_json(const ObExpr &expr,
|
||||
j_text.assign_ptr(in_str.ptr(), in_str.length());
|
||||
}
|
||||
bool is_enumset_to_str = ((expr.args_[0]->type_ == T_FUN_SET_TO_STR)
|
||||
|| (expr.args_[0]->type_ == T_FUN_ENUM_TO_STR));
|
||||
|| (expr.args_[0]->type_ == T_FUN_ENUM_TO_STR)
|
||||
|| ob_is_enum_or_set_type(expr.args_[0]->datum_meta_.type_));
|
||||
ObIJsonBase *j_base = NULL;
|
||||
ObJsonOpaque j_opaque(j_text, in_type);
|
||||
ObJsonString j_string(j_text.ptr(), j_text.length());
|
||||
@ -4075,7 +4114,7 @@ CAST_FUNC_NAME(string, json)
|
||||
&ctx.exec_ctx_))) {
|
||||
LOG_WARN("fail to get real data.", K(ret), K(in_str));
|
||||
} else {
|
||||
ret = common_string_json(expr, in_str, ctx, res_datum);
|
||||
ret = common_string_json(expr, expr.args_[0]->datum_meta_.type_, in_str, ctx, res_datum);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -7094,6 +7133,137 @@ CAST_FUNC_NAME(enumset, decimalint)
|
||||
return ret;
|
||||
}
|
||||
|
||||
CAST_FUNC_NAME(enumset, datetime)
|
||||
{
|
||||
EVAL_ARG() {
|
||||
const uint64_t in_val = child_res->get_enumset();
|
||||
ObExpr &enumset_expr = *expr.args_[0];
|
||||
ObEvalCtx::TempAllocGuard tmp_alloc_g(ctx);
|
||||
common::ObArenaAllocator &temp_allocator = tmp_alloc_g.get_allocator();
|
||||
ObTextStringResult text_result(ObVarcharType, false, &temp_allocator);
|
||||
ObString es_str;
|
||||
if (OB_FAIL(common_enumset_string(enumset_expr, in_val, ctx, text_result))) {
|
||||
LOG_WARN("common_enumset_string failed", K(ret), K(in_val));
|
||||
} else if (FALSE_IT(text_result.get_result_buffer(es_str))) {
|
||||
} else if (OB_FAIL(common_string_datetime(expr, es_str, ctx, res_datum))) {
|
||||
LOG_WARN("common_string_datetime failed", K(ret), K(es_str));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
CAST_FUNC_NAME(enumset, date)
|
||||
{
|
||||
EVAL_ARG() {
|
||||
const uint64_t in_val = child_res->get_enumset();
|
||||
ObExpr &enumset_expr = *expr.args_[0];
|
||||
ObEvalCtx::TempAllocGuard tmp_alloc_g(ctx);
|
||||
common::ObArenaAllocator &temp_allocator = tmp_alloc_g.get_allocator();
|
||||
ObTextStringResult text_result(ObVarcharType, false, &temp_allocator);
|
||||
ObString es_str;
|
||||
if (OB_FAIL(common_enumset_string(enumset_expr, in_val, ctx, text_result))) {
|
||||
LOG_WARN("common_enumset_string failed", K(ret), K(in_val));
|
||||
} else if (FALSE_IT(text_result.get_result_buffer(es_str))) {
|
||||
} else if (OB_FAIL(common_string_date(expr, es_str, res_datum))) {
|
||||
LOG_WARN("common_string_date failed", K(ret), K(es_str));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
CAST_FUNC_NAME(enumset, time)
|
||||
{
|
||||
EVAL_ARG() {
|
||||
const uint64_t in_val = child_res->get_enumset();
|
||||
ObExpr &enumset_expr = *expr.args_[0];
|
||||
ObEvalCtx::TempAllocGuard tmp_alloc_g(ctx);
|
||||
common::ObArenaAllocator &temp_allocator = tmp_alloc_g.get_allocator();
|
||||
ObTextStringResult text_result(ObVarcharType, false, &temp_allocator);
|
||||
ObString es_str;
|
||||
if (OB_FAIL(common_enumset_string(enumset_expr, in_val, ctx, text_result))) {
|
||||
LOG_WARN("common_enumset_string failed", K(ret), K(in_val));
|
||||
} else if (FALSE_IT(text_result.get_result_buffer(es_str))) {
|
||||
} else if (OB_FAIL(common_string_time(expr, es_str, res_datum))) {
|
||||
LOG_WARN("common_string_time failed", K(ret), K(es_str));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
CAST_FUNC_NAME(enumset, string)
|
||||
{
|
||||
EVAL_ARG() {
|
||||
const uint64_t in_val = child_res->get_enumset();
|
||||
ObTextStringDatumResult text_result(expr.datum_meta_.type_, &expr, &ctx, &res_datum);
|
||||
if (OB_FAIL(common_enumset_string(*expr.args_[0], in_val, ctx, text_result))) {
|
||||
LOG_WARN("common_enumset_string failed", K(ret), K(in_val));
|
||||
} else {
|
||||
text_result.set_result();
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
CAST_FUNC_NAME(enumset, text)
|
||||
{
|
||||
EVAL_ARG() {
|
||||
const uint64_t in_val = child_res->get_enumset();
|
||||
ObExpr &enumset_expr = *expr.args_[0];
|
||||
ObEvalCtx::TempAllocGuard tmp_alloc_g(ctx);
|
||||
common::ObArenaAllocator &temp_allocator = tmp_alloc_g.get_allocator();
|
||||
ObTextStringResult text_result(ObVarcharType, false, &temp_allocator);
|
||||
ObString es_str;
|
||||
if (OB_FAIL(common_enumset_string(enumset_expr, in_val, ctx, text_result))) {
|
||||
LOG_WARN("common_enumset_string failed", K(ret), K(in_val));
|
||||
} else if (FALSE_IT(text_result.get_result_buffer(es_str))) {
|
||||
} else if (OB_FAIL(common_string_text(expr, es_str, ctx, NULL, res_datum))) {
|
||||
LOG_WARN("common_string_text failed", K(ret), K(es_str));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
CAST_FUNC_NAME(enumset, lob)
|
||||
{
|
||||
EVAL_ARG() {
|
||||
const uint64_t in_val = child_res->get_enumset();
|
||||
ObExpr &enumset_expr = *expr.args_[0];
|
||||
ObEvalCtx::TempAllocGuard tmp_alloc_g(ctx);
|
||||
common::ObArenaAllocator &temp_allocator = tmp_alloc_g.get_allocator();
|
||||
ObTextStringResult text_result(ObVarcharType, false, &temp_allocator);
|
||||
ObString es_str;
|
||||
if (OB_FAIL(common_enumset_string(enumset_expr, in_val, ctx, text_result))) {
|
||||
LOG_WARN("common_enumset_string failed", K(ret), K(in_val));
|
||||
} else if (FALSE_IT(text_result.get_result_buffer(es_str))) {
|
||||
} else if (OB_FAIL(common_string_lob(expr, es_str, ctx, NULL, res_datum))) {
|
||||
LOG_WARN("common_string_lob failed", K(ret), K(es_str));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
CAST_FUNC_NAME(enumset, json)
|
||||
{
|
||||
EVAL_ARG() {
|
||||
const uint64_t in_val = child_res->get_enumset();
|
||||
ObExpr &enumset_expr = *expr.args_[0];
|
||||
ObEvalCtx::TempAllocGuard tmp_alloc_g(ctx);
|
||||
common::ObArenaAllocator &temp_allocator = tmp_alloc_g.get_allocator();
|
||||
ObTextStringResult text_result(ObVarcharType, false, &temp_allocator);
|
||||
ObString es_str;
|
||||
if (OB_FAIL(common_enumset_string(enumset_expr, in_val, ctx, text_result))) {
|
||||
LOG_WARN("common_enumset_string failed", K(ret), K(in_val));
|
||||
} else if (FALSE_IT(text_result.get_result_buffer(es_str))) {
|
||||
} else if (OB_FAIL(ObTextStringHelper::read_real_string_data(
|
||||
&temp_allocator, ObVarcharType, false, es_str, &ctx.exec_ctx_))) {
|
||||
LOG_WARN("fail to get real data.", K(ret), K(es_str));
|
||||
} else if (OB_FAIL(common_string_json(expr, ObVarcharType, es_str, ctx, res_datum))) {
|
||||
LOG_WARN("common_string_json failed", K(ret), K(es_str));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
CAST_FUNC_NAME(enumset_inner, int)
|
||||
{
|
||||
EVAL_ARG() {
|
||||
@ -7834,7 +8004,7 @@ CAST_FUNC_NAME(raw, json)
|
||||
EVAL_ARG()
|
||||
{
|
||||
ObString in_str(child_res->len_, child_res->ptr_);
|
||||
ret = common_string_json(expr, in_str, ctx, res_datum);
|
||||
ret = common_string_json(expr, expr.args_[0]->datum_meta_.type_, in_str, ctx, res_datum);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -8222,7 +8392,7 @@ CAST_FUNC_NAME(lob, json)
|
||||
{
|
||||
const ObLobLocator &lob_locator = child_res->get_lob_locator();
|
||||
ObString in_str(lob_locator.payload_size_, lob_locator.get_payload_ptr());
|
||||
OZ(common_string_json(expr, in_str, ctx, res_datum));
|
||||
OZ(common_string_json(expr, expr.args_[0]->datum_meta_.type_, in_str, ctx, res_datum));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -10382,7 +10552,7 @@ int string_to_enum(ObIAllocator &alloc,
|
||||
uint64_t &output_value)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
const ObCollationType cs_type = expr.obj_meta_.get_collation_type();
|
||||
const ObCollationType cs_type = expr.datum_meta_.cs_type_;
|
||||
uint64_t value = 0;
|
||||
int32_t pos = 0;
|
||||
ObString in_str;
|
||||
@ -10468,7 +10638,7 @@ int string_to_set(ObIAllocator &alloc,
|
||||
int ret = OB_SUCCESS;
|
||||
uint64_t value = 0;
|
||||
ObString in_str;
|
||||
const ObCollationType cs_type = expr.obj_meta_.get_collation_type();
|
||||
const ObCollationType cs_type = expr.datum_meta_.cs_type_;
|
||||
OZ(ObCharset::charset_convert(alloc, orig_in_str, in_cs_type, cs_type, in_str));
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (in_str.empty()) {
|
||||
@ -11250,6 +11420,38 @@ CAST_FUNC_NAME(roaringbitmap, roaringbitmap)
|
||||
return ret;
|
||||
}
|
||||
|
||||
CAST_FUNC_NAME(enumset, enumset)
|
||||
{
|
||||
EVAL_ARG() {
|
||||
const uint64_t in_val = child_res->get_enumset();
|
||||
ObExpr &enumset_expr = *expr.args_[0];
|
||||
ObEvalCtx::TempAllocGuard tmp_alloc_g(ctx);
|
||||
common::ObArenaAllocator &temp_allocator = tmp_alloc_g.get_allocator();
|
||||
ObTextStringResult text_result(ObVarcharType, false, &temp_allocator);
|
||||
ObString es_str;
|
||||
const ObEnumSetMeta *meta = NULL;
|
||||
if (OB_FAIL(common_enumset_string(enumset_expr, in_val, ctx, text_result))) {
|
||||
LOG_WARN("common_enumset_string failed", K(ret), K(in_val));
|
||||
} else if (FALSE_IT(text_result.get_result_buffer(es_str))) {
|
||||
} else if (OB_FAIL(get_enumset_meta(ctx, expr.obj_meta_, meta))) {
|
||||
LOG_WARN("fail to get enumset meta", K(ret));
|
||||
} else {
|
||||
int warning = 0;
|
||||
uint64_t value = 0;
|
||||
const ObCastMode cast_mode = expr.extra_;
|
||||
if (ObEnumType == expr.datum_meta_.type_) {
|
||||
ret = string_to_enum(temp_allocator, es_str, expr.args_[0]->datum_meta_.cs_type_,
|
||||
*meta->get_str_values(), cast_mode, expr, warning, value);
|
||||
SET_RES_ENUM(value);
|
||||
} else {
|
||||
ret = string_to_set(temp_allocator, es_str, expr.args_[0]->datum_meta_.cs_type_,
|
||||
*meta->get_str_values(), cast_mode, expr, warning, value);
|
||||
SET_RES_SET(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
// exclude varchar/char type
|
||||
int anytype_anytype_explicit(const sql::ObExpr &expr,
|
||||
sql::ObEvalCtx &ctx,
|
||||
@ -14744,24 +14946,24 @@ ObExpr::EvalFunc OB_DATUM_CAST_MYSQL_IMPLICIT[ObMaxTC][ObMaxTC] =
|
||||
enumset_float, // /*float*/
|
||||
enumset_double, // /*double*/
|
||||
enumset_number, // /*number*/
|
||||
cast_not_expected,/*datetime*/
|
||||
cast_not_expected,/*date*/
|
||||
cast_not_expected,/*time*/
|
||||
enumset_datetime,/*datetime*/
|
||||
enumset_date,/*date*/
|
||||
enumset_time,/*time*/
|
||||
enumset_year, // /*year*/
|
||||
cast_not_expected,/*string*/
|
||||
enumset_string,/*string*/
|
||||
cast_not_support,/*extend*/
|
||||
cast_not_support,/*unknown*/
|
||||
cast_not_expected,/*text*/
|
||||
enumset_text,/*text*/
|
||||
enumset_bit, // /*bit*/
|
||||
cast_not_expected,/*enumset*/
|
||||
enumset_enumset, /*enumset*/
|
||||
cast_not_expected,/*enumset_inner*/
|
||||
cast_not_support,/*otimestamp*/
|
||||
cast_inconsistent_types,/*raw*/
|
||||
cast_not_expected,/*interval*/
|
||||
cast_not_expected,/*rowid*/
|
||||
cast_not_expected,/*lob*/
|
||||
cast_not_expected,/*json*/
|
||||
cast_not_expected,/*geometry*/
|
||||
enumset_lob,/*lob*/
|
||||
enumset_json,/*json*/
|
||||
cast_not_support,/*geometry*/
|
||||
cast_not_expected,/*udt, not implemented in mysql mode*/
|
||||
enumset_decimalint,/*decimalint*/
|
||||
cast_not_expected,/*collection, not implemented in mysql mode*/
|
||||
|
@ -437,8 +437,9 @@ int ObExprCast::calc_result_type2(ObExprResType &type,
|
||||
ObCollationType collation_nation = session->get_nls_collation_nation();
|
||||
type1.set_calc_type(get_calc_cast_type(type1.get_type(), dst_type.get_type()));
|
||||
int32_t length = 0;
|
||||
if (ob_is_string_or_lob_type(dst_type.get_type()) || ob_is_raw(dst_type.get_type()) || ob_is_json(dst_type.get_type())
|
||||
|| ob_is_geometry(dst_type.get_type())) {
|
||||
if (ob_is_string_or_lob_type(dst_type.get_type()) || ob_is_raw(dst_type.get_type())
|
||||
|| ob_is_json(dst_type.get_type())
|
||||
|| ob_is_geometry(dst_type.get_type())) {
|
||||
type.set_collation_level(dst_type.get_collation_level());
|
||||
int32_t len = dst_type.get_length();
|
||||
int16_t length_semantics = ((dst_type.is_string_or_lob_locator_type() || dst_type.is_json())
|
||||
@ -557,15 +558,19 @@ int ObExprCast::calc_result_type2(ObExprResType &type,
|
||||
sql_xml_type.set_sql_udt(ObXMLSqlType);
|
||||
type1.set_calc_meta(sql_xml_type.get_obj_meta());
|
||||
} else {
|
||||
bool need_warp = false;
|
||||
bool need_wrap = false;
|
||||
if (ob_is_enumset_tc(type1.get_type())) {
|
||||
// For enum/set type, need to check whether warp to string is required.
|
||||
if (OB_FAIL(ObRawExprUtils::need_wrap_to_string(type1.get_type(), type1.get_calc_type(),
|
||||
false, need_warp))) {
|
||||
if (OB_FAIL(ObRawExprUtils::need_wrap_to_string(type1, type1.get_calc_type(),
|
||||
false, need_wrap))) {
|
||||
LOG_WARN("need_wrap_to_string failed", K(ret), K(type1));
|
||||
} else if (!need_wrap) {
|
||||
// need_wrap is false, set calc_type to type1 itself.
|
||||
type1.set_calc_meta(type1.get_obj_meta());
|
||||
type1.set_calc_accuracy(type1.get_calc_accuracy());
|
||||
}
|
||||
} else if (OB_LIKELY(need_warp)) {
|
||||
// need_warp is true, no-op and keep type1's calc_type is dst_type. It will be wrapped
|
||||
} else if (OB_LIKELY(need_wrap)) {
|
||||
// need_wrap is true, no-op and keep type1's calc_type is dst_type. It will be wrapped
|
||||
// to string in ObRawExprWrapEnumSet::visit(ObSysFunRawExpr &expr) later.
|
||||
} else {
|
||||
if (ob_is_geometry_tc(dst_type.get_type())) {
|
||||
@ -581,7 +586,7 @@ int ObExprCast::calc_result_type2(ObExprResType &type,
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
// need_warp is false, set calc_type to type1 itself.
|
||||
// need_wrap is false, set calc_type to type1 itself.
|
||||
type1.set_calc_meta(type1.get_obj_meta());
|
||||
}
|
||||
}
|
||||
|
@ -62,18 +62,22 @@ int ObExprCoalesce::calc_result_typeN(ObExprResType &type,
|
||||
LOG_WARN("cast basic session to sql session info failed", K(ret));
|
||||
} else {
|
||||
ObExprOperator::calc_result_flagN(type, types, param_num);
|
||||
ObObjType calc_type = enumset_calc_types_[OBJ_TYPE_TO_CLASS[type.get_type()]];
|
||||
bool is_expr_integer_type = (ob_is_int_tc(type.get_type()) ||
|
||||
ob_is_uint_tc(type.get_type()));
|
||||
bool all_null_type = true;
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < param_num; ++i) {
|
||||
all_null_type = (types[i].get_type() != ObNullType) ? false : all_null_type;
|
||||
if (ob_is_enumset_tc(types[i].get_type())) {
|
||||
ObObjType calc_type = get_enumset_calc_type(type.get_type(), i);
|
||||
if (OB_UNLIKELY(ObMaxType == calc_type)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
SQL_ENG_LOG(WARN, "invalid type of parameter ", K(i), K(ret));
|
||||
} else {
|
||||
types[i].set_calc_type(calc_type);
|
||||
if (ob_is_string_type(calc_type)) {
|
||||
types[i].set_calc_collation_type(type.get_collation_type());
|
||||
types[i].set_calc_collation_level(CS_LEVEL_IMPLICIT);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
bool is_arg_integer_type = (ob_is_int_tc(types[i].get_type()) ||
|
||||
|
@ -272,21 +272,12 @@ int ObExprColumnConv::calc_result_typeN(ObExprResType &type,
|
||||
type.set_result_flag(NOT_NULL_FLAG | NOT_NULL_WRITE_FLAG);
|
||||
}
|
||||
|
||||
bool enumset_to_varchar = false;
|
||||
//here will wrap type_to_str if necessary
|
||||
if (OB_SUCC(ret) && ob_is_enumset_tc(types[4].get_type())) {
|
||||
ObObjType calc_type = enumset_calc_types_[OBJ_TYPE_TO_CLASS[types[0].get_type()]];
|
||||
if (OB_UNLIKELY(ObMaxType == calc_type)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
SQL_ENG_LOG(WARN, "invalid type of parameter ", K(types[4]), K(types), K(ret));
|
||||
} else if (ObVarcharType == calc_type) {
|
||||
enumset_to_varchar = true;
|
||||
types[4].set_calc_type(calc_type);
|
||||
types[4].set_calc_collation_type(coll_type);
|
||||
types[4].set_calc_collation_level(CS_LEVEL_IMPLICIT);
|
||||
type_ctx.set_cast_mode(type_ctx.get_cast_mode() | type_ctx.get_raw_expr()->get_extra());
|
||||
}
|
||||
bool wrap_to_str = false;
|
||||
if (OB_SUCC(ret) && OB_FAIL(calc_enum_set_result_type(type, types, coll_type, type_ctx,
|
||||
wrap_to_str))) {
|
||||
LOG_WARN("fail to calc enum set result type", K(ret));
|
||||
}
|
||||
|
||||
// for table modify in oracle mode, we ignore charset convert failed
|
||||
if (OB_SUCC(ret) && lib::is_oracle_mode()) {
|
||||
type_ctx.set_cast_mode(type_ctx.get_cast_mode() | CM_CHARSET_CONVERT_IGNORE_ERR);
|
||||
@ -298,7 +289,7 @@ int ObExprColumnConv::calc_result_typeN(ObExprResType &type,
|
||||
LOG_WARN("failed to check valid implicit convert", K(ret));
|
||||
}
|
||||
|
||||
if (OB_SUCC(ret) && !enumset_to_varchar) {
|
||||
if (OB_SUCC(ret) && !wrap_to_str) {
|
||||
//cast type when type not same.
|
||||
const ObObjTypeClass value_tc = ob_obj_type_class(types[4].get_type());
|
||||
const ObObjTypeClass type_tc = ob_obj_type_class(types[0].get_type());
|
||||
@ -325,7 +316,70 @@ int ObExprColumnConv::calc_result_typeN(ObExprResType &type,
|
||||
}
|
||||
}
|
||||
}
|
||||
LOG_DEBUG("finish calc_result_typeN", K(type), K(types[4]), K(types[0]), K(enumset_to_varchar));
|
||||
LOG_DEBUG("finish calc_result_typeN", K(type), K(types[4]), K(types[0]), K(wrap_to_str));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObExprColumnConv::calc_enum_set_result_type(ObExprResType &type,
|
||||
ObExprResType *types,
|
||||
ObCollationType coll_type,
|
||||
ObExprTypeCtx &type_ctx,
|
||||
bool &wrap_to_str) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
// here will wrap type_to_str if necessary
|
||||
// for enum set type with subschema, it can directly execute any type of cast,
|
||||
// so there is no need to wrap type_to_str.
|
||||
if (ob_is_enumset_tc(types[4].get_type())) {
|
||||
ObObjType calc_type = get_enumset_calc_type(types[0].get_type(), 4);
|
||||
// When the types are inconsistent or it doesn't support enum/set type with subschema,
|
||||
// new cast expression is required.
|
||||
const bool support_enum_set_type_subschema = is_enum_set_with_subschema_arg(4);
|
||||
bool need_add_cast = type.get_type() != types[4].get_type() || !support_enum_set_type_subschema;
|
||||
// keep old behavior use session collation
|
||||
coll_type = support_enum_set_type_subschema ? types[1].get_collation_type() : coll_type;
|
||||
if (OB_UNLIKELY(ObMaxType == calc_type)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
SQL_ENG_LOG(WARN, "invalid type of parameter ", K(types[4]), K(types), K(ret));
|
||||
} else if (ob_is_string_type(calc_type) && need_add_cast) {
|
||||
wrap_to_str = true;
|
||||
} else if (!need_add_cast && ob_is_enum_or_set_type(type.get_type())) {
|
||||
wrap_to_str = true; // set wrap to str to true first
|
||||
// the src and dst types are the same, and both are enum/set. we need to check the
|
||||
// subschema id of the expr result type.
|
||||
const ObRawExpr *conv_expr = get_raw_expr();
|
||||
const ObRawExpr *enumset_expr = NULL;
|
||||
const ObEnumSetMeta *src_meta = NULL;
|
||||
const ObExecContext *exec_ctx = NULL;
|
||||
if (OB_ISNULL(conv_expr) || OB_ISNULL(enumset_expr = conv_expr->get_param_expr(4))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("raw expr or child expr is null", K(ret), KP(conv_expr));
|
||||
} else if (OB_ISNULL(exec_ctx = type_ctx.get_session()->get_cur_exec_ctx())) {
|
||||
} else if (OB_UNLIKELY(!enumset_expr->is_enum_set_with_subschema())) {
|
||||
// skip check enum/set expr with old behavior
|
||||
} else if (OB_UNLIKELY(conv_expr->get_enum_set_values().empty())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("str values for enum set expr is empty", K(ret));
|
||||
} else if (OB_FAIL(exec_ctx->get_enumset_meta_by_subschema_id(
|
||||
enumset_expr->get_subschema_id(), src_meta))) {
|
||||
LOG_WARN("failed to meta from exec_ctx", K(ret), K(enumset_expr->get_subschema_id()));
|
||||
} else if (OB_ISNULL(src_meta)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("src meta is unexpected", K(ret), KP(src_meta));
|
||||
} else if (src_meta->is_same(src_meta->get_obj_meta(), conv_expr->get_enum_set_values())) {
|
||||
// set wrap to str to false, it will be checked in `ObRawExprWrapEnumSet`
|
||||
wrap_to_str = false;
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
if (wrap_to_str) {
|
||||
types[4].set_calc_type(calc_type);
|
||||
types[4].set_calc_collation_type(coll_type);
|
||||
types[4].set_calc_collation_level(CS_LEVEL_IMPLICIT);
|
||||
type_ctx.set_cast_mode(type_ctx.get_cast_mode() | type_ctx.get_raw_expr()->get_extra());
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -150,6 +150,11 @@ public:
|
||||
{ return ob_is_enum_or_set_type(result_type_.get_type()); }
|
||||
|
||||
private:
|
||||
int calc_enum_set_result_type(ObExprResType &type,
|
||||
ObExprResType *types,
|
||||
ObCollationType coll_type,
|
||||
common::ObExprTypeCtx &type_ctx,
|
||||
bool &wrap_to_str) const;
|
||||
static int eval_enumset(const ObExpr &expr, ObEvalCtx &ctx, common::ObDatum *&datum);
|
||||
|
||||
private:
|
||||
|
@ -346,7 +346,7 @@ int ObExprSubAddtime::calc_result_type2(ObExprResType &type,
|
||||
date_arg.set_calc_type(ObVarcharType);
|
||||
}
|
||||
if (ob_is_enumset_tc(time_arg.get_type())) {
|
||||
time_arg.set_calc_type(ObVarcharType);
|
||||
time_arg.set_calc_type(get_enumset_calc_type(ObTimeType, 1));
|
||||
} else {
|
||||
type_ctx.set_cast_mode(type_ctx.get_cast_mode() | CM_NULL_ON_WARN);
|
||||
time_arg.set_calc_type(ObTimeType);
|
||||
|
@ -43,7 +43,7 @@ public:
|
||||
|
||||
TO_STRING_KV(KP_(expr), KP_(ctx), KPC_(res_datum));
|
||||
|
||||
int init(int64_t res_len, ObIAllocator *allocator = NULL);
|
||||
int init(int64_t res_len, ObIAllocator *allocator = NULL) override;
|
||||
int init_with_batch_idx(int64_t res_len, int64_t batch_idx);
|
||||
void set_result();
|
||||
void set_result_null();
|
||||
@ -142,7 +142,7 @@ public:
|
||||
~ObTextStringObObjResult(){};
|
||||
|
||||
TO_STRING_KV(KP_(params), KP_(res_obj));
|
||||
int init(int64_t res_len, ObIAllocator *allocator = NULL);
|
||||
int init(int64_t res_len, ObIAllocator *allocator = NULL) override;
|
||||
void set_result();
|
||||
|
||||
private:
|
||||
|
@ -89,12 +89,12 @@ int ObExprNullif::se_deduce_type(ObExprResType &type,
|
||||
OZ(calc_cmp_type2(cmp_type, type1, type2, type_ctx));
|
||||
if (OB_SUCC(ret)) {
|
||||
if (ob_is_enumset_tc(type1.get_type()) || ob_is_enumset_tc(type2.get_type())) {
|
||||
ObObjType calc_type = enumset_calc_types_[OBJ_TYPE_TO_CLASS[cmp_type.get_calc_type()]];
|
||||
ObObjType calc_type = get_enumset_calc_type(cmp_type.get_calc_type(), -1);
|
||||
CK(ObMaxType != calc_type);
|
||||
if (OB_SUCC(ret)) {
|
||||
cmp_type.set_calc_type(calc_type);
|
||||
cmp_type.set_calc_collation_type(ObCharset::get_system_collation());
|
||||
if (ObVarcharType == calc_type) {
|
||||
if (ob_is_string_type(calc_type)) {
|
||||
if (ob_is_enumset_tc(type1.get_type())) {
|
||||
// only set calc type when calc_type is varchar.
|
||||
// EnumWrapper will add EnumToStr when calc_type is varchar, and otherwise add EnumToInner.
|
||||
@ -108,7 +108,7 @@ int ObExprNullif::se_deduce_type(ObExprResType &type,
|
||||
if (type1.is_decimal_int()) {
|
||||
type1.set_calc_type(calc_type);
|
||||
}
|
||||
// set calc type for type2 no matter whether calc_type is varchar or not, and no matther which param is enum.
|
||||
// set calc type for type2 no matter whether calc_type is varchar or not, and no matter which param is enum.
|
||||
type2.set_calc_type(calc_type);
|
||||
type2.set_calc_collation_type(cmp_type.get_calc_collation_type());
|
||||
type2.set_calc_collation_level(cmp_type.get_calc_collation_level());
|
||||
|
@ -179,19 +179,20 @@ int ObExprNvl::calc_result_type2(ObExprResType &type,
|
||||
const bool type1_is_enumset = ob_is_enumset_tc(type1.get_type());
|
||||
const bool type2_is_enumset = ob_is_enumset_tc(type2.get_type());
|
||||
if (type1_is_enumset || type2_is_enumset) {
|
||||
ObObjType calc_type = enumset_calc_types_[OBJ_TYPE_TO_CLASS[type.get_type()]];
|
||||
ObObjType calc_type = get_enumset_calc_type(type.get_type(), OB_INVALID_INDEX);
|
||||
if (OB_UNLIKELY(ObMaxType == calc_type)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
SQL_ENG_LOG(WARN, "invalid type of parameter ", K(type1), K(type2), K(ret));
|
||||
} else if (ObVarcharType == calc_type) {
|
||||
if (type1_is_enumset) {
|
||||
type1.set_calc_type(calc_type);
|
||||
type1.set_calc_collation_type(ObCharset::get_system_collation());
|
||||
type1.set_calc_type(get_enumset_calc_type(type.get_type(), 0));
|
||||
type1.set_calc_collation_type(type.get_collation_type());
|
||||
} else {
|
||||
set_calc_type(type, type1);
|
||||
}
|
||||
if (type2_is_enumset) {
|
||||
type2.set_calc_type(calc_type);
|
||||
type2.set_calc_type(get_enumset_calc_type(type.get_type(), 1));
|
||||
type2.set_calc_collation_type(type.get_collation_type());
|
||||
} else {
|
||||
set_calc_type(type, type2);
|
||||
}
|
||||
|
@ -865,7 +865,7 @@ int ObExprOperator::aggregate_charsets_for_string_result(
|
||||
if (OB_FAIL(enable_old_charset_aggregation(type_ctx.get_session(), flags))) {
|
||||
LOG_WARN("failed to check is_old_charset_aggregation_enabled", K(ret));
|
||||
} else {
|
||||
ret = aggregate_charsets(type, types, param_num, flags, type_ctx.get_coll_type());
|
||||
ret = aggregate_charsets(type, types, param_num, flags, type_ctx);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -883,7 +883,7 @@ int ObExprOperator::aggregate_charsets_for_string_result(
|
||||
if (OB_FAIL(enable_old_charset_aggregation(type_ctx.get_session(), flags))) {
|
||||
LOG_WARN("failed to check is_old_charset_aggregation_enabled", K(ret));
|
||||
} else {
|
||||
ret = aggregate_charsets(type, types, param_num, flags, type_ctx.get_coll_type());
|
||||
ret = aggregate_charsets(type, types, param_num, flags, type_ctx);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -901,7 +901,7 @@ int ObExprOperator::aggregate_charsets_for_comparison(
|
||||
if (OB_FAIL(enable_old_charset_aggregation(type_ctx.get_session(), flags))) {
|
||||
LOG_WARN("failed to check is_old_charset_aggregation_enabled", K(ret));
|
||||
} else {
|
||||
ret = aggregate_charsets(type, types, param_num, flags, type_ctx.get_coll_type());
|
||||
ret = aggregate_charsets(type, types, param_num, flags, type_ctx);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -920,7 +920,7 @@ int ObExprOperator::aggregate_charsets_for_comparison(
|
||||
if (OB_FAIL(enable_old_charset_aggregation(type_ctx.get_session(), flags))) {
|
||||
LOG_WARN("failed to check is_old_charset_aggregation_enabled", K(ret));
|
||||
} else {
|
||||
ret = aggregate_charsets(type.get_calc_meta(), types, param_num, flags, type_ctx.get_coll_type());
|
||||
ret = aggregate_charsets(type.get_calc_meta(), types, param_num, flags, type_ctx);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -939,7 +939,7 @@ int ObExprOperator::aggregate_charsets_for_string_result_with_comparison(
|
||||
if (OB_FAIL(enable_old_charset_aggregation(type_ctx.get_session(), flags))) {
|
||||
LOG_WARN("failed to check is_old_charset_aggregation_enabled", K(ret));
|
||||
} else {
|
||||
ret = aggregate_charsets(type, types, param_num, flags, type_ctx.get_coll_type());
|
||||
ret = aggregate_charsets(type, types, param_num, flags, type_ctx);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -958,7 +958,7 @@ int ObExprOperator::aggregate_charsets_for_string_result_with_comparison(
|
||||
if (OB_FAIL(enable_old_charset_aggregation(type_ctx.get_session(), flags))) {
|
||||
LOG_WARN("failed to check is_old_charset_aggregation_enabled", K(ret));
|
||||
} else {
|
||||
ret = aggregate_charsets(type, types, param_num, flags, type_ctx.get_coll_type());
|
||||
ret = aggregate_charsets(type, types, param_num, flags, type_ctx);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -968,9 +968,9 @@ int ObExprOperator::aggregate_charsets(
|
||||
const ObObjMeta *types,
|
||||
int64_t param_num,
|
||||
uint32_t flags,
|
||||
const ObCollationType conn_coll_type)
|
||||
common::ObExprTypeCtx &type_ctx)
|
||||
{
|
||||
return aggregate_collations(type, types, param_num, flags, conn_coll_type);
|
||||
return aggregate_collations(type, types, param_num, flags, type_ctx.get_coll_type());
|
||||
}
|
||||
|
||||
int ObExprOperator::aggregate_charsets(
|
||||
@ -978,7 +978,7 @@ int ObExprOperator::aggregate_charsets(
|
||||
const ObExprResType *types,
|
||||
int64_t param_num,
|
||||
uint32_t flags,
|
||||
const ObCollationType conn_coll_type)
|
||||
common::ObExprTypeCtx &type_ctx)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
CK(OB_NOT_NULL(types),
|
||||
@ -990,20 +990,30 @@ int ObExprOperator::aggregate_charsets(
|
||||
for (int i = 0; OB_SUCC(ret) && i < param_num; ++i) {
|
||||
coll.reset();
|
||||
// issue:49962420 The xml type calls get_collation_type() to return the result of binary, here is set to utf8
|
||||
coll.set_collation_level(types[i].get_collation_level());
|
||||
if (type.is_string_type() && types[i].is_xml_sql_type()) {
|
||||
coll.set_collation_type(ObCollationType::CS_TYPE_UTF8MB4_BIN);
|
||||
} else if (types[i].is_enum_set_with_subschema()) {
|
||||
ObObjMeta obj_meta;
|
||||
if (OB_FAIL(ObRawExprUtils::extract_enum_set_collation(types[i], type_ctx.get_session(),
|
||||
obj_meta))) {
|
||||
LOG_WARN("fail to extract enum set cs type", K(ret));
|
||||
} else {
|
||||
coll.set_collation(obj_meta);
|
||||
}
|
||||
} else {
|
||||
coll.set_collation_type(types[i].get_collation_type());
|
||||
}
|
||||
coll.set_collation_level(types[i].get_collation_level());
|
||||
ret = coll_types.push_back(coll);
|
||||
if (OB_SUCC(ret)) {
|
||||
ret = coll_types.push_back(coll);
|
||||
}
|
||||
} // end for
|
||||
|
||||
OZ (aggregate_charsets(type,
|
||||
&coll_types.at(0),
|
||||
param_num,
|
||||
flags,
|
||||
conn_coll_type));
|
||||
type_ctx));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -1273,9 +1283,9 @@ int ObExprOperator::aggregate_result_type_for_case(
|
||||
if (OB_FAIL(aggregate_numeric_accuracy_for_merge(type, types, param_num, is_oracle_mode))) {
|
||||
LOG_WARN("fail to aggregate numeric accuracy", K(ret));
|
||||
}
|
||||
} else if (OB_FAIL(aggregate_result_type_for_merge(type, types, param_num,
|
||||
is_oracle_mode, type_ctx, need_merge_type, skip_null,
|
||||
is_called_in_sql))) {
|
||||
// the collation of case_expr has been restored
|
||||
} else if (OB_FAIL(aggregate_result_type_for_merge(type, types, param_num, is_oracle_mode,
|
||||
type_ctx, need_merge_type, skip_null, is_called_in_sql))) {
|
||||
LOG_WARN("fail to aggregate result type", K(ret));
|
||||
} else if (ObFloatType == type.get_type() && !is_oracle_mode) {
|
||||
type.set_type(ObDoubleType);
|
||||
@ -1309,6 +1319,7 @@ int ObExprOperator::aggregate_result_type_for_merge(
|
||||
const ObLengthSemantics default_length_semantics = ((OB_NOT_NULL(type_ctx.get_session())) ?
|
||||
type_ctx.get_session()->get_actual_nls_length_semantics() : LS_BYTE);
|
||||
|
||||
bool has_new_enum_set_type = types[0].is_enum_set_with_subschema();
|
||||
for (int64_t i = 1; OB_SUCC(ret) && i < param_num; ++i) {
|
||||
if (OB_FAIL(ObExprResultTypeUtil::get_merge_result_type(res_type,
|
||||
res_type,
|
||||
@ -1327,6 +1338,8 @@ int ObExprOperator::aggregate_result_type_for_merge(
|
||||
types[i].get_precision() == types[i-1].get_precision() &&
|
||||
types[i].get_scale() == types[i-1].get_scale();
|
||||
}
|
||||
} else if (types[i].is_enum_set_with_subschema()) {
|
||||
has_new_enum_set_type = true;
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
@ -1345,8 +1358,32 @@ int ObExprOperator::aggregate_result_type_for_merge(
|
||||
} else if (ob_is_temporal_type(res_type) || ob_is_otimestamp_type(res_type)) {
|
||||
ret = aggregate_temporal_accuracy_for_merge(type, types, param_num);
|
||||
} else if (ob_is_string_or_lob_type(res_type)) {
|
||||
if (OB_FAIL(aggregate_charsets_for_string_result(type, types, param_num, type_ctx))) {
|
||||
} else if (OB_FAIL(aggregate_max_length_for_string_result(type, types, param_num,
|
||||
const ObExprResType *new_types = types;
|
||||
const ObSQLSessionInfo *session_info = type_ctx.get_session();
|
||||
if (has_new_enum_set_type && session_info != NULL) {
|
||||
ObSEArray<ObExprResType, 2> restored_types;
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < param_num; ++i) {
|
||||
if (OB_FAIL(restored_types.push_back(types[i]))) {
|
||||
LOG_WARN("fail to push back types", K(ret));
|
||||
} else if (types[i].is_enum_set_with_subschema()) {
|
||||
ObObjMeta obj_meta;
|
||||
if (OB_FAIL(ObRawExprUtils::extract_enum_set_collation(types[i], session_info,
|
||||
obj_meta))) {
|
||||
LOG_WARN("fail to extract enum set cs type", K(ret));
|
||||
} else {
|
||||
restored_types[i].set_collation(obj_meta);
|
||||
restored_types[i].reset_enum_set_meta_state();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
new_types = &restored_types.at(0);
|
||||
}
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_FAIL(aggregate_charsets_for_string_result(type, new_types, param_num,
|
||||
type_ctx))) {
|
||||
} else if (OB_FAIL(aggregate_max_length_for_string_result(type, new_types, param_num,
|
||||
is_oracle_mode, default_length_semantics, need_merge_type, skip_null,
|
||||
is_called_in_sql))) {
|
||||
} else {/*do nothing*/}
|
||||
@ -1770,38 +1807,72 @@ int ObExprDFMConvertCtx::parse_format(const ObString &format_str,
|
||||
ObExprFindIntCachedValue::~ObExprFindIntCachedValue() {
|
||||
}
|
||||
|
||||
ObObjType ObExprOperator::enumset_calc_types_[ObMaxTC] =
|
||||
ObObjType ObExprOperator::enumset_calc_types_[2 /*use_subschema*/][ObMaxTC] =
|
||||
{
|
||||
ObUInt64Type,/*ObNullTC*/
|
||||
ObUInt64Type,/*ObIntTC*/
|
||||
ObUInt64Type,/*ObUIntTC*/
|
||||
ObUInt64Type,/*ObFloatTC*/
|
||||
ObUInt64Type,/*ObDoubleTC*/
|
||||
ObUInt64Type,/*ObNumberTC*/
|
||||
ObVarcharType,/*ObDateTimeTC*/
|
||||
ObVarcharType,/*ObDateTC*/
|
||||
ObVarcharType,/*ObTimeTC*/
|
||||
ObUInt64Type,/*ObYearTC*/
|
||||
ObVarcharType,/*ObStringTC*/
|
||||
ObMaxType,/*ObExtendTC*/
|
||||
ObMaxType,/*ObUnknownTC*/
|
||||
ObVarcharType,/*ObTextTC*/
|
||||
ObUInt64Type,/*ObBitTC*/
|
||||
ObVarcharType,/*ObEnumSetTC*/
|
||||
ObVarcharType,/*ObEnumSetInnerTC*/
|
||||
ObVarcharType, /*ObOTimestampTC*/
|
||||
ObNullType, /*ObRawTC*/
|
||||
ObVarcharType, /*ObInternalTC*/
|
||||
ObVarcharType, /*ObRowIDTC*/
|
||||
ObMaxType, /*ObLobTC*/
|
||||
ObVarcharType, /*ObJsonTC*/
|
||||
ObVarcharType, /*ObGeometryTC*/
|
||||
ObNullType, /*UDT*/
|
||||
ObUInt64Type, /*ObDecimalIntTC*/
|
||||
ObNullType, /*COLLECTION*/
|
||||
ObVarcharType, /*ObMySQLDateTC*/
|
||||
ObVarcharType, /*ObMySQLDateTimeTC*/
|
||||
ObVarcharType, /*ObRoaringBitmapTC*/
|
||||
{
|
||||
ObUInt64Type,/*ObNullTC*/
|
||||
ObUInt64Type,/*ObIntTC*/
|
||||
ObUInt64Type,/*ObUIntTC*/
|
||||
ObUInt64Type,/*ObFloatTC*/
|
||||
ObUInt64Type,/*ObDoubleTC*/
|
||||
ObUInt64Type,/*ObNumberTC*/
|
||||
ObVarcharType,/*ObDateTimeTC*/
|
||||
ObVarcharType,/*ObDateTC*/
|
||||
ObVarcharType,/*ObTimeTC*/
|
||||
ObUInt64Type,/*ObYearTC*/
|
||||
ObVarcharType,/*ObStringTC*/
|
||||
ObMaxType,/*ObExtendTC*/
|
||||
ObMaxType,/*ObUnknownTC*/
|
||||
ObVarcharType,/*ObTextTC*/
|
||||
ObUInt64Type,/*ObBitTC*/
|
||||
ObVarcharType,/*ObEnumSetTC*/
|
||||
ObVarcharType,/*ObEnumSetInnerTC*/
|
||||
ObVarcharType, /*ObOTimestampTC*/
|
||||
ObNullType, /*ObRawTC*/
|
||||
ObVarcharType, /*ObInternalTC*/
|
||||
ObVarcharType, /*ObRowIDTC*/
|
||||
ObMaxType, /*ObLobTC*/
|
||||
ObVarcharType, /*ObJsonTC*/
|
||||
ObVarcharType, /*ObGeometryTC*/
|
||||
ObNullType, /*UDT*/
|
||||
ObUInt64Type, /*ObDecimalIntTC*/
|
||||
ObNullType, /*COLLECTION*/
|
||||
ObVarcharType, /*ObMySQLDateTC*/
|
||||
ObVarcharType, /*ObMySQLDateTimeTC*/
|
||||
ObVarcharType, /*ObRoaringBitmapTC*/
|
||||
},
|
||||
{
|
||||
ObUInt64Type,/*ObNullTC*/
|
||||
ObUInt64Type,/*ObIntTC*/
|
||||
ObUInt64Type,/*ObUIntTC*/
|
||||
ObUInt64Type,/*ObFloatTC*/
|
||||
ObUInt64Type,/*ObDoubleTC*/
|
||||
ObUInt64Type,/*ObNumberTC*/
|
||||
ObDateTimeType,/*ObDateTimeTC*/
|
||||
ObDateType,/*ObDateTC*/
|
||||
ObTimeType,/*ObTimeTC*/
|
||||
ObUInt64Type,/*ObYearTC*/
|
||||
ObVarcharType,/*ObStringTC*/
|
||||
ObMaxType,/*ObExtendTC*/
|
||||
ObMaxType,/*ObUnknownTC*/
|
||||
ObVarcharType,/*ObTextTC*/
|
||||
ObUInt64Type,/*ObBitTC*/
|
||||
ObVarcharType,/*ObEnumSetTC*/
|
||||
ObVarcharType,/*ObEnumSetInnerTC*/
|
||||
ObVarcharType, /*ObOTimestampTC*/
|
||||
ObNullType, /*ObRawTC*/
|
||||
ObVarcharType, /*ObInternalTC*/
|
||||
ObVarcharType, /*ObRowIDTC*/
|
||||
ObMaxType, /*ObLobTC*/
|
||||
ObJsonType, /*ObJsonTC*/
|
||||
ObVarcharType, /*ObGeometryTC*/
|
||||
ObNullType, /*UDT*/
|
||||
ObUInt64Type, /*ObDecimalIntTC*/
|
||||
ObNullType, /*COLLECTION*/
|
||||
ObMaxType, /*ObMySQLDateTC*/
|
||||
ObMaxType, /*ObMySQLDateTimeTC*/
|
||||
ObVarcharType, /*ObRoaringBitmapTC*/
|
||||
},
|
||||
};
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -2556,6 +2627,34 @@ int ObExprOperator::add_local_var_to_expr(ObSysVarClassType var_type,
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool ObExprOperator::is_enum_set_with_subschema_arg(const int64_t arg_idx) const
|
||||
{
|
||||
bool bret = false;
|
||||
const ObRawExpr *arg_expr = NULL;
|
||||
if (arg_idx >= 0 && OB_NOT_NULL(raw_expr_) && arg_idx < raw_expr_->get_param_count()
|
||||
&& OB_NOT_NULL(arg_expr = raw_expr_->get_param_expr(arg_idx))
|
||||
&& arg_expr->is_enum_set_with_subschema()) {
|
||||
bret = true;
|
||||
}
|
||||
return bret;
|
||||
}
|
||||
|
||||
ObObjType ObExprOperator::get_enumset_calc_type(const ObObjType expected_type,
|
||||
const int64_t arg_idx) const
|
||||
{
|
||||
ObObjType calc_type = ObMaxType;
|
||||
if (is_enum_set_with_subschema_arg(arg_idx)) {
|
||||
calc_type = enumset_calc_types_[1 /*use subschema*/][OBJ_TYPE_TO_CLASS[expected_type]];
|
||||
// set calc type to dst type direct, otherwise multiple casts may occur.
|
||||
if (ob_is_string_type(expected_type)) {
|
||||
calc_type = expected_type;
|
||||
}
|
||||
} else {
|
||||
calc_type = enumset_calc_types_[0 /*for compatibility*/][OBJ_TYPE_TO_CLASS[expected_type]];
|
||||
}
|
||||
return calc_type;
|
||||
}
|
||||
|
||||
OB_SERIALIZE_MEMBER(ObIterExprOperator, expr_id_, expr_type_);
|
||||
|
||||
int ObRelationalExprOperator::calc_result_type2(ObExprResType &type,
|
||||
@ -4978,6 +5077,26 @@ void ObStringExprOperator::calc_temporal_format_result_length(ObExprResType &typ
|
||||
type.set_length(default_text_length);
|
||||
}
|
||||
}
|
||||
int ObStringExprOperator::extract_enum_set_collation_for_args(const ObExprResType &text,
|
||||
const ObExprResType &pattern,
|
||||
ObExprTypeCtx &type_ctx,
|
||||
ObObjMeta *real_types)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_SUCC(ret) && text.is_enum_set_with_subschema()) {
|
||||
if (OB_FAIL(ObRawExprUtils::extract_enum_set_collation(text, type_ctx.get_session(),
|
||||
real_types[0]))) {
|
||||
LOG_WARN("fail to extract enum set collation", K(ret));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) && pattern.is_enum_set_with_subschema()) {
|
||||
if (OB_FAIL(ObRawExprUtils::extract_enum_set_collation(pattern, type_ctx.get_session(),
|
||||
real_types[1]))) {
|
||||
LOG_WARN("fail to extract enum set collation", K(ret));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
ObObjType ObStringExprOperator::get_result_type_mysql(int64_t char_length) const
|
||||
{
|
||||
@ -5896,18 +6015,16 @@ int ObMinMaxExprOperator::calc_result_meta_for_comparison(
|
||||
}
|
||||
}
|
||||
|
||||
if (OB_SUCC(ret)) {
|
||||
ObObjType dest_type = enumset_calc_types_[OBJ_TYPE_TO_CLASS[type.get_calc_type()]];
|
||||
if (OB_UNLIKELY(ObMaxType == dest_type)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
SQL_ENG_LOG(WARN, "invalid type", K(type), K(ret));
|
||||
} else if (ObVarcharType == dest_type) {
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < param_num; ++i) {
|
||||
if (ob_is_enumset_tc(types_stack[i].get_type())) {
|
||||
types_stack[i].set_calc_type(dest_type);
|
||||
}
|
||||
}
|
||||
} else {/*do nothing*/}
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < param_num; ++i) {
|
||||
if (ob_is_enumset_tc(types_stack[i].get_type())) {
|
||||
ObObjType dest_type = get_enumset_calc_type(type.get_calc_type(), i);
|
||||
if (OB_UNLIKELY(ObMaxType == dest_type)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
SQL_ENG_LOG(WARN, "invalid type", K(type), K(ret));
|
||||
} else if (ob_is_string_type(dest_type)) {
|
||||
types_stack[i].set_calc_type(dest_type);
|
||||
} else {/*do nothing*/}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -506,6 +506,8 @@ public:
|
||||
J_OBJ_END();
|
||||
return pos;
|
||||
}
|
||||
bool is_enum_set_with_subschema_arg(const int64_t arg_idx) const;
|
||||
ObObjType get_enumset_calc_type(const ObObjType expected_type, const int64_t arg_idx) const;
|
||||
public:
|
||||
/*
|
||||
Aggregate arguments for comparison, e.g: a=b, a LIKE b, a RLIKE b
|
||||
@ -705,10 +707,10 @@ protected:
|
||||
const ObExprResType *types,
|
||||
int64_t param_num);
|
||||
static common::ObObjType get_calc_cast_type(common::ObObjType param_type, common::ObObjType calc_type);
|
||||
static common::ObObjType enumset_calc_types_[common::ObMaxTC];
|
||||
|
||||
void disable_operand_auto_cast() { operand_auto_cast_ = false; }
|
||||
private:
|
||||
static common::ObObjType enumset_calc_types_[2 /*use_subschema*/][common::ObMaxTC];
|
||||
/*
|
||||
* 计算框架本身提供了一个通用的数据类型转换方法,将参数转为input_types_中的类型。
|
||||
* 这可能并不是表达式期望的行为,如需要禁止此行为,需要在构造函数中显示调 disable_operand_auto_cast().
|
||||
@ -739,14 +741,14 @@ protected:
|
||||
const common::ObObjMeta *types,
|
||||
int64_t param_num,
|
||||
uint32_t flags,
|
||||
const common::ObCollationType conn_coll_type);
|
||||
common::ObExprTypeCtx &type_ctx);
|
||||
|
||||
static int aggregate_charsets(
|
||||
common::ObObjMeta &type,
|
||||
const ObExprResType *types,
|
||||
int64_t param_num,
|
||||
uint32_t flags,
|
||||
const common::ObCollationType conn_coll_type);
|
||||
common::ObExprTypeCtx &type_ctx);
|
||||
|
||||
|
||||
// data members
|
||||
@ -1934,6 +1936,11 @@ public:
|
||||
common::ObObj &result,
|
||||
common::ObIAllocator *allocator);
|
||||
void calc_temporal_format_result_length(ObExprResType &type, const ObExprResType &format) const;
|
||||
protected:
|
||||
static int extract_enum_set_collation_for_args(const ObExprResType &text,
|
||||
const ObExprResType &pattern,
|
||||
ObExprTypeCtx &type_ctx,
|
||||
ObObjMeta *real_types);
|
||||
protected:
|
||||
common::ObObjType get_result_type_mysql(int64_t char_length) const;
|
||||
static const int64_t MAX_CHAR_LENGTH_FOR_VARCAHR_RESULT = 512;
|
||||
|
@ -251,7 +251,7 @@ int ObExprOracleDecode::calc_result_typeN(ObExprResType &type,
|
||||
}
|
||||
else {
|
||||
// 这里针对calc的转换是不是可以直接用在result上??
|
||||
result_type = enumset_calc_types_[OBJ_TYPE_TO_CLASS[type.get_type()]];
|
||||
result_type = get_enumset_calc_type(type.get_type(), OB_INVALID_INDEX);
|
||||
}
|
||||
if (OB_UNLIKELY(ObMaxType == result_type)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
@ -259,30 +259,30 @@ int ObExprOracleDecode::calc_result_typeN(ObExprResType &type,
|
||||
} else if (ObVarcharType == result_type) {
|
||||
for (int64_t i = 2; i < param_num; i += 2 /*skip conditions */) {
|
||||
if (types_stack[i].is_enum_or_set()) {
|
||||
types_stack[i].set_calc_type(ObVarcharType);
|
||||
types_stack[i].set_calc_type(get_enumset_calc_type(type.get_type(), i));
|
||||
}
|
||||
}
|
||||
if (has_default) {
|
||||
if (types_stack[param_num - 1].is_enum_or_set()) {
|
||||
types_stack[param_num - 1].set_calc_type(ObVarcharType);
|
||||
types_stack[param_num - 1].set_calc_type(get_enumset_calc_type(type.get_type(), param_num - 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (OB_SUCC(ret)) {
|
||||
ObObjType calc_type = enumset_calc_types_[OBJ_TYPE_TO_CLASS[type.get_calc_type()]];
|
||||
ObObjType calc_type = get_enumset_calc_type(type.get_calc_type(), OB_INVALID_INDEX);
|
||||
if (OB_UNLIKELY(ObMaxType == calc_type)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
SQL_ENG_LOG(WARN, "invalid type of parameter ", K(type), K(ret));
|
||||
} else if (ObVarcharType == calc_type) {
|
||||
if (types_stack[0].is_enum_or_set()) {
|
||||
types_stack[0].set_calc_type(ObVarcharType);
|
||||
types_stack[0].set_calc_type(get_enumset_calc_type(type.get_calc_type(), 0));
|
||||
}
|
||||
for (int64_t i = 1; i < param_num; i += 2 /*skip conditions */) {
|
||||
//here to let enumset wrapper knows
|
||||
if (types_stack[i].is_enum_or_set()) {
|
||||
types_stack[i].set_calc_type(ObVarcharType);
|
||||
types_stack[i].set_calc_type(get_enumset_calc_type(type.get_calc_type(), i));
|
||||
}
|
||||
}
|
||||
} else {/*do nothing*/}
|
||||
|
@ -63,7 +63,7 @@ int ObExprPrior::calc_prior_expr(const ObExpr &expr, ObEvalCtx &ctx, ObDatum &re
|
||||
if (OB_ISNULL(kit) || OB_ISNULL(kit->op_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("operator is NULL", K(ret), K(operator_id), KP(kit));
|
||||
} else if (OB_UNLIKELY(PHY_NESTED_LOOP_CONNECT_BY != kit->op_->get_spec().type_
|
||||
} else if (OB_UNLIKELY(PHY_CONNECT_BY != kit->op_->get_spec().type_
|
||||
&& PHY_NESTED_LOOP_CONNECT_BY_WITH_INDEX != kit->op_->get_spec().type_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("is not connect by operator", K(ret), K(operator_id), "spec", kit->op_->get_spec());
|
||||
@ -71,7 +71,7 @@ int ObExprPrior::calc_prior_expr(const ObExpr &expr, ObEvalCtx &ctx, ObDatum &re
|
||||
LOG_WARN("failed to eval expr", K(ret));
|
||||
} else {
|
||||
int64_t level = 0;
|
||||
if (PHY_NESTED_LOOP_CONNECT_BY == kit->op_->get_spec().type_) {
|
||||
if (PHY_CONNECT_BY == kit->op_->get_spec().type_) {
|
||||
ObNLConnectByOp *cnntby_op = static_cast<ObNLConnectByOp *>(kit->op_);
|
||||
level = cnntby_op->connect_by_pump_.get_current_level();
|
||||
} else {
|
||||
|
@ -109,6 +109,8 @@ int ObExprRegexpReplace::calc_result_typeN(ObExprResType &type,
|
||||
type.set_length(max_allowed_packet);
|
||||
if (OB_FAIL(ObExprRegexContext::check_binary_compatible(types, 3))) {
|
||||
LOG_WARN("types are not compatible with binary.", K(ret));
|
||||
} else if (OB_FAIL(extract_enum_set_collation_for_args(text, pattern, type_ctx, real_types))) {
|
||||
LOG_WARN("fail to extract enum set meta", K(ret));
|
||||
} else {
|
||||
ret = aggregate_charsets_for_string_result(type, real_types, 2, type_ctx);
|
||||
is_case_sensitive = ObCharset::is_bin_sort(type.get_collation_type());
|
||||
|
@ -97,6 +97,8 @@ int ObExprRegexpSubstr::calc_result_typeN(ObExprResType &type,
|
||||
type.set_length(text.get_length());
|
||||
if (OB_FAIL(ObExprRegexContext::check_binary_compatible(types, 2))) {
|
||||
LOG_WARN("types are not compatible with binary.", K(ret));
|
||||
} else if (OB_FAIL(extract_enum_set_collation_for_args(text, pattern, type_ctx, real_types))) {
|
||||
LOG_WARN("fail to extract enum set meta", K(ret));
|
||||
} else {
|
||||
ret = aggregate_charsets_for_string_result(type, real_types, 2, type_ctx);
|
||||
is_case_sensitive = ObCharset::is_bin_sort(type.get_collation_type());
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "lib/utility/utility.h"
|
||||
#include "common/ob_accuracy.h"
|
||||
#include "common/object/ob_obj_type.h"
|
||||
#include "lib/enumset/ob_enum_set_meta.h"
|
||||
|
||||
namespace oceanbase
|
||||
{
|
||||
@ -338,6 +339,16 @@ public:
|
||||
}
|
||||
|
||||
uint64_t get_cast_mode() const { return cast_mode_; }
|
||||
|
||||
OB_INLINE void mark_enum_set_with_subschema()
|
||||
{
|
||||
if (is_enum_or_set()) {
|
||||
set_scale(ObEnumSetMeta::MetaState::READY);
|
||||
}
|
||||
}
|
||||
OB_INLINE bool is_enum_set_with_subschema() const
|
||||
{ return is_enum_or_set() && get_scale() == ObEnumSetMeta::MetaState::READY; }
|
||||
OB_INLINE void reset_enum_set_meta_state() { set_scale(ObEnumSetMeta::MetaState::UNINITIALIZED); }
|
||||
uint64_t hash(uint64_t seed) const
|
||||
{
|
||||
seed = common::do_hash(type_, seed);
|
||||
|
@ -30,6 +30,59 @@ namespace oceanbase
|
||||
namespace sql
|
||||
{
|
||||
|
||||
int calc_digest_text_inner(const ObString &query,
|
||||
const int64_t i,
|
||||
ObIAllocator &allocator,
|
||||
ObPlanCacheCtx &pc_ctx,
|
||||
ObParser &parser,
|
||||
ObCharsets4Parser &charsets4parser,
|
||||
ObString &digest_str)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ParseResult parse_result;
|
||||
ParamStore tmp_params((ObWrapperAllocator(allocator)));
|
||||
stmt::StmtType stmt_type = stmt::T_NONE;
|
||||
ObItemType item_type = T_NULL;
|
||||
if (OB_FAIL(parser.parse(query, parse_result))) {
|
||||
LOG_WARN("fail to parse sql str", K(query), K(ret));
|
||||
} else if (OB_ISNULL(parse_result.result_tree_)
|
||||
|| OB_ISNULL(parse_result.result_tree_->children_[0])) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected parse result", K(ret));
|
||||
} else if (FALSE_IT(item_type = parse_result.result_tree_->children_[0]->type_)) {
|
||||
} else if (i > 0) {
|
||||
if (OB_UNLIKELY(T_EMPTY_QUERY != item_type)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid stmt type", K(item_type), K(ret));
|
||||
LOG_USER_ERROR(OB_INVALID_ARGUMENT, "digest function");
|
||||
}
|
||||
} else if (OB_UNLIKELY(T_EMPTY_QUERY == item_type)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid empty query", K(item_type), K(ret));
|
||||
LOG_USER_ERROR(OB_INVALID_ARGUMENT, "digest function");
|
||||
} else if (OB_FAIL(ObResolverUtils::resolve_stmt_type(parse_result, stmt_type))) {
|
||||
LOG_WARN("failed to resolve stmt type", K(ret));
|
||||
} else if (ObStmt::is_dml_stmt(stmt_type) && !ObStmt::is_show_stmt(stmt_type)) {
|
||||
if (OB_UNLIKELY(parse_result.result_tree_->children_[0]->value_ > 0)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("query contains questionmark", K(query), K(ret));
|
||||
LOG_USER_ERROR(OB_INVALID_ARGUMENT, "digest function");
|
||||
} else if (OB_FAIL(ObSqlParameterization::parameterize_syntax_tree(allocator,
|
||||
true,
|
||||
pc_ctx,
|
||||
parse_result.result_tree_,
|
||||
tmp_params,
|
||||
charsets4parser))) {
|
||||
LOG_WARN("fail to parameterize syntax tree", K(query), K(ret));
|
||||
} else {
|
||||
digest_str = pc_ctx.sql_ctx_.spm_ctx_.bl_key_.format_sql_;
|
||||
}
|
||||
} else {
|
||||
digest_str = query;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int calc_digest_text(ObIAllocator &allocator,
|
||||
const ObString sql_str,
|
||||
const ObCollationType cs_type,
|
||||
@ -57,48 +110,12 @@ int calc_digest_text(ObIAllocator &allocator,
|
||||
ObMPParseStat parse_stat;
|
||||
if (OB_FAIL(parser.split_multiple_stmt(sql_str, queries, parse_stat))) {
|
||||
LOG_WARN("failed to split multiple stmt", K(ret));
|
||||
}
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < queries.count(); ++i) {
|
||||
ParseResult parse_result;
|
||||
ParamStore tmp_params((ObWrapperAllocator(allocator)));
|
||||
stmt::StmtType stmt_type = stmt::T_NONE;
|
||||
ObItemType item_type = T_NULL;
|
||||
if (OB_FAIL(parser.parse(queries.at(i), parse_result))) {
|
||||
LOG_WARN("fail to parse sql str", K(sql_str), K(ret));
|
||||
} else if (OB_ISNULL(parse_result.result_tree_)
|
||||
|| OB_ISNULL(parse_result.result_tree_->children_[0])) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected parse result", K(ret));
|
||||
} else if (FALSE_IT(item_type = parse_result.result_tree_->children_[0]->type_)) {
|
||||
} else if (i > 0) {
|
||||
if (OB_UNLIKELY(T_EMPTY_QUERY != item_type)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid stmt type", K(item_type), K(ret));
|
||||
LOG_USER_ERROR(OB_INVALID_ARGUMENT, "digest function");
|
||||
} else {
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < queries.count(); ++i) {
|
||||
if (OB_FAIL(calc_digest_text_inner(queries.at(i), i, allocator, pc_ctx, parser,
|
||||
charsets4parser, digest_str))) {
|
||||
LOG_WARN("fail to calc digest test inner", K(ret), K(sql_str));
|
||||
}
|
||||
} else if (OB_UNLIKELY(T_EMPTY_QUERY == item_type)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid empty query", K(item_type), K(ret));
|
||||
LOG_USER_ERROR(OB_INVALID_ARGUMENT, "digest function");
|
||||
} else if (OB_FAIL(ObResolverUtils::resolve_stmt_type(parse_result, stmt_type))) {
|
||||
LOG_WARN("failed to resolve stmt type", K(ret));
|
||||
} else if (ObStmt::is_dml_stmt(stmt_type) && !ObStmt::is_show_stmt(stmt_type)) {
|
||||
if (OB_UNLIKELY(parse_result.result_tree_->children_[0]->value_ > 0)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("query contains questionmark", K(queries.at(i)), K(ret));
|
||||
LOG_USER_ERROR(OB_INVALID_ARGUMENT, "digest function");
|
||||
} else if (OB_FAIL(ObSqlParameterization::parameterize_syntax_tree(allocator,
|
||||
true,
|
||||
pc_ctx,
|
||||
parse_result.result_tree_,
|
||||
tmp_params,
|
||||
charsets4parser))) {
|
||||
LOG_WARN("fail to parameterize syntax tree", K(sql_str), K(ret));
|
||||
} else {
|
||||
digest_str = pc_ctx.sql_ctx_.spm_ctx_.bl_key_.format_sql_;
|
||||
}
|
||||
} else {
|
||||
digest_str = queries.at(i);
|
||||
}
|
||||
}
|
||||
exec_ctx.set_physical_plan_ctx(NULL);
|
||||
|
@ -74,7 +74,7 @@ int ObExprToBase64::calc_result_type1(ObExprResType &type,
|
||||
|
||||
str.set_calc_type(ObVarcharType);
|
||||
str.set_calc_collation_type(
|
||||
str.is_string_type() ? str.get_collation_type() : CS_TYPE_UTF8MB4_BIN);
|
||||
(str.is_string_type() || str.is_enum_or_set()) ? str.get_collation_type() : CS_TYPE_UTF8MB4_BIN);
|
||||
|
||||
int64_t mbmaxlen = 0;
|
||||
int64_t max_result_length = 0;
|
||||
|
@ -201,7 +201,8 @@ int ObExprToType::calc_result_type_for_column(ObExprResType &type,
|
||||
type.set_accuracy(ObAccuracy::MAX_ACCURACY2[get_compatibility_mode()][expect_type_]);
|
||||
|
||||
if (ob_is_enumset_tc(type1.get_type())) {
|
||||
ObObjType calc_type = enumset_calc_types_[OBJ_TYPE_TO_CLASS[expect_type_]];
|
||||
// There is no need to check whether it is enumset with subschema
|
||||
ObObjType calc_type = get_enumset_calc_type(expect_type_, OB_INVALID_INDEX);
|
||||
if (OB_UNLIKELY(ObMaxType == calc_type)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
SQL_ENG_LOG(WARN, "invalid type of parameter ", K(expect_type_), K(ret));
|
||||
|
@ -62,7 +62,7 @@ int ObExprTypeToStr::calc_result_type2(ObExprResType &type,
|
||||
type.set_type(ObVarcharType);
|
||||
} else {
|
||||
ObObjType dst_type = static_cast<ObObjType>(get_raw_expr()->get_extra());
|
||||
if (!ob_is_large_text(dst_type)) {
|
||||
if (!ob_is_large_text(dst_type) && dst_type != ObCharType) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("invalid dst type", K(ret), K(dst_type));
|
||||
} else {
|
||||
@ -255,7 +255,6 @@ int ObExprSetToStr::calc_to_str_expr(const ObExpr &expr, ObEvalCtx &ctx, ObDatum
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObDatum *set_datum = NULL;
|
||||
const ObString &sep = ObCharsetUtils::get_const_str(expr.datum_meta_.cs_type_, ',');
|
||||
if (OB_UNLIKELY(expr.arg_cnt_ != 2)
|
||||
|| OB_ISNULL(expr.args_)
|
||||
|| OB_ISNULL(expr.args_[1])
|
||||
@ -269,55 +268,66 @@ int ObExprSetToStr::calc_to_str_expr(const ObExpr &expr, ObEvalCtx &ctx, ObDatum
|
||||
} else {
|
||||
ObIArray<ObString> &str_values = static_cast<ObEnumSetInfo *>(expr.extra_info_)->str_values_;
|
||||
uint64_t set_val = set_datum->get_set();
|
||||
|
||||
//在value存在重复的情况时,element_num会大于64,忽略64以后的值
|
||||
int64_t element_num = str_values.count();
|
||||
if (OB_UNLIKELY(element_num < 1)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("invalid element num", K(element_num), K(ret));
|
||||
} else if (OB_UNLIKELY(element_num < EFFECTIVE_COUNT && set_val >= (1ULL << element_num))) {
|
||||
ret = OB_ERR_DATA_TRUNCATED;
|
||||
LOG_WARN("set value out of range", K(set_val), K(element_num));
|
||||
ObTextStringDatumResult text_result(expr.datum_meta_.type_, &expr, &ctx, &res_datum);
|
||||
if (OB_FAIL(ObExprSetToStr::inner_to_str(expr.datum_meta_.cs_type_, set_val, str_values,
|
||||
text_result))) {
|
||||
LOG_WARN("enum to str failed", K(ret), K(set_val));
|
||||
} else {
|
||||
text_result.set_result();
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int64_t need_size = 0;
|
||||
uint64_t index = 1ULL;
|
||||
for (int64_t i = 0;
|
||||
OB_SUCC(ret) && i < element_num && i < EFFECTIVE_COUNT && set_val >= index;
|
||||
++i, index = index << 1) {
|
||||
if (set_val & (index)) {
|
||||
need_size += str_values.at(i).length();
|
||||
need_size += ((set_val >= (index << 1)) ? sep.length() : 0);
|
||||
}
|
||||
int ObExprSetToStr::inner_to_str(const ObCollationType cs_type,
|
||||
const uint64_t set_val,
|
||||
const ObIArray<common::ObString> &str_values,
|
||||
common::ObTextStringResult &text_result)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
const ObString &sep = ObCharsetUtils::get_const_str(cs_type, ',');
|
||||
// When there are duplicate values, element_num will be greater than 64,
|
||||
// and values after 64 will be ignored.
|
||||
int64_t element_num = str_values.count();
|
||||
if (OB_UNLIKELY(element_num < 1)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("invalid element num", K(element_num), K(ret));
|
||||
} else if (OB_UNLIKELY(element_num < EFFECTIVE_COUNT && set_val >= (1ULL << element_num))) {
|
||||
ret = OB_ERR_DATA_TRUNCATED;
|
||||
LOG_WARN("set value out of range", K(set_val), K(element_num));
|
||||
}
|
||||
|
||||
int64_t need_size = 0;
|
||||
uint64_t index = 1ULL;
|
||||
for (int64_t i = 0;
|
||||
OB_SUCC(ret) && i < element_num && i < EFFECTIVE_COUNT && set_val >= index;
|
||||
++i, index = index << 1) {
|
||||
if (set_val & (index)) {
|
||||
need_size += str_values.at(i).length();
|
||||
need_size += ((set_val >= (index << 1)) ? sep.length() : 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (OB_SUCC(ret)) {
|
||||
int64_t pos = 0;
|
||||
char *buf = NULL;
|
||||
ObTextStringDatumResult text_result(expr.datum_meta_.type_, &expr, &ctx, &res_datum);
|
||||
if (OB_FAIL(text_result.init(need_size))) {
|
||||
LOG_WARN("init lob result failed", K(ret), K(need_size));
|
||||
} else {
|
||||
uint64_t index = 1ULL;
|
||||
for (int64_t i = 0;
|
||||
OB_SUCC(ret) && i < element_num && i < EFFECTIVE_COUNT && set_val >= index;
|
||||
++i, index = index << 1) {
|
||||
if (set_val & (index)) {
|
||||
const ObString &element_val = str_values.at(i);
|
||||
if (OB_FAIL(text_result.append(element_val))) {
|
||||
LOG_WARN("fail to append str to lob result", K(ret), K(element_val));
|
||||
} else if ((i + 1) < element_num && (i + 1) < EFFECTIVE_COUNT &&
|
||||
((index << 1) <= set_val)) {
|
||||
// skip setting last seperator
|
||||
if (OB_FAIL(text_result.append(sep))) {
|
||||
LOG_WARN("fail to append str to lob result", K(ret), K(sep));
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
if (OB_FAIL(text_result.init(need_size))) {
|
||||
LOG_WARN("init lob result failed", K(ret), K(need_size));
|
||||
} else {
|
||||
uint64_t index = 1ULL;
|
||||
for (int64_t i = 0;
|
||||
OB_SUCC(ret) && i < element_num && i < EFFECTIVE_COUNT && set_val >= index;
|
||||
++i, index = index << 1) {
|
||||
if (set_val & (index)) {
|
||||
const ObString &element_val = str_values.at(i);
|
||||
if (OB_FAIL(text_result.append(element_val))) {
|
||||
LOG_WARN("fail to append str to lob result", K(ret), K(element_val));
|
||||
} else if ((i + 1) < element_num && (i + 1) < EFFECTIVE_COUNT &&
|
||||
((index << 1) <= set_val)) {
|
||||
// skip setting last seperator
|
||||
if (OB_FAIL(text_result.append(sep))) {
|
||||
LOG_WARN("fail to append str to lob result", K(ret), K(sep));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
text_result.set_result();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -365,32 +375,41 @@ int ObExprEnumToStr::calc_to_str_expr(const ObExpr &expr, ObEvalCtx &ctx, ObDatu
|
||||
res_datum.set_null();
|
||||
} else {
|
||||
ObIArray<ObString> &str_values = static_cast<ObEnumSetInfo *>(expr.extra_info_)->str_values_;
|
||||
char *buf = NULL;
|
||||
uint64_t enum_val = enum_datum->get_enum();
|
||||
int64_t element_num = str_values.count();
|
||||
uint64_t element_idx = enum_val - 1;
|
||||
ObString element_str;
|
||||
if (OB_UNLIKELY(element_num < 1)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("invalid element num", K(element_num), K(element_num));
|
||||
} else if (0 == enum_val) {
|
||||
// ObString empty_string;
|
||||
// res_datum.set_enumset_inner(empty_string.make_empty_string());
|
||||
} else if (OB_UNLIKELY(element_idx > element_num - 1)) {
|
||||
ret = OB_ERR_DATA_TRUNCATED;
|
||||
LOG_WARN("enum value out of range", K(element_idx), K(element_num), K(ret));
|
||||
ObTextStringDatumResult text_result(expr.datum_meta_.type_, &expr, &ctx, &res_datum);
|
||||
if (OB_FAIL(ObExprEnumToStr::inner_to_str(enum_val, str_values, text_result))) {
|
||||
LOG_WARN("enum to str failed", K(ret), K(enum_val));
|
||||
} else {
|
||||
element_str = str_values.at(element_idx);
|
||||
text_result.set_result();
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
ObTextStringDatumResult text_result(expr.datum_meta_.type_, &expr, &ctx, &res_datum);
|
||||
if (OB_FAIL(text_result.init(element_str.length()))) {
|
||||
LOG_WARN("init lob result failed");
|
||||
} else if (OB_FAIL(text_result.append(element_str.ptr(), element_str.length()))) {
|
||||
LOG_WARN("failed to append realdata", K(ret), K(text_result));
|
||||
} else {
|
||||
text_result.set_result();
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObExprEnumToStr::inner_to_str(const uint64_t enum_val,
|
||||
const ObIArray<ObString> &str_values,
|
||||
common::ObTextStringResult &text_result)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
const int64_t element_num = str_values.count();
|
||||
const uint64_t element_idx = enum_val - 1;
|
||||
ObString element_str;
|
||||
if (OB_UNLIKELY(element_num < 1)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("invalid element num", K(element_num), K(element_num));
|
||||
} else if (0 == enum_val) {
|
||||
// ObString empty_string;
|
||||
} else if (OB_UNLIKELY(element_idx > element_num - 1)) {
|
||||
ret = OB_ERR_DATA_TRUNCATED;
|
||||
LOG_WARN("enum value out of range", K(element_idx), K(element_num), K(ret));
|
||||
} else {
|
||||
element_str = str_values.at(element_idx);
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
if (OB_FAIL(text_result.init(element_str.length()))) {
|
||||
LOG_WARN("init lob result failed");
|
||||
} else if (OB_FAIL(text_result.append(element_str.ptr(), element_str.length()))) {
|
||||
LOG_WARN("failed to append real data", K(ret), K(text_result));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
#include "sql/engine/expr/ob_expr_operator.h"
|
||||
#include "sql/engine/expr/ob_i_expr_extra_info.h"
|
||||
#include "sql/engine/expr/ob_expr_lob_utils.h"
|
||||
|
||||
namespace oceanbase
|
||||
{
|
||||
@ -110,7 +111,10 @@ public:
|
||||
const ObRawExpr &raw_expr,
|
||||
ObExpr &rt_expr) const override;
|
||||
static int calc_to_str_expr(const ObExpr &expr, ObEvalCtx &ctx, ObDatum &res_datum);
|
||||
|
||||
static int inner_to_str(const ObCollationType cs_type,
|
||||
const uint64_t enum_val,
|
||||
const ObIArray<common::ObString> &str_values,
|
||||
common::ObTextStringResult &text_result);
|
||||
private:
|
||||
// disallow copy
|
||||
DISALLOW_COPY_AND_ASSIGN(ObExprSetToStr) const;
|
||||
@ -125,6 +129,9 @@ public:
|
||||
const ObRawExpr &raw_expr,
|
||||
ObExpr &rt_expr) const override;
|
||||
static int calc_to_str_expr(const ObExpr &expr, ObEvalCtx &ctx, ObDatum &res_datum);
|
||||
static int inner_to_str(const uint64_t enum_val,
|
||||
const ObIArray<common::ObString> &str_values,
|
||||
common::ObTextStringResult &text_result);
|
||||
private:
|
||||
// disallow copy
|
||||
DISALLOW_COPY_AND_ASSIGN(ObExprEnumToStr) const;
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "ob_operator.h"
|
||||
#include "observer/ob_server.h"
|
||||
#include "storage/lob/ob_lob_persistent_reader.h"
|
||||
#include "sql/executor/ob_memory_tracker.h"
|
||||
#ifdef OB_BUILD_SPM
|
||||
#include "sql/spm/ob_spm_controller.h"
|
||||
#endif
|
||||
@ -509,6 +510,8 @@ int ObExecContext::check_status()
|
||||
LOG_WARN("px execution was interrupted", K(ic), K(ret));
|
||||
} else if (lib::Worker::WS_OUT_OF_THROTTLE == THIS_WORKER.check_wait()) {
|
||||
ret = OB_KILLED_BY_THROTTLING;
|
||||
} else if (OB_UNLIKELY((OB_SUCCESS != (ret = CHECK_MEM_STATUS())))) {
|
||||
LOG_WARN("Exceeded memory usage limit", K(ret));
|
||||
}
|
||||
int tmp_ret = OB_SUCCESS;
|
||||
if (OB_SUCCESS != (tmp_ret = check_extra_status())) {
|
||||
@ -1211,6 +1214,22 @@ int ObExecContext::get_sqludt_meta_by_subschema_id(uint16_t subschema_id, ObSubS
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObExecContext::get_enumset_meta_by_subschema_id(uint16_t subschema_id,
|
||||
const ObEnumSetMeta *&meta) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (ob_is_reserved_subschema_id(subschema_id)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
SQL_ENG_LOG(WARN, "reserved subschema id not used in enumset meta", K(ret), K(lbt()));
|
||||
} else if (OB_ISNULL(phy_plan_ctx_)) {
|
||||
ret = OB_NOT_INIT;
|
||||
SQL_ENG_LOG(WARN, "not phyical plan ctx for subschema mapping", K(ret), K(lbt()));
|
||||
} else {
|
||||
ret = phy_plan_ctx_->get_enumset_meta_by_subschema_id(subschema_id, meta);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObExecContext::get_subschema_id_by_udt_id(uint64_t udt_type_id,
|
||||
uint16_t &subschema_id,
|
||||
share::schema::ObSchemaGetterGuard *schema_guard)
|
||||
@ -1242,6 +1261,44 @@ int ObExecContext::get_subschema_id_by_collection_elem_type(ObNestedType coll_ty
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool ObExecContext::support_enum_set_type_subschema(ObSQLSessionInfo &session)
|
||||
{
|
||||
// Considering compatibility, enumset subschema is only supported in versions [4_2_5, 4_3_0) and
|
||||
// versions 4_3_5 at least.
|
||||
bool bret = true;
|
||||
const uint64_t min_cluster_version = GET_MIN_CLUSTER_VERSION();
|
||||
if ((min_cluster_version < MOCK_CLUSTER_VERSION_4_2_5_0) ||
|
||||
(min_cluster_version >= CLUSTER_VERSION_4_3_0_0
|
||||
&& min_cluster_version < CLUSTER_VERSION_4_3_5_0)) {
|
||||
bret = false;
|
||||
} else {
|
||||
// tenant configuration Control
|
||||
if (!session.is_enable_enum_set_with_subschema()) {
|
||||
bret = false;
|
||||
}
|
||||
// hint control
|
||||
if (OB_NOT_NULL(stmt_factory_) && OB_NOT_NULL(stmt_factory_->get_query_ctx())) {
|
||||
stmt_factory_->get_query_ctx()->get_global_hint().opt_params_.get_bool_opt_param(
|
||||
ObOptParamHint::ENABLE_ENUM_SET_SUBSCHEMA, bret);
|
||||
}
|
||||
}
|
||||
return bret;
|
||||
}
|
||||
|
||||
int ObExecContext::get_subschema_id_by_type_info(const ObObjMeta &obj_meta,
|
||||
const ObIArray<common::ObString> &type_info,
|
||||
uint16_t &subschema_id)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_ISNULL(phy_plan_ctx_)) {
|
||||
ret = OB_NOT_INIT;
|
||||
SQL_ENG_LOG(WARN, "not phyical plan ctx for reverse mapping", K(ret), K(lbt()));
|
||||
} else {
|
||||
ret = phy_plan_ctx_->get_subschema_id_by_type_info(obj_meta, type_info, subschema_id);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObExecContext::get_subschema_id_by_type_string(const ObString &type_string, uint16_t &subschema_id)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
|
@ -514,6 +514,11 @@ public:
|
||||
const ObDataType &elem_type,
|
||||
uint16_t &subschema_id);
|
||||
int get_subschema_id_by_type_string(const ObString &type_string, uint16_t &subschema_id);
|
||||
int get_enumset_meta_by_subschema_id(uint16_t subschema_id, const ObEnumSetMeta *&meta) const;
|
||||
bool support_enum_set_type_subschema(ObSQLSessionInfo &session);
|
||||
int get_subschema_id_by_type_info(const ObObjMeta &obj_meta,
|
||||
const ObIArray<common::ObString> &type_info,
|
||||
uint16_t &subschema_id);
|
||||
ObExecFeedbackInfo &get_feedback_info() { return fb_info_; };
|
||||
inline void set_cur_rownum(int64_t cur_rownum) { user_logging_ctx_.row_num_ = cur_rownum; }
|
||||
inline int64_t get_cur_rownum() const { return user_logging_ctx_.row_num_; }
|
||||
|
@ -438,7 +438,7 @@ REGISTER_OPERATOR(ObLogJoin, PHY_NESTED_LOOP_CONNECT_BY_WITH_INDEX,
|
||||
class ObLogJoin;
|
||||
class ObNLConnectBySpec;
|
||||
class ObNLConnectByOp;
|
||||
REGISTER_OPERATOR(ObLogJoin, PHY_NESTED_LOOP_CONNECT_BY, ObNLConnectBySpec,
|
||||
REGISTER_OPERATOR(ObLogJoin, PHY_CONNECT_BY, ObNLConnectBySpec,
|
||||
ObNLConnectByOp, NOINPUT);
|
||||
|
||||
class ObLogJoin;
|
||||
|
@ -102,7 +102,7 @@ PHY_OP_DEF(PHY_PX_MULTI_PART_DELETE)
|
||||
PHY_OP_DEF(PHY_PX_MULTI_PART_UPDATE)
|
||||
PHY_OP_DEF(PHY_PX_MULTI_PART_INSERT)
|
||||
PHY_OP_DEF(PHY_UNPIVOT)
|
||||
PHY_OP_DEF(PHY_NESTED_LOOP_CONNECT_BY) /*90*/
|
||||
PHY_OP_DEF(PHY_CONNECT_BY) /*90*/
|
||||
PHY_OP_DEF(PHY_LINK_SCAN)
|
||||
PHY_OP_DEF(PHY_LOCK)
|
||||
PHY_OP_DEF(PHY_MULTI_LOCK)
|
||||
|
@ -1115,6 +1115,44 @@ int ObPhysicalPlanCtx::get_sqludt_meta_by_subschema_id(uint16_t subschema_id, Ob
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObPhysicalPlanCtx::get_enumset_meta_by_subschema_id(uint16_t subschema_id,
|
||||
const ObEnumSetMeta *&meta) const
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObSubSchemaValue value;
|
||||
if (subschema_id == ObMaxSystemUDTSqlType || subschema_id >= UINT_MAX16) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("invalid subschema id", K(ret), K(subschema_id));
|
||||
} else if (OB_NOT_NULL(phy_plan_)) { // physical plan exist, use subschema ctx on phy plan
|
||||
if (!phy_plan_->get_subschema_ctx().is_inited()) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("plan with empty subschema mapping", K(ret), K(phy_plan_->get_subschema_ctx()));
|
||||
} else if (OB_FAIL(phy_plan_->get_subschema_ctx().get_subschema(subschema_id, value))) {
|
||||
if (OB_HASH_NOT_EXIST != ret) {
|
||||
LOG_WARN("failed to get subschema by subschema id", K(ret), K(subschema_id));
|
||||
} else {
|
||||
LOG_WARN("subschema not exist in subschema mapping", K(ret), K(subschema_id));
|
||||
}
|
||||
} else {
|
||||
meta = reinterpret_cast<const ObEnumSetMeta *>(value.value_);
|
||||
}
|
||||
} else if (!subschema_ctx_.is_inited()) { // no phy plan
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("invalid subschema id", K(ret), K(subschema_id), K(lbt()));
|
||||
} else {
|
||||
if (OB_FAIL(subschema_ctx_.get_subschema(subschema_id, value))) {
|
||||
LOG_WARN("failed to get subschema", K(ret), K(subschema_id));
|
||||
} else if (value.type_ >= OB_SUBSCHEMA_MAX_TYPE) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("invalid subschema type", K(ret), K(value));
|
||||
} else { // Notice: shallow copy
|
||||
meta = reinterpret_cast<const ObEnumSetMeta *>(value.value_);
|
||||
}
|
||||
}
|
||||
LOG_TRACE("ENUMSET: search subschema", K(ret), KP(this), K(subschema_id));
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObPhysicalPlanCtx::get_subschema_id_by_udt_id(uint64_t udt_type_id,
|
||||
uint16_t &subschema_id,
|
||||
share::schema::ObSchemaGetterGuard *schema_guard)
|
||||
@ -1237,6 +1275,51 @@ int ObPhysicalPlanCtx::get_subschema_id_by_type_string(const ObString &type_stri
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObPhysicalPlanCtx::get_subschema_id_by_type_info(const ObObjMeta &obj_meta,
|
||||
const ObIArray<common::ObString> &type_info,
|
||||
uint16_t &subschema_id)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
uint16_t temp_subschema_id = ObMaxSystemUDTSqlType;
|
||||
bool found = false;
|
||||
ObEnumSetMeta src_meta(obj_meta, &type_info);
|
||||
if (OB_NOT_NULL(phy_plan_)) { // physical plan exist, use subschema ctx on phy plan
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("get type info when physical plan exist is not unexpected", K(ret), K(type_info));
|
||||
} else if (!subschema_ctx_.is_inited() && OB_FAIL(subschema_ctx_.init())) {
|
||||
LOG_WARN("subschema ctx init failed", K(ret));
|
||||
} else if (OB_FAIL(subschema_ctx_.get_subschema_id(OB_SUBSCHEMA_ENUM_SET_TYPE,
|
||||
src_meta,
|
||||
temp_subschema_id))) {
|
||||
if (OB_HASH_NOT_EXIST != ret) {
|
||||
LOG_WARN("failed to get subschema id by udt_id", K(ret), K(type_info));
|
||||
} else { // build new meta
|
||||
ret = OB_SUCCESS;
|
||||
uint16 new_subschema_id = ObMaxSystemUDTSqlType;
|
||||
ObSubSchemaValue value;
|
||||
ObEnumSetMeta *dst_meta = NULL;
|
||||
if (OB_FAIL(src_meta.deep_copy(allocator_, dst_meta))) {
|
||||
LOG_WARN("fail to deep copy enumset meta", K(ret));
|
||||
} else if (OB_FAIL(subschema_ctx_.get_new_subschema_id(new_subschema_id))) {
|
||||
LOG_WARN("failed to get new subschema id", K(ret), K(get_tenant_id()));
|
||||
} else {
|
||||
value.type_ = OB_SUBSCHEMA_ENUM_SET_TYPE;
|
||||
value.signature_ = dst_meta->get_signature();
|
||||
value.value_ = static_cast<void *>(dst_meta);
|
||||
if (OB_FAIL(subschema_ctx_.set_subschema(new_subschema_id, value))) {
|
||||
LOG_WARN("failed to set new subschema", K(ret), K(new_subschema_id), K(value));
|
||||
} else {
|
||||
subschema_id = new_subschema_id;
|
||||
}
|
||||
}
|
||||
LOG_TRACE("ENUMSET: build subschema", K(ret), KP(this), K(subschema_id));
|
||||
}
|
||||
} else { // success
|
||||
subschema_id = temp_subschema_id;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObPhysicalPlanCtx::set_all_local_session_vars(ObIArray<ObLocalSessionVar> &all_local_session_vars)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "sql/engine/user_defined_function/ob_udf_ctx_mgr.h"
|
||||
#include "sql/engine/expr/ob_expr.h"
|
||||
#include "lib/udt/ob_udt_type.h"
|
||||
#include "lib/enumset/ob_enum_set_meta.h"
|
||||
#include "sql/engine/ob_subschema_ctx.h"
|
||||
#include "sql/engine/expr/ob_expr_util.h"
|
||||
|
||||
@ -508,6 +509,7 @@ public:
|
||||
int get_sqludt_meta_by_subschema_id(uint16_t subschema_id, ObSqlUDTMeta &udt_meta);
|
||||
int get_sqludt_meta_by_subschema_id(uint16_t subschema_id, ObSubSchemaValue &sub_meta);
|
||||
bool is_subschema_ctx_inited();
|
||||
int get_enumset_meta_by_subschema_id(uint16_t subschema_id, const ObEnumSetMeta *&meta) const;
|
||||
int get_subschema_id_by_udt_id(uint64_t udt_type_id,
|
||||
uint16_t &subschema_id,
|
||||
share::schema::ObSchemaGetterGuard *schema_guard = NULL);
|
||||
@ -515,6 +517,9 @@ public:
|
||||
const ObDataType &elem_type,
|
||||
uint16_t &subschema_id);
|
||||
int get_subschema_id_by_type_string(const ObString &type_string, uint16_t &subschema_id);
|
||||
int get_subschema_id_by_type_info(const ObObjMeta &obj_meta,
|
||||
const ObIArray<common::ObString> &type_info,
|
||||
uint16_t &subschema_id);
|
||||
int build_subschema_by_fields(const ColumnsFieldIArray *fields,
|
||||
share::schema::ObSchemaGetterGuard *schema_guard);
|
||||
int build_subschema_ctx_by_param_store(share::schema::ObSchemaGetterGuard *schema_guard);
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "sql/engine/ob_subschema_ctx.h"
|
||||
#include "deps/oblib/src/lib/udt/ob_udt_type.h"
|
||||
#include "deps/oblib/src/lib/udt/ob_array_type.h"
|
||||
#include "lib/enumset/ob_enum_set_meta.h"
|
||||
#include "src/share/rc/ob_tenant_base.h"
|
||||
|
||||
namespace oceanbase
|
||||
@ -28,192 +29,130 @@ namespace sql
|
||||
// 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>, \
|
||||
#define DEF_SUBSCHEMA_ENTRY(SUBSCHEMATYPE, CLZ) \
|
||||
{ \
|
||||
subschema_value_serialize<SUBSCHEMATYPE, CLZ>, \
|
||||
subschema_value_deserialize<SUBSCHEMATYPE, CLZ>, \
|
||||
subschema_value_serialize_size<SUBSCHEMATYPE, CLZ>, \
|
||||
subschema_value_get_signature<SUBSCHEMATYPE, CLZ>, \
|
||||
subschema_value_deep_copy<SUBSCHEMATYPE, CLZ>, \
|
||||
subschema_value_init<SUBSCHEMATYPE, CLZ>, \
|
||||
}
|
||||
|
||||
template<>
|
||||
int subschema_value_serialize<OB_SUBSCHEMA_UDT_TYPE>(void *value, char* buf, const int64_t buf_len, int64_t& pos)
|
||||
template<ObSubSchemaType TYPE, typename CLZ>
|
||||
int subschema_value_serialize(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));
|
||||
LOG_WARN("null sql subschema value for serialize", K(ret), K(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));
|
||||
const CLZ *subschema_value = reinterpret_cast<CLZ *>(value);
|
||||
if (OB_FAIL(subschema_value->serialize(buf, buf_len, pos))) {
|
||||
LOG_WARN("failed to do sql subschema value serialize", K(ret), K(*subschema_value));
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <>
|
||||
int subschema_value_deserialize<OB_SUBSCHEMA_UDT_TYPE>(void *value, const char* buf, const int64_t data_len, int64_t& pos)
|
||||
template<ObSubSchemaType TYPE, typename CLZ>
|
||||
int subschema_value_deserialize(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));
|
||||
LOG_WARN("null sql subschema value for deserialize", K(ret), K(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));
|
||||
CLZ *subschema_value = reinterpret_cast<CLZ *>(value);
|
||||
if (OB_FAIL(subschema_value->deserialize(buf, data_len, pos))) {
|
||||
LOG_WARN("failed to do sql subschema value deserialize", K(ret), KP(buf), K(data_len));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <>
|
||||
int64_t subschema_value_serialize_size<OB_SUBSCHEMA_UDT_TYPE>(void *value)
|
||||
template<ObSubSchemaType TYPE, typename CLZ>
|
||||
int64_t subschema_value_serialize_size(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();
|
||||
const CLZ *subschema_value = reinterpret_cast<CLZ *>(value);
|
||||
len += subschema_value->get_serialize_size();
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
template <>
|
||||
int subschema_value_get_signature<OB_SUBSCHEMA_UDT_TYPE>(void *value, uint64_t &signature)
|
||||
template<ObSubSchemaType TYPE, typename CLZ>
|
||||
int subschema_value_get_signature(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));
|
||||
LOG_WARN("null subschema value", K(ret), K(TYPE));
|
||||
} else {
|
||||
const ObSqlUDTMeta* udt_meta = reinterpret_cast<ObSqlUDTMeta *>(value);
|
||||
signature = udt_meta->udt_id_;
|
||||
const CLZ *subschema_value = reinterpret_cast<CLZ *>(value);
|
||||
signature = subschema_value->get_signature();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <>
|
||||
int subschema_value_deep_copy<OB_SUBSCHEMA_UDT_TYPE>(const void *src_value, void *&dst_value, ObIAllocator &allocator)
|
||||
template<ObSubSchemaType TYPE, typename CLZ>
|
||||
int subschema_value_deep_copy(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));
|
||||
LOG_WARN("null subschema value for deep copy", K(ret), K(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)) {
|
||||
const CLZ *src_subschema_value = reinterpret_cast<const CLZ *>(src_value);
|
||||
CLZ* copy_value = NULL;
|
||||
if (OB_FAIL(src_subschema_value->deep_copy(allocator, copy_value))) {
|
||||
LOG_WARN("failed to deep copy subschema value", K(ret), K(TYPE));
|
||||
} else if (OB_ISNULL(copy_value)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("deep copy udt meta result is null", K(ret), K(OB_SUBSCHEMA_UDT_TYPE));
|
||||
LOG_WARN("deep copy subschema value result is null", K(ret), K(TYPE));
|
||||
} else {
|
||||
dst_value = static_cast<void *>(copy_meta);
|
||||
dst_value = static_cast<void *>(copy_value);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<>
|
||||
int subschema_value_serialize<OB_SUBSCHEMA_COLLECTION_TYPE>(void *value, char* buf, const int64_t buf_len, int64_t& pos)
|
||||
template<ObSubSchemaType TYPE, typename CLZ>
|
||||
int subschema_value_init(void *&value, ObIAllocator &allocator)
|
||||
{
|
||||
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_COLLECTION_TYPE));
|
||||
void *mem = value;
|
||||
if (OB_NOT_NULL(mem)) {
|
||||
ret = OB_INIT_TWICE;
|
||||
LOG_WARN("value is not null", K(ret), KP(value));
|
||||
} else if (OB_ISNULL(mem = allocator.alloc(sizeof(CLZ)))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("fail to alloc value", K(ret), K(TYPE));
|
||||
} else {
|
||||
const ObSqlCollectionInfo* coll_meta = reinterpret_cast<ObSqlCollectionInfo *>(value);
|
||||
if (OB_FAIL(coll_meta->serialize(buf, buf_len, pos))) {
|
||||
LOG_WARN("failed to do sql udt meta seriazlie", K(ret), K(*coll_meta));
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <>
|
||||
int subschema_value_deserialize<OB_SUBSCHEMA_COLLECTION_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_COLLECTION_TYPE));
|
||||
} else {
|
||||
ObSqlCollectionInfo* coll_meta = reinterpret_cast<ObSqlCollectionInfo *>(value);
|
||||
if (OB_FAIL(coll_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_COLLECTION_TYPE>(void *value)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
int64_t len = 0;
|
||||
if (OB_ISNULL(value)) {
|
||||
} else {
|
||||
ObSqlCollectionInfo* coll_meta = reinterpret_cast<ObSqlCollectionInfo *>(value);
|
||||
len += coll_meta->get_serialize_size();
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
template <>
|
||||
int subschema_value_get_signature<OB_SUBSCHEMA_COLLECTION_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_COLLECTION_TYPE));
|
||||
} else {
|
||||
const ObSqlCollectionInfo* coll_meta = reinterpret_cast<ObSqlCollectionInfo *>(value);
|
||||
signature = coll_meta->get_def_string().hash();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <>
|
||||
int subschema_value_deep_copy<OB_SUBSCHEMA_COLLECTION_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_COLLECTION_TYPE));
|
||||
} else {
|
||||
const ObSqlCollectionInfo* coll_meta = reinterpret_cast<const ObSqlCollectionInfo *>(src_value);
|
||||
ObSqlCollectionInfo* copy_meta = NULL;
|
||||
if (OB_FAIL(coll_meta->deep_copy(allocator, copy_meta))) {
|
||||
LOG_WARN("failed to deep copy udt meta", K(ret), K(OB_SUBSCHEMA_COLLECTION_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_COLLECTION_TYPE));
|
||||
} else {
|
||||
dst_value = static_cast<void *>(copy_meta);
|
||||
}
|
||||
CLZ *meta = new(mem)CLZ(&allocator);
|
||||
value = meta;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
ObSubSchemaFuncs SUBSCHEMA_FUNCS[OB_SUBSCHEMA_MAX_TYPE] =
|
||||
{
|
||||
DEF_SUBSCHEMA_ENTRY(OB_SUBSCHEMA_UDT_TYPE),
|
||||
DEF_SUBSCHEMA_ENTRY(OB_SUBSCHEMA_ENUM_SET_TYPE),
|
||||
DEF_SUBSCHEMA_ENTRY(OB_SUBSCHEMA_COLLECTION_TYPE),
|
||||
DEF_SUBSCHEMA_ENTRY(OB_SUBSCHEMA_UDT_TYPE, ObSqlUDTMeta),
|
||||
DEF_SUBSCHEMA_ENTRY(OB_SUBSCHEMA_ENUM_SET_TYPE, ObEnumSetMeta),
|
||||
DEF_SUBSCHEMA_ENTRY(OB_SUBSCHEMA_COLLECTION_TYPE, ObSqlCollectionInfo),
|
||||
};
|
||||
|
||||
int ObSubSchemaValue::deep_copy_value(const void *src_value, ObIAllocator &allocator)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_ISNULL(src_value)) {
|
||||
if (!is_valid_type(type_)) {
|
||||
// do nothing
|
||||
} else 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))) {
|
||||
@ -231,7 +170,8 @@ OB_DEF_SERIALIZE(ObSubSchemaValue)
|
||||
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))) {
|
||||
} else if (is_valid_type(type_) &&
|
||||
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;
|
||||
@ -248,26 +188,16 @@ OB_DEF_DESERIALIZE(ObSubSchemaValue)
|
||||
} else if (OB_ISNULL(allocator_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("allocator is null", K(ret), K(type_), K(signature_));
|
||||
} else if (type_ == ObSubSchemaType::OB_SUBSCHEMA_UDT_TYPE) {
|
||||
ObSqlUDTMeta *udt_meta = OB_NEWx(ObSqlUDTMeta, allocator_);
|
||||
if (OB_ISNULL(udt_meta)) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("alloc udt meta memory failed", K(ret));
|
||||
} else if (is_valid_type(type_)) {
|
||||
ObIAllocator *alloc = allocator_;
|
||||
void *value_meta = NULL;
|
||||
if (OB_FAIL(SUBSCHEMA_FUNCS[type_].init(value_meta, *alloc))) {
|
||||
LOG_WARN("fail to init value", K(ret));
|
||||
} else if (OB_FAIL(SUBSCHEMA_FUNCS[type_].value_deserialize(value_meta, buf, data_len, pos))) {
|
||||
LOG_WARN("fail to deserialize subschema data", K(ret), K(type_), K(signature_));
|
||||
} else {
|
||||
value_ = udt_meta;
|
||||
value_ = value_meta;
|
||||
}
|
||||
} else if (type_ == ObSubSchemaType::OB_SUBSCHEMA_COLLECTION_TYPE) {
|
||||
ObSqlCollectionInfo *coll_meta = OB_NEWx(ObSqlCollectionInfo, allocator_, *allocator_);
|
||||
if (OB_ISNULL(coll_meta)) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("alloc collection info memory failed", K(ret));
|
||||
} else {
|
||||
value_ = coll_meta;
|
||||
}
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} 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;
|
||||
}
|
||||
@ -279,7 +209,9 @@ OB_DEF_SERIALIZE_SIZE(ObSubSchemaValue)
|
||||
LST_DO_CODE(OB_UNIS_ADD_LEN,
|
||||
type_,
|
||||
signature_);
|
||||
len += SUBSCHEMA_FUNCS[type_].get_value_serialize_size(value_);
|
||||
if (is_valid_type(type_)) {
|
||||
len += SUBSCHEMA_FUNCS[type_].get_value_serialize_size(value_);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
@ -287,19 +219,19 @@ OB_DEF_SERIALIZE_SIZE(ObSubSchemaValue)
|
||||
OB_DEF_SERIALIZE(ObSubSchemaCtx)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (!is_inited_ || subschema_map_.empty()) { // do nothing
|
||||
if (!is_inited_ || subschema_array_.empty()) { // do nothing
|
||||
} else { // subschema count more then zero
|
||||
uint32_t subschema_count = subschema_map_.size();
|
||||
const uint32_t subschema_count = subschema_array_.count();
|
||||
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++;
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < subschema_array_.count(); ++i) {
|
||||
if (OB_LIKELY(subschema_array_.at(i).is_valid())) {
|
||||
OB_UNIS_ENCODE(i);
|
||||
OB_UNIS_ENCODE(subschema_array_.at(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -326,9 +258,9 @@ OB_DEF_DESERIALIZE(ObSubSchemaCtx)
|
||||
value.allocator_ = &allocator_;
|
||||
OB_UNIS_DECODE(subschema_id);
|
||||
OB_UNIS_DECODE(value);
|
||||
if (OB_FAIL(ret)) {
|
||||
if (OB_FAIL(ret)) { // copy value from buffer to local memory
|
||||
} else if (OB_FAIL(set_subschema(subschema_id, value))) {
|
||||
LOG_WARN("fail to set subschema", K(ret), K(subschema_id), K(value));
|
||||
LOG_WARN("fail to set subschema", K(ret), K(subschema_id), K(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -341,16 +273,16 @@ OB_DEF_DESERIALIZE(ObSubSchemaCtx)
|
||||
OB_DEF_SERIALIZE_SIZE(ObSubSchemaCtx)
|
||||
{
|
||||
int64_t len = 0;
|
||||
if (!is_inited_ || subschema_map_.empty()) { // do nothing
|
||||
if (!is_inited_ || subschema_array_.empty()) { // do nothing
|
||||
} else { // subschema count more then zero
|
||||
uint32_t subschema_count = subschema_map_.size();
|
||||
uint32_t subschema_count = subschema_array_.count();
|
||||
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++;
|
||||
for (int64_t i = 0; i < subschema_array_.count(); ++i) {
|
||||
if (OB_LIKELY(subschema_array_.at(i).is_valid())) {
|
||||
OB_UNIS_ADD_LEN(i);
|
||||
OB_UNIS_ADD_LEN(subschema_array_.at(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
return len;
|
||||
@ -369,16 +301,15 @@ int ObSubSchemaCtx::assgin(const ObSubSchemaCtx &other)
|
||||
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));
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < other.get_subschema_array().count(); ++i) {
|
||||
uint64_t subschema_id = i;
|
||||
const ObSubSchemaValue src = other.get_subschema_array().at(subschema_id);
|
||||
ObSubSchemaValue dst = src;
|
||||
if (OB_FAIL(dst.deep_copy_value(src.value_, allocator_))) {
|
||||
LOG_WARN("deep copy value failed", K(ret), K(i), K(dst));
|
||||
} else if (OB_FAIL(set_subschema(i, dst))) {
|
||||
LOG_WARN("fail to set subschema", K(ret), K(i), K(dst));
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
used_subschema_id_ = other.used_subschema_id_;
|
||||
}
|
||||
@ -397,17 +328,17 @@ int ObSubSchemaCtx::init()
|
||||
if (tenant_id == OB_INVALID_TENANT_ID) {
|
||||
tenant_id = OB_SERVER_TENANT_ID;
|
||||
}
|
||||
if (OB_FAIL(subschema_map_.create(SUBSCHEMA_BUCKET_NUM,
|
||||
"SubSchemaHash",
|
||||
"SubSchemaHash",
|
||||
tenant_id))) {
|
||||
LOG_WARN("fail to create subschema map", K(ret));
|
||||
} else if (OB_FAIL(subschema_reverse_map_.create(SUBSCHEMA_BUCKET_NUM,
|
||||
if (OB_FAIL(subschema_reverse_map_.create(SUBSCHEMA_BUCKET_NUM,
|
||||
"SubSchemaRev",
|
||||
"SubSchemaRev",
|
||||
tenant_id))) {
|
||||
LOG_WARN("fail to create subschema map", K(ret));
|
||||
} else if (OB_FAIL(enum_set_meta_reverse_map_.create(SUBSCHEMA_BUCKET_NUM,
|
||||
"SubSchemaRev",
|
||||
"SubSchemaRev",
|
||||
tenant_id))) {
|
||||
} else {
|
||||
subschema_array_.set_attr(ObMemAttr(MTL_ID(), "SubSchemaHash"));
|
||||
is_inited_ = true;
|
||||
used_subschema_id_ = MAX_NON_RESERVED_SUBSCHEMA_ID;
|
||||
}
|
||||
@ -418,8 +349,9 @@ int ObSubSchemaCtx::init()
|
||||
void ObSubSchemaCtx::reset() {
|
||||
// content in subschema value is alloc from plan object allocator? need a new allocator?
|
||||
if (is_inited_) {
|
||||
subschema_map_.destroy();
|
||||
subschema_array_.destroy();
|
||||
subschema_reverse_map_.destroy();
|
||||
enum_set_meta_reverse_map_.destroy();
|
||||
is_inited_ = false;
|
||||
used_subschema_id_ = MAX_NON_RESERVED_SUBSCHEMA_ID;
|
||||
reserved_ = 0;
|
||||
@ -433,7 +365,7 @@ uint32_t ObSubSchemaCtx::get_subschema_count() const
|
||||
uint32_t subschema_count = 0;
|
||||
if (!is_inited_) {
|
||||
} else {
|
||||
subschema_count = subschema_map_.size();
|
||||
subschema_count = subschema_array_.count();
|
||||
}
|
||||
return subschema_count;
|
||||
}
|
||||
@ -467,6 +399,17 @@ int ObSubSchemaCtx::get_subschema_id_from_fields(uint64_t udt_id, uint16_t &subs
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
int ObSubSchemaCtx::ensure_array_capacity(const uint16_t count)
|
||||
{
|
||||
int ret = common::OB_SUCCESS;
|
||||
if (OB_UNLIKELY(count >= subschema_array_.get_capacity()) &&
|
||||
OB_FAIL(subschema_array_.reserve(next_pow2(count)))) {
|
||||
LOG_WARN("fail to reserve array capacity", K(ret), K(count), K_(subschema_array));
|
||||
} else if (OB_FAIL(subschema_array_.prepare_allocate(count))) {
|
||||
LOG_WARN("fail to prepare allocate array", K(ret), K(count), K_(subschema_array));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObSubSchemaCtx::set_subschema(uint16_t subschema_id, ObSubSchemaValue &value)
|
||||
{
|
||||
@ -474,7 +417,7 @@ int ObSubSchemaCtx::set_subschema(uint16_t subschema_id, ObSubSchemaValue &value
|
||||
uint64_t key = subschema_id;
|
||||
ObSubSchemaValue tmp_value;
|
||||
ObSubSchemaReverseKey rev_key(value.type_, value.signature_);
|
||||
if (OB_FAIL(subschema_map_.get_refactored(key, tmp_value))) {
|
||||
if (OB_FAIL(get_subschema(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 if (value.type_ == ObSubSchemaType::OB_SUBSCHEMA_COLLECTION_TYPE) {
|
||||
@ -484,14 +427,29 @@ int ObSubSchemaCtx::set_subschema(uint16_t subschema_id, ObSubSchemaValue &value
|
||||
if (OB_HASH_NOT_EXIST == ret) {
|
||||
// not exist
|
||||
ret = OB_SUCCESS;
|
||||
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));
|
||||
LOG_INFO("add new subschema", K(ret), K(subschema_id), K(value), K(subschema_array_.count()));
|
||||
if (OB_FAIL(ensure_array_capacity(subschema_id + 1))) {
|
||||
LOG_WARN("fail to ensure array capacity", K(ret));
|
||||
} else if (FALSE_IT(subschema_array_.at(subschema_id) = value)) {
|
||||
} 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));
|
||||
if (OB_HASH_EXIST == ret) {
|
||||
ret = OB_SUCCESS;
|
||||
} else {
|
||||
LOG_WARN("set subschema map failed", K(ret), K(rev_key));
|
||||
subschema_array_.at(subschema_id).reset();
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) && value.type_ == OB_SUBSCHEMA_ENUM_SET_TYPE) {
|
||||
const ObEnumSetMeta* enumset_meta = reinterpret_cast<const ObEnumSetMeta*>(value.value_);
|
||||
ObEnumSetMetaReverseKey meta_rev_key(value.type_, enumset_meta);
|
||||
if (OB_FAIL(enum_set_meta_reverse_map_.set_refactored(meta_rev_key, key))) {
|
||||
if (OB_HASH_EXIST == ret) {
|
||||
ret = OB_SUCCESS;
|
||||
} else {
|
||||
LOG_WARN("set subschema map failed", K(ret), K(rev_key));
|
||||
subschema_array_.at(subschema_id).reset();
|
||||
subschema_reverse_map_.erase_refactored(rev_key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -504,8 +462,14 @@ int ObSubSchemaCtx::set_subschema(uint16_t subschema_id, ObSubSchemaValue &value
|
||||
|
||||
int ObSubSchemaCtx::get_subschema(uint16_t subschema_id, ObSubSchemaValue &value) const
|
||||
{
|
||||
uint64_t key = subschema_id;
|
||||
return subschema_map_.get_refactored(key, value);
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_LIKELY(subschema_id < subschema_array_.count() &&
|
||||
subschema_array_.at(subschema_id).is_valid())) {
|
||||
value = subschema_array_.at(subschema_id);
|
||||
} else {
|
||||
ret = OB_HASH_NOT_EXIST;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObSubSchemaCtx::get_subschema_id(uint64_t value_signature,
|
||||
@ -555,14 +519,12 @@ int ObSubSchemaCtx::get_subschema_id_by_typedef(const ObString &type_def,
|
||||
value.value_ = static_cast<void *>(buf);
|
||||
uint64_t key = tmp_subid;
|
||||
rev_key.str_signature_.assign_ptr(type_info.ptr(), type_info.length());
|
||||
if (OB_FAIL(subschema_map_.set_refactored(key, value))) {
|
||||
LOG_WARN("set subschema map failed", K(ret), K(key));
|
||||
if (OB_FAIL(ensure_array_capacity(key + 1))) {
|
||||
LOG_WARN("fail to ensure array capacity", K(ret));
|
||||
} else if (FALSE_IT(subschema_array_.at(key) = value)) {
|
||||
} 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(key);
|
||||
if (tmp_ret != OB_SUCCESS) {
|
||||
LOG_WARN("erase subschema map failed", K(ret), K(tmp_ret), K(key));
|
||||
}
|
||||
subschema_array_.at(key).reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -625,5 +587,16 @@ int ObSubSchemaCtx::get_subschema_id_by_typedef(ObNestedType coll_type,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObSubSchemaCtx::get_subschema_id(const ObSubSchemaType type,
|
||||
const ObEnumSetMeta &meta,
|
||||
uint16_t &subschema_id) const
|
||||
{
|
||||
ObEnumSetMetaReverseKey rev_key(type, &meta);
|
||||
uint64_t value = ObMaxSystemUDTSqlType; // init invalid subschema value
|
||||
int ret = enum_set_meta_reverse_map_.get_refactored(rev_key, value);
|
||||
subschema_id = value;
|
||||
return ret;
|
||||
}
|
||||
|
||||
} //sql
|
||||
} //oceanbase
|
||||
|
@ -37,9 +37,20 @@ class ObSubSchemaValue
|
||||
{
|
||||
OB_UNIS_VERSION(1);
|
||||
public:
|
||||
ObSubSchemaValue() : type_(OB_SUBSCHEMA_MAX_TYPE), signature_(0), value_(NULL) {}
|
||||
ObSubSchemaValue() : type_(OB_SUBSCHEMA_MAX_TYPE), signature_(0), value_(NULL),
|
||||
allocator_(NULL) {}
|
||||
~ObSubSchemaValue() {}
|
||||
int deep_copy_value(const void *src_value, ObIAllocator &allocator);
|
||||
static bool is_valid_type(ObSubSchemaType type)
|
||||
{ return type >= OB_SUBSCHEMA_UDT_TYPE && type < OB_SUBSCHEMA_MAX_TYPE; }
|
||||
inline bool is_valid() const { return is_valid_type(type_); }
|
||||
inline void reset()
|
||||
{
|
||||
type_ = OB_SUBSCHEMA_MAX_TYPE;
|
||||
signature_ = 0;
|
||||
value_ = NULL;
|
||||
allocator_ = NULL;
|
||||
}
|
||||
TO_STRING_KV(K_(type), K_(signature), KP_(value));
|
||||
public:
|
||||
ObSubSchemaType type_;
|
||||
@ -54,6 +65,7 @@ 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);
|
||||
typedef int (*ob_subschema_value_init)(void *&value, ObIAllocator &allocator);
|
||||
|
||||
struct ObSubSchemaFuncs
|
||||
{
|
||||
@ -63,33 +75,22 @@ struct ObSubSchemaFuncs
|
||||
ob_subschema_value_get_signature get_signature;
|
||||
|
||||
ob_subschema_value_deep_copy deep_copy;
|
||||
|
||||
ob_subschema_value_init init;
|
||||
};
|
||||
|
||||
template <ObSubSchemaType type>
|
||||
int subschema_value_serialize(void *value, char* buf, const int64_t buf_len, int64_t& pos)
|
||||
{
|
||||
return OB_NOT_SUPPORTED;
|
||||
}
|
||||
template <ObSubSchemaType type>
|
||||
int subschema_value_deserialize(void *value, const char* buf, const int64_t data_len, int64_t& pos)
|
||||
{
|
||||
return OB_NOT_SUPPORTED;
|
||||
}
|
||||
template <ObSubSchemaType type> int64_t subschema_value_serialize_size(void *value)
|
||||
{
|
||||
return OB_NOT_SUPPORTED;
|
||||
}
|
||||
template <ObSubSchemaType type>
|
||||
int subschema_value_get_signature(void *value, uint64_t &signature)
|
||||
{
|
||||
return OB_NOT_SUPPORTED;
|
||||
}
|
||||
template <ObSubSchemaType type>
|
||||
int subschema_value_deep_copy(const void *src_value, void *&dst_value, ObIAllocator &allocator)
|
||||
{
|
||||
return OB_NOT_SUPPORTED;
|
||||
}
|
||||
template <ObSubSchemaType TYPE, typename CLZ>
|
||||
int subschema_value_serialize(void *value, char* buf, const int64_t buf_len, int64_t& pos);
|
||||
template <ObSubSchemaType TYPE, typename CLZ>
|
||||
int subschema_value_deserialize(void *value, const char* buf, const int64_t data_len, int64_t& pos);
|
||||
template <ObSubSchemaType TYPE, typename CLZ>
|
||||
int64_t subschema_value_serialize_size(void *value);
|
||||
template <ObSubSchemaType TYPE, typename CLZ>
|
||||
int subschema_value_get_signature(void *value, uint64_t &signature);
|
||||
template <ObSubSchemaType TYPE, typename CLZ>
|
||||
int subschema_value_deep_copy(const void *src_value, void *&dst_value, ObIAllocator &allocator);
|
||||
|
||||
template <ObSubSchemaType TYPE, typename CLZ>
|
||||
int subschema_value_init(void *&value, ObIAllocator &allocator);
|
||||
|
||||
class ObSubSchemaReverseKey
|
||||
{
|
||||
@ -124,14 +125,57 @@ class ObSubSchemaReverseKey
|
||||
ObString str_signature_;
|
||||
};
|
||||
|
||||
class ObEnumSetMetaReverseKey
|
||||
{
|
||||
public:
|
||||
ObEnumSetMetaReverseKey() : type_(OB_SUBSCHEMA_MAX_TYPE), meta_(NULL) {}
|
||||
ObEnumSetMetaReverseKey(const ObSubSchemaType type, const ObEnumSetMeta *meta) :
|
||||
type_(type), meta_(meta) {}
|
||||
~ObEnumSetMetaReverseKey() {}
|
||||
|
||||
inline uint64_t hash() const
|
||||
{
|
||||
uint64_t hash_val = 0;
|
||||
if (OB_NOT_NULL(meta_)) {
|
||||
hash_val = meta_->hash() + static_cast<uint64_t>(type_);
|
||||
}
|
||||
return hash_val;
|
||||
}
|
||||
|
||||
inline int hash(uint64_t &res) const
|
||||
{
|
||||
res = hash();
|
||||
return OB_SUCCESS;
|
||||
}
|
||||
|
||||
inline bool operator==(const ObEnumSetMetaReverseKey &other) const
|
||||
{
|
||||
bool eq_ret = true;
|
||||
if (other.type_ != this->type_) {
|
||||
eq_ret = false;
|
||||
} else if (meta_ == NULL || other.meta_ == NULL) {
|
||||
eq_ret = (meta_ == other.meta_);
|
||||
} else {
|
||||
eq_ret = (*meta_ == *other.meta_);
|
||||
}
|
||||
return eq_ret;
|
||||
}
|
||||
|
||||
TO_STRING_KV(K_(type), KP_(meta));
|
||||
|
||||
ObSubSchemaType type_;
|
||||
const ObEnumSetMeta *meta_;
|
||||
};
|
||||
|
||||
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;
|
||||
typedef common::ObSEArray<ObSubSchemaValue, SUBSCHEMA_BUCKET_NUM> ObSubSchemaArray;
|
||||
// reverse map is used for conflict check and reverse search, reverse key is a signature from value;
|
||||
typedef common::hash::ObHashMap<ObSubSchemaReverseKey, uint64_t, common::hash::NoPthreadDefendMode> ObSubSchemaReverseMap;
|
||||
typedef common::hash::ObHashMap<ObEnumSetMetaReverseKey, uint64_t, common::hash::NoPthreadDefendMode> ObEnumSetMetaReverseMap;
|
||||
|
||||
public:
|
||||
ObSubSchemaCtx(ObIAllocator &allocator) :
|
||||
@ -153,19 +197,28 @@ public:
|
||||
|
||||
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_; }
|
||||
ObSubSchemaArray &get_subschema_array() { return subschema_array_; }
|
||||
const ObSubSchemaArray &get_subschema_array() const { return subschema_array_; }
|
||||
|
||||
int get_subschema_id(uint64_t value_signature, ObSubSchemaType type, uint16_t &subschema_id) const;
|
||||
int get_subschema_id_by_typedef(ObNestedType coll_type, const ObDataType &elem_type, uint16_t &subschema_id);
|
||||
int get_subschema_id_by_typedef(ObNestedType coll_type, const ObDataType &elem_type, uint16_t &subschema_id) const;
|
||||
int get_subschema_id_by_typedef(const ObString &type_def, uint16_t &subschema_id);
|
||||
int get_subschema_id_by_typedef(const ObString &type_def, uint16_t &subschema_id) const;
|
||||
int get_subschema_id(const ObSubSchemaType type, const ObEnumSetMeta &meta,
|
||||
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()));
|
||||
K(subschema_array_.count()), K(subschema_reverse_map_.size()));
|
||||
private:
|
||||
inline int ensure_array_capacity(const uint16_t count);
|
||||
static bool is_type_info_subschema(const ObSubSchemaType type)
|
||||
{
|
||||
return type == OB_SUBSCHEMA_ENUM_SET_TYPE;
|
||||
}
|
||||
|
||||
private:
|
||||
bool is_inited_;
|
||||
@ -174,8 +227,9 @@ private:
|
||||
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)
|
||||
ObSubSchemaArray subschema_array_; // subschema id (as array index) mapping to subschema (e.g. udt meta)
|
||||
ObSubSchemaReverseMap subschema_reverse_map_; // subschema type+signature (e.g. udt_id) mapping to subschema id
|
||||
ObEnumSetMetaReverseMap enum_set_meta_reverse_map_; // subschema type + meta_ mapping to subschema id
|
||||
};
|
||||
|
||||
}
|
||||
|
83
src/sql/executor/ob_memory_tracker.cpp
Normal file
83
src/sql/executor/ob_memory_tracker.cpp
Normal file
@ -0,0 +1,83 @@
|
||||
/**
|
||||
* 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 "sql/executor/ob_memory_tracker.h"
|
||||
#include "lib/rc/context.h"
|
||||
#include "observer/omt/ob_tenant_config_mgr.h"
|
||||
#include "share/rc/ob_tenant_base.h"
|
||||
|
||||
using namespace oceanbase::lib;
|
||||
|
||||
thread_local ObMemTracker ObMemTrackerGuard::mem_tracker_;
|
||||
|
||||
void ObMemTrackerGuard::reset_try_check_tick()
|
||||
{
|
||||
mem_tracker_.try_check_tick_ = 0;
|
||||
}
|
||||
|
||||
void ObMemTrackerGuard::dump_mem_tracker_info()
|
||||
{
|
||||
int64_t tenant_mem_limit = lib::get_tenant_memory_limit(MTL_ID());
|
||||
int64_t mem_quota_pct = 100;
|
||||
int64_t tree_mem_hold = 0;
|
||||
omt::ObTenantConfigGuard tenant_config(TENANT_CONF(MTL_ID()));
|
||||
if (OB_UNLIKELY(tenant_config.is_valid())) {
|
||||
mem_quota_pct = tenant_config->query_memory_limit_percentage;
|
||||
}
|
||||
if (nullptr != mem_tracker_.mem_context_) {
|
||||
tree_mem_hold = mem_tracker_.mem_context_->tree_mem_hold();
|
||||
}
|
||||
int64_t mem_limit = tenant_mem_limit / 100 * mem_quota_pct;
|
||||
SQL_LOG(INFO, "dump memory tracker info", K(MTL_ID()), K(tenant_mem_limit), K(mem_limit),
|
||||
K(tree_mem_hold));
|
||||
}
|
||||
|
||||
void ObMemTrackerGuard::update_mem_limit()
|
||||
{
|
||||
int ret = common::OB_SUCCESS;
|
||||
int64_t tenant_mem_limit = lib::get_tenant_memory_limit(MTL_ID());
|
||||
int64_t mem_quota_pct = 100;
|
||||
omt::ObTenantConfigGuard tenant_config(TENANT_CONF(MTL_ID()));
|
||||
if (OB_UNLIKELY(tenant_config.is_valid())) {
|
||||
mem_quota_pct = tenant_config->query_memory_limit_percentage;
|
||||
}
|
||||
mem_tracker_.cache_mem_limit_ = tenant_mem_limit / 100 * mem_quota_pct;
|
||||
}
|
||||
int ObMemTrackerGuard::check_status()
|
||||
{
|
||||
int ret = common::OB_SUCCESS;
|
||||
if (nullptr != mem_tracker_.mem_context_) {
|
||||
int64_t tree_mem_hold = mem_tracker_.mem_context_->tree_mem_hold();
|
||||
++mem_tracker_.check_status_times_;
|
||||
if (0 == mem_tracker_.cache_mem_limit_
|
||||
|| (mem_tracker_.check_status_times_ % UPDATE_MEM_LIMIT_THRESHOLD == 0)) {
|
||||
update_mem_limit();
|
||||
}
|
||||
if (tree_mem_hold >= mem_tracker_.cache_mem_limit_) {
|
||||
ret = OB_EXCEED_QUERY_MEM_LIMIT;
|
||||
SQL_LOG(WARN, "Exceeded memory usage limit", K(ret), K(tree_mem_hold),
|
||||
K(mem_tracker_.cache_mem_limit_));
|
||||
LOG_USER_ERROR(OB_EXCEED_QUERY_MEM_LIMIT, mem_tracker_.cache_mem_limit_, tree_mem_hold);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
int ObMemTrackerGuard::try_check_status(int64_t check_try_times)
|
||||
{
|
||||
int ret = common::OB_SUCCESS;
|
||||
if (nullptr != mem_tracker_.mem_context_
|
||||
&& ((++mem_tracker_.try_check_tick_) % check_try_times == 0)) {
|
||||
ret = check_status();
|
||||
}
|
||||
return ret;
|
||||
}
|
79
src/sql/executor/ob_memory_tracker.h
Normal file
79
src/sql/executor/ob_memory_tracker.h
Normal file
@ -0,0 +1,79 @@
|
||||
/**
|
||||
* 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_MEMORY_TRACKER_H
|
||||
#define OCEANBASE_SQL_OB_MEMORY_TRACKER_H
|
||||
|
||||
#include "lib/alloc/alloc_func.h"
|
||||
|
||||
namespace oceanbase
|
||||
{
|
||||
namespace lib
|
||||
{
|
||||
class MemoryContext;
|
||||
|
||||
struct ObMemTracker
|
||||
{
|
||||
ObMemTracker() :
|
||||
cache_mem_limit_(0), check_status_times_(0), try_check_tick_(0), mem_context_(nullptr)
|
||||
{}
|
||||
void reset()
|
||||
{
|
||||
cache_mem_limit_ = 0;
|
||||
check_status_times_ = 0;
|
||||
try_check_tick_ = 0;
|
||||
mem_context_ = nullptr;
|
||||
}
|
||||
|
||||
int64_t cache_mem_limit_;
|
||||
uint16_t check_status_times_;
|
||||
uint16_t try_check_tick_;
|
||||
lib::MemoryContext *mem_context_;
|
||||
};
|
||||
|
||||
class ObMemTrackerGuard
|
||||
{
|
||||
public:
|
||||
const static uint64_t DEFAULT_CHECK_STATUS_TRY_TIMES = 1024;
|
||||
const static uint64_t UPDATE_MEM_LIMIT_THRESHOLD = 512;
|
||||
ObMemTrackerGuard(lib::MemoryContext &mem_context)
|
||||
{
|
||||
mem_tracker_.reset();
|
||||
mem_tracker_.mem_context_ = &mem_context;
|
||||
}
|
||||
~ObMemTrackerGuard()
|
||||
{
|
||||
mem_tracker_.reset();
|
||||
}
|
||||
static void reset_try_check_tick();
|
||||
static void dump_mem_tracker_info();
|
||||
static void update_mem_limit();
|
||||
static int check_status();
|
||||
static int try_check_status(int64_t check_try_times = DEFAULT_CHECK_STATUS_TRY_TIMES);
|
||||
|
||||
private:
|
||||
static thread_local ObMemTracker mem_tracker_;
|
||||
};
|
||||
|
||||
} // end namespace lib
|
||||
} // end namespace oceanbase
|
||||
|
||||
#define MEM_TRACKER_GUARD(mem_context) \
|
||||
oceanbase::lib::ObMemTrackerGuard mem_tracker_guard(mem_context);
|
||||
#define RESET_TRY_CHECK_TICK \
|
||||
oceanbase::lib::ObMemTrackerGuard::reset_try_check_tick();
|
||||
#define CHECK_MEM_STATUS() \
|
||||
oceanbase::lib::ObMemTrackerGuard::check_status()
|
||||
#define TRY_CHECK_MEM_STATUS(check_try_times) \
|
||||
oceanbase::lib::ObMemTrackerGuard::try_check_status(check_try_times)
|
||||
|
||||
#endif /* OCEANBASE_SQL_OB_MEMORY_TRACKER_H */
|
24
src/sql/executor/ob_memory_tracker_wrapper.cpp
Normal file
24
src/sql/executor/ob_memory_tracker_wrapper.cpp
Normal file
@ -0,0 +1,24 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "sql/executor/ob_memory_tracker_wrapper.h"
|
||||
#include "sql/executor/ob_memory_tracker.h"
|
||||
|
||||
int check_mem_status()
|
||||
{
|
||||
return oceanbase::lib::ObMemTrackerGuard::check_status();
|
||||
}
|
||||
|
||||
int try_check_mem_status(int64_t check_try_times)
|
||||
{
|
||||
return oceanbase::lib::ObMemTrackerGuard::try_check_status(check_try_times);
|
||||
}
|
29
src/sql/executor/ob_memory_tracker_wrapper.h
Normal file
29
src/sql/executor/ob_memory_tracker_wrapper.h
Normal file
@ -0,0 +1,29 @@
|
||||
/**
|
||||
* 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_MEMORY_TRACKER_WRAPPER_H
|
||||
#define OCEANBASE_SQL_OB_MEMORY_TRACKER_WRAPPER_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int check_mem_status();
|
||||
int try_check_mem_status(int64_t check_try_times);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* OCEANBASE_SQL_OB_MEMORY_TRACKER_WRAPPER_H */
|
@ -734,6 +734,7 @@ int ObSPIService::cast_enum_set_to_string(ObExecContext &ctx,
|
||||
OX (result_type.set_meta(src.get_meta()));
|
||||
OX (result_type.set_accuracy(src.get_accuracy()));
|
||||
OX (c_expr->set_result_type(result_type));
|
||||
OX (c_expr->mark_enum_set_skip_build_subschema());
|
||||
OZ (ObRawExprUtils::create_type_to_str_expr(*expr_factory, c_expr, out_expr, session_info, true));
|
||||
CK (OB_NOT_NULL(out_expr));
|
||||
OZ (ObSPIService::spi_calc_raw_expr(session_info, &(ctx.get_allocator()), out_expr, &result));
|
||||
@ -7572,6 +7573,16 @@ int ObSPIService::convert_obj(ObPLExecCtx *ctx,
|
||||
OX (result_type.set_accuracy(current_type.at(i).get_accuracy()));
|
||||
} else {
|
||||
OX (result_type.set_accuracy(result_types[i].get_accuracy()));
|
||||
if (OB_SUCC(ret) && result_type.is_enum_set_with_subschema()) {
|
||||
ObObjMeta org_obj_meta;
|
||||
if (OB_FAIL(ObRawExprUtils::extract_enum_set_collation(result_type,
|
||||
ctx->exec_ctx_->get_my_session(),
|
||||
org_obj_meta))) {
|
||||
LOG_WARN("fail to extrac enum set meta", K(ret));
|
||||
} else {
|
||||
result_type.set_collation(org_obj_meta);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) && (result_type.is_blob() || result_type.is_blob_locator() || obj.is_blob() || obj.is_blob_locator())
|
||||
&& lib::is_oracle_mode()) {
|
||||
|
@ -6149,7 +6149,8 @@ bool ObSQLUtils::check_need_disconnect_parser_err(const int ret_code)
|
||||
|| OB_ERR_VIEW_SELECT_CONTAIN_QUESTIONMARK == ret_code
|
||||
|| OB_ERR_NON_INT_LITERAL == ret_code
|
||||
|| OB_ERR_PARSER_INIT == ret_code
|
||||
|| OB_NOT_SUPPORTED == ret_code)) {
|
||||
|| OB_NOT_SUPPORTED == ret_code
|
||||
|| OB_ALLOCATE_MEMORY_FAILED == ret_code)) {
|
||||
bret = false;
|
||||
}
|
||||
return bret;
|
||||
|
@ -11425,6 +11425,9 @@ int ObJoinOrder::create_and_add_hash_path(const Path *left_path,
|
||||
LOG_WARN("failed to create subplan filter for join path", K(ret));
|
||||
} else if (OB_FAIL(add_path(join_path))) {
|
||||
LOG_WARN("failed to add path", K(ret));
|
||||
} else if (CONNECT_BY_JOIN == join_type &&
|
||||
OB_FAIL(push_down_order_siblings(join_path, right_path))) {
|
||||
LOG_WARN("push down order siblings by condition failed", K(ret));
|
||||
} else {
|
||||
LOG_TRACE("succeed to create a hash join path", K(join_type),
|
||||
K(join_dist_algo), K(equal_join_conditions), K(other_join_conditions));
|
||||
@ -12768,7 +12771,7 @@ int ObJoinOrder::get_valid_path_info(const ObJoinOrder &left_tree,
|
||||
const bool both_access = ACCESS == left_tree.get_type() && ACCESS == right_tree.get_type();
|
||||
const bool contain_fake_cte = left_paths.at(0)->contain_fake_cte() || right_paths.at(0)->contain_fake_cte();
|
||||
if (CONNECT_BY_JOIN == path_info.join_type_) {
|
||||
path_info.local_methods_ = NESTED_LOOP_JOIN;
|
||||
path_info.local_methods_ = NESTED_LOOP_JOIN | HASH_JOIN;
|
||||
path_info.distributed_methods_ = DIST_PULL_TO_LOCAL | DIST_BASIC_METHOD;
|
||||
OPT_TRACE("connect by will use nl join");
|
||||
OPT_TRACE("connect by will use pull to local / basic method");
|
||||
|
@ -12207,7 +12207,7 @@ int ObLogPlan::generate_column_expr(ObRawExprFactory &expr_factory,
|
||||
column_item.expr_ = rowkey;
|
||||
if (OB_FAIL(rowkey->add_relation_id(stmt->get_table_bit_index(table_id)))) {
|
||||
LOG_WARN("add relation id to expr failed", K(ret));
|
||||
} else if (OB_FAIL(rowkey->formalize(NULL))) {
|
||||
} else if (OB_FAIL(rowkey->formalize(optimizer_context_.get_session_info()))) {
|
||||
LOG_WARN("formalize rowkey failed", K(ret));
|
||||
} else if (OB_FAIL(rowkey->pull_relation_id())) {
|
||||
LOG_WARN("failed to pullup relation ids", K(ret));
|
||||
|
@ -1889,7 +1889,8 @@ int ObOptimizerUtil::generate_rowkey_exprs(const ObDMLStmt *stmt,
|
||||
table_id,
|
||||
*table_schema,
|
||||
keys,
|
||||
ordering))) {
|
||||
ordering,
|
||||
opt_ctx.get_session_info()))) {
|
||||
LOG_WARN("failed to get rowkeys raw expr", K(table_id), K(ref_table_id), K(ret));
|
||||
} else { /*do nothing*/ }
|
||||
|
||||
@ -1901,7 +1902,8 @@ int ObOptimizerUtil::generate_rowkey_exprs(const ObDMLStmt* cstmt,
|
||||
uint64_t table_id,
|
||||
const ObTableSchema &index_table_schema,
|
||||
ObIArray<ObRawExpr*> &index_keys,
|
||||
ObIArray<ObRawExpr*> &index_ordering)
|
||||
ObIArray<ObRawExpr*> &index_ordering,
|
||||
ObSQLSessionInfo *session)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObDMLStmt *stmt = const_cast<ObDMLStmt *>(cstmt);
|
||||
@ -1927,7 +1929,8 @@ int ObOptimizerUtil::generate_rowkey_exprs(const ObDMLStmt* cstmt,
|
||||
//or other opt need to use different indexes in one logical plan, remember this problem.
|
||||
if (NULL != (raw_expr = stmt->get_column_expr_by_id(table_id, column_id))) {
|
||||
expr = static_cast<ObColumnRefRawExpr*>(raw_expr);
|
||||
} else if (OB_FAIL(generate_rowkey_expr(stmt, expr_factory, table_id, *column_schema, expr))) {
|
||||
} else if (OB_FAIL(generate_rowkey_expr(stmt, expr_factory, table_id, *column_schema, expr,
|
||||
session))) {
|
||||
LOG_WARN("failed to get row key expr", K(ret));
|
||||
} else { /*do nothing*/ }
|
||||
|
||||
@ -7004,7 +7007,8 @@ int ObOptimizerUtil::add_cast_to_set_list(ObSQLSessionInfo *session_info,
|
||||
|| OB_ISNULL(src_expr = stmt->get_select_item(idx).expr_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected stmt", K(ret), K(stmts.at(i)));
|
||||
} else if (ob_is_enumset_tc(src_expr->get_result_type().get_type())) {
|
||||
} else if (ob_is_enumset_tc(src_expr->get_result_type().get_type())
|
||||
&& !src_expr->is_enum_set_with_subschema()) {
|
||||
ObSysFunRawExpr *to_str_expr = NULL;
|
||||
if (src_expr->get_result_type() == res_type) {
|
||||
/*do nothing*/
|
||||
@ -8623,6 +8627,7 @@ int ObOptimizerUtil::generate_rowkey_expr(ObDMLStmt *stmt,
|
||||
const uint64_t &table_id,
|
||||
const ObColumnSchemaV2 &column_schema,
|
||||
ObColumnRefRawExpr *&rowkey,
|
||||
ObSQLSessionInfo *session,
|
||||
ObIArray<ColumnItem> *column_items)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
@ -8655,7 +8660,7 @@ int ObOptimizerUtil::generate_rowkey_expr(ObDMLStmt *stmt,
|
||||
LOG_WARN("add column item to stmt failed", K(ret));
|
||||
} else if (FALSE_IT(rowkey->clear_explicited_referece())) {
|
||||
/*do nothing*/
|
||||
} else if (OB_FAIL(rowkey->formalize(NULL))) {
|
||||
} else if (OB_FAIL(rowkey->formalize(session))) {
|
||||
LOG_WARN("formalize rowkey failed", K(ret));
|
||||
} else if (OB_FAIL(rowkey->pull_relation_id())) {
|
||||
LOG_WARN("failed to pullup relation ids", K(ret));
|
||||
|
@ -411,7 +411,8 @@ public:
|
||||
uint64_t table_id,
|
||||
const share::schema::ObTableSchema &index_table_schema,
|
||||
common::ObIArray<ObRawExpr*> &index_keys,
|
||||
common::ObIArray<ObRawExpr*> &index_ordering);
|
||||
common::ObIArray<ObRawExpr*> &index_ordering,
|
||||
ObSQLSessionInfo *session);
|
||||
|
||||
static int build_range_columns(const ObDMLStmt *stmt,
|
||||
common::ObIArray<ObRawExpr*> &rowkeys,
|
||||
@ -1425,6 +1426,7 @@ public:
|
||||
const uint64_t &table_id,
|
||||
const share::schema::ObColumnSchemaV2 &column_schema,
|
||||
ObColumnRefRawExpr *&rowkey,
|
||||
ObSQLSessionInfo *session,
|
||||
common::ObIArray<ColumnItem> *column_items = NULL);
|
||||
|
||||
static int check_contain_ora_rowscn_expr(const ObRawExpr *expr, bool &contains);
|
||||
|
@ -4732,6 +4732,7 @@ int ValueItemExpr::deserialize(common::ObIAllocator &allocator, const char *buf,
|
||||
enum_set_values_ =
|
||||
static_cast<ObString *>(allocator.alloc(sizeof(ObString) * enum_set_values_cnt_));
|
||||
CK(OB_NOT_NULL(enum_set_values_));
|
||||
MEMSET(enum_set_values_, 0, sizeof(ObString) * enum_set_values_cnt_);
|
||||
OB_UNIS_DECODE_ARRAY(enum_set_values_, enum_set_values_cnt_)
|
||||
}
|
||||
}
|
||||
|
@ -98,18 +98,13 @@ int ObFastParser::parse(const common::ObString &stmt,
|
||||
return ret;
|
||||
}
|
||||
|
||||
ObFastParserBase::ObFastParserBase(
|
||||
ObIAllocator &allocator,
|
||||
const FPContext fp_ctx) :
|
||||
no_param_sql_(nullptr), no_param_sql_len_(0),
|
||||
param_num_(0), is_oracle_mode_(false),
|
||||
ObFastParserBase::ObFastParserBase(ObIAllocator &allocator, const FPContext fp_ctx) :
|
||||
no_param_sql_(nullptr), no_param_sql_len_(0), param_num_(0), is_oracle_mode_(false),
|
||||
is_batched_multi_stmt_split_on_(fp_ctx.enable_batched_multi_stmt_),
|
||||
is_udr_mode_(fp_ctx.is_udr_mode_),
|
||||
def_name_ctx_(fp_ctx.def_name_ctx_),
|
||||
cur_token_begin_pos_(0), copy_begin_pos_(0), copy_end_pos_(0),
|
||||
tmp_buf_(nullptr), tmp_buf_len_(0), last_escape_check_pos_(0),
|
||||
param_node_list_(nullptr), tail_param_node_(nullptr),
|
||||
cur_token_type_(INVALID_TOKEN), allocator_(allocator),
|
||||
is_udr_mode_(fp_ctx.is_udr_mode_), def_name_ctx_(fp_ctx.def_name_ctx_), cur_token_begin_pos_(0),
|
||||
copy_begin_pos_(0), copy_end_pos_(0), tmp_buf_(nullptr), tmp_buf_len_(0),
|
||||
last_escape_check_pos_(0), try_check_tick_(0), param_node_list_(nullptr),
|
||||
tail_param_node_(nullptr), cur_token_type_(INVALID_TOKEN), allocator_(allocator),
|
||||
found_insert_status_(NOT_FOUND_INSERT_TOKEN), values_token_pos_(0),
|
||||
parse_next_token_func_(nullptr), process_idf_func_(nullptr)
|
||||
{
|
||||
@ -2234,6 +2229,12 @@ inline int ObFastParserBase::process_format_token() {
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline int ObFastParserBase::try_check_status()
|
||||
{
|
||||
return ((++try_check_tick_) % CHECK_STATUS_TRY_TIMES == 0) ? THIS_WORKER.check_status() :
|
||||
common::OB_SUCCESS;
|
||||
}
|
||||
|
||||
inline void ObFastParserBase::process_token()
|
||||
{
|
||||
if (NORMAL_TOKEN == cur_token_type_) {
|
||||
@ -3025,15 +3026,12 @@ int ObFastParserMysql::parse_next_token()
|
||||
break;
|
||||
}
|
||||
} // end switch
|
||||
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (is_format_) {
|
||||
if(OB_FAIL(process_format_token())) {
|
||||
LOG_WARN("failed to process foramt token", K(ret));
|
||||
}
|
||||
if (is_format_) {
|
||||
OZ (process_format_token());
|
||||
} else {
|
||||
OX (process_token());
|
||||
}
|
||||
OZ (try_check_status());
|
||||
} // end while
|
||||
if (OB_SUCC(ret)) {
|
||||
// After processing the string, there are still parts that have not been saved, save directly
|
||||
@ -3440,14 +3438,12 @@ int ObFastParserOracle::parse_next_token()
|
||||
}
|
||||
} // end switch
|
||||
last_ch = ch;
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (is_format_) {
|
||||
if (OB_FAIL(process_format_token())) {
|
||||
LOG_WARN("failed to process foramt token", K(ret));
|
||||
}
|
||||
if (is_format_) {
|
||||
OZ (process_format_token());
|
||||
} else {
|
||||
OX (process_token());
|
||||
}
|
||||
OZ (try_check_status());
|
||||
} // end while
|
||||
if (OB_SUCC(ret)) {
|
||||
// After processing the string, there are still parts that have not been saved, save directly
|
||||
|
@ -245,6 +245,7 @@ protected:
|
||||
// this will not affect any correctness issues, and will make the code look better
|
||||
static const int64_t PARSER_NODE_SIZE = sizeof(ParseNode);
|
||||
static const int64_t FIEXED_PARAM_NODE_SIZE = PARSER_NODE_SIZE + sizeof(ParamList);
|
||||
static const int64_t CHECK_STATUS_TRY_TIMES = 512;
|
||||
|
||||
protected:
|
||||
/**
|
||||
@ -644,6 +645,7 @@ protected:
|
||||
bool is_invalid_character(ObRawSql &raw_sql, int64_t pos, int64_t& skip_len);
|
||||
int extend_alloc_sql_buffer();
|
||||
int process_format_token();
|
||||
int try_check_status();
|
||||
protected:
|
||||
enum FoundInsertTokenStatus
|
||||
{
|
||||
@ -665,6 +667,7 @@ protected:
|
||||
char *tmp_buf_;
|
||||
int64_t tmp_buf_len_;
|
||||
int64_t last_escape_check_pos_;
|
||||
uint64_t try_check_tick_;
|
||||
public:
|
||||
ParamList *param_node_list_;
|
||||
ParamList *tail_param_node_;
|
||||
|
24
src/sql/parser/ob_memory_tracker_wrapper.cpp
Normal file
24
src/sql/parser/ob_memory_tracker_wrapper.cpp
Normal file
@ -0,0 +1,24 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "sql/executor/ob_memory_tracker_wrapper.h"
|
||||
#include "sql/executor/ob_memory_tracker.h"
|
||||
|
||||
int check_mem_status()
|
||||
{
|
||||
return oceanbase::lib::ObMemTrackerGuard::check_status();
|
||||
}
|
||||
|
||||
int try_check_mem_status(int64_t check_try_times)
|
||||
{
|
||||
return oceanbase::lib::ObMemTrackerGuard::try_check_status(check_try_times);
|
||||
}
|
29
src/sql/parser/ob_memory_tracker_wrapper.h
Normal file
29
src/sql/parser/ob_memory_tracker_wrapper.h
Normal file
@ -0,0 +1,29 @@
|
||||
/**
|
||||
* 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_MEMORY_TRACKER_WRAPPER_H
|
||||
#define OCEANBASE_SQL_OB_MEMORY_TRACKER_WRAPPER_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int check_mem_status();
|
||||
int try_check_mem_status(int64_t check_try_times);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* OCEANBASE_SQL_OB_MEMORY_TRACKER_WRAPPER_H */
|
@ -20,6 +20,7 @@
|
||||
#include "pl/parser/ob_pl_parser.h"
|
||||
#include "lib/utility/ob_tracepoint.h"
|
||||
#include "lib/json/ob_json_print_utils.h"
|
||||
|
||||
using namespace oceanbase::pl;
|
||||
using namespace oceanbase::sql;
|
||||
using namespace oceanbase::common;
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "sql/parser/parse_node_hash.h"
|
||||
#include "sql/parser/parse_define.h"
|
||||
#include "sql/parser/sql_parser_base.h"
|
||||
#include "sql/executor/ob_memory_tracker_wrapper.h"
|
||||
extern const char *get_type_name(int type);
|
||||
|
||||
#ifdef SQL_PARSER_COMPILATION
|
||||
@ -173,30 +174,40 @@ int deep_copy_parse_node(void *malloc_pool, const ParseNode *src_node, ParseNode
|
||||
return ret;
|
||||
}
|
||||
|
||||
int __attribute__((weak)) check_mem_status() { return OB_PARSER_SUCCESS; }
|
||||
int __attribute__((weak)) try_check_mem_status(int64_t check_try_times) { return OB_PARSER_SUCCESS; }
|
||||
|
||||
ParseNode *new_node(void *malloc_pool, ObItemType type, int num)
|
||||
{
|
||||
int ret = OB_PARSER_SUCCESS;
|
||||
const int64_t check_try_times = 1024;
|
||||
ParseNode *node = NULL;
|
||||
// the mem alloced by parse_malloc has been memset;
|
||||
ParseNode *node = (ParseNode *)parse_malloc(sizeof(ParseNode), malloc_pool);
|
||||
if (OB_UNLIKELY(NULL == node)) {
|
||||
(void)printf("malloc memory failed\n");
|
||||
if (OB_UNLIKELY((OB_PARSER_SUCCESS != (ret = try_check_mem_status(check_try_times))))) {
|
||||
(void)printf("Exceeded memory usage limit\n");
|
||||
} else {
|
||||
node->type_ = type;
|
||||
node->num_child_ = num;
|
||||
node->value_ = INT64_MAX;
|
||||
node->pl_str_off_ = -1;
|
||||
#ifdef SQL_PARSER_COMPILATION
|
||||
node->token_off_ = -1;
|
||||
node->token_len_ = -1;
|
||||
#endif
|
||||
if (num > 0) {
|
||||
int64_t alloc_size = sizeof(ParseNode *) * num ;
|
||||
node->children_ = (ParseNode **)parse_malloc(alloc_size, malloc_pool);
|
||||
if (OB_UNLIKELY(NULL == node->children_)) {
|
||||
parse_free(node);
|
||||
node = NULL;
|
||||
}
|
||||
node = (ParseNode *)parse_malloc(sizeof(ParseNode), malloc_pool);
|
||||
if (OB_UNLIKELY(NULL == node)) {
|
||||
(void)printf("malloc memory failed\n");
|
||||
} else {
|
||||
node->children_ = NULL;
|
||||
node->type_ = type;
|
||||
node->num_child_ = num;
|
||||
node->value_ = INT64_MAX;
|
||||
node->pl_str_off_ = -1;
|
||||
#ifdef SQL_PARSER_COMPILATION
|
||||
node->token_off_ = -1;
|
||||
node->token_len_ = -1;
|
||||
#endif
|
||||
if (num > 0) {
|
||||
int64_t alloc_size = sizeof(ParseNode *) * num ;
|
||||
node->children_ = (ParseNode **)parse_malloc(alloc_size, malloc_pool);
|
||||
if (OB_UNLIKELY(NULL == node->children_)) {
|
||||
parse_free(node);
|
||||
node = NULL;
|
||||
}
|
||||
} else {
|
||||
node->children_ = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
return node;
|
||||
|
@ -390,6 +390,8 @@ extern ParseNode *new_terminal_node(void *malloc_pool, ObItemType type);
|
||||
extern ParseNode *new_list_node(void *malloc_pool, ObItemType node_tag, int capacity, int num, ...);
|
||||
|
||||
extern int obpl_parser_check_stack_overflow();
|
||||
extern int check_mem_status();
|
||||
extern int try_check_mem_status(int64_t check_try_times);
|
||||
|
||||
int get_deep_copy_size(const ParseNode *node, int64_t *size);
|
||||
int deep_copy_parse_node(void *malloc_pool, const ParseNode *src, ParseNode *dst);
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
#include "sql/parser/parser_utility.h"
|
||||
#include "lib/utility/ob_macro_utils.h"
|
||||
#include "sql/executor/ob_memory_tracker.h"
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
|
@ -510,10 +510,10 @@ int ObValuesTableCompression::resolve_params_for_values_clause(ObPlanCacheCtx &p
|
||||
ObExprTypeCtx type_ctx;
|
||||
ObSQLUtils::init_type_ctx(session, type_ctx);
|
||||
if (OB_FAIL(dummy_op.aggregate_result_type_for_merge(new_res_type,
|
||||
&res_types.at(0),
|
||||
res_types.count(),
|
||||
false,
|
||||
type_ctx))) {
|
||||
&res_types.at(0),
|
||||
res_types.count(),
|
||||
false,
|
||||
type_ctx))) {
|
||||
LOG_WARN("failed to aggregate result type for merge", K(ret));
|
||||
}
|
||||
}
|
||||
|
@ -5952,6 +5952,9 @@ int ObAlterTableResolver::alter_column_expr_in_part_expr(
|
||||
column_ref->set_data_type(dst_col_schema.get_data_type());
|
||||
column_ref->set_accuracy(dst_col_schema.get_accuracy());
|
||||
}
|
||||
if (ob_is_enum_or_set_type(column_ref->get_result_type().get_type())) {
|
||||
OZ (column_ref->set_enum_set_values(dst_col_schema.get_extended_type_info()));
|
||||
}
|
||||
} else {
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < part_expr->get_param_count(); ++i) {
|
||||
ObRawExpr *sub_expr = part_expr->get_param_expr(i);
|
||||
|
@ -2169,8 +2169,7 @@ int ObCreateTableResolver::resolve_table_elements_from_select(const ParseNode &p
|
||||
column_meta.set_type(ObLongTextType);
|
||||
}
|
||||
column.set_meta_type(column_meta);
|
||||
if (column.is_enum_or_set()
|
||||
|| column.is_collection()) { // array column
|
||||
if (column.is_collection()) { // array column
|
||||
if (OB_FAIL(column.set_extended_type_info(expr->get_enum_set_values()))) {
|
||||
LOG_WARN("set enum or set info failed", K(ret), K(*expr));
|
||||
}
|
||||
@ -2191,6 +2190,25 @@ int ObCreateTableResolver::resolve_table_elements_from_select(const ParseNode &p
|
||||
column.set_accuracy(expr->get_accuracy());
|
||||
column.set_zero_fill(expr->get_result_flag() & ZEROFILL_FLAG);
|
||||
OZ (adjust_number_decimal_column_accuracy_within_max(column, lib::is_oracle_mode()));
|
||||
if (OB_SUCC(ret) && column.is_enum_or_set()) {
|
||||
if (expr->is_enum_set_with_subschema()) {
|
||||
const ObEnumSetMeta *enum_set_meta = NULL;
|
||||
if (OB_FAIL(ObRawExprUtils::extract_enum_set_meta(expr->get_result_type(),
|
||||
session_info_,
|
||||
enum_set_meta))) {
|
||||
LOG_WARN("fail to extrac enum set mete", K(ret));
|
||||
} else if (OB_FAIL(column.set_extended_type_info(*enum_set_meta->get_str_values()))) {
|
||||
LOG_WARN("set enum or set info failed", K(ret), K(*expr));
|
||||
} else {
|
||||
column.set_collation_type(enum_set_meta->get_collation_type());
|
||||
column.set_data_scale(SCALE_UNKNOWN_YET);
|
||||
}
|
||||
} else {
|
||||
if (OB_FAIL(column.set_extended_type_info(expr->get_enum_set_values()))) {
|
||||
LOG_WARN("set enum or set info failed", K(ret), K(*expr));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) && lib::is_oracle_mode() && expr->get_result_type().is_user_defined_sql_type()) {
|
||||
// udt column is varbinary used for null bitmap
|
||||
column.set_collation_type(CS_TYPE_BINARY);
|
||||
|
@ -1746,6 +1746,7 @@ int ObCreateViewResolver::add_column_infos(const uint64_t tenant_id,
|
||||
} else if (OB_FAIL(fill_column_meta_infos(*expr,
|
||||
table_schema.get_charset_type(),
|
||||
table_schema.get_table_id(),
|
||||
session_info,
|
||||
column,
|
||||
is_from_create_mview))) {
|
||||
LOG_WARN("failed to fill column meta infos", K(ret), K(column));
|
||||
@ -1766,6 +1767,7 @@ int ObCreateViewResolver::add_column_infos(const uint64_t tenant_id,
|
||||
int ObCreateViewResolver::fill_column_meta_infos(const ObRawExpr &expr,
|
||||
const ObCharsetType charset_type,
|
||||
const uint64_t table_id,
|
||||
sql::ObSQLSessionInfo &session_info,
|
||||
ObColumnSchemaV2 &column,
|
||||
bool is_from_create_mview /* =false */)
|
||||
{
|
||||
@ -1790,9 +1792,11 @@ int ObCreateViewResolver::fill_column_meta_infos(const ObRawExpr &expr,
|
||||
column.set_nullable(expr.get_result_type().is_not_null_for_read() ? false : true);
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if ((column.is_enum_or_set() || column.is_collection())
|
||||
} else if (column.is_collection()
|
||||
&& OB_FAIL(column.set_extended_type_info(expr.get_enum_set_values()))) {
|
||||
LOG_WARN("set enum or set info failed", K(ret), K(expr));
|
||||
} else if (OB_FAIL(adjust_enum_set_column_meta_info(expr, session_info, column))) {
|
||||
LOG_WARN("fail to adjust enum set colum meta info", K(ret), K(expr));
|
||||
} else if (OB_FAIL(adjust_string_column_length_within_max(column, lib::is_oracle_mode()))) {
|
||||
LOG_WARN("failed to adjust string column length within max", K(ret), K(expr));
|
||||
} else if (OB_FAIL(adjust_number_decimal_column_accuracy_within_max(column, lib::is_oracle_mode()))) {
|
||||
|
@ -77,6 +77,7 @@ public:
|
||||
static int fill_column_meta_infos(const ObRawExpr &expr,
|
||||
const ObCharsetType charset_type,
|
||||
const uint64_t table_id,
|
||||
sql::ObSQLSessionInfo &session_info,
|
||||
ObColumnSchemaV2 &column,
|
||||
bool is_from_create_mview = false);
|
||||
static int resolve_column_default_value(const sql::ObSelectStmt *select_stmt,
|
||||
|
@ -7470,6 +7470,30 @@ int ObDDLResolver::adjust_number_decimal_column_accuracy_within_max(share::schem
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObDDLResolver::adjust_enum_set_column_meta_info(const ObRawExpr &expr,
|
||||
sql::ObSQLSessionInfo &session_info,
|
||||
share::schema::ObColumnSchemaV2 &column)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (column.is_enum_or_set()) {
|
||||
const ObEnumSetMeta *enum_set_meta = nullptr;
|
||||
if (expr.is_enum_set_with_subschema()) {
|
||||
if (OB_FAIL(ObRawExprUtils::extract_enum_set_meta(expr.get_result_type(),
|
||||
&session_info,
|
||||
enum_set_meta))) {
|
||||
LOG_WARN("fail to extract enum set meta", K(ret), K(expr));
|
||||
} else {
|
||||
column.set_meta_type(enum_set_meta->get_obj_meta());
|
||||
column.set_data_scale(-1);
|
||||
OZ(column.set_extended_type_info(*enum_set_meta->get_str_values()), expr);
|
||||
}
|
||||
} else {
|
||||
OZ(column.set_extended_type_info(expr.get_enum_set_values()), expr);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObDDLResolver::resolve_range_partition_elements(ParseNode *node,
|
||||
const bool is_subpartition,
|
||||
const ObPartitionFuncType part_type,
|
||||
|
@ -377,6 +377,10 @@ public:
|
||||
const bool is_oracle_mode);
|
||||
static int adjust_number_decimal_column_accuracy_within_max(share::schema::ObColumnSchemaV2 &column,
|
||||
const bool is_oracle_mode);
|
||||
static int adjust_enum_set_column_meta_info(const ObRawExpr &expr,
|
||||
sql::ObSQLSessionInfo &session_info,
|
||||
share::schema::ObColumnSchemaV2 &column);
|
||||
|
||||
// { used for enum and set
|
||||
int fill_extended_type_info(
|
||||
const ParseNode &str_list_node,
|
||||
|
@ -260,7 +260,7 @@ int ObDefaultValueUtils::resolve_default_expr(const ColumnItem &column_item, ObR
|
||||
LOG_WARN("params_.session_info_ is null", K(ret));
|
||||
} else {
|
||||
default_func_expr->set_func_name(ObString::make_string(N_DEFAULT));
|
||||
default_func_expr->set_data_type(column_item.get_column_type()->get_type());
|
||||
default_func_expr->set_result_type(*column_item.get_column_type());
|
||||
if (OB_FAIL(build_type_expr(&column_item, c_expr))) {
|
||||
LOG_WARN("fail to build type expr", K(ret));
|
||||
} else if (OB_FAIL(default_func_expr->add_param_expr(c_expr))) {
|
||||
|
@ -930,6 +930,11 @@ bool ObOptParamHint::is_param_val_valid(const OptParamType param_type, const ObO
|
||||
|| 0 == val.get_varchar().case_compare("false"));
|
||||
break;
|
||||
}
|
||||
case ENABLE_ENUM_SET_SUBSCHEMA: {
|
||||
is_valid = val.is_varchar() && (0 == val.get_varchar().case_compare("true")
|
||||
|| 0 == val.get_varchar().case_compare("false"));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
LOG_TRACE("invalid opt param val", K(param_type), K(val));
|
||||
break;
|
||||
|
@ -188,6 +188,7 @@ struct ObOptParamHint
|
||||
DEF(PARTITION_INDEX_DIVE_LIMIT,) \
|
||||
DEF(OB_TABLE_ACCESS_POLICY,) \
|
||||
DEF(PARTITION_WISE_PLAN_ENABLED,) \
|
||||
DEF(ENABLE_ENUM_SET_SUBSCHEMA,) \
|
||||
|
||||
DECLARE_ENUM(OptParamType, opt_param, OPT_PARAM_TYPE_DEF, static);
|
||||
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "common/ob_smart_call.h"
|
||||
#include "sql/engine/expr/ob_expr_regexp_context.h"
|
||||
#include "sql/engine/expr/ob_json_param_type.h"
|
||||
#include "sql/executor/ob_memory_tracker.h"
|
||||
namespace oceanbase
|
||||
{
|
||||
using namespace common;
|
||||
@ -1511,7 +1512,10 @@ int ObSelectResolver::resolve(const ParseNode &parse_tree)
|
||||
int ret = OB_SUCCESS;
|
||||
ObSelectStmt *select_stmt = NULL;
|
||||
bool is_stack_overflow = false;
|
||||
if (NULL == (select_stmt = create_stmt<ObSelectStmt>())) {
|
||||
const int64_t check_try_times = 32;
|
||||
if (OB_UNLIKELY((OB_SUCCESS != (ret = TRY_CHECK_MEM_STATUS(check_try_times))))) {
|
||||
LOG_WARN("Exceeded memory usage limit", K(ret));
|
||||
} else if (NULL == (select_stmt = create_stmt<ObSelectStmt>())) {
|
||||
ret = OB_SQL_RESOLVER_NO_MEMORY;
|
||||
LOG_WARN("failed to create select stmt");
|
||||
} else if (OB_FAIL(check_stack_overflow(is_stack_overflow))) {
|
||||
@ -5468,6 +5472,8 @@ int ObSelectResolver::resolve_column_ref_in_all_namespace(
|
||||
real_ref_expr,
|
||||
exec_param))) {
|
||||
LOG_WARN("failed to get exec param expr", K(ret));
|
||||
} else if (OB_FAIL(exec_param->formalize(session_info_))) {
|
||||
LOG_WARN("fail to formalize exec param", K(ret));
|
||||
} else {
|
||||
/// succeed to resolve the correlated column, do the replace here
|
||||
real_ref_expr = exec_param;
|
||||
|
@ -428,7 +428,7 @@ int ObRawExpr::deduce_type(const ObSQLSessionInfo *session_info,
|
||||
ObRawExprDeduceType expr_deducer(session_info, solidify_session_vars, local_vars, local_var_id);
|
||||
expr_deducer.set_expr_factory(expr_factory_);
|
||||
if (OB_FAIL(expr_deducer.deduce(*this))) {
|
||||
if (session_info->is_varparams_sql_prepare() &&
|
||||
if (OB_NOT_NULL(session_info) && session_info->is_varparams_sql_prepare() &&
|
||||
OB_ERR_INVALID_COLUMN_NUM != ret &&
|
||||
OB_ERR_TOO_MANY_VALUES != ret) {
|
||||
ret = OB_SUCCESS;
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include "sql/engine/expr/ob_expr_join_filter.h"
|
||||
#include "sql/engine/expr/ob_expr_calc_partition_id.h"
|
||||
#include "sql/resolver/dml/ob_raw_expr_sets.h"
|
||||
#include "sql/executor/ob_memory_tracker.h"
|
||||
namespace oceanbase
|
||||
{
|
||||
namespace share
|
||||
@ -4961,11 +4962,13 @@ private:
|
||||
class ObRawExprFactory
|
||||
{
|
||||
public:
|
||||
const static uint64_t CHECK_STATUS_TRY_TIMES = 1024;
|
||||
explicit ObRawExprFactory(common::ObIAllocator &alloc)
|
||||
: allocator_(alloc),
|
||||
expr_store_(alloc),
|
||||
is_called_sql_(true),
|
||||
proxy_(nullptr)
|
||||
proxy_(nullptr),
|
||||
try_check_tick_(0)
|
||||
{
|
||||
}
|
||||
ObRawExprFactory(ObRawExprFactory &expr_factory) : allocator_(expr_factory.allocator_),
|
||||
@ -5030,10 +5033,23 @@ public:
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline int try_check_status()
|
||||
{
|
||||
return ((++try_check_tick_) % CHECK_STATUS_TRY_TIMES == 0)
|
||||
? CHECK_MEM_STATUS()
|
||||
: common::OB_SUCCESS;
|
||||
}
|
||||
|
||||
template <typename ExprType>
|
||||
int create_raw_expr(ObItemType expr_type, ExprType *&raw_expr)
|
||||
{
|
||||
return create_raw_expr_inner(expr_type, raw_expr);
|
||||
int ret = common::OB_SUCCESS;
|
||||
if (OB_FAIL(try_check_status())) {
|
||||
SQL_RESV_LOG(WARN, "Exceeded memory usage limit", K(ret));
|
||||
} else if (OB_FAIL(create_raw_expr_inner(expr_type, raw_expr))) {
|
||||
SQL_RESV_LOG(WARN, "failed to create raw expr", K(ret));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@ -5062,6 +5078,7 @@ private:
|
||||
bool is_called_sql_;
|
||||
//if not null, raw_expr is create by pl resolver
|
||||
ObRawExprFactory *proxy_;
|
||||
int64_t try_check_tick_;
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(ObRawExprFactory);
|
||||
};
|
||||
|
@ -60,6 +60,9 @@ int ObRawExprDeduceType::visit(ObConstRawExpr &expr)
|
||||
K(expr.get_expr_obj_meta().get_type()),
|
||||
K(ret));
|
||||
}
|
||||
if (expr.is_enum_set_with_subschema()) {
|
||||
expr.reset_enum_set_meta_state();
|
||||
}
|
||||
expr.set_meta_type(expr.get_expr_obj_meta());
|
||||
//expr.set_meta_type(expr.get_value().get_meta());
|
||||
expr.set_param(expr.get_value());
|
||||
@ -72,7 +75,9 @@ int ObRawExprDeduceType::visit(ObConstRawExpr &expr)
|
||||
}
|
||||
//add local vars to expr
|
||||
if (OB_SUCC(ret)) {
|
||||
if (solidify_session_vars_) {
|
||||
if (OB_FAIL(build_subschema_for_enum_set_type(expr))) {
|
||||
LOG_WARN("fail to build subschema for enum set type", K(ret));
|
||||
} else if (solidify_session_vars_) {
|
||||
if (OB_FAIL(expr.set_local_session_vars(NULL, my_session_, local_vars_id_))) {
|
||||
LOG_WARN("fail to set session vars", K(ret), K(expr));
|
||||
}
|
||||
@ -202,6 +207,8 @@ int ObRawExprDeduceType::visit(ObColumnRefRawExpr &expr)
|
||||
LOG_WARN("failed to construct collection attr expr", K(ret));
|
||||
}
|
||||
}
|
||||
} else if (OB_FAIL(build_subschema_for_enum_set_type(expr))) {
|
||||
LOG_WARN("fail to build subschema for enum set type", K(ret), K(expr));
|
||||
}
|
||||
|
||||
if (OB_SUCC(ret)) {
|
||||
@ -535,7 +542,7 @@ int ObRawExprDeduceType::calc_result_type(ObNonTerminalRawExpr &expr,
|
||||
// casted into number. However, this requirements are not remembered in the input_types
|
||||
// for the avg() expression but as the calc_type for the input expression itself. This
|
||||
// demands that we set the calculation type here.
|
||||
for (int64_t i = 0; i < types.count(); ++i) {
|
||||
for (int64_t i = 0; i < types.count() && OB_SUCC(ret); ++i) {
|
||||
types.at(i).set_calc_meta(types.at(i));
|
||||
if (lib::is_mysql_mode() && types.at(i).is_double()) {
|
||||
const ObPrecision p = types.at(i).get_precision();
|
||||
@ -545,6 +552,20 @@ int ObRawExprDeduceType::calc_result_type(ObNonTerminalRawExpr &expr,
|
||||
(s >= 0 && s <= OB_MAX_DOUBLE_FLOAT_SCALE && p >= s)) {
|
||||
types.at(i).set_calc_accuracy(types.at(i).get_accuracy());
|
||||
}
|
||||
} else if (ob_is_enumset_tc(types.at(i).get_type())) {
|
||||
ObObjMeta param_obj_meta;
|
||||
if (OB_FAIL(ObRawExprUtils::extract_enum_set_collation(types.at(i),
|
||||
my_session_,
|
||||
param_obj_meta))) {
|
||||
LOG_WARN("fail to extract enum set cs type", K(ret));
|
||||
} else {
|
||||
// restore enum/set collation there, the expr type deduce is not aware of enum/set
|
||||
// subschema meta.
|
||||
types.at(i).set_collation(param_obj_meta);
|
||||
types.at(i).set_calc_collation_type(param_obj_meta.get_collation_type());
|
||||
types.at(i).set_calc_collation_level(param_obj_meta.get_collation_level());
|
||||
types.at(i).reset_enum_set_meta_state();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ignore_scale_adjust_for_decimal_int(expr.get_expr_type())) {
|
||||
@ -602,6 +623,7 @@ int ObRawExprDeduceType::calc_result_type(ObNonTerminalRawExpr &expr,
|
||||
break;
|
||||
} // end switch
|
||||
}
|
||||
|
||||
if (OB_NOT_IMPLEMENT == ret) {
|
||||
if (OB_FAIL(calc_result_type_with_const_arg(expr, types, type_ctx, op, result_type, row_dimension))) {
|
||||
if (OB_NOT_IMPLEMENT == ret) {
|
||||
@ -1455,6 +1477,16 @@ int ObRawExprDeduceType::set_json_agg_result_type(ObAggFunRawExpr &expr, ObExprR
|
||||
|
||||
switch (expr.get_expr_type()) {
|
||||
case T_FUN_JSON_ARRAYAGG: {
|
||||
ObRawExpr *param_expr1 = NULL;
|
||||
if (OB_UNLIKELY(expr.get_real_param_count() != 1) ||
|
||||
OB_ISNULL(param_expr1 = expr.get_param_expr(0))) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("get unexpected error", K(ret), K(expr.get_param_count()),
|
||||
K(expr.get_real_param_count()), K(expr));
|
||||
} else {
|
||||
ObExprResType& expr_type1 = const_cast<ObExprResType&>(param_expr1->get_result_type());
|
||||
need_add_cast = expr_type1.is_enum_set_with_subschema();
|
||||
}
|
||||
result_type.set_json();
|
||||
result_type.set_length((ObAccuracy::DDL_DEFAULT_ACCURACY[ObJsonType]).get_length());
|
||||
expr.set_result_type(result_type);
|
||||
@ -1856,10 +1888,14 @@ int ObRawExprDeduceType::visit(ObAggFunRawExpr &expr)
|
||||
}
|
||||
} else if (ob_is_json(obj_type) || ob_is_string_type(obj_type) ||
|
||||
ob_is_enumset_tc(obj_type)) {
|
||||
// string to double no need scale information
|
||||
result_type.set_double();
|
||||
// todo jiuren
|
||||
// todo blob and text@hanhui
|
||||
if (result_type.get_scale() >= 0) {
|
||||
if (ob_is_enumset_tc(obj_type)) {
|
||||
result_type.set_scale(SCALE_UNKNOWN_YET);
|
||||
result_type.set_precision(PRECISION_UNKNOWN_YET);
|
||||
} else if (result_type.get_scale() >= 0) {
|
||||
scale_increment_recover = result_type.get_scale();
|
||||
result_type.set_scale(static_cast<ObScale>(result_type.get_scale() + scale_increment));
|
||||
}
|
||||
@ -2116,7 +2152,18 @@ int ObRawExprDeduceType::visit(ObAggFunRawExpr &expr)
|
||||
const_cast<ObExprResType&>(param_expr->get_result_type()).set_calc_type(ObIntType);
|
||||
}
|
||||
} else if (i == 1) {
|
||||
result_type.set_collation_type(param_expr->get_result_type().get_collation_type());
|
||||
if (param_expr->is_enum_set_with_subschema()) {
|
||||
ObObjMeta org_obj_meta;
|
||||
if (OB_FAIL(ObRawExprUtils::extract_enum_set_collation(param_expr->get_result_type(),
|
||||
my_session_,
|
||||
org_obj_meta))) {
|
||||
LOG_WARN("fail to extract enum set cs type", K(ret));
|
||||
} else {
|
||||
result_type.set_collation_type(org_obj_meta.get_collation_type());
|
||||
}
|
||||
} else {
|
||||
result_type.set_collation_type(param_expr->get_result_type().get_collation_type());
|
||||
}
|
||||
} else {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("get unexpected NULL", K(expr.get_param_count()), K(ret));
|
||||
@ -2162,7 +2209,18 @@ int ObRawExprDeduceType::visit(ObAggFunRawExpr &expr)
|
||||
result_type.set_blob();
|
||||
result_type.set_length(OB_MAX_LONGTEXT_LENGTH);
|
||||
result_type.set_collation_level(CS_LEVEL_IMPLICIT);
|
||||
result_type.set_collation_type(param_expr1->get_result_type().get_collation_type());
|
||||
if (param_expr1->is_enum_set_with_subschema()) {
|
||||
ObObjMeta org_obj_meta;
|
||||
if (OB_FAIL(ObRawExprUtils::extract_enum_set_collation(param_expr1->get_result_type(),
|
||||
my_session_,
|
||||
org_obj_meta))) {
|
||||
LOG_WARN("fail to extract enum set cs type", K(ret));
|
||||
} else {
|
||||
result_type.set_collation_type(org_obj_meta.get_collation_type());
|
||||
}
|
||||
} else {
|
||||
result_type.set_collation_type(param_expr1->get_result_type().get_collation_type());
|
||||
}
|
||||
if (lib::is_oracle_mode()) {
|
||||
const_cast<ObExprResType&>(param_expr2->get_result_type()).set_calc_type(ObNumberType);
|
||||
} else {
|
||||
@ -2677,6 +2735,19 @@ int ObRawExprDeduceType::visit(ObSysFunRawExpr &expr)
|
||||
} else {/*do nothing*/}
|
||||
}
|
||||
}
|
||||
// There are some exprs such as nullif, column convert, etc. that require build subschema for
|
||||
// enum or set types
|
||||
if (OB_SUCC(ret) && ob_is_enumset_tc(expr.get_data_type())) {
|
||||
const ObItemType expr_type = expr.get_expr_type();
|
||||
if (T_FUN_SYS_REMOVE_CONST == expr_type ||
|
||||
T_FUN_SYS_CAST == expr_type ||
|
||||
T_FUN_SYS_WRAPPER_INNER == expr_type ||
|
||||
T_FUN_SYS_DEFAULT == expr_type) {
|
||||
// skip some inner added expr, their result type meta should be determined by the args.
|
||||
} else if (OB_FAIL(build_subschema_for_enum_set_type(expr))) {
|
||||
LOG_WARN("fail to build subschema for enum set type", K(ret), K(expr));
|
||||
}
|
||||
}
|
||||
CK(OB_NOT_NULL(my_session_));
|
||||
if (OB_SUCC(ret)) {
|
||||
// Casting from bit to binary depends on this flag to be compatible with MySQL,
|
||||
@ -3526,8 +3597,12 @@ int ObRawExprDeduceType::set_agg_min_max_result_type(ObAggFunRawExpr &expr,
|
||||
const ObExprResType& res_type = child_expr->get_result_type();
|
||||
result_type.set_varchar();
|
||||
result_type.set_length(res_type.get_length());
|
||||
result_type.set_collation_type(res_type.get_collation_type());
|
||||
result_type.set_collation_level(CS_LEVEL_IMPLICIT);
|
||||
ObObjMeta obj_meta;
|
||||
if (OB_FAIL(ObRawExprUtils::extract_enum_set_collation(res_type, my_session_, obj_meta))) {
|
||||
LOG_WARN("fail to extract enum set cs type", K(ret));
|
||||
} else {
|
||||
result_type.set_collation(obj_meta);
|
||||
}
|
||||
expr.set_result_type(result_type);
|
||||
} else {
|
||||
// keep same with default path
|
||||
@ -3883,6 +3958,27 @@ int ObRawExprDeduceType::add_implicit_cast(ObAggFunRawExpr &parent,
|
||||
if (skip_cast_expr(parent, i)) {
|
||||
// do nothing
|
||||
//兼容oracle行为,regr_sxx和regr_syy只需在计算的参数加cast,regr_sxy行为和regr_syy一致,比较诡异,暂时兼容
|
||||
} else if ((parent.get_expr_type() == T_FUN_JSON_OBJECTAGG ||
|
||||
parent.get_expr_type() == T_FUN_JSON_ARRAYAGG) &&
|
||||
child_ptr->get_result_type().is_enum_set_with_subschema()) {
|
||||
ObExprResType result_type(alloc_);
|
||||
result_type.set_varchar();
|
||||
result_type.set_length(child_ptr->get_result_type().get_length());
|
||||
ObObjMeta obj_meta;
|
||||
if (OB_FAIL(ObRawExprUtils::extract_enum_set_collation(child_ptr->get_result_type(),
|
||||
my_session_,
|
||||
obj_meta))) {
|
||||
LOG_WARN("fail to extract enum set cs type", K(ret));
|
||||
} else {
|
||||
result_type.set_collation(obj_meta);
|
||||
}
|
||||
result_type.set_calc_meta(result_type.get_obj_meta());
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_FAIL(try_add_cast_expr(parent, i, result_type, cast_mode))) {
|
||||
LOG_WARN("try_add_cast_expr failed", K(ret));
|
||||
} else {
|
||||
LOG_DEBUG("add_implicit_cast for ObAggFunRawExpr", K(i), K(res_type), KPC(child_ptr));
|
||||
}
|
||||
} else if ((parent.get_expr_type() == T_FUN_REGR_SXX && i == 0) ||
|
||||
(parent.get_expr_type() == T_FUN_REGR_SYY && i == 1) ||
|
||||
(parent.get_expr_type() == T_FUN_REGR_SXY && i == 1) ||
|
||||
@ -4014,6 +4110,10 @@ int ObRawExprDeduceType::try_add_cast_expr_above_for_deduce_type(ObRawExpr &expr
|
||||
|| ob_is_decimal_int_tc(dst_type.get_calc_meta().get_type()))
|
||||
&& dst_type.get_calc_scale() == -1) {
|
||||
cast_dst_type.set_accuracy(child_res_type.get_accuracy());
|
||||
if (child_res_type.is_enum_or_set()) {
|
||||
cast_dst_type.set_precision(PRECISION_UNKNOWN_YET);
|
||||
cast_dst_type.set_scale(SCALE_UNKNOWN_YET);
|
||||
}
|
||||
} else if (lib::is_oracle_mode()
|
||||
&& ob_is_decimal_int_tc(dst_type.get_calc_meta().get_type())
|
||||
&& dst_type.get_calc_scale() == SCALE_UNKNOWN_YET) {
|
||||
@ -4250,5 +4350,42 @@ int ObRawExprDeduceType::try_replace_cast_with_questionmark_ora(ObRawExpr &paren
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObRawExprDeduceType::build_subschema_for_enum_set_type(ObRawExpr &expr)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObSQLSessionInfo *session = NULL;
|
||||
ObExecContext *exec_ctx = NULL;
|
||||
uint16_t subschema_id = 0;
|
||||
if (!expr.get_result_type().is_enum_or_set()) {
|
||||
// Non-enum or set types do not need to build subschema
|
||||
} else if (expr.skip_build_subschema_for_enumset() || !expr.is_called_in_sql()) {
|
||||
// skiping pl scenario, because compilation and calling do not share the same plan ctx
|
||||
// the subschema has been built, do nothing
|
||||
} else if (OB_ISNULL(session = const_cast<ObSQLSessionInfo *>(my_session_))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("session can not be null", K(ret));
|
||||
} else if (OB_ISNULL(exec_ctx = session->get_cur_exec_ctx()) ||
|
||||
OB_ISNULL(exec_ctx->get_physical_plan_ctx()) ||
|
||||
OB_NOT_NULL(exec_ctx->get_physical_plan_ctx()->get_phy_plan())) {
|
||||
// exec_ctx may be null in ddl generated column scenarios, and it all use column_convert,
|
||||
// so the subschema meta build for this scenario is skipped
|
||||
LOG_INFO("exec ctx is null", K(ret), K(*session));
|
||||
} else if (!exec_ctx->support_enum_set_type_subschema(*session)) {
|
||||
} else if (OB_UNLIKELY(expr.get_enum_set_values().empty())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("str values for enum set expr is empty", K(ret), K(expr.get_enum_set_values()));
|
||||
} else if (OB_FAIL(exec_ctx->get_subschema_id_by_type_info(
|
||||
expr.get_result_type().get_obj_meta(),
|
||||
expr.get_enum_set_values(),
|
||||
subschema_id))) {
|
||||
LOG_WARN("failed to get subschema id by udt id", K(ret));
|
||||
} else {
|
||||
expr.set_subschema_id(subschema_id);
|
||||
expr.mark_enum_set_with_subschema();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
|
@ -155,6 +155,7 @@ private:
|
||||
int try_replace_casts_with_questionmarks_ora(ObRawExpr *row_expr);
|
||||
|
||||
int try_replace_cast_with_questionmark_ora(ObRawExpr &parent, ObRawExpr *cast_expr, int param_idx);
|
||||
int build_subschema_for_enum_set_type(ObRawExpr &expr);
|
||||
private:
|
||||
const sql::ObSQLSessionInfo *my_session_;
|
||||
common::ObArenaAllocator alloc_;
|
||||
|
@ -42,6 +42,8 @@
|
||||
#include "sql/resolver/dml/ob_dml_resolver.h"
|
||||
#include "sql/resolver/dml/ob_select_resolver.h"
|
||||
#include "sql/resolver/expr/ob_raw_expr_deduce_type.h"
|
||||
#include "sql/resolver/dml/ob_inlist_resolver.h"
|
||||
#include "lib/enumset/ob_enum_set_meta.h"
|
||||
|
||||
namespace oceanbase
|
||||
{
|
||||
@ -1093,7 +1095,7 @@ int ObRawExprUtils::resolve_udf_param_exprs(ObResolverParams ¶ms,
|
||||
OX (mode = static_cast<pl::ObPLRoutineParamMode>(iparam->get_mode()));
|
||||
if (OB_SUCC(ret) && lib::is_mysql_mode()) {
|
||||
bool need_wrap = false;
|
||||
OZ (ObRawExprUtils::need_wrap_to_string(udf_raw_expr->get_param_expr(i)->get_result_type().get_type(),
|
||||
OZ (ObRawExprUtils::need_wrap_to_string(udf_raw_expr->get_param_expr(i)->get_result_type(),
|
||||
iparam->get_pl_data_type().get_obj_type(),
|
||||
true,
|
||||
need_wrap));
|
||||
@ -4374,26 +4376,30 @@ int ObRawExprUtils::create_cast_expr(ObRawExprFactory &expr_factory,
|
||||
need_extra_cast_for_dst_type);
|
||||
|
||||
// extra cast expr: cast non-utf8 to utf8
|
||||
ObExprResType extra_type;
|
||||
ObSysFunRawExpr *extra_cast = NULL;
|
||||
if (need_extra_cast_for_src_type) {
|
||||
ObExprResType src_type_utf8;
|
||||
OZ(setup_extra_cast_utf8_type(src_type, src_type_utf8));
|
||||
OZ(create_real_cast_expr(expr_factory, src_expr, src_type_utf8, extra_cast, session));
|
||||
OZ(setup_extra_cast_utf8_type(src_type, extra_type));
|
||||
OZ(create_real_cast_expr(expr_factory, src_expr, extra_type, extra_cast, session));
|
||||
OZ(create_real_cast_expr(expr_factory, extra_cast, dst_type, func_expr, session));
|
||||
} else if (need_extra_cast_for_dst_type) {
|
||||
ObExprResType dst_type_utf8;
|
||||
OZ(setup_extra_cast_utf8_type(dst_type, dst_type_utf8));
|
||||
OZ(create_real_cast_expr(expr_factory, src_expr, dst_type_utf8, extra_cast, session));
|
||||
OZ(setup_extra_cast_utf8_type(dst_type, extra_type));
|
||||
OZ(create_real_cast_expr(expr_factory, src_expr, extra_type, extra_cast, session));
|
||||
OZ(create_real_cast_expr(expr_factory, extra_cast, dst_type, func_expr, session));
|
||||
} else if (src_type.get_type() == ObExtendType
|
||||
&& src_type.get_udt_id() == T_OBJ_XML
|
||||
&& dst_type.is_character_type()
|
||||
&& src_expr->is_called_in_sql()) {
|
||||
// pl xmltype -> sql xmltype -> char type is supported only in sql scenario
|
||||
ObExprResType sql_udt_type;
|
||||
sql_udt_type.set_sql_udt(ObXMLSqlType); // set subschema id
|
||||
sql_udt_type.set_udt_id(T_OBJ_XML);
|
||||
OZ(create_real_cast_expr(expr_factory, src_expr, sql_udt_type, extra_cast, session));
|
||||
extra_type.set_sql_udt(ObXMLSqlType); // set subschema id
|
||||
extra_type.set_udt_id(T_OBJ_XML);
|
||||
OZ(create_real_cast_expr(expr_factory, src_expr, extra_type, extra_cast, session));
|
||||
OZ(create_real_cast_expr(expr_factory, extra_cast, dst_type, func_expr, session));
|
||||
} else if (OB_FAIL(need_extra_cast_for_enumset(src_type, dst_type, session, extra_type,
|
||||
need_extra_cast_for_src_type))) {
|
||||
LOG_WARN("fail to check need extra for enumset", K(ret), K(src_type), K(dst_type));
|
||||
} else if (need_extra_cast_for_src_type) {
|
||||
OZ(create_real_cast_expr(expr_factory, src_expr, extra_type, extra_cast, session));
|
||||
OZ(create_real_cast_expr(expr_factory, extra_cast, dst_type, func_expr, session));
|
||||
} else {
|
||||
OZ(create_real_cast_expr(expr_factory, src_expr, dst_type, func_expr, session));
|
||||
@ -4443,7 +4449,8 @@ void ObRawExprUtils::need_extra_cast(const ObExprResType &src_type,
|
||||
need_extra_cast_for_src_type = true;
|
||||
}
|
||||
} else if (nonstr_to_str) {
|
||||
if (CHARSET_BINARY != dst_cs && ObCharset::get_default_charset() != dst_cs && !src_type.is_bit()) {
|
||||
if (CHARSET_BINARY != dst_cs && ObCharset::get_default_charset() != dst_cs && !src_type.is_bit()
|
||||
&& !src_type.is_enum_set_with_subschema()) {
|
||||
need_extra_cast_for_dst_type = true;
|
||||
}
|
||||
}
|
||||
@ -4940,7 +4947,7 @@ int ObRawExprUtils::create_type_to_str_expr(ObRawExprFactory &expr_factory,
|
||||
LOG_ERROR("allocate expr operator failed", K(ret));
|
||||
} else {
|
||||
out_expr->set_func_name(ObString::make_string(func_name));
|
||||
if (ob_is_large_text(dst_type)) {
|
||||
if (ob_is_large_text(dst_type) || dst_type == ObCharType) {
|
||||
out_expr->set_extra(static_cast<uint64_t>(dst_type));
|
||||
} else {
|
||||
out_expr->set_extra(0);
|
||||
@ -4950,8 +4957,13 @@ int ObRawExprUtils::create_type_to_str_expr(ObRawExprFactory &expr_factory,
|
||||
ObConstRawExpr *col_accuracy_expr = NULL;
|
||||
if (OB_SUCC(ret)) {
|
||||
ObString str_col_accuracy;
|
||||
if (OB_FAIL(build_const_string_expr(expr_factory, ObVarcharType, str_col_accuracy,
|
||||
src_expr->get_collation_type(), col_accuracy_expr))) {
|
||||
ObObjMeta obj_meta;
|
||||
if (OB_FAIL(ObRawExprUtils::extract_enum_set_collation(src_expr->get_result_type(),
|
||||
session_info,
|
||||
obj_meta))) {
|
||||
LOG_WARN("fail to extract enum set cs type", K(ret));
|
||||
} else if (OB_FAIL(build_const_string_expr(expr_factory, ObVarcharType, str_col_accuracy,
|
||||
obj_meta.get_collation_type(), col_accuracy_expr))) {
|
||||
LOG_WARN("fail to build type expr", K(ret));
|
||||
} else if (OB_ISNULL(col_accuracy_expr)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
@ -4960,6 +4972,7 @@ int ObRawExprUtils::create_type_to_str_expr(ObRawExprFactory &expr_factory,
|
||||
col_accuracy_expr->set_collation_type(src_expr->get_collation_type());
|
||||
col_accuracy_expr->set_collation_level(src_expr->get_collation_level());
|
||||
col_accuracy_expr->set_accuracy(src_expr->get_accuracy());
|
||||
col_accuracy_expr->set_scale(SCALE_UNKNOWN_YET);
|
||||
}
|
||||
}
|
||||
|
||||
@ -5329,7 +5342,19 @@ int ObRawExprUtils::build_column_conv_expr(ObRawExprFactory &expr_factory,
|
||||
}
|
||||
CK(session_info);
|
||||
if (OB_SUCC(ret)) {
|
||||
if (col_ref.is_fulltext_column() ||
|
||||
ObObjMeta obj_meta = col_ref.get_result_meta();
|
||||
ObAccuracy accuracy = col_ref.get_accuracy();
|
||||
if (col_ref.is_enum_set_with_subschema()) {
|
||||
if (OB_FAIL(ObRawExprUtils::extract_enum_set_collation(col_ref.get_result_type(),
|
||||
session_info,
|
||||
obj_meta))) {
|
||||
LOG_WARN("fail to extract enum set cs type", K(ret));
|
||||
} else {
|
||||
accuracy.set_scale(SCALE_UNKNOWN_YET);
|
||||
}
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (col_ref.is_fulltext_column() ||
|
||||
col_ref.is_spatial_generated_column() ||
|
||||
col_ref.is_multivalue_generated_column() ||
|
||||
col_ref.is_multivalue_generated_array_column() ||
|
||||
@ -5339,9 +5364,9 @@ int ObRawExprUtils::build_column_conv_expr(ObRawExprFactory &expr_factory,
|
||||
} else if (OB_FAIL(build_column_conv_expr(session_info,
|
||||
expr_factory,
|
||||
col_ref.get_data_type(),
|
||||
col_ref.get_collation_type(),
|
||||
obj_meta.get_collation_type(),
|
||||
// accuracy used as udt id for udt columns
|
||||
col_ref.get_accuracy().get_accuracy(),
|
||||
accuracy.get_accuracy(),
|
||||
!col_ref.is_not_null_for_write(),
|
||||
&column_conv_info,
|
||||
&col_ref.get_enum_set_values(),
|
||||
@ -7145,6 +7170,8 @@ int ObRawExprUtils::init_column_expr(const ObColumnSchemaV2 &column_schema, ObCo
|
||||
if (OB_SUCC(ret) && (column_schema.is_enum_or_set() || column_schema.is_collection())) {
|
||||
if (OB_FAIL(column_expr.set_enum_set_values(column_schema.get_extended_type_info()))) {
|
||||
LOG_WARN("failed to set enum set values", K(ret));
|
||||
} else {
|
||||
column_expr.reset_enum_set_meta_state();
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) && column_schema.is_xmltype()) {
|
||||
@ -7261,11 +7288,14 @@ int ObRawExprUtils::extract_int_value(const ObRawExpr *expr, int64_t &val)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObRawExprUtils::need_wrap_to_string(ObObjType param_type, ObObjType calc_type, const bool is_same_type_need, bool &need_wrap)
|
||||
int ObRawExprUtils::need_wrap_to_string(const ObExprResType &src_res_type,
|
||||
ObObjType calc_type,
|
||||
const bool is_same_type_need, bool &need_wrap)
|
||||
{
|
||||
//TODO(yaoying.yyy):这个函数需要在case中覆盖 且ObExtendType 和ObUnknownType
|
||||
int ret = OB_SUCCESS;
|
||||
need_wrap = false;
|
||||
ObObjType param_type = src_res_type.get_type();
|
||||
if (!ob_is_enumset_tc(param_type)) {
|
||||
//输入参数不是enum 类型 则不需要转换
|
||||
} else if (param_type == calc_type && (!is_same_type_need)) {
|
||||
@ -7319,7 +7349,8 @@ int ObRawExprUtils::need_wrap_to_string(ObObjType param_type, ObObjType calc_typ
|
||||
case ObIntervalYMType:
|
||||
case ObNVarchar2Type:
|
||||
case ObNCharType: {
|
||||
need_wrap = true;
|
||||
// use the generic cast expr to process the enumset cast.
|
||||
need_wrap = !src_res_type.is_enum_set_with_subschema();
|
||||
break;
|
||||
}
|
||||
default : {
|
||||
@ -7333,6 +7364,48 @@ int ObRawExprUtils::need_wrap_to_string(ObObjType param_type, ObObjType calc_typ
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObRawExprUtils::extract_enum_set_collation(const ObExprResType &src_res_type,
|
||||
const sql::ObSQLSessionInfo *session,
|
||||
ObObjMeta &obj_meta)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
obj_meta = src_res_type.get_obj_meta();
|
||||
const ObEnumSetMeta *meta = NULL;
|
||||
if (OB_FAIL(extract_enum_set_meta(src_res_type, session, meta))) {
|
||||
LOG_WARN("fail to extrac enum set meta", K(ret));
|
||||
} else if (OB_NOT_NULL(meta)) {
|
||||
obj_meta = meta->get_obj_meta();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObRawExprUtils::extract_enum_set_meta(const ObExprResType &src_res_type,
|
||||
const sql::ObSQLSessionInfo *session,
|
||||
const ObEnumSetMeta *&meta)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
meta = NULL;
|
||||
if (src_res_type.is_enum_set_with_subschema()) {
|
||||
if (OB_ISNULL(session) || OB_ISNULL(session->get_cur_exec_ctx())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("session is null", K(ret), KP(session), KP(session->get_cur_exec_ctx()));
|
||||
} else {
|
||||
const ObEnumSetMeta *enum_set_meta = NULL;
|
||||
const uint16_t subschema_id = src_res_type.get_subschema_id();
|
||||
if (OB_FAIL(session->get_cur_exec_ctx()->get_enumset_meta_by_subschema_id(subschema_id,
|
||||
enum_set_meta))) {
|
||||
LOG_WARN("fail to get enum set meta", K(ret), K(subschema_id));
|
||||
} else if (OB_ISNULL(enum_set_meta)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("fail to get meta", K(ret), K(subschema_id));
|
||||
} else {
|
||||
meta = enum_set_meta;
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObRawExprUtils::extract_param_idxs(const ObRawExpr *expr, ObIArray<int64_t> ¶m_idxs)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
@ -8299,7 +8372,10 @@ int ObRawExprUtils::check_need_cast_expr(const ObExprResType &src_type,
|
||||
ignore_dup_cast_error = true; // scale adjust cast need ignore duplicate cast error.
|
||||
}
|
||||
} else if (ob_is_enumset_tc(out_type)) {
|
||||
//no need add cast, will add column_conv later
|
||||
// no need add cast, will add column_conv later
|
||||
// currently, only the column convert expr's dst type will be enum/set. there is enough meta
|
||||
// information in column_conv to do type conversion, so we keep no cast in both the old and
|
||||
// new behaviors here.
|
||||
need_cast = false;
|
||||
} else if ((ob_is_xml_sql_type(in_type, src_type.get_subschema_id()) || ob_is_xml_pl_type(in_type, src_type.get_udt_id())) &&
|
||||
ob_is_blob(out_type, out_cs_type)) {
|
||||
@ -8307,7 +8383,7 @@ int ObRawExprUtils::check_need_cast_expr(const ObExprResType &src_type,
|
||||
// there are cases cannot skip cast expr, and xmltype cast to clob is not support and cast func will check:
|
||||
// case: select xmlserialize(content xmltype_var as clob) || xmltype_var from t;
|
||||
need_cast = false;
|
||||
} else if (OB_FAIL(ObRawExprUtils::need_wrap_to_string(in_type, out_type,
|
||||
} else if (OB_FAIL(ObRawExprUtils::need_wrap_to_string(src_type, out_type,
|
||||
is_same_need, need_wrap))) {
|
||||
LOG_WARN("failed to check_need_wrap_to_string", K(ret));
|
||||
} else if (need_wrap) {
|
||||
@ -9977,5 +10053,31 @@ int ObRawExprUtils::copy_and_formalize(const ObIArray<ObRawExpr *> &exprs,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObRawExprUtils::need_extra_cast_for_enumset(const ObExprResType &src_type,
|
||||
const ObExprResType &dst_type,
|
||||
const ObSQLSessionInfo *session_info,
|
||||
ObExprResType &extra_type,
|
||||
bool &need_extra_cast)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
need_extra_cast = false;
|
||||
if (OB_ISNULL(session_info)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("session is null", K(ret));
|
||||
} else if (src_type.is_enum_set_with_subschema() &&
|
||||
dst_type.is_string_or_lob_locator_type()) {
|
||||
ObObjMeta param_obj_meta;
|
||||
if (OB_FAIL(ObRawExprUtils::extract_enum_set_collation(src_type, session_info, param_obj_meta))) {
|
||||
LOG_WARN("fail to extract enum set cs type", K(ret));
|
||||
} else if (param_obj_meta.get_collation_type() != dst_type.get_collation_type()) {
|
||||
need_extra_cast = true;
|
||||
extra_type = dst_type;
|
||||
extra_type.set_collation(param_obj_meta);
|
||||
extra_type.set_length(src_type.get_length());
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -888,8 +888,14 @@ public:
|
||||
//extract from const value
|
||||
static int extract_int_value(const ObRawExpr *expr, int64_t &val);
|
||||
//used for enum set type
|
||||
static int need_wrap_to_string(common::ObObjType param_type, common::ObObjType calc_type,
|
||||
static int need_wrap_to_string(const ObExprResType &src_res_type, common::ObObjType calc_type,
|
||||
const bool is_same_type_need, bool &need_wrap);
|
||||
static int extract_enum_set_collation(const ObExprResType &src_res_type,
|
||||
const sql::ObSQLSessionInfo *session,
|
||||
ObObjMeta &obj_meta);
|
||||
static int extract_enum_set_meta(const ObExprResType &src_res_type,
|
||||
const sql::ObSQLSessionInfo *session,
|
||||
const ObEnumSetMeta *&meta);
|
||||
static bool contain_id(const common::ObIArray<uint64_t> &ids, const uint64_t target);
|
||||
static int clear_exprs_flag(const common::ObIArray<ObRawExpr*> &exprs, ObExprInfoFlag flag);
|
||||
|
||||
@ -1283,6 +1289,12 @@ public:
|
||||
ObIArray<ObRawExpr *> &new_exprs,
|
||||
ObRawExprCopier *copier,
|
||||
ObSQLSessionInfo *session_info);
|
||||
private:
|
||||
static int need_extra_cast_for_enumset(const ObExprResType &src_type,
|
||||
const ObExprResType &dst_type,
|
||||
const ObSQLSessionInfo *session_info,
|
||||
ObExprResType &extra_type,
|
||||
bool &need_extra_cast);
|
||||
|
||||
private :
|
||||
static int create_real_cast_expr(ObRawExprFactory &expr_factory,
|
||||
|
@ -32,7 +32,9 @@ int ObRawExprWrapEnumSet::wrap_enum_set(ObDMLStmt &stmt)
|
||||
int ret = OB_SUCCESS;
|
||||
cur_stmt_ = &stmt;
|
||||
if (stmt.is_select_stmt()) {
|
||||
//handle the target list of first level
|
||||
// handle the target list of first level
|
||||
// In the enum/set type with subschema, we keep this behavior now, as the obj meta information
|
||||
// of the original expr is not valid that can be directly returned to the client.
|
||||
ObSelectStmt &select_stmt = static_cast<ObSelectStmt &>(stmt);
|
||||
if (OB_FAIL(wrap_target_list(select_stmt))) {
|
||||
LOG_WARN("failed to wrap target list", K(ret));
|
||||
@ -83,12 +85,49 @@ int ObRawExprWrapEnumSet::wrap_sub_select(ObInsertStmt &stmt)
|
||||
} else if (OB_FAIL(static_cast<ObConstRawExpr *>(conv_expr->get_param_expr(0))
|
||||
->get_value().get_int32(const_value))) {
|
||||
LOG_WARN("failed to get obj type from convert expr", K(ret));
|
||||
} else if (conv_expr->get_param_expr(4)->is_enum_set_with_subschema()) {
|
||||
ObRawExpr *arg_expr = conv_expr->get_param_expr(4);
|
||||
if (arg_expr->get_data_type() == const_value) {
|
||||
bool need_to_str = true;
|
||||
// same type
|
||||
if (OB_ISNULL(my_session_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("session is null", K(ret));
|
||||
} else if (my_session_->get_ddl_info().is_ddl()) {
|
||||
uint16_t subschema_id = 0;
|
||||
ObExecContext *exec_ctx = NULL;
|
||||
if (conv_expr->is_enum_set_with_subschema()) {
|
||||
need_to_str = (arg_expr->get_subschema_id() != conv_expr->get_subschema_id());
|
||||
} else if (OB_ISNULL(exec_ctx = my_session_->get_cur_exec_ctx())) {
|
||||
} else if (OB_UNLIKELY(conv_expr->get_enum_set_values().empty())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("str values for enum set expr is empty", K(ret));
|
||||
} else if (OB_FAIL(exec_ctx->get_subschema_id_by_type_info(
|
||||
conv_expr->get_result_type().get_obj_meta(),
|
||||
conv_expr->get_enum_set_values(),
|
||||
subschema_id))) {
|
||||
LOG_WARN("failed to get subschema id by udt id", K(ret));
|
||||
} else if (subschema_id == arg_expr->get_subschema_id()) {
|
||||
need_to_str = false;
|
||||
}
|
||||
}
|
||||
if (OB_FAIL(ret) || !need_to_str) {
|
||||
} else if (OB_FAIL(ObRawExprUtils::create_type_to_str_expr(expr_factory_,
|
||||
arg_expr,
|
||||
wrapped_expr,
|
||||
my_session_,
|
||||
true /*is_type_to_str*/,
|
||||
static_cast<ObObjType>(const_value)))) {
|
||||
LOG_WARN("failed to create_type_to_string_expr", K(ret));
|
||||
}
|
||||
}
|
||||
} else if (OB_FAIL(wrap_type_to_str_if_necessary(conv_expr->get_param_expr(4),
|
||||
static_cast<ObObjType>(const_value),
|
||||
is_same_need,
|
||||
wrapped_expr))) {
|
||||
LOG_WARN("failed to wrap_type_to_str_if_necessary", K(i), K(ret));
|
||||
} else if (NULL != wrapped_expr) {
|
||||
}
|
||||
if (OB_SUCC(ret) && NULL != wrapped_expr) {
|
||||
conv_expr->get_param_expr(4) = wrapped_expr;
|
||||
}
|
||||
}
|
||||
@ -126,12 +165,28 @@ int ObRawExprWrapEnumSet::wrap_value_vector(ObInsertStmt &stmt)
|
||||
} else {
|
||||
int64_t index = i % desc_count;
|
||||
ObSysFunRawExpr *new_expr = NULL;
|
||||
if (OB_FAIL(wrap_type_to_str_if_necessary(value_expr, stmt.get_values_desc().at(index)->get_data_type(),
|
||||
const ObExprResType &dst_type = stmt.get_values_desc().at(index)->get_result_type();
|
||||
if (value_expr->is_enum_set_with_subschema()) {
|
||||
if (!ob_is_enum_or_set_type(dst_type.get_type())) {
|
||||
// skip wrap to string, it can cast directly
|
||||
} else if (dst_type.is_enum_set_with_subschema() &&
|
||||
dst_type.get_subschema_id() == value_expr->get_subschema_id()) {
|
||||
// same type, no need to cast
|
||||
} else if (OB_FAIL(ObRawExprUtils::create_type_to_str_expr(expr_factory_,
|
||||
value_expr,
|
||||
new_expr,
|
||||
my_session_,
|
||||
true /*is_type_to_str*/,
|
||||
dst_type.get_type()))) {
|
||||
LOG_WARN("failed to create_type_to_string_expr", K(ret));
|
||||
}
|
||||
} else if (OB_FAIL(wrap_type_to_str_if_necessary(value_expr, dst_type.get_type(),
|
||||
is_same_need, new_expr))) {
|
||||
LOG_WARN("failed to wrap_type_to_str_if_necessary", K(i), K(ret));
|
||||
} else if (NULL != new_expr) {
|
||||
}
|
||||
if (OB_SUCC(ret) && NULL != new_expr) {
|
||||
value_expr = new_expr;
|
||||
} else {/*do nothing*/}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -150,9 +205,15 @@ int ObRawExprWrapEnumSet::wrap_target_list(ObSelectStmt &select_stmt)
|
||||
LOG_WARN("expr of select_items should not be NULL", K(i), K(ret));
|
||||
} else if (ob_is_enumset_tc(target_expr->get_data_type())) {
|
||||
ObSysFunRawExpr *new_expr = NULL;
|
||||
// the return type of mysql client for enum/set is FIELD_TYPE_STRING instead of
|
||||
// FIELD_TYPE_VAR_STRING.
|
||||
const ObObjType dst_type = target_expr->is_enum_set_with_subschema() ?
|
||||
ObCharType : ObVarcharType;
|
||||
if (OB_FAIL(ObRawExprUtils::create_type_to_str_expr(expr_factory_, target_expr,
|
||||
new_expr,
|
||||
my_session_, is_type_to_str))) {
|
||||
my_session_,
|
||||
is_type_to_str,
|
||||
dst_type))) {
|
||||
LOG_WARN("failed to create_type_to_string_expr", K(i), K(target_expr), K(ret));
|
||||
} else if (OB_ISNULL(new_expr)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
@ -275,7 +336,7 @@ int ObRawExprWrapEnumSet::visit(ObColumnRefRawExpr &expr)
|
||||
int ObRawExprWrapEnumSet::visit(ObWinFunRawExpr &expr)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (expr.has_enum_set_column() || expr.has_flag(CNT_SUB_QUERY)) {
|
||||
if (has_enumset_expr_need_wrap(expr) || expr.has_flag(CNT_SUB_QUERY)) {
|
||||
if (T_WIN_FUN_LEAD == expr.get_func_type() ||
|
||||
T_WIN_FUN_LAG == expr.get_func_type()) {
|
||||
ObIArray<ObRawExpr*> &real_parm_exprs = expr.get_func_params();
|
||||
@ -303,7 +364,7 @@ int ObRawExprWrapEnumSet::visit(ObOpRawExpr &expr)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
ObExprOperator *op = NULL;
|
||||
if (!expr.has_enum_set_column() && !expr.has_flag(CNT_SUB_QUERY)) {
|
||||
if (!has_enumset_expr_need_wrap(expr) && !expr.has_flag(CNT_SUB_QUERY)) {
|
||||
//不含有enum或者set,则不需要做任何转换
|
||||
} else if (T_OP_ROW != expr.get_expr_type()) {
|
||||
if (OB_ISNULL(op = expr.get_op())) {
|
||||
@ -322,10 +383,10 @@ int ObRawExprWrapEnumSet::visit(ObOpRawExpr &expr)
|
||||
} else if (OB_ISNULL(left_expr = expr.get_param_expr(0)) || OB_ISNULL(right_expr = expr.get_param_expr(1))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("child expr is NULL", K(left_expr), K(right_expr), K(ret));
|
||||
} else if ((left_expr->has_enum_set_column() || left_expr->has_flag(CNT_SUB_QUERY)) &&
|
||||
} else if ((has_enumset_expr_need_wrap(*left_expr) || left_expr->has_flag(CNT_SUB_QUERY)) &&
|
||||
OB_FAIL(visit_left_expr(expr, row_dimension, cmp_types))) {
|
||||
LOG_WARN("failed to visit left expr", K(expr), K(ret));
|
||||
} else if ((right_expr->has_enum_set_column() || right_expr->has_flag(CNT_SUB_QUERY))
|
||||
} else if ((has_enumset_expr_need_wrap(*right_expr) || right_expr->has_flag(CNT_SUB_QUERY))
|
||||
&& OB_FAIL(visit_right_expr(*right_expr, row_dimension,
|
||||
cmp_types, expr.get_expr_type()))) {
|
||||
LOG_WARN("failed to visit right expr", K(expr), K(ret));
|
||||
@ -452,7 +513,7 @@ int ObRawExprWrapEnumSet::check_and_wrap_left(ObRawExpr &expr, int64_t idx,
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < target_num && !(need_numberic && need_varchar); ++i) {
|
||||
bool need_wrap = false;
|
||||
dest_type = cmp_types.at(row_dimension * i + idx).get_type();
|
||||
if (OB_FAIL(ObRawExprUtils::need_wrap_to_string(expr_type,
|
||||
if (OB_FAIL(ObRawExprUtils::need_wrap_to_string(expr.get_result_type(),
|
||||
dest_type,
|
||||
is_same_type_need, need_wrap))) {
|
||||
LOG_WARN("failed to check whether need wrap", K(i), K(expr), K(ret));
|
||||
@ -647,7 +708,7 @@ int ObRawExprWrapEnumSet::wrap_type_to_str_if_necessary(ObRawExpr *expr,
|
||||
if (OB_ISNULL(expr)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("expr is NULL", K(ret));
|
||||
} else if (OB_FAIL(ObRawExprUtils::need_wrap_to_string(expr->get_data_type(), dest_type,
|
||||
} else if (OB_FAIL(ObRawExprUtils::need_wrap_to_string(expr->get_result_type(), dest_type,
|
||||
is_same_need, need_wrap))) {
|
||||
LOG_WARN("failed to check_need_wrap_to_string", K(ret));
|
||||
} else if (need_wrap && OB_FAIL(ObRawExprUtils::create_type_to_str_expr(expr_factory_, expr,
|
||||
@ -692,7 +753,7 @@ int ObRawExprWrapEnumSet::visit(ObCaseOpRawExpr &expr)
|
||||
LOG_WARN("failed to wrap_type_to_str_if_necessary", K(i), K(ret));
|
||||
} else if (NULL != wrapped_expr && OB_FAIL(expr.replace_when_param_expr(i, wrapped_expr))){
|
||||
LOG_WARN("failed to replace_when_param_expr", K(i), K(ret));
|
||||
} else if (OB_FAIL(ObRawExprUtils::need_wrap_to_string(arg_type, calc_type, is_same_need, need_wrap))) {
|
||||
} else if (OB_FAIL(ObRawExprUtils::need_wrap_to_string(arg_param_expr->get_result_type(), calc_type, is_same_need, need_wrap))) {
|
||||
LOG_WARN("failed to check whether need wrap", K(arg_type), K(calc_type), K(ret));
|
||||
} else if (need_wrap) {
|
||||
need_varchar = true;
|
||||
@ -758,7 +819,7 @@ int ObRawExprWrapEnumSet::visit(ObCaseOpRawExpr &expr)
|
||||
int ObRawExprWrapEnumSet::visit(ObAggFunRawExpr &expr)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if ((expr.has_enum_set_column() || expr.has_flag(CNT_SUB_QUERY)) &&
|
||||
if ((has_enumset_expr_need_wrap(expr) || expr.has_flag(CNT_SUB_QUERY)) &&
|
||||
(T_FUN_GROUP_CONCAT == expr.get_expr_type() ||
|
||||
T_FUN_MAX == expr.get_expr_type() ||
|
||||
T_FUN_MIN == expr.get_expr_type() ||
|
||||
@ -857,7 +918,7 @@ int ObRawExprWrapEnumSet::visit(ObAliasRefRawExpr &expr)
|
||||
if (OB_ISNULL(ref_expr)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("ref expr is null", K(ret));
|
||||
} else if (expr.has_enum_set_column() && OB_FAIL(analyze_expr(ref_expr))) {
|
||||
} else if (has_enumset_expr_need_wrap(expr) && OB_FAIL(analyze_expr(ref_expr))) {
|
||||
LOG_WARN("failed to analyze expr", K(ret));
|
||||
} else {/*do nothing*/}
|
||||
return ret;
|
||||
@ -925,7 +986,7 @@ int ObRawExprWrapEnumSet::visit_query_ref_expr(ObQueryRefRawExpr &expr,
|
||||
const bool is_same_need)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (!expr.has_enum_set_column() && !expr.has_flag(CNT_SUB_QUERY)) {
|
||||
if (!has_enumset_expr_need_wrap(expr) && !expr.has_flag(CNT_SUB_QUERY)) {
|
||||
// no-op if expr doesn't have enumset column
|
||||
} else if (1 == expr.get_output_column() && expr.is_set() &&
|
||||
ob_is_enumset_tc(expr.get_column_types().at(0).get_type())) {
|
||||
@ -979,5 +1040,23 @@ int ObRawExprWrapEnumSet::wrap_param_expr(ObIArray<ObRawExpr*> ¶m_exprs, ObO
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool ObRawExprWrapEnumSet::has_enumset_expr_need_wrap(const ObRawExpr &expr)
|
||||
{
|
||||
int need_wrap = false;
|
||||
if (expr.has_enum_set_column()) {
|
||||
if (expr.get_result_type().is_enum_or_set()) {
|
||||
need_wrap = !expr.is_enum_set_with_subschema();
|
||||
}
|
||||
for (int64_t i = 0; !need_wrap && i < expr.get_param_count(); ++i) {
|
||||
const ObRawExpr *param_expr = expr.get_param_expr(i);
|
||||
if (OB_ISNULL(param_expr)) {
|
||||
} else {
|
||||
need_wrap = has_enumset_expr_need_wrap(*param_expr);
|
||||
}
|
||||
}
|
||||
}
|
||||
return need_wrap;
|
||||
}
|
||||
|
||||
} // namespace sql
|
||||
} // namespace oceanbase
|
||||
|
@ -76,6 +76,7 @@ private:
|
||||
const common::ObObjType dest_type,
|
||||
const bool is_same_need);
|
||||
int wrap_param_expr(ObIArray<ObRawExpr*> ¶m_exprs, ObObjType dest_typ);
|
||||
static bool has_enumset_expr_need_wrap(const ObRawExpr &expr);
|
||||
private:
|
||||
ObDMLStmt *cur_stmt_;
|
||||
ObRawExprFactory &expr_factory_;
|
||||
|
@ -107,7 +107,7 @@ int ObMVProvider::init_mv_provider(const share::SCN &last_refresh_scn,
|
||||
LOG_WARN("failed to collect dep infos", K(ret));
|
||||
} else if (OB_FAIL(dependency_infos_.assign(dependency_infos))) {
|
||||
LOG_WARN("failed to assign fixed array", K(ret));
|
||||
} else if (OB_FAIL(check_mv_column_type(mv_schema, view_stmt))) {
|
||||
} else if (OB_FAIL(check_mv_column_type(mv_schema, view_stmt, *session_info))) {
|
||||
if (OB_ERR_MVIEW_CAN_NOT_FAST_REFRESH == ret) {
|
||||
inited_ = true;
|
||||
refreshable_type_ = OB_MV_REFRESH_INVALID;
|
||||
@ -215,7 +215,8 @@ int ObMVProvider::get_mv_dependency_infos(ObIArray<ObDependencyInfo> &dep_infos)
|
||||
// if the result type from mv_schema and view_stmt is different, no refresh method is allowed
|
||||
// get new column info same as ObCreateViewResolver::add_column_infos
|
||||
int ObMVProvider::check_mv_column_type(const ObTableSchema *mv_schema,
|
||||
const ObSelectStmt *view_stmt)
|
||||
const ObSelectStmt *view_stmt,
|
||||
ObSQLSessionInfo &session)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_ISNULL(mv_schema) || OB_ISNULL(view_stmt)) {
|
||||
@ -236,6 +237,7 @@ int ObMVProvider::check_mv_column_type(const ObTableSchema *mv_schema,
|
||||
} else if (OB_FAIL(ObCreateViewResolver::fill_column_meta_infos(*select_items.at(i).expr_,
|
||||
mv_schema->get_charset_type(),
|
||||
mv_schema->get_table_id(),
|
||||
session,
|
||||
cur_column))) {
|
||||
LOG_WARN("failed to fill column meta infos", K(ret), K(cur_column));
|
||||
} else if (OB_FAIL(check_mv_column_type(*org_column, cur_column))) {
|
||||
|
@ -65,7 +65,8 @@ public:
|
||||
const bool gen_error,
|
||||
bool &is_vars_matched);
|
||||
private:
|
||||
int check_mv_column_type(const ObTableSchema *mv_schema, const ObSelectStmt *view_stmt);
|
||||
int check_mv_column_type(const ObTableSchema *mv_schema, const ObSelectStmt *view_stmt,
|
||||
ObSQLSessionInfo &session);
|
||||
int check_mv_column_type(const ObColumnSchemaV2 &org_column, const ObColumnSchemaV2 &cur_column);
|
||||
int check_column_type_and_accuracy(const ObColumnSchemaV2 &org_column,
|
||||
const ObColumnSchemaV2 &cur_column,
|
||||
|
@ -517,7 +517,10 @@ int ObTransformPreProcess::add_all_rowkey_columns_to_stmt(const ObTableSchema &t
|
||||
} else if (OB_FAIL(column_items.push_back(column_item))) {
|
||||
LOG_WARN("failed to push back column item", K(ret));
|
||||
} else if (FALSE_IT(rowkey->clear_explicited_referece())) {
|
||||
} else if (OB_FAIL(rowkey->formalize(NULL))) {
|
||||
} else if (OB_ISNULL(ctx_)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("trans ctx is null", K(ret));
|
||||
} else if (OB_FAIL(rowkey->formalize(ctx_->session_info_))) {
|
||||
LOG_WARN("formalize rowkey failed", K(ret));
|
||||
} else if (OB_FAIL(rowkey->pull_relation_id())) {
|
||||
LOG_WARN("failed to pullup relation ids", K(ret));
|
||||
@ -5825,17 +5828,28 @@ int ObTransformPreProcess::transform_in_or_notin_expr_without_row(ObRawExprFacto
|
||||
ObRawExpr *right_expr = in_expr->get_param_expr(1);
|
||||
ObSEArray<DistinctObjMeta, 4> distinct_types;
|
||||
for (int i = 0; OB_SUCC(ret) && i < right_expr->get_param_count(); i++) {
|
||||
if (OB_ISNULL(right_expr->get_param_expr(i))) {
|
||||
ObRawExpr *param_expr = right_expr->get_param_expr(i);
|
||||
if (OB_ISNULL(param_expr)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid null param expr", K(ret), K(right_expr->get_param_expr(i)));
|
||||
LOG_WARN("invalid null param expr", K(ret), K(param_expr));
|
||||
} else {
|
||||
ObObjType obj_type = right_expr->get_param_expr(i)->get_result_type().get_type();
|
||||
ObCollationType coll_type = right_expr->get_param_expr(i)
|
||||
->get_result_type().get_collation_type();
|
||||
ObCollationLevel coll_level = right_expr->get_param_expr(i)
|
||||
->get_result_type().get_collation_level();
|
||||
ObScale scale = right_expr->get_param_expr(i)->get_result_type().get_scale();
|
||||
if (OB_UNLIKELY(obj_type == ObMaxType)) {
|
||||
ObObjType obj_type = param_expr->get_result_type().get_type();
|
||||
ObCollationType coll_type = param_expr->get_result_type().get_collation_type();
|
||||
ObCollationLevel coll_level = param_expr->get_result_type().get_collation_level();
|
||||
ObScale scale = param_expr->get_result_type().get_scale();
|
||||
if (param_expr->is_enum_set_with_subschema()) {
|
||||
ObObjMeta obj_meta;
|
||||
if (OB_FAIL(ObRawExprUtils::extract_enum_set_collation(param_expr->get_result_type(),
|
||||
&session,
|
||||
obj_meta))) {
|
||||
LOG_WARN("fail to extract enum set cs type", K(ret));
|
||||
} else {
|
||||
coll_type = obj_meta.get_collation_type();
|
||||
coll_level = obj_meta.get_collation_level();
|
||||
}
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_UNLIKELY(obj_type == ObMaxType)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("get unexpected obj type", K(ret), K(obj_type), K(*in_expr));
|
||||
} else if (OB_FAIL(add_var_to_array_no_dup(distinct_types,
|
||||
@ -5867,14 +5881,25 @@ int ObTransformPreProcess::transform_in_or_notin_expr_without_row(ObRawExprFacto
|
||||
same_type_exprs.reuse();
|
||||
DistinctObjMeta obj_meta = distinct_types.at(i);
|
||||
for (int j = 0; OB_SUCC(ret) && j < right_expr->get_param_count(); j++) {
|
||||
ObObjType obj_type = right_expr->get_param_expr(j)->get_result_type().get_type();
|
||||
ObCollationType coll_type = right_expr->get_param_expr(j)
|
||||
->get_result_type().get_collation_type();
|
||||
ObCollationLevel coll_level = right_expr->get_param_expr(j)
|
||||
->get_result_type().get_collation_level();
|
||||
ObScale scale = right_expr->get_param_expr(j)->get_result_type().get_scale();
|
||||
DistinctObjMeta tmp_meta(obj_type, coll_type, coll_level, scale);
|
||||
if (obj_meta == tmp_meta
|
||||
ObRawExpr *param_expr = right_expr->get_param_expr(j);
|
||||
ObObjType obj_type = param_expr->get_result_type().get_type();
|
||||
ObCollationType coll_type = param_expr->get_result_type().get_collation_type();
|
||||
ObCollationLevel coll_level = param_expr->get_result_type().get_collation_level();
|
||||
ObScale scale = param_expr->get_result_type().get_scale();
|
||||
if (param_expr->is_enum_set_with_subschema()) {
|
||||
ObObjMeta enum_set_obj_meta;
|
||||
if (OB_FAIL(ObRawExprUtils::extract_enum_set_collation(param_expr->get_result_type(),
|
||||
&session,
|
||||
enum_set_obj_meta))) {
|
||||
LOG_WARN("fail to extract enum set cs type", K(ret));
|
||||
} else {
|
||||
coll_type = enum_set_obj_meta.get_collation_type();
|
||||
coll_level = enum_set_obj_meta.get_collation_level();
|
||||
}
|
||||
}
|
||||
DistinctObjMeta tmp_meta(obj_type, coll_type, coll_level, scale);
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (obj_meta == tmp_meta
|
||||
&& OB_FAIL(same_type_exprs.push_back(right_expr->get_param_expr(j)))) {
|
||||
LOG_WARN("failed to add param expr", K(ret));
|
||||
} else { /* do nothing */ }
|
||||
|
@ -39,7 +39,7 @@ struct DistinctObjMeta
|
||||
: obj_type_(obj_type), coll_type_(coll_type),
|
||||
coll_level_(coll_level), scale_(scale)
|
||||
{
|
||||
if (!ObDatumFuncs::is_string_type(obj_type_)) {
|
||||
if (!ObDatumFuncs::is_string_type(obj_type_) && !ob_is_enum_or_set_type(obj_type_)) {
|
||||
coll_type_ = CS_TYPE_MAX;
|
||||
coll_level_ = CS_LEVEL_INVALID;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user