patch bugfix to master
This commit is contained in:
@ -1443,23 +1443,26 @@ int ObRawExprPrinter::print_json_object(ObSysFunRawExpr *expr)
|
||||
if (OB_SUCC(ret)) {
|
||||
for (int i = 0; i < num_para - 4; i += 3) {
|
||||
PRINT_EXPR(expr->get_param_expr(i));
|
||||
DATA_PRINTF(" VALUE ");
|
||||
PRINT_EXPR(expr->get_param_expr(i + 1));
|
||||
if (!static_cast<ObConstRawExpr*>(expr->get_param_expr(i + 2))->get_value().is_int()) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("type value isn't int value");
|
||||
if (T_FUN_SYS_JSON_OBJECT_WILD_STAR == expr->get_param_expr(i)->get_expr_type()) { // do nothing
|
||||
} else {
|
||||
int64_t type = static_cast<ObConstRawExpr*>(expr->get_param_expr(i + 2))->get_value().get_int();
|
||||
switch (type) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
DATA_PRINTF(" format json");
|
||||
break;
|
||||
default:
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("invalid type value.", K(type));
|
||||
break;
|
||||
DATA_PRINTF(" VALUE ");
|
||||
PRINT_EXPR(expr->get_param_expr(i + 1));
|
||||
if (!static_cast<ObConstRawExpr*>(expr->get_param_expr(i + 2))->get_value().is_int()) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("type value isn't int value");
|
||||
} else {
|
||||
int64_t type = static_cast<ObConstRawExpr*>(expr->get_param_expr(i + 2))->get_value().get_int();
|
||||
switch (type) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
DATA_PRINTF(" format json");
|
||||
break;
|
||||
default:
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("invalid type value.", K(type));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (i != num_para - 7 && OB_SUCC(ret)) {
|
||||
@ -1968,6 +1971,23 @@ int ObRawExprPrinter::print_json_value(ObSysFunRawExpr *expr)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObRawExprPrinter::print_dot_notation(ObSysFunRawExpr *expr)
|
||||
{
|
||||
INIT_SUCC(ret);
|
||||
PRINT_EXPR(expr->get_param_expr(0));
|
||||
// DATA_PRINTF(".");
|
||||
// PRINT_EXPR(expr->get_param_expr(1));
|
||||
ObObj path_obj = static_cast<ObConstRawExpr*>(expr->get_param_expr(1))->get_value();
|
||||
ObItemType expr_type = expr->get_param_expr(1)->get_expr_type();
|
||||
if (T_VARCHAR != expr_type && T_CHAR != expr_type) {
|
||||
} else if (!path_obj.get_string().empty()) {
|
||||
// we should print string without quote
|
||||
DATA_PRINTF("%.*s", (path_obj.get_string().length() - 1), (path_obj.get_string().ptr() + 1));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObRawExprPrinter::print_json_query(ObSysFunRawExpr *expr)
|
||||
{
|
||||
INIT_SUCC(ret);
|
||||
@ -2362,6 +2382,23 @@ int ObRawExprPrinter::print_is_json(ObSysFunRawExpr *expr)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObRawExprPrinter::print_json_object_star(ObSysFunRawExpr *expr)
|
||||
{
|
||||
INIT_SUCC(ret);
|
||||
ObObj tab_obj = static_cast<ObConstRawExpr*>(expr->get_param_expr(0))->get_value();
|
||||
ObItemType expr_type = expr->get_param_expr(0)->get_expr_type();
|
||||
if (T_VARCHAR != expr_type && T_CHAR != expr_type) {
|
||||
} else if (!tab_obj.get_string().empty()) {
|
||||
// we should print string without qoute
|
||||
DATA_PRINTF("%.*s", (tab_obj.get_string().length()), (tab_obj.get_string().ptr()));
|
||||
DATA_PRINTF(".");
|
||||
}
|
||||
if (OB_SUCC(ret)) {
|
||||
DATA_PRINTF("*");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObRawExprPrinter::print_json_expr(ObSysFunRawExpr *expr)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
@ -2372,11 +2409,20 @@ int ObRawExprPrinter::print_json_expr(ObSysFunRawExpr *expr)
|
||||
ObString func_name = expr->get_func_name();
|
||||
switch (expr->get_expr_type()) {
|
||||
case T_FUN_SYS_JSON_VALUE: {
|
||||
// if json value only have one mismatch clause, the size of parameter is 12
|
||||
const int8_t JSN_VAL_WITH_ONE_MISMATCH = 12;
|
||||
// json value parameter count more than 12, because mismatch is multi-val and default value.
|
||||
// json_value(expr(0), expr(1) returning cast_type ascii xxx on empty(default value) xxx on error(default value) xxx on mismatch (xxx))
|
||||
if (OB_UNLIKELY(expr->get_param_count() < 12)) {
|
||||
if (OB_UNLIKELY(expr->get_param_count() < JSN_VAL_WITH_ONE_MISMATCH)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected param count of expr to type", K(ret), KPC(expr));
|
||||
} else if (!static_cast<ObConstRawExpr*>(expr->get_param_expr(JSN_VAL_WITH_ONE_MISMATCH - 1))->get_value().is_int()) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("type value isn't int value");
|
||||
} else if (static_cast<ObConstRawExpr*>(expr->get_param_expr(JSN_VAL_WITH_ONE_MISMATCH - 1))->get_value().get_int() == 8) {
|
||||
if (OB_FAIL(print_dot_notation(expr))) {
|
||||
LOG_WARN("fail to print dot notation", K(ret));
|
||||
}
|
||||
} else {
|
||||
DATA_PRINTF("json_value(");
|
||||
PRINT_EXPR(expr->get_param_expr(0));
|
||||
@ -2390,9 +2436,17 @@ int ObRawExprPrinter::print_json_expr(ObSysFunRawExpr *expr)
|
||||
}
|
||||
case T_FUN_SYS_JSON_QUERY: {
|
||||
// json query (json doc, json path, (returning cast_type) opt_scalars opt_pretty opt_ascii opt_wrapper on_error on_empty on_mismatch).
|
||||
int64_t type = 0;
|
||||
if (OB_UNLIKELY(expr->get_param_count() != 11)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected param count of expr to type", K(ret), KPC(expr), K(expr->get_param_count()));
|
||||
} else if (!static_cast<ObConstRawExpr*>(expr->get_param_expr(10))->get_value().is_int()) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("type value isn't int value");
|
||||
} else if (static_cast<ObConstRawExpr*>(expr->get_param_expr(10))->get_value().get_int() == 3) {
|
||||
if (OB_FAIL(print_dot_notation(expr))) {
|
||||
LOG_WARN("fail to print dot notation", K(ret));
|
||||
}
|
||||
} else {
|
||||
DATA_PRINTF("json_query(");
|
||||
PRINT_EXPR(expr->get_param_expr(0));
|
||||
@ -3077,6 +3131,12 @@ int ObRawExprPrinter::print(ObSysFunRawExpr *expr)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case T_FUN_SYS_JSON_OBJECT_WILD_STAR: {
|
||||
if (OB_FAIL(print_json_object_star(expr))) {
|
||||
LOG_WARN("fail to print star in json object", K(ret));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case T_FUN_PAD: {
|
||||
if (print_params_.for_dblink_) {
|
||||
// Oracle do not have function pad,
|
||||
|
||||
@ -138,6 +138,8 @@ private:
|
||||
int print_json_expr(ObSysFunRawExpr *expr);
|
||||
int print_json_value(ObSysFunRawExpr *expr);
|
||||
int print_json_query(ObSysFunRawExpr *expr);
|
||||
int print_dot_notation(ObSysFunRawExpr *expr);
|
||||
int print_json_object_star(ObSysFunRawExpr *expr);
|
||||
int print_json_exists(ObSysFunRawExpr *expr);
|
||||
int print_json_equal(ObSysFunRawExpr *expr);
|
||||
int print_json_array(ObSysFunRawExpr *expr);
|
||||
|
||||
@ -955,7 +955,7 @@ int ObRawExprResolverImpl::do_recursive_resolve(const ParseNode *node, ObRawExpr
|
||||
}
|
||||
case T_FUN_SYS_JSON_QUERY: {
|
||||
if (OB_FAIL(process_json_query_node(node, expr))) {
|
||||
LOG_WARN("fail to process lnnvl node", K(ret), K(node));
|
||||
LOG_WARN("fail to process json query node", K(ret), K(node));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -967,7 +967,13 @@ int ObRawExprResolverImpl::do_recursive_resolve(const ParseNode *node, ObRawExpr
|
||||
}
|
||||
case T_FUN_SYS_JSON_OBJECT: {
|
||||
if (OB_FAIL(process_ora_json_object_node(node, expr))) {
|
||||
LOG_WARN("fail to process lnnvl node", K(ret), K(node));
|
||||
LOG_WARN("fail to process json object node", K(ret), K(node));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case T_FUN_SYS_JSON_OBJECT_WILD_STAR: {
|
||||
if (OB_FAIL(process_ora_json_object_star_node(node, expr))) {
|
||||
LOG_WARN("fail to process json object star node", K(ret), K(node));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -5253,6 +5259,26 @@ int ObRawExprResolverImpl::malloc_new_specified_type_node(common::ObIAllocator &
|
||||
t_vec[1] = NULL;
|
||||
col_node->children_ = t_vec;
|
||||
}
|
||||
} else if (type == T_FUN_SYS_JSON_OBJECT_WILD_STAR) {
|
||||
col_node->type_ = T_FUN_SYS_JSON_OBJECT_WILD_STAR;
|
||||
col_node->num_child_ = 1;
|
||||
col_node->is_hidden_const_ = 1;
|
||||
int64_t alloc_access_size = sizeof(ParseNode *) * 1;
|
||||
ParseNode **t_vec = NULL;
|
||||
if (OB_ISNULL(t_vec = static_cast<ParseNode **>(allocator.alloc(alloc_access_size)))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("fail to allocate memory", K(ret), K(sizeof(ParseNode)));
|
||||
} else {
|
||||
t_vec[0] = NULL;
|
||||
col_node->children_ = t_vec;
|
||||
}
|
||||
} else if (type == T_VARCHAR) {
|
||||
col_node->type_ = T_VARCHAR;
|
||||
col_node->str_value_ = col_name.ptr();
|
||||
col_node->raw_text_ = col_name.ptr();
|
||||
col_node->str_len_ = col_name.length();
|
||||
col_node->text_len_ = col_name.length();
|
||||
col_node->num_child_ = 0;
|
||||
} else {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("node type not exits");
|
||||
@ -5354,6 +5380,83 @@ int ObRawExprResolverImpl::get_column_raw_text_from_node(const ParseNode *node,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObRawExprResolverImpl::create_json_object_star_node(ParseNode *&node, common::ObIAllocator &allocator, int64_t &pos)
|
||||
{
|
||||
INIT_SUCC(ret);
|
||||
bool all_tab = true;
|
||||
ObSEArray<ColumnItem, 4> columns_list;
|
||||
ParseNode* json_object_star = NULL;
|
||||
ParseNode* table_node = NULL;
|
||||
ParseNode* value_node = NULL;
|
||||
ObString tab_name;
|
||||
if (OB_ISNULL(node)) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("node should not be null", K(ret));
|
||||
} else if (OB_NOT_NULL(node->children_[pos]) && OB_NOT_NULL(node->children_[pos]->children_[1])) {
|
||||
tab_name.assign_ptr(node->children_[pos]->children_[1]->str_value_, node->children_[pos]->children_[1]->str_len_);
|
||||
all_tab = false;
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_ISNULL(json_object_star = static_cast<ParseNode*>(allocator.alloc(sizeof(ParseNode))))) {
|
||||
ret = OB_ALLOCATE_MEMORY_FAILED;
|
||||
LOG_WARN("fail to allocate memory", K(ret), K(sizeof(ParseNode)));
|
||||
} else {
|
||||
json_object_star = new(json_object_star) ParseNode;
|
||||
if (OB_FAIL(ObRawExprResolverImpl::malloc_new_specified_type_node(allocator, "", json_object_star, T_FUN_SYS_JSON_OBJECT_WILD_STAR))) {
|
||||
LOG_WARN("create json doc node fail", K(ret));
|
||||
} else if (OB_ISNULL(table_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 {
|
||||
table_node = new(table_node) ParseNode;
|
||||
}
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (all_tab && OB_FAIL(ObRawExprResolverImpl::malloc_new_specified_type_node(allocator, "", table_node, T_INT))) {
|
||||
LOG_WARN("fail to create int node", K(ret));
|
||||
} else if (!all_tab && OB_FAIL(ObRawExprResolverImpl::malloc_new_specified_type_node(allocator, tab_name, table_node, T_VARCHAR))) {
|
||||
LOG_WARN("fail to create table name node", K(ret));
|
||||
} else {
|
||||
json_object_star->children_[0] = table_node;
|
||||
node->children_[pos] = json_object_star;
|
||||
}
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (OB_ISNULL(value_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 {
|
||||
value_node = new(value_node) ParseNode;
|
||||
if (OB_FAIL(ObRawExprResolverImpl::malloc_new_specified_type_node(allocator, "", value_node, T_INT))) {
|
||||
LOG_WARN("create json doc node fail", K(ret));
|
||||
} else {
|
||||
node->children_[pos + 1] = value_node;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObRawExprResolverImpl::process_ora_json_object_star_node(const ParseNode *node, ObRawExpr *&expr)
|
||||
{
|
||||
INIT_SUCC(ret);
|
||||
ObSysFunRawExpr *func_expr = NULL;
|
||||
if (OB_FAIL(ctx_.expr_factory_.create_raw_expr(T_FUN_SYS, func_expr))) {
|
||||
LOG_WARN("fail to create func_expr");
|
||||
} else {
|
||||
CK(OB_NOT_NULL(func_expr));
|
||||
OX(func_expr->set_func_name(ObString::make_string("json_object_star")));
|
||||
// child 0 is table name
|
||||
for (int64_t i = 0; OB_SUCC(ret) && i < node->num_child_; i++) {
|
||||
ObRawExpr *param_expr = NULL;
|
||||
CK(OB_NOT_NULL(node->children_[i]));
|
||||
OZ(SMART_CALL(recursive_resolve(node->children_[i], param_expr)));
|
||||
CK(OB_NOT_NULL(param_expr));
|
||||
OZ(func_expr->add_param_expr(param_expr));
|
||||
}
|
||||
OX(expr = func_expr);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObRawExprResolverImpl::process_ora_json_object_node(const ParseNode *node, ObRawExpr *&expr)
|
||||
{
|
||||
INIT_SUCC(ret);
|
||||
@ -5429,9 +5532,14 @@ int ObRawExprResolverImpl::process_ora_json_object_node(const ParseNode *node, O
|
||||
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;
|
||||
cur_node_kv = NULL;
|
||||
cur_node_kv = data_node->children_[i];
|
||||
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])) {
|
||||
if (OB_ISNULL(cur_node_kv)) {
|
||||
} else if (cur_node_kv->type_ == T_COLUMN_REF // process star node
|
||||
&& OB_NOT_NULL(cur_node_kv->children_[2])
|
||||
&& cur_node_kv->children_[2]->type_ == T_STAR
|
||||
&& OB_FAIL(ObRawExprResolverImpl::create_json_object_star_node(data_node, ctx_.local_allocator_, i))) {
|
||||
LOG_WARN("fail to create json object star node", K(ret));
|
||||
} 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 {
|
||||
|
||||
@ -119,6 +119,8 @@ private:
|
||||
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 create_json_object_star_node(ParseNode *&node, common::ObIAllocator &allocator, int64_t &pos);
|
||||
int process_ora_json_object_star_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);
|
||||
int process_json_query_node(const ParseNode *node, ObRawExpr *&expr);
|
||||
|
||||
Reference in New Issue
Block a user