bugfix : json object resolve column expr cause core-dump
This commit is contained in:
parent
cb1ec965d4
commit
607b78760e
@ -4954,7 +4954,7 @@ int ObRawExprResolverImpl::malloc_new_specified_type_node(common::ObIAllocator &
|
||||
return ret;
|
||||
}
|
||||
|
||||
// use: json value (mismatch ype) ; json object (entry_op)
|
||||
// use: json value (mismatch ype)
|
||||
int ObRawExprResolverImpl::expand_node(common::ObIAllocator &allocator, ParseNode *node, int p, ObVector<const ParseNode*> &arr) {
|
||||
int ret = OB_SUCCESS;
|
||||
if (node->type_ == T_LINK_NODE || node->type_ == T_VALUE_VECTOR)
|
||||
@ -4962,149 +4962,11 @@ int ObRawExprResolverImpl::expand_node(common::ObIAllocator &allocator, ParseNod
|
||||
for (int32_t i = 0; OB_SUCC(ret) && i < node->num_child_; i++){
|
||||
if (OB_ISNULL(node->children_[i])) {
|
||||
} else {
|
||||
ObString rownum_str(6, "rownum");
|
||||
if (lib::is_oracle_mode() && ctx_.current_scope_ == T_FIELD_LIST_SCOPE && node->children_[i]->type_ == T_FUN_SYS
|
||||
&& node->children_[i]->num_child_ == 1 && OB_NOT_NULL(node->children_[i]->children_[0])
|
||||
&& node->children_[i]->children_[0]->type_ == T_IDENT
|
||||
&& 0 == rownum_str.case_compare(node->children_[i]->children_[0]->str_value_)
|
||||
&& i % 3 == 0 && node->children_[i + 1]->type_ == T_NULL
|
||||
&& node->children_[i + 1]->value_ == 2) {
|
||||
ParseNode *fun_key_node;
|
||||
if (OB_ISNULL(fun_key_node = static_cast<ParseNode*>(allocator.alloc(sizeof(ParseNode))))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("fail to allocate memory", K(ret), K(sizeof(ParseNode)));
|
||||
} else {
|
||||
fun_key_node = new(fun_key_node) ParseNode;
|
||||
if (OB_ISNULL(node->children_[i]->children_[0])) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("no legeal fun", K(ret));
|
||||
} else {
|
||||
ObString str_fun(node->children_[i]->children_[0]->str_len_, node->children_[i]->children_[0]->str_value_);
|
||||
if (OB_FAIL(ObRawExprResolverImpl::malloc_new_specified_type_node(allocator, str_fun, fun_key_node, T_CHAR))) {
|
||||
LOG_WARN("key node create fail", K(ret));
|
||||
} else {
|
||||
node->children_[i + 1] = node->children_[i];
|
||||
node->children_[i] = fun_key_node;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (node->children_[i]->type_ == T_OBJ_ACCESS_REF
|
||||
&& i % 3 == 0 && node->children_[i+1]->type_ == T_NULL && node->children_[i+1]->value_ == 2) {
|
||||
ParseNode *column_ref_node;
|
||||
ParseNode *t_node = node->children_[i];
|
||||
ParseNode *pre_node = NULL;
|
||||
bool is_fun_sys = false;
|
||||
if (OB_ISNULL(column_ref_node = static_cast<ParseNode*>(allocator.alloc(sizeof(ParseNode))))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("fail to allocate memory", K(ret), K(sizeof(ParseNode)));
|
||||
} else {
|
||||
column_ref_node = new(column_ref_node) ParseNode;
|
||||
if (OB_FAIL(ObRawExprResolverImpl::malloc_new_specified_type_node(allocator, "", column_ref_node, T_OBJ_ACCESS_REF))) {
|
||||
LOG_WARN("key node create fail", K(ret));
|
||||
} else {
|
||||
node->children_[i]->value_ = 1;
|
||||
pre_node = column_ref_node;
|
||||
}
|
||||
}
|
||||
while (OB_SUCC(ret) && !is_fun_sys && t_node != NULL && t_node->type_ == T_OBJ_ACCESS_REF) {
|
||||
if (OB_ISNULL(t_node->children_[0]) || t_node->children_[0]->type_ != T_IDENT) {
|
||||
is_fun_sys = true;
|
||||
} else {
|
||||
ParseNode *col_ref_node = NULL;
|
||||
ParseNode *ident_node = NULL;
|
||||
if (OB_ISNULL(ident_node = static_cast<ParseNode*>(allocator.alloc(sizeof(ParseNode))))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("fail to allocate memory", K(ret), K(sizeof(ParseNode)));
|
||||
} else {
|
||||
ident_node = new(ident_node) ParseNode;
|
||||
memset(ident_node, 0, sizeof(ParseNode));
|
||||
ident_node->type_ = T_IDENT;
|
||||
ident_node->str_value_ = t_node->children_[0]->str_value_;
|
||||
ident_node->str_len_ = t_node->children_[0]->str_len_;
|
||||
ident_node->raw_text_ = t_node->children_[0]->raw_text_;
|
||||
ident_node->text_len_ = t_node->children_[0]->text_len_;
|
||||
pre_node->children_[0] = ident_node;
|
||||
}
|
||||
if (OB_FAIL(ret) || OB_ISNULL(t_node->children_[1])) {
|
||||
} else if (OB_ISNULL(col_ref_node = static_cast<ParseNode*>(allocator.alloc(sizeof(ParseNode))))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("fail to allocate memory", K(ret), K(sizeof(ParseNode)));
|
||||
} else {
|
||||
col_ref_node = new(col_ref_node) ParseNode;
|
||||
if (OB_FAIL(ObRawExprResolverImpl::malloc_new_specified_type_node(allocator, "", col_ref_node, T_OBJ_ACCESS_REF))) {
|
||||
LOG_WARN("key node create fail", K(ret));
|
||||
} else {
|
||||
pre_node->children_[1] = col_ref_node;
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
pre_node = col_ref_node;
|
||||
}
|
||||
t_node = t_node->children_[1];
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) && !is_fun_sys && OB_ISNULL(node->children_[i+1] = column_ref_node)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("column_node copy failed", K(ret));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) && OB_FAIL(SMART_CALL(expand_node(allocator, node->children_[i], i, arr)))) {
|
||||
LOG_WARN("node expand fail", K(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (node->type_ == T_STAR) {
|
||||
// do nothing
|
||||
} else if ((node->type_ == T_COLUMN_REF || node->type_ == T_OBJ_ACCESS_REF) && node->value_ == 1 && p % 3 == 0) {
|
||||
ObQualifiedName column_ref;
|
||||
ParseNode *col_node;
|
||||
if (nullptr == (col_node = static_cast<ParseNode*>(allocator.alloc(sizeof(ParseNode))))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("fail to allocate memory", K(ret), K(sizeof(ParseNode)));
|
||||
} else if (node->type_ == T_COLUMN_REF) {
|
||||
if (OB_FAIL(ObResolverUtils::resolve_column_ref(
|
||||
node, ctx_.case_mode_, column_ref))) {
|
||||
LOG_WARN("fail to resolve column ref", K(ret));
|
||||
}
|
||||
if (OB_NOT_NULL(node->children_[2]->raw_text_)) {
|
||||
column_ref.col_name_ = node->children_[2]->raw_text_;
|
||||
}
|
||||
} else if (node->type_ == T_OBJ_ACCESS_REF) {
|
||||
while (node->children_[1] != NULL) {
|
||||
node = node->children_[1];
|
||||
}
|
||||
if (OB_NOT_NULL(node->children_[0]) && node->children_[0]->type_ == T_IDENT) {
|
||||
if (OB_FAIL(ObResolverUtils::resolve_obj_access_ref_node(
|
||||
ctx_.expr_factory_, node->children_[0], column_ref, *ctx_.session_info_))) {
|
||||
LOG_WARN("fail to resolve column ref", K(ret));
|
||||
}
|
||||
if (OB_NOT_NULL(node->children_[0]->raw_text_)) {
|
||||
column_ref.col_name_ = node->children_[0]->raw_text_;
|
||||
}
|
||||
} else {
|
||||
column_ref.is_star_ = true;
|
||||
const ParseNode* new_node = node;
|
||||
if (OB_FAIL(arr.push_back(node))) {
|
||||
LOG_WARN("node resolver fail", K(ret));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (OB_SUCC(ret) && !column_ref.is_star_) {
|
||||
col_node = new(col_node) ParseNode;
|
||||
ObString col_name = column_ref.col_name_;
|
||||
if (OB_FAIL(ObRawExprResolverImpl::malloc_new_specified_type_node(allocator, col_name, col_node, T_CHAR))) {
|
||||
LOG_WARN("fail to create column node ");
|
||||
}
|
||||
const ParseNode* new_node = col_node;
|
||||
if (OB_FAIL(arr.push_back(new_node))) {
|
||||
LOG_WARN("node resolver fail", K(ret));
|
||||
}
|
||||
}
|
||||
} else if (node->type_ == T_COLUMN_REF && node->children_[2]->type_ == T_STAR) {
|
||||
// do nothing
|
||||
} else if (node->type_ == T_NULL && node->value_ == 2) {
|
||||
// do nothing
|
||||
} else {
|
||||
const ParseNode* new_node = node;
|
||||
if (OB_FAIL(arr.push_back(node))) {
|
||||
@ -5162,9 +5024,38 @@ int ObRawExprResolverImpl::remove_strict_opt_in_pl(ParseNode *node, int8_t expr_
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObRawExprResolverImpl::get_column_raw_text_from_node(const ParseNode *node, ObString &col_name)
|
||||
{
|
||||
INIT_SUCC(ret);
|
||||
ObQualifiedName column_ref;
|
||||
if (node->type_ == T_COLUMN_REF) {
|
||||
col_name = node->children_[2]->raw_text_;
|
||||
} else if (node->type_ == T_OBJ_ACCESS_REF) {
|
||||
while (OB_SUCC(ret) && node->children_[1] != NULL) {
|
||||
node = node->children_[1];
|
||||
if (node->type_ != T_OBJ_ACCESS_REF) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("fail to get column name from node", K(ret));
|
||||
}
|
||||
}
|
||||
if (OB_SUCC(ret) && OB_NOT_NULL(node->children_[0]) && node->children_[0]->type_ == T_IDENT) {
|
||||
col_name = node->children_[0]->raw_text_;
|
||||
} else {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("fail to get column name from node", K(ret));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObRawExprResolverImpl::process_ora_json_object_node(const ParseNode *node, ObRawExpr *&expr)
|
||||
{
|
||||
INIT_SUCC(ret);
|
||||
ObVector<const ParseNode*> key_value_arr;
|
||||
ParseNode* data_node = NULL;
|
||||
ParseNode* cur_node_kv = NULL;
|
||||
int cur_col_size = 0;
|
||||
ParseNode key_node;
|
||||
CK(OB_NOT_NULL(node));
|
||||
int32_t num = 0;
|
||||
if (OB_SUCC(ret)) {
|
||||
@ -5208,7 +5099,6 @@ int ObRawExprResolverImpl::process_ora_json_object_node(const ParseNode *node, O
|
||||
}
|
||||
}
|
||||
|
||||
ObVector<const ParseNode*> key_value_arr;
|
||||
if (OB_SUCC(ret)) {
|
||||
const ParseNode *key_value = node->children_[0];
|
||||
if (OB_ISNULL(key_value)) {
|
||||
@ -5226,30 +5116,76 @@ int ObRawExprResolverImpl::process_ora_json_object_node(const ParseNode *node, O
|
||||
LOG_WARN("illegal use of 'strcit' clause.");
|
||||
}
|
||||
}
|
||||
ParseNode *cur_node = NULL;
|
||||
if (OB_FAIL(ret) || OB_ISNULL(key_value)) {
|
||||
} else if (OB_NOT_NULL(node->children_[0]) && (node->children_[0]->num_child_ == 0 || (node->children_[0]->num_child_ > 0 && OB_ISNULL(cur_node = node->children_[0]->children_[0])))) {
|
||||
} else if (cur_node->type_ == T_COLUMN_REF && OB_NOT_NULL(cur_node->children_[2]) && cur_node->children_[2]->type_ == T_STAR) {
|
||||
} else if (OB_FAIL(expand_node(ctx_.local_allocator_, const_cast<ParseNode *>(key_value), 0, key_value_arr))) {
|
||||
LOG_WARN("expand node has error", K(ret), K(key_value_arr.size()));
|
||||
} else if (key_value_arr.size() != key_value->num_child_) {
|
||||
ret = OB_ERR_MISS_VALUE;
|
||||
LOG_WARN("missing value keyword", K(ret), K(key_value_arr.size()), K(key_value->num_child_));
|
||||
}
|
||||
|
||||
if (OB_SUCC(ret)) {
|
||||
// [key-value(vector)][null_type][returning_type][strict][unique_keys]
|
||||
for (int32_t i = 0; OB_SUCC(ret) && i < key_value_arr.size(); i++) {
|
||||
if (key_value_arr[i]->type_ == T_LINK_NODE || key_value_arr[i]->type_ == T_VALUE_VECTOR) {
|
||||
} else {
|
||||
// [key-value(vector)]
|
||||
if (OB_NOT_NULL(node->children_[0])) {
|
||||
data_node = node->children_[0];
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < data_node->num_child_; i++) { // 3 node in group
|
||||
ObRawExpr *para_expr = NULL;
|
||||
CK(OB_NOT_NULL(key_value_arr[i]));
|
||||
OZ(SMART_CALL(recursive_resolve(key_value_arr[i], para_expr)));
|
||||
CK(OB_NOT_NULL(para_expr));
|
||||
OZ(func_expr->add_param_expr(para_expr));
|
||||
cur_node_kv = NULL;
|
||||
int val_pos = i + 1; // key is i where i % 3 == 0 , value is i + 1, format json is i + 2
|
||||
if (OB_ISNULL(data_node->children_[i])) {
|
||||
} else if ((i % 3 == 1) && data_node->children_[i]->type_ == T_NULL && data_node->children_[i]->value_ == 2) { // 2 is flag of empty value
|
||||
cur_node_kv = data_node->children_[i - 1];
|
||||
} else {
|
||||
cur_node_kv = data_node->children_[i];
|
||||
}
|
||||
if (OB_FAIL(ret) || OB_ISNULL(cur_node_kv)) {
|
||||
} else if (OB_FAIL(SMART_CALL(recursive_resolve(cur_node_kv, para_expr)))) {
|
||||
LOG_WARN("fail to get raw expr from node", K(ret), K(i));
|
||||
} else if (OB_ISNULL(para_expr)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("raw expr is null", K(ret), K(i));
|
||||
} else if ((i % JSON_OBJECT_GROUP == ObJsonObjectEntry::JSON_OBJECT_KEY) && data_node->children_[val_pos]->type_ == T_NULL
|
||||
&& data_node->children_[val_pos]->value_ == 2 // 2 is flag of empty value
|
||||
&& !(((para_expr->get_expr_type() == T_COLUMN_REF // column type
|
||||
|| para_expr->get_expr_type() == T_REF_COLUMN)
|
||||
&& ctx_.columns_->at(ctx_.columns_->count()-1).access_idents_.at(0).get_type() == oceanbase::sql::UNKNOWN)
|
||||
|| para_expr->get_expr_type() == T_FUN_SYS_ROWNUM)) { // rownum
|
||||
ret = OB_ERR_MISS_VALUE;
|
||||
LOG_WARN("missing value keyword", K(ret), K(para_expr->get_expr_type()), K(i));
|
||||
} else if ((i % JSON_OBJECT_GROUP == ObJsonObjectEntry::JSON_OBJECT_KEY) && data_node->children_[val_pos]->type_ == T_NULL
|
||||
&& data_node->children_[val_pos]->value_ == 2 // 2 is flag of empty value
|
||||
&& (((para_expr->get_expr_type() == T_COLUMN_REF // column type
|
||||
|| para_expr->get_expr_type() == T_REF_COLUMN)
|
||||
&& ctx_.columns_->at(ctx_.columns_->count() - 1).access_idents_.at(0).get_type() == oceanbase::sql::UNKNOWN)
|
||||
|| para_expr->get_expr_type() == T_FUN_SYS_ROWNUM)) { // rownum
|
||||
ObString col_name;
|
||||
if (para_expr->get_expr_type() == T_FUN_SYS_ROWNUM) {
|
||||
col_name.assign_ptr("rownum", 6);
|
||||
} else if (ctx_.columns_->count() > cur_col_size && OB_SUCC(get_column_raw_text_from_node(cur_node_kv, col_name))) {
|
||||
for (int col_pos = cur_col_size; col_pos < ctx_.columns_->count(); col_pos ++) {
|
||||
ctx_.columns_->pop_back(); // delete column para
|
||||
}
|
||||
} else {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("fail to resolve column", K(ret), K(cur_col_size), K(ctx_.columns_->count()));
|
||||
}
|
||||
para_expr = NULL;
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_FAIL(ObRawExprResolverImpl::malloc_new_specified_type_node(ctx_.local_allocator_, col_name, &key_node, T_CHAR))) {
|
||||
LOG_WARN("create json doc node fail", K(ret));
|
||||
} else if (OB_FAIL(SMART_CALL(recursive_resolve(&key_node, para_expr)))) {
|
||||
LOG_WARN("fail to get raw expr from node", K(ret), K(i));
|
||||
} else if (OB_ISNULL(para_expr)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("raw expr is null", K(ret), K(i));
|
||||
} else if (OB_FAIL(func_expr->add_param_expr(para_expr))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("fail to add into func expr", K(ret), K(i));
|
||||
} else {
|
||||
cur_col_size = ctx_.columns_->count();
|
||||
}
|
||||
} else if (OB_FAIL(func_expr->add_param_expr(para_expr))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("fail to add into func expr", K(ret), K(i));
|
||||
} else {
|
||||
cur_col_size = ctx_.columns_->count();
|
||||
}
|
||||
}
|
||||
} //end for
|
||||
// ([on_mismatch][opt_mismatch_types] on oracle)
|
||||
}
|
||||
// [null_type][returning_type][strict][unique_keys]
|
||||
for (int32_t i = 1; OB_SUCC(ret) && i < num; i++) {
|
||||
ObRawExpr *para_expr = NULL;
|
||||
CK(OB_NOT_NULL(node->children_[i]));
|
||||
|
@ -104,10 +104,17 @@ private:
|
||||
OPT_JSON_OBJECT,
|
||||
OPT_JSON_ARRAY,
|
||||
};
|
||||
enum ObJsonObjectEntry: int8_t {
|
||||
JSON_OBJECT_KEY = 0,
|
||||
JSON_OBJECT_VAL = 1,
|
||||
JSON_OBJECT_FORMAT = 2
|
||||
};
|
||||
const int JSON_OBJECT_GROUP = 3;
|
||||
int remove_strict_opt_in_pl(ParseNode *node, int8_t expr_flag);
|
||||
int remove_format_json_opt_in_pl(ParseNode *node, int8_t expr_flag);
|
||||
int process_json_value_node(const ParseNode *node, ObRawExpr *&expr);
|
||||
int pre_check_json_path_valid(const ParseNode *node);
|
||||
int get_column_raw_text_from_node(const ParseNode *node, ObString &col_name);
|
||||
int process_ora_json_object_node(const ParseNode *node, ObRawExpr *&expr);
|
||||
int process_is_json_node(const ParseNode *node, ObRawExpr *&expr);
|
||||
int process_json_equal_node(const ParseNode *node, ObRawExpr *&expr);
|
||||
|
Loading…
x
Reference in New Issue
Block a user