Skip to content

[CALCITE-7828] Aggregate whose grouping sets include () returns no rows on empty input - #5339

Open
xuzifu666 wants to merge 1 commit into
apache:mainfrom
xuzifu666:calcite-7828
Open

xuzifu666 wants to merge 1 commit into
apache:mainfrom
xuzifu666:calcite-7828

Conversation

@xuzifu666

Copy link
Copy Markdown
Member

@mihaibudiu mihaibudiu left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could benefit from some quidem tests too.

resultSelector));
final Method groupByMultipleMethod;
if (hasEmptyGroup) {
// The key of the empty grouping set is a constant: each grouping

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it would be much better to explain what happens here without references to calcite issues closed long ago.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, I had added comments to explain the behavior on its own: the key of the empty grouping set is a constant, built the same way as the key the selector for that grouping set computes for any input row, and passed to groupByMultiple so that the empty grouping set produces its single row when the input is empty, just as a query with no GROUP BY produces a row over an empty input.

builder.append("emptyGroupKey",
keyPhysType.record(keyExpressions));
arguments.add(emptyGroupKey);
groupByMultipleMethod = BuiltInMethod.GROUP_BY_MULTIPLE2.method;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it would help a lot the reviewers if you showed in a comment the generated Java code.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

}

public void end(Sink sink) throws InterruptedException {
if (accumulators.isEmpty() && grouping.isEmpty()) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the interpreter is hopelessly unmaintained, but it's fine to fix bugs here and there.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed and I wouldn't want to invest much in the interpreter either.
The fix is only a few lines in AggregateNode.Grouping.end, and it keeps the two runtimes consistent now that PruneEmptyRules no longer prunes an aggregate with an empty grouping set: without it, the interpreter would still return 0 rows while the enumerable path returns the grand-total row. I've also dropped the stale issue reference from the comment there.

@xuzifu666

xuzifu666 commented Oct 20, 2026 •

Copy link
Copy Markdown
Member Author

This could benefit from some quidem tests too.

Thanks for the suggestion! @mihaibudiu I had added related quidem and validated in postgresql in https://onecompiler.com/postgresql/456r8bnfy
The results are in line with expectations.

@iwanttobepowerful

Copy link
Copy Markdown
Contributor

This could benefit from some quidem tests too.

Thanks for the suggestion! @mihaibudiu I had added related quidem and validated in postgresql in onecompiler.com/postgresql/456r8bnfy The results are in line with expectations.

what is the result in oracle/sql server?

@mihaibudiu

Copy link
Copy Markdown
Contributor

Do you really expect the results to differ?

@xuzifu666

Copy link
Copy Markdown
Member Author

Do you really expect the results to differ?

I tested it on SQL Server, and it doesn't support this syntax. I believe PostgreSQL is a more convincing solution in this case.

@iwanttobepowerful

Copy link
Copy Markdown
Contributor

@mihaibudiu

Copy link
Copy Markdown
Contributor

This is rather strange if you ask me. This makes the semantics of this query not really compositional as the union of the implied component queries.

@xuzifu666

Copy link
Copy Markdown
Member Author

As concluded in the Jira discussion, the current PR implementation aligns with that outcome; barring any further objections, I will proceed to merge it. cc @mihaibudiu @iwanttobepowerful

@sonarqubecloud

Copy link
Copy Markdown

@xuzifu666 xuzifu666 added the LGTM-will-merge-soon Overall PR looks OK. Only minor things left. label Oct 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

LGTM-will-merge-soon Overall PR looks OK. Only minor things left.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants