From ff893e6e4fc8f29506766c4631cfaf60e8764d96 Mon Sep 17 00:00:00 2001 From: obdev Date: Mon, 13 Feb 2023 12:41:36 +0000 Subject: [PATCH] bugfix:47099280, 47725591, 47679463, 47077540, 47024555 --- deps/oblib/src/lib/json_type/ob_json_path.cpp | 4 ++- .../engine/expr/ob_expr_json_func_helper.cpp | 10 +++---- src/sql/engine/expr/ob_expr_json_query.cpp | 15 +++++++++-- src/sql/engine/expr/ob_expr_json_value.cpp | 3 ++- src/sql/resolver/dml/ob_dml_resolver.cpp | 26 +++++++++++++++++++ src/sql/resolver/dml/ob_dml_resolver.h | 1 + .../expr/ob_raw_expr_resolver_impl.cpp | 3 +-- 7 files changed, 49 insertions(+), 13 deletions(-) diff --git a/deps/oblib/src/lib/json_type/ob_json_path.cpp b/deps/oblib/src/lib/json_type/ob_json_path.cpp index 534069573..fc768b49e 100644 --- a/deps/oblib/src/lib/json_type/ob_json_path.cpp +++ b/deps/oblib/src/lib/json_type/ob_json_path.cpp @@ -818,7 +818,9 @@ int ObJsonPath::change_json_expr_res_type_if_need(common::ObIAllocator &allocato case JPN_LENGTH : case JPN_SIZE : case JPN_NUM_ONLY : - case JPN_NUMBER : { + case JPN_NUMBER : + case JPN_FLOOR : + case JPN_CEILING : { ret_node.value_ = 0; if (ret_node.type_ == T_NULL) { ret_node.int16_values_[OB_NODE_CAST_TYPE_IDX] = T_VARCHAR; diff --git a/src/sql/engine/expr/ob_expr_json_func_helper.cpp b/src/sql/engine/expr/ob_expr_json_func_helper.cpp index 81d323415..78032d16b 100644 --- a/src/sql/engine/expr/ob_expr_json_func_helper.cpp +++ b/src/sql/engine/expr/ob_expr_json_func_helper.cpp @@ -1562,9 +1562,6 @@ int ObJsonExprHelper::check_item_func_with_return(ObJsonPathNodeType path_type, } break; } - case JPN_CEILING :{ - break; - } case JPN_DATE :{ if (dst_type == ObDateTimeType) { } else { @@ -1581,14 +1578,13 @@ int ObJsonExprHelper::check_item_func_with_return(ObJsonPathNodeType path_type, } break; } - case JPN_FLOOR :{ - break; - } + case JPN_FLOOR : + case JPN_CEILING : case JPN_LENGTH : case JPN_NUMBER : case JPN_NUM_ONLY : case JPN_SIZE :{ - if (JSON_EXPR_FLAG == 1 || (JSON_EXPR_FLAG ==0 && dst_type == ObNumberType)) { + if (JSON_EXPR_FLAG == 1 || (JSON_EXPR_FLAG == 0 && dst_type == ObNumberType)) { } else { ret = OB_ERR_INVALID_DATA_TYPE_RETURNING; LOG_WARN("item func is lower/upper, but return type is ", K(dst_type), K(ret)); diff --git a/src/sql/engine/expr/ob_expr_json_query.cpp b/src/sql/engine/expr/ob_expr_json_query.cpp index baa3c686d..06e1e908e 100644 --- a/src/sql/engine/expr/ob_expr_json_query.cpp +++ b/src/sql/engine/expr/ob_expr_json_query.cpp @@ -292,10 +292,11 @@ int ObExprJsonQuery::eval_json_query(const ObExpr &expr, ObEvalCtx &ctx, ObDatum LOG_WARN("error occur in wrapper type"); } else if (use_wrapper == 0 && hits[0]->json_type() == ObJsonNodeType::J_NULL && !hits[0]->is_real_json_null(hits[0])) { is_null_result = true; - } else if (use_wrapper == 0 && j_path->get_last_node_type() == JPN_BOOLEAN && (hits[0]->is_json_number(hits[0]->json_type()) || hits[0]->json_type() == ObJsonNodeType::J_NULL)) { - is_null_result = true; } else if (use_wrapper == 0 && j_path->is_last_func() && j_path->path_node_cnt() == 1) { // do nothing + } else if (use_wrapper == 0 && j_path->get_last_node_type() == JPN_BOOLEAN + && (hits[0]->is_json_number(hits[0]->json_type()) || hits[0]->json_type() == ObJsonNodeType::J_NULL)) { + is_null_result = true; } else if (use_wrapper == 0 && (j_path->get_last_node_type() == JPN_DATE || j_path->get_last_node_type() == JPN_TIMESTAMP) && !hits[0]->is_json_date(hits[0]->json_type())) { is_null_result = true; @@ -308,6 +309,16 @@ int ObExprJsonQuery::eval_json_query(const ObExpr &expr, ObEvalCtx &ctx, ObDatum } else if (use_wrapper == 0 && (j_path->get_last_node_type() == JPN_UPPER || j_path->get_last_node_type() == JPN_LOWER) && (hits[0]->json_type() == ObJsonNodeType::J_OBJECT || hits[0]->json_type() == ObJsonNodeType::J_ARRAY)) { is_null_result = true; + } else if (use_wrapper == 0 && (j_path->get_last_node_type() == JPN_NUMBER || j_path->get_last_node_type() == JPN_NUM_ONLY + || j_path->get_last_node_type() == JPN_DOUBLE) + && (!hits[0]->is_json_number(hits[0]->json_type()) && hits[0]->json_type() != ObJsonNodeType::J_NULL)) { + is_null_result = true; + } else if (use_wrapper == 0 && j_path->get_last_node_type() == JPN_LENGTH && !(hits[0]->json_type() == ObJsonNodeType::J_UINT + && ((ObJsonUint *)hits[0])->get_is_string_length())) { + is_null_result = true; + } else if (use_wrapper == 0 && (j_path->get_last_node_type() == JPN_DATE || j_path->get_last_node_type() == JPN_TIMESTAMP) + && !hits[0]->is_json_date(hits[0]->json_type())) { + is_null_result = true; } } } else if (hits.size() == 0) { diff --git a/src/sql/engine/expr/ob_expr_json_value.cpp b/src/sql/engine/expr/ob_expr_json_value.cpp index f676624ce..049ef1bb8 100644 --- a/src/sql/engine/expr/ob_expr_json_value.cpp +++ b/src/sql/engine/expr/ob_expr_json_value.cpp @@ -651,7 +651,8 @@ int ObExprJsonValue::doc_do_seek(ObJsonBaseVector &hits, bool &is_null_result, O } else if (j_path->is_last_func()) { if (j_path->get_last_node_type() == ObJsonPathNodeType::JPN_BOOLEAN && hits[0]->json_type() != ObJsonNodeType::J_BOOLEAN) { - if (hits[0]->json_type() == ObJsonNodeType::J_INT + if ((hits[0]->json_type() == ObJsonNodeType::J_INT + && (hits[0]->get_int() == 1 || hits[0]->get_int() == 0) ) || (hits[0]->json_type() == ObJsonNodeType::J_DOUBLE && (hits[0]->get_double() == 1.0 || hits[0]->get_double() == 0.0))) { bool is_true = hits[0]->json_type() == ObJsonNodeType::J_INT ? (hits[0]->get_int() == 1) : (hits[0]->get_double() == 1.0); diff --git a/src/sql/resolver/dml/ob_dml_resolver.cpp b/src/sql/resolver/dml/ob_dml_resolver.cpp index 956f93889..06350b967 100755 --- a/src/sql/resolver/dml/ob_dml_resolver.cpp +++ b/src/sql/resolver/dml/ob_dml_resolver.cpp @@ -2166,6 +2166,8 @@ int ObDMLResolver::resolve_columns(ObRawExpr *&expr, ObArray &c LOG_WARN("push back failed", K(ret)); } else if (OB_FAIL(ObRawExprUtils::replace_ref_column(expr, q_name.ref_expr_, real_ref_expr))) { LOG_WARN("replace column ref expr failed", K(ret)); + } else if (expr->is_sys_func_expr() && OB_FAIL(check_col_param_on_expr(expr))) { + LOG_WARN("illegal param on func_expr", K(ret)); } else { /*do nothing*/ } } return ret; @@ -5898,6 +5900,30 @@ int ObDMLResolver::do_resolve_subquery_info(const ObSubQueryInfo &subquery_info, return ret; } +int ObDMLResolver::check_col_param_on_expr(ObRawExpr *expr) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(expr)) { + ret = OB_NULL_CHECK_ERROR; + LOG_WARN("should not be nullptr", K(ret)); + } else if (expr->is_sys_func_expr()) { + int param_num = expr->get_param_count(); + ObSysFunRawExpr* f_expr = static_cast(expr); + // check param of json_exists passing clause + if (0 == f_expr->get_func_name().case_compare("json_exists") && param_num >= 6) { + for (int i = 2; i < param_num - 2 && OB_SUCC(ret); i += 2) { + if (expr->get_param_expr(i)->get_expr_type() == T_REF_COLUMN) { + ret = OB_ERR_INVALID_VARIABLE_IN_JSON_PATH; + LOG_USER_ERROR(OB_ERR_INVALID_VARIABLE_IN_JSON_PATH); + } + } + } + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("should be function expr", K(ret)); + } + return ret; +} int ObDMLResolver::check_expr_param(const ObRawExpr &expr) { int ret = OB_SUCCESS; diff --git a/src/sql/resolver/dml/ob_dml_resolver.h b/src/sql/resolver/dml/ob_dml_resolver.h index 81c68b910..85cbe2d3c 100644 --- a/src/sql/resolver/dml/ob_dml_resolver.h +++ b/src/sql/resolver/dml/ob_dml_resolver.h @@ -309,6 +309,7 @@ protected: ObSelectStmt *select_stmt); int resolve_sys_vars(common::ObArray &sys_vars); int check_expr_param(const ObRawExpr &expr); + int check_col_param_on_expr(ObRawExpr *expr); int resolve_columns_field_list_first(ObRawExpr *&expr, ObArray &columns, ObSelectStmt* sel_stmt); int resolve_columns(ObRawExpr *&expr, common::ObArray &columns); int resolve_qualified_identifier(ObQualifiedName &q_name, diff --git a/src/sql/resolver/expr/ob_raw_expr_resolver_impl.cpp b/src/sql/resolver/expr/ob_raw_expr_resolver_impl.cpp index 22bfc15b0..5e2e817af 100644 --- a/src/sql/resolver/expr/ob_raw_expr_resolver_impl.cpp +++ b/src/sql/resolver/expr/ob_raw_expr_resolver_impl.cpp @@ -5360,8 +5360,7 @@ int ObRawExprResolverImpl::process_json_exists_node(const ParseNode *node, ObRaw ObRawExpr *para_expr = NULL; CK(OB_NOT_NULL(node->children_[i]->children_[name_idx])); OZ(SMART_CALL(recursive_resolve(node->children_[i]->children_[name_idx], para_expr))); - CK(OB_NOT_NULL(para_expr)); - if (name_idx % 2 == 0 && para_expr->get_expr_type() == T_REF_COLUMN) { + if (name_idx % 2 == 0 && para_expr->get_expr_type() == T_REF_QUERY) { ret = OB_ERR_INVALID_VARIABLE_IN_JSON_PATH; LOG_USER_ERROR(OB_ERR_INVALID_VARIABLE_IN_JSON_PATH); } else {