Skip to content

Commit dd6bd6b

Browse files
JanJakesbgrgicak
andauthored
Add support for CURRENT_TIMESTAMP() calls with parentheses (#151)
While SQLite does support `CURRENT_TIMESTAMP` function calls natively, it doesn't support calling the function with parentheses in the form of `CURRENT_TIMESTAMP()`. This pull request removes the parentheses after `CURRENT_TIMESTAMP` keyword for all types of queries. The following types of queries will now work: ```sql SELECT current_timestamp AS t1, CURRENT_TIMESTAMP AS t2, current_timestamp() AS t3, CURRENT_TIMESTAMP() AS t4; INSERT INTO _dates (option_name, option_value) VALUES ('first', current_timestamp()); UPDATE _dates SET option_value = CURRENT_TIMESTAMP(); DELETE FROM _dates WHERE option_value = CURRENT_TIMESTAMP(); ``` Closes #129. --------- Co-authored-by: Bero <[email protected]>
1 parent e7b8ce7 commit dd6bd6b

File tree

2 files changed

+57
-1
lines changed

2 files changed

+57
-1
lines changed

tests/WP_SQLite_Translator_Tests.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3008,6 +3008,46 @@ public function testDefaultNullValue() {
30083008
);
30093009
}
30103010

3011+
public function testCurrentTimestamp() {
3012+
// SELECT
3013+
$results = $this->assertQuery(
3014+
'SELECT
3015+
current_timestamp AS t1,
3016+
CURRENT_TIMESTAMP AS t2,
3017+
current_timestamp() AS t3,
3018+
CURRENT_TIMESTAMP() AS t4'
3019+
);
3020+
$this->assertIsArray( $results );
3021+
$this->assertCount( 1, $results );
3022+
$this->assertRegExp( '/\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d/', $results[0]->t1 );
3023+
$this->assertRegExp( '/\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d/', $results[0]->t2 );
3024+
$this->assertRegExp( '/\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d/', $results[0]->t3 );
3025+
3026+
// INSERT
3027+
$this->assertQuery(
3028+
"INSERT INTO _dates (option_name, option_value) VALUES ('first', CURRENT_TIMESTAMP())"
3029+
);
3030+
$results = $this->assertQuery( 'SELECT option_value AS t FROM _dates' );
3031+
$this->assertCount( 1, $results );
3032+
$this->assertRegExp( '/\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d/', $results[0]->t );
3033+
3034+
// UPDATE
3035+
$this->assertQuery( 'UPDATE _dates SET option_value = NULL' );
3036+
$results = $this->assertQuery( 'SELECT option_value AS t FROM _dates' );
3037+
$this->assertCount( 1, $results );
3038+
$this->assertEmpty( $results[0]->t );
3039+
3040+
$this->assertQuery( 'UPDATE _dates SET option_value = CURRENT_TIMESTAMP()' );
3041+
$results = $this->assertQuery( 'SELECT option_value AS t FROM _dates' );
3042+
$this->assertCount( 1, $results );
3043+
$this->assertRegExp( '/\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d/', $results[0]->t );
3044+
3045+
// DELETE
3046+
// We can only assert that the query passes. It is not guaranteed that we'll actually
3047+
// delete the existing record, as the delete query could fall into a different second.
3048+
$this->assertQuery( 'DELETE FROM _dates WHERE option_value = CURRENT_TIMESTAMP()' );
3049+
}
3050+
30113051
/**
30123052
* @dataProvider mysqlVariablesToTest
30133053
*/

wp-includes/sqlite/class-wp-sqlite-translator.php

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -772,7 +772,23 @@ public function get_return_value() {
772772
* @throws Exception If the query is not supported.
773773
*/
774774
private function execute_mysql_query( $query ) {
775-
$tokens = ( new WP_SQLite_Lexer( $query ) )->tokens;
775+
$tokens = ( new WP_SQLite_Lexer( $query ) )->tokens;
776+
777+
// SQLite does not support CURRENT_TIMESTAMP() calls with parentheses.
778+
// Since CURRENT_TIMESTAMP() can appear in most types of SQL queries,
779+
// let's remove the parentheses globally before further processing.
780+
foreach ( $tokens as $i => $token ) {
781+
if ( WP_SQLite_Token::TYPE_KEYWORD === $token->type && 'CURRENT_TIMESTAMP' === $token->keyword ) {
782+
$paren_open = $tokens[ $i + 1 ] ?? null;
783+
$paren_close = $tokens[ $i + 2 ] ?? null;
784+
if ( WP_SQLite_Token::TYPE_OPERATOR === $paren_open->type && '(' === $paren_open->value
785+
&& WP_SQLite_Token::TYPE_OPERATOR === $paren_close->type && ')' === $paren_close->value ) {
786+
unset( $tokens[ $i + 1 ], $tokens[ $i + 2 ] );
787+
}
788+
}
789+
}
790+
$tokens = array_values( $tokens );
791+
776792
$this->rewriter = new WP_SQLite_Query_Rewriter( $tokens );
777793
$this->query_type = $this->rewriter->peek()->value;
778794

0 commit comments

Comments
 (0)