Fix insert use incorrect plan bug

This commit is contained in:
2149
2023-08-04 03:18:27 +00:00
committed by ob-robot
parent 1bd325cc15
commit 82e3f02450
8 changed files with 62 additions and 3 deletions

View File

@ -2755,6 +2755,7 @@ int ObSql::generate_stmt(ParseResult &parse_result,
context.all_pre_calc_constraints_ = &(resolver_ctx.query_ctx_->all_pre_calc_constraints_);
context.all_expr_constraints_ = &(resolver_ctx.query_ctx_->all_expr_constraints_);
context.all_priv_constraints_ = &(resolver_ctx.query_ctx_->all_priv_constraints_);
context.need_match_all_params_ = resolver_ctx.query_ctx_->need_match_all_params_;
context.cur_stmt_ = stmt;
context.res_map_rule_id_ = resolver_ctx.query_ctx_->res_map_rule_id_;
context.res_map_rule_param_idx_ = resolver_ctx.query_ctx_->res_map_rule_param_idx_;

View File

@ -187,6 +187,7 @@ ObSqlCtx::ObSqlCtx()
all_pre_calc_constraints_(nullptr),
all_expr_constraints_(nullptr),
all_priv_constraints_(nullptr),
need_match_all_params_(false),
is_ddl_from_primary_(false),
cur_stmt_(NULL),
cur_plan_(nullptr),
@ -236,6 +237,7 @@ void ObSqlCtx::reset()
all_pre_calc_constraints_ = nullptr;
all_expr_constraints_ = nullptr;
all_priv_constraints_ = nullptr;
need_match_all_params_ = false;
is_ddl_from_primary_ = false;
can_reroute_sql_ = false;
is_sensitive_ = false;

View File

@ -522,6 +522,7 @@ public:
common::ObDList<ObPreCalcExprConstraint> *all_pre_calc_constraints_;
common::ObIArray<ObExprConstraint> *all_expr_constraints_;
common::ObIArray<ObPCPrivInfo> *all_priv_constraints_;
bool need_match_all_params_; //only used for matching plans
bool is_ddl_from_primary_;//备集群从主库同步过来需要处理的ddl sql语句
const sql::ObStmt *cur_stmt_;
const ObPhysicalPlan *cur_plan_;
@ -565,6 +566,7 @@ public:
temp_table_count_(0),
anonymous_view_count_(0),
all_user_variable_(),
need_match_all_params_(false),
has_udf_(false),
disable_udf_parallel_(false),
has_is_table_(false),
@ -604,6 +606,7 @@ public:
temp_table_count_ = 0;
anonymous_view_count_ = 0;
all_user_variable_.reset();
need_match_all_params_= false;
has_udf_ = false;
disable_udf_parallel_ = false;
has_is_table_ = false;
@ -680,6 +683,7 @@ public:
common::ObSArray<ObPCPrivInfo, common::ModulePageAllocator, true> all_priv_constraints_;
common::ObSArray<ObUserVarIdentRawExpr *, common::ModulePageAllocator, true> all_user_variable_;
common::hash::ObHashMap<uint64_t, ObObj, common::hash::NoPthreadDefendMode> calculable_expr_results_;
bool need_match_all_params_; //only used for matching plans
bool has_udf_;
bool disable_udf_parallel_; //used to deterministic pl udf parallel execute
bool has_is_table_; // used to mark query has information schema table

View File

@ -235,7 +235,7 @@ int ObPlanSet::match_param_info(const ObParamInfo &param_info,
// insert into t values (:0)
// two sql have the same key `insert into t values (?)`
// but they have complete different plans
if (param_info.flag_.need_to_check_type_
if ((param_info.flag_.need_to_check_type_ || need_match_all_params_)
|| (is_sql_planset && lib::is_oracle_mode() &&
(param_info.type_ == ObTinyIntType || param.get_type() == ObTinyIntType))) {
if (lib::is_oracle_mode() &&
@ -497,7 +497,8 @@ int ObPlanSet::match_params_info(const Ob2DArray<ObParamInfo,
} else {
int64_t N = infos.count();
for (int64_t i = 0; is_same && i < N; ++i) {
if (true == is_same && params_info_.at(i).flag_.need_to_check_type_) {
if (true == is_same
&& (params_info_.at(i).flag_.need_to_check_type_ || need_match_all_params_)) {
if (infos.at(i).type_ != params_info_.at(i).type_
|| infos.at(i).scale_ != params_info_.at(i).scale_
|| infos.at(i).col_type_ != params_info_.at(i).col_type_
@ -658,6 +659,7 @@ int ObPlanSet::init_new_set(const ObPlanCacheCtx &pc_ctx,
SQL_PC_LOG(WARN, "fail to push back param info", K(ret));
}
}
need_match_all_params_ = sql_ctx.need_match_all_params_;
// add user session vars if necessary
CK( OB_NOT_NULL(sql_ctx.session_info_) );

View File

@ -115,6 +115,7 @@ public:
all_plan_const_param_constraints_(alloc_),
all_pre_calc_constraints_(),
all_priv_constraints_(),
need_match_all_params_(false),
multi_stmt_rowkey_pos_(alloc_),
pre_cal_expr_handler_(NULL),
res_map_rule_id_(common::OB_INVALID_ID),
@ -234,6 +235,8 @@ protected:
EqualParamConstraint all_equal_param_constraints_;
PreCalcExprConstraint all_pre_calc_constraints_;
PrivConstraint all_priv_constraints_;
//if true, check the datatypes of all params
bool need_match_all_params_;
// maintain the rowkey position for multi_stmt
common::ObFixedArray<int64_t, common::ObIAllocator> multi_stmt_rowkey_pos_;
// pre calculable expression list handler.

View File

@ -3196,7 +3196,7 @@ int ObDelUpdResolver::resolve_insert_values(const ParseNode *node,
uint64_t value_count = OB_INVALID_ID;
bool is_all_default = false;
if (OB_ISNULL(del_upd_stmt) || OB_ISNULL(node) || OB_ISNULL(session_info_) ||
T_VALUE_LIST != node->type_ || OB_ISNULL(node->children_)) {
T_VALUE_LIST != node->type_ || OB_ISNULL(node->children_) || OB_ISNULL(del_upd_stmt->get_query_ctx())) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid arguemnt", K(del_upd_stmt), K(node), K(session_info_), K(ret));
} else if (is_oracle_mode() && 1 < node->num_child_) {
@ -3214,6 +3214,12 @@ int ObDelUpdResolver::resolve_insert_values(const ParseNode *node,
// works for most cases. except label security/timestamp generation needs extend memory
LOG_WARN("reserve memory fail", K(ret));
}
if (OB_SUCC(ret)) {
if (OB_FAIL(check_need_match_all_params(table_info.values_desc_,
del_upd_stmt->get_query_ctx()->need_match_all_params_))) {
LOG_WARN("check need match all params failed", K(ret));
}
}
if (OB_SUCC(ret)) {
//move generated columns behind basic columns before resolve values
ObArray<ObColumnRefRawExpr*> tmp_values_desc;
@ -4498,5 +4504,39 @@ int ObDelUpdResolver::recursive_search_sequence_expr(const ObRawExpr *default_ex
return ret;
}
int ObDelUpdResolver::check_need_match_all_params(const common::ObIArray<ObColumnRefRawExpr*> &value_descs, bool &need_match)
{
int ret = OB_SUCCESS;
need_match = false;
ObSEArray<uint64_t, 4> col_ids;
ObBitSet<> column_bs;
for (int64_t i = 0; OB_SUCC(ret) && i < value_descs.count() && !need_match; ++i) {
ObColumnRefRawExpr *value_desc = value_descs.at(i);
if (OB_ISNULL(value_desc)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("value desc is null", K(ret), K(value_descs));
} else if (OB_FAIL(column_bs.add_member(value_desc->get_column_id()))) {
LOG_WARN("add column id failed", K(ret));
}
}
//if a depend column exists in value_desc, need match the datatypes of all params
for (int64_t i = 0; OB_SUCC(ret) && i < value_descs.count() && !need_match; ++i) {
if (value_descs.at(i)->is_generated_column()) {
col_ids.reset();
if (OB_FAIL(ObRawExprUtils::extract_column_ids(value_descs.at(i)->get_dependant_expr(),
col_ids))) {
LOG_WARN("extract column exprs failed", K(ret));
} else {
for (int64_t j = 0; j < col_ids.count() && !need_match; ++j) {
if (column_bs.has_member(col_ids.at(j))) {
need_match = true;
}
}
}
}
}
return ret;
}
} /* namespace sql */
} /* namespace oceanbase */

View File

@ -252,6 +252,7 @@ protected:
int replace_column_ref_for_check_constraint(ObInsertTableInfo& table_info, ObRawExpr *&expr);
int add_default_sequence_id_to_stmt(const uint64_t table_id);
int recursive_search_sequence_expr(const ObRawExpr *default_expr);
int check_need_match_all_params(const common::ObIArray<ObColumnRefRawExpr*> &value_desc, bool &need_match);
private:
common::hash::ObPlacementHashSet<uint64_t, 4229> insert_column_ids_;
bool is_column_specify_;

View File

@ -510,6 +510,12 @@ int ObInsertResolver::resolve_insert_assign(const ParseNode &assign_list)
}
}
}
if (OB_SUCC(ret)) {
if (OB_FAIL(check_need_match_all_params(insert_stmt->get_insert_table_info().values_desc_,
insert_stmt->get_query_ctx()->need_match_all_params_))) {
LOG_WARN("check need match all params failed", K(ret));
}
}
const ObIArray<ObColumnRefRawExpr*> &dep_cols = insert_stmt->get_insert_table_info().part_generated_col_dep_cols_;
if (OB_SUCC(ret) && 0 != dep_cols.count()) {
ColumnItem *col_item = NULL;