Skip to content

Add PostgreSQL database driver#428

Open
adamziel wants to merge 629 commits into
WordPress:trunkfrom
adamziel:codex/postgresql-backend
Open

Add PostgreSQL database driver#428
adamziel wants to merge 629 commits into
WordPress:trunkfrom
adamziel:codex/postgresql-backend

Conversation

@adamziel

@adamziel adamziel commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator

Big picture

Adds PostgreSQL backend support alongside the existing SQLite backend.

WordPress core unit tests pass to the same extent as with the SQLite backend.

Implementation checkpoints

  • PostgreSQL UDF rewrite checkpoint: e1b0bacfe9cd7dc12c2ab0927e7e1a7c73c53cb7 (Rewrite MySQL UDF calls for PostgreSQL).

Try it on a fresh WordPress site

Prerequisites: pdo and pdo_pgsql enabled in PHP.

Install the plugin files into the WordPress site:

export REPO=/path/to/sqlite-database-integration
export WP_ROOT=/path/to/wordpress

mkdir -p "$WP_ROOT/wp-content/plugins/sqlite-database-integration"
rsync -a --delete \
  "$REPO/packages/plugin-sqlite-database-integration/" \
  "$WP_ROOT/wp-content/plugins/sqlite-database-integration/"

# Replace the development symlink with a real copy of the shared database package:
rm -rf "$WP_ROOT/wp-content/plugins/sqlite-database-integration/wp-includes/database"
cp -R \
  "$REPO/packages/mysql-on-sqlite/src" \
  "$WP_ROOT/wp-content/plugins/sqlite-database-integration/wp-includes/database"

Install the WordPress database drop-in:

cp \
  "$WP_ROOT/wp-content/plugins/sqlite-database-integration/db.copy" \
  "$WP_ROOT/wp-content/db.php"

php -r '$file = getenv( "WP_ROOT" ) . "/wp-content/db.php"; $contents = file_get_contents( $file ); $contents = str_replace( array( "'{SQLITE_IMPLEMENTATION_FOLDER_PATH}'", "{SQLITE_PLUGIN}" ), array( "__DIR__ . \"/plugins/sqlite-database-integration\"", "sqlite-database-integration/load.php" ), $contents ); file_put_contents( $file, $contents );'

Configure the database access in wp-config.php:

define( 'DB_ENGINE', 'postgresql' );

define( 'DB_NAME', 'wordpress' );
define( 'DB_USER', 'wordpress' );
define( 'DB_PASSWORD', 'password' );
define( 'DB_HOST', '127.0.0.1:5432' );
define( 'DB_CHARSET', 'utf8mb4' );
define( 'DB_COLLATE', '' );

Then open the site in a browser and run the normal WordPress installer at /wp-admin/install.php. The wp-content/db.php drop-in loads the PostgreSQL wpdb adapter before install, and the PostgreSQL install hooks translate the WordPress schema for PostgreSQL.

After install, a quick smoke test is enough to confirm the site is using the PostgreSQL adapter:

<?php
require __DIR__ . '/wp-load.php';
var_dump( DB_ENGINE );
var_dump( get_class( $GLOBALS['wpdb'] ) );

Expected output includes:

postgresql
WP_PostgreSQL_DB

Repo test environment

The repo still has a supported generated test environment for CI and local parity work:

WP_TEST_DB_BACKEND=postgresql composer run wp-setup
WP_TEST_DB_BACKEND=postgresql composer run wp-test-php
WP_TEST_DB_BACKEND=postgresql composer run wp-test-e2e

Those commands generate the WordPress checkout, Docker override, test configs, drop-in wiring, and node dependencies used by CI. They are useful for repeatable testing, but they are not required to try PostgreSQL on a fresh WordPress site.

Benchmark results

Scenario Native WordPress WordPress SQLite WordPress PostgreSQLite
All WordPress unit tests 449.085s 722.336s 564.026s
SELECT option by name (1,000x) 0.113s 0.136s 0.344s
INSERT post + meta + category (100x) 6.175s 8.297s 5.293s

@adamziel adamziel force-pushed the codex/postgresql-backend branch from 0565082 to f3b5bd7 Compare June 16, 2026 16:36
@adamziel adamziel changed the title Add PostgreSQL backend scaffolding Add PostgreSQL as a first-class WordPress test backend Jun 16, 2026
@adamziel adamziel changed the title Add PostgreSQL as a first-class WordPress test backend Add PostgreSQL database driver Jun 17, 2026
@adamziel adamziel force-pushed the codex/postgresql-backend branch from c7578b6 to 47915f7 Compare June 17, 2026 15:53
adamziel and others added 28 commits June 24, 2026 12:29
Account for CREATE-time metadata preseed in the no-auto-increment identity eligibility test. The first pre-ALTER DML lookup now uses cached created-table metadata, so it should not emit a live eligibility metadata query before ALTER invalidates the cache.
Return an empty result for suppressed active-prefix siteurl probes when the PostgreSQL options table is absent. This keeps WordPress alternate-prefix install detection from treating a harmless missing options table as a backend relation error while preserving normal driver behavior for existing tables and non-matching queries.
PostgreSQL: add reusable query context
PostgreSQL: table-drive simple function rewrites
…0260627-lane4

PostgreSQL: harden SELECT translator ordering
@adamziel adamziel marked this pull request as ready for review June 30, 2026 15:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant