bugfix for string_to_array and support unsigned float and double type in array
This commit is contained in:
parent
226981c115
commit
3f08f92f54
4
deps/oblib/src/lib/udt/ob_array_type.cpp
vendored
4
deps/oblib/src/lib/udt/ob_array_type.cpp
vendored
@ -102,10 +102,12 @@ int ObArrayTypeObjFactory::construct(common::ObIAllocator &alloc, const ObCollec
|
||||
CONSTRUCT_FIXED_ARRAY_OBJ(uint64_t);
|
||||
break;
|
||||
}
|
||||
case ObUFloatType:
|
||||
case ObFloatType: {
|
||||
CONSTRUCT_FIXED_ARRAY_OBJ(float);
|
||||
break;
|
||||
}
|
||||
case ObUDoubleType:
|
||||
case ObDoubleType: {
|
||||
CONSTRUCT_FIXED_ARRAY_OBJ(double);
|
||||
break;
|
||||
@ -1275,7 +1277,7 @@ int ObArrayNested::print_element(const ObCollectionTypeBase *elem_type, ObString
|
||||
is_first_elem = false;
|
||||
uint32_t start = offset_at(i, offsets_);
|
||||
uint32_t elem_cnt = offsets_[i] - start;
|
||||
if (OB_FAIL(data_->print_element(array_type->element_type_, format_str, start, elem_cnt, delimiter, null_str))) {
|
||||
if (OB_FAIL(data_->print_element(array_type->element_type_, format_str, start, elem_cnt, delimiter, has_null_str, null_str))) {
|
||||
OB_LOG(WARN, "fail to append string to format_str", K(ret));
|
||||
}
|
||||
}
|
||||
|
8
deps/oblib/src/lib/udt/ob_array_type.h
vendored
8
deps/oblib/src/lib/udt/ob_array_type.h
vendored
@ -358,14 +358,16 @@ public :
|
||||
break;
|
||||
}
|
||||
case ObFloatType:
|
||||
case ObDoubleType: {
|
||||
int buf_size = obj_type == ObFloatType ? FLOAT_TO_STRING_CONVERSION_BUFFER_SIZE : DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE;
|
||||
case ObUFloatType:
|
||||
case ObDoubleType:
|
||||
case ObUDoubleType: {
|
||||
int buf_size = ob_is_float_tc(obj_type) ? FLOAT_TO_STRING_CONVERSION_BUFFER_SIZE : DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE;
|
||||
if (OB_FAIL(format_str.reserve(buf_size + 1))) {
|
||||
OB_LOG(WARN, "fail to reserve memory for format_str", K(ret));
|
||||
} else {
|
||||
char *start = format_str.ptr() + format_str.length();
|
||||
uint64_t len = ob_gcvt(data_[i],
|
||||
obj_type == ObFloatType ? ob_gcvt_arg_type::OB_GCVT_ARG_FLOAT : ob_gcvt_arg_type::OB_GCVT_ARG_DOUBLE,
|
||||
ob_is_float_tc(obj_type) ? ob_gcvt_arg_type::OB_GCVT_ARG_FLOAT : ob_gcvt_arg_type::OB_GCVT_ARG_DOUBLE,
|
||||
buf_size, start, NULL);
|
||||
if (OB_FAIL(format_str.set_length(format_str.length() + len))) {
|
||||
OB_LOG(WARN, "fail to set format_str len", K(ret), K(format_str.length()), K(len));
|
||||
|
2
deps/oblib/src/lib/udt/ob_array_utils.cpp
vendored
2
deps/oblib/src/lib/udt/ob_array_utils.cpp
vendored
@ -231,10 +231,12 @@ int ObArrayUtil::append(ObIArrayType &array, const ObObjType elem_type, const Ob
|
||||
FIXED_SIZE_ARRAY_APPEND(uint64_t, get_uint64);
|
||||
break;
|
||||
}
|
||||
case ObUFloatType:
|
||||
case ObFloatType: {
|
||||
FIXED_SIZE_ARRAY_APPEND(float, get_float);
|
||||
break;
|
||||
}
|
||||
case ObUDoubleType:
|
||||
case ObDoubleType: {
|
||||
FIXED_SIZE_ARRAY_APPEND(double, get_double);
|
||||
break;
|
||||
|
@ -265,6 +265,12 @@ int ObSqlCollectionInfo::set_element_meta_unsigned(ObCollectionBasicType *meta_i
|
||||
case ObIntType:
|
||||
meta_info->basic_meta_.meta_.set_uint64();
|
||||
break;
|
||||
case ObFloatType:
|
||||
meta_info->basic_meta_.meta_.set_ufloat();
|
||||
break;
|
||||
case ObDoubleType:
|
||||
meta_info->basic_meta_.meta_.set_udouble();
|
||||
break;
|
||||
default:
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("invalid meta info", K(ret), K(meta_info));
|
||||
|
@ -154,11 +154,13 @@ int ObArrayCastUtils::cast_get_element(ObIArrayType *src, const ObCollectionBasi
|
||||
src_elem.set_varchar((*arr)[idx]);
|
||||
break;
|
||||
}
|
||||
case ObUDoubleType:
|
||||
case ObDoubleType: {
|
||||
ObArrayFixedSize<double> *arr = static_cast<ObArrayFixedSize<double> *>(src);
|
||||
src_elem.set_double((*arr)[idx]);
|
||||
break;
|
||||
}
|
||||
case ObUFloatType:
|
||||
case ObFloatType: {
|
||||
ObArrayFixedSize<float> *arr = static_cast<ObArrayFixedSize<float> *>(src);
|
||||
src_elem.set_float((*arr)[idx]);
|
||||
@ -251,6 +253,7 @@ int ObArrayCastUtils::cast_add_element(common::ObIAllocator &alloc, ObObj &src_e
|
||||
// to do
|
||||
break;
|
||||
}
|
||||
case ObUFloatType:
|
||||
case ObFloatType: {
|
||||
ObArrayFixedSize<float> *dst_arr = static_cast<ObArrayFixedSize<float> *>(dst);
|
||||
if (OB_FAIL(dst_arr->push_back(res.get_float()))) {
|
||||
@ -258,6 +261,7 @@ int ObArrayCastUtils::cast_add_element(common::ObIAllocator &alloc, ObObj &src_e
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ObUDoubleType:
|
||||
case ObDoubleType: {
|
||||
ObArrayFixedSize<double> *dst_arr = static_cast<ObArrayFixedSize<double> *>(dst);
|
||||
if (OB_FAIL(dst_arr->push_back(res.get_double()))) {
|
||||
|
@ -918,8 +918,12 @@ int ObExprResultTypeUtil::get_array_calc_type(ObExecContext *exec_ctx,
|
||||
ObObjType coll_calc_type = ARITH_RESULT_TYPE[type1][type2];
|
||||
if (ob_is_int_uint(ob_obj_type_class(type1), ob_obj_type_class(type2))) {
|
||||
coll_calc_type = ObIntType;
|
||||
} else if (type1 == ObFloatType && type2 == ObFloatType) {
|
||||
coll_calc_type = ObFloatType;
|
||||
} else if (ob_is_float_tc(type1) && ob_is_float_tc(type2)) {
|
||||
if (type1 == ObFloatType || type2 == ObFloatType) {
|
||||
coll_calc_type = ObFloatType;
|
||||
} else {
|
||||
coll_calc_type = ObUFloatType;
|
||||
}
|
||||
} else if (ob_is_null(type1)) {
|
||||
coll_calc_type = type2;
|
||||
} else if (ob_is_null(type2)) {
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "sql/engine/expr/ob_array_expr_utils.h"
|
||||
#include "sql/engine/ob_exec_context.h"
|
||||
#include "sql/engine/expr/ob_expr_result_type_util.h"
|
||||
#include "lib/charset/ob_ctype.h"
|
||||
|
||||
using namespace oceanbase::common;
|
||||
using namespace oceanbase::sql;
|
||||
@ -51,6 +52,8 @@ int ObExprStringToArray::calc_result_typeN(ObExprResType &type,
|
||||
if (!ob_is_string_tc(types[i].get_type()) && !ob_is_null(types[i].get_type())) {
|
||||
ret = OB_ERR_INVALID_TYPE_FOR_OP;
|
||||
LOG_USER_ERROR(OB_ERR_INVALID_TYPE_FOR_OP, "VARCHAR", ob_obj_type_str(types[i].get_type()));
|
||||
} else {
|
||||
types[i].set_calc_collation_type(ObCharset::get_system_collation());
|
||||
}
|
||||
}
|
||||
|
||||
@ -73,10 +76,11 @@ int ObExprStringToArray::eval_string_to_array(const ObExpr &expr, ObEvalCtx &ctx
|
||||
ObEvalCtx::TempAllocGuard tmp_alloc_g(ctx);
|
||||
common::ObArenaAllocator &tmp_allocator = tmp_alloc_g.get_allocator();
|
||||
uint16_t subschema_id = expr.obj_meta_.get_subschema_id();
|
||||
ObDatum *arr_datum = NULL;
|
||||
ObCollationType cs_type = expr.args_[0]->datum_meta_.cs_type_;;
|
||||
ObDatum *arr_str_datum = NULL;
|
||||
ObDatum *delimiter_datum = NULL;
|
||||
ObDatum *null_str_datum = NULL;
|
||||
if (OB_FAIL(expr.args_[0]->eval(ctx, arr_datum))) {
|
||||
if (OB_FAIL(expr.args_[0]->eval(ctx, arr_str_datum))) {
|
||||
LOG_WARN("eval source array failed", K(ret));
|
||||
} else if (OB_FAIL(expr.args_[1]->eval(ctx, delimiter_datum))) {
|
||||
LOG_WARN("eval delimiter string failed", K(ret));
|
||||
@ -91,9 +95,9 @@ int ObExprStringToArray::eval_string_to_array(const ObExpr &expr, ObEvalCtx &ctx
|
||||
bool has_null_str = false;
|
||||
ObIArrayType *arr_obj = NULL;
|
||||
ObArrayBinary *binary_array = NULL;
|
||||
if (!arr_datum->is_null()) {
|
||||
if (!arr_str_datum->is_null()) {
|
||||
has_arr_str = true;
|
||||
arr_str.assign(arr_datum->get_string().ptr(), arr_datum->get_string().length());
|
||||
arr_str.assign(arr_str_datum->get_string().ptr(), arr_str_datum->get_string().length());
|
||||
}
|
||||
if (!delimiter_datum->is_null()) {
|
||||
has_delimiter = true;
|
||||
@ -108,7 +112,7 @@ int ObExprStringToArray::eval_string_to_array(const ObExpr &expr, ObEvalCtx &ctx
|
||||
} else if (OB_ISNULL(binary_array = static_cast<ObArrayBinary *>(arr_obj))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("binary array is null", K(ret), K(subschema_id));
|
||||
} else if (OB_FAIL(string_to_array(binary_array, arr_str, delimiter, null_str, has_arr_str, has_delimiter, has_null_str))) {
|
||||
} else if (OB_FAIL(string_to_array(binary_array, arr_str, delimiter, null_str, cs_type, has_arr_str, has_delimiter, has_null_str))) {
|
||||
LOG_WARN("failed to convert string to array", K(ret));
|
||||
} else if (!has_arr_str) {
|
||||
res.set_null();
|
||||
@ -133,6 +137,7 @@ int ObExprStringToArray::eval_string_to_array_batch(const ObExpr &expr, ObEvalCt
|
||||
ObEvalCtx::TempAllocGuard tmp_alloc_g(ctx);
|
||||
common::ObArenaAllocator &tmp_allocator = tmp_alloc_g.get_allocator();
|
||||
const uint16_t subschema_id = expr.obj_meta_.get_subschema_id();
|
||||
ObCollationType cs_type = expr.args_[0]->datum_meta_.cs_type_;;
|
||||
ObIArrayType *arr_obj = NULL;
|
||||
|
||||
if (OB_FAIL(expr.args_[0]->eval_batch(ctx, skip, batch_size))) {
|
||||
@ -176,7 +181,7 @@ int ObExprStringToArray::eval_string_to_array_batch(const ObExpr &expr, ObEvalCt
|
||||
} else if (OB_ISNULL(binary_array = static_cast<ObArrayBinary *>(arr_obj))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("binary array is null", K(ret), K(subschema_id));
|
||||
} else if (OB_FAIL(string_to_array(binary_array, arr_str, delimiter, null_str, has_arr_str, has_delimiter, has_null_str))) {
|
||||
} else if (OB_FAIL(string_to_array(binary_array, arr_str, delimiter, null_str, cs_type, has_arr_str, has_delimiter, has_null_str))) {
|
||||
LOG_WARN("failed to convert string to array", K(ret));
|
||||
} else if (!has_arr_str) {
|
||||
res_datum.at(j)->set_null();
|
||||
@ -212,6 +217,7 @@ int ObExprStringToArray::eval_string_to_array_vector(const ObExpr &expr, ObEvalC
|
||||
ObEvalCtx::TempAllocGuard tmp_alloc_g(ctx);
|
||||
common::ObArenaAllocator &tmp_allocator = tmp_alloc_g.get_allocator();
|
||||
const uint16_t subschema_id = expr.obj_meta_.get_subschema_id();
|
||||
ObCollationType cs_type = expr.args_[0]->datum_meta_.cs_type_;;
|
||||
ObIArrayType *arr_obj = NULL;
|
||||
|
||||
if (OB_FAIL(expr.args_[0]->eval_vector(ctx, skip, bound))) {
|
||||
@ -260,7 +266,7 @@ int ObExprStringToArray::eval_string_to_array_vector(const ObExpr &expr, ObEvalC
|
||||
} else if (OB_ISNULL(binary_array = static_cast<ObArrayBinary *>(arr_obj))) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("binary array is null", K(ret), K(subschema_id));
|
||||
} else if (OB_FAIL(string_to_array(binary_array, arr_str, delimiter, null_str, has_arr_str, has_delimiter, has_null_str))) {
|
||||
} else if (OB_FAIL(string_to_array(binary_array, arr_str, delimiter, null_str, cs_type, has_arr_str, has_delimiter, has_null_str))) {
|
||||
LOG_WARN("failed to convert string to array", K(ret));
|
||||
} else if (!has_arr_str) {
|
||||
res_vec->set_null(idx);
|
||||
@ -284,18 +290,30 @@ int ObExprStringToArray::eval_string_to_array_vector(const ObExpr &expr, ObEvalC
|
||||
|
||||
int ObExprStringToArray::string_to_array(ObArrayBinary *binary_array,
|
||||
std::string arr_str, std::string delimiter, std::string null_str,
|
||||
bool has_arr_str, bool has_delimiter, bool has_null_str)
|
||||
ObCollationType cs_type, bool has_arr_str, bool has_delimiter, bool has_null_str)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
if (!has_arr_str) {
|
||||
int32_t str_len_char = 0;
|
||||
if (!has_arr_str || arr_str.empty()) {
|
||||
// do nothing
|
||||
} else if (!has_delimiter) {
|
||||
// add value to array character by character
|
||||
for (int i = 0; OB_SUCC(ret) && i < arr_str.length(); ++i) {
|
||||
if (OB_FAIL(add_value_str_to_array(binary_array, std::string(1, arr_str[i]), has_null_str, null_str))) {
|
||||
LOG_WARN("failed to add character to array", K(ret), K(arr_str[i]));
|
||||
size_t offset = 0;
|
||||
const ObCharsetInfo *cs = ObCharset::get_charset(cs_type);
|
||||
while (offset < arr_str.length() && OB_SUCC(ret)) {
|
||||
int mb_len = use_mb(cs) ? ob_ismbchar(cs, arr_str.data() + offset, arr_str.data() + arr_str.length()) : 0;
|
||||
size_t char_len = mb_len ? mb_len : 1;
|
||||
std::string value_str;
|
||||
if (offset + char_len > arr_str.length()) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("unexpected string end", K(arr_str.length()), K(offset), K(char_len));
|
||||
} else if (OB_FALSE_IT(value_str = arr_str.substr(offset, char_len))) {
|
||||
} else if (OB_FAIL(add_value_str_to_array(binary_array, value_str, has_null_str, null_str))) {
|
||||
LOG_WARN("failed to add character to array", K(ret), K(ObString(value_str.length(), value_str.data())));
|
||||
} else {
|
||||
offset += char_len;
|
||||
}
|
||||
}
|
||||
} // end while
|
||||
} else {
|
||||
size_t value_start = 0;
|
||||
size_t value_end = 0;
|
||||
|
@ -39,7 +39,7 @@ public:
|
||||
static int add_value_str_to_array(ObArrayBinary *binary_array, std::string value_str, bool has_null_str, std::string null_str);
|
||||
static int string_to_array(ObArrayBinary *binary_array,
|
||||
std::string arr_str, std::string delimiter, std::string null_str,
|
||||
bool has_arr_str, bool has_delimiter, bool has_null_str);
|
||||
ObCollationType cs_type, bool has_arr_str, bool has_delimiter, bool has_null_str);
|
||||
virtual int cg_expr(ObExprCGCtx &expr_cg_ctx,
|
||||
const ObRawExpr &raw_expr,
|
||||
ObExpr &rt_expr) const override;
|
||||
|
@ -423,6 +423,7 @@ inline bool ObResolverUtils::is_collection_support_type(const ObObjType type)
|
||||
type == ObUTinyIntType || type == ObUSmallIntType ||
|
||||
type == ObUInt32Type || type == ObUInt64Type ||
|
||||
type == ObFloatType || type == ObDoubleType ||
|
||||
type == ObUFloatType || type == ObUDoubleType ||
|
||||
type == ObVarcharType || type == ObCollectionSQLType);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user