Skip to content

Commit c72af18

Browse files
committed
Fix YEAR type behavior
1 parent 51daf2b commit c72af18

3 files changed

Lines changed: 102 additions & 1 deletion

File tree

tests/WP_SQLite_Driver_Tests.php

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10239,6 +10239,37 @@ public function testCastValuesOnInsert(): void {
1023910239
$this->assertSame( '2025-10-23 18:30:00', $result[2]->value );
1024010240
$this->assertSame( '2025-10-23 18:30:00', $result[3]->value );
1024110241
$this->assertQuery( 'DROP TABLE t' );
10242+
10243+
// YEAR
10244+
$this->assertQuery( 'CREATE TABLE t (value YEAR)' );
10245+
$this->assertQuery( 'INSERT INTO t VALUES (NULL)' );
10246+
$this->assertQuery( 'INSERT INTO t VALUES (FALSE)' );
10247+
$this->assertQuery( 'INSERT INTO t VALUES (TRUE)' );
10248+
$this->assertQuery( "INSERT INTO t VALUES ('2025')" );
10249+
$this->assertQuery( "INSERT INTO t VALUES ('2025-10-23')" );
10250+
$this->assertQuery( "INSERT INTO t VALUES ('2025-10-23 18:30:00')" );
10251+
$this->assertQuery( "INSERT INTO t VALUES ('2025-10-23 18:30:00.123456')" );
10252+
$this->assertQuery( 'INSERT INTO t VALUES (1)' );
10253+
$this->assertQuery( 'INSERT INTO t VALUES (50)' );
10254+
$this->assertQuery( 'INSERT INTO t VALUES (70)' );
10255+
$this->assertQuery( 'INSERT INTO t VALUES (99)' );
10256+
$this->assertQueryError( 'INSERT INTO t VALUES (-1)', "Out of range value: '-1'" );
10257+
$this->assertQueryError( 'INSERT INTO t VALUES (1900)', "Out of range value: '1900'" );
10258+
$this->assertQueryError( 'INSERT INTO t VALUES (2156)', "Out of range value: '2156'" );
10259+
10260+
$result = $this->assertQuery( 'SELECT * FROM t' );
10261+
$this->assertSame( null, $result[0]->value );
10262+
$this->assertSame( '0000', $result[1]->value );
10263+
$this->assertSame( '2001', $result[2]->value );
10264+
$this->assertSame( '2025', $result[3]->value );
10265+
$this->assertSame( '2025', $result[4]->value );
10266+
$this->assertSame( '2025', $result[5]->value );
10267+
$this->assertSame( '2025', $result[6]->value );
10268+
$this->assertSame( '2001', $result[7]->value );
10269+
$this->assertSame( '2050', $result[8]->value );
10270+
$this->assertSame( '1970', $result[9]->value );
10271+
$this->assertSame( '1999', $result[10]->value );
10272+
$this->assertQuery( 'DROP TABLE t' );
1024210273
}
1024310274

