diff --git a/grammar-tools/MySQLParser.g4 b/grammar-tools/MySQLParser.g4 index 44669f2..40c114d 100644 --- a/grammar-tools/MySQLParser.g4 +++ b/grammar-tools/MySQLParser.g4 @@ -298,14 +298,18 @@ alterListItem: | OPEN_PAR_SYMBOL tableElementList CLOSE_PAR_SYMBOL ) | ADD_SYMBOL tableConstraintDef - | CHANGE_SYMBOL COLUMN_SYMBOL? columnInternalRef identifier fieldDefinition place? - | MODIFY_SYMBOL COLUMN_SYMBOL? columnInternalRef fieldDefinition place? + /* @CHANGED: Replaced "columnInternalRef" with "fieldIdentifier" as per sql_yacc.yy. */ + | CHANGE_SYMBOL COLUMN_SYMBOL? fieldIdentifier identifier fieldDefinition place? + /* @CHANGED: Replaced "columnInternalRef" with "fieldIdentifier" as per sql_yacc.yy. */ + | MODIFY_SYMBOL COLUMN_SYMBOL? fieldIdentifier fieldDefinition place? | DROP_SYMBOL ( - COLUMN_SYMBOL? columnInternalRef restrict? + /* @CHANGED: Replaced "columnInternalRef" with "fieldIdentifier" as per sql_yacc.yy. */ + COLUMN_SYMBOL? fieldIdentifier restrict? | FOREIGN_SYMBOL KEY_SYMBOL ( + /* @CHANGED: Replaced "columnInternalRef" with "fieldIdentifier" as per sql_yacc.yy. */ // This part is no longer optional starting with 5.7. - {serverVersion >= 50700}? columnInternalRef - | {serverVersion < 50700}? columnInternalRef? + {serverVersion >= 50700}? fieldIdentifier + | {serverVersion < 50700}? fieldIdentifier? ) | PRIMARY_SYMBOL KEY_SYMBOL | keyOrIndex indexRef @@ -314,7 +318,8 @@ alterListItem: ) | DISABLE_SYMBOL KEYS_SYMBOL | ENABLE_SYMBOL KEYS_SYMBOL - | ALTER_SYMBOL COLUMN_SYMBOL? columnInternalRef ( + /* @CHANGED: Replaced "columnInternalRef" with "fieldIdentifier" as per sql_yacc.yy. */ + | ALTER_SYMBOL COLUMN_SYMBOL? fieldIdentifier ( SET_SYMBOL DEFAULT_SYMBOL ( {serverVersion >= 80014}? exprWithParentheses | signedLiteral @@ -325,7 +330,8 @@ alterListItem: | {serverVersion >= 80000}? ALTER_SYMBOL INDEX_SYMBOL indexRef visibility | {serverVersion >= 80017}? ALTER_SYMBOL CHECK_SYMBOL identifier constraintEnforcement | {serverVersion >= 80019}? ALTER_SYMBOL CONSTRAINT_SYMBOL identifier constraintEnforcement - | {serverVersion >= 80000}? RENAME_SYMBOL COLUMN_SYMBOL columnInternalRef TO_SYMBOL identifier + /* @CHANGED: Replaced "columnInternalRef" with "fieldIdentifier" as per sql_yacc.yy. */ + | {serverVersion >= 80000}? RENAME_SYMBOL COLUMN_SYMBOL fieldIdentifier TO_SYMBOL identifier | RENAME_SYMBOL (TO_SYMBOL | AS_SYMBOL)? tableName | {serverVersion >= 50700}? RENAME_SYMBOL keyOrIndex indexRef TO_SYMBOL indexName | CONVERT_SYMBOL TO_SYMBOL charset ( @@ -353,11 +359,11 @@ restrict: /* * @CHANGED: - * Fixed ALTER TABLE with ORDER to use 'qualifiedIdentifier' instead of just 'identifier'. + * Fixed ALTER TABLE with ORDER to use 'simpleIdentifier' instead of just 'identifier'. * This is necessary to support "t.id" in a query like "ALTER TABLE t ORDER BY t.id". */ alterOrderList: - qualifiedIdentifier direction? (COMMA_SYMBOL qualifiedIdentifier direction?)* + simpleIdentifier direction? (COMMA_SYMBOL simpleIdentifier direction?)* ; alterAlgorithmOption: @@ -1711,7 +1717,7 @@ xid: /* * @CHANGED: * Fixed "replicationStatement" to correctly support the "RESET PERSIST" statement. - * The "ifExists" clause wasn't optional, and "identifier" was used instead of "qualifiedIdentifier". + * The "ifExists" clause wasn't optional, and "identifier" was used instead of "internalVariableName". */ replicationStatement: PURGE_SYMBOL (BINARY_SYMBOL | MASTER_SYMBOL) LOGS_SYMBOL ( @@ -3561,7 +3567,8 @@ getDiagnostics: signalAllowedExpr: literal | variable - | qualifiedIdentifier + /* @CHANGED: Changed "qualifiedIdentifier" to "simpleIdentifier" as per sql_yacc.yy. */ + | simpleIdentifier ; statementInformationItem: @@ -3627,7 +3634,8 @@ schedule: ; columnDefinition: - columnName fieldDefinition checkOrReferences? + /* @CHANGED: Replaced "columnInternalRef" with "fieldIdentifier" as per sql_yacc.yy. */ + fieldIdentifier fieldDefinition checkOrReferences? ; checkOrReferences: @@ -4265,16 +4273,19 @@ usePartition: // Sometimes we need additional reference rules with different form, depending on the place such a reference is used. // A name for a field (column/index). Can be qualified with the current schema + table (although it's not a reference). +/* @CHANGED: Moved the conditional from "columnName" to "fieldIdentifier" as per sql_yacc.yy. */ fieldIdentifier: - dotIdentifier - | qualifiedIdentifier dotIdentifier? + // With server 8.0 this became a simple identifier. + {serverVersion < 80000}? (dotIdentifier | qualifiedIdentifier dotIdentifier?) + | {serverVersion >= 80000}? identifier ; -columnName: +/* @CHANGED: Replaced more universally with "fieldIdentifier" as per sql_yacc.yy. */ +/*columnName: // With server 8.0 this became a simple identifier. {serverVersion >= 80000}? identifier | {serverVersion < 80000}? fieldIdentifier -; +;*/ // A reference to a column of the object we are working on. columnInternalRef: @@ -4340,12 +4351,14 @@ triggerRef: viewName: qualifiedIdentifier - | dotIdentifier + /* @CHANGED: Added missing version constraint. */ + | {serverVersion < 80000}? dotIdentifier ; viewRef: qualifiedIdentifier - | dotIdentifier + /* @CHANGED: Added missing version constraint. */ + | {serverVersion < 80000}? dotIdentifier ; tablespaceName: @@ -4390,7 +4403,8 @@ engineRef: tableName: qualifiedIdentifier - | dotIdentifier + /* @CHANGED: Added missing version constraint. */ + | {serverVersion < 80000}? dotIdentifier ; filterTableRef: // Always qualified. @@ -4403,7 +4417,8 @@ tableRefWithWildcard: tableRef: qualifiedIdentifier - | dotIdentifier + /* @CHANGED: Added missing version constraint. */ + | {serverVersion < 80000}? dotIdentifier ; tableRefList: diff --git a/tests/WP_SQLite_Driver_Metadata_Tests.php b/tests/WP_SQLite_Driver_Metadata_Tests.php new file mode 100644 index 0000000..ef3d4d2 --- /dev/null +++ b/tests/WP_SQLite_Driver_Metadata_Tests.php @@ -0,0 +1,511 @@ +suppress_errors = false; + $GLOBALS['wpdb']->show_errors = true; + } + return; + } + + // Before each test, we create a new database + public function setUp(): void { + global $blog_tables; + $queries = explode( ';', $blog_tables ); + + $this->sqlite = new PDO( 'sqlite::memory:' ); + $this->engine = new WP_SQLite_Driver( + array( + 'connection' => $this->sqlite, + 'database' => 'wp', + ) + ); + + $translator = $this->engine; + + try { + $translator->begin_transaction(); + foreach ( $queries as $query ) { + $query = trim( $query ); + if ( empty( $query ) ) { + continue; + } + + $translator->execute_sqlite_query( $query ); + } + $translator->commit(); + } catch ( PDOException $err ) { + $err_data = + $err->errorInfo; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase + $err_code = $err_data[1]; + $translator->rollback(); + $message = sprintf( + 'Error occurred while creating tables or indexes...
Query was: %s
', + var_export( $query, true ) + ); + $message .= sprintf( 'Error message is: %s', $err_data[2] ); + wp_die( $message, 'Database Error!' ); + } + } + + public function testCountTables() { + $this->assertQuery( 'CREATE TABLE t1 (id INT)' ); + $this->assertQuery( 'CREATE TABLE t2 (id INT)' ); + + $result = $this->assertQuery( "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'wp'" ); + $this->assertEquals( array( (object) array( 'COUNT ( * )' => '2' ) ), $result ); + + $result = $this->assertQuery( "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'other'" ); + $this->assertEquals( array( (object) array( 'COUNT ( * )' => '0' ) ), $result ); + + // @TODO: The result key should be "COUNT(*)" instead of "COUNT ( * )". + // The spacing was probably inserted by the translator. + } + + public function testInformationSchemaTables() { + $this->assertQuery( + ' + CREATE TABLE t (id INT PRIMARY KEY, name TEXT, age INT) + ' + ); + + $result = $this->assertQuery( "SELECT * FROM information_schema.tables WHERE TABLE_NAME = 't'" ); + $this->assertCount( 1, $result ); + $this->assertRegExp( '/\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d/', $result[0]->CREATE_TIME ); + $this->assertEquals( + array( + 'TABLE_CATALOG' => 'def', + 'TABLE_SCHEMA' => 'wp', + 'TABLE_NAME' => 't', + 'TABLE_TYPE' => 'BASE TABLE', + 'ENGINE' => 'InnoDB', + 'VERSION' => '10', + 'ROW_FORMAT' => 'Dynamic', + 'TABLE_ROWS' => '0', + 'AVG_ROW_LENGTH' => '0', + 'DATA_LENGTH' => '0', + 'MAX_DATA_LENGTH' => '0', + 'INDEX_LENGTH' => '0', + 'DATA_FREE' => '0', + 'AUTO_INCREMENT' => null, + 'CREATE_TIME' => $result[0]->CREATE_TIME, + 'UPDATE_TIME' => null, + 'CHECK_TIME' => null, + 'TABLE_COLLATION' => 'utf8mb4_general_ci', + 'CHECKSUM' => null, + 'CREATE_OPTIONS' => '', + 'TABLE_COMMENT' => '', + ), + (array) $result[0] + ); + + $result = $this->assertQuery( + "SELECT + table_name as 'name', + engine AS 'engine', + FLOOR( data_length / 1024 / 1024 ) 'data' + FROM INFORMATION_SCHEMA.TABLES + WHERE TABLE_NAME = 't' + ORDER BY name ASC" + ); + + $this->assertEquals( + array( + 'name' => 't', + 'engine' => 'InnoDB', + 'data' => '0', + ), + (array) $result[0] + ); + } + + public function testInformationSchemaQueryHidesSqliteSystemTables() { + /** + * By default, system tables are not returned. + */ + $result = $this->assertQuery( "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'sqlite_sequence'" ); + $this->assertEquals( 0, count( $result ) ); + } + + public function testUseStatement() { + $this->assertQuery( 'CREATE TABLE tables (ENGINE TEXT)' ); + $this->assertQuery( "INSERT INTO tables (ENGINE) VALUES ('test')" ); + + $this->assertQuery( 'USE wp' ); + $result = $this->assertQuery( 'SELECT * FROM tables' ); + $this->assertSame( 'test', $result[0]->ENGINE ); + + $this->assertQuery( 'USE information_schema' ); + $result = $this->assertQuery( 'SELECT * FROM tables' ); + $this->assertSame( 'InnoDB', $result[0]->ENGINE ); + } + + private function assertQuery( $sql ) { + $retval = $this->engine->query( $sql ); + $this->assertNotFalse( $retval ); + return $retval; + } + + public function testCheckTable() { + $this->assertQuery( 'CREATE TABLE t1 (id INT, name TEXT)' ); + $this->assertQuery( 'CREATE TABLE t2 (id INT, name TEXT)' ); + + // A good table. + $result = $this->assertQuery( 'CHECK TABLE t1' ); + $this->assertEquals( + array( + (object) array( + 'Table' => 'wp.t1', + 'Op' => 'check', + 'Msg_type' => 'status', + 'Msg_text' => 'OK', + ), + ), + $result + ); + + // Multiple tables. + $result = $this->assertQuery( 'CHECK TABLE t1, t2' ); + $this->assertEquals( + array( + (object) array( + 'Table' => 'wp.t1', + 'Op' => 'check', + 'Msg_type' => 'status', + 'Msg_text' => 'OK', + ), + (object) array( + 'Table' => 'wp.t2', + 'Op' => 'check', + 'Msg_type' => 'status', + 'Msg_text' => 'OK', + ), + ), + $result + ); + + // A missing table. + $result = $this->assertQuery( 'CHECK TABLE missing' ); + $this->assertEquals( + array( + (object) array( + 'Table' => 'wp.missing', + 'Op' => 'check', + 'Msg_type' => 'Error', + 'Msg_text' => "Table 'missing' doesn't exist", + ), + (object) array( + 'Table' => 'wp.missing', + 'Op' => 'check', + 'Msg_type' => 'status', + 'Msg_text' => 'Operation failed', + ), + ), + $result + ); + + // One good and one missing table. + $result = $this->assertQuery( 'CHECK TABLE t1, missing' ); + $this->assertEquals( + array( + (object) array( + 'Table' => 'wp.t1', + 'Op' => 'check', + 'Msg_type' => 'status', + 'Msg_text' => 'OK', + ), + (object) array( + 'Table' => 'wp.missing', + 'Op' => 'check', + 'Msg_type' => 'Error', + 'Msg_text' => "Table 'missing' doesn't exist", + ), + (object) array( + 'Table' => 'wp.missing', + 'Op' => 'check', + 'Msg_type' => 'status', + 'Msg_text' => 'Operation failed', + ), + ), + $result + ); + } + + public function testOptimizeTable() { + $this->assertQuery( 'CREATE TABLE t1 (id INT, name TEXT)' ); + $this->assertQuery( 'CREATE TABLE t2 (id INT, name TEXT)' ); + + // A good table. + $result = $this->assertQuery( 'OPTIMIZE TABLE t1' ); + $this->assertEquals( + array( + (object) array( + 'Table' => 'wp.t1', + 'Op' => 'optimize', + 'Msg_type' => 'status', + 'Msg_text' => 'OK', + ), + ), + $result + ); + + // Multiple tables. + $result = $this->assertQuery( 'OPTIMIZE TABLE t1, t2' ); + $this->assertEquals( + array( + (object) array( + 'Table' => 'wp.t1', + 'Op' => 'optimize', + 'Msg_type' => 'status', + 'Msg_text' => 'OK', + ), + (object) array( + 'Table' => 'wp.t2', + 'Op' => 'optimize', + 'Msg_type' => 'status', + 'Msg_text' => 'OK', + ), + ), + $result + ); + + // A missing table. + $this->assertQuery( 'OPTIMIZE TABLE missing' ); + $this->assertEquals( + array( + (object) array( + 'Table' => 'wp.missing', + 'Op' => 'optimize', + 'Msg_type' => 'Error', + 'Msg_text' => "Table 'missing' doesn't exist", + ), + (object) array( + 'Table' => 'wp.missing', + 'Op' => 'optimize', + 'Msg_type' => 'status', + 'Msg_text' => 'Operation failed', + ), + ), + $this->engine->get_query_results() + ); + + // One good and one missing table. + $result = $this->assertQuery( 'OPTIMIZE TABLE t1, missing' ); + $this->assertEquals( + array( + (object) array( + 'Table' => 'wp.t1', + 'Op' => 'optimize', + 'Msg_type' => 'status', + 'Msg_text' => 'OK', + ), + (object) array( + 'Table' => 'wp.missing', + 'Op' => 'optimize', + 'Msg_type' => 'Error', + 'Msg_text' => "Table 'missing' doesn't exist", + ), + (object) array( + 'Table' => 'wp.missing', + 'Op' => 'optimize', + 'Msg_type' => 'status', + 'Msg_text' => 'Operation failed', + ), + ), + $result + ); + } + + public function testRepairTable() { + $this->assertQuery( 'CREATE TABLE t1 (id INT, name TEXT)' ); + $this->assertQuery( 'CREATE TABLE t2 (id INT, name TEXT)' ); + + // A good table. + $result = $this->assertQuery( 'REPAIR TABLE t1' ); + $this->assertEquals( + array( + (object) array( + 'Table' => 'wp.t1', + 'Op' => 'repair', + 'Msg_type' => 'status', + 'Msg_text' => 'OK', + ), + ), + $result + ); + + // Multiple tables. + $result = $this->assertQuery( 'REPAIR TABLE t1, t2' ); + $this->assertEquals( + array( + (object) array( + 'Table' => 'wp.t1', + 'Op' => 'repair', + 'Msg_type' => 'status', + 'Msg_text' => 'OK', + ), + (object) array( + 'Table' => 'wp.t2', + 'Op' => 'repair', + 'Msg_type' => 'status', + 'Msg_text' => 'OK', + ), + ), + $result + ); + + // A missing table. + $result = $this->assertQuery( 'REPAIR TABLE missing' ); + $this->assertEquals( + array( + (object) array( + 'Table' => 'wp.missing', + 'Op' => 'repair', + 'Msg_type' => 'Error', + 'Msg_text' => "Table 'missing' doesn't exist", + ), + (object) array( + 'Table' => 'wp.missing', + 'Op' => 'repair', + 'Msg_type' => 'status', + 'Msg_text' => 'Operation failed', + ), + ), + $result + ); + + // One good and one missing table. + $result = $this->assertQuery( 'REPAIR TABLE t1, missing' ); + $this->assertEquals( + array( + (object) array( + 'Table' => 'wp.t1', + 'Op' => 'repair', + 'Msg_type' => 'status', + 'Msg_text' => 'OK', + ), + (object) array( + 'Table' => 'wp.missing', + 'Op' => 'repair', + 'Msg_type' => 'Error', + 'Msg_text' => "Table 'missing' doesn't exist", + ), + (object) array( + 'Table' => 'wp.missing', + 'Op' => 'repair', + 'Msg_type' => 'status', + 'Msg_text' => 'Operation failed', + ), + ), + $result + ); + } + + public function testShowTableStatus() { + $this->assertQuery( 'CREATE TABLE t ( comment_author TEXT, comment_content TEXT )' ); + + $this->assertQuery( + "INSERT INTO t ( comment_author, comment_content ) VALUES ( 'PhpUnit', 'Testing' )" + ); + + $this->assertQuery( + "INSERT INTO t ( comment_author, comment_content ) VALUES ( 'PhpUnit0', 'Testing0' ), ( 'PhpUnit1', 'Testing1' ), ( 'PhpUnit2', 'Testing2' )" + ); + + $this->assertTableEmpty( 't', false ); + $results = $this->assertQuery( 'SHOW TABLE STATUS FROM wp' ); + + $this->assertEquals( + array( + (object) array( + 'Name' => 't', + 'Engine' => 'InnoDB', + 'Version' => '10', + 'Row_format' => 'Dynamic', + 'Rows' => '0', + 'Avg_row_length' => '0', + 'Data_length' => '0', + 'Max_data_length' => '0', + 'Index_length' => '0', + 'Data_free' => '0', + 'Auto_increment' => null, + 'Create_time' => $results[0]->Create_time, + 'Update_time' => null, + 'Check_time' => null, + 'Collation' => 'utf8mb4_general_ci', + 'Checksum' => null, + 'Create_options' => '', + 'Comment' => '', + ), + ), + $results + ); + } + + private function assertTableEmpty( $table_name, $empty_var ) { + + $this->assertQuery( + "SELECT COUNT(*) num FROM $table_name" + ); + + $actual = $this->engine->get_query_results(); + if ( $empty_var ) { + $this->assertEquals( 0, $actual[0]->num, "$table_name is not empty" ); + } else { + $this->assertGreaterThan( 0, $actual[0]->num, "$table_name is empty" ); + } + } + + public function testTruncateTable() { + + $this->assertQuery( + "INSERT INTO wp_comments ( comment_author, comment_content ) VALUES ( 'PhpUnit', 'Testing' )" + ); + + $this->assertQuery( + "INSERT INTO wp_comments ( comment_author, comment_content ) VALUES ( 'PhpUnit0', 'Testing0' ), ( 'PhpUnit1', 'Testing1' ), ( 'PhpUnit2', 'Testing2' )" + ); + + $this->assertTableEmpty( 'wp_comments', false ); + + $this->assertQuery( + 'TRUNCATE TABLE wp_comments;' + ); + $actual = $this->engine->get_query_results(); + $this->assertEquals( + true, + $actual + ); + $this->assertTableEmpty( 'wp_comments', true ); + } + + public function testBogusQuery() { + $this->expectExceptionMessage( 'no such table: bogus' ); + $this->assertQuery( + 'SELECT 1, BOGUS(1) FROM bogus;' + ); + } +} diff --git a/tests/WP_SQLite_Driver_Query_Tests.php b/tests/WP_SQLite_Driver_Query_Tests.php new file mode 100644 index 0000000..51b6b13 --- /dev/null +++ b/tests/WP_SQLite_Driver_Query_Tests.php @@ -0,0 +1,604 @@ +suppress_errors = false; + $GLOBALS['wpdb']->show_errors = true; + } + return; + } + + /** + * Before each test, we create a new volatile database and WordPress tables. + * + * @return void + * @throws Exception + */ + public function setUp(): void { + /* This is the DDL for WordPress tables in SQLite syntax. */ + global $blog_tables; + $queries = explode( ';', $blog_tables ); + + $this->sqlite = new PDO( 'sqlite::memory:' ); + $this->engine = new WP_SQLite_Driver( + array( + 'connection' => $this->sqlite, + 'database' => 'wp', + ) + ); + + $translator = $this->engine; + + try { + $translator->begin_transaction(); + foreach ( $queries as $query ) { + $query = trim( $query ); + if ( empty( $query ) ) { + continue; + } + + $translator->execute_sqlite_query( $query ); + } + $translator->commit(); + } catch ( PDOException $err ) { + $err_data = + $err->errorInfo; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase + $err_code = $err_data[1]; + $translator->rollback(); + $message = sprintf( + 'Error occurred while creating tables or indexes...
Query was: %s
', + var_export( $query, true ) + ); + $message .= sprintf( 'Error message is: %s', $err_data[2] ); + wp_die( $message, 'Database Error!' ); + } + + /* Mock up some metadata rows. When meta_key starts with _, the custom field isn't visible to the editor. */ + for ( $i = 1; $i <= 40; $i++ ) { + $k1 = 'visible_meta_key_' . str_pad( $i, 2, '0', STR_PAD_LEFT ); + $k2 = '_invisible_meta_key_%_percent' . str_pad( $i, 2, '0', STR_PAD_LEFT ); + $this->assertQuery( + "INSERT INTO wp_postmeta (post_id, meta_key, meta_value) VALUES (1, '$k1', '$k1-value');" + ); + $this->assertQuery( + "INSERT INTO wp_postmeta (post_id, meta_key, meta_value) VALUES (1, '$k2', '$k2-value');" + ); + } + + /* Mock up some transients for testing. Site transients. Two expired, one in the future. */ + $time = - 90; + foreach ( array( 'tag1', 'tag2', 'tag3' ) as $tag ) { + $tv = '_site_transient_' . $tag; + $tt = '_site_transient_timeout_' . $tag; + $this->assertQuery( + "INSERT INTO wp_options (option_name, option_value, autoload) VALUES ('$tv', '$tag', 'no');" + ); + $this->assertQuery( + "INSERT INTO wp_options (option_name, option_value, autoload) VALUES ('$tt', UNIX_TIMESTAMP() + $time, 'no');" + ); + $time += 60; + } + /* Ordinary transients. */ + $time = - 90; + foreach ( array( 'tag4', 'tag5', 'tag6' ) as $tag ) { + $tv = '_transient_' . $tag; + $tt = '_transient_timeout_' . $tag; + $this->assertQuery( + "INSERT INTO wp_options (option_name, option_value, autoload) VALUES ('$tv', '$tag', 'no');" + ); + $this->assertQuery( + "INSERT INTO wp_options (option_name, option_value, autoload) VALUES ('$tt', UNIX_TIMESTAMP() + $time, 'no');" + ); + $time += 60; + } + } + + public function testGreatestLeast() { + $q = <<<'QUERY' +SELECT GREATEST('a', 'b') letter; +QUERY; + + $result = $this->assertQuery( $q ); + $actual = $this->engine->get_query_results(); + $this->assertEquals( 1, count( $actual ) ); + $this->assertEquals( 'b', $actual[0]->letter ); + + $q = <<<'QUERY' +SELECT LEAST('a', 'b') letter; +QUERY; + + $result = $this->assertQuery( $q ); + $actual = $this->engine->get_query_results(); + $this->assertEquals( 1, count( $actual ) ); + $this->assertEquals( 'a', $actual[0]->letter ); + + $q = <<<'QUERY' +SELECT GREATEST(2, 1.5) num; +QUERY; + + $result = $this->assertQuery( $q ); + $actual = $this->engine->get_query_results(); + $this->assertEquals( 1, count( $actual ) ); + $this->assertEquals( 2, $actual[0]->num ); + + $q = <<<'QUERY' +SELECT LEAST(2, 1.5, 1.0) num; +QUERY; + + $result = $this->assertQuery( $q ); + $actual = $this->engine->get_query_results(); + $this->assertEquals( 1, count( $actual ) ); + $this->assertEquals( 1, $actual[0]->num ); + } + + public function testLikeEscapingSimpleNoSemicolon() { + $q = <<<'QUERY' +SELECT DISTINCT meta_key FROM wp_postmeta WHERE meta_key LIKE '\_%' +QUERY; + + $result = $this->assertQuery( $q ); + + $actual = $this->engine->get_query_results(); + $this->assertEquals( 40, count( $actual ) ); + } + + public function testLikeEscapingPercent() { + $q = <<<'QUERY' +SELECT DISTINCT meta_key FROM wp_postmeta WHERE meta_key LIKE '%\_\%\_percent%' +QUERY; + + $result = $this->assertQuery( $q ); + + $actual = $this->engine->get_query_results(); + $this->assertEquals( 40, count( $actual ) ); + } + + public function testLikeEscapingSimpleSemicolon() { + $q = <<<'QUERY' +SELECT DISTINCT meta_key FROM wp_postmeta WHERE meta_key LIKE '\_%'; +QUERY; + + $result = $this->assertQuery( $q ); + + $actual = $this->engine->get_query_results(); + $this->assertEquals( 40, count( $actual ) ); + } + + public function testLikeEscapingBasic() { + $q = <<<'QUERY' +SELECT DISTINCT meta_key FROM wp_postmeta WHERE meta_key NOT BETWEEN '_' AND '_z' AND meta_key NOT LIKE '\_%' ORDER BY meta_key LIMIT 30 +QUERY; + + $result = $this->assertQuery( $q ); + + $actual = $this->engine->get_query_results(); + $this->assertEquals( 30, count( $actual ) ); + $last = $actual[ count( $actual ) - 1 ]->meta_key; + $this->assertEquals( 'visible_meta_key_30', $last ); + } + + public function testLikeEscapingParenAfterLike() { + $q = <<<'QUERY' + SELECT DISTINCT meta_key + FROM wp_postmeta + WHERE (meta_key != 'hello' AND meta_key NOT LIKE '\_%') AND meta_id > 0 +QUERY; + + $this->assertQuery( $q ); + + $actual = $this->engine->get_query_results(); + $this->assertEquals( 40, count( $actual ) ); + $last = $actual[ count( $actual ) - 1 ]->meta_key; + $this->assertEquals( 'visible_meta_key_40', $last ); + } + + public function testLikeEscapingWithConcatFunction() { + $q = <<<'QUERY' +SELECT DISTINCT meta_key FROM wp_postmeta WHERE meta_key NOT BETWEEN '_' AND '_z' AND meta_key NOT LIKE CONCAT('\_', '%') ORDER BY meta_key LIMIT 30 +QUERY; + + $result = $this->assertQuery( $q ); + + $actual = $this->engine->get_query_results(); + $this->assertEquals( 30, count( $actual ) ); + $last = $actual[ count( $actual ) - 1 ]->meta_key; + $this->assertEquals( 'visible_meta_key_30', $last ); + } + + // https://github.com/WordPress/sqlite-database-integration/issues/19 + + public function testHavingWithoutGroupBy() { + + $q = <<<'QUERY' +SELECT DISTINCT meta_key FROM wp_postmeta WHERE meta_key NOT BETWEEN '_' AND '_z' HAVING meta_key NOT LIKE '\_%' ORDER BY meta_key LIMIT 30 +QUERY; + + $result = $this->assertQuery( $q ); + + $actual = $this->engine->get_query_results(); + $this->assertEquals( 30, count( $actual ) ); + $last = $actual[ count( $actual ) - 1 ]->meta_key; + $this->assertEquals( 'visible_meta_key_30', $last ); + + $q = <<<'QUERY' +SELECT DISTINCT meta_key FROM wp_postmeta WHERE meta_key NOT BETWEEN '_' AND '_z' HAVING meta_key NOT LIKE CONCAT('\_', '%') ORDER BY meta_key LIMIT 30 +QUERY; + + $result = $this->assertQuery( $q ); + + $actual = $this->engine->get_query_results(); + $this->assertEquals( 30, count( $actual ) ); + $last = $actual[ count( $actual ) - 1 ]->meta_key; + $this->assertEquals( 'visible_meta_key_30', $last ); + } + + public function testCharLengthSimple() { + $query = <<<'QUERY' +SELECT * FROM wp_options WHERE LENGTH(option_name) != CHAR_LENGTH(option_name) +QUERY; + + $this->assertQuery( $query ); + $actual = $this->engine->get_query_results(); + $this->assertEquals( 0, count( $actual ) ); + } + + public function testSubstringSimple() { + $query = <<<'QUERY' +SELECT SUBSTR(option_name, 1) ss1, SUBSTRING(option_name, 1) sstr1, + SUBSTR(option_name, -2) es1, SUBSTRING(option_name, -2) estr1 +FROM wp_options +WHERE SUBSTR(option_name, -2) != SUBSTRING(option_name, -2) + OR SUBSTR(option_name, 1) != SUBSTRING(option_name, 1) +QUERY; + + $this->assertQuery( $query ); + $actual = $this->engine->get_query_results(); + $this->assertEquals( 0, count( $actual ) ); + } + + public function testCharLengthComplex() { + $query = <<<'QUERY' +SELECT option_name, + CHAR_LENGTH( + CASE WHEN option_name LIKE '\_site\_transient\_%' + THEN '_site_transient_' + WHEN option_name LIKE '\_transient\_%' + THEN '_transient_' + ELSE '' END + ) prefix_length, + + SUBSTR(option_name, CHAR_LENGTH( + CASE WHEN option_name LIKE '\_site\_transient\_%' + THEN '_site_transient_' + WHEN option_name LIKE '\_transient\_%' + THEN '_transient_' + ELSE '' END + ) + 1) suffix +FROM wp_options +WHERE option_name LIKE '\_%transient\_%' +AND option_name NOT LIKE '%\_transient\_timeout\_%' +QUERY; + + $this->assertQuery( $query ); + $actual = $this->engine->get_query_results(); + $this->assertEquals( 6, count( $actual ) ); + foreach ( $actual as $row ) { + self::assertTrue( str_ends_with( $row->option_name, '_' . $row->suffix ) ); + } + } + + public function testAllTransients() { + $this->assertQuery( + "SELECT * FROM wp_options WHERE option_name LIKE '\_%transient\_%'" + ); + $actual = $this->engine->get_query_results(); + $this->assertEquals( 12, count( $actual ) ); + } + + public function testExpiredTransients() { + $query = <<<'QUERY' +SELECT a.option_id, a.option_name, a.option_value as option_content, a.autoload, b.option_value as option_timeout, + UNIX_TIMESTAMP() - b.option_value as age, + CONCAT ( + CASE WHEN a.option_name LIKE '\_site\_transient\_%' + THEN '_site_transient_timeout_' + ELSE '_transient_timeout_' + END, + SUBSTRING(a.option_name, CHAR_LENGTH( + CASE WHEN a.option_name LIKE '\_site\_transient\_%' + THEN '_site_transient_' + ELSE '_transient_' + END + ) + 1)) AS timeout_name + + + FROM wp_options a LEFT JOIN wp_options b ON b.option_name = + CONCAT( + CASE WHEN a.option_name LIKE '\_site\_transient\_%' + THEN '_site_transient_timeout_' + ELSE '_transient_timeout_' + END + , + SUBSTRING(a.option_name, CHAR_LENGTH( + CASE WHEN a.option_name LIKE '\_site\_transient\_%' + THEN '_site_transient_' + ELSE '_transient_' + END + ) + 1) + ) + WHERE (a.option_name LIKE '\_transient\_%' OR a.option_name LIKE '\_site\_transient\_%') + AND a.option_name NOT LIKE '%\_transient\_timeout\_%' + AND b.option_value < UNIX_TIMESTAMP() +QUERY; + + $this->assertQuery( $query ); + $actual = $this->engine->get_query_results(); + $this->assertEquals( 4, count( $actual ) ); + foreach ( $actual as $row ) { + self::assertLessThan( time(), $row->option_timeout ); + } + } + + public function testDeleteExpiredNonSiteTransients() { + + $now = time(); + + /* option.php: delete_expired_transients is the source of this query. */ + $query = <<<'QUERY' +DELETE a, b FROM wp_options a, wp_options b +WHERE a.option_name LIKE '\_transient\_%' +AND a.option_name NOT LIKE '\_transient\_timeout_%' +AND b.option_name = CONCAT( '_transient_timeout_', SUBSTRING( a.option_name, 12 ) ) +AND b.option_value < UNIX_TIMESTAMP() +QUERY; + $this->assertQuery( $query ); + + /* are the expired transients gone? */ + $query = <<<'QUERY' +SELECT a.option_id, a.option_name, a.option_value as option_content, + a.autoload, b.option_value as option_timeout, + UNIX_TIMESTAMP() - b.option_value as age, + CONCAT ( + CASE WHEN a.option_name LIKE '\_site\_transient\_%' + THEN '_site_transient_timeout_' + ELSE '_transient_timeout_' + END, + SUBSTRING(a.option_name, CHAR_LENGTH( + CASE WHEN a.option_name LIKE '\_site\_transient\_%' + THEN '_site_transient_' + ELSE '_transient_' + END + ) + 1)) AS timeout_name + + + FROM wp_options a LEFT JOIN wp_options b ON b.option_name = + CONCAT( + CASE WHEN a.option_name LIKE '\_site\_transient\_%' + THEN '_site_transient_timeout_' + ELSE '_transient_timeout_' + END + , + SUBSTRING(a.option_name, CHAR_LENGTH( + CASE WHEN a.option_name LIKE '\_site\_transient\_%' + THEN '_site_transient_' + ELSE '_transient_' + END + ) + 1) + ) + WHERE (a.option_name LIKE '\_transient\_%' OR a.option_name LIKE '\_site\_transient\_%') + AND a.option_name NOT LIKE '%\_transient\_timeout\_%' +QUERY; + + $this->assertQuery( $query ); + $actual = $this->engine->get_query_results(); + $count_unexpired = 0; + foreach ( $actual as $row ) { + if ( str_starts_with( $row->option_name, '_transient' ) ) { + ++$count_unexpired; + $this->assertGreaterThan( $now, $row->option_timeout ); + } + } + $this->assertEquals( 1, $count_unexpired ); + } + + public function testUserCountsByRole() { + /* commas appear after the LIKE term sometimes, as here. */ + $query = <<<'QUERY' +SELECT COUNT(NULLIF(`meta_value` LIKE '%\"administrator\"%', false)), + COUNT(NULLIF(`meta_value` LIKE '%\"editor\"%', false)), + COUNT(NULLIF(`meta_value` LIKE '%\"author\"%', false)), + COUNT(NULLIF(`meta_value` LIKE '%\"contributor\"%', false)), + COUNT(NULLIF(`meta_value` LIKE '%\"subscriber\"%', false)), + COUNT(NULLIF(`meta_value` = 'a:0:{}', false)), + COUNT(*) +FROM wp_usermeta +INNER JOIN wp_users ON user_id = ID +WHERE meta_key = 'wp_capabilities' + +QUERY; + $this->assertQuery( $query ); + } + + public function testTranscendental() { + $this->markTestIncomplete( 'For some reason sqlite\'s transcendental functions are missing.' ); + $this->assertQuery( 'SELECT 2.0, SQRT(2.0) sqr, SIN(0.5) s;' ); + } + + public function testRecoverSerialized() { + + $obj = array( + 'this' => 'that', + 'that' => array( 'the', 'other', 'thing' ), + 'two' => 2, + 2 => 'two', + 'pi' => pi(), + 'moo' => "Mrs O'Leary's cow!", + ); + $option_name = 'serialized_option'; + $option_value = serialize( $obj ); + $option_value_escaped = $this->engine->get_pdo()->quote( $option_value ); + /* Note well: this is heredoc not nowdoc */ + $insert = <<assertQuery( $insert ); + $get = <<assertQuery( $get ); + + $actual = $this->engine->get_query_results(); + $retrieved_name = $actual[0]->option_name; + $retrieved_string = $actual[0]->option_value; + $this->assertEquals( $option_value, $retrieved_string ); + $unserialized = unserialize( $retrieved_string ); + $this->assertEquals( $obj, $unserialized ); + + ++$obj ['two']; + $obj ['pi'] *= 2; + $option_value = serialize( $obj ); + $option_value_escaped = $this->engine->get_pdo()->quote( $option_value ); + /* Note well: this is heredoc not nowdoc */ + $insert = <<assertQuery( $insert ); + $get = <<assertQuery( $get ); + + $actual = $this->engine->get_query_results(); + $retrieved_string = $actual[0]->option_value; + $this->assertEquals( $option_value, $retrieved_string ); + $unserialized = unserialize( $retrieved_string ); + $this->assertEquals( $obj, $unserialized ); + } + + public function testOnDuplicateKey() { + $this->assertQuery( + 'CREATE TABLE `test` ( + `id` INT PRIMARY KEY, + `text` VARCHAR(255) + );' + ); + // The order is deliberate to test that the query works with the keys in any order. + $this->assertQuery( + 'INSERT INTO test (`text`, `id`) + VALUES ("test", 1) + ON DUPLICATE KEY UPDATE `text` = "test1"' + ); + } + public function testOnDuplicateKeyWithUnnamedKeys() { + $this->assertQuery( + 'CREATE TABLE `test` ( + `id` INT, + `name` VARCHAR(255), + `other` VARCHAR(255), + PRIMARY KEY (id), + UNIQUE KEY (name) + );' + ); + // The order is deliberate to test that the query works with the keys in any order. + $this->assertQuery( + 'INSERT INTO test (id, `name`, other) + VALUES (1, "name", "test") + ON DUPLICATE KEY UPDATE `other` = values(other)' + ); + } + + public function testOnCreateTableIfNotExistsWithIndexAdded() { + $this->assertQuery( + 'CREATE TABLE IF not EXISTS `test` ( + `id` INT, + `name` VARCHAR(255), + `other` VARCHAR(255), + PRIMARY KEY (id), + UNIQUE KEY (name) + );' + ); + $this->assertQuery( + 'CREATE TABLE if NOT ExisTS `test` ( + `id` INT, + `name` VARCHAR(255), + `other` VARCHAR(255), + PRIMARY KEY (id), + UNIQUE KEY (name) + );' + ); + } + + public function testShowColumns() { + $this->assertQuery( + ' + CREATE TABLE t ( + id INT PRIMARY KEY, + name VARCHAR(255) NOT NULL, + age INT DEFAULT 0, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + deleted_at TIMESTAMP DEFAULT NULL, + CONSTRAINT name_unique UNIQUE (name), + INDEX name_index (name) + ); + ' + ); + + $query = 'SHOW COLUMNS FROM t'; + $this->assertQuery( $query ); + + $actual = $this->engine->get_query_results(); + $this->assertCount( 6, $actual ); + foreach ( $actual as $row ) { + $this->assertIsObject( $row ); + $this->assertTrue( property_exists( $row, 'Field' ) ); + $this->assertTrue( property_exists( $row, 'Type' ) ); + $this->assertTrue( property_exists( $row, 'Null' ) ); + $this->assertTrue( ( 'NO' === $row->Null ) || ( 'YES' === $row->Null ) ); + $this->assertTrue( property_exists( $row, 'Key' ) ); + $this->assertTrue( property_exists( $row, 'Default' ) ); + } + } + + private function assertQuery( $sql ) { + $retval = $this->engine->query( $sql ); + $this->assertNotFalse( $retval ); + return $retval; + } +} diff --git a/tests/WP_SQLite_Driver_Tests.php b/tests/WP_SQLite_Driver_Tests.php index c1f4222..1b2af7b 100644 --- a/tests/WP_SQLite_Driver_Tests.php +++ b/tests/WP_SQLite_Driver_Tests.php @@ -3776,4 +3776,204 @@ public function testUnionAll(): void { $this->engine->get_query_results() ); } + + public function testShowCreateTableWithEmptyDatetimeDefault() { + $this->assertQuery( + "CREATE TABLE _tmp_table ( + ID BIGINT PRIMARY KEY AUTO_INCREMENT, + timestamp1 datetime NOT NULL, + timestamp2 date NOT NULL, + timestamp3 time NOT NULL, + timestamp4 timestamp NOT NULL, + timestamp5 year NOT NULL, + notempty1 datetime DEFAULT '1999-12-12 12:12:12', + notempty2 date DEFAULT '1999-12-12', + notempty3 time DEFAULT '12:12:12', + notempty4 year DEFAULT '2024', + notempty5 timestamp DEFAULT '1999-12-12 12:12:12' + );" + ); + + $this->assertQuery( + 'SHOW CREATE TABLE _tmp_table;' + ); + $results = $this->engine->get_query_results(); + + $this->assertEquals( + "CREATE TABLE `_tmp_table` ( + `ID` bigint NOT NULL AUTO_INCREMENT, + `timestamp1` datetime NOT NULL, + `timestamp2` date NOT NULL, + `timestamp3` time NOT NULL, + `timestamp4` timestamp NOT NULL, + `timestamp5` year NOT NULL, + `notempty1` datetime DEFAULT '1999-12-12 12:12:12', + `notempty2` date DEFAULT '1999-12-12', + `notempty3` time DEFAULT '12:12:12', + `notempty4` year DEFAULT '2024', + `notempty5` timestamp NULL DEFAULT '1999-12-12 12:12:12', + PRIMARY KEY (`ID`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci", + $results[0]->{'Create Table'} + ); + } + + public function testShowCreateTablePreservesKeyLengths() { + $this->assertQuery( + 'CREATE TABLE _tmp__table ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `order_id` bigint(20) unsigned DEFAULT NULL, + `meta_key` varchar(255) DEFAULT NULL, + `meta_value` text DEFAULT NULL, + `meta_data` mediumblob DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `meta_key_value` (`meta_key`(20),`meta_value`(82)), + KEY `order_id_meta_key_meta_value` (`order_id`,`meta_key`(100),`meta_value`(82)), + KEY `order_id_meta_key_meta_data` (`order_id`,`meta_key`(100),`meta_data`(100)) + );' + ); + + $this->assertQuery( + 'SHOW CREATE TABLE _tmp__table;' + ); + $results = $this->engine->get_query_results(); + $this->assertEquals( + 'CREATE TABLE `_tmp__table` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `order_id` bigint(20) unsigned DEFAULT NULL, + `meta_key` varchar(255) DEFAULT NULL, + `meta_value` text DEFAULT NULL, + `meta_data` mediumblob DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `meta_key_value` (`meta_key`(20), `meta_value`(82)), + KEY `order_id_meta_key_meta_value` (`order_id`, `meta_key`(100), `meta_value`(82)), + KEY `order_id_meta_key_meta_data` (`order_id`, `meta_key`(100), `meta_data`(100)) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci', + $results[0]->{'Create Table'} + ); + } + + public function testTimestampColumnNamedTimestamp() { + $this->assertQuery( + 'CREATE TABLE `_tmp_table` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `timestamp` datetime NOT NULL, + PRIMARY KEY (`id`), + KEY timestamp (timestamp) + );' + ); + $results = $this->assertQuery( 'DESCRIBE _tmp_table;' ); + $this->assertEquals( + array( + (object) array( + 'Field' => 'id', + 'Type' => 'bigint(20) unsigned', + 'Null' => 'NO', + 'Key' => 'PRI', + 'Default' => null, + 'Extra' => 'auto_increment', + ), + (object) array( + 'Field' => 'timestamp', + 'Type' => 'datetime', + 'Null' => 'NO', + 'Key' => 'MUL', + 'Default' => null, + 'Extra' => '', + ), + ), + $results + ); + } + + public function testCompoundPrimaryKeyAndAutoincrementNotSupported(): void { + $this->expectException( WP_SQLite_Driver_Exception::class ); + $this->expectExceptionMessage( 'Cannot combine AUTOINCREMENT and multiple primary keys in SQLite' ); + $this->assertQuery( + 'CREATE TABLE t1 (id1 INT AUTO_INCREMENT, id2 INT, PRIMARY KEY(id1, id2))' + ); + } + + /** + * @dataProvider getReservedPrefixTestData + */ + public function testReservedPrefix( string $query, string $error ): void { + $this->expectException( WP_SQLite_Driver_Exception::class ); + $this->expectExceptionMessage( $error ); + $this->assertQuery( $query ); + } + + public function getReservedPrefixTestData(): array { + return array( + array( + 'SELECT * FROM _wp_sqlite_t', + "Invalid identifier `_wp_sqlite_t`, prefix '_wp_sqlite_' is reserved", + ), + array( + 'SELECT _wp_sqlite_t FROM t', + "Invalid identifier `_wp_sqlite_t`, prefix '_wp_sqlite_' is reserved", + ), + array( + 'SELECT t._wp_sqlite_t FROM t', + "Invalid identifier `t`.`_wp_sqlite_t`, prefix '_wp_sqlite_' is reserved", + ), + array( + 'CREATE TABLE _wp_sqlite_t (id INT)', + "Invalid identifier `_wp_sqlite_t`, prefix '_wp_sqlite_' is reserved", + ), + array( + 'ALTER TABLE _wp_sqlite_t ADD COLUMN name TEXT', + "Invalid identifier `_wp_sqlite_t`, prefix '_wp_sqlite_' is reserved", + ), + array( + 'DROP TABLE _wp_sqlite_t', + "Invalid identifier `_wp_sqlite_t`, prefix '_wp_sqlite_' is reserved", + ), + ); + } + + /** + * @dataProvider getInformationSchemaIsReadonlyTestData + */ + public function testInformationSchemaIsReadonly( string $query ): void { + $this->assertQuery( 'CREATE TABLE t1 (id INT)' ); + $this->expectException( WP_SQLite_Driver_Exception::class ); + $this->expectExceptionMessage( "Access denied for user 'sqlite'@'%' to database 'information_schema'" ); + $this->assertQuery( $query ); + } + + public function getInformationSchemaIsReadonlyTestData(): array { + return array( + array( 'INSERT INTO information_schema.tables (table_name) VALUES ("t")' ), + array( 'UPDATE information_schema.tables SET table_name = "new_t" WHERE table_name = "t"' ), + array( 'DELETE FROM information_schema.tables WHERE table_name = "t"' ), + array( 'CREATE TABLE information_schema.new_table (id INT)' ), + array( 'ALTER TABLE information_schema.tables ADD COLUMN new_column INT' ), + array( 'DROP TABLE information_schema.tables' ), + array( 'TRUNCATE information_schema.tables' ), + ); + } + + /** + * @dataProvider getInformationSchemaIsReadonlyWithUseTestData + */ + public function testInformationSchemaIsReadonlyWithUse( string $query ): void { + $this->assertQuery( 'CREATE TABLE t1 (id INT)' ); + $this->expectException( WP_SQLite_Driver_Exception::class ); + $this->expectExceptionMessage( "Access denied for user 'sqlite'@'%' to database 'information_schema'" ); + $this->assertQuery( 'USE information_schema' ); + $this->assertQuery( $query ); + } + + public function getInformationSchemaIsReadonlyWithUseTestData(): array { + return array( + array( 'INSERT INTO tables (table_name) VALUES ("t")' ), + array( 'UPDATE tables SET table_name = "new_t" WHERE table_name = "t"' ), + array( 'DELETE FROM tables WHERE table_name = "t"' ), + array( 'CREATE TABLE new_table (id INT)' ), + array( 'ALTER TABLE tables ADD COLUMN new_column INT' ), + array( 'DROP TABLE tables' ), + array( 'TRUNCATE tables' ), + ); + } } diff --git a/tests/WP_SQLite_Driver_Translation_Tests.php b/tests/WP_SQLite_Driver_Translation_Tests.php index 2f1bed3..7400d90 100644 --- a/tests/WP_SQLite_Driver_Translation_Tests.php +++ b/tests/WP_SQLite_Driver_Translation_Tests.php @@ -106,8 +106,8 @@ public function testInsert(): void { ); $this->assertQuery( - 'INSERT INTO `s`.`t` ( `c` ) VALUES ( 1 )', - 'INSERT INTO s.t (c) VALUES (1)' + 'INSERT INTO `t` ( `c` ) VALUES ( 1 )', + 'INSERT INTO wp.t (c) VALUES (1)' ); $this->assertQuery( @@ -133,8 +133,8 @@ public function testReplace(): void { ); $this->assertQuery( - 'REPLACE INTO `s`.`t` ( `c` ) VALUES ( 1 )', - 'REPLACE INTO s.t (c) VALUES (1)' + 'REPLACE INTO `t` ( `c` ) VALUES ( 1 )', + 'REPLACE INTO wp.t (c) VALUES (1)' ); $this->assertQuery( @@ -160,8 +160,8 @@ public function testUpdate(): void { ); $this->assertQuery( - 'UPDATE `s`.`t` SET `c` = 1', - 'UPDATE s.t SET c = 1' + 'UPDATE `t` SET `c` = 1', + 'UPDATE wp.t SET c = 1' ); $this->assertQuery( @@ -194,8 +194,8 @@ public function testDelete(): void { ); $this->assertQuery( - 'DELETE FROM `s`.`t`', - 'DELETE FROM s.t' + 'DELETE FROM `t`', + 'DELETE FROM wp.t' ); $this->assertQuery( @@ -212,13 +212,13 @@ public function testCreateTable(): void { $this->assertExecutedInformationSchemaQueries( array( - 'INSERT INTO _mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' - . " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'DYNAMIC', 'utf8mb4_general_ci')", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' + . " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'Dynamic', 'utf8mb4_general_ci')", + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'id', 1, null, 'YES', 'int', null, null, 10, 0, null, null, null, 'int', '', '', 'select,insert,update,references', '', '', null)", - "SELECT * FROM _mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", ) ); } @@ -231,17 +231,17 @@ public function testCreateTableWithMultipleColumns(): void { $this->assertExecutedInformationSchemaQueries( array( - 'INSERT INTO _mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' - . " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'DYNAMIC', 'utf8mb4_general_ci')", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' + . " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'Dynamic', 'utf8mb4_general_ci')", + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'id', 1, null, 'YES', 'int', null, null, 10, 0, null, null, null, 'int', '', '', 'select,insert,update,references', '', '', null)", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'name', 2, null, 'YES', 'text', 65535, 65535, null, null, null, 'utf8mb4', 'utf8mb4_general_ci', 'text', '', '', 'select,insert,update,references', '', '', null)", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'score', 3, '0.0', 'YES', 'float', null, null, 12, null, null, null, null, 'float', '', '', 'select,insert,update,references', '', '', null)", - "SELECT * FROM _mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", ) ); } @@ -254,15 +254,15 @@ public function testCreateTableWithBasicConstraints(): void { $this->assertExecutedInformationSchemaQueries( array( - 'INSERT INTO _mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' - . " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'DYNAMIC', 'utf8mb4_general_ci')", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' + . " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'Dynamic', 'utf8mb4_general_ci')", + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'id', 1, null, 'NO', 'int', null, null, 10, 0, null, null, null, 'int', 'PRI', 'auto_increment', 'select,insert,update,references', '', '', null)", - 'INSERT INTO _mysql_information_schema_statistics (table_schema, table_name, non_unique, index_schema, index_name, seq_in_index, column_name, collation, cardinality, sub_part, packed, nullable, index_type, comment, index_comment, is_visible, expression)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_statistics (table_schema, table_name, non_unique, index_schema, index_name, seq_in_index, column_name, collation, cardinality, sub_part, packed, nullable, index_type, comment, index_comment, is_visible, expression)' . " VALUES ('wp', 't', 0, 'wp', 'PRIMARY', 1, 'id', 'A', 0, null, null, '', 'BTREE', '', '', 'YES', null)", - "SELECT * FROM _mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", ) ); } @@ -276,13 +276,13 @@ public function testCreateTableWithEngine(): void { $this->assertExecutedInformationSchemaQueries( array( - 'INSERT INTO _mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' - . " VALUES ('wp', 't', 'BASE TABLE', 'MyISAM', 'FIXED', 'utf8mb4_general_ci')", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' + . " VALUES ('wp', 't', 'BASE TABLE', 'MyISAM', 'Fixed', 'utf8mb4_general_ci')", + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'id', 1, null, 'YES', 'int', null, null, 10, 0, null, null, null, 'int', '', '', 'select,insert,update,references', '', '', null)", - "SELECT * FROM _mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", ) ); } @@ -296,13 +296,13 @@ public function testCreateTableWithCollate(): void { $this->assertExecutedInformationSchemaQueries( array( - 'INSERT INTO _mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' - . " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'DYNAMIC', 'utf8mb4_czech_ci')", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' + . " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'Dynamic', 'utf8mb4_czech_ci')", + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'id', 1, null, 'YES', 'int', null, null, 10, 0, null, null, null, 'int', '', '', 'select,insert,update,references', '', '', null)", - "SELECT * FROM _mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", ) ); } @@ -324,15 +324,15 @@ public function testCreateTableWithPrimaryKey(): void { $this->assertExecutedInformationSchemaQueries( array( - 'INSERT INTO _mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' - . " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'DYNAMIC', 'utf8mb4_general_ci')", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' + . " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'Dynamic', 'utf8mb4_general_ci')", + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'id', 1, null, 'NO', 'int', null, null, 10, 0, null, null, null, 'int', 'PRI', '', 'select,insert,update,references', '', '', null)", - 'INSERT INTO _mysql_information_schema_statistics (table_schema, table_name, non_unique, index_schema, index_name, seq_in_index, column_name, collation, cardinality, sub_part, packed, nullable, index_type, comment, index_comment, is_visible, expression)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_statistics (table_schema, table_name, non_unique, index_schema, index_name, seq_in_index, column_name, collation, cardinality, sub_part, packed, nullable, index_type, comment, index_comment, is_visible, expression)' . " VALUES ('wp', 't', 0, 'wp', 'PRIMARY', 1, 'id', 'A', 0, null, null, '', 'BTREE', '', '', 'YES', null)", - "SELECT * FROM _mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", ) ); } @@ -346,15 +346,15 @@ public function testCreateTableWithPrimaryKeyAndAutoincrement(): void { $this->assertExecutedInformationSchemaQueries( array( - 'INSERT INTO _mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' - . " VALUES ('wp', 't1', 'BASE TABLE', 'InnoDB', 'DYNAMIC', 'utf8mb4_general_ci')", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' + . " VALUES ('wp', 't1', 'BASE TABLE', 'InnoDB', 'Dynamic', 'utf8mb4_general_ci')", + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't1', 'id', 1, null, 'NO', 'int', null, null, 10, 0, null, null, null, 'int', 'PRI', 'auto_increment', 'select,insert,update,references', '', '', null)", - 'INSERT INTO _mysql_information_schema_statistics (table_schema, table_name, non_unique, index_schema, index_name, seq_in_index, column_name, collation, cardinality, sub_part, packed, nullable, index_type, comment, index_comment, is_visible, expression)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_statistics (table_schema, table_name, non_unique, index_schema, index_name, seq_in_index, column_name, collation, cardinality, sub_part, packed, nullable, index_type, comment, index_comment, is_visible, expression)' . " VALUES ('wp', 't1', 0, 'wp', 'PRIMARY', 1, 'id', 'A', 0, null, null, '', 'BTREE', '', '', 'YES', null)", - "SELECT * FROM _mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't1'", - "SELECT * FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't1'", - "SELECT * FROM _mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't1'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't1'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't1'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't1'", ) ); @@ -366,15 +366,15 @@ public function testCreateTableWithPrimaryKeyAndAutoincrement(): void { $this->assertExecutedInformationSchemaQueries( array( - 'INSERT INTO _mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' - . " VALUES ('wp', 't2', 'BASE TABLE', 'InnoDB', 'DYNAMIC', 'utf8mb4_general_ci')", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' + . " VALUES ('wp', 't2', 'BASE TABLE', 'InnoDB', 'Dynamic', 'utf8mb4_general_ci')", + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't2', 'id', 1, null, 'NO', 'int', null, null, 10, 0, null, null, null, 'int', 'PRI', 'auto_increment', 'select,insert,update,references', '', '', null)", - 'INSERT INTO _mysql_information_schema_statistics (table_schema, table_name, non_unique, index_schema, index_name, seq_in_index, column_name, collation, cardinality, sub_part, packed, nullable, index_type, comment, index_comment, is_visible, expression)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_statistics (table_schema, table_name, non_unique, index_schema, index_name, seq_in_index, column_name, collation, cardinality, sub_part, packed, nullable, index_type, comment, index_comment, is_visible, expression)' . " VALUES ('wp', 't2', 0, 'wp', 'PRIMARY', 1, 'id', 'A', 0, null, null, '', 'BTREE', '', '', 'YES', null)", - "SELECT * FROM _mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't2'", - "SELECT * FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't2'", - "SELECT * FROM _mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't2'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't2'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't2'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't2'", ) ); @@ -386,17 +386,17 @@ public function testCreateTableWithPrimaryKeyAndAutoincrement(): void { $this->assertExecutedInformationSchemaQueries( array( - 'INSERT INTO _mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' - . " VALUES ('wp', 't3', 'BASE TABLE', 'InnoDB', 'DYNAMIC', 'utf8mb4_general_ci')", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' + . " VALUES ('wp', 't3', 'BASE TABLE', 'InnoDB', 'Dynamic', 'utf8mb4_general_ci')", + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't3', 'id', 1, null, 'YES', 'int', null, null, 10, 0, null, null, null, 'int', '', 'auto_increment', 'select,insert,update,references', '', '', null)", - "SELECT column_name, data_type, is_nullable, character_maximum_length FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't3' AND column_name IN ('id')", - 'INSERT INTO _mysql_information_schema_statistics (table_schema, table_name, non_unique, index_schema, index_name, seq_in_index, column_name, collation, cardinality, sub_part, packed, nullable, index_type, comment, index_comment, is_visible, expression)' + "SELECT column_name, data_type, is_nullable, character_maximum_length FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't3' AND column_name IN ('id')", + 'INSERT INTO _wp_sqlite_mysql_information_schema_statistics (table_schema, table_name, non_unique, index_schema, index_name, seq_in_index, column_name, collation, cardinality, sub_part, packed, nullable, index_type, comment, index_comment, is_visible, expression)' . " VALUES ('wp', 't3', 0, 'wp', 'PRIMARY', 1, 'id', 'A', 0, null, null, '', 'BTREE', '', '', 'YES', null)", - "WITH s AS ( SELECT column_name, CASE WHEN MAX(index_name = 'PRIMARY') THEN 'PRI' WHEN MAX(non_unique = 0 AND seq_in_index = 1) THEN 'UNI' WHEN MAX(seq_in_index = 1) THEN 'MUL' ELSE '' END AS column_key FROM _mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't3' GROUP BY column_name ) UPDATE _mysql_information_schema_columns AS c SET column_key = s.column_key, is_nullable = IIF(s.column_key = 'PRI', 'NO', c.is_nullable) FROM s WHERE c.table_schema = 'wp' AND c.table_name = 't3' AND s.column_name = c.column_name", - "SELECT * FROM _mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't3'", - "SELECT * FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't3'", - "SELECT * FROM _mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't3'", + "WITH s AS ( SELECT column_name, CASE WHEN MAX(index_name = 'PRIMARY') THEN 'PRI' WHEN MAX(non_unique = 0 AND seq_in_index = 1) THEN 'UNI' WHEN MAX(seq_in_index = 1) THEN 'MUL' ELSE '' END AS column_key FROM _wp_sqlite_mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't3' GROUP BY column_name ) UPDATE _wp_sqlite_mysql_information_schema_columns AS c SET column_key = s.column_key, is_nullable = IIF(s.column_key = 'PRI', 'NO', c.is_nullable) FROM s WHERE c.table_schema = 'wp' AND c.table_name = 't3' AND s.column_name = c.column_name", + "SELECT * FROM _wp_sqlite_mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't3'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't3'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't3'", ) ); } @@ -410,9 +410,9 @@ public function testCreateTableWithPrimaryKeyAndAutoincrement(): void { $this->assertExecutedInformationSchemaQueries( array( - 'INSERT INTO _mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' - . " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'DYNAMIC', 'utf8mb4_general_ci')", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' + . " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'Dynamic', 'utf8mb4_general_ci')", + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'id', 1, null, 'YES', 'int', null, null, 10, 0, null, null, null, 'int', '', '', 'select,insert,update,references', '', '', null)", ) ); @@ -430,19 +430,19 @@ public function testCreateTableWithInlineUniqueIndexes(): void { $this->assertExecutedInformationSchemaQueries( array( - 'INSERT INTO _mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' - . " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'DYNAMIC', 'utf8mb4_general_ci')", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' + . " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'Dynamic', 'utf8mb4_general_ci')", + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'id', 1, null, 'YES', 'int', null, null, 10, 0, null, null, null, 'int', 'UNI', '', 'select,insert,update,references', '', '', null)", - 'INSERT INTO _mysql_information_schema_statistics (table_schema, table_name, non_unique, index_schema, index_name, seq_in_index, column_name, collation, cardinality, sub_part, packed, nullable, index_type, comment, index_comment, is_visible, expression)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_statistics (table_schema, table_name, non_unique, index_schema, index_name, seq_in_index, column_name, collation, cardinality, sub_part, packed, nullable, index_type, comment, index_comment, is_visible, expression)' . " VALUES ('wp', 't', 0, 'wp', 'id', 1, 'id', 'A', 0, null, null, 'YES', 'BTREE', '', '', 'YES', null)", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'name', 2, null, 'YES', 'text', 65535, 65535, null, null, null, 'utf8mb4', 'utf8mb4_general_ci', 'text', 'UNI', '', 'select,insert,update,references', '', '', null)", - 'INSERT INTO _mysql_information_schema_statistics (table_schema, table_name, non_unique, index_schema, index_name, seq_in_index, column_name, collation, cardinality, sub_part, packed, nullable, index_type, comment, index_comment, is_visible, expression)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_statistics (table_schema, table_name, non_unique, index_schema, index_name, seq_in_index, column_name, collation, cardinality, sub_part, packed, nullable, index_type, comment, index_comment, is_visible, expression)' . " VALUES ('wp', 't', 0, 'wp', 'name', 1, 'name', 'A', 0, null, null, 'YES', 'BTREE', '', '', 'YES', null)", - "SELECT * FROM _mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", ) ); } @@ -459,23 +459,23 @@ public function testCreateTableWithStandaloneUniqueIndexes(): void { $this->assertExecutedInformationSchemaQueries( array( - 'INSERT INTO _mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' - . " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'DYNAMIC', 'utf8mb4_general_ci')", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' + . " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'Dynamic', 'utf8mb4_general_ci')", + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'id', 1, null, 'YES', 'int', null, null, 10, 0, null, null, null, 'int', '', '', 'select,insert,update,references', '', '', null)", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'name', 2, null, 'YES', 'varchar', 100, 400, null, null, null, 'utf8mb4', 'utf8mb4_general_ci', 'varchar(100)', '', '', 'select,insert,update,references', '', '', null)", - "SELECT column_name, data_type, is_nullable, character_maximum_length FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't' AND column_name IN ('id')", - 'INSERT INTO _mysql_information_schema_statistics (table_schema, table_name, non_unique, index_schema, index_name, seq_in_index, column_name, collation, cardinality, sub_part, packed, nullable, index_type, comment, index_comment, is_visible, expression)' + "SELECT column_name, data_type, is_nullable, character_maximum_length FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't' AND column_name IN ('id')", + 'INSERT INTO _wp_sqlite_mysql_information_schema_statistics (table_schema, table_name, non_unique, index_schema, index_name, seq_in_index, column_name, collation, cardinality, sub_part, packed, nullable, index_type, comment, index_comment, is_visible, expression)' . " VALUES ('wp', 't', 0, 'wp', 'id', 1, 'id', 'A', 0, null, null, 'YES', 'BTREE', '', '', 'YES', null)", - "WITH s AS ( SELECT column_name, CASE WHEN MAX(index_name = 'PRIMARY') THEN 'PRI' WHEN MAX(non_unique = 0 AND seq_in_index = 1) THEN 'UNI' WHEN MAX(seq_in_index = 1) THEN 'MUL' ELSE '' END AS column_key FROM _mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't' GROUP BY column_name ) UPDATE _mysql_information_schema_columns AS c SET column_key = s.column_key, is_nullable = IIF(s.column_key = 'PRI', 'NO', c.is_nullable) FROM s WHERE c.table_schema = 'wp' AND c.table_name = 't' AND s.column_name = c.column_name", - "SELECT column_name, data_type, is_nullable, character_maximum_length FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't' AND column_name IN ('name')", - 'INSERT INTO _mysql_information_schema_statistics (table_schema, table_name, non_unique, index_schema, index_name, seq_in_index, column_name, collation, cardinality, sub_part, packed, nullable, index_type, comment, index_comment, is_visible, expression)' + "WITH s AS ( SELECT column_name, CASE WHEN MAX(index_name = 'PRIMARY') THEN 'PRI' WHEN MAX(non_unique = 0 AND seq_in_index = 1) THEN 'UNI' WHEN MAX(seq_in_index = 1) THEN 'MUL' ELSE '' END AS column_key FROM _wp_sqlite_mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't' GROUP BY column_name ) UPDATE _wp_sqlite_mysql_information_schema_columns AS c SET column_key = s.column_key, is_nullable = IIF(s.column_key = 'PRI', 'NO', c.is_nullable) FROM s WHERE c.table_schema = 'wp' AND c.table_name = 't' AND s.column_name = c.column_name", + "SELECT column_name, data_type, is_nullable, character_maximum_length FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't' AND column_name IN ('name')", + 'INSERT INTO _wp_sqlite_mysql_information_schema_statistics (table_schema, table_name, non_unique, index_schema, index_name, seq_in_index, column_name, collation, cardinality, sub_part, packed, nullable, index_type, comment, index_comment, is_visible, expression)' . " VALUES ('wp', 't', 0, 'wp', 'name', 1, 'name', 'A', 0, null, null, 'YES', 'BTREE', '', '', 'YES', null)", - "WITH s AS ( SELECT column_name, CASE WHEN MAX(index_name = 'PRIMARY') THEN 'PRI' WHEN MAX(non_unique = 0 AND seq_in_index = 1) THEN 'UNI' WHEN MAX(seq_in_index = 1) THEN 'MUL' ELSE '' END AS column_key FROM _mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't' GROUP BY column_name ) UPDATE _mysql_information_schema_columns AS c SET column_key = s.column_key, is_nullable = IIF(s.column_key = 'PRI', 'NO', c.is_nullable) FROM s WHERE c.table_schema = 'wp' AND c.table_name = 't' AND s.column_name = c.column_name", - "SELECT * FROM _mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", + "WITH s AS ( SELECT column_name, CASE WHEN MAX(index_name = 'PRIMARY') THEN 'PRI' WHEN MAX(non_unique = 0 AND seq_in_index = 1) THEN 'UNI' WHEN MAX(seq_in_index = 1) THEN 'MUL' ELSE '' END AS column_key FROM _wp_sqlite_mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't' GROUP BY column_name ) UPDATE _wp_sqlite_mysql_information_schema_columns AS c SET column_key = s.column_key, is_nullable = IIF(s.column_key = 'PRI', 'NO', c.is_nullable) FROM s WHERE c.table_schema = 'wp' AND c.table_name = 't' AND s.column_name = c.column_name", + "SELECT * FROM _wp_sqlite_mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", ) ); } @@ -508,6 +508,19 @@ public function testCreateTemporaryTable(): void { ); } + public function testDropTemporaryTable(): void { + $this->assertQuery( + 'DROP TABLE `temp`.`t`', + 'DROP TEMPORARY TABLE t' + ); + + // With IF NOT EXISTS. + $this->assertQuery( + 'DROP TABLE IF EXISTS `temp`.`t`', + 'DROP TEMPORARY TABLE IF EXISTS t' + ); + } + public function testAlterTableAddColumn(): void { $this->driver->query( 'CREATE TABLE t (id INT)' ); $this->assertQuery( @@ -526,13 +539,13 @@ public function testAlterTableAddColumn(): void { $this->assertExecutedInformationSchemaQueries( array( - "SELECT COLUMN_NAME FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", - "SELECT MAX(ordinal_position) FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + "SELECT COLUMN_NAME FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT MAX(ordinal_position) FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'a', 2, null, 'YES', 'int', null, null, 10, 0, null, null, null, 'int', '', '', 'select,insert,update,references', '', '', null)", - "SELECT * FROM _mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", ) ); } @@ -555,13 +568,13 @@ public function testAlterTableAddColumnWithNotNull(): void { $this->assertExecutedInformationSchemaQueries( array( - "SELECT COLUMN_NAME FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", - "SELECT MAX(ordinal_position) FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + "SELECT COLUMN_NAME FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT MAX(ordinal_position) FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'a', 2, null, 'NO', 'int', null, null, 10, 0, null, null, null, 'int', '', '', 'select,insert,update,references', '', '', null)", - "SELECT * FROM _mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", ) ); } @@ -584,13 +597,13 @@ public function testAlterTableAddColumnWithDefault(): void { $this->assertExecutedInformationSchemaQueries( array( - "SELECT COLUMN_NAME FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", - "SELECT MAX(ordinal_position) FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + "SELECT COLUMN_NAME FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT MAX(ordinal_position) FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'a', 2, '0', 'YES', 'int', null, null, 10, 0, null, null, null, 'int', '', '', 'select,insert,update,references', '', '', null)", - "SELECT * FROM _mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", ) ); } @@ -613,13 +626,13 @@ public function testAlterTableAddColumnWithNotNullAndDefault(): void { $this->assertExecutedInformationSchemaQueries( array( - "SELECT COLUMN_NAME FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", - "SELECT MAX(ordinal_position) FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + "SELECT COLUMN_NAME FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT MAX(ordinal_position) FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'a', 2, '0', 'NO', 'int', null, null, 10, 0, null, null, null, 'int', '', '', 'select,insert,update,references', '', '', null)", - "SELECT * FROM _mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", ) ); } @@ -642,19 +655,19 @@ public function testAlterTableAddMultipleColumns(): void { $this->assertExecutedInformationSchemaQueries( array( - "SELECT COLUMN_NAME FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", - "SELECT MAX(ordinal_position) FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + "SELECT COLUMN_NAME FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT MAX(ordinal_position) FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'a', 2, null, 'YES', 'int', null, null, 10, 0, null, null, null, 'int', '', '', 'select,insert,update,references', '', '', null)", - "SELECT MAX(ordinal_position) FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + "SELECT MAX(ordinal_position) FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'b', 3, null, 'YES', 'text', 65535, 65535, null, null, null, 'utf8mb4', 'utf8mb4_general_ci', 'text', '', '', 'select,insert,update,references', '', '', null)", - "SELECT MAX(ordinal_position) FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + "SELECT MAX(ordinal_position) FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'c', 4, null, 'YES', 'tinyint', null, null, 3, 0, null, null, null, 'tinyint(1)', '', '', 'select,insert,update,references', '', '', null)", - "SELECT * FROM _mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", ) ); } @@ -677,13 +690,13 @@ public function testAlterTableDropColumn(): void { $this->assertExecutedInformationSchemaQueries( array( - "SELECT COLUMN_NAME FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", - "DELETE FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't' AND column_name = 'a'", - "DELETE FROM _mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't' AND column_name = 'a'", - "WITH s AS ( SELECT column_name, CASE WHEN MAX(index_name = 'PRIMARY') THEN 'PRI' WHEN MAX(non_unique = 0 AND seq_in_index = 1) THEN 'UNI' WHEN MAX(seq_in_index = 1) THEN 'MUL' ELSE '' END AS column_key FROM _mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't' GROUP BY column_name ) UPDATE _mysql_information_schema_columns AS c SET column_key = s.column_key, is_nullable = IIF(s.column_key = 'PRI', 'NO', c.is_nullable) FROM s WHERE c.table_schema = 'wp' AND c.table_name = 't' AND s.column_name = c.column_name", - "SELECT * FROM _mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT COLUMN_NAME FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", + "DELETE FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't' AND column_name = 'a'", + "DELETE FROM _wp_sqlite_mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't' AND column_name = 'a'", + "WITH s AS ( SELECT column_name, CASE WHEN MAX(index_name = 'PRIMARY') THEN 'PRI' WHEN MAX(non_unique = 0 AND seq_in_index = 1) THEN 'UNI' WHEN MAX(seq_in_index = 1) THEN 'MUL' ELSE '' END AS column_key FROM _wp_sqlite_mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't' GROUP BY column_name ) UPDATE _wp_sqlite_mysql_information_schema_columns AS c SET column_key = s.column_key, is_nullable = IIF(s.column_key = 'PRI', 'NO', c.is_nullable) FROM s WHERE c.table_schema = 'wp' AND c.table_name = 't' AND s.column_name = c.column_name", + "SELECT * FROM _wp_sqlite_mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", ) ); } @@ -705,16 +718,16 @@ public function testAlterTableDropMultipleColumns(): void { $this->assertExecutedInformationSchemaQueries( array( - "SELECT COLUMN_NAME FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", - "DELETE FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't' AND column_name = 'a'", - "DELETE FROM _mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't' AND column_name = 'a'", - "WITH s AS ( SELECT column_name, CASE WHEN MAX(index_name = 'PRIMARY') THEN 'PRI' WHEN MAX(non_unique = 0 AND seq_in_index = 1) THEN 'UNI' WHEN MAX(seq_in_index = 1) THEN 'MUL' ELSE '' END AS column_key FROM _mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't' GROUP BY column_name ) UPDATE _mysql_information_schema_columns AS c SET column_key = s.column_key, is_nullable = IIF(s.column_key = 'PRI', 'NO', c.is_nullable) FROM s WHERE c.table_schema = 'wp' AND c.table_name = 't' AND s.column_name = c.column_name", - "DELETE FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't' AND column_name = 'b'", - "DELETE FROM _mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't' AND column_name = 'b'", - "WITH s AS ( SELECT column_name, CASE WHEN MAX(index_name = 'PRIMARY') THEN 'PRI' WHEN MAX(non_unique = 0 AND seq_in_index = 1) THEN 'UNI' WHEN MAX(seq_in_index = 1) THEN 'MUL' ELSE '' END AS column_key FROM _mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't' GROUP BY column_name ) UPDATE _mysql_information_schema_columns AS c SET column_key = s.column_key, is_nullable = IIF(s.column_key = 'PRI', 'NO', c.is_nullable) FROM s WHERE c.table_schema = 'wp' AND c.table_name = 't' AND s.column_name = c.column_name", - "SELECT * FROM _mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT COLUMN_NAME FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", + "DELETE FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't' AND column_name = 'a'", + "DELETE FROM _wp_sqlite_mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't' AND column_name = 'a'", + "WITH s AS ( SELECT column_name, CASE WHEN MAX(index_name = 'PRIMARY') THEN 'PRI' WHEN MAX(non_unique = 0 AND seq_in_index = 1) THEN 'UNI' WHEN MAX(seq_in_index = 1) THEN 'MUL' ELSE '' END AS column_key FROM _wp_sqlite_mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't' GROUP BY column_name ) UPDATE _wp_sqlite_mysql_information_schema_columns AS c SET column_key = s.column_key, is_nullable = IIF(s.column_key = 'PRI', 'NO', c.is_nullable) FROM s WHERE c.table_schema = 'wp' AND c.table_name = 't' AND s.column_name = c.column_name", + "DELETE FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't' AND column_name = 'b'", + "DELETE FROM _wp_sqlite_mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't' AND column_name = 'b'", + "WITH s AS ( SELECT column_name, CASE WHEN MAX(index_name = 'PRIMARY') THEN 'PRI' WHEN MAX(non_unique = 0 AND seq_in_index = 1) THEN 'UNI' WHEN MAX(seq_in_index = 1) THEN 'MUL' ELSE '' END AS column_key FROM _wp_sqlite_mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't' GROUP BY column_name ) UPDATE _wp_sqlite_mysql_information_schema_columns AS c SET column_key = s.column_key, is_nullable = IIF(s.column_key = 'PRI', 'NO', c.is_nullable) FROM s WHERE c.table_schema = 'wp' AND c.table_name = 't' AND s.column_name = c.column_name", + "SELECT * FROM _wp_sqlite_mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", ) ); } @@ -737,16 +750,16 @@ public function testAlterTableAddAndDropColumns(): void { $this->assertExecutedInformationSchemaQueries( array( - "SELECT COLUMN_NAME FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", - "SELECT MAX(ordinal_position) FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + "SELECT COLUMN_NAME FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT MAX(ordinal_position) FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'b', 2, null, 'YES', 'int', null, null, 10, 0, null, null, null, 'int', '', '', 'select,insert,update,references', '', '', null)", - "DELETE FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't' AND column_name = 'a'", - "DELETE FROM _mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't' AND column_name = 'a'", - "WITH s AS ( SELECT column_name, CASE WHEN MAX(index_name = 'PRIMARY') THEN 'PRI' WHEN MAX(non_unique = 0 AND seq_in_index = 1) THEN 'UNI' WHEN MAX(seq_in_index = 1) THEN 'MUL' ELSE '' END AS column_key FROM _mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't' GROUP BY column_name ) UPDATE _mysql_information_schema_columns AS c SET column_key = s.column_key, is_nullable = IIF(s.column_key = 'PRI', 'NO', c.is_nullable) FROM s WHERE c.table_schema = 'wp' AND c.table_name = 't' AND s.column_name = c.column_name", - "SELECT * FROM _mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", + "DELETE FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't' AND column_name = 'a'", + "DELETE FROM _wp_sqlite_mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't' AND column_name = 'a'", + "WITH s AS ( SELECT column_name, CASE WHEN MAX(index_name = 'PRIMARY') THEN 'PRI' WHEN MAX(non_unique = 0 AND seq_in_index = 1) THEN 'UNI' WHEN MAX(seq_in_index = 1) THEN 'MUL' ELSE '' END AS column_key FROM _wp_sqlite_mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't' GROUP BY column_name ) UPDATE _wp_sqlite_mysql_information_schema_columns AS c SET column_key = s.column_key, is_nullable = IIF(s.column_key = 'PRI', 'NO', c.is_nullable) FROM s WHERE c.table_schema = 'wp' AND c.table_name = 't' AND s.column_name = c.column_name", + "SELECT * FROM _wp_sqlite_mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", ) ); } @@ -769,16 +782,16 @@ public function testAlterTableDropAndAddSingleColumn(): void { $this->assertExecutedInformationSchemaQueries( array( - "SELECT COLUMN_NAME FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", - "DELETE FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't' AND column_name = 'a'", - "DELETE FROM _mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't' AND column_name = 'a'", - "WITH s AS ( SELECT column_name, CASE WHEN MAX(index_name = 'PRIMARY') THEN 'PRI' WHEN MAX(non_unique = 0 AND seq_in_index = 1) THEN 'UNI' WHEN MAX(seq_in_index = 1) THEN 'MUL' ELSE '' END AS column_key FROM _mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't' GROUP BY column_name ) UPDATE _mysql_information_schema_columns AS c SET column_key = s.column_key, is_nullable = IIF(s.column_key = 'PRI', 'NO', c.is_nullable) FROM s WHERE c.table_schema = 'wp' AND c.table_name = 't' AND s.column_name = c.column_name", - "SELECT MAX(ordinal_position) FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + "SELECT COLUMN_NAME FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", + "DELETE FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't' AND column_name = 'a'", + "DELETE FROM _wp_sqlite_mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't' AND column_name = 'a'", + "WITH s AS ( SELECT column_name, CASE WHEN MAX(index_name = 'PRIMARY') THEN 'PRI' WHEN MAX(non_unique = 0 AND seq_in_index = 1) THEN 'UNI' WHEN MAX(seq_in_index = 1) THEN 'MUL' ELSE '' END AS column_key FROM _wp_sqlite_mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't' GROUP BY column_name ) UPDATE _wp_sqlite_mysql_information_schema_columns AS c SET column_key = s.column_key, is_nullable = IIF(s.column_key = 'PRI', 'NO', c.is_nullable) FROM s WHERE c.table_schema = 'wp' AND c.table_name = 't' AND s.column_name = c.column_name", + "SELECT MAX(ordinal_position) FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'a', 1, null, 'YES', 'int', null, null, 10, 0, null, null, null, 'int', '', '', 'select,insert,update,references', '', '', null)", - "SELECT * FROM _mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", ) ); } @@ -791,15 +804,15 @@ public function testBitDataTypes(): void { $this->assertExecutedInformationSchemaQueries( array( - 'INSERT INTO _mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' - . " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'DYNAMIC', 'utf8mb4_general_ci')", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' + . " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'Dynamic', 'utf8mb4_general_ci')", + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'i1', 1, null, 'YES', 'bit', null, null, 1, null, null, null, null, 'bit(1)', '', '', 'select,insert,update,references', '', '', null)", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'i2', 2, null, 'YES', 'bit', null, null, 10, null, null, null, null, 'bit(10)', '', '', 'select,insert,update,references', '', '', null)", - "SELECT * FROM _mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", ) ); } @@ -812,15 +825,15 @@ public function testBooleanDataTypes(): void { $this->assertExecutedInformationSchemaQueries( array( - 'INSERT INTO _mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' - . " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'DYNAMIC', 'utf8mb4_general_ci')", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' + . " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'Dynamic', 'utf8mb4_general_ci')", + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'i1', 1, null, 'YES', 'tinyint', null, null, 3, 0, null, null, null, 'tinyint(1)', '', '', 'select,insert,update,references', '', '', null)", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'i2', 2, null, 'YES', 'tinyint', null, null, 3, 0, null, null, null, 'tinyint(1)', '', '', 'select,insert,update,references', '', '', null)", - "SELECT * FROM _mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", ) ); } @@ -833,23 +846,23 @@ public function testIntegerDataTypes(): void { $this->assertExecutedInformationSchemaQueries( array( - 'INSERT INTO _mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' - . " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'DYNAMIC', 'utf8mb4_general_ci')", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' + . " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'Dynamic', 'utf8mb4_general_ci')", + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'i1', 1, null, 'YES', 'tinyint', null, null, 3, 0, null, null, null, 'tinyint', '', '', 'select,insert,update,references', '', '', null)", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'i2', 2, null, 'YES', 'smallint', null, null, 5, 0, null, null, null, 'smallint', '', '', 'select,insert,update,references', '', '', null)", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'i3', 3, null, 'YES', 'mediumint', null, null, 7, 0, null, null, null, 'mediumint', '', '', 'select,insert,update,references', '', '', null)", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'i4', 4, null, 'YES', 'int', null, null, 10, 0, null, null, null, 'int', '', '', 'select,insert,update,references', '', '', null)", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'i5', 5, null, 'YES', 'int', null, null, 10, 0, null, null, null, 'int', '', '', 'select,insert,update,references', '', '', null)", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'i6', 6, null, 'YES', 'bigint', null, null, 19, 0, null, null, null, 'bigint', '', '', 'select,insert,update,references', '', '', null)", - "SELECT * FROM _mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", ) ); } @@ -862,19 +875,19 @@ public function testFloatDataTypes(): void { $this->assertExecutedInformationSchemaQueries( array( - 'INSERT INTO _mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' - . " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'DYNAMIC', 'utf8mb4_general_ci')", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' + . " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'Dynamic', 'utf8mb4_general_ci')", + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'f1', 1, null, 'YES', 'float', null, null, 12, null, null, null, null, 'float', '', '', 'select,insert,update,references', '', '', null)", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'f2', 2, null, 'YES', 'double', null, null, 22, null, null, null, null, 'double', '', '', 'select,insert,update,references', '', '', null)", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'f3', 3, null, 'YES', 'double', null, null, 22, null, null, null, null, 'double', '', '', 'select,insert,update,references', '', '', null)", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'f4', 4, null, 'YES', 'double', null, null, 22, null, null, null, null, 'double', '', '', 'select,insert,update,references', '', '', null)", - "SELECT * FROM _mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", ) ); } @@ -887,19 +900,19 @@ public function testDecimalTypes(): void { $this->assertExecutedInformationSchemaQueries( array( - 'INSERT INTO _mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' - . " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'DYNAMIC', 'utf8mb4_general_ci')", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' + . " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'Dynamic', 'utf8mb4_general_ci')", + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'f1', 1, null, 'YES', 'decimal', null, null, 10, 0, null, null, null, 'decimal(10,0)', '', '', 'select,insert,update,references', '', '', null)", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'f2', 2, null, 'YES', 'decimal', null, null, 10, 0, null, null, null, 'decimal(10,0)', '', '', 'select,insert,update,references', '', '', null)", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'f3', 3, null, 'YES', 'decimal', null, null, 10, 0, null, null, null, 'decimal(10,0)', '', '', 'select,insert,update,references', '', '', null)", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'f4', 4, null, 'YES', 'decimal', null, null, 10, 0, null, null, null, 'decimal(10,0)', '', '', 'select,insert,update,references', '', '', null)", - "SELECT * FROM _mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", ) ); } @@ -912,15 +925,15 @@ public function testCharDataTypes(): void { $this->assertExecutedInformationSchemaQueries( array( - 'INSERT INTO _mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' - . " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'DYNAMIC', 'utf8mb4_general_ci')", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' + . " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'Dynamic', 'utf8mb4_general_ci')", + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'c1', 1, null, 'YES', 'char', 1, 4, null, null, null, 'utf8mb4', 'utf8mb4_general_ci', 'char(1)', '', '', 'select,insert,update,references', '', '', null)", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'c2', 2, null, 'YES', 'char', 10, 40, null, null, null, 'utf8mb4', 'utf8mb4_general_ci', 'char(10)', '', '', 'select,insert,update,references', '', '', null)", - "SELECT * FROM _mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", ) ); } @@ -933,17 +946,17 @@ public function testVarcharDataTypes(): void { $this->assertExecutedInformationSchemaQueries( array( - 'INSERT INTO _mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' - . " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'DYNAMIC', 'utf8mb4_general_ci')", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' + . " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'Dynamic', 'utf8mb4_general_ci')", + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'c1', 1, null, 'YES', 'varchar', 255, 1020, null, null, null, 'utf8mb4', 'utf8mb4_general_ci', 'varchar(255)', '', '', 'select,insert,update,references', '', '', null)", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'c2', 2, null, 'YES', 'varchar', 255, 1020, null, null, null, 'utf8mb4', 'utf8mb4_general_ci', 'varchar(255)', '', '', 'select,insert,update,references', '', '', null)", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'c3', 3, null, 'YES', 'varchar', 255, 1020, null, null, null, 'utf8mb4', 'utf8mb4_general_ci', 'varchar(255)', '', '', 'select,insert,update,references', '', '', null)", - "SELECT * FROM _mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", ) ); } @@ -956,19 +969,19 @@ public function testNationalCharDataTypes(): void { $this->assertExecutedInformationSchemaQueries( array( - 'INSERT INTO _mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' - . " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'DYNAMIC', 'utf8mb4_general_ci')", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' + . " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'Dynamic', 'utf8mb4_general_ci')", + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'c1', 1, null, 'YES', 'char', 1, 3, null, null, null, 'utf8', 'utf8_general_ci', 'char(1)', '', '', 'select,insert,update,references', '', '', null)", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'c2', 2, null, 'YES', 'char', 1, 3, null, null, null, 'utf8', 'utf8_general_ci', 'char(1)', '', '', 'select,insert,update,references', '', '', null)", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'c3', 3, null, 'YES', 'char', 10, 30, null, null, null, 'utf8', 'utf8_general_ci', 'char(10)', '', '', 'select,insert,update,references', '', '', null)", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'c4', 4, null, 'YES', 'char', 10, 30, null, null, null, 'utf8', 'utf8_general_ci', 'char(10)', '', '', 'select,insert,update,references', '', '', null)", - "SELECT * FROM _mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", ) ); } @@ -981,17 +994,17 @@ public function testNcharVarcharDataTypes(): void { $this->assertExecutedInformationSchemaQueries( array( - 'INSERT INTO _mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' - . " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'DYNAMIC', 'utf8mb4_general_ci')", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' + . " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'Dynamic', 'utf8mb4_general_ci')", + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'c1', 1, null, 'YES', 'varchar', 255, 765, null, null, null, 'utf8', 'utf8_general_ci', 'varchar(255)', '', '', 'select,insert,update,references', '', '', null)", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'c2', 2, null, 'YES', 'varchar', 255, 765, null, null, null, 'utf8', 'utf8_general_ci', 'varchar(255)', '', '', 'select,insert,update,references', '', '', null)", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'c3', 3, null, 'YES', 'varchar', 255, 765, null, null, null, 'utf8', 'utf8_general_ci', 'varchar(255)', '', '', 'select,insert,update,references', '', '', null)", - "SELECT * FROM _mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", ) ); } @@ -1004,17 +1017,17 @@ public function testNationalVarcharDataTypes(): void { $this->assertExecutedInformationSchemaQueries( array( - 'INSERT INTO _mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' - . " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'DYNAMIC', 'utf8mb4_general_ci')", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' + . " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'Dynamic', 'utf8mb4_general_ci')", + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'c1', 1, null, 'YES', 'varchar', 255, 765, null, null, null, 'utf8', 'utf8_general_ci', 'varchar(255)', '', '', 'select,insert,update,references', '', '', null)", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'c2', 2, null, 'YES', 'varchar', 255, 765, null, null, null, 'utf8', 'utf8_general_ci', 'varchar(255)', '', '', 'select,insert,update,references', '', '', null)", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'c3', 3, null, 'YES', 'varchar', 255, 765, null, null, null, 'utf8', 'utf8_general_ci', 'varchar(255)', '', '', 'select,insert,update,references', '', '', null)", - "SELECT * FROM _mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", ) ); } @@ -1027,19 +1040,19 @@ public function testTextDataTypes(): void { $this->assertExecutedInformationSchemaQueries( array( - 'INSERT INTO _mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' - . " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'DYNAMIC', 'utf8mb4_general_ci')", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' + . " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'Dynamic', 'utf8mb4_general_ci')", + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 't1', 1, null, 'YES', 'tinytext', 255, 255, null, null, null, 'utf8mb4', 'utf8mb4_general_ci', 'tinytext', '', '', 'select,insert,update,references', '', '', null)", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 't2', 2, null, 'YES', 'text', 65535, 65535, null, null, null, 'utf8mb4', 'utf8mb4_general_ci', 'text', '', '', 'select,insert,update,references', '', '', null)", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 't3', 3, null, 'YES', 'mediumtext', 16777215, 16777215, null, null, null, 'utf8mb4', 'utf8mb4_general_ci', 'mediumtext', '', '', 'select,insert,update,references', '', '', null)", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 't4', 4, null, 'YES', 'longtext', 4294967295, 4294967295, null, null, null, 'utf8mb4', 'utf8mb4_general_ci', 'longtext', '', '', 'select,insert,update,references', '', '', null)", - "SELECT * FROM _mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", ) ); } @@ -1052,13 +1065,13 @@ public function testEnumDataTypes(): void { $this->assertExecutedInformationSchemaQueries( array( - 'INSERT INTO _mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' - . " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'DYNAMIC', 'utf8mb4_general_ci')", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' + . " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'Dynamic', 'utf8mb4_general_ci')", + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'e', 1, null, 'YES', 'enum', 1, 4, null, null, null, 'utf8mb4', 'utf8mb4_general_ci', 'enum(''a'',''b'',''c'')', '', '', 'select,insert,update,references', '', '', null)", - "SELECT * FROM _mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", ) ); } @@ -1071,21 +1084,21 @@ public function testDateAndTimeDataTypes(): void { $this->assertExecutedInformationSchemaQueries( array( - 'INSERT INTO _mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' - . " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'DYNAMIC', 'utf8mb4_general_ci')", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' + . " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'Dynamic', 'utf8mb4_general_ci')", + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'd', 1, null, 'YES', 'date', null, null, null, null, null, null, null, 'date', '', '', 'select,insert,update,references', '', '', null)", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 't', 2, null, 'YES', 'time', null, null, null, null, 0, null, null, 'time', '', '', 'select,insert,update,references', '', '', null)", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'dt', 3, null, 'YES', 'datetime', null, null, null, null, 0, null, null, 'datetime', '', '', 'select,insert,update,references', '', '', null)", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'ts', 4, null, 'YES', 'timestamp', null, null, null, null, 0, null, null, 'timestamp', '', '', 'select,insert,update,references', '', '', null)", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'y', 5, null, 'YES', 'year', null, null, null, null, null, null, null, 'year', '', '', 'select,insert,update,references', '', '', null)", - "SELECT * FROM _mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", ) ); } @@ -1098,15 +1111,15 @@ public function testBinaryDataTypes(): void { $this->assertExecutedInformationSchemaQueries( array( - 'INSERT INTO _mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' - . " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'DYNAMIC', 'utf8mb4_general_ci')", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' + . " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'Dynamic', 'utf8mb4_general_ci')", + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'b', 1, null, 'YES', 'binary', 1, 1, null, null, null, null, null, 'binary(1)', '', '', 'select,insert,update,references', '', '', null)", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'v', 2, null, 'YES', 'varbinary', 255, 255, null, null, null, null, null, 'varbinary(255)', '', '', 'select,insert,update,references', '', '', null)", - "SELECT * FROM _mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", ) ); } @@ -1119,19 +1132,19 @@ public function testBlobDataTypes(): void { $this->assertExecutedInformationSchemaQueries( array( - 'INSERT INTO _mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' - . " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'DYNAMIC', 'utf8mb4_general_ci')", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' + . " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'Dynamic', 'utf8mb4_general_ci')", + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'b1', 1, null, 'YES', 'tinyblob', 255, 255, null, null, null, null, null, 'tinyblob', '', '', 'select,insert,update,references', '', '', null)", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'b2', 2, null, 'YES', 'blob', 65535, 65535, null, null, null, null, null, 'blob', '', '', 'select,insert,update,references', '', '', null)", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'b3', 3, null, 'YES', 'mediumblob', 16777215, 16777215, null, null, null, null, null, 'mediumblob', '', '', 'select,insert,update,references', '', '', null)", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'b4', 4, null, 'YES', 'longblob', 4294967295, 4294967295, null, null, null, null, null, 'longblob', '', '', 'select,insert,update,references', '', '', null)", - "SELECT * FROM _mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", ) ); } @@ -1144,19 +1157,19 @@ public function testBasicSpatialDataTypes(): void { $this->assertExecutedInformationSchemaQueries( array( - 'INSERT INTO _mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' - . " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'DYNAMIC', 'utf8mb4_general_ci')", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' + . " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'Dynamic', 'utf8mb4_general_ci')", + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'g1', 1, null, 'YES', 'geometry', null, null, null, null, null, null, null, 'geometry', '', '', 'select,insert,update,references', '', '', null)", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'g2', 2, null, 'YES', 'point', null, null, null, null, null, null, null, 'point', '', '', 'select,insert,update,references', '', '', null)", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'g3', 3, null, 'YES', 'linestring', null, null, null, null, null, null, null, 'linestring', '', '', 'select,insert,update,references', '', '', null)", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'g4', 4, null, 'YES', 'polygon', null, null, null, null, null, null, null, 'polygon', '', '', 'select,insert,update,references', '', '', null)", - "SELECT * FROM _mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", ) ); } @@ -1169,17 +1182,17 @@ public function testMultiObjectSpatialDataTypes(): void { $this->assertExecutedInformationSchemaQueries( array( - 'INSERT INTO _mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' - . " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'DYNAMIC', 'utf8mb4_general_ci')", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' + . " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'Dynamic', 'utf8mb4_general_ci')", + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'g1', 1, null, 'YES', 'multipoint', null, null, null, null, null, null, null, 'multipoint', '', '', 'select,insert,update,references', '', '', null)", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'g2', 2, null, 'YES', 'multilinestring', null, null, null, null, null, null, null, 'multilinestring', '', '', 'select,insert,update,references', '', '', null)", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'g3', 3, null, 'YES', 'multipolygon', null, null, null, null, null, null, null, 'multipolygon', '', '', 'select,insert,update,references', '', '', null)", - "SELECT * FROM _mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", ) ); } @@ -1192,15 +1205,15 @@ public function testGeometryCollectionDataTypes(): void { $this->assertExecutedInformationSchemaQueries( array( - 'INSERT INTO _mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' - . " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'DYNAMIC', 'utf8mb4_general_ci')", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' + . " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'Dynamic', 'utf8mb4_general_ci')", + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'g1', 1, null, 'YES', 'geomcollection', null, null, null, null, null, null, null, 'geomcollection', '', '', 'select,insert,update,references', '', '', null)", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'g2', 2, null, 'YES', 'geomcollection', null, null, null, null, null, null, null, 'geomcollection', '', '', 'select,insert,update,references', '', '', null)", - "SELECT * FROM _mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", ) ); } @@ -1213,13 +1226,13 @@ public function testSerialDataTypes(): void { $this->assertExecutedInformationSchemaQueries( array( - 'INSERT INTO _mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' - . " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'DYNAMIC', 'utf8mb4_general_ci')", - 'INSERT INTO _mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' + 'INSERT INTO _wp_sqlite_mysql_information_schema_tables (table_schema, table_name, table_type, engine, row_format, table_collation)' + . " VALUES ('wp', 't', 'BASE TABLE', 'InnoDB', 'Dynamic', 'utf8mb4_general_ci')", + 'INSERT INTO _wp_sqlite_mysql_information_schema_columns (table_schema, table_name, column_name, ordinal_position, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra, privileges, column_comment, generation_expression, srs_id)' . " VALUES ('wp', 't', 'id', 1, null, 'NO', 'bigint', null, null, 20, 0, null, null, null, 'bigint unsigned', 'PRI', 'auto_increment', 'select,insert,update,references', '', '', null)", - "SELECT * FROM _mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", - "SELECT * FROM _mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_tables WHERE table_type = 'BASE TABLE' AND table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_columns WHERE table_schema = 'wp' AND table_name = 't'", + "SELECT * FROM _wp_sqlite_mysql_information_schema_statistics WHERE table_schema = 'wp' AND table_name = 't'", ) ); } @@ -1248,6 +1261,68 @@ public function testConcatFunction(): void { ); } + public function testIndexHints(): void { + // USE INDEX + $this->assertQuery( + 'SELECT * FROM `t`', + 'SELECT * FROM t USE INDEX (i)' + ); + + // USE KEY + $this->assertQuery( + 'SELECT * FROM `t`', + 'SELECT * FROM t USE KEY (k)' + ); + + // FORCE INDEX + $this->assertQuery( + 'SELECT * FROM `t`', + 'SELECT * FROM t FORCE INDEX (i)' + ); + + // FORCE KEY + $this->assertQuery( + 'SELECT * FROM `t`', + 'SELECT * FROM t FORCE KEY (k)' + ); + + // IGNORE INDEX + $this->assertQuery( + 'SELECT * FROM `t`', + 'SELECT * FROM t IGNORE INDEX (i)' + ); + + // IGNORE KEY + $this->assertQuery( + 'SELECT * FROM `t`', + 'SELECT * FROM t IGNORE KEY (k)' + ); + + // FOR JOIN + $this->assertQuery( + 'SELECT * FROM `t` JOIN `j` ON `t`.`id` = `j`.`t_id`', + 'SELECT * FROM t USE INDEX FOR JOIN (i) JOIN j ON t.id = j.t_id' + ); + + // FOR ORDER BY + $this->assertQuery( + 'SELECT * FROM `t` ORDER BY `id` DESC', + 'SELECT * FROM t USE INDEX FOR ORDER BY (i) ORDER BY id DESC' + ); + + // FOR GROUP BY + $this->assertQuery( + 'SELECT * FROM `t` GROUP BY `id` HAVING `id` = 1', + 'SELECT * FROM t USE INDEX FOR GROUP BY (i) GROUP BY id HAVING id = 1' + ); + + // A complex query with multiple hints and conditions. + $this->assertQuery( + 'SELECT * FROM `t` JOIN `j` ON `t`.`id` = `j`.`t_id` WHERE `id` = 1 GROUP BY `id` HAVING `id` = 1 ORDER BY `id` DESC', + 'SELECT * FROM `t` USE INDEX (i) USE INDEX FOR JOIN (j) USE KEY FOR ORDER BY (o) IGNORE INDEX FOR GROUP BY (g) JOIN j ON t.id = j.t_id WHERE id = 1 GROUP BY id HAVING id = 1 ORDER BY id DESC' + ); + } + private function assertQuery( $expected, string $query ): void { $error = null; try { @@ -1277,7 +1352,7 @@ private function assertQuery( $expected, string $query ): void { array_filter( $executed_queries, function ( $query ) { - return ! str_contains( $query, '_mysql_information_schema_' ); + return ! str_contains( $query, '_wp_sqlite_mysql_information_schema_' ); } ) ); @@ -1310,7 +1385,7 @@ private function assertExecutedInformationSchemaQueries( array $expected ): void // Collect and normalize "information_schema" queries. $queries = array(); foreach ( $this->driver->get_last_sqlite_queries() as $query ) { - if ( ! str_contains( $query['sql'], '_mysql_information_schema_' ) ) { + if ( ! str_contains( $query['sql'], '_wp_sqlite_mysql_information_schema_' ) ) { continue; } diff --git a/wp-includes/mysql/mysql-grammar.php b/wp-includes/mysql/mysql-grammar.php index c6cf391..80f1b6c 100644 --- a/wp-includes/mysql/mysql-grammar.php +++ b/wp-includes/mysql/mysql-grammar.php @@ -1,4 +1,4 @@ 2000,'rules_names'=>['query','%f1','%f2','%f3','simpleStatement','%f4','%f5','%f6','%f7','alterStatement','%f8','%f9','%f10','alterInstance','%f11','%f12','%f13','%f14','%f15','%f16','%f17','%f18','%f19','%f20','%f21','%f22','%f23','%f24','alterDatabase','%f25','%f26','%f27','%f28','%f29','%f30','%f31','%f32','%f33','%f34','alterEvent','%f35','%f36','%f37','%f38','%f39','%f40','%f41','%f42','%f43','%f44','alterLogfileGroup','%f45','alterLogfileGroupOptions','%f46','%f47','alterLogfileGroupOption','alterServer','%f48','%f49','%f50','alterTable','%f51','%f52','%f53','%f54','alterTableActions','%f55','%f56','%f57','alterCommandList','%f58','%f59','alterCommandsModifierList','%f60','standaloneAlterCommands','%f61','%f62','%f63','%f64','%f65','%f66','%f67','alterPartition','%f68','%f69','%f70','%f71','%f72','alterList','%f73','%f74','%f75','alterCommandsModifier','%f76','%f77','%f78','%f79','alterListItem','%f80','%f81','%f82','%f83','%f84','%f85','%f86','%f87','%f88','%f89','%f90','%f91','%f92','%f93','%f94','%f95','%f96','%f97','%f98','%f99','%f100','%f101','%f102','place','restrict','%f103','%f104','alterOrderList','%f105','%f106','alterAlgorithmOption','%f107','alterLockOption','%f108','%f109','%f110','indexLockAndAlgorithm','withValidation','%f111','%f112','removePartitioning','allOrPartitionNameList','alterTablespace','%f113','%f114','%f115','%f116','%f117','%f118','%f119','%f120','%f121','%f122','%f123','%f124','alterUndoTablespace','%f125','%f126','undoTableSpaceOptions','%f127','undoTableSpaceOption','%f128','alterTablespaceOptions','%f129','alterTablespaceOption','%f130','changeTablespaceOption','%f131','%f132','alterView','%f133','viewTail','%f134','viewSelect','%f135','viewCheckOption','%f136','createStatement','%f137','%f138','%f139','%f140','%f141','%f142','createDatabase','createDatabaseOption','%f143','%f144','createTable','%f145','%f146','%f147','%f148','%f149','%f150','%f151','tableElementList','%f152','tableElement','%f153','%f154','duplicateAsQueryExpression','%f155','queryExpressionOrParens','%f156','createRoutine','%f157','%f158','%f159','createProcedure','%f160','%f161','%f162','%f163','%f164','%f165','createFunction','%f166','%f167','%f168','%f169','%f170','%f171','createUdf','%f172','routineCreateOption','%f173','routineAlterOptions','routineOption','%f174','%f175','createIndex','%f176','%f177','%f178','%f179','%f180','%f181','%f182','%f183','%f184','%f185','%f186','indexNameAndType','%f187','%f188','createIndexTarget','%f189','createLogfileGroup','%f190','%f191','logfileGroupOptions','%f192','logfileGroupOption','createServer','%f193','serverOptions','%f194','serverOption','%f195','%f196','createTablespace','%f197','createUndoTablespace','tsDataFileName','%f198','%f199','%f200','tsDataFile','%f201','tablespaceOptions','%f202','tablespaceOption','%f203','%f204','%f205','tsOptionInitialSize','tsOptionUndoRedoBufferSize','%f206','tsOptionAutoextendSize','tsOptionMaxSize','tsOptionExtentSize','tsOptionNodegroup','%f207','tsOptionEngine','tsOptionEngineAttribute','tsOptionWait','%f208','tsOptionComment','tsOptionFileblockSize','tsOptionEncryption','%f209','createView','viewReplaceOrAlgorithm','viewAlgorithm','%f210','viewSuid','%f211','%f212','createTrigger','%f213','%f214','%f215','%f216','triggerFollowsPrecedesClause','%f217','%f218','%f219','%f220','%f221','createEvent','%f222','%f223','%f224','%f225','%f226','createRole','%f227','createSpatialReference','srsAttribute','dropStatement','%f228','%f229','%f230','%f231','%f232','dropDatabase','dropEvent','dropFunction','dropProcedure','dropIndex','%f233','dropLogfileGroup','%f234','%f235','%f236','dropLogfileGroupOption','dropServer','%f237','dropTable','%f238','%f239','%f240','dropTableSpace','%f241','%f242','%f243','dropTrigger','%f244','dropView','%f245','dropRole','dropSpatialReference','dropUndoTablespace','%f246','renameTableStatement','%f247','%f248','renamePair','%f249','truncateTableStatement','importStatement','%f250','callStatement','%f251','%f252','%f253','%f254','deleteStatement','%f255','%f256','%f257','%f258','%f259','%f260','%f261','%f262','%f263','%f264','%f265','partitionDelete','%f266','deleteStatementOption','doStatement','%f267','%f268','%f269','handlerStatement','%f270','%f271','%f272','%f273','handlerReadOrScan','%f274','%f275','%f276','%f277','%f278','%f279','%f280','%f281','%f282','insertStatement','%f283','%f284','%f285','%f286','%f287','%f288','%f289','insertLockOption','%f290','insertFromConstructor','%f291','%f292','%f293','fields','%f294','insertValues','%f295','insertQueryExpression','%f296','%f297','valueList','%f298','%f299','values','%f300','%f301','%f302','valuesReference','insertUpdateList','%f303','%f304','%f305','%f306','%f307','%f308','%f309','loadStatement','%f310','%f311','dataOrXml','xmlRowsIdentifiedBy','%f312','%f313','%f314','loadDataFileTail','%f315','%f316','%f317','%f318','loadDataFileTargetList','%f319','fieldOrVariableList','%f320','%f321','%f322','%f323','replaceStatement','%f324','%f325','%f326','selectStatement','selectStatementWithInto','%f327','%f328','queryExpression','%f329','%f330','%f331','%f332','%f333','%f334','queryExpressionBody','%f335','%f336','%f337','%f338','%f339','queryTerm','%f340','%f341','%f342','%f343','queryExpressionParens','queryPrimary','%f344','%f345','%f346','%f347','%f348','%f349','%f350','%f351','querySpecification','%f352','%f353','subquery','querySpecOption','limitClause','simpleLimitClause','%f354','limitOptions','%f355','%f356','limitOption','%f357','intoClause','%f358','%f359','%f360','%f361','%f362','%f363','procedureAnalyseClause','%f364','%f365','%f366','havingClause','%f367','windowClause','%f368','windowDefinition','windowSpec','%f369','%f370','%f371','%f372','%f373','windowSpecDetails','%f374','%f375','%f376','%f377','windowFrameClause','windowFrameUnits','windowFrameExtent','windowFrameStart','windowFrameBetween','windowFrameBound','windowFrameExclusion','%f378','%f379','%f380','withClause','%f381','commonTableExpression','%f382','groupByClause','olapOption','%f383','orderClause','direction','fromClause','%f384','%f385','tableReferenceList','%f386','%f387','tableValueConstructor','%f388','explicitTable','rowValueExplicit','selectOption','%f389','%f390','%f391','lockingClauseList','%f392','%f393','lockingClause','%f394','%f395','%f396','%f397','lockStrengh','%f398','lockedRowAction','%f399','selectItemList','%f400','%f401','%f402','selectItem','selectAlias','%f403','whereClause','%f404','tableReference','%f405','%f406','%f407','escapedTableReference','%f408','joinedTable','%f409','%f410','%f411','%f412','naturalJoinType','%f413','%f414','innerJoinType','%f415','outerJoinType','%f416','tableFactor','%f417','%f418','singleTable','singleTableParens','%f419','%f420','derivedTable','%f421','%f422','%f423','tableReferenceListParens','%f424','tableFunction','%f425','columnsClause','%f426','%f427','%f428','%f429','jtColumn','%f430','%f431','%f432','%f433','onEmptyOrError','onEmpty','onError','jtOnResponse','setOperationOption','%f434','tableAlias','%f435','%f436','%f437','indexHintList','%f438','%f439','indexHint','indexHintType','keyOrIndex','%f440','constraintKeyType','indexHintClause','%f441','%f442','indexList','%f443','indexListElement','%f444','%f445','updateStatement','%f446','%f447','transactionOrLockingStatement','%f448','%f449','%f450','%f451','transactionStatement','%f452','%f453','%f454','beginWork','%f455','transactionCharacteristicList','%f456','transactionCharacteristic','%f457','%f458','savepointStatement','%f459','%f460','%f461','%f462','%f463','%f464','%f465','lockStatement','%f466','%f467','%f468','%f469','%f470','lockItem','lockOption','xaStatement','%f471','%f472','%f473','%f474','%f475','%f476','%f477','%f478','%f479','%f480','xaConvert','%f481','%f482','%f483','%f484','xid','%f485','%f486','%f487','%f488','replicationStatement','%f489','%f490','%f491','%f492','%f493','%f494','%f495','%f496','%f497','%f498','%f499','resetOption','%f500','masterResetOptions','%f501','%f502','%f503','%f504','replicationLoad','%f505','changeMaster','%f506','changeMasterOptions','%f507','masterOption','privilegeCheckDef','tablePrimaryKeyCheckDef','masterTlsCiphersuitesDef','masterFileDef','%f508','serverIdList','%f509','%f510','%f511','%f512','%f513','changeReplication','%f514','%f515','%f516','%f517','changeReplicationSourceOptions','%f518','replicationSourceOption','%f519','%f520','%f521','%f522','%f523','%f524','%f525','%f526','%f527','%f528','%f529','%f530','%f531','%f532','%f533','%f534','%f535','%f536','%f537','%f538','%f539','%f540','%f541','%f542','%f543','%f544','%f545','%f546','%f547','%f548','%f549','filterDefinition','%f550','filterDbList','%f551','%f552','filterTableList','%f553','%f554','filterStringList','%f555','filterWildDbTableString','%f556','filterDbPairList','%f557','%f558','%f559','slave','%f560','%f561','slaveUntilOptions','%f562','%f563','%f564','%f565','%f566','slaveConnectionOptions','%f567','%f568','%f569','%f570','%f571','%f572','%f573','%f574','%f575','%f576','slaveThreadOptions','%f577','slaveThreadOption','groupReplication','%f578','preparedStatement','%f579','%f580','%f581','executeStatement','%f582','%f583','executeVarList','%f584','cloneStatement','%f585','%f586','%f587','%f588','%f589','%f590','%f591','dataDirSSL','ssl','accountManagementStatement','%f592','%f593','%f594','alterUser','%f595','%f596','alterUserTail','%f597','%f598','%f599','%f600','%f601','%f602','userFunction','createUser','%f603','%f604','createUserTail','%f605','%f606','%f607','%f608','%f609','%f610','%f611','%f612','defaultRoleClause','%f613','%f614','%f615','requireClause','%f616','%f617','%f618','connectOptions','%f619','accountLockPasswordExpireOptions','%f620','%f621','%f622','%f623','%f624','%f625','%f626','%f627','%f628','%f629','%f630','dropUser','%f631','%f632','grant','%f633','%f634','%f635','%f636','%f637','%f638','%f639','%f640','%f641','%f642','%f643','%f644','grantTargetList','%f645','%f646','grantOptions','%f647','%f648','%f649','exceptRoleList','withRoles','%f650','%f651','%f652','grantAs','versionedRequireClause','%f653','%f654','renameUser','%f655','%f656','%f657','revoke','%f658','%f659','%f660','%f661','%f662','%f663','%f664','%f665','%f666','%f667','%f668','onTypeTo','%f669','%f670','%f671','%f672','aclType','%f673','roleOrPrivilegesList','%f674','%f675','%f676','roleOrPrivilege','%f677','%f678','%f679','%f680','%f681','%f682','%f683','%f684','%f685','%f686','%f687','grantIdentifier','%f688','%f689','%f690','%f691','requireList','%f692','%f693','requireListElement','grantOption','%f694','setRole','%f695','%f696','%f697','%f698','roleList','%f699','%f700','role','%f701','%f702','%f703','tableAdministrationStatement','%f704','%f705','%f706','%f707','%f708','%f709','%f710','%f711','%f712','%f713','histogram','%f714','%f715','checkOption','%f716','repairType','%f717','%f718','installUninstallStatment','%f719','%f720','installOptionType','%f721','installSetValue','%f722','%f723','installSetValueList','%f724','setStatement','%f725','startOptionValueList','%f726','%f727','%f728','%f729','%f730','%f731','%f732','%f733','%f734','%f735','%f736','transactionCharacteristics','%f737','%f738','transactionAccessMode','%f739','isolationLevel','%f740','%f741','%f742','optionValueListContinued','%f743','optionValueNoOptionType','%f744','%f745','optionValue','%f746','setSystemVariable','startOptionValueListFollowingOptionType','optionValueFollowingOptionType','setExprOrDefault','%f747','%f748','%f749','showStatement','%f750','%f751','%f752','%f753','%f754','%f755','%f756','%f757','%f758','%f759','%f760','%f761','%f762','%f763','%f764','%f765','%f766','%f767','%f768','%f769','%f770','%f771','%f772','%f773','%f774','%f775','%f776','%f777','%f778','%f779','%f780','%f781','%f782','%f783','showCommandType','%f784','nonBlocking','%f785','%f786','fromOrIn','inDb','profileType','%f787','%f788','otherAdministrativeStatement','%f789','%f790','%f791','%f792','%f793','%f794','keyCacheListOrParts','%f795','keyCacheList','%f796','%f797','assignToKeycache','assignToKeycachePartition','%f798','cacheKeyList','keyUsageElement','%f799','keyUsageList','%f800','%f801','flushOption','%f802','%f803','%f804','logType','%f805','flushTables','%f806','%f807','%f808','flushTablesOptions','%f809','%f810','preloadTail','%f811','%f812','preloadList','%f813','%f814','preloadKeys','%f815','adminPartition','resourceGroupManagement','%f816','%f817','%f818','createResourceGroup','%f819','%f820','resourceGroupVcpuList','%f821','%f822','vcpuNumOrRange','%f823','resourceGroupPriority','resourceGroupEnableDisable','%f824','alterResourceGroup','%f825','setResourceGroup','%f826','%f827','threadIdList','%f828','dropResourceGroup','utilityStatement','%f829','%f830','describeStatement','%f831','%f832','%f833','explainStatement','%f834','%f835','%f836','%f837','%f838','%f839','%f840','explainableStatement','%f841','%f842','%f843','helpCommand','useCommand','restartServer','%f844','expr','%f845','%f846','%f847','%f848','%f849','%f850','%f851','%f852','%f853','%f854','boolPri','%f855','%f856','compOp','%f857','predicate','%f858','%f859','%f860','%f861','predicateOperations','%f862','%f863','%f864','bitExpr','%f865','%f866','%f867','%f868','%f869','%f870','simpleExpr','%f871','%f872','%f873','%f874','%f875','%f876','%f877','%f878','%f879','%f880','%f881','%f882','%f883','%f884','%f885','%f886','%f887','%f888','%f889','%f890','%f891','%f892','arrayCast','%f893','jsonOperator','%f894','%f895','%f896','%f897','%f898','%f899','%f900','%f901','%f902','%f903','%f904','%f905','%f906','%f907','%f908','%f909','sumExpr','%f910','%f911','%f912','%f913','%f914','%f915','%f916','%f917','%f918','%f919','%f920','%f921','%f922','%f923','%f924','%f925','%f926','%f927','%f928','%f929','%f930','%f931','%f932','%f933','%f934','%f935','%f936','%f937','groupingOperation','%f938','%f939','%f940','windowFunctionCall','%f941','%f942','%f943','%f944','%f945','windowingClause','%f946','%f947','leadLagInfo','%f948','%f949','nullTreatment','%f950','%f951','jsonFunction','inSumExpr','identListArg','%f952','identList','%f953','%f954','fulltextOptions','%f955','%f956','%f957','%f958','%f959','%f960','%f961','%f962','runtimeFunctionCall','%f963','%f964','%f965','%f966','%f967','%f968','%f969','%f970','%f971','%f972','%f973','%f974','%f975','%f976','%f977','%f978','%f979','%f980','%f981','%f982','geometryFunction','%f983','%f984','timeFunctionParameters','fractionalPrecision','%f985','weightStringLevels','%f986','%f987','%f988','%f989','weightStringLevelListItem','%f990','%f991','%f992','dateTimeTtype','trimFunction','%f993','%f994','%f995','substringFunction','%f996','%f997','%f998','%f999','%f1000','%f1001','functionCall','%f1002','udfExprList','%f1003','udfExpr','variable','userVariable','%f1004','%f1005','systemVariable','internalVariableName','%f1006','%f1007','%f1008','whenExpression','thenExpression','elseExpression','%f1009','%f1010','%f1011','%f1012','castType','%f1013','%f1014','%f1015','%f1016','%f1017','exprList','%f1018','charset','notRule','not2Rule','interval','%f1019','intervalTimeStamp','exprListWithParentheses','exprWithParentheses','simpleExprWithParentheses','%f1020','orderList','%f1021','orderExpression','%f1022','groupList','%f1023','groupingExpression','channel','%f1024','compoundStatement','returnStatement','ifStatement','%f1025','ifBody','%f1026','thenStatement','%f1027','compoundStatementList','%f1028','%f1029','%f1030','caseStatement','%f1031','elseStatement','%f1032','labeledBlock','unlabeledBlock','label','%f1033','%f1034','beginEndBlock','labeledControl','unlabeledControl','loopBlock','whileDoBlock','repeatUntilBlock','%f1035','spDeclarations','%f1036','spDeclaration','%f1037','variableDeclaration','%f1038','conditionDeclaration','spCondition','%f1039','sqlstate','%f1040','handlerDeclaration','%f1041','%f1042','handlerCondition','cursorDeclaration','iterateStatement','leaveStatement','%f1043','getDiagnostics','%f1044','%f1045','%f1046','%f1047','%f1048','%f1049','%f1050','signalAllowedExpr','statementInformationItem','%f1051','%f1052','conditionInformationItem','%f1053','%f1054','signalInformationItemName','%f1055','signalStatement','%f1056','%f1057','%f1058','%f1059','%f1060','%f1061','resignalStatement','%f1062','%f1063','%f1064','%f1065','signalInformationItem','cursorOpen','cursorClose','%f1066','cursorFetch','%f1067','%f1068','%f1069','%f1070','schedule','%f1071','%f1072','columnDefinition','checkOrReferences','%f1073','checkConstraint','constraintEnforcement','%f1074','tableConstraintDef','%f1075','%f1076','%f1077','%f1078','%f1079','%f1080','%f1081','constraintName','fieldDefinition','%f1082','%f1083','%f1084','%f1085','%f1086','%f1087','%f1088','%f1089','%f1090','%f1091','%f1092','%f1093','%f1094','columnAttribute','%f1095','%f1096','%f1097','%f1098','%f1099','%f1100','%f1101','columnFormat','storageMedia','gcolAttribute','%f1102','%f1103','%f1104','references','%f1105','%f1106','%f1107','%f1108','%f1109','%f1110','%f1111','deleteOption','%f1112','%f1113','keyList','%f1114','keyPart','%f1115','keyListWithExpression','%f1116','keyPartOrExpression','keyListVariants','%f1117','%f1118','indexType','%f1119','indexOption','commonIndexOption','%f1120','visibility','indexTypeClause','%f1121','fulltextIndexOption','spatialIndexOption','dataTypeDefinition','%f1122','%f1123','%f1124','%f1125','dataType','%f1126','%f1127','%f1128','%f1129','%f1130','%f1131','%f1132','%f1133','%f1134','%f1135','%f1136','nchar','realType','fieldLength','%f1137','%f1138','fieldOptions','%f1139','%f1140','charsetWithOptBinary','%f1141','ascii','unicode','wsNumCodepoints','typeDatetimePrecision','charsetName','%f1142','collationName','%f1143','%f1144','%f1145','createTableOptions','%f1146','%f1147','createTableOptionsSpaceSeparated','%f1148','createTableOption','%f1149','%f1150','%f1151','%f1152','%f1153','%f1154','%f1155','%f1156','%f1157','%f1158','%f1159','%f1160','%f1161','%f1162','%f1163','ternaryOption','%f1164','defaultCollation','defaultEncryption','defaultCharset','%f1165','%f1166','%f1167','partitionClause','%f1168','%f1169','%f1170','%f1171','partitionTypeDef','%f1172','%f1173','%f1174','subPartitions','%f1175','%f1176','partitionKeyAlgorithm','%f1177','%f1178','partitionDefinitions','%f1179','%f1180','%f1181','%f1182','partitionDefinition','%f1183','%f1184','%f1185','%f1186','%f1187','%f1188','partitionValuesIn','%f1189','partitionOption','%f1190','%f1191','subpartitionDefinition','%f1192','partitionValueItemListParen','%f1193','partitionValueItem','definerClause','ifExists','ifNotExists','%f1194','procedureParameter','%f1195','functionParameter','collate','typeWithOptCollate','schemaIdentifierPair','%f1196','viewRefList','%f1197','%f1198','updateList','%f1199','updateElement','%f1200','charsetClause','%f1201','fieldsClause','%f1202','fieldTerm','%f1203','linesClause','lineTerm','%f1204','%f1205','userList','%f1206','%f1207','createUserList','%f1208','%f1209','alterUserList','%f1210','%f1211','createUserEntry','%f1212','%f1213','%f1214','%f1215','%f1216','%f1217','%f1218','%f1219','%f1220','%f1221','%f1222','alterUserEntry','%f1223','%f1224','%f1225','%f1226','%f1227','%f1228','%f1229','%f1230','%f1231','%f1232','%f1233','retainCurrentPassword','discardOldPassword','replacePassword','%f1234','userIdentifierOrText','%f1235','%f1236','user','likeClause','likeOrWhere','onlineOption','noWriteToBinLog','usePartition','%f1237','fieldIdentifier','columnName','%f1238','%f1239','columnInternalRef','%f1240','columnInternalRefList','%f1241','columnRef','insertIdentifier','indexName','indexRef','%f1242','tableWild','%f1243','schemaName','schemaRef','procedureName','procedureRef','functionName','functionRef','triggerName','triggerRef','viewName','viewRef','tablespaceName','tablespaceRef','logfileGroupName','logfileGroupRef','eventName','eventRef','udfName','serverName','serverRef','engineRef','tableName','filterTableRef','%f1244','tableRefWithWildcard','%f1245','%f1246','%f1247','tableRef','%f1248','tableRefList','%f1249','%f1250','tableAliasRefList','%f1251','parameterName','labelIdentifier','labelRef','roleIdentifier','roleRef','pluginRef','componentRef','resourceGroupRef','windowName','pureIdentifier','%f1252','%f1253','identifier','%f1254','identifierList','%f1255','identifierListWithParentheses','qualifiedIdentifier','%f1256','simpleIdentifier','%f1257','%f1258','dotIdentifier','ulong_number','real_ulong_number','ulonglong_number','real_ulonglong_number','%f1259','%f1260','literal','%f1261','signedLiteral','%f1262','stringList','%f1263','textStringLiteral','%f1264','textString','textStringHash','%f1265','%f1266','textLiteral','%f1267','textStringNoLinebreak','%f1268','textStringLiteralList','%f1269','numLiteral','boolLiteral','nullLiteral','temporalLiteral','floatOptions','standardFloatOptions','precision','textOrIdentifier','lValueIdentifier','roleIdentifierOrText','sizeNumber','parentheses','equal','optionType','varIdentType','setVarIdentType','identifierKeyword','%f1270','%f1271','%f1272','%f1273','%f1274','identifierKeywordsAmbiguous1RolesAndLabels','identifierKeywordsAmbiguous2Labels','labelKeyword','%f1275','%f1276','%f1277','identifierKeywordsAmbiguous3Roles','identifierKeywordsUnambiguous','%f1278','%f1279','%f1280','roleKeyword','%f1281','%f1282','%f1283','lValueKeyword','identifierKeywordsAmbiguous4SystemVariables','roleOrIdentifierKeyword','%f1284','%f1285','%f1286','roleOrLabelKeyword','%f1287','%f1288','%f1289','%f1290','%f1291','%f1292','%f1293'],'grammar'=>[[[-1],[2001,2003]],[[2004],[2668]],[[-1],[0]],[[755,2002],[-1]],[[2009],[2175],[2318],[2353],[2358],[2005],[2361],[2366],[2381],[2385],[2400],[2437],[2457],[2461],[2656],[2659],[2712],[2829],[2006],[2848],[2991],[3010],[3020],[3057],[2007],[3102],[3168],[2008],[3489],[3496]],[[2359]],[[2838]],[[3145]],[[3472]],[[11,2012]],[[2153]],[[2225],[0]],[[2060],[2028],[422,3783,2011],[206,3785,2011],[2167],[2039],[2140],[2010],[2050],[2056],[2013]],[[2026]],[[33]],[[844],[2014]],[[2017],[0]],[[373,480,383,165]],[[451,845,2016]],[[2020],[0]],[[373,480,383,165]],[[451,845,200,57,3826,2019]],[[156],[140]],[[2022,844,846]],[[451,847]],[[482,2015,316,265],[2018],[2021],[2023],[2024]],[[244,2025]],[[3781],[0]],[[109,2027,2031]],[[615,112,139,357]],[[2183,2030],[2183]],[[2030],[2029]],[[3690],[0]],[[2040],[0]],[[2042],[0]],[[2043],[0]],[[2046],[0]],[[2047],[0]],[[2048],[0]],[[2032,170,3795,2033,2034,2035,2036,2037,2038]],[[383,490,3510]],[[371],[0]],[[383,79,2041,418]],[[453,590,3826]],[[2045],[0]],[[383,514]],[[156],[140,2044]],[[75,3855]],[[147,3425]],[[2052],[0]],[[288,217,3793,4,603,3855,2049]],[[2054,2051],[2054],[0]],[[2055,2051]],[[750],[0]],[[2053,2055]],[[2274],[2282],[2284]],[[503,3798,2254]],[[3761],[0]],[[2062],[0]],[[2065],[0]],[[2057,2058,574,3807,2059]],[[232]],[[2061]],[[2066],[0]],[[2067],[0]],[[2063,2074],[2069,2064],[3653],[2138]],[[2072,750]],[[3653],[2138]],[[2070],[0]],[[2072,2068],[2088]],[[750,2088]],[[2073,2071],[2073],[0]],[[2092,2071]],[[750,2092]],[[141,572],[234,572],[2082],[2076]],[[722],[723]],[[2075]],[[3762],[0]],[[3005,2078],[3005],[0]],[[3007,2079],[3007],[0]],[[2084],[0]],[[2135],[0]],[[4,405,2077,2083],[148,405,3828],[438,405,2077,2139],[388,405,2077,2139,2077],[14,405,2077,2139],[62,405,2139,2078],[455,405,2077,2139,2079],[67,405,2077,3838],[597,405,2139],[454,405,2077,2080],[172,405,3826,645,574,3807,2081],[2085],[2086]],[[3668],[404,3838]],[[3828,248,3668]],[[141,405,2139,572]],[[234,405,2139,572]],[[2091,2087],[2091],[0]],[[2089,2087]],[[2097],[3627]],[[2097],[2092],[3627]],[[750,2090]],[[2128],[2130],[2135]],[[72],[0]],[[2121],[0]],[[2116],[0]],[[3697],[0]],[[4,2093,2099],[4,3519],[55,2093,3769,3826,3528,2094],[348,2093,3769,3528,2094],[148,2107],[140,263],[156,263],[11,2093,3769,2111],[2112],[2113],[2114],[2115],[453,2095,3800],[2117],[94,590,3406,2119,2096],[198],[393,45,2125],[2120]],[[3514],[0]],[[3826,3528,2098,2094],[753,2194,748]],[[3769]],[[3769],[0]],[[2101]],[[2100],[2102]],[[62,3826]],[[86,3826]],[[2122],[0]],[[2093,3769,2106],[199,265,2103],[420,265],[2645,3776],[2104],[2105]],[[3413]],[[2108],[3845]],[[506,3582]],[[506,128,2109],[148,128],[2110]],[[11,236,3776,3582]],[[11,62,3826,3517]],[[11,86,3826,3517]],[[453,72,3769,590,3826]],[[590],[17]],[[453,2645,3776,590,3775]],[[128]],[[2118],[3618]],[[615,403]],[[6,3826],[191]],[[471],[49]],[[2551],[0]],[[2126,2124],[2126],[0]],[[3831,2123,2124]],[[750,3831,2123]],[[763],[0]],[[9,2127,2129]],[[128],[3826]],[[287,2127,2131]],[[128],[3826]],[[2130],[0]],[[2128],[0]],[[2128,2132],[2130,2133]],[[2137]],[[645],[646]],[[2136,625]],[[452,403]],[[10],[3828]],[[572,3791,2151]],[[4],[148]],[[2143,2142],[2143],[0]],[[2053,2164]],[[2145],[0]],[[2164,2142]],[[434],[436]],[[55,111,3855,2144],[2146],[371,1]],[[2147]],[[2160]],[[2160],[0]],[[2141,111,3855,2150],[2148],[453,590,3826],[2149]],[[2156],[0]],[[605,572,3791,506,2154,2152]],[[724],[725]],[[2157,2155],[2157],[0]],[[2158,2155]],[[2053,2158]],[[2282]],[[2161,2159],[2161],[0]],[[2162,2159]],[[2053,2162]],[[238,2127,3871],[2277],[2278],[2282],[2163],[2284],[2288]],[[2283]],[[238,2127,3871],[2277],[2278]],[[2292],[0]],[[2294],[0]],[[2165,2032,2166,636,3789,2169]],[[3771],[0]],[[2168,17,2171]],[[2173],[0]],[[2201,2170]],[[2174],[0]],[[645,2172,62,391]],[[50],[284]],[[97,2179]],[[2314]],[[2316]],[[2261]],[[2182],[2186],[2214],[2207],[2221],[2246],[2290],[2297],[2229],[2252],[2259],[2308],[2176],[2177],[2178]],[[3692],[0]],[[2183,2181],[2183],[0]],[[109,2180,3780,2181]],[[3649],[3647],[2184]],[[3648]],[[577],[0]],[[2185,574,2180,3800,2192]],[[2188],[0]],[[753,2194,748]],[[3624],[0]],[[3653],[0]],[[2199],[0]],[[275,3807],[753,275,3807,748],[2187,2189,2190,2191]],[[2195,2193],[2195],[0]],[[2196,2193]],[[750,2196]],[[3513],[3519]],[[2200],[0]],[[17],[0]],[[2197,2198,2201]],[[458],[232]],[[2465],[2483]],[[755],[0]],[[97,2204,2202,-1]],[[2207],[2214],[2221]],[[2212],[0]],[[2223,2206],[2223],[0]],[[2032,422,2209,3782,753,2205,748,2206,3425]],[[2180]],[[2208]],[[2211,2210],[2211],[0]],[[750,3694]],[[3694,2210]],[[2219],[0]],[[2032,206,2216,3784,753,2213,748,474,3698,2206,3425]],[[2180]],[[2215]],[[2218,2217],[2218],[0]],[[750,3696]],[[3696,2217]],[[8],[0]],[[2220,206,3796,474,2222,520,3855]],[[556],[249],[437],[126]],[[2226],[2041,137]],[[2223,2224],[2223]],[[2224]],[[75,3855],[267,537],[373,537],[90,537],[433,537,112],[347,537,112],[537,496,2227]],[[130],[250]],[[2134],[0]],[[2057,2238,2228]],[[3583],[0]],[[3775,2230]],[[2241],[0]],[[2231],[2232]],[[609],[0]],[[3579,2235],[3579],[0]],[[3585,2236],[3585],[0]],[[3586,2237],[3586],[0]],[[2234,236,2233,2244,2235],[205,236,3775,2244,2236],[523,236,3775,2244,2237]],[[3775],[0]],[[2243],[0]],[[2239,2240]],[[621],[599]],[[2242,3577]],[[383,3807,3574]],[[2249],[0]],[[288,217,3792,4,2247,3855,2245]],[[603],[440]],[[2250,2248],[2250],[0]],[[2251,2248]],[[2053,2251]],[[2274],[2275],[2280],[2282],[2284],[2286]],[[503,3797,199,112,648,3868,2254]],[[2255,2253],[2255],[0]],[[390,753,2256,2253,748]],[[750,2256]],[[224,3855],[109,3855],[618,3855],[406,3855],[519,3855],[398,3855],[413,3837]],[[2260],[0]],[[2268],[0]],[[572,3790,2262,2257,2258]],[[620,288,217,3793]],[[605,572,3790,4,2266,2152]],[[2265],[4,2266]],[[2264],[0]],[[4,2266]],[[2263]],[[111,3855]],[[2269,2267],[2269],[0]],[[2270,2267]],[[2053,2270]],[[2274],[2277],[2278],[2279],[2280],[2282],[2271],[2284],[2286],[2272],[2273]],[[2283]],[[2287]],[[2288]],[[238,2127,3871]],[[2276,2127,3871]],[[604],[441]],[[23,2127,3871]],[[324,2127,3871]],[[181,2127,3871]],[[368,2127,3838]],[[553],[0]],[[2281,163,2127,3799]],[[848,2127,3849]],[[2285]],[[638],[374]],[[75,2127,3855]],[[189,2127,3871]],[[158,2127,3849]],[[2291],[0]],[[2289,2032,2166,636,3788,2169]],[[394,458,2165],[2292]],[[9,763,2293]],[[602],[335],[578]],[[537,496,2295]],[[130],[250]],[[2302],[0]],[[2032,594,2299,3786,2300,2301,383,3807,200,153,487,2296,3425]],[[2180]],[[2298]],[[28],[6]],[[242],[614],[133]],[[2304]],[[197],[415]],[[2303,3868]],[[2309],[0]],[[2312],[0]],[[2313],[0]],[[2032,170,2180,3794,383,490,3510,2305,2306,2307,147,3425]],[[383,79,2041,418]],[[2311],[0]],[[383,514]],[[156],[140,2310]],[[75,3855]],[[659,2180,2984]],[[2317,2315],[2317],[0]],[[394,458,523,718,710,3840,2315],[523,718,710,2180,3840,2315]],[[357,580,3857],[715,580,3857],[717,3857,230,45,3840],[716,580,3857]],[[148,2322]],[[2349]],[[2350]],[[2351]],[[2324],[2325],[2326],[2327],[2328],[2330],[2335],[2337],[2341],[2345],[2347],[2319],[2320],[2321]],[[3691],[0]],[[109,2323,3781]],[[170,2323,3795]],[[206,2323,3785]],[[422,2323,3783]],[[2057,236,3776,383,3807,2228]],[[2333],[0]],[[288,217,3793,2329]],[[2332,2331],[2332],[0]],[[2053,2334]],[[2334,2331]],[[2284],[2282]],[[503,2323,3798]],[[2339],[0]],[[2185,2338,2323,3809,2336]],[[574],[571]],[[471],[49]],[[2344],[0]],[[572,3791,2340]],[[2343,2342],[2343],[0]],[[2053,2334]],[[2334,2342]],[[594,2323,3787]],[[2348],[0]],[[636,2323,3701,2346]],[[471],[49]],[[659,2323,2984]],[[523,718,710,2323,3840]],[[605,572,3791,2152]],[[2355,2352],[2355],[0]],[[453,2354,2356,2352]],[[574],[571]],[[750,2356]],[[3807,590,3800]],[[574],[0]],[[597,2357,3807]],[[234,574,203,3859]],[[2363],[0]],[[48,3783,2360]],[[3404],[0]],[[753,2362,748]],[[2368],[0]],[[2380,2365],[2380],[0]],[[2364,133,2365,2377]],[[2543]],[[2367]],[[2636]],[[2371],[0]],[[2369]],[[2585],[0]],[[2378],[0]],[[2550],[0]],[[2499],[0]],[[3812,621,2555,2372],[3807,2370,2373,2372,2374,2375]],[[203,2376],[3812,203,2555,2372]],[[2379]],[[405,753,3828,748]],[[431],[295],[431],[232]],[[147,2384]],[[2578]],[[3404]],[[2382],[2383]],[[219,2389]],[[2498],[0]],[[66],[435,2390,2372,2386]],[[2636],[0]],[[3807,387,2388],[3826,2387]],[[2391],[3826,2394]],[[191],[367]],[[191],[367],[419],[268]],[[763],[769],[765],[768],[764]],[[2392],[2393,753,2424,748]],[[2408],[0]],[[232],[0]],[[248],[0]],[[3763],[0]],[[2429],[0]],[[242,2395,2396,2397,3807,2398,2407,2399]],[[2428]],[[2403],[0]],[[2401]],[[2428]],[[2406],[0]],[[2404]],[[2410,2402],[506,3704,2405],[2418]],[[295],[131],[223]],[[2412],[0]],[[2409,2416]],[[2414],[0]],[[753,2411,748]],[[2415,2413],[2415],[0]],[[3774,2413]],[[750,3774]],[[2417,2421]],[[626],[627]],[[2201],[753,2411,748,2201]],[[2424],[0]],[[2422,2420],[2422],[0]],[[753,2419,748,2420]],[[750,753,2419,748]],[[2427,2423],[2427],[0]],[[2425,2423]],[[3191],[128]],[[3191],[128]],[[750,2426]],[[17,3826,2168]],[[383,151,265,614,3704]],[[2438],[0]],[[284],[0]],[[2439],[0]],[[3708],[0]],[[2441],[0]],[[3710],[0]],[[3714],[0]],[[281,2440,2430,2431,237,3855,2432,248,574,3807,2398,2433,2434,2435,2436,2445]],[[295],[82]],[[458],[232]],[[112],[653]],[[484,230,45,3851]],[[2447],[0]],[[2450],[0]],[[2448],[0]],[[2442,2443,2444]],[[278],[484]],[[232,787,2446]],[[506,3704]],[[2452],[0]],[[753,2449,748]],[[2455,2451],[2455],[0]],[[2453,2451]],[[3773],[3383]],[[3773],[3383]],[[750,2454]],[[2458],[0]],[[458,2456,2397,3807,2398,2459]],[[295],[131]],[[2410],[506,3704],[2418]],[[2566],[0]],[[2465,2460],[2462]],[[753,2462,748],[2465,2506,2460],[2465,2566,2506]],[[2467],[0]],[[2470],[0]],[[2463,2468,2464]],[[2543]],[[2466]],[[2472,2374,2386],[2483,2374,2386]],[[2513]],[[2469]],[[2476,2471],[2476],[0]],[[2478,2471]],[[663]],[[608],[2473]],[[2634],[0]],[[2474,2475,2478]],[[2482,2477],[2482],[0]],[[2479,2477]],[[2484],[2483]],[[2484],[2483]],[[811,2475,2480]],[[2481]],[[753,2465,2460,748]],[[2493],[2485],[2486]],[[2558]],[[2560]],[[2562,2487],[2562],[0]],[[2506],[0]],[[2552],[0]],[[2547],[0]],[[2517],[0]],[[2495],[0]],[[497,2487,2578,2488,2489,2372,2490,2491,2492]],[[2519]],[[2494]],[[2483]],[[10],[143],[555],[223],[536],[531],[532],[534]],[[276,2501]],[[276,2504]],[[2503],[0]],[[2504,2500]],[[750],[381]],[[2502,2504]],[[3826],[2505]],[[754],[791],[788],[787]],[[248,2511]],[[3868],[3383]],[[3868],[3383]],[[2510,2509],[2510],[0]],[[750,2508]],[[396,3849,2433,2435,2436],[150,3849],[2507,2509]],[[2516],[0]],[[422,13,753,2512,748]],[[2515],[0]],[[750,787]],[[787,2514]],[[221,3191]],[[2520,2518],[2520],[0]],[[699,2521,2518]],[[750,2521]],[[3822,17,2522]],[[753,2528,748]],[[2533],[0]],[[2529],[0]],[[2530],[0]],[[3822],[0]],[[2531],[0]],[[405,45,3416,2374,2523],[2524,2550,2523],[2525,2374,2533],[2526,2527,2374,2523]],[[405,45,3416]],[[405,45,3416]],[[405,45,3416]],[[2539],[0]],[[2534,2535,2532]],[[484],[432],[683]],[[2536],[2537]],[[698,693],[3839,693],[754,693],[247,3191,3409,693],[101,487]],[[30,2538,15,2538]],[[2536],[698,682],[3839,682],[754,682],[247,3191,3409,682]],[[680,2540]],[[101,487],[217],[697],[373,690]],[[665],[0]],[[2544,2542],[2544],[0]],[[645,2541,2545,2542]],[[750,2545]],[[3826,2168,17,2496]],[[2548],[0]],[[217,45,3416,2546]],[[645,481],[2549]],[[645,99]],[[393,45,3416]],[[18],[134]],[[203,2553]],[[149],[2555]],[[2556,2554],[2556],[0]],[[2587,2554]],[[750,2587]],[[2559,2557],[2559],[0]],[[626,2561,2557]],[[750,2561]],[[574,3807]],[[487,753,2419,748]],[[2497],[535],[2563],[2564]],[[533]],[[325,763,3838]],[[2569,2565],[2569]],[[2565]],[[2571],[0]],[[2573],[0]],[[200,2574,2567,2568],[287,251,508,346]],[[668,3812]],[[2570]],[[2576]],[[2572]],[[614],[2575]],[[508]],[[669,670],[671]],[[2580,2577],[2580],[0]],[[2579,2577]],[[2582],[775]],[[750,2582]],[[2583],[0]],[[3778],[3191,2581]],[[2198,2584]],[[3826],[3849]],[[643,3191]],[[2593,2586],[2593],[0]],[[2590,2586]],[[3826]],[[2588],[732]],[[2605],[752,2589,2591,747]],[[2605,2586]],[[2594],[0]],[[2601,2587,2592],[2603,2587,2595],[2598,2605]],[[383,3191],[621,3830]],[[383,3191],[621,3830]],[[239],[0]],[[395],[0]],[[359,2596,261],[359,2599,2597,261]],[[272],[478]],[[2602],[0]],[[2600,261],[555]],[[239],[98]],[[2604,2597,261]],[[272],[478]],[[2608],[2609],[2612],[2616],[2606]],[[2618]],[[2640],[0]],[[3807,2398,2388,2607]],[[753,2610,748]],[[2608],[2609]],[[2614],[0]],[[2496,2388,2611],[2615]],[[3771]],[[2613]],[[726,2496,2388,2168]],[[753,2617,748]],[[2555],[2616]],[[701,753,3191,750,3849,2620,748,2388]],[[2621,2619],[2621],[0]],[[71,753,2625,2619,748]],[[750,2625]],[[2627],[0]],[[174],[0]],[[2630],[0]],[[3826,200,703],[3826,3592,2622,2623,704,3849,2624],[702,704,3849,2620]],[[3697]],[[2626]],[[2632],[0]],[[2631],[0]],[[2631,2628],[2632,2629]],[[2633,383,700]],[[2633,383,165]],[[165],[376],[128,3849]],[[143],[10]],[[2638],[0]],[[2635,3826]],[[763]],[[17],[2637]],[[2643,2639],[2643]],[[2639]],[[2648],[0]],[[2651],[0]],[[2644,2645,2641,753,2651,748],[620,2645,2641,753,2642,748]],[[198],[232]],[[265],[236]],[[2645],[0]],[[420,265],[609,2646]],[[200,2649]],[[261],[393,45],[217,45]],[[2652,2650],[2652],[0]],[[2653,2650]],[[750,2653]],[[3826],[420]],[[2658],[0]],[[295],[0]],[[2654,614,2655,2396,2555,506,3704,2372,2374,2375]],[[2543]],[[2657]],[[2664],[2675],[2683],[2691]],[[2670],[0]],[[647],[0]],[[2666],[0]],[[2667],[0]],[[543,592,2660],[77,2661,2662,2663]],[[373],[0]],[[15,2665,54]],[[2665,450]],[[29,2661]],[[2671,2669],[2671],[0]],[[2672,2669]],[[750,2672]],[[645,85,517],[2674]],[[649],[386]],[[435,2673]],[[489,3826],[480,2661,2681],[450,489,3826]],[[2677],[0]],[[15,2665,54]],[[2679],[0]],[[2665,450]],[[489],[0]],[[590,2680,3826],[2676,2678]],[[2685,2682],[2685],[0]],[[287,2684,2689,2682],[2686],[611,2688]],[[571],[574]],[[750,2689]],[[287,244,200,27]],[[244]],[[571],[574],[2687]],[[3807,2388,2690]],[[435,2431],[2655,649]],[[651,2701]],[[543],[29]],[[2694],[0]],[[261],[472]],[[2696],[0]],[[200,340]],[[2698],[0]],[[566,2695]],[[2700],[0]],[[384,407]],[[2692,2707,2693],[159,2707,2697],[417,2707],[77,2707,2699],[480,2707],[439,2702]],[[2705],[0]],[[2704],[0]],[[94,652]],[[2703]],[[2710],[0]],[[3851,2706]],[[2709],[0]],[[750,3837]],[[750,3851,2708]],[[2715,2711],[2715],[0]],[[428,2713,289,2714],[2733],[468,2724,2711],[2718],[2804],[2719],[2731],[2720]],[[32],[316]],[[590,3855],[28,3191]],[[750,2724]],[[2717],[0]],[[2323,3387]],[[468,658,2716]],[[2749]],[[2827]],[[2726],[0]],[[10],[0]],[[3423],[0]],[[316,2721],[2725],[514,2722,2723]],[[430,47]],[[2730]],[[3838]],[[3840]],[[2727],[2728]],[[590,2729]],[[281,2732,203,316]],[[112],[574,3807]],[[55,316,590,2735,2723]],[[2736,2734],[2736],[0]],[[2737,2734]],[[750,2737]],[[300,763,3857],[729,763,3857],[297,763,3857],[318,763,3857],[303,763,3857],[304,763,3837],[298,763,3837],[305,763,3837],[299,763,3837],[314,763,3837],[308,763,3857],[307,763,3857],[317,763,3857],[309,763,3857],[738,763,2740],[310,763,3857],[313,763,3857],[315,763,3837],[311,763,3855],[312,763,3857],[712,763,3857],[713,763,3837],[319,763,3837],[233,763,2743],[735,763,3849],[736,763,3837],[296,763,3837],[737,763,2738],[739,763,3837],[742,763,2739],[2741]],[[3755],[376]],[[743],[383],[744]],[[3857],[376]],[[301,763,3857],[302,763,3839],[447,763,3857],[448,763,3837]],[[2746],[0]],[[753,2742,748]],[[2745,2744],[2745],[0]],[[750,3837]],[[3837,2744]],[[2750,2747],[2750],[0]],[[2752],[0]],[[55,459,522,590,2754,2723],[55,459,190,2788,2747,2748]],[[750,2788]],[[3423]],[[2751]],[[2755,2753],[2755],[0]],[[2756,2753]],[[750,2756]],[[2757,763,3857],[2758,763,3857],[2759,763,3857],[2760,763,3857],[2761,763,3837],[2762,763,3857],[2763,763,3839],[2764,763,3837],[2765,763,3837],[2766,763,3837],[2767,763,3837],[817,763,3837],[2768,763,3837],[2769,763,3849],[2770,763,3837],[2771,763,3837],[2772,763,3857],[2773,763,3857],[2774,763,3857],[2775,763,3855],[2776,763,3857],[2777,763,3857],[2778,763,3857],[2779,763,3837],[2780,763,3857],[2781,763,2740],[2782,763,3857],[2783,763,3837],[729,763,3857],[233,763,2743],[841,763,3837],[737,763,2738],[739,763,3837],[742,763,2739],[842,763,3837],[447,763,3857],[448,763,3837]],[[814],[297]],[[820],[300]],[[838],[318]],[[823],[303]],[[824],[304]],[[821],[301]],[[822],[302]],[[813],[296]],[[819],[319]],[[816],[298]],[[826],[305]],[[818],[299]],[[815],[735]],[[839],[736]],[[827],[314]],[[828],[308]],[[829],[307]],[[830],[309]],[[832],[311]],[[833],[312]],[[834],[313]],[[831],[310]],[[835],[315]],[[837],[317]],[[836],[738]],[[825],[712]],[[840],[713]],[[2790],[0]],[[2793],[0]],[[2796],[0]],[[2800],[0]],[[460,763,753,2784,748],[461,763,753,2784,748],[462,763,753,2785,748],[463,763,753,2785,748],[464,763,753,2786,748],[465,763,753,2786,748],[466,763,753,2787,748]],[[2791,2789],[2791],[0]],[[3781,2789]],[[750,3781]],[[2794,2792],[2794],[0]],[[3801,2792]],[[750,3801]],[[2797,2795],[2797],[0]],[[2798,2795]],[[750,2798]],[[3857]],[[2801,2799],[2801],[0]],[[3699,2799]],[[750,3699]],[[2824],[0]],[[2805],[0]],[[543,514,2802,2803,2813,2723],[552,514,2802,2723]],[[613,2807]],[[2812,2806],[2812],[0]],[[2811,2806]],[[530],[528]],[[2808,763,3851]],[[529]],[[2741],[2809],[2810]],[[750,2741]],[[2822],[0]],[[2815],[0]],[[618,763,3851]],[[2817],[0]],[[406,763,3851]],[[2819],[0]],[[129,763,3851]],[[2821],[0]],[[409,763,3851]],[[2814,2816,2818,2820]],[[2825,2823],[2825],[0]],[[2826,2823]],[[750,2826]],[[449],[538]],[[2828,210]],[[543],[552]],[[417,3826,203,2830],[2833],[2831,417,3826]],[[3855],[3383]],[[123],[148]],[[2834],[0]],[[173,3826,2832]],[[621,2836]],[[2837,2835],[2837],[0]],[[3383,2835]],[[750,3383]],[[677,2844]],[[2840],[0]],[[200,459]],[[2846],[0]],[[244,203,3758,749,3837,230,45,3849,2841]],[[3873],[0]],[[284,112,139,2843,3849],[676,2839],[2842]],[[2847],[0]],[[2847],[112,139,2843,3849,2845]],[[467,2665,539]],[[2849],[2863],[2897],[2900],[2929],[2933],[2850]],[[2852]],[[2979]],[[2854],[0]],[[11,618,2851,2855]],[[3691]],[[2853]],[[2858],[2861,2866]],[[2862],[3758]],[[10],[369],[2984]],[[2856,128,659,2857]],[[3724]],[[3721]],[[2859],[2860]],[[618,3872]],[[97,618,2865,3721,2875,2866]],[[3692]],[[2864],[0]],[[2874],[0]],[[75],[812]],[[2867,3851]],[[2870],[0]],[[2868]],[[2879],[0]],[[2883],[0]],[[2885,2873],[2885],[0]],[[2871,2872,2873,2869]],[[2878],[0]],[[2877],[0]],[[128,659,2984]],[[2876]],[[467,2881]],[[539],[650],[369]],[[2973],[2880]],[[2884,2882],[2884]],[[645,2882]],[[322,3837],[327,3837],[321,3837],[328,3837]],[[2,2886],[406,2894],[740,2895],[741,3838]],[[287],[611]],[[2888],[0]],[[247,3838,122],[365],[128]],[[3838],[128]],[[3838,122],[128]],[[2892],[0]],[[128],[719]],[[467,101,2891]],[[177,2887],[705,2889],[706,247,2890],[2893]],[[3838],[698]],[[2899],[0]],[[148,618,2896,3718]],[[3691]],[[2898]],[[215,2912]],[[2902],[0]],[[645,660,391]],[[2952,590,3718,2901]],[[421],[0]],[[2952],[10,2904]],[[2907],[0]],[[645,215,391]],[[2950],[0]],[[2926],[0]],[[2916],[0]],[[2925],[0]],[[2903],[2905,383,2908,2968,590,2913,2909,2910,2911],[427,383,3758,590,2913,2906]],[[2914],[2915]],[[3721]],[[3718]],[[2918],[2919]],[[2977,2917],[2977]],[[645,2917]],[[645,215,391]],[[663,2984]],[[645,659,2923]],[[2920],[0]],[[2984],[10,2922],[369],[128]],[[2921],[0]],[[17,618,2924]],[[2927]],[[2879]],[[2930,2928],[2930],[0]],[[453,618,3758,590,3758,2928]],[[750,3758,590,3758]],[[2935],[0]],[[2944],[0]],[[477,2931,2942,2932]],[[3691]],[[2934]],[[2952,203,3718]],[[2945],[0]],[[2939],[0]],[[2937,203,3718]],[[383,2908,2968,2938]],[[2940],[750,215,391,203,3718]],[[2936],[2952,2945,203,3718],[10,2904,2941],[427,383,3758,203,3718]],[[232,610,618]],[[2943]],[[2946],[2949]],[[383,2908,2968]],[[2948],[0]],[[383,2908,2968]],[[2947]],[[574],[206],[422]],[[2953,2951],[2953],[0]],[[2956,2951]],[[750,2956]],[[2965],[0]],[[483],[0]],[[2959],[2960,2168],[2962],[2963],[215,391],[509,110],[97,2954],[287,571],[459,2966],[509,636],[11,2955]],[[792],[746,3868]],[[3870,2957],[3870,2168]],[[2958]],[[497],[242],[614],[443]],[[97],[148]],[[2961,659]],[[133],[616],[236],[148],[173],[451],[510],[423],[188],[427],[565],[170],[594]],[[483],[572],[618],[636]],[[577,571],[2964]],[[65],[514]],[[2969],[0]],[[775,2967],[3781,751,2971],[3781],[3807]],[[751,775]],[[3807]],[[775],[2970]],[[2975,2972],[2975],[0]],[[2976,2972]],[[15],[0]],[[2974,2976]],[[63,3851],[259,3851],[559,3851]],[[215,391],[322,3837],[327,3837],[321,3837],[328,3837]],[[2982],[0]],[[506,659,2984],[506,659,2980],[506,128,659,2981,590,2984],[506,659,10,2978]],[[369],[128]],[[2984],[369],[10]],[[663,2984]],[[2985,2983],[2985],[0]],[[2987,2983]],[[750,2987]],[[2988],[0]],[[3870,2986]],[[746,3868],[792]],[[2994],[0]],[[2997],[0]],[[14,2077,2992,3809,2989],[62,2995,3809,2078],[61,2996,3809,2990],[388,2077,2998,3809],[455,2077,2999,3809,2079]],[[574],[571]],[[3002]],[[2993]],[[574],[571]],[[574],[571]],[[431],[180]],[[574],[571]],[[574],[571]],[[3003],[0]],[[3004],[0]],[[614,674,383,3828,3000,3001],[148,674,383,3828]],[[645,787,675]],[[621,112,3849]],[[200,615],[3006]],[[431],[184],[333],[180],[56]],[[431],[180],[619]],[[3011],[0]],[[3012,3009],[3012],[0]],[[245,410,3826,520,3849],[245,664,3859,3008],[607,410,3819],[607,664,3820,3009]],[[506,3018]],[[750,3820]],[[214],[658]],[[3013],[0]],[[3014,3387,3873,3016]],[[383],[3191]],[[3019,3017],[3019],[0]],[[3015,3017]],[[750,3015]],[[506,3022]],[[3023],[0]],[[592,3034],[406,3021,3873,3028],[3031],[3045,3043],[3874,3051]],[[200,3758]],[[382,753,3851,748]],[[406,753,3851,748]],[[3753],[0]],[[3751],[0]],[[3851,3026,3027],[3851,3026,3027],[3024],[3025]],[[3030],[0]],[[200,3758]],[[406,3029,590,734,3026,3027]],[[3035],[0]],[[3036],[0]],[[3037,3032],[3039,3033]],[[750,3039]],[[750,3037]],[[435,3038]],[[649],[386]],[[258,274,3041]],[[76],[601]],[[456,435],[435,3040],[500]],[[3044,3042],[3044],[0]],[[3042]],[[750,3048]],[[3387,3873,3053],[3708],[3383,3873,3191],[3050,3873,3053],[356,3047]],[[128]],[[3873,3191],[3618,2096],[3046]],[[3874,3387,3873,3053],[3045]],[[3876],[0]],[[745,3049,3387]],[[3052,3043],[592,3034]],[[3387,3873,3053]],[[3191],[3054],[3056]],[[128],[383],[10],[32]],[[487],[710]],[[3055]],[[509,3091]],[[22]],[[3799],[10]],[[547],[354],[289]],[[203],[251]],[[32],[316]],[[225],[547,3094,2723]],[[33],[446]],[[3066],[0]],[[251,3851]],[[3068],[0]],[[203,3839]],[[180]],[[3071],[0]],[[3069]],[[236],[235],[263]],[[639],[166]],[[3075,3074],[3075],[0]],[[750,3099]],[[3077],[0]],[[3099,3074]],[[3079],[0]],[[200,430,787]],[[547],[631]],[[93]],[[3083],[0]],[[200,3758]],[[618,3758]],[[109,2180,3781],[170,3795],[206,3785],[422,3783],[574,3807],[594,3787],[636,3789],[3084]],[[3760],[0]],[[3092],[0]],[[3098],[0]],[[204],[0]],[[3874],[0]],[[3058],[110,3086],[3087,571,3088,3086],[3089,593,3088,3086],[169,3088,3086],[574,547,3088,3086],[387,571,3088,3086],[408],[163,3059,3060],[3087,71,3061,3807,3088,3086],[3062,289],[514,3063],[3064,169,3065,3067,2386,2723],[3070,3072,3097,3807,3088,2372],[2281,162],[95,753,775,748,3073],[639,2386],[166,2386],[426],[425,3076,3078,2386],[3090,3080,3086],[3089,424],[3406,3086],[70,3086],[3081],[421],[216,200,3758,621,3718],[216,3082],[316,547],[97,3085],[422,547,3086],[206,547,3086],[422,68,3783],[206,68,3785]],[[204],[3093]],[[180,3089]],[[3096],[0]],[[370],[0]],[[3095]],[[203],[251]],[[3097,3826]],[[40,255],[91,568],[400,185],[3100]],[[10],[96],[256],[334],[522],[567]],[[3107],[0]],[[33,3855],[47,236,3109,251,3103],[196,2077,3106],[266,3101,3191],[281,236,248,47,3136],[3108]],[[3826],[128]],[[3105,3104],[3105],[0]],[[750,3123]],[[3129],[3123,3104]],[[84],[430]],[[510]],[[3111],[3115]],[[3112,3110],[3112],[0]],[[3114,3110]],[[750,3114]],[[3117],[0]],[[3807,3113]],[[3807,405,753,2139,748,3113]],[[3120],[0]],[[2645,753,3116,748]],[[3826],[420]],[[3121,3119],[3121],[0]],[[3118,3119]],[[750,3118]],[[3127],[0]],[[3124],[3122,289],[445,289,2723],[3125],[3126]],[[136],[225],[421],[547],[617]],[[430,47]],[[389]],[[32],[163],[165],[208],[515]],[[3132],[0]],[[3130,3128]],[[571],[574]],[[3133],[0]],[[645,435,287],[3809,3131]],[[3134],[645,435,287]],[[200,179]],[[3137],[0]],[[3807,3144,3113,3135],[3139]],[[232,270]],[[3140,3138],[3140],[0]],[[3142,3138]],[[750,3142]],[[3143],[0]],[[3807,3113,3141]],[[232,270]],[[405,753,2139,748]],[[3149],[3160],[3162],[3167]],[[3152],[0]],[[3157],[0]],[[3158],[0]],[[97,709,217,3826,599,2843,3150,3146,3147,3148]],[[618],[710]],[[3153,3151],[3153],[0]],[[711,2843,3155,3151]],[[2053,3155]],[[3156],[0]],[[787,3154]],[[773,787]],[[708,2843,787]],[[156],[140]],[[198],[0]],[[11,709,217,3821,3146,3147,3148,3159]],[[3163],[0]],[[506,709,217,3826,3161]],[[200,3165]],[[3166,3164],[3166],[0]],[[3838,3164]],[[2053,3838]],[[148,709,217,3821,3159]],[[3175],[3171],[3187],[3188],[3169]],[[3189]],[[3173],[0]],[[3172,3807,3170]],[[178],[135],[134]],[[3851],[3773]],[[3182],[0]],[[3176,3174,3183]],[[178],[135],[134]],[[180]],[[404]],[[201,763,3868]],[[14,201,763,3868]],[[14]],[[3177],[3178],[3179],[3180],[3181]],[[2461],[3185],[3186]],[[2366],[2400],[2457],[2656]],[[3184]],[[200,84,3838]],[[222,3868]],[[620,3826]],[[714]],[[3198,3190],[3198],[0]],[[3193,3190]],[[3196],[0]],[[3202,3192],[3197]],[[596],[183],[610]],[[3407],[0]],[[257,3195,3194]],[[371,3191]],[[3199,3191],[654,3191],[3200,3191]],[[15],[770]],[[394],[772]],[[3203,3201],[3203],[0]],[[3207,3201]],[[257,3195,376],[3205,3204,2496],[3205,3207]],[[10],[16]],[[763],[777],[764],[765],[768],[769],[776]],[[3210],[0]],[[3216,3206]],[[668],[0]],[[733,3208,3414]],[[3195,3212],[3209],[521,275,3216]],[[3214],[0]],[[251,3213],[30,3216,15,3207],[275,3223,3211],[444,3216]],[[2496],[753,3404,748]],[[168,3223]],[[3217,3215],[3217],[0]],[[3223,3215]],[[760,3216],[3218,3216],[3219,3216],[3220,247,3191,3409],[3221,3216],[757,3216],[759,3216]],[[775],[762],[774],[145],[349]],[[778],[773]],[[778],[773]],[[779],[780]],[[3224,3222],[3224],[0]],[[3226,3222]],[[761,3226]],[[3227],[0]],[[3236,3225]],[[69,3868]],[[3237],[0]],[[487],[0]],[[3320],[0]],[[3246],[0]],[[3191],[0]],[[3245,3233],[3245]],[[3393],[0]],[[3248],[0]],[[3843],[3265],[3382,3228],[754],[3238],[3239],[3240,3223],[3408,3223],[3229,753,3404,748],[2623,2496],[752,3826,3191,747],[320,3315,7,753,3216,3230,748],[32,3223],[3244],[52,753,3191,17,3398,3231,748],[51,3232,3233,3234,159],[94,753,3191,750,3398,748],[94,753,3191,621,3618,748],[128,753,3833,748],[626,753,3833,748],[247,3191,3409,778,3191],[3377],[3329],[3773,3235]],[[3873,3191]],[[3294]],[[3298]],[[778],[773],[758]],[[247],[0]],[[3617],[0]],[[52,753,3191,21,586,843,3241,3849,17,113,3242,748]],[[3243]],[[3391,3392]],[[3247]],[[731]],[[3249],[3250]],[[766,3849]],[[767,3849]],[[143],[0]],[[3267],[0]],[[3270],[0]],[[3273],[0]],[[3276],[0]],[[3278],[0]],[[3280],[0]],[[3282],[0]],[[3284],[0]],[[3286],[0]],[[3288],[0]],[[3290],[0]],[[3291],[0]],[[3293],[0]],[[26,753,3251,3314,748,3252],[3268,753,3314,748,3253],[3271],[95,753,2722,775,748,3254],[95,753,3274,748,3255],[345,753,3251,3314,748,3256],[326,753,3251,3314,748,3257],[551,753,3314,748,3258],[632,753,3314,748,3259],[548,753,3314,748,3260],[635,753,3314,748,3261],[564,753,3251,3314,748,3262],[218,753,3251,3404,2374,3263,748,3264]],[[3304]],[[3266]],[[35],[36],[38]],[[3304]],[[3269]],[[3313]],[[3304]],[[3272]],[[2722,775],[3314],[143,3404]],[[3304]],[[3275]],[[3304]],[[3277]],[[3304]],[[3279]],[[3304]],[[3281]],[[3304]],[[3283]],[[3304]],[[3285]],[[3304]],[[3287]],[[3304]],[[3289]],[[499,3851]],[[3304]],[[3292]],[[672,753,3404,748]],[[3307],[0]],[[3310],[0]],[[3303],[0]],[[3299,3872,3304],[688,3414,3304],[3300,753,3191,3295,748,3296,3304],[3301,3413,3296,3304],[687,753,3191,750,3223,748,3297,3296,3304]],[[696],[694],[679],[678],[692]],[[686],[684]],[[681],[685]],[[191],[268]],[[203,3302]],[[691,3305]],[[3822],[2522]],[[3309],[0]],[[750,3308,3306]],[[3839],[754],[3826],[3383]],[[750,3191]],[[3311,689]],[[695],[232]],[[3304],[0]],[[667,753,3314,748,3312],[666,753,3314,750,3314,748,3312]],[[2722,3191]],[[3317],[753,3317,748]],[[3318,3316],[3318],[0]],[[3833,3316]],[[750,3833]],[[3321],[0]],[[251,41,346],[251,359,267,346,3319],[645,430,176]],[[645,430,176]],[[3330],[0]],[[3872],[0]],[[3331,3324],[3331]],[[3335],[0]],[[3353],[0]],[[3340],[0]],[[3343],[0]],[[60,753,3404,3322,748],[105,3323],[116,3413],[122,3413],[229,3413],[242,753,3191,750,3191,750,3191,750,3191,748],[247,753,3191,3324,748],[3334],[272,753,3191,750,3191,748],[343,3413],[350,3413],[478,753,3191,750,3191,748],[495,3413],[586,3413],[583,753,3191,3325,748],[3366],[618,3872],[626,3413],[656,3413],[3336,753,3191,750,3337,748],[100,3323],[108,3326],[3338,753,3191,750,247,3191,3409,748],[182,753,3409,203,3191,748],[213,753,3365,750,3191,748],[372,3326],[414,753,3216,251,3191,748],[3370],[569,3326],[3339,753,3411,750,3191,750,3191,748],[622,3323],[624,3326],[623,3326],[19,3413],[58,3413],[67,3412],[70,3413],[109,3872],[231,753,3191,750,3191,750,3191,748],[201,753,3191,750,3191,3327,748],[337,3413],[349,753,3191,750,3191,748],[3341],[3342],[429,3413],[457,753,3191,750,3191,748],[458,753,3191,750,3191,750,3191,748],[476,3413],[485,3872],[597,753,3191,750,3191,748],[640,753,3191,3328,748],[641,753,3191,17,60,748],[641,753,3191,3349,748],[3350]],[[621,3618]],[[750,3191]],[[3333],[0]],[[851,3398]],[[850,753,3223,750,3855,3332,2624,748]],[[750,3191]],[[5],[558]],[[3191],[247,3191,3409]],[[114],[115]],[[584],[585]],[[750,3191]],[[382,753,3855,748]],[[406,3413]],[[750,3191]],[[3345],[0]],[[17,60,3616]],[[3356]],[[3348],[0]],[[3346]],[[17,32,3616],[3344,3347],[750,3837,750,3837,750,3837]],[[3351],[211,753,2362,748],[279,3412],[351,3412],[352,3412],[353,3412],[411,753,3191,750,3191,748],[412,3412]],[[90,753,3191,750,3191,748]],[[3354],[0]],[[753,3352,748]],[[3355]],[[787]],[[274,3359]],[[3358,3357],[3358],[0]],[[750,3361]],[[3838,773,3838],[3361,3357]],[[3364],[0]],[[3838,3360]],[[18],[134]],[[476],[0]],[[3362,3363],[476]],[[116],[586],[113],[583]],[[595,753,3369,748]],[[3368],[0]],[[203,3191]],[[3191,3367],[269,3232,203,3191],[591,3232,203,3191],[43,3232,203,3191]],[[563,753,3191,3375,748]],[[3372],[0]],[[750,3191]],[[3374],[0]],[[200,3191]],[[750,3191,3371],[203,3191,3373]],[[3379],[0]],[[3823,753,3376,748],[3831,753,2362,748]],[[3380,3378],[3380],[0]],[[3381,3378]],[[750,3381]],[[3191,2581]],[[3383],[3386]],[[746,3868],[792]],[[3875],[0]],[[3836],[0]],[[745,3384,3868,3385]],[[3390],[128,3836]],[[3826,3385]],[[3869,3385]],[[3388],[3389]],[[642,3191]],[[582,3191]],[[154,3191]],[[3606],[0]],[[3612],[0]],[[249],[0]],[[3865],[0]],[[32,3394],[60,3394,3395],[3604,3394],[512,3396],[612,3396],[116],[586,3242],[113,3242],[126,3397],[656],[3399],[3400],[3402]],[[262]],[[3605]],[[3866],[0]],[[195,3401]],[[3405,3403],[3405],[0]],[[3191,3403]],[[750,3191]],[[60,506],[58]],[[371],[800]],[[771],[800]],[[3411],[3410]],[[494],[341],[342],[226],[228],[227],[119],[121],[120],[118],[655]],[[337],[495],[343],[229],[122],[640],[350],[429],[656]],[[753,3404,748]],[[753,3191,748]],[[753,3223,748]],[[3417,3415],[3417],[0]],[[3418,3415]],[[750,3418]],[[3191,2123]],[[3421,3419],[3421],[0]],[[3422,3419]],[[750,3422]],[[3191]],[[3424]],[[200,57,3857]],[[2004],[3426],[3427],[3437],[3441],[3442],[3447],[3448],[3470],[3469],[3502],[3505],[3503]],[[475,3191]],[[231,3429,159,231]],[[3430],[0]],[[3191,3431,3428]],[[155,3429],[154,3433]],[[582,3433]],[[3434,3432],[3434]],[[3432]],[[3425,755]],[[3438,3435],[3438]],[[3439],[0]],[[51,3232,3435,3436,159,51]],[[3391,3431]],[[154,3433]],[[3816],[0]],[[3443,3446,3440]],[[3446]],[[3815,749]],[[3453],[0]],[[3433],[0]],[[29,3444,3445,159]],[[3443,3448,3440]],[[3449],[3450],[3451]],[[294,3433,159,294]],[[644,3191,147,3433,159,644]],[[457,3433,613,3191,159,457]],[[3454,3452],[3454]],[[3452]],[[3455,755]],[[3457],[3459],[3464],[3468]],[[3458],[0]],[[127,3828,3592,2096,3456]],[[128,3191]],[[127,3826,83,200,3460]],[[3837],[3462]],[[627],[0]],[[526,3461,3855]],[[3466,3463],[3466],[0]],[[127,3465,219,200,3467,3463,3425]],[[92],[175],[605]],[[750,3467]],[[3460],[3826],[527],[3407,202],[525]],[[127,3826,106,200,2461]],[[260,3816]],[[271,3816]],[[3474],[0]],[[207,3471,138,3479]],[[540]],[[101],[3473]],[[3476,3475],[3476],[0]],[[750,3481]],[[3478,3477],[3478],[0]],[[750,3484]],[[3481,3475],[83,3480,3484,3477]],[[3843],[3382],[3831]],[[3482,763,3483]],[[3382],[3826]],[[377],[485]],[[3485,763,3486]],[[3382],[3826]],[[3487],[473]],[[64],[557],[87],[89],[88],[53],[492],[576],[73],[107],[336],[355]],[[3493],[0]],[[511,3490,3488]],[[3826],[3462]],[[3492,3491],[3492],[0]],[[750,3501]],[[506,3501,3491]],[[3497],[0]],[[3500],[0]],[[469,3494,3495]],[[3826],[3462]],[[3499,3498],[3499],[0]],[[750,3501]],[[506,3501,3498]],[[3487,763,3480]],[[387,3826]],[[66,3826]],[[3507],[0]],[[186,3504,3826,248,3828]],[[367],[0]],[[3506,203]],[[3511],[0]],[[3512],[0]],[[21,3191],[171,3191,3409,3508,3509]],[[542,3191]],[[160,3191]],[[3766,3528,2098]],[[3515],[3556]],[[3516]],[[62,3413]],[[2041,730]],[[3527],[0]],[[3520,2232,3574,2235],[205,2646,2239,3574,2236],[523,2646,2239,3574,2237],[3518,3525]],[[265],[236]],[[420,265],[609,2646]],[[3517]],[[3524],[0]],[[3522]],[[3521,2232,3574,2235],[199,265,2239,3567,3556],[3516,3523]],[[3826],[0]],[[86,3526]],[[3592,3539]],[[3530],[0]],[[209,12]],[[3532],[0]],[[637],[554]],[[3542,3533],[3542],[0]],[[3533]],[[3552,3535],[3552],[0]],[[3535]],[[3534],[3536]],[[2096,3529,17,3413,3531,3537]],[[3538],[3533]],[[420],[0]],[[265],[0]],[[2041,3863],[3543],[128,3545],[3546],[383,614,372,3326],[24],[501,128,627],[3540,265],[609,3541],[75,3855],[3697],[74,3550],[553,3551],[3547],[3548],[3549]],[[371,720]],[[3413]],[[3845],[372,3326],[3544]],[[3582]],[[707,3840]],[[3518,3516]],[[3517]],[[192],[152],[128]],[[142],[334],[128]],[[609,3541],[75,3851],[3195,376],[3540,265]],[[3830],[0]],[[3558],[0]],[[3563],[0]],[[443,3807,3553,3554,3555]],[[204],[402],[513]],[[320,3557]],[[3560],[0]],[[383,133,3564]],[[3562],[0]],[[383,614,3564]],[[383,614,3564,3559],[383,133,3564,3561]],[[3565],[506,3863],[373,3],[506,128]],[[471],[49]],[[3568,3566],[3568],[0]],[[753,3569,3566,748]],[[750,3569]],[[3826,3394,2123]],[[3572,3570],[3572],[0]],[[753,3573,3570,748]],[[750,3573]],[[3569],[3413,2123]],[[3575],[3576]],[[3571]],[[3567]],[[3578]],[[44],[488],[220]],[[3580],[3583]],[[264,2127,3837],[75,3855],[3581]],[[3582]],[[662],[661]],[[3584,3577]],[[621],[599]],[[3580],[645,401,3826]],[[3580]],[[3592,-1]],[[3609],[0]],[[3867],[0]],[[32],[0]],[[3601],[0]],[[3593,3394,3588],[3595,3589,3588],[3596,3397,3588],[37,3394],[3597],[3598,3606,3395],[60,3394,3395],[32,3394],[3599,3606,3590],[3604,3394,3590],[628,3606],[656,3394,3588],[116],[586,3242],[583,3242],[113,3242],[587],[39,3394],[3600],[293,628],[293,3591,3395],[589,3395],[580,3394,3395],[332,3395],[291,3395],[164,3847,3395],[506,3847,3395],[501],[3602],[3603]],[[249],[588],[516],[331],[31]],[[416],[0]],[[437],[146,3594]],[[195],[126],[378],[192]],[[42],[41]],[[60,633],[629]],[[358,629],[379],[361,629],[358,60,633],[361,633]],[[330],[290]],[[60,633],[629]],[[262]],[[212],[211],[411],[352],[279],[351],[412],[353]],[[361],[358,60]],[[437],[146,3594]],[[753,3607,748]],[[3840],[783]],[[3610,3608],[3610]],[[3608]],[[512],[612],[657]],[[3613],[0]],[[3614],[3615],[46],[3406,3618,3590],[32,3611]],[[3406,3618]],[[19,3590],[32,19]],[[606,3590],[32,606]],[[753,3838,748]],[[753,787,748]],[[3868],[32],[3619]],[[128]],[[3868],[3621],[3622]],[[128]],[[32]],[[3625,3623],[3625],[0]],[[3629,3623]],[[2053,3629]],[[3629,3626],[3629]],[[3626]],[[3809],[0]],[[163,2127,3799],[3631],[323,2127,3839],[344,2127,3839],[25,2127,3837],[406,2127,3849],[75,2127,3849],[3632],[3633],[24,2127,3839],[399,2127,3645],[3634,2127,3645],[3635,2127,3837],[132,2127,3837],[486,2127,3636],[608,2127,753,3628,748],[3649],[3647],[243,2127,3637],[112,139,2127,3851],[236,139,2127,3851],[572,3639,3826],[553,3640],[84,2127,3851],[264,2127,3837],[3641],[3642],[3643],[3644]],[[376],[3868]],[[721,2843,3630]],[[81,2127,3851]],[[158,2127,3851]],[[544],[545],[546]],[[61],[575]],[[128],[152],[192],[80],[442],[78]],[[373],[191],[268]],[[2127]],[[3638],[0]],[[142],[334]],[[543,592]],[[848,2127,3851]],[[849,2127,3851]],[[2277]],[[3837],[128]],[[128],[0]],[[3646,69,2127,3620]],[[3646,158,2127,3849]],[[3646,3406,2127,3618]],[[3654],[0]],[[3662],[0]],[[3668],[0]],[[405,45,3658,3650,3651,3652]],[[404,3838]],[[277],[0]],[[3665],[0]],[[3828],[0]],[[3655,265,3656,753,3657,748],[3655,220,753,3216,748],[3659,3660]],[[432],[280]],[[753,3216,748],[71,753,3657,748]],[[3664],[0]],[[561,45,3655,3663,3661]],[[220,753,3216,748],[265,3656,3830]],[[560,3838]],[[3666]],[[9,763,3838]],[[3669,3667],[3669],[0]],[[753,3673,3667,748]],[[750,3673]],[[3675],[0]],[[3682,3671],[3682],[0]],[[3678],[0]],[[405,3826,3670,3671,3672]],[[3687],[329]],[[626,273,581,3674],[626,251,3680]],[[3677,3676],[3677],[0]],[[750,3685]],[[753,3685,3676,748]],[[3681,3679],[3681],[0]],[[3687],[753,3687,3679,748]],[[750,3687]],[[572,2127,3826],[2281,163,2127,3799],[368,2127,3838],[3683,2127,3838],[3684,139,2127,3855],[75,2127,3855]],[[323],[344]],[[112],[236]],[[561,3868,3671]],[[3688,3686],[3688],[0]],[[753,3689,3686,748]],[[750,3689]],[[3216],[329]],[[130,763,3758]],[[231,174]],[[231,3407,174]],[[3695],[0]],[[3693,3696]],[[251],[397],[240]],[[3814,3698]],[[69,3620]],[[3592,2096]],[[753,3781,750,3781,748]],[[3702,3700],[3702],[0]],[[3789,3700]],[[750,3789]],[[3705,3703],[3705],[0]],[[3706,3703]],[[750,3706]],[[3773,3873,3707]],[[3191],[128]],[[3406,3618]],[[3712,3709],[3712]],[[71,3709]],[[392],[0]],[[579,45,3851],[3711,157,45,3851],[167,45,3851]],[[3715,3713],[3715]],[[278,3713]],[[3716,45,3851]],[[579],[541]],[[3719,3717],[3719],[0]],[[3758,3717]],[[750,3758]],[[3722,3720],[3722],[0]],[[3727,3720]],[[750,3727]],[[3725,3723],[3725],[0]],[[3739,3723]],[[750,3739]],[[3738],[0]],[[3758,3726]],[[406]],[[3730],[0]],[[3728]],[[45,3851]],[[3733],[0]],[[17,3852],[3731]],[[3735],[0]],[[645,3868]],[[3734,45,734,406]],[[45,3729,3851],[645,3868,3732],[3736]],[[230,3737]],[[3740,3750]],[[2862],[3758]],[[3742],[0]],[[645,3868]],[[734,406]],[[3743],[3851]],[[3746],[0]],[[17,3852,3027]],[[3748],[0]],[[3741,45,3744,3026,3027],[645,3868,3745]],[[3752]],[[230,3747],[3749],[0]],[[727,101,406]],[[141,728,406]],[[458,3851]],[[3757],[0]],[[3868,3754]],[[3868],[0]],[[746,3756],[792]],[[3755],[105,3323]],[[275,3849]],[[3759],[2585]],[[385],[380]],[[284],[375]],[[3764]],[[405,3830]],[[3836],[3831,3385]],[[3767],[3768]],[[3826]],[[3765]],[[3826]],[[3772,3770],[3772],[0]],[[753,3769,3770,748]],[[750,3769]],[[3765]],[[3773],[3778]],[[3826]],[[3765]],[[3779],[0]],[[3826,751,3777,775]],[[3826,751]],[[3826]],[[3826]],[[3831]],[[3831]],[[3831]],[[3831]],[[3831]],[[3831]],[[3831],[3836]],[[3831],[3836]],[[3826]],[[3826]],[[3826]],[[3826]],[[3831]],[[3831]],[[3826]],[[3868]],[[3868]],[[3868]],[[3831],[3836]],[[3781,3836]],[[3806],[0]],[[3826,3802]],[[3805],[0]],[[751,775]],[[751,775],[3836,3804]],[[3831],[3836]],[[3810,3808],[3810],[0]],[[3807,3808]],[[750,3807]],[[3813,3811],[3813],[0]],[[3803,3811]],[[750,3803]],[[3826]],[[3823],[3885]],[[3815]],[[3823],[3894]],[[3817]],[[3826]],[[3849]],[[3826]],[[3826]],[[3824],[3825]],[[793],[781]],[[784]],[[3823],[3877]],[[3829,3827],[3829],[0]],[[3826,3827]],[[750,3826]],[[753,3828,748]],[[3826,3385]],[[3834],[0]],[[3826,3832],[3835]],[[3836,3385]],[[3836,3836]],[[751,3826]],[[787],[786],[788],[791],[783],[785]],[[787],[786],[788],[791]],[[787],[788],[791],[783],[785]],[[787],[3841],[791],[788]],[[786]],[[794],[0]],[[3855],[3861],[3864],[3863],[3862],[3842,3844]],[[786],[782]],[[3843],[778,3837],[773,3837]],[[3848,3846],[3848],[0]],[[753,3851,3846,748]],[[750,3851]],[[790],[3850]],[[784]],[[3849],[786],[782]],[[3849],[3853]],[[786]],[[3849,3854],[3849],[0]],[[3856,3854]],[[3842,3849],[789]],[[3849]],[[3860,3858],[3860],[0]],[[3849,3858]],[[750,3849]],[[787],[788],[791],[783],[785]],[[596],[183]],[[376],[801]],[[116,3849],[586,3849],[583,3849]],[[3606],[3867]],[[3606]],[[753,787,750,787,748]],[[3826],[3849]],[[3823],[3898]],[[3817],[3849]],[[3840],[3823]],[[753,748]],[[763],[756]],[[658],[673],[214],[284],[502]],[[214,751],[284,751],[502,751]],[[658,751],[673,751],[214,751],[284,751],[502,751]],[[3881],[3882]],[[510]],[[714]],[[3885],[3900],[173],[3878],[3879]],[[3880]],[[3890],[3883],[3884],[3889],[3899]],[[173],[714],[510]],[[19],[29],[46],[47],[58],[61],[677],[75],[77],[90],[123],[147],[159],[196],[197],[219],[222],[234],[245],[267],[373],[415],[417],[455],[468],[480],[489],[512],[514],[543],[552],[597],[606],[607],[651]],[[3887],[3888]],[[3904],[170],[188],[369],[423],[427],[451],[459],[709],[565]],[[3886]],[[3890],[3889],[3899]],[[170],[188],[369],[423],[427],[451],[459],[709],[565]],[[3891],[3893]],[[3],[2],[724],[5],[660],[6],[7],[8],[9],[12],[16],[21],[812],[23],[24],[25],[26],[27],[33],[37],[40],[41],[42],[44],[675],[50],[53],[54],[56],[57],[63],[64],[65],[66],[67],[68],[70],[71],[74],[73],[76],[78],[79],[664],[80],[81],[82],[84],[85],[87],[88],[89],[91],[96],[101],[107],[111],[112],[113],[116],[122],[129],[130],[715],[132],[716],[138],[139],[140],[141],[142],[150],[151],[152],[156],[158],[160],[730],[162],[163],[848],[164],[166],[165],[168],[169],[171],[172],[680],[176],[177],[179],[180],[181],[184],[185],[189],[190],[191],[192],[682],[201],[202],[204],[208],[211],[212],[213],[713],[840],[216],[210],[841],[220],[674],[705],[225],[224],[229],[230],[233],[725],[235],[238],[844],[243],[244],[661],[250],[255],[256],[258],[259],[262],[264],[847],[268],[270],[273],[274],[279],[280],[670],[286],[288],[289],[296],[735],[298],[299],[319],[300],[729],[301],[302],[303],[304],[712],[305],[306],[307],[308],[309],[310],[312],[311],[313],[314],[316],[738],[317],[318],[736],[321],[322],[323],[324],[327],[328],[333],[334],[335],[336],[337],[340],[343],[344],[346],[348],[350],[351],[352],[353],[354],[355],[356],[357],[358],[361],[363],[702],[365],[366],[367],[368],[671],[374],[689],[377],[379],[381],[732],[728],[384],[386],[387],[719],[390],[703],[717],[690],[398],[399],[400],[401],[402],[403],[404],[406],[704],[407],[408],[409],[410],[411],[412],[413],[693],[418],[419],[421],[737],[424],[426],[425],[429],[430],[431],[434],[438],[439],[441],[846],[442],[718],[445],[446],[447],[448],[449],[452],[842],[454],[456],[460],[462],[461],[463],[466],[464],[465],[617],[695],[470],[472],[727],[473],[851],[474],[706],[476],[659],[481],[482],[483],[485],[486],[488],[490],[492],[721],[849],[722],[720],[723],[495],[496],[500],[501],[503],[508],[513],[669],[515],[517],[519],[520],[521],[813],[814],[815],[817],[816],[818],[819],[820],[821],[822],[823],[824],[825],[826],[829],[828],[830],[831],[833],[832],[834],[827],[835],[522],[836],[837],[838],[839],[528],[529],[530],[532],[535],[538],[707],[540],[542],[544],[545],[546],[547],[553],[556],[557],[558],[559],[560],[561],[566],[567],[568],[571],[572],[575],[576],[577],[578],[580],[581],[708],[697],[584],[585],[583],[586],[845],[592],[593],[598],[599],[698],[601],[602],[603],[604],[610],[613],[615],[618],[619],[625],[627],[631],[711],[636],[662],[638],[639],[640],[641],[646],[647],[648],[650],[652],[653],[656],[843]],[[731],[741],[735],[738],[736],[733],[744],[740],[737],[734],[739],[742],[743],[583],[586]],[[3892]],[[3896],[3897]],[[3904],[3900]],[[3895]],[[3890],[3884],[3899]],[[3890],[3883],[3884],[3889]],[[214],[284],[658],[673],[502]],[[3901],[3902],[3903]],[[2],[19],[12],[27],[29],[46],[47],[58],[61],[677],[66],[75],[77],[90],[123],[147],[159],[196],[197],[201],[210],[219],[222],[224],[245],[661],[267],[373],[387],[390],[398],[401],[413],[415],[417],[452],[455],[468],[470],[659],[480],[489],[720],[721],[722],[723],[496],[503],[512],[519],[514],[520],[543],[552],[597],[606],[607],[615],[662],[648],[651]],[[510]],[[234]],[[3905],[3906],[3908],[3910],[3911]],[[3],[724],[5],[6],[7],[8],[9],[13],[16],[21],[22],[24],[23],[25],[26],[33],[37],[40],[42],[41],[44],[675],[50],[53],[54],[56],[57],[63],[65],[64],[67],[68],[70],[73],[74],[71],[76],[78],[79],[664],[80],[81],[82],[84],[85],[87],[89],[88],[91],[93],[96],[101],[107],[112],[111],[113],[116],[122],[129],[130],[132],[136],[716],[138],[139],[140],[141],[142],[150],[151],[152],[158],[160],[164],[163],[162],[165],[166],[168],[169],[171],[680],[176],[179],[180],[181],[185],[184],[682],[202],[156],[204],[189],[190],[191],[192],[208],[212],[211],[213],[216],[214],[220],[674],[705],[225],[229],[230],[233],[250],[235],[238],[244],[725],[255],[256],[258],[259],[243],[262],[850],[264],[268],[270],[273],[274],[279],[280],[284],[670],[286],[288],[289],[323],[316],[319],[300],[304],[301],[302],[318],[303],[712],[306],[298],[305],[299],[314],[308],[307],[317],[309],[310],[311],[312],[313],[296],[321],[322],[325],[324],[327],[328],[333],[334],[335],[336],[337],[340],[343],[344],[348],[346],[350],[351],[352],[353],[354],[355],[357],[356],[358],[361],[363],[702],[365],[367],[366],[374],[368],[689],[671],[377],[379],[381],[728],[382],[384],[719],[703],[717],[690],[399],[400],[402],[403],[404],[406],[704],[407],[409],[410],[408],[411],[412],[693],[418],[419],[708],[421],[424],[425],[426],[429],[430],[431],[434],[438],[439],[441],[440],[442],[445],[446],[447],[448],[449],[676],[454],[456],[460],[461],[462],[463],[464],[465],[466],[617],[695],[472],[727],[473],[474],[706],[476],[481],[482],[483],[485],[486],[488],[490],[492],[495],[501],[500],[502],[508],[513],[669],[515],[517],[521],[522],[528],[529],[530],[533],[532],[535],[538],[707],[540],[542],[544],[545],[546],[547],[553],[556],[557],[558],[559],[561],[560],[565],[566],[567],[568],[576],[571],[575],[572],[577],[578],[580],[581],[697],[592],[593],[583],[584],[585],[586],[598],[599],[600],[698],[601],[602],[604],[603],[610],[613],[618],[619],[631],[711],[636],[627],[639],[638],[640],[647],[641],[650],[652],[653],[656]],[[510]],[[99],[234],[206],[484],[487]],[[3907]],[[172],[177],[386],[565],[625],[646]],[[3909]],[[660]]]]; +return ['rules_offset'=>2000,'rules_names'=>['query','%f1','%f2','%f3','simpleStatement','%f4','%f5','%f6','%f7','alterStatement','%f8','%f9','%f10','alterInstance','%f11','%f12','%f13','%f14','%f15','%f16','%f17','%f18','%f19','%f20','%f21','%f22','%f23','%f24','alterDatabase','%f25','%f26','%f27','%f28','%f29','%f30','%f31','%f32','%f33','%f34','alterEvent','%f35','%f36','%f37','%f38','%f39','%f40','%f41','%f42','%f43','%f44','alterLogfileGroup','%f45','alterLogfileGroupOptions','%f46','%f47','alterLogfileGroupOption','alterServer','%f48','%f49','%f50','alterTable','%f51','%f52','%f53','%f54','alterTableActions','%f55','%f56','%f57','alterCommandList','%f58','%f59','alterCommandsModifierList','%f60','standaloneAlterCommands','%f61','%f62','%f63','%f64','%f65','%f66','%f67','alterPartition','%f68','%f69','%f70','%f71','%f72','alterList','%f73','%f74','%f75','alterCommandsModifier','%f76','%f77','%f78','%f79','alterListItem','%f80','%f81','%f82','%f83','%f84','%f85','%f86','%f87','%f88','%f89','%f90','%f91','%f92','%f93','%f94','%f95','%f96','%f97','%f98','%f99','%f100','%f101','%f102','place','restrict','%f103','%f104','alterOrderList','%f105','%f106','alterAlgorithmOption','%f107','alterLockOption','%f108','%f109','%f110','indexLockAndAlgorithm','withValidation','%f111','%f112','removePartitioning','allOrPartitionNameList','alterTablespace','%f113','%f114','%f115','%f116','%f117','%f118','%f119','%f120','%f121','%f122','%f123','%f124','alterUndoTablespace','%f125','%f126','undoTableSpaceOptions','%f127','undoTableSpaceOption','%f128','alterTablespaceOptions','%f129','alterTablespaceOption','%f130','changeTablespaceOption','%f131','%f132','alterView','%f133','viewTail','%f134','viewSelect','%f135','viewCheckOption','%f136','createStatement','%f137','%f138','%f139','%f140','%f141','%f142','createDatabase','createDatabaseOption','%f143','%f144','createTable','%f145','%f146','%f147','%f148','%f149','%f150','%f151','tableElementList','%f152','tableElement','%f153','%f154','duplicateAsQueryExpression','%f155','queryExpressionOrParens','%f156','createRoutine','%f157','%f158','%f159','createProcedure','%f160','%f161','%f162','%f163','%f164','%f165','createFunction','%f166','%f167','%f168','%f169','%f170','%f171','createUdf','%f172','routineCreateOption','%f173','routineAlterOptions','routineOption','%f174','%f175','createIndex','%f176','%f177','%f178','%f179','%f180','%f181','%f182','%f183','%f184','%f185','%f186','indexNameAndType','%f187','%f188','createIndexTarget','%f189','createLogfileGroup','%f190','%f191','logfileGroupOptions','%f192','logfileGroupOption','createServer','%f193','serverOptions','%f194','serverOption','%f195','%f196','createTablespace','%f197','createUndoTablespace','tsDataFileName','%f198','%f199','%f200','tsDataFile','%f201','tablespaceOptions','%f202','tablespaceOption','%f203','%f204','%f205','tsOptionInitialSize','tsOptionUndoRedoBufferSize','%f206','tsOptionAutoextendSize','tsOptionMaxSize','tsOptionExtentSize','tsOptionNodegroup','%f207','tsOptionEngine','tsOptionEngineAttribute','tsOptionWait','%f208','tsOptionComment','tsOptionFileblockSize','tsOptionEncryption','%f209','createView','viewReplaceOrAlgorithm','viewAlgorithm','%f210','viewSuid','%f211','%f212','createTrigger','%f213','%f214','%f215','%f216','triggerFollowsPrecedesClause','%f217','%f218','%f219','%f220','%f221','createEvent','%f222','%f223','%f224','%f225','%f226','createRole','%f227','createSpatialReference','srsAttribute','dropStatement','%f228','%f229','%f230','%f231','%f232','dropDatabase','dropEvent','dropFunction','dropProcedure','dropIndex','%f233','dropLogfileGroup','%f234','%f235','%f236','dropLogfileGroupOption','dropServer','%f237','dropTable','%f238','%f239','%f240','dropTableSpace','%f241','%f242','%f243','dropTrigger','%f244','dropView','%f245','dropRole','dropSpatialReference','dropUndoTablespace','%f246','renameTableStatement','%f247','%f248','renamePair','%f249','truncateTableStatement','importStatement','%f250','callStatement','%f251','%f252','%f253','%f254','deleteStatement','%f255','%f256','%f257','%f258','%f259','%f260','%f261','%f262','%f263','%f264','%f265','partitionDelete','%f266','deleteStatementOption','doStatement','%f267','%f268','%f269','handlerStatement','%f270','%f271','%f272','%f273','handlerReadOrScan','%f274','%f275','%f276','%f277','%f278','%f279','%f280','%f281','%f282','insertStatement','%f283','%f284','%f285','%f286','%f287','%f288','%f289','insertLockOption','%f290','insertFromConstructor','%f291','%f292','%f293','fields','%f294','insertValues','%f295','insertQueryExpression','%f296','%f297','valueList','%f298','%f299','values','%f300','%f301','%f302','valuesReference','insertUpdateList','%f303','%f304','%f305','%f306','%f307','%f308','%f309','loadStatement','%f310','%f311','dataOrXml','xmlRowsIdentifiedBy','%f312','%f313','%f314','loadDataFileTail','%f315','%f316','%f317','%f318','loadDataFileTargetList','%f319','fieldOrVariableList','%f320','%f321','%f322','%f323','replaceStatement','%f324','%f325','%f326','selectStatement','selectStatementWithInto','%f327','%f328','queryExpression','%f329','%f330','%f331','%f332','%f333','%f334','queryExpressionBody','%f335','%f336','%f337','%f338','%f339','queryTerm','%f340','%f341','%f342','%f343','queryExpressionParens','queryPrimary','%f344','%f345','%f346','%f347','%f348','%f349','%f350','%f351','querySpecification','%f352','%f353','subquery','querySpecOption','limitClause','simpleLimitClause','%f354','limitOptions','%f355','%f356','limitOption','%f357','intoClause','%f358','%f359','%f360','%f361','%f362','%f363','procedureAnalyseClause','%f364','%f365','%f366','havingClause','%f367','windowClause','%f368','windowDefinition','windowSpec','%f369','%f370','%f371','%f372','%f373','windowSpecDetails','%f374','%f375','%f376','%f377','windowFrameClause','windowFrameUnits','windowFrameExtent','windowFrameStart','windowFrameBetween','windowFrameBound','windowFrameExclusion','%f378','%f379','%f380','withClause','%f381','commonTableExpression','%f382','groupByClause','olapOption','%f383','orderClause','direction','fromClause','%f384','%f385','tableReferenceList','%f386','%f387','tableValueConstructor','%f388','explicitTable','rowValueExplicit','selectOption','%f389','%f390','%f391','lockingClauseList','%f392','%f393','lockingClause','%f394','%f395','%f396','%f397','lockStrengh','%f398','lockedRowAction','%f399','selectItemList','%f400','%f401','%f402','selectItem','selectAlias','%f403','whereClause','%f404','tableReference','%f405','%f406','%f407','escapedTableReference','%f408','joinedTable','%f409','%f410','%f411','%f412','naturalJoinType','%f413','%f414','innerJoinType','%f415','outerJoinType','%f416','tableFactor','%f417','%f418','singleTable','singleTableParens','%f419','%f420','derivedTable','%f421','%f422','%f423','tableReferenceListParens','%f424','tableFunction','%f425','columnsClause','%f426','%f427','%f428','%f429','jtColumn','%f430','%f431','%f432','%f433','onEmptyOrError','onEmpty','onError','jtOnResponse','setOperationOption','%f434','tableAlias','%f435','%f436','%f437','indexHintList','%f438','%f439','indexHint','indexHintType','keyOrIndex','%f440','constraintKeyType','indexHintClause','%f441','%f442','indexList','%f443','indexListElement','%f444','%f445','updateStatement','%f446','%f447','transactionOrLockingStatement','%f448','%f449','%f450','%f451','transactionStatement','%f452','%f453','%f454','beginWork','%f455','transactionCharacteristicList','%f456','transactionCharacteristic','%f457','%f458','savepointStatement','%f459','%f460','%f461','%f462','%f463','%f464','%f465','lockStatement','%f466','%f467','%f468','%f469','%f470','lockItem','lockOption','xaStatement','%f471','%f472','%f473','%f474','%f475','%f476','%f477','%f478','%f479','%f480','xaConvert','%f481','%f482','%f483','%f484','xid','%f485','%f486','%f487','%f488','replicationStatement','%f489','%f490','%f491','%f492','%f493','%f494','%f495','%f496','%f497','%f498','%f499','resetOption','%f500','masterResetOptions','%f501','%f502','%f503','%f504','replicationLoad','%f505','changeMaster','%f506','changeMasterOptions','%f507','masterOption','privilegeCheckDef','tablePrimaryKeyCheckDef','masterTlsCiphersuitesDef','masterFileDef','%f508','serverIdList','%f509','%f510','%f511','%f512','%f513','changeReplication','%f514','%f515','%f516','%f517','changeReplicationSourceOptions','%f518','replicationSourceOption','%f519','%f520','%f521','%f522','%f523','%f524','%f525','%f526','%f527','%f528','%f529','%f530','%f531','%f532','%f533','%f534','%f535','%f536','%f537','%f538','%f539','%f540','%f541','%f542','%f543','%f544','%f545','%f546','%f547','%f548','%f549','filterDefinition','%f550','filterDbList','%f551','%f552','filterTableList','%f553','%f554','filterStringList','%f555','filterWildDbTableString','%f556','filterDbPairList','%f557','%f558','%f559','slave','%f560','%f561','slaveUntilOptions','%f562','%f563','%f564','%f565','%f566','slaveConnectionOptions','%f567','%f568','%f569','%f570','%f571','%f572','%f573','%f574','%f575','%f576','slaveThreadOptions','%f577','slaveThreadOption','groupReplication','%f578','preparedStatement','%f579','%f580','%f581','executeStatement','%f582','%f583','executeVarList','%f584','cloneStatement','%f585','%f586','%f587','%f588','%f589','%f590','%f591','dataDirSSL','ssl','accountManagementStatement','%f592','%f593','%f594','alterUser','%f595','%f596','alterUserTail','%f597','%f598','%f599','%f600','%f601','%f602','userFunction','createUser','%f603','%f604','createUserTail','%f605','%f606','%f607','%f608','%f609','%f610','%f611','%f612','defaultRoleClause','%f613','%f614','%f615','requireClause','%f616','%f617','%f618','connectOptions','%f619','accountLockPasswordExpireOptions','%f620','%f621','%f622','%f623','%f624','%f625','%f626','%f627','%f628','%f629','%f630','dropUser','%f631','%f632','grant','%f633','%f634','%f635','%f636','%f637','%f638','%f639','%f640','%f641','%f642','%f643','%f644','grantTargetList','%f645','%f646','grantOptions','%f647','%f648','%f649','exceptRoleList','withRoles','%f650','%f651','%f652','grantAs','versionedRequireClause','%f653','%f654','renameUser','%f655','%f656','%f657','revoke','%f658','%f659','%f660','%f661','%f662','%f663','%f664','%f665','%f666','%f667','%f668','onTypeTo','%f669','%f670','%f671','%f672','aclType','%f673','roleOrPrivilegesList','%f674','%f675','%f676','roleOrPrivilege','%f677','%f678','%f679','%f680','%f681','%f682','%f683','%f684','%f685','%f686','%f687','grantIdentifier','%f688','%f689','%f690','%f691','requireList','%f692','%f693','requireListElement','grantOption','%f694','setRole','%f695','%f696','%f697','%f698','roleList','%f699','%f700','role','%f701','%f702','%f703','tableAdministrationStatement','%f704','%f705','%f706','%f707','%f708','%f709','%f710','%f711','%f712','%f713','histogram','%f714','%f715','checkOption','%f716','repairType','%f717','%f718','installUninstallStatment','%f719','%f720','installOptionType','%f721','installSetValue','%f722','%f723','installSetValueList','%f724','setStatement','%f725','startOptionValueList','%f726','%f727','%f728','%f729','%f730','%f731','%f732','%f733','%f734','%f735','%f736','transactionCharacteristics','%f737','%f738','transactionAccessMode','%f739','isolationLevel','%f740','%f741','%f742','optionValueListContinued','%f743','optionValueNoOptionType','%f744','%f745','optionValue','%f746','setSystemVariable','startOptionValueListFollowingOptionType','optionValueFollowingOptionType','setExprOrDefault','%f747','%f748','%f749','showStatement','%f750','%f751','%f752','%f753','%f754','%f755','%f756','%f757','%f758','%f759','%f760','%f761','%f762','%f763','%f764','%f765','%f766','%f767','%f768','%f769','%f770','%f771','%f772','%f773','%f774','%f775','%f776','%f777','%f778','%f779','%f780','%f781','%f782','%f783','showCommandType','%f784','nonBlocking','%f785','%f786','fromOrIn','inDb','profileType','%f787','%f788','otherAdministrativeStatement','%f789','%f790','%f791','%f792','%f793','%f794','keyCacheListOrParts','%f795','keyCacheList','%f796','%f797','assignToKeycache','assignToKeycachePartition','%f798','cacheKeyList','keyUsageElement','%f799','keyUsageList','%f800','%f801','flushOption','%f802','%f803','%f804','logType','%f805','flushTables','%f806','%f807','%f808','flushTablesOptions','%f809','%f810','preloadTail','%f811','%f812','preloadList','%f813','%f814','preloadKeys','%f815','adminPartition','resourceGroupManagement','%f816','%f817','%f818','createResourceGroup','%f819','%f820','resourceGroupVcpuList','%f821','%f822','vcpuNumOrRange','%f823','resourceGroupPriority','resourceGroupEnableDisable','%f824','alterResourceGroup','%f825','setResourceGroup','%f826','%f827','threadIdList','%f828','dropResourceGroup','utilityStatement','%f829','%f830','describeStatement','%f831','%f832','%f833','explainStatement','%f834','%f835','%f836','%f837','%f838','%f839','%f840','explainableStatement','%f841','%f842','%f843','helpCommand','useCommand','restartServer','%f844','expr','%f845','%f846','%f847','%f848','%f849','%f850','%f851','%f852','%f853','%f854','boolPri','%f855','%f856','compOp','%f857','predicate','%f858','%f859','%f860','%f861','predicateOperations','%f862','%f863','%f864','bitExpr','%f865','%f866','%f867','%f868','%f869','%f870','simpleExpr','%f871','%f872','%f873','%f874','%f875','%f876','%f877','%f878','%f879','%f880','%f881','%f882','%f883','%f884','%f885','%f886','%f887','%f888','%f889','%f890','%f891','%f892','arrayCast','%f893','jsonOperator','%f894','%f895','%f896','%f897','%f898','%f899','%f900','%f901','%f902','%f903','%f904','%f905','%f906','%f907','%f908','%f909','sumExpr','%f910','%f911','%f912','%f913','%f914','%f915','%f916','%f917','%f918','%f919','%f920','%f921','%f922','%f923','%f924','%f925','%f926','%f927','%f928','%f929','%f930','%f931','%f932','%f933','%f934','%f935','%f936','%f937','groupingOperation','%f938','%f939','%f940','windowFunctionCall','%f941','%f942','%f943','%f944','%f945','windowingClause','%f946','%f947','leadLagInfo','%f948','%f949','nullTreatment','%f950','%f951','jsonFunction','inSumExpr','identListArg','%f952','identList','%f953','%f954','fulltextOptions','%f955','%f956','%f957','%f958','%f959','%f960','%f961','%f962','runtimeFunctionCall','%f963','%f964','%f965','%f966','%f967','%f968','%f969','%f970','%f971','%f972','%f973','%f974','%f975','%f976','%f977','%f978','%f979','%f980','%f981','%f982','geometryFunction','%f983','%f984','timeFunctionParameters','fractionalPrecision','%f985','weightStringLevels','%f986','%f987','%f988','%f989','weightStringLevelListItem','%f990','%f991','%f992','dateTimeTtype','trimFunction','%f993','%f994','%f995','substringFunction','%f996','%f997','%f998','%f999','%f1000','%f1001','functionCall','%f1002','udfExprList','%f1003','udfExpr','variable','userVariable','%f1004','%f1005','systemVariable','internalVariableName','%f1006','%f1007','%f1008','whenExpression','thenExpression','elseExpression','%f1009','%f1010','%f1011','%f1012','castType','%f1013','%f1014','%f1015','%f1016','%f1017','exprList','%f1018','charset','notRule','not2Rule','interval','%f1019','intervalTimeStamp','exprListWithParentheses','exprWithParentheses','simpleExprWithParentheses','%f1020','orderList','%f1021','orderExpression','%f1022','groupList','%f1023','groupingExpression','channel','%f1024','compoundStatement','returnStatement','ifStatement','%f1025','ifBody','%f1026','thenStatement','%f1027','compoundStatementList','%f1028','%f1029','%f1030','caseStatement','%f1031','elseStatement','%f1032','labeledBlock','unlabeledBlock','label','%f1033','%f1034','beginEndBlock','labeledControl','unlabeledControl','loopBlock','whileDoBlock','repeatUntilBlock','%f1035','spDeclarations','%f1036','spDeclaration','%f1037','variableDeclaration','%f1038','conditionDeclaration','spCondition','%f1039','sqlstate','%f1040','handlerDeclaration','%f1041','%f1042','handlerCondition','cursorDeclaration','iterateStatement','leaveStatement','%f1043','getDiagnostics','%f1044','%f1045','%f1046','%f1047','%f1048','%f1049','%f1050','signalAllowedExpr','statementInformationItem','%f1051','%f1052','conditionInformationItem','%f1053','%f1054','signalInformationItemName','%f1055','signalStatement','%f1056','%f1057','%f1058','%f1059','%f1060','%f1061','resignalStatement','%f1062','%f1063','%f1064','%f1065','signalInformationItem','cursorOpen','cursorClose','%f1066','cursorFetch','%f1067','%f1068','%f1069','%f1070','schedule','%f1071','%f1072','columnDefinition','checkOrReferences','%f1073','checkConstraint','constraintEnforcement','%f1074','tableConstraintDef','%f1075','%f1076','%f1077','%f1078','%f1079','%f1080','%f1081','constraintName','fieldDefinition','%f1082','%f1083','%f1084','%f1085','%f1086','%f1087','%f1088','%f1089','%f1090','%f1091','%f1092','%f1093','%f1094','columnAttribute','%f1095','%f1096','%f1097','%f1098','%f1099','%f1100','%f1101','columnFormat','storageMedia','gcolAttribute','%f1102','%f1103','%f1104','references','%f1105','%f1106','%f1107','%f1108','%f1109','%f1110','%f1111','deleteOption','%f1112','%f1113','keyList','%f1114','keyPart','%f1115','keyListWithExpression','%f1116','keyPartOrExpression','keyListVariants','%f1117','%f1118','indexType','%f1119','indexOption','commonIndexOption','%f1120','visibility','indexTypeClause','%f1121','fulltextIndexOption','spatialIndexOption','dataTypeDefinition','%f1122','%f1123','%f1124','%f1125','dataType','%f1126','%f1127','%f1128','%f1129','%f1130','%f1131','%f1132','%f1133','%f1134','%f1135','%f1136','nchar','realType','fieldLength','%f1137','%f1138','fieldOptions','%f1139','%f1140','charsetWithOptBinary','%f1141','ascii','unicode','wsNumCodepoints','typeDatetimePrecision','charsetName','%f1142','collationName','%f1143','%f1144','%f1145','createTableOptions','%f1146','%f1147','createTableOptionsSpaceSeparated','%f1148','createTableOption','%f1149','%f1150','%f1151','%f1152','%f1153','%f1154','%f1155','%f1156','%f1157','%f1158','%f1159','%f1160','%f1161','%f1162','%f1163','ternaryOption','%f1164','defaultCollation','defaultEncryption','defaultCharset','%f1165','%f1166','%f1167','partitionClause','%f1168','%f1169','%f1170','%f1171','partitionTypeDef','%f1172','%f1173','%f1174','subPartitions','%f1175','%f1176','partitionKeyAlgorithm','%f1177','%f1178','partitionDefinitions','%f1179','%f1180','%f1181','%f1182','partitionDefinition','%f1183','%f1184','%f1185','%f1186','%f1187','%f1188','partitionValuesIn','%f1189','partitionOption','%f1190','%f1191','subpartitionDefinition','%f1192','partitionValueItemListParen','%f1193','partitionValueItem','definerClause','ifExists','ifNotExists','%f1194','procedureParameter','%f1195','functionParameter','collate','typeWithOptCollate','schemaIdentifierPair','%f1196','viewRefList','%f1197','%f1198','updateList','%f1199','updateElement','%f1200','charsetClause','%f1201','fieldsClause','%f1202','fieldTerm','%f1203','linesClause','lineTerm','%f1204','%f1205','userList','%f1206','%f1207','createUserList','%f1208','%f1209','alterUserList','%f1210','%f1211','createUserEntry','%f1212','%f1213','%f1214','%f1215','%f1216','%f1217','%f1218','%f1219','%f1220','%f1221','%f1222','alterUserEntry','%f1223','%f1224','%f1225','%f1226','%f1227','%f1228','%f1229','%f1230','%f1231','%f1232','%f1233','retainCurrentPassword','discardOldPassword','replacePassword','%f1234','userIdentifierOrText','%f1235','%f1236','user','likeClause','likeOrWhere','onlineOption','noWriteToBinLog','usePartition','%f1237','fieldIdentifier','%f1238','%f1239','%f1240','columnInternalRef','%f1241','columnInternalRefList','%f1242','columnRef','insertIdentifier','indexName','indexRef','%f1243','tableWild','%f1244','schemaName','schemaRef','procedureName','procedureRef','functionName','functionRef','triggerName','triggerRef','viewName','%f1245','viewRef','%f1246','tablespaceName','tablespaceRef','logfileGroupName','logfileGroupRef','eventName','eventRef','udfName','serverName','serverRef','engineRef','tableName','%f1247','filterTableRef','%f1248','tableRefWithWildcard','%f1249','%f1250','%f1251','tableRef','%f1252','%f1253','tableRefList','%f1254','%f1255','tableAliasRefList','%f1256','parameterName','labelIdentifier','labelRef','roleIdentifier','roleRef','pluginRef','componentRef','resourceGroupRef','windowName','pureIdentifier','%f1257','%f1258','identifier','%f1259','identifierList','%f1260','identifierListWithParentheses','qualifiedIdentifier','%f1261','simpleIdentifier','%f1262','%f1263','dotIdentifier','ulong_number','real_ulong_number','ulonglong_number','real_ulonglong_number','%f1264','%f1265','literal','%f1266','signedLiteral','%f1267','stringList','%f1268','textStringLiteral','%f1269','textString','textStringHash','%f1270','%f1271','textLiteral','%f1272','textStringNoLinebreak','%f1273','textStringLiteralList','%f1274','numLiteral','boolLiteral','nullLiteral','temporalLiteral','floatOptions','standardFloatOptions','precision','textOrIdentifier','lValueIdentifier','roleIdentifierOrText','sizeNumber','parentheses','equal','optionType','varIdentType','setVarIdentType','identifierKeyword','%f1275','%f1276','%f1277','%f1278','%f1279','identifierKeywordsAmbiguous1RolesAndLabels','identifierKeywordsAmbiguous2Labels','labelKeyword','%f1280','%f1281','%f1282','identifierKeywordsAmbiguous3Roles','identifierKeywordsUnambiguous','%f1283','%f1284','%f1285','roleKeyword','%f1286','%f1287','%f1288','lValueKeyword','identifierKeywordsAmbiguous4SystemVariables','roleOrIdentifierKeyword','%f1289','%f1290','%f1291','roleOrLabelKeyword','%f1292','%f1293','%f1294','%f1295','%f1296','%f1297','%f1298'],'grammar'=>[[[-1],[2001,2003]],[[2004],[2668]],[[-1],[0]],[[755,2002],[-1]],[[2009],[2175],[2318],[2353],[2358],[2005],[2361],[2366],[2381],[2385],[2400],[2437],[2457],[2461],[2656],[2659],[2712],[2829],[2006],[2848],[2991],[3010],[3020],[3057],[2007],[3102],[3168],[2008],[3489],[3496]],[[2359]],[[2838]],[[3145]],[[3472]],[[11,2012]],[[2153]],[[2225],[0]],[[2060],[2028],[422,3783,2011],[206,3785,2011],[2167],[2039],[2140],[2010],[2050],[2056],[2013]],[[2026]],[[33]],[[844],[2014]],[[2017],[0]],[[373,480,383,165]],[[451,845,2016]],[[2020],[0]],[[373,480,383,165]],[[451,845,200,57,3830,2019]],[[156],[140]],[[2022,844,846]],[[451,847]],[[482,2015,316,265],[2018],[2021],[2023],[2024]],[[244,2025]],[[3781],[0]],[[109,2027,2031]],[[615,112,139,357]],[[2183,2030],[2183]],[[2030],[2029]],[[3690],[0]],[[2040],[0]],[[2042],[0]],[[2043],[0]],[[2046],[0]],[[2047],[0]],[[2048],[0]],[[2032,170,3797,2033,2034,2035,2036,2037,2038]],[[383,490,3510]],[[371],[0]],[[383,79,2041,418]],[[453,590,3830]],[[2045],[0]],[[383,514]],[[156],[140,2044]],[[75,3859]],[[147,3425]],[[2052],[0]],[[288,217,3795,4,603,3859,2049]],[[2054,2051],[2054],[0]],[[2055,2051]],[[750],[0]],[[2053,2055]],[[2274],[2282],[2284]],[[503,3800,2254]],[[3761],[0]],[[2062],[0]],[[2065],[0]],[[2057,2058,574,3810,2059]],[[232]],[[2061]],[[2066],[0]],[[2067],[0]],[[2063,2074],[2069,2064],[3653],[2138]],[[2072,750]],[[3653],[2138]],[[2070],[0]],[[2072,2068],[2088]],[[750,2088]],[[2073,2071],[2073],[0]],[[2092,2071]],[[750,2092]],[[141,572],[234,572],[2082],[2076]],[[722],[723]],[[2075]],[[3762],[0]],[[3005,2078],[3005],[0]],[[3007,2079],[3007],[0]],[[2084],[0]],[[2135],[0]],[[4,405,2077,2083],[148,405,3832],[438,405,2077,2139],[388,405,2077,2139,2077],[14,405,2077,2139],[62,405,2139,2078],[455,405,2077,2139,2079],[67,405,2077,3842],[597,405,2139],[454,405,2077,2080],[172,405,3830,645,574,3810,2081],[2085],[2086]],[[3668],[404,3842]],[[3832,248,3668]],[[141,405,2139,572]],[[234,405,2139,572]],[[2091,2087],[2091],[0]],[[2089,2087]],[[2097],[3627]],[[2097],[2092],[3627]],[[750,2090]],[[2128],[2130],[2135]],[[72],[0]],[[2121],[0]],[[2116],[0]],[[3697],[0]],[[4,2093,2099],[4,3519],[55,2093,3765,3830,3528,2094],[348,2093,3765,3528,2094],[148,2107],[140,263],[156,263],[11,2093,3765,2111],[2112],[2113],[2114],[2115],[453,2095,3802],[2117],[94,590,3406,2119,2096],[198],[393,45,2125],[2120]],[[3514],[0]],[[3830,3528,2098,2094],[753,2194,748]],[[3765]],[[3765],[0]],[[2101]],[[2100],[2102]],[[62,3830]],[[86,3830]],[[2122],[0]],[[2093,3765,2106],[199,265,2103],[420,265],[2645,3776],[2104],[2105]],[[3413]],[[2108],[3849]],[[506,3582]],[[506,128,2109],[148,128],[2110]],[[11,236,3776,3582]],[[11,62,3830,3517]],[[11,86,3830,3517]],[[453,72,3765,590,3830]],[[590],[17]],[[453,2645,3776,590,3775]],[[128]],[[2118],[3618]],[[615,403]],[[6,3830],[191]],[[471],[49]],[[2551],[0]],[[2126,2124],[2126],[0]],[[3837,2123,2124]],[[750,3837,2123]],[[763],[0]],[[9,2127,2129]],[[128],[3830]],[[287,2127,2131]],[[128],[3830]],[[2130],[0]],[[2128],[0]],[[2128,2132],[2130,2133]],[[2137]],[[645],[646]],[[2136,625]],[[452,403]],[[10],[3832]],[[572,3793,2151]],[[4],[148]],[[2143,2142],[2143],[0]],[[2053,2164]],[[2145],[0]],[[2164,2142]],[[434],[436]],[[55,111,3859,2144],[2146],[371,1]],[[2147]],[[2160]],[[2160],[0]],[[2141,111,3859,2150],[2148],[453,590,3830],[2149]],[[2156],[0]],[[605,572,3793,506,2154,2152]],[[724],[725]],[[2157,2155],[2157],[0]],[[2158,2155]],[[2053,2158]],[[2282]],[[2161,2159],[2161],[0]],[[2162,2159]],[[2053,2162]],[[238,2127,3875],[2277],[2278],[2282],[2163],[2284],[2288]],[[2283]],[[238,2127,3875],[2277],[2278]],[[2292],[0]],[[2294],[0]],[[2165,2032,2166,636,3790,2169]],[[3771],[0]],[[2168,17,2171]],[[2173],[0]],[[2201,2170]],[[2174],[0]],[[645,2172,62,391]],[[50],[284]],[[97,2179]],[[2314]],[[2316]],[[2261]],[[2182],[2186],[2214],[2207],[2221],[2246],[2290],[2297],[2229],[2252],[2259],[2308],[2176],[2177],[2178]],[[3692],[0]],[[2183,2181],[2183],[0]],[[109,2180,3780,2181]],[[3649],[3647],[2184]],[[3648]],[[577],[0]],[[2185,574,2180,3802,2192]],[[2188],[0]],[[753,2194,748]],[[3624],[0]],[[3653],[0]],[[2199],[0]],[[275,3810],[753,275,3810,748],[2187,2189,2190,2191]],[[2195,2193],[2195],[0]],[[2196,2193]],[[750,2196]],[[3513],[3519]],[[2200],[0]],[[17],[0]],[[2197,2198,2201]],[[458],[232]],[[2465],[2483]],[[755],[0]],[[97,2204,2202,-1]],[[2207],[2214],[2221]],[[2212],[0]],[[2223,2206],[2223],[0]],[[2032,422,2209,3782,753,2205,748,2206,3425]],[[2180]],[[2208]],[[2211,2210],[2211],[0]],[[750,3694]],[[3694,2210]],[[2219],[0]],[[2032,206,2216,3784,753,2213,748,474,3698,2206,3425]],[[2180]],[[2215]],[[2218,2217],[2218],[0]],[[750,3696]],[[3696,2217]],[[8],[0]],[[2220,206,3798,474,2222,520,3859]],[[556],[249],[437],[126]],[[2226],[2041,137]],[[2223,2224],[2223]],[[2224]],[[75,3859],[267,537],[373,537],[90,537],[433,537,112],[347,537,112],[537,496,2227]],[[130],[250]],[[2134],[0]],[[2057,2238,2228]],[[3583],[0]],[[3775,2230]],[[2241],[0]],[[2231],[2232]],[[609],[0]],[[3579,2235],[3579],[0]],[[3585,2236],[3585],[0]],[[3586,2237],[3586],[0]],[[2234,236,2233,2244,2235],[205,236,3775,2244,2236],[523,236,3775,2244,2237]],[[3775],[0]],[[2243],[0]],[[2239,2240]],[[621],[599]],[[2242,3577]],[[383,3810,3574]],[[2249],[0]],[[288,217,3794,4,2247,3859,2245]],[[603],[440]],[[2250,2248],[2250],[0]],[[2251,2248]],[[2053,2251]],[[2274],[2275],[2280],[2282],[2284],[2286]],[[503,3799,199,112,648,3872,2254]],[[2255,2253],[2255],[0]],[[390,753,2256,2253,748]],[[750,2256]],[[224,3859],[109,3859],[618,3859],[406,3859],[519,3859],[398,3859],[413,3841]],[[2260],[0]],[[2268],[0]],[[572,3792,2262,2257,2258]],[[620,288,217,3795]],[[605,572,3792,4,2266,2152]],[[2265],[4,2266]],[[2264],[0]],[[4,2266]],[[2263]],[[111,3859]],[[2269,2267],[2269],[0]],[[2270,2267]],[[2053,2270]],[[2274],[2277],[2278],[2279],[2280],[2282],[2271],[2284],[2286],[2272],[2273]],[[2283]],[[2287]],[[2288]],[[238,2127,3875]],[[2276,2127,3875]],[[604],[441]],[[23,2127,3875]],[[324,2127,3875]],[[181,2127,3875]],[[368,2127,3842]],[[553],[0]],[[2281,163,2127,3801]],[[848,2127,3853]],[[2285]],[[638],[374]],[[75,2127,3859]],[[189,2127,3875]],[[158,2127,3853]],[[2291],[0]],[[2289,2032,2166,636,3788,2169]],[[394,458,2165],[2292]],[[9,763,2293]],[[602],[335],[578]],[[537,496,2295]],[[130],[250]],[[2302],[0]],[[2032,594,2299,3786,2300,2301,383,3810,200,153,487,2296,3425]],[[2180]],[[2298]],[[28],[6]],[[242],[614],[133]],[[2304]],[[197],[415]],[[2303,3872]],[[2309],[0]],[[2312],[0]],[[2313],[0]],[[2032,170,2180,3796,383,490,3510,2305,2306,2307,147,3425]],[[383,79,2041,418]],[[2311],[0]],[[383,514]],[[156],[140,2310]],[[75,3859]],[[659,2180,2984]],[[2317,2315],[2317],[0]],[[394,458,523,718,710,3844,2315],[523,718,710,2180,3844,2315]],[[357,580,3861],[715,580,3861],[717,3861,230,45,3844],[716,580,3861]],[[148,2322]],[[2349]],[[2350]],[[2351]],[[2324],[2325],[2326],[2327],[2328],[2330],[2335],[2337],[2341],[2345],[2347],[2319],[2320],[2321]],[[3691],[0]],[[109,2323,3781]],[[170,2323,3797]],[[206,2323,3785]],[[422,2323,3783]],[[2057,236,3776,383,3810,2228]],[[2333],[0]],[[288,217,3795,2329]],[[2332,2331],[2332],[0]],[[2053,2334]],[[2334,2331]],[[2284],[2282]],[[503,2323,3800]],[[2339],[0]],[[2185,2338,2323,3813,2336]],[[574],[571]],[[471],[49]],[[2344],[0]],[[572,3793,2340]],[[2343,2342],[2343],[0]],[[2053,2334]],[[2334,2342]],[[594,2323,3787]],[[2348],[0]],[[636,2323,3701,2346]],[[471],[49]],[[659,2323,2984]],[[523,718,710,2323,3844]],[[605,572,3793,2152]],[[2355,2352],[2355],[0]],[[453,2354,2356,2352]],[[574],[571]],[[750,2356]],[[3810,590,3802]],[[574],[0]],[[597,2357,3810]],[[234,574,203,3863]],[[2363],[0]],[[48,3783,2360]],[[3404],[0]],[[753,2362,748]],[[2368],[0]],[[2380,2365],[2380],[0]],[[2364,133,2365,2377]],[[2543]],[[2367]],[[2636]],[[2371],[0]],[[2369]],[[2585],[0]],[[2378],[0]],[[2550],[0]],[[2499],[0]],[[3816,621,2555,2372],[3810,2370,2373,2372,2374,2375]],[[203,2376],[3816,203,2555,2372]],[[2379]],[[405,753,3832,748]],[[431],[295],[431],[232]],[[147,2384]],[[2578]],[[3404]],[[2382],[2383]],[[219,2389]],[[2498],[0]],[[66],[435,2390,2372,2386]],[[2636],[0]],[[3810,387,2388],[3830,2387]],[[2391],[3830,2394]],[[191],[367]],[[191],[367],[419],[268]],[[763],[769],[765],[768],[764]],[[2392],[2393,753,2424,748]],[[2408],[0]],[[232],[0]],[[248],[0]],[[3763],[0]],[[2429],[0]],[[242,2395,2396,2397,3810,2398,2407,2399]],[[2428]],[[2403],[0]],[[2401]],[[2428]],[[2406],[0]],[[2404]],[[2410,2402],[506,3704,2405],[2418]],[[295],[131],[223]],[[2412],[0]],[[2409,2416]],[[2414],[0]],[[753,2411,748]],[[2415,2413],[2415],[0]],[[3774,2413]],[[750,3774]],[[2417,2421]],[[626],[627]],[[2201],[753,2411,748,2201]],[[2424],[0]],[[2422,2420],[2422],[0]],[[753,2419,748,2420]],[[750,753,2419,748]],[[2427,2423],[2427],[0]],[[2425,2423]],[[3191],[128]],[[3191],[128]],[[750,2426]],[[17,3830,2168]],[[383,151,265,614,3704]],[[2438],[0]],[[284],[0]],[[2439],[0]],[[3708],[0]],[[2441],[0]],[[3710],[0]],[[3714],[0]],[[281,2440,2430,2431,237,3859,2432,248,574,3810,2398,2433,2434,2435,2436,2445]],[[295],[82]],[[458],[232]],[[112],[653]],[[484,230,45,3855]],[[2447],[0]],[[2450],[0]],[[2448],[0]],[[2442,2443,2444]],[[278],[484]],[[232,787,2446]],[[506,3704]],[[2452],[0]],[[753,2449,748]],[[2455,2451],[2455],[0]],[[2453,2451]],[[3773],[3383]],[[3773],[3383]],[[750,2454]],[[2458],[0]],[[458,2456,2397,3810,2398,2459]],[[295],[131]],[[2410],[506,3704],[2418]],[[2566],[0]],[[2465,2460],[2462]],[[753,2462,748],[2465,2506,2460],[2465,2566,2506]],[[2467],[0]],[[2470],[0]],[[2463,2468,2464]],[[2543]],[[2466]],[[2472,2374,2386],[2483,2374,2386]],[[2513]],[[2469]],[[2476,2471],[2476],[0]],[[2478,2471]],[[663]],[[608],[2473]],[[2634],[0]],[[2474,2475,2478]],[[2482,2477],[2482],[0]],[[2479,2477]],[[2484],[2483]],[[2484],[2483]],[[811,2475,2480]],[[2481]],[[753,2465,2460,748]],[[2493],[2485],[2486]],[[2558]],[[2560]],[[2562,2487],[2562],[0]],[[2506],[0]],[[2552],[0]],[[2547],[0]],[[2517],[0]],[[2495],[0]],[[497,2487,2578,2488,2489,2372,2490,2491,2492]],[[2519]],[[2494]],[[2483]],[[10],[143],[555],[223],[536],[531],[532],[534]],[[276,2501]],[[276,2504]],[[2503],[0]],[[2504,2500]],[[750],[381]],[[2502,2504]],[[3830],[2505]],[[754],[791],[788],[787]],[[248,2511]],[[3872],[3383]],[[3872],[3383]],[[2510,2509],[2510],[0]],[[750,2508]],[[396,3853,2433,2435,2436],[150,3853],[2507,2509]],[[2516],[0]],[[422,13,753,2512,748]],[[2515],[0]],[[750,787]],[[787,2514]],[[221,3191]],[[2520,2518],[2520],[0]],[[699,2521,2518]],[[750,2521]],[[3826,17,2522]],[[753,2528,748]],[[2533],[0]],[[2529],[0]],[[2530],[0]],[[3826],[0]],[[2531],[0]],[[405,45,3416,2374,2523],[2524,2550,2523],[2525,2374,2533],[2526,2527,2374,2523]],[[405,45,3416]],[[405,45,3416]],[[405,45,3416]],[[2539],[0]],[[2534,2535,2532]],[[484],[432],[683]],[[2536],[2537]],[[698,693],[3843,693],[754,693],[247,3191,3409,693],[101,487]],[[30,2538,15,2538]],[[2536],[698,682],[3843,682],[754,682],[247,3191,3409,682]],[[680,2540]],[[101,487],[217],[697],[373,690]],[[665],[0]],[[2544,2542],[2544],[0]],[[645,2541,2545,2542]],[[750,2545]],[[3830,2168,17,2496]],[[2548],[0]],[[217,45,3416,2546]],[[645,481],[2549]],[[645,99]],[[393,45,3416]],[[18],[134]],[[203,2553]],[[149],[2555]],[[2556,2554],[2556],[0]],[[2587,2554]],[[750,2587]],[[2559,2557],[2559],[0]],[[626,2561,2557]],[[750,2561]],[[574,3810]],[[487,753,2419,748]],[[2497],[535],[2563],[2564]],[[533]],[[325,763,3842]],[[2569,2565],[2569]],[[2565]],[[2571],[0]],[[2573],[0]],[[200,2574,2567,2568],[287,251,508,346]],[[668,3816]],[[2570]],[[2576]],[[2572]],[[614],[2575]],[[508]],[[669,670],[671]],[[2580,2577],[2580],[0]],[[2579,2577]],[[2582],[775]],[[750,2582]],[[2583],[0]],[[3778],[3191,2581]],[[2198,2584]],[[3830],[3853]],[[643,3191]],[[2593,2586],[2593],[0]],[[2590,2586]],[[3830]],[[2588],[732]],[[2605],[752,2589,2591,747]],[[2605,2586]],[[2594],[0]],[[2601,2587,2592],[2603,2587,2595],[2598,2605]],[[383,3191],[621,3834]],[[383,3191],[621,3834]],[[239],[0]],[[395],[0]],[[359,2596,261],[359,2599,2597,261]],[[272],[478]],[[2602],[0]],[[2600,261],[555]],[[239],[98]],[[2604,2597,261]],[[272],[478]],[[2608],[2609],[2612],[2616],[2606]],[[2618]],[[2640],[0]],[[3810,2398,2388,2607]],[[753,2610,748]],[[2608],[2609]],[[2614],[0]],[[2496,2388,2611],[2615]],[[3771]],[[2613]],[[726,2496,2388,2168]],[[753,2617,748]],[[2555],[2616]],[[701,753,3191,750,3853,2620,748,2388]],[[2621,2619],[2621],[0]],[[71,753,2625,2619,748]],[[750,2625]],[[2627],[0]],[[174],[0]],[[2630],[0]],[[3830,200,703],[3830,3592,2622,2623,704,3853,2624],[702,704,3853,2620]],[[3697]],[[2626]],[[2632],[0]],[[2631],[0]],[[2631,2628],[2632,2629]],[[2633,383,700]],[[2633,383,165]],[[165],[376],[128,3853]],[[143],[10]],[[2638],[0]],[[2635,3830]],[[763]],[[17],[2637]],[[2643,2639],[2643]],[[2639]],[[2648],[0]],[[2651],[0]],[[2644,2645,2641,753,2651,748],[620,2645,2641,753,2642,748]],[[198],[232]],[[265],[236]],[[2645],[0]],[[420,265],[609,2646]],[[200,2649]],[[261],[393,45],[217,45]],[[2652,2650],[2652],[0]],[[2653,2650]],[[750,2653]],[[3830],[420]],[[2658],[0]],[[295],[0]],[[2654,614,2655,2396,2555,506,3704,2372,2374,2375]],[[2543]],[[2657]],[[2664],[2675],[2683],[2691]],[[2670],[0]],[[647],[0]],[[2666],[0]],[[2667],[0]],[[543,592,2660],[77,2661,2662,2663]],[[373],[0]],[[15,2665,54]],[[2665,450]],[[29,2661]],[[2671,2669],[2671],[0]],[[2672,2669]],[[750,2672]],[[645,85,517],[2674]],[[649],[386]],[[435,2673]],[[489,3830],[480,2661,2681],[450,489,3830]],[[2677],[0]],[[15,2665,54]],[[2679],[0]],[[2665,450]],[[489],[0]],[[590,2680,3830],[2676,2678]],[[2685,2682],[2685],[0]],[[287,2684,2689,2682],[2686],[611,2688]],[[571],[574]],[[750,2689]],[[287,244,200,27]],[[244]],[[571],[574],[2687]],[[3810,2388,2690]],[[435,2431],[2655,649]],[[651,2701]],[[543],[29]],[[2694],[0]],[[261],[472]],[[2696],[0]],[[200,340]],[[2698],[0]],[[566,2695]],[[2700],[0]],[[384,407]],[[2692,2707,2693],[159,2707,2697],[417,2707],[77,2707,2699],[480,2707],[439,2702]],[[2705],[0]],[[2704],[0]],[[94,652]],[[2703]],[[2710],[0]],[[3855,2706]],[[2709],[0]],[[750,3841]],[[750,3855,2708]],[[2715,2711],[2715],[0]],[[428,2713,289,2714],[2733],[468,2724,2711],[2718],[2804],[2719],[2731],[2720]],[[32],[316]],[[590,3859],[28,3191]],[[750,2724]],[[2717],[0]],[[2323,3387]],[[468,658,2716]],[[2749]],[[2827]],[[2726],[0]],[[10],[0]],[[3423],[0]],[[316,2721],[2725],[514,2722,2723]],[[430,47]],[[2730]],[[3842]],[[3844]],[[2727],[2728]],[[590,2729]],[[281,2732,203,316]],[[112],[574,3810]],[[55,316,590,2735,2723]],[[2736,2734],[2736],[0]],[[2737,2734]],[[750,2737]],[[300,763,3861],[729,763,3861],[297,763,3861],[318,763,3861],[303,763,3861],[304,763,3841],[298,763,3841],[305,763,3841],[299,763,3841],[314,763,3841],[308,763,3861],[307,763,3861],[317,763,3861],[309,763,3861],[738,763,2740],[310,763,3861],[313,763,3861],[315,763,3841],[311,763,3859],[312,763,3861],[712,763,3861],[713,763,3841],[319,763,3841],[233,763,2743],[735,763,3853],[736,763,3841],[296,763,3841],[737,763,2738],[739,763,3841],[742,763,2739],[2741]],[[3755],[376]],[[743],[383],[744]],[[3861],[376]],[[301,763,3861],[302,763,3843],[447,763,3861],[448,763,3841]],[[2746],[0]],[[753,2742,748]],[[2745,2744],[2745],[0]],[[750,3841]],[[3841,2744]],[[2750,2747],[2750],[0]],[[2752],[0]],[[55,459,522,590,2754,2723],[55,459,190,2788,2747,2748]],[[750,2788]],[[3423]],[[2751]],[[2755,2753],[2755],[0]],[[2756,2753]],[[750,2756]],[[2757,763,3861],[2758,763,3861],[2759,763,3861],[2760,763,3861],[2761,763,3841],[2762,763,3861],[2763,763,3843],[2764,763,3841],[2765,763,3841],[2766,763,3841],[2767,763,3841],[817,763,3841],[2768,763,3841],[2769,763,3853],[2770,763,3841],[2771,763,3841],[2772,763,3861],[2773,763,3861],[2774,763,3861],[2775,763,3859],[2776,763,3861],[2777,763,3861],[2778,763,3861],[2779,763,3841],[2780,763,3861],[2781,763,2740],[2782,763,3861],[2783,763,3841],[729,763,3861],[233,763,2743],[841,763,3841],[737,763,2738],[739,763,3841],[742,763,2739],[842,763,3841],[447,763,3861],[448,763,3841]],[[814],[297]],[[820],[300]],[[838],[318]],[[823],[303]],[[824],[304]],[[821],[301]],[[822],[302]],[[813],[296]],[[819],[319]],[[816],[298]],[[826],[305]],[[818],[299]],[[815],[735]],[[839],[736]],[[827],[314]],[[828],[308]],[[829],[307]],[[830],[309]],[[832],[311]],[[833],[312]],[[834],[313]],[[831],[310]],[[835],[315]],[[837],[317]],[[836],[738]],[[825],[712]],[[840],[713]],[[2790],[0]],[[2793],[0]],[[2796],[0]],[[2800],[0]],[[460,763,753,2784,748],[461,763,753,2784,748],[462,763,753,2785,748],[463,763,753,2785,748],[464,763,753,2786,748],[465,763,753,2786,748],[466,763,753,2787,748]],[[2791,2789],[2791],[0]],[[3781,2789]],[[750,3781]],[[2794,2792],[2794],[0]],[[3804,2792]],[[750,3804]],[[2797,2795],[2797],[0]],[[2798,2795]],[[750,2798]],[[3861]],[[2801,2799],[2801],[0]],[[3699,2799]],[[750,3699]],[[2824],[0]],[[2805],[0]],[[543,514,2802,2803,2813,2723],[552,514,2802,2723]],[[613,2807]],[[2812,2806],[2812],[0]],[[2811,2806]],[[530],[528]],[[2808,763,3855]],[[529]],[[2741],[2809],[2810]],[[750,2741]],[[2822],[0]],[[2815],[0]],[[618,763,3855]],[[2817],[0]],[[406,763,3855]],[[2819],[0]],[[129,763,3855]],[[2821],[0]],[[409,763,3855]],[[2814,2816,2818,2820]],[[2825,2823],[2825],[0]],[[2826,2823]],[[750,2826]],[[449],[538]],[[2828,210]],[[543],[552]],[[417,3830,203,2830],[2833],[2831,417,3830]],[[3859],[3383]],[[123],[148]],[[2834],[0]],[[173,3830,2832]],[[621,2836]],[[2837,2835],[2837],[0]],[[3383,2835]],[[750,3383]],[[677,2844]],[[2840],[0]],[[200,459]],[[2846],[0]],[[244,203,3758,749,3841,230,45,3853,2841]],[[3877],[0]],[[284,112,139,2843,3853],[676,2839],[2842]],[[2847],[0]],[[2847],[112,139,2843,3853,2845]],[[467,2665,539]],[[2849],[2863],[2897],[2900],[2929],[2933],[2850]],[[2852]],[[2979]],[[2854],[0]],[[11,618,2851,2855]],[[3691]],[[2853]],[[2858],[2861,2866]],[[2862],[3758]],[[10],[369],[2984]],[[2856,128,659,2857]],[[3724]],[[3721]],[[2859],[2860]],[[618,3876]],[[97,618,2865,3721,2875,2866]],[[3692]],[[2864],[0]],[[2874],[0]],[[75],[812]],[[2867,3855]],[[2870],[0]],[[2868]],[[2879],[0]],[[2883],[0]],[[2885,2873],[2885],[0]],[[2871,2872,2873,2869]],[[2878],[0]],[[2877],[0]],[[128,659,2984]],[[2876]],[[467,2881]],[[539],[650],[369]],[[2973],[2880]],[[2884,2882],[2884]],[[645,2882]],[[322,3841],[327,3841],[321,3841],[328,3841]],[[2,2886],[406,2894],[740,2895],[741,3842]],[[287],[611]],[[2888],[0]],[[247,3842,122],[365],[128]],[[3842],[128]],[[3842,122],[128]],[[2892],[0]],[[128],[719]],[[467,101,2891]],[[177,2887],[705,2889],[706,247,2890],[2893]],[[3842],[698]],[[2899],[0]],[[148,618,2896,3718]],[[3691]],[[2898]],[[215,2912]],[[2902],[0]],[[645,660,391]],[[2952,590,3718,2901]],[[421],[0]],[[2952],[10,2904]],[[2907],[0]],[[645,215,391]],[[2950],[0]],[[2926],[0]],[[2916],[0]],[[2925],[0]],[[2903],[2905,383,2908,2968,590,2913,2909,2910,2911],[427,383,3758,590,2913,2906]],[[2914],[2915]],[[3721]],[[3718]],[[2918],[2919]],[[2977,2917],[2977]],[[645,2917]],[[645,215,391]],[[663,2984]],[[645,659,2923]],[[2920],[0]],[[2984],[10,2922],[369],[128]],[[2921],[0]],[[17,618,2924]],[[2927]],[[2879]],[[2930,2928],[2930],[0]],[[453,618,3758,590,3758,2928]],[[750,3758,590,3758]],[[2935],[0]],[[2944],[0]],[[477,2931,2942,2932]],[[3691]],[[2934]],[[2952,203,3718]],[[2945],[0]],[[2939],[0]],[[2937,203,3718]],[[383,2908,2968,2938]],[[2940],[750,215,391,203,3718]],[[2936],[2952,2945,203,3718],[10,2904,2941],[427,383,3758,203,3718]],[[232,610,618]],[[2943]],[[2946],[2949]],[[383,2908,2968]],[[2948],[0]],[[383,2908,2968]],[[2947]],[[574],[206],[422]],[[2953,2951],[2953],[0]],[[2956,2951]],[[750,2956]],[[2965],[0]],[[483],[0]],[[2959],[2960,2168],[2962],[2963],[215,391],[509,110],[97,2954],[287,571],[459,2966],[509,636],[11,2955]],[[792],[746,3872]],[[3874,2957],[3874,2168]],[[2958]],[[497],[242],[614],[443]],[[97],[148]],[[2961,659]],[[133],[616],[236],[148],[173],[451],[510],[423],[188],[427],[565],[170],[594]],[[483],[572],[618],[636]],[[577,571],[2964]],[[65],[514]],[[2969],[0]],[[775,2967],[3781,751,2971],[3781],[3810]],[[751,775]],[[3810]],[[775],[2970]],[[2975,2972],[2975],[0]],[[2976,2972]],[[15],[0]],[[2974,2976]],[[63,3855],[259,3855],[559,3855]],[[215,391],[322,3841],[327,3841],[321,3841],[328,3841]],[[2982],[0]],[[506,659,2984],[506,659,2980],[506,128,659,2981,590,2984],[506,659,10,2978]],[[369],[128]],[[2984],[369],[10]],[[663,2984]],[[2985,2983],[2985],[0]],[[2987,2983]],[[750,2987]],[[2988],[0]],[[3874,2986]],[[746,3872],[792]],[[2994],[0]],[[2997],[0]],[[14,2077,2992,3813,2989],[62,2995,3813,2078],[61,2996,3813,2990],[388,2077,2998,3813],[455,2077,2999,3813,2079]],[[574],[571]],[[3002]],[[2993]],[[574],[571]],[[574],[571]],[[431],[180]],[[574],[571]],[[574],[571]],[[3003],[0]],[[3004],[0]],[[614,674,383,3832,3000,3001],[148,674,383,3832]],[[645,787,675]],[[621,112,3853]],[[200,615],[3006]],[[431],[184],[333],[180],[56]],[[431],[180],[619]],[[3011],[0]],[[3012,3009],[3012],[0]],[[245,410,3830,520,3853],[245,664,3863,3008],[607,410,3823],[607,664,3824,3009]],[[506,3018]],[[750,3824]],[[214],[658]],[[3013],[0]],[[3014,3387,3877,3016]],[[383],[3191]],[[3019,3017],[3019],[0]],[[3015,3017]],[[750,3015]],[[506,3022]],[[3023],[0]],[[592,3034],[406,3021,3877,3028],[3031],[3045,3043],[3878,3051]],[[200,3758]],[[382,753,3855,748]],[[406,753,3855,748]],[[3753],[0]],[[3751],[0]],[[3855,3026,3027],[3855,3026,3027],[3024],[3025]],[[3030],[0]],[[200,3758]],[[406,3029,590,734,3026,3027]],[[3035],[0]],[[3036],[0]],[[3037,3032],[3039,3033]],[[750,3039]],[[750,3037]],[[435,3038]],[[649],[386]],[[258,274,3041]],[[76],[601]],[[456,435],[435,3040],[500]],[[3044,3042],[3044],[0]],[[3042]],[[750,3048]],[[3387,3877,3053],[3708],[3383,3877,3191],[3050,3877,3053],[356,3047]],[[128]],[[3877,3191],[3618,2096],[3046]],[[3878,3387,3877,3053],[3045]],[[3880],[0]],[[745,3049,3387]],[[3052,3043],[592,3034]],[[3387,3877,3053]],[[3191],[3054],[3056]],[[128],[383],[10],[32]],[[487],[710]],[[3055]],[[509,3091]],[[22]],[[3801],[10]],[[547],[354],[289]],[[203],[251]],[[32],[316]],[[225],[547,3094,2723]],[[33],[446]],[[3066],[0]],[[251,3855]],[[3068],[0]],[[203,3843]],[[180]],[[3071],[0]],[[3069]],[[236],[235],[263]],[[639],[166]],[[3075,3074],[3075],[0]],[[750,3099]],[[3077],[0]],[[3099,3074]],[[3079],[0]],[[200,430,787]],[[547],[631]],[[93]],[[3083],[0]],[[200,3758]],[[618,3758]],[[109,2180,3781],[170,3797],[206,3785],[422,3783],[574,3810],[594,3787],[636,3790],[3084]],[[3760],[0]],[[3092],[0]],[[3098],[0]],[[204],[0]],[[3878],[0]],[[3058],[110,3086],[3087,571,3088,3086],[3089,593,3088,3086],[169,3088,3086],[574,547,3088,3086],[387,571,3088,3086],[408],[163,3059,3060],[3087,71,3061,3810,3088,3086],[3062,289],[514,3063],[3064,169,3065,3067,2386,2723],[3070,3072,3097,3810,3088,2372],[2281,162],[95,753,775,748,3073],[639,2386],[166,2386],[426],[425,3076,3078,2386],[3090,3080,3086],[3089,424],[3406,3086],[70,3086],[3081],[421],[216,200,3758,621,3718],[216,3082],[316,547],[97,3085],[422,547,3086],[206,547,3086],[422,68,3783],[206,68,3785]],[[204],[3093]],[[180,3089]],[[3096],[0]],[[370],[0]],[[3095]],[[203],[251]],[[3097,3830]],[[40,255],[91,568],[400,185],[3100]],[[10],[96],[256],[334],[522],[567]],[[3107],[0]],[[33,3859],[47,236,3109,251,3103],[196,2077,3106],[266,3101,3191],[281,236,248,47,3136],[3108]],[[3830],[128]],[[3105,3104],[3105],[0]],[[750,3123]],[[3129],[3123,3104]],[[84],[430]],[[510]],[[3111],[3115]],[[3112,3110],[3112],[0]],[[3114,3110]],[[750,3114]],[[3117],[0]],[[3810,3113]],[[3810,405,753,2139,748,3113]],[[3120],[0]],[[2645,753,3116,748]],[[3830],[420]],[[3121,3119],[3121],[0]],[[3118,3119]],[[750,3118]],[[3127],[0]],[[3124],[3122,289],[445,289,2723],[3125],[3126]],[[136],[225],[421],[547],[617]],[[430,47]],[[389]],[[32],[163],[165],[208],[515]],[[3132],[0]],[[3130,3128]],[[571],[574]],[[3133],[0]],[[645,435,287],[3813,3131]],[[3134],[645,435,287]],[[200,179]],[[3137],[0]],[[3810,3144,3113,3135],[3139]],[[232,270]],[[3140,3138],[3140],[0]],[[3142,3138]],[[750,3142]],[[3143],[0]],[[3810,3113,3141]],[[232,270]],[[405,753,2139,748]],[[3149],[3160],[3162],[3167]],[[3152],[0]],[[3157],[0]],[[3158],[0]],[[97,709,217,3830,599,2843,3150,3146,3147,3148]],[[618],[710]],[[3153,3151],[3153],[0]],[[711,2843,3155,3151]],[[2053,3155]],[[3156],[0]],[[787,3154]],[[773,787]],[[708,2843,787]],[[156],[140]],[[198],[0]],[[11,709,217,3825,3146,3147,3148,3159]],[[3163],[0]],[[506,709,217,3830,3161]],[[200,3165]],[[3166,3164],[3166],[0]],[[3842,3164]],[[2053,3842]],[[148,709,217,3825,3159]],[[3175],[3171],[3187],[3188],[3169]],[[3189]],[[3173],[0]],[[3172,3810,3170]],[[178],[135],[134]],[[3855],[3773]],[[3182],[0]],[[3176,3174,3183]],[[178],[135],[134]],[[180]],[[404]],[[201,763,3872]],[[14,201,763,3872]],[[14]],[[3177],[3178],[3179],[3180],[3181]],[[2461],[3185],[3186]],[[2366],[2400],[2457],[2656]],[[3184]],[[200,84,3842]],[[222,3872]],[[620,3830]],[[714]],[[3198,3190],[3198],[0]],[[3193,3190]],[[3196],[0]],[[3202,3192],[3197]],[[596],[183],[610]],[[3407],[0]],[[257,3195,3194]],[[371,3191]],[[3199,3191],[654,3191],[3200,3191]],[[15],[770]],[[394],[772]],[[3203,3201],[3203],[0]],[[3207,3201]],[[257,3195,376],[3205,3204,2496],[3205,3207]],[[10],[16]],[[763],[777],[764],[765],[768],[769],[776]],[[3210],[0]],[[3216,3206]],[[668],[0]],[[733,3208,3414]],[[3195,3212],[3209],[521,275,3216]],[[3214],[0]],[[251,3213],[30,3216,15,3207],[275,3223,3211],[444,3216]],[[2496],[753,3404,748]],[[168,3223]],[[3217,3215],[3217],[0]],[[3223,3215]],[[760,3216],[3218,3216],[3219,3216],[3220,247,3191,3409],[3221,3216],[757,3216],[759,3216]],[[775],[762],[774],[145],[349]],[[778],[773]],[[778],[773]],[[779],[780]],[[3224,3222],[3224],[0]],[[3226,3222]],[[761,3226]],[[3227],[0]],[[3236,3225]],[[69,3872]],[[3237],[0]],[[487],[0]],[[3320],[0]],[[3246],[0]],[[3191],[0]],[[3245,3233],[3245]],[[3393],[0]],[[3248],[0]],[[3847],[3265],[3382,3228],[754],[3238],[3239],[3240,3223],[3408,3223],[3229,753,3404,748],[2623,2496],[752,3830,3191,747],[320,3315,7,753,3216,3230,748],[32,3223],[3244],[52,753,3191,17,3398,3231,748],[51,3232,3233,3234,159],[94,753,3191,750,3398,748],[94,753,3191,621,3618,748],[128,753,3837,748],[626,753,3837,748],[247,3191,3409,778,3191],[3377],[3329],[3773,3235]],[[3877,3191]],[[3294]],[[3298]],[[778],[773],[758]],[[247],[0]],[[3617],[0]],[[52,753,3191,21,586,843,3241,3853,17,113,3242,748]],[[3243]],[[3391,3392]],[[3247]],[[731]],[[3249],[3250]],[[766,3853]],[[767,3853]],[[143],[0]],[[3267],[0]],[[3270],[0]],[[3273],[0]],[[3276],[0]],[[3278],[0]],[[3280],[0]],[[3282],[0]],[[3284],[0]],[[3286],[0]],[[3288],[0]],[[3290],[0]],[[3291],[0]],[[3293],[0]],[[26,753,3251,3314,748,3252],[3268,753,3314,748,3253],[3271],[95,753,2722,775,748,3254],[95,753,3274,748,3255],[345,753,3251,3314,748,3256],[326,753,3251,3314,748,3257],[551,753,3314,748,3258],[632,753,3314,748,3259],[548,753,3314,748,3260],[635,753,3314,748,3261],[564,753,3251,3314,748,3262],[218,753,3251,3404,2374,3263,748,3264]],[[3304]],[[3266]],[[35],[36],[38]],[[3304]],[[3269]],[[3313]],[[3304]],[[3272]],[[2722,775],[3314],[143,3404]],[[3304]],[[3275]],[[3304]],[[3277]],[[3304]],[[3279]],[[3304]],[[3281]],[[3304]],[[3283]],[[3304]],[[3285]],[[3304]],[[3287]],[[3304]],[[3289]],[[499,3855]],[[3304]],[[3292]],[[672,753,3404,748]],[[3307],[0]],[[3310],[0]],[[3303],[0]],[[3299,3876,3304],[688,3414,3304],[3300,753,3191,3295,748,3296,3304],[3301,3413,3296,3304],[687,753,3191,750,3223,748,3297,3296,3304]],[[696],[694],[679],[678],[692]],[[686],[684]],[[681],[685]],[[191],[268]],[[203,3302]],[[691,3305]],[[3826],[2522]],[[3309],[0]],[[750,3308,3306]],[[3843],[754],[3830],[3383]],[[750,3191]],[[3311,689]],[[695],[232]],[[3304],[0]],[[667,753,3314,748,3312],[666,753,3314,750,3314,748,3312]],[[2722,3191]],[[3317],[753,3317,748]],[[3318,3316],[3318],[0]],[[3837,3316]],[[750,3837]],[[3321],[0]],[[251,41,346],[251,359,267,346,3319],[645,430,176]],[[645,430,176]],[[3330],[0]],[[3876],[0]],[[3331,3324],[3331]],[[3335],[0]],[[3353],[0]],[[3340],[0]],[[3343],[0]],[[60,753,3404,3322,748],[105,3323],[116,3413],[122,3413],[229,3413],[242,753,3191,750,3191,750,3191,750,3191,748],[247,753,3191,3324,748],[3334],[272,753,3191,750,3191,748],[343,3413],[350,3413],[478,753,3191,750,3191,748],[495,3413],[586,3413],[583,753,3191,3325,748],[3366],[618,3876],[626,3413],[656,3413],[3336,753,3191,750,3337,748],[100,3323],[108,3326],[3338,753,3191,750,247,3191,3409,748],[182,753,3409,203,3191,748],[213,753,3365,750,3191,748],[372,3326],[414,753,3216,251,3191,748],[3370],[569,3326],[3339,753,3411,750,3191,750,3191,748],[622,3323],[624,3326],[623,3326],[19,3413],[58,3413],[67,3412],[70,3413],[109,3876],[231,753,3191,750,3191,750,3191,748],[201,753,3191,750,3191,3327,748],[337,3413],[349,753,3191,750,3191,748],[3341],[3342],[429,3413],[457,753,3191,750,3191,748],[458,753,3191,750,3191,750,3191,748],[476,3413],[485,3876],[597,753,3191,750,3191,748],[640,753,3191,3328,748],[641,753,3191,17,60,748],[641,753,3191,3349,748],[3350]],[[621,3618]],[[750,3191]],[[3333],[0]],[[851,3398]],[[850,753,3223,750,3859,3332,2624,748]],[[750,3191]],[[5],[558]],[[3191],[247,3191,3409]],[[114],[115]],[[584],[585]],[[750,3191]],[[382,753,3859,748]],[[406,3413]],[[750,3191]],[[3345],[0]],[[17,60,3616]],[[3356]],[[3348],[0]],[[3346]],[[17,32,3616],[3344,3347],[750,3841,750,3841,750,3841]],[[3351],[211,753,2362,748],[279,3412],[351,3412],[352,3412],[353,3412],[411,753,3191,750,3191,748],[412,3412]],[[90,753,3191,750,3191,748]],[[3354],[0]],[[753,3352,748]],[[3355]],[[787]],[[274,3359]],[[3358,3357],[3358],[0]],[[750,3361]],[[3842,773,3842],[3361,3357]],[[3364],[0]],[[3842,3360]],[[18],[134]],[[476],[0]],[[3362,3363],[476]],[[116],[586],[113],[583]],[[595,753,3369,748]],[[3368],[0]],[[203,3191]],[[3191,3367],[269,3232,203,3191],[591,3232,203,3191],[43,3232,203,3191]],[[563,753,3191,3375,748]],[[3372],[0]],[[750,3191]],[[3374],[0]],[[200,3191]],[[750,3191,3371],[203,3191,3373]],[[3379],[0]],[[3827,753,3376,748],[3835,753,2362,748]],[[3380,3378],[3380],[0]],[[3381,3378]],[[750,3381]],[[3191,2581]],[[3383],[3386]],[[746,3872],[792]],[[3879],[0]],[[3840],[0]],[[745,3384,3872,3385]],[[3390],[128,3840]],[[3830,3385]],[[3873,3385]],[[3388],[3389]],[[642,3191]],[[582,3191]],[[154,3191]],[[3606],[0]],[[3612],[0]],[[249],[0]],[[3869],[0]],[[32,3394],[60,3394,3395],[3604,3394],[512,3396],[612,3396],[116],[586,3242],[113,3242],[126,3397],[656],[3399],[3400],[3402]],[[262]],[[3605]],[[3870],[0]],[[195,3401]],[[3405,3403],[3405],[0]],[[3191,3403]],[[750,3191]],[[60,506],[58]],[[371],[800]],[[771],[800]],[[3411],[3410]],[[494],[341],[342],[226],[228],[227],[119],[121],[120],[118],[655]],[[337],[495],[343],[229],[122],[640],[350],[429],[656]],[[753,3404,748]],[[753,3191,748]],[[753,3223,748]],[[3417,3415],[3417],[0]],[[3418,3415]],[[750,3418]],[[3191,2123]],[[3421,3419],[3421],[0]],[[3422,3419]],[[750,3422]],[[3191]],[[3424]],[[200,57,3861]],[[2004],[3426],[3427],[3437],[3441],[3442],[3447],[3448],[3470],[3469],[3502],[3505],[3503]],[[475,3191]],[[231,3429,159,231]],[[3430],[0]],[[3191,3431,3428]],[[155,3429],[154,3433]],[[582,3433]],[[3434,3432],[3434]],[[3432]],[[3425,755]],[[3438,3435],[3438]],[[3439],[0]],[[51,3232,3435,3436,159,51]],[[3391,3431]],[[154,3433]],[[3820],[0]],[[3443,3446,3440]],[[3446]],[[3819,749]],[[3453],[0]],[[3433],[0]],[[29,3444,3445,159]],[[3443,3448,3440]],[[3449],[3450],[3451]],[[294,3433,159,294]],[[644,3191,147,3433,159,644]],[[457,3433,613,3191,159,457]],[[3454,3452],[3454]],[[3452]],[[3455,755]],[[3457],[3459],[3464],[3468]],[[3458],[0]],[[127,3832,3592,2096,3456]],[[128,3191]],[[127,3830,83,200,3460]],[[3841],[3462]],[[627],[0]],[[526,3461,3859]],[[3466,3463],[3466],[0]],[[127,3465,219,200,3467,3463,3425]],[[92],[175],[605]],[[750,3467]],[[3460],[3830],[527],[3407,202],[525]],[[127,3830,106,200,2461]],[[260,3820]],[[271,3820]],[[3474],[0]],[[207,3471,138,3479]],[[540]],[[101],[3473]],[[3476,3475],[3476],[0]],[[750,3481]],[[3478,3477],[3478],[0]],[[750,3484]],[[3481,3475],[83,3480,3484,3477]],[[3847],[3382],[3837]],[[3482,763,3483]],[[3382],[3830]],[[377],[485]],[[3485,763,3486]],[[3382],[3830]],[[3487],[473]],[[64],[557],[87],[89],[88],[53],[492],[576],[73],[107],[336],[355]],[[3493],[0]],[[511,3490,3488]],[[3830],[3462]],[[3492,3491],[3492],[0]],[[750,3501]],[[506,3501,3491]],[[3497],[0]],[[3500],[0]],[[469,3494,3495]],[[3830],[3462]],[[3499,3498],[3499],[0]],[[750,3501]],[[506,3501,3498]],[[3487,763,3480]],[[387,3830]],[[66,3830]],[[3507],[0]],[[186,3504,3830,248,3832]],[[367],[0]],[[3506,203]],[[3511],[0]],[[3512],[0]],[[21,3191],[171,3191,3409,3508,3509]],[[542,3191]],[[160,3191]],[[3765,3528,2098]],[[3515],[3556]],[[3516]],[[62,3413]],[[2041,730]],[[3527],[0]],[[3520,2232,3574,2235],[205,2646,2239,3574,2236],[523,2646,2239,3574,2237],[3518,3525]],[[265],[236]],[[420,265],[609,2646]],[[3517]],[[3524],[0]],[[3522]],[[3521,2232,3574,2235],[199,265,2239,3567,3556],[3516,3523]],[[3830],[0]],[[86,3526]],[[3592,3539]],[[3530],[0]],[[209,12]],[[3532],[0]],[[637],[554]],[[3542,3533],[3542],[0]],[[3533]],[[3552,3535],[3552],[0]],[[3535]],[[3534],[3536]],[[2096,3529,17,3413,3531,3537]],[[3538],[3533]],[[420],[0]],[[265],[0]],[[2041,3867],[3543],[128,3545],[3546],[383,614,372,3326],[24],[501,128,627],[3540,265],[609,3541],[75,3859],[3697],[74,3550],[553,3551],[3547],[3548],[3549]],[[371,720]],[[3413]],[[3849],[372,3326],[3544]],[[3582]],[[707,3844]],[[3518,3516]],[[3517]],[[192],[152],[128]],[[142],[334],[128]],[[609,3541],[75,3855],[3195,376],[3540,265]],[[3834],[0]],[[3558],[0]],[[3563],[0]],[[443,3810,3553,3554,3555]],[[204],[402],[513]],[[320,3557]],[[3560],[0]],[[383,133,3564]],[[3562],[0]],[[383,614,3564]],[[383,614,3564,3559],[383,133,3564,3561]],[[3565],[506,3867],[373,3],[506,128]],[[471],[49]],[[3568,3566],[3568],[0]],[[753,3569,3566,748]],[[750,3569]],[[3830,3394,2123]],[[3572,3570],[3572],[0]],[[753,3573,3570,748]],[[750,3573]],[[3569],[3413,2123]],[[3575],[3576]],[[3571]],[[3567]],[[3578]],[[44],[488],[220]],[[3580],[3583]],[[264,2127,3841],[75,3859],[3581]],[[3582]],[[662],[661]],[[3584,3577]],[[621],[599]],[[3580],[645,401,3830]],[[3580]],[[3592,-1]],[[3609],[0]],[[3871],[0]],[[32],[0]],[[3601],[0]],[[3593,3394,3588],[3595,3589,3588],[3596,3397,3588],[37,3394],[3597],[3598,3606,3395],[60,3394,3395],[32,3394],[3599,3606,3590],[3604,3394,3590],[628,3606],[656,3394,3588],[116],[586,3242],[583,3242],[113,3242],[587],[39,3394],[3600],[293,628],[293,3591,3395],[589,3395],[580,3394,3395],[332,3395],[291,3395],[164,3851,3395],[506,3851,3395],[501],[3602],[3603]],[[249],[588],[516],[331],[31]],[[416],[0]],[[437],[146,3594]],[[195],[126],[378],[192]],[[42],[41]],[[60,633],[629]],[[358,629],[379],[361,629],[358,60,633],[361,633]],[[330],[290]],[[60,633],[629]],[[262]],[[212],[211],[411],[352],[279],[351],[412],[353]],[[361],[358,60]],[[437],[146,3594]],[[753,3607,748]],[[3844],[783]],[[3610,3608],[3610]],[[3608]],[[512],[612],[657]],[[3613],[0]],[[3614],[3615],[46],[3406,3618,3590],[32,3611]],[[3406,3618]],[[19,3590],[32,19]],[[606,3590],[32,606]],[[753,3842,748]],[[753,787,748]],[[3872],[32],[3619]],[[128]],[[3872],[3621],[3622]],[[128]],[[32]],[[3625,3623],[3625],[0]],[[3629,3623]],[[2053,3629]],[[3629,3626],[3629]],[[3626]],[[3813],[0]],[[163,2127,3801],[3631],[323,2127,3843],[344,2127,3843],[25,2127,3841],[406,2127,3853],[75,2127,3853],[3632],[3633],[24,2127,3843],[399,2127,3645],[3634,2127,3645],[3635,2127,3841],[132,2127,3841],[486,2127,3636],[608,2127,753,3628,748],[3649],[3647],[243,2127,3637],[112,139,2127,3855],[236,139,2127,3855],[572,3639,3830],[553,3640],[84,2127,3855],[264,2127,3841],[3641],[3642],[3643],[3644]],[[376],[3872]],[[721,2843,3630]],[[81,2127,3855]],[[158,2127,3855]],[[544],[545],[546]],[[61],[575]],[[128],[152],[192],[80],[442],[78]],[[373],[191],[268]],[[2127]],[[3638],[0]],[[142],[334]],[[543,592]],[[848,2127,3855]],[[849,2127,3855]],[[2277]],[[3841],[128]],[[128],[0]],[[3646,69,2127,3620]],[[3646,158,2127,3853]],[[3646,3406,2127,3618]],[[3654],[0]],[[3662],[0]],[[3668],[0]],[[405,45,3658,3650,3651,3652]],[[404,3842]],[[277],[0]],[[3665],[0]],[[3832],[0]],[[3655,265,3656,753,3657,748],[3655,220,753,3216,748],[3659,3660]],[[432],[280]],[[753,3216,748],[71,753,3657,748]],[[3664],[0]],[[561,45,3655,3663,3661]],[[220,753,3216,748],[265,3656,3834]],[[560,3842]],[[3666]],[[9,763,3842]],[[3669,3667],[3669],[0]],[[753,3673,3667,748]],[[750,3673]],[[3675],[0]],[[3682,3671],[3682],[0]],[[3678],[0]],[[405,3830,3670,3671,3672]],[[3687],[329]],[[626,273,581,3674],[626,251,3680]],[[3677,3676],[3677],[0]],[[750,3685]],[[753,3685,3676,748]],[[3681,3679],[3681],[0]],[[3687],[753,3687,3679,748]],[[750,3687]],[[572,2127,3830],[2281,163,2127,3801],[368,2127,3842],[3683,2127,3842],[3684,139,2127,3859],[75,2127,3859]],[[323],[344]],[[112],[236]],[[561,3872,3671]],[[3688,3686],[3688],[0]],[[753,3689,3686,748]],[[750,3689]],[[3216],[329]],[[130,763,3758]],[[231,174]],[[231,3407,174]],[[3695],[0]],[[3693,3696]],[[251],[397],[240]],[[3818,3698]],[[69,3620]],[[3592,2096]],[[753,3781,750,3781,748]],[[3702,3700],[3702],[0]],[[3790,3700]],[[750,3790]],[[3705,3703],[3705],[0]],[[3706,3703]],[[750,3706]],[[3773,3877,3707]],[[3191],[128]],[[3406,3618]],[[3712,3709],[3712]],[[71,3709]],[[392],[0]],[[579,45,3855],[3711,157,45,3855],[167,45,3855]],[[3715,3713],[3715]],[[278,3713]],[[3716,45,3855]],[[579],[541]],[[3719,3717],[3719],[0]],[[3758,3717]],[[750,3758]],[[3722,3720],[3722],[0]],[[3727,3720]],[[750,3727]],[[3725,3723],[3725],[0]],[[3739,3723]],[[750,3739]],[[3738],[0]],[[3758,3726]],[[406]],[[3730],[0]],[[3728]],[[45,3855]],[[3733],[0]],[[17,3856],[3731]],[[3735],[0]],[[645,3872]],[[3734,45,734,406]],[[45,3729,3855],[645,3872,3732],[3736]],[[230,3737]],[[3740,3750]],[[2862],[3758]],[[3742],[0]],[[645,3872]],[[734,406]],[[3743],[3855]],[[3746],[0]],[[17,3856,3027]],[[3748],[0]],[[3741,45,3744,3026,3027],[645,3872,3745]],[[3752]],[[230,3747],[3749],[0]],[[727,101,406]],[[141,728,406]],[[458,3855]],[[3757],[0]],[[3872,3754]],[[3872],[0]],[[746,3756],[792]],[[3755],[105,3323]],[[275,3853]],[[3759],[2585]],[[385],[380]],[[284],[375]],[[3764]],[[405,3834]],[[3767],[3768]],[[3840],[3835,3385]],[[3766]],[[3830]],[[3830]],[[3772,3770],[3772],[0]],[[753,3769,3770,748]],[[750,3769]],[[3765]],[[3773],[3778]],[[3830]],[[3765]],[[3779],[0]],[[3830,751,3777,775]],[[3830,751]],[[3830]],[[3830]],[[3835]],[[3835]],[[3835]],[[3835]],[[3835]],[[3835]],[[3835],[3789]],[[3840]],[[3835],[3791]],[[3840]],[[3830]],[[3830]],[[3830]],[[3830]],[[3835]],[[3835]],[[3830]],[[3872]],[[3872]],[[3872]],[[3835],[3803]],[[3840]],[[3781,3840]],[[3809],[0]],[[3830,3805]],[[3808],[0]],[[751,775]],[[751,775],[3840,3807]],[[3835],[3811]],[[3840]],[[3814,3812],[3814],[0]],[[3810,3812]],[[750,3810]],[[3817,3815],[3817],[0]],[[3806,3815]],[[750,3806]],[[3830]],[[3827],[3889]],[[3819]],[[3827],[3898]],[[3821]],[[3830]],[[3853]],[[3830]],[[3830]],[[3828],[3829]],[[793],[781]],[[784]],[[3827],[3881]],[[3833,3831],[3833],[0]],[[3830,3831]],[[750,3830]],[[753,3832,748]],[[3830,3385]],[[3838],[0]],[[3830,3836],[3839]],[[3840,3385]],[[3840,3840]],[[751,3830]],[[787],[786],[788],[791],[783],[785]],[[787],[786],[788],[791]],[[787],[788],[791],[783],[785]],[[787],[3845],[791],[788]],[[786]],[[794],[0]],[[3859],[3865],[3868],[3867],[3866],[3846,3848]],[[786],[782]],[[3847],[778,3841],[773,3841]],[[3852,3850],[3852],[0]],[[753,3855,3850,748]],[[750,3855]],[[790],[3854]],[[784]],[[3853],[786],[782]],[[3853],[3857]],[[786]],[[3853,3858],[3853],[0]],[[3860,3858]],[[3846,3853],[789]],[[3853]],[[3864,3862],[3864],[0]],[[3853,3862]],[[750,3853]],[[787],[788],[791],[783],[785]],[[596],[183]],[[376],[801]],[[116,3853],[586,3853],[583,3853]],[[3606],[3871]],[[3606]],[[753,787,750,787,748]],[[3830],[3853]],[[3827],[3902]],[[3821],[3853]],[[3844],[3827]],[[753,748]],[[763],[756]],[[658],[673],[214],[284],[502]],[[214,751],[284,751],[502,751]],[[658,751],[673,751],[214,751],[284,751],[502,751]],[[3885],[3886]],[[510]],[[714]],[[3889],[3904],[173],[3882],[3883]],[[3884]],[[3894],[3887],[3888],[3893],[3903]],[[173],[714],[510]],[[19],[29],[46],[47],[58],[61],[677],[75],[77],[90],[123],[147],[159],[196],[197],[219],[222],[234],[245],[267],[373],[415],[417],[455],[468],[480],[489],[512],[514],[543],[552],[597],[606],[607],[651]],[[3891],[3892]],[[3908],[170],[188],[369],[423],[427],[451],[459],[709],[565]],[[3890]],[[3894],[3893],[3903]],[[170],[188],[369],[423],[427],[451],[459],[709],[565]],[[3895],[3897]],[[3],[2],[724],[5],[660],[6],[7],[8],[9],[12],[16],[21],[812],[23],[24],[25],[26],[27],[33],[37],[40],[41],[42],[44],[675],[50],[53],[54],[56],[57],[63],[64],[65],[66],[67],[68],[70],[71],[74],[73],[76],[78],[79],[664],[80],[81],[82],[84],[85],[87],[88],[89],[91],[96],[101],[107],[111],[112],[113],[116],[122],[129],[130],[715],[132],[716],[138],[139],[140],[141],[142],[150],[151],[152],[156],[158],[160],[730],[162],[163],[848],[164],[166],[165],[168],[169],[171],[172],[680],[176],[177],[179],[180],[181],[184],[185],[189],[190],[191],[192],[682],[201],[202],[204],[208],[211],[212],[213],[713],[840],[216],[210],[841],[220],[674],[705],[225],[224],[229],[230],[233],[725],[235],[238],[844],[243],[244],[661],[250],[255],[256],[258],[259],[262],[264],[847],[268],[270],[273],[274],[279],[280],[670],[286],[288],[289],[296],[735],[298],[299],[319],[300],[729],[301],[302],[303],[304],[712],[305],[306],[307],[308],[309],[310],[312],[311],[313],[314],[316],[738],[317],[318],[736],[321],[322],[323],[324],[327],[328],[333],[334],[335],[336],[337],[340],[343],[344],[346],[348],[350],[351],[352],[353],[354],[355],[356],[357],[358],[361],[363],[702],[365],[366],[367],[368],[671],[374],[689],[377],[379],[381],[732],[728],[384],[386],[387],[719],[390],[703],[717],[690],[398],[399],[400],[401],[402],[403],[404],[406],[704],[407],[408],[409],[410],[411],[412],[413],[693],[418],[419],[421],[737],[424],[426],[425],[429],[430],[431],[434],[438],[439],[441],[846],[442],[718],[445],[446],[447],[448],[449],[452],[842],[454],[456],[460],[462],[461],[463],[466],[464],[465],[617],[695],[470],[472],[727],[473],[851],[474],[706],[476],[659],[481],[482],[483],[485],[486],[488],[490],[492],[721],[849],[722],[720],[723],[495],[496],[500],[501],[503],[508],[513],[669],[515],[517],[519],[520],[521],[813],[814],[815],[817],[816],[818],[819],[820],[821],[822],[823],[824],[825],[826],[829],[828],[830],[831],[833],[832],[834],[827],[835],[522],[836],[837],[838],[839],[528],[529],[530],[532],[535],[538],[707],[540],[542],[544],[545],[546],[547],[553],[556],[557],[558],[559],[560],[561],[566],[567],[568],[571],[572],[575],[576],[577],[578],[580],[581],[708],[697],[584],[585],[583],[586],[845],[592],[593],[598],[599],[698],[601],[602],[603],[604],[610],[613],[615],[618],[619],[625],[627],[631],[711],[636],[662],[638],[639],[640],[641],[646],[647],[648],[650],[652],[653],[656],[843]],[[731],[741],[735],[738],[736],[733],[744],[740],[737],[734],[739],[742],[743],[583],[586]],[[3896]],[[3900],[3901]],[[3908],[3904]],[[3899]],[[3894],[3888],[3903]],[[3894],[3887],[3888],[3893]],[[214],[284],[658],[673],[502]],[[3905],[3906],[3907]],[[2],[19],[12],[27],[29],[46],[47],[58],[61],[677],[66],[75],[77],[90],[123],[147],[159],[196],[197],[201],[210],[219],[222],[224],[245],[661],[267],[373],[387],[390],[398],[401],[413],[415],[417],[452],[455],[468],[470],[659],[480],[489],[720],[721],[722],[723],[496],[503],[512],[519],[514],[520],[543],[552],[597],[606],[607],[615],[662],[648],[651]],[[510]],[[234]],[[3909],[3910],[3912],[3914],[3915]],[[3],[724],[5],[6],[7],[8],[9],[13],[16],[21],[22],[24],[23],[25],[26],[33],[37],[40],[42],[41],[44],[675],[50],[53],[54],[56],[57],[63],[65],[64],[67],[68],[70],[73],[74],[71],[76],[78],[79],[664],[80],[81],[82],[84],[85],[87],[89],[88],[91],[93],[96],[101],[107],[112],[111],[113],[116],[122],[129],[130],[132],[136],[716],[138],[139],[140],[141],[142],[150],[151],[152],[158],[160],[164],[163],[162],[165],[166],[168],[169],[171],[680],[176],[179],[180],[181],[185],[184],[682],[202],[156],[204],[189],[190],[191],[192],[208],[212],[211],[213],[216],[214],[220],[674],[705],[225],[229],[230],[233],[250],[235],[238],[244],[725],[255],[256],[258],[259],[243],[262],[850],[264],[268],[270],[273],[274],[279],[280],[284],[670],[286],[288],[289],[323],[316],[319],[300],[304],[301],[302],[318],[303],[712],[306],[298],[305],[299],[314],[308],[307],[317],[309],[310],[311],[312],[313],[296],[321],[322],[325],[324],[327],[328],[333],[334],[335],[336],[337],[340],[343],[344],[348],[346],[350],[351],[352],[353],[354],[355],[357],[356],[358],[361],[363],[702],[365],[367],[366],[374],[368],[689],[671],[377],[379],[381],[728],[382],[384],[719],[703],[717],[690],[399],[400],[402],[403],[404],[406],[704],[407],[409],[410],[408],[411],[412],[693],[418],[419],[708],[421],[424],[425],[426],[429],[430],[431],[434],[438],[439],[441],[440],[442],[445],[446],[447],[448],[449],[676],[454],[456],[460],[461],[462],[463],[464],[465],[466],[617],[695],[472],[727],[473],[474],[706],[476],[481],[482],[483],[485],[486],[488],[490],[492],[495],[501],[500],[502],[508],[513],[669],[515],[517],[521],[522],[528],[529],[530],[533],[532],[535],[538],[707],[540],[542],[544],[545],[546],[547],[553],[556],[557],[558],[559],[561],[560],[565],[566],[567],[568],[576],[571],[575],[572],[577],[578],[580],[581],[697],[592],[593],[583],[584],[585],[586],[598],[599],[600],[698],[601],[602],[604],[603],[610],[613],[618],[619],[631],[711],[636],[627],[639],[638],[640],[647],[641],[650],[652],[653],[656]],[[510]],[[99],[234],[206],[484],[487]],[[3911]],[[172],[177],[386],[565],[625],[646]],[[3913]],[[660]]]]; diff --git a/wp-includes/sqlite-ast/class-wp-sqlite-driver-exception.php b/wp-includes/sqlite-ast/class-wp-sqlite-driver-exception.php index d14a391..a72dd71 100644 --- a/wp-includes/sqlite-ast/class-wp-sqlite-driver-exception.php +++ b/wp-includes/sqlite-ast/class-wp-sqlite-driver-exception.php @@ -1,6 +1,6 @@ code = $code; $this->driver = $driver; } diff --git a/wp-includes/sqlite-ast/class-wp-sqlite-driver.php b/wp-includes/sqlite-ast/class-wp-sqlite-driver.php index e97e388..49f4908 100644 --- a/wp-includes/sqlite-ast/class-wp-sqlite-driver.php +++ b/wp-includes/sqlite-ast/class-wp-sqlite-driver.php @@ -239,7 +239,19 @@ class WP_SQLite_Driver { private static $mysql_grammar; /** - * The database name. + * The main database name. + * + * The name of the main database that is used by the driver. + * + * @var string|null + */ + private $main_db_name; + + /** + * The name of the current database in use. + * + * This can be set with the USE statement. At the moment, we support only + * the main driver database and the INFORMATION_SCHEMA database. * * @var string */ @@ -294,6 +306,13 @@ class WP_SQLite_Driver { */ private $last_sql_calc_found_rows = null; + /** + * Whether the current MySQL query is read-only. + * + * @var bool + */ + private $is_readonly; + /** * Transaction nesting level of the executed SQLite queries. * @@ -335,7 +354,8 @@ public function __construct( array $options ) { if ( ! isset( $options['database'] ) || ! is_string( $options['database'] ) ) { throw $this->new_driver_exception( 'Option "database" is required.' ); } - $this->db_name = $options['database']; + $this->main_db_name = $options['database']; + $this->db_name = $this->main_db_name; // Database connection. if ( isset( $options['connection'] ) && $options['connection'] instanceof PDO ) { @@ -413,7 +433,8 @@ public function __construct( array $options ) { // Initialize information schema builder. $this->information_schema_builder = new WP_SQLite_Information_Schema_Builder( - $this->db_name, + $this->main_db_name, + self::RESERVED_PREFIX, array( $this, 'execute_sqlite_query' ) ); $this->information_schema_builder->ensure_information_schema_tables(); @@ -480,6 +501,11 @@ public function get_insert_id() { * @return mixed Return value, depending on the query type. * * @throws WP_SQLite_Driver_Exception When the query execution fails. + * + * TODO: + * The API of this function is not final. + * We should also add support for parametrized queries. + * See: https://github.com/Automattic/sqlite-database-integration/issues/7 */ public function query( string $query, $fetch_mode = PDO::FETCH_OBJ, ...$fetch_mode_args ) { $this->flush(); @@ -684,6 +710,7 @@ private function execute_mysql_query( WP_Parser_Node $node ): void { $node = $children[0]->get_first_child_node(); switch ( $node->rule_name ) { case 'selectStatement': + $this->is_readonly = true; $this->execute_select_statement( $node ); break; case 'insertStatement': @@ -699,9 +726,20 @@ private function execute_mysql_query( WP_Parser_Node $node ): void { case 'createStatement': $subtree = $node->get_first_child_node(); switch ( $subtree->rule_name ) { + case 'createDatabase': + /* + * TODO: + * We could support this by creating a new SQLite database + * file (e.g., $slugified_db_name.sqlite). + * + * Alternatively, it could be a no-op, in combination with + * DROP DATABASE deleting the data file and recreating it. + */ case 'createTable': $this->execute_create_table_statement( $node ); break; + case 'createIndex': + // TODO: SQLite has a CREATE INDEX statement. We should support it. default: throw $this->new_not_supported_exception( sprintf( @@ -740,6 +778,9 @@ private function execute_mysql_query( WP_Parser_Node $node ): void { $this->set_result_from_affected_rows(); } break; + case 'truncateTableStatement': + $this->execute_truncate_table_statement( $node ); + break; case 'setStatement': /* * It would be lovely to support at least SET autocommit, @@ -748,14 +789,19 @@ private function execute_mysql_query( WP_Parser_Node $node ): void { $this->last_result = 0; break; case 'showStatement': + $this->is_readonly = true; $this->execute_show_statement( $node ); break; case 'utilityStatement': $subtree = $node->get_first_child_node(); switch ( $subtree->rule_name ) { case 'describeStatement': + $this->is_readonly = true; $this->execute_describe_statement( $subtree ); break; + case 'useCommand': + $this->execute_use_statement( $subtree ); + break; default: throw $this->new_not_supported_exception( sprintf( @@ -766,6 +812,9 @@ private function execute_mysql_query( WP_Parser_Node $node ): void { ); } break; + case 'tableAdministrationStatement': + $this->execute_administration_statement( $node ); + break; default: throw $this->new_not_supported_exception( sprintf( 'statement type: "%s"', $node->rule_name ) @@ -1054,8 +1103,9 @@ private function execute_create_table_statement( WP_Parser_Node $node ): void { // Handle IF NOT EXISTS. if ( $subnode->has_child_node( 'ifNotExists' ) ) { + $tables_table = $this->information_schema_builder->get_table_name( 'tables' ); $table_exists = $this->execute_sqlite_query( - 'SELECT 1 FROM _mysql_information_schema_tables WHERE table_schema = ? AND table_name = ?', + "SELECT 1 FROM $tables_table WHERE table_schema = ? AND table_name = ?", array( $this->db_name, $table_name ) )->fetchColumn(); @@ -1092,16 +1142,12 @@ private function execute_alter_table_statement( WP_Parser_Node $node ): void { ); // Save all column names from the original table. - $column_names = $this->execute_sqlite_query( - 'SELECT COLUMN_NAME FROM _mysql_information_schema_columns WHERE table_schema = ? AND table_name = ?', + $columns_table = $this->information_schema_builder->get_table_name( 'columns' ); + $column_names = $this->execute_sqlite_query( + "SELECT COLUMN_NAME FROM $columns_table WHERE table_schema = ? AND table_name = ?", array( $this->db_name, $table_name ) )->fetchAll( PDO::FETCH_COLUMN ); - // Preserve ROWIDs. - // This also addresses a special case when all original columns are dropped - // and there is nothing to copy. We'll always have at least the ROWID column. - array_unshift( $column_names, 'rowid' ); - // Track column renames and removals. $column_map = array_combine( $column_names, $column_names ); foreach ( $node->get_descendant_nodes( 'alterListItem' ) as $action ) { @@ -1109,7 +1155,7 @@ private function execute_alter_table_statement( WP_Parser_Node $node ): void { switch ( $first_token->id ) { case WP_MySQL_Lexer::DROP_SYMBOL: - $name = $this->translate( $action->get_first_child_node( 'columnInternalRef' ) ); + $name = $this->translate( $action->get_first_child_node( 'fieldIdentifier' ) ); if ( null !== $name ) { $name = $this->unquote_sqlite_identifier( $name ); unset( $column_map[ $name ] ); @@ -1117,7 +1163,7 @@ private function execute_alter_table_statement( WP_Parser_Node $node ): void { break; case WP_MySQL_Lexer::CHANGE_SYMBOL: $old_name = $this->unquote_sqlite_identifier( - $this->translate( $action->get_first_child_node( 'columnInternalRef' ) ) + $this->translate( $action->get_first_child_node( 'fieldIdentifier' ) ) ); $new_name = $this->unquote_sqlite_identifier( $this->translate( $action->get_first_child_node( 'identifier' ) ) @@ -1126,7 +1172,7 @@ private function execute_alter_table_statement( WP_Parser_Node $node ): void { $column_map[ $old_name ] = $new_name; break; case WP_MySQL_Lexer::RENAME_SYMBOL: - $column_ref = $action->get_first_child_node( 'columnInternalRef' ); + $column_ref = $action->get_first_child_node( 'fieldIdentifier' ); if ( null !== $column_ref ) { $old_name = $this->unquote_sqlite_identifier( $this->translate( $column_ref ) @@ -1142,66 +1188,7 @@ private function execute_alter_table_statement( WP_Parser_Node $node ): void { } $this->information_schema_builder->record_alter_table( $node ); - - /* - * See: - * https://www.sqlite.org/lang_altertable.html#making_other_kinds_of_table_schema_changes - */ - - // 1. If foreign key constraints are enabled, disable them. - $pragma_foreign_keys = $this->execute_sqlite_query( 'PRAGMA foreign_keys' )->fetchColumn(); - $this->execute_sqlite_query( 'PRAGMA foreign_keys = OFF' ); - - // 2. Create a new table with the new schema. - $tmp_table_name = self::RESERVED_PREFIX . "tmp_{$table_name}_" . uniqid(); - $quoted_table_name = $this->quote_sqlite_identifier( $table_name ); - $quoted_tmp_table_name = $this->quote_sqlite_identifier( $tmp_table_name ); - $queries = $this->get_sqlite_create_table_statement( $table_name, $tmp_table_name ); - $create_table_query = $queries[0]; - $constraint_queries = array_slice( $queries, 1 ); - $this->execute_sqlite_query( $create_table_query ); - - // 3. Copy data from the original table to the new table. - $this->execute_sqlite_query( - sprintf( - 'INSERT INTO %s (%s) SELECT %s FROM %s', - $quoted_tmp_table_name, - implode( - ', ', - array_map( array( $this, 'quote_sqlite_identifier' ), $column_map ) - ), - implode( - ', ', - array_map( array( $this, 'quote_sqlite_identifier' ), array_keys( $column_map ) ) - ), - $quoted_table_name - ) - ); - - // 4. Drop the original table. - $this->execute_sqlite_query( sprintf( 'DROP TABLE %s', $quoted_table_name ) ); - - // 5. Rename the new table to the original table name. - $this->execute_sqlite_query( - sprintf( - 'ALTER TABLE %s RENAME TO %s', - $quoted_tmp_table_name, - $quoted_table_name - ) - ); - - // 6. Reconstruct indexes, triggers, and views. - foreach ( $constraint_queries as $query ) { - $this->execute_sqlite_query( $query ); - } - - // 7. If foreign key constraints were enabled, verify and enable them. - if ( '1' === $pragma_foreign_keys ) { - $this->execute_sqlite_query( 'PRAGMA foreign_key_check' ); - $this->execute_sqlite_query( 'PRAGMA foreign_keys = ON' ); - } - - // @TODO: Triggers and views. + $this->recreate_table_from_information_schema( $table_name, $column_map ); // @TODO: Consider using a "fast path" for ALTER TABLE statements that // consist only of operations that SQLite's ALTER TABLE supports. @@ -1234,7 +1221,7 @@ private function execute_drop_table_statement( WP_Parser_Node $node ): void { // Replace table list with the current table reference. if ( ! $is_token && 'tableRefList' === $child->rule_name ) { // Add a "temp." schema prefix for temporary tables. - $prefix = $is_temporary ? '"temp".' : ''; + $prefix = $is_temporary ? '`temp`.' : ''; $part = $prefix . $this->translate( $table_ref ); } else { $part = $this->translate( $child ); @@ -1253,6 +1240,24 @@ private function execute_drop_table_statement( WP_Parser_Node $node ): void { $this->information_schema_builder->record_drop_table( $node ); } + /** + * Translate and execute a MySQL TRUNCATE TABLE statement in SQLite. + * + * @param WP_Parser_Node $node The "truncateTableStatement" AST node. + * @throws WP_SQLite_Driver_Exception When the query execution fails. + */ + private function execute_truncate_table_statement( WP_Parser_Node $node ): void { + $table_name = $this->unquote_sqlite_identifier( + $this->translate( $node->get_first_child_node( 'tableRef' ) ) + ); + + $quoted_table_name = $this->quote_sqlite_identifier( $table_name ); + + $this->execute_sqlite_query( "DELETE FROM $quoted_table_name" ); + $this->execute_sqlite_query( 'DELETE FROM sqlite_sequence WHERE name = ?', array( $table_name ) ); + $this->set_result_from_affected_rows(); + } + /** * Translate and execute a MySQL SHOW statement in SQLite. * @@ -1265,6 +1270,10 @@ private function execute_show_statement( WP_Parser_Node $node ): void { $keyword2 = $tokens[2] ?? null; switch ( $keyword1->id ) { + case WP_MySQL_Lexer::COLUMNS_SYMBOL: + case WP_MySQL_Lexer::FIELDS_SYMBOL: + $this->execute_show_columns_statement( $node ); + break; case WP_MySQL_Lexer::CREATE_SYMBOL: if ( WP_MySQL_Lexer::TABLE_SYMBOL === $keyword2->id ) { $table_name = $this->unquote_sqlite_identifier( @@ -1329,7 +1338,29 @@ private function execute_show_statement( WP_Parser_Node $node ): void { * @param string $table_name The table name to show indexes for. */ private function execute_show_index_statement( string $table_name ): void { - $index_info = $this->execute_sqlite_query( + // TODO: FROM/IN (multiple) + // TODO: WHERE + + /* + * TODO: Index naming. + * + * From the old driver: + * + * SQLite automatically assigns names to some indexes. + * However, dbDelta in WordPress expects the name to be + * the same as in the original CREATE TABLE. Let's + * translate the name back. + * + * The old driver does the two following conversions: + * 1) + * $mysql_key_name = substr( $mysql_key_name, strlen( 'sqlite_autoindex_' ) ); + * $mysql_key_name = preg_replace( '/_[0-9]+$/', '', $mysql_key_name ); + * 2) + * $mysql_key_name = substr( $mysql_key_name, strlen( "{$table_name}__" ) ); + */ + + $statistics_table = $this->information_schema_builder->get_table_name( 'statistics' ); + $index_info = $this->execute_sqlite_query( ' SELECT TABLE_NAME AS `Table`, @@ -1347,7 +1378,7 @@ private function execute_show_index_statement( string $table_name ): void { INDEX_COMMENT AS `Index_comment`, IS_VISIBLE AS `Visible`, EXPRESSION AS `Expression` - FROM _mysql_information_schema_statistics + FROM ' . $statistics_table . ' WHERE table_schema = ? AND table_name = ? ORDER BY @@ -1385,9 +1416,10 @@ private function execute_show_table_status_statement( WP_Parser_Node $node ): vo } // Fetch table information. - $table_info = $this->execute_sqlite_query( + $tables_tables = $this->information_schema_builder->get_table_name( 'tables' ); + $table_info = $this->execute_sqlite_query( sprintf( - 'SELECT * FROM _mysql_information_schema_tables WHERE table_schema = ? %s', + "SELECT * FROM $tables_tables WHERE table_schema = ? %s", $condition ?? '' ), array( $database ) @@ -1449,9 +1481,10 @@ private function execute_show_tables_statement( WP_Parser_Node $node ): void { } // Fetch table information. - $table_info = $this->execute_sqlite_query( + $table_tables = $this->information_schema_builder->get_table_name( 'tables' ); + $table_info = $this->execute_sqlite_query( sprintf( - 'SELECT * FROM _mysql_information_schema_tables WHERE table_schema = ? %s', + "SELECT * FROM $table_tables WHERE table_schema = ? %s", $condition ?? '' ), array( $database ) @@ -1480,6 +1513,80 @@ private function execute_show_tables_statement( WP_Parser_Node $node ): void { $this->set_results_from_fetched_data( $tables ); } + /** + * Translate and execute a MySQL SHOW COLUMNS statement in SQLite. + * + * @param WP_Parser_Node $node The "showStatement" AST node. + * @throws WP_SQLite_Driver_Exception When the query execution fails. + * @throws PDOException When given table doesn't exist. + */ + private function execute_show_columns_statement( WP_Parser_Node $node ): void { + // TODO: EXTENDED, FULL + $table_name = $this->unquote_sqlite_identifier( + $this->translate( $node->get_first_child_node( 'tableRef' ) ) + ); + + // FROM/IN database. + $in_db = $node->get_first_child_node( 'inDb' ); + if ( null === $in_db ) { + $database = $this->db_name; + } else { + $database = $this->unquote_sqlite_identifier( + $this->translate( $in_db->get_first_child_node( 'identifier' ) ) + ); + } + + // Check if the table exists. + $tables_tables = $this->information_schema_builder->get_table_name( 'tables' ); + $table_exists = $this->execute_sqlite_query( + "SELECT 1 FROM $tables_tables WHERE table_schema = ? AND table_name = ?", + array( $this->db_name, $table_name ) + )->fetchColumn(); + + if ( ! $table_exists ) { + throw $this->new_driver_exception( + sprintf( "Table '%s.%s' doesn't exist", $database, $table_name ), + '42S02' + ); + } + + // LIKE and WHERE clauses. + $like_or_where = $node->get_first_child_node( 'likeOrWhere' ); + if ( null !== $like_or_where ) { + $condition = $this->translate_show_like_or_where_condition( $like_or_where ); + } + + // Fetch column information. + $column_info = $this->execute_sqlite_query( + sprintf( + 'SELECT * FROM %s WHERE table_schema = ? AND table_name = ? %s', + $this->information_schema_builder->get_table_name( 'columns' ), + $condition ?? '' + ), + array( $database, $table_name ) + )->fetchAll( PDO::FETCH_ASSOC ); + + if ( false === $column_info ) { + $this->set_results_from_fetched_data( array() ); + } + + // Format the results. + $columns = array(); + foreach ( $column_info as $value ) { + $column = array( + 'Field' => $value['COLUMN_NAME'], + 'Type' => $value['COLUMN_TYPE'], + 'Null' => $value['IS_NULLABLE'], + 'Key' => $value['COLUMN_KEY'], + 'Default' => $value['COLUMN_DEFAULT'], + 'Extra' => $value['EXTRA'], + ); + $columns[] = (object) $column; + } + + $this->set_results_from_fetched_data( $columns ); + } + /** * Translate and execute a MySQL DESCRIBE statement in SQLite. * @@ -1491,8 +1598,9 @@ private function execute_describe_statement( WP_Parser_Node $node ): void { $this->translate( $node->get_first_child_node( 'tableRef' ) ) ); - $column_info = $this->execute_sqlite_query( - ' + $columns_table = $this->information_schema_builder->get_table_name( 'columns' ); + $column_info = $this->execute_sqlite_query( + " SELECT column_name AS `Field`, column_type AS `Type`, @@ -1500,16 +1608,121 @@ private function execute_describe_statement( WP_Parser_Node $node ): void { column_key AS `Key`, column_default AS `Default`, extra AS Extra - FROM _mysql_information_schema_columns + FROM $columns_table WHERE table_schema = ? AND table_name = ? - ', + ", array( $this->db_name, $table_name ) )->fetchAll( PDO::FETCH_OBJ ); $this->set_results_from_fetched_data( $column_info ); } + /** + * Translate and execute a MySQL USE statement in SQLite. + * + * @param WP_Parser_Node $node The "useStatement" AST node. + * @throws WP_SQLite_Driver_Exception When the query execution fails. + */ + private function execute_use_statement( WP_Parser_Node $node ): void { + $database_name = $this->unquote_sqlite_identifier( + $this->translate( $node->get_first_child_node( 'identifier' ) ) + ); + + if ( 'information_schema' === strtolower( $database_name ) ) { + $this->db_name = 'information_schema'; + } elseif ( $this->db_name === $database_name ) { + $this->db_name = $database_name; + } else { + throw $this->new_not_supported_exception( + sprintf( + "can't use schema '%s', only '%s' and 'information_schema' are supported", + $database_name, + $this->db_name + ) + ); + } + } + + /** + * Translate and execute a MySQL administration statement in SQLite. + * + * This emulates the following MySQL statements: + * - ANALYZE TABLE + * - CHECK TABLE + * - OPTIMIZE TABLE + * - REPAIR TABLE + * + * @param WP_Parser_Node $node A "tableAdministrationStatement" AST node. + * @throws WP_SQLite_Driver_Exception When the query execution fails. + */ + private function execute_administration_statement( WP_Parser_Node $node ): void { + $first_token = $node->get_first_child_token(); + $table_ref_list = $node->get_first_child_node( 'tableRefList' ); + $results = array(); + foreach ( $table_ref_list->get_child_nodes( 'tableRef' ) as $table_ref ) { + $table_name = $this->unquote_sqlite_identifier( $this->translate( $table_ref ) ); + $quoted_table_name = $this->quote_sqlite_identifier( $table_name ); + try { + switch ( $first_token->id ) { + case WP_MySQL_Lexer::ANALYZE_SYMBOL: + $stmt = $this->execute_sqlite_query( "ANALYZE $quoted_table_name" ); + $errors = $stmt->fetchAll( PDO::FETCH_COLUMN ); + break; + case WP_MySQL_Lexer::CHECK_SYMBOL: + $stmt = $this->execute_sqlite_query( "PRAGMA integrity_check($quoted_table_name)" ); + $errors = $stmt->fetchAll( PDO::FETCH_COLUMN ); + if ( 'ok' === $errors[0] ) { + array_shift( $errors ); + } + break; + case WP_MySQL_Lexer::OPTIMIZE_SYMBOL: + case WP_MySQL_Lexer::REPAIR_SYMBOL: + /* + * SQLite doesn't support OPTIMIZE and REPAIR TABLE commands. + * We will recreate the table and copy the data instead. + * This corresponds to older MySQL OPTIMIZE TABLE behavior + * and still applies to some storage engines in some cases. + */ + $this->recreate_table_from_information_schema( $table_name ); + $errors = array(); + break; + default: + throw $this->new_not_supported_exception( + sprintf( + 'statement type: "%s" > "%s"', + $node->rule_name, + $first_token->value + ) + ); + } + } catch ( PDOException $e ) { + if ( 'HY000' === $e->getCode() ) { + $errors = array( "Table '$table_name' doesn't exist" ); + } else { + $errors = array( $e->getMessage() ); + } + } + + $operation = strtolower( $first_token->value ); + foreach ( $errors as $error ) { + $results[] = (object) array( + 'Table' => $this->db_name . '.' . $table_name, + 'Op' => $operation, + 'Msg_type' => 'Error', + 'Msg_text' => $error, + ); + } + $results[] = (object) array( + 'Table' => $this->db_name . '.' . $table_name, + 'Op' => $operation, + 'Msg_type' => 'status', + 'Msg_text' => count( $errors ) > 0 ? 'Operation failed' : 'OK', + ); + } + $this->set_results_from_fetched_data( $results ); + } + /** * Translate a MySQL AST node or token to an SQLite query fragment. * @@ -1553,7 +1766,30 @@ private function translate( $node ): ?string { return implode( ' ', $parts ); } return $this->translate_sequence( $node->get_children() ); + case 'schemaRef': + return $this->translate_schema_identifier( $node ); case 'qualifiedIdentifier': + case 'tableRefWithWildcard': + $parts = $node->get_descendant_nodes( 'identifier' ); + if ( count( $parts ) === 2 ) { + return $this->translate_qualified_identifier( $parts[0], $parts[1] ); + } + return $this->translate_qualified_identifier( null, $parts[0] ); + case 'fieldIdentifier': + case 'simpleIdentifier': + $parts = $node->get_descendant_nodes( 'identifier' ); + if ( count( $parts ) === 3 ) { + return $this->translate_qualified_identifier( $parts[0], $parts[1], $parts[2] ); + } elseif ( count( $parts ) === 2 ) { + return $this->translate_qualified_identifier( null, $parts[0], $parts[1] ); + } + return $this->translate_qualified_identifier( null, null, $parts[0] ); + case 'tableWild': + $parts = $node->get_descendant_nodes( 'identifier' ); + if ( count( $parts ) === 2 ) { + return $this->translate_qualified_identifier( $parts[0], $parts[1] ) . '.*'; + } + return $this->translate_qualified_identifier( null, $parts[0] ) . '.*'; case 'dotIdentifier': return $this->translate_sequence( $node->get_children(), '' ); case 'identifierKeyword': @@ -1820,6 +2056,107 @@ private function translate_pure_identifier( WP_Parser_Node $node ): string { return '`' . str_replace( '`', '``', $value ) . '`'; } + /** + * Translate a qualified MySQL identifier to SQLite. + * + * The identifier can be composed of 1 to 3 parts (schema, object, child). + * + * @param WP_Parser_Node|null $schema_node An identifier node representing a schema name (database). + * @param WP_Parser_Node|null $object_node An identifier node representing a database-level object name + * (table, view, procedure, trigger, etc.). + * @param WP_Parser_Node|null $child_node An identifier node representing an object child name (column, index, etc.). + * @return string The translated value. + * @throws WP_SQLite_Driver_Exception When the translation fails. + */ + private function translate_qualified_identifier( + ?WP_Parser_Node $schema_node, + ?WP_Parser_Node $object_node = null, + ?WP_Parser_Node $child_node = null + ): string { + $parts = array(); + $uses_reserved_prefix = false; + + // Database name. + $is_information_schema = 'information_schema' === $this->db_name; + if ( null !== $schema_node ) { + $schema_name = $this->unquote_sqlite_identifier( + $this->translate_sequence( $schema_node->get_children() ) + ); + if ( 'information_schema' === strtolower( $schema_name ) ) { + $is_information_schema = true; + } elseif ( $this->db_name === $schema_name ) { + $is_information_schema = false; + } else { + throw $this->new_not_supported_exception( + sprintf( + "can't use schema '%s', only '%s' and 'information_schema' are supported", + $schema_name, + $this->db_name + ) + ); + } + } + + /* + * Make the 'information_schema' database read-only. + * + * This basic approach is rather restrictive, as it blocks the usage + * of information schema tables in all data-modifying statements. + * + * Some of these statements can be valid, when the schema is only read: + * DELETE t FROM t JOIN information_schema.columns c ON ... + * + * If needed, a more granular approach can be implemented in the future. + */ + if ( true === $is_information_schema && false === $this->is_readonly ) { + throw $this->new_driver_exception( + "Access denied for user 'sqlite'@'%' to database 'information_schema'", + '42000' + ); + } + + // Database-level object name (table, view, procedure, trigger, etc.). + if ( null !== $object_node ) { + if ( $is_information_schema ) { + $object_name = $this->unquote_sqlite_identifier( + $this->translate_sequence( $object_node->get_children() ) + ); + $parts[] = $this->information_schema_builder->get_table_name( $object_name ); + } else { + $quoted_object_name = $this->translate( $object_node ); + $object_name = $this->unquote_sqlite_identifier( $quoted_object_name ); + if ( str_starts_with( $object_name, self::RESERVED_PREFIX ) ) { + $uses_reserved_prefix = true; + } + $parts[] = $quoted_object_name; + } + } + + // Object child name (column, index, etc.). + if ( null !== $child_node ) { + $quoted_object_name = $this->translate( $child_node ); + $object_name = $this->unquote_sqlite_identifier( $quoted_object_name ); + if ( str_starts_with( $object_name, self::RESERVED_PREFIX ) ) { + $uses_reserved_prefix = true; + } + $parts[] = $quoted_object_name; + } + + $identifier = implode( '.', $parts ); + + if ( true === $uses_reserved_prefix ) { + throw $this->new_driver_exception( + sprintf( + "Invalid identifier %s, prefix '%s' is reserved", + $identifier, + self::RESERVED_PREFIX + ) + ); + } + + return $identifier; + } + /** * Translate a MySQL simple expression to SQLite. * @@ -2108,6 +2445,97 @@ private function translate_datetime_literal( string $value ): string { return $value; } + /** + * Recreate an existing table using data in the information schema. + * + * This is used for a generic support of ALTER TABLE queries, as well as + * for some other statements like OPTIMIZE TABLE and REPAIR TABLE. + * + * See: + * https://www.sqlite.org/lang_altertable.html#making_other_kinds_of_table_schema_changes + * + * @param string $table_name The name of the table to recreate. + * @param array $column_map Optional. A map of column names (old name -> new name) + * to use when copying data from the original table. + * When not provided, all columns are copied without renaming. + * @throws WP_SQLite_Driver_Exception + */ + private function recreate_table_from_information_schema( string $table_name, array $column_map = null ): void { + if ( null === $column_map ) { + $columns_table = $this->information_schema_builder->get_table_name( 'columns' ); + $column_names = $this->execute_sqlite_query( + "SELECT COLUMN_NAME FROM $columns_table WHERE table_schema = ? AND table_name = ?", + array( $this->db_name, $table_name ) + )->fetchAll( PDO::FETCH_COLUMN ); + $column_map = array_combine( $column_names, $column_names ); + } + + // Preserve ROWIDs. + // This also addresses a special case when all original columns are dropped + // and there is nothing to copy. We'll always have at least the ROWID column. + $column_map = array( 'rowid' => 'rowid' ) + $column_map; + + /* + * See: + * https://www.sqlite.org/lang_altertable.html#making_other_kinds_of_table_schema_changes + */ + + // 1. If foreign key constraints are enabled, disable them. + $pragma_foreign_keys = $this->execute_sqlite_query( 'PRAGMA foreign_keys' )->fetchColumn(); + $this->execute_sqlite_query( 'PRAGMA foreign_keys = OFF' ); + + // 2. Create a new table with the new schema. + $tmp_table_name = self::RESERVED_PREFIX . "tmp_{$table_name}_" . uniqid(); + $quoted_table_name = $this->quote_sqlite_identifier( $table_name ); + $quoted_tmp_table_name = $this->quote_sqlite_identifier( $tmp_table_name ); + $queries = $this->get_sqlite_create_table_statement( $table_name, $tmp_table_name ); + $create_table_query = $queries[0]; + $constraint_queries = array_slice( $queries, 1 ); + $this->execute_sqlite_query( $create_table_query ); + + // 3. Copy data from the original table to the new table. + $this->execute_sqlite_query( + sprintf( + 'INSERT INTO %s (%s) SELECT %s FROM %s', + $quoted_tmp_table_name, + implode( + ', ', + array_map( array( $this, 'quote_sqlite_identifier' ), $column_map ) + ), + implode( + ', ', + array_map( array( $this, 'quote_sqlite_identifier' ), array_keys( $column_map ) ) + ), + $quoted_table_name + ) + ); + + // 4. Drop the original table. + $this->execute_sqlite_query( sprintf( 'DROP TABLE %s', $quoted_table_name ) ); + + // 5. Rename the new table to the original table name. + $this->execute_sqlite_query( + sprintf( + 'ALTER TABLE %s RENAME TO %s', + $quoted_tmp_table_name, + $quoted_table_name + ) + ); + + // 6. Reconstruct indexes, triggers, and views. + foreach ( $constraint_queries as $query ) { + $this->execute_sqlite_query( $query ); + } + + // 7. If foreign key constraints were enabled, verify and enable them. + if ( '1' === $pragma_foreign_keys ) { + $this->execute_sqlite_query( 'PRAGMA foreign_key_check' ); + $this->execute_sqlite_query( 'PRAGMA foreign_keys = ON' ); + } + + // @TODO: Triggers and views. + } + /** * Translate a MySQL SHOW LIKE ... or SHOW WHERE ... condition to SQLite. * @@ -2146,10 +2574,11 @@ private function translate_show_like_or_where_condition( WP_Parser_Node $like_or */ private function get_sqlite_create_table_statement( string $table_name, ?string $new_table_name = null ): array { // 1. Get table info. - $table_info = $this->execute_sqlite_query( + $tables_table = $this->information_schema_builder->get_table_name( 'tables' ); + $table_info = $this->execute_sqlite_query( " SELECT * - FROM _mysql_information_schema_tables + FROM $tables_table WHERE table_type = 'BASE TABLE' AND table_schema = ? AND table_name = ? @@ -2159,19 +2588,22 @@ private function get_sqlite_create_table_statement( string $table_name, ?string if ( false === $table_info ) { throw $this->new_driver_exception( - sprintf( 'Table "%s" not found in information schema', $table_name ) + sprintf( "Table '%s' doesn't exist", $table_name ), + '42S02' ); } // 2. Get column info. - $column_info = $this->execute_sqlite_query( - 'SELECT * FROM _mysql_information_schema_columns WHERE table_schema = ? AND table_name = ?', + $columns_table = $this->information_schema_builder->get_table_name( 'columns' ); + $column_info = $this->execute_sqlite_query( + "SELECT * FROM $columns_table WHERE table_schema = ? AND table_name = ?", array( $this->db_name, $table_name ) )->fetchAll( PDO::FETCH_ASSOC ); // 3. Get index info, grouped by index name. - $constraint_info = $this->execute_sqlite_query( - 'SELECT * FROM _mysql_information_schema_statistics WHERE table_schema = ? AND table_name = ?', + $statistics_table = $this->information_schema_builder->get_table_name( 'statistics' ); + $constraint_info = $this->execute_sqlite_query( + "SELECT * FROM $statistics_table WHERE table_schema = ? AND table_name = ?", array( $this->db_name, $table_name ) )->fetchAll( PDO::FETCH_ASSOC ); @@ -2263,6 +2695,11 @@ private function get_sqlite_create_table_statement( string $table_name, ?string if ( 'PRIMARY' === $info['INDEX_NAME'] ) { if ( $has_autoincrement ) { + if ( count( $constraint ) > 1 ) { + throw $this->new_driver_exception( + 'Cannot combine AUTOINCREMENT and multiple primary keys in SQLite' + ); + } continue; } $query = ' PRIMARY KEY ('; @@ -2325,10 +2762,11 @@ function ( $column ) { */ private function get_mysql_create_table_statement( string $table_name ): ?string { // 1. Get table info. - $table_info = $this->execute_sqlite_query( + $tables_table = $this->information_schema_builder->get_table_name( 'tables' ); + $table_info = $this->execute_sqlite_query( " SELECT * - FROM _mysql_information_schema_tables + FROM $tables_table WHERE table_type = 'BASE TABLE' AND table_schema = ? AND table_name = ? @@ -2341,14 +2779,16 @@ private function get_mysql_create_table_statement( string $table_name ): ?string } // 2. Get column info. - $column_info = $this->execute_sqlite_query( - 'SELECT * FROM _mysql_information_schema_columns WHERE table_schema = ? AND table_name = ?', + $columns_table = $this->information_schema_builder->get_table_name( 'columns' ); + $column_info = $this->execute_sqlite_query( + "SELECT * FROM $columns_table WHERE table_schema = ? AND table_name = ?", array( $this->db_name, $table_name ) )->fetchAll( PDO::FETCH_ASSOC ); // 3. Get index info, grouped by index name. - $constraint_info = $this->execute_sqlite_query( - 'SELECT * FROM _mysql_information_schema_statistics WHERE table_schema = ? AND table_name = ?', + $statistics_table = $this->information_schema_builder->get_table_name( 'statistics' ); + $constraint_info = $this->execute_sqlite_query( + "SELECT * FROM $statistics_table WHERE table_schema = ? AND table_name = ?", array( $this->db_name, $table_name ) )->fetchAll( PDO::FETCH_ASSOC ); @@ -2424,7 +2864,11 @@ function ( $column ) { ', ', array_map( function ( $column ) { - return $this->quote_mysql_identifier( $column['COLUMN_NAME'] ); + $definition = $this->quote_mysql_identifier( $column['COLUMN_NAME'] ); + if ( null !== $column['SUB_PART'] ) { + $definition .= sprintf( '(%d)', $column['SUB_PART'] ); + } + return $definition; }, $constraint ) @@ -2524,6 +2968,7 @@ private function flush(): void { $this->last_sqlite_queries = array(); $this->last_result = null; $this->last_return_value = null; + $this->is_readonly = false; } /** @@ -2560,13 +3005,13 @@ private function set_result_from_affected_rows( int $override = null ): void { * Create a new SQLite driver exception. * * @param string $message The exception message. - * @param int $code The exception code. + * @param int|string $code The exception code. For PDO errors, a string representing SQLSTATE. * @param Throwable|null $previous The previous exception. * @return WP_SQLite_Driver_Exception */ private function new_driver_exception( string $message, - int $code = 0, + $code = 0, Throwable $previous = null ): WP_SQLite_Driver_Exception { return new WP_SQLite_Driver_Exception( $this, $message, $code, $previous ); diff --git a/wp-includes/sqlite-ast/class-wp-sqlite-information-schema-builder.php b/wp-includes/sqlite-ast/class-wp-sqlite-information-schema-builder.php index ac4322a..7c2d87b 100644 --- a/wp-includes/sqlite-ast/class-wp-sqlite-information-schema-builder.php +++ b/wp-includes/sqlite-ast/class-wp-sqlite-information-schema-builder.php @@ -29,7 +29,7 @@ class WP_SQLite_Information_Schema_Builder { */ const CREATE_INFORMATION_SCHEMA_QUERIES = array( // TABLES - "CREATE TABLE IF NOT EXISTS _mysql_information_schema_tables ( + "CREATE TABLE IF NOT EXISTS tables ( -- '' is a placeholder replaced at runtime TABLE_CATALOG TEXT NOT NULL DEFAULT 'def', -- always 'def' TABLE_SCHEMA TEXT NOT NULL, -- database name TABLE_NAME TEXT NOT NULL, -- table name @@ -50,12 +50,12 @@ class WP_SQLite_Information_Schema_Builder { CHECK_TIME TEXT, -- not implemented TABLE_COLLATION TEXT NOT NULL, -- table collation CHECKSUM INTEGER, -- not implemented - CREATE_OPTIONS TEXT, -- extra CREATE TABLE options + CREATE_OPTIONS TEXT NOT NULL DEFAULT '', -- extra CREATE TABLE options TABLE_COMMENT TEXT NOT NULL DEFAULT '' -- comment ) STRICT", // COLUMNS - "CREATE TABLE IF NOT EXISTS _mysql_information_schema_columns ( + "CREATE TABLE IF NOT EXISTS columns ( -- '' is a placeholder replaced at runtime TABLE_CATALOG TEXT NOT NULL DEFAULT 'def', -- always 'def' TABLE_SCHEMA TEXT NOT NULL, -- database name TABLE_NAME TEXT NOT NULL, -- table name @@ -82,7 +82,7 @@ class WP_SQLite_Information_Schema_Builder { // VIEWS // @TODO: Implement. - 'CREATE TABLE IF NOT EXISTS _mysql_information_schema_views ( + "CREATE TABLE IF NOT EXISTS views ( -- '' is a placeholder replaced at runtime TABLE_CATALOG TEXT NOT NULL, TABLE_SCHEMA TEXT NOT NULL, TABLE_NAME TEXT NOT NULL, @@ -94,54 +94,54 @@ class WP_SQLite_Information_Schema_Builder { CHARACTER_SET_CLIENT TEXT NOT NULL, COLLATION_CONNECTION TEXT NOT NULL, ALGORITHM TEXT NOT NULL - ) STRICT', + ) STRICT", // STATISTICS (indexes) - "CREATE TABLE IF NOT EXISTS _mysql_information_schema_statistics ( - TABLE_CATALOG TEXT NOT NULL DEFAULT 'def', -- always 'def' - TABLE_SCHEMA TEXT NOT NULL, -- database name - TABLE_NAME TEXT NOT NULL, -- table name - NON_UNIQUE INTEGER NOT NULL, -- 0 for unique indexes, 1 otherwise - INDEX_SCHEMA TEXT NOT NULL, -- index database name - INDEX_NAME TEXT NOT NULL, -- index name, for PKs always 'PRIMARY' - SEQ_IN_INDEX INTEGER NOT NULL, -- column position in index (from 1) - COLUMN_NAME TEXT, -- column name (NULL for functional indexes) - COLLATION TEXT, -- column sort in the index ('A', 'D', or NULL) - CARDINALITY INTEGER, -- not implemented - SUB_PART INTEGER, -- number of indexed chars, NULL for full column - PACKED TEXT, -- not implemented - NULLABLE TEXT NOT NULL, -- 'YES' if column can contain NULL, '' otherwise - INDEX_TYPE TEXT NOT NULL, -- 'BTREE', 'FULLTEXT', 'SPATIAL' - COMMENT TEXT NOT NULL DEFAULT '', -- not implemented - INDEX_COMMENT TEXT NOT NULL DEFAULT '', -- index comment - IS_VISIBLE TEXT NOT NULL DEFAULT 'YES', -- 'NO' if column is hidden, 'YES' otherwise - EXPRESSION TEXT -- expression for functional indexes + "CREATE TABLE IF NOT EXISTS statistics ( -- '' is a placeholder replaced at runtime + TABLE_CATALOG TEXT NOT NULL DEFAULT 'def', -- always 'def' + TABLE_SCHEMA TEXT NOT NULL, -- database name + TABLE_NAME TEXT NOT NULL, -- table name + NON_UNIQUE INTEGER NOT NULL, -- 0 for unique indexes, 1 otherwise + INDEX_SCHEMA TEXT NOT NULL, -- index database name + INDEX_NAME TEXT NOT NULL, -- index name, for PKs always 'PRIMARY' + SEQ_IN_INDEX INTEGER NOT NULL, -- column position in index (from 1) + COLUMN_NAME TEXT, -- column name (NULL for functional indexes) + COLLATION TEXT, -- column sort in the index ('A', 'D', or NULL) + CARDINALITY INTEGER, -- not implemented + SUB_PART INTEGER, -- number of indexed chars, NULL for full column + PACKED TEXT, -- not implemented + NULLABLE TEXT NOT NULL, -- 'YES' if column can contain NULL, '' otherwise + INDEX_TYPE TEXT NOT NULL, -- 'BTREE', 'FULLTEXT', 'SPATIAL' + COMMENT TEXT NOT NULL DEFAULT '', -- not implemented + INDEX_COMMENT TEXT NOT NULL DEFAULT '', -- index comment + IS_VISIBLE TEXT NOT NULL DEFAULT 'YES', -- 'NO' if column is hidden, 'YES' otherwise + EXPRESSION TEXT -- expression for functional indexes ) STRICT", // TABLE_CONSTRAINTS // @TODO: Implement. Could this be just a view? - 'CREATE TABLE IF NOT EXISTS _mysql_information_schema_table_constraints ( + "CREATE TABLE IF NOT EXISTS constraints ( -- '' is a placeholder replaced at runtime CONSTRAINT_CATALOG TEXT NOT NULL, CONSTRAINT_SCHEMA TEXT NOT NULL, CONSTRAINT_NAME TEXT NOT NULL, TABLE_SCHEMA TEXT NOT NULL, TABLE_NAME TEXT NOT NULL, CONSTRAINT_TYPE TEXT NOT NULL - ) STRICT', + ) STRICT", // CHECK_CONSTRAINTS // @TODO: Implement. - 'CREATE TABLE IF NOT EXISTS _mysql_information_schema_check_constraints ( + "CREATE TABLE IF NOT EXISTS check_constraints ( -- '' is a placeholder replaced at runtime CONSTRAINT_CATALOG TEXT NOT NULL, CONSTRAINT_SCHEMA TEXT NOT NULL, TABLE_NAME TEXT NOT NULL, CONSTRAINT_NAME TEXT NOT NULL, CHECK_CLAUSE TEXT NOT NULL - ) STRICT', + ) STRICT", // KEY_COLUMN_USAGE // @TODO: Implement. - 'CREATE TABLE IF NOT EXISTS _mysql_information_schema_key_column_usage ( + "CREATE TABLE IF NOT EXISTS key_column_usage ( -- '' is a placeholder replaced at runtime CONSTRAINT_CATALOG TEXT NOT NULL, CONSTRAINT_SCHEMA TEXT NOT NULL, CONSTRAINT_NAME TEXT NOT NULL, @@ -154,11 +154,11 @@ class WP_SQLite_Information_Schema_Builder { REFERENCED_TABLE_SCHEMA TEXT, REFERENCED_TABLE_NAME TEXT, REFERENCED_COLUMN_NAME TEXT - ) STRICT', + ) STRICT", // REFERENTIAL_CONSTRAINTS // @TODO: Implement. - 'CREATE TABLE IF NOT EXISTS _mysql_information_schema_referential_constraints ( + "CREATE TABLE IF NOT EXISTS referential_constraints ( -- '' is a placeholder replaced at runtime CONSTRAINT_CATALOG TEXT NOT NULL, CONSTRAINT_SCHEMA TEXT NOT NULL, CONSTRAINT_NAME TEXT NOT NULL, @@ -169,11 +169,11 @@ class WP_SQLite_Information_Schema_Builder { UPDATE_RULE TEXT NOT NULL, DELETE_RULE TEXT NOT NULL, REFERENCED_TABLE_NAME TEXT NOT NULL - ) STRICT', + ) STRICT", // TRIGGERS // @TODO: Implement. - 'CREATE TABLE IF NOT EXISTS _mysql_information_schema_triggers ( + "CREATE TABLE IF NOT EXISTS triggers ( -- '' is a placeholder replaced at runtime TRIGGER_CATALOG TEXT NOT NULL, TRIGGER_SCHEMA TEXT NOT NULL, TRIGGER_NAME TEXT NOT NULL, @@ -196,7 +196,7 @@ class WP_SQLite_Information_Schema_Builder { CHARACTER_SET_CLIENT TEXT NOT NULL, COLLATION_CONNECTION TEXT NOT NULL, DATABASE_COLLATION TEXT NOT NULL - ) STRICT', + ) STRICT", ); /** @@ -329,6 +329,13 @@ class WP_SQLite_Information_Schema_Builder { */ private $db_name; + /** + * A prefix for information schema table names. + * + * @var string + */ + private $table_prefix; + /** * Query callback. * @@ -342,12 +349,24 @@ class WP_SQLite_Information_Schema_Builder { /** * Constructor. * - * @param string $database Database name. - * @param callable(string, array): PDOStatement $query_callback A callback that executes an SQLite query. + * @param string $database Database name. + * @param string $reserved_prefix An identifier prefix for internal database objects. + * @param callable(string, array): PDOStatement $query_callback A callback that executes an SQLite query. */ - public function __construct( string $database, callable $query_callback ) { + public function __construct( string $database, string $reserved_prefix, callable $query_callback ) { $this->db_name = $database; $this->query_callback = $query_callback; + $this->table_prefix = $reserved_prefix . 'mysql_information_schema_'; + } + + /** + * Get SQLite table name for the given MySQL information schema table name. + * + * @param string $infromation_schema_table_name The MySQL information schema table name. + * @return string The SQLite table name. + */ + public function get_table_name( string $infromation_schema_table_name ): string { + return $this->table_prefix . $infromation_schema_table_name; } /** @@ -356,7 +375,7 @@ public function __construct( string $database, callable $query_callback ) { */ public function ensure_information_schema_tables(): void { foreach ( self::CREATE_INFORMATION_SCHEMA_QUERIES as $query ) { - $this->query( $query ); + $this->query( str_replace( '', $this->table_prefix, $query ) ); } } @@ -368,12 +387,12 @@ public function ensure_information_schema_tables(): void { public function record_create_table( WP_Parser_Node $node ): void { $table_name = $this->get_value( $node->get_first_descendant_node( 'tableName' ) ); $table_engine = $this->get_table_engine( $node ); - $table_row_format = 'MyISAM' === $table_engine ? 'FIXED' : 'DYNAMIC'; + $table_row_format = 'MyISAM' === $table_engine ? 'Fixed' : 'Dynamic'; $table_collation = $this->get_table_collation( $node ); // 1. Table. $this->insert_values( - '_mysql_information_schema_tables', + 'tables', array( 'table_schema' => $this->db_name, 'table_name' => $table_name, @@ -387,7 +406,7 @@ public function record_create_table( WP_Parser_Node $node ): void { // 2. Columns. $column_position = 1; foreach ( $node->get_descendant_nodes( 'columnDefinition' ) as $column_node ) { - $column_name = $this->get_value( $column_node->get_first_child_node( 'columnName' ) ); + $column_name = $this->get_value( $column_node->get_first_child_node( 'fieldIdentifier' ) ); // Column definition. $column_data = $this->extract_column_data( @@ -396,7 +415,7 @@ public function record_create_table( WP_Parser_Node $node ): void { $column_node, $column_position ); - $this->insert_values( '_mysql_information_schema_columns', $column_data ); + $this->insert_values( 'columns', $column_data ); // Inline column constraint. $column_constraint_data = $this->extract_column_constraint_data( @@ -406,10 +425,7 @@ public function record_create_table( WP_Parser_Node $node ): void { 'YES' === $column_data['is_nullable'] ); if ( null !== $column_constraint_data ) { - $this->insert_values( - '_mysql_information_schema_statistics', - $column_constraint_data - ); + $this->insert_values( 'statistics', $column_constraint_data ); } $column_position += 1; @@ -466,7 +482,7 @@ public function record_alter_table( WP_Parser_Node $node ): void { // CHANGE [COLUMN] if ( WP_MySQL_Lexer::CHANGE_SYMBOL === $first_token->id ) { - $old_name = $this->get_value( $action->get_first_child_node( 'columnInternalRef' ) ); + $old_name = $this->get_value( $action->get_first_child_node( 'fieldIdentifier' ) ); $new_name = $this->get_value( $action->get_first_child_node( 'identifier' ) ); $this->record_change_column( $table_name, @@ -479,7 +495,7 @@ public function record_alter_table( WP_Parser_Node $node ): void { // MODIFY [COLUMN] if ( WP_MySQL_Lexer::MODIFY_SYMBOL === $first_token->id ) { - $name = $this->get_value( $action->get_first_child_node( 'columnInternalRef' ) ); + $name = $this->get_value( $action->get_first_child_node( 'fieldIdentifier' ) ); $this->record_modify_column( $table_name, $name, @@ -491,7 +507,7 @@ public function record_alter_table( WP_Parser_Node $node ): void { // DROP if ( WP_MySQL_Lexer::DROP_SYMBOL === $first_token->id ) { // DROP [COLUMN] - $column_ref = $action->get_first_child_node( 'columnInternalRef' ); + $column_ref = $action->get_first_child_node( 'fieldIdentifier' ); if ( null !== $column_ref ) { $name = $this->get_value( $column_ref ); $this->record_drop_column( $table_name, $name ); @@ -523,21 +539,21 @@ public function record_drop_table( WP_Parser_Node $node ): void { foreach ( $table_refs as $table_ref ) { $table_name = $this->get_value( $table_ref ); $this->delete_values( - '_mysql_information_schema_tables', + 'tables', array( 'table_schema' => $this->db_name, 'table_name' => $table_name, ) ); $this->delete_values( - '_mysql_information_schema_columns', + 'columns', array( 'table_schema' => $this->db_name, 'table_name' => $table_name, ) ); $this->delete_values( - '_mysql_information_schema_statistics', + 'statistics', array( 'table_schema' => $this->db_name, 'table_name' => $table_name, @@ -556,22 +572,23 @@ public function record_drop_table( WP_Parser_Node $node ): void { * @param WP_Parser_Node $node The "columnDefinition" or "fieldDefinition" AST node. */ private function record_add_column( string $table_name, string $column_name, WP_Parser_Node $node ): void { - $position = $this->query( - ' + $columns_table_name = $this->get_table_name( 'columns' ); + $position = $this->query( + " SELECT MAX(ordinal_position) - FROM _mysql_information_schema_columns + FROM $columns_table_name WHERE table_schema = ? AND table_name = ? - ', + ", array( $this->db_name, $table_name ) )->fetchColumn(); $column_data = $this->extract_column_data( $table_name, $column_name, $node, (int) $position + 1 ); - $this->insert_values( '_mysql_information_schema_columns', $column_data ); + $this->insert_values( 'columns', $column_data ); $column_constraint_data = $this->extract_column_constraint_data( $table_name, $column_name, $node, true ); if ( null !== $column_constraint_data ) { - $this->insert_values( '_mysql_information_schema_statistics', $column_constraint_data ); + $this->insert_values( 'statistics', $column_constraint_data ); } } @@ -591,7 +608,7 @@ private function record_change_column( ): void { $column_data = $this->extract_column_data( $table_name, $new_column_name, $node, 0 ); $this->update_values( - '_mysql_information_schema_columns', + 'columns', $column_data, array( 'table_schema' => $this->db_name, @@ -603,7 +620,7 @@ private function record_change_column( // Update column name in statistics, if it has changed. if ( $new_column_name !== $column_name ) { $this->update_values( - '_mysql_information_schema_statistics', + 'statistics', array( 'column_name' => $new_column_name, ), @@ -624,7 +641,7 @@ private function record_change_column( 'YES' === $column_data['is_nullable'] ); if ( null !== $column_constraint_data ) { - $this->insert_values( '_mysql_information_schema_statistics', $column_constraint_data ); + $this->insert_values( 'statistics', $column_constraint_data ); $this->sync_column_key_info( $table_name ); } } @@ -652,7 +669,7 @@ private function record_modify_column( */ private function record_drop_column( $table_name, $column_name ): void { $this->delete_values( - '_mysql_information_schema_columns', + 'columns', array( 'table_schema' => $this->db_name, 'table_name' => $table_name, @@ -674,7 +691,7 @@ private function record_drop_column( $table_name, $column_name ): void { * - https://dev.mysql.com/doc/refman/8.4/en/alter-table.html */ $this->delete_values( - '_mysql_information_schema_statistics', + 'statistics', array( 'table_schema' => $this->db_name, 'table_name' => $table_name, @@ -695,7 +712,7 @@ private function record_drop_column( $table_name, $column_name ): void { */ private function record_drop_index( string $table_name, string $index_name ): void { $this->delete_values( - '_mysql_information_schema_statistics', + 'statistics', array( 'table_schema' => $this->db_name, 'table_name' => $table_name, @@ -746,13 +763,14 @@ private function record_add_constraint( string $table_name, WP_Parser_Node $node // Fetch column info. $column_names = array_filter( $key_part_column_names ); if ( count( $column_names ) > 0 ) { - $column_info = $this->query( - ' + $columns_table_name = $this->get_table_name( 'columns' ); + $column_info = $this->query( + " SELECT column_name, data_type, is_nullable, character_maximum_length - FROM _mysql_information_schema_columns + FROM $columns_table_name WHERE table_schema = ? AND table_name = ? - AND column_name IN (' . implode( ',', array_fill( 0, count( $column_names ), '?' ) ) . ') + AND column_name IN (" . implode( ',', array_fill( 0, count( $column_names ), '?' ) ) . ') ', array_merge( array( $this->db_name, $table_name ), $column_names ) )->fetchAll( @@ -796,7 +814,7 @@ private function record_add_constraint( string $table_name, WP_Parser_Node $node ); $this->insert_values( - '_mysql_information_schema_statistics', + 'statistics', array( 'table_schema' => $this->db_name, 'table_name' => $table_name, @@ -926,6 +944,8 @@ private function extract_column_constraint_data( string $table_name, string $col */ private function sync_column_key_info( string $table_name ): void { // @TODO: Consider listing only affected columns. + $columns_table_name = $this->get_table_name( 'columns' ); + $statistics_table_name = $this->get_table_name( 'statistics' ); $this->query( " WITH s AS ( @@ -937,12 +957,12 @@ private function sync_column_key_info( string $table_name ): void { WHEN MAX(seq_in_index = 1) THEN 'MUL' ELSE '' END AS column_key - FROM _mysql_information_schema_statistics + FROM $statistics_table_name WHERE table_schema = ? AND table_name = ? GROUP BY column_name ) - UPDATE _mysql_information_schema_columns AS c + UPDATE $columns_table_name AS c SET column_key = s.column_key, is_nullable = IIF(s.column_key = 'PRI', 'NO', c.is_nullable) @@ -1742,7 +1762,7 @@ private function get_value( WP_Parser_Node $node ): string { private function insert_values( string $table_name, array $data ): void { $this->query( ' - INSERT INTO ' . $table_name . ' (' . implode( ', ', array_keys( $data ) ) . ') + INSERT INTO ' . $this->get_table_name( $table_name ) . ' (' . implode( ', ', array_keys( $data ) ) . ') VALUES (' . implode( ', ', array_fill( 0, count( $data ), '?' ) ) . ') ', array_values( $data ) @@ -1769,7 +1789,7 @@ private function update_values( string $table_name, array $data, array $where ): $this->query( ' - UPDATE ' . $table_name . ' + UPDATE ' . $this->get_table_name( $table_name ) . ' SET ' . implode( ', ', $set ) . ' WHERE ' . implode( ' AND ', $where_clause ) . ' ', @@ -1791,7 +1811,7 @@ private function delete_values( string $table_name, array $where ): void { $this->query( ' - DELETE FROM ' . $table_name . ' + DELETE FROM ' . $this->get_table_name( $table_name ) . ' WHERE ' . implode( ' AND ', $where_clause ) . ' ', array_values( $where )