Merge pull request #21761 from ClickHouse/aku/chunk-no-columns

fix incorrect number of rows for Chunks with no columns in PartialSor…
This commit is contained in:
Alexander Kuzmenkov 2021-03-18 17:58:09 +03:00 committed by GitHub
commit c821c0c27a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 37 additions and 7 deletions

View File

@ -2038,7 +2038,13 @@ void InterpreterSelectQuery::executeWindow(QueryPlan & query_plan)
for (size_t i = 0; i < windows_sorted.size(); ++i)
{
const auto & w = *windows_sorted[i];
if (i == 0 || !sortIsPrefix(w, *windows_sorted[i - 1]))
// We don't need to sort again if the input from previous window already
// has suitable sorting. Also don't create sort steps when there are no
// columns to sort by, because the sort nodes are confused by this. It
// happens in case of `over ()`.
if (!w.full_sort_description.empty()
&& (i == 0 || !sortIsPrefix(w, *windows_sorted[i - 1])))
{
auto partial_sorting = std::make_unique<PartialSortingStep>(
query_plan.getCurrentDataStream(),

View File

@ -10,6 +10,8 @@ PartialSortingTransform::PartialSortingTransform(
: ISimpleTransform(header_, header_, false)
, description(description_), limit(limit_)
{
// Sorting by no columns doesn't make sense.
assert(!description.empty());
}
static ColumnRawPtrs extractColumns(const Block & block, const SortDescription & description)
@ -91,6 +93,14 @@ size_t getFilterMask(const ColumnRawPtrs & lhs, const ColumnRawPtrs & rhs, size_
void PartialSortingTransform::transform(Chunk & chunk)
{
if (chunk.getNumRows())
{
// The following code works with Blocks and will lose the number of
// rows when there are no columns. We shouldn't get such block, because
// we have to sort by at least one column.
assert(chunk.getNumColumns());
}
if (read_rows)
read_rows->add(chunk.getNumRows());

View File

@ -881,12 +881,13 @@ void WindowTransform::appendChunk(Chunk & chunk)
assert(chunk.hasRows());
blocks.push_back({});
auto & block = blocks.back();
// Use the number of rows from the Chunk, because it is correct even in
// the case where the Chunk has no columns. Not sure if this actually
// happens, because even in the case of `count() over ()` we have a dummy
// input column.
block.rows = chunk.getNumRows();
block.input_columns = chunk.detachColumns();
// Even in case of `count() over ()` we should have a dummy input column.
// Not sure how reliable this is...
block.rows = block.input_columns[0]->size();
for (auto & ws : workspaces)
{
// Aggregate functions can't work with constant columns, so we have to
@ -1109,9 +1110,7 @@ IProcessor::Status WindowTransform::prepare()
if (output.canPush())
{
// Output the ready block.
// fmt::print(stderr, "output block {}\n", next_output_block_number);
const auto i = next_output_block_number - first_block_number;
++next_output_block_number;
auto & block = blocks[i];
auto columns = block.input_columns;
for (auto & res : block.output_columns)
@ -1120,6 +1119,12 @@ IProcessor::Status WindowTransform::prepare()
}
output_data.chunk.setColumns(columns, block.rows);
// fmt::print(stderr, "output block {} as chunk '{}'\n",
// next_output_block_number,
// output_data.chunk.dumpStructure());
++next_output_block_number;
output.pushData(std::move(output_data));
}

View File

@ -993,3 +993,8 @@ order by number
7 6 8
8 7 9
9 8 9
-- In this case, we had a problem with PartialSortingTransform returning zero-row
-- chunks for input chunks w/o columns.
select count() over () from numbers(4) where number < 2;
2
2

View File

@ -345,3 +345,7 @@ from numbers(10)
window w as (order by number range between 1 preceding and 1 following)
order by number
;
-- In this case, we had a problem with PartialSortingTransform returning zero-row
-- chunks for input chunks w/o columns.
select count() over () from numbers(4) where number < 2;