From bff45aaa70307e957ecee48061b7446ed3a733f7 Mon Sep 17 00:00:00 2001 From: jingtaoye35 <1255153887@qq.com> Date: Tue, 2 Jan 2024 13:13:05 +0000 Subject: [PATCH] [CP] fix serialize ObSqlArrayObj bugs --- deps/oblib/src/common/object/ob_obj_funcs.h | 41 +++++- deps/oblib/src/common/object/ob_object.cpp | 120 ++++++++---------- deps/oblib/src/common/object/ob_object.h | 4 + src/sql/engine/ob_physical_plan_ctx.cpp | 60 ++++++--- src/sql/engine/ob_physical_plan_ctx.h | 1 + .../ob_values_table_compression.cpp | 79 ++++++++---- .../plan_cache/ob_values_table_compression.h | 2 + src/sql/resolver/dml/ob_dml_resolver.cpp | 57 +++++---- src/sql/resolver/dml/ob_dml_resolver.h | 7 +- src/sql/rewrite/ob_transform_utils.cpp | 22 +--- 10 files changed, 239 insertions(+), 154 deletions(-) diff --git a/deps/oblib/src/common/object/ob_obj_funcs.h b/deps/oblib/src/common/object/ob_obj_funcs.h index 0d610a118..b285f584c 100644 --- a/deps/oblib/src/common/object/ob_obj_funcs.h +++ b/deps/oblib/src/common/object/ob_obj_funcs.h @@ -2320,8 +2320,8 @@ template <> inline int obj_val_serialize(const ObObj &obj, char* buf, const int64_t buf_len, int64_t& pos) { int ret = OB_SUCCESS; - OB_UNIS_ENCODE(obj.get_ext()); if (obj.is_pl_extend()) { + OB_UNIS_ENCODE(obj.get_ext()); COMMON_LOG(ERROR, "Unexpected serialize", K(OB_NOT_SUPPORTED), K(obj), K(obj.get_meta().get_extend_type())); return OB_NOT_SUPPORTED; //TODO:@ryan.ly: close this feature before composite refactor if (NULL == serialize_composite_callback) { @@ -2329,6 +2329,18 @@ inline int obj_val_serialize(const ObObj &obj, char* buf, const in } else { ret = serialize_composite_callback(obj, buf, buf_len, pos); } + } else if (obj.is_ext_sql_array()) { + int64_t v = 0; + OB_UNIS_ENCODE(v); + const ObSqlArrayObj *array_obj = reinterpret_cast(obj.get_ext()); + if (OB_SUCC(ret) && NULL != array_obj) { + int64_t len = array_obj->get_serialize_size(); + int64_t tmp_pos = pos; + OB_UNIS_ENCODE(len); + OB_UNIS_ENCODE(*array_obj); + } + } else { + OB_UNIS_ENCODE(obj.get_ext()); } return ret; } @@ -2347,6 +2359,20 @@ inline int obj_val_deserialize(ObObj &obj, const char* buf, const } else { ret = deserialize_composite_callback(obj, buf, data_len, pos); } + } else if (obj.is_ext_sql_array()) { + if (OB_UNLIKELY(v != 0)) { + ret = OB_NOT_SUPPORTED; + COMMON_LOG(WARN, "using such type in upgrade period", K(ret)); + } else { + int64_t len = 0; + int64_t tmp_pos = pos; + OB_UNIS_DECODE(len); + /* record the buffer and delay it's deserialize. + * should call ObSqlArrayObj::do_real_deserialize which need an allocator + */ + obj.set_extend(reinterpret_cast(buf + pos), T_EXT_SQL_ARRAY, int32_t(len)); + pos += len; + } } else { obj.set_obj_value(v); } @@ -2357,8 +2383,8 @@ template <> inline int64_t obj_val_get_serialize_size(const ObObj &obj) { int64_t len = 0; - OB_UNIS_ADD_LEN(obj.get_ext()); if (obj.is_pl_extend()) { + OB_UNIS_ADD_LEN(obj.get_ext()); COMMON_LOG_RET(ERROR, OB_NOT_SUPPORTED, "Unexpected serialize", K(OB_NOT_SUPPORTED), K(obj), K(obj.get_meta().get_extend_type())); return len; //TODO:@ryan.ly: close this feature before composite refactor if (NULL == composite_serialize_size_callback) { @@ -2366,6 +2392,17 @@ inline int64_t obj_val_get_serialize_size(const ObObj &obj) } else { len += composite_serialize_size_callback(obj); } + } else if (obj.is_ext_sql_array()) { + int64_t v = 0; + OB_UNIS_ADD_LEN(v); + const ObSqlArrayObj *array_obj = reinterpret_cast(obj.get_ext()); + if (NULL != array_obj) { + int64_t array_obj_len = array_obj->get_serialize_size(); + OB_UNIS_ADD_LEN(array_obj_len); + OB_UNIS_ADD_LEN(*array_obj); + } + } else { + OB_UNIS_ADD_LEN(obj.get_ext()); } return len; } diff --git a/deps/oblib/src/common/object/ob_object.cpp b/deps/oblib/src/common/object/ob_object.cpp index 939705444..b875052b7 100644 --- a/deps/oblib/src/common/object/ob_object.cpp +++ b/deps/oblib/src/common/object/ob_object.cpp @@ -2227,35 +2227,6 @@ DEFINE_SERIALIZE(ObObjParam) if (OB_SUCC(ret)) { OB_UNIS_ENCODE(accuracy_); OB_UNIS_ENCODE(res_flags_); - if (OB_SUCC(ret) && is_ext_sql_array()) { - const ObSqlArrayObj *array_obj = reinterpret_cast(get_ext()); - int64_t n = sizeof(ObSqlArrayObj); - if (OB_ISNULL(array_obj)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected NULL ptr", K(ret), KP(array_obj)); - } else if (buf_len - pos < n) { - ret = OB_BUF_NOT_ENOUGH; - LOG_WARN("serialize buf not enough", K(ret), "remain", buf_len - pos, "needed", n); - } else { - MEMCPY(buf + pos, array_obj, n); - pos += n; - if (array_obj->count_ == 0) { - /* do nothing */ - } else if (OB_ISNULL(array_obj->data_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("data is NULL ptr", K(ret), KP(array_obj->data_)); - } else { - n = sizeof(array_obj->data_[0]) * array_obj->count_; - if (buf_len - pos < n) { - ret = OB_BUF_NOT_ENOUGH; - LOG_WARN("serialize buf not enough", K(ret), "remain", buf_len - pos, "needed", n); - } else { - MEMCPY(buf + pos, static_cast(array_obj->data_), n); - pos += n; - } - } - } - } } return ret; } @@ -2266,30 +2237,6 @@ DEFINE_DESERIALIZE(ObObjParam) if (OB_SUCC(ret)) { OB_UNIS_DECODE(accuracy_); OB_UNIS_DECODE(res_flags_); - if (OB_SUCC(ret) && is_ext_sql_array()) { - ObSqlArrayObj *array_obj = NULL; - int64_t n = sizeof(ObSqlArrayObj); - if (data_len - pos < n) { - ret = OB_BUF_NOT_ENOUGH; - LOG_WARN("deserialize buf not enough", K(ret), "remain", data_len - pos, "needed", n); - } else { - array_obj = reinterpret_cast(const_cast(buf + pos)); - pos += n; - } - if (OB_SUCC(ret) && array_obj->count_ > 0) { - n = sizeof(ObObjParam) * array_obj->count_; - if (data_len - pos < n) { - ret = OB_BUF_NOT_ENOUGH; - LOG_WARN("deserialize buf not enough", K(ret), "remain", data_len - pos, "needed", n); - } else { - array_obj->data_ = reinterpret_cast(const_cast(buf + pos)); - pos += n; - } - } - if (OB_SUCC(ret)) { - set_extend(reinterpret_cast(array_obj), T_EXT_SQL_ARRAY); - } - } } return ret; } @@ -2299,18 +2246,6 @@ DEFINE_GET_SERIALIZE_SIZE(ObObjParam) int64_t len = ObObj::get_serialize_size(); OB_UNIS_ADD_LEN(accuracy_); OB_UNIS_ADD_LEN(res_flags_); - if (is_ext_sql_array()) { - len += sizeof(ObSqlArrayObj); - const ObSqlArrayObj *array_obj = reinterpret_cast(get_ext()); - if (NULL != array_obj) { - len += sizeof(ObSqlArrayObj); - if (array_obj->count_ == 0) { - /* do nothing */ - } else if (NULL != array_obj->data_) { - len += sizeof(array_obj->data_[0]) * array_obj->count_; - } - } - } return len; } @@ -2451,3 +2386,58 @@ int64_t ObHexEscapeSqlStr::get_extra_length() const } return ret_length; } + +int ObSqlArrayObj::do_real_deserialize(common::ObIAllocator &allocator, char *buf, int64_t data_len, + ObSqlArrayObj *&array_obj) +{ + int ret = OB_SUCCESS; + int64_t n = sizeof(ObSqlArrayObj); + void *array_buf = allocator.alloc(n); + int64_t pos = 0; + if (OB_ISNULL(array_buf)) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("allocate memory failed", K(ret)); + } else { + array_obj = new (array_buf) ObSqlArrayObj(); + if (OB_FAIL(array_obj->deserialize(allocator, buf, data_len, pos))) { + LOG_WARN("failed to deserialize ObSqlArrayObj", K(ret)); + } + } + return ret; +} + +DEFINE_SERIALIZE(ObSqlArrayObj) +{ + int ret = OB_SUCCESS; + int64_t len = 0; + OB_UNIS_ENCODE(element_); + OB_UNIS_ENCODE_ARRAY(data_, count_); + return ret; +} + +int ObSqlArrayObj::deserialize(ObIAllocator &allocator, const char* buf, const int64_t data_len, + int64_t& pos) +{ + int ret = OB_SUCCESS; + OB_UNIS_DECODE(element_); + OB_UNIS_DECODE(count_); + if (OB_SUCC(ret) && count_ > 0) { + void *data_buf = allocator.alloc(sizeof(ObObjParam) * count_); + if (OB_ISNULL(data_buf)) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("allocate memory failed", K(ret)); + } else { + data_ = new (data_buf) common::ObObjParam[count_]; + OB_UNIS_DECODE_ARRAY(data_, count_); + } + } + return ret; +} + +DEFINE_GET_SERIALIZE_SIZE(ObSqlArrayObj) +{ + int64_t len = 0; + OB_UNIS_ADD_LEN(element_); + OB_UNIS_ADD_LEN_ARRAY(data_, count_); + return len; +} diff --git a/deps/oblib/src/common/object/ob_object.h b/deps/oblib/src/common/object/ob_object.h index 13446a8d3..203fd535d 100644 --- a/deps/oblib/src/common/object/ob_object.h +++ b/deps/oblib/src/common/object/ob_object.h @@ -4150,6 +4150,10 @@ struct ObSqlArrayObj } typedef common::ObArrayWrap DataArray; static ObSqlArrayObj *alloc(common::ObIAllocator &allocator, int64_t count); + static int do_real_deserialize(common::ObIAllocator &allocator, char *buf, int64_t data_len, ObSqlArrayObj *&array_obj); + int serialize(char* buf, const int64_t buf_len, int64_t& pos) const; + int deserialize(common::ObIAllocator &allocator, const char* buf, const int64_t data_len, int64_t& pos); + int64_t get_serialize_size(void) const; TO_STRING_KV("data", DataArray(data_, count_), K_(count), K_(element)); common::ObObjParam *data_; int64_t count_; diff --git a/src/sql/engine/ob_physical_plan_ctx.cpp b/src/sql/engine/ob_physical_plan_ctx.cpp index d8c28f792..b99f46019 100644 --- a/src/sql/engine/ob_physical_plan_ctx.cpp +++ b/src/sql/engine/ob_physical_plan_ctx.cpp @@ -949,22 +949,6 @@ OB_DEF_DESERIALIZE(ObPhysicalPlanCtx) } } } - if (OB_SUCC(ret) && array_group_count > 0 && - datum_param_store_.count() == 0 && - datum_param_store_.count() != param_store_.count()) { - if (OB_FAIL(datum_param_store_.prepare_allocate(param_store_.count()))) { - LOG_WARN("fail to prepare allocate", K(ret), K(param_store_.count())); - } - for (int64_t i = 0; OB_SUCC(ret) && i < param_store_.count(); i++) { - ObDatumObjParam &datum_param = datum_param_store_.at(i); - if (OB_FAIL(datum_param.alloc_datum_reserved_buff( - param_store_.at(i).meta_, param_store_.at(i).get_precision(), allocator_))) { - LOG_WARN("alloc datum reserved buffer failed", K(ret)); - } else if (OB_FAIL(datum_param.from_objparam(param_store_.at(i), &allocator_))) { - LOG_WARN("fail to convert obj param", K(ret), K(param_store_.at(i))); - } - } - } OB_UNIS_DECODE(enable_rich_format_); OB_UNIS_DECODE(local_var_array_cnt); if (OB_SUCC(ret)) { @@ -984,6 +968,15 @@ OB_DEF_DESERIALIZE(ObPhysicalPlanCtx) OB_UNIS_DECODE(*local_vars); } } + + // following is not deserialize, please add deserialize ahead. + if (OB_SUCC(ret) && array_group_count > 0 && + datum_param_store_.count() == 0 && + datum_param_store_.count() != param_store_.count()) { + if (OB_FAIL(init_param_store_after_deserialize())) { + LOG_WARN("failed to deserialize param store", K(ret)); + } + } return ret; } @@ -1041,5 +1034,40 @@ int ObPhysicalPlanCtx::get_local_session_vars(int64_t local_var_array_id, const return ret; } +// white list: init param_store after deserialize which it's needed really. +int ObPhysicalPlanCtx::init_param_store_after_deserialize() +{ + int ret = OB_SUCCESS; + datum_param_store_.reuse(); + if (OB_FAIL(datum_param_store_.prepare_allocate(param_store_.count()))) { + LOG_WARN("fail to prepare allocate", K(ret), K(param_store_.count())); + } + for (int64_t i = 0; OB_SUCC(ret) && i < param_store_.count(); i++) { + ObObjParam &obj_param = param_store_.at(i); + ObDatumObjParam &datum_param = datum_param_store_.at(i); + if (obj_param.is_ext_sql_array()) { + ObSqlArrayObj *array_obj = NULL; + if (OB_FAIL(ObSqlArrayObj::do_real_deserialize(allocator_, + reinterpret_cast(obj_param.get_ext()), + obj_param.get_val_len(), + array_obj))) { + LOG_WARN("failed to alloc array_obj after decode", K(ret)); + } else { + obj_param.set_extend(reinterpret_cast(array_obj), T_EXT_SQL_ARRAY); + } + } + if (OB_SUCC(ret)) { + if (OB_FAIL(datum_param.alloc_datum_reserved_buff(obj_param.meta_, + obj_param.get_precision(), + allocator_))) { + LOG_WARN("alloc datum reserved buffer failed", K(ret)); + } else if (OB_FAIL(datum_param.from_objparam(obj_param, &allocator_))) { + LOG_WARN("fail to convert obj param", K(ret), K(obj_param)); + } + } + } + return ret; +} + } //sql } //oceanbase diff --git a/src/sql/engine/ob_physical_plan_ctx.h b/src/sql/engine/ob_physical_plan_ctx.h index eabf8c6d1..cbcc6e3d0 100644 --- a/src/sql/engine/ob_physical_plan_ctx.h +++ b/src/sql/engine/ob_physical_plan_ctx.h @@ -466,6 +466,7 @@ public: int set_all_local_session_vars(ObIArray &all_local_session_vars); int get_local_session_vars(int64_t idx, const ObLocalSessionVar *&local_vars); private: + int init_param_store_after_deserialize(); void reset_datum_frame(char *frame, int64_t expr_cnt); int extend_param_frame(const int64_t old_size); int reserve_param_frame(const int64_t capacity); diff --git a/src/sql/plan_cache/ob_values_table_compression.cpp b/src/sql/plan_cache/ob_values_table_compression.cpp index 1b6f2a830..33bde3d37 100644 --- a/src/sql/plan_cache/ob_values_table_compression.cpp +++ b/src/sql/plan_cache/ob_values_table_compression.cpp @@ -189,6 +189,8 @@ int ObValuesTableCompression::rebuild_new_raw_sql(ObPlanCacheCtx &pc_ctx, const int64_t param_cnt, const int64_t delta_length, const ObString &no_param_sql, + ObIArray &no_param_pos, + ObIArray &raw_sql_offset, ObString &new_raw_sql, int64_t &no_param_sql_pos, int64_t &new_raw_pos) @@ -211,6 +213,7 @@ int ObValuesTableCompression::rebuild_new_raw_sql(ObPlanCacheCtx &pc_ctx, LOG_WARN("get unexpected NULL ptr", K(ret), KP(pc_param)); } else { int64_t param_pos = pc_param->node_->pos_ - delta_length; // get pos is in new no param sql + int64_t param_raw_offset = pc_param->node_->raw_sql_offset_; int64_t param_len = pc_param->node_->text_len_; len = param_pos - no_param_sql_pos; if (OB_UNLIKELY(len < 0) || OB_UNLIKELY(new_raw_pos + len + param_len > buff_len)) { @@ -225,10 +228,17 @@ int ObValuesTableCompression::rebuild_new_raw_sql(ObPlanCacheCtx &pc_ctx, } if (param_pos == no_param_sql_pos) { //copy raw param + param_raw_offset = new_raw_pos; MEMCPY(buff + new_raw_pos, pc_param->node_->raw_text_, param_len); new_raw_pos += param_len; no_param_sql_pos += 1; } + if (OB_FAIL(ret)) { + } else if (OB_FAIL(no_param_pos.push_back(param_pos))) { + LOG_WARN("failed to push back", K(ret)); + } else if (OB_FAIL(raw_sql_offset.push_back(param_raw_offset))) { + LOG_WARN("failed to push back", K(ret)); + } } } } @@ -260,7 +270,8 @@ int ObValuesTableCompression::try_batch_exec_params(ObIAllocator &allocator, int64_t no_param_sql_pos = 0; int64_t new_raw_sql_pos = 0; ObString &new_raw_sql = pc_ctx.new_raw_sql_; - ObSEArray raw_pos; + ObSEArray no_param_pos; + ObSEArray raw_sql_offset; ObPhysicalPlanCtx *phy_ctx = NULL; uint64_t data_version = 0; if (pc_ctx.sql_ctx_.handle_batched_multi_stmt() || @@ -270,9 +281,8 @@ int ObValuesTableCompression::try_batch_exec_params(ObIAllocator &allocator, fp_result.values_tokens_.empty() || !GCONF._enable_values_table_folding) { /* do nothing */ - } else if (OB_FAIL(GET_MIN_DATA_VERSION(session_info.get_effective_tenant_id(), data_version))) { - LOG_WARN("get tenant data version failed", K(ret), K(session_info.get_effective_tenant_id())); - } else if (data_version < DATA_VERSION_4_2_1_0 || + /* TODO NOTE@yejingtao.yjt: remove following upgrade checking after next barrier version */ + } else if (GET_MIN_CLUSTER_VERSION() < CLUSTER_VERSION_4_2_1_2 || !is_support_compress_values_table(pc_ctx.raw_sql_)) { /* do nothing */ } else if (OB_ISNULL(phy_ctx = pc_ctx.exec_ctx_.get_physical_plan_ctx())) { @@ -306,20 +316,15 @@ int ObValuesTableCompression::try_batch_exec_params(ObIAllocator &allocator, } } for (int64_t j = last_raw_param_idx; OB_SUCC(ret) && j < param_idx + param_count; j++) { - ObPCParam *pc_param = pc_ctx.fp_result_.raw_params_.at(j); - if (OB_ISNULL(pc_param) || OB_ISNULL(pc_param->node_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("pc_param is null", K(ret), KP(pc_param)); - } else if (OB_FAIL(temp_store.push_back(pc_param))) { - LOG_WARN("failed to push back", K(ret)); - } else if (OB_FAIL(raw_pos.push_back(pc_param->node_->pos_ - total_delta_len))) { + if (OB_FAIL(temp_store.push_back(pc_ctx.fp_result_.raw_params_.at(j)))) { LOG_WARN("failed to push back", K(ret)); } } if (OB_FAIL(ret)) { } else if (OB_FAIL(rebuild_new_raw_sql(pc_ctx, temp_store, new_raw_idx, temp_store.count() - new_raw_idx, total_delta_len, new_no_param_sql, - new_raw_sql, no_param_sql_pos, new_raw_sql_pos))) { + no_param_pos, raw_sql_offset, new_raw_sql, no_param_sql_pos, + new_raw_sql_pos))) { LOG_WARN("failed to rebuild new raw sql", K(ret)); } else { int64_t batch_begin_idx = new_raw_idx + param_idx - last_raw_param_idx; @@ -337,24 +342,20 @@ int ObValuesTableCompression::try_batch_exec_params(ObIAllocator &allocator, } if (OB_SUCC(ret) && can_fold_params) { for (int64_t j = last_raw_param_idx; OB_SUCC(ret) && j < pc_ctx.fp_result_.raw_params_.count(); j++) { - ObPCParam *pc_param = pc_ctx.fp_result_.raw_params_.at(j); - if (OB_ISNULL(pc_param) || OB_ISNULL(pc_param->node_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("pc_param is null", K(ret), KP(pc_param)); - } else if (OB_FAIL(temp_store.push_back(pc_param))) { - LOG_WARN("failed to push back", K(ret)); - } else if (OB_FAIL(raw_pos.push_back(pc_param->node_->pos_ - total_delta_len))) { + if (OB_FAIL(temp_store.push_back(pc_ctx.fp_result_.raw_params_.at(j)))) { LOG_WARN("failed to push back", K(ret)); } } if (OB_SUCC(ret)) { if (OB_FAIL(rebuild_new_raw_sql(pc_ctx, temp_store, new_raw_idx, temp_store.count() - new_raw_idx, total_delta_len, new_no_param_sql, - new_raw_sql, no_param_sql_pos, new_raw_sql_pos))) { + no_param_pos, raw_sql_offset, new_raw_sql, no_param_sql_pos, + new_raw_sql_pos))) { LOG_WARN("failed to rebuild new raw sql", K(ret)); - } else if (OB_UNLIKELY(raw_pos.count() != temp_store.count())) { + } else if (OB_UNLIKELY(no_param_pos.count() != temp_store.count()) || + OB_UNLIKELY(raw_sql_offset.count() != temp_store.count())) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("param is invalid", K(ret)); + LOG_WARN("params is invalid", K(ret)); } else { int64_t len = new_no_param_sql.length() - no_param_sql_pos; if (OB_UNLIKELY(len < 0) || OB_UNLIKELY(new_raw_sql_pos + len > buff_len)) { @@ -385,7 +386,8 @@ int ObValuesTableCompression::try_batch_exec_params(ObIAllocator &allocator, fp_result.raw_params_.set_capacity(temp_store.count()); for (int64_t i = 0; i < temp_store.count(); i++) { // checked null before - temp_store.at(i)->node_->pos_ = raw_pos.at(i); + temp_store.at(i)->node_->pos_ = no_param_pos.at(i); + temp_store.at(i)->node_->raw_sql_offset_ = raw_sql_offset.at(i); } if (OB_FAIL(fp_result.raw_params_.assign(temp_store))) { LOG_WARN("fail to assign raw_param", K(ret)); @@ -446,12 +448,14 @@ int ObValuesTableCompression::resolve_params_for_values_clause(ObPlanCacheCtx &p obj_param, is_param, enable_decimal_int))) { LOG_WARN("failed to resolver param", K(ret), K(raw_idx)); } else if (!is_param) { - not_param_cnt++; // in value clause, which wonn't happen actually + not_param_cnt++; } else if (OB_FAIL(ab_params->push_back(obj_param))) { LOG_WARN("fail to push item to array", K(ret), K(raw_idx)); } } - + if (OB_SUCC(ret)) { + array_param_groups.at(i).start_param_idx_ -= not_param_cnt; + } // 1.2 build array_param in batch group for (int64_t j = 0; OB_SUCC(ret) && j < param_num; j++, raw_idx++, array_param_idx++) { ObArrayPCParam *raw_array_param = pc_ctx.fp_result_.array_params_.at(array_param_idx); @@ -564,7 +568,7 @@ int ObValuesTableCompression::resolve_params_for_values_clause(ObPlanCacheCtx &p bool enable_decimal_int = false; const ObIArray ¶m_charset_type = pc_ctx.param_charset_type_; if (OB_UNLIKELY(!pc_ctx.exec_ctx_.has_dynamic_values_table()) || OB_ISNULL(session) || - OB_ISNULL(phy_ctx) || OB_UNLIKELY(param_charset_type.count() != raw_param_cnt)) { + OB_ISNULL(phy_ctx) || OB_UNLIKELY(param_charset_type.count() > raw_param_cnt)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("sql should be mutil stmt", K(ret), KP(session), KP(phy_ctx), K(raw_param_cnt), K(param_charset_type.count())); @@ -573,6 +577,29 @@ int ObValuesTableCompression::resolve_params_for_values_clause(ObPlanCacheCtx &p } else { ParamStore &phy_param_store = phy_ctx->get_param_store_for_update(); ObIArray &array_param_groups = phy_ctx->get_array_param_groups(); + int64_t not_param_offset = 0; + int64_t tmp_raw_idx = 0; + for (int64_t i = 0; OB_SUCC(ret) && i < array_param_groups.count(); i++) { + int64_t array_idx = array_param_groups.at(i).start_param_idx_; + while (OB_SUCC(ret) && tmp_raw_idx < array_idx && tmp_raw_idx < raw_param_cnt) { + ObPCParam *pc_param = pc_ctx.fp_result_.raw_params_.at(tmp_raw_idx); + if (OB_ISNULL(pc_param)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("null expr", K(ret)); + } else if (pc_param->flag_ == NOT_PARAM) { + not_param_offset++; + } + tmp_raw_idx++; + } + if (OB_SUCC(ret)) { + if (OB_UNLIKELY(not_param_offset > array_idx)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected param", K(ret), K(array_idx), K(not_param_offset)); + } else { + array_param_groups.at(i).start_param_idx_ -= not_param_offset; + } + } + } for (int64_t i = 0; OB_SUCC(ret) && i < array_param_groups.count(); ++i) { int64_t param_num = array_param_groups.at(i).column_count_; int64_t batch_num = array_param_groups.at(i).row_count_; diff --git a/src/sql/plan_cache/ob_values_table_compression.h b/src/sql/plan_cache/ob_values_table_compression.h index ce5fc0146..784d43476 100644 --- a/src/sql/plan_cache/ob_values_table_compression.h +++ b/src/sql/plan_cache/ob_values_table_compression.h @@ -74,6 +74,8 @@ private: const int64_t param_cnt, const int64_t delta_length, const common::ObString &no_param_sql, + common::ObIArray &no_param_pos, + common::ObIArray &raw_sql_offset, common::ObString &new_raw_sql, int64_t &no_param_sql_pos, int64_t &new_raw_pos); diff --git a/src/sql/resolver/dml/ob_dml_resolver.cpp b/src/sql/resolver/dml/ob_dml_resolver.cpp index 00f6e0ac1..b189e7d91 100755 --- a/src/sql/resolver/dml/ob_dml_resolver.cpp +++ b/src/sql/resolver/dml/ob_dml_resolver.cpp @@ -15671,16 +15671,19 @@ int ObDMLResolver::resolve_values_table_item(const ParseNode &table_node, TableI } if (OB_SUCC(ret)) { int64_t column_cnt = 0; + ObSEArray res_types; //common values table: values row(...), row(...),... if (upper_insert_resolver_ == NULL && OB_FAIL(resolve_table_values_for_select(table_node, new_table_item->table_values_, + res_types, column_cnt))) { LOG_WARN("failed to resolve table values for select", K(ret)); //insert values table: insert into ....values row(...), row(...),... } else if (upper_insert_resolver_ != NULL && OB_FAIL(resolve_table_values_for_insert(table_node, new_table_item->table_values_, + res_types, column_cnt))) { LOG_WARN("failed to resolve table values for insert", K(ret)); } else { @@ -15691,7 +15694,7 @@ int ObDMLResolver::resolve_values_table_item(const ParseNode &table_node, TableI new_table_item->is_view_table_ = false; if (OB_FAIL(dml_stmt->add_table_item(session_info_, new_table_item))) { LOG_WARN("add table item failed", K(ret)); - } else if (OB_FAIL(gen_values_table_column_items(column_cnt, *new_table_item))) { + } else if (OB_FAIL(gen_values_table_column_items(column_cnt, res_types, *new_table_item))) { LOG_WARN("failed to gen values table column items", K(ret)); } else { table_item = new_table_item; @@ -15704,6 +15707,7 @@ int ObDMLResolver::resolve_values_table_item(const ParseNode &table_node, TableI int ObDMLResolver::resolve_table_values_for_select(const ParseNode &table_node, ObIArray &table_values, + ObIArray &res_types, int64_t &column_cnt) { int ret = OB_SUCCESS; @@ -15718,7 +15722,6 @@ int ObDMLResolver::resolve_table_values_for_select(const ParseNode &table_node, LOG_WARN("get unexpected null", K(ret), K(values_node), K(table_node.type_), K(table_node.num_child_), K(params_.expr_factory_)); } else { - ObSEArray res_types; for (int64_t i = 0; OB_SUCC(ret) && i < values_node->num_child_; i++) { ParseNode *vector_node = values_node->children_[i]; if (OB_ISNULL(vector_node) || @@ -15804,6 +15807,7 @@ int ObDMLResolver::resolve_table_values_for_select(const ParseNode &table_node, int ObDMLResolver::resolve_table_values_for_insert(const ParseNode &table_node, ObIArray &table_values, + ObIArray &res_types, int64_t &column_cnt) { int ret = OB_SUCCESS; @@ -15937,7 +15941,12 @@ int ObDMLResolver::resolve_table_values_for_insert(const ParseNode &table_node, if (OB_SUCC(ret)) { if (OB_FAIL(append(table_values, cur_values_vector))) { LOG_WARN("failed to append", K(ret)); - } else { + } else if (i == 0) { + for (int64_t k = 0; OB_SUCC(ret) && k < cur_values_vector.count(); k++) { + if (OB_FAIL(res_types.push_back(cur_values_vector.at(k)->get_result_type()))) { + LOG_WARN("failed to append", K(ret)); + } + } LOG_TRACE("succeed to resolve one row", K(cur_values_vector), K(table_values)); } } @@ -16018,12 +16027,15 @@ int ObDMLResolver::try_add_cast_to_values(const ObIArray &res_typ return ret; } -int ObDMLResolver::gen_values_table_column_items(const int64_t column_cnt, TableItem &table_item) +int ObDMLResolver::gen_values_table_column_items(const int64_t column_cnt, + const ObIArray &res_types, + TableItem &table_item) { int ret = OB_SUCCESS; if (OB_ISNULL(params_.expr_factory_) || OB_ISNULL(allocator_) || OB_ISNULL(get_stmt()) || OB_UNLIKELY(column_cnt <= 0 || table_item.table_values_.empty() || - table_item.table_values_.count() % column_cnt != 0)) { + table_item.table_values_.count() % column_cnt != 0 || + res_types.count() != column_cnt)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get unexpected error", K(column_cnt), K(params_.expr_factory_), K(table_item.table_values_), K(ret)); @@ -16036,7 +16048,7 @@ int ObDMLResolver::gen_values_table_column_items(const int64_t column_cnt, Table ret = OB_ERR_UNEXPECTED; LOG_WARN(("value desc is null")); } else { - column_expr->set_result_type(table_item.table_values_.at(i)->get_result_type()); + column_expr->set_result_type(res_types.at(i)); column_expr->set_result_flag(table_item.table_values_.at(i)->get_result_flag()); column_expr->set_ref_id(table_item.table_id_, i + OB_APP_MIN_COLUMN_ID); // compatible Mysql8.0, column name is column_0, column_1, ... @@ -16051,24 +16063,23 @@ int ObDMLResolver::gen_values_table_column_items(const int64_t column_cnt, Table MEMCPY(buf, tmp_col_name.ptr(), tmp_col_name.length()); ObString column_name(tmp_col_name.length(), buf); column_expr->set_column_attr(table_item.table_name_, column_name); - if (ob_is_enumset_tc(table_item.table_values_.at(i)->get_result_type().get_type()) - && OB_FAIL(column_expr->set_enum_set_values(table_item.table_values_.at(i)->get_enum_set_values()))) { - LOG_WARN("failed to set_enum_set_values", K(ret)); - } - if (OB_SUCC(ret)) { - if (OB_FAIL(column_expr->add_flag(IS_COLUMN))) { - LOG_WARN("failed to add flag IS_COLUMN", K(ret)); + if (ob_is_enumset_tc(column_expr->get_result_type().get_type()) || + column_expr->get_result_type().is_lob_storage()) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("values stmt not support such column type", K(ret)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "type of column in values table"); + } else if (OB_FAIL(column_expr->add_flag(IS_COLUMN))) { + LOG_WARN("failed to add flag IS_COLUMN", K(ret)); + } else { + ColumnItem column_item; + column_item.expr_ = column_expr; + column_item.table_id_ = column_expr->get_table_id(); + column_item.column_id_ = column_expr->get_column_id(); + column_item.column_name_ = column_expr->get_column_name(); + if (OB_FAIL(get_stmt()->add_column_item(column_item))) { + LOG_WARN("failed to add column item", K(ret)); } else { - ColumnItem column_item; - column_item.expr_ = column_expr; - column_item.table_id_ = column_expr->get_table_id(); - column_item.column_id_ = column_expr->get_column_id(); - column_item.column_name_ = column_expr->get_column_name(); - if (OB_FAIL(get_stmt()->add_column_item(column_item))) { - LOG_WARN("failed to add column item", K(ret)); - } else { - LOG_TRACE("succeed to gen table values desc", K(column_name), KPC(column_expr)); - } + LOG_TRACE("succeed to gen table values desc", K(column_name), KPC(column_expr)); } } } diff --git a/src/sql/resolver/dml/ob_dml_resolver.h b/src/sql/resolver/dml/ob_dml_resolver.h index 78e8251d5..eb7f08c25 100644 --- a/src/sql/resolver/dml/ob_dml_resolver.h +++ b/src/sql/resolver/dml/ob_dml_resolver.h @@ -935,11 +935,16 @@ private: int resolve_values_table_item(const ParseNode &table_node, TableItem *&table_item); int resolve_table_values_for_select(const ParseNode &table_node, ObIArray &table_values, + ObIArray &res_types, int64_t &column_cnt); int resolve_table_values_for_insert(const ParseNode &table_node, ObIArray &table_values, + ObIArray &res_types, int64_t &column_cnt); - int gen_values_table_column_items(const int64_t column_cnt, TableItem &table_item); + + int gen_values_table_column_items(const int64_t column_cnt, + const ObIArray &res_types, + TableItem &table_item); int get_values_res_types(const ObIArray &cur_values_types, ObIArray &res_types); int try_add_cast_to_values(const ObIArray &res_types, diff --git a/src/sql/rewrite/ob_transform_utils.cpp b/src/sql/rewrite/ob_transform_utils.cpp index 96ae06267..9778465de 100644 --- a/src/sql/rewrite/ob_transform_utils.cpp +++ b/src/sql/rewrite/ob_transform_utils.cpp @@ -2309,27 +2309,7 @@ int ObTransformUtils::is_column_expr_not_null(ObNotNullContext &ctx, LOG_WARN("failed to check expr not null", K(ret)); } } else if (table->is_values_table()) { - int64_t idx = expr->get_column_id() - OB_APP_MIN_COLUMN_ID; - int64_t column_cnt = ctx.stmt_->get_column_size(table->table_id_); - if (OB_UNLIKELY(idx >= column_cnt || column_cnt == 0 || table->table_values_.empty() || - table->table_values_.count() % column_cnt != 0)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("get unexpected error", K(ret), K(idx), KPC(table), K(column_cnt)); - } else { - is_not_null = true; - int64_t row_count = table->table_values_.count() / column_cnt; - for (int64_t i = 0; OB_SUCC(ret) && is_not_null && i < row_count; ++i) { - if (OB_UNLIKELY(column_cnt * i + idx >= table->table_values_.count())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("get unexpected error", K(ret), K(i), K(idx), KPC(table), K(column_cnt)); - } else if (OB_FAIL(is_expr_not_null(ctx, - table->table_values_.at(column_cnt * i + idx), - is_not_null, - constraints))) { - LOG_WARN("failed to check expr not null", K(ret)); - } else {/*do nothing*/} - } - } + // It is temporarily considered that the values table is not satisfied. } else { // do nothing }