Skip to content

Commit d04ff75

Browse files
committed
Fix YEAR type behavior
1 parent 7845a02 commit d04ff75

File tree

3 files changed

+91
-1
lines changed

3 files changed

+91
-1
lines changed

tests/WP_SQLite_Driver_Tests.php

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10239,6 +10239,34 @@ 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+
10257+
$result = $this->assertQuery( 'SELECT * FROM t' );
10258+
$this->assertSame( null, $result[0]->value );
10259+
$this->assertSame( '0000', $result[1]->value );
10260+
$this->assertSame( '2001', $result[2]->value );
10261+
$this->assertSame( '2025', $result[3]->value );
10262+
$this->assertSame( '2025', $result[4]->value );
10263+
$this->assertSame( '2025', $result[5]->value );
10264+
$this->assertSame( '2025', $result[6]->value );
10265+
$this->assertSame( '2001', $result[7]->value );
10266+
$this->assertSame( '2050', $result[8]->value );
10267+
$this->assertSame( '1970', $result[9]->value );
10268+
$this->assertSame( '1999', $result[10]->value );
10269+
$this->assertQuery( 'DROP TABLE t' );
1024210270
}
1024310271

1024410272
public function testCastValuesOnInsertInNonStrictMode(): void {
@@ -10425,5 +10453,33 @@ public function testCastValuesOnInsertInNonStrictMode(): void {
1042510453
$this->assertSame( '2025-10-23 18:30:00', $result[5]->value );
1042610454
$this->assertSame( '2025-10-23 18:30:00', $result[6]->value );
1042710455
$this->assertQuery( 'DROP TABLE t' );
10456+
10457+
// YEAR
10458+
$this->assertQuery( 'CREATE TABLE t (value YEAR)' );
10459+
$this->assertQuery( 'INSERT INTO t VALUES (NULL)' );
10460+
$this->assertQuery( 'INSERT INTO t VALUES (FALSE)' );
10461+
$this->assertQuery( 'INSERT INTO t VALUES (TRUE)' );
10462+
$this->assertQuery( "INSERT INTO t VALUES ('2025')" );
10463+
$this->assertQuery( "INSERT INTO t VALUES ('2025-10-23')" );
10464+
$this->assertQuery( "INSERT INTO t VALUES ('2025-10-23 18:30:00')" );
10465+
$this->assertQuery( "INSERT INTO t VALUES ('2025-10-23 18:30:00.123456')" );
10466+
$this->assertQuery( 'INSERT INTO t VALUES (1)' );
10467+
$this->assertQuery( 'INSERT INTO t VALUES (50)' );
10468+
$this->assertQuery( 'INSERT INTO t VALUES (70)' );
10469+
$this->assertQuery( 'INSERT INTO t VALUES (99)' );
10470+
10471+
$result = $this->assertQuery( 'SELECT * FROM t' );
10472+
$this->assertSame( null, $result[0]->value );
10473+
$this->assertSame( '0000', $result[1]->value );
10474+
$this->assertSame( '2001', $result[2]->value );
10475+
$this->assertSame( '2025', $result[3]->value );
10476+
$this->assertSame( '2025', $result[4]->value );
10477+
$this->assertSame( '2025', $result[5]->value );
10478+
$this->assertSame( '2025', $result[6]->value );
10479+
$this->assertSame( '2001', $result[7]->value );
10480+
$this->assertSame( '2050', $result[8]->value );
10481+
$this->assertSame( '1970', $result[9]->value );
10482+
$this->assertSame( '1999', $result[10]->value );
10483+
$this->assertQuery( 'DROP TABLE t' );
1042810484
}
1042910485
}

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

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

50065027
// 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)