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/10/15 13:03:39 UTC
(datafusion) branch gh-readonly-queue/main/pr-26096-91211237689551dfae0f6bd8299ac54bcc1fb1f1 created (now c52eb9734b)
This is an automated email from the ASF dual-hosted git repository.
github-merge-queue[bot] pushed a change to branch gh-readonly-queue/main/pr-26096-91211237689551dfae0f6bd8299ac54bcc1fb1f1
in repository https://gitbox.apache.org/repos/asf/datafusion.git
at c52eb9734b fix: downcast to FixedSizeBinaryArray in CASE literal lookup table (#26096)
This branch includes the following new commits:
new c52eb9734b fix: downcast to FixedSizeBinaryArray in CASE literal lookup table (#26096)
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@datafusion.apache.org
For additional commands, e-mail: commits-help@datafusion.apache.org
(datafusion) 01/01: fix: downcast to FixedSizeBinaryArray in CASE literal lookup table (#26096)
Posted by gi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
github-merge-queue[bot] pushed a commit to branch gh-readonly-queue/main/pr-26096-91211237689551dfae0f6bd8299ac54bcc1fb1f1
in repository https://gitbox.apache.org/repos/asf/datafusion.git
commit c52eb9734b4c968ad9880fb82f3214efd88cd82b
Author: Patrick Ribbsaeter <pa...@gmail.com>
AuthorDate: Thu Oct 15 12:48:50 2026 +0000
fix: downcast to FixedSizeBinaryArray in CASE literal lookup table (#26096)
## Which issue does this PR close?
Closes #26012.
## Rationale for this change
In `LiteralLookupTable`, evaluation of `CASE <expr> WHEN <literal> ...`
with byte-like literals delegates to `BytesLikeIndexMap`. In
`try_get_bytes_iterator`, the `DataType::FixedSizeBinary(_)` match arm
erroneously attempted to downcast the array via `as_binary::<i64>()`
(inherited from `DataType::LargeBinary`), rather than handling
`FixedSizeBinaryArray`.
When a query contained 2 or more `FixedSizeBinary` WHEN literals,
`LiteralLookupTable` was constructed and panicked during evaluation when
downcasting to `GenericBinaryArray<i64>`:
```text
thread 'main' panicked at arrow-array-60.0.0/src/cast.rs:938:29:
binary array
```
## What changes are included in this PR?
1. **Fix Downcast in Lookup Table**: Updated
`DataType::FixedSizeBinary(_)` arm in `try_get_bytes_iterator`
(`bytes_like_lookup_table.rs`) to downcast via
`array.as_fixed_size_binary().iter()`, matching the dictionary
downcasting path and returning byte slices correctly.
2. **Unit Test**: Added
`test_case_when_literal_lookup_fixed_size_binary_to_int32` in
`datafusion/physical-expr/src/expressions/case.rs` testing
`LiteralLookupTable` evaluation with `FixedSizeBinary` literals with and
without ELSE, with and without NULLs.
3. **Sqllogictest**: Added regression tests in
`datafusion/sqllogictest/test_files/case.slt` verifying
`FixedSizeBinary` `CASE` evaluation against branch 1, branch 2,
fallback, NULL inputs, and multiple rows.
## Are these changes tested?
Yes:
- Unit test in `datafusion/physical-expr/src/expressions/case.rs`
(`test_case_when_literal_lookup_fixed_size_binary_to_int32`)
- Sqllogictest in `datafusion/sqllogictest/test_files/case.slt`
- Validated locally with `cargo test` and `cargo clippy`.
## Are there any user-facing changes?
Bug fix: queries with `CASE` expressions containing multiple
`FixedSizeBinary` literals now evaluate correctly instead of panicking.
---
*Diff minimization and pre-flight validation performed with [ZeroSlop™
CI](https://github.com/marketplace/actions/zeroslop-by-ribbsaeter-systems)
— [Ribbsaeter Systems](https://ribbsaetersystems.com/).*
Signed-off-by: Patrick Ribbsaeter <pa...@users.noreply.github.com>
---
datafusion/physical-expr/src/expressions/case.rs | 46 +++++++++++++++++
.../bytes_like_lookup_table.rs | 2 +-
datafusion/sqllogictest/test_files/case.slt | 60 ++++++++++++++++++++++
3 files changed, 107 insertions(+), 1 deletion(-)
diff --git a/datafusion/physical-expr/src/expressions/case.rs b/datafusion/physical-expr/src/expressions/case.rs
index 1e4d106837..c30eb9d332 100644
--- a/datafusion/physical-expr/src/expressions/case.rs
+++ b/datafusion/physical-expr/src/expressions/case.rs
@@ -3500,6 +3500,52 @@ mod tests {
);
}
+ #[test]
+ fn test_case_when_literal_lookup_fixed_size_binary_to_int32() {
+ let lookup_map = vec![
+ (
+ ScalarValue::FixedSizeBinary(1, Some(vec![1])),
+ ScalarValue::Int32(Some(10)),
+ ),
+ (
+ ScalarValue::FixedSizeBinary(1, Some(vec![2])),
+ ScalarValue::Int32(Some(20)),
+ ),
+ ];
+
+ let input_values = ScalarValue::iter_to_array(vec![
+ ScalarValue::FixedSizeBinary(1, Some(vec![1])),
+ ScalarValue::FixedSizeBinary(1, Some(vec![2])),
+ ScalarValue::FixedSizeBinary(1, Some(vec![3])),
+ ScalarValue::FixedSizeBinary(1, None),
+ ])
+ .expect("valid fixed size binary array");
+
+ let expected_no_else =
+ Arc::new(Int32Array::from(vec![Some(10), Some(20), None, None])) as ArrayRef;
+
+ test_case_when_literal_lookup(
+ Arc::clone(&input_values),
+ &lookup_map,
+ None,
+ expected_no_else,
+ );
+
+ let expected_with_else = Arc::new(Int32Array::from(vec![
+ Some(10),
+ Some(20),
+ Some(99),
+ Some(99),
+ ])) as ArrayRef;
+
+ test_case_when_literal_lookup(
+ input_values,
+ &lookup_map,
+ Some(ScalarValue::Int32(Some(99))),
+ expected_with_else,
+ );
+ }
+
/// Reproduces https://github.com/apache/datafusion/issues/22173
///
/// Nested self-referential CASE chains (common in rewrite-style projections)
diff --git a/datafusion/physical-expr/src/expressions/case/literal_lookup_table/bytes_like_lookup_table.rs b/datafusion/physical-expr/src/expressions/case/literal_lookup_table/bytes_like_lookup_table.rs
index e5cf3f84fd..658d9cdaee 100644
--- a/datafusion/physical-expr/src/expressions/case/literal_lookup_table/bytes_like_lookup_table.rs
+++ b/datafusion/physical-expr/src/expressions/case/literal_lookup_table/bytes_like_lookup_table.rs
@@ -106,7 +106,7 @@ fn try_get_bytes_iterator(
DataType::LargeBinary => Box::new(array.as_binary::<i64>().into_iter()),
- DataType::FixedSizeBinary(_) => Box::new(array.as_binary::<i64>().into_iter()),
+ DataType::FixedSizeBinary(_) => Box::new(array.as_fixed_size_binary().iter()),
DataType::Utf8View => Box::new(
array
diff --git a/datafusion/sqllogictest/test_files/case.slt b/datafusion/sqllogictest/test_files/case.slt
index 3f9058bce8..712981ed83 100644
--- a/datafusion/sqllogictest/test_files/case.slt
+++ b/datafusion/sqllogictest/test_files/case.slt
@@ -846,6 +846,66 @@ drop table letters;
statement ok
drop table letters_binary;
+# Regression test for https://github.com/apache/datafusion/issues/26012
+# CASE with two or more FixedSizeBinary WHEN literals
+query I
+SELECT CASE x
+ WHEN arrow_cast(X'01', 'FixedSizeBinary(1)') THEN 1
+ WHEN arrow_cast(X'02', 'FixedSizeBinary(1)') THEN 2
+ ELSE 3
+ END AS r
+FROM (SELECT arrow_cast(X'03', 'FixedSizeBinary(1)') AS x);
+----
+3
+
+query I
+SELECT CASE x
+ WHEN arrow_cast(X'01', 'FixedSizeBinary(1)') THEN 1
+ WHEN arrow_cast(X'02', 'FixedSizeBinary(1)') THEN 2
+ ELSE 3
+ END AS r
+FROM (SELECT arrow_cast(X'02', 'FixedSizeBinary(1)') AS x);
+----
+2
+
+query I
+SELECT CASE x
+ WHEN arrow_cast(X'01', 'FixedSizeBinary(1)') THEN 1
+ WHEN arrow_cast(X'02', 'FixedSizeBinary(1)') THEN 2
+ ELSE 3
+ END AS r
+FROM (SELECT arrow_cast(X'01', 'FixedSizeBinary(1)') AS x);
+----
+1
+
+query I
+SELECT CASE x
+ WHEN arrow_cast(X'01', 'FixedSizeBinary(1)') THEN 1
+ WHEN arrow_cast(X'02', 'FixedSizeBinary(1)') THEN 2
+ ELSE 3
+ END AS r
+FROM (SELECT arrow_cast(NULL, 'FixedSizeBinary(1)') AS x);
+----
+3
+
+query I
+SELECT CASE x
+ WHEN arrow_cast(X'01', 'FixedSizeBinary(1)') THEN 10
+ WHEN arrow_cast(X'02', 'FixedSizeBinary(1)') THEN 20
+ ELSE 99
+ END AS r
+FROM (VALUES
+ (arrow_cast(X'01', 'FixedSizeBinary(1)')),
+ (arrow_cast(X'02', 'FixedSizeBinary(1)')),
+ (arrow_cast(X'03', 'FixedSizeBinary(1)')),
+ (arrow_cast(NULL, 'FixedSizeBinary(1)'))
+) t(x);
+----
+10
+20
+99
+99
+
# Tests for CASE with boolean expressions
statement ok
create table booleans (b boolean) as values (true), (false), (null), (true), (null), (false);
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@datafusion.apache.org
For additional commands, e-mail: commits-help@datafusion.apache.org