diff --git a/src/sql/engine/basic/ob_json_table_op.cpp b/src/sql/engine/basic/ob_json_table_op.cpp index 3850d4eb9d..e344607546 100644 --- a/src/sql/engine/basic/ob_json_table_op.cpp +++ b/src/sql/engine/basic/ob_json_table_op.cpp @@ -29,53 +29,6 @@ using namespace common; namespace sql { -/* json table empty or error */ -const static int32_t JSN_TABLE_ERROR = 0; -const static int32_t JSN_TABLE_NULL = 1; -const static int32_t JSN_TABLE_DEFAULT = 2; -const static int32_t JSN_TABLE_IMPLICIT = 3; - -/* json query empty or error */ -const static int32_t JSN_QUERY_ERROR = 0; -const static int32_t JSN_QUERY_NULL = 1; -const static int32_t JSN_QUERY_EMPTY = 2; -const static int32_t JSN_QUERY_EMPTY_ARRAY = 3; -const static int32_t JSN_QUERY_EMPTY_OBJECT = 4; -const static int32_t JSN_QUERY_IMPLICIT = 5; - -/* json query on mismatch { error : 0, null : 1, implicit : 2 }*/ -const static int32_t JSN_QUERY_MISMATCH_ERROR = 0; -const static int32_t JSN_QUERY_MISMATCH_NULL = 1; -const static int32_t JSN_QUERY_MISMATCH_IMPLICIT = 2; - -/* json query wrapper type */ -const static int32_t JSN_QUERY_WITHOUT_WRAPPER = 0; -const static int32_t JSN_QUERY_WITHOUT_ARRAY_WRAPPER = 1; -const static int32_t JSN_QUERY_WITH_WRAPPER = 2; -const static int32_t JSN_QUERY_WITH_ARRAY_WRAPPER = 3; -const static int32_t JSN_QUERY_WITH_UNCONDITIONAL_WRAPPER = 4; -const static int32_t JSN_QUERY_WITH_CONDITIONAL_WRAPPER = 5; -const static int32_t JSN_QUERY_WITH_UNCONDITIONAL_ARRAY_WRAPPER = 6; -const static int32_t JSN_QUERY_WITH_CONDITIONAL_ARRAY_WRAPPER = 7; -const static int32_t JSN_QUERY_WRAPPER_IMPLICIT = 8; - -/* json query on scalars { allow : 0, disallow : 1, implicit : 2 }*/ -const static int32_t JSN_QUERY_SCALARS_ALLOW = 0; -const static int32_t JSN_QUERY_SCALARS_DISALLOW = 1; -const static int32_t JSN_QUERY_SCALARS_IMPLICIT = 2; - -/* json value empty or error */ -const static int32_t JSN_VALUE_ERROR = 0; -const static int32_t JSN_VALUE_NULL = 1; -const static int32_t JSN_VALUE_DEFAULT = 2; -const static int32_t JSN_VALUE_IMPLICIT = 3; - -/* json value on mismatch { error : 0, null : 1, ignore : 2 }*/ -const static int32_t JSN_VALUE_MISMATCH_ERROR = 0; -const static int32_t JSN_VALUE_MISMATCH_NULL = 1; -const static int32_t JSN_VALUE_MISMATCH_IGNORE = 2; -const static int32_t JSN_VALUE_MISMATCH_IMPLICIT = 3; - /* json value mismatch type { MISSING : 0, EXTRA : 1, TYPE : 2, EMPTY : 3} */ const static int32_t JSN_VALUE_TYPE_MISSING_DATA = 0; const static int32_t JSN_VALUE_TYPE_EXTRA_DATA = 1; @@ -3348,7 +3301,7 @@ int ObJsonTableOp::inner_get_next_row() ret = OB_ERR_JSON_SYNTAX_ERROR; SET_COVER_ERROR(&jt_ctx_, ret); jt_ctx_.is_need_end_ = 1; - if (lib::is_oracle_mode() && jt_root_->col_info_.on_error_ != JSN_TABLE_ERROR) { + if (lib::is_oracle_mode() && jt_root_->col_info_.on_error_ != JSN_VALUE_ERROR) { ret = OB_SUCCESS; } } else { diff --git a/src/sql/engine/basic/ob_json_table_op.h b/src/sql/engine/basic/ob_json_table_op.h index 850129384d..defcca2c94 100644 --- a/src/sql/engine/basic/ob_json_table_op.h +++ b/src/sql/engine/basic/ob_json_table_op.h @@ -23,6 +23,7 @@ #include "sql/resolver/dml/ob_dml_stmt.h" #include "sql/engine/ob_exec_context.h" #include "sql/engine/expr/ob_expr.h" +#include "sql/engine/expr/ob_json_param_type.h" namespace oceanbase { diff --git a/src/sql/engine/expr/ob_expr_json_query.cpp b/src/sql/engine/expr/ob_expr_json_query.cpp index d64db7dc83..0014ad5c7b 100644 --- a/src/sql/engine/expr/ob_expr_json_query.cpp +++ b/src/sql/engine/expr/ob_expr_json_query.cpp @@ -178,7 +178,7 @@ int ObExprJsonQuery::eval_json_query(const ObExpr &expr, ObEvalCtx &ctx, ObDatum // parse pretty ascii scalars uint8_t pretty_type = OB_JSON_PRE_ASC_EMPTY; uint8_t ascii_type = OB_JSON_PRE_ASC_EMPTY; - uint8_t scalars_type = OB_JSON_SCALARS_IMPLICIT; + uint8_t scalars_type = JSN_QUERY_SCALARS_IMPLICIT; if (OB_SUCC(ret) && !is_null_result) { ret = get_clause_pre_asc_sca_opt(expr, ctx, is_cover_by_error, pretty_type, ascii_type, scalars_type); } @@ -239,12 +239,12 @@ int ObExprJsonQuery::eval_json_query(const ObExpr &expr, ObEvalCtx &ctx, ObDatum } // parse error option - uint8_t error_type = OB_JSON_ON_RESPONSE_IMPLICIT; + uint8_t error_type = JSN_QUERY_IMPLICIT; ObDatum *error_val = NULL; if (OB_SUCC(ret) && !is_null_result) { - ret = get_clause_opt(expr, ctx, 8, is_cover_by_error, error_type, OB_JSON_ON_RESPONSE_COUNT); + ret = get_clause_opt(expr, ctx, 8, is_cover_by_error, error_type, JSN_QUERY_RESPONSE_COUNT); } else if (is_cover_by_error) { // always get error option on error - int temp_ret = get_clause_opt(expr, ctx, 8, is_cover_by_error, error_type, OB_JSON_ON_RESPONSE_COUNT); + int temp_ret = get_clause_opt(expr, ctx, 8, is_cover_by_error, error_type, JSN_QUERY_RESPONSE_COUNT); if (temp_ret != OB_SUCCESS) { ret = temp_ret; LOG_WARN("failed to get error option.", K(temp_ret)); @@ -252,9 +252,9 @@ int ObExprJsonQuery::eval_json_query(const ObExpr &expr, ObEvalCtx &ctx, ObDatum } // parse wrapper - uint8_t wrapper_type = OB_WRAPPER_IMPLICIT; + uint8_t wrapper_type = JSN_QUERY_WRAPPER_IMPLICIT; if (OB_SUCC(ret)) { - ret = get_clause_opt(expr, ctx, 7, is_cover_by_error, wrapper_type, OB_WRAPPER_COUNT); + ret = get_clause_opt(expr, ctx, 7, is_cover_by_error, wrapper_type, JSN_QUERY_WRAPPER_COUNT); } if (OB_SUCC(ret) && j_path->get_last_node_type() > JPN_BEGIN_FUNC_FLAG @@ -264,18 +264,18 @@ int ObExprJsonQuery::eval_json_query(const ObExpr &expr, ObEvalCtx &ctx, ObDatum || j_path->get_last_node_type() == JPN_LENGTH || j_path->get_last_node_type() == JPN_TYPE || j_path->get_last_node_type() == JPN_SIZE ) - && (wrapper_type == OB_WITHOUT_WRAPPER || wrapper_type == OB_WITHOUT_ARRAY_WRAPPER - || wrapper_type == OB_WRAPPER_IMPLICIT)) { + && (wrapper_type == JSN_QUERY_WITHOUT_WRAPPER || wrapper_type == JSN_QUERY_WITHOUT_ARRAY_WRAPPER + || wrapper_type == JSN_QUERY_WRAPPER_IMPLICIT)) { is_cover_by_error = false; ret = OB_ERR_WITHOUT_ARR_WRAPPER; // result cannot be returned without array wrapper LOG_WARN("result cannot be returned without array wrapper.", K(ret), K(j_path->get_last_node_type()), K(wrapper_type)); } // mismatch // if mismatch_type == 3 from dot notation - uint8_t mismatch_type = OB_JSON_ON_MISMATCH_IMPLICIT; + uint8_t mismatch_type = JSN_QUERY_MISMATCH_IMPLICIT; uint8_t mismatch_val = 7; if (OB_SUCC(ret) && !is_null_result) { - if (OB_FAIL(get_clause_opt(expr, ctx, 10, is_cover_by_error, mismatch_type, OB_JSON_ON_MISMATCH_COUNT))) { + if (OB_FAIL(get_clause_opt(expr, ctx, 10, is_cover_by_error, mismatch_type, JSN_QUERY_MISMATCH_COUNT))) { LOG_WARN("failed to get mismatch option.", K(ret), K(mismatch_type)); } } @@ -304,7 +304,7 @@ int ObExprJsonQuery::eval_json_query(const ObExpr &expr, ObEvalCtx &ctx, ObDatum } LOG_WARN("json seek failed", K(json_datum->get_string()), K(ret)); } else if (hits.size() == 1) { - if (mismatch_type == OB_JSON_ON_MISMATCH_DOT) { + if (mismatch_type == JSN_QUERY_MISMATCH_DOT) { if (hits[0]->json_type() == ObJsonNodeType::J_NULL && hits[0]->is_real_json_null(hits[0]) && dst_type != ObJsonType) { is_null_result = true; } @@ -346,9 +346,9 @@ int ObExprJsonQuery::eval_json_query(const ObExpr &expr, ObEvalCtx &ctx, ObDatum } } else if (hits.size() == 0) { // parse empty option - uint8_t empty_type = OB_JSON_ON_RESPONSE_IMPLICIT; + uint8_t empty_type = JSN_QUERY_IMPLICIT; if (OB_SUCC(ret) && !is_null_result) { - ret = get_clause_opt(expr, ctx, 9, is_cover_by_error, empty_type, OB_JSON_ON_RESPONSE_COUNT); + ret = get_clause_opt(expr, ctx, 9, is_cover_by_error, empty_type, JSN_QUERY_RESPONSE_COUNT); } if (OB_SUCC(ret) && OB_FAIL(get_empty_option(hits, is_cover_by_error, empty_type, is_null_result, is_null_json_obj, is_null_json_array))) { LOG_WARN("get empty type", K(ret)); @@ -372,12 +372,12 @@ int ObExprJsonQuery::eval_json_query(const ObExpr &expr, ObEvalCtx &ctx, ObDatum LOG_WARN("json_query failed", K(ret)); } else if (is_null_result) { res.set_null(); - } else if (mismatch_type == OB_JSON_ON_MISMATCH_DOT && hits.size() == 1 && dst_type != ObJsonType) { + } else if (mismatch_type == JSN_QUERY_MISMATCH_DOT && hits.size() == 1 && dst_type != ObJsonType) { ObVector mismatch_val_tmp; ObVector mismatch_type_tmp; //OB_JSON_TYPE_IMPLICIT ObCollationType in_coll_type = expr.args_[0]->datum_meta_.cs_type_; ObCollationType dst_coll_type = expr.datum_meta_.cs_type_; - ret = ObExprJsonValue::cast_to_res(&temp_allocator, expr, ctx, hits[0], OB_JSON_ON_RESPONSE_NULL, error_val, + ret = ObExprJsonValue::cast_to_res(&temp_allocator, expr, ctx, hits[0], JSN_QUERY_NULL, error_val, accuracy, dst_type, in_coll_type, dst_coll_type, res, mismatch_val_tmp, mismatch_type_tmp, is_type_cast, ascii_type, is_truncate); } else { if (is_null_json_obj) { @@ -495,7 +495,7 @@ int ObExprJsonQuery::set_result(ObObjType dst_type, } ret = OB_OPERATE_OVERFLOW; LOG_USER_ERROR(OB_OPERATE_OVERFLOW, res_ptr, "json_query"); - if (!try_set_error_val(allocator, ctx, expr, res, ret, error_type, OB_JSON_ON_MISMATCH_IMPLICIT, dst_type)) { + if (!try_set_error_val(allocator, ctx, expr, res, ret, error_type, JSN_QUERY_MISMATCH_IMPLICIT, dst_type)) { LOG_WARN("set error val fail", K(ret)); } } @@ -573,7 +573,7 @@ int ObExprJsonQuery::get_clause_pre_asc_sca_opt(const ObExpr &expr, ObEvalCtx &c } // parse scalars if (OB_SUCC(ret)) { - ret = get_clause_opt(expr, ctx, 4, is_cover_by_error, scalars_type, OB_JSON_SCALARS_COUNT); + ret = get_clause_opt(expr, ctx, 4, is_cover_by_error, scalars_type, JSN_QUERY_SCALARS_COUNT); } return ret; } @@ -661,29 +661,29 @@ int ObExprJsonQuery::get_empty_option(ObJsonBaseVector &hits, bool &is_cover_by_ { INIT_SUCC(ret); switch (empty_type) { - case OB_JSON_ON_RESPONSE_IMPLICIT: { + case JSN_QUERY_IMPLICIT: { ret = OB_ERR_JSON_VALUE_NO_VALUE; LOG_USER_ERROR(OB_ERR_JSON_VALUE_NO_VALUE); LOG_WARN("json value seek result empty.", K(hits.size())); break; } - case OB_JSON_ON_RESPONSE_ERROR: { + case JSN_QUERY_ERROR: { is_cover_by_error = false; ret = OB_ERR_JSON_VALUE_NO_VALUE; LOG_USER_ERROR(OB_ERR_JSON_VALUE_NO_VALUE); LOG_WARN("json value seek result empty.", K(hits.size())); break; } - case OB_JSON_ON_RESPONSE_EMPTY_OBJECT: { + case JSN_QUERY_EMPTY_OBJECT: { is_null_json_obj = true; break; } - case OB_JSON_ON_RESPONSE_NULL: { + case JSN_QUERY_NULL: { is_null_result = true; break; } - case OB_JSON_ON_RESPONSE_EMPTY: - case OB_JSON_ON_RESPONSE_EMPTY_ARRAY: { + case JSN_QUERY_EMPTY: + case JSN_QUERY_EMPTY_ARRAY: { is_null_json_array = true; // set_json_array break; } @@ -697,27 +697,27 @@ int ObExprJsonQuery::get_single_obj_wrapper(uint8_t wrapper_type, int &use_wrapp { INIT_SUCC(ret); switch (wrapper_type) { - case OB_WITHOUT_WRAPPER: - case OB_WITHOUT_ARRAY_WRAPPER: - case OB_WRAPPER_IMPLICIT: { + case JSN_QUERY_WITHOUT_WRAPPER: + case JSN_QUERY_WITHOUT_ARRAY_WRAPPER: + case JSN_QUERY_WRAPPER_IMPLICIT: { if ((in_type != ObJsonNodeType::J_OBJECT && in_type != ObJsonNodeType::J_ARRAY - && scalars_type == OB_JSON_SCALARS_DISALLOW)) { + && scalars_type == JSN_QUERY_SCALARS_DISALLOW)) { ret = OB_ERR_WITHOUT_ARR_WRAPPER; // result cannot be returned without array wrapper LOG_USER_ERROR(OB_ERR_WITHOUT_ARR_WRAPPER); LOG_WARN("result cannot be returned without array wrapper.", K(ret)); } break; } - case OB_WITH_WRAPPER: - case OB_WITH_ARRAY_WRAPPER: - case OB_WITH_UNCONDITIONAL_WRAPPER: - case OB_WITH_UNCONDITIONAL_ARRAY_WRAPPER: { + case JSN_QUERY_WITH_WRAPPER: + case JSN_QUERY_WITH_ARRAY_WRAPPER: + case JSN_QUERY_WITH_UNCONDITIONAL_WRAPPER: + case JSN_QUERY_WITH_UNCONDITIONAL_ARRAY_WRAPPER: { use_wrapper = 1; break; } - case OB_WITH_CONDITIONAL_WRAPPER: - case OB_WITH_CONDITIONAL_ARRAY_WRAPPER: { - if (in_type != ObJsonNodeType::J_OBJECT && in_type != ObJsonNodeType::J_ARRAY && scalars_type == OB_JSON_SCALARS_DISALLOW ) { + case JSN_QUERY_WITH_CONDITIONAL_WRAPPER: + case JSN_QUERY_WITH_CONDITIONAL_ARRAY_WRAPPER: { + if (in_type != ObJsonNodeType::J_OBJECT && in_type != ObJsonNodeType::J_ARRAY && scalars_type == JSN_QUERY_SCALARS_DISALLOW ) { use_wrapper = 1; } break; @@ -732,23 +732,23 @@ int ObExprJsonQuery::get_multi_scalars_wrapper_type(uint8_t wrapper_type, int &u { INIT_SUCC(ret); switch (wrapper_type) { - case OB_WITHOUT_WRAPPER: - case OB_WITHOUT_ARRAY_WRAPPER: - case OB_WRAPPER_IMPLICIT: { + case JSN_QUERY_WITHOUT_WRAPPER: + case JSN_QUERY_WITHOUT_ARRAY_WRAPPER: + case JSN_QUERY_WRAPPER_IMPLICIT: { ret = OB_ERR_WITHOUT_ARR_WRAPPER; // result cannot be returned without array wrapper LOG_USER_ERROR(OB_ERR_WITHOUT_ARR_WRAPPER); LOG_WARN("result cannot be returned without array wrapper.", K(ret), K(hits.size())); break; } - case OB_WITH_WRAPPER: - case OB_WITH_ARRAY_WRAPPER: - case OB_WITH_UNCONDITIONAL_WRAPPER: - case OB_WITH_UNCONDITIONAL_ARRAY_WRAPPER: { + case JSN_QUERY_WITH_WRAPPER: + case JSN_QUERY_WITH_ARRAY_WRAPPER: + case JSN_QUERY_WITH_UNCONDITIONAL_WRAPPER: + case JSN_QUERY_WITH_UNCONDITIONAL_ARRAY_WRAPPER: { use_wrapper = 1; break; } - case OB_WITH_CONDITIONAL_WRAPPER: - case OB_WITH_CONDITIONAL_ARRAY_WRAPPER: { + case JSN_QUERY_WITH_CONDITIONAL_WRAPPER: + case JSN_QUERY_WITH_CONDITIONAL_ARRAY_WRAPPER: { use_wrapper = 1; break; } @@ -771,7 +771,7 @@ bool ObExprJsonQuery::try_set_error_val(common::ObIAllocator *allocator, bool mismatch_error = true; if (OB_FAIL(ret)) { - if (error_type == OB_JSON_ON_RESPONSE_EMPTY_ARRAY || error_type == OB_JSON_ON_RESPONSE_EMPTY) { + if (error_type == JSN_QUERY_EMPTY_ARRAY || error_type == JSN_QUERY_EMPTY) { ret = OB_SUCCESS; ObJsonArray j_arr_res(allocator); ObIJsonBase *jb_res = NULL; @@ -779,7 +779,7 @@ bool ObExprJsonQuery::try_set_error_val(common::ObIAllocator *allocator, if (OB_FAIL(set_result(dst_type, OB_MAX_TEXT_LENGTH, jb_res, allocator, ctx, expr, res, error_type, 0, 0))) { LOG_WARN("result set fail", K(ret)); } - } else if (error_type == OB_JSON_ON_RESPONSE_EMPTY_OBJECT) { + } else if (error_type == JSN_QUERY_EMPTY_OBJECT) { ret = OB_SUCCESS; ObJsonObject j_node_null(allocator); ObIJsonBase *jb_res = NULL; @@ -787,7 +787,7 @@ bool ObExprJsonQuery::try_set_error_val(common::ObIAllocator *allocator, if (OB_FAIL(set_result(dst_type, OB_MAX_TEXT_LENGTH, jb_res, allocator, ctx, expr, res, error_type, 0, 0))) { LOG_WARN("result set fail", K(ret)); } - } else if (error_type == OB_JSON_ON_RESPONSE_NULL || error_type == OB_JSON_ON_RESPONSE_IMPLICIT) { + } else if (error_type == JSN_QUERY_NULL || error_type == JSN_QUERY_IMPLICIT) { res.set_null(); ret = OB_SUCCESS; } diff --git a/src/sql/engine/expr/ob_expr_json_query.h b/src/sql/engine/expr/ob_expr_json_query.h index dc977770e4..a8fe9987e6 100644 --- a/src/sql/engine/expr/ob_expr_json_query.h +++ b/src/sql/engine/expr/ob_expr_json_query.h @@ -17,7 +17,7 @@ #include "sql/engine/expr/ob_expr_operator.h" #include "lib/json_type/ob_json_tree.h" #include "lib/json_type/ob_json_base.h" - +#include "ob_json_param_type.h" using namespace oceanbase::common; @@ -58,45 +58,7 @@ private: common::ObIAllocator *allocator, ObEvalCtx &ctx, const ObExpr &expr, ObDatum &res, uint8_t error_type, uint8_t ascii_type, uint8_t pretty_type = 0, uint8_t is_truncate = 0); - /* process empty or error */ - const static uint8_t OB_JSON_ON_RESPONSE_COUNT = 6; - const static uint8_t OB_JSON_ON_RESPONSE_ERROR = 0; - const static uint8_t OB_JSON_ON_RESPONSE_NULL = 1; - const static uint8_t OB_JSON_ON_RESPONSE_EMPTY = 2; - const static uint8_t OB_JSON_ON_RESPONSE_EMPTY_ARRAY = 3; - const static uint8_t OB_JSON_ON_RESPONSE_EMPTY_OBJECT = 4; - const static uint8_t OB_JSON_ON_RESPONSE_IMPLICIT = 5; - /* process on mismatch { error : 0, null : 1, implicit : 2 }*/ - const static uint8_t OB_JSON_ON_MISMATCH_COUNT = 4; - const static uint8_t OB_JSON_ON_MISMATCH_ERROR = 0; - const static uint8_t OB_JSON_ON_MISMATCH_NULL = 1; - const static uint8_t OB_JSON_ON_MISMATCH_IMPLICIT = 2; - const static uint8_t OB_JSON_ON_MISMATCH_DOT = 3; - - - /* process wrapper type */ - const static uint8_t OB_WRAPPER_COUNT = 9; - const static uint8_t OB_WITHOUT_WRAPPER = 0; - const static uint8_t OB_WITHOUT_ARRAY_WRAPPER = 1; - const static uint8_t OB_WITH_WRAPPER = 2; - const static uint8_t OB_WITH_ARRAY_WRAPPER = 3; - const static uint8_t OB_WITH_UNCONDITIONAL_WRAPPER = 4; - const static uint8_t OB_WITH_CONDITIONAL_WRAPPER = 5; - const static uint8_t OB_WITH_UNCONDITIONAL_ARRAY_WRAPPER = 6; - const static uint8_t OB_WITH_CONDITIONAL_ARRAY_WRAPPER = 7; - const static uint8_t OB_WRAPPER_IMPLICIT = 8; - - /* process on scalars { allow : 0, disallow : 1, implicit : 2 }*/ - const static uint8_t OB_JSON_SCALARS_COUNT = 3; - const static uint8_t OB_JSON_SCALARS_ALLOW = 0; - const static uint8_t OB_JSON_SCALARS_DISALLOW = 1; - const static uint8_t OB_JSON_SCALARS_IMPLICIT = 2; - - /* pretty ascii 0 : null 1 : yes */ - const static uint8_t OB_JSON_PRE_ASC_COUNT = 2; - const static uint8_t OB_JSON_PRE_ASC_EMPTY = 0; - const static uint8_t OB_JSON_PRE_ASC_SET = 1; static int get_clause_opt(const ObExpr &expr, ObEvalCtx &ctx, diff --git a/src/sql/engine/expr/ob_expr_json_value.cpp b/src/sql/engine/expr/ob_expr_json_value.cpp index 5cc45ab104..989a0406bf 100644 --- a/src/sql/engine/expr/ob_expr_json_value.cpp +++ b/src/sql/engine/expr/ob_expr_json_value.cpp @@ -70,12 +70,12 @@ int ObExprJsonValue::calc_result_typeN(ObExprResType& type, bool is_oracle_mode = lib::is_oracle_mode(); //type.set_json(); // json doc : 0 - ObObjType doc_type = types_stack[json_doc_id].get_type(); - if (types_stack[json_doc_id].get_type() == ObNullType) { + ObObjType doc_type = types_stack[JSN_VAL_DOC].get_type(); + if (types_stack[JSN_VAL_DOC].get_type() == ObNullType) { } else if (!ObJsonExprHelper::is_convertible_to_json(doc_type)) { if (lib::is_oracle_mode()) { ret = OB_ERR_INVALID_TYPE_FOR_OP; - LOG_USER_ERROR(OB_ERR_INVALID_TYPE_FOR_OP, ob_obj_type_str(types_stack[json_doc_id].get_type()), "JSON"); + LOG_USER_ERROR(OB_ERR_INVALID_TYPE_FOR_OP, ob_obj_type_str(types_stack[JSN_VAL_DOC].get_type()), "JSON"); } else { ret = OB_ERR_INVALID_TYPE_FOR_JSON; LOG_USER_ERROR(OB_ERR_INVALID_TYPE_FOR_JSON, 1, "json_value"); @@ -83,50 +83,50 @@ int ObExprJsonValue::calc_result_typeN(ObExprResType& type, } } else if (ob_is_string_type(doc_type)) { if (is_oracle_mode) { - if (types_stack[json_doc_id].get_collation_type() == CS_TYPE_BINARY) { - types_stack[json_doc_id].set_calc_collation_type(CS_TYPE_BINARY); - } else if (types_stack[json_doc_id].get_charset_type() != CHARSET_UTF8MB4) { - types_stack[json_doc_id].set_calc_collation_type(CS_TYPE_UTF8MB4_BIN); + if (types_stack[JSN_VAL_DOC].get_collation_type() == CS_TYPE_BINARY) { + types_stack[JSN_VAL_DOC].set_calc_collation_type(CS_TYPE_BINARY); + } else if (types_stack[JSN_VAL_DOC].get_charset_type() != CHARSET_UTF8MB4) { + types_stack[JSN_VAL_DOC].set_calc_collation_type(CS_TYPE_UTF8MB4_BIN); } } else { - if (types_stack[json_doc_id].get_collation_type() == CS_TYPE_BINARY) { + if (types_stack[JSN_VAL_DOC].get_collation_type() == CS_TYPE_BINARY) { // unsuport string type with binary charset ret = OB_ERR_INVALID_JSON_CHARSET; LOG_WARN("Unsupport for string type with binary charset input.", K(ret), K(doc_type)); - } else if (types_stack[json_doc_id].get_charset_type() != CHARSET_UTF8MB4) { - types_stack[json_doc_id].set_calc_collation_type(CS_TYPE_UTF8MB4_BIN); + } else if (types_stack[JSN_VAL_DOC].get_charset_type() != CHARSET_UTF8MB4) { + types_stack[JSN_VAL_DOC].set_calc_collation_type(CS_TYPE_UTF8MB4_BIN); } } } else if (doc_type == ObJsonType) { // do nothing } else { - types_stack[json_doc_id].set_calc_type(ObLongTextType); - types_stack[json_doc_id].set_calc_collation_type(CS_TYPE_UTF8MB4_BIN); + types_stack[JSN_VAL_DOC].set_calc_type(ObLongTextType); + types_stack[JSN_VAL_DOC].set_calc_collation_type(CS_TYPE_UTF8MB4_BIN); } // json path : 1 if (OB_SUCC(ret)) { - if (types_stack[json_path_id].get_type() == ObNullType) { + if (types_stack[JSN_VAL_PATH].get_type() == ObNullType) { if (lib::is_oracle_mode()) { ret = OB_ERR_PATH_EXPRESSION_NOT_LITERAL; LOG_USER_ERROR(OB_ERR_PATH_EXPRESSION_NOT_LITERAL); } // do nothing - } else if (ob_is_string_type(types_stack[json_path_id].get_type())) { - if (types_stack[json_path_id].get_charset_type() != CHARSET_UTF8MB4) { - types_stack[json_path_id].set_calc_collation_type(CS_TYPE_UTF8MB4_BIN); + } else if (ob_is_string_type(types_stack[JSN_VAL_PATH].get_type())) { + if (types_stack[JSN_VAL_PATH].get_charset_type() != CHARSET_UTF8MB4) { + types_stack[JSN_VAL_PATH].set_calc_collation_type(CS_TYPE_UTF8MB4_BIN); } } else { - types_stack[json_path_id].set_calc_type(ObLongTextType); - types_stack[json_path_id].set_calc_collation_type(CS_TYPE_UTF8MB4_BIN); + types_stack[JSN_VAL_PATH].set_calc_type(ObLongTextType); + types_stack[JSN_VAL_PATH].set_calc_collation_type(CS_TYPE_UTF8MB4_BIN); } } // returning type : 2 ObExprResType dst_type; if (OB_SUCC(ret)) { - if (OB_FAIL(get_cast_type(types_stack[ret_type_id], dst_type, type_ctx))) { + if (OB_FAIL(get_cast_type(types_stack[JSN_VAL_RET], dst_type, type_ctx))) { LOG_WARN("get cast dest type failed", K(ret)); - } else if (OB_FAIL(set_dest_type(types_stack[json_doc_id], type, dst_type, type_ctx))) { + } else if (OB_FAIL(set_dest_type(types_stack[JSN_VAL_DOC], type, dst_type, type_ctx))) { LOG_WARN("set dest type failed", K(ret)); } else { type.set_calc_collation_type(type.get_collation_type()); @@ -143,63 +143,63 @@ int ObExprJsonValue::calc_result_typeN(ObExprResType& type, // empty : 4, 5, 6 if (OB_SUCC(ret)) { ObExprResType temp_type; - if (types_stack[empty_type_id].get_type() == ObNullType) { + if (types_stack[JSN_VAL_EMPTY].get_type() == ObNullType) { ret = OB_ERR_UNEXPECTED; - LOG_WARN(" param type is unexpected", K(types_stack[empty_type_id].get_type())); - } else if (types_stack[empty_type_id].get_type() != ObIntType) { - types_stack[empty_type_id].set_calc_type(ObIntType); - } else if (types_stack[empty_val_id].get_type() == ObNullType) { + LOG_WARN(" param type is unexpected", K(types_stack[JSN_VAL_EMPTY].get_type())); + } else if (types_stack[JSN_VAL_EMPTY].get_type() != ObIntType) { + types_stack[JSN_VAL_EMPTY].set_calc_type(ObIntType); + } else if (types_stack[JSN_VAL_EMPTY_DEF].get_type() == ObNullType) { // do nothing - } else if (OB_FAIL(set_dest_type(types_stack[empty_val_id], temp_type, dst_type, type_ctx))) { + } else if (OB_FAIL(set_dest_type(types_stack[JSN_VAL_EMPTY_DEF], temp_type, dst_type, type_ctx))) { LOG_WARN("set dest type failed", K(ret)); } else { - types_stack[empty_val_id].set_calc_type(temp_type.get_type()); - types_stack[empty_val_id].set_calc_collation_type(temp_type.get_collation_type()); - types_stack[empty_val_id].set_calc_collation_level(temp_type.get_collation_level()); - types_stack[empty_val_id].set_calc_accuracy(temp_type.get_accuracy()); + types_stack[JSN_VAL_EMPTY_DEF].set_calc_type(temp_type.get_type()); + types_stack[JSN_VAL_EMPTY_DEF].set_calc_collation_type(temp_type.get_collation_type()); + types_stack[JSN_VAL_EMPTY_DEF].set_calc_collation_level(temp_type.get_collation_level()); + types_stack[JSN_VAL_EMPTY_DEF].set_calc_accuracy(temp_type.get_accuracy()); } - if (types_stack[empty_val_pre_id].get_type() == ObNullType) { + if (types_stack[JSN_VAL_EMPTY_DEF_PRE].get_type() == ObNullType) { // do nothing } else { - types_stack[empty_val_pre_id].set_calc_type(types_stack[empty_val_pre_id].get_type()); - types_stack[empty_val_pre_id].set_calc_collation_type(types_stack[empty_val_pre_id].get_collation_type()); - types_stack[empty_val_pre_id].set_calc_collation_level(types_stack[empty_val_pre_id].get_collation_level()); - types_stack[empty_val_pre_id].set_calc_accuracy(types_stack[empty_val_pre_id].get_accuracy()); + types_stack[JSN_VAL_EMPTY_DEF_PRE].set_calc_type(types_stack[JSN_VAL_EMPTY_DEF_PRE].get_type()); + types_stack[JSN_VAL_EMPTY_DEF_PRE].set_calc_collation_type(types_stack[JSN_VAL_EMPTY_DEF_PRE].get_collation_type()); + types_stack[JSN_VAL_EMPTY_DEF_PRE].set_calc_collation_level(types_stack[JSN_VAL_EMPTY_DEF_PRE].get_collation_level()); + types_stack[JSN_VAL_EMPTY_DEF_PRE].set_calc_accuracy(types_stack[JSN_VAL_EMPTY_DEF_PRE].get_accuracy()); } } // error : 7, 8,9 if (OB_SUCC(ret)) { ObExprResType temp_type; - if (types_stack[error_type_id].get_type() == ObNullType) { + if (types_stack[JSN_VAL_ERROR].get_type() == ObNullType) { ret = OB_ERR_UNEXPECTED; - LOG_WARN(" param type is unexpected", K(types_stack[error_type_id].get_type())); - } else if (types_stack[error_type_id].get_type() != ObIntType) { - types_stack[error_type_id].set_calc_type(ObIntType); - } else if (types_stack[error_val_id].get_type() == ObNullType) { + LOG_WARN(" param type is unexpected", K(types_stack[JSN_VAL_ERROR].get_type())); + } else if (types_stack[JSN_VAL_ERROR].get_type() != ObIntType) { + types_stack[JSN_VAL_ERROR].set_calc_type(ObIntType); + } else if (types_stack[JSN_VAL_ERROR_DEF].get_type() == ObNullType) { // do nothing - } else if (OB_FAIL(set_dest_type(types_stack[error_val_id], temp_type, dst_type, type_ctx))) { + } else if (OB_FAIL(set_dest_type(types_stack[JSN_VAL_ERROR_DEF], temp_type, dst_type, type_ctx))) { LOG_WARN("set dest type failed", K(ret)); } else { - types_stack[error_val_id].set_calc_type(temp_type.get_type()); - types_stack[error_val_id].set_calc_collation_type(temp_type.get_collation_type()); - types_stack[error_val_id].set_calc_collation_level(temp_type.get_collation_level()); - types_stack[error_val_id].set_calc_accuracy(temp_type.get_accuracy()); + types_stack[JSN_VAL_ERROR_DEF].set_calc_type(temp_type.get_type()); + types_stack[JSN_VAL_ERROR_DEF].set_calc_collation_type(temp_type.get_collation_type()); + types_stack[JSN_VAL_ERROR_DEF].set_calc_collation_level(temp_type.get_collation_level()); + types_stack[JSN_VAL_ERROR_DEF].set_calc_accuracy(temp_type.get_accuracy()); } - if (types_stack[error_val_pre_id].get_type() == ObNullType) { + if (types_stack[JSN_VAL_ERROR_DEF_PRE].get_type() == ObNullType) { // do nothing } else { - types_stack[error_val_pre_id].set_calc_type(types_stack[error_val_pre_id].get_type()); - types_stack[error_val_pre_id].set_calc_collation_type(types_stack[error_val_pre_id].get_collation_type()); - types_stack[error_val_pre_id].set_calc_collation_level(types_stack[error_val_pre_id].get_collation_level()); - types_stack[error_val_pre_id].set_calc_accuracy(types_stack[error_val_pre_id].get_accuracy()); + types_stack[JSN_VAL_ERROR_DEF_PRE].set_calc_type(types_stack[JSN_VAL_ERROR_DEF_PRE].get_type()); + types_stack[JSN_VAL_ERROR_DEF_PRE].set_calc_collation_type(types_stack[JSN_VAL_ERROR_DEF_PRE].get_collation_type()); + types_stack[JSN_VAL_ERROR_DEF_PRE].set_calc_collation_level(types_stack[JSN_VAL_ERROR_DEF_PRE].get_collation_level()); + types_stack[JSN_VAL_ERROR_DEF_PRE].set_calc_accuracy(types_stack[JSN_VAL_ERROR_DEF_PRE].get_accuracy()); } } // mismatch : 10, if (OB_SUCC(ret)) { - for (size_t i = opt_mismatch_id; OB_SUCC(ret) && i < param_num; i++) { + for (size_t i = JSN_VAL_MISMATCH; OB_SUCC(ret) && i < param_num; i++) { if (types_stack[i].get_type() == ObNullType) { ret = OB_ERR_UNEXPECTED; LOG_WARN(" param type is unexpected", K(types_stack[i].get_type()), K(ret), K(i)); @@ -289,7 +289,7 @@ int ObExprJsonValue::eval_json_value(const ObExpr &expr, ObEvalCtx &ctx, ObDatum // parse empty option ObDatum *empty_datum = NULL; ObObjType empty_val_type; - uint8_t empty_type = OB_JSON_ON_RESPONSE_IMPLICIT; + uint8_t empty_type = JSN_VALUE_IMPLICIT; if (OB_SUCC(ret) && !is_null_result) { ret = get_on_empty_or_error(expr, ctx, 5, is_cover_by_error, accuracy, empty_type, &empty_datum, dst_type, empty_val_type); } @@ -297,7 +297,7 @@ int ObExprJsonValue::eval_json_value(const ObExpr &expr, ObEvalCtx &ctx, ObDatum // parse error option ObDatum *error_val = NULL; ObObjType error_val_type; - uint8_t error_type = OB_JSON_ON_RESPONSE_IMPLICIT; + uint8_t error_type = JSN_VALUE_IMPLICIT; if (OB_SUCC(ret) && !is_null_result) { ret = get_on_empty_or_error(expr, ctx, 8, is_cover_by_error, accuracy, error_type, &error_val, dst_type, error_val_type); } else if (is_cover_by_error) { // always get error option for return default value on error @@ -348,7 +348,7 @@ int ObExprJsonValue::eval_json_value(const ObExpr &expr, ObEvalCtx &ctx, ObDatum ObVector mismatch_val; ObVector mismatch_type; //OB_JSON_TYPE_IMPLICIT if (OB_SUCC(ret) && !is_null_result) { - ret = get_on_mismatch(expr, ctx, opt_mismatch_id, is_cover_by_error, accuracy, mismatch_val, mismatch_type); + ret = get_on_mismatch(expr, ctx, JSN_VAL_MISMATCH, is_cover_by_error, accuracy, mismatch_val, mismatch_type); if (ret != OB_SUCCESS || mismatch_type.size() == 0 || mismatch_val.size() == 0) { LOG_WARN("failed to get mismatch option.", K(ret), K(mismatch_type.size()), K(mismatch_val.size())); } @@ -382,7 +382,7 @@ int ObExprJsonValue::eval_ora_json_value(const ObExpr &expr, ObEvalCtx &ctx, ObD { INIT_SUCC(ret); ObDatum *json_datum = NULL; - ObExpr *json_arg = expr.args_[json_path_id]; + ObExpr *json_arg = expr.args_[JSN_VAL_PATH]; ObObjType type = json_arg->datum_meta_.type_; bool is_cover_by_error = true; bool is_null_result = false; @@ -435,12 +435,12 @@ int ObExprJsonValue::eval_ora_json_value(const ObExpr &expr, ObEvalCtx &ctx, ObD // parse ascii uint8_t ascii_type = OB_JSON_ON_ASCII_IMPLICIT; if (OB_SUCC(ret) && !is_null_result) { - ret = get_on_ascii(expr, ctx, opt_ascii_id, is_cover_by_error, ascii_type); + ret = get_on_ascii(expr, ctx, JSN_VAL_ASCII, is_cover_by_error, ascii_type); } uint8_t is_truncate = 0; if (OB_SUCC(ret) && !is_null_result) { - if (OB_FAIL(get_on_truncate(expr, ctx, opt_truncate_id, is_cover_by_error, is_truncate))) { + if (OB_FAIL(get_on_truncate(expr, ctx, JSN_VAL_TRUNC, is_cover_by_error, is_truncate))) { LOG_WARN("eval truncate option error", K(ret)); } } @@ -465,7 +465,7 @@ int ObExprJsonValue::eval_ora_json_value(const ObExpr &expr, ObEvalCtx &ctx, ObD } // parse json doc - json_arg = expr.args_[json_doc_id]; + json_arg = expr.args_[JSN_VAL_DOC]; type = json_arg->datum_meta_.type_; ObCollationType cs_type = json_arg->datum_meta_.cs_type_; ObJsonInType j_in_type; @@ -504,15 +504,15 @@ int ObExprJsonValue::eval_ora_json_value(const ObExpr &expr, ObEvalCtx &ctx, ObD // error default val type ObObjType empty_val_type; ObDatum *empty_datum = NULL; - uint8_t empty_type = OB_JSON_ON_RESPONSE_IMPLICIT; + uint8_t empty_type = JSN_VALUE_IMPLICIT; if (OB_SUCC(ret) && !is_null_result) { - ret = get_on_empty_or_error(expr, ctx, empty_type_id, is_cover_by_error, accuracy, empty_type, &empty_datum, dst_type, empty_val_type); + ret = get_on_empty_or_error(expr, ctx, JSN_VAL_EMPTY, is_cover_by_error, accuracy, empty_type, &empty_datum, dst_type, empty_val_type); } // parse error option ObDatum *error_val = NULL; - uint8_t error_type = OB_JSON_ON_RESPONSE_IMPLICIT; - json_arg = expr.args_[error_type_id + 2]; + uint8_t error_type = JSN_VALUE_IMPLICIT; + json_arg = expr.args_[JSN_VAL_ERROR + 2]; ObObjType val_type = json_arg->datum_meta_.type_; if ((OB_SUCC(ret) && !is_null_result) || is_cover_by_error) { int temp_ret = OB_SUCCESS; @@ -549,12 +549,12 @@ int ObExprJsonValue::eval_ora_json_value(const ObExpr &expr, ObEvalCtx &ctx, ObD ObVector mismatch_val; ObVector mismatch_type; //OB_JSON_TYPE_IMPLICIT if (OB_SUCC(ret) && !is_null_result) { - ret = get_on_mismatch(expr, ctx, opt_mismatch_id, is_cover_by_error, accuracy, mismatch_val, mismatch_type); + ret = get_on_mismatch(expr, ctx, JSN_VAL_MISMATCH, is_cover_by_error, accuracy, mismatch_val, mismatch_type); if (ret != OB_SUCCESS || mismatch_type.size() == 0 || mismatch_val.size() == 0) { LOG_WARN("failed to get mismatch option.", K(ret), K(mismatch_type.size()), K(mismatch_val.size())); } } else if (is_type_cast) { - int tmp_ret = get_on_mismatch(expr, ctx, opt_mismatch_id, is_cover_by_error, accuracy, mismatch_val, mismatch_type); + int tmp_ret = get_on_mismatch(expr, ctx, JSN_VAL_MISMATCH, is_cover_by_error, accuracy, mismatch_val, mismatch_type); if (tmp_ret != OB_SUCCESS || mismatch_type.size() == 0 || mismatch_val.size() == 0) { LOG_WARN("failed to get mismatch option.", K(ret), K(mismatch_type.size()), K(mismatch_val.size())); } @@ -747,7 +747,8 @@ int ObExprJsonValue::doc_do_seek(ObJsonBaseVector &hits, bool &is_null_result, O } else if (hits.size() == 0) { if (OB_SUCC(ret)) { switch (empty_type) { - case OB_JSON_ON_RESPONSE_ERROR: { + case JSN_VALUE_ERROR +: { is_cover_by_error = false; if (lib::is_oracle_mode()) { ret = OB_ERR_JSON_VALUE_NO_VALUE; @@ -759,15 +760,15 @@ int ObExprJsonValue::doc_do_seek(ObJsonBaseVector &hits, bool &is_null_result, O LOG_WARN("json value seek result empty.", K(hits.size())); break; } - case OB_JSON_ON_RESPONSE_DEFAULT: { + case JSN_VALUE_DEFAULT: { return_val = empty_datum; break; } - case OB_JSON_ON_RESPONSE_NULL: { + case JSN_VALUE_NULL: { is_null_result = true; break; } - case OB_JSON_ON_RESPONSE_IMPLICIT: { + case JSN_VALUE_IMPLICIT: { if (lib::is_oracle_mode()) { ret = OB_ERR_JSON_VALUE_NO_VALUE; LOG_USER_ERROR(OB_ERR_JSON_VALUE_NO_VALUE); @@ -786,18 +787,18 @@ int ObExprJsonValue::doc_do_seek(ObJsonBaseVector &hits, bool &is_null_result, O // return val decide by error option if (lib::is_mysql_mode()) { switch (error_type) { - case OB_JSON_ON_RESPONSE_ERROR: { + case JSN_VALUE_ERROR: { ret = OB_ERR_MULTIPLE_JSON_VALUES; LOG_USER_ERROR(OB_ERR_MULTIPLE_JSON_VALUES, "json_value"); LOG_WARN("json value seek result more than one.", K(hits.size())); break; } - case OB_JSON_ON_RESPONSE_DEFAULT: { + case JSN_VALUE_DEFAULT: { return_val = error_datum; break; } - case OB_JSON_ON_RESPONSE_NULL: - case OB_JSON_ON_RESPONSE_IMPLICIT: { + case JSN_VALUE_NULL: + case JSN_VALUE_IMPLICIT: { is_null_result = true; break; } @@ -1761,24 +1762,24 @@ bool ObExprJsonValue::try_set_error_val(const ObExpr &expr, if (OB_FAIL(ret)) { int temp_ret = 0; - if (lib::is_oracle_mode() && error_type == OB_JSON_ON_RESPONSE_IMPLICIT) { - temp_ret = get_on_empty_or_error(expr, ctx, error_type_id, is_cover_by_error, accuracy, error_type, &error_val, dst_type, default_val_type); + if (lib::is_oracle_mode() && error_type == JSN_VALUE_IMPLICIT) { + temp_ret = get_on_empty_or_error(expr, ctx, JSN_VAL_ERROR, is_cover_by_error, accuracy, error_type, &error_val, dst_type, default_val_type); } if (temp_ret != OB_SUCCESS && !is_cover_by_error) { ret = temp_ret; LOG_WARN("failed to get error option.", K(temp_ret)); } else { - if (error_type == OB_JSON_ON_RESPONSE_DEFAULT) { + if (error_type == JSN_VALUE_DEFAULT) { set_default_val = true; - } else if (error_type == OB_JSON_ON_RESPONSE_NULL || error_type == OB_JSON_ON_RESPONSE_IMPLICIT) { + } else if (error_type == JSN_VALUE_NULL || error_type == JSN_VALUE_IMPLICIT) { is_null_res = true; } if (lib::is_oracle_mode() && is_type_cast == 1) { for(size_t i = 0; i < mismatch_val.size(); i++) { // 目前不支持UDT,因此只考虑第一个参数中的 error 和 null。 - if (mismatch_val[i] == OB_JSON_ON_MISMATCH_ERROR) { + if (mismatch_val[i] == JSN_QUERY_MISMATCH_ERROR) { mismatch_error = false; - } else if (mismatch_val[i] == OB_JSON_ON_MISMATCH_NULL || mismatch_val[i] == OB_JSON_ON_MISMATCH_IGNORE) { + } else if (mismatch_val[i] == JSN_VALUE_MISMATCH_NULL || mismatch_val[i] == JSN_VALUE_MISMATCH_IGNORE) { is_null_res = true; } } @@ -1837,8 +1838,8 @@ int ObExprJsonValue::get_on_mismatch(const ObExpr &expr, LOG_WARN("input type error", K(val_type), K(ret)); } else { int64_t option_type = json_datum->get_int(); - if (option_type >= OB_JSON_ON_MISMATCH_ERROR && - option_type <= OB_JSON_ON_MISMATCH_IMPLICIT) { + if (option_type >= JSN_QUERY_MISMATCH_ERROR && + option_type <= JSN_VALUE_MISMATCH_IMPLICIT) { pos ++; if (OB_FAIL(val.push_back(static_cast(option_type)))) { LOG_WARN("mismtach add fail", K(ret)); @@ -1928,8 +1929,8 @@ int ObExprJsonValue::get_on_empty_or_error(const ObExpr &expr, LOG_WARN("input type error", K(val_type)); } else { int64_t option_type = json_datum->get_int(); - if (option_type < OB_JSON_ON_RESPONSE_ERROR || - option_type > OB_JSON_ON_RESPONSE_IMPLICIT) { + if (option_type < JSN_VALUE_ERROR || + option_type > JSN_VALUE_IMPLICIT) { ret = OB_ERR_UNEXPECTED; LOG_WARN("input option type error", K(option_type)); } else { @@ -1938,7 +1939,7 @@ int ObExprJsonValue::get_on_empty_or_error(const ObExpr &expr, } json_arg = expr.args_[index + 2]; val_type = json_arg->datum_meta_.type_; - if (OB_SUCC(ret) && index != error_type_id) { + if (OB_SUCC(ret) && index != JSN_VAL_ERROR) { if (lib::is_oracle_mode() && (val_type == ObCharType || val_type == ObNumberType || val_type == ObDecimalIntType)) { if (OB_FAIL(json_arg->eval(ctx, json_datum))) { @@ -1971,7 +1972,7 @@ int ObExprJsonValue::get_on_empty_or_error(const ObExpr &expr, is_cover_by_error = false; LOG_WARN("eval json arg failed", K(ret)); } else if (val_type == ObNullType || json_datum->is_null()) { - } else if ((lib::is_mysql_mode() || index == empty_type_id) && OB_FAIL(check_default_val_accuracy(accuracy, val_type, json_datum))) { + } else if ((lib::is_mysql_mode() || index == JSN_VAL_EMPTY) && OB_FAIL(check_default_val_accuracy(accuracy, val_type, json_datum))) { is_cover_by_error = false; } else { *default_value = json_datum; diff --git a/src/sql/engine/expr/ob_expr_json_value.h b/src/sql/engine/expr/ob_expr_json_value.h index 94cf761101..3368e92922 100644 --- a/src/sql/engine/expr/ob_expr_json_value.h +++ b/src/sql/engine/expr/ob_expr_json_value.h @@ -17,6 +17,7 @@ #include "sql/engine/expr/ob_expr_operator.h" #include "lib/json_type/ob_json_tree.h" #include "lib/json_type/ob_json_base.h" +#include "ob_json_param_type.h" using namespace oceanbase::common; @@ -163,19 +164,6 @@ private: const static uint8_t OB_JSON_ON_ASCII_IMPLICIT = 0; const static uint8_t OB_JSON_ON_ASCII_USE = 1; - /* process empty or error */ - const static uint8_t OB_JSON_ON_RESPONSE_ERROR = 0; - const static uint8_t OB_JSON_ON_RESPONSE_NULL = 1; - const static uint8_t OB_JSON_ON_RESPONSE_DEFAULT = 2; - const static uint8_t OB_JSON_ON_RESPONSE_IMPLICIT = 3; - - /* process on mismatch { error : 0, null : 1, ignore : 2 }*/ - const static uint8_t OB_JSON_ON_MISMATCH_ERROR = 0; - const static uint8_t OB_JSON_ON_MISMATCH_NULL = 1; - const static uint8_t OB_JSON_ON_MISMATCH_IGNORE = 2; - const static uint8_t OB_JSON_ON_MISMATCH_IMPLICIT = 3; - - /* process mismatch type { MISSING : 4 (1), EXTRA : 5 (2), TYPE : 6 (4), EMPTY : 7 (0)} make diff with mismatch type */ const static uint8_t OB_JSON_TYPE_MISSING_DATA = 4; const static uint8_t OB_JSON_TYPE_EXTRA_DATA = 5; @@ -183,19 +171,6 @@ private: const static uint8_t OB_JSON_TYPE_IMPLICIT = 7; const static uint8_t OB_JSON_TYPE_DOT = 8; - const static uint8_t json_doc_id = 0; - const static uint8_t json_path_id = 1; - const static uint8_t ret_type_id = 2; - const static uint8_t opt_truncate_id = 3; - const static uint8_t opt_ascii_id = 4; - const static uint8_t empty_type_id = 5; - const static uint8_t empty_val_id = 6; - const static uint8_t empty_val_pre_id = 7; - const static uint8_t error_type_id = 8; - const static uint8_t error_val_id = 9; - const static uint8_t error_val_pre_id = 10; - const static uint8_t opt_mismatch_id = 11; - static int get_on_empty_or_error(const ObExpr &expr, ObEvalCtx &ctx, uint8_t index, diff --git a/src/sql/engine/expr/ob_json_param_type.h b/src/sql/engine/expr/ob_json_param_type.h new file mode 100644 index 0000000000..9e9256fb6d --- /dev/null +++ b/src/sql/engine/expr/ob_json_param_type.h @@ -0,0 +1,136 @@ +/** + * Copyright (c) 2021 OceanBase + * OceanBase CE is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan PubL v2. + * You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + */ + +#ifndef OCEANBASE_SRC_SQL_ENGINE_EXPR_OB_JSON_PARAM_TYPE_H +#define OCEANBASE_SRC_SQL_ENGINE_EXPR_OB_JSON_PARAM_TYPE_H +namespace oceanbase +{ +namespace sql +{ + +// json_query +/* process empty or error */ +typedef enum JsnQueryType { + JSN_QUERY_ERROR, // 0 + JSN_QUERY_NULL, // 1 + JSN_QUERY_EMPTY, // 2 + JSN_QUERY_EMPTY_ARRAY, // 3 + JSN_QUERY_EMPTY_OBJECT, // 4 + JSN_QUERY_IMPLICIT, // 5 + JSN_QUERY_RESPONSE_COUNT, // 6 +} JsnQueryType; + +/* process on mismatch { error : 0, null : 1, implicit : 2 }*/ +typedef enum JsnQueryMisMatch { + JSN_QUERY_MISMATCH_ERROR, // 0 + JSN_QUERY_MISMATCH_NULL, // 1 + JSN_QUERY_MISMATCH_IMPLICIT, // 2 + JSN_QUERY_MISMATCH_DOT, // 3 + JSN_QUERY_MISMATCH_COUNT, // 4 +} JsnQueryMisMatch; + +/* process wrapper type */ +typedef enum JsnQueryWrapper { + JSN_QUERY_WITHOUT_WRAPPER, // 0 + JSN_QUERY_WITHOUT_ARRAY_WRAPPER, // 1 + JSN_QUERY_WITH_WRAPPER, // 2 + JSN_QUERY_WITH_ARRAY_WRAPPER, // 3 + JSN_QUERY_WITH_UNCONDITIONAL_WRAPPER, // 4 + JSN_QUERY_WITH_CONDITIONAL_WRAPPER, // 5 + JSN_QUERY_WITH_UNCONDITIONAL_ARRAY_WRAPPER, // 6 + JSN_QUERY_WITH_CONDITIONAL_ARRAY_WRAPPER, // 7 + JSN_QUERY_WRAPPER_IMPLICIT , // 8 + JSN_QUERY_WRAPPER_COUNT, // 9 +} JsnQueryWrapper; + +/* process on scalars { allow : 0, disallow : 1, implicit : 2 }*/ +typedef enum JsnQueryScalar { + JSN_QUERY_SCALARS_ALLOW, // 0 + JSN_QUERY_SCALARS_DISALLOW, // 1 + JSN_QUERY_SCALARS_IMPLICIT, // 2 + JSN_QUERY_SCALARS_COUNT // 3 +} JsnQueryScalar; + +/* pretty ascii 0 : null 1 : yes */ +typedef enum JsnQueryAsc { + OB_JSON_PRE_ASC_EMPTY, // 0 + OB_JSON_PRE_ASC_SET, // 1 + OB_JSON_PRE_ASC_COUNT // 2 +} JsnQueryAsc; + +// json query clause position +typedef enum JsnQueryClause { + JSN_QUE_DOC, // 0 + JSN_QUE_PATH, // 1 + JSN_QUE_RET, // 2 + JSN_QUE_TRUNC, // 3 + JSN_QUE_SCALAR, // 4 + JSN_QUE_PRETTY, // 5 + JSN_QUE_ASCII, // 6 + JSN_QUE_WRAPPER, // 7 + JSN_QUE_ERROR, // 8 + JSN_QUE_EMPTY, // 9 + JSN_QUE_MISMATCH, //10 +} JsnQueryClause; + +typedef enum JsnQueryOpt { + JSN_QUE_TRUNC_OPT, // 0 + JSN_QUE_SCALAR_OPT, // 1 + JSN_QUE_PRETTY_OPT, // 2 + JSN_QUE_ASCII_OPT, // 3 + JSN_QUE_WRAPPER_OPT, // 4 + JSN_QUE_ERROR_OPT, // 5 + JSN_QUE_EMPTY_OPT, // 6 + JSN_QUE_MISMATCH_OPT, // 7 +} JsnQueryOpt; + +// json_value +/* process empty or error */ +typedef enum JsnValueType { + JSN_VALUE_ERROR, // 0 + JSN_VALUE_NULL, // 1 + JSN_VALUE_DEFAULT, // 2 + JSN_VALUE_IMPLICIT, // 3 +} JsnValueType; +/* process mismatch type { MISSING : 4 (1), EXTRA : 5 (2), TYPE : 6 (4), EMPTY : 7 (0)} make diff with mismatch type */ +typedef enum JsnValueClause { + JSN_VAL_DOC, // 0 + JSN_VAL_PATH, // 1 + JSN_VAL_RET, // 2 + JSN_VAL_TRUNC, // 3 + JSN_VAL_ASCII, // 4 + JSN_VAL_EMPTY, // 5 + JSN_VAL_EMPTY_DEF, // 6 + JSN_VAL_EMPTY_DEF_PRE, // 7 + JSN_VAL_ERROR, // 8 + JSN_VAL_ERROR_DEF, // 9 + JSN_VAL_ERROR_DEF_PRE, // 10 + JSN_VAL_MISMATCH // 11 +} JsnValueClause; + +typedef enum JsnValueMisMatch { + JSN_VALUE_MISMATCH_ERROR, // 0 + JSN_VALUE_MISMATCH_NULL, // 1 + JSN_VALUE_MISMATCH_IGNORE, // 2 + JSN_VALUE_MISMATCH_IMPLICIT // 3 +} JsnValueMisMatch; + +typedef enum JsnValueOpt { + JSN_VAL_TRUNC_OPT, // 0 + JSN_VAL_ASCII_OPT, // 1 + JSN_VAL_EMPTY_OPT, // 2 + JSN_VAL_ERROR_OPT, // 3 +} JsnValueOpt; + +} // namespace sql +} // namespace oceanbase +#endif /* OCEANBASE_SRC_SQL_ENGINE_EXPR_OB_JSON_PARAM_TYPE_H */ \ No newline at end of file diff --git a/src/sql/ob_sql_utils.cpp b/src/sql/ob_sql_utils.cpp index 1e0ba7510e..d46a09a6f7 100644 --- a/src/sql/ob_sql_utils.cpp +++ b/src/sql/ob_sql_utils.cpp @@ -5452,3 +5452,23 @@ int ObSQLUtils::print_identifier_require_quotes(ObCollationType collation_type, } return ret; } + +bool ObSQLUtils::check_json_expr(ObItemType type) +{ + bool res = false; + switch(type) { + case T_FUN_SYS_JSON_ARRAY: + case T_FUN_SYS_JSON_OBJECT: + case T_FUN_ORA_JSON_ARRAYAGG: + case T_FUN_ORA_JSON_OBJECTAGG: + case T_FUN_SYS_JSON_QUERY: + case T_FUN_SYS_JSON_MERGE_PATCH: { + res = true; + break; + } + default : { + break; + } + } + return res; +} diff --git a/src/sql/ob_sql_utils.h b/src/sql/ob_sql_utils.h index 860e555c99..00aaa36c0c 100644 --- a/src/sql/ob_sql_utils.h +++ b/src/sql/ob_sql_utils.h @@ -670,6 +670,7 @@ public: share::schema::ObObjectType &obj_type, uint64_t &schema_version); static bool check_need_disconnect_parser_err(const int ret_code); + static bool check_json_expr(ObItemType type); static int print_identifier_require_quotes(ObCollationType collation_type, const ObString &ident, diff --git a/src/sql/resolver/dml/ob_dml_resolver.cpp b/src/sql/resolver/dml/ob_dml_resolver.cpp index 6af74d6f36..dd1b002dfa 100755 --- a/src/sql/resolver/dml/ob_dml_resolver.cpp +++ b/src/sql/resolver/dml/ob_dml_resolver.cpp @@ -9788,6 +9788,8 @@ int ObDMLResolver::resolve_generated_table_column_item(const TableItem &table_it } } else if (ob_is_geometry(select_expr->get_data_type()) && !select_expr->is_column_ref_expr()) { col_expr->set_srs_id(OB_DEFAULT_COLUMN_SRS_ID); + } else if (ObSQLUtils::check_json_expr(select_expr->get_expr_type())) { + with_is_json_constraint = true; } is_break = true; diff --git a/src/sql/resolver/dml/ob_select_resolver.cpp b/src/sql/resolver/dml/ob_select_resolver.cpp index 3b75e0af9f..e85727e203 100644 --- a/src/sql/resolver/dml/ob_select_resolver.cpp +++ b/src/sql/resolver/dml/ob_select_resolver.cpp @@ -34,6 +34,7 @@ #include "sql/rewrite/ob_transform_utils.h" #include "common/ob_smart_call.h" #include "sql/engine/expr/ob_expr_regexp_context.h" +#include "sql/engine/expr/ob_json_param_type.h" namespace oceanbase { using namespace common; @@ -2098,6 +2099,9 @@ int ObSelectResolver::resolve_field_list(const ParseNode &node) ObString string_name(ptr_name); select_item.alias_name_ = string_name; select_item.is_real_alias_ = true; + } else if (T_FUN_SYS_JSON_QUERY == sel_expr->get_expr_type() + && OB_FAIL(add_alias_from_dot_notation(sel_expr, select_item))) { // deal dot notation without alias + LOG_WARN("fail to resolve alias in dot notation", K(ret)); } else { if (params_.is_prepare_protocol_ || !session_info_->get_local_ob_enable_plan_cache() @@ -2235,6 +2239,44 @@ inline bool ObSelectResolver::is_colum_without_alias(ParseNode *project_node) { return bret; } +int ObSelectResolver::add_alias_from_dot_notation(ObRawExpr *sel_expr, SelectItem& select_item) +{ + INIT_SUCC(ret); + int64_t pos = -1; + int64_t len = 0; + ObString path_str; + ObConstRawExpr* path_expr = NULL; + // whether is dot notation + if (OB_NOT_NULL(sel_expr->get_param_expr(JSN_QUE_MISMATCH)) + && JSN_QUERY_MISMATCH_DOT == static_cast(sel_expr->get_param_expr(JSN_QUE_MISMATCH))->get_value().get_int()) { + if (!select_item.alias_name_.empty()) { + select_item.is_real_alias_ = true; + } else if (OB_NOT_NULL(sel_expr->get_param_expr(JSN_QUE_PATH)) + && T_CHAR == sel_expr->get_param_expr(JSN_QUE_PATH)->get_expr_type()) { + path_expr = static_cast(sel_expr->get_param_expr(JSN_QUE_PATH)); + path_str = path_expr->get_value().get_string(); + pos = path_str.length() - 1; + len = 0; + char *buf = NULL; + while (pos >= 0 && path_str[pos] != '.') { + pos --; + } + len = path_str.length() - (pos + 1); + if (pos < 0) { + } else if (OB_ISNULL(buf = static_cast(allocator_->alloc(len)))) { + ret = common::OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("failed to allocate memory", K(ret), K(buf)); + } else { + MEMCPY(buf, path_str.ptr() + (pos + 1), len); + ObString alias_name(len, buf); + select_item.alias_name_ = alias_name; + select_item.is_real_alias_ = true; + } + } + } + return ret; +} + int ObSelectResolver::expand_target_list( const TableItem &table_item, ObIArray &target_list) { diff --git a/src/sql/resolver/dml/ob_select_resolver.h b/src/sql/resolver/dml/ob_select_resolver.h index d96a0ba234..6bcbe3ac67 100644 --- a/src/sql/resolver/dml/ob_select_resolver.h +++ b/src/sql/resolver/dml/ob_select_resolver.h @@ -348,6 +348,8 @@ private: int recursive_check_auto_gen_column_names(ObSelectStmt *select_stmt, bool in_outer_stmt); int recursive_update_column_name(ObSelectStmt *select_stmt, ObRawExpr *expr); int check_listagg_aggr_param_valid(ObAggFunRawExpr *aggr_expr); + + int add_alias_from_dot_notation(ObRawExpr *sel_expr, SelectItem& select_item); protected: // data members /*these member is only for with clause*/ 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 c20a7a401c..dbdad2880b 100644 --- a/src/sql/resolver/expr/ob_raw_expr_resolver_impl.cpp +++ b/src/sql/resolver/expr/ob_raw_expr_resolver_impl.cpp @@ -2233,6 +2233,9 @@ int ObRawExprResolverImpl::resolve_left_node_of_obj_access_idents(const ParseNod || T_FUN_SYS_XMLPARSE == left_node.type_ || T_FUN_ORA_XMLAGG == left_node.type_) { OZ (resolve_func_node_of_obj_access_idents(left_node, q_name)); + } else if (left_node.type_ == T_LINK_NODE && left_node.value_ == 3) { + ret = OB_ERR_PARSER_SYNTAX; // array not in object access ref : array[1] + LOG_WARN("input invalid arguments", K(ret)); } else { ret = OB_ERR_UNEXPECTED; LOG_WARN("left node of obj access ref node not T_IDENT/T_QUESTIONMARK/T_FUN_SYS", K(ret), K(left_node.type_)); @@ -5701,7 +5704,7 @@ int ObRawExprResolverImpl::process_json_query_node(const ParseNode *node, ObRawE ObSysFunRawExpr *func_expr = NULL; if (OB_SUCC(ret)) { num = node->num_child_; - ctx_.expr_factory_.create_raw_expr(T_FUN_SYS, func_expr); + ctx_.expr_factory_.create_raw_expr(T_FUN_SYS_JSON_QUERY, func_expr); CK(OB_NOT_NULL(func_expr)); OX(func_expr->set_func_name(ObString::make_string("json_query"))); }