Skip to content

feat(layout): add a Filter plan over dense segment scans - #10389

Closed
joseph-isaacs wants to merge 5 commits into
developfrom
ji/exec-1-filter-plan
Closed

joseph-isaacs wants to merge 5 commits into
developfrom
ji/exec-1-filter-plan

Conversation

@joseph-isaacs

@joseph-isaacs joseph-isaacs commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Summary

First piece pulled out of the V2 scan work in #10349. It prepares the plan layer for a push-based executor, which follows in a separate stack of five PRs starting with the ExecNode trait and exec graph.

In that executor a bare SegmentScan produces every row of its range, taking the selection only as a hint, so that a predicate can be evaluated over a whole decoded segment and the selection applied afterwards. Something above the scan has to keep the selected rows. That is what Filter is for.

Changes

  • Add Filter, a plan operator with no predicate. The rows it keeps are the selection it is executed with. Its child produces every row of the same row domain, and values outside the selection are unspecified. Its dtype and row domain are its child's.
  • lower now lowers a flat layout to Filter(SegmentScan) instead of a bare SegmentScan.
  • Existing plan display snapshots are updated for the extra level, and the three shape assertions on flat layouts now expect Filter.

Add `Filter`, a plan operator with no predicate that keeps only the rows
of the selection it is executed with. Its child produces every row of the
same row domain, and values outside the selection are unspecified.

Flat layouts now lower to a `Filter` over their `SegmentScan`, so a bare
scan can stay dense and return every row of its range while the filter
above it keeps the selected ones. Plan display snapshots are updated for
the extra level.

Signed-off-by: Joe Isaacs <[email protected]>
Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01NWYmfHTFtaEdhdyd3u5hv3
@codspeed

codspeed Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

Merging this PR will improve performance by 10.62%

⚠️ Unknown Walltime execution environment detected

Using the Walltime instrument on standard Hosted Runners will lead to inconsistent data.

For the most accurate results, we recommend using CodSpeed Macro Runners: bare-metal machines fine-tuned for performance measurement consistency.

⚠️ 1 benchmark measured no execution time

Nothing ran under measurement, usually because the compiler removed the code under test. This result is not comparable, so it counts as unchanged.

Preventing compiler optimizations

⚡ 1 improved benchmark
✅ 2170 untouched benchmarks
⏩ 534 skipped benchmarks1

Performance Changes

Mode Benchmark BASE HEAD Efficiency
⚡ WallTime words_gather_dispatch_neon[65536] 2.3 µs 2 µs +10.62%
⚠️ Simulation bench_compare_primitive[(10000, 2)] 64.4 µs < 1 ns N/A

Tip

Curious why performance improved? Comment @codspeedbot explain why performance improved on this PR, or directly use the CodSpeed MCP with your agent.


Comparing ji/exec-1-filter-plan (3670db8) with develop (8185e6a)2

Open in CodSpeed

Footnotes

  1. 534 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩

  2. No successful run was found on develop (e0c00d5) during the generation of this report, so 8185e6a was used instead as the comparison base. There might be some changes unrelated to this pull request in this report. ↩

@joseph-isaacs joseph-isaacs added the changelog/feature A new feature label Oct 8, 2026
Lowering a flat layout returns the bare SegmentScan again; Filter stays
an opt-in operator for the executor to insert. Filter carries no
operator data, so its PlanData is () like Take's.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01DbnSuK9EpzvTSbrwpJT1sW
Signed-off-by: Joe Isaacs <[email protected]>
Filter now has two children, [child, mask], where mask is a
non-nullable bool plan over the same row domain. A predicate is
Filter(x, Eval(pred, x)). The rows a plan is executed with become a
Selection leaf that the executor binds per range, so the mask is a
visible part of the plan rather than ambient execution state.

Construction and with_children reject a mask of another dtype or row
count, which catches domain mismatches under Take and ListPack.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01DbnSuK9EpzvTSbrwpJT1sW
Signed-off-by: Joe Isaacs <[email protected]>
@joseph-isaacs
joseph-isaacs disabled auto-merge October 8, 2026 16:20
@joseph-isaacs
joseph-isaacs enabled auto-merge (squash) October 8, 2026 16:20
@github-actions

Copy link
Copy Markdown
Contributor

This PR has been marked as stale because it has been open for 14 days with no activity. Please comment or remove the stale label if you wish to keep it active, otherwise it will be closed in 7 days

@github-actions github-actions Bot added the stale This PR is stale and will be auto-closed soon label Oct 24, 2026

Copy link
Copy Markdown
Contributor Author

Closing as superseded: develop has a Filter plan with the same semantics in vortex-layout/src/plan/physical/plans/filter.rs, from #10392 and #10625/#10706.


Generated by Claude Code

auto-merge was automatically disabled November 3, 2026 11:32

Pull request was closed

@robert3005
robert3005 deleted the ji/exec-1-filter-plan branch November 10, 2026 11:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

changelog/feature A new feature stale This PR is stale and will be auto-closed soon

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants