Skip to content

Commit 0d04475

Browse files
authored
fix: align array_has null buffer for scalar (#17272) (#17274)
* fix: align `array_has` null buffer for scalar (#17272) * fix: align `array_has` null buffer for scalar * merge
1 parent a6068c2 commit 0d04475

File tree

2 files changed

+34
-2
lines changed

2 files changed

+34
-2
lines changed

datafusion/physical-expr-common/src/datum.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,9 +154,26 @@ pub fn compare_op_for_nested(
154154
if matches!(op, Operator::IsDistinctFrom | Operator::IsNotDistinctFrom) {
155155
Ok(BooleanArray::new(values, None))
156156
} else {
157-
// If one of the side is NULL, we returns NULL
157+
// If one of the side is NULL, we return NULL
158158
// i.e. NULL eq NULL -> NULL
159-
let nulls = NullBuffer::union(l.nulls(), r.nulls());
159+
// For nested comparisons, we need to ensure the null buffer matches the result length
160+
let nulls = match (is_l_scalar, is_r_scalar) {
161+
(false, false) | (true, true) => NullBuffer::union(l.nulls(), r.nulls()),
162+
(true, false) => {
163+
// When left is null-scalar and right is array, expand left nulls to match result length
164+
match l.nulls().filter(|nulls| !nulls.is_valid(0)) {
165+
Some(_) => Some(NullBuffer::new_null(len)), // Left scalar is null
166+
None => r.nulls().cloned(), // Left scalar is non-null
167+
}
168+
}
169+
(false, true) => {
170+
// When right is null-scalar and left is array, expand right nulls to match result length
171+
match r.nulls().filter(|nulls| !nulls.is_valid(0)) {
172+
Some(_) => Some(NullBuffer::new_null(len)), // Right scalar is null
173+
None => l.nulls().cloned(), // Right scalar is non-null
174+
}
175+
}
176+
};
160177
Ok(BooleanArray::new(values, nulls))
161178
}
162179
}

datafusion/sqllogictest/test_files/array.slt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8065,6 +8065,18 @@ FixedSizeList(Field { name: "item", data_type: Int32, nullable: true, dict_id: 0
80658065
statement error
80668066
create table varying_fixed_size_col_table (a int[3]) as values ([1,2,3]), ([4,5]);
80678067

8068+
statement ok
8069+
COPY (select [[true, false], [false, true]] a, [false, true] b union select [[null, null]], null) to 'test_files/scratch/array/array_has/single_file.parquet' stored as parquet;
8070+
8071+
statement ok
8072+
CREATE EXTERNAL TABLE array_has STORED AS PARQUET location 'test_files/scratch/array/array_has/single_file.parquet';
8073+
8074+
query B
8075+
select array_contains(a, b) from array_has order by 1 nulls last;
8076+
----
8077+
true
8078+
NULL
8079+
80688080
### Delete tables
80698081

80708082
statement ok
@@ -8243,3 +8255,6 @@ drop table values_all_empty;
82438255

82448256
statement ok
82458257
drop table fixed_size_col_table;
8258+
8259+
statement ok
8260+
drop table array_has;

0 commit comments

Comments
 (0)