From d13ac87c2960938311347218f7dd9acd1cc22a45 Mon Sep 17 00:00:00 2001 From: Jan Jakes Date: Thu, 16 Oct 2025 13:04:23 +0200 Subject: [PATCH 1/5] Fix USE statement when switching to the main database --- tests/WP_SQLite_Driver_Tests.php | 17 +++++++++++++++++ .../sqlite-ast/class-wp-sqlite-driver.php | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/tests/WP_SQLite_Driver_Tests.php b/tests/WP_SQLite_Driver_Tests.php index e28fab8a..798f8dd1 100644 --- a/tests/WP_SQLite_Driver_Tests.php +++ b/tests/WP_SQLite_Driver_Tests.php @@ -9366,5 +9366,22 @@ public function testDynamicDatabaseNameWithUseStatement(): void { $result = $this->assertQuery( 'SELECT * FROM information_schema.tables' ); $this->assertCount( 1, $result ); $this->assertEquals( 'tables', $result[0]->TABLE_NAME ); + + // Switch back to the "wp" database. + $this->assertQuery( 'USE wp' ); + + // Now, unqualified "tables" refers to the "wp.tables". + $result = $this->assertQuery( 'SELECT * FROM tables' ); + $this->assertCount( 2, $result ); + $this->assertEquals( array( (object) array( 'id' => '1' ), (object) array( 'id' => '2' ) ), $result ); + + // Qualified references should still work. + $result = $this->assertQuery( 'SELECT * FROM wp.tables' ); + $this->assertCount( 2, $result ); + $this->assertEquals( array( (object) array( 'id' => '1' ), (object) array( 'id' => '2' ) ), $result ); + + $result = $this->assertQuery( 'SELECT * FROM information_schema.tables' ); + $this->assertCount( 1, $result ); + $this->assertEquals( 'tables', $result[0]->TABLE_NAME ); } } diff --git a/wp-includes/sqlite-ast/class-wp-sqlite-driver.php b/wp-includes/sqlite-ast/class-wp-sqlite-driver.php index cfddff47..71b23332 100644 --- a/wp-includes/sqlite-ast/class-wp-sqlite-driver.php +++ b/wp-includes/sqlite-ast/class-wp-sqlite-driver.php @@ -2609,7 +2609,7 @@ private function execute_use_statement( WP_Parser_Node $node ): void { if ( 'information_schema' === strtolower( $database_name ) ) { $this->db_name = 'information_schema'; - } elseif ( $this->db_name === $database_name ) { + } elseif ( $this->main_db_name === $database_name ) { $this->db_name = $database_name; } else { throw $this->new_not_supported_exception( From 8c7917b52061082d7b02cc4cb82420727576c745 Mon Sep 17 00:00:00 2001 From: Jan Jakes Date: Thu, 16 Oct 2025 13:05:18 +0200 Subject: [PATCH 2/5] Add support for @@version and @@version_comment --- tests/WP_SQLite_Driver_Tests.php | 8 +++++ .../sqlite-ast/class-wp-sqlite-driver.php | 30 ++++++++++++++++--- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/tests/WP_SQLite_Driver_Tests.php b/tests/WP_SQLite_Driver_Tests.php index 798f8dd1..91f7c5c5 100644 --- a/tests/WP_SQLite_Driver_Tests.php +++ b/tests/WP_SQLite_Driver_Tests.php @@ -6033,6 +6033,14 @@ public function testSetStatement(): void { $this->assertQuery( 'SET CHARACTER SET utf8mb4' ); } + public function testBuiltInSystemVariables(): void { + $result = $this->assertQuery( 'SELECT @@version' ); + $this->assertSame( '8.0.38', $result[0]->{'@@version'} ); + + $result = $this->assertQuery( 'SELECT @@version_comment' ); + $this->assertSame( 'MySQL Community Server - GPL', $result[0]->{'@@version_comment'} ); + } + public function testSessionSystemVariables(): void { $this->assertQuery( "SET character_set_client = 'latin1'" ); $result = $this->assertQuery( 'SELECT @@character_set_client' ); diff --git a/wp-includes/sqlite-ast/class-wp-sqlite-driver.php b/wp-includes/sqlite-ast/class-wp-sqlite-driver.php index 71b23332..fb776b9a 100644 --- a/wp-includes/sqlite-ast/class-wp-sqlite-driver.php +++ b/wp-includes/sqlite-ast/class-wp-sqlite-driver.php @@ -380,6 +380,13 @@ class WP_SQLite_Driver { 'BLOB' => array( 'BLOB', 252, null, 0 ), ); + /** + * The version of the MySQL server that the driver is configured for. + * + * @var int + */ + private $mysql_version; + /** * The SQLite engine version. * @@ -563,10 +570,15 @@ class WP_SQLite_Driver { * * @throws WP_SQLite_Driver_Exception When the driver initialization fails. */ - public function __construct( WP_SQLite_Connection $connection, string $database ) { - $this->connection = $connection; - $this->main_db_name = $database; - $this->db_name = $database; + public function __construct( + WP_SQLite_Connection $connection, + string $database, + int $mysql_version = 80038 + ) { + $this->mysql_version = $mysql_version; + $this->connection = $connection; + $this->main_db_name = $database; + $this->db_name = $database; // Check the database name. if ( '' === $this->db_name ) { @@ -3105,6 +3117,16 @@ private function translate( $node ): ?string { $type = $type_token ? $type_token->id : WP_MySQL_Lexer::SESSION_SYMBOL; if ( 'sql_mode' === $name ) { $value = implode( ',', $this->active_sql_modes ); + } elseif ( 'version' === $name ) { + $version = (string) $this->mysql_version; + $value = sprintf( + '%d.%d.%d', + $version[0], + substr( $version, 1, 2 ), + substr( $version, 3, 2 ) + ); + } elseif ( 'version_comment' === $name ) { + $value = 'MySQL Community Server - GPL'; } elseif ( WP_MySQL_Lexer::SESSION_SYMBOL === $type ) { $value = $this->session_system_variables[ $name ] ?? null; } else { From 5ec853b5eee7b58485ae59f3fc96f11236e23c57 Mon Sep 17 00:00:00 2001 From: Jan Jakes Date: Thu, 16 Oct 2025 13:43:35 +0200 Subject: [PATCH 3/5] Add support for information schema CHARACTER_SETS and COLLATIONS tables --- tests/WP_SQLite_Driver_Metadata_Tests.php | 99 +++++++++++++++++++ .../sqlite-ast/class-wp-sqlite-driver.php | 11 +++ ...s-wp-sqlite-information-schema-builder.php | 48 +++++++++ 3 files changed, 158 insertions(+) diff --git a/tests/WP_SQLite_Driver_Metadata_Tests.php b/tests/WP_SQLite_Driver_Metadata_Tests.php index abbd3b39..225072ab 100644 --- a/tests/WP_SQLite_Driver_Metadata_Tests.php +++ b/tests/WP_SQLite_Driver_Metadata_Tests.php @@ -94,6 +94,105 @@ public function testInformationSchemaQueryHidesSqliteSystemTables() { $this->assertEquals( 0, count( $result ) ); } + public function testInfromationSchemaCharacterSets(): void { + $result = $this->assertQuery( 'SELECT * FROM INFORMATION_SCHEMA.CHARACTER_SETS ORDER BY CHARACTER_SET_NAME' ); + $this->assertEquals( + array( + (object) array( + 'CHARACTER_SET_NAME' => 'binary', + 'DEFAULT_COLLATE_NAME' => 'binary', + 'DESCRIPTION' => 'Binary pseudo charset', + 'MAXLEN' => '1', + ), + (object) array( + 'CHARACTER_SET_NAME' => 'utf8', + 'DEFAULT_COLLATE_NAME' => 'utf8_general_ci', + 'DESCRIPTION' => 'UTF-8 Unicode', + 'MAXLEN' => '3', + ), + (object) array( + 'CHARACTER_SET_NAME' => 'utf8mb4', + 'DEFAULT_COLLATE_NAME' => 'utf8mb4_0900_ai_ci', + 'DESCRIPTION' => 'UTF-8 Unicode', + 'MAXLEN' => '4', + ), + ), + $result + ); + } + + public function testInfromationSchemaCollations(): void { + $result = $this->assertQuery( 'SELECT * FROM INFORMATION_SCHEMA.COLLATIONS ORDER BY COLLATION_NAME' ); + $this->assertEquals( + array( + (object) array( + 'COLLATION_NAME' => 'binary', + 'CHARACTER_SET_NAME' => 'binary', + 'ID' => '63', + 'IS_DEFAULT' => 'Yes', + 'IS_COMPILED' => 'Yes', + 'SORTLEN' => '1', + 'PAD_ATTRIBUTE' => 'NO PAD', + ), + (object) array( + 'COLLATION_NAME' => 'utf8_bin', + 'CHARACTER_SET_NAME' => 'utf8', + 'ID' => '83', + 'IS_DEFAULT' => '', + 'IS_COMPILED' => 'Yes', + 'SORTLEN' => '1', + 'PAD_ATTRIBUTE' => 'PAD SPACE', + ), + (object) array( + 'COLLATION_NAME' => 'utf8_general_ci', + 'CHARACTER_SET_NAME' => 'utf8', + 'ID' => '33', + 'IS_DEFAULT' => 'Yes', + 'IS_COMPILED' => 'Yes', + 'SORTLEN' => '1', + 'PAD_ATTRIBUTE' => 'PAD SPACE', + ), + (object) array( + 'COLLATION_NAME' => 'utf8_unicode_ci', + 'CHARACTER_SET_NAME' => 'utf8', + 'ID' => '192', + 'IS_DEFAULT' => '', + 'IS_COMPILED' => 'Yes', + 'SORTLEN' => '8', + 'PAD_ATTRIBUTE' => 'PAD SPACE', + ), + (object) array( + 'COLLATION_NAME' => 'utf8mb4_0900_ai_ci', + 'CHARACTER_SET_NAME' => 'utf8mb4', + 'ID' => '255', + 'IS_DEFAULT' => 'Yes', + 'IS_COMPILED' => 'Yes', + 'SORTLEN' => '0', + 'PAD_ATTRIBUTE' => 'NO PAD', + ), + (object) array( + 'COLLATION_NAME' => 'utf8mb4_bin', + 'CHARACTER_SET_NAME' => 'utf8mb4', + 'ID' => '46', + 'IS_DEFAULT' => '', + 'IS_COMPILED' => 'Yes', + 'SORTLEN' => '1', + 'PAD_ATTRIBUTE' => 'PAD SPACE', + ), + (object) array( + 'COLLATION_NAME' => 'utf8mb4_unicode_ci', + 'CHARACTER_SET_NAME' => 'utf8mb4', + 'ID' => '224', + 'IS_DEFAULT' => '', + 'IS_COMPILED' => 'Yes', + 'SORTLEN' => '8', + 'PAD_ATTRIBUTE' => 'PAD SPACE', + ), + ), + $result + ); + } + public function testUseStatement() { $this->assertQuery( 'CREATE TABLE tables (ENGINE TEXT)' ); $this->assertQuery( "INSERT INTO tables (ENGINE) VALUES ('test')" ); diff --git a/wp-includes/sqlite-ast/class-wp-sqlite-driver.php b/wp-includes/sqlite-ast/class-wp-sqlite-driver.php index fb776b9a..bad7c0bd 100644 --- a/wp-includes/sqlite-ast/class-wp-sqlite-driver.php +++ b/wp-includes/sqlite-ast/class-wp-sqlite-driver.php @@ -3983,6 +3983,17 @@ public function translate_table_ref( WP_Parser_Node $node ): string { ( null === $schema_name && 'information_schema' === $this->db_name ) || ( null !== $schema_name && 'information_schema' === strtolower( $schema_name ) ) ) { + $table_name = strtolower( $table_name ); + + // Some information schema tables can be computed on the fly. + if ( 'character_sets' === $table_name || 'collations' === $table_name ) { + $table_definition = $this->information_schema_builder + ->get_computed_information_schema_table_definition( $table_name ); + if ( null !== $table_definition ) { + return sprintf( '(%s)', $table_definition ); + } + } + $table_is_temporary = $this->information_schema_builder->temporary_table_exists( $table_name ); $sqlite_table_name = $this->information_schema_builder->get_table_name( $table_is_temporary, $table_name ); 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 95d4039c..cf864597 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 @@ -404,6 +404,54 @@ public function ensure_information_schema_tables(): void { } } + /** + * Get the definition and data of a computed information schema table. + * + * Some information schema tables can be computed on the fly when they are + * referenced in a query. This method provides their definitions and data. + * + * @param string $table_name The table name. + * @return string|null The table definition and data, or null if + * the table is not a computed table. + */ + public function get_computed_information_schema_table_definition( string $table_name ): ?string { + switch ( strtolower( $table_name ) ) { + case 'character_sets': + return "SELECT + column1 AS CHARACTER_SET_NAME, + column2 AS DEFAULT_COLLATE_NAME, + column3 AS DESCRIPTION, + column4 AS MAXLEN + FROM ( + VALUES + ('binary', 'binary', 'Binary pseudo charset', 1), + ('utf8', 'utf8_general_ci', 'UTF-8 Unicode', 3), + ('utf8mb4', 'utf8mb4_0900_ai_ci', 'UTF-8 Unicode', 4) + )"; + case 'collations': + return "SELECT + column1 AS COLLATION_NAME, + column2 AS CHARACTER_SET_NAME, + column3 AS ID, + column4 AS IS_DEFAULT, + column5 AS IS_COMPILED, + column6 AS SORTLEN, + column7 AS PAD_ATTRIBUTE + FROM ( + VALUES + ('binary', 'binary', 63, 'Yes', 'Yes', 1, 'NO PAD'), + ('utf8_bin', 'utf8', 83, '', 'Yes', 1, 'PAD SPACE'), + ('utf8_general_ci', 'utf8', 33, 'Yes', 'Yes', 1, 'PAD SPACE'), + ('utf8_unicode_ci', 'utf8', 192, '', 'Yes', 8, 'PAD SPACE'), + ('utf8mb4_bin', 'utf8mb4', 46, '', 'Yes', 1, 'PAD SPACE'), + ('utf8mb4_unicode_ci', 'utf8mb4', 224, '', 'Yes', 8, 'PAD SPACE'), + ('utf8mb4_0900_ai_ci', 'utf8mb4', 255, 'Yes', 'Yes', 0, 'NO PAD') + )"; + default: + return null; + } + } + /** * Ensure that the temporary information schema tables exist in * the SQLite database. Tables that are missing will be created. From 321028268284008ba14877722d6ead4b4460886d Mon Sep 17 00:00:00 2001 From: Jan Jakes Date: Thu, 16 Oct 2025 14:06:36 +0200 Subject: [PATCH 4/5] Improve CAST expression handling --- tests/WP_SQLite_Driver_Tests.php | 61 ++++++++++++++++--- .../sqlite-ast/class-wp-sqlite-driver.php | 33 ++++++++-- 2 files changed, 83 insertions(+), 11 deletions(-) diff --git a/tests/WP_SQLite_Driver_Tests.php b/tests/WP_SQLite_Driver_Tests.php index 91f7c5c5..a5c106c6 100644 --- a/tests/WP_SQLite_Driver_Tests.php +++ b/tests/WP_SQLite_Driver_Tests.php @@ -8403,22 +8403,22 @@ public function testColumnInfoForExpressions(): void { ), array( // "CAST('2024-01-01' AS DATE)" seems to behave differently in SQLite. - 'native_type' => 'LONGLONG', // "DATE" in MySQL. - 'pdo_type' => PDO::PARAM_INT, // PARAM_STR in MySQL. + 'native_type' => 'VAR_STRING', // "DATE" in MySQL. + 'pdo_type' => PDO::PARAM_STR, 'flags' => array( 'not_null' ), // Empty in MySQL. 'table' => '', 'name' => 'col_expr_11', - 'len' => 21, // 10 in MySQL. - 'precision' => 0, + 'len' => 65535, // 10 in MySQL. + 'precision' => 31, // 0 in MySQL. 'sqlite:decl_type' => '', // Additional MySQLi metadata. 'mysqli:orgname' => 'col_expr_11', 'mysqli:orgtable' => '', 'mysqli:db' => 'wp', - 'mysqli:charsetnr' => 63, - 'mysqli:flags' => 0, // 128 in MySQL. - 'mysqli:type' => 8, // 10 in MySQL. + 'mysqli:charsetnr' => 255, // 63 in MySQL. + 'mysqli:flags' => 0, // 128 in MySQL. + 'mysqli:type' => 253, // 10 in MySQL. ), array( 'native_type' => 'VAR_STRING', @@ -9392,4 +9392,51 @@ public function testDynamicDatabaseNameWithUseStatement(): void { $this->assertCount( 1, $result ); $this->assertEquals( 'tables', $result[0]->TABLE_NAME ); } + + public function testCastExpression(): void { + $result = $this->assertQuery( + "SELECT + CAST('abc' AS BINARY) AS expr_1, + CAST('abc' AS BINARY(2)) AS expr_2, + CAST('abc' AS CHAR) AS expr_3, + CAST('abc' AS CHAR(2) CHARACTER SET utf8 BINARY)AS expr_4, + CAST('abc' AS NCHAR)AS expr_5, + CAST('abc' AS NATIONAL CHAR (2)) AS expr_6, + CAST('-10' AS SIGNED) AS expr_7, + CAST('-10' AS UNSIGNED INT) AS expr_8, + CAST('2025-10-05 14:05:28' AS DATE) AS expr_9, + CAST('2025-10-05 14:05:28' AS TIME) AS expr_10, + CAST('2025-10-05 14:05:28' AS DATETIME) AS expr_11, + CAST('123.456' AS DECIMAL(10,1)) AS expr_12, + CAST('123.456' AS FLOAT) AS expr_13, + CAST('123.456' AS REAL) AS expr_14, + CAST('123.456' AS DOUBLE) AS expr_15, + CAST('{\"name\":\"value\"}' AS JSON) AS expr_16 + " + ); + + $this->assertEquals( + array( + (object) array( + 'expr_1' => 'abc', + 'expr_2' => 'abc', // 'ab' In MySQL + 'expr_3' => 'abc', + 'expr_4' => 'abc', // 'ab' In MySQL + 'expr_5' => 'abc', + 'expr_6' => 'abc', // 'ab' In MySQL + 'expr_7' => '-10', + 'expr_8' => '-10', // 18446744073709551606 in MySQL + 'expr_9' => '2025-10-05 14:05:28', // 2025-10-05 in MySQL + 'expr_10' => '2025-10-05 14:05:28', // 14:05:28 in MySQL + 'expr_11' => '2025-10-05 14:05:28', + 'expr_12' => '123.456', // 123.5 in MySQL + 'expr_13' => '123.456', + 'expr_14' => '123.456', + 'expr_15' => '123.456', + 'expr_16' => '{"name":"value"}', + ), + ), + $result + ); + } } diff --git a/wp-includes/sqlite-ast/class-wp-sqlite-driver.php b/wp-includes/sqlite-ast/class-wp-sqlite-driver.php index bad7c0bd..89a787aa 100644 --- a/wp-includes/sqlite-ast/class-wp-sqlite-driver.php +++ b/wp-includes/sqlite-ast/class-wp-sqlite-driver.php @@ -3156,11 +3156,36 @@ private function translate( $node ): ?string { } return (string) $value; case 'castType': - // Translate "CAST(... AS BINARY)" to "CAST(... AS BLOB)". - if ( $node->has_child_token( WP_MySQL_Lexer::BINARY_SYMBOL ) ) { - return 'BLOB'; + $first_child = $node->get_first_child(); + if ( $first_child instanceof WP_Parser_Node ) { + $first_token = $first_child->get_first_child_token(); + } else { + $first_token = $first_child; + } + switch ( $first_token->id ) { + case WP_MySQL_Lexer::BINARY_SYMBOL: + return 'BLOB'; + case WP_MySQL_Lexer::CHAR_SYMBOL: + case WP_MySQL_Lexer::NCHAR_SYMBOL: + case WP_MySQL_Lexer::NATIONAL_SYMBOL: + case WP_MySQL_Lexer::DATE_SYMBOL: + case WP_MySQL_Lexer::TIME_SYMBOL: + case WP_MySQL_Lexer::DATETIME_SYMBOL: + case WP_MySQL_Lexer::JSON_SYMBOL: + return 'TEXT'; + case WP_MySQL_Lexer::SIGNED_SYMBOL: + case WP_MySQL_Lexer::UNSIGNED_SYMBOL: + return 'INTEGER'; + case WP_MySQL_Lexer::DECIMAL_SYMBOL: + case WP_MySQL_Lexer::FLOAT_SYMBOL: + case WP_MySQL_Lexer::REAL_SYMBOL: + case WP_MySQL_Lexer::DOUBLE_SYMBOL: + return 'REAL'; + default: + throw $this->new_not_supported_exception( + sprintf( 'cast type: %s', $first_child->get_value() ) + ); } - return $this->translate_sequence( $node->get_children() ); case 'defaultCollation': // @TODO: Check and save in information schema. return null; From 821a8ce4a4803dee33a304c8ba9079a057d5b4b9 Mon Sep 17 00:00:00 2001 From: Jan Jakes Date: Thu, 16 Oct 2025 16:52:40 +0200 Subject: [PATCH 5/5] Add support for SHOW COLLATIONS statement --- tests/WP_SQLite_Driver_Metadata_Tests.php | 13 +++++++++ .../sqlite-ast/class-wp-sqlite-driver.php | 29 +++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/tests/WP_SQLite_Driver_Metadata_Tests.php b/tests/WP_SQLite_Driver_Metadata_Tests.php index 225072ab..abb8f7db 100644 --- a/tests/WP_SQLite_Driver_Metadata_Tests.php +++ b/tests/WP_SQLite_Driver_Metadata_Tests.php @@ -467,6 +467,19 @@ public function testRepairTable() { ); } + public function testShowCollation(): void { + $this->assertQuery( 'SHOW COLLATION' ); + $actual = $this->engine->get_query_results(); + $this->assertCount( 7, $actual ); + $this->assertEquals( 'binary', $actual[0]->Collation ); + $this->assertEquals( 'utf8_bin', $actual[1]->Collation ); + $this->assertEquals( 'utf8_general_ci', $actual[2]->Collation ); + $this->assertEquals( 'utf8_unicode_ci', $actual[3]->Collation ); + $this->assertEquals( 'utf8mb4_bin', $actual[4]->Collation ); + $this->assertEquals( 'utf8mb4_unicode_ci', $actual[5]->Collation ); + $this->assertEquals( 'utf8mb4_0900_ai_ci', $actual[6]->Collation ); + } + public function testShowDatabases(): void { // Simple. $this->assertQuery( 'SHOW DATABASES' ); diff --git a/wp-includes/sqlite-ast/class-wp-sqlite-driver.php b/wp-includes/sqlite-ast/class-wp-sqlite-driver.php index 89a787aa..23a45172 100644 --- a/wp-includes/sqlite-ast/class-wp-sqlite-driver.php +++ b/wp-includes/sqlite-ast/class-wp-sqlite-driver.php @@ -2200,6 +2200,9 @@ private function execute_show_statement( WP_Parser_Node $node ): void { $keyword2 = $tokens[2] ?? null; switch ( $keyword1->id ) { + case WP_MySQL_Lexer::COLLATION_SYMBOL: + $this->execute_show_collation_statement(); + return; case WP_MySQL_Lexer::DATABASES_SYMBOL: $this->execute_show_databases_statement( $node ); return; @@ -2267,6 +2270,32 @@ private function execute_show_statement( WP_Parser_Node $node ): void { ); } + /** + * Translate and execute a MySQL SHOW COLLATION statement in SQLite. + */ + private function execute_show_collation_statement(): void { + $definition = $this->information_schema_builder + ->get_computed_information_schema_table_definition( 'collations' ); + + // TODO: LIKE and WHERE clauses. + + $result = $this->execute_sqlite_query( $definition )->fetchAll( PDO::FETCH_ASSOC ); + + $collations = array(); + foreach ( $result as $row ) { + $collations[] = (object) array( + 'Collation' => $row['COLLATION_NAME'], + 'Charset' => $row['CHARACTER_SET_NAME'], + 'Id' => $row['ID'], + 'Default' => $row['IS_DEFAULT'], + 'Compiled' => $row['IS_COMPILED'], + 'Sortlen' => $row['SORTLEN'], + 'Pad_attribute' => $row['PAD_ATTRIBUTE'], + ); + } + $this->set_results_from_fetched_data( $collations ); + } + /** * Translate and execute a MySQL SHOW DATABASES statement in SQLite. *