diff --git a/src/sql/ob_sql.cpp b/src/sql/ob_sql.cpp index 6aa6a3a15811b1aea51d62773604bfb4a384aa68..b426320e477b220c713324a29efe7e3489af4f40 100644 --- a/src/sql/ob_sql.cpp +++ b/src/sql/ob_sql.cpp @@ -808,7 +808,8 @@ int ObSql::construct_not_paramalize( return ret; } -int ObSql::construct_no_check_type_params(const ObIArray &offsets, ParamStore ¶ms_store) +int ObSql::construct_no_check_type_params( + const ObIArray &offsets, const ObBitSet<> &need_check_type_offsets, ParamStore ¶ms_store) { int ret = OB_SUCCESS; for (int64_t i = 0; OB_SUCC(ret) && i < offsets.count(); i++) { @@ -816,6 +817,8 @@ int ObSql::construct_no_check_type_params(const ObIArray &offsets, Para if (offset < 0 || offset >= params_store.count()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("Invalid offset", K(ret), K(offset), K(params_store.count())); + } else if (need_check_type_offsets.has_member(offset)) { + // do nothing } else if (!params_store.at(offset).is_ext()) { // extend type need to be checked params_store.at(offset).set_need_to_check_type(false); } else { @@ -3255,6 +3258,7 @@ int ObSql::handle_parser(const ObString &sql, ObExecContext &exec_ctx, ObPlanCac int64_t question_mark_count = 0; ObArray not_param_offsets; ObArray no_check_type_offsets; + ObBitSet<> need_check_type_param_offsets; ObIAllocator &allocator = pc_ctx.allocator_; ObSQLSessionInfo &session = *(pc_ctx.sql_ctx_.session_info_); ObParser parser(allocator, session.get_sql_mode(), session.get_local_collation_connection()); @@ -3263,12 +3267,16 @@ int ObSql::handle_parser(const ObString &sql, ObExecContext &exec_ctx, ObPlanCac } else if (OB_ISNULL(parse_result.result_tree_)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("result_tree should not be null", K(ret), K(sql)); - } else if (OB_FAIL(helper.find_special_paramalize( - *parse_result.result_tree_, question_mark_count, no_check_type_offsets, not_param_offsets))) { + } else if (OB_FAIL(helper.find_special_paramalize(*parse_result.result_tree_, + question_mark_count, + no_check_type_offsets, + need_check_type_param_offsets, + not_param_offsets))) { LOG_WARN("invalid argument", K(ret), KP(parse_result.result_tree_)); } else if (OB_FAIL(construct_not_paramalize(not_param_offsets, pctx->get_param_store(), pc_ctx))) { LOG_WARN("construct not paramalize failed", K(ret)); - } else if (OB_FAIL(construct_no_check_type_params(no_check_type_offsets, pctx->get_param_store_for_update()))) { + } else if (OB_FAIL(construct_no_check_type_params( + no_check_type_offsets, need_check_type_param_offsets, pctx->get_param_store_for_update()))) { LOG_WARN("construct no check type params failed", K(ret)); } else { parse_result.question_mark_ctx_.count_ = static_cast(question_mark_count); diff --git a/src/sql/ob_sql.h b/src/sql/ob_sql.h index 904403c0e275e5e100c73c846957e1fa70d13930..4c8fb0f75deb31eb5e0448446866db23fb77de7b 100644 --- a/src/sql/ob_sql.h +++ b/src/sql/ob_sql.h @@ -191,7 +191,9 @@ public: static int construct_not_paramalize( const ObIArray& offsets, const ParamStore& param_store, ObPlanCacheCtx& plan_ctx); - static int construct_no_check_type_params(const ObIArray& offsets, ParamStore& param_store); + static int construct_no_check_type_params(const ObIArray& offsets, + const ObBitSet<> &need_check_type_offsets, + ParamStore& param_store); static int construct_ps_param(const ParamStore& params, ObPlanCacheCtx& phy_ctx); storage::ObPartitionService* get_partition_service() const diff --git a/src/sql/plan_cache/ob_ps_sql_utils.cpp b/src/sql/plan_cache/ob_ps_sql_utils.cpp index dd6f7037ef11cf0cb02ca8e0d852d63dec22e899..df3ccc0c472bd3d94b19eb957a76ad83f1b9842c 100644 --- a/src/sql/plan_cache/ob_ps_sql_utils.cpp +++ b/src/sql/plan_cache/ob_ps_sql_utils.cpp @@ -35,8 +35,8 @@ int ObPsSqlUtils::deep_copy_str(common::ObIAllocator& allocator, const common::O return ret; } -int ObPsSqlParamHelper::find_special_paramalize(const ParseNode& parse_node, int64_t& question_mark_count, - ObIArray& no_check_type_offsets, ObIArray& not_param_offsets) +int ObPsSqlParamHelper::find_special_paramalize(const ParseNode &parse_node, int64_t &question_mark_count, + ObIArray &no_check_type_offsets, ObBitSet<> &need_check_type_offsets, ObIArray ¬_param_offsets) { int ret = OB_SUCCESS; TraverseContext ctx; @@ -44,7 +44,7 @@ int ObPsSqlParamHelper::find_special_paramalize(const ParseNode& parse_node, int question_mark_count = 0; SQL_PC_LOG(DEBUG, "traverse syntax tree for ps mode", "result_tree", SJ(ObParserResultPrintWrapper(parse_node))); - if (OB_FAIL(traverse(ctx, no_check_type_offsets, not_param_offsets))) { + if (OB_FAIL(traverse(ctx, no_check_type_offsets, need_check_type_offsets, not_param_offsets))) { LOG_WARN("traverse node failed", K(ret)); } else { question_mark_count = ctx.question_marks_.num_members(); @@ -58,8 +58,10 @@ int ObPsSqlParamHelper::find_special_paramalize(const ParseNode& parse_node, int // return bret; //} -int ObPsSqlParamHelper::traverse( - TraverseContext& ctx, ObIArray& no_check_type_offsets, ObIArray& not_param_offsets) +// TODO: 这里目前比较受限,只能判断是否对整个表达式的子节点是否not param +// 应该按照ObSqlParameterization::mark_tree()的方式来做 +int ObPsSqlParamHelper::traverse(TraverseContext &ctx, ObIArray &no_check_type_offsets, + ObBitSet<> &need_check_type_offsets, ObIArray ¬_param_offsets) { int ret = OB_SUCCESS; bool is_overflow = false; @@ -87,13 +89,18 @@ int ObPsSqlParamHelper::traverse( LOG_INFO("pushback offset success", K(ctx)); } } - if (OB_SUCC(ret) && INSERT_VALUE_VECTOR_CHILD_LEVEL == ctx.insert_vector_level_) { + if (OB_FAIL(ret)) { + } else if (INSERT_VALUE_VECTOR_CHILD_LEVEL == ctx.insert_vector_level_) { // insert values (?, ?), ? do not need check type if (OB_FAIL(no_check_type_offsets.push_back(parent.value_))) { LOG_WARN("failed to push back element", K(ret)); } else { LOG_DEBUG("pushback offset success", K(ret), K(parent.value_)); } + } else { + if (OB_FAIL(need_check_type_offsets.add_member(parent.value_))) { + LOG_WARN("failed to add member", K(parent.value_)); + } } if (OB_SUCC(ret)) { if (OB_FAIL(ctx.question_marks_.add_member(parent.value_))) { @@ -124,7 +131,7 @@ int ObPsSqlParamHelper::traverse( ctx.is_child_not_param_ = true; } ctx.node_ = parent.children_[i]; - if (OB_FAIL(traverse(ctx, no_check_type_offsets, not_param_offsets))) { + if (OB_FAIL(traverse(ctx, no_check_type_offsets, need_check_type_offsets, not_param_offsets))) { LOG_WARN("visit child node failed", K(i)); } } diff --git a/src/sql/plan_cache/ob_ps_sql_utils.h b/src/sql/plan_cache/ob_ps_sql_utils.h index 667a5687d1be58d0d3958e460751e18ae443db76..c85cbf31044c2d91a761e35c614abb74a71313ec 100644 --- a/src/sql/plan_cache/ob_ps_sql_utils.h +++ b/src/sql/plan_cache/ob_ps_sql_utils.h @@ -98,13 +98,14 @@ public: {} // find param that should no be paramalize - int find_special_paramalize(const ParseNode& parse_node, int64_t& question_mark_count, - common::ObIArray& no_check_type_offsets, common::ObIArray& not_param_offsets); + int find_special_paramalize(const ParseNode &parse_node, int64_t &question_mark_count, + common::ObIArray &no_check_type_offsets, common::ObBitSet<> &need_check_type_offsets, + common::ObIArray ¬_param_offsets); private: static const int64_t INSERT_VALUE_VECTOR_CHILD_LEVEL = 1; - int traverse(TraverseContext& ctx, common::ObIArray& no_check_type_offsets, - common::ObIArray& not_param_offsets); + int traverse(TraverseContext &ctx, common::ObIArray &no_check_type_offsets, + common::ObBitSet<> &need_check_type_offsets, common::ObIArray ¬_param_offsets); private: DISALLOW_COPY_AND_ASSIGN(ObPsSqlParamHelper);