fix: procedure with xmltype inputs not supported

This commit is contained in:
obdev
2023-05-12 01:11:19 +00:00
committed by ob-robot
parent 94004732ee
commit a8ac8b911f
3 changed files with 43 additions and 11 deletions

View File

@ -28,6 +28,7 @@
#include "pl/ob_pl_stmt.h"
#include "share/ob_common_rpc_proxy.h"
#include "share/ob_rpc_struct.h"
#include "sql/engine/expr/ob_expr_column_conv.h"
namespace oceanbase
{
@ -128,7 +129,34 @@ int ObCallProcedureExecutor::execute(ObExecContext &ctx, ObCallProcedureStmt &st
if (expr->get_is_pl_mock_default_expr()) {
param.set_is_pl_mock_default_param(true);
}
if (OB_FAIL(params.push_back(param))) {
if (ob_is_xml_sql_type(param.get_type(), param.get_udt_subschema_id())) {
// convert call procedure input sql udt types to pl extend (only xmltype supported currently)
bool is_strict = is_strict_mode(ctx.get_my_session()->get_sql_mode());
const ObDataTypeCastParams dtc_params =
ObBasicSessionInfo::create_dtc_params(ctx.get_my_session());
ObCastMode cast_mode = CM_NONE;
ObExprResType result_type;
OZ (ObSQLUtils::get_default_cast_mode(stmt::T_NONE, ctx.get_my_session(), cast_mode));
ObCastCtx cast_ctx(&ctx.get_allocator(), &dtc_params, cast_mode, param.get_collation_type());
result_type.reset();
// if is xml type
result_type.set_ext();
result_type.set_extend_type(pl::PL_OPAQUE_TYPE);
result_type.set_udt_id(T_OBJ_XML);
ObObj tmp;
if (OB_FAIL(ret)) {
} else if (OB_FAIL(ObExprColumnConv::convert_with_null_check(tmp, param, result_type,
is_strict, cast_ctx, NULL))) {
LOG_WARN("Cast sql udt to pl extend failed",
K(ret), K(param), K(result_type), K(is_strict), K(i));
} else {
param = tmp;
param.set_udt_id(T_OBJ_XML);
param.set_param_meta();
}
}
if (OB_FAIL(ret)) {
} else if (OB_FAIL(params.push_back(param))) {
LOG_WARN("push back error", K(i), K(*expr), K(ret));
} else {
params.at(params.count() - 1).set_param_meta();

View File

@ -1869,6 +1869,18 @@ int ObRawExprResolverImpl::check_name_type(
return ret;
}
void ObRawExprResolverImpl::get_special_func_ident_name(ObString &ident_name, const ObItemType func_type)
{
// get ident name of spacial exprs not using first child as function name
if (func_type == T_FUN_SYS_XML_ELEMENT) {
ident_name = ObString::make_string("xmlelement");
} else if (func_type == T_FUN_SYS_XMLPARSE) {
ident_name = ObString::make_string("xmlparse");
} else if (func_type == T_FUN_ORA_XMLAGG) {
ident_name = ObString::make_string("xmlagg");
} else { /* do nothing */}
}
int ObRawExprResolverImpl::resolve_func_node_of_obj_access_idents(const ParseNode &left_node, ObQualifiedName &q_name)
{
int ret = OB_SUCCESS;
@ -1879,6 +1891,7 @@ int ObRawExprResolverImpl::resolve_func_node_of_obj_access_idents(const ParseNod
} else {
ObString ident_name(static_cast<int32_t>(
func_node.children_[0]->str_len_), func_node.children_[0]->str_value_);
get_special_func_ident_name(ident_name, func_node.type_);
// first bit in value_ of T_FUN_SYS node is used to mark NEW keyword,
// value_ & 0x1 == 1: not used,
@ -1889,16 +1902,6 @@ int ObRawExprResolverImpl::resolve_func_node_of_obj_access_idents(const ParseNod
if (ident_name.empty() && T_PL_SCOPE == ctx_.current_scope_ && lib::is_oracle_mode()) {
ret = OB_ERR_IDENT_EMPTY;
LOG_WARN("Identifier cannot be an empty string", K(ret), K(ident_name));
} else if (ident_name.empty()) {
if (func_node.type_ == T_FUN_SYS_MAKEXML) {
ident_name = ObString::make_string("sys_makexml");
} else if (func_node.type_ == T_FUN_SYS_XML_ELEMENT) {
ident_name = ObString::make_string("xmlelement");
} else if (func_node.type_ == T_FUN_SYS_XMLPARSE) {
ident_name = ObString::make_string("xmlparse");
} else if (func_node.type_ == T_FUN_ORA_XMLAGG) {
ident_name = ObString::make_string("xmlagg");
}
}
OZ (q_name.access_idents_.push_back(ObObjAccessIdent(ident_name, OB_INVALID_INDEX)), K(ident_name));

View File

@ -204,6 +204,7 @@ private:
int process_xml_attributes_node(const ParseNode *node, ObRawExpr *&expr);
int process_xml_attributes_values_node(const ParseNode *node, ObRawExpr *&expr);
int process_xmlparse_node(const ParseNode *node, ObRawExpr *&expr);
void get_special_func_ident_name(ObString &ident_name, const ObItemType func_type);
private:
int process_sys_func_params(ObSysFunRawExpr &func_expr, int current_columns_count);
int transform_ratio_afun_to_arg_div_sum(const ParseNode *ratio_to_report, ParseNode *&div);