[fix](fe) Validate casts before constant folding - #66785
Conversation
### What problem does this PR solve? Issue Number: N/A Problem Summary: Constant folding evaluated literal casts before validating whether their source and target types were compatible. This allowed an unsupported BIGINT to TIMESTAMPTZ cast to be folded into an incorrect timestamp literal while the same cast on a column was rejected. Reuse CheckCast during FE constant folding so unsupported casts remain for the normal validation rule to reject consistently. ### Release note Reject unsupported constant casts from BIGINT to TIMESTAMPTZ consistently with non-constant casts. ### Check List (For Author) - Test: Added unit and regression coverage; passed FE Checkstyle. Unit and regression tests were not run. - Behavior changed: Yes. Unsupported constant casts are rejected instead of being folded. - Does this need documentation: No
|
Thank you for your contribution to Apache Doris. Please clearly describe your PR:
|
|
/review |
|
Codex automated review failed and did not complete. Error: This content was flagged for possible cybersecurity risk. If this seems wrong, try rephrasing your request. To get authorized for security work, join the Trusted Access for Cyber program: https://chatgpt.com/cyber Please inspect the workflow logs and rerun the review after the underlying issue is resolved. |
|
/review |
There was a problem hiding this comment.
Automated review conclusion: changes requested.
The projected SELECT fix is directionally correct, but the stated goal of a consistent analysis error is not reached across all reachable plan shapes. The attached blocking finding shows that invalid constant casts can be discarded before CheckCast, while default fast INSERT ... VALUES never runs that validator.
Critical checkpoint conclusions:
- Goal and correctness: The guard fixes the ordinary FE-folded projection, and the added tests prove that local path, but the reachable ORDER BY, GROUP BY, and fast-insert paths leave the goal incomplete.
- Scope and conditional design: The patch is small and reuses the existing legality table, but returning a residual cast is only safe when every consumer is guaranteed to validate it; that invariant does not hold.
- Parallel paths and configuration: Strict/non-strict casting,
TryCast, BE folding, fold-disabled execution, nested casts, and recursive complex casts were checked. The normal variants preserve the cast until validation; default fast values analysis is the surviving parallel-path gap. No new configuration was added. - Tests and results: The unit checks and expected-error regression are coherent, but they omit the three concrete failing plan shapes in the inline finding. No local build or test was run, as required by the review runner. CI shows successful CheckStyle and general repository checks, but no relevant FE unit/regression result was present.
- Concurrency and lifecycle: Not involved; this is a stateless expression rewrite and introduces no lock, thread, resource, or initialization lifecycle.
- Compatibility and protocol: No function symbol, storage format, persisted state, or FE-BE variable/protocol change is introduced.
- Transactions and data writes: No transaction or persistence mechanism is changed. The fast-insert issue is validation timing before execution, not a new atomicity mechanism.
- Performance and observability: The legality lookup is bounded and no material performance issue was found; this analysis-time validation change does not require new logs or metrics.
- User focus: No additional user-provided focus was supplied.
- Other issues: No additional non-duplicate defect remained after three rounds; the final round converged.
| Expression child = cast.child(); | ||
| DataType dataType = cast.getDataType(); | ||
| if (!CheckCast.check(child.getDataType(), dataType, SessionVariable.enableStrictCast())) { | ||
| return cast; |
There was a problem hiding this comment.
This early return relies on a later CheckCast, but validation currently happens after rules that can erase constant expressions. For example:
Sort(CAST(CAST(20240229112233 AS BIGINT) AS TIMESTAMPTZ(6)))
is processed by EliminateOrderByConstant before expression normalization; because the invalid deterministic cast is still isConstant(), the sort key is removed and CheckCast never sees it. Similarly, NormalizeAggregate.eliminateGroupByConstant folds a GROUP BY-only occurrence, treats the unchanged cast as constant, and removes it before validation. Thus the corresponding ORDER BY and GROUP BY queries can be accepted while the projected expression in the new regression errors. The default fast INSERT ... VALUES analyzer also invokes this folder without any CheckCast and skips normal rewrite, so that path fails only during BE execution. Please enforce cast legality before constant-expression elimination/translation, and add regressions for these paths.
Problem Summary: Constant folding evaluated literal casts before
CheckCastvalidated whether the source and target types were compatible. As a result, an unsupportedBIGINTtoTIMESTAMPTZcast could be folded into an incorrect timestamp literal, while the same cast on a column was rejected. This change reusesCheckCastin FE constant folding and leaves unsupported casts unchanged so the normal validation rule reports a consistent analysis error.Release note
None
Check List (For Author)
Test
Behavior changed:
Does this need documentation?
Check List (For Reviewer who merge this PR)