fix:when case compare json type result not correct

This commit is contained in:
obdev
2023-07-11 14:53:55 +00:00
committed by ob-robot
parent ebe04c05a9
commit a77abb22ee
5 changed files with 69 additions and 31 deletions

View File

@ -1842,7 +1842,10 @@ int JtScanNode::get_next_row(ObIJsonBase* in, JtScanCtx* ctx, bool& is_null_valu
total_ = 1;
is_null_value = is_null_result_ = true;
curr_ = iter_ = nullptr;
if (col_info_.parent_id_ == common::OB_INVALID_ID) { ret = OB_ITER_END; }
if (col_info_.parent_id_ == common::OB_INVALID_ID
|| (ctx->jt_op_->get_root_param() == in && ctx->jt_op_->get_root_entry()->reg_column_count() == 0)) {
ret = OB_ITER_END;
}
} else if (hit.size() == 1) {
iter_ = curr_ = hit[0];
is_null_value = is_null_result_ = false;

View File

@ -416,6 +416,8 @@ public:
ObJsonNull* get_js_null() { return &j_null_; }
ObJsonArray* get_js_array() { return &j_arr_; }
ObJsonObject* get_js_object() { return &j_obj_; }
ObIJsonBase* get_root_param() { return in_; }
JtScanNode* get_root_entry() { return jt_root_; }
TO_STRING_KV(K_(is_inited),
K_(col_count));

View File

@ -3005,6 +3005,11 @@ static int common_string_json(const ObExpr &expr,
ObJsonNull j_null;
ObJsonNode *j_tree = NULL;
bool is_null_res = false;
bool is_scalar = (j_text.length()
&& ((j_text[0] == '\'' && j_text[j_text.length() - 1] == '\'')
|| (j_text[0] == '\"' && j_text[j_text.length() - 1] == '\"')));
bool is_oracle = lib::is_oracle_mode();
bool relaxed_json = lib::is_oracle_mode() && !(CM_IS_STRICT_JSON(expr.extra_));
uint32_t parse_flag = ObJsonParser::JSN_STRICT_FLAG;
@ -3012,28 +3017,46 @@ static int common_string_json(const ObExpr &expr,
ADD_FLAG_IF_NEED(relaxed_json, parse_flag, ObJsonParser::JSN_RELAXED_FLAG);
ADD_FLAG_IF_NEED(lib::is_oracle_mode(), parse_flag, ObJsonParser::JSN_UNIQUE_FLAG);
if (lib::is_mysql_mode() && in_cs_type == CS_TYPE_BINARY) {
bool is_convert_jstr_type = (in_type == ObTinyTextType
|| in_type == ObTextType
|| in_type == ObMediumTextType
|| in_type == ObLongTextType);
if (!is_oracle && in_cs_type == CS_TYPE_BINARY) {
j_base = &j_opaque;
} else if (lib::is_oracle_mode() && CM_IS_IMPLICIT_CAST(expr.extra_) && OB_ISNULL(j_text.ptr())) {
} else if (is_oracle && CM_IS_IMPLICIT_CAST(expr.extra_) && OB_ISNULL(j_text.ptr())) {
res_datum.set_null();
is_null_res = true;
} else if (is_enumset_to_str || (CM_IS_IMPLICIT_CAST(expr.extra_)
&& !CM_IS_COLUMN_CONVERT(expr.extra_) && !CM_IS_JSON_VALUE(expr.extra_)
&& ob_is_string_type(in_type))) {
} else if (!is_oracle
&& (is_enumset_to_str
|| (CM_IS_IMPLICIT_CAST(expr.extra_)
&& !CM_IS_COLUMN_CONVERT(expr.extra_)
&& !CM_IS_JSON_VALUE(expr.extra_)
&& is_convert_jstr_type))) {
// consistent with mysql: TINYTEXT, TEXT, MEDIUMTEXT, and LONGTEXT. We want to treat them like strings
j_base = &j_string;
} else if (lib::is_oracle_mode() && (OB_ISNULL(j_text.ptr()) || j_text.length() == 0)) {
} else if (is_oracle && (OB_ISNULL(j_text.ptr()) || j_text.length() == 0)) {
j_base = &j_null;
} else if (OB_FAIL(ObJsonParser::get_tree(&temp_allocator, j_text, j_tree, parse_flag))) {
if (lib::is_mysql_mode() && CM_IS_IMPLICIT_CAST(expr.extra_) && !CM_IS_COLUMN_CONVERT(expr.extra_)) {
if (!is_oracle && CM_IS_IMPLICIT_CAST(expr.extra_) && !CM_IS_COLUMN_CONVERT(expr.extra_)) {
ret = OB_SUCCESS;
j_base = &j_string;
} else {
LOG_WARN("fail to parse string as json tree", K(ret), K(in_type), K(in_str));
LOG_DEBUG("fail to parse string as json tree", K(ret), K(in_type), K(in_str));
if (CM_IS_COLUMN_CONVERT(expr.extra_)) {
if (lib::is_mysql_mode()) {
if (!is_oracle) {
ret = OB_ERR_INVALID_JSON_TEXT;
LOG_USER_ERROR(OB_ERR_INVALID_JSON_TEXT);
} else if (is_scalar) {
ObString tmp;
if (OB_FAIL(ob_write_string(temp_allocator, j_text, tmp))) {
LOG_DEBUG("fail to write buffer", K(ret), K(in_type), K(j_text));
} else {
tmp.ptr()[0] = tmp.ptr()[tmp.length() - 1] = '"';
new (&j_string)ObJsonString(tmp.ptr(), tmp.length());
j_base = &j_string;
}
}
} else {
ret = OB_ERR_INVALID_JSON_TEXT_IN_PARAM;

View File

@ -1497,14 +1497,17 @@ int ObJsonExprHelper::parse_res_type(ObExprResType& type1,
const ObObj &param = res_type.get_param();
if (param.get_int() == 0) {
result_type.set_type(type1.get_type());
result_type.set_collation_type(type1.get_collation_type());
result_type.set_accuracy(type1.get_accuracy());
ObObjType obj_type = type1.get_type();
int16_t length_semantics = ((dst_type.is_string_type())
? dst_type.get_length_semantics()
: (OB_NOT_NULL(type_ctx.get_session())
? type_ctx.get_session()->get_actual_nls_length_semantics() : LS_BYTE));
// result_type.set_type(type1.get_type());
// result_type.set_collation_type(type1.get_collation_type());
// result_type.set_accuracy(type1.get_accuracy());
// ObObjType obj_type = type1.get_type();
ObObjType obj_type = ObJsonType;
result_type.set_type(ObJsonType);
result_type.set_collation_type(CS_TYPE_UTF8MB4_BIN);
int16_t length_semantics = (OB_NOT_NULL(type_ctx.get_session())
? type_ctx.get_session()->get_actual_nls_length_semantics() : LS_BYTE);
result_type.set_length((ObAccuracy::DDL_DEFAULT_ACCURACY[ObJsonType]).get_length());
result_type.set_collation_level(CS_LEVEL_IMPLICIT);
if (obj_type == ObVarcharType) {
@ -1732,6 +1735,9 @@ int ObJsonExprHelper::parse_asc_option(ObExprResType& asc_type,
} else {
type1.set_calc_length(length);
res_type.set_length(length * 10);
if (res_type.is_lob()) {
res_type.set_length((ObAccuracy::DDL_DEFAULT_ACCURACY[ObLongTextType]).get_length());
}
}
}
@ -1749,8 +1755,8 @@ int ObJsonExprHelper::character2_ascii_string(common::ObIAllocator *allocator,
int64_t buf_len = result.length() * ObCharset::MAX_MB_LEN * 2;
int32_t length = 0;
if ((OB_NOT_NULL(allocator) && OB_ISNULL(buf = static_cast<char*>(allocator->alloc(buf_len + reserve_len))))
|| (OB_ISNULL(buf = static_cast<char*>(expr.get_str_res_mem(ctx, buf_len + reserve_len))))) {
if ((OB_NOT_NULL(allocator) && OB_ISNULL(buf = static_cast<char*>(allocator->alloc(buf_len + reserve_len + 1))))
|| (OB_ISNULL(allocator) && OB_ISNULL(buf = static_cast<char*>(expr.get_str_res_mem(ctx, buf_len + reserve_len + 1))))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_WARN("fail to allocate memory", K(ret), K(buf_len), K(result.length()));
} else if (OB_FAIL(ObJsonExprHelper::calc_asciistr_in_expr(result,
@ -1759,6 +1765,7 @@ int ObJsonExprHelper::character2_ascii_string(common::ObIAllocator *allocator,
buf, buf_len, length))) {
LOG_WARN("fail to calc unistr", K(ret));
} else {
buf[length] = 0;
result.assign_ptr(buf, length);
}
return ret;

View File

@ -215,12 +215,15 @@ int ObExprJsonMergePatch::eval_ora_json_merge_patch(const ObExpr &expr, ObEvalCt
// some constraint check
ObObjType dst_type;
int32_t dst_len; // bugfix:
int32_t dst_len;
if (OB_FAIL(ret)) {
} else if (return_type == 0) {
dst_type = expr.args_[0]->datum_meta_.type_;
const ObAccuracy &default_accuracy = ObAccuracy::DDL_DEFAULT_ACCURACY[dst_type];
dst_len = dst_type == ObVarcharType ? OB_MAX_ORACLE_VARCHAR_LENGTH : default_accuracy.get_length();
dst_type = ObJsonType;
const ObAccuracy &default_accuracy = ObAccuracy::DDL_DEFAULT_ACCURACY[ObJsonType];
dst_len = default_accuracy.get_length();
// dst_type = expr.args_[0]->datum_meta_.type_;
// const ObAccuracy &default_accuracy = ObAccuracy::DDL_DEFAULT_ACCURACY[dst_type];
// dst_len = dst_type == ObVarcharType ? OB_MAX_ORACLE_VARCHAR_LENGTH : default_accuracy.get_length();
} else if (OB_FAIL(ObJsonExprHelper::eval_and_check_res_type(return_type, dst_type, dst_len))) {
LOG_WARN("fail to check returning type", K(ret));
} else if ((expr.datum_meta_.cs_type_ == CS_TYPE_BINARY || dst_type == ObJsonType) && (opt_array[OPT_PRETTY_ID] > 0 || opt_array[OPT_ASCII_ID] > 0)) {
@ -308,13 +311,13 @@ int ObExprJsonMergePatch::eval_ora_json_merge_patch(const ObExpr &expr, ObEvalCt
}
ObString tmp_val(jbuf.length(), jbuf.ptr());
if (OB_SUCC(ret)
&& is_asc
&& !is_res_blob // clob varchar
&& OB_FAIL(ObJsonExprHelper::character2_ascii_string(&temp_allocator, expr, ctx, tmp_val, 1))) {
LOG_WARN("fail to transform string 2 ascii character", K(ret));
if (OB_SUCC(ret) && is_asc && !is_res_blob /* clob varchar */ ) {
if (OB_FAIL(ObJsonExprHelper::character2_ascii_string(&temp_allocator, expr, ctx, tmp_val, 1))) {
LOG_WARN("fail to transform string 2 ascii character", K(ret));
}
}
if (is_trunc && dst_type != ObLongTextType) {
if (tmp_val.length() > dst_len) {
if (ob_is_string_type(dst_type)) {
@ -372,8 +375,8 @@ int ObExprJsonMergePatch::eval_ora_json_merge_patch(const ObExpr &expr, ObEvalCt
LOG_WARN("failed to lltostr", K(ret), K(dst_len));
}
if (!err_type) {
ret = OB_OPERATE_OVERFLOW;
LOG_USER_ERROR(OB_OPERATE_OVERFLOW, res_ptr, "json_mergepatch");
ret = OB_ERR_VALUE_EXCEEDED_MAX;
LOG_USER_ERROR(OB_ERR_VALUE_EXCEEDED_MAX, static_cast<int>(length), static_cast<int>(dst_len));
} else {
ret = OB_SUCCESS;
res.set_null();