Merge pull request #100 from PostgreSQL-For-Wordpress/site-health
add rewrite logic for SHOW TABLE STATUS and a catch for calls to information_schema
This commit is contained in:
@ -12,7 +12,7 @@ spl_autoload_register(function ($className) {
|
|||||||
function createSQLRewriter(string $sql): AbstractSQLRewriter
|
function createSQLRewriter(string $sql): AbstractSQLRewriter
|
||||||
{
|
{
|
||||||
$sql = trim($sql);
|
$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")
|
// Convert to a format suitable for class names (e.g., "SHOW TABLES" becomes "ShowTables")
|
||||||
$type = str_replace(' ', '', ucwords(str_replace('_', ' ', strtolower($matches[1]))));
|
$type = str_replace(' ', '', ucwords(str_replace('_', ' ', strtolower($matches[1]))));
|
||||||
$className = $type . 'SQLRewriter';
|
$className = $type . 'SQLRewriter';
|
||||||
|
@ -28,9 +28,10 @@ class DescribeSQLRewriter extends AbstractSQLRewriter
|
|||||||
* Generates a PostgreSQL-compatible SQL query to mimic MySQL's "DESCRIBE".
|
* Generates a PostgreSQL-compatible SQL query to mimic MySQL's "DESCRIBE".
|
||||||
*
|
*
|
||||||
* @param string $tableName The table name
|
* @param string $tableName The table name
|
||||||
|
* @param string $schema The schema name
|
||||||
* @return string The generated SQL query
|
* @return string The generated SQL query
|
||||||
*/
|
*/
|
||||||
public function generatePostgresDescribeTable($tableName)
|
public function generatePostgresDescribeTable($tableName, $schema = "public")
|
||||||
{
|
{
|
||||||
$sql = <<<SQL
|
$sql = <<<SQL
|
||||||
SELECT
|
SELECT
|
||||||
@ -70,7 +71,7 @@ class DescribeSQLRewriter extends AbstractSQLRewriter
|
|||||||
LEFT JOIN pg_constraint p ON p.conrelid = c.oid AND f.attnum = ANY (p.conkey)
|
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
|
LEFT JOIN pg_class AS g ON p.confrelid = g.oid
|
||||||
WHERE c.relkind = 'r'::char
|
WHERE c.relkind = 'r'::char
|
||||||
AND n.nspname = 'public'
|
AND n.nspname = '$schema'
|
||||||
AND c.relname = '$tableName'
|
AND c.relname = '$tableName'
|
||||||
AND f.attnum > 0 ORDER BY number
|
AND f.attnum > 0 ORDER BY number
|
||||||
SQL;
|
SQL;
|
||||||
|
@ -34,6 +34,16 @@ class SelectSQLRewriter extends AbstractSQLRewriter
|
|||||||
$sql = preg_replace('/SELECT\s+.*?\s+FROM\s+/is', 'SELECT COUNT(*) FROM ', $sql, 1);
|
$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);
|
$sql = $this->ensureOrderByInSelect($sql);
|
||||||
|
|
||||||
// Convert CONVERT to CAST
|
// Convert CONVERT to CAST
|
||||||
@ -350,4 +360,29 @@ class SelectSQLRewriter extends AbstractSQLRewriter
|
|||||||
return $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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -28,9 +28,10 @@ class ShowFullColumnsSQLRewriter extends AbstractSQLRewriter
|
|||||||
* Generates a PostgreSQL-compatible SQL query to mimic MySQL's "SHOW FULL COLUMNS".
|
* Generates a PostgreSQL-compatible SQL query to mimic MySQL's "SHOW FULL COLUMNS".
|
||||||
*
|
*
|
||||||
* @param string $tableName The table name
|
* @param string $tableName The table name
|
||||||
|
* @param string $schema The schema name
|
||||||
* @return string The generated SQL query
|
* @return string The generated SQL query
|
||||||
*/
|
*/
|
||||||
public function generatePostgresShowColumns($tableName)
|
public function generatePostgresShowColumns($tableName, $schema = "public")
|
||||||
{
|
{
|
||||||
$sql = <<<SQL
|
$sql = <<<SQL
|
||||||
SELECT
|
SELECT
|
||||||
@ -62,7 +63,7 @@ class ShowFullColumnsSQLRewriter extends AbstractSQLRewriter
|
|||||||
FROM pg_catalog.pg_class c
|
FROM pg_catalog.pg_class c
|
||||||
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
|
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
|
||||||
WHERE c.relname = '$tableName'
|
WHERE c.relname = '$tableName'
|
||||||
AND n.nspname = 'public'
|
AND n.nspname = '$schema'
|
||||||
)
|
)
|
||||||
ORDER BY
|
ORDER BY
|
||||||
a.attnum;
|
a.attnum;
|
||||||
|
54
pg4wp/rewriters/ShowTableStatusSQLRewriter.php
Normal file
54
pg4wp/rewriters/ShowTableStatusSQLRewriter.php
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -4,6 +4,7 @@ class ShowTablesSQLRewriter extends AbstractSQLRewriter
|
|||||||
{
|
{
|
||||||
public function rewrite(): string
|
public function rewrite(): string
|
||||||
{
|
{
|
||||||
return 'SELECT tablename FROM pg_tables WHERE schemaname = \'public\';';
|
$schema = "public";
|
||||||
|
return 'SELECT tablename FROM pg_tables WHERE schemaname = \'$schema\';';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user