[CP] make_set expr adapt lob

This commit is contained in:
shadowao 2025-01-02 18:16:02 +00:00 committed by ob-robot
parent a833ad60db
commit 94aa4524c8
4 changed files with 83 additions and 13 deletions

View File

@ -210,13 +210,10 @@ int ObExprConcatWs::calc_text(const ObExpr &expr, ObEvalCtx &ctx, ObDatum &res)
int ret = OB_SUCCESS;
ObEvalCtx::TempAllocGuard tmp_alloc_g(ctx);
common::ObArenaAllocator &temp_allocator = tmp_alloc_g.get_allocator();
ObTextStringDatumResult output_result(expr.datum_meta_.type_, &expr, &ctx, &res);
const ObExpr *sep_expr = expr.args_[0];
const ObDatum &sep_datum = expr.locate_param_datum(ctx, 0);
ObString sep_str;
ObSEArray<int64_t, 32> words;
int64_t res_len = 0;
int64_t word_cnt = 0;
ObSEArray<ObExpr*, 32> words;
if (OB_FAIL(ObTextStringHelper::read_real_string_data(temp_allocator, sep_datum, sep_expr->datum_meta_, sep_expr->obj_meta_.has_lob_header(), sep_str))) {
LOG_WARN("fail to get real data.", K(ret), K(sep_datum));
@ -224,16 +221,34 @@ int ObExprConcatWs::calc_text(const ObExpr &expr, ObEvalCtx &ctx, ObDatum &res)
for (int64_t i = 1; OB_SUCC(ret) && i < expr.arg_cnt_; ++i) {
const ObDatum &dat = expr.locate_param_datum(ctx, i);
if (!dat.is_null() && OB_FAIL(words.push_back(i))) {
if (!dat.is_null() && OB_FAIL(words.push_back(expr.args_[i]))) {
LOG_WARN("push back string failed", K(ret), K(i));
}
}
if (OB_FAIL(ret)) {
} else if (OB_FAIL(calc_text(expr, ctx, sep_str, words, temp_allocator, res))) {
LOG_WARN("calc_text fail", K(ret), K(expr), K(words), K(sep_str));
}
return ret;
}
int ObExprConcatWs::calc_text(
const ObExpr &expr,
ObEvalCtx &ctx,
const ObString &sep_str,
const ObIArray<ObExpr *> &words,
ObIAllocator &temp_allocator,
ObDatum &res)
{
int ret = OB_SUCCESS;
int64_t res_len = 0;
int64_t word_cnt = 0;
ObTextStringDatumResult output_result(expr.datum_meta_.type_, &expr, &ctx, &res);
// calc total len of all words
for (int64_t i = 0; OB_SUCC(ret) && i < words.count(); i++) {
int64_t word_idx = words.at(i);
const ObExpr *word_expr = expr.args_[word_idx];
ObDatum &v = expr.locate_param_datum(ctx, word_idx);
const ObExpr *word_expr = words.at(i);;
ObDatum &v = word_expr->locate_expr_datum(ctx);
if (! ob_is_text_tc(word_expr->datum_meta_.type_)) {
res_len += v.len_;
} else {
@ -261,9 +276,8 @@ int ObExprConcatWs::calc_text(const ObExpr &expr, ObEvalCtx &ctx, ObDatum &res)
} else {
int64_t append_data_len = 0;
for (int64_t i = 0; OB_SUCC(ret) && i < words.count(); i++) {
int64_t word_idx = words.at(i);
const ObExpr *word_expr = expr.args_[word_idx];
ObDatum &word_datum = expr.locate_param_datum(ctx, word_idx);
const ObExpr *word_expr = words.at(i);;
ObDatum &word_datum = word_expr->locate_expr_datum(ctx);
ObDatumMeta word_meta = word_expr->datum_meta_;
bool has_lob_header = word_expr->obj_meta_.has_lob_header();

View File

@ -41,6 +41,8 @@ public:
static int calc(const common::ObString &sep_str, const common::ObIArray<common::ObString> &words,
common::ObIAllocator &alloc, common::ObString &res_str);
static int calc_text(const ObExpr &expr, ObEvalCtx &ctx, ObDatum &res);
static int calc_text(const ObExpr &expr, ObEvalCtx &ctx, const ObString &sep_str,
const ObIArray<ObExpr *> &words, ObIAllocator &temp_allocator, ObDatum &res);
DECLARE_SET_LOCAL_SESSION_VARS;
private:

View File

@ -31,6 +31,14 @@ ObExprMakeSet::~ObExprMakeSet()
{
}
static bool enable_return_longtext()
{
const uint64_t min_cluster_version = GET_MIN_CLUSTER_VERSION();
// [4.2.5.2, 4.3.0) || [4.3.5.1, )
return (min_cluster_version >= CLUSTER_VERSION_4_3_5_1)
|| (MOCK_CLUSTER_VERSION_4_2_5_2 <= min_cluster_version && min_cluster_version < CLUSTER_VERSION_4_3_0_0);
}
int ObExprMakeSet::calc_result_typeN(ObExprResType &type,
ObExprResType *types,
int64_t param_num,
@ -46,12 +54,23 @@ int ObExprMakeSet::calc_result_typeN(ObExprResType &type,
ObLength max_len = 0;
type_ctx.set_cast_mode(type_ctx.get_cast_mode() | CM_STRING_INTEGER_TRUNC);
types[0].set_calc_type(ObIntType);
bool has_text = false;
for (int64_t i = 1; !has_text && i < param_num; ++i) {
if (ObTinyTextType != types[i].get_type() && types[i].is_lob()) {
has_text = true;
}
}
if (has_text && enable_return_longtext()) {
type.set_type(ObLongTextType);
} else {
type.set_varchar();
}
for (int64_t i = 1; i < param_num; ++i) {
types[i].set_calc_type(ObVarcharType);
types[i].set_calc_type(type.get_type());
max_len += types[i].get_length();
}
// set expected type of results
type.set_varchar();
type.set_length(max_len);
if OB_FAIL(aggregate_charsets_for_string_result(type, &types[1], param_num - 1, type_ctx)) {
LOG_WARN("aggregate charset for string result failed", K(ret));
@ -77,6 +96,10 @@ int ObExprMakeSet::calc_make_set_expr(const ObExpr &expr, ObEvalCtx &ctx,
LOG_WARN("eval param failed", K(ret));
} else if (input_bits_dat->is_null()) {
res.set_null();
} else if (ob_is_text_tc(expr.datum_meta_.type_)) {
if (OB_FAIL(calc_text(expr, ctx, *input_bits_dat, res))) {
LOG_WARN("calc concat text ws failed", K(ret));
}
} else {
// compute input bits representation
uint64_t input_bits = static_cast<uint64_t>(input_bits_dat->get_int());
@ -114,6 +137,36 @@ int ObExprMakeSet::calc_make_set_expr(const ObExpr &expr, ObEvalCtx &ctx,
return ret;
}
int ObExprMakeSet::calc_text(const ObExpr &expr, ObEvalCtx &ctx, const ObDatum &input_bits_dat, ObDatum &res)
{
int ret = OB_SUCCESS;
ObEvalCtx::TempAllocGuard tmp_alloc_g(ctx);
common::ObArenaAllocator &temp_allocator = tmp_alloc_g.get_allocator();
const ObString sep_str = ObCharsetUtils::get_const_str(expr.datum_meta_.cs_type_, ',');
ObSEArray<ObExpr*, 32> words;
// compute input bits representation
uint64_t input_bits = static_cast<uint64_t>(input_bits_dat.get_int());
if (expr.arg_cnt_ <= 64) {
input_bits &= ((ulonglong) 1 << (expr.arg_cnt_ - 1)) - 1;
}
for (int64_t pos = 1, temp_input_bits = input_bits; OB_SUCC(ret) && temp_input_bits > 0;
temp_input_bits >>= 1, ++pos) {
const ObDatum &dat = expr.locate_param_datum(ctx, pos);
if (((temp_input_bits & 1) > 0) && (!dat.is_null())) {
if (OB_FAIL(words.push_back(expr.args_[pos]))) {
LOG_WARN("push back word failed", K(ret), K(pos), K(input_bits), K(temp_input_bits));
}
}
}
if (OB_FAIL(ret)) {
} else if (OB_FAIL(ObExprConcatWs::calc_text(expr, ctx, sep_str, words, temp_allocator, res))) {
LOG_WARN("calc_text fail", K(ret), K(expr), K(words), K(sep_str));
}
return ret;
}
int ObExprMakeSet::cg_expr(ObExprCGCtx &expr_cg_ctx, const ObRawExpr &raw_expr,
ObExpr &rt_expr) const
{

View File

@ -31,6 +31,7 @@ public:
virtual int cg_expr(ObExprCGCtx &expr_cg_ctx, const ObRawExpr &raw_expr,
ObExpr &rt_expr) const;
static int calc_make_set_expr(const ObExpr &expr, ObEvalCtx &ctx, ObDatum &res);
static int calc_text(const ObExpr &expr, ObEvalCtx &ctx, const ObDatum &input_bits_dat, ObDatum &res);
DECLARE_SET_LOCAL_SESSION_VARS;
private: