Skip to content

Commit 60e50e6

Browse files
committed
Fix YEAR type behavior
1 parent 740ef5d commit 60e50e6

File tree

3 files changed

+62
-1
lines changed

3 files changed

+62
-1
lines changed

tests/WP_SQLite_Driver_Tests.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10202,5 +10202,33 @@ public function testCastValuesOnInsert(): void {
1020210202
$this->assertSame( '2025-10-23 18:30:00', $result[4]->value );
1020310203
$this->assertSame( '2025-10-23 18:30:00', $result[5]->value );
1020410204
$this->assertQuery( 'DROP TABLE t' );
10205+
10206+
// YEAR
10207+
$this->assertQuery( 'CREATE TABLE t (value YEAR)' );
10208+
$this->assertQuery( 'INSERT INTO t VALUES (NULL)' );
10209+
$this->assertQuery( 'INSERT INTO t VALUES (FALSE)' );
10210+
$this->assertQuery( 'INSERT INTO t VALUES (TRUE)' );
10211+
$this->assertQuery( "INSERT INTO t VALUES ('2025')" );
10212+
$this->assertQuery( "INSERT INTO t VALUES ('2025-10-23')" );
10213+
$this->assertQuery( "INSERT INTO t VALUES ('2025-10-23 18:30:00')" );
10214+
$this->assertQuery( "INSERT INTO t VALUES ('2025-10-23 18:30:00.123456')" );
10215+
$this->assertQuery( 'INSERT INTO t VALUES (1)' );
10216+
$this->assertQuery( 'INSERT INTO t VALUES (50)' );
10217+
$this->assertQuery( 'INSERT INTO t VALUES (70)' );
10218+
$this->assertQuery( 'INSERT INTO t VALUES (99)' );
10219+
10220+
$result = $this->assertQuery( 'SELECT * FROM t' );
10221+
$this->assertSame( null, $result[0]->value );
10222+
$this->assertSame( '0', $result[1]->value );
10223+
$this->assertSame( '2001', $result[2]->value );
10224+
$this->assertSame( '2025', $result[3]->value );
10225+
$this->assertSame( '2025', $result[4]->value );
10226+
$this->assertSame( '2025', $result[5]->value );
10227+
$this->assertSame( '2025', $result[6]->value );
10228+
$this->assertSame( '2001', $result[7]->value );
10229+
$this->assertSame( '2050', $result[8]->value );
10230+
$this->assertSame( '1970', $result[9]->value );
10231+
$this->assertSame( '1999', $result[10]->value );
10232+
$this->assertQuery( 'DROP TABLE t' );
1020510233
}
1020610234
}

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

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5000,7 +5000,27 @@ 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+
$function_call = sprintf(
5011+
"(
5012+
SELECT CASE
5013+
WHEN value > 1900 AND value < 2156 THEN value
5014+
WHEN value = 0 THEN 0
5015+
WHEN value < 70 THEN 2000 + value
5016+
WHEN value < 100 THEN 1900 + value
5017+
ELSE THROW('Out of range value: ''' || %s || '''')
5018+
END
5019+
FROM (SELECT CAST(%s AS INTEGER) AS value)
5020+
)",
5021+
$translated_value,
5022+
$translated_value,
5023+
);
50045024
}
50055025

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