[CP] [#2024101800104734653]Fix:can not find type by the mocked nested table type id
This commit is contained in:
parent
7df860d1dc
commit
22c8279a5b
@ -3569,7 +3569,8 @@ int ObPLExecState::check_routine_param_legal(ParamStore *params)
|
||||
} else if (!params->at(i).is_pl_extend()) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("real parameter is ext ptr, but extend type not set property", K(ret), K(params->at(i)), K(i));
|
||||
} else if (PL_OPAQUE_TYPE == params->at(i).get_meta().get_extend_type() || params->at(i).get_udt_id() != OB_INVALID_ID) {
|
||||
} else if (PL_OPAQUE_TYPE == params->at(i).get_meta().get_extend_type()
|
||||
|| !is_mocked_anonymous_array_id(params->at(i).get_udt_id())) {
|
||||
if (params->at(i).get_udt_id() != dest_type.get_user_type_id()) {
|
||||
bool is_compatible = false;
|
||||
OZ (ObPLResolver::check_composite_compatible(
|
||||
@ -3584,7 +3585,8 @@ int ObPLExecState::check_routine_param_legal(ParamStore *params)
|
||||
ObPLComposite *composite = reinterpret_cast<ObPLComposite *>(params->at(i).get_ext());
|
||||
CK (OB_NOT_NULL(composite));
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_INVALID_ID == composite->get_id()) { // anonymous collection, should check element composite.
|
||||
} else if (is_mocked_anonymous_array_id(composite->get_id())) {
|
||||
// anonymous collection, should check element composite.
|
||||
bool need_cast = false;
|
||||
if (!dest_type.is_collection_type()) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
@ -3860,7 +3862,8 @@ do { \
|
||||
get_params().at(i).set_is_ref_cursor_type(true); // last assignment statement could clear this flag
|
||||
get_params().at(i).set_extend(
|
||||
get_params().at(i).get_ext(), PL_REF_CURSOR_TYPE, get_params().at(i).get_val_len());
|
||||
} else if (pl_type.is_collection_type() && OB_INVALID_ID == params->at(i).get_udt_id()) {
|
||||
} else if (pl_type.is_collection_type()
|
||||
&& (is_mocked_anonymous_array_id(params->at(i).get_udt_id()))) {
|
||||
ObPLComposite *composite = NULL;
|
||||
get_params().at(i) = params->at(i);
|
||||
get_params().at(i).set_udt_id(pl_type.get_user_type_id());
|
||||
|
@ -100,7 +100,7 @@ int ObPLCompiler::init_anonymous_ast(
|
||||
func_ast.set_ret_type(pl_type);
|
||||
|
||||
for (int64_t i = 0; OB_SUCC(ret) && OB_NOT_NULL(params) && i < params->count(); ++i) {
|
||||
const ObObjParam param = params->at(i);
|
||||
ObObjParam& param = const_cast<ObObjParam&>(params->at(i));
|
||||
if (param.is_pl_extend()) {
|
||||
#ifdef OB_BUILD_ORACLE_PL
|
||||
if (PL_REF_CURSOR_TYPE == param.get_meta().get_extend_type()) {
|
||||
@ -109,7 +109,7 @@ int ObPLCompiler::init_anonymous_ast(
|
||||
pl_type.set_type_from(pl::PL_TYPE_SYS_REFCURSOR);
|
||||
} else
|
||||
#endif
|
||||
if (param.get_udt_id() != OB_INVALID_ID) {
|
||||
if (!is_mocked_anonymous_array_id(param.get_udt_id())) {
|
||||
const ObUserDefinedType *user_type = NULL;
|
||||
OZ (ObResolverUtils::get_user_type(&allocator,
|
||||
&session_info,
|
||||
@ -140,9 +140,10 @@ int ObPLCompiler::init_anonymous_ast(
|
||||
}
|
||||
OX (nested_type->set_element_type(element_type));
|
||||
OX (nested_type->set_user_type_id(
|
||||
func_ast.get_user_type_table().generate_user_type_id(OB_INVALID_ID)));
|
||||
func_ast.get_user_type_table().generate_user_type_id(OB_PL_MOCK_ANONYMOUS_ID)));
|
||||
OZ (func_ast.get_user_type_table().add_type(nested_type));
|
||||
OZ (func_ast.get_user_type_table().add_external_type(nested_type));
|
||||
OX (param.set_udt_id(nested_type->get_user_type_id()));
|
||||
OX (pl_type = *nested_type);
|
||||
#endif
|
||||
} else {
|
||||
|
@ -6170,7 +6170,7 @@ int ObPLResolver::resolve_using(const ObStmtNodeTree *using_node,
|
||||
} else {
|
||||
bool legal_extend = false;
|
||||
if (ObExtendType == expr->get_result_type().get_type()) {
|
||||
if (expr->get_result_type().get_udt_id() != OB_INVALID_ID) {
|
||||
if (!is_mocked_anonymous_array_id(expr->get_result_type().get_udt_id())) {
|
||||
const ObUserDefinedType *user_type = NULL;
|
||||
CK (OB_NOT_NULL(current_block_));
|
||||
OZ (current_block_->get_namespace().get_pl_data_type_by_id(
|
||||
@ -7372,42 +7372,8 @@ int ObPLResolver::check_in_param_type_legal(const ObIRoutineParam *param_info,
|
||||
} else if (actually_type.is_obj_type() && ObNullType == actually_type.get_obj_type()) {
|
||||
// do nothing ...
|
||||
} else if (actually_type.is_composite_type() && expected_type.is_composite_type()) {
|
||||
|
||||
if (is_anonymous_array_type && expected_type.is_collection_type()) { // check anonymous array compatible
|
||||
|
||||
const ObUserDefinedType *left_type = NULL;
|
||||
const ObUserDefinedType *right_type = NULL;
|
||||
const ObCollectionType *left_coll_type = NULL;
|
||||
const ObCollectionType *right_coll_type = NULL;
|
||||
|
||||
OZ (current_block_->get_namespace().get_pl_data_type_by_id(actually_type.get_user_type_id(), left_type));
|
||||
OZ (current_block_->get_namespace().get_pl_data_type_by_id(expected_type.get_user_type_id(), right_type));
|
||||
CK (OB_NOT_NULL(left_coll_type = static_cast<const ObCollectionType *>(left_type)));
|
||||
CK (OB_NOT_NULL(right_coll_type = static_cast<const ObCollectionType *>(right_type)));
|
||||
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (left_coll_type->get_element_type().is_obj_type() ^ right_coll_type->get_element_type().is_obj_type()) {
|
||||
is_legal = false;
|
||||
LOG_WARN("uncompatible with anonymous array type", K(ret), KPC(left_coll_type), KPC(right_coll_type));
|
||||
} else if (left_coll_type->get_element_type().is_obj_type()) {
|
||||
const ObDataType *left_basic_type = left_coll_type->get_element_type().get_data_type();
|
||||
const ObDataType *right_basic_type = right_coll_type->get_element_type().get_data_type();
|
||||
if (left_basic_type->get_obj_type() != right_basic_type->get_obj_type()
|
||||
&& !cast_supported(left_basic_type->get_obj_type(),
|
||||
left_basic_type->get_collation_type(),
|
||||
right_basic_type->get_obj_type(),
|
||||
right_basic_type->get_collation_type())) {
|
||||
is_legal = false;
|
||||
LOG_WARN("uncompatible with anonymous array type", K(ret), KPC(left_coll_type), KPC(right_coll_type));
|
||||
} else {
|
||||
// compatible with anonymous array type
|
||||
}
|
||||
} else if (left_coll_type->get_element_type().get_user_type_id() != right_coll_type->get_element_type().get_user_type_id()) {
|
||||
OZ (check_composite_compatible(current_block_->get_namespace(),
|
||||
left_coll_type->get_element_type().get_user_type_id(),
|
||||
right_coll_type->get_element_type().get_user_type_id(),
|
||||
is_legal));
|
||||
}
|
||||
OZ (check_anonymous_array_compatible(actually_type.get_user_type_id(), expected_type.get_user_type_id(), is_legal));
|
||||
} else if (actually_type.get_user_type_id() != expected_type.get_user_type_id()) {
|
||||
OZ (check_composite_compatible(current_block_->get_namespace(),
|
||||
actually_type.get_user_type_id(),
|
||||
@ -10006,7 +9972,7 @@ int ObPLResolver::formalize_expr(ObRawExpr &expr,
|
||||
int ret = OB_SUCCESS;
|
||||
if (OB_SUCC(ret)
|
||||
&& expr.get_result_type().is_ext()
|
||||
&& OB_INVALID_ID != expr.get_udt_id()) {
|
||||
&& !is_mocked_anonymous_array_id(expr.get_udt_id())) {
|
||||
int64_t size = 0;
|
||||
const ObUserDefinedType *user_type = NULL;
|
||||
OZ (ns.get_user_type(expr.get_udt_id(), user_type, NULL));
|
||||
@ -10178,10 +10144,14 @@ int ObPLResolver::resolve_expr(const ParseNode *node,
|
||||
&& expected_type->get_user_type_id() != expr->get_result_type().get_udt_id()
|
||||
&& expr->get_expr_type() != T_FUN_SYS_PDB_GET_RUNTIME_INFO) {
|
||||
bool is_compatible = false;
|
||||
OZ (check_composite_compatible(current_block_->get_namespace(),
|
||||
expr->get_result_type().get_udt_id(),
|
||||
expected_type->get_user_type_id(),
|
||||
is_compatible));
|
||||
if (is_mocked_anonymous_array_id(expr->get_result_type().get_udt_id())) {
|
||||
OZ (check_anonymous_array_compatible(expr->get_result_type().get_udt_id(), expected_type->get_user_type_id(), is_compatible));
|
||||
} else {
|
||||
OZ (check_composite_compatible(current_block_->get_namespace(),
|
||||
expr->get_result_type().get_udt_id(),
|
||||
expected_type->get_user_type_id(),
|
||||
is_compatible));
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (!is_compatible) {
|
||||
ret = OB_ERR_INVALID_TYPE_FOR_OP;
|
||||
@ -10386,6 +10356,47 @@ int ObPLResolver::resolve_expr(const ParseNode *node,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObPLResolver::check_anonymous_array_compatible (uint64_t actual_param_type_id,
|
||||
uint64_t formal_param_type_id,
|
||||
bool &is_compatible)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
const ObUserDefinedType *left_type = NULL;
|
||||
const ObUserDefinedType *right_type = NULL;
|
||||
const ObCollectionType *left_coll_type = NULL;
|
||||
const ObCollectionType *right_coll_type = NULL;
|
||||
OZ (current_block_->get_namespace().get_pl_data_type_by_id(actual_param_type_id, left_type));
|
||||
OZ (current_block_->get_namespace().get_pl_data_type_by_id(formal_param_type_id, right_type));
|
||||
CK (OB_NOT_NULL(left_coll_type = static_cast<const ObCollectionType *>(left_type)));
|
||||
CK (OB_NOT_NULL(right_coll_type = static_cast<const ObCollectionType *>(right_type)));
|
||||
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (left_coll_type->get_element_type().is_obj_type() ^ right_coll_type->get_element_type().is_obj_type()) {
|
||||
is_compatible = false;
|
||||
LOG_WARN("uncompatible with anonymous array type", K(ret), KPC(left_coll_type), KPC(right_coll_type));
|
||||
} else if (left_coll_type->get_element_type().is_obj_type()) {
|
||||
const ObDataType *left_basic_type = left_coll_type->get_element_type().get_data_type();
|
||||
const ObDataType *right_basic_type = right_coll_type->get_element_type().get_data_type();
|
||||
if (left_basic_type->get_obj_type() != right_basic_type->get_obj_type()
|
||||
&& !cast_supported(left_basic_type->get_obj_type(),
|
||||
left_basic_type->get_collation_type(),
|
||||
right_basic_type->get_obj_type(),
|
||||
right_basic_type->get_collation_type())) {
|
||||
is_compatible = false;
|
||||
LOG_WARN("uncompatible with anonymous array type", K(ret), KPC(left_coll_type), KPC(right_coll_type));
|
||||
} else {
|
||||
is_compatible = true;// compatible with anonymous array type
|
||||
}
|
||||
} else if (left_coll_type->get_element_type().get_user_type_id() != right_coll_type->get_element_type().get_user_type_id()) {
|
||||
OZ (check_composite_compatible(current_block_->get_namespace(),
|
||||
left_coll_type->get_element_type().get_user_type_id(),
|
||||
right_coll_type->get_element_type().get_user_type_id(),
|
||||
is_compatible));
|
||||
} else {
|
||||
is_compatible = true; // user_type_id equal
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObPLResolver::transform_subquery_expr(const ParseNode *node,
|
||||
ObRawExpr *&expr,
|
||||
|
@ -525,7 +525,9 @@ public:
|
||||
static int check_composite_compatible(const ObUserDefinedType *actual_param_type,
|
||||
const ObUserDefinedType *formal_param_type,
|
||||
bool &is_compatible);
|
||||
|
||||
int check_anonymous_array_compatible( uint64_t actual_param_type_id,
|
||||
uint64_t formal_param_type_id,
|
||||
bool &is_compatible);
|
||||
static
|
||||
int resolve_nocopy_params(const share::schema::ObIRoutineInfo *routine_info,
|
||||
sql::ObUDFInfo &udf_info);
|
||||
|
@ -31,6 +31,7 @@
|
||||
|
||||
#define ObCursorType ObIntType
|
||||
#define ObPtrType ObIntType
|
||||
#define OB_PL_MOCK_ANONYMOUS_ID 0xFFFFFFFFFFFFFFFE
|
||||
|
||||
#define IS_TYPE_FROM_TYPE_OR_ROWTYPE(type_from) \
|
||||
(PL_TYPE_ATTR_ROWTYPE == type_from) || \
|
||||
@ -234,6 +235,25 @@ struct ObPLExternTypeInfo
|
||||
};
|
||||
|
||||
class ObPLEnumSetCtx;
|
||||
|
||||
OB_INLINE bool is_mocked_anonymous_array_id(uint64_t udt_id)
|
||||
{
|
||||
uint64_t mask = 0xFFFFFFFFFF000000;
|
||||
uint64_t res = 0xFFFFFFFFFE000000;
|
||||
// anonymous_array will use OB_PL_MOCK_ANONYMOUS_ID to generate a mocked id ,
|
||||
// OB_PL_MOCK_ANONYMOUS_ID = (uint64)OB_INVALID_ID - 1.
|
||||
// Why do not use OB_INVALID_ID? Anonymous block has declare local nested type (this package_id is OB_INVALID_ID)
|
||||
// use OB_INVALID_ID - 1 to identify this scenery.
|
||||
// So the first 40 bits of mocked id in hex is: 0xFFFFFFFFFE
|
||||
// We can use (mocked_id & mask) to get the first 40 bits and check if it is mocked.
|
||||
return (udt_id & mask) == res || OB_INVALID_ID == udt_id;
|
||||
}
|
||||
|
||||
OB_INLINE bool is_invalid_or_mocked_package_id(uint64_t udt_id)
|
||||
{
|
||||
return OB_INVALID_ID == extract_package_id(udt_id) || OB_PL_MOCK_ANONYMOUS_ID == extract_package_id(udt_id);
|
||||
}
|
||||
|
||||
class ObPLDataType
|
||||
{
|
||||
public:
|
||||
|
@ -615,7 +615,7 @@ int ObAnonymousBlockExecutor::execute(ObExecContext &ctx, ObAnonymousBlockStmt &
|
||||
field.length_ = field.accuracy_.get_length();
|
||||
if (value.is_ref_cursor_type()) {
|
||||
OZ (ob_write_string(ctx.get_allocator(), ObString("SYS_REFCURSOR"), field.type_name_));
|
||||
} else if (value.get_udt_id() != OB_INVALID_ID && extract_package_id(value.get_udt_id()) != OB_INVALID_ID) {
|
||||
} else if (value.get_udt_id() != OB_INVALID_ID && !pl::is_invalid_or_mocked_package_id(value.get_udt_id())) {
|
||||
OZ (fill_field_with_udt_id(ctx, value.get_udt_id(), field));
|
||||
} else if (value.is_pl_extend()
|
||||
&& pl::PL_NESTED_TABLE_TYPE == value.get_meta().get_extend_type()) {
|
||||
|
@ -1080,7 +1080,7 @@ int ObResolverUtils::check_type_match(const pl::ObPLResolveCtx &resolve_ctx,
|
||||
OX (match_info = (ObRoutineMatchInfo::MatchInfo(false, src_type, dst_type)));
|
||||
} else if (resolve_ctx.is_prepare_protocol_ &&
|
||||
ObExtendType == src_type &&
|
||||
OB_INVALID_ID == src_type_id &&
|
||||
is_mocked_anonymous_array_id(src_type_id) &&
|
||||
T_QUESTIONMARK == expr->get_expr_type()) { // 匿名数组
|
||||
const ObConstRawExpr *const_expr = static_cast<const ObConstRawExpr*>(expr);
|
||||
int64_t idx = const_expr->get_value().get_unknown();
|
||||
|
Loading…
x
Reference in New Issue
Block a user