Skip to content

Commit e962cdf

Browse files
committed
Inline zero-date mode checks into the CASE expression
Instead of conditionally building $zero_date_whens in PHP, the WHEN clauses are always present in the CASE statement with the SQL mode check embedded as a literal boolean (AND NOT 0/1). This keeps the generated SQL structure consistent regardless of active modes.
1 parent f8c58de commit e962cdf

1 file changed

Lines changed: 21 additions & 51 deletions

File tree

wp-includes/sqlite-ast/class-wp-pdo-mysql-on-sqlite.php

Lines changed: 21 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -4511,11 +4511,11 @@ private function translate_datetime_literal( string $value ): string {
45114511
*
45124512
* See: https://dev.mysql.com/doc/refman/8.4/en/sql-mode.html#sqlmode_no_zero_in_date
45134513
*/
4514-
$is_zero_in_date = (
4514+
$has_zero_in_date = (
4515+
( '00' === $matches[2] || '00' === $matches[3] ) &&
45154516
'0000' !== $matches[1]
4516-
&& ( '00' === $matches[2] || '00' === $matches[3] )
45174517
);
4518-
if ( ! $is_zero_in_date || $this->is_sql_mode_active( 'NO_ZERO_IN_DATE' ) ) {
4518+
if ( ! $has_zero_in_date || $this->is_sql_mode_active( 'NO_ZERO_IN_DATE' ) ) {
45194519
$value = '0000-00-00 00:00:00';
45204520
}
45214521
}
@@ -5678,8 +5678,11 @@ private function cast_value_for_saving(
56785678
}
56795679

56805680
/*
5681-
* Build additional WHEN clauses to accept zero dates based
5682-
* on the NO_ZERO_DATE and NO_ZERO_IN_DATE SQL modes.
5681+
* Build the CASE expression for date/time validation.
5682+
*
5683+
* SQLite's DATE()/DATETIME() functions return NULL for zero
5684+
* dates, so the CASE includes explicit checks controlled by
5685+
* the NO_ZERO_DATE and NO_ZERO_IN_DATE SQL modes.
56835686
*
56845687
* In MySQL, the behavior of zero dates depends on these modes:
56855688
*
@@ -5692,60 +5695,27 @@ private function cast_value_for_saving(
56925695
* - Disabled: dates with zero month/day parts (e.g. '2020-00-15') are permitted.
56935696
* - Enabled without strict mode: zero-part dates produce a warning and are stored as '0000-00-00'.
56945697
* - Enabled with strict mode: zero-part dates produce an error.
5695-
*
5696-
* SQLite's DATE()/DATETIME() functions return NULL for zero dates,
5697-
* so without these extra WHEN clauses, zero dates would always fall
5698-
* through to the error/implicit-default fallback.
56995698
*/
5700-
$zero_date_whens = '';
5701-
if ( 'time' !== $mysql_data_type ) {
5702-
/*
5703-
* When NO_ZERO_DATE is not active, or when it is active but
5704-
* strict mode is off, accept all-zero dates. In MySQL, only
5705-
* the combination of NO_ZERO_DATE + strict mode rejects them.
5706-
*/
5707-
$reject_zero_date = (
5708-
$this->is_sql_mode_active( 'NO_ZERO_DATE' )
5709-
&& $is_strict_mode
5710-
);
5711-
if ( ! $reject_zero_date ) {
5712-
$zero_date_value = 'date' === $mysql_data_type
5713-
? "'0000-00-00'"
5714-
: "'0000-00-00 00:00:00'";
5715-
$zero_date_whens .= sprintf(
5716-
"WHEN %s IN ('0000-00-00', '0000-00-00 00:00:00') THEN %s\n",
5717-
$translated_value,
5718-
$zero_date_value
5719-
);
5720-
}
5721-
5722-
/*
5723-
* When NO_ZERO_IN_DATE is not active, accept dates where the
5724-
* year is nonzero but the month or day part is zero (e.g.
5725-
* '2020-00-15' or '2020-01-00'). These are valid in MySQL when
5726-
* the NO_ZERO_IN_DATE mode is disabled.
5727-
*/
5728-
if ( ! $this->is_sql_mode_active( 'NO_ZERO_IN_DATE' ) ) {
5729-
$zero_date_whens .= sprintf(
5730-
"WHEN SUBSTR(%s, 1, 4) != '0000' AND (SUBSTR(%s, 6, 2) = '00' OR SUBSTR(%s, 9, 2) = '00') THEN %s\n",
5731-
$translated_value,
5732-
$translated_value,
5733-
$translated_value,
5734-
$translated_value
5735-
);
5736-
}
5737-
}
5699+
$reject_zero_date = (
5700+
$this->is_sql_mode_active( 'NO_ZERO_DATE' ) && $is_strict_mode
5701+
) ? 1 : 0;
5702+
$reject_zero_in_date = $this->is_sql_mode_active( 'NO_ZERO_IN_DATE' ) ? 1 : 0;
5703+
$zero_date_value = 'date' === $mysql_data_type
5704+
? "'0000-00-00'"
5705+
: "'0000-00-00 00:00:00'";
57385706

57395707
return sprintf(
57405708
"CASE
57415709
WHEN %s IS NULL THEN NULL
5742-
%sWHEN %s > '0' THEN %s
5710+
WHEN %s IN ('0000-00-00', '0000-00-00 00:00:00') AND NOT %d THEN %s
5711+
WHEN SUBSTR(%s, 1, 4) != '0000' AND (SUBSTR(%s, 6, 2) = '00' OR SUBSTR(%s, 9, 2) = '00') AND NOT %d THEN %s
5712+
WHEN %s > '0' THEN %s
57435713
ELSE %s
57445714
END",
57455715
$translated_value,
5746-
$zero_date_whens,
5747-
$function_call,
5748-
$function_call,
5716+
$translated_value, $reject_zero_date, $zero_date_value,
5717+
$translated_value, $translated_value, $translated_value, $reject_zero_in_date, $translated_value,
5718+
$function_call, $function_call,
57495719
$fallback
57505720
);
57515721
default:

0 commit comments

Comments
 (0)