diff --git a/src/share/aggregate/sum.h b/src/share/aggregate/sum.h index 1bf13a86b5..929f34e61f 100644 --- a/src/share/aggregate/sum.h +++ b/src/share/aggregate/sum.h @@ -791,6 +791,8 @@ public: const char *agg_data = reinterpret_cast(*reinterpret_cast(agg_cell)); ObLobCommon *agg_lob_comm = (ObLobCommon*)(agg_data); ObString agg_array_data(agg_cell_len, agg_data); + ObLobLocatorV2 locator(agg_array_data, true/*has_lob_header*/); + bool is_outrow = !locator.has_inrow_data(); if (!agg_lob_comm->is_valid()) { ret = OB_ERR_UNEXPECTED; SQL_LOG(WARN, "unexpected data", K(ret), K(*agg_lob_comm)); @@ -815,6 +817,15 @@ public: SQL_LOG(WARN, "value overflow", K(ret), K(i), K(float_data[i]), K(float_res[i])); } } + if (OB_SUCC(ret) && is_outrow) { + ObString res; + if (OB_FAIL(ObArrayExprUtils::set_array_res(nullptr, agg_array_data.length(), agg_ctx.allocator_, res, agg_array_data.ptr()))) { + SQL_LOG(WARN, "failed to set array res", K(ret)); + } else { + *reinterpret_cast(agg_cell) = reinterpret_cast(res.ptr()); + *reinterpret_cast(agg_cell + sizeof(char *)) = res.length(); + } + } } } } else { @@ -873,6 +884,8 @@ public: const char *agg_data = reinterpret_cast(*reinterpret_cast(aggr_cell)); ObLobCommon *agg_lob_comm = (ObLobCommon*)(agg_data); ObString agg_array_data(agg_cell_len, agg_data); + ObLobLocatorV2 locator(agg_array_data, true/*has_lob_header*/); + bool is_outrow = !locator.has_inrow_data(); if (!agg_lob_comm->is_valid()) { ret = OB_ERR_UNEXPECTED; SQL_LOG(WARN, "unexpected data", K(ret), K(*agg_lob_comm)); @@ -897,6 +910,15 @@ public: SQL_LOG(WARN, "value overflow", K(ret), K(i), K(float_data[i]), K(float_res[i])); } } + if (OB_SUCC(ret) && is_outrow) { + ObString res; + if (OB_FAIL(ObArrayExprUtils::set_array_res(nullptr, agg_array_data.length(), agg_ctx.allocator_, res, agg_array_data.ptr()))) { + SQL_LOG(WARN, "failed to set array res", K(ret)); + } else { + *reinterpret_cast(aggr_cell) = reinterpret_cast(res.ptr()); + *reinterpret_cast(aggr_cell + sizeof(char *)) = res.length(); + } + } } } } else if (is_add) { diff --git a/src/sql/engine/aggregate/ob_aggregate_processor.cpp b/src/sql/engine/aggregate/ob_aggregate_processor.cpp index e98a7d9ced..56ce801ab5 100644 --- a/src/sql/engine/aggregate/ob_aggregate_processor.cpp +++ b/src/sql/engine/aggregate/ob_aggregate_processor.cpp @@ -1538,6 +1538,21 @@ OB_INLINE int ObAggregateProcessor::clone_number_cell(const ObNumber &src_number return ret; } +OB_INLINE int ObAggregateProcessor::clone_vector_cell(const ObDatum &src_cell, AggrCell &aggr_cell) +{ + int ret = OB_SUCCESS; + int64_t need_size = sizeof(int64_t) * 2 + src_cell.len_; + if (OB_FAIL(clone_cell(aggr_cell, need_size, nullptr))) { + SQL_LOG(WARN, "failed to clone cell", K(ret)); + } else { + ObDatum &target_cell = aggr_cell.get_iter_result(); + memcpy((char*)target_cell.ptr_, src_cell.ptr_, src_cell.len_); + target_cell.pack_ = src_cell.pack_; + } + OX(SQL_LOG(DEBUG, "succ to clone cell", K(src_cell), K(aggr_cell), K(need_size))); + return ret; +} + int ObAggregateProcessor::prepare(GroupRow &group_row) { int ret = OB_SUCCESS; @@ -5631,8 +5646,19 @@ int ObAggregateProcessor::add_calc( case ObCollectionSQLTC: { if (result_datum.is_null()) { ret = clone_aggr_cell(aggr_cell, iter_value, false); - } else if (OB_FAIL(ObArrayExprUtils::vector_datum_add(result_datum, iter_value, aggr_alloc_))) { - LOG_WARN("failed to add vector", K(ret)); + } else { + ObString blob_res = result_datum.get_string(); + ObLobLocatorV2 locator(blob_res, true/*has_lob_header*/); + bool is_outrow = !locator.has_inrow_data(); + ObDatum tmp_datum; + if (OB_FAIL(ObArrayExprUtils::vector_datum_add(result_datum, iter_value, aggr_alloc_, + is_outrow ? &tmp_datum : nullptr))) { + LOG_WARN("failed to add vector", K(ret)); + } else if (is_outrow) { + if (OB_FAIL(clone_vector_cell(tmp_datum, aggr_cell))) { + LOG_WARN("failed to clone vector cell", K(ret)); + } + } } break; } @@ -5803,8 +5829,19 @@ int ObAggregateProcessor::sub_calc( case ObCollectionSQLTC: { if (result_datum.is_null()) { ret = clone_aggr_cell(aggr_cell, iter_value, false); - } else if (OB_FAIL(ObArrayExprUtils::vector_datum_add(result_datum, iter_value, aggr_alloc_, true /*negative*/))) { - LOG_WARN("failed to sub vector", K(ret)); + } else { + ObString blob_res = result_datum.get_string(); + ObLobLocatorV2 locator(blob_res, true/*has_lob_header*/); + bool is_outrow = !locator.has_inrow_data(); + ObDatum tmp_datum; + if (OB_FAIL(ObArrayExprUtils::vector_datum_add(result_datum, iter_value, aggr_alloc_, + is_outrow ? &tmp_datum : nullptr, true /*negative*/))) { + LOG_WARN("failed to add vector", K(ret)); + } else if (is_outrow) { + if (OB_FAIL(clone_vector_cell(tmp_datum, aggr_cell))) { + LOG_WARN("failed to clone vector cell", K(ret)); + } + } } break; } @@ -6352,8 +6389,19 @@ int ObAggregateProcessor::add_calc_batch( } if (result_datum.is_null()) { ret = clone_aggr_cell(aggr_cell, *src.at(i), false); - } else if (OB_FAIL(ObArrayExprUtils::vector_datum_add(result_datum, *src.at(i), aggr_alloc_))) { - LOG_WARN("failed to add vector", K(ret)); + } else { + ObString blob_res = result_datum.get_string(); + ObLobLocatorV2 locator(blob_res, true/*has_lob_header*/); + bool is_outrow = !locator.has_inrow_data(); + ObDatum tmp_datum; + if (OB_FAIL(ObArrayExprUtils::vector_datum_add(result_datum, *src.at(i), aggr_alloc_, + is_outrow ? &tmp_datum : nullptr))) { + LOG_WARN("failed to add vector", K(ret)); + } else if (is_outrow) { + if (OB_FAIL(clone_vector_cell(tmp_datum, aggr_cell))) { + LOG_WARN("failed to clone vector cell", K(ret)); + } + } } } break; diff --git a/src/sql/engine/aggregate/ob_aggregate_processor.h b/src/sql/engine/aggregate/ob_aggregate_processor.h index 935303e756..95caf8f847 100644 --- a/src/sql/engine/aggregate/ob_aggregate_processor.h +++ b/src/sql/engine/aggregate/ob_aggregate_processor.h @@ -975,6 +975,7 @@ private: public: OB_INLINE int clone_number_cell(const number::ObNumber &src_cell, AggrCell &aggr_cell); + OB_INLINE int clone_vector_cell(const ObDatum &src_cell, AggrCell &aggr_cell); private: template int init_group_extra_aggr_info( diff --git a/src/sql/engine/expr/ob_array_expr_utils.cpp b/src/sql/engine/expr/ob_array_expr_utils.cpp index 2303ba2bb5..d3506de240 100644 --- a/src/sql/engine/expr/ob_array_expr_utils.cpp +++ b/src/sql/engine/expr/ob_array_expr_utils.cpp @@ -81,11 +81,13 @@ int ObArrayExprUtils::get_type_vector( return ret; } -int ObArrayExprUtils::vector_datum_add(ObDatum &res, const ObDatum &data, ObIAllocator &allocator, bool negative) +int ObArrayExprUtils::vector_datum_add(ObDatum &res, const ObDatum &data, ObIAllocator &allocator, ObDatum *tmp_res, bool negative) { int ret = OB_SUCCESS; ObString blob_res = res.get_string(); ObString blob_data = data.get_string(); + ObLobLocatorV2 locator(blob_res, true/*has_lob_header*/); + bool is_outrow = !locator.has_inrow_data(); if (OB_FAIL(ObTextStringHelper::read_real_string_data(&allocator, ObLongTextType, CS_TYPE_BINARY, @@ -109,6 +111,16 @@ int ObArrayExprUtils::vector_datum_add(ObDatum &res, const ObDatum &data, ObIAll SQL_LOG(WARN, "value overflow", K(ret), K(i), K(float_data[i]), K(float_res[i])); } } + if (OB_SUCC(ret) && is_outrow) { + ObString res_str; + if (OB_FAIL(ObArrayExprUtils::set_array_res(nullptr, blob_res.length(), allocator, res_str, blob_res.ptr()))) { + SQL_LOG(WARN, "failed to set array res", K(ret)); + } else if (OB_NOT_NULL(tmp_res)) { + tmp_res->set_string(res_str); + } else { + res.set_string(res_str); + } + } } return ret; } diff --git a/src/sql/engine/expr/ob_array_expr_utils.h b/src/sql/engine/expr/ob_array_expr_utils.h index b62741f33b..d6e98024e3 100644 --- a/src/sql/engine/expr/ob_array_expr_utils.h +++ b/src/sql/engine/expr/ob_array_expr_utils.h @@ -94,7 +94,7 @@ public: static int collect_vector_cast_info(ObExprResType &type, ObExecContext &exec_ctx, ObVectorCastInfo &info); // update inplace - static int vector_datum_add(ObDatum &res, const ObDatum &data, ObIAllocator &allocator, bool negative = false); + static int vector_datum_add(ObDatum &res, const ObDatum &data, ObIAllocator &allocator, ObDatum *tmp_res = nullptr, bool negative = false); private: static const char* DEFAULT_CAST_TYPE_NAME; static const ObString DEFAULT_CAST_TYPE_STR;