From 5896e45dac27f94bba0600474cd7e26302741188 Mon Sep 17 00:00:00 2001 From: chertus Date: Thu, 11 Oct 2018 17:33:01 +0300 Subject: [PATCH] SummingMergeTree for Decimal128 [issue-3282] --- .../AggregateFunctionGroupArrayInsertAt.h | 2 +- dbms/src/Columns/ColumnDecimal.cpp | 5 +--- dbms/src/Columns/ColumnDecimal.h | 1 + dbms/src/Columns/IColumn.h | 1 + .../GraphiteRollupSortedBlockInputStream.cpp | 2 +- .../SummingSortedBlockInputStream.cpp | 2 +- .../queries/0_stateless/issue_3282.reference | 2 ++ dbms/tests/queries/0_stateless/issue_3282.sql | 27 +++++++++++++++++++ 8 files changed, 35 insertions(+), 7 deletions(-) create mode 100644 dbms/tests/queries/0_stateless/issue_3282.reference create mode 100644 dbms/tests/queries/0_stateless/issue_3282.sql diff --git a/dbms/src/AggregateFunctions/AggregateFunctionGroupArrayInsertAt.h b/dbms/src/AggregateFunctions/AggregateFunctionGroupArrayInsertAt.h index b998ee97216..5ad93c042c2 100644 --- a/dbms/src/AggregateFunctions/AggregateFunctionGroupArrayInsertAt.h +++ b/dbms/src/AggregateFunctions/AggregateFunctionGroupArrayInsertAt.h @@ -107,7 +107,7 @@ public: void add(AggregateDataPtr place, const IColumn ** columns, size_t row_num, Arena *) const override { /// TODO Do positions need to be 1-based for this function? - size_t position = columns[1]->get64(row_num); + size_t position = columns[1]->getUInt(row_num); /// If position is larger than size to which array will be cutted - simply ignore value. if (length_to_resize && position >= length_to_resize) diff --git a/dbms/src/Columns/ColumnDecimal.cpp b/dbms/src/Columns/ColumnDecimal.cpp index 01ec69b7eb1..66873379c09 100644 --- a/dbms/src/Columns/ColumnDecimal.cpp +++ b/dbms/src/Columns/ColumnDecimal.cpp @@ -1,6 +1,3 @@ -#include -#include - #include #include #include @@ -53,7 +50,7 @@ UInt64 ColumnDecimal::get64(size_t n) const { if constexpr (sizeof(T) > sizeof(UInt64)) throw Exception(String("Method get64 is not supported for ") + getFamilyName(), ErrorCodes::NOT_IMPLEMENTED); - return ext::bit_cast(data[n]); + return static_cast(data[n]); } template diff --git a/dbms/src/Columns/ColumnDecimal.h b/dbms/src/Columns/ColumnDecimal.h index e2e52bfe8ed..70571988392 100644 --- a/dbms/src/Columns/ColumnDecimal.h +++ b/dbms/src/Columns/ColumnDecimal.h @@ -112,6 +112,7 @@ public: bool getBool(size_t n) const override { return bool(data[n]); } Int64 getInt(size_t n) const override { return Int64(data[n] * scale); } UInt64 get64(size_t n) const override; + bool isDefaultAt(size_t n) const override { return data[n] == 0; } ColumnPtr filter(const IColumn::Filter & filt, ssize_t result_size_hint) const override; ColumnPtr permute(const IColumn::Permutation & perm, size_t limit) const override; diff --git a/dbms/src/Columns/IColumn.h b/dbms/src/Columns/IColumn.h index 034bf9d5ca4..18085e36c49 100644 --- a/dbms/src/Columns/IColumn.h +++ b/dbms/src/Columns/IColumn.h @@ -105,6 +105,7 @@ public: throw Exception("Method getInt is not supported for " + getName(), ErrorCodes::NOT_IMPLEMENTED); } + virtual bool isDefaultAt(size_t n) const { return get64(n) == 0; } virtual bool isNullAt(size_t /*n*/) const { return false; } /** If column is numeric, return value of n-th element, casted to bool. diff --git a/dbms/src/DataStreams/GraphiteRollupSortedBlockInputStream.cpp b/dbms/src/DataStreams/GraphiteRollupSortedBlockInputStream.cpp index 294f98d20c3..a2740dabdaa 100644 --- a/dbms/src/DataStreams/GraphiteRollupSortedBlockInputStream.cpp +++ b/dbms/src/DataStreams/GraphiteRollupSortedBlockInputStream.cpp @@ -132,7 +132,7 @@ void GraphiteRollupSortedBlockInputStream::merge(MutableColumns & merged_columns is_first = false; - time_t next_row_time = next_cursor->all_columns[time_column_num]->get64(next_cursor->pos); + time_t next_row_time = next_cursor->all_columns[time_column_num]->getUInt(next_cursor->pos); /// Is new key before rounding. bool is_new_key = new_path || next_row_time != current_time; diff --git a/dbms/src/DataStreams/SummingSortedBlockInputStream.cpp b/dbms/src/DataStreams/SummingSortedBlockInputStream.cpp index 00f3f55c3a8..d2af46f198e 100644 --- a/dbms/src/DataStreams/SummingSortedBlockInputStream.cpp +++ b/dbms/src/DataStreams/SummingSortedBlockInputStream.cpp @@ -216,7 +216,7 @@ void SummingSortedBlockInputStream::insertCurrentRowIfNeeded(MutableColumns & me if (desc.column_numbers.size() == 1) { // Flag row as non-empty if at least one column number if non-zero - current_row_is_zero = current_row_is_zero && desc.merged_column->get64(desc.merged_column->size() - 1) == 0; + current_row_is_zero = current_row_is_zero && desc.merged_column->isDefaultAt(desc.merged_column->size() - 1); } else { diff --git a/dbms/tests/queries/0_stateless/issue_3282.reference b/dbms/tests/queries/0_stateless/issue_3282.reference new file mode 100644 index 00000000000..1644f50993c --- /dev/null +++ b/dbms/tests/queries/0_stateless/issue_3282.reference @@ -0,0 +1,2 @@ +2001-01-01 2.0000 0.00000000 -2.0000000000 +2001-01-01 0.0000 1.00000000 0.0000000000 diff --git a/dbms/tests/queries/0_stateless/issue_3282.sql b/dbms/tests/queries/0_stateless/issue_3282.sql new file mode 100644 index 00000000000..f560283434f --- /dev/null +++ b/dbms/tests/queries/0_stateless/issue_3282.sql @@ -0,0 +1,27 @@ +CREATE DATABASE IF NOT EXISTS test; +DROP TABLE IF EXISTS test.decimal_sum; +CREATE TABLE test.decimal_sum +( + date Date, + sum32 Decimal32(4), + sum64 Decimal64(8), + sum128 Decimal128(10) +) Engine = SummingMergeTree(date, (date), 8192); + +INSERT INTO test.decimal_sum VALUES ('2001-01-01', 1, 1, -1); +INSERT INTO test.decimal_sum VALUES ('2001-01-01', 1, -1, -1); + +OPTIMIZE TABLE test.decimal_sum; +SELECT * FROM test.decimal_sum; + +INSERT INTO test.decimal_sum VALUES ('2001-01-01', -2, 1, 2); + +OPTIMIZE TABLE test.decimal_sum; +SELECT * FROM test.decimal_sum; + +INSERT INTO test.decimal_sum VALUES ('2001-01-01', 0, -1, 0); + +OPTIMIZE TABLE test.decimal_sum; +SELECT * FROM test.decimal_sum; + +drop table test.decimal_sum;