mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-24 08:32:02 +00:00
dbms: fixed error with merging [#METR-16247].
This commit is contained in:
parent
566b62854b
commit
e3b0c97b0f
@ -50,7 +50,7 @@ protected:
|
|||||||
Block readImpl() override;
|
Block readImpl() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Logger * log = &Logger::get("SummingSortedBlockInputStream");
|
Logger * log = &Logger::get("AggregatingSortedBlockInputStream");
|
||||||
|
|
||||||
/// Прочитали до конца.
|
/// Прочитали до конца.
|
||||||
bool finished = false;
|
bool finished = false;
|
||||||
@ -68,7 +68,7 @@ private:
|
|||||||
* Шаблоны используем вместо полиморфных SortCursor'ов и вызовов виртуальных функций.
|
* Шаблоны используем вместо полиморфных SortCursor'ов и вызовов виртуальных функций.
|
||||||
*/
|
*/
|
||||||
template<class TSortCursor>
|
template<class TSortCursor>
|
||||||
void merge(Block & merged_block, ColumnPlainPtrs & merged_columns, std::priority_queue<TSortCursor> & queue);
|
void merge(ColumnPlainPtrs & merged_columns, std::priority_queue<TSortCursor> & queue);
|
||||||
|
|
||||||
/// Вставить в результат первую строку для текущей группы.
|
/// Вставить в результат первую строку для текущей группы.
|
||||||
void insertCurrentRow(ColumnPlainPtrs & merged_columns);
|
void insertCurrentRow(ColumnPlainPtrs & merged_columns);
|
||||||
|
@ -81,7 +81,7 @@ private:
|
|||||||
* Шаблоны используем вместо полиморфных SortCursor'ов и вызовов виртуальных функций.
|
* Шаблоны используем вместо полиморфных SortCursor'ов и вызовов виртуальных функций.
|
||||||
*/
|
*/
|
||||||
template<class TSortCursor>
|
template<class TSortCursor>
|
||||||
void merge(Block & merged_block, ColumnPlainPtrs & merged_columns, std::priority_queue<TSortCursor> & queue);
|
void merge(ColumnPlainPtrs & merged_columns, std::priority_queue<TSortCursor> & queue);
|
||||||
|
|
||||||
/// Вставить в результат строки для текущего идентификатора "визита".
|
/// Вставить в результат строки для текущего идентификатора "визита".
|
||||||
void insertRows(ColumnPlainPtrs & merged_columns, size_t & merged_rows, bool last_in_stream = false);
|
void insertRows(ColumnPlainPtrs & merged_columns, size_t & merged_rows, bool last_in_stream = false);
|
||||||
|
@ -136,7 +136,7 @@ private:
|
|||||||
void initQueue(std::priority_queue<TSortCursor> & queue);
|
void initQueue(std::priority_queue<TSortCursor> & queue);
|
||||||
|
|
||||||
template <typename TSortCursor>
|
template <typename TSortCursor>
|
||||||
void merge(Block & merged_block, ColumnPlainPtrs & merged_columns, std::priority_queue<TSortCursor> & queue);
|
void merge(ColumnPlainPtrs & merged_columns, std::priority_queue<TSortCursor> & queue);
|
||||||
|
|
||||||
Logger * log = &Logger::get("MergingSortedBlockInputStream");
|
Logger * log = &Logger::get("MergingSortedBlockInputStream");
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ private:
|
|||||||
* Шаблоны используем вместо полиморфных SortCursor'ов и вызовов виртуальных функций.
|
* Шаблоны используем вместо полиморфных SortCursor'ов и вызовов виртуальных функций.
|
||||||
*/
|
*/
|
||||||
template<class TSortCursor>
|
template<class TSortCursor>
|
||||||
void merge(Block & merged_block, ColumnPlainPtrs & merged_columns, std::priority_queue<TSortCursor> & queue);
|
void merge(ColumnPlainPtrs & merged_columns, std::priority_queue<TSortCursor> & queue);
|
||||||
|
|
||||||
/// Вставить в результат просуммированную строку для текущей группы.
|
/// Вставить в результат просуммированную строку для текущей группы.
|
||||||
void insertCurrentRow(ColumnPlainPtrs & merged_columns);
|
void insertCurrentRow(ColumnPlainPtrs & merged_columns);
|
||||||
|
@ -61,16 +61,16 @@ Block AggregatingSortedBlockInputStream::readImpl()
|
|||||||
columns_to_aggregate[i] = typeid_cast<ColumnAggregateFunction *>(merged_columns[column_numbers_to_aggregate[i]]);
|
columns_to_aggregate[i] = typeid_cast<ColumnAggregateFunction *>(merged_columns[column_numbers_to_aggregate[i]]);
|
||||||
|
|
||||||
if (has_collation)
|
if (has_collation)
|
||||||
merge(merged_block, merged_columns, queue_with_collation);
|
merge(merged_columns, queue_with_collation);
|
||||||
else
|
else
|
||||||
merge(merged_block, merged_columns, queue);
|
merge(merged_columns, queue);
|
||||||
|
|
||||||
return merged_block;
|
return merged_block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class TSortCursor>
|
template<class TSortCursor>
|
||||||
void AggregatingSortedBlockInputStream::merge(Block & merged_block, ColumnPlainPtrs & merged_columns, std::priority_queue<TSortCursor> & queue)
|
void AggregatingSortedBlockInputStream::merge(ColumnPlainPtrs & merged_columns, std::priority_queue<TSortCursor> & queue)
|
||||||
{
|
{
|
||||||
size_t merged_rows = 0;
|
size_t merged_rows = 0;
|
||||||
|
|
||||||
@ -81,13 +81,15 @@ void AggregatingSortedBlockInputStream::merge(Block & merged_block, ColumnPlainP
|
|||||||
|
|
||||||
setPrimaryKey(next_key, current);
|
setPrimaryKey(next_key, current);
|
||||||
|
|
||||||
|
bool key_differs = next_key != current_key;
|
||||||
|
|
||||||
/// если накопилось достаточно строк и последняя посчитана полностью
|
/// если накопилось достаточно строк и последняя посчитана полностью
|
||||||
if (next_key != current_key && merged_rows >= max_block_size)
|
if (key_differs && merged_rows >= max_block_size)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
queue.pop();
|
queue.pop();
|
||||||
|
|
||||||
if (next_key != current_key)
|
if (key_differs)
|
||||||
{
|
{
|
||||||
current_key = std::move(next_key);
|
current_key = std::move(next_key);
|
||||||
next_key.resize(description.size());
|
next_key.resize(description.size());
|
||||||
|
@ -104,15 +104,15 @@ Block CollapsingSortedBlockInputStream::readImpl()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (has_collation)
|
if (has_collation)
|
||||||
merge(merged_block, merged_columns, queue_with_collation);
|
merge(merged_columns, queue_with_collation);
|
||||||
else
|
else
|
||||||
merge(merged_block, merged_columns, queue);
|
merge(merged_columns, queue);
|
||||||
|
|
||||||
return merged_block;
|
return merged_block;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class TSortCursor>
|
template<class TSortCursor>
|
||||||
void CollapsingSortedBlockInputStream::merge(Block & merged_block, ColumnPlainPtrs & merged_columns, std::priority_queue<TSortCursor> & queue)
|
void CollapsingSortedBlockInputStream::merge(ColumnPlainPtrs & merged_columns, std::priority_queue<TSortCursor> & queue)
|
||||||
{
|
{
|
||||||
size_t merged_rows = 0;
|
size_t merged_rows = 0;
|
||||||
|
|
||||||
@ -120,12 +120,22 @@ void CollapsingSortedBlockInputStream::merge(Block & merged_block, ColumnPlainPt
|
|||||||
while (!queue.empty())
|
while (!queue.empty())
|
||||||
{
|
{
|
||||||
TSortCursor current = queue.top();
|
TSortCursor current = queue.top();
|
||||||
queue.pop();
|
|
||||||
|
|
||||||
Int8 sign = get<Int64>((*current->all_columns[sign_column_number])[current->pos]);
|
Int8 sign = get<Int64>((*current->all_columns[sign_column_number])[current->pos]);
|
||||||
setPrimaryKey(next_key, current);
|
setPrimaryKey(next_key, current);
|
||||||
|
|
||||||
if (next_key != current_key)
|
bool key_differs = next_key != current_key;
|
||||||
|
|
||||||
|
/// если накопилось достаточно строк и последняя посчитана полностью
|
||||||
|
if (key_differs && merged_rows >= max_block_size)
|
||||||
|
{
|
||||||
|
++blocks_written;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
queue.pop();
|
||||||
|
|
||||||
|
if (key_differs)
|
||||||
{
|
{
|
||||||
/// Запишем данные для предыдущего визита.
|
/// Запишем данные для предыдущего визита.
|
||||||
insertRows(merged_columns, merged_rows);
|
insertRows(merged_columns, merged_rows);
|
||||||
@ -168,12 +178,6 @@ void CollapsingSortedBlockInputStream::merge(Block & merged_block, ColumnPlainPt
|
|||||||
/// Достаём из соответствующего источника следующий блок, если есть.
|
/// Достаём из соответствующего источника следующий блок, если есть.
|
||||||
fetchNextBlock(current, queue);
|
fetchNextBlock(current, queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (merged_rows >= max_block_size)
|
|
||||||
{
|
|
||||||
++blocks_written;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Запишем данные для последнего визита.
|
/// Запишем данные для последнего визита.
|
||||||
|
@ -111,15 +111,15 @@ Block MergingSortedBlockInputStream::readImpl()
|
|||||||
return Block();
|
return Block();
|
||||||
|
|
||||||
if (has_collation)
|
if (has_collation)
|
||||||
merge(merged_block, merged_columns, queue_with_collation);
|
merge(merged_columns, queue_with_collation);
|
||||||
else
|
else
|
||||||
merge(merged_block, merged_columns, queue);
|
merge(merged_columns, queue);
|
||||||
|
|
||||||
return merged_block;
|
return merged_block;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TSortCursor>
|
template <typename TSortCursor>
|
||||||
void MergingSortedBlockInputStream::merge(Block & merged_block, ColumnPlainPtrs & merged_columns, std::priority_queue<TSortCursor> & queue)
|
void MergingSortedBlockInputStream::merge(ColumnPlainPtrs & merged_columns, std::priority_queue<TSortCursor> & queue)
|
||||||
{
|
{
|
||||||
size_t merged_rows = 0;
|
size_t merged_rows = 0;
|
||||||
|
|
||||||
|
@ -142,16 +142,16 @@ Block SummingSortedBlockInputStream::readImpl()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (has_collation)
|
if (has_collation)
|
||||||
merge(merged_block, merged_columns, queue_with_collation);
|
merge(merged_columns, queue_with_collation);
|
||||||
else
|
else
|
||||||
merge(merged_block, merged_columns, queue);
|
merge(merged_columns, queue);
|
||||||
|
|
||||||
return merged_block;
|
return merged_block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class TSortCursor>
|
template<class TSortCursor>
|
||||||
void SummingSortedBlockInputStream::merge(Block & merged_block, ColumnPlainPtrs & merged_columns, std::priority_queue<TSortCursor> & queue)
|
void SummingSortedBlockInputStream::merge(ColumnPlainPtrs & merged_columns, std::priority_queue<TSortCursor> & queue)
|
||||||
{
|
{
|
||||||
size_t merged_rows = 0;
|
size_t merged_rows = 0;
|
||||||
|
|
||||||
@ -159,11 +159,18 @@ void SummingSortedBlockInputStream::merge(Block & merged_block, ColumnPlainPtrs
|
|||||||
while (!queue.empty())
|
while (!queue.empty())
|
||||||
{
|
{
|
||||||
TSortCursor current = queue.top();
|
TSortCursor current = queue.top();
|
||||||
queue.pop();
|
|
||||||
|
|
||||||
setPrimaryKey(next_key, current);
|
setPrimaryKey(next_key, current);
|
||||||
|
|
||||||
if (next_key != current_key)
|
bool key_differs = next_key != current_key;
|
||||||
|
|
||||||
|
/// если накопилось достаточно строк и последняя посчитана полностью
|
||||||
|
if (key_differs && merged_rows >= max_block_size)
|
||||||
|
return;
|
||||||
|
|
||||||
|
queue.pop();
|
||||||
|
|
||||||
|
if (key_differs)
|
||||||
{
|
{
|
||||||
/// Запишем данные для предыдущей группы.
|
/// Запишем данные для предыдущей группы.
|
||||||
if (!current_key[0].isNull() && !current_row_is_zero)
|
if (!current_key[0].isNull() && !current_row_is_zero)
|
||||||
@ -194,9 +201,6 @@ void SummingSortedBlockInputStream::merge(Block & merged_block, ColumnPlainPtrs
|
|||||||
/// Достаём из соответствующего источника следующий блок, если есть.
|
/// Достаём из соответствующего источника следующий блок, если есть.
|
||||||
fetchNextBlock(current, queue);
|
fetchNextBlock(current, queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (merged_rows >= max_block_size)
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Запишем данные для последней группы, если она ненулевая.
|
/// Запишем данные для последней группы, если она ненулевая.
|
||||||
|
120
dbms/tests/queries/0_stateless/00155_merges.reference
Normal file
120
dbms/tests/queries/0_stateless/00155_merges.reference
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
1 1
|
||||||
|
1 1
|
||||||
|
|
||||||
|
1 1
|
||||||
|
1 1
|
||||||
|
|
||||||
|
1 1
|
||||||
|
1 1
|
||||||
|
|
||||||
|
|
||||||
|
1 1
|
||||||
|
1 1
|
||||||
|
|
||||||
|
1 1
|
||||||
|
1 1
|
||||||
|
|
||||||
|
1 1
|
||||||
|
1 1
|
||||||
|
|
||||||
|
|
||||||
|
1 1
|
||||||
|
1 1
|
||||||
|
|
||||||
|
1 1
|
||||||
|
1 1
|
||||||
|
|
||||||
|
1 1
|
||||||
|
1 1
|
||||||
|
|
||||||
|
|
||||||
|
1 1
|
||||||
|
1 1
|
||||||
|
|
||||||
|
1 1
|
||||||
|
1 1
|
||||||
|
|
||||||
|
1 1
|
||||||
|
1 1
|
||||||
|
|
||||||
|
|
||||||
|
1 1
|
||||||
|
1 1
|
||||||
|
|
||||||
|
1 1
|
||||||
|
1 1
|
||||||
|
|
||||||
|
1 1
|
||||||
|
1 1
|
||||||
|
|
||||||
|
|
||||||
|
1 1
|
||||||
|
1 1
|
||||||
|
|
||||||
|
1 1
|
||||||
|
1 1
|
||||||
|
|
||||||
|
1 1
|
||||||
|
1 1
|
||||||
|
|
||||||
|
|
||||||
|
1 1
|
||||||
|
1 1
|
||||||
|
|
||||||
|
1 1
|
||||||
|
1 1
|
||||||
|
|
||||||
|
1 1
|
||||||
|
1 1
|
||||||
|
|
||||||
|
|
||||||
|
1 1
|
||||||
|
1 1
|
||||||
|
|
||||||
|
1 1
|
||||||
|
1 1
|
||||||
|
|
||||||
|
1 1
|
||||||
|
1 1
|
||||||
|
|
||||||
|
|
||||||
|
1 1
|
||||||
|
1 1
|
||||||
|
|
||||||
|
1 1
|
||||||
|
1 1
|
||||||
|
|
||||||
|
1 1
|
||||||
|
1 1
|
||||||
|
|
||||||
|
|
||||||
|
1 1
|
||||||
|
1 1
|
||||||
|
|
||||||
|
1 1
|
||||||
|
1 1
|
||||||
|
|
||||||
|
1 1
|
||||||
|
1 1
|
||||||
|
|
||||||
|
|
||||||
|
1 1
|
||||||
|
1 1
|
||||||
|
|
||||||
|
1 1
|
||||||
|
1 1
|
||||||
|
|
||||||
|
1 1
|
||||||
|
1 1
|
||||||
|
|
||||||
|
|
||||||
|
1 1
|
||||||
|
1 1
|
||||||
|
|
||||||
|
1 1
|
||||||
|
1 1
|
||||||
|
|
||||||
|
1 1
|
||||||
|
1 1
|
||||||
|
|
||||||
|
|
64
dbms/tests/queries/0_stateless/00155_merges.sh
Executable file
64
dbms/tests/queries/0_stateless/00155_merges.sh
Executable file
@ -0,0 +1,64 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
function create {
|
||||||
|
clickhouse-client --query="DROP TABLE IF EXISTS test.summing"
|
||||||
|
clickhouse-client --query="DROP TABLE IF EXISTS test.collapsing"
|
||||||
|
clickhouse-client --query="DROP TABLE IF EXISTS test.aggregating"
|
||||||
|
|
||||||
|
clickhouse-client --query="CREATE TABLE test.summing (d Date DEFAULT today(), x UInt64, s UInt64 DEFAULT 1) ENGINE = SummingMergeTree(d, x, 8192)"
|
||||||
|
clickhouse-client --query="CREATE TABLE test.collapsing (d Date DEFAULT today(), x UInt64, s UInt64 DEFAULT 1) ENGINE = CollapsingMergeTree(d, x, 8192, s)"
|
||||||
|
clickhouse-client --query="CREATE TABLE test.aggregating (d Date DEFAULT today(), x UInt64, s AggregateFunction(sum, UInt64)) ENGINE = AggregatingMergeTree(d, x, 8192)"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function cleanup {
|
||||||
|
clickhouse-client --query="DROP TABLE test.summing"
|
||||||
|
clickhouse-client --query="DROP TABLE test.collapsing"
|
||||||
|
clickhouse-client --query="DROP TABLE test.aggregating"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function test {
|
||||||
|
create
|
||||||
|
|
||||||
|
SUM=$(( $1 + $2 ))
|
||||||
|
MAX=$(( $1 > $2 ? $1 : $2 ))
|
||||||
|
|
||||||
|
clickhouse-client --query="INSERT INTO test.summing (x) SELECT number AS x FROM system.numbers LIMIT $1"
|
||||||
|
clickhouse-client --query="INSERT INTO test.summing (x) SELECT number AS x FROM system.numbers LIMIT $2"
|
||||||
|
|
||||||
|
clickhouse-client --query="INSERT INTO test.collapsing (x) SELECT number AS x FROM system.numbers LIMIT $1"
|
||||||
|
clickhouse-client --query="INSERT INTO test.collapsing (x) SELECT number AS x FROM system.numbers LIMIT $2"
|
||||||
|
|
||||||
|
clickhouse-client --query="INSERT INTO test.aggregating (d, x, s) SELECT today() AS d, number AS x, sumState(materialize(toUInt64(1))) AS s FROM (SELECT number FROM system.numbers LIMIT $1) GROUP BY number"
|
||||||
|
clickhouse-client --query="INSERT INTO test.aggregating (d, x, s) SELECT today() AS d, number AS x, sumState(materialize(toUInt64(1))) AS s FROM (SELECT number FROM system.numbers LIMIT $2) GROUP BY number"
|
||||||
|
|
||||||
|
clickhouse-client --query="SELECT count() = $SUM, sum(s) = $SUM FROM test.summing"
|
||||||
|
clickhouse-client --query="OPTIMIZE TABLE test.summing"
|
||||||
|
clickhouse-client --query="SELECT count() = $MAX, sum(s) = $SUM FROM test.summing"
|
||||||
|
echo
|
||||||
|
clickhouse-client --query="SELECT count() = $SUM, sum(s) = $SUM FROM test.collapsing"
|
||||||
|
clickhouse-client --query="OPTIMIZE TABLE test.collapsing"
|
||||||
|
clickhouse-client --query="SELECT count() = $MAX, sum(s) = $MAX FROM test.collapsing"
|
||||||
|
echo
|
||||||
|
clickhouse-client --query="SELECT count() = $SUM, sumMerge(s) = $SUM FROM test.aggregating"
|
||||||
|
clickhouse-client --query="OPTIMIZE TABLE test.aggregating"
|
||||||
|
clickhouse-client --query="SELECT count() = $MAX, sumMerge(s) = $SUM FROM test.aggregating"
|
||||||
|
echo
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
test 8191 8191
|
||||||
|
test 8191 8192
|
||||||
|
test 8192 8191
|
||||||
|
test 8192 8192
|
||||||
|
test 8192 8193
|
||||||
|
test 8193 8192
|
||||||
|
test 8193 8193
|
||||||
|
test 8191 8193
|
||||||
|
test 8193 8191
|
||||||
|
test 8193 8194
|
||||||
|
test 8194 8193
|
||||||
|
test 8194 8194
|
||||||
|
|
||||||
|
cleanup
|
Loading…
Reference in New Issue
Block a user