1024410275
public function testCastValuesOnInsertInNonStrictMode(): void {
@@ -10425,5 +10456,39 @@ public function testCastValuesOnInsertInNonStrictMode(): void {
1042510456
$this->assertSame( '2025-10-23 18:30:00', $result[5]->value );
1042610457
$this->assertSame( '2025-10-23 18:30:00', $result[6]->value );
1042710458
$this->assertQuery( 'DROP TABLE t' );
10459+
10460+
// YEAR
10461+
$this->assertQuery( 'CREATE TABLE t (value YEAR)' );
10462+
$this->assertQuery( 'INSERT INTO t VALUES (NULL)' );
10463+
$this->assertQuery( 'INSERT INTO t VALUES (FALSE)' );
10464+
$this->assertQuery( 'INSERT INTO t VALUES (TRUE)' );
10465+
$this->assertQuery( "INSERT INTO t VALUES ('2025')" );
10466+
$this->assertQuery( "INSERT INTO t VALUES ('2025-10-23')" );
10467+
$this->assertQuery( "INSERT INTO t VALUES ('2025-10-23 18:30:00')" );
10468+
$this->assertQuery( "INSERT INTO t VALUES ('2025-10-23 18:30:00.123456')" );
10469+
$this->assertQuery( 'INSERT INTO t VALUES (1)' );
10470+
$this->assertQuery( 'INSERT INTO t VALUES (50)' );
10471+
$this->assertQuery( 'INSERT INTO t VALUES (70)' );
10472+
$this->assertQuery( 'INSERT INTO t VALUES (99)' );
10473+
$this->assertQuery( 'INSERT INTO t VALUES (-1)' );
10474+
$this->assertQuery( 'INSERT INTO t VALUES (1900)' );
10475+
$this->assertQuery( 'INSERT INTO t VALUES (2156)' );
10476+
10477+
$result = $this->assertQuery( 'SELECT * FROM t' );
10478+
$this->assertSame( null, $result[0]->value );
10479+
$this->assertSame( '0000', $result[1]->value );
10480+
$this->assertSame( '2001', $result[2]->value );
10481+
$this->assertSame( '2025', $result[3]->value );
10482+
$this->assertSame( '2025', $result[4]->value );
10483+
$this->assertSame( '2025', $result[5]->value );
10484+
$this->assertSame( '2025', $result[6]->value );
10485+
$this->assertSame( '2001', $result[7]->value );
10486+
$this->assertSame( '2050', $result[8]->value );
10487+
$this->assertSame( '1970', $result[9]->value );
10488+
$this->assertSame( '1999', $result[10]->value );
10489+
$this->assertSame( '0000', $result[11]->value );
10490+
$this->assertSame( '0000', $result[12]->value );
10491+
$this->assertSame( '0000', $result[13]->value );
10492+
$this->assertQuery( 'DROP TABLE t' );
1042810493
}
1042910494
}

wp-includes/sqlite-ast/class-wp-sqlite-driver.php

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5003,7 +5003,30 @@ private function cast_value_for_insert_or_update(
50035003
} elseif ( 'datetime' === $mysql_data_type || 'timestamp' === $mysql_data_type ) {
50045004
$function_call = sprintf( 'DATETIME(%s)', $translated_value );
50055005
} elseif ( 'year' === $mysql_data_type ) {
5006-
$function_call = sprintf( "STRFTIME('%%Y', %s)", $translated_value );
5006+
/*
5007+
* The YEAR type in MySQL only uses 1 byte and therefore
5008+
* covers only 256 values from 1901 to 2155 included.
5009+
* Additionally:
5010+
* - Numbers from 0 to 69 correspond to years 2000 to 2069.
5011+
* - Numbers from 70 to 99 correspond to years 1970 to 1999.
5012+
*/
5013+
return sprintf(
5014+
"(
5015+
SELECT CASE
5016+
WHEN value IS NULL THEN NULL
5017+
WHEN value = 0 THEN '0000'
5018+
WHEN value BETWEEN 1901 AND 2155 THEN value
5019+
WHEN value BETWEEN 1 AND 69 THEN 2000 + value
5020+
WHEN value BETWEEN 70 AND 99 THEN 1900 + value
5021+
ELSE %s
5022+
END
5023+
FROM (SELECT CAST(%s AS INTEGER) AS value)
5024+
)",
5025+
$is_strict_mode
5026+
? sprintf( "THROW('Out of range value: ''' || %s || '''')", $translated_value )
5027+
: "'0000'",
5028+
$translated_value
5029+
);
50075030
}
50085031

50095032
// In strict mode, invalid date/time values are rejected.

wp-includes/sqlite/class-wp-sqlite-pdo-user-defined-functions.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ public static function register_for( PDO $pdo ): self {
4444
* @var array
4545
*/
4646
private $functions = array(
47+
'throw' => 'throw',
4748
'month' => 'month',
4849
'monthnum' => 'month',
4950
'year' => 'year',
@@ -88,6 +89,18 @@ public static function register_for( PDO $pdo ): self {
8889
'_helper_like_to_glob_pattern' => '_helper_like_to_glob_pattern',
8990
);
9091

92+
/**
93+
* A helper function to throw an error from SQLite expressions.
94+
*
95+
* @param string $message The error message.
96+
*
97+
* @throws Exception The error message.
98+
* @return void
99+
*/
100+
public function throw( $message ): void {
101+
throw new Exception( $message );
102+
}
103+
91104
/**
92105
* Method to return the unix timestamp.
93106
*

0 commit comments

Comments
 (0)