diff --git a/src/sql/engine/basic/ob_json_table_op.cpp b/src/sql/engine/basic/ob_json_table_op.cpp index bb8f8316a..87fdff561 100644 --- a/src/sql/engine/basic/ob_json_table_op.cpp +++ b/src/sql/engine/basic/ob_json_table_op.cpp @@ -1340,6 +1340,25 @@ int JtColNode::check_col_res_type(JtScanCtx* ctx) return ret; } +void JtColNode::proc_query_on_error(int& ret, bool& is_null) +{ + ret = OB_SUCCESS; + if (col_info_.on_error_ == JSN_QUERY_ERROR) { + is_null = true; + iter_ = curr_ = NULL; + LOG_WARN("result can't be returned without array wrapper", K(ret)); + } else if (col_info_.on_error_ == JSN_QUERY_EMPTY || col_info_.on_error_ == JSN_QUERY_EMPTY_ARRAY) { + iter_ = curr_ = ObJsonTableOp::get_js_array(); + is_null = false; + } else if (col_info_.on_error_ == JSN_QUERY_EMPTY_OBJECT) { + iter_ = curr_ = ObJsonTableOp::get_js_object(); + is_null = false; + } else if (col_info_.on_error_ == JSN_QUERY_NULL || col_info_.on_error_ == JSN_QUERY_IMPLICIT) { + iter_ = curr_ = NULL; + is_null = true; + } +} + int JtColNode::set_val_on_empty(JtScanCtx* ctx, bool& need_cast_res) { INIT_SUCC(ret); @@ -1360,17 +1379,12 @@ int JtColNode::set_val_on_empty(JtScanCtx* ctx, bool& need_cast_res) iter_ = curr_ = nullptr; is_null_result_ = true; ret = OB_SUCCESS; - if (col_info_.on_empty_ == JSN_QUERY_IMPLICIT - && col_info_.on_error_ == JSN_QUERY_ERROR) { - ret = OB_ERR_JSON_VALUE_NO_VALUE; - } else if (col_info_.on_empty_ == JSN_QUERY_IMPLICIT - && (col_info_.on_error_ == JSN_QUERY_EMPTY || col_info_.on_error_ == JSN_QUERY_EMPTY_ARRAY)) { - iter_ = curr_ = ObJsonTableOp::get_js_array(); - is_null_result_ = false; - } else if (col_info_.on_empty_ == JSN_QUERY_IMPLICIT - && (col_info_.on_error_ == JSN_QUERY_EMPTY || col_info_.on_error_ == JSN_QUERY_EMPTY_OBJECT)) { - iter_ = curr_ = ObJsonTableOp::get_js_object(); - is_null_result_ = false; + + if (col_info_.on_empty_ == JSN_QUERY_IMPLICIT) { + proc_query_on_error(ret, is_null_result_); + if (col_info_.on_error_ == JSN_QUERY_ERROR) { + ret = OB_ERR_JSON_VALUE_NO_VALUE; + } } break; } @@ -1505,7 +1519,7 @@ int JtColNode::set_val_on_empty(JtScanCtx* ctx, bool& need_cast_res) case JSN_EXIST_ERROR: case JSN_EXIST_DEFAULT: { if (ob_is_string_type(col_info_.data_type_.get_obj_type())) { - ObString value = col_info_.on_empty_ == JSN_EXIST_TRUE ? "true" : "false"; + ObString value = "false"; void* buf = ctx->row_alloc_.alloc(sizeof(ObJsonString)); if (OB_ISNULL(buf)) { ret = OB_ALLOCATE_MEMORY_FAILED; @@ -1544,6 +1558,9 @@ int JtColNode::get_next_row(ObIJsonBase* in, JtScanCtx* ctx, bool& is_null_value if (col_type == COL_TYPE_ORDINALITY) { col_expr->locate_datum_for_write(*ctx->eval_ctx_).set_int(ctx->ord_val_); col_expr->get_eval_info(*ctx->eval_ctx_).evaluated_ = true; + if (ctx->is_need_end_) { + ret = OB_ITER_END; + } } else if (OB_FAIL(check_col_res_type(ctx))) { LOG_WARN("check column res type failed", K(ret), K(col_info_.data_type_), K(col_info_.col_type_)); } else if (OB_FAIL(init_js_path(ctx))) { @@ -1581,8 +1598,7 @@ int JtColNode::get_next_row(ObIJsonBase* in, JtScanCtx* ctx, bool& is_null_value || col_info_.wrapper_ == JSN_QUERY_WITHOUT_ARRAY_WRAPPER || col_info_.wrapper_ == JSN_QUERY_WRAPPER_IMPLICIT) { if (hit.size() > 1) { - curr_ = nullptr; - is_null_result_ = true; + proc_query_on_error(ret, is_null_result_); if (col_info_.on_error_ == JSN_QUERY_ERROR) { ret = OB_ERR_WITHOUT_ARR_WRAPPER; LOG_WARN("result can't be returned without array wrapper", K(ret)); @@ -2720,8 +2736,8 @@ int ObJsonTableOp::inner_get_next_row() in_= nullptr; ret = OB_ERR_JSON_SYNTAX_ERROR; SET_COVER_ERROR(&jt_ctx_, ret); + jt_ctx_.is_need_end_ = 1; if (jt_root_->col_info_.on_error_ != JSN_TABLE_ERROR) { - jt_ctx_.is_need_end_ = 1; 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 83203e677..7d5e02311 100644 --- a/src/sql/engine/basic/ob_json_table_op.h +++ b/src/sql/engine/basic/ob_json_table_op.h @@ -121,7 +121,8 @@ public: virtual int open(); virtual int get_next_row(ObIJsonBase* in, JtScanCtx* ctx, bool& is_null_value); - void set_in(ObIJsonBase* input) { in_ = input; } + + void proc_query_on_error(int& err_code, bool& is_null); // fixed member diff --git a/src/sql/engine/expr/ob_expr_json_func_helper.cpp b/src/sql/engine/expr/ob_expr_json_func_helper.cpp index 0527fd9d1..81d323415 100644 --- a/src/sql/engine/expr/ob_expr_json_func_helper.cpp +++ b/src/sql/engine/expr/ob_expr_json_func_helper.cpp @@ -1628,7 +1628,7 @@ int ObJsonExprHelper::check_item_func_with_return(ObJsonPathNodeType path_type, return ret; } -int ObJsonExprHelper::get_ascii_type(const ObExprResType param_type2, int64_t &dst_type) +int ObJsonExprHelper::get_expr_option_value(const ObExprResType param_type2, int64_t &dst_type) { INIT_SUCC(ret); if (!param_type2.is_int() && !param_type2.get_param().is_int()) { @@ -1703,6 +1703,70 @@ int ObJsonExprHelper::calc_asciistr_in_expr(const ObString &src, return ret; } +int ObJsonExprHelper::parse_asc_option(ObExprResType& asc_type, + ObExprResType& type1, + ObExprResType& res_type, + ObExprTypeCtx& type_ctx) +{ + INIT_SUCC(ret); + ObExprResType temp_type; + ObObjType doc_type = type1.get_type(); + int64_t asc_option = 0; + + if (asc_type.get_type() != ObIntType) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN(" param type is unexpected", K(asc_type.get_type())); + } else if (OB_FAIL(ObJsonExprHelper::get_expr_option_value(asc_type, asc_option))) { + LOG_WARN("get ascii type fail", K(ret)); + } else if (asc_option == 1 + && ob_is_string_type(doc_type) + && ((res_type.is_character_type() && (res_type.get_length_semantics() == LS_CHAR || res_type.get_length_semantics() == LS_BYTE)) + || res_type.is_lob())) { + type1.set_calc_length_semantics(res_type.get_length_semantics()); + ObLength length = 0; + ObExprResType temp_type; + temp_type.set_meta(type1.get_calc_meta()); + temp_type.set_length_semantics(res_type.get_length_semantics()); + if (OB_FAIL(ObExprResultTypeUtil::deduce_max_string_length_oracle(type_ctx.get_session()->get_dtc_params(), + type1, + temp_type, + length))) { + LOG_WARN("fail to deduce max string length.", K(ret), K(temp_type), K(type1)); + } else { + type1.set_calc_length(length); + res_type.set_length(length * 10); + } + } + + return ret; +} + +int ObJsonExprHelper::character2_ascii_string(common::ObIAllocator *allocator, + const ObExpr &expr, + ObEvalCtx &ctx, + ObString& result, + int32_t reserve_len) +{ + INIT_SUCC(ret); + char *buf = NULL; + 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(allocator->alloc(buf_len + reserve_len)))) + || (OB_ISNULL(buf = static_cast(expr.get_str_res_mem(ctx, buf_len + reserve_len))))) { + 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, + expr.datum_meta_.cs_type_, + expr.datum_meta_.cs_type_, + buf, buf_len, length))) { + LOG_WARN("fail to calc unistr", K(ret)); + } else { + result.assign_ptr(buf, length); + } + return ret; +} + int ObJsonExprHelper::pre_default_value_check(ObObjType dst_type, ObString time_str, ObObjType val_type) { INIT_SUCC(ret); size_t len; diff --git a/src/sql/engine/expr/ob_expr_json_func_helper.h b/src/sql/engine/expr/ob_expr_json_func_helper.h index 64545ae3b..995e1738d 100644 --- a/src/sql/engine/expr/ob_expr_json_func_helper.h +++ b/src/sql/engine/expr/ob_expr_json_func_helper.h @@ -219,7 +219,7 @@ public: static int check_item_func_with_return(ObJsonPathNodeType path_type, ObObjType dst_type, common::ObCollationType dst_coll_type, int8_t JSON_EXPR_FLAG); static int set_dest_type(ObExprResType &type1, ObExprResType &type, ObExprResType &dst_type, ObExprTypeCtx &type_ctx); - static int get_ascii_type(const ObExprResType param_type2, int64_t &dst_type); + static int get_expr_option_value(const ObExprResType param_type2, int64_t &dst_type); static int calc_asciistr_in_expr(const ObString &src, const ObCollationType src_cs_type, const ObCollationType dst_cs_type, @@ -238,7 +238,17 @@ public: ObExprResType& json_res_type, ObExprResType& result_type, ObExprTypeCtx& type_ctx); + static int parse_asc_option(ObExprResType& asc, + ObExprResType& type1, + ObExprResType& res_type, + ObExprTypeCtx& type_ctx); static int pre_default_value_check(ObObjType dst_type, ObString time_str, ObObjType val_type); + + static int character2_ascii_string(common::ObIAllocator *allocator, + const ObExpr &expr, + ObEvalCtx &ctx, + ObString& result, + int32_t reserve_len = 0); private: const static uint32_t RESERVE_MIN_BUFF_SIZE = 32; DISALLOW_COPY_AND_ASSIGN(ObJsonExprHelper); diff --git a/src/sql/engine/expr/ob_expr_json_merge_patch.cpp b/src/sql/engine/expr/ob_expr_json_merge_patch.cpp index 5f1b7df11..41379da91 100644 --- a/src/sql/engine/expr/ob_expr_json_merge_patch.cpp +++ b/src/sql/engine/expr/ob_expr_json_merge_patch.cpp @@ -83,9 +83,11 @@ int ObExprJsonMergePatch::calc_result_typeN(ObExprResType& type, } // returning type : 2 - if (OB_SUCC(ret) - && OB_FAIL(ObJsonExprHelper::parse_res_type(types_stack[0], types_stack[2], type, type_ctx))) { + if (OB_FAIL(ret)) { + } else if (OB_FAIL(ObJsonExprHelper::parse_res_type(types_stack[0], types_stack[2], type, type_ctx))) { LOG_WARN("fail to parse res type.", K(ret)); + } else if (OB_FAIL(ObJsonExprHelper::parse_asc_option(types_stack[4], types_stack[0], type, type_ctx))) { + LOG_WARN("fail to parse asc option.", K(ret)); } for (size_t i = 2; OB_SUCC(ret) && i < param_num; ++i) { @@ -186,6 +188,7 @@ int ObExprJsonMergePatch::eval_ora_json_merge_patch(const ObExpr &expr, ObEvalCt bool is_cover_error = false; int err_code = 0; + // eval option original int64 type value int64_t opt_array[OPT_MAX_ID] = {0}; for (size_t i = 2; OB_SUCC(ret) && i < expr.arg_cnt_; i++) { ObDatum *opt_datum = NULL; @@ -205,8 +208,13 @@ int ObExprJsonMergePatch::eval_ora_json_merge_patch(const ObExpr &expr, ObEvalCt } } - int64_t& err_type = opt_array[OPT_ERROR_ID]; - int64_t& return_type = opt_array[OPT_RES_TYPE_ID]; + const int64_t& is_pretty = opt_array[OPT_PRETTY_ID]; + const int64_t& is_trunc = opt_array[OPT_TRUNC_ID]; + const int64_t& is_asc = opt_array[OPT_ASCII_ID]; + const int64_t& err_type = opt_array[OPT_ERROR_ID]; + const int64_t& return_type = opt_array[OPT_RES_TYPE_ID]; + + // some constraint check ObObjType dst_type; int32_t dst_len; // bugfix: https://work.aone.alibaba-inc.com/issue/47046350 if (OB_FAIL(ret)) { @@ -219,9 +227,8 @@ int ObExprJsonMergePatch::eval_ora_json_merge_patch(const ObExpr &expr, ObEvalCt } } 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)); - } - - if ((expr.datum_meta_.cs_type_ == CS_TYPE_BINARY || dst_type == ObJsonType) && (opt_array[OPT_PRETTY_ID] > 0 || opt_array[OPT_ASCII_ID] > 0)) { + } 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)) { + // ascii or pretty only support text ret = OB_ERR_NON_TEXT_RET_NOTSUPPORT; LOG_WARN("ASCII or PRETTY not supported for non-textual return data type", K(ret)); } @@ -287,27 +294,38 @@ int ObExprJsonMergePatch::eval_ora_json_merge_patch(const ObExpr &expr, ObEvalCt } else { ObJsonBuffer jbuf(&temp_allocator); ObString res_string; + bool is_res_blob = expr.datum_meta_.cs_type_ == CS_TYPE_BINARY && dst_type == ObLongTextType; + if (dst_type == ObJsonType) { if (OB_FAIL(j_base->get_raw_binary(res_string, &temp_allocator))) { LOG_WARN("failed: get json raw binary", K(ret)); } } else { - int64_t& is_pretty = opt_array[OPT_PRETTY_ID]; - int64_t& is_trunc = opt_array[OPT_TRUNC_ID]; bool is_quote = j_base->json_type() == ObJsonNodeType::J_STRING; if (OB_FAIL(j_base->print(jbuf, is_quote, is_pretty > 0))) { LOG_WARN("json binary to string failed", K(ret)); } else if (jbuf.empty()) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("allocate memory for result failed", K(ret)); - } else if (is_trunc && dst_type != ObLongTextType) { - if (jbuf.length() > dst_len) { + } + + 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 (is_trunc && dst_type != ObLongTextType) { + if (tmp_val.length() > dst_len) { if (ob_is_string_type(dst_type)) { int64_t char_len; // not used int64_t real_dst_len; - real_dst_len = ObCharset::max_bytes_charpos(expr.datum_meta_.cs_type_, jbuf.ptr(), - jbuf.length(), dst_len, char_len); - jbuf.set_length(real_dst_len); + real_dst_len = ObCharset::max_bytes_charpos(expr.datum_meta_.cs_type_, tmp_val.ptr(), + tmp_val.length(), dst_len, char_len); + + tmp_val.assign_ptr(tmp_val.ptr(), real_dst_len); // compact with oracle: https://work.aone.alibaba-inc.com/issue/46640577 if (real_dst_len != dst_len && real_dst_len > 0) { // get last char @@ -315,17 +333,17 @@ int ObExprJsonMergePatch::eval_ora_json_merge_patch(const ObExpr &expr, ObEvalCt bool append_quote = false; int64_t last_char_len = 0; if (OB_FAIL(ObCharset::last_valid_char(expr.datum_meta_.cs_type_, - jbuf.ptr(), jbuf.length(), + tmp_val.ptr(), tmp_val.length(), last_char_len))) { - LOG_WARN("failed to get last char", K(ret), K(expr.datum_meta_.cs_type_), K(jbuf)); + LOG_WARN("failed to get last char", K(ret), K(expr.datum_meta_.cs_type_), K(tmp_val)); } else if (last_char_len == 1) { if (real_dst_len > 1) { if (OB_FAIL(ObCharset::last_valid_char(expr.datum_meta_.cs_type_, - jbuf.ptr(), jbuf.length() - 1, + tmp_val.ptr(), tmp_val.length() - 1, last_char_len))) { - LOG_WARN("failed to get second last char", K(ret), K(expr.datum_meta_.cs_type_), K(jbuf)); + LOG_WARN("failed to get second last char", K(ret), K(expr.datum_meta_.cs_type_), K(tmp_val)); } else if (last_char_len == 1) { - if ((jbuf.ptr()[real_dst_len - 1] == '"') && (jbuf.ptr()[real_dst_len - 2] != '"')) { + if ((tmp_val.ptr()[real_dst_len - 1] == '"') && (tmp_val.ptr()[real_dst_len - 2] != '"')) { append_quote = true; } } @@ -334,17 +352,18 @@ int ObExprJsonMergePatch::eval_ora_json_merge_patch(const ObExpr &expr, ObEvalCt } } if (OB_FAIL(ret)) { - } else if (append_quote && OB_FAIL(jbuf.append("\"", 1))) { - LOG_WARN("fail to append \"", K(ret)); + } else if (append_quote) { + // already reserve 1 byte calling character2_ascii_string + *(tmp_val.ptr() + tmp_val.length()) = '\"'; + tmp_val.assign_ptr(tmp_val.ptr(), tmp_val.length() + 1); } } } else { - jbuf.set_length(dst_len); + tmp_val.assign_ptr(tmp_val.ptr(), dst_len); } - } } - res_string.assign_ptr(jbuf.ptr(), jbuf.length()); + res_string.assign_ptr(tmp_val.ptr(), tmp_val.length()); } if (OB_SUCC(ret)) { diff --git a/src/sql/engine/expr/ob_expr_json_query.cpp b/src/sql/engine/expr/ob_expr_json_query.cpp index b4a9a95db..baa3c686d 100644 --- a/src/sql/engine/expr/ob_expr_json_query.cpp +++ b/src/sql/engine/expr/ob_expr_json_query.cpp @@ -133,23 +133,12 @@ int ObExprJsonQuery::calc_result_typeN(ObExprResType& type, types_stack[i].set_calc_type(ObIntType); } } - int64_t asc_type = 0; - if (OB_SUCC(ret) && lib::is_oracle_mode() && OB_FAIL(ObJsonExprHelper::get_ascii_type(types_stack[4], asc_type))) { - LOG_WARN("get ascii type fail", K(ret)); - } else if (asc_type > 0 && ob_is_string_type(doc_type) && ((type.is_character_type() - && (type.get_length_semantics() == LS_CHAR || type.get_length_semantics() == LS_BYTE)) || type.is_lob())) { - types_stack[0].set_calc_length_semantics(type.get_length_semantics()); - type.set_calc_collation_type(type.is_string_type() ? type.get_collation_type() : CS_TYPE_UTF8MB4_BIN); - ObLength length = 0; - ObExprResType temp_type; - temp_type.set_meta(types_stack[0].get_calc_meta()); - temp_type.set_length_semantics(type.get_length_semantics()); - OZ (ObExprResultTypeUtil::deduce_max_string_length_oracle(type_ctx.get_session()->get_dtc_params(), - types_stack[0], - temp_type, - length)); - types_stack[0].set_calc_length(length); - type.set_length(length * 10); + + // ASCII clause + if (OB_SUCC(ret)) { + if (OB_FAIL(ObJsonExprHelper::parse_asc_option(types_stack[4], types_stack[0], type, type_ctx))) { + LOG_WARN("fail to parse asc option.", K(ret)); + } } } return ret; diff --git a/src/sql/engine/expr/ob_expr_json_value.cpp b/src/sql/engine/expr/ob_expr_json_value.cpp index b0c56039e..f676624ce 100644 --- a/src/sql/engine/expr/ob_expr_json_value.cpp +++ b/src/sql/engine/expr/ob_expr_json_value.cpp @@ -67,6 +67,7 @@ int ObExprJsonValue::calc_result_typeN(ObExprResType& type, ret = OB_ERR_PARAM_SIZE; LOG_WARN("invalid param number", K(ret), K(param_num)); } else { + bool is_oracle_mode = lib::is_oracle_mode(); //type.set_json(); // json doc : 0 ObObjType doc_type = types_stack[json_value_param_json_doc].get_type(); @@ -81,7 +82,7 @@ int ObExprJsonValue::calc_result_typeN(ObExprResType& type, LOG_WARN("Invalid type for json doc", K(doc_type), K(ret)); } } else if (ob_is_string_type(doc_type)) { - if (lib::is_oracle_mode()) { + if (is_oracle_mode) { if (types_stack[json_value_param_json_doc].get_collation_type() == CS_TYPE_BINARY) { types_stack[json_value_param_json_doc].set_calc_collation_type(CS_TYPE_BINARY); } else if (types_stack[json_value_param_json_doc].get_charset_type() != CHARSET_UTF8MB4) { @@ -133,30 +134,9 @@ int ObExprJsonValue::calc_result_typeN(ObExprResType& type, } // ascii 3 - int64_t asc_type = 0; - if (OB_SUCC(ret)) { - ObExprResType temp_type; - if (types_stack[json_value_param_opt_ascii].get_type() == ObNullType) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN(" param type is unexpected", K(types_stack[json_value_param_opt_ascii].get_type())); - } else if (types_stack[json_value_param_opt_ascii].get_type() != ObIntType) { - types_stack[json_value_param_opt_ascii].set_calc_type(ObIntType); - } - if (OB_SUCC(ret) && lib::is_oracle_mode() && OB_FAIL(ObJsonExprHelper::get_ascii_type(types_stack[json_value_param_opt_ascii], asc_type))) { - LOG_WARN("get ascii type fail", K(ret)); - } else if (asc_type == 1 && ob_is_string_type(doc_type) && ((type.is_character_type() - && (type.get_length_semantics() == LS_CHAR || type.get_length_semantics() == LS_BYTE)) || type.is_lob())) { - types_stack[0].set_calc_length_semantics(type.get_length_semantics()); - ObLength length = 0; - ObExprResType temp_type; - temp_type.set_meta(types_stack[0].get_calc_meta()); - temp_type.set_length_semantics(type.get_length_semantics()); - OZ (ObExprResultTypeUtil::deduce_max_string_length_oracle(type_ctx.get_session()->get_dtc_params(), - types_stack[0], - temp_type, - length)); - types_stack[0].set_calc_length(length); - type.set_length(length * 10); + if (OB_SUCC(ret) && is_oracle_mode) { + if (OB_FAIL(ObJsonExprHelper::parse_asc_option(types_stack[3], types_stack[0], type, type_ctx))) { + LOG_WARN("fail to parse asc option.", K(ret)); } } diff --git a/src/sql/resolver/dml/ob_dml_resolver.cpp b/src/sql/resolver/dml/ob_dml_resolver.cpp index 4967acf46..956f93889 100755 --- a/src/sql/resolver/dml/ob_dml_resolver.cpp +++ b/src/sql/resolver/dml/ob_dml_resolver.cpp @@ -7772,6 +7772,7 @@ int ObDMLResolver::resolve_json_table_column_type(const ParseNode &parse_tree, data_type.set_obj_type(obj_type); ObCollationType coll_type = static_cast(parse_tree.int16_values_[OB_NODE_CAST_COLL_IDX]); if (CS_TYPE_INVALID != coll_type) { + data_type.set_collation_type(coll_type); } else if (OB_ISNULL(session_info_)) { // use connection_collation. for cast('a' as char) ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpected collation type", K(ret));