You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@datafusion.apache.org by gi...@apache.org on 2026/09/13 08:03:49 UTC
(datafusion) branch main updated: fix: reject groups accumulator for bit_xor(DISTINCT) (#24989)
This is an automated email from the ASF dual-hosted git repository.
github-merge-queue[bot] pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/datafusion.git
The following commit(s) were added to refs/heads/main by this push:
new 681705e6fd fix: reject groups accumulator for bit_xor(DISTINCT) (#24989)
681705e6fd is described below
commit 681705e6fdc4ab1c3df7f734e845a409b8797a83
Author: jackylee <qc...@gmail.com>
AuthorDate: Sun Sep 13 07:53:24 2026 +0000
fix: reject groups accumulator for bit_xor(DISTINCT) (#24989)
## Which issue does this PR close?
- N/A
## Rationale for this change
`bit_xor(DISTINCT c)` with `GROUP BY` fails with `column types must
match schema types, expected List(Int16) but found Int16`:
`groups_accumulator_supported` ignored `is_distinct`, so the plan got
the non-distinct groups accumulator while `state_fields` declared the
`List` state.
## What changes are included in this PR?
`groups_accumulator_supported` now returns false only for
`bit_xor(DISTINCT)`, matching `accumulator` and `state_fields`.
`bit_and` and `bit_or` are idempotent, so they keep the vectorized path.
## What is the testing strategy for this PR?
Three `aggregate.slt` queries: the two shapes `SingleDistinctToGroupBy`
does not rewrite (a non-distinct aggregate alongside, a `FILTER`) fail
on `main`; a `bit_and`/`bit_or` `DISTINCT` row pins the narrower
predicate.
## Are there any user-facing changes?
`bit_xor(DISTINCT)` with `GROUP BY` now works. No API change.
---------
Co-authored-by: Jay Zhan <ja...@gmail.com>
---
.../functions-aggregate/src/bit_and_or_xor.rs | 5 ++--
datafusion/sqllogictest/test_files/aggregate.slt | 29 ++++++++++++++++++++++
2 files changed, 32 insertions(+), 2 deletions(-)
diff --git a/datafusion/functions-aggregate/src/bit_and_or_xor.rs b/datafusion/functions-aggregate/src/bit_and_or_xor.rs
index d730a6c1cb..92212b328e 100644
--- a/datafusion/functions-aggregate/src/bit_and_or_xor.rs
+++ b/datafusion/functions-aggregate/src/bit_and_or_xor.rs
@@ -290,8 +290,9 @@ impl AggregateUDFImpl for BitwiseOperation {
}
}
- fn groups_accumulator_supported(&self, _args: AccumulatorArgs) -> bool {
- true
+ fn groups_accumulator_supported(&self, args: AccumulatorArgs) -> bool {
+ // DISTINCT only changes the result of XOR; AND and OR are idempotent
+ !(args.is_distinct && self.operation == BitwiseOperationType::Xor)
}
fn create_groups_accumulator(
diff --git a/datafusion/sqllogictest/test_files/aggregate.slt b/datafusion/sqllogictest/test_files/aggregate.slt
index edc493cfa1..a4cd3b0ccc 100644
--- a/datafusion/sqllogictest/test_files/aggregate.slt
+++ b/datafusion/sqllogictest/test_files/aggregate.slt
@@ -5123,6 +5123,35 @@ ORDER BY tag
33 11 NULL 33 11 NULL 33 11 NULL B
+# bit_xor(DISTINCT) with GROUP BY must not use the non-distinct groups
+# accumulator: for tag A, 5 ^ 5 ^ 9 = 9 but 5 ^ 9 = 12. AND and OR are
+# idempotent, so they keep the groups accumulator.
+statement ok
+create table bit_distinct (c SMALLINT, tag varchar) as values
+ (5, 'A'), (5, 'A'), (9, 'A'), (33, 'B'), (33, 'B');
+
+query IIT
+SELECT bit_xor(DISTINCT c), count(c), tag FROM bit_distinct GROUP BY tag ORDER BY tag;
+----
+12 3 A
+33 2 B
+
+query IT
+SELECT bit_xor(DISTINCT c) FILTER (WHERE c > 4), tag FROM bit_distinct GROUP BY tag ORDER BY tag;
+----
+12 A
+33 B
+
+query IIIT
+SELECT bit_and(DISTINCT c), bit_or(DISTINCT c), count(c), tag FROM bit_distinct GROUP BY tag ORDER BY tag;
+----
+1 13 3 A
+33 33 2 B
+
+statement ok
+drop table bit_distinct;
+
+
# bit_and_i32
statement ok
create table t (c int) as values (4), (7), (15);
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@datafusion.apache.org
For additional commands, e-mail: commits-help@datafusion.apache.org