First of all, congrats on the v3 release! I know this was a huge lift for the team, so kudos!
We've been running tests in WP-CLI with SQLite for quite a while now, and today I noticed some failures because of this new release. Most of them could be addressed in our tests because behavior changed (improved) in the SQLite plugin. However, there was one situation where I think it might be a regression.
Since v3.0.0, opening a database connection fails when MULTISITE is defined in wp-config.php but the database is still empty. This makes it impossible to install a multisite network from scratch — for example via wp core multisite-install, where WordPress is expected to create the tables itself.
WP_SQLite_Information_Schema_Reconstructor::get_wp_create_table_statements() checks is_multisite() and, if so, queries wp_blogs to collect the schema of every existing site:
https://github.com/WordPress/sqlite-database-integration/blob/v3.0.0/packages/mysql-on-sqlite/src/sqlite/class-wp-sqlite-information-schema-reconstructor.php#L211-L226
That table does not exist yet on a fresh install, so the query throws while the connection is still being configured (WP_MySQL_On_SQLite::__construct() → WP_SQLite_Configurator::ensure_database_configured()).
The failure is also confusing to diagnose from the outside: the exception leaves $wpdb->last_error set, so the subsequent DESCRIBE loop in is_blog_installed() takes the dead_db() branch, and the user sees "One or more database tables are unavailable. The database may need to be repaired." rather than the actual error.
Steps to reproduce
-
Extract WordPress into an empty directory and install the plugin's db.php drop-in, with no database file yet.
-
Create a wp-config.php that already declares multisite:
define( 'WP_ALLOW_MULTISITE', true );
define( 'MULTISITE', true );
define( 'SUBDOMAIN_INSTALL', false );
define( 'DOMAIN_CURRENT_SITE', 'localhost' );
define( 'PATH_CURRENT_SITE', '/' );
define( 'SITE_ID_CURRENT_SITE', 1 );
define( 'BLOG_ID_CURRENT_SITE', 1 );
-
Run wp core multisite-install --url=localhost --title=Test --admin_user=admin --admin_email=admin@example.org.
Expected
The network is installed, as it is with MySQL.
Actual
Error: One or more database tables are unavailable. The database may need to be repaired.
With the error output unsuppressed, the underlying cause is:
SQLSTATE[HY000]: General error: 1 no such table: wp_blogs
#0 wp-includes/database/sqlite/class-wp-sqlite-connection.php(195): PDO->prepare()
#1 wp-includes/database/sqlite/class-wp-mysql-on-sqlite.php(1615): WP_SQLite_Connection->query()
#2 wp-includes/database/sqlite/class-wp-sqlite-information-schema-reconstructor.php(218): WP_MySQL_On_SQLite->execute_sqlite_query()
#3 wp-includes/database/sqlite/class-wp-sqlite-information-schema-reconstructor.php(68): WP_SQLite_Information_Schema_Reconstructor->get_wp_create_table_statements()
#4 wp-includes/database/sqlite/class-wp-sqlite-configurator.php(84): WP_SQLite_Information_Schema_Reconstructor->ensure_correct_information_schema()
#5 wp-includes/database/sqlite/class-wp-sqlite-configurator.php(65): WP_SQLite_Configurator->configure_database()
#6 wp-includes/database/sqlite/class-wp-mysql-on-sqlite.php(955): WP_SQLite_Configurator->ensure_database_configured()
#7 wp-includes/sqlite/class-wp-sqlite-db.php(468): WP_MySQL_On_SQLite->__construct()
#8 wp-includes/class-wpdb.php(772): WP_SQLite_DB->db_connect()
Reproduced on WordPress 6.9 and trunk, PHP 7.2 through 8.5, on Linux, macOS and Windows.
Notes
Converting an existing single-site install with wp core multisite-convert is unaffected, because wp_blogs is created before MULTISITE is defined.
Skipping the wp_blogs lookup when the table is absent — the schema of a site that does not exist yet cannot be reconstructed anyway — would seem to be enough, but I have not looked into whether that has other consequences.
This surfaced as a CI regression in wp-cli/entity-command: its wp core multisite-install scenarios passed against v2 and started failing on the nightly run after v3.0.0 went out as the stable version on wordpress.org. They are skipped on SQLite for now (wp-cli/entity-command#635).
First of all, congrats on the v3 release! I know this was a huge lift for the team, so kudos!
We've been running tests in WP-CLI with SQLite for quite a while now, and today I noticed some failures because of this new release. Most of them could be addressed in our tests because behavior changed (improved) in the SQLite plugin. However, there was one situation where I think it might be a regression.
Since v3.0.0, opening a database connection fails when
MULTISITEis defined inwp-config.phpbut the database is still empty. This makes it impossible to install a multisite network from scratch — for example viawp core multisite-install, where WordPress is expected to create the tables itself.WP_SQLite_Information_Schema_Reconstructor::get_wp_create_table_statements()checksis_multisite()and, if so, querieswp_blogsto collect the schema of every existing site:https://github.com/WordPress/sqlite-database-integration/blob/v3.0.0/packages/mysql-on-sqlite/src/sqlite/class-wp-sqlite-information-schema-reconstructor.php#L211-L226
That table does not exist yet on a fresh install, so the query throws while the connection is still being configured (
WP_MySQL_On_SQLite::__construct()→WP_SQLite_Configurator::ensure_database_configured()).The failure is also confusing to diagnose from the outside: the exception leaves
$wpdb->last_errorset, so the subsequentDESCRIBEloop inis_blog_installed()takes thedead_db()branch, and the user sees "One or more database tables are unavailable. The database may need to be repaired." rather than the actual error.Steps to reproduce
Extract WordPress into an empty directory and install the plugin's
db.phpdrop-in, with no database file yet.Create a
wp-config.phpthat already declares multisite:Run
wp core multisite-install --url=localhost --title=Test --admin_user=admin --admin_email=admin@example.org.Expected
The network is installed, as it is with MySQL.
Actual
With the error output unsuppressed, the underlying cause is:
Reproduced on WordPress 6.9 and trunk, PHP 7.2 through 8.5, on Linux, macOS and Windows.
Notes
Converting an existing single-site install with
wp core multisite-convertis unaffected, becausewp_blogsis created beforeMULTISITEis defined.Skipping the
wp_blogslookup when the table is absent — the schema of a site that does not exist yet cannot be reconstructed anyway — would seem to be enough, but I have not looked into whether that has other consequences.This surfaced as a CI regression in wp-cli/entity-command: its
wp core multisite-installscenarios passed against v2 and started failing on the nightly run after v3.0.0 went out as the stable version on wordpress.org. They are skipped on SQLite for now (wp-cli/entity-command#635).