Skip to content

Commit 8c6600f

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 770246a commit 8c6600f

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
}
@@ -5671,8 +5671,11 @@ private function cast_value_for_saving(
56715671
}
56725672

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

57325700
return sprintf(
57335701
"CASE
57345702
WHEN %s IS NULL THEN NULL
5735-
%sWHEN %s > '0' THEN %s
5703+
WHEN %s IN ('0000-00-00', '0000-00-00 00:00:00') AND NOT %d THEN %s
5704+
WHEN SUBSTR(%s, 1, 4) != '0000' AND (SUBSTR(%s, 6, 2) = '00' OR SUBSTR(%s, 9, 2) = '00') AND NOT %d THEN %s
5705+
WHEN %s > '0' THEN %s
57365706
ELSE %s
57375707
END",
57385708
$translated_value,
5739-
$zero_date_whens,
5740-
$function_call,
5741-
$function_call,
5709+
$translated_value, $reject_zero_date, $zero_date_value,
5710+
$translated_value, $translated_value, $translated_value, $reject_zero_in_date, $translated_value,
5711+
$function_call, $function_call,
57425712
$fallback
57435713
);
57445714
default:

0 commit comments

Comments
 (0)