From 87223f9a44c3b1c41e95712b03795358f49ae9c7 Mon Sep 17 00:00:00 2001 From: obdev Date: Thu, 2 Mar 2023 19:18:38 +0000 Subject: [PATCH] [BUGFIX] fix expr to str support return text --- src/sql/engine/expr/ob_expr_type_to_str.cpp | 52 +++++++++++-------- src/sql/resolver/expr/ob_raw_expr_util.cpp | 6 ++- src/sql/resolver/expr/ob_raw_expr_util.h | 3 +- .../expr/ob_raw_expr_wrap_enum_set.cpp | 16 +++--- 4 files changed, 46 insertions(+), 31 deletions(-) diff --git a/src/sql/engine/expr/ob_expr_type_to_str.cpp b/src/sql/engine/expr/ob_expr_type_to_str.cpp index 389e82d5e..6681f6095 100644 --- a/src/sql/engine/expr/ob_expr_type_to_str.cpp +++ b/src/sql/engine/expr/ob_expr_type_to_str.cpp @@ -16,6 +16,7 @@ #include "lib/string/ob_sql_string.h" #include "lib/container/ob_array_serialization.h" #include "sql/code_generator/ob_static_engine_expr_cg.h" +#include "sql/engine/expr/ob_expr_lob_utils.h" using namespace oceanbase::common; namespace oceanbase @@ -57,7 +58,11 @@ int ObExprTypeToStr::calc_result_type2(ObExprResType &type, UNUSED(type_ctx); UNUSED(type2); int ret = OB_SUCCESS; - type.set_type(ObVarcharType); + if (get_raw_expr()->get_extra() == 1) { + type.set_type(ObLongTextType); + } else { + type.set_type(ObVarcharType); + } type.set_collation_type(type1.get_collation_type()); type.set_collation_level(CS_LEVEL_IMPLICIT); type.set_length(type1.get_length()); @@ -281,9 +286,9 @@ int ObExprSetToStr::calc_to_str_expr(const ObExpr &expr, ObEvalCtx &ctx, ObDatum if (OB_SUCC(ret)) { int64_t pos = 0; char *buf = NULL; - if (OB_ISNULL(buf = expr.get_str_res_mem(ctx, need_size))) { - ret = OB_ALLOCATE_MEMORY_FAILED; - LOG_WARN("alloc memory failed", K(ret), K(buf), K(need_size)); + ObTextStringDatumResult text_result(expr.datum_meta_.type_, &expr, &ctx, &res_datum); + if (OB_FAIL(text_result.init(need_size))) { + LOG_WARN("init lob result failed", K(ret), K(need_size)); } else { uint64_t index = 1ULL; for (int64_t i = 0; @@ -291,20 +296,19 @@ int ObExprSetToStr::calc_to_str_expr(const ObExpr &expr, ObEvalCtx &ctx, ObDatum ++i, index = index << 1) { if (set_val & (index)) { const ObString &element_val = str_values.at(i); - MEMCPY(buf + pos, element_val.ptr(), element_val.length()); - pos += element_val.length(); - if ((i + 1) < element_num && (i + 1) < EFFECTIVE_COUNT && + if (OB_FAIL(text_result.append(element_val))) { + LOG_WARN("fail to append str to lob result", K(ret), K(element_val)); + } else if ((i + 1) < element_num && (i + 1) < EFFECTIVE_COUNT && ((index << 1) <= set_val)) { // skip setting last seperator - MEMCPY(buf + pos, sep.ptr(), sep.length()); - pos += sep.length(); + if (OB_FAIL(text_result.append(sep))) { + LOG_WARN("fail to append str to lob result", K(ret), K(sep)); + } } } } - if (0 == pos) { - res_datum.set_enumset_inner(buf, static_cast(pos)); - } else { - res_datum.set_enumset_inner(buf, static_cast(pos)); + if (OB_SUCC(ret)) { + text_result.set_result(); } } } @@ -357,25 +361,27 @@ int ObExprEnumToStr::calc_to_str_expr(const ObExpr &expr, ObEvalCtx &ctx, ObDatu uint64_t enum_val = enum_datum->get_enum(); int64_t element_num = str_values.count(); uint64_t element_idx = enum_val - 1; + ObString element_str; if (OB_UNLIKELY(element_num < 1)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid element num", K(element_num), K(element_num)); } else if (0 == enum_val) { - ObString empty_string; - res_datum.set_enumset_inner(empty_string.make_empty_string()); + // ObString empty_string; + // res_datum.set_enumset_inner(empty_string.make_empty_string()); } else if (OB_UNLIKELY(element_idx > element_num - 1)) { ret = OB_ERR_DATA_TRUNCATED; LOG_WARN("enum value out of range", K(element_idx), K(element_num), K(ret)); } else { - const ObString &element_str = str_values.at(element_idx); - if (element_str.empty()) { - res_datum.set_enumset_inner(element_str); - } else if (OB_ISNULL(buf = expr.get_str_res_mem(ctx, element_str.length()))) { - ret = OB_ALLOCATE_MEMORY_FAILED; - LOG_WARN("alloc memory failed", K(ret), K(buf), K(element_str.length())); + element_str = str_values.at(element_idx); + } + if (OB_SUCC(ret)) { + ObTextStringDatumResult text_result(expr.datum_meta_.type_, &expr, &ctx, &res_datum); + if (OB_FAIL(text_result.init(element_str.length()))) { + LOG_WARN("init lob result failed"); + } else if (OB_FAIL(text_result.append(element_str.ptr(), element_str.length()))) { + LOG_WARN("failed to append realdata", K(ret), K(text_result)); } else { - MEMCPY(buf, element_str.ptr(), element_str.length()); - res_datum.set_enumset_inner(buf, static_cast(element_str.length())); + text_result.set_result(); } } } diff --git a/src/sql/resolver/expr/ob_raw_expr_util.cpp b/src/sql/resolver/expr/ob_raw_expr_util.cpp index 1ab6941cf..da342ee56 100644 --- a/src/sql/resolver/expr/ob_raw_expr_util.cpp +++ b/src/sql/resolver/expr/ob_raw_expr_util.cpp @@ -3803,7 +3803,8 @@ int ObRawExprUtils::create_type_to_str_expr(ObRawExprFactory &expr_factory, ObRawExpr *src_expr, ObSysFunRawExpr *&out_expr, ObSQLSessionInfo *session_info, - bool is_type_to_str) + bool is_type_to_str, + ObObjType dst_type) { int ret = OB_SUCCESS; ObExprOperator *op = NULL; @@ -3839,6 +3840,9 @@ int ObRawExprUtils::create_type_to_str_expr(ObRawExprFactory &expr_factory, LOG_ERROR("allocate expr operator failed", K(ret)); } else { out_expr->set_func_name(ObString::make_string(func_name)); + if (is_lob_storage(dst_type)) { + out_expr->set_extra(1); + } } ObConstRawExpr *col_accuracy_expr = NULL; diff --git a/src/sql/resolver/expr/ob_raw_expr_util.h b/src/sql/resolver/expr/ob_raw_expr_util.h index 708ce1a0b..584016239 100644 --- a/src/sql/resolver/expr/ob_raw_expr_util.h +++ b/src/sql/resolver/expr/ob_raw_expr_util.h @@ -474,7 +474,8 @@ public: ObRawExpr *src_expr, ObSysFunRawExpr *&out_expr, ObSQLSessionInfo *session_info, - bool is_type_to_str); + bool is_type_to_str, + ObObjType dst_type = ObMaxType); static int get_exec_param_expr(ObRawExprFactory &expr_factory, ObQueryRefRawExpr *query_ref, diff --git a/src/sql/resolver/expr/ob_raw_expr_wrap_enum_set.cpp b/src/sql/resolver/expr/ob_raw_expr_wrap_enum_set.cpp index e2f42ebaf..d2b74bb46 100644 --- a/src/sql/resolver/expr/ob_raw_expr_wrap_enum_set.cpp +++ b/src/sql/resolver/expr/ob_raw_expr_wrap_enum_set.cpp @@ -433,10 +433,12 @@ int ObRawExprWrapEnumSet::check_and_wrap_left(ObRawExpr &expr, int64_t idx, bool need_numberic = false; bool need_varchar = false; const bool is_same_type_need = false; + ObObjType dest_type = ObMaxType; for (int64_t i = 0; OB_SUCC(ret) && i < target_num && !(need_numberic && need_varchar); ++i) { bool need_wrap = false; + dest_type = cmp_types.at(row_dimension * i + idx).get_type(); if (OB_FAIL(ObRawExprUtils::need_wrap_to_string(expr_type, - cmp_types.at(row_dimension * i + idx).get_type(), + dest_type, is_same_type_need, need_wrap))) { LOG_WARN("failed to check whether need wrap", K(i), K(expr), K(ret)); } else if (need_wrap) { @@ -449,7 +451,7 @@ int ObRawExprWrapEnumSet::check_and_wrap_left(ObRawExpr &expr, int64_t idx, if (OB_SUCC(ret) && need_varchar) { const bool is_type_to_str = !need_numberic; if (OB_FAIL(ObRawExprUtils::create_type_to_str_expr(expr_factory_, &expr, - wrapped_expr, my_session_, is_type_to_str))) { + wrapped_expr, my_session_, is_type_to_str, dest_type))) { LOG_WARN("failed to create_type_to_string_expr",K(expr), K(ret)); } } @@ -633,7 +635,7 @@ int ObRawExprWrapEnumSet::wrap_type_to_str_if_necessary(ObRawExpr *expr, is_same_need, need_wrap))) { LOG_WARN("failed to check_need_wrap_to_string", K(ret)); } else if (need_wrap && OB_FAIL(ObRawExprUtils::create_type_to_str_expr(expr_factory_, expr, - wrapped_expr, my_session_, is_type_to_str))) { + wrapped_expr, my_session_, is_type_to_str, dest_type))) { LOG_WARN("failed to create_type_to_string_expr", KPC(expr), K(is_type_to_str), K(ret)); } else { LOG_DEBUG("finish wrap_type_to_str_if_necessary", K(ret), K(need_wrap), K(dest_type), KPC(expr), @@ -663,8 +665,9 @@ int ObRawExprWrapEnumSet::visit(ObCaseOpRawExpr &expr) bool need_numberic = false; bool need_varchar = false; ObObjType arg_type = arg_param_expr->get_data_type(); + ObObjType calc_type = ObMaxType; for (int64_t i = 0; OB_SUCC(ret) && i < expr.get_when_expr_size(); ++i) { - ObObjType calc_type = expr.get_input_types().at(i + 1).get_calc_type(); + calc_type = expr.get_input_types().at(i + 1).get_calc_type(); wrapped_expr = NULL; ObRawExpr *when_expr = expr.get_when_param_expr(i); bool need_wrap = false; @@ -685,7 +688,7 @@ int ObRawExprWrapEnumSet::visit(ObCaseOpRawExpr &expr) const bool is_type_to_str = !need_numberic; wrapped_expr = NULL; if (OB_FAIL(ObRawExprUtils::create_type_to_str_expr(expr_factory_, arg_param_expr, - wrapped_expr, my_session_, is_type_to_str))) { + wrapped_expr, my_session_, is_type_to_str, calc_type))) { LOG_WARN("failed to create_type_to_string_expr", K(ret)); } else if (OB_ISNULL(wrapped_expr)) { ret = OB_ERR_UNEXPECTED; @@ -870,7 +873,8 @@ int ObRawExprWrapEnumSet::wrap_nullif_expr(ObSysFunRawExpr &expr) left_param, wrapped_expr, my_session_, - is_type_to_str))) { + is_type_to_str, + calc_type))) { LOG_WARN("failed to create_type_to_string_expr", K(ret)); } else if ((NULL != wrapped_expr) && OB_FAIL(expr.replace_param_expr(0, wrapped_expr))) { LOG_WARN("failed to replace left param expr", K(ret));