Skip to content

Commit

Permalink
Merge pull request #100 from PostgreSQL-For-Wordpress/site-health
Browse files Browse the repository at this point in the history
add rewrite logic for SHOW TABLE STATUS and a catch for calls to information_schema
  • Loading branch information
mattbucci authored Feb 26, 2024
2 parents cdd38f6 + 66cd2fb commit ab2809d
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 6 deletions.
2 changes: 1 addition & 1 deletion pg4wp/driver_pgsql_rewrite.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
function createSQLRewriter(string $sql): AbstractSQLRewriter
{
$sql = trim($sql);
if (preg_match('/^(SELECT|INSERT|REPLACE INTO|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|REPLACE INTO|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';
Expand Down
5 changes: 3 additions & 2 deletions pg4wp/rewriters/DescribeSQLRewriter.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@ protected function extractTableName($sql)
* 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 = <<<SQL
SELECT
Expand Down Expand Up @@ -70,7 +71,7 @@ public function generatePostgresDescribeTable($tableName)
LEFT JOIN pg_constraint p ON p.conrelid = c.oid AND f.attnum = ANY (p.conkey)
LEFT JOIN pg_class AS g ON p.confrelid = g.oid
WHERE c.relkind = 'r'::char
AND n.nspname = 'public'
AND n.nspname = '$schema'
AND c.relname = '$tableName'
AND f.attnum > 0 ORDER BY number
SQL;
Expand Down
35 changes: 35 additions & 0 deletions pg4wp/rewriters/SelectSQLRewriter.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,16 @@ public function rewrite(): string
$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
Expand Down Expand Up @@ -350,4 +360,29 @@ protected function convertToPostgresLimitSyntax($sql)
return $sql;
}

// This method is specifically to handle should_suggest_persistent_object_cache in wp site health
protected function postgresTableSizeRewrite($schema = 'public')
{

$sql = <<<SQL
SELECT
C.relname AS "table",
S.n_live_tup AS "rows",
pg_total_relation_size(C.oid) AS "bytes"
FROM
pg_class C
LEFT JOIN
pg_namespace N ON (N.oid = C.relnamespace)
INNER JOIN
pg_stat_user_tables S ON (S.relid = C.oid)
WHERE
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;
SQL;

return $sql;
}

}
5 changes: 3 additions & 2 deletions pg4wp/rewriters/ShowFullColumnsSQLRewriter.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@ protected function extractTableNameFromShowColumns($sql)
* Generates a PostgreSQL-compatible SQL query to mimic MySQL's "SHOW FULL COLUMNS".
*
* @param string $tableName The table name
* @param string $schema The schema name
* @return string The generated SQL query
*/
public function generatePostgresShowColumns($tableName)
public function generatePostgresShowColumns($tableName, $schema = "public")
{
$sql = <<<SQL
SELECT
Expand Down Expand Up @@ -62,7 +63,7 @@ public function generatePostgresShowColumns($tableName)
FROM pg_catalog.pg_class c
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE c.relname = '$tableName'
AND n.nspname = 'public'
AND n.nspname = '$schema'
)
ORDER BY
a.attnum;
Expand Down
54 changes: 54 additions & 0 deletions pg4wp/rewriters/ShowTableStatusSQLRewriter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

class ShowTableStatusSQLRewriter extends AbstractSQLRewriter
{
public function rewrite(): string
{
$sql = $this->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 = <<<SQL
SELECT
'Postgres' AS Engine,
cls.relname AS TableName,
NULL AS Version,
NULL AS Row_format,
cls.reltuples AS Rows,
NULL AS Avg_row_length,
pg_size_pretty(pg_relation_size(cls.oid)) AS Data_length,
NULL AS Max_data_length,
pg_size_pretty(pg_indexes_size(cls.oid)) AS Index_length,
NULL AS Data_free,
NULL AS Auto_increment,
NULL AS Create_time,
NULL AS Update_time,
NULL AS Check_time,
'UTF8' AS Table_collation,
NULL AS Checksum,
NULL AS Create_options,
obj_description(cls.oid) AS Comment
FROM
pg_class cls
JOIN
pg_namespace nsp ON cls.relnamespace = nsp.oid
WHERE
cls.relkind = 'r'
AND nsp.nspname NOT LIKE 'pg_%'
AND nsp.nspname != 'information_schema'
AND nsp.nspname = '$schema'
ORDER BY
cls.relname ASC;
SQL;

return $sql;
}
}
3 changes: 2 additions & 1 deletion pg4wp/rewriters/ShowTablesSQLRewriter.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ class ShowTablesSQLRewriter extends AbstractSQLRewriter
{
public function rewrite(): string
{
return 'SELECT tablename FROM pg_tables WHERE schemaname = \'public\';';
$schema = "public";
return 'SELECT tablename FROM pg_tables WHERE schemaname = \'$schema\';';
}
}

0 comments on commit ab2809d

Please sign in to comment.