From 3427c08b8f5f845bde9416971657568de19e431c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Zieli=C5=84ski?= Date: Wed, 3 Apr 2024 12:49:31 +0200 Subject: [PATCH 1/3] Support SHOW GRANTS FOR A naive implementation of SHOW GRANTS FOR It always returns ALL_PRIVILIGES, which MySQL 8.0 doesn't do, but MySQL < 8.0 may. https://dev.mysql.com/doc/refman/8.0/en/show-grants.html Testing instructions: ``` ./vendor/bin/phpunit -c ./phpunit.xml.dist --filter testShowGrants ``` --- tests/WP_SQLite_Translator_Tests.php | 11 +++++++++++ wp-includes/sqlite/class-wp-sqlite-translator.php | 8 ++++++++ 2 files changed, 19 insertions(+) diff --git a/tests/WP_SQLite_Translator_Tests.php b/tests/WP_SQLite_Translator_Tests.php index 260689c1..26e6823e 100644 --- a/tests/WP_SQLite_Translator_Tests.php +++ b/tests/WP_SQLite_Translator_Tests.php @@ -1244,6 +1244,17 @@ public function testAlterTableAddColumnChangesMySQLDataType() { $fields ); } + public function testShowGrantsFor() { + $result = $this->assertQuery( 'SHOW GRANTS FOR current_user();' ); + $this->assertEquals( + $result, + array( + (object) array( + 'Grants for root@localhost' => 'ALL PRIVILIGES' + ) + ) + ); + } public function testShowIndex() { $result = $this->assertQuery( diff --git a/wp-includes/sqlite/class-wp-sqlite-translator.php b/wp-includes/sqlite/class-wp-sqlite-translator.php index 9c784244..fe9704f8 100644 --- a/wp-includes/sqlite/class-wp-sqlite-translator.php +++ b/wp-includes/sqlite/class-wp-sqlite-translator.php @@ -3026,6 +3026,14 @@ private function execute_show() { $this->results = true; return; + case 'GRANTS FOR': + $this->set_results_from_fetched_data( array( + (object) array( + 'Grants for root@localhost' => 'ALL PRIVILIGES' + ) + ) ); + return; + case 'FULL COLUMNS': $this->rewriter->consume(); // Fall through. From b13141c39f9ddf012bc6e0fb3d6bf90aeabe4705 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Zieli=C5=84ski?= Date: Wed, 3 Apr 2024 12:55:42 +0200 Subject: [PATCH 2/3] Return GRANT *.* ON % TO `root`@`localhost` --- tests/WP_SQLite_Translator_Tests.php | 2 +- wp-includes/sqlite/class-wp-sqlite-translator.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/WP_SQLite_Translator_Tests.php b/tests/WP_SQLite_Translator_Tests.php index 26e6823e..51e74314 100644 --- a/tests/WP_SQLite_Translator_Tests.php +++ b/tests/WP_SQLite_Translator_Tests.php @@ -1250,7 +1250,7 @@ public function testShowGrantsFor() { $result, array( (object) array( - 'Grants for root@localhost' => 'ALL PRIVILIGES' + 'Grants for root@localhost' => 'GRANT *.* ON % TO `root`@`localhost`' ) ) ); diff --git a/wp-includes/sqlite/class-wp-sqlite-translator.php b/wp-includes/sqlite/class-wp-sqlite-translator.php index fe9704f8..24cb2445 100644 --- a/wp-includes/sqlite/class-wp-sqlite-translator.php +++ b/wp-includes/sqlite/class-wp-sqlite-translator.php @@ -3029,7 +3029,7 @@ private function execute_show() { case 'GRANTS FOR': $this->set_results_from_fetched_data( array( (object) array( - 'Grants for root@localhost' => 'ALL PRIVILIGES' + 'Grants for root@localhost' => 'GRANT *.* ON % TO `root`@`localhost`', ) ) ); return; From a2e47589370ca89b00a02dc9ef58143819df36a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Zieli=C5=84ski?= Date: Wed, 3 Apr 2024 13:03:05 +0200 Subject: [PATCH 3/3] Return all permissions --- tests/WP_SQLite_Translator_Tests.php | 31 ++++++++++++++- .../sqlite/class-wp-sqlite-translator.php | 38 ++++++++++++++++++- 2 files changed, 67 insertions(+), 2 deletions(-) diff --git a/tests/WP_SQLite_Translator_Tests.php b/tests/WP_SQLite_Translator_Tests.php index 51e74314..85247a36 100644 --- a/tests/WP_SQLite_Translator_Tests.php +++ b/tests/WP_SQLite_Translator_Tests.php @@ -146,6 +146,34 @@ public function testSelectFromDual() { $this->assertEquals( 1, $result[0]->output ); } + public function testLeftFunction1Char() { + $result = $this->assertQuery( + 'SELECT LEFT("abc", 1) as output' + ); + $this->assertEquals( "a", $result[0]->output ); + } + + public function testLeftFunction5Chars() { + $result = $this->assertQuery( + 'SELECT LEFT("Lorem ipsum", 5) as output' + ); + $this->assertEquals( "Lorem", $result[0]->output ); + } + + public function testLeftFunctionNullString() { + $result = $this->assertQuery( + 'SELECT LEFT(NULL, 5) as output' + ); + $this->assertEquals( null, $result[0]->output ); + } + + public function testLeftFunctionNullLength() { + $result = $this->assertQuery( + 'SELECT LEFT("Test", NULL) as output' + ); + $this->assertEquals( null, $result[0]->output ); + } + public function testInsertSelectFromDual() { $result = $this->assertQuery( 'INSERT INTO _options (option_name, option_value) SELECT "A", "b" FROM DUAL WHERE ( SELECT NULL FROM DUAL ) IS NULL' @@ -153,6 +181,7 @@ public function testInsertSelectFromDual() { $this->assertEquals( 1, $result ); } + public function testCreateTemporaryTable() { $this->assertQuery( "CREATE TEMPORARY TABLE _tmp_table ( @@ -1250,7 +1279,7 @@ public function testShowGrantsFor() { $result, array( (object) array( - 'Grants for root@localhost' => 'GRANT *.* ON % TO `root`@`localhost`' + 'Grants for root@localhost' => 'GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE, CREATE ROLE, DROP ROLE ON *.* TO `root`@`localhost` WITH GRANT OPTION' ) ) ); diff --git a/wp-includes/sqlite/class-wp-sqlite-translator.php b/wp-includes/sqlite/class-wp-sqlite-translator.php index 24cb2445..857e6336 100644 --- a/wp-includes/sqlite/class-wp-sqlite-translator.php +++ b/wp-includes/sqlite/class-wp-sqlite-translator.php @@ -1824,6 +1824,7 @@ private function translate_expression( $token ) { || $this->capture_group_by( $token ) || $this->translate_ungrouped_having( $token ) || $this->translate_like_escape( $token ) + || $this->translate_left_function( $token ) ); } @@ -2025,6 +2026,41 @@ private function translate_date_add_sub( $token ) { return true; } + /** + * Translate the LEFT() function. + * + * > Returns the leftmost len characters from the string str, or NULL if any argument is NULL. + * + * https://dev.mysql.com/doc/refman/8.3/en/string-functions.html#function_left + * + * @param WP_SQLite_Token $token The token to translate. + * + * @return bool + */ + private function translate_left_function( $token ) { + if ( + ! $token->matches( + WP_SQLite_Token::TYPE_KEYWORD, + WP_SQLite_Token::FLAG_KEYWORD_FUNCTION, + array( 'LEFT' ) + ) + ) { + return false; + } + + $this->rewriter->skip(); + $this->rewriter->add( new WP_SQLite_Token( 'SUBSTRING', WP_SQLite_Token::TYPE_KEYWORD, WP_SQLite_Token::FLAG_KEYWORD_FUNCTION ) ); + $this->rewriter->consume( + array( + 'type' => WP_SQLite_Token::TYPE_OPERATOR, + 'value' => ',', + ) + ); + $this->rewriter->add( new WP_SQLite_Token( 1, WP_SQLite_Token::TYPE_NUMBER ) ); + $this->rewriter->add( new WP_SQLite_Token( ',', WP_SQLite_Token::TYPE_OPERATOR ) ); + return true; + } + /** * Convert function aliases. * @@ -3029,7 +3065,7 @@ private function execute_show() { case 'GRANTS FOR': $this->set_results_from_fetched_data( array( (object) array( - 'Grants for root@localhost' => 'GRANT *.* ON % TO `root`@`localhost`', + 'Grants for root@localhost' => 'GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE, CREATE ROLE, DROP ROLE ON *.* TO `root`@`localhost` WITH GRANT OPTION' ) ) ); return;