From 09cf24cd13ddfae93e07993d493339609f998998 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Wed, 22 Jun 2016 00:42:57 +0300 Subject: [PATCH] Fixed error with ColumnAggregateFunction and LIMIT [#METR-2944]. --- .../DB/Columns/ColumnAggregateFunction.h | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/dbms/include/DB/Columns/ColumnAggregateFunction.h b/dbms/include/DB/Columns/ColumnAggregateFunction.h index 41f41dc04b0..96416919601 100644 --- a/dbms/include/DB/Columns/ColumnAggregateFunction.h +++ b/dbms/include/DB/Columns/ColumnAggregateFunction.h @@ -61,7 +61,7 @@ private: /// Источник. Используется (удерживает источник от уничтожения), /// если данный столбец создан из другого и использует все или часть его значений. - const std::shared_ptr src; + std::shared_ptr src; /// Массив указателей на состояния агрегатных функций, расположенных в пулах. Container_t data; @@ -211,21 +211,31 @@ public: return res; } - void insertRangeFrom(const IColumn & src, size_t start, size_t length) override + void insertRangeFrom(const IColumn & from, size_t start, size_t length) override { - const ColumnAggregateFunction & src_concrete = static_cast(src); + const ColumnAggregateFunction & from_concrete = static_cast(from); - if (start + length > src_concrete.getData().size()) + if (start + length > from_concrete.getData().size()) throw Exception("Parameters start = " + toString(start) + ", length = " + toString(length) + " are out of bound in ColumnAggregateFunction::insertRangeFrom method" - " (data.size() = " + toString(src_concrete.getData().size()) + ").", + " (data.size() = " + toString(from_concrete.getData().size()) + ").", ErrorCodes::PARAMETER_OUT_OF_BOUND); + if (src && src.get() != &from_concrete) + { + throw Exception("ColumnAggregateFunction could have only one source that owns aggregation states", ErrorCodes::BAD_ARGUMENTS); + } + else + { + /// Keep shared ownership of aggregation states. + src = from_concrete.shared_from_this(); + } + auto & data = getData(); size_t old_size = data.size(); data.resize(old_size + length); - memcpy(&data[old_size], &src_concrete.getData()[start], length * sizeof(data[0])); + memcpy(&data[old_size], &from_concrete.getData()[start], length * sizeof(data[0])); } void popBack(size_t n) override