diff --git a/src/pl/ob_pl.cpp b/src/pl/ob_pl.cpp index 4d42702d8..60c147a21 100644 --- a/src/pl/ob_pl.cpp +++ b/src/pl/ob_pl.cpp @@ -1666,7 +1666,7 @@ int ObPL::parameter_anonymous_block(ObExecContext &ctx, } // for execute anonymous -int ObPL::execute(ObExecContext &ctx, const ObStmtNodeTree *block) +int ObPL::execute(ObExecContext &ctx, ParamStore ¶ms, const ObStmtNodeTree *block) { int ret = OB_SUCCESS; FLTSpanGuard(pl_entry); @@ -1674,7 +1674,7 @@ int ObPL::execute(ObExecContext &ctx, const ObStmtNodeTree *block) lib::ContextParam param; ObPLFunction *routine = NULL; ObCacheObjGuard cacheobj_guard(PL_ANON_HANDLE); - bool is_forbid_anony_parameter = block->is_forbid_anony_parameter_; + bool is_forbid_anony_parameter = block->is_forbid_anony_parameter_ || (params.count() > 0); int64_t old_worker_timeout_ts = 0; /* !!! * PL,req_timeinfo_guard一定要在执行前定义 @@ -1726,7 +1726,7 @@ int ObPL::execute(ObExecContext &ctx, const ObStmtNodeTree *block) K(ret), K(sizeof(ObPLFunction))); } OX (routine = new(routine)ObPLFunction(mem_context)); - OZ (compiler.compile(block, *routine, NULL, false)); + OZ (compiler.compile(block, *routine, ¶ms, false)); OX (routine->set_debug_priv()); } } @@ -1747,7 +1747,7 @@ int ObPL::execute(ObExecContext &ctx, const ObStmtNodeTree *block) ctx.get_allocator(), *(ctx.get_package_guard()), *routine, - is_forbid_anony_parameter ? NULL : &exec_params, // params + is_forbid_anony_parameter ? ¶ms : &exec_params, // params NULL, // nocopy params NULL, // result NULL, // status diff --git a/src/pl/ob_pl.h b/src/pl/ob_pl.h index 7cbc71f44..9fa16bdcf 100644 --- a/src/pl/ob_pl.h +++ b/src/pl/ob_pl.h @@ -1105,6 +1105,7 @@ public: int trans_sql(PlTransformTreeCtx &trans_ctx, ParseNode *root, ObExecContext &ctx); // for anonymous int execute(sql::ObExecContext &ctx, + ParamStore ¶ms, const ObStmtNodeTree *block); // for normal routine or package routine diff --git a/src/pl/ob_pl_resolver.cpp b/src/pl/ob_pl_resolver.cpp index a58459294..6b755ca23 100644 --- a/src/pl/ob_pl_resolver.cpp +++ b/src/pl/ob_pl_resolver.cpp @@ -8593,9 +8593,11 @@ int ObPLResolver::resolve_condition_compile( ObPLResolver resolver( allocator, session, *schema_guard, *package_guard, *sql_proxy, expr_factory, NULL, false); + int64_t question_mark_count = 0; OZ (resolver.resolve_condition_compile( node, new_node, + question_mark_count, is_inner_parse, is_for_trigger, is_for_dynamic, @@ -8612,9 +8614,11 @@ int ObPLResolver::resolve_condition_compile( ObPLResolver resolver( allocator, *session_info, *schema_guard, *package_guard, *sql_proxy, expr_factory, NULL, false); + int64_t question_mark_count = 0; OZ (resolver.resolve_condition_compile( node, new_node, + question_mark_count, is_inner_parse, is_for_trigger, is_for_dynamic, @@ -8627,6 +8631,7 @@ int ObPLResolver::resolve_condition_compile( int ObPLResolver::resolve_condition_compile( const ParseNode *node, const ParseNode *&new_node, + int64_t &question_mark_count, bool is_inner_parse, bool is_for_trigger, bool is_for_dynamic, @@ -8657,6 +8662,7 @@ int ObPLResolver::resolve_condition_compile( CK (1 == parse_result.result_tree_->num_child_); CK (OB_NOT_NULL(new_node = parse_result.result_tree_->children_[0])); + OX (question_mark_count = parse_result.question_mark_ctx_.count_); if (OB_SUCC(ret) && T_SP_CREATE_TYPE == new_node->type_) { ret = OB_ERR_DIRECTIVE_CONTEXT; LOG_WARN("preprocessor directives are not supported in this context", diff --git a/src/pl/ob_pl_resolver.h b/src/pl/ob_pl_resolver.h index eed59f538..ae6881d4d 100644 --- a/src/pl/ob_pl_resolver.h +++ b/src/pl/ob_pl_resolver.h @@ -510,6 +510,7 @@ public: int resolve_condition_compile( const ParseNode *node, const ParseNode *&new_node, + int64_t &question_mark_count, bool is_inner_parse = false, bool is_for_trigger = false, bool is_for_dynamic = false, diff --git a/src/sql/engine/cmd/ob_routine_executor.cpp b/src/sql/engine/cmd/ob_routine_executor.cpp index 382964e69..b8df360e3 100644 --- a/src/sql/engine/cmd/ob_routine_executor.cpp +++ b/src/sql/engine/cmd/ob_routine_executor.cpp @@ -437,7 +437,8 @@ int ObAnonymousBlockExecutor::execute(ObExecContext &ctx, ObAnonymousBlockStmt & } } } else { - OZ (ctx.get_pl_engine()->execute(ctx, stmt.get_body())); + CK (OB_NOT_NULL(stmt.get_params())); + OZ (ctx.get_pl_engine()->execute(ctx, *stmt.get_params(), stmt.get_body())); } return ret; } diff --git a/src/sql/resolver/cmd/ob_anonymous_block_resolver.cpp b/src/sql/resolver/cmd/ob_anonymous_block_resolver.cpp index 13b1b9c8b..048ea06f7 100644 --- a/src/sql/resolver/cmd/ob_anonymous_block_resolver.cpp +++ b/src/sql/resolver/cmd/ob_anonymous_block_resolver.cpp @@ -87,6 +87,7 @@ int ObAnonymousBlockResolver::resolve(const ParseNode &parse_tree) || T_SP_LABELED_BLOCK == block_node->type_)); OX (stmt->set_prepare_protocol(false)); OX (stmt->set_body(block_node)); + OZ (add_param()); } } return ret; @@ -157,9 +158,19 @@ int ObAnonymousBlockResolver::add_param() anonymous_stmt = static_cast(stmt_); } CK (OB_NOT_NULL(anonymous_stmt)); - for (int64_t i = 0; OB_SUCC(ret) && i < params_.param_list_->count(); ++i) { - if (OB_FAIL(anonymous_stmt->add_param(params_.param_list_->at(i)))) { - LOG_WARN("fail to push back param", K(i), K(ret)); + if (OB_FAIL(ret)) { + } else if (params_.param_list_->count() > 0) { + CK (params_.param_list_->count() == params_.query_ctx_->question_marks_count_); + for (int64_t i = 0; OB_SUCC(ret) && i < params_.param_list_->count(); ++i) { + if (OB_FAIL(anonymous_stmt->add_param(params_.param_list_->at(i)))) { + LOG_WARN("fail to push back param", K(i), K(ret)); + } + } + } else if (params_.query_ctx_->question_marks_count_ > 0) { + for (int64_t i =0; OB_SUCC(ret) && i < params_.query_ctx_->question_marks_count_; ++i) { + if (OB_FAIL(anonymous_stmt->add_param(ObObjParam(ObObj(ObNullType))))) { + LOG_WARN("failed to push back param", K(ret), K(i)); + } } } return ret; diff --git a/src/sql/resolver/ob_resolver.cpp b/src/sql/resolver/ob_resolver.cpp index e040fe2aa..af6f50a83 100644 --- a/src/sql/resolver/ob_resolver.cpp +++ b/src/sql/resolver/ob_resolver.cpp @@ -222,7 +222,7 @@ int ObResolver::resolve(IsPrepared if_prepared, const ParseNode &parse_tree, ObS *(params_.expr_factory_), NULL, params_.is_prepare_protocol_); - OZ (resolver.resolve_condition_compile(&parse_tree, real_parse_tree)); + OZ (resolver.resolve_condition_compile(&parse_tree, real_parse_tree, params_.query_ctx_->question_marks_count_)); } else { real_parse_tree = &parse_tree; }