dragonknightk opened a new pull request, #70461:
URL: https://github.com/apache/doris/pull/70461

   ### Background
   
   Nereids folds date and datetime constants with `java.time.LocalDateTime`, 
which treats year 0 as leap because `0 % 400 == 0`. Doris already treats year 0 
as a common year. The FE parser (`DateLiteral.checkDate`) accepts February 29 
only when `year > 0`, and BE `is_leap` requires `&& year` 
(`be/src/util/time_lut.h`). MySQL documents the same rule in WL#16895 and 
implements it as `year % 400 == 0 && year` in `mysys/my_time.cc`.
   
   ### What problem does this PR solve?
   
   Issue Number: close #68723
   Related PR: None
   PR Type: Bugfix
   
   Problem Summary:
   Queries whose year-0 date constants are folded by FE can return results that 
differ from BE execution. For example, FE folding produced 
`date_add('0000-02-28', 1) = 0000-02-29` and `last_day('0000-02-01') = 
0000-02-29`, while BE returns `0000-03-01` and `0000-02-28`. This fix aligns FE 
folding with the existing Doris common-year convention and leaves BE unchanged; 
changing BE would change parsing and date arithmetic across the engine. After 
upgrading, folded year-0 constants match BE.
   
   ### Details
   
   - **Change map:** 494 lines: 154 production, 313 tests (161 FE unit, 152 
regression suite), 27 generated `.out`, 0 docs. Production: date literal 
`plus*` and day-of-year arithmetic across 0000-02-29 (`DateLiteral` and five 
subclasses, 119 lines); `last_day`, `weekday`, `week`, and `makedate` folding 
(`DateTimeExtractAndTransform`, 35 lines).
   - **Frequency:** FE folds of `date_add`, `last_day`, `dayofyear`, `weekday`, 
`week`, and `makedate` that land on or cross 0000-02-29.
   - **Root cause:** Java inserts 0000-02-29; Doris `is_leap` and `checkDate` 
treat year 0 as a common year.
   - **Why existing tests missed it:** Tests only constructed `0000-02-29` and 
checked the parser exception.
   - **Fix:** Shift day/week arithmetic that crosses 0000-02-29, and clamp 
month/year/`last_day` results of 0000-02-29 to 0000-02-28.
   - **Other paths and branches:** `plusHours`/`plusMinutes`/`plusSeconds` and 
`next_day`/`previous_day`/`to_monday` still use Java day counts; `week()` keeps 
the existing 0000-01-01/02 lookup.
   - **Behavior change:** Folded year-0 dates that crossed 0000-02-29 now 
follow the Doris common-year calendar.
   
   ### Testing
   
   - `mvn checkstyle:check -pl fe-core`: 0 violations.
   - `FoldConstantTest`: 34 passed. `DateLiteralTest`: 16 passed, 2 skipped.
   - Regression suite `test_year0_common_year_fold`: passed. It fails on the 
old FE (`HEAD^`).
   - The local cluster paired this branch's FE with the official 4.1.5 prebuilt 
BE.
   
   ### Release note
   
   FE constant folding of year-0 dates now matches BE: `date_add('0000-02-28', 
1)` is `0000-03-01`, and `last_day('0000-02-01')` is `0000-02-28`.
   
   ### Check List (For Author)
   
   - Behavior changed: Yes (see Details)
   - Does this need documentation: No
   - Pre-submission status: Ready
   
   ### AI Disclosure
   
   - Tool: Grok Bot
   - Generated: production date helpers and folding adjustments, unit tests, 
the new regression suite, and this description
   - Human review: the generated production changes, tests, and this 
description were fully reviewed
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to