[CP] fix serialize ObSqlArrayObj bugs

This commit is contained in:
jingtaoye35 2024-01-02 13:13:05 +00:00 committed by ob-robot
parent 47aea9865a
commit bff45aaa70
10 changed files with 239 additions and 154 deletions

View File

@ -2320,8 +2320,8 @@ template <>
inline int obj_val_serialize<ObExtendType>(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<ObExtendType>(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<const ObSqlArrayObj*>(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<ObExtendType>(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<int64_t>(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<ObExtendType>(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<ObExtendType>(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<const ObSqlArrayObj*>(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;
}

View File

@ -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<const ObSqlArrayObj*>(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<const void*>(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<ObSqlArrayObj *>(const_cast<char *>(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<ObObjParam *>(const_cast<char *>(buf + pos));
pos += n;
}
}
if (OB_SUCC(ret)) {
set_extend(reinterpret_cast<int64_t>(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<const ObSqlArrayObj*>(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;
}

View File

@ -4150,6 +4150,10 @@ struct ObSqlArrayObj
}
typedef common::ObArrayWrap<common::ObObjParam> 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_;

View File

@ -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<char *>(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<int64_t>(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

View File

@ -466,6 +466,7 @@ public:
int set_all_local_session_vars(ObIArray<ObLocalSessionVar> &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);

View File

@ -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<int64_t> &no_param_pos,
ObIArray<int64_t> &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<int64_t, 16> raw_pos;
ObSEArray<int64_t, 16> no_param_pos;
ObSEArray<int64_t, 16> 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<ObCharsetType> &param_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<ObArrayParamGroup> &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_;

View File

@ -74,6 +74,8 @@ private:
const int64_t param_cnt,
const int64_t delta_length,
const common::ObString &no_param_sql,
common::ObIArray<int64_t> &no_param_pos,
common::ObIArray<int64_t> &raw_sql_offset,
common::ObString &new_raw_sql,
int64_t &no_param_sql_pos,
int64_t &new_raw_pos);

View File

@ -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<ObExprResType, 8> 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<ObRawExpr*> &table_values,
ObIArray<ObExprResType> &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<ObExprResType, 8> 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<ObRawExpr*> &table_values,
ObIArray<ObExprResType> &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<ObExprResType> &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<ObExprResType> &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));
}
}
}

View File

@ -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<ObRawExpr*> &table_values,
ObIArray<ObExprResType> &res_types,
int64_t &column_cnt);
int resolve_table_values_for_insert(const ParseNode &table_node,
ObIArray<ObRawExpr*> &table_values,
ObIArray<ObExprResType> &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<ObExprResType> &res_types,
TableItem &table_item);
int get_values_res_types(const ObIArray<ObExprResType> &cur_values_types,
ObIArray<ObExprResType> &res_types);
int try_add_cast_to_values(const ObIArray<ObExprResType> &res_types,

View File

@ -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
}