From 54fbf31d943167410626a95ec39ce14426d4ea33 Mon Sep 17 00:00:00 2001 From: obdev Date: Tue, 23 May 2023 05:11:45 +0000 Subject: [PATCH] [to #49602206] no codegen objaccess & can calc it in pure sql context --- src/pl/ob_pl_resolver.cpp | 13 +- .../code_generator/ob_expr_generator_impl.cpp | 9 +- src/sql/engine/expr/ob_expr_obj_access.cpp | 166 +++++++++++++++++- src/sql/engine/expr/ob_expr_obj_access.h | 18 +- src/sql/resolver/dml/ob_dml_resolver.cpp | 126 ++++++++----- src/sql/resolver/dml/ob_dml_resolver.h | 3 + src/sql/resolver/expr/ob_raw_expr_printer.cpp | 35 ++-- 7 files changed, 285 insertions(+), 85 deletions(-) diff --git a/src/pl/ob_pl_resolver.cpp b/src/pl/ob_pl_resolver.cpp index b6591bc020..87a50e2bd9 100644 --- a/src/pl/ob_pl_resolver.cpp +++ b/src/pl/ob_pl_resolver.cpp @@ -8972,7 +8972,9 @@ int ObPLResolver::resolve_inner_call( OZ (resolve_obj_access_idents(*parse_tree->children_[0], obj_access_idents, func)); OZ (init_udf_info_of_accessidents(obj_access_idents)); for (int64_t i = 0; OB_SUCC(ret) && i < obj_access_idents.count(); ++i) { - bool is_routine = obj_access_idents.at(i).is_pl_udf(); + // TODO: distinguish coll(idx).proc() and func(arg1).proc() + bool is_routine = obj_access_idents.at(i).is_pl_udf() + || (obj_access_idents.at(i).params_.count() != 1 && obj_access_idents.at(i).has_brackets_); if (i == obj_access_idents.count() - 1) { if (access_idxs.count() > 0) { if (access_idxs.at(access_idxs.count() - 1).access_type_ == ObObjAccessIdx::IS_DB_NS @@ -9881,7 +9883,8 @@ int ObPLResolver::resolve_udf_without_brackets( OX (udf_expr->set_func_name(q_name.col_name_)); OX (udf_info.ref_expr_ = udf_expr); OX (udf_info.udf_name_ = access_ident.access_name_); - OZ (resolve_name(q_name, current_block_->get_namespace(), expr_factory_, &resolve_ctx_.session_info_, access_idxs, unit_ast)); + OZ (resolve_name(q_name, current_block_->get_namespace(), expr_factory_, &resolve_ctx_.session_info_, access_idxs, unit_ast), + K(access_idxs), K(q_name)); OV (access_idxs.at(access_idxs.count() - 1).is_udf_type()); OX (expr = access_idxs.at(access_idxs.count() - 1).get_sysfunc_); CK (OB_NOT_NULL(expr)); @@ -11668,7 +11671,9 @@ int ObPLMockSelfArg::mock() { int ret = OB_SUCCESS; if (access_idxs_.count() > 0 && expr_params_.count() > 0) { - if (ObObjAccessIdx::IS_UDT_NS == access_idxs_.at(access_idxs_.count() - 1).access_type_ + if (expr_params_.at(0)->has_flag(IS_UDT_UDF_SELF_PARAM)) { + // already has self argument, do nothing ... + } else if (ObObjAccessIdx::IS_UDT_NS == access_idxs_.at(access_idxs_.count() - 1).access_type_ && expr_params_.at(0)->get_result_type().get_udt_id() == access_idxs_.at(access_idxs_.count() - 1).var_index_) { expr_params_.at(0)->add_flag(IS_UDT_UDF_SELF_PARAM); @@ -14820,7 +14825,7 @@ int ObPLResolver::replace_map_or_order_expr( if (routine_infos.at(i)->is_udt_order()) { CK (OB_ISNULL(routine_info)); OX (routine_info = routine_infos.at(i)); - } else if (routine_info->is_udt_map()) { + } else if (routine_infos.at(i)->is_udt_map()) { CK (OB_ISNULL(routine_info)); OX (routine_info = routine_infos.at(i)); } diff --git a/src/sql/code_generator/ob_expr_generator_impl.cpp b/src/sql/code_generator/ob_expr_generator_impl.cpp index d9f67321fe..ce9c1a47e4 100644 --- a/src/sql/code_generator/ob_expr_generator_impl.cpp +++ b/src/sql/code_generator/ob_expr_generator_impl.cpp @@ -1523,13 +1523,8 @@ int ObExprGeneratorImpl::visit(ObOpRawExpr &expr) } else if (T_OBJ_ACCESS_REF == expr.get_expr_type()) { ObExprObjAccess *obj_access_op = static_cast(op); const ObObjAccessRawExpr &obj_access_expr = static_cast(expr); - if (OB_ISNULL(reinterpret_cast(obj_access_expr.get_get_attr_func_addr()))) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("func addr is NULL", K(obj_access_expr), K(obj_access_expr.get_var_indexs()), K(ret)); - } else { - obj_access_op->set_real_param_num(static_cast(obj_access_expr.get_param_count())); - OZ(obj_access_op->get_info().from_raw_expr(obj_access_expr)); - } + obj_access_op->set_real_param_num(static_cast(obj_access_expr.get_param_count())); + OZ(obj_access_op->get_info().from_raw_expr(obj_access_expr)); } else if (T_OP_MULTISET == expr.get_expr_type()) { ObExprMultiSet *ms_op = static_cast(op); const ObMultiSetRawExpr &ms_expr = static_cast(expr); diff --git a/src/sql/engine/expr/ob_expr_obj_access.cpp b/src/sql/engine/expr/ob_expr_obj_access.cpp index 5169884a8c..4fe94c81cc 100644 --- a/src/sql/engine/expr/ob_expr_obj_access.cpp +++ b/src/sql/engine/expr/ob_expr_obj_access.cpp @@ -16,6 +16,7 @@ #include "sql/engine/ob_exec_context.h" #include "sql/ob_spi.h" #include "pl/ob_pl.h" +#include "pl/ob_pl_resolver.h" #include "sql/engine/expr/ob_expr_lob_utils.h" namespace oceanbase @@ -32,7 +33,8 @@ ObExprObjAccess::ExtraInfo::ExtraInfo(common::ObIAllocator &alloc, ObExprOperato for_write_(false), property_type_(pl::ObCollectionType::INVALID_PROPERTY), coll_idx_(OB_INVALID_INDEX), - extend_size_(0) + extend_size_(0), + access_idxs_(alloc) { } @@ -74,6 +76,7 @@ void ObExprObjAccess::ExtraInfo::reset() property_type_ = pl::ObCollectionType::INVALID_PROPERTY; coll_idx_ = OB_INVALID_INDEX; extend_size_ = 0; + access_idxs_.reset(); } void ObExprObjAccess::reset() @@ -105,6 +108,7 @@ int ObExprObjAccess::ExtraInfo::assign(const ObExprObjAccess::ExtraInfo &other) coll_idx_ = other.coll_idx_; extend_size_ = other.extend_size_; OZ(param_idxs_.assign(other.param_idxs_)); + OZ(access_idxs_.assign(other.access_idxs_)); return ret; } @@ -211,26 +215,169 @@ int ObExprObjAccess::calc_result(ObObj &result, get_result_type().get_extend_size(), param_store, objs_stack, - param_num); + param_num, + nullptr); } + +int ObExprObjAccess::ExtraInfo::get_collection_attr(int64_t* params, + const pl::ObObjAccessIdx ¤t_access, + bool for_write, + void *¤t_value) const +{ + int ret = OB_SUCCESS; + pl::ObPLCollection *current_coll = reinterpret_cast(current_value); + int64_t element_idx; + CK (OB_NOT_NULL(current_coll)); + if (OB_SUCC(ret) && !current_coll->is_inited()) { + ret = OB_NOT_INIT; + LOG_WARN("", K(ret), KPC(current_coll)); + } + if (OB_SUCC(ret) && !current_access.is_property()) { + if (current_access.is_const()) { + element_idx = current_access.var_index_ - 1; + } else { + element_idx = params[current_access.var_index_] - 1; + } + if (element_idx < 0 || element_idx >= current_coll->get_count()) { + ret = OB_READ_NOTHING; + LOG_WARN("", K(ret), K(element_idx)); + } + } + if (OB_SUCC(ret) && !current_access.is_property()) { + ObObj &element_obj = current_coll->get_data()[element_idx]; + if (ObMaxType == element_obj.get_type()) { + if (!for_write) { + ret = OB_READ_NOTHING; + LOG_WARN("", K(ret), KPC(current_coll)); + } else { + if (current_access.var_type_.is_composite_type()) { + element_obj.set_type(ObExtendType); + } + } + } + OX (current_value = &element_obj); + } + return ret; +} + +int ObExprObjAccess::ExtraInfo::get_record_attr(const pl::ObObjAccessIdx ¤t_access, + uint64_t udt_id, + bool for_write, + void *¤t_value, + ObEvalCtx &ctx) const +{ + int ret = OB_SUCCESS; + + ObArenaAllocator alloc; + const pl::ObUserDefinedType *user_type = NULL; + const pl::ObRecordType *record_type = NULL; + pl::ObPLComposite *current_composite = reinterpret_cast(current_value); + pl::ObPLRecord* current_record = static_cast(current_composite); + ObObj* element_obj = NULL; + CK (OB_NOT_NULL(current_composite)); + CK (current_composite->is_record()); + CK (OB_NOT_NULL(current_record)); + CK (OB_NOT_NULL(ctx.exec_ctx_.get_my_session())); + CK (OB_NOT_NULL(ctx.exec_ctx_.get_sql_ctx())); + CK (OB_NOT_NULL(ctx.exec_ctx_.get_sql_ctx()->schema_guard_)); + CK (OB_NOT_NULL(ctx.exec_ctx_.get_sql_proxy())); + if (OB_FAIL(ret)) { + } else if (ctx.exec_ctx_.get_my_session()->get_pl_context()) { + pl::ObPLINS *ns = ctx.exec_ctx_.get_my_session()->get_pl_context()->get_current_ctx(); + CK (OB_NOT_NULL(ns)); + OZ (ns->get_user_type(udt_id, user_type)); + } else { + pl::ObPLResolveCtx resolve_ctx(alloc, + *ctx.exec_ctx_.get_my_session(), + *ctx.exec_ctx_.get_sql_ctx()->schema_guard_, + *ctx.exec_ctx_.get_package_guard(), + *ctx.exec_ctx_.get_sql_proxy(), + false); + OZ (resolve_ctx.get_user_type(udt_id, user_type)); + } + CK (OB_NOT_NULL(user_type)); + CK (user_type->is_record_type()); + CK (OB_NOT_NULL(record_type = static_cast(user_type))); + CK (current_access.is_const()); + if (OB_SUCC(ret) && user_type->is_object_type() && for_write_ && current_composite->is_null()) { + ret = OB_ERR_ACCESS_INTO_NULL; + LOG_WARN("", K(ret), KPC(current_composite)); + } + OZ (current_record->get_element(current_access.var_index_, element_obj)); + CK (OB_NOT_NULL(current_value = element_obj)); + + return ret; +} + +int ObExprObjAccess::ExtraInfo::get_attr_func(int64_t param_cnt, + int64_t *params, + int64_t *element_val, + ObEvalCtx &ctx) const +{ + int ret = OB_SUCCESS; + pl::ObPLComposite *composite_addr + = reinterpret_cast(params[access_idxs_.at(0).var_index_]); + void *current_value = NULL; + CK (OB_NOT_NULL(element_val)); + CK (access_idxs_.count() > 0); + for (int64_t i = 1; OB_SUCC(ret) && i < access_idxs_.count(); ++i) { + const pl::ObPLDataType &parent_type = access_idxs_.at(i - 1).var_type_; + const pl::ObObjAccessIdx &parent_access = access_idxs_.at(i - 1); + const pl::ObObjAccessIdx ¤t_access = access_idxs_.at(i); + current_value = composite_addr; + if (parent_type.is_collection_type()) { + OZ (get_collection_attr(params, + current_access, + for_write_, + current_value)); + } else { + OZ (get_record_attr(current_access, + parent_type.get_user_type_id(), + for_write_, + current_value, + ctx));; + } + if (OB_FAIL(ret)) { + } else if (current_access.var_type_.is_composite_type()) { + ObObj* value = reinterpret_cast(current_value); + CK (OB_NOT_NULL(value)); + CK (value->is_ext()); + OX (composite_addr = reinterpret_cast(value->get_ext())); + CK (OB_NOT_NULL(composite_addr)); + } + } + if (OB_FAIL(ret)) { + } else if (pl::ObObjAccessIdx::get_final_type(access_idxs_).is_obj_type()) { + *element_val = reinterpret_cast(current_value); + } else { + *element_val = reinterpret_cast(composite_addr); + } + return ret; +} + int ObExprObjAccess::ExtraInfo::calc(ObObj &result, const ObObjMeta &res_type, const int32_t extend_size, const ParamStore ¶m_store, const common::ObObj *params, - int64_t param_num) const + int64_t param_num, + ObEvalCtx *ctx) const { int ret = OB_SUCCESS; typedef int32_t (*GetAttr)(int64_t, int64_t [], int64_t *); GetAttr get_attr = reinterpret_cast(get_attr_func_); ParamArray param_array; - CK (OB_NOT_NULL(get_attr)); OZ (init_param_array(param_store, params, param_num, param_array)); if (OB_SUCC(ret)) { int64_t *param_ptr = const_cast(param_array.head()); int64_t attr_addr = 0; - OZ (get_attr(param_array.count(), param_ptr, &attr_addr)); + if (OB_NOT_NULL(get_attr)) { + OZ (get_attr(param_array.count(), param_ptr, &attr_addr)); + } else { + CK (OB_NOT_NULL(ctx)); + OZ (get_attr_func(param_array.count(), param_ptr, &attr_addr, *ctx)); + } if (OB_FAIL(ret)) { if (OB_NOT_INIT == ret && pl::ObCollectionType::EXISTS_PROPERTY == property_type_) { ret = OB_SUCCESS; @@ -285,7 +432,6 @@ int ObExprObjAccess::ExtraInfo::calc(ObObj &result, int ObExprObjAccess::ExtraInfo::from_raw_expr(const ObObjAccessRawExpr &raw_access) { int ret = 0; - CK(0 != raw_access.get_get_attr_func_addr()); if (OB_SUCC(ret)) { extend_size_ = raw_access.get_result_type().get_extend_size(); get_attr_func_ = raw_access.get_get_attr_func_addr(); @@ -298,6 +444,8 @@ int ObExprObjAccess::ExtraInfo::from_raw_expr(const ObObjAccessRawExpr &raw_acce } OZ(param_idxs_.init(raw_access.get_var_indexs().count())); OZ(param_idxs_.assign(raw_access.get_var_indexs())); + OZ(access_idxs_.init(raw_access.get_access_idxs().count())); + OZ(access_idxs_.assign(raw_access.get_access_idxs())); } return ret; } @@ -313,7 +461,6 @@ int ObExprObjAccess::cg_expr(ObExprCGCtx &op_cg_ctx, LOG_WARN("allocate memory failed", K(ret)); } else { const ObObjAccessRawExpr &raw_access = static_cast(raw_expr); - CK(0 != raw_access.get_get_attr_func_addr()); if (OB_SUCC(ret)) { info->extend_size_ = raw_expr.get_result_type().get_extend_size(); info->get_attr_func_ = raw_access.get_get_attr_func_addr(); @@ -327,6 +474,8 @@ int ObExprObjAccess::cg_expr(ObExprCGCtx &op_cg_ctx, info->coll_idx_ = coll_idx; OZ(info->param_idxs_.init(raw_access.get_var_indexs().count())); OZ(info->param_idxs_.assign(raw_access.get_var_indexs())); + OZ(info->access_idxs_.init(raw_access.get_access_idxs().count())); + OZ(info->access_idxs_.assign(raw_access.get_access_idxs())); } if (OB_SUCC(ret)) { rt_expr.extra_info_ = info; @@ -357,7 +506,8 @@ int ObExprObjAccess::eval_obj_access(const ObExpr &expr, info->extend_size_, param_store, params, - expr.arg_cnt_)); + expr.arg_cnt_, + &ctx)); OZ(expr_datum.from_obj(result, expr.obj_datum_map_)); if (is_lob_storage(result.get_type())) { diff --git a/src/sql/engine/expr/ob_expr_obj_access.h b/src/sql/engine/expr/ob_expr_obj_access.h index 7fea5dc3d3..efe116f72f 100644 --- a/src/sql/engine/expr/ob_expr_obj_access.h +++ b/src/sql/engine/expr/ob_expr_obj_access.h @@ -75,13 +75,28 @@ public: int update_coll_first_last( const ParamStore ¶m_store, const ObObj *objs_stack, int64_t param_num) const; + int get_attr_func(int64_t param_cnt, + int64_t* params, + int64_t *element_val, + ObEvalCtx &ctx) const; + int get_record_attr(const pl::ObObjAccessIdx ¤t_access, + uint64_t udt_id, + bool for_write, + void *¤t_value, + ObEvalCtx &ctx) const; + int get_collection_attr(int64_t* params, + const pl::ObObjAccessIdx ¤t_access, + bool for_write, + void *¤t_value) const; + int calc(ObObj &result, const ObObjMeta &res_type, const int32_t extend_size, const ParamStore ¶m_store, const common::ObObj *params, - int64_t param_num) const; + int64_t param_num, + ObEvalCtx *ctx) const; TO_STRING_KV(K_(get_attr_func), K_(param_idxs), @@ -99,6 +114,7 @@ public: int64_t coll_idx_; // index of Collection in ParamArray // extend size only used in static engine, the old expr get extend size from ObExprResType int32_t extend_size_; + common::ObFixedArray access_idxs_; }; private: ExtraInfo info_; diff --git a/src/sql/resolver/dml/ob_dml_resolver.cpp b/src/sql/resolver/dml/ob_dml_resolver.cpp index 10cbbb6405..aaec973226 100755 --- a/src/sql/resolver/dml/ob_dml_resolver.cpp +++ b/src/sql/resolver/dml/ob_dml_resolver.cpp @@ -2678,6 +2678,64 @@ int ObDMLResolver::resolve_columns(ObRawExpr *&expr, ObArray &c return ret; } +bool ObDMLResolver::check_expr_has_colref(ObRawExpr *expr) +{ + bool has_colref = false; + if (OB_ISNULL(expr)) { + } else if (expr->is_column_ref_expr()) { + has_colref = true; + } else { + for (int64_t i = 0; !has_colref && i < expr->get_param_count(); ++i) { + has_colref = check_expr_has_colref(expr->get_param_expr(i)); + } + } + return has_colref; +} + +int ObDMLResolver::replace_pl_relative_expr_to_question_mark(ObRawExpr *&real_ref_expr) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(real_ref_expr)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("expr is NULL", K(ret)); + } else if (real_ref_expr->is_const_raw_expr() //local variable access + || (real_ref_expr->is_obj_access_expr() && !check_expr_has_colref(real_ref_expr)) // composite variable access + || T_OP_GET_PACKAGE_VAR == real_ref_expr->get_expr_type() //package variable access, must not (system/user variable) + || real_ref_expr->is_sys_func_expr() + || T_FUN_PL_GET_CURSOR_ATTR == real_ref_expr->get_expr_type()) { //允许CURSOR%ROWID通过 + if (OB_FAIL(ObResolverUtils::resolve_external_param_info(params_.external_param_info_, + *params_.expr_factory_, + params_.prepare_param_count_, + real_ref_expr))) { + LOG_WARN("failed to resolve external param info", K(ret), KPC(real_ref_expr)); + } + } else if (real_ref_expr->is_udf_expr() //replace self argument of udt routine + && OB_NOT_NULL(real_ref_expr->get_param_expr(0)) + && real_ref_expr->get_param_expr(0)->has_flag(IS_UDT_UDF_SELF_PARAM)) { + if (real_ref_expr->get_param_expr(0)->is_const_raw_expr()//local variable access + || (real_ref_expr->get_param_expr(0)->is_obj_access_expr() + && !check_expr_has_colref(real_ref_expr->get_param_expr(0)))//composite variable access + || T_OP_GET_PACKAGE_VAR == real_ref_expr->get_param_expr(0)->get_expr_type()) { + ObRawExpr *self = real_ref_expr->get_param_expr(0); + if (OB_FAIL(ObResolverUtils::resolve_external_param_info( + params_.external_param_info_, *params_.expr_factory_, params_.prepare_param_count_, self))) { + LOG_WARN("failed to resolve external param info", K(ret), KPC(self)); + } else if (OB_FAIL(ObResolverUtils::revert_external_param_info( + params_.external_param_info_, real_ref_expr->get_param_expr(0)))) { + LOG_WARN("failed to revert external param info", K(ret), KPC(self)); + } else if (OB_FAIL(ObRawExprUtils::replace_ref_column( + real_ref_expr, real_ref_expr->get_param_expr(0), self))) { + LOG_WARN("failed to replace ref column", K(ret), KPC(self)); + } + } else if (real_ref_expr->get_param_expr(0)->is_udf_expr()) { + if (OB_FAIL(replace_pl_relative_expr_to_question_mark(real_ref_expr->get_param_expr(0)))) { + LOG_WARN("failed replace pl relative expr to question mark", K(ret), KPC(real_ref_expr)); + } + } + } + return ret; +} + int ObDMLResolver::resolve_qualified_identifier(ObQualifiedName &q_name, ObIArray &columns, ObIArray &real_exprs, @@ -2838,10 +2896,18 @@ int ObDMLResolver::resolve_qualified_identifier(ObQualifiedName &q_name, } } } - if (OB_SUCC(ret) && OB_NOT_NULL(real_ref_expr) && real_ref_expr->is_udf_expr()) { - ObUDFRawExpr *udf = static_cast(real_ref_expr); - if (OB_NOT_NULL(udf)) { - OX (stmt_->get_query_ctx()->disable_udf_parallel_ |= !udf->is_parallel_enable()); + if (OB_SUCC(ret) && OB_NOT_NULL(real_ref_expr)) { + if (T_FUN_PL_SQLCODE_SQLERRM == real_ref_expr->get_expr_type()) { + ret = OB_ERR_SP_UNDECLARED_VAR; + LOG_WARN("sqlcode or sqlerrm can not use in dml directly", K(ret), KPC(real_ref_expr)); + } else if (real_ref_expr->is_udf_expr()) { + ObUDFRawExpr *udf = static_cast(real_ref_expr); + if (OB_ISNULL(udf)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed cast udf raw expr", K(ret)); + } else { + stmt_->get_query_ctx()->disable_udf_parallel_ |= !udf->is_parallel_enable(); + } } } } @@ -2856,50 +2922,14 @@ int ObDMLResolver::resolve_qualified_identifier(ObQualifiedName &q_name, } //把需要传给PL的表达式整体替换成param - if (OB_SUCC(ret)) { - if (OB_ISNULL(real_ref_expr)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("expr is NULL", K(ret)); - } else if (T_FUN_PL_SQLCODE_SQLERRM == real_ref_expr->get_expr_type()) { - ret = OB_ERR_SP_UNDECLARED_VAR; - LOG_WARN("sqlcode or sqlerrm can not use in dml directly", K(ret), KPC(real_ref_expr)); - } else { - if (q_name.is_access_root() - && is_external - && !params_.is_default_param_ - && T_INTO_SCOPE != current_scope_ - && NULL != params_.secondary_namespace_) { //仅PL里的SQL出现了外部变量需要替换成QUESTIONMARK,纯SQL语境的不需要 - if (real_ref_expr->is_const_raw_expr() //local变量 - || real_ref_expr->is_obj_access_expr() //复杂变量 - || T_OP_GET_PACKAGE_VAR == real_ref_expr->get_expr_type() //package变量(system/user variable不会走到这里) - || real_ref_expr->is_sys_func_expr() - || T_FUN_PL_GET_CURSOR_ATTR == real_ref_expr->get_expr_type()) { //允许CURSOR%ROWID通过 - /* - * 在已有的表达式里寻找是否有相同,如果有相同则使用同一个QuestionMark - * */ - OZ (ObResolverUtils::resolve_external_param_info(params_.external_param_info_, - *params_.expr_factory_, - params_.prepare_param_count_, - real_ref_expr)); - } else if (real_ref_expr->is_udf_expr() - && OB_NOT_NULL(real_ref_expr->get_param_expr(0)) - && real_ref_expr->get_param_expr(0)->has_flag(IS_UDT_UDF_SELF_PARAM)) { - ObRawExpr *self = real_ref_expr->get_param_expr(0); - if (self->is_const_raw_expr() - || self->is_obj_access_expr() - || T_OP_GET_PACKAGE_VAR == self->get_expr_type()) { - OZ (ObResolverUtils::resolve_external_param_info(params_.external_param_info_, - *params_.expr_factory_, - params_.prepare_param_count_, - self)); - OZ (ObResolverUtils::revert_external_param_info(params_.external_param_info_, - real_ref_expr->get_param_expr(0))); - OZ (ObRawExprUtils::replace_ref_column(real_ref_expr, - real_ref_expr->get_param_expr(0), - self)); - } - } - } + if (OB_SUCC(ret) + && q_name.is_access_root() + && is_external + && !params_.is_default_param_ + && T_INTO_SCOPE != current_scope_ + && NULL != params_.secondary_namespace_) { //仅PL里的SQL出现了外部变量需要替换成QUESTIONMARK,纯SQL语境的不需要 + if (OB_FAIL(replace_pl_relative_expr_to_question_mark(real_ref_expr))) { + LOG_WARN("failed to replace pl realtive expr to question mark", K(ret), KPC(real_ref_expr), K(q_name)); } } diff --git a/src/sql/resolver/dml/ob_dml_resolver.h b/src/sql/resolver/dml/ob_dml_resolver.h index c21c9f5166..9e32c563d9 100644 --- a/src/sql/resolver/dml/ob_dml_resolver.h +++ b/src/sql/resolver/dml/ob_dml_resolver.h @@ -886,6 +886,9 @@ private: int check_column_udt_type(ParseNode *root_node); int resolve_table_dynamic_sampling_hint(const ParseNode &hint_node, ObOptHint *&opt_hint); + int replace_pl_relative_expr_to_question_mark(ObRawExpr *&real_ref_expr); + bool check_expr_has_colref(ObRawExpr *expr); + //////////end of functions for sql hint///////////// protected: struct GenColumnExprInfo { diff --git a/src/sql/resolver/expr/ob_raw_expr_printer.cpp b/src/sql/resolver/expr/ob_raw_expr_printer.cpp index 64a1178576..f399ab8444 100644 --- a/src/sql/resolver/expr/ob_raw_expr_printer.cpp +++ b/src/sql/resolver/expr/ob_raw_expr_printer.cpp @@ -743,25 +743,26 @@ int ObRawExprPrinter::print(ObOpRawExpr *expr) break; } case T_OBJ_ACCESS_REF: { - bool parent_is_table = false; ObObjAccessRawExpr *obj_access_expr = static_cast(expr); - for (int64_t i = 0; OB_SUCC(ret) && i < obj_access_expr->get_access_idxs().count(); ++i) { - const ObString &var_name = obj_access_expr->get_access_idxs().at(i).var_name_; - if (!var_name.empty()) { - if (parent_is_table) { - DATA_PRINTF("("); - } else if (i > 0) { - DATA_PRINTF("."); - } - DATA_PRINTF("%.*s", LEN_AND_PTR(var_name)); - if (parent_is_table) { - DATA_PRINTF(")"); - } - } else { - int64_t var_index = obj_access_expr->get_access_idxs().at(i).var_index_; - DATA_PRINTF("(%ld)", var_index); + bool parent_is_table = false; + for (int64_t i = 0; OB_SUCC(ret) && i < obj_access_expr->get_orig_access_idxs().count(); ++i) { + pl::ObObjAccessIdx ¤t_idx = obj_access_expr->get_orig_access_idxs().at(i); + if (parent_is_table) { + DATA_PRINTF("("); + } else if (i > 0) { + DATA_PRINTF("."); } - parent_is_table = obj_access_expr->get_access_idxs().at(i).elem_type_.is_nested_table_type(); + if (OB_NOT_NULL(current_idx.get_sysfunc_)) { + PRINT_EXPR(current_idx.get_sysfunc_); + } else if (!current_idx.var_name_.empty()) { + DATA_PRINTF("%.*s", current_idx.var_name_.length(), current_idx.var_name_.ptr()); + } else { + DATA_PRINTF("%ld", current_idx.var_index_); + } + if (parent_is_table) { + DATA_PRINTF(")"); + } + parent_is_table = current_idx.elem_type_.is_nested_table_type(); } break; }