Skip to content

Make PlannerContext implement Calcite Context for rule-time option access#18567

Merged
gortiz merged 1 commit into
apache:masterfrom
gortiz:feat/planner-context-implements-context
May 25, 2026
Merged

Make PlannerContext implement Calcite Context for rule-time option access#18567
gortiz merged 1 commit into
apache:masterfrom
gortiz:feat/planner-context-implements-context

Conversation

@gortiz
Copy link
Copy Markdown
Contributor

@gortiz gortiz commented May 22, 2026

Summary

PlannerContext now implements org.apache.calcite.plan.Context and passes itself as the context to both the opt planner and the trait planner.

This allows Calcite rules contributed via the RuleSetCustomizer SPI (#18387) to read per-query options at match time without reflection:

PlannerContext ctx =
    call.getPlanner().getContext().unwrap(PlannerContext.class);
String runtime = ctx.getOptions().get("workerRuntime");

unwrap() also delegates to _envConfig, so any code that previously unwrapped QueryEnvironment.Config continues to work unchanged.

A package-private constructor and a forTesting() factory method are added so unit tests can construct a PlannerContext without going through QueryEnvironment, and PlannerContextTest covers the unwrap contract and verifies that both planners expose the PlannerContext instance through their context.

Changes

  • PlannerContext implements Context
  • Both _relOptPlanner and _relTraitPlanner receive this as their context
  • unwrap(PlannerContext.class) and unwrap(Context.class) return this; unwrap(QueryEnvironment.Config.class) delegates to _envConfig
  • forTesting() factory + package-private constructor for unit testing
  • PlannerContextTest — 5 tests verifying the unwrap contract and planner context exposure

Test plan

  • PlannerContextTest (5 tests) — all pass
  • Existing pinot-query-planner test suite passes

PlannerContext now implements org.apache.calcite.plan.Context and passes
itself as the context to both the opt planner (LogicalPlanner backed by
optProgram) and the trait planner (LogicalPlanner backed by traitProgram).

This allows Calcite rules contributed via the new RuleSetCustomizer SPI
(see apache#18387) to read per-query options at match time without reflection:

  PlannerContext ctx =
      call.getPlanner().getContext().unwrap(PlannerContext.class);
  String runtime = ctx.getOptions().get("workerRuntime");

unwrap() also delegates to _envConfig, so any rule that currently
unwraps QueryEnvironment.Config continues to work unchanged.

A package-private constructor and a public forTesting() factory are
added so unit tests can construct a PlannerContext without going through
QueryEnvironment (which requires a full broker setup).
@gortiz gortiz requested a review from yashmayya May 22, 2026 12:44
@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented May 22, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 64.28%. Comparing base (bc2f955) to head (8f6b3b4).

Additional details and impacted files
@@             Coverage Diff              @@
##             master   #18567      +/-   ##
============================================
- Coverage     64.29%   64.28%   -0.01%     
  Complexity     1137     1137              
============================================
  Files          3314     3314              
  Lines        204064   204082      +18     
  Branches      31760    31761       +1     
============================================
- Hits         131193   131186       -7     
- Misses        62348    62372      +24     
- Partials      10523    10524       +1     
Flag Coverage Δ
custom-integration1 100.00% <ø> (ø)
integration 100.00% <ø> (ø)
integration1 100.00% <ø> (ø)
integration2 0.00% <ø> (?)
java-21 64.28% <100.00%> (-0.01%) ⬇️
temurin 64.28% <100.00%> (-0.01%) ⬇️
unittests 64.27% <100.00%> (-0.01%) ⬇️
unittests1 56.73% <100.00%> (+<0.01%) ⬆️
unittests2 35.53% <19.04%> (-0.02%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@yashmayya yashmayya added the multi-stage Related to the multi-stage query engine label May 22, 2026
@gortiz gortiz merged commit f77730e into apache:master May 25, 2026
11 checks passed
@gortiz gortiz deleted the feat/planner-context-implements-context branch May 25, 2026 13:05
@xiangfu0
Copy link
Copy Markdown
Contributor

Opened the matching docs update in pinot-contrib/pinot-docs#825: pinot-contrib/pinot-docs#825

xiangfu0 added a commit to pinot-contrib/pinot-docs that referenced this pull request May 25, 2026
## Summary
- document the new `PlannerContext` access path for `RuleSetCustomizer`
plugins
- show how planner rules can unwrap `PlannerContext` from Calcite
context and read per-query options
- keep the update scoped to the existing planner rule customizer SPI
docs

## Validation
- `git diff --check`
- lightweight link resolution check for
`developers/plugin-architecture/README.md`

## Source cross-check
-
`pinot-query-planner/src/main/java/org/apache/pinot/query/context/PlannerContext.java`
-
`pinot-query-planner/src/test/java/org/apache/pinot/query/context/PlannerContextTest.java`
- `apache/pinot#18567`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

multi-stage Related to the multi-stage query engine

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants