[FLINK-40169][table] Add target option to the EARLY_FIRE hint - #28827
Conversation
|
Hi @RocMarshal, opening PR-2 of the FLIP-497 stack early as a draft so it's queued behind #28796. Since it's stacked, the commit list and diff here also carry #28796's commit for now. Once that one is merged I'll rebase this onto master, leaving only the Thanks! |
Add an optional `target` option to the EARLY_FIRE join hint. Only `interval_join` is accepted today; any other value fails planning. An omitted target is equivalent to `interval_join`, so existing hints keep their meaning. `target` scopes the hint to a single operator kind. The interval-join rule consumes the hint only when it targets the interval join and leaves a hint aimed at another operator kind untouched, so an untargeted hint never silently expands its scope.
0ef163a to
3b14d56
Compare
|
Hi @RocMarshal, #28796 is merged, so this one is rebased onto master and out of draft. One thing worth your eye: the rule-level target check in PTAL when you have a moment. Thanks! |
|
The one failing check looks unrelated to this PR.
Why it cannot be this change: the PR touches 5 files, all under The failure also looks like a timing flake rather than a real regression. The test races a rescale, a Retriggering CI to confirm. |
|
Still red on
Same source tree, two different failures, so this does not look like a regression from this PR. The PR touches 5 files, all under The clearest evidence is on Same test, same two line numbers, on a commit that does not contain this change. Both failures also occur outside this PR. I grepped the failed
One caveat on those counts: only builds whose final result is For what it is worth, |
| // target scopes the hint to one operator kind: this rule applies it only when it targets | ||
| // the interval join, and leaves a hint aimed at any other operator kind untouched. | ||
| String target = conf.get(EarlyFireJoinHintOptions.TARGET); | ||
| if (target != null && !EarlyFireJoinHintOptions.INTERVAL_JOIN.equals(target)) { |
There was a problem hiding this comment.
| if (target != null && !EarlyFireJoinHintOptions.INTERVAL_JOIN.equals(target)) { | |
| if (!EarlyFireJoinHintOptions.INTERVAL_JOIN.equals(target)) { |
There was a problem hiding this comment.
Thanks for the review. Good catch. I had to add one more piece to make it work.
target had no default, so when someone leaves it out, conf.get returns null and !INTERVAL_JOIN.equals(null) is true. The hint would get thrown away for the common EARLY_FIRE('delay'='5s') form. Six tests catch it, and in two of them the validation errors stop firing, so a bad hint would plan fine instead of failing.
So I gave target a default of interval_join. It is never null now, your line works as written, and the checker in FlinkHintStrategies drops its null check too. Pushed in 559ab5d.
There was a problem hiding this comment.
Sorry and thanks @weiqingy for your clarify.
Given that this involves changing a config default, I'm unsure if it conflicts with the ratified FLIP.
That said, the original implementation remains perfectly reasonable to me. If altering this default goes against the design outlined in the FLIP, please revert to the original approach. Thanks.
…_join Declaring TARGET with a default of interval_join puts the "an omitted target means interval_join" contract in the option itself, so the rule and the hint checker both reduce to a plain equality check instead of each re-deriving the contract from a null test.
There was a problem hiding this comment.
Pull request overview
This PR extends the EARLY_FIRE SQL join hint (part of the FLIP-497 implementation stack) by introducing a target option that scopes the hint to a specific operator kind. Today, only interval_join is accepted (and remains the default), preserving existing behavior while preventing a bare EARLY_FIRE hint from unintentionally expanding scope if additional operators support it in the future.
Changes:
- Add
EarlyFireJoinHintOptions.TARGET(defaulting tointerval_join) and theINTERVAL_JOINconstant in the@PublicEvolvinghint options. - Validate
targetin the EARLY_FIRE KV option checker to reject unsupported values at planning time. - Ensure
StreamPhysicalIntervalJoinRuleonly applies the hint whentarget=interval_join, plus add/extend planner tests to cover explicit and unsupported targets.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| flink-table/flink-table-planner/src/test/resources/org/apache/flink/table/planner/plan/hints/stream/EarlyFireJoinHintTest.xml | Adds golden-plan coverage for an explicit target='interval_join' EARLY_FIRE hint. |
| flink-table/flink-table-planner/src/test/java/org/apache/flink/table/planner/plan/hints/stream/EarlyFireJoinHintTest.java | Adds test cases for unsupported target validation and explicit interval_join targeting. |
| flink-table/flink-table-planner/src/main/java/org/apache/flink/table/planner/plan/rules/physical/stream/StreamPhysicalIntervalJoinRule.java | Applies EARLY_FIRE only when the hint targets interval joins. |
| flink-table/flink-table-planner/src/main/java/org/apache/flink/table/planner/hint/FlinkHintStrategies.java | Extends EARLY_FIRE hint option validation to check target. |
| flink-table/flink-table-api-java/src/main/java/org/apache/flink/table/api/config/EarlyFireJoinHintOptions.java | Introduces the TARGET option and INTERVAL_JOIN constant in the public hint-option surface. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Restore the explicit null handling for an omitted target so the option surface stays as designed: target is optional with no default, and both the hint checker and the interval-join rule treat an absent target as interval_join. Scope the INTERVAL_JOIN javadoc to the operator kind supported today, since target exists so that a future operator kind can opt in explicitly.
RocMarshal
left a comment
There was a problem hiding this comment.
Given the lack of further responses over the past days,
we will proceed with merging this PR to keep things moving. If there are additional suggestions, please feel free to submit a hotfix or follow-up PR.
Thanks!
Part of the FLIP-497 implementation stack under umbrella FLINK-36953. Landing order:
targetoptionWhat is the purpose of the change
Adds an optional
targetoption to theEARLY_FIREhint so a hint can be explicitly scoped to a single operator kind. Onlyinterval_joinis accepted today, and an omittedtargetmeansinterval_join, so existing hints keep their meaning. This is a forward-compatibility guard: it keeps a bareEARLY_FIREhint from silently expanding its scope if other operators honor the hint in the future.Brief change log
EarlyFireJoinHintOptions.TARGET(optionalstringType) and theINTERVAL_JOINconstant.EARLY_FIREKV option checker validatestargetagainst the supported set. Any other value fails planning.StreamPhysicalIntervalJoinRuleapplies the hint only when it targets the interval join, and leaves a hint aimed at another operator kind untouched. That rule-level check is redundant with validation today, since an unsupported value already fails planning. It is there so that a hint aimed at a future operator kind is ignored by this rule rather than misapplied.Verifying this change
This change added tests and can be verified as follows:
EarlyFireJoinHintTest: an explicittarget='interval_join'still threadsearlyFireDelay/earlyFireTimeModeinto the exec plan, and an unsupportedtargetvalue fails planning with a message naming the supported set.Does this pull request potentially affect one of the following parts:
@Public(Evolving): yes (a new option on the@PublicEvolvingEarlyFireJoinHintOptions)Documentation
Was generative AI tooling used to co-author this PR?
Generated-by: Claude Code (Anthropic)