Merge pull request #37667 from ClickHouse/group-by-enum-fix

Support types with non-standard defaults in ROLLUP, CUBE, GROUPING SETS
This commit is contained in:
Alexey Milovidov 2022-06-15 05:14:33 +03:00 committed by GitHub
commit ab9fc572d5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 178 additions and 4 deletions

View File

@ -90,7 +90,7 @@ public:
/// Creates column with the same type and specified size.
/// If size is less current size, then data is cut.
/// If size is greater, than default values are appended.
[[nodiscard]] virtual MutablePtr cloneResized(size_t /*size*/) const { throw Exception("Cannot cloneResized() column " + getName(), ErrorCodes::NOT_IMPLEMENTED); }
[[nodiscard]] virtual MutablePtr cloneResized(size_t /*size*/) const { throw Exception(ErrorCodes::NOT_IMPLEMENTED, "Cannot cloneResized() column {}", getName()); }
/// Returns number of values in column.
[[nodiscard]] virtual size_t size() const = 0;

View File

@ -1,3 +1,4 @@
#include <cstddef>
#include <Columns/IColumn.h>
#include <Columns/ColumnConst.h>
#include <Columns/ColumnSparse.h>
@ -162,6 +163,12 @@ void IDataType::insertDefaultInto(IColumn & column) const
column.insertDefault();
}
void IDataType::insertManyDefaultsInto(IColumn & column, size_t n) const
{
for (size_t i = 0; i < n; ++i)
insertDefaultInto(column);
}
void IDataType::setCustomization(DataTypeCustomDescPtr custom_desc_) const
{
/// replace only if not null

View File

@ -159,6 +159,8 @@ public:
*/
virtual void insertDefaultInto(IColumn & column) const;
void insertManyDefaultsInto(IColumn & column, size_t n) const;
/// Checks that two instances belong to the same type
virtual bool equals(const IDataType & rhs) const = 0;

View File

@ -241,7 +241,9 @@ void AggregatingStep::transformPipeline(QueryPipelineBuilder & pipeline, const B
if (missign_column_index < missing_columns.size() && missing_columns[missign_column_index] == i)
{
++missign_column_index;
auto column = ColumnConst::create(col.column->cloneResized(1), 0);
auto column_with_default = col.column->cloneEmpty();
col.type->insertDefaultInto(*column_with_default);
auto column = ColumnConst::create(std::move(column_with_default), 0);
const auto * node = &dag->addColumn({ColumnPtr(std::move(column)), col.type, col.name});
node = &dag->materializeNode(*node);
index.push_back(node);

View File

@ -35,6 +35,8 @@ void CubeTransform::consume(Chunk chunk)
consumed_chunks.emplace_back(std::move(chunk));
}
MutableColumnPtr getColumnWithDefaults(Block const & header, size_t key, size_t n);
Chunk CubeTransform::generate()
{
if (!consumed_chunks.empty())
@ -53,8 +55,9 @@ Chunk CubeTransform::generate()
current_zero_columns.clear();
current_zero_columns.reserve(keys.size());
auto const & input_header = getInputPort().getHeader();
for (auto key : keys)
current_zero_columns.emplace_back(current_columns[key]->cloneEmpty()->cloneResized(num_rows));
current_zero_columns.emplace_back(getColumnWithDefaults(input_header, key, num_rows));
}
auto gen_chunk = std::move(cube_chunk);

View File

@ -29,6 +29,14 @@ Chunk RollupTransform::merge(Chunks && chunks, bool final)
return Chunk(rollup_block.getColumns(), num_rows);
}
MutableColumnPtr getColumnWithDefaults(Block const & header, size_t key, size_t n)
{
auto const & col = header.getByPosition(key);
auto result_column = col.column->cloneEmpty();
col.type->insertManyDefaultsInto(*result_column, n);
return result_column;
}
Chunk RollupTransform::generate()
{
if (!consumed_chunks.empty())
@ -51,7 +59,7 @@ Chunk RollupTransform::generate()
auto num_rows = gen_chunk.getNumRows();
auto columns = gen_chunk.getColumns();
columns[key] = columns[key]->cloneEmpty()->cloneResized(num_rows);
columns[key] = getColumnWithDefaults(getInputPort().getHeader(), key, num_rows);
Chunks chunks;
chunks.emplace_back(std::move(columns), num_rows);

View File

@ -0,0 +1,113 @@
-- { echoOn }
SELECT
count() as d, a, b, c
FROM test02313
GROUP BY ROLLUP(a, b, c)
ORDER BY d, a, b, c;
1 one default 0
1 one default 2
1 one default 4
1 one default 6
1 one default 8
1 two non-default 1
1 two non-default 3
1 two non-default 5
1 two non-default 7
1 two non-default 9
5 one default 0
5 one default 0
5 two default 0
5 two non-default 0
10 one default 0
SELECT
count() as d, a, b, c
FROM test02313
GROUP BY CUBE(a, b, c)
ORDER BY d, a, b, c;
1 one default 0
1 one default 0
1 one default 0
1 one default 0
1 one default 1
1 one default 2
1 one default 2
1 one default 2
1 one default 2
1 one default 3
1 one default 4
1 one default 4
1 one default 4
1 one default 4
1 one default 5
1 one default 6
1 one default 6
1 one default 6
1 one default 6
1 one default 7
1 one default 8
1 one default 8
1 one default 8
1 one default 8
1 one default 9
1 one non-default 1
1 one non-default 3
1 one non-default 5
1 one non-default 7
1 one non-default 9
1 two default 1
1 two default 3
1 two default 5
1 two default 7
1 two default 9
1 two non-default 1
1 two non-default 3
1 two non-default 5
1 two non-default 7
1 two non-default 9
5 one default 0
5 one default 0
5 one default 0
5 one non-default 0
5 two default 0
5 two non-default 0
10 one default 0
SELECT
count() as d, a, b, c
FROM test02313
GROUP BY GROUPING SETS
(
(c),
(a, c),
(b, c)
)
ORDER BY d, a, b, c;
1 one default 0
1 one default 0
1 one default 0
1 one default 1
1 one default 2
1 one default 2
1 one default 2
1 one default 3
1 one default 4
1 one default 4
1 one default 4
1 one default 5
1 one default 6
1 one default 6
1 one default 6
1 one default 7
1 one default 8
1 one default 8
1 one default 8
1 one default 9
1 one non-default 1
1 one non-default 3
1 one non-default 5
1 one non-default 7
1 one non-default 9
1 two default 1
1 two default 3
1 two default 5
1 two default 7
1 two default 9

View File

@ -0,0 +1,39 @@
DROP TABLE IF EXISTS test02313;
CREATE TABLE test02313
(
a Enum('one' = 1, 'two' = 2),
b Enum('default' = 0, 'non-default' = 1),
c UInt8
)
ENGINE = MergeTree()
ORDER BY (a, b, c);
INSERT INTO test02313 SELECT number % 2 + 1 AS a, number % 2 AS b, number FROM numbers(10);
-- { echoOn }
SELECT
count() as d, a, b, c
FROM test02313
GROUP BY ROLLUP(a, b, c)
ORDER BY d, a, b, c;
SELECT
count() as d, a, b, c
FROM test02313
GROUP BY CUBE(a, b, c)
ORDER BY d, a, b, c;
SELECT
count() as d, a, b, c
FROM test02313
GROUP BY GROUPING SETS
(
(c),
(a, c),
(b, c)
)
ORDER BY d, a, b, c;
-- { echoOff }
DROP TABLE test02313;