Skip to content

Add plan optimizer rules and push expressions - #9196

Open
joseph-isaacs wants to merge 1 commit into
developfrom
vortex-plan-rules
Open

Add plan optimizer rules and push expressions#9196
joseph-isaacs wants to merge 1 commit into
developfrom
vortex-plan-rules

Conversation

@joseph-isaacs

@joseph-isaacs joseph-isaacs commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Summary

  • add typed PlanParentReduceRule and type-erased adapter APIs for child-driven physical-plan rewrites
  • add an ordered static PlanParentRuleSet whose first successful rewrite wins
  • register concrete Eval reductions for Concat, Take, RowIdx, and Pack
  • drive optimization top-down so a rewrite can discard unused children before those children are optimized
  • partition bound expressions directly, pushing independent struct-field work into referenced fields while retaining cross-field residuals
  • push safe boolean expressions through dictionary values and optimize heterogeneous chunks independently
  • preserve global row-index semantics and reduce root-independent expressions through RowIdx, including the empty pack() used by COUNT(*)
  • keep recursive traversal in the optimizer: rules return one unoptimized replacement and the optimizer continues from it

Why these are one change

The rule interfaces have no useful behavior without registered rules, and the pushdown implementation defines the invariants the interfaces must support. Keeping them together makes the API reviewable against its real consumers and leaves one complete optimizer commit. This PR therefore absorbs the former #9166, which is closed with no remaining implementation diff.

Safety

  • debug builds verify every successful rewrite preserves row count and dtype
  • dictionary pushdown requires boolean output, a root reference, strictness, and infallibility
  • nullable struct expressions remain above parent validity
  • cross-field expressions remain residual expressions over a struct pruned to referenced fields
  • chunk pushdown rejects expressions that reference global row indices
  • a same-child-type guard prevents a residual expression from immediately reapplying the same rule

Stack

This is the first active PR after merged plan-model PR #9142. It is followed directly by #9187.

Checks

  • RUSTC_WRAPPER= cargo test -p vortex-layout — 229 passed
  • RUSTC_WRAPPER= cargo clippy -p vortex-layout --all-targets --all-features -- -D warnings
  • cargo +nightly fmt --all -- --check
  • git diff --check

@codspeed-hq

codspeed-hq Bot commented Aug 5, 2026

Copy link
Copy Markdown

Merging this PR will improve performance by 20.44%

⚠️ 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 improved benchmark
✅ 1993 untouched benchmarks
⏩ 89 skipped benchmarks1

Performance Changes

Mode Benchmark BASE HEAD Efficiency
Simulation cold_misaligned[(64, 256)] 5.3 ms 4.4 ms +20.44%

Tip

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


Comparing vortex-plan-rules (5361eb1) with develop (15c73f3)

Open in CodSpeed

Footnotes

  1. 89 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.

@joseph-isaacs
joseph-isaacs force-pushed the vortex-plan-rules branch 3 times, most recently from 3675240 to 79b24a6 Compare August 6, 2026 20:40
@joseph-isaacs
joseph-isaacs force-pushed the vortex-plan-rules branch 3 times, most recently from 29488db to 6c8e44e Compare August 7, 2026 15:33
@joseph-isaacs
joseph-isaacs force-pushed the vortex-plan-rules branch 2 times, most recently from 08b86f2 to 825351d Compare August 7, 2026 16:05
@joseph-isaacs
joseph-isaacs force-pushed the vortex-plan-rules branch 2 times, most recently from 15deec3 to 9b8ffd7 Compare August 10, 2026 14:10
Base automatically changed from vortex-plan to develop August 12, 2026 10:41
@joseph-isaacs
joseph-isaacs marked this pull request as ready for review August 12, 2026 10:41
@joseph-isaacs joseph-isaacs changed the title Add plan parent-reduction rule API Add plan optimizer rules and push expressions Aug 12, 2026
Comment thread vortex-layout/src/plan/plans/eval.rs Outdated
// A residual expression may remain above the same child kind after a successful rewrite.
// Do not immediately apply that rule again; recursively optimize only the retained child.
let child_type = eval.child_plan()?.id();
let blocked = (child_type == previous_child_type).then_some(previous_child_type);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't work for nested field access since the next level is the same planid, not sure if this is handled in a follow up but you likely want to return some kind of continuation token

@joseph-isaacs
joseph-isaacs force-pushed the vortex-plan-rules branch 2 times, most recently from 2cd6302 to ce79a77 Compare August 13, 2026 16:37
@joseph-isaacs
joseph-isaacs force-pushed the vortex-plan-rules branch 2 times, most recently from 8eee7bd to ad5bb90 Compare August 14, 2026 11:49
Signed-off-by: Joe Isaacs <joe.isaacs@live.co.uk>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

changelog/feature A new feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants