提交 d30a2a77 编写于 作者: 0 0xacc 提交者: ob-robot

[to #42398480] fix NEW obj(...) syntax

上级 17bea01c
......@@ -9802,11 +9802,15 @@ int ObPLResolver::resolve_qualified_name(ObQualifiedName &q_name,
if (q_name.is_pl_udf()) {
// 首先尝试下是不是复杂类型的构造函数
int64_t acc_cnt = q_name.access_idents_.count();
bool is_construct = false;
if (1 < acc_cnt && q_name.access_idents_.at(acc_cnt - 2).is_udt_ns()) {
// udt obj.func(), this func can not be a constructor
ret = OB_ERR_SP_UNDECLARED_TYPE;
} else {
OZ (resolve_construct(q_name, udf_info, expr), K(q_name));
if (OB_SUCC(ret)) {
is_construct = true;
}
}
// 其次尝试下是不是UDF
if (OB_ERR_SP_UNDECLARED_TYPE == ret || OB_ERR_PACKAGE_DOSE_NOT_EXIST == ret) {
......@@ -9815,6 +9819,11 @@ int ObPLResolver::resolve_qualified_name(ObQualifiedName &q_name,
OZ (access_name.push_back(ObString("SELF")));
OZ (resolve_udf(udf_info, access_name, unit_ast), q_name, udf_info);
}
if (OB_SUCC(ret) && is_construct == false && udf_info.is_new_keyword_used_) {
ret = OB_ERR_PARSER_SYNTAX;
LOG_WARN("NEW key word is only allowed for constructors", K(q_name));
}
} else { //如果是udf return access,需要当做var解析
if (OB_FAIL(resolve_var(q_name, unit_ast, expr))) {
LOG_WARN("failed to resolve var", K(q_name), K(ret));
......
......@@ -948,6 +948,7 @@ struct ObUDFInfo
is_udt_udf_(false),
is_contain_self_param_(false),
is_udt_udf_inside_pkg_(false),
is_new_keyword_used_(false),
flag_(0),
self_arg_(NULL) {}
......@@ -997,6 +998,7 @@ struct ObUDFInfo
K_(is_udt_udf),
K_(is_contain_self_param),
K_(is_udt_udf_inside_pkg),
K_(is_new_keyword_used),
K_(flag));
common::ObString udf_name_;
......@@ -1009,6 +1011,7 @@ struct ObUDFInfo
bool is_udt_udf_; // if this udf is udt object routine
bool is_contain_self_param_; // self param is mocked.
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
};
......
......@@ -1943,6 +1943,13 @@ int ObRawExprResolverImpl::resolve_obj_access_idents(const ParseNode &node, ObQu
LOG_WARN("node is NULL", K(node.num_child_), K(ret));
} else {
ObString ident_name(static_cast<int32_t>(func_node.children_[0]->str_len_), func_node.children_[0]->str_value_);
// first bit in value_ of T_FUN_SYS node is used to mark NEW keyword,
// value_ & 0x1 == 1: not used,
// value_ & 0x1 == 0: used,
// refer to sql_parser_oracle_mode.y
bool is_new_key_word_used = !(func_node.value_ & 0x1);
if (lib::is_oracle_mode()
&& T_PL_SCOPE == ctx_.current_scope_
&& ident_name.empty()) {
......@@ -1964,6 +1971,9 @@ int ObRawExprResolverImpl::resolve_obj_access_idents(const ParseNode &node, ObQu
|| func_node.children_[2]->type_ == T_ALL)) {
ret = OB_DISTINCT_NOT_ALLOWED;
LOG_WARN("distinct/all/unique not allowed here", K(ret));
} else if (is_new_key_word_used && PL_UDF != name_type) {
ret = OB_ERR_PARSER_SYNTAX;
LOG_WARN("NEW keyword is only allowed for constructors", K(q_name));
} else {
switch (name_type) {
case SYS_FUNC: {
......@@ -1990,6 +2000,7 @@ int ObRawExprResolverImpl::resolve_obj_access_idents(const ParseNode &node, ObQu
int64_t cnt = q_name.access_idents_.count();
ParseNode *udt_udf_self_param_node = NULL;
ObRawExpr *self_param = NULL;
access_ident.udf_info_.is_new_keyword_used_ = is_new_key_word_used;
if (OB_FAIL(ObResolverUtils::transform_func_sys_to_udf(&ctx_.expr_factory_.get_allocator(),
&func_node,
q_name.database_name_,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册