Skip to content

Test that the physical optimizer sees a fold's fallback once - #122

Merged
alxmrs merged 1 commit into
mainfrom
m2/fallback-planned-once
Oct 30, 2026
Merged

alxmrs merged 1 commit into
mainfrom
m2/fallback-planned-once

Conversation

@alxmrs

@alxmrs alxmrs commented Oct 30, 2026

Copy link
Copy Markdown
Member

🪭 Claude (einfold)

Nothing changes for users. Fixes #66, which never reached main, and adds a test that would catch it if it did.

#66 reported a planning failure: Cannot swap HashJoinExec inputs after dynamic filters have been constructed. DataFusion's physical optimizer (the rules, such as JoinSelection, that rewrite a physical plan) was optimizing a fold's fallback twice, where the fallback is the host's own plan, run where einfold's kernels decline. The fallback was optimized once when it was planned, and again as a child of EinFoldExec. That child was a commit (a49e236) in the stack before it was squash-merged. On main, EinFoldExec's children have only ever been its operands, and since #87 the fallback is a logical plan, planned only when it runs. So the optimizer can't reach it twice.

Decisions to review

Not in this pull request

#112's DataFusion bugs: #113 steps the simulation around them.

🤖 Generated with Claude Code

https://claude.ai/code/session_01M96xSez6PZwTmfaGh2eJgS

@coderabbitai

coderabbitai Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Caution

Review failed

The pull request is closed.

No actionable comments were generated in the recent review.

Recent review info
Run configuration
Commits

Reviewing files that changed from the base of the PR and between 908b5a5 and cb1cff9.

Files selected for processing: 2
  • crates/einfold-datafusion/tests/detect_vs_host.rs
  • crates/einfold-datafusion/tests/simulation.rs
Files with no reviewable changes: 1
  • crates/einfold-datafusion/tests/simulation.rs

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 7 remain after this review.

Walkthrough

The DataFusion tests add a physical optimizer rule that detects repeated plan leaves and exercise it on a host-fallback fold. The simulation removes the known-issue exemption for dynamic-filter join-swap errors, so host-success/einfold-error cases are reported as failures.

Changes: Fallback optimizer tests

Layer / File(s) Summary
Repeated leaf detection in fallback planning
crates/einfold-datafusion/tests/detect_vs_host.rs
A custom physical optimizer rule records plan leaves and asserts that it does not receive a leaf twice. A host-fallback fold test checks that the plan contains one fold and execution returns four rows.
Dynamic-filter error reporting
crates/einfold-datafusion/tests/simulation.rs
The simulation removes the known-issue exemption for the dynamic-filter join-swap error. When the host succeeds and einfold errors, the simulation now reports the error.

Priority: Low

Estimated code review effort: 2 (Simple) | ~12 minutes

Change: Other

Merge Risk: Minimal · previous review cb1cf

The changes add regression coverage and expose simulation failures. No merge-blocking issue remains.

Pre-merge checks: Passed 3 · Failed 1 · Inconclusive 1

Failed Failed checks: 1 warning · 1 inconclusive

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documenta… Write docstrings for the functions missing them to satisfy the coverage threshold.
Linked Issues check Inconclusive Linked issue: #66 (open, direct). Requirement: a fold with a fallback must plan. The #66 reproduction query must plan at every target_partitions value from 1 to 4. The issue's suggested direction is t… Provide evidence that, at the reviewed head, the planner no longer plans the fallback with create_physical_plan and no longer makes it a child of EinFoldExec. The inspected source paths are crates/einfold-datafusion/src/planner.rs, ein_fold…
Passed Passed checks: 3 passed
Check name Status Explanation
Title check Passed The title is concise, specific, and accurately describes the added regression test for physical optimizer handling of a fold fallback.
Description check Passed The description explains the user impact, links the change to issue #66, documents the design decision, describes the regression test and simulation soak, and states what is out of scope. The testing …
Out of Scope Changes check Passed Both changed files relate directly to #66 and to the pull request objective. detect_vs_host.rs adds imports, a no-op physical optimizer rule named Leaves, and the test the_optimizer_sees_a_fallback_on…
Full details: Description check

Explanation

The description explains the user impact, links the change to issue #66, documents the design decision, describes the regression test and simulation soak, and states what is out of scope. The testing details appear without the template's explicit "## How it is tested" heading, but the required information is present.

Full details: Out of Scope Changes check

Explanation

Both changed files relate directly to #66 and to the pull request objective. detect_vs_host.rs adds imports, a no-op physical optimizer rule named Leaves, and the test the_optimizer_sees_a_fallback_once. The rule fails when it sees a plan leaf twice. This targets the double-optimization cause described in #66. simulation.rs removes the Known::FallbackOptimizedTwice entry from the Known enum and from KNOWN. It also removes the match arm that returned success for errors containing 'Cannot swap HashJoinExec inputs after dynamic filters'. That skip existed only for #66. Removing it lets this error surface as a failure. The diff contains no unrelated behavior changes. The PR description states that #112 and #113 work is not included here, and the diff contains no such changes.

Full details: Docstring Coverage

Explanation

Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 3 functions across 1 files.

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

Full details: Linked Issues check

Explanation

Linked issue: #66 (open, direct). Requirement: a fold with a fallback must plan. The #66 reproduction query must plan at every target_partitions value from 1 to 4. The issue's suggested direction is to optimize the fallback once, with the rest of the plan. This pull request changes only tests: detect_vs_host.rs and simulation.rs. No planner, EinFoldExec, or FoldNode source changes. The PR description says #66 is absent on main, because the fallback is a logical plan planned only when it runs (since #87). I could not verify this from the supplied evidence. The new test, the_optimizer_sees_a_fallback_once, does not run #66's SQL. It uses a different query over TEXT_TABLES and asserts one fold and four rows. Its pass or fail status on head is not shown in the evidence. The soak result (10,399 cases, no planning errors) is an author claim, not verified here. The issue also asks that the test pin both sides, using #66's reproduction. That reproduction is not covered by the new test. Requirement status is therefore unknown, not failed: the source-level claim is plausible but unconfirmed.

Resolution

Provide evidence that, at the reviewed head, the planner no longer plans the fallback with create_physical_plan and no longer makes it a child of EinFoldExec. The inspected source paths are crates/einfold-datafusion/src/planner.rs, ein_fold_exec.rs, and fold_node.rs. Also provide a passing run of the #66 reproduction SQL at target_partitions 1 through 4 on head. If the issue owner requires a test that uses #66's query, that test must also be added. Linked-issue scope is limited to #66 only.

Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@alxmrs
alxmrs force-pushed the m2/fallback-planned-once branch from cb1cff9 to 693abc3 Compare October 30, 2026 04:54
@alxmrs
alxmrs merged commit 18aa3eb into main Oct 30, 2026
6 checks passed
@alxmrs
alxmrs deleted the m2/fallback-planned-once branch October 30, 2026 04:54
alxmrs added a commit that referenced this pull request Oct 30, 2026
🪭 Claude (einfold)

Users install einfold for Python with a plain `pip install
"einfold[datafusion]"`, without `--pre`, once this merges and
`python-v0.1.0` is tagged on it.
[xarray-sql](https://github.com/xqlsystems/xarray-sql), an XQL Systems
project that queries Xarray datasets with SQL, accepted 0.1.0rc2, so
this sets the version in `python/pyproject.toml` from `0.1.0rc2` to
`0.1.0`. The code is the same as rc2's, plus the fixes since then: #122
(a test for #66), #124 (a test's thread counts) and #125 (the Rust
crates' packaging).

## Decisions to review

- **The READMEs drop `--pre`, and keep `--upgrade`, so the command
replaces an installed release candidate** ([`README.md`](README.md),
[`python/README.md`](python/README.md)). The top README now says 0.1 is
released, from Python and from Rust, since the crates are on crates.io
as 0.1.0.
- **The classifier stays `Development Status :: 3 - Alpha`.** einfold
detects a limited set of shapes, and Windows isn't supported yet (#118).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01M96xSez6PZwTmfaGh2eJgS

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Folds with a fallback can fail to plan: the physical optimizer runs over the fallback twice

1 participant