Conversation
7670652 to
230d2fb
Compare
f4c8400 to
ae242b1
Compare
gkodinov
left a comment
There was a problem hiding this comment.
Now that the formal requirements are met please find below an honest attempt to review the substance.
| for (uint i=0; i < arg_count ; i++) | ||
| { | ||
| longlong res= args[i]->val_datetime_packed(thd); | ||
| /* |
There was a problem hiding this comment.
I believe the implementation needs more work.
First of all, I believe that val_datetime_packed() can and will check nullness, if there's an actual NULL.
The basic premise of the bug report that DATE('') must return NULL is IMHO flawed. This is not always the case and that's for a reason. MariaDB supports things like fuzzy dates, allow invalid dates etc.
I'd suggest that you explore why DATE('') does not return NULL and what causes it to do that exactly. Then add this to the pull request description.
There was a problem hiding this comment.
What I suggested here is not resolved even by the latest change. But, since this looks like a final review issue (and I have said my peace), I'll let this one slide to final review.
val_datetime_packed() evaluates arguments with TIME_FUZZY_DATES and
TIME_INVALID_DATES. DATE/DATETIME casts pass these flags to their input
conversion, so a failed cast such as DATE('') becomes a zero date and
sets null_value to false before the existing NULL check runs.
Clear only TIME_FUZZY_DATES for DATE/DATETIME arguments. Keep
TIME_INVALID_DATES for calendar-date comparison, all comparison flags
for other input types, and the caller's validation of the selected
result. Evaluate each visited argument once and check the Datetime
before packing it.
Cover failed casts, actual NULLs, mixed input types, columns and views,
stored zero dates, temporal equality, and permissive/invalid calendar
dates under ALLOW_INVALID_DATES, NO_ZERO_DATE and NO_ZERO_IN_DATE.
ae242b1 to
d3a957a
Compare
gkodinov
left a comment
There was a problem hiding this comment.
LGTM. Please stand by for the final review.
GREATEST(DATE(''), DATE('2026-08-20'))currently returns2026-08-20: the comparison context converts the failed DATE cast to a zero date before the existing NULL check runs. This change disables that fallback for DATE/DATETIME arguments ofLEASTandGREATEST, while retaining permissive calendar-date comparison.Bug report: https://jira.mariadb.org/browse/MDEV-40809
Why DATE('') behaves differently in this context
DATE('')does not have a context-independent NULL result. Withsql_mode='', the unmodified server returns NULL forSELECT DATE(''), but returns 1 forSELECT DATE('') = DATE'0000-00-00'. The relevant path inLEAST/GREATESTis:Item_func_min_max::get_date_native()callsval_datetime_packed(). The default implementation constructs aDatetimeusingOptions_cmp, which supplies bothTIME_INVALID_DATESandTIME_FUZZY_DATES.Item_date_typecast::get_date()andItem_datetime_typecast::get_date()combine those caller flags withsql_mode_for_dates(thd)and pass them to the input conversion.Temporal::make_from_str()callsmake_fuzzy_date(): withTIME_FUZZY_DATES, it constructs a zero DATETIME; without that flag, it leavesMYSQL_TIMESTAMP_NONE.null_value=false, so the existing NULL check correctly sees a non-NULL zero date.GREATESTselects the valid date. An actual SQL NULL, such asDATE(NULL), already propagates through the old code.ALLOW_INVALID_DATEScontrols a separate case: dates such as February 30 with individually valid month/day fields. It does not make an empty string parseable. Comparison also deliberately setsTIME_INVALID_DATESindependently of SQL mode, then validates the selected result against the caller's flags. For example, withsql_mode='',GREATEST(DATE('2026-02-30'), DATE'2026-08-20')returns the valid August date, whileLEASTreturns NULL. WithALLOW_INVALID_DATES,LEASTreturns February 30. These behaviors are retained.Change and compatibility
Start with the existing comparison flags and clear only
TIME_FUZZY_DATESfor DATE/DATETIME arguments. Check the resultingDatetimebefore packing it, with one evaluation per visited argument. The conversion context changes; this does not add a missing NULL check toval_datetime_packed().TIME_INVALID_DATES; the previous revision cleared it as well, unnecessarily changing the February 30 example above.NO_ZERO_DATE/NO_ZERO_IN_DATEin explicit casts. Stored temporal values continue to participate in comparison before the selected result is validated.val_datetime_packed()unchanged. TheDATE('') = DATE'0000-00-00'example is covered as an unchanged control.The
main.type_dateregression covers both functions and argument orders, DATE and DATETIME casts, actual NULLs, mixed input types, columns/views, stored zero dates, permissive dates, and the SQL modes above. Its results before the new regression block are unchanged. The PR contains one commit.Validation
Built and tested on the original 11.4 parent,
d10e5d726799b1cd57cc866f40aad68c720803da:main.type_date,main.type_datetime,main.func_time,main.func_hybrid_type,json.type_json,vcol.wrong_arena,innodb.innodb_mysql, andmain.select.main.type_datefixture fails on the unmodified parent only within the new regression block.git diff --checkpassed. The upstream 11.4 head at validation time was511d7527eb356aab52fa183456333c5ba9741bcf; its 17 newer commits do not overlap the three changed files or the inspected conversion implementations.The full test suite and Windows/ARM64/sanitizer builds were not run locally.