[Json] json patch from 3.2.2 branch since 2021.12

This commit is contained in:
xj0
2022-02-16 17:34:14 +08:00
committed by LINxiansheng
parent 63edf11b9a
commit bb573a7cd4
47 changed files with 947 additions and 682 deletions

View File

@ -4812,7 +4812,6 @@ CAST_FUNC_NAME(json, int)
int64_t out_val = 0;
ObObjType out_type = expr.datum_meta_.type_;
const uint64_t extra = CM_UNSET_STRING_INTEGER_TRUNC(CM_SET_WARN_ON_FAIL(expr.extra_));
common::ObArenaAllocator &temp_allocator = ctx.get_reset_tmp_alloc();
ObString j_text = child_res->get_string();
ObJsonBin j_bin(j_text.ptr(), j_text.length());
ObIJsonBase *j_base = &j_bin;
@ -4839,7 +4838,6 @@ CAST_FUNC_NAME(json, uint)
int warning = OB_SUCCESS;
uint64_t out_val = 0;
ObObjType out_type = expr.datum_meta_.type_;
common::ObArenaAllocator &temp_allocator = ctx.get_reset_tmp_alloc();
ObString j_text = child_res->get_string();
ObJsonBin j_bin(j_text.ptr(), j_text.length());
ObIJsonBase *j_base = &j_bin;
@ -4868,7 +4866,6 @@ CAST_FUNC_NAME(json, double)
int warning = OB_SUCCESS;
double out_val = 0.0;
ObObjType out_type = expr.datum_meta_.type_;
common::ObArenaAllocator &temp_allocator = ctx.get_reset_tmp_alloc();
ObString j_text = child_res->get_string();
ObJsonBin j_bin(j_text.ptr(), j_text.length());
ObIJsonBase *j_base = &j_bin;
@ -4896,7 +4893,6 @@ CAST_FUNC_NAME(json, float)
double tmp_val = 0.0;
float out_val = 0.0;
ObObjType out_type = expr.datum_meta_.type_;
common::ObArenaAllocator &temp_allocator = ctx.get_reset_tmp_alloc();
ObString j_text = child_res->get_string();
ObJsonBin j_bin(j_text.ptr(), j_text.length());
ObIJsonBase *j_base = &j_bin;
@ -4933,7 +4929,7 @@ CAST_FUNC_NAME(json, number)
if (OB_FAIL(j_bin.reset_iter())) {
LOG_WARN("failed to reset json bin iter", K(ret), K(j_text));
} else if (CAST_FAIL(j_base->to_number(out_val))) {
} else if (CAST_FAIL(j_base->to_number(&temp_allocator, out_val))) {
LOG_WARN("fail to cast json to number type", K(ret), K(j_text));
ret = OB_ERR_INVALID_JSON_VALUE_FOR_CAST;
LOG_USER_ERROR(OB_ERR_INVALID_JSON_VALUE_FOR_CAST);
@ -4953,7 +4949,6 @@ CAST_FUNC_NAME(json, datetime)
int warning = OB_SUCCESS;
int64_t out_val;
ObObjType out_type = expr.datum_meta_.type_;
common::ObArenaAllocator &temp_allocator = ctx.get_reset_tmp_alloc();
ObString j_text = child_res->get_string();
ObJsonBin j_bin(j_text.ptr(), j_text.length());
ObIJsonBase *j_base = &j_bin;
@ -4978,7 +4973,6 @@ CAST_FUNC_NAME(json, date)
int warning = OB_SUCCESS;
int32_t out_val;
ObObjType out_type = expr.datum_meta_.type_;
common::ObArenaAllocator &temp_allocator = ctx.get_reset_tmp_alloc();
ObString j_text = child_res->get_string();
ObJsonBin j_bin(j_text.ptr(), j_text.length());
ObIJsonBase *j_base = &j_bin;
@ -5003,7 +4997,6 @@ CAST_FUNC_NAME(json, time)
int warning = OB_SUCCESS;
int64_t out_val;
ObObjType out_type = expr.datum_meta_.type_;
common::ObArenaAllocator &temp_allocator = ctx.get_reset_tmp_alloc();
ObString j_text = child_res->get_string();
ObJsonBin j_bin(j_text.ptr(), j_text.length());
ObIJsonBase *j_base = &j_bin;
@ -5029,7 +5022,6 @@ CAST_FUNC_NAME(json, year)
uint8_t out_val = 0;
int64_t int_val;
ObObjType out_type = expr.datum_meta_.type_;
common::ObArenaAllocator &temp_allocator = ctx.get_reset_tmp_alloc();
ObString j_text = child_res->get_string();
ObJsonBin j_bin(j_text.ptr(), j_text.length());
ObIJsonBase *j_base = &j_bin;
@ -5098,16 +5090,16 @@ CAST_FUNC_NAME(json, bit)
EVAL_STRING_ARG()
{
int warning = OB_SUCCESS;
ObString j_text = child_res->get_string();
ObJsonBin j_bin(j_text.ptr(), j_text.length());
ObString j_bin_str = child_res->get_string();
ObJsonBin j_bin(j_bin_str.ptr(), j_bin_str.length());
ObIJsonBase *j_base = &j_bin;
uint64_t out_val;
ObObjType out_type = expr.datum_meta_.type_;
if (OB_FAIL(j_bin.reset_iter())) {
LOG_WARN("failed to reset json bin iter", K(ret), K(j_text));
LOG_WARN("failed to reset json bin iter", K(ret), K(j_bin_str));
} else if (CAST_FAIL(j_base->to_bit(out_val))) {
LOG_WARN("fail to cast json as bit", K(ret), K(j_text));
LOG_WARN("fail to cast json as bit", K(ret), K(j_bin_str));
ret = OB_ERR_INVALID_JSON_VALUE_FOR_CAST;
LOG_USER_ERROR(OB_ERR_INVALID_JSON_VALUE_FOR_CAST);
} else {
@ -5124,7 +5116,6 @@ CAST_FUNC_NAME(json, otimestamp)
int warning = OB_SUCCESS;
int64_t datetime_val;
ObObjType out_type = expr.datum_meta_.type_;
common::ObArenaAllocator &temp_allocator = ctx.get_reset_tmp_alloc();
ObString j_text = child_res->get_string();
ObJsonBin j_bin(j_text.ptr(), j_text.length());
ObIJsonBase *j_base = &j_bin;

View File

@ -13,6 +13,7 @@
#define USING_LOG_PREFIX SQL_ENG
#include "sql/engine/expr/ob_expr_bool.h"
#include "sql/engine/expr/ob_expr_json_func_helper.h"
namespace oceanbase {
namespace sql {
@ -32,9 +33,12 @@ int ObExprBool::calc_result_type1(ObExprResType& type, ObExprResType& type1, ObE
if (!lib::is_mysql_mode()) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("bool expr is only for mysql mode", K(ret));
} else if (ob_is_numeric_type(type1.get_type())) {
} else if (ob_is_numeric_type(type1.get_type()) || ob_is_json(type1.get_type())) {
type1.set_calc_meta(type1.get_obj_meta());
type1.set_calc_accuracy(type1.get_accuracy());
if (ob_is_json(type1.get_type())) {
type1.set_calc_type(type1.get_type());
}
} else {
const ObObjType& calc_type = ObDoubleType;
type1.set_calc_type(calc_type);
@ -95,8 +99,18 @@ CHECK_IS_TRUE_FUNC_NAME(other_type)
{
EVAL_ARG()
{
int32_t res = child_datum->get_number().is_zero() ? 0 : 1;
res_datum.set_int32(res);
if (ob_is_json(expr.args_[0]->datum_meta_.type_)) {
int cmp_result = 0;
if (OB_FAIL(ObJsonExprHelper::is_json_zero(child_datum->get_string(), cmp_result))) {
LOG_WARN("failed: compare json", K(ret));
} else {
res_datum.set_int32(cmp_result);
}
} else {
int32_t res = child_datum->get_number().is_zero() ? 0 : 1;
res_datum.set_int32(res);
}
}
return ret;
}

View File

@ -162,6 +162,9 @@ int ObExprColumnConv::convert_skip_null_check(ObObj& result, const ObObj& obj, c
const ObObj* res_obj = NULL;
cast_ctx.expect_obj_collation_ = collation_type;
cast_ctx.dest_collation_ = collation_type;
ObAccuracy tmp_accuracy = accuracy;
cast_ctx.res_accuracy_ = &tmp_accuracy;
if (OB_UNLIKELY(ob_is_enum_or_set_type(type))) {
ObExpectType expect_type;
expect_type.set_type(type);

View File

@ -107,16 +107,8 @@ int ObExprJsonArray::calc_resultN(ObObj &result,
if (OB_FAIL(j_base->get_raw_binary(raw_bin, allocator))) {
LOG_WARN("failed: get json raw binary", K(ret));
} else {
uint64_t length = raw_bin.length();
char *buf = reinterpret_cast<char *>(allocator->alloc(length));
if (OB_ISNULL(buf)) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_WARN("fail to alloc memory for json array result", K(ret), K(length));
} else {
MEMMOVE(buf, raw_bin.ptr(), length);
result.set_collation_type(CS_TYPE_UTF8MB4_BIN);
result.set_string(ObJsonType, buf, length);
}
result.set_collation_type(CS_TYPE_UTF8MB4_BIN);
result.set_string(ObJsonType, raw_bin.ptr(), raw_bin.length());
}
}
}

View File

@ -167,16 +167,8 @@ int ObExprJsonArrayAppend::calc_resultN(ObObj &result, const ObObj *objs,
} else if (OB_FAIL(j_base->get_raw_binary(raw_bin, allocator))) {
LOG_WARN("fail to get json raw binary", K(ret));
} else {
uint64_t length = raw_bin.length();
char *buf = reinterpret_cast<char *>(allocator->alloc(length));
if (OB_ISNULL(buf)) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_WARN("fail to alloc memory for json array append result", K(ret), K(length));
} else {
MEMCPY(buf, raw_bin.ptr(), length);
result.set_collation_type(CS_TYPE_UTF8MB4_BIN);
result.set_string(ObJsonType, buf, length);
}
result.set_collation_type(CS_TYPE_UTF8MB4_BIN);
result.set_string(ObJsonType, raw_bin.ptr(), raw_bin.length());
}
}

View File

@ -147,16 +147,8 @@ int ObExprJsonArrayInsert::calc_resultN(ObObj &result, const ObObj *objs, int64_
} else if (OB_FAIL(j_base->get_raw_binary(raw_bin, allocator))) {
LOG_WARN("fail to get json raw binary", K(ret));
} else {
uint64_t length = raw_bin.length();
char *buf = reinterpret_cast<char *>(allocator->alloc(length));
if (OB_ISNULL(buf)) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_WARN("fail to alloc memory for json array insert result", K(ret), K(length));
} else {
MEMCPY(buf, raw_bin.ptr(), length);
result.set_collation_type(CS_TYPE_UTF8MB4_BIN);
result.set_string(ObJsonType, buf, length);
}
result.set_collation_type(CS_TYPE_UTF8MB4_BIN);
result.set_string(ObJsonType, raw_bin.ptr(), raw_bin.length());
}
}

View File

@ -224,13 +224,13 @@ int ObExprJsonContains::json_contains_object(ObIJsonBase* json_target, ObIJsonBa
} else {
JsonObjectIterator iter_t = json_target->object_iterator();
JsonObjectIterator iter_c = json_candidate->object_iterator();
while (!iter_t.empty() && !iter_c.empty() && OB_SUCC(ret)) {
while (!iter_t.end() && !iter_c.end() && OB_SUCC(ret)) {
// find the same key
ObString key1;
if (OB_FAIL(iter_c.get_key(key1))) {
LOG_WARN("fail to get key from iterator", K(ret));
} else {
while (!iter_t.empty() && OB_SUCC(ret)) {
while (!iter_t.end() && OB_SUCC(ret)) {
ObString key2;
if (OB_FAIL(iter_t.get_key(key2))) {
LOG_WARN("fail to get key from iterator", K(ret));
@ -240,7 +240,7 @@ int ObExprJsonContains::json_contains_object(ObIJsonBase* json_target, ObIJsonBa
iter_t.next();
}
}
if (iter_t.empty()) {
if (iter_t.end()) {
*result = false;
break;
}
@ -278,7 +278,8 @@ int ObExprJsonContains::json_contains_array(ObIJsonBase* json_target,
if (json_candidate->json_type() != ObJsonNodeType::J_ARRAY) {
// convert to array
ObIJsonBase *jb_node = NULL;
if (ObJsonBaseFactory::transform(allocator, json_candidate, ObJsonInType::JSON_TREE, jb_node)) {
if (OB_FAIL(ObJsonBaseFactory::transform(allocator, json_candidate,
ObJsonInType::JSON_TREE, jb_node))) {
LOG_WARN("fail to transform to tree", K(ret), K(*json_candidate));
} else {
ObJsonNode *j_node = static_cast<ObJsonNode *>(jb_node);

View File

@ -107,9 +107,9 @@ int ObExprJsonExtract::calc_resultN(ObObj &result, const ObObj *objs,
objs[0].get_collation_type()))) {
LOG_WARN("fail to ensure collation", K(ret), K(objs[0].get_type()), K(objs[0].get_collation_type()));
} else {
ObString j_text = objs[0].get_string();
ObString j_str = objs[0].get_string();
ObJsonInType j_in_type = ObJsonExprHelper::get_json_internal_type(objs[0].get_type());
if (OB_FAIL(ObJsonBaseFactory::get_json_base(allocator, j_text, j_in_type, j_in_type, j_base))) {
if (OB_FAIL(ObJsonBaseFactory::get_json_base(allocator, j_str, j_in_type, j_in_type, j_base))) {
LOG_WARN("fail to get json base", K(ret), K(j_in_type));
ret = OB_ERR_INVALID_JSON_TEXT;
}
@ -163,9 +163,10 @@ int ObExprJsonExtract::calc_resultN(ObObj &result, const ObObj *objs,
ObJsonNode *j_node = NULL;
ObIJsonBase *jb_node = NULL;
for (int32_t i = 0; OB_SUCC(ret) && i < hit_size; i++) {
if (ObJsonBaseFactory::transform(allocator, hit[i], ObJsonInType::JSON_TREE, jb_node)) { // to tree
if (OB_FAIL(ObJsonBaseFactory::transform(allocator, hit[i],
ObJsonInType::JSON_TREE, jb_node))) { // to tree
LOG_WARN("fail to transform to tree", K(ret), K(i), K(*(hit[i])));
} else {
} else { // is_tree, need deep copy, cause array append will change parent of value.
j_node = static_cast<ObJsonNode *>(jb_node);
if (OB_FAIL(jb_res->array_append(j_node->clone(allocator)))) {
LOG_WARN("result array append failed", K(ret), K(i), K(*j_node));
@ -174,21 +175,14 @@ int ObExprJsonExtract::calc_resultN(ObObj &result, const ObObj *objs,
}
}
ObString raw_str;
ObString raw_bin;
if (OB_FAIL(ret)) {
LOG_WARN("json extarct get results failed", K(ret));
} else if (OB_FAIL(jb_res->get_raw_binary(raw_str, allocator))) {
} else if (OB_FAIL(jb_res->get_raw_binary(raw_bin, allocator))) {
LOG_WARN("json extarct get result binary failed", K(ret));
} else {
char *buf = static_cast<char*>(allocator->alloc(raw_str.length()));
if (OB_UNLIKELY(buf == NULL)){
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_WARN("failed:allocate memory for result", K(raw_str.length()), K(ret));
} else {
MEMCPY(buf, raw_str.ptr(), raw_str.length());
result.set_collation_type(CS_TYPE_UTF8MB4_BIN);
result.set_string(ObJsonType, buf, raw_str.length());
}
result.set_collation_type(CS_TYPE_UTF8MB4_BIN);
result.set_string(ObJsonType, raw_bin.ptr(), raw_bin.length());
}
}
}
@ -227,9 +221,9 @@ int ObExprJsonExtract::eval_json_extract(const ObExpr &expr, ObEvalCtx &ctx, ObD
} else if (OB_FAIL(ObJsonExprHelper::ensure_collation(val_type, cs_type))) {
LOG_WARN("fail to ensure collation", K(ret), K(val_type), K(cs_type));
} else {
ObString j_text = json_datum->get_string();
ObString j_str = json_datum->get_string();
ObJsonInType j_in_type = ObJsonExprHelper::get_json_internal_type(val_type);
if (OB_FAIL(ObJsonBaseFactory::get_json_base(&allocator, j_text, j_in_type, j_in_type, j_base))) {
if (OB_FAIL(ObJsonBaseFactory::get_json_base(&allocator, j_str, j_in_type, j_in_type, j_base))) {
LOG_WARN("fail to get json base", K(ret), K(j_in_type));
ret = OB_ERR_INVALID_JSON_TEXT;
}
@ -285,9 +279,10 @@ int ObExprJsonExtract::eval_json_extract(const ObExpr &expr, ObEvalCtx &ctx, ObD
ObJsonNode *j_node = NULL;
ObIJsonBase *jb_node = NULL;
for (int32_t i = 0; OB_SUCC(ret) && i < hit_size; i++) {
if (ObJsonBaseFactory::transform(&allocator, hit[i], ObJsonInType::JSON_TREE, jb_node)) { // to tree
if (OB_FAIL(ObJsonBaseFactory::transform(&allocator, hit[i],
ObJsonInType::JSON_TREE, jb_node))) { // to tree
LOG_WARN("fail to transform to tree", K(ret), K(i), K(*(hit[i])));
} else {
} else { // is_tree, need deep copy, cause array append will change parent of value.
j_node = static_cast<ObJsonNode *>(jb_node);
if (OB_FAIL(jb_res->array_append(j_node->clone(&allocator)))) {
LOG_WARN("result array append failed", K(ret), K(i), K(*j_node));

View File

@ -60,10 +60,10 @@ int ObJsonExprHelper::get_json_doc(const ObExpr &expr, ObEvalCtx &ctx,
} else if (OB_FAIL(ObJsonExprHelper::ensure_collation(val_type, cs_type))) {
LOG_WARN("fail to ensure collation", K(ret), K(val_type), K(cs_type));
} else {
ObString j_text = json_datum->get_string();
ObString j_str = json_datum->get_string();
ObJsonInType j_in_type = ObJsonExprHelper::get_json_internal_type(val_type);
ObJsonInType expect_type = need_to_tree ? ObJsonInType::JSON_TREE : j_in_type;
if (OB_FAIL(ObJsonBaseFactory::get_json_base(&allocator, j_text, j_in_type,
if (OB_FAIL(ObJsonBaseFactory::get_json_base(&allocator, j_str, j_in_type,
expect_type, j_base))) {
LOG_WARN("fail to get json base", K(ret), K(j_in_type));
ret = OB_ERR_INVALID_JSON_TEXT_IN_PARAM;
@ -89,10 +89,10 @@ int ObJsonExprHelper::get_json_doc(const ObObj *objs, common::ObIAllocator *allo
} else if (OB_FAIL(ObJsonExprHelper::ensure_collation(val_type, cs_type))) {
LOG_WARN("fail to ensure collation", K(ret), K(val_type), K(cs_type));
} else {
ObString j_text = objs[index].get_string();
ObString j_str = objs[index].get_string();
ObJsonInType j_in_type = ObJsonExprHelper::get_json_internal_type(val_type);
ObJsonInType expect_type = need_to_tree ? ObJsonInType::JSON_TREE : j_in_type;
if (OB_FAIL(ObJsonBaseFactory::get_json_base(allocator, j_text, j_in_type,
if (OB_FAIL(ObJsonBaseFactory::get_json_base(allocator, j_str, j_in_type,
expect_type, j_base))) {
LOG_WARN("fail to get json base", K(ret), K(j_in_type));
ret = OB_ERR_INVALID_JSON_TEXT_IN_PARAM;
@ -108,7 +108,22 @@ int ObJsonExprHelper::get_json_val(const common::ObObj &data, ObExprCtx &ctx,
{
INIT_SUCC(ret);
ObObjType val_type = data.get_type();
if (is_bool) {
if (data.is_null()) {
void *json_node_buf = allocator->alloc(sizeof(ObJsonNull));
if (OB_ISNULL(json_node_buf)) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_WARN("failed: alloscate jsonboolean", K(ret));
} else {
ObJsonNull *null_node = static_cast<ObJsonNull*>(new(json_node_buf) ObJsonNull());
if (to_bin) {
if (OB_FAIL(ObJsonBaseFactory::transform(allocator, null_node, ObJsonInType::JSON_BIN, j_base))) {
LOG_WARN("failed: json tree to bin", K(ret));
}
} else {
j_base = null_node;
}
}
} else if (is_bool) {
void *json_node_buf = allocator->alloc(sizeof(ObJsonBoolean));
if (OB_ISNULL(json_node_buf)) {
ret = OB_ALLOCATE_MEMORY_FAILED;
@ -155,6 +170,21 @@ int ObJsonExprHelper::get_json_val(const ObExpr &expr, ObEvalCtx &ctx,
ObObjType val_type = json_arg->datum_meta_.type_;
if (OB_UNLIKELY(OB_FAIL(json_arg->eval(ctx, json_datum)))) {
LOG_WARN("eval json arg failed", K(ret), K(val_type));
} else if (json_datum->is_null()) {
void *json_node_buf = allocator->alloc(sizeof(ObJsonNull));
if (OB_ISNULL(json_node_buf)) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_WARN("failed: alloscate jsonboolean", K(ret));
} else {
ObJsonNull *null_node = static_cast<ObJsonNull*>(new(json_node_buf) ObJsonNull());
if (to_bin) {
if (OB_FAIL(ObJsonBaseFactory::transform(allocator, null_node, ObJsonInType::JSON_BIN, j_base))) {
LOG_WARN("failed: json tree to bin", K(ret));
}
} else {
j_base = null_node;
}
}
} else if (json_arg->is_boolean_ == 1) {
void *json_node_buf = allocator->alloc(sizeof(ObJsonBoolean));
if (OB_ISNULL(json_node_buf)) {
@ -343,6 +373,23 @@ void ObJsonExprHelper::set_type_for_value(ObExprResType* types_stack, uint32_t i
}
}
int ObJsonExprHelper::is_json_zero(const ObString& data, int& result)
{
INIT_SUCC(ret);
int tmp_result = 0;
ObJsonBin j_bin(data.ptr(), data.length());
if (data.length() == 0) {
result = 1;
} else if (OB_FAIL(j_bin.reset_iter())) {
LOG_WARN("failed: reset iter", K(ret));
} else if (OB_FAIL(ObJsonBaseUtil::compare_int_json(0, &j_bin, tmp_result))) {
LOG_WARN("failed: cmp json", K(ret));
} else {
result = (tmp_result == 0) ? 0 : 1;
}
return ret;
}
template <typename T>
int ObJsonExprHelper::transform_scalar_2jsonBase(const T &datum,
ObObjType type,

View File

@ -114,6 +114,8 @@ public:
static ObJsonPathCache* get_path_cache_ctx(const uint64_t& id, ObExecContext *exec_ctx);
static int is_json_zero(const ObString& data, int& result);
/*
try to transfrom scalar data to jsonBase
@param[in] datum the input datum

View File

@ -184,16 +184,8 @@ int ObExprJsonInsert::calc_resultN(ObObj &result, const ObObj *objs, int64_t par
} else if (OB_FAIL(j_base->get_raw_binary(raw_bin, allocator))) {
LOG_WARN("fail to get json raw binary", K(ret));
} else {
uint64_t length = raw_bin.length();
char *buf = reinterpret_cast<char *>(allocator->alloc(length));
if (OB_ISNULL(buf)) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_WARN("fail to alloc memory for json insert result", K(ret), K(length));
} else {
MEMCPY(buf, raw_bin.ptr(), length);
result.set_collation_type(result_type_.get_collation_type());
result.set_string(ObJsonType, buf, length);
}
result.set_collation_type(CS_TYPE_UTF8MB4_BIN);
result.set_string(ObJsonType, raw_bin.ptr(), raw_bin.length());
}
}

View File

@ -120,19 +120,12 @@ int ObExprJsonKeys::calc_resultN(ObObj &result,
} else if (is_null_result){
result.set_null();
} else {
ObString str;
if (OB_FAIL(get_keys_from_wrapper(json_doc, allocator, str))) {
ObString raw_bin;
if (OB_FAIL(get_keys_from_wrapper(json_doc, allocator, raw_bin))) {
LOG_WARN("get_keys_from_wrapper failed", K(ret));
} else {
char *buf = reinterpret_cast<char *>(allocator->alloc(str.length()));
if (OB_UNLIKELY(OB_ISNULL(buf))) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_WARN("fail to alloc memory for json_keys result", K(ret), K(str.length()));
} else {
MEMCPY(buf, str.ptr(), str.length());
result.set_collation_type(CS_TYPE_UTF8MB4_BIN);
result.set_string(ObJsonType, buf, str.length());
}
result.set_collation_type(CS_TYPE_UTF8MB4_BIN);
result.set_string(ObJsonType, raw_bin.ptr(), raw_bin.length());
}
}
}
@ -146,7 +139,7 @@ int ObExprJsonKeys::get_keys_from_wrapper(ObIJsonBase *json_doc,
INIT_SUCC(ret);
ObJsonArray res_array(allocator);
JsonObjectIterator iter = json_doc->object_iterator();
while (!iter.empty() && OB_SUCC(ret)) {
while (!iter.end() && OB_SUCC(ret)) {
ObString key;
if (OB_FAIL(iter.get_key(key))) {
LOG_WARN("fail to get key from iterator", K(ret));

View File

@ -56,20 +56,27 @@ int ObExprJsonMemberOf::calc_result_type2(ObExprResType &type,
return ret;
}
static int json_member_of_array(const ObIJsonBase *json_a, const ObIJsonBase *json_b, bool *result)
int ObExprJsonMemberOf::check_json_member_of_array(const ObIJsonBase *json_a,
const ObIJsonBase *json_b,
bool &is_member_of)
{
int ret = OB_SUCCESS;
int ret_tmp;
is_member_of = false;
uint64_t b_len = json_b->element_count();
for (uint64_t i = 0; i < b_len && OB_SUCC(ret); i++) {
ObIJsonBase *tmp = NULL;
if (OB_FAIL(json_b->get_array_element(i, tmp))) {
break;
} else {
if (OB_SUCC(json_a->compare(*tmp, ret_tmp)) && ret_tmp == 0) {
*result = true;
break;
if (OB_ISNULL(json_a) || OB_ISNULL(json_b)) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("param is null", K(ret), KP(json_a), KP(json_b));
} else {
int cmp_res = 0;
uint64_t b_len = json_b->element_count();
for (uint64_t i = 0; i < b_len && OB_SUCC(ret) && !is_member_of; i++) {
ObIJsonBase *tmp = NULL;
if (OB_FAIL(json_b->get_array_element(i, tmp))) {
LOG_WARN("fail to get array element", K(ret), K(i), K(*json_b));
} else if (OB_FAIL(json_a->compare(*tmp, cmp_res))) {
LOG_WARN("fail to compare json", K(ret), K(i), K(*json_a), K((*tmp)));
} else if (cmp_res == 0) {
is_member_of = true;
}
}
}
@ -114,8 +121,8 @@ int ObExprJsonMemberOf::eval_json_member_of(const ObExpr &expr, ObEvalCtx &ctx,
} else {
is_member_of = (result == 0);
}
} else if (OB_FAIL(json_member_of_array(json_a, json_b, &is_member_of))) {
LOG_WARN("json_member_of_array failed", K(ret));
} else if (OB_FAIL(check_json_member_of_array(json_a, json_b, is_member_of))) {
LOG_WARN("check_json_member_of_array failed", K(ret));
}
}
@ -171,8 +178,8 @@ int ObExprJsonMemberOf::calc_result2(common::ObObj &result,
} else {
is_member_of = (result == 0);
}
} else if (OB_FAIL(json_member_of_array(json_a, json_b, &is_member_of))) {
LOG_WARN("json_member_of_array failed", K(ret));
} else if (OB_FAIL(check_json_member_of_array(json_a, json_b, is_member_of))) {
LOG_WARN("check_json_member_of_array failed", K(ret));
}
}

View File

@ -36,6 +36,9 @@ public:
const common::ObObj &obj1,
const common::ObObj &obj2,
common::ObExprCtx &expr_ctx) const;
static int check_json_member_of_array(const ObIJsonBase *json_a,
const ObIJsonBase *json_b,
bool &is_member_of);
static int eval_json_member_of(const ObExpr &expr, ObEvalCtx &ctx, ObDatum &res);
virtual int cg_expr(ObExprCGCtx &expr_cg_ctx, const ObRawExpr &raw_expr,
ObExpr &rt_expr) const override;

View File

@ -103,12 +103,14 @@ int ObExprJsonMergePatch::calc_resultN(ObObj &result, const ObObj *objs, int64_t
j_obj = new (buf) ObJsonObject(allocator);
}
}
if (OB_FAIL(j_obj->merge_patch(allocator, static_cast<ObJsonObject*>(j_patch_node)))) {
LOG_WARN("error, json merge patch failed", K(ret));
} else {
j_base = j_obj;
has_null = false;
if (OB_SUCC(ret)) {
if (OB_FAIL(j_obj->merge_patch(allocator, static_cast<ObJsonObject*>(j_patch_node)))) {
LOG_WARN("error, json merge patch failed", K(ret));
} else {
j_base = j_obj;
has_null = false;
}
}
}
}
@ -120,16 +122,8 @@ int ObExprJsonMergePatch::calc_resultN(ObObj &result, const ObObj *objs, int64_t
} else if (OB_FAIL(j_base->get_raw_binary(raw_bin, allocator))) {
LOG_WARN("fail to get json raw binary", K(ret));
} else {
uint64_t length = raw_bin.length();
char *buf = reinterpret_cast<char *>(allocator->alloc(length));
if (OB_ISNULL(buf)) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_WARN("fail to alloc memory for json insert result", K(ret), K(length));
} else {
MEMCPY(buf, raw_bin.ptr(), length);
result.set_collation_type(CS_TYPE_UTF8MB4_BIN);
result.set_string(ObJsonType, buf, length);
}
result.set_collation_type(CS_TYPE_UTF8MB4_BIN);
result.set_string(ObJsonType, raw_bin.ptr(), raw_bin.length());
}
}
@ -178,11 +172,13 @@ int ObExprJsonMergePatch::eval_json_merge_patch(const ObExpr &expr, ObEvalCtx &c
}
}
if (OB_FAIL(j_obj->merge_patch(&temp_allocator, static_cast<ObJsonObject*>(j_patch_node)))) {
LOG_WARN("error, json merge patch failed", K(ret));
} else {
j_base = j_obj;
has_null = false;
if (OB_SUCC(ret)) {
if (OB_FAIL(j_obj->merge_patch(&temp_allocator, static_cast<ObJsonObject*>(j_patch_node)))) {
LOG_WARN("error, json merge patch failed", K(ret));
} else {
j_base = j_obj;
has_null = false;
}
}
}
}

View File

@ -105,16 +105,8 @@ int ObExprJsonMergePreserve::calc_resultN(ObObj &result, const ObObj *objs, int6
} else if (OB_FAIL(j_base->get_raw_binary(raw_bin, allocator))) {
LOG_WARN("fail to get json raw binary", K(ret));
} else {
uint64_t length = raw_bin.length();
char *buf = reinterpret_cast<char *>(allocator->alloc(length));
if (OB_ISNULL(buf)) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_WARN("fail to alloc memory for json merge result", K(ret), K(length));
} else {
MEMMOVE(buf, raw_bin.ptr(), length);
result.set_collation_type(CS_TYPE_UTF8MB4_BIN);
result.set_string(ObJsonType, buf, length);
}
result.set_collation_type(CS_TYPE_UTF8MB4_BIN);
result.set_string(ObJsonType, raw_bin.ptr(), raw_bin.length());
}
}
}

View File

@ -123,16 +123,8 @@ int ObExprJsonObject::calc_resultN(ObObj &result, const ObObj *objs,
if (OB_FAIL(j_base->get_raw_binary(raw_bin, allocator))) {
LOG_WARN("failed: get json raw binary", K(ret));
} else {
uint64_t length = raw_bin.length();
char *buf = reinterpret_cast<char *>(allocator->alloc(length));
if (OB_ISNULL(buf)) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_WARN("failed: alloc memory for json object result", K(ret), K(length));
} else {
MEMCPY(buf, raw_bin.ptr(), length);
result.set_collation_type(CS_TYPE_UTF8MB4_BIN);
result.set_string(ObJsonType, buf, length);
}
result.set_collation_type(CS_TYPE_UTF8MB4_BIN);
result.set_string(ObJsonType, raw_bin.ptr(), raw_bin.length());
}
}
return ret;

View File

@ -148,7 +148,7 @@ int ObExprJsonOverlaps::json_overlaps_object(ObIJsonBase *json_a,
} else {
JsonObjectIterator iter_a = json_a->object_iterator();
JsonObjectIterator iter_b = json_b->object_iterator();
while (!iter_b.empty() && OB_SUCC(ret)) {
while (!iter_b.end() && OB_SUCC(ret)) {
ObString key_b;
ObIJsonBase *a_tmp = NULL;
ObIJsonBase *b_tmp = NULL;
@ -191,7 +191,8 @@ int ObExprJsonOverlaps::json_overlaps_array(ObIJsonBase *json_a,
if (json_b->json_type() != ObJsonNodeType::J_ARRAY) {
// convert to array if needed
ObIJsonBase *jb_node = NULL;
if (ObJsonBaseFactory::transform(allocator, json_b, ObJsonInType::JSON_TREE, jb_node)) {
if (OB_FAIL(ObJsonBaseFactory::transform(allocator, json_b,
ObJsonInType::JSON_TREE, jb_node))) {
LOG_WARN("fail to transform to tree", K(ret), K(*json_b));
} else {
ObJsonNode *j_node = static_cast<ObJsonNode *>(jb_node);

View File

@ -60,7 +60,7 @@ int ObExprJsonPretty::calc(const T &data, ObObjType type, ObCollationType cs_typ
INIT_SUCC(ret);
ObIJsonBase *j_base = NULL;
ObJsonInType j_in_type = ObJsonExprHelper::get_json_internal_type(type);
common::ObString j_text = data.get_string(); // json text or json binary
common::ObString j_str = data.get_string(); // json text or json binary
if (OB_ISNULL(allocator)) { // check allocator
ret = OB_NOT_INIT;
@ -72,11 +72,14 @@ int ObExprJsonPretty::calc(const T &data, ObObjType type, ObCollationType cs_typ
LOG_USER_ERROR(OB_ERR_INVALID_TYPE_FOR_JSON, 1, "json_pretty");
} else if (OB_FAIL(ObJsonExprHelper::ensure_collation(type, cs_type))) {
LOG_WARN("fail to ensure collation", K(ret), K(type), K(cs_type));
} else if (OB_FAIL(ObJsonBaseFactory::get_json_base(allocator, j_text, j_in_type,
} else if (OB_FAIL(ObJsonBaseFactory::get_json_base(allocator, j_str, j_in_type,
j_in_type, j_base))) {
LOG_WARN("fail to get json base", K(ret), K(type), K(j_text), K(j_in_type));
if (ret == OB_ERR_INVALID_JSON_TEXT) {
ret = OB_ERR_INVALID_JSON_TEXT_IN_PARAM;
}
LOG_WARN("fail to get json base", K(ret), K(type), K(j_str), K(j_in_type));
} else if (OB_FAIL(j_base->print(j_buf, true, true))) {
LOG_WARN("fail to print json", K(ret), K(type), K(j_text), K(j_in_type));
LOG_WARN("fail to print json", K(ret), K(type), K(j_str), K(j_in_type));
}
return ret;

View File

@ -138,19 +138,12 @@ int ObExprJsonRemove::calc_resultN(common::ObObj &result,
} else if (is_null_result) {
result.set_null();
} else {
ObString str;
if (OB_FAIL(json_doc->get_raw_binary(str, allocator))) {
ObString raw_bin;
if (OB_FAIL(json_doc->get_raw_binary(raw_bin, allocator))) {
LOG_WARN("json_remove get result binary failed", K(ret));
} else {
char *buf = reinterpret_cast<char *>(allocator->alloc(str.length()));
if (OB_ISNULL(buf)){
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_WARN("json_remove alloc jsonString failed", K(ret), K(str.length()));
} else {
MEMCPY(buf, str.ptr(), str.length());
result.set_collation_type(CS_TYPE_UTF8MB4_BIN);
result.set_string(ObJsonType, buf, str.length());
}
result.set_collation_type(CS_TYPE_UTF8MB4_BIN);
result.set_string(ObJsonType, raw_bin.ptr(), raw_bin.length());
}
}
}

View File

@ -134,19 +134,12 @@ int ObExprJsonReplace::calc_resultN(common::ObObj &result,
} else if (is_null_result) {
result.set_null();
} else {
ObString str;
if (OB_FAIL(json_doc->get_raw_binary(str, allocator))) {
ObString raw_bin;
if (OB_FAIL(json_doc->get_raw_binary(raw_bin, allocator))) {
LOG_WARN("json_replace result to binary failed", K(ret));
} else {
char *buf = reinterpret_cast<char *>(allocator->alloc(str.length()));
if (OB_ISNULL(buf)){
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_WARN("json_remove alloc jsonString failed", K(ret), K(str.length()));
} else {
MEMCPY(buf, str.ptr(), str.length());
result.set_collation_type(CS_TYPE_UTF8MB4_BIN);
result.set_string(ObJsonType, buf, str.length());
}
result.set_collation_type(CS_TYPE_UTF8MB4_BIN);
result.set_string(ObJsonType, raw_bin.ptr(), raw_bin.length());
}
}
}

View File

@ -464,16 +464,8 @@ int ObExprJsonSearch::calc_resultN(ObObj& result,
if (OB_FAIL(j_res->get_raw_binary(raw_bin, allocator))) {
LOG_WARN("json_keys get result binary failed", K(ret));
} else {
uint64_t length = raw_bin.length();
char *buf = reinterpret_cast<char *>(allocator->alloc(length));
if (OB_ISNULL(buf)){
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_WARN("json_search alloc jsonString failed", K(ret), K(length));
} else {
MEMCPY(buf, raw_bin.ptr(), length);
result.set_collation_type(CS_TYPE_UTF8MB4_BIN);
result.set_string(ObJsonType, buf, length);
}
result.set_collation_type(CS_TYPE_UTF8MB4_BIN);
result.set_string(ObJsonType, raw_bin.ptr(), raw_bin.length());
}
}
}

View File

@ -122,20 +122,12 @@ int ObExprJsonSet::calc_resultN(common::ObObj &result,
} else if (is_null_result) {
result.set_null();
} else {
ObString str;
if (OB_FAIL(json_doc->get_raw_binary(str, allocator))) {
ObString raw_bin;
if (OB_FAIL(json_doc->get_raw_binary(raw_bin, allocator))) {
LOG_WARN("json_set result to binary failed", K(ret));
} else {
uint64_t length = str.length();
char *buf = reinterpret_cast<char *>(allocator->alloc(length));
if (OB_ISNULL(buf)) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_WARN("fail to alloc memory for json set result", K(ret), K(length));
} else {
MEMCPY(buf, str.ptr(), length);
result.set_string(ObJsonType, buf, length);
result.set_collation_type(CS_TYPE_UTF8MB4_BIN);
}
result.set_collation_type(CS_TYPE_UTF8MB4_BIN);
result.set_string(ObJsonType, raw_bin.ptr(), raw_bin.length());
}
}
return ret;

View File

@ -70,20 +70,20 @@ int ObExprJsonStorageFree::calc(const T &data, ObObjType type, ObCollationType c
LOG_WARN("fail to ensure collation", K(ret), K(type), K(cs_type));
} else {
uint64_t free_space = 0;
common::ObString j_text = data.get_string();
common::ObString j_str = data.get_string();
ObIJsonBase *j_base = NULL;
ObJsonInType j_in_type = ObJsonExprHelper::get_json_internal_type(type);
if (j_text.length() == 0) {
if (j_str.length() == 0) {
ret = OB_ERR_INVALID_JSON_TEXT;
LOG_USER_ERROR(OB_ERR_INVALID_JSON_TEXT);
} else if (OB_FAIL(ObJsonBaseFactory::get_json_base(allocator, j_text, j_in_type,
} else if (OB_FAIL(ObJsonBaseFactory::get_json_base(allocator, j_str, j_in_type,
j_in_type, j_base))) {
if (ret == OB_ERR_INVALID_JSON_TEXT) {
LOG_USER_ERROR(OB_ERR_INVALID_JSON_TEXT);
}
LOG_WARN("fail to get json base", K(ret), K(type), K(j_text), K(j_in_type));
LOG_WARN("fail to get json base", K(ret), K(type), K(j_str), K(j_in_type));
} else if (OB_FAIL(j_base->get_free_space(free_space))) {
LOG_WARN("fail to get free space", K(ret), K(type), K(j_text), K(j_in_type));
LOG_WARN("fail to get free space", K(ret), K(type), K(j_str), K(j_in_type));
} else {
res.set_int32(free_space);
}

View File

@ -69,20 +69,20 @@ int ObExprJsonStorageSize::calc(const T &data, ObObjType type, ObCollationType c
LOG_WARN("fail to ensure collation", K(ret), K(type), K(cs_type));
} else {
uint64_t size = 0;
common::ObString j_text = data.get_string();
common::ObString j_str = data.get_string();
ObIJsonBase *j_base = NULL;
ObJsonInType j_in_type = ObJsonExprHelper::get_json_internal_type(type);
if (j_text.length() == 0) {
if (j_str.length() == 0) {
ret = OB_ERR_INVALID_JSON_TEXT;
LOG_USER_ERROR(OB_ERR_INVALID_JSON_TEXT);
} else if (OB_FAIL(ObJsonBaseFactory::get_json_base(allocator, j_text, j_in_type,
} else if (OB_FAIL(ObJsonBaseFactory::get_json_base(allocator, j_str, j_in_type,
j_in_type, j_base))) {
if (ret == OB_ERR_INVALID_JSON_TEXT) {
LOG_USER_ERROR(OB_ERR_INVALID_JSON_TEXT);
}
LOG_WARN("fail to get json base", K(ret), K(type), K(j_text), K(j_in_type));
LOG_WARN("fail to get json base", K(ret), K(type), K(j_str), K(j_in_type));
} else if (OB_FAIL(j_base->get_used_size(size))) {
LOG_WARN("fail to get used size", K(ret), K(type), K(j_text), K(j_in_type));
LOG_WARN("fail to get used size", K(ret), K(type), K(j_str), K(j_in_type));
} else {
res.set_int32(size);
}

View File

@ -142,17 +142,17 @@ int ObExprJsonType::calc(const T &data, ObObjType type, ObCollationType cs_type,
case ObMediumTextType:
case ObJsonType:
case ObLongTextType: {
common::ObString j_text = data.get_string(); // json text or json binary
common::ObString j_str = data.get_string(); // json text or json binary
ObJsonInType j_in_type = ObJsonExprHelper::get_json_internal_type(type);
ObIJsonBase *j_base = NULL;
if (OB_FAIL(ObJsonExprHelper::ensure_collation(type, cs_type))) {
LOG_WARN("fail to ensure collation", K(ret), K(type), K(cs_type));
} else if (j_text.length() == 0) {
} else if (j_str.length() == 0) {
ret = OB_ERR_INVALID_JSON_TEXT;
LOG_USER_ERROR(OB_ERR_INVALID_JSON_TEXT);
} else if (OB_FAIL(ObJsonBaseFactory::get_json_base(allocator, j_text, j_in_type,
} else if (OB_FAIL(ObJsonBaseFactory::get_json_base(allocator, j_str, j_in_type,
j_in_type, j_base))) {
LOG_WARN("fail to get json base", K(ret), K(type), K(j_text), K(j_in_type));
LOG_WARN("fail to get json base", K(ret), K(type), K(j_str), K(j_in_type));
if (ret == OB_ERR_INVALID_JSON_TEXT) {
LOG_USER_ERROR(OB_ERR_INVALID_JSON_TEXT);
}

View File

@ -83,16 +83,19 @@ int ObExprJsonUnquote::calc(const T &data, ObObjType type, ObCollationType cs_ty
LOG_WARN("fail to ensure collation", K(ret), K(type), K(cs_type));
} else {
ObIJsonBase *j_base = NULL;
ObString j_text = data.get_string();
size_t len = j_text.length();
ObString j_str = data.get_string();
size_t len = j_str.length();
ObJsonInType j_in_type = ObJsonExprHelper::get_json_internal_type(type);
if (ob_is_string_type(type) && (len < 2 || j_text[0] != '"' || j_text[len - 1] != '"')) {
if (OB_FAIL(j_buf.append(j_text))) {
LOG_WARN("failed: copy original string", K(ret), K(j_text));
if (ob_is_string_type(type) && (len < 2 || j_str[0] != '"' || j_str[len - 1] != '"')) {
if (OB_FAIL(j_buf.append(j_str))) {
LOG_WARN("failed: copy original string", K(ret), K(j_str));
}
} else if (OB_FAIL(ObJsonBaseFactory::get_json_base(allocator, j_text, j_in_type,
} else if (OB_FAIL(ObJsonBaseFactory::get_json_base(allocator, j_str, j_in_type,
j_in_type, j_base))) {
LOG_WARN("failed: get json base", K(ret), K(type));
if (OB_ERR_INVALID_JSON_TEXT) {
ret = OB_ERR_INVALID_JSON_TEXT_IN_PARAM;
}
if (ret == OB_ERR_INVALID_JSON_TEXT_IN_PARAM) {
LOG_USER_ERROR(OB_ERR_INVALID_JSON_TEXT_IN_PARAM);
}

View File

@ -83,8 +83,8 @@ int ObExprJsonValid::calc(const T &data, ObObjType type, ObCollationType cs_type
} else if (ob_is_string_type(type) && cs_type == CS_TYPE_BINARY) {
is_invalid = true;
} else {
common::ObString j_text = data.get_string();
if (OB_UNLIKELY(j_text == "")) {
common::ObString j_str = data.get_string();
if (OB_UNLIKELY(j_str == "")) {
if (type == ObJsonType) {
is_null = true;
} else {
@ -92,13 +92,13 @@ int ObExprJsonValid::calc(const T &data, ObObjType type, ObCollationType cs_type
}
} else if (type == ObJsonType) { // json bin
ObIJsonBase *j_bin = NULL;
if (ObJsonBaseFactory::get_json_base(allocator, j_text, ObJsonInType::JSON_BIN,
ObJsonInType::JSON_BIN, j_bin)) {
LOG_WARN("fail to get json base", K(ret), K(type), K(j_text));
if (OB_FAIL(ObJsonBaseFactory::get_json_base(allocator, j_str, ObJsonInType::JSON_BIN,
ObJsonInType::JSON_BIN, j_bin))) {
LOG_WARN("fail to get json base", K(ret), K(type), K(j_str));
}
} else { // json tree
if (OB_FAIL(ObJsonParser::check_json_syntax(j_text, allocator))) {
LOG_WARN("fail to check json syntax", K(ret), K(type), K(j_text));
if (OB_FAIL(ObJsonParser::check_json_syntax(j_str, allocator))) {
LOG_WARN("fail to check json syntax", K(ret), K(type), K(j_str));
}
}
}

View File

@ -130,8 +130,6 @@ int ObExprJsonValue::calc_result_typeN(ObExprResType& type,
types_stack[4].set_calc_type(temp_type.get_type());
types_stack[4].set_calc_collation_type(temp_type.get_collation_type());
types_stack[4].set_calc_collation_level(temp_type.get_collation_level());
// types_stack[4].set_calc_length(temp_type.get_length());
// types_stack[4].set_calc_length_semantics(temp_type.get_length_semantics());
types_stack[4].set_calc_accuracy(temp_type.get_accuracy());
}
}
@ -152,8 +150,6 @@ int ObExprJsonValue::calc_result_typeN(ObExprResType& type,
types_stack[6].set_calc_type(temp_type.get_type());
types_stack[6].set_calc_collation_type(temp_type.get_collation_type());
types_stack[6].set_calc_collation_level(temp_type.get_collation_level());
// types_stack[6].set_calc_length(temp_type.get_length());
// types_stack[6].set_calc_length_semantics(temp_type.get_length_semantics());
types_stack[6].set_calc_accuracy(temp_type.get_accuracy());
}
}
@ -189,13 +185,13 @@ int ObExprJsonValue::calc_resultN(ObObj& result,
ret = OB_ERR_UNEXPECTED;
LOG_WARN("input type error", K(type));
} else {
ObString j_text = params[0].get_string();
ObString j_str = params[0].get_string();
ObJsonInType j_in_type = ObJsonExprHelper::get_json_internal_type(type);
if (j_text.length() == 0) { // maybe input json doc is null type
if (j_str.length() == 0) { // maybe input json doc is null type
is_null_result = true;
} else if (OB_FAIL(ObJsonBaseFactory::get_json_base(allocator, j_text, j_in_type,
} else if (OB_FAIL(ObJsonBaseFactory::get_json_base(allocator, j_str, j_in_type,
j_in_type, j_base))) {
LOG_WARN("fail to get json base.", K(ret), K(type), K(j_text), K(j_in_type));
LOG_WARN("fail to get json base.", K(ret), K(type), K(j_str), K(j_in_type));
if (ret == OB_ERR_JSON_OUT_OF_DEPTH) {
is_cover_by_error = false;
}
@ -238,8 +234,11 @@ int ObExprJsonValue::calc_resultN(ObObj& result,
ret = get_on_empty_or_error_old(params, expr_ctx, dst_type, 5, is_cover_by_error,
accuracy, error_type, &error_val);
} else if (is_cover_by_error) { // always get error option for return default value on error
get_on_empty_or_error_old(params, expr_ctx, dst_type, 5, is_cover_by_error,
accuracy, error_type, &error_val);
int temp_ret = get_on_empty_or_error_old(params, expr_ctx, dst_type, 5, is_cover_by_error,
accuracy, error_type, &error_val);
if (temp_ret != OB_SUCCESS) {
LOG_WARN("failed to get on empty or error.", K(ret), K(dst_type));
}
}
// parse json path and do seek
@ -364,13 +363,13 @@ int ObExprJsonValue::eval_json_value(const ObExpr &expr, ObEvalCtx &ctx, ObDatum
ret = OB_ERR_UNEXPECTED;
LOG_WARN("input type error", K(type));
} else {
ObString j_text = json_datum->get_string();
ObString j_str = json_datum->get_string();
ObJsonInType j_in_type = ObJsonExprHelper::get_json_internal_type(type);
if (j_text.length() == 0) { // maybe input json doc is null type
if (j_str.length() == 0) { // maybe input json doc is null type
is_null_result = true;
} else if (OB_FAIL(ObJsonBaseFactory::get_json_base(&temp_allocator, j_text, j_in_type,
} else if (OB_FAIL(ObJsonBaseFactory::get_json_base(&temp_allocator, j_str, j_in_type,
j_in_type, j_base))) {
LOG_WARN("fail to get json base.", K(ret), K(type), K(j_text), K(j_in_type));
LOG_WARN("fail to get json base.", K(ret), K(type), K(j_str), K(j_in_type));
if (ret == OB_ERR_JSON_OUT_OF_DEPTH) {
is_cover_by_error = false;
}
@ -999,7 +998,7 @@ int ObExprJsonValue::cast_to_number(common::ObIAllocator *allocator,
if (OB_ISNULL(j_base)) {
ret = OB_ERR_NULL_VALUE;
LOG_WARN("json base is null", K(ret));
} else if (CAST_FAIL(j_base->to_number(val))) {
} else if (CAST_FAIL(j_base->to_number(allocator, val))) {
LOG_WARN("fail to cast json as decimal", K(ret));
} else if (ObUNumberType == dst_type && CAST_FAIL(numeric_negative_check(val))) {
LOG_WARN("numeric_negative_check failed", K(ret), K(val));
@ -1538,6 +1537,7 @@ int ObExprJsonValue::get_on_empty_or_error_old(const ObObj *params,
expr_ctx.cast_mode_ &= ~CM_NO_RANGE_CHECK; // make cast check range
expr_ctx.cast_mode_ &= ~CM_STRING_INTEGER_TRUNC; // make cast check range when string to uint
expr_ctx.cast_mode_ |= CM_ERROR_ON_SCALE_OVER; // make cast check presion and scale
expr_ctx.cast_mode_ |= CM_EXPLICIT_CAST; // make cast json fail return error
if (OB_FAIL(param_eval(expr_ctx, params[index + 1], index + 1))) {
is_cover_by_error = false;
LOG_WARN("eval json arg failed", K(ret));
@ -1597,6 +1597,7 @@ int ObExprJsonValue::get_on_empty_or_error(const ObExpr &expr,
json_arg->extra_ &= ~CM_NO_RANGE_CHECK; // make cast check range
json_arg->extra_ &= ~CM_STRING_INTEGER_TRUNC; // make cast check range when string to uint
json_arg->extra_ |= CM_ERROR_ON_SCALE_OVER; // make cast check presion and scale
json_arg->extra_ |= CM_EXPLICIT_CAST; // make cast json fail return error
if (OB_FAIL(json_arg->eval(ctx, json_datum))) {
is_cover_by_error = false;
LOG_WARN("eval json arg failed", K(ret));

View File

@ -14,7 +14,7 @@
#include "sql/engine/expr/ob_expr_or.h"
#include "lib/oblog/ob_log.h"
#include "share/object/ob_obj_cast.h"
//#include "sql/engine/expr/ob_expr_promotion_util.h"
#include "sql/engine/expr/ob_expr_json_func_helper.h"
#include "sql/session/ob_sql_session_info.h"
namespace oceanbase {
@ -49,7 +49,17 @@ int ObExprOr::calc_result2(
bool obj1_is_true = false;
EXPR_SET_CAST_CTX_MODE(expr_ctx);
if (OB_FAIL(ObLogicalExprOperator::is_true(obj1, expr_ctx.cast_mode_ | CM_NO_RANGE_CHECK, obj1_is_true))) {
if (ob_is_json(obj1.get_type())) {
// cause for json type, in some case can't transform to number type
// add special process for json type
// use the some logical as mysql
int cmp_result = 0;
if (OB_FAIL(ObJsonExprHelper::is_json_zero(obj1.get_string(), cmp_result))) {
LOG_WARN("failed: compare json", K(ret));
} else {
result.set_int32(cmp_result);
}
} else if (OB_FAIL(ObLogicalExprOperator::is_true(obj1, expr_ctx.cast_mode_ | CM_NO_RANGE_CHECK, obj1_is_true))) {
LOG_WARN("fail to evaluate obj1", K(obj1), K(ret));
} else if (obj1_is_true) {
result.set_int32(static_cast<int32_t>(true));
@ -119,7 +129,6 @@ int ObExprOr::cacl_res_with_one_param_null(
// By design, compatible with mysql and oracle:
// null or false == NULL. null or true == true.
// see "NULL and the three-valued logic"
// https://en.wikipedia.org/wiki/Null_(SQL)#Comparisons_with_NULL_and_the_three-valued_logic_(3VL)
} else if (value) {
res.set_int32(static_cast<int32_t>(true));
} else {