Skip to content

Commit

Permalink
Merge pull request #3391 from 4ertus2/decimal
Browse files Browse the repository at this point in the history
fix for Decimal128 group by [issue-3378]
  • Loading branch information
4ertus2 authored Oct 16, 2018
2 parents ff1598e + 29bd00f commit 3359ba0
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 18 deletions.
8 changes: 8 additions & 0 deletions dbms/src/Columns/ColumnDecimal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,14 @@ MutableColumnPtr ColumnDecimal<T>::cloneResized(size_t size) const
return std::move(res);
}

template <typename T>
void ColumnDecimal<T>::insertData(const char * src, size_t /*length*/)
{
T tmp;
memcpy(&tmp, src, sizeof(T));
data.emplace_back(tmp);
}

template <typename T>
void ColumnDecimal<T>::insertRangeFrom(const IColumn & src, size_t start, size_t length)
{
Expand Down
2 changes: 1 addition & 1 deletion dbms/src/Columns/ColumnDecimal.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ class ColumnDecimal final : public COWPtrHelper<IColumn, ColumnDecimal<T>>
void reserve(size_t n) override { data.reserve(n); }

void insertFrom(const IColumn & src, size_t n) override { data.push_back(static_cast<const Self &>(src).getData()[n]); }
void insertData(const char * pos, size_t /*length*/) override { data.push_back(*reinterpret_cast<const T *>(pos)); }
void insertData(const char * pos, size_t /*length*/) override;
void insertDefault() override { data.push_back(T()); }
void insert(const Field & x) override { data.push_back(DB::get<typename NearestFieldType<T>::Type>(x)); }
void insertRangeFrom(const IColumn & src, size_t start, size_t length) override;
Expand Down
8 changes: 5 additions & 3 deletions dbms/src/Interpreters/Aggregator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1132,6 +1132,9 @@ void Aggregator::convertToBlockImpl(
if (data.empty())
return;

if (key_columns.size() != params.keys_size)
throw Exception{"Aggregate. Unexpected key columns size.", ErrorCodes::LOGICAL_ERROR};

if (final)
convertToBlockImplFinal(method, data, key_columns, final_aggregate_columns);
else
Expand All @@ -1151,7 +1154,7 @@ void NO_INLINE Aggregator::convertToBlockImplFinal(
{
for (const auto & value : data)
{
method.insertKeyIntoColumns(value, key_columns, params.keys_size, key_sizes);
method.insertKeyIntoColumns(value, key_columns, key_sizes);

for (size_t i = 0; i < params.aggregates_size; ++i)
aggregate_functions[i]->insertResultInto(
Expand All @@ -1169,10 +1172,9 @@ void NO_INLINE Aggregator::convertToBlockImplNotFinal(
MutableColumns & key_columns,
AggregateColumnsData & aggregate_columns) const
{

for (auto & value : data)
{
method.insertKeyIntoColumns(value, key_columns, params.keys_size, key_sizes);
method.insertKeyIntoColumns(value, key_columns, key_sizes);

/// reserved, so push_back does not throw exceptions
for (size_t i = 0; i < params.aggregates_size; ++i)
Expand Down
27 changes: 13 additions & 14 deletions dbms/src/Interpreters/Aggregator.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ struct AggregationMethodOneNumber

/** Insert the key from the hash table into columns.
*/
static void insertKeyIntoColumns(const typename Data::value_type & value, MutableColumns & key_columns, size_t /*keys_size*/, const Sizes & /*key_sizes*/)
static void insertKeyIntoColumns(const typename Data::value_type & value, MutableColumns & key_columns, const Sizes & /*key_sizes*/)
{
static_cast<ColumnVector<FieldType> *>(key_columns[0].get())->insertData(reinterpret_cast<const char *>(&value.first), sizeof(value.first));
}
Expand Down Expand Up @@ -243,7 +243,7 @@ struct AggregationMethodString
return StringRef(value.first.data, value.first.size);
}

static void insertKeyIntoColumns(const typename Data::value_type & value, MutableColumns & key_columns, size_t, const Sizes &)
static void insertKeyIntoColumns(const typename Data::value_type & value, MutableColumns & key_columns, const Sizes &)
{
key_columns[0]->insertData(value.first.data, value.first.size);
}
Expand Down Expand Up @@ -312,7 +312,7 @@ struct AggregationMethodFixedString
return StringRef(value.first.data, value.first.size);
}

static void insertKeyIntoColumns(const typename Data::value_type & value, MutableColumns & key_columns, size_t, const Sizes &)
static void insertKeyIntoColumns(const typename Data::value_type & value, MutableColumns & key_columns, const Sizes &)
{
key_columns[0]->insertData(value.first.data, value.first.size);
}
Expand Down Expand Up @@ -580,7 +580,7 @@ struct AggregationMethodSingleLowCardinalityColumn : public SingleColumnMethod
static const bool no_consecutive_keys_optimization = true;
static const bool low_cardinality_optimization = true;

static void insertKeyIntoColumns(const typename Data::value_type & value, MutableColumns & key_columns, size_t /*keys_size*/, const Sizes & /*key_sizes*/)
static void insertKeyIntoColumns(const typename Data::value_type & value, MutableColumns & key_columns, const Sizes & /*key_sizes*/)
{
auto ref = Base::getValueRef(value);
static_cast<ColumnLowCardinality *>(key_columns[0].get())->insertData(ref.data, ref.size);
Expand Down Expand Up @@ -783,8 +783,10 @@ struct AggregationMethodKeysFixed
static const bool no_consecutive_keys_optimization = false;
static const bool low_cardinality_optimization = false;

static void insertKeyIntoColumns(const typename Data::value_type & value, MutableColumns & key_columns, size_t keys_size, const Sizes & key_sizes)
static void insertKeyIntoColumns(const typename Data::value_type & value, MutableColumns & key_columns, const Sizes & key_sizes)
{
size_t keys_size = key_columns.size();

static constexpr auto bitmap_size = has_nullable_keys ? std::tuple_size<KeysNullMap<Key>>::value : 0;
/// In any hash key value, column values to be read start just after the bitmap, if it exists.
size_t pos = bitmap_size;
Expand Down Expand Up @@ -891,10 +893,10 @@ struct AggregationMethodSerialized
static const bool no_consecutive_keys_optimization = true;
static const bool low_cardinality_optimization = false;

static void insertKeyIntoColumns(const typename Data::value_type & value, MutableColumns & key_columns, size_t keys_size, const Sizes &)
static void insertKeyIntoColumns(const typename Data::value_type & value, MutableColumns & key_columns, const Sizes &)
{
auto pos = value.first.data;
for (size_t i = 0; i < keys_size; ++i)
for (size_t i = 0; i < key_columns.size(); ++i)
pos = key_columns[i]->deserializeAndInsertFromArena(pos);
}

Expand Down Expand Up @@ -1284,10 +1286,10 @@ class Aggregator
Block intermediate_header;

/// What to count.
ColumnNumbers keys;
AggregateDescriptions aggregates;
size_t keys_size;
size_t aggregates_size;
const ColumnNumbers keys;
const AggregateDescriptions aggregates;
const size_t keys_size;
const size_t aggregates_size;

/// The settings of approximate calculation of GROUP BY.
const bool overflow_row; /// Do we need to put into AggregatedDataVariants::without_key aggregates for keys that are not in max_rows_to_group_by.
Expand Down Expand Up @@ -1344,9 +1346,6 @@ class Aggregator
{
intermediate_header = intermediate_header_;
}

/// Calculate the column numbers in `keys` and `aggregates`.
void calculateColumnNumbers(const Block & block);
};

Aggregator(const Params & params_);
Expand Down
11 changes: 11 additions & 0 deletions dbms/tests/queries/0_stateless/00737_decimal_group_by.reference
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
1.10
2.1000
3.100000000000
1.20
2.2000
3.200000000000
1.30
2.3000
3.300000000000
1 1.000000000000000000 10.000000000000000000
1 1.000000000000000000 10.000000000000000000
26 changes: 26 additions & 0 deletions dbms/tests/queries/0_stateless/00737_decimal_group_by.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
select toDecimal32(1.1, 2) as x group by x;
select toDecimal64(2.1, 4) as x group by x;
select toDecimal128(3.1, 12) as x group by x;

select materialize(toDecimal32(1.2, 2)) as x group by x;
select materialize(toDecimal64(2.2, 4)) as x group by x;
select materialize(toDecimal128(3.2, 12)) as x group by x;

select x from (select toDecimal32(1.3, 2) x) group by x;
select x from (select toDecimal64(2.3, 4) x) group by x;
select x from (select toDecimal128(3.3, 12) x) group by x;

DROP TABLE IF EXISTS test.decimal;
CREATE TABLE IF NOT EXISTS test.decimal
(
A UInt64,
B Decimal128(18),
C Decimal128(18)
) Engine = Memory;

INSERT INTO test.decimal VALUES (1,1,1), (1,1,2), (1,1,3), (1,1,4);

SELECT A, toString(B) AS B_str, toString(SUM(C)) AS c_str FROM test.decimal GROUP BY A, B_str;
SELECT A, B_str, toString(cc) FROM (SELECT A, toString(B) AS B_str, SUM(C) AS cc FROM test.decimal GROUP BY A, B_str);

DROP TABLE test.decimal;

0 comments on commit 3359ba0

Please sign in to comment.