Skip to content

feat: add Plan.ExecutionBehavior support#224

Open
nielspardon wants to merge 1 commit into
substrait-io:mainfrom
nielspardon:feat/issue-185-execution-behavior
Open

feat: add Plan.ExecutionBehavior support#224
nielspardon wants to merge 1 commit into
substrait-io:mainfrom
nielspardon:feat/issue-185-execution-behavior

Conversation

@nielspardon

Copy link
Copy Markdown
Member

What

Adds support for the plan-level execution behavior introduced in Substrait 0.87.0 (Plan.execution_behavior.variable_eval_mode). This is the last open sub-issue of #161; the companion ExecutionContextVariable support (#186) is already merged.

variable_eval_mode controls how often execution context variables (current_timestamp / current_date / current_timezone) are evaluated — once per plan (VARIABLE_EVALUATION_MODE_PER_PLAN) or once per record (VARIABLE_EVALUATION_MODE_PER_RECORD).

Changes

  • builders.plan.with_execution_behavior(plan, variable_eval_mode) — sets Plan.execution_behavior on a copy of the plan.
  • Propagation — execution behavior is now carried over by every relational builder. Rather than sprinkle a call into ~19 builders, it is folded into the single metadata choke point every builder already routes its inputs through (_merge_extensions, renamed to _merge_plan_metadata). As a result the setting survives subsequent operations and is order-independent across a pipeline, instead of only surviving as the last step.
  • DataFrame.with_execution_behavior("per_plan" | "per_record") — wires it into the native fluent frame, following the existing string→enum convention (_JOIN_TYPES, _CREATE_MODES, …).

Test plan

  • New tests/builders/plan/test_with_execution_behavior.py: set/preserve-relations/no-input-mutation, propagation through a later builder, first-input-wins for multi-input builders, last-wins overwrite, unset-by-default.
  • New DataFrame cases in tests/dataframe/test_frame.py: both modes, preserved-through-later-ops, set mid-chain, invalid-mode error, and an end-to-end pairing with current_timestamp.
  • Full suite: 536 passed, 30 skipped; ruff check and ruff format --check clean.

Resolves #185.

🤖 Generated with AI

Exposes the plan-level execution behavior introduced in Substrait 0.87.0
(Plan.execution_behavior.variable_eval_mode), which governs how often
execution context variables (current_timestamp / current_date /
current_timezone) are evaluated -- once per plan or once per record.

- builders.plan.with_execution_behavior(plan, variable_eval_mode) sets it
- execution behavior is now carried over by every relational builder (folded
  into the renamed _merge_plan_metadata helper), so it survives subsequent
  operations and is order independent across a pipeline
- DataFrame.with_execution_behavior("per_plan" | "per_record") wires it into
  the native fluent frame

Resolves substrait-io#185.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

return self._next(resolve)

def with_execution_behavior(self, mode: str) -> "DataFrame":

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.

mode feels too generic here, maybe variable_eval_mode?

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.

add new Plan.ExecutionBehavior

2 participants