cql3: selection: fix GROUP BY, empty groups, and aggregations

A GROUP BY combined with aggregation should produce a single
row per group, except for empty groups. This is in contrast
to an aggregation without GROUP BY, which produces a single
row no matter what.

The existing code only considered the case of no grouping
and forced a row into the result, but this caused an unwanted
row if grouping was used.

Fix by refining the check to also consider GROUP BY.

XFAIL tests are relaxed.

Fixes #12477.

Note, forward_service requires that aggregation produce
exactly one row, but since it can't work with grouping,
it isn't affected.

Closes #14399
This commit is contained in:
Avi Kivity
2023-06-26 21:28:41 +03:00
committed by Nadav Har'El
parent b912eeade5
commit f6f974cdeb
4 changed files with 5 additions and 5 deletions

View File

@@ -427,7 +427,7 @@ void result_set_builder::new_row() {
std::unique_ptr<result_set> result_set_builder::build() {
process_current_row(/*more_rows_coming=*/false);
if (_result_set->empty() && _selectors->is_aggregate()) {
if (_result_set->empty() && _selectors->is_aggregate() && _group_by_cell_indices.empty()) {
_result_set->add_row(_selectors->get_output_row());
}
return std::move(_result_set);

View File

@@ -1247,7 +1247,7 @@ def testCompactStorage(cql, test_keyspace):
assert_rows2(execute(cql, table, "INSERT INTO %s (partition, key, owner) VALUES ('a', 'c', 'x') IF NOT EXISTS"), [row(True)], [row(True,None,None,None)])
# SelectGroupByTest
@pytest.mark.xfail(reason="issue #4244, #5361, #5362, #5363, #12477, #12479")
@pytest.mark.xfail(reason="issue #4244, #5361, #5362, #5363, #12479")
def testGroupByWithoutPaging(cql, test_keyspace):
with create_table(cql, test_keyspace, "(a int, b int, c int, d int, e int, PRIMARY KEY (a, b, c, d)) WITH COMPACT STORAGE") as table:
execute(cql, table, "INSERT INTO %s (a, b, c, d, e) VALUES (1, 2, 1, 3, 6)")

View File

@@ -7,7 +7,7 @@
from cassandra_tests.porting import *
@pytest.mark.xfail(reason="Issue #2060, #5361, #5362, #5363, #12477, #12479, #13109")
@pytest.mark.xfail(reason="Issue #2060, #5361, #5362, #5363, #12479, #13109")
def testGroupByWithoutPaging(cql, test_keyspace):
with create_table(cql, test_keyspace, "(a int, b int, c int, d int, e int, primary key (a, b, c, d))") as table:

View File

@@ -124,12 +124,12 @@ def test_count_and_group_by_partition(cql, table1):
# In the above tests we looked for per-row or per-partition counts and got
# back more than one count. But if our query matches no row, we should get
# back no count.
@pytest.mark.xfail(reason="issue #12477")
#
# Reproduces #12477
def test_count_and_group_by_row_none(cql, table1):
p = unique_key_int()
assert [] == list(cql.execute(f"select p, c, count(v) from {table1} where p = {p} group by p,c"))
@pytest.mark.xfail(reason="issue #12477")
def test_count_and_group_by_partition_none(cql, table1):
p = unique_key_int()
assert [] == list(cql.execute(f"select p, count(v) from {table1} where p = {p} group by p"))