diff --git a/src/objit/include/objit/expr/ob_iraw_expr.h b/src/objit/include/objit/expr/ob_iraw_expr.h index 65a150bf95..e545d04b2d 100644 --- a/src/objit/include/objit/expr/ob_iraw_expr.h +++ b/src/objit/include/objit/expr/ob_iraw_expr.h @@ -121,6 +121,11 @@ public: || T_FUN_SYS_VERSION == type_ || T_FUN_SYS_OB_VERSION == type_ || T_FUN_SYS_ICU_VERSION == type_; } + + inline bool is_pl_expr() const { return EXPR_UDF == expr_class_ + || T_FUN_PL_COLLECTION_CONSTRUCT == type_ + || T_FUN_PL_OBJECT_CONSTRUCT == type_ + || T_FUN_SYS_PDB_GET_RUNTIME_INFO == type_; } inline void set_expr_type(ObItemType v) { type_ = v; } inline ObItemType get_expr_type() const { return type_; } diff --git a/src/sql/resolver/dml/ob_dml_resolver.cpp b/src/sql/resolver/dml/ob_dml_resolver.cpp index b40b5c1029..399d176cc3 100755 --- a/src/sql/resolver/dml/ob_dml_resolver.cpp +++ b/src/sql/resolver/dml/ob_dml_resolver.cpp @@ -1323,7 +1323,8 @@ int ObDMLResolver::replace_col_udt_qname(ObQualifiedName& q_name) LOG_WARN("try get udt col ref failed", K(ret), K(udt_col_candidate)); // should not return error if not found ret = OB_SUCCESS; - } else if (OB_FAIL(implict_cast_sql_udt_to_pl_udt(udt_col_ref_expr))) { + } else if (OB_FAIL(ObRawExprUtils::implict_cast_sql_udt_to_pl_udt(params_.expr_factory_, + params_.session_info_, udt_col_ref_expr))) { LOG_WARN("try add implict cast above sql udt col ref failed", K(ret), K(udt_col_candidate), K(udt_col_ref_expr)); } else { @@ -1349,68 +1350,6 @@ int ObDMLResolver::replace_col_udt_qname(ObQualifiedName& q_name) return ret; } -int ObDMLResolver::implict_cast_pl_udt_to_sql_udt(ObRawExpr* &real_ref_expr) -{ - int ret = OB_SUCCESS; - - if (OB_ISNULL(real_ref_expr)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("real_ref_expr is null", K(ret)); - } else if (real_ref_expr->get_result_type().is_ext()) { - if (real_ref_expr->get_result_type().get_udt_id() == T_OBJ_XML) { - // add implicit cast to sql xmltype - ObRawExpr *new_expr = NULL; - ObCastMode cast_mode = CM_NONE; - ObExprResType sql_udt_type; - sql_udt_type.set_sql_udt(ObXMLSqlType); // set subschema id - if (OB_FAIL(ObSQLUtils::get_default_cast_mode(params_.session_info_, cast_mode))) { - LOG_WARN("get default cast mode failed", K(ret)); - } else if (OB_FAIL(ObRawExprUtils::try_add_cast_expr_above( - params_.expr_factory_, params_.session_info_, - *real_ref_expr, sql_udt_type, cast_mode, new_expr))) { - LOG_WARN("try add cast expr above failed", K(ret)); - } else if (OB_FAIL(new_expr->add_flag(IS_OP_OPERAND_IMPLICIT_CAST))) { - LOG_WARN("failed to add flag", K(ret)); - } else { - real_ref_expr = new_expr; - } - } - } - return ret; -} - -int ObDMLResolver::implict_cast_sql_udt_to_pl_udt(ObRawExpr* &real_ref_expr) -{ - int ret = OB_SUCCESS; - - if (OB_ISNULL(real_ref_expr)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("real_ref_expr is null", K(ret)); - } else if (real_ref_expr->get_result_type().is_user_defined_sql_type()) { - if (real_ref_expr->get_result_type().is_xml_sql_type()) { - // add implicit cast to sql xmltype - ObRawExpr *new_expr = NULL; - ObCastMode cast_mode = CM_NONE; - ObExprResType pl_udt_type; - pl_udt_type.set_ext(); - pl_udt_type.set_extend_type(PL_OPAQUE_TYPE); - pl_udt_type.set_udt_id(T_OBJ_XML); - if (OB_FAIL(ObSQLUtils::get_default_cast_mode(params_.session_info_, cast_mode))) { - LOG_WARN("get default cast mode failed", K(ret)); - } else if (OB_FAIL(ObRawExprUtils::try_add_cast_expr_above( - params_.expr_factory_, params_.session_info_, - *real_ref_expr, pl_udt_type, cast_mode, new_expr))) { - LOG_WARN("try add cast expr above failed", K(ret)); - } else if (OB_FAIL(new_expr->add_flag(IS_OP_OPERAND_IMPLICIT_CAST))) { - LOG_WARN("failed to add flag", K(ret)); - } else { - real_ref_expr = new_expr; - } - } - } - return ret; -} - int ObDMLResolver::check_column_udt_type(ParseNode *root_node) { INIT_SUCC(ret); @@ -2655,7 +2594,8 @@ int ObDMLResolver::resolve_columns(ObRawExpr *&expr, ObArray &c report_user_error_msg(ret, expr, q_name); } else if (OB_FAIL(real_exprs.push_back(real_ref_expr))) { LOG_WARN("push back failed", K(ret)); - } else if (OB_FAIL(implict_cast_pl_udt_to_sql_udt(real_ref_expr))) { + } else if (OB_FAIL(ObRawExprUtils::implict_cast_pl_udt_to_sql_udt(params_.expr_factory_, + params_.session_info_, real_ref_expr))) { LOG_WARN("add implict cast to pl udt expr failed", K(ret)); } else if (OB_FAIL(ObRawExprUtils::replace_ref_column(expr, q_name.ref_expr_, real_ref_expr))) { LOG_WARN("replace column ref expr failed", K(ret)); diff --git a/src/sql/resolver/dml/ob_dml_resolver.h b/src/sql/resolver/dml/ob_dml_resolver.h index 9e32c563d9..bf8f57dac2 100644 --- a/src/sql/resolver/dml/ob_dml_resolver.h +++ b/src/sql/resolver/dml/ob_dml_resolver.h @@ -881,8 +881,6 @@ private: int resolve_pq_distribute_window_hint(const ParseNode &hint_node, ObOptHint *&opt_hint); int check_cast_multiset(const ObRawExpr *expr, const ObRawExpr *parent_expr = NULL); int replace_col_udt_qname(ObQualifiedName& q_name); - int implict_cast_pl_udt_to_sql_udt(ObRawExpr* &real_ref_expr); - int implict_cast_sql_udt_to_pl_udt(ObRawExpr* &real_ref_expr); int check_column_udt_type(ParseNode *root_node); int resolve_table_dynamic_sampling_hint(const ParseNode &hint_node, ObOptHint *&opt_hint); diff --git a/src/sql/resolver/expr/ob_raw_expr_deduce_type.cpp b/src/sql/resolver/expr/ob_raw_expr_deduce_type.cpp index 922345a4a7..92a3cd8a30 100644 --- a/src/sql/resolver/expr/ob_raw_expr_deduce_type.cpp +++ b/src/sql/resolver/expr/ob_raw_expr_deduce_type.cpp @@ -2177,7 +2177,7 @@ int ObRawExprDeduceType::visit(ObSysFunRawExpr &expr) ObExprResTypes types; ObCastMode expr_cast_mode = CM_NONE; for (int64_t i = 0; OB_SUCC(ret) && i < expr.get_param_count(); i++) { - const ObRawExpr *param_expr = expr.get_param_expr(i); + ObRawExpr *param_expr = expr.get_param_expr(i); if (OB_ISNULL(param_expr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid argument", K(param_expr)); @@ -2194,6 +2194,15 @@ int ObRawExprDeduceType::visit(ObSysFunRawExpr &expr) if (OB_FAIL(deduce_type_visit_for_special_func(i, *param_expr, types))) { LOG_WARN("fail to visit for column_conv", K(ret), K(i)); } + } else if (lib::is_oracle_mode() && !expr.is_pl_expr() && expr.is_called_in_sql() + && T_FUN_SYS_CAST != expr.get_expr_type() && param_expr->get_expr_type() != T_FUN_SYS_CAST + && param_expr->get_result_type().get_type() == ObExtendType + && param_expr->get_result_type().get_udt_id() == T_OBJ_XML) { + if (OB_FAIL(ObRawExprUtils::implict_cast_pl_udt_to_sql_udt(expr_factory_, my_session_, param_expr))) { + LOG_WARN("add implict cast to pl udt expr failed", K(ret)); + } else if (OB_FAIL(types.push_back(param_expr->get_result_type()))) { + LOG_WARN("push back param type failed", K(ret)); + } } else { if (OB_FAIL(types.push_back(param_expr->get_result_type()))) { LOG_WARN("push back param type failed", K(ret)); diff --git a/src/sql/resolver/expr/ob_raw_expr_util.cpp b/src/sql/resolver/expr/ob_raw_expr_util.cpp index 0b7550ab6a..f55b818563 100644 --- a/src/sql/resolver/expr/ob_raw_expr_util.cpp +++ b/src/sql/resolver/expr/ob_raw_expr_util.cpp @@ -3657,6 +3657,71 @@ int ObRawExprUtils::try_add_cast_expr_above(ObRawExprFactory *expr_factory, return ret; } +int ObRawExprUtils::implict_cast_pl_udt_to_sql_udt(ObRawExprFactory *expr_factory, + const ObSQLSessionInfo *session, + ObRawExpr* &real_ref_expr) +{ + int ret = OB_SUCCESS; + + if (OB_ISNULL(real_ref_expr)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("real_ref_expr is null", K(ret)); + } else if (real_ref_expr->get_result_type().is_ext()) { + if (real_ref_expr->get_result_type().get_udt_id() == T_OBJ_XML) { + // add implicit cast to sql xmltype + ObRawExpr *new_expr = NULL; + ObCastMode cast_mode = CM_NONE; + ObExprResType sql_udt_type; + sql_udt_type.set_sql_udt(ObXMLSqlType); // set subschema id + if (OB_FAIL(ObSQLUtils::get_default_cast_mode(false, 0, session, cast_mode))) { + LOG_WARN("get default cast mode failed", K(ret)); + } else if (OB_FAIL(ObRawExprUtils::try_add_cast_expr_above( + expr_factory, session, + *real_ref_expr, sql_udt_type, cast_mode, new_expr))) { + LOG_WARN("try add cast expr above failed", K(ret)); + } else if (OB_FAIL(new_expr->add_flag(IS_OP_OPERAND_IMPLICIT_CAST))) { + LOG_WARN("failed to add flag", K(ret)); + } else { + real_ref_expr = new_expr; + } + } + } + return ret; +} + +int ObRawExprUtils::implict_cast_sql_udt_to_pl_udt(ObRawExprFactory *expr_factory, + const ObSQLSessionInfo *session, + ObRawExpr* &real_ref_expr) +{ + int ret = OB_SUCCESS; + + if (OB_ISNULL(real_ref_expr)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("real_ref_expr is null", K(ret)); + } else if (real_ref_expr->get_result_type().is_user_defined_sql_type()) { + if (real_ref_expr->get_result_type().is_xml_sql_type()) { + // add implicit cast to sql xmltype + ObRawExpr *new_expr = NULL; + ObCastMode cast_mode = CM_NONE; + ObExprResType pl_udt_type; + pl_udt_type.set_ext(); + pl_udt_type.set_extend_type(pl::PL_OPAQUE_TYPE); + pl_udt_type.set_udt_id(T_OBJ_XML); + if (OB_FAIL(ObSQLUtils::get_default_cast_mode(session, cast_mode))) { + LOG_WARN("get default cast mode failed", K(ret)); + } else if (OB_FAIL(ObRawExprUtils::try_add_cast_expr_above( + expr_factory, session, + *real_ref_expr, pl_udt_type, cast_mode, new_expr))) { + LOG_WARN("try add cast expr above failed", K(ret)); + } else if (OB_FAIL(new_expr->add_flag(IS_OP_OPERAND_IMPLICIT_CAST))) { + LOG_WARN("failed to add flag", K(ret)); + } else { + real_ref_expr = new_expr; + } + } + } + return ret; +} int ObRawExprUtils::create_cast_expr(ObRawExprFactory &expr_factory, ObRawExpr *src_expr, diff --git a/src/sql/resolver/expr/ob_raw_expr_util.h b/src/sql/resolver/expr/ob_raw_expr_util.h index a51c304bd3..6547392806 100644 --- a/src/sql/resolver/expr/ob_raw_expr_util.h +++ b/src/sql/resolver/expr/ob_raw_expr_util.h @@ -428,6 +428,14 @@ public: const ObExprResType &dst_type, const ObCastMode &cm, ObRawExpr *&new_expr); + + static int implict_cast_pl_udt_to_sql_udt(ObRawExprFactory *expr_factory, + const ObSQLSessionInfo *session, + ObRawExpr* &real_ref_expr); + + static int implict_cast_sql_udt_to_pl_udt(ObRawExprFactory *expr_factory, + const ObSQLSessionInfo *session, + ObRawExpr* &real_ref_expr); // new engine: may create more cast exprs to handle non-system-collation string. // e.g.: utf16->number: utf16->utf8->number (two cast expr) // utf8_bin->number: utf8->number (just one cat expr)