From ebbe2915c64db39a2dafa8d9a9491ee21fdce23d Mon Sep 17 00:00:00 2001 From: Matthew Bucci Date: Wed, 21 Feb 2024 01:15:51 -0800 Subject: [PATCH 1/3] add rewrite logic for SHOW TABLE STATUS and a catch for calls to information_schema --- pg4wp/driver_pgsql_rewrite.php | 2 +- pg4wp/rewriters/SelectSQLRewriter.php | 35 ++++++++++++ .../rewriters/ShowTableStatusSQLRewriter.php | 54 +++++++++++++++++++ 3 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 pg4wp/rewriters/ShowTableStatusSQLRewriter.php diff --git a/pg4wp/driver_pgsql_rewrite.php b/pg4wp/driver_pgsql_rewrite.php index 0292cd0..d666d28 100644 --- a/pg4wp/driver_pgsql_rewrite.php +++ b/pg4wp/driver_pgsql_rewrite.php @@ -12,7 +12,7 @@ spl_autoload_register(function ($className) { function createSQLRewriter(string $sql): AbstractSQLRewriter { $sql = trim($sql); - if (preg_match('/^(SELECT|INSERT|UPDATE|DELETE|DESCRIBE|ALTER TABLE|CREATE TABLE|DROP TABLE|SHOW INDEX|SHOW VARIABLES|SHOW TABLES|OPTIMIZE TABLE|SET NAMES|SHOW FULL COLUMNS)\b/i', $sql, $matches)) { + if (preg_match('/^(SELECT|INSERT|UPDATE|DELETE|DESCRIBE|ALTER TABLE|CREATE TABLE|DROP TABLE|SHOW INDEX|SHOW VARIABLES|SHOW TABLES|OPTIMIZE TABLE|SET NAMES|SHOW FULL COLUMNS|SHOW TABLE STATUS)\b/i', $sql, $matches)) { // Convert to a format suitable for class names (e.g., "SHOW TABLES" becomes "ShowTables") $type = str_replace(' ', '', ucwords(str_replace('_', ' ', strtolower($matches[1])))); $className = $type . 'SQLRewriter'; diff --git a/pg4wp/rewriters/SelectSQLRewriter.php b/pg4wp/rewriters/SelectSQLRewriter.php index 90b6d37..e8e0e8a 100644 --- a/pg4wp/rewriters/SelectSQLRewriter.php +++ b/pg4wp/rewriters/SelectSQLRewriter.php @@ -31,6 +31,16 @@ class SelectSQLRewriter extends AbstractSQLRewriter $sql = preg_replace('/SELECT\s+.*?\s+FROM\s+/is', 'SELECT COUNT(*) FROM ', $sql, 1); } + if(false !== strpos($sql, 'information_schema')) { + // WP Site Health rewrites + if (false !== strpos($sql, "SELECT TABLE_NAME AS 'table', TABLE_ROWS AS 'rows', SUM(data_length + index_length)")) { + $sql = $this->postgresTableSizeRewrite(); + return $sql; + } + + throw new Exception("Unsupported call to information_schema, this probably won't work correctly and needs to be specifically handled, open a github issue with the SQL"); + } + $sql = $this->ensureOrderByInSelect($sql); // Convert CONVERT to CAST @@ -347,4 +357,29 @@ class SelectSQLRewriter extends AbstractSQLRewriter return $sql; } + // This method is specifically to handle should_suggest_persistent_object_cache in wp site health + protected function postgresTableSizeRewrite() + { + + $sql = <<original(); + return $this->generatePostgresShowTableStatus(); + } + + + /** + * Generates a PostgreSQL-compatible SQL query to mimic MySQL's "SHOW TABLE STATUS". + * + * @return string The generated SQL query + */ + public function generatePostgresShowTableStatus($schema = "public") + { + $sql = << Date: Wed, 21 Feb 2024 01:22:57 -0800 Subject: [PATCH 2/3] extract public to schema variable so we can use a constant later --- pg4wp/rewriters/DescribeSQLRewriter.php | 5 +++-- pg4wp/rewriters/SelectSQLRewriter.php | 4 ++-- pg4wp/rewriters/ShowFullColumnsSQLRewriter.php | 5 +++-- pg4wp/rewriters/ShowTableStatusSQLRewriter.php | 4 ++-- pg4wp/rewriters/ShowTablesSQLRewriter.php | 3 ++- 5 files changed, 12 insertions(+), 9 deletions(-) diff --git a/pg4wp/rewriters/DescribeSQLRewriter.php b/pg4wp/rewriters/DescribeSQLRewriter.php index 6b841c1..98dfb8c 100644 --- a/pg4wp/rewriters/DescribeSQLRewriter.php +++ b/pg4wp/rewriters/DescribeSQLRewriter.php @@ -28,9 +28,10 @@ class DescribeSQLRewriter extends AbstractSQLRewriter * Generates a PostgreSQL-compatible SQL query to mimic MySQL's "DESCRIBE". * * @param string $tableName The table name + * @param string $schema The schema name * @return string The generated SQL query */ - public function generatePostgresDescribeTable($tableName) + public function generatePostgresDescribeTable($tableName, $schema = "public") { $sql = << 0 ORDER BY number SQL; diff --git a/pg4wp/rewriters/SelectSQLRewriter.php b/pg4wp/rewriters/SelectSQLRewriter.php index e8e0e8a..d9ef394 100644 --- a/pg4wp/rewriters/SelectSQLRewriter.php +++ b/pg4wp/rewriters/SelectSQLRewriter.php @@ -358,7 +358,7 @@ class SelectSQLRewriter extends AbstractSQLRewriter } // This method is specifically to handle should_suggest_persistent_object_cache in wp site health - protected function postgresTableSizeRewrite() + protected function postgresTableSizeRewrite($schema = 'public') { $sql = << Date: Mon, 26 Feb 2024 12:27:23 -0800 Subject: [PATCH 3/3] quote any variable usages in SQL --- pg4wp/rewriters/SelectSQLRewriter.php | 2 +- pg4wp/rewriters/ShowTableStatusSQLRewriter.php | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pg4wp/rewriters/SelectSQLRewriter.php b/pg4wp/rewriters/SelectSQLRewriter.php index d9ef394..8ff6f63 100644 --- a/pg4wp/rewriters/SelectSQLRewriter.php +++ b/pg4wp/rewriters/SelectSQLRewriter.php @@ -373,7 +373,7 @@ class SelectSQLRewriter extends AbstractSQLRewriter INNER JOIN pg_stat_user_tables S ON (S.relid = C.oid) WHERE - N.nspname = $schema AND + N.nspname = '$schema' AND C.relname IN ('wp_comments','wp_options','wp_posts','wp_terms','wp_users') GROUP BY C.relname, pg_total_relation_size(C.oid), S.n_live_tup; diff --git a/pg4wp/rewriters/ShowTableStatusSQLRewriter.php b/pg4wp/rewriters/ShowTableStatusSQLRewriter.php index cf7ea68..794a99e 100644 --- a/pg4wp/rewriters/ShowTableStatusSQLRewriter.php +++ b/pg4wp/rewriters/ShowTableStatusSQLRewriter.php @@ -42,9 +42,9 @@ class ShowTableStatusSQLRewriter extends AbstractSQLRewriter pg_namespace nsp ON cls.relnamespace = nsp.oid WHERE cls.relkind = 'r' - AND nsp.nspname NOT LIKE 'pg_%' -- Ignore schemas with names starting with pg_ - AND nsp.nspname != 'information_schema' -- Ignore the information_schema - AND nsp.nspname = $schema -- Select only tables in the 'myschema' schema + AND nsp.nspname NOT LIKE 'pg_%' + AND nsp.nspname != 'information_schema' + AND nsp.nspname = '$schema' ORDER BY cls.relname ASC; SQL;