[FEAT MERGE] [to #48722125] pl/sql name resolve refactor

This commit is contained in:
obdev 2023-04-18 06:12:14 +00:00 committed by ob-robot
parent 52e0115965
commit 0a0ba897c9
27 changed files with 1796 additions and 2178 deletions

View File

@ -61,20 +61,6 @@ typedef common::ParamStore ParamStore;
class ObPLCacheCtx;
enum ObProcType
{
INVALID_PROC_TYPE = 0,
STANDALONE_PROCEDURE = 1,
STANDALONE_FUNCTION = 2,
PACKAGE_PROCEDURE = 3, /* A subprogram created inside a package is a packaged subprogram */
PACKAGE_FUNCTION = 4,
NESTED_PROCEDURE = 5, /* A subprogram created inside a PL/SQL block is a nested subprogram */
NESTED_FUNCTION = 6,
STANDALONE_ANONYMOUS = 7,
UDT_PROCEDURE = 8,
UDT_FUNCTION = 9,
};
enum ObPLObjectType
{
INVALID_OBJECT_TYPE = -1,

View File

@ -2631,7 +2631,7 @@ int ObPLCodeGenerateVisitor::visit(const ObPLCallStmt &s)
ObLLVMValue array_value;
ObLLVMValue nocopy_array_value;
uint64_t package_id = s.get_package_id();
package_id = 1 == s.get_is_object_udf()
package_id = (1 == s.get_is_object_udf())
? share::schema::ObUDTObjectType::mask_object_id(package_id) : package_id;
if (OB_FAIL(args.push_back(generator_.get_vars().at(generator_.CTX_IDX)))) { //PL的执行环境
LOG_WARN("push_back error", K(ret));

File diff suppressed because it is too large Load Diff

View File

@ -116,6 +116,26 @@ public:
bool is_sync_package_var_;
};
class ObPLMockSelfArg
{
public:
ObPLMockSelfArg(
const ObIArray<ObObjAccessIdx> &access_idxs, ObSEArray<ObRawExpr*, 4> &expr_params, ObRawExprFactory &expr_factory)
: access_idxs_(access_idxs),
expr_params_(expr_params),
expr_factory_(expr_factory),
mark_only_(false),
mocked_(false) {}
int mock();
~ObPLMockSelfArg();
private:
const ObIArray<ObObjAccessIdx> &access_idxs_;
ObSEArray<ObRawExpr*, 4> &expr_params_;
ObRawExprFactory &expr_factory_;
bool mark_only_;
bool mocked_;
};
class ObPLPackageAST;
class ObPLResolver
{
@ -304,6 +324,10 @@ public:
int resolve_sqlcode_or_sqlerrm(sql::ObQualifiedName &q_name,
ObPLCompileUnitAST &unit_ast,
sql::ObRawExpr *&expr);
int resolve_construct(const ObQualifiedName &q_name,
const ObUDFInfo &udf_info,
const ObUserDefinedType &user_type,
ObRawExpr *&expr);
int resolve_construct(const sql::ObQualifiedName &q_name,
const sql::ObUDFInfo &udf_info,
ObRawExpr *&expr);
@ -506,6 +530,11 @@ public:
int check_static_bool_expr(const ObRawExpr *expr, bool &is_static_bool_expr);
static int adjust_routine_param_type(ObPLDataType &type);
int resolve_udf_info(
sql::ObUDFInfo &udf_info, ObIArray<ObObjAccessIdx> &access_idxs, ObPLCompileUnitAST &func);
int construct_name(ObString &database_name, ObString &package_name, ObString &routine_name, ObSqlString &object_name);
private:
int resolve_declare_var(const ObStmtNodeTree *parse_tree, ObPLDeclareVarStmt *stmt, ObPLFunctionAST &func_ast);
int resolve_declare_var(const ObStmtNodeTree *parse_tree, ObPLPackageAST &package_ast);
@ -624,9 +653,12 @@ private:
sql::ObRawExpr *&expr,
bool for_write = false);
int resolve_udf_without_brackets(sql::ObQualifiedName &q_name, ObPLCompileUnitAST &unit_ast, ObRawExpr *&expr);
int resolve_udf(sql::ObUDFInfo &udf_info,
const ObIArray<ObString> &access_name,
ObPLCompileUnitAST &func);
int make_self_symbol_expr(ObPLCompileUnitAST &func, ObRawExpr *&expr);
int add_udt_self_argument(const ObIRoutineInfo *routine_info,
ObIArray<ObRawExpr*> &expr_params,
ObIArray<ObObjAccessIdx> &access_idxs,
ObUDFInfo &udf_info,
ObPLCompileUnitAST &func);
int resolve_qualified_identifier(sql::ObQualifiedName &q_name,
ObIArray<sql::ObQualifiedName> &columns,
ObIArray<ObRawExpr*> &real_exprs,
@ -909,12 +941,9 @@ private:
ObParamExternType type,
uint64_t obj_id,
ObPLExternTypeInfo &extern_type_info);
int check_is_udt_routine(const ObObjAccessIdent &access_ident, // 当前正在resolve的ident
int check_is_udt_routine(const ObObjAccessIdent &access_ident,
const ObPLBlockNS &ns,
ObIArray<ObObjAccessIdx> &access_idxs,
ObObjAccessIdx &access_id,
ObString &udt_type_name,
uint64_t &udt_id,
bool &is_routine);
static int get_number_literal_value(ObRawExpr *expr, int64_t &result);
int check_assign_type(const ObPLDataType &dest_data_type, const ObRawExpr *right_expr);
@ -967,6 +996,10 @@ private:
ObPLFunctionAST &func,
int64_t &idx);
int check_update_column(const ObPLBlockNS &ns, const ObIArray<ObObjAccessIdx>& access_idxs);
static int get_udt_names(ObSchemaGetterGuard &schema_guard,
const uint64_t udt_id,
ObString &database_name,
ObString &udt_name);
static int get_udt_database_name(ObSchemaGetterGuard &schema_guard,
const uint64_t udt_id, ObString &db_name);
static bool check_with_rowid(const ObString &routine_name,
@ -974,6 +1007,71 @@ private:
static int recursive_replace_expr(ObRawExpr *expr,
ObQualifiedName &qualified_name,
ObRawExpr *real_expr);
int replace_udf_param_expr(ObQualifiedName &q_name,
ObIArray<ObQualifiedName> &columns,
ObIArray<ObRawExpr*> &real_exprs);
int replace_udf_param_expr(ObObjAccessIdent &access_ident,
ObIArray<ObQualifiedName> &columns,
ObIArray<ObRawExpr*> &real_exprs);
int get_names_by_access_ident(ObObjAccessIdent &access_ident,
ObIArray<ObObjAccessIdx> &access_idxs,
ObString &database_name,
ObString &package_name,
ObString &routine_name);
int check_routine_callable(const ObPLBlockNS &ns,
ObIArray<ObObjAccessIdx> &access_idxs,
ObIArray<ObRawExpr*> &expr_params,
const ObIRoutineInfo &routine_info);
int resolve_routine(ObObjAccessIdent &access_ident,
const ObPLBlockNS &ns,
ObIArray<ObObjAccessIdx> &access_idxs,
ObPLCompileUnitAST &func);
int resolve_function(ObObjAccessIdent &access_ident,
ObIArray<ObObjAccessIdx> &access_idxs,
const ObIRoutineInfo *routine_info,
ObPLCompileUnitAST &func);
int resolve_procedure(ObObjAccessIdent &access_ident,
ObIArray<ObObjAccessIdx> &access_idxs,
const ObIRoutineInfo *routine_info,
ObProcType routine_type);
int resolve_construct(ObObjAccessIdent &access_ident,
const ObPLBlockNS &ns,
ObIArray<ObObjAccessIdx> &access_idxs,
uint64_t user_type_id,
ObPLCompileUnitAST &func);
int resolve_self_element_access(ObObjAccessIdent &access_ident,
const ObPLBlockNS &ns,
ObIArray<ObObjAccessIdx> &access_idxs,
ObPLCompileUnitAST &func);
int build_current_access_idx(uint64_t parent_id,
ObObjAccessIdx &access_idx,
ObObjAccessIdent &access_ident,
const ObPLBlockNS &ns,
ObIArray<ObObjAccessIdx> &access_idxs,
ObPLCompileUnitAST &func);
int build_collection_index_expr(ObObjAccessIdent &access_ident,
ObObjAccessIdx &access_idx,
const ObPLBlockNS &ns,
ObIArray<ObObjAccessIdx> &access_idxs,
const ObUserDefinedType &user_type,
ObPLCompileUnitAST &func);
int build_access_idx_sys_func(uint64_t parent_id, ObObjAccessIdx &access_idx);
int resolve_composite_access(ObObjAccessIdent &access_ident,
ObIArray<ObObjAccessIdx> &access_idxs,
const ObPLBlockNS &ns,
ObPLCompileUnitAST &func);
int init_udf_info_of_accessidents(ObIArray<ObObjAccessIdent> &access_ident);
private:
ObPLResolveCtx resolve_ctx_;
ObPLExternalNS external_ns_;

View File

@ -1489,8 +1489,11 @@ int ObPLExternalNS::resolve_external_symbol(const common::ObString &name,
uint64_t package_id = OB_INVALID_ID;
if (parent_id != OB_INVALID_INDEX) {
db_id = parent_id;
} else {
OZ (session_info.get_database_id(db_id));
} else if (OB_FAIL(session_info.get_database_id(db_id))) {
LOG_WARN("failed to get session database id", K(ret), K(db_id));
} else if (OB_INVALID_ID == db_id) {
ret = OB_ERR_NO_DB_SELECTED;
LOG_WARN("No database selected", K(ret));
}
if (OB_SUCC(ret)) {
if (OB_FAIL(schema_guard.get_package_id(
@ -1669,7 +1672,9 @@ int ObPLExternalNS::resolve_external_symbol(const common::ObString &name,
}
break;
case PKG_VAR: {
if (lib::is_mysql_mode()) {
if (lib::is_mysql_mode()
&& get_tenant_id_by_object_id(parent_id) != OB_SYS_TENANT_ID
&& session_info.get_effective_tenant_id() != OB_SYS_TENANT_ID) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("package is not supported in Mysql mode", K(type), K(ret));
} else {

View File

@ -859,6 +859,9 @@ public:
|| UDT_FUNCTION == type_; }
inline uint64_t get_tenant_id() const { return tenant_id_; }
inline uint64_t get_db_id() const { return db_id_; }
virtual uint64_t get_database_id() const { return db_id_; }
virtual uint64_t get_package_id() const { return pkg_id_; }
inline uint64_t get_pkg_id() const { return pkg_id_; }
inline ObProcType get_type() const { return type_; }
int get_idx(int64_t &idx) const;

View File

@ -78,6 +78,20 @@ class ObPLUserTypeTable;
class ObUserDefinedType;
class ObPLStmt;
enum ObProcType
{
INVALID_PROC_TYPE = 0,
STANDALONE_PROCEDURE,
STANDALONE_FUNCTION,
PACKAGE_PROCEDURE, /* A subprogram created inside a package is a packaged subprogram */
PACKAGE_FUNCTION,
NESTED_PROCEDURE, /* A subprogram created inside a PL/SQL block is a nested subprogram */
NESTED_FUNCTION,
STANDALONE_ANONYMOUS,
UDT_PROCEDURE,
UDT_FUNCTION,
};
enum ObPLType
{
PL_INVALID_TYPE = -1,
@ -644,7 +658,7 @@ public:
bool is_subprogram_var() const { return IS_SUBPROGRAM_VAR == access_type_; }
bool is_user_var() const { return IS_USER == access_type_; }
bool is_session_var() const { return IS_SESSION == access_type_ || IS_GLOBAL == access_type_; }
bool is_ns() const { return IS_DB_NS == access_type_ || IS_PKG_NS == access_type_; }
bool is_ns() const { return IS_DB_NS == access_type_ || IS_PKG_NS == access_type_ || IS_UDT_NS == access_type_; }
bool is_const() const { return IS_CONST == access_type_; }
bool is_property() const { return IS_PROPERTY == access_type_; }
bool is_external() const

View File

@ -30303,7 +30303,7 @@ int ObDDLService::drop_user_defined_function(const obrpc::ObDropUserDefinedFunct
LOG_WARN("check_udf_exist failed", K(tenant_id), K(name), K(ret));
} else if (!is_exist) {
if (if_exist) {
LOG_USER_NOTE(OB_ERR_FUNCTION_UNKNOWN, name.length(), name.ptr());
LOG_USER_NOTE(OB_ERR_FUNCTION_UNKNOWN, "FUNCTION", name.length(), name.ptr());
LOG_INFO("function not exist, no need to delete it", K(tenant_id), K(name));
} else {
ret = OB_ERR_FUNCTION_UNKNOWN;

View File

@ -7120,10 +7120,10 @@ static const _error _error_OB_ERR_FUNCTION_UNKNOWN = {
.mysql_errno = ER_SP_DOES_NOT_EXIST,
.sqlstate = "42000",
.str_error = "FUNCTION does not exist",
.str_user_error = "FUNCTION %.*s does not exist",
.str_user_error = "%s %.*s does not exist",
.oracle_errno = 600,
.oracle_str_error = "ORA-00600: internal error code, arguments: -5055, FUNCTION does not exist",
.oracle_str_user_error = "ORA-00600: internal error code, arguments: -5055, FUNCTION %.*s does not exist"
.oracle_str_user_error = "ORA-00600: internal error code, arguments: -5055, %s %.*s does not exist"
};
static const _error _error_OB_ERR_CREAT_MODIFY_TIME_COLUMN = {
.error_name = "OB_ERR_CREAT_MODIFY_TIME_COLUMN",

View File

@ -695,7 +695,7 @@ DEFINE_ERROR(OB_ERR_PASSWORD_EMPTY, -5051, -1, "HY000", "Empty password");
DEFINE_ERROR(OB_ERR_GRANT_PRIVILEGES_TO_CREATE_TABLE, -5052, -1, "42000", "Failed to grant privelege");
DEFINE_ERROR_EXT(OB_ERR_WRONG_DYNAMIC_PARAM, -5053, -1, "HY093", "Wrong dynamic parameters", "Incorrect arguments number to EXECUTE, need %ld arguments but give %ld");
DEFINE_ORACLE_ERROR_EXT(OB_ERR_PARAM_SIZE, -5054, ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, "42000", "Incorrect parameter count", "Incorrect parameter count in the call to native function '%.*s'", 909, "invalid number of arguments", "invalid number of arguments in the call to native function '%.*s'");
DEFINE_ERROR_EXT(OB_ERR_FUNCTION_UNKNOWN, -5055, ER_SP_DOES_NOT_EXIST, "42000", "FUNCTION does not exist", "FUNCTION %.*s does not exist");
DEFINE_ERROR_EXT(OB_ERR_FUNCTION_UNKNOWN, -5055, ER_SP_DOES_NOT_EXIST, "42000", "FUNCTION does not exist", "%s %.*s does not exist");
DEFINE_ERROR(OB_ERR_CREAT_MODIFY_TIME_COLUMN, -5056, -1, "23000", "CreateTime or ModifyTime column cannot be modified");
DEFINE_ERROR(OB_ERR_MODIFY_PRIMARY_KEY, -5057, -1, "23000", "Primary key cannot be modified");
DEFINE_ERROR(OB_ERR_PARAM_DUPLICATE, -5058, -1, "42000", "Duplicated parameters");

View File

@ -2302,7 +2302,7 @@ constexpr int OB_ERR_INVALID_DATE_MSG_FMT_V2 = -4219;
#define OB_ERR_GRANT_PRIVILEGES_TO_CREATE_TABLE__USER_ERROR_MSG "Failed to grant privelege"
#define OB_ERR_WRONG_DYNAMIC_PARAM__USER_ERROR_MSG "Incorrect arguments number to EXECUTE, need %ld arguments but give %ld"
#define OB_ERR_PARAM_SIZE__USER_ERROR_MSG "Incorrect parameter count in the call to native function '%.*s'"
#define OB_ERR_FUNCTION_UNKNOWN__USER_ERROR_MSG "FUNCTION %.*s does not exist"
#define OB_ERR_FUNCTION_UNKNOWN__USER_ERROR_MSG "%s %.*s does not exist"
#define OB_ERR_CREAT_MODIFY_TIME_COLUMN__USER_ERROR_MSG "CreateTime or ModifyTime column cannot be modified"
#define OB_ERR_MODIFY_PRIMARY_KEY__USER_ERROR_MSG "Primary key cannot be modified"
#define OB_ERR_PARAM_DUPLICATE__USER_ERROR_MSG "Duplicated parameters"
@ -4346,7 +4346,7 @@ constexpr int OB_ERR_INVALID_DATE_MSG_FMT_V2 = -4219;
#define OB_ERR_GRANT_PRIVILEGES_TO_CREATE_TABLE__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -5052, Failed to grant privelege"
#define OB_ERR_WRONG_DYNAMIC_PARAM__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -5053, Incorrect arguments number to EXECUTE, need %ld arguments but give %ld"
#define OB_ERR_PARAM_SIZE__ORA_USER_ERROR_MSG "ORA-00909: invalid number of arguments in the call to native function '%.*s'"
#define OB_ERR_FUNCTION_UNKNOWN__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -5055, FUNCTION %.*s does not exist"
#define OB_ERR_FUNCTION_UNKNOWN__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -5055, %s %.*s does not exist"
#define OB_ERR_CREAT_MODIFY_TIME_COLUMN__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -5056, CreateTime or ModifyTime column cannot be modified"
#define OB_ERR_MODIFY_PRIMARY_KEY__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -5057, Primary key cannot be modified"
#define OB_ERR_PARAM_DUPLICATE__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -5058, Duplicated parameters"

View File

@ -125,6 +125,8 @@ public:
virtual int find_param_by_name(const common::ObString &name, int64_t &position) const = 0;
virtual int get_routine_param(int64_t position, ObIRoutineParam *&param) const = 0;
virtual const ObIRoutineParam* get_ret_info() const = 0;
virtual uint64_t get_database_id() const = 0;
virtual uint64_t get_package_id() const = 0;
virtual void set_deterministic() = 0;
virtual bool is_deterministic() const = 0;
virtual void set_parallel_enable() = 0;

View File

@ -6759,7 +6759,7 @@ int ObSPIService::resolve_ref_objects(const ParseResult &parse_result,
}
}
if (OB_SUCC(ret)) {
if (OB_FAIL(ObResolverUtils::resolve_udf(udf_node, case_mode, udf_info))) {
if (OB_FAIL(ObResolverUtils::resolve_udf_name_by_parse_node(udf_node, case_mode, udf_info))) {
LOG_WARN("fail to resolve udf name", K(ret));
} else if (udf_info.udf_database_.empty()) {
udf_info.udf_database_ = session.get_database_name();

View File

@ -2675,18 +2675,19 @@ MOD '(' expr ',' expr ')'
}
| relation_name '.' function_name '(' opt_expr_as_list ')'
{
ParseNode *params = NULL;
ParseNode *function = NULL;
ParseNode *sub_obj_access_ref = NULL;
ParseNode *udf_node = NULL;
if (NULL != $5)
{
ParseNode *params = NULL;
merge_nodes(params, result, T_EXPR_LIST, $5);
malloc_non_terminal_node($$, result->malloc_pool_, T_FUN_UDF, 4, $3, params, $1, NULL);
store_pl_ref_object_symbol($$, result, REF_FUNC);
}
else
{
malloc_non_terminal_node($$, result->malloc_pool_, T_FUN_UDF, 4, $3, NULL, $1, NULL);
store_pl_ref_object_symbol($$, result, REF_FUNC);
}
malloc_non_terminal_node(function, result->malloc_pool_, T_FUN_SYS, 2, $3, params);
malloc_non_terminal_node(sub_obj_access_ref, result->malloc_pool_, T_OBJ_ACCESS_REF, 2, function, NULL);
malloc_non_terminal_node($$, result->malloc_pool_, T_OBJ_ACCESS_REF, 2, $1, sub_obj_access_ref);
malloc_non_terminal_node(udf_node, result->malloc_pool_, T_FUN_UDF, 4, $3, params, $1, NULL);
store_pl_ref_object_symbol(udf_node, result, REF_FUNC);
}
| sys_interval_func
{

View File

@ -223,11 +223,9 @@ int ObVariableSetResolver::resolve_value_expr(ParseNode &val_node, ObRawExpr *&v
sub_query_info, aggr_exprs, win_exprs,
udf_info, op_exprs, user_var_exprs))) {
LOG_WARN("resolve expr failed", K(ret));
} else if (udf_info.count() > 0 &&
OB_FAIL(ObRawExprUtils::init_udfs_info(params_, udf_info))) {
LOG_WARN("failed to init udf infos", K(ret));
} else if (OB_FAIL(ObResolverUtils::resolve_columns_for_const_expr(value_expr, columns, params_))) {
LOG_WARN("resolve columns for const expr failed", K(ret));
} else if (udf_info.count() > 0) {
ret = OB_ERR_UNEXPECTED;
LOG_ERROR("UDFInfo should not found be here!!!", K(ret));
} else if (value_expr->get_expr_type() == T_SP_CPARAM) {
ObCallParamRawExpr *call_expr = static_cast<ObCallParamRawExpr *>(value_expr);
if (OB_ISNULL(call_expr->get_expr())) {
@ -249,6 +247,8 @@ int ObVariableSetResolver::resolve_value_expr(ParseNode &val_node, ObRawExpr *&v
LOG_TRACE("set user variable with subquery", K(sub_query_info.count()), K(is_mysql_mode()));
}
if (OB_FAIL(ret)) {
} else if (OB_FAIL(ObResolverUtils::resolve_columns_for_const_expr(value_expr, columns, params_))) {
LOG_WARN("resolve columns for const expr failed", K(ret));
} else if (OB_FAIL(value_expr->formalize(params_.session_info_))) {
LOG_WARN("failed to formalize value expr", K(ret));
} else {

View File

@ -1468,34 +1468,8 @@ int ObDMLResolver::resolve_sql_expr(const ParseNode &node, ObRawExpr *&expr,
}
if (OB_SUCC(ret) && udf_info.count() > 0) {
stmt_->get_query_ctx()->has_pl_udf_ = true;
for (int64_t i = 0; OB_SUCC(ret) && i < udf_info.count(); ++i) {
ObUDFInfo &udf = udf_info.at(i);
if(OB_FAIL(ObRawExprUtils::init_udf_info(params_, udf))) {
LOG_WARN("resolve user defined functions failed", K(ret));
} else {
ObDMLStmt *stmt = get_stmt();
ObUDFRawExpr *udf_expr = static_cast<ObUDFRawExpr*>(udf_info.at(i).ref_expr_);
share::schema::ObSchemaGetterGuard *schema_guard = NULL;
uint64_t database_id = OB_INVALID_ID;
if (OB_ISNULL(stmt) || OB_ISNULL(udf_expr)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("stmt or expr is null", K(stmt), K(udf_expr), K(ret));
} else if (OB_ISNULL(schema_guard = params_.schema_checker_->get_schema_guard())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("table schema is null", K(ret), K(schema_guard));
} else if (OB_FAIL(schema_guard->get_database_id(session_info_->get_effective_tenant_id(), udf_expr->get_database_name(), database_id))) {
LOG_WARN("failed to get database id", K(ret));
} else if (udf_expr->need_add_dependency()) {
ObSchemaObjVersion udf_version;
uint64_t dep_obj_id = view_ref_id_;
uint64_t dep_db_id = database_id;
OZ (udf_expr->get_schema_object_version(udf_version));
OZ (stmt->add_global_dependency_table(udf_version));
OZ (stmt->add_ref_obj_version(dep_obj_id, dep_db_id, ObObjectType::VIEW, udf_version, *allocator_));
}
}
}
ret = OB_ERR_UNEXPECTED;
LOG_ERROR("UDFInfo should not found be here!!!", K(ret));
}
//try to convert ObUDFRawExpr to ObAggRawExpr for pl agg udf
if (OB_SUCC(ret)) {
@ -2331,22 +2305,39 @@ int ObDMLResolver::resolve_qualified_identifier(ObQualifiedName &q_name,
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语境的不需要
&& (real_ref_expr->is_const_raw_expr() //local变量
&& 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));
|| 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()
|| self->is_sys_func_expr()) {
OZ (ObResolverUtils::resolve_external_param_info(params_.external_param_info_,
*params_.expr_factory_,
params_.prepare_param_count_,
self));
OZ (ObRawExprUtils::replace_ref_column(real_ref_expr,
real_ref_expr->get_param_expr(0),
self));
}
}
}
}
}
@ -10160,7 +10151,9 @@ int ObDMLResolver::resolve_external_name(ObQualifiedName &q_name,
} else if (OB_ISNULL(schema_guard = params_.schema_checker_->get_schema_guard())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("table schema is null", K(ret), K(schema_guard));
} else if (OB_FAIL(schema_guard->get_database_id(session_info_->get_effective_tenant_id(), udf_expr->get_database_name(), database_id))) {
} else if (OB_FAIL(schema_guard->get_database_id(session_info_->get_effective_tenant_id(),
udf_expr->get_database_name().empty() ? session_info_->get_database_name() : udf_expr->get_database_name(),
database_id))) {
LOG_WARN("failed to get database id", K(ret));
} else if (udf_expr->need_add_dependency()) {
uint64_t dep_obj_id = view_ref_id_;

View File

@ -94,7 +94,7 @@ int ObRawExprFactory::create_raw_expr<ObOpRawExpr>(ObItemType expr_type, ObOpRaw
void ObQualifiedName::format_qualified_name(ObNameCaseMode mode)
{
UNUSED(mode); //TODO: @ryan.ly @yuming.wyc
bool maybe_column = !is_sys_func() && !is_pl_udf() && !is_dll_udf() && !is_pl_var();
bool maybe_column = !is_sys_func() && !is_pl_udf() && !is_dll_udf() && !is_pl_var() && !is_udf_return_access();
for (int64_t i = 0; maybe_column && i < access_idents_.count(); ++i) {
if (access_idents_.at(i).access_name_.empty() || access_idents_.at(i).access_index_ != OB_INVALID_INDEX) {
maybe_column = false;
@ -2638,7 +2638,8 @@ int ObObjAccessRawExpr::add_access_indexs(const ObIArray<pl::ObObjAccessIdx> &ac
//do nothing
}
break;
case pl::ObObjAccessIdx::IS_UDF_NS: {
case pl::ObObjAccessIdx::IS_UDF_NS:
case pl::ObObjAccessIdx::IS_UDT_NS: {
//do nothing
}
break;

View File

@ -949,15 +949,11 @@ struct ObUDFInfo
is_contain_self_param_(false),
is_udt_udf_inside_pkg_(false),
is_new_keyword_used_(false),
flag_(0),
self_arg_(NULL) {}
flag_(0) {}
void set_is_udf_udt_static() {
flag_ |= UDF_UDT_STATIC;
}
bool is_udf_udt_static() const {
return is_udt_udf_ && !!(flag_ & UDF_UDT_STATIC);
}
bool is_udf_udt_member() const {
return is_udt_udf_ && !(flag_ & UDF_UDT_STATIC);
}
@ -1013,7 +1009,6 @@ struct ObUDFInfo
bool is_udt_udf_inside_pkg_;
bool is_new_keyword_used_; // if in NEW obj(...) form
uint64_t flag_;
ObRawExpr *self_arg_; // if this is udt routine, it has self argument
};
enum AccessNameType
@ -1082,6 +1077,7 @@ public:
inline void set_type_method() { type_ = TYPE_METHOD; }
inline void set_cursor_attr() { type_ = CURSOR_ATTR; }
inline void set_udt_ns() { type_ = UDT_NS; }
inline bool is_unknown() const { return UNKNOWN == type_; }
inline bool is_sys_func() const { return SYS_FUNC == type_; }
inline bool is_dll_udf() const { return DLL_UDF == type_; }
inline bool is_pl_udf() const { return PL_UDF == type_; }
@ -1150,7 +1146,21 @@ public:
}
void format_qualified_name(common::ObNameCaseMode mode);
inline bool is_sys_func() const { return 1 == access_idents_.count() && access_idents_.at(0).is_sys_func(); }
inline bool is_unknown() const
{
bool bret = true;
for (int64_t i = 0; bret && i < access_idents_.count(); ++i) {
if (!access_idents_.at(i).is_unknown()) {
bret = false;
break;
}
}
return bret;
}
inline bool is_sys_func() const
{
return 1 == access_idents_.count() && access_idents_.at(0).is_sys_func();
}
inline bool is_pl_udf() const
{
bool bret = !access_idents_.empty()
@ -3841,6 +3851,7 @@ public:
K_(is_aggr_udf_distinct),
K_(loc),
K_(is_udt_cons),
K_(params_desc_v2),
N_CHILDREN, exprs_);
private:
uint64_t udf_id_;

View File

@ -3131,13 +3131,15 @@ int ObRawExprPrinter::print(ObUDFRawExpr *expr)
LOG_WARN("stmt_ is NULL of buf_ is NULL or pos_ is NULL or expr is NULL", K(ret));
} else {
if (!print_params_.for_dblink_ &&
!expr->get_database_name().empty()) {
!expr->get_database_name().empty() &&
expr->get_database_name().case_compare("oceanbase") != 0) {
PRINT_QUOT;
DATA_PRINTF("%.*s", LEN_AND_PTR(expr->get_database_name()));
PRINT_QUOT;
DATA_PRINTF(".");
}
if (!expr->get_package_name().empty()) {
if (!expr->get_package_name().empty() &&
!expr->get_is_udt_cons()) {
PRINT_QUOT;
DATA_PRINTF("%.*s", LEN_AND_PTR(expr->get_package_name()));
PRINT_QUOT;
@ -3156,6 +3158,8 @@ int ObRawExprPrinter::print(ObUDFRawExpr *expr)
for (int64_t i = 0; OB_SUCC(ret) && i < expr->get_param_count(); ++i) {
if (params_type.at(i).is_null()) { // default parameter, do not print
// do nothing ...
} else if (0 == i && expr->get_is_udt_cons()) {
// do not print construnct null self argument
} else {
if (!params_name.at(i).empty()) {
PRINT_QUOT;

File diff suppressed because it is too large Load Diff

View File

@ -43,11 +43,14 @@ public:
int check_first_node(const ParseNode *node);
static int check_sys_func(ObQualifiedName &q_name, bool &is_sys_func);
static int check_pl_udf(ObQualifiedName &q_name, const ObSQLSessionInfo *session_info,
static int check_pl_udf(ObQualifiedName &q_name,
const ObSQLSessionInfo *session_info,
ObSchemaChecker *schema_checker,
pl::ObPLBlockNS *secondary_namespace,
bool &is_pl_udf);
pl::ObProcType &proc_type);
int resolve_func_node_of_obj_access_idents(const ParseNode &func_node, ObQualifiedName &q_name);
int check_name_type(
ObQualifiedName &q_name, ObStmtScope scope, AccessNameType &type);
// types and constants
private:
// disallow copy
@ -161,9 +164,7 @@ private:
int process_cursor_attr_node(const ParseNode &node, ObRawExpr *&expr);
int process_obj_access_node(const ParseNode &node, ObRawExpr *&expr);
int resolve_obj_access_idents(const ParseNode &node, ObQualifiedName &q_name);
int check_name_type(ObQualifiedName &q_name, ObStmtScope scope, AccessNameType &type);
int check_pl_variable(ObQualifiedName &q_name, bool &is_pl_var);
int check_dll_udf(ObQualifiedName &q_name, bool &is_dll_udf);
int is_explict_func_expr(const ParseNode &node, bool &is_func);
int check_pseudo_column_exist(ObItemType type, ObPseudoColumnRawExpr *&expr);
int process_pseudo_column_node(const ParseNode &node, ObRawExpr *&expr);
@ -177,9 +178,7 @@ private:
inline bool is_prior_expr_valid_scope(ObStmtScope scope) const;
static bool should_not_contain_window_clause(const ObItemType func_type);
static bool should_contain_order_by_clause(const ObItemType func_type);
int process_udf_node(const ParseNode *node, bool record_udf_info, ObRawExpr *&expr);
int resolve_udf_info(const ParseNode *node, bool record_udf_info, ObUDFInfo &udf_info,
ParseNode *extra_param = NULL, ObRawExpr *extar_expr = NULL);
int resolve_udf_node(const ParseNode *node, ObUDFInfo &udf_info);
int process_sqlerrm_node(const ParseNode *node, ObRawExpr *&expr);
int process_plsql_var_node(const ParseNode *node, ObRawExpr *&expr);
int process_call_param_node(const ParseNode *node, ObRawExpr *&expr);
@ -210,6 +209,11 @@ private:
int reset_aggr_sort_nulls_first(ObIArray<OrderItem> &aggr_sort_item);
inline void set_udf_param_syntax_err(const bool val) { is_udf_param_syntax_err_ = val; }
inline bool get_udf_param_syntax_err() { return is_udf_param_syntax_err_; }
int resolve_left_node_of_obj_access_idents(const ParseNode &node, ObQualifiedName &q_name);
int resolve_right_node_of_obj_access_idents(const ParseNode &node, ObQualifiedName &q_name);
private:
// data members
ObExprResolveContext &ctx_;
bool is_contains_assignment_;

View File

@ -729,7 +729,6 @@ int ObRawExprUtils::resolve_udf_common_info(const ObString &db_name,
OX (udf_raw_expr->set_pkg_body_udf(is_pkg_body_udf));
OX (udf_raw_expr->set_type_id(type_id));
OX (udf_raw_expr->set_is_aggregate_udf(is_pl_agg));
LOG_DEBUG("resolve_udf_common_info!!!", K(type_id), K(is_pl_agg));
return ret;
}
@ -787,11 +786,10 @@ int ObRawExprUtils::resolve_udf_param_types(const ObIRoutineInfo* func_info,
OX (udf_raw_expr->set_is_return_sys_cursor(true));
}
SET_RES_TYPE_BY_PL_TYPE(result_type, ret_pl_type);
if (lib::is_oracle_mode()
&& OB_INVALID_ID != static_cast<const ObRoutineInfo *> (func_info)->get_package_id()
&& is_sys_tenant(
pl::get_tenant_id_by_object_id(
static_cast<const ObRoutineInfo *>(func_info)->get_package_id()))
if (OB_SUCC(ret)
&& lib::is_oracle_mode()
&& OB_INVALID_ID != func_info->get_package_id()
&& is_sys_tenant(pl::get_tenant_id_by_object_id(func_info->get_package_id()))
&& OB_NOT_NULL(ret_pl_type.get_data_type())
&& !(ret_pl_type.get_data_type()->get_meta_type().get_type() == ObLongTextType)
&& ob_is_string_type(ret_pl_type.get_data_type()->get_meta_type().get_type())) {
@ -803,13 +801,7 @@ int ObRawExprUtils::resolve_udf_param_types(const ObIRoutineInfo* func_info,
OX (udf_raw_expr->set_pls_type(ret_pl_type.get_pl_integer_type()));
if (OB_FAIL(ret)) {
} else if (!ret_pl_type.is_obj_type()) {
// if (ret_pl_type.is_udt_type()) {
OX (result_type.set_udt_id(ret_pl_type.get_user_type_id()));
// } else {
// ret = OB_NOT_SUPPORTED;
// LOG_WARN("not supported other type as function return type",
// K(ret), K(ret_pl_type));
// }
OX (result_type.set_udt_id(ret_pl_type.get_user_type_id()));
} else if (result_type.is_enum_or_set()) {
const ObRoutineParam* r_param = static_cast<const ObRoutineParam*>(ret_param);
CK (OB_NOT_NULL(r_param));
@ -989,7 +981,8 @@ int ObRawExprUtils::resolve_udf_param_exprs(ObResolverParams &params,
OZ (udf_raw_expr->add_param_expr(param_exprs.at(i)));
OZ (udf_raw_expr->add_param_name(param_names.at(i)));
}
CK ((udf_info.udf_param_num_ + param_exprs.count()) == udf_raw_expr->get_param_count());
OV ((udf_info.udf_param_num_ + param_exprs.count()) == udf_raw_expr->get_param_count(),
OB_ERR_UNEXPECTED, K(udf_info.udf_param_num_), K(param_exprs.count()), K(udf_raw_expr->get_param_count()));
}
if (OB_SUCC(ret)
&& (func_info->get_param_count() != udf_info.udf_param_num_ + param_exprs.count())) {
@ -1125,7 +1118,7 @@ do {
}
}
OZ (pl::ObPLResolver::resolve_nocopy_params(func_info, udf_info));
CK (udf_raw_expr->get_params_desc().count() == udf_raw_expr->get_param_count());
OV (udf_raw_expr->get_params_desc().count() == udf_raw_expr->get_param_count(), OB_ERR_UNEXPECTED, KPC(udf_raw_expr));
return ret;
}
@ -1152,135 +1145,29 @@ int ObRawExprUtils::rebuild_expr_params(ObUDFInfo &udf_info,
return ret;
}
int ObRawExprUtils::init_udf_info(ObResolverParams &params,
ObUDFInfo &udf_info)
int ObRawExprUtils::resolve_udf_info(common::ObIAllocator &allocator,
sql::ObRawExprFactory &expr_factory,
sql::ObSQLSessionInfo &session_info,
share::schema::ObSchemaGetterGuard &schema_guard,
ObUDFInfo &udf_info)
{
int ret = OB_SUCCESS;
ObString db_name;
ObString package_name;
ObString udf_name;
CK (OB_NOT_NULL(params.schema_checker_));
CK (OB_NOT_NULL(params.session_info_));
CK (OB_NOT_NULL(params.allocator_));
CK (OB_NOT_NULL(GCTX.sql_proxy_));
OZ (ObResolverUtils::resolve_udf_name(*params.schema_checker_,
*params.session_info_,
udf_info,
db_name,
package_name,
udf_name));
if (OB_SUCC(ret) && db_name.empty()) {
db_name = params.session_info_->get_database_name();
}
if (OB_SUCC(ret) && db_name.empty()) {
ret = OB_ERR_NO_DB_SELECTED;
LOG_WARN("no database selected", K(ret), K(db_name));
}
if(OB_SUCC(ret)) {
const ObPackageInfo *package_info = NULL;
const ObRoutineInfo *func_info = NULL;
ObSEArray<ObRawExpr*, 8> expr_params;
if (OB_FAIL(rebuild_expr_params(udf_info, params.expr_factory_, expr_params))) {
LOG_WARN("failed to rebuild expr params", K(ret), K(udf_info));
} else if (OB_FAIL(ObResolverUtils::get_routine(params,
params.session_info_->get_effective_tenant_id(),
params.session_info_->get_database_name(),
db_name,
package_name,
udf_name,
ROUTINE_FUNCTION_TYPE,
expr_params,
func_info))) {
ret = OB_ERR_SP_DOES_NOT_EXIST == ret ? OB_ERR_FUNCTION_UNKNOWN : ret;
LOG_WARN("failed to get routine info",
K(db_name), K(udf_info.udf_package_), K(udf_info.udf_name_), K(ret));
} else if (OB_ISNULL(func_info)) {
ret = OB_ERR_FUNCTION_UNKNOWN;
LOG_WARN("stored function not exists", K(ret), K(udf_info.udf_name_), K(db_name));
LOG_USER_ERROR(OB_ERR_FUNCTION_UNKNOWN, udf_info.udf_name_.length(), udf_info.udf_name_.ptr());
} else if (!func_info->is_function()) {
ret = OB_ERR_FUNCTION_UNKNOWN;
LOG_WARN("user define function must be stored function, but got a procedure",
K(ret), K(db_name), K(package_name), K(udf_name), K(func_info->is_function()));
LOG_USER_ERROR(OB_ERR_FUNCTION_UNKNOWN, udf_info.udf_name_.length(), udf_info.udf_name_.ptr());
pl::ObPLPackageGuard dummy_pkg_guard(session_info.get_effective_tenant_id());
pl::ObPLResolver pl_resolver(allocator,
session_info,
schema_guard,
dummy_pkg_guard,
*GCTX.sql_proxy_,
expr_factory,
NULL,
false);
HEAP_VAR(pl::ObPLFunctionAST, func_ast, allocator) {
ObSEArray<pl::ObObjAccessIdx, 1> access_idxs;
if (OB_FAIL(pl_resolver.init(func_ast))) {
LOG_WARN("pl resolver init failed", K(ret));
} else if (OB_FAIL(pl_resolver.resolve_udf_info(udf_info, access_idxs, func_ast))) {
LOG_WARN("failed to resolve udf info", K(ret));
}
if (OB_SUCC(ret) && func_info->is_udt_routine() && !func_info->is_udt_static_routine()) {
ret = OB_ERR_CALL_WRONG_ARG;
LOG_USER_ERROR(OB_ERR_CALL_WRONG_ARG, func_info->get_routine_name().length(),
func_info->get_routine_name().ptr());
}
if (OB_SUCC(ret) && func_info->is_udt_routine()) {
udf_info.is_udt_udf_ = true;
}
if (OB_SUCC(ret) && OB_INVALID_ID != func_info->get_package_id()) {
CK (OB_NOT_NULL(params.schema_checker_));
CK (OB_NOT_NULL(params.schema_checker_->get_schema_guard()));
OZ (params.schema_checker_->get_schema_guard()
->get_package_info(func_info->get_tenant_id(),
func_info->get_package_id(), package_info));
CK (OB_NOT_NULL(package_info));
}
OZ (resolve_udf_common_info(db_name,
package_name,
OB_INVALID_ID == func_info->get_package_id()
? func_info->get_routine_id()
: func_info->get_subprogram_id(),
func_info->get_package_id(),
ObArray<int64_t>(),
OB_INVALID_ID == func_info->get_package_id()
? func_info->get_schema_version()
: common::OB_INVALID_VERSION,
OB_INVALID_ID == func_info->get_package_id()
? common::OB_INVALID_VERSION
: package_info->get_schema_version(),
func_info->is_deterministic(),
func_info->is_parallel_enable(),
false, /*is_pkg_body_udf*/
func_info->is_aggregate(),
func_info->get_type_id(),
udf_info));
OZ (resolve_udf_param_types(func_info,
*(params.schema_checker_->get_schema_mgr()),
*(params.session_info_),
*(params.allocator_),
*(GCTX.sql_proxy_),
udf_info));
OZ (resolve_udf_param_exprs(params, func_info, udf_info));
}
return ret;
}
int ObRawExprUtils::init_udfs_info(ObResolverParams &params,
ObIArray<ObUDFInfo> &udfs_info)
{
int ret = OB_SUCCESS;
for (int64_t i = 0; OB_SUCC(ret) && i < udfs_info.count(); ++i) {
if (OB_FAIL(init_udf_info(params, udfs_info.at(i)))) {
LOG_WARN("init user define function failed", K(ret));
}
}
return ret;
}
int ObRawExprUtils::init_udf_info(pl::ObPLResolveCtx &resolve_ctx,
sql::ObRawExprFactory &expr_factory,
ObUDFInfo &udf_info)
{
int ret = OB_SUCCESS;
ObResolverParams params;
ObSchemaChecker schema_checker;
if (OB_FAIL(schema_checker.init(resolve_ctx.schema_guard_))) {
LOG_WARN("failed to init schema checker", K(ret));
} else {
params.schema_checker_ = &(schema_checker);
params.session_info_ = &(resolve_ctx.session_info_);
params.allocator_ = &(resolve_ctx.allocator_);
params.is_prepare_protocol_ = resolve_ctx.is_prepare_protocol_;
params.expr_factory_ = &(expr_factory);
params.sql_proxy_ = &(resolve_ctx.sql_proxy_);
}
if (OB_SUCC(ret) && OB_FAIL(init_udf_info(params, udf_info))) {
LOG_WARN("failed to init udf info", K(ret));
}
return ret;
}

View File

@ -807,9 +807,11 @@ public:
static int rebuild_expr_params(ObUDFInfo &udf_info,
sql::ObRawExprFactory *expr_factory,
common::ObIArray<sql::ObRawExpr*> &expr_params);
static int init_udf_info(ObResolverParams &params, ObUDFInfo &udf_info);
static int init_udf_info(pl::ObPLResolveCtx &resolve_ctx, sql::ObRawExprFactory &expr_factory, ObUDFInfo &udf_info);
static int init_udfs_info(ObResolverParams &params, common::ObIArray<ObUDFInfo> &udfs_info);
static int resolve_udf_info(common::ObIAllocator &allocator,
sql::ObRawExprFactory &expr_factory,
sql::ObSQLSessionInfo &session_info,
share::schema::ObSchemaGetterGuard &schema_guard,
ObUDFInfo &udf_info);
//判断expr里是否包含字符串前缀的表达式
static bool has_prefix_str_expr(const ObRawExpr &expr,
const ObColumnRefRawExpr &orig_column_expr,

View File

@ -874,71 +874,30 @@ int ObResolverUtils::check_match(const pl::ObPLResolveCtx &resolve_ctx,
match_info.match_info_.push_back(ObRoutineMatchInfo::MatchInfo());
}
// first we have to check udt udf's self argument, case study:
/*
* 1. this udf is static, do nothing
* 2. this udf is member, we have to possiblility here
* 1) self argument is mocked, such as obj.routine(a), self argument should be existed
* in expr_params;
* 2) self argument is not mocked, etc: func_name is begin routine(a); end; which func_name
* is a udt member function, and routine is also a member function. in such case, routine's
* self argument is not exist, we should ignore the first param in routine info, if it has
* a self param.
*/
int64_t offset = 0;
if(OB_SUCC(ret) && 0 < expr_params.count() && OB_NOT_NULL(expr_params.at(0))) {
ObRawExpr *first_arg = expr_params.at(0);
if (first_arg->has_flag(IS_UDT_UDF_SELF_PARAM)) {
// do nothing, may be we can check if routine is static or not
} else if (routine_info->is_udt_routine() && !routine_info->is_udt_static_routine()
&& expr_params.count() != routine_info->get_param_count()) {
/*
* what are we doing here?
* suppose a member routine has three params; but the arguments(expr_params) is less than three
* we get three case here:
* case 1 case 2 case 3
* arg [1][2] [2][3] [2]
* param [1][2][default] [self][2][3] [self][2][default]
* case 1 has default param, but argument is pass default
* case 2 has self, but argument is not passed in
* case 3 is th combine of 2 and 3
* we have to handle case 2, and case 3, when argument is not having self,
* we just passed this type check test, and suppose it is same
*/
ObIRoutineParam *iparam = NULL;
OZ (routine_info->get_routine_param(0, iparam));
for (int64_t i = 0; i< routine_info->get_param_count(); ++i) {
ObIRoutineParam *ip = NULL;
routine_info->get_routine_param(i, ip);
}
CK (OB_NOT_NULL(iparam));
CK (iparam->is_self_param());
if (OB_SUCC(ret)) {
ObPLDataType dst_pl_type;
if (iparam->is_schema_routine_param()) {
ObRoutineParam *param = static_cast<ObRoutineParam*>(iparam);
OZ (pl::ObPLDataType::transform_from_iparam(param,
resolve_ctx.schema_guard_,
resolve_ctx.session_info_,
resolve_ctx.allocator_,
resolve_ctx.sql_proxy_,
dst_pl_type));
} else {
dst_pl_type = iparam->get_pl_data_type();
}
// to check first is self type or not
ObObjType src_type;
uint64_t src_type_id;
} else if (routine_info->is_udt_routine()
&& !routine_info->is_udt_static_routine()
&& expr_params.count() != routine_info->get_param_count()) {
uint64_t src_type_id = OB_INVALID_ID;
ObObjType src_type;
if (T_SP_CPARAM == first_arg->get_expr_type()) {
ObCallParamRawExpr *call_expr = static_cast<ObCallParamRawExpr*>(first_arg);
OZ (call_expr->get_expr()->deduce_type(&resolve_ctx.session_info_));
OZ (get_type_and_type_id(call_expr->get_expr(), src_type, src_type_id));
} else {
OZ (first_arg->deduce_type(&resolve_ctx.session_info_));
OZ (get_type_and_type_id(first_arg, src_type, src_type_id));
if (OB_SUCC(ret) && src_type_id != dst_pl_type.get_user_type_id() /*not case 1*/) {
// set first param matched
OX (match_info.match_info_.at(0) =
(ObRoutineMatchInfo::MatchInfo(false,
dst_pl_type.get_obj_type(),
dst_pl_type.get_obj_type())));
OX (offset = 1);
}
}
if (OB_SUCC(ret)
&& (src_type_id != routine_info->get_package_id()
|| routine_info->is_udt_cons())) {
// set first param matched
OX (match_info.match_info_.at(0) = (ObRoutineMatchInfo::MatchInfo(false, src_type, src_type)));
OX (offset = 1);
}
}
}
@ -1047,21 +1006,6 @@ int ObResolverUtils::match_vacancy_parameters(
}
}
}
// // 看看是否udt的self 参数
// if (OB_ERR_SP_WRONG_ARG_NUM == ret) {
// if (routine_info.is_udt_routine() && !routine_info.is_udt_static_routine()) {
// int cnt = 0;
// for (int64_t i = 0; i < match_info.match_info_.count(); ++i) {
// if (ObMaxType == match_info.match_info_.at(i).dest_type_) {
// ++cnt;
// }
// }
// // 只能有一个self参数
// if (1 == cnt) {
// ret = OB_SUCCESS;
// }
// }
// }
CANCLE_LOG_CHECK_MODE();
return ret;
}
@ -1320,7 +1264,7 @@ int ObResolverUtils::get_routine(const pl::ObPLResolveCtx &resolve_ctx,
OX (routine = static_cast<const ObRoutineInfo *>(candidate_routine_infos.at(0)));
} else {
OZ (pick_routine(resolve_ctx, expr_params, candidate_routine_infos, routine));
LOG_DEBUG("call ObResolverUtils::get_routine fit routine",
LOG_INFO("call ObResolverUtils::get_routine fit routine",
K(db_name),
K(package_name),
K(routine_name),
@ -1334,7 +1278,7 @@ int ObResolverUtils::get_routine(const pl::ObPLResolveCtx &resolve_ctx,
if (ROUTINE_FUNCTION_TYPE == routine_type) {
ret = OB_ERR_FUNCTION_UNKNOWN;
LOG_WARN("stored function not exists", K(ret), K(routine_name), K(db_name), K(package_name));
LOG_USER_ERROR(OB_ERR_FUNCTION_UNKNOWN, routine_name.length(), routine_name.ptr());
LOG_USER_ERROR(OB_ERR_FUNCTION_UNKNOWN, "FUNCTION", routine_name.length(), routine_name.ptr());
} else {
ret = OB_ERR_SP_DOES_NOT_EXIST;
LOG_USER_ERROR(OB_ERR_SP_DOES_NOT_EXIST,
@ -2799,9 +2743,9 @@ int ObResolverUtils::resolve_const_expr(ObResolverParams &params,
} else if (sub_query_info.count() > 0) {
ret = OB_NOT_SUPPORTED;
LOG_USER_ERROR(OB_NOT_SUPPORTED, "subqueries or stored function calls here");
} else if (udf_info.count() > 0
&& OB_FAIL(ObRawExprUtils::init_udfs_info(params, udf_info))) {
LOG_WARN("resolve udf info failed", K(ret), K(udf_info));
} else if (udf_info.count() > 0) {
ret = OB_ERR_UNEXPECTED;
LOG_ERROR("UDFInfo should not found be here!!!", K(ret));
}
//process oracle compatible implicit conversion
@ -3592,7 +3536,7 @@ int ObResolverUtils::log_err_msg_for_partition_value(const ObQualifiedName &name
const ObString &func_name = name.access_idents_.at(name.access_idents_.count() - 1).access_name_;
ret = OB_ERR_FUNCTION_UNKNOWN;
LOG_WARN("Invalid function name in partition function", K(name.access_idents_.count()), K(ret), K(func_name));
LOG_USER_ERROR(OB_ERR_FUNCTION_UNKNOWN, func_name.length(), func_name.ptr());
LOG_USER_ERROR(OB_ERR_FUNCTION_UNKNOWN, "FUNCTION", func_name.length(), func_name.ptr());
} else {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("name is invalid", K(name), K(ret));
@ -3890,11 +3834,9 @@ int ObResolverUtils::resolve_partition_range_value_expr(ObResolverParams &params
} else if (OB_FAIL(resolve_columns_for_partition_range_value_expr(part_value_expr, columns))) {
LOG_WARN("resolve columns failed", K(ret));
}
if (OB_SUCC(ret) && udf_info.count()) {
if (OB_FAIL(ObRawExprUtils::init_udfs_info(params,
udf_info))) {
LOG_WARN("resolve udf info failed", K(ret));
}
if (OB_SUCC(ret) && udf_info.count() > 0) {
ret = OB_ERR_UNEXPECTED;
LOG_ERROR("UDFInfo should not found be here!!!", K(ret));
}
if (OB_SUCC(ret)) {
@ -3945,7 +3887,7 @@ int ObResolverUtils::resolve_columns_for_partition_expr(ObRawExpr *&expr,
OZ (real_sys_exprs.push_back(std::pair<ObRawExpr*, ObRawExpr*>(q_name.ref_expr_, real_ref_expr)));
}
} else if (q_name.is_pl_udf() || q_name.is_pl_var()) {
ret = OB_ERR_UNEXPECTED;
ret = OB_NOT_SUPPORTED;
LOG_WARN("pl variable is not invalid for partition", K(ret));
} else if (q_name.database_name_.length() > 0 || q_name.tbl_name_.length() > 0) {
ret = OB_ERR_BAD_FIELD_ERROR;
@ -5582,82 +5524,8 @@ int ObResolverUtils::set_sync_ddl_id_str(ObSQLSessionInfo *session_info, ObStrin
return ret;
}
int ObResolverUtils::resolve_udf_name(ObSchemaChecker &schema_checker,
const ObSQLSessionInfo &session_info,
const ObUDFInfo &udf_info,
ObString &db_name, ObString &pkg_name, ObString &udf_name)
{
int ret = OB_SUCCESS;
udf_name.assign_ptr(udf_info.udf_name_.ptr(), udf_info.udf_name_.length());
if (!udf_info.udf_database_.empty() && !udf_info.udf_package_.empty()) {
db_name.assign_ptr(udf_info.udf_database_.ptr(), udf_info.udf_database_.length());
pkg_name.assign_ptr(udf_info.udf_package_.ptr(), udf_info.udf_package_.length());
} else if (!udf_info.udf_database_.empty() && udf_info.udf_package_.empty()) {
// need to make sure whether the db name is real db name or package name
// first search db name, then package name
uint64_t database_id = OB_INVALID_ID;
uint64_t package_id = OB_INVALID_ID;
int64_t compatible_mode = lib::is_oracle_mode() ? COMPATIBLE_ORACLE_MODE
: COMPATIBLE_MYSQL_MODE;
if (OB_FAIL(schema_checker.get_database_id(session_info.get_effective_tenant_id(),
udf_info.udf_database_, database_id))) {
if (OB_ERR_BAD_DATABASE != ret) {
LOG_WARN("get database id failed", K(udf_info.udf_database_), K(ret));
} else {
if (OB_FAIL(schema_checker.get_package_id(session_info.get_effective_tenant_id(),
session_info.get_database_name(),
udf_info.udf_database_,
compatible_mode,
package_id))) {
if (OB_ERR_PACKAGE_DOSE_NOT_EXIST == ret) {
if (OB_FAIL(schema_checker.get_package_id(OB_SYS_TENANT_ID, OB_SYS_DATABASE_NAME,
udf_info.udf_database_,
compatible_mode,
package_id))) {
if (OB_ERR_PACKAGE_DOSE_NOT_EXIST == ret) {
ret = OB_ERR_BAD_DATABASE;
LOG_USER_ERROR(OB_ERR_BAD_DATABASE, udf_info.udf_database_.length(),
udf_info.udf_database_.ptr());
} else {
LOG_WARN("get package id failed", K(udf_info.udf_database_), K(ret));
}
} else {
pkg_name.assign_ptr(udf_info.udf_database_.ptr(), udf_info.udf_database_.length());
db_name.assign_ptr(OB_SYS_DATABASE_NAME,
static_cast<ObString::obstr_size_t>(strlen(OB_SYS_DATABASE_NAME)));
}
} else {
LOG_WARN("get package id failed", K(udf_info.udf_database_), K(ret));
}
}
if (OB_SUCC(ret)) {
pkg_name.assign_ptr(udf_info.udf_database_.ptr(), udf_info.udf_database_.length());
db_name = session_info.get_database_name();
if (lib::is_oracle_mode()) {
size_t size = ObCharset::caseup(CS_TYPE_UTF8MB4_GENERAL_CI, db_name.ptr(), db_name.length(), db_name.ptr(), db_name.length());
db_name.set_length(static_cast<int32_t>(size));
}
}
}
} else {
db_name.assign_ptr(udf_info.udf_database_.ptr(), udf_info.udf_database_.length());
if (lib::is_oracle_mode()) {
size_t size = ObCharset::caseup(CS_TYPE_UTF8MB4_GENERAL_CI, db_name.ptr(), db_name.length(), db_name.ptr(), db_name.length());
db_name.set_length(static_cast<int32_t>(size));
}
}
} else if (udf_info.udf_database_.empty() && !udf_info.udf_package_.empty()) {
pkg_name = udf_info.udf_package_;
} else {
//do nothing
//in pl context, this call may be a package private procedure, not a schema object
}
return ret;
}
int ObResolverUtils::resolve_udf(const ParseNode *node,
const common::ObNameCaseMode case_mode,
ObUDFInfo &udf_info)
int ObResolverUtils::resolve_udf_name_by_parse_node(
const ParseNode *node, const common::ObNameCaseMode case_mode, ObUDFInfo &udf_info)
{
int ret = OB_SUCCESS;
ObString udf_name;
@ -6208,6 +6076,21 @@ int ObResolverUtils::check_foreign_key_columns_type(const ObTableSchema &child_t
return ret;
}
int ObResolverUtils::transform_sys_func_to_objaccess(
ObIAllocator *allocator, const ParseNode *sys_func, ParseNode *&obj_access)
{
int ret = OB_SUCCESS;
if (allocator == nullptr || sys_func == nullptr || sys_func->type_ != T_FUN_SYS) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("func_sys node is null", K(ret));
} else if (OB_ISNULL(obj_access
= new_non_terminal_node(allocator, T_OBJ_ACCESS_REF, 2, sys_func, nullptr))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_WARN("make T_OBJ_ACCESS node failed", K(ret));
}
return ret;
}
int ObResolverUtils::transform_func_sys_to_udf(ObIAllocator *allocator, const ParseNode *func_sys,
const ObString &db_name, const ObString &pkg_name,
ParseNode *&func_udf)
@ -6311,19 +6194,19 @@ int ObResolverUtils::resolve_string(const ParseNode *node, ObString &string)
}
int ObResolverUtils::resolve_external_symbol(common::ObIAllocator &allocator,
sql::ObRawExprFactory &expr_factory,
sql::ObSQLSessionInfo &session_info,
share::schema::ObSchemaGetterGuard &schema_guard,
common::ObMySQLProxy *sql_proxy,
ExternalParams *extern_param_info,
pl::ObPLBlockNS *ns,
ObQualifiedName &q_name,
ObIArray<ObQualifiedName> &columns,
ObIArray<ObRawExpr*> &real_exprs,
ObRawExpr *&expr,
bool is_prepare_protocol,
bool is_check_mode,
bool is_sql_scope)
sql::ObRawExprFactory &expr_factory,
sql::ObSQLSessionInfo &session_info,
share::schema::ObSchemaGetterGuard &schema_guard,
common::ObMySQLProxy *sql_proxy,
ExternalParams *extern_param_info,
pl::ObPLBlockNS *ns,
ObQualifiedName &q_name,
ObIArray<ObQualifiedName> &columns,
ObIArray<ObRawExpr*> &real_exprs,
ObRawExpr *&expr,
bool is_prepare_protocol,
bool is_check_mode,
bool is_sql_scope)
{
int ret = OB_SUCCESS;
pl::ObPLPackageGuard dummy_pkg_guard(session_info.get_effective_tenant_id());

View File

@ -534,15 +534,8 @@ public:
static bool is_restore_user(ObSQLSessionInfo &session_info);
static bool is_drc_user(ObSQLSessionInfo &session_info);
static int set_sync_ddl_id_str(ObSQLSessionInfo *session_info, common::ObString &ddl_id_str);
static int resolve_udf_name(ObSchemaChecker &schema_checker,
const ObSQLSessionInfo &session_info,
const ObUDFInfo &udf_info,
common::ObString &db_name,
common::ObString &pkg_name,
common::ObString &udf_name);
static int resolve_udf(const ParseNode *node,
const common::ObNameCaseMode case_mode,
ObUDFInfo& udf_info);
static int resolve_udf_name_by_parse_node(
const ParseNode *node, const common::ObNameCaseMode case_mode, ObUDFInfo& udf_info);
// for create table with fk in oracle mode
static int check_dup_foreign_keys_exist(
const common::ObSArray<obrpc::ObCreateForeignKeyArg> &fk_args);
@ -596,6 +589,8 @@ public:
const share::schema::ObColumnSchemaV2 *column = NULL);
static int get_columns_name_from_index_table_schema(const share::schema::ObTableSchema &index_table_schema,
ObIArray<ObString> &index_columns_name);
static int transform_sys_func_to_objaccess(
common::ObIAllocator *allocator, const ParseNode *sys_func, ParseNode *&obj_access);
static int transform_func_sys_to_udf(common::ObIAllocator *allocator,
const ParseNode *func_sys,
const common::ObString &db_name,

View File

@ -3460,6 +3460,7 @@ int ObTransformPreProcess::calc_policy_function(ObDMLStmt &stmt,
if (OB_ISNULL(ctx_)
|| OB_ISNULL(session_info = ctx_->session_info_)
|| OB_ISNULL(schema_checker = ctx_->schema_checker_)
|| OB_ISNULL(schema_checker->get_schema_guard())
|| OB_ISNULL(expr_factory = ctx_->expr_factory_)
|| OB_ISNULL(ctx_->exec_ctx_)
|| OB_ISNULL(ctx_->allocator_)) {
@ -3504,7 +3505,8 @@ int ObTransformPreProcess::calc_policy_function(ObDMLStmt &stmt,
} else if (OB_FAIL(udf_expr->add_param_expr(object_name_expr))) {
LOG_WARN("failed to add param expr", K(object_name_expr), K(ret));
} else if (FALSE_IT(udf_info.ref_expr_ = udf_expr)) {
} else if (OB_FAIL(ObRawExprUtils::init_udf_info(params, udf_info))) {
} else if (OB_FAIL(ObRawExprUtils::resolve_udf_info(
*params.allocator_, *params.expr_factory_, *params.session_info_, *params.schema_checker_->get_schema_guard(), udf_info))) {
LOG_WARN("failed to init udf_info", K(udf_info), K(ret));
} else if (OB_FAIL(udf_expr->formalize(session_info))) {
LOG_WARN("failed to formalize", K(ret));

View File

@ -1061,7 +1061,7 @@ a f8()
3 1
drop function f1|
select * from v1|
ERROR 42000: FUNCTION f1 does not exist
ERROR 42000: FUNCTION test.f1 does not exist
create function f1() returns int
return (select sum(data) from t1) + (select sum(data) from v1)|
select f1()|