diff --git a/src/pl/ob_pl_code_generator.cpp b/src/pl/ob_pl_code_generator.cpp index 952ce47d4c..98d956a312 100644 --- a/src/pl/ob_pl_code_generator.cpp +++ b/src/pl/ob_pl_code_generator.cpp @@ -433,6 +433,11 @@ int ObPLCodeGenerateVisitor::visit(const ObPLAssignStmt &s) LOG_WARN("Unexpected const expr", K(const_expr->get_value()), K(ret)); } } else if (into_expr->is_obj_access_expr()) { + if (s.get_value_index(i) != PL_CONSTRUCT_COLLECTION + && ObObjAccessIdx::has_same_collection_access(s.get_value_expr(i), static_cast(into_expr))) { + ObLLVMValue p_result_obj; + OZ (generator_.generate_expr(s.get_value_index(i), s, OB_INVALID_INDEX, p_result_obj)); + } OZ (generator_.generate_expr(s.get_into_index(i), s, OB_INVALID_INDEX, into_address)); } diff --git a/src/pl/ob_pl_resolver.h b/src/pl/ob_pl_resolver.h index d23ffa29ea..5d3d2870e0 100644 --- a/src/pl/ob_pl_resolver.h +++ b/src/pl/ob_pl_resolver.h @@ -454,6 +454,19 @@ public: static bool is_question_mark_value(ObRawExpr *into_expr, ObPLBlockNS *ns); static int set_question_mark_type(ObRawExpr *into_expr, ObPLBlockNS *ns, const ObPLDataType *type); + static + int build_obj_access_func_name(const ObIArray &access_idxs, + ObRawExprFactory &expr_factory, + const sql::ObSQLSessionInfo *session_info, + ObSchemaGetterGuard *schema_guard, + bool for_write, + ObString &result); + static + int set_write_property(ObRawExpr *obj_expr, + ObRawExprFactory &expr_factory, + const ObSQLSessionInfo *session_info, + ObSchemaGetterGuard *schema_guard, + bool for_write); int get_caller_accessor_item( const ObPLStmtBlock *caller, AccessorItem &caller_item); int check_package_accessible( @@ -915,19 +928,6 @@ private: int get_subprogram_var( ObPLBlockNS &ns, uint64_t subprogram_id, int64_t var_idx, const ObPLVar *&var); static - int build_obj_access_func_name(const ObIArray &access_idxs, - ObRawExprFactory &expr_factory, - const sql::ObSQLSessionInfo *session_info, - ObSchemaGetterGuard *schema_guard, - bool for_write, - ObString &result); - static - int set_write_property(ObRawExpr *obj_expr, - ObRawExprFactory &expr_factory, - const ObSQLSessionInfo *session_info, - ObSchemaGetterGuard *schema_guard, - bool for_write); - static int make_var_from_access(const ObIArray &access_idxs, ObRawExprFactory &expr_factory, const sql::ObSQLSessionInfo *session_info, diff --git a/src/pl/ob_pl_type.cpp b/src/pl/ob_pl_type.cpp index b265bc1e1c..7fdf0ae6fb 100644 --- a/src/pl/ob_pl_type.cpp +++ b/src/pl/ob_pl_type.cpp @@ -1554,7 +1554,6 @@ void ObObjAccessIdx::reset() bool ObObjAccessIdx::operator==(const ObObjAccessIdx &other) const { - int ret = OB_SUCCESS; // udf deterministic default value is false, we need display setting check_ctx.need_check_deterministic_ ObExprEqualCheckContext check_ctx; check_ctx.need_check_deterministic_ = false; @@ -1901,6 +1900,31 @@ int ObObjAccessIdx::get_package_id( return ret; } +bool ObObjAccessIdx::has_same_collection_access(const ObRawExpr *expr, const ObObjAccessRawExpr *access_expr) +{ + bool ret = false; + if (expr->is_obj_access_expr()) { + const ObIArray &left = static_cast(expr)->get_access_idxs(); + const ObIArray &right= access_expr->get_access_idxs(); + for (int64_t i = 0; i < left.count() && i < right.count(); ++i) { + if (!(left.at(i) == right.at(i))) { + break; + } else if (left.at(i).elem_type_.is_collection_type()) { + ret = true; + break; + } + } + } else { + for (int64_t i = 0; i < expr->get_param_count(); ++i) { + if (has_same_collection_access(expr->get_param_expr(i), access_expr)) { + ret = true; + break; + } + } + } + return ret; +} + bool ObObjAccessIdx::has_collection_access(const ObRawExpr *expr) { bool ret = false; diff --git a/src/pl/ob_pl_type.h b/src/pl/ob_pl_type.h index 994dc16e49..d0e21ca2b2 100644 --- a/src/pl/ob_pl_type.h +++ b/src/pl/ob_pl_type.h @@ -41,6 +41,7 @@ namespace oceanbase namespace sql { class ObRawExpr; +class ObObjAccessRawExpr; class ObSqlExpression; class ObRawExprFactory; class ObExecContext; @@ -753,6 +754,7 @@ public: uint64_t &package_id, uint64_t &var_idx); static int get_package_id(const sql::ObRawExpr *expr, uint64_t& package_id, uint64_t *p_var_idx = NULL); + static bool has_same_collection_access(const sql::ObRawExpr *expr, const sql::ObObjAccessRawExpr *access_expr); static bool has_collection_access(const sql::ObRawExpr *expr); static int datum_need_copy(const sql::ObRawExpr *into, const sql::ObRawExpr *value, AccessType &alloc_scop); static int64_t get_local_variable_idx(const common::ObIArray &access_idxs); diff --git a/src/sql/resolver/expr/ob_raw_expr_util.cpp b/src/sql/resolver/expr/ob_raw_expr_util.cpp index 8d458b6083..ad55b11d84 100644 --- a/src/sql/resolver/expr/ob_raw_expr_util.cpp +++ b/src/sql/resolver/expr/ob_raw_expr_util.cpp @@ -1114,9 +1114,8 @@ int ObRawExprUtils::resolve_udf_param_exprs(ObResolverParams ¶ms, if (extern_params.at(i).second->same_as(*c_expr)) { ObRawExpr *rawexpr = extern_params.at(i).first; if (T_OBJ_ACCESS_REF == rawexpr->get_expr_type()) { - ObObjAccessRawExpr* obj = static_cast(rawexpr); - CK (OB_NOT_NULL(obj)); - OX (obj->set_write(true)); + OZ (pl::ObPLResolver::set_write_property( + rawexpr, *(params.expr_factory_), params.session_info_, params.schema_checker_->get_schema_guard(), true)); } break; } @@ -1152,9 +1151,8 @@ do { ObObjAccessRawExpr* obj = static_cast(iexpr); uint64_t pkg_id = OB_INVALID_ID; uint64_t var_id = OB_INVALID_ID; - CK (OB_NOT_NULL(obj)); - OX (obj->set_write(true)); - OZ (obj->formalize(params.session_info_)); + OZ (pl::ObPLResolver::set_write_property( + iexpr, *(params.expr_factory_), params.session_info_, params.schema_checker_->get_schema_guard(), true)); if (obj->get_access_idxs().count() > 0 && OB_NOT_NULL(obj->get_access_idxs().at(0).get_sysfunc_) && T_OP_GET_PACKAGE_VAR == obj->get_access_idxs().at(0).get_sysfunc_->get_expr_type()) {