diff --git a/src/pl/ob_pl_resolver.cpp b/src/pl/ob_pl_resolver.cpp index 5ebe8ddd15..b6591bc020 100644 --- a/src/pl/ob_pl_resolver.cpp +++ b/src/pl/ob_pl_resolver.cpp @@ -8331,18 +8331,13 @@ int ObPLResolver::resolve_expr(const ParseNode *node, // Step 1: resolve parse node to raw expr OZ (build_raw_expr(node, unit_ast, expr, expected_type)); CK (OB_NOT_NULL(expr)); - bool is_order = false; - OZ (replace_object_compare_expr(expr, unit_ast, is_order)); + OZ (replace_object_compare_expr(expr, unit_ast)); OZ (analyze_expr_type(expr, unit_ast)); // check op illegal - if (OB_SUCC(ret) && !OB_ISNULL(expr) + if (OB_SUCC(ret) && OB_NOT_NULL(expr) && (T_OP_EQ == expr->get_expr_type() || T_OP_NE == expr->get_expr_type())) { bool is_obj_acc = false; - if (OB_FAIL(check_collection_expr_illegal(expr, is_obj_acc))) { - LOG_WARN("failed to check collection expr illegal", K(ret)); - } else { - // do nothing - } + OZ (check_collection_expr_illegal(expr, is_obj_acc)); } CK (OB_NOT_NULL(current_block_)); @@ -8932,26 +8927,32 @@ int ObPLResolver::resolve_raw_expr(const ParseNode &node, return ret; } +int ObPLResolver::init_udf_info_of_accessident(ObObjAccessIdent &access_ident) +{ + int ret = OB_SUCCESS; + ObUDFRawExpr *func_expr = NULL; + OX (new (&access_ident.udf_info_) ObUDFInfo()); + OZ (expr_factory_.create_raw_expr(T_FUN_UDF, func_expr)); + CK (OB_NOT_NULL(func_expr)); + for (int64_t i = 0; OB_SUCC(ret) && i < access_ident.params_.count(); ++i) { + std::pair ¶m = access_ident.params_.at(i); + if (0 == param.second) { + OZ (func_expr->add_param_expr(param.first)); + OX (access_ident.udf_info_.udf_param_num_++); + } else { + break; + } + } + OX (func_expr->set_func_name(access_ident.access_name_)); + OX (access_ident.udf_info_.ref_expr_ = func_expr); + return ret; +} + int ObPLResolver::init_udf_info_of_accessidents(ObIArray &access_idents) { int ret = OB_SUCCESS; for (int64_t i = 0; OB_SUCC(ret) && i < access_idents.count(); ++i) { - ObObjAccessIdent &access_ident = access_idents.at(i); - ObUDFRawExpr *func_expr = NULL; - OX (new (&access_ident.udf_info_) ObUDFInfo()); - OZ (expr_factory_.create_raw_expr(T_FUN_UDF, func_expr)); - CK (OB_NOT_NULL(func_expr)); - for (int64_t i = 0; OB_SUCC(ret) && i < access_ident.params_.count(); ++i) { - std::pair ¶m = access_ident.params_.at(i); - if (0 == param.second) { - OZ (func_expr->add_param_expr(param.first)); - OX (access_ident.udf_info_.udf_param_num_++); - } else { - break; - } - } - OX (func_expr->set_func_name(access_ident.access_name_)); - OX (access_ident.udf_info_.ref_expr_ = func_expr); + OZ (init_udf_info_of_accessident(access_idents.at(i))); } return ret; } @@ -9341,16 +9342,6 @@ do { \ return ret; } -int ObPLResolver::make_udt_udf_self_expr(const ObIArray &access_name, - ObPLCompileUnitAST &func, - ObRawExpr *&expr, - bool need_add) -{ - int ret = OB_SUCCESS; - UNUSEDx(access_name, func, expr, need_add); - return ret; -} - int ObPLResolver::resolve_obj_access_node(const ParseNode &node, ObSQLSessionInfo &session_info, ObRawExprFactory &expr_factory, @@ -14811,189 +14802,107 @@ int64_t ObPLResolver::combine_line_and_col(const ObStmtLoc &loc) return bloc; } -int ObPLResolver::resolve_mocked_map_order_udf(const uint64_t udt_id, - const ObString &self_name, - const ObString &other_name, - ObPLCompileUnitAST &unit_ast, - ObIArray &expr, - ObRawExpr *org_expr, - bool &is_order) +int ObPLResolver::replace_map_or_order_expr( + uint64_t udt_id, ObRawExpr *&expr, ObPLCompileUnitAST &func) { int ret = OB_SUCCESS; - ObSqlString sql_str; - is_order = false; - const ObRoutineInfo *routine_info = NULL; - CK (OB_INVALID_ID != udt_id); - CK (OB_NOT_NULL(org_expr)); - if (OB_SUCC(ret)) { - ObArray routine_infos; - uint64_t sess_id = resolve_ctx_.session_info_.get_effective_tenant_id(); - OZ (resolve_ctx_.schema_guard_.get_routine_infos_in_udt(sess_id, udt_id, routine_infos)); - for (int64_t i = 0; OB_SUCC(ret) && i < routine_infos.count(); ++i) { - routine_info = routine_infos.at(i); - CK (OB_NOT_NULL(routine_info)); - CK (routine_info->is_udt_function()); - if (OB_SUCC(ret)) { - if (routine_info->is_udt_order()) { - is_order = true; - break; - } else if(routine_info->is_udt_map()) { - break; - } else { - // do nothing - } - } + ObSEArray routine_infos; + const ObRoutineInfo* routine_info = NULL; + ObRawExpr *left = expr->get_param_expr(0); + ObRawExpr *right = expr->get_param_expr(1); + ObObjAccessRawExpr *left_access = static_cast(left); + ObObjAccessRawExpr *right_access = static_cast(right); + CK (OB_NOT_NULL(left_access)); + CK (OB_NOT_NULL(right_access)); + OZ (resolve_ctx_.schema_guard_.get_routine_infos_in_udt( + get_tenant_id_by_object_id(udt_id), udt_id, routine_infos)); + for (int64_t i = 0; OB_SUCC(ret) && i < routine_infos.count(); ++i) { + 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()) { + CK (OB_ISNULL(routine_info)); + OX (routine_info = routine_infos.at(i)); } - if (OB_SUCC(ret) && OB_NOT_NULL(routine_info)) { - const ObString &routine_name = routine_info->get_routine_name(); - if (is_order) { - OZ (sql_str.append_fmt( - "select \"%.*s\".\"%.*s\"(\"%.*s\") from dual", - self_name.length(), self_name.ptr(), - routine_name.length(), routine_name.ptr(), - other_name.length(), other_name.ptr())); + } + if (OB_FAIL(ret)) { + } else if (OB_NOT_NULL(routine_info)) { + const ObString &routine_name = routine_info->get_routine_name(); + ObObjAccessIdent access_ident(routine_name); + ObSEArray left_idxs; + ObSEArray right_idxs; + OZ (left_idxs.assign(left_access->get_orig_access_idxs())); + OZ (right_idxs.assign(right_access->get_orig_access_idxs())); + OX (access_ident.set_pl_udf()); + OX (access_ident.access_name_ = routine_name); + if (routine_info->is_udt_order()) { + OZ (access_ident.params_.push_back(std::make_pair(right, 0))); + } + CK (OB_NOT_NULL(current_block_)); + OZ (init_udf_info_of_accessident(access_ident)); + OZ (resolve_access_ident(access_ident, current_block_->get_namespace(), expr_factory_, &resolve_ctx_.session_info_, left_idxs, func, true)); + CK (left_idxs.at(left_idxs.count() - 1).is_udf_type()); + OX (left = left_idxs.at(left_idxs.count() - 1).get_sysfunc_); + if (OB_FAIL(ret)) { + } else if (routine_info->is_udt_order()) { + ObObjType result_type = left->get_result_type().get_type(); + ObConstRawExpr *const_expr = NULL; + if (left->get_result_type().get_type() == ObNumberType) { + number::ObNumber zero; + OZ (zero.from(static_cast(0), resolve_ctx_.allocator_)); + OZ (ObRawExprUtils::build_const_number_expr(expr_factory_, ObNumberType, zero, const_expr)); } else { - OZ (sql_str.append_fmt( - "select \"%.*s\".\"%.*s\"(), \"%.*s\".\"%.*s\"() from dual", - self_name.length(), self_name.ptr(), - routine_name.length(), routine_name.ptr(), - other_name.length(), other_name.ptr(), - routine_name.length(), routine_name.ptr())); + OZ (ObRawExprUtils::build_const_int_expr(expr_factory_, left->get_result_type().get_type(), 0, const_expr)); } - if (OB_SUCC(ret)) { - ParseResult parse_result; - ParseNode *select_node = NULL; - ParseNode *select_expr_list = NULL; - ParseNode *select_expr = NULL; - ParseNode *select_expr1 = NULL; - ObRawExpr *udf_expr = NULL; - ObRawExpr *udf_expr_r = NULL; - ObParser parser(resolve_ctx_.allocator_, resolve_ctx_.session_info_.get_sql_mode(), - resolve_ctx_.session_info_.get_local_collation_connection()); - OZ (parser.parse(sql_str.string(), parse_result), sql_str.string()); - CK (OB_NOT_NULL(parse_result.result_tree_)); - CK (T_STMT_LIST == parse_result.result_tree_->type_); - CK (1 == parse_result.result_tree_->num_child_); - OX (select_node = parse_result.result_tree_->children_[0]); - CK (T_SELECT == select_node->type_); - OX (select_expr_list = select_node->children_[PARSE_SELECT_SELECT]); - CK (OB_NOT_NULL(select_expr_list) && OB_NOT_NULL(select_expr_list->children_[0])); - OX (select_expr = select_expr_list->children_[0]); - CK (OB_NOT_NULL(select_expr)); - -#define RESOLVE_EXPR(cexpr, node, exp_type) \ -do { \ - if (OB_SUCC(ret)) { \ - CK (OB_NOT_NULL(node)); \ - OZ (resolve_expr(node, unit_ast, cexpr, 0, true, exp_type)); \ - CK (OB_NOT_NULL(cexpr)); \ - CK (T_FUN_UDF == cexpr->get_expr_type()); \ - OZ (cexpr->formalize(&resolve_ctx_.session_info_)); \ - OZ (expr.push_back(cexpr)); \ - } \ -}while (0) - - if (is_order) { - CK (OB_NOT_NULL(select_expr->children_[0])); - RESOLVE_EXPR(udf_expr, select_expr->children_[0], NULL); - } else { - CK (2 == select_expr_list->num_child_); - CK (OB_NOT_NULL(select_expr->children_[0])); - OX (select_expr1 = select_expr_list->children_[1]); - CK (OB_NOT_NULL(select_expr1)); - RESOLVE_EXPR(udf_expr, select_expr->children_[0], NULL); - RESOLVE_EXPR(udf_expr_r, select_expr1->children_[0], NULL); - } -#undef RESOLVE_EXPR - } - } else if (OB_SUCC(ret) && OB_ISNULL(routine_info)) { - ret = OB_ERR_NO_ORDER_MAP; - LOG_WARN("A MAP or ORDER function is required for comparing objects in PL/SQL", K(ret)); + OX (right = const_expr); + } else { + OZ (resolve_access_ident(access_ident, current_block_->get_namespace(), expr_factory_, &resolve_ctx_.session_info_, right_idxs, func, true)); + CK (right_idxs.at(right_idxs.count() - 1).is_udf_type()); + OX (right = right_idxs.at(right_idxs.count() - 1).get_sysfunc_); } + CK (OB_NOT_NULL(static_cast(expr))); + OZ (static_cast(expr)->replace_param_expr(0, left)); + OZ (static_cast(expr)->replace_param_expr(1, right)); + OZ (expr->formalize(&resolve_ctx_.session_info_)); + } else { + ret = OB_ERR_NO_ORDER_MAP; + LOG_WARN("A MAP or ORDER function is required for comparing objects in PL/SQL", K(ret)); } return ret; } -int ObPLResolver::replace_object_compare_expr(ObRawExpr *&expr, ObPLCompileUnitAST &unit_ast, - bool &is_order) + +int ObPLResolver::replace_object_compare_expr(ObRawExpr *&expr, ObPLCompileUnitAST &unit_ast) { int ret = OB_SUCCESS; - is_order = false; CK (OB_NOT_NULL(expr)); - if (OB_SUCC(ret)) { - if (IS_COMMON_COMPARISON_OP(expr->get_expr_type())) { - const ObOpRawExpr *op_cmp = static_cast(expr); - CK (2 == op_cmp->get_param_count()); - const ObRawExpr *left = NULL; - const ObRawExpr *right = NULL; - OX (left = op_cmp->get_param_expr(0)); - OX (right = op_cmp->get_param_expr(1)); - if (OB_ISNULL(left) || OB_ISNULL(right)) { + if (OB_FAIL(ret)) { + } else if (IS_COMMON_COMPARISON_OP(expr->get_expr_type())) { + CK (2 == expr->get_param_count()); + CK (OB_NOT_NULL(expr->get_param_expr(0))); + CK (OB_NOT_NULL(expr->get_param_expr(1))); + if (OB_FAIL(ret)) { + } else if (T_OBJ_ACCESS_REF == expr->get_param_expr(0)->get_expr_type() + && T_OBJ_ACCESS_REF == expr->get_param_expr(1)->get_expr_type()) { + const ObObjAccessRawExpr *l + = static_cast(expr->get_param_expr(0)); + const ObObjAccessRawExpr *r + = static_cast(expr->get_param_expr(1)); + if (OB_ISNULL(l) || OB_ISNULL(r)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("expr left or right children is null", K(ret)); + LOG_WARN("unexpected expression", K(ret), K(*expr)); } else { - if (T_OBJ_ACCESS_REF == left->get_expr_type() - && T_OBJ_ACCESS_REF == right->get_expr_type()) { - const ObObjAccessRawExpr *l = static_cast(left); - const ObObjAccessRawExpr *r = static_cast(right); - if (OB_ISNULL(l) || OB_ISNULL(r)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected expression", K(ret), K(*expr)); - } else { - ObArray cmp_expr; - const ObPLDataType &l_type = ObObjAccessIdx::get_final_type(l->get_access_idxs()); - const ObPLDataType &r_type = ObObjAccessIdx::get_final_type(r->get_access_idxs()); - uint64_t luid = l_type.get_user_type_id(); - uint64_t ruid = r_type.get_user_type_id(); - if (OB_INVALID_ID == luid || OB_INVALID_ID == ruid) { - // do nothing, such as: obj1.a > obj2.a - } else if (luid != ruid) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("compare between two different udt type", K(ret), K(luid), K(ruid)); - } else if (l_type.is_object_type() && r_type.is_object_type()) { - const ObString &self_name - = l->get_access_idxs().at(l->get_access_idxs().count() - 1).var_name_; - const ObString &other_name - = r->get_access_idxs().at(r->get_access_idxs().count() - 1).var_name_; - OZ (resolve_mocked_map_order_udf(luid, self_name, other_name, - unit_ast, cmp_expr, expr, is_order)); - if (is_order) { - // obj1 > obj2 => obj1.order() > 0 - // obj1 < obj2 => obj1.order() < 0 - // obj1 = obj2 => obj1.order() = 0 - CK (1 == cmp_expr.count()); - ObConstRawExpr *zero_expr = NULL; - ObObjType result_type; - OX (result_type = cmp_expr.at(0)->get_result_type().get_type()); - if (OB_FAIL(ret)) { - } else if (ObNumberType == result_type) { - number::ObNumber zero; - OZ (zero.from(static_cast(0), resolve_ctx_.allocator_)); - OZ (ObRawExprUtils::build_const_number_expr(expr_factory_, - result_type, zero, zero_expr)); - } else { - OZ (ObRawExprUtils::build_const_int_expr(expr_factory_, - result_type, 0, zero_expr)); - } - CK (OB_NOT_NULL(zero_expr)); - OZ (const_cast(op_cmp)->replace_param_expr(0, cmp_expr.at(0))); - OZ (const_cast(op_cmp)->replace_param_expr(1, zero_expr)); - } else { - CK (2 == cmp_expr.count()); - // obj1 > obj2 => obj1.map() > obj2.map() - // obj1 = obj2 => obj1.map() = obj2.map() - // obj1 < obj2 => obj1.map() < obj2.map() - OZ (const_cast(op_cmp)->replace_param_expr(0, cmp_expr.at(0))); - OZ (const_cast(op_cmp)->replace_param_expr(1, cmp_expr.at(1))); - } - OZ (expr->formalize(&resolve_ctx_.session_info_)); - } else { - // do nothing - } - } + const ObPLDataType &l_type = ObObjAccessIdx::get_final_type(l->get_access_idxs()); + const ObPLDataType &r_type = ObObjAccessIdx::get_final_type(r->get_access_idxs()); + if (l_type.get_user_type_id() != r_type.get_user_type_id()) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("compare between two different udt type", K(ret), K(l_type), K(r_type)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "compare between two different composite type"); + } else if (l_type.is_object_type() && r_type.is_object_type()) { + OZ (replace_map_or_order_expr(l_type.get_user_type_id(), expr, unit_ast)); } } - } else { /* do nothing */ } + } } return ret; } diff --git a/src/pl/ob_pl_resolver.h b/src/pl/ob_pl_resolver.h index 8f5053e0a9..fe7f2cd8e5 100644 --- a/src/pl/ob_pl_resolver.h +++ b/src/pl/ob_pl_resolver.h @@ -951,20 +951,11 @@ private: int get_const_number_variable_literal_value(ObRawExpr *expr, int64_t &result); int check_assign_type(const ObPLDataType &dest_data_type, const ObRawExpr *right_expr); int is_return_ref_cursor_type(const ObRawExpr *expr, bool &is_ref_cursor_type); - int make_udt_udf_self_expr(const ObIArray &access_name, - ObPLCompileUnitAST &func, - ObRawExpr *&expr, - bool need_add = true); - int resolve_mocked_map_order_udf(const uint64_t udt_id, - const ObString &self_name, - const ObString &other_name, - ObPLCompileUnitAST &unit_ast, - ObIArray &expr, - ObRawExpr *org_expr, - bool &is_order); + int replace_map_or_order_expr(uint64_t udt_id, + ObRawExpr *&expr, + ObPLCompileUnitAST &unit_ast); int replace_object_compare_expr(ObRawExpr *&relation_expr, - ObPLCompileUnitAST &unit_ast, - bool &is_order); + ObPLCompileUnitAST &unit_ast); static const ObRawExpr *skip_implict_cast(const ObRawExpr *e); @@ -1073,6 +1064,7 @@ private: const ObPLBlockNS &ns, ObPLCompileUnitAST &func); + int init_udf_info_of_accessident(ObObjAccessIdent &access_ident); int init_udf_info_of_accessidents(ObIArray &access_ident); int resolve_sys_func_access(ObObjAccessIdent &access_ident, diff --git a/src/sql/resolver/expr/ob_raw_expr.cpp b/src/sql/resolver/expr/ob_raw_expr.cpp index 7872aead21..051021516f 100644 --- a/src/sql/resolver/expr/ob_raw_expr.cpp +++ b/src/sql/resolver/expr/ob_raw_expr.cpp @@ -2574,6 +2574,8 @@ int ObObjAccessRawExpr::assign(const ObRawExpr &other) LOG_WARN("append error", K(ret)); } else if (OB_FAIL(append(var_indexs_, tmp.var_indexs_))) { LOG_WARN("append error", K(ret)); + } else if (OB_FAIL(append(orig_access_indexs_, tmp.orig_access_indexs_))) { + LOG_WARN("append error", K(ret)); } else { get_attr_func_ = tmp.get_attr_func_; func_name_ = tmp.func_name_; @@ -2599,6 +2601,8 @@ int ObObjAccessRawExpr::inner_deep_copy(ObIRawExprCopier &copier) } else { pl::ObObjAccessIdx access; common::ObSEArray access_array; + pl::ObObjAccessIdx orig_access; + common::ObSEArray orig_access_array; for (int64_t i = 0; OB_SUCC(ret) && i < access_indexs_.count(); ++i) { access.reset(); if (OB_FAIL(access.deep_copy(*inner_alloc_, copier.get_expr_factory(), access_indexs_.at(i)))) { @@ -2610,6 +2614,17 @@ int ObObjAccessRawExpr::inner_deep_copy(ObIRawExprCopier &copier) if (OB_SUCC(ret) && OB_FAIL(access_indexs_.assign(access_array))) { LOG_WARN("assign array error", K(access_array), K(ret)); } + for (int64_t i = 0; OB_SUCC(ret) && i < orig_access_indexs_.count(); ++i) { + orig_access.reset(); + if (OB_FAIL(orig_access.deep_copy(*inner_alloc_, copier.get_expr_factory(), orig_access_indexs_.at(i)))) { + LOG_WARN("failed to deep copy ObObjAccessIdx", K(i), K(orig_access_indexs_.at(i)), K(ret)); + } else if (OB_FAIL(orig_access_array.push_back(orig_access))) { + LOG_WARN("push back error", K(i), K(orig_access_indexs_.at(i)), K(orig_access), K(ret)); + } else { /*do nothing*/ } + } + if (OB_SUCC(ret) && OB_FAIL(orig_access_indexs_.assign(orig_access_array))) { + LOG_WARN("assign array error", K(orig_access_array), K(ret)); + } } } return ret; @@ -2627,7 +2642,8 @@ bool ObObjAccessRawExpr::inner_same_as(const ObRawExpr &expr, && is_array_equal(access_indexs_, obj_access_expr.access_indexs_) && is_array_equal(var_indexs_, obj_access_expr.var_indexs_) && for_write_ == obj_access_expr.for_write_ - && property_type_ == obj_access_expr.property_type_; + && property_type_ == obj_access_expr.property_type_ + && is_array_equal(orig_access_indexs_, obj_access_expr.orig_access_indexs_); } else { /*do nothing*/ } return bool_ret; } @@ -2745,6 +2761,9 @@ int ObObjAccessRawExpr::add_access_indexs(const ObIArray &ac } } } + if (OB_SUCC(ret) && OB_FAIL(orig_access_indexs_.assign(access_idxs))) { + LOG_WARN("failed to assign access indexs", K(ret), K(access_idxs)); + } return ret; } diff --git a/src/sql/resolver/expr/ob_raw_expr.h b/src/sql/resolver/expr/ob_raw_expr.h index d24fa02c9e..a9817a05c9 100644 --- a/src/sql/resolver/expr/ob_raw_expr.h +++ b/src/sql/resolver/expr/ob_raw_expr.h @@ -4123,7 +4123,8 @@ public: access_indexs_(), var_indexs_(), for_write_(false), - property_type_(pl::ObCollectionType::INVALID_PROPERTY) {} + property_type_(pl::ObCollectionType::INVALID_PROPERTY), + orig_access_indexs_() {} ObObjAccessRawExpr() : ObOpRawExpr(), get_attr_func_(0), @@ -4131,7 +4132,8 @@ public: access_indexs_(), var_indexs_(), for_write_(false), - property_type_(pl::ObCollectionType::INVALID_PROPERTY) {} + property_type_(pl::ObCollectionType::INVALID_PROPERTY), + orig_access_indexs_() {} virtual ~ObObjAccessRawExpr() {} int assign(const ObRawExpr &other) override; int inner_deep_copy(ObIRawExprCopier &copier) override; @@ -4152,6 +4154,8 @@ public: bool is_property() const { return pl::ObCollectionType::INVALID_PROPERTY != property_type_; } pl::ObCollectionType::PropertyType get_property() const { return property_type_; } void set_property(pl::ObCollectionType::PropertyType property_type) { property_type_ = property_type; } + common::ObIArray &get_orig_access_idxs() { return orig_access_indexs_; } + const common::ObIArray &get_orig_access_idxs() const { return orig_access_indexs_; } private: DISALLOW_COPY_AND_ASSIGN(ObObjAccessRawExpr); uint64_t get_attr_func_; //获取用户自定义类型数据的函数指针 @@ -4160,6 +4164,7 @@ private: common::ObSEArray var_indexs_; bool for_write_; pl::ObCollectionType::PropertyType property_type_; + common::ObSEArray orig_access_indexs_; }; enum ObMultiSetType {