[FEAT MERGE] [to #48722125] pl/sql name resolve refactor
This commit is contained in:
parent
52e0115965
commit
0a0ba897c9
@ -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,
|
||||
|
@ -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
@ -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_;
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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",
|
||||
|
@ -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");
|
||||
|
@ -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"
|
||||
|
@ -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 *¶m) 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;
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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 {
|
||||
|
@ -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_;
|
||||
|
@ -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;
|
||||
|
@ -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_;
|
||||
|
@ -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
@ -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_;
|
||||
|
@ -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 ¶ms,
|
||||
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 ¶ms,
|
||||
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 ¶ms,
|
||||
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;
|
||||
}
|
||||
|
@ -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 ¶ms, 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 ¶ms, 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,
|
||||
|
@ -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 ¶ms,
|
||||
} 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 ¶ms
|
||||
} 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());
|
||||
|
@ -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,
|
||||
|
@ -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));
|
||||
|
@ -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()|
|
||||
|
Loading…
x
Reference in New Issue
Block a user