Skip to content

Commit

Permalink
Add support for USE <database> statement (to switch between main DB a…
Browse files Browse the repository at this point in the history
…nd information schema)
  • Loading branch information
JanJakes committed Feb 12, 2025
1 parent 3f4fa06 commit c1b3c8c
Showing 1 changed file with 48 additions and 2 deletions.
50 changes: 48 additions & 2 deletions wp-includes/sqlite-ast/class-wp-sqlite-driver.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down Expand Up @@ -335,7 +347,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 ) {
Expand Down Expand Up @@ -757,6 +770,9 @@ private function execute_mysql_query( WP_Parser_Node $node ): void {
case 'describeStatement':
$this->execute_describe_statement( $subtree );
break;
case 'useCommand':
$this->execute_use_statement( $subtree );
break;
default:
throw $this->new_not_supported_exception(
sprintf(
Expand Down Expand Up @@ -1594,6 +1610,32 @@ private function execute_describe_statement( WP_Parser_Node $node ): void {
$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 database '%s', only '%s' and 'information_schema' are supported",
$database_name,
$this->db_name
)
);
}
}

/**
* Translate a MySQL AST node or token to an SQLite query fragment.
*
Expand Down Expand Up @@ -1690,6 +1732,10 @@ private function translate( $node ): ?string {
case 'tableRef':
// Translate information schema table references.
$identifiers = $node->get_descendant_nodes( 'identifier' );
if ( 'information_schema' === $this->db_name && count( $identifiers ) === 1 ) {
$table_name = $this->unquote_sqlite_identifier( $this->translate( $identifiers[0] ) );
return $this->information_schema_builder->get_table_name( $table_name );
}
if ( count( $identifiers ) === 2 ) {
$schema_name = $this->unquote_sqlite_identifier( $this->translate( $identifiers[0] ) );
$table_name = $this->unquote_sqlite_identifier( $this->translate( $identifiers[1] ) );
Expand Down

0 comments on commit c1b3c8c

Please sign in to comment.