From 6cd54a1c9e5c7a844281d7b8afb20777fb87db94 Mon Sep 17 00:00:00 2001 From: Jianhong Shi Date: Thu, 6 Aug 2026 03:55:20 -0500 Subject: [PATCH 1/2] fix incorrect results when probing multiple bloom filters --- src/operators/physical_probe_filter.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/operators/physical_probe_filter.cpp b/src/operators/physical_probe_filter.cpp index dd239ac..8357e9d 100644 --- a/src/operators/physical_probe_filter.cpp +++ b/src/operators/physical_probe_filter.cpp @@ -171,7 +171,8 @@ OperatorResultType PhysicalProbeFilter::ExecuteInternal(ExecutionContext &contex // } // lookup directly into selection vector - result_count = bf->LookupSel(input, sel, {bound_column_indices[i]}, state.bit_vector.data()); + SelectionVector newSel = SelectionVector(input.size()); + result_count = bf->LookupSel(input, newSel, {bound_column_indices[i]}, state.bit_vector.data()); // early exit if no rows passed if (result_count == 0) { @@ -185,7 +186,7 @@ OperatorResultType PhysicalProbeFilter::ExecuteInternal(ExecutionContext &contex // apply filter if we filtered rows if (result_count < row_num) { - input.Slice(sel, result_count); + input.Slice(newSel, result_count); row_num = result_count; } } From b02b6215282665cec7d5b541d1c8c665e17b3091 Mon Sep 17 00:00:00 2001 From: Jianhong Shi Date: Thu, 27 Aug 2026 21:45:22 -0500 Subject: [PATCH 2/2] move selection vectors into state --- src/operators/physical_probe_filter.cpp | 15 +++++---------- src/operators/physical_probe_filter.hpp | 5 ++--- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/src/operators/physical_probe_filter.cpp b/src/operators/physical_probe_filter.cpp index 8357e9d..ddb2176 100644 --- a/src/operators/physical_probe_filter.cpp +++ b/src/operators/physical_probe_filter.cpp @@ -104,6 +104,7 @@ OperatorResultType PhysicalProbeFilter::ExecuteInternal(ExecutionContext &contex (unsigned long long)build_col.table_index, (unsigned long long)build_col.column_index, build_table.c_str()); state.bloom_filters.push_back(bf); + state.sel_vector.emplace_back(STANDARD_VECTOR_SIZE); break; // found the filter for this column } } @@ -131,7 +132,6 @@ OperatorResultType PhysicalProbeFilter::ExecuteInternal(ExecutionContext &contex // apply bloom filters idx_t result_count = row_num; - auto &sel = state.sel; unique_ptr probe_timer; if (profiling_stats) { @@ -171,8 +171,8 @@ OperatorResultType PhysicalProbeFilter::ExecuteInternal(ExecutionContext &contex // } // lookup directly into selection vector - SelectionVector newSel = SelectionVector(input.size()); - result_count = bf->LookupSel(input, newSel, {bound_column_indices[i]}, state.bit_vector.data()); + + result_count = bf->LookupSel(input, state.sel_vector[i], {bound_column_indices[i]}, state.bit_vector.data()); // early exit if no rows passed if (result_count == 0) { @@ -186,7 +186,7 @@ OperatorResultType PhysicalProbeFilter::ExecuteInternal(ExecutionContext &contex // apply filter if we filtered rows if (result_count < row_num) { - input.Slice(newSel, result_count); + input.Slice(state.sel_vector[i], result_count); row_num = result_count; } } @@ -194,12 +194,7 @@ OperatorResultType PhysicalProbeFilter::ExecuteInternal(ExecutionContext &contex // stop probe timer before output work probe_timer.reset(); - // optimization: if all rows passed, just reference input (zero-copy) - if (result_count == row_num) { - chunk.Reference(input); - } else { - chunk.Slice(input, sel, result_count); - } + chunk.Reference(input); if (profiling_stats) { profiling_stats->rows_in.fetch_add(original_row_num, std::memory_order_relaxed); diff --git a/src/operators/physical_probe_filter.hpp b/src/operators/physical_probe_filter.hpp index ec8d655..70e7d63 100644 --- a/src/operators/physical_probe_filter.hpp +++ b/src/operators/physical_probe_filter.hpp @@ -12,15 +12,14 @@ class PhysicalCreateFilter; class PhysicalProbeFilterState : public CachingOperatorState { public: - PhysicalProbeFilterState() - : bloom_filters_initialized(false), sel(STANDARD_VECTOR_SIZE), bit_vector((STANDARD_VECTOR_SIZE + 7) / 8) { + PhysicalProbeFilterState() : bloom_filters_initialized(false), bit_vector((STANDARD_VECTOR_SIZE + 7) / 8) { } vector> bloom_filters; bool bloom_filters_initialized; // reusable buffers to avoid per-chunk heap allocations - SelectionVector sel; + vector sel_vector; vector bit_vector; };