Skip to content

Commit 359f140

Browse files
committed
more work
Signed-off-by: Adam Gutglick <adamgsal@gmail.com>
1 parent 48402be commit 359f140

2 files changed

Lines changed: 49 additions & 11 deletions

File tree

datafusion/physical-plan/src/joins/hash_join/exec.rs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,8 @@ pub(super) struct JoinLeftData {
197197
values: Vec<ArrayRef>,
198198
/// Shared bitmap builder for visited left indices
199199
visited_indices_bitmap: SharedBitmapBuilder,
200+
/// Shared bitmap builder for null marks
201+
null_indices_bitmap: SharedBitmapBuilder,
200202
/// Counter of running probe-threads, potentially
201203
/// able to update `visited_indices_bitmap`
202204
probe_threads_counter: AtomicUsize,
@@ -2024,16 +2026,18 @@ async fn collect_left_input(
20242026
};
20252027

20262028
// Reserve additional memory for visited indices bitmap and create shared builder
2027-
let visited_indices_bitmap = if with_visited_indices_bitmap {
2029+
let (visited_indices_bitmap, null_indices_bitmap) = if with_visited_indices_bitmap {
20282030
let bitmap_size = bit_util::ceil(batch.num_rows(), 8);
2029-
reservation.try_grow(bitmap_size)?;
2030-
metrics.build_mem_used.add(bitmap_size);
2031-
2032-
let mut bitmap_buffer = BooleanBufferBuilder::new(batch.num_rows());
2033-
bitmap_buffer.append_n(num_rows, false);
2034-
bitmap_buffer
2031+
reservation.try_grow(bitmap_size * 2)?;
2032+
metrics.build_mem_used.add(bitmap_size * 2);
2033+
2034+
let mut visited = BooleanBufferBuilder::new(batch.num_rows());
2035+
let mut nulls = BooleanBufferBuilder::new(batch.num_rows());
2036+
visited.append_n(num_rows, false);
2037+
nulls.append_n(num_rows, false);
2038+
(visited, nulls)
20352039
} else {
2036-
BooleanBufferBuilder::new(0)
2040+
(BooleanBufferBuilder::new(0), BooleanBufferBuilder::new(0))
20372041
};
20382042

20392043
let map = Arc::new(join_hash_map);
@@ -2073,6 +2077,7 @@ async fn collect_left_input(
20732077
batch,
20742078
values: left_values,
20752079
visited_indices_bitmap: Mutex::new(visited_indices_bitmap),
2080+
null_indices_bitmap: Mutex::new(null_indices_bitmap),
20762081
probe_threads_counter: AtomicUsize::new(probe_threads_count),
20772082
_reservation: reservation,
20782083
bounds,

datafusion/sqllogictest/test_files/null_aware_mark_join.slt

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,20 @@ CREATE TABLE inner_table_with_null(id INT) AS VALUES
3333
(2),
3434
(NULL);
3535

36+
statement ok
37+
CREATE TABLE outer_corr_table(id INT, grp INT, value TEXT) AS VALUES
38+
(1, 1, 'a'),
39+
(3, 1, 'b'),
40+
(1, 2, 'c'),
41+
(NULL, 1, 'd'),
42+
(5, 3, 'e');
43+
44+
statement ok
45+
CREATE TABLE inner_corr_table(id INT, grp INT) AS VALUES
46+
(2, 1),
47+
(NULL, 1),
48+
(1, 2);
49+
3650
statement ok
3751
CREATE TABLE empty_table(id INT) AS
3852
SELECT *
@@ -121,9 +135,22 @@ c
121135
d
122136
e
123137

124-
###################################
125-
## Sort-merge join null-aware mark
126-
###################################
138+
# Regression test for correlated NOT IN inside a mark join.
139+
query T rowsort
140+
SELECT value
141+
FROM outer_corr_table
142+
WHERE (id NOT IN (
143+
SELECT id
144+
FROM inner_corr_table
145+
WHERE inner_corr_table.grp = outer_corr_table.grp
146+
)) IS NULL;
147+
----
148+
a
149+
b
150+
d
151+
152+
# These queries would fall back to a sort-merge, but we force them
153+
# into hash joins to make sure we null awareness.
127154

128155
statement ok
129156
set datafusion.execution.target_partitions = 2;
@@ -257,5 +284,11 @@ DROP TABLE inner_table_with_null;
257284
statement ok
258285
DROP TABLE inner_table_no_null;
259286

287+
statement ok
288+
DROP TABLE inner_corr_table;
289+
290+
statement ok
291+
DROP TABLE outer_corr_table;
292+
260293
statement ok
261294
DROP TABLE outer_table;

0 commit comments

Comments
 (0)