mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-22 23:52:03 +00:00
Support types with non-standard defaults in ROLLUP, CUBE, GROUPING SETS
This commit is contained in:
parent
18bda56e4c
commit
0e63583b8f
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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
|
@ -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;
|
Loading…
Reference in New Issue
Block a user