Merge remote-tracking branch 'origin/v3' into rewrite-fixes

This commit is contained in:
Matthew Bucci
2024-02-26 23:55:09 -08:00
23 changed files with 454 additions and 78 deletions

View File

@ -0,0 +1,31 @@
---
name: SQL Rewriting Issue
about: This is used for filing bugs or problems with PG4WP
title: ''
labels: ''
assignees: ''
---
WP Version:
PG4WP Version:
Error:
```
```
RAW SQL
```
```
Expected Rewritten SQL
```
```
Actual Rewritten SQL
```
```

6
.github/pull_request_template.md vendored Normal file
View File

@ -0,0 +1,6 @@
Related Issues:
-
Added Tests:
-

View File

@ -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|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';

View File

@ -3,11 +3,6 @@
class AlterTableSQLRewriter extends AbstractSQLRewriter
{
private $stringReplacements = [
' bigint(40)' => ' bigint',
' bigint(20)' => ' bigint',
' bigint(10)' => ' int',
' int(11)' => ' int',
' int(10)' => ' int',
' tinytext' => ' text',
' mediumtext' => ' text',
' longtext' => ' text',
@ -16,16 +11,15 @@ class AlterTableSQLRewriter extends AbstractSQLRewriter
'default \'0000-00-00 00:00:00\'' => 'DEFAULT now()',
'\'0000-00-00 00:00:00\'' => 'now()',
' datetime' => ' timestamp',
' DEFAULT CHARACTER SET utf8mb4' => '',
' DEFAULT CHARACTER SET utf8' => '',
// WP 2.7.1 compatibility
' int(4)' => ' smallint',
// For WPMU (starting with WP 3.2)
' tinyint(2)' => ' smallint',
' tinyint(1)' => ' smallint',
" enum('0','1')" => ' smallint',
' COLLATE utf8mb4_unicode_520_ci' => '',
' COLLATE utf8_general_ci' => '',
' CHARACTER SET utf8' => '',
' DEFAULT CHARSET=utf8' => '',
// For flash-album-gallery plugin
' tinyint' => ' smallint'
@ -34,11 +28,14 @@ class AlterTableSQLRewriter extends AbstractSQLRewriter
public function rewrite(): string
{
$sql = $this->original();
$sql = $this->rewrite_numeric_type($sql);
if (str_contains($sql, 'ADD INDEX') || str_contains($sql, 'ADD UNIQUE INDEX')) {
$sql = $this->rewriteAddIndex($sql);
return $sql;
}
if (str_contains($sql, 'CHANGE COLUMN')) {
$sql = $this->rewriteChangeColumn($sql);
return $sql;
@ -219,4 +216,50 @@ class AlterTableSQLRewriter extends AbstractSQLRewriter
return $sql;
}
private function rewrite_numeric_type($sql){
// Numeric types in MySQL which need to be rewritten
$numeric_types = ["bigint", "int", "integer", "smallint", "mediumint", "tinyint", "double", "decimal"];
$numeric_types_imploded = implode('|', $numeric_types);
// Prepare regex pattern to match 'type(x)'
$pattern = "/(" . $numeric_types_imploded . ")\(\d+\)/";
// Execute type find & replace
$sql = preg_replace_callback($pattern, function ($matches) {
return $matches[1];
}, $sql);
// bigint
$pattern = '/bigint(\(\d+\))?([ ]*NOT NULL)?[ ]*auto_increment/i';
preg_match($pattern, $sql, $matches);
if($matches) {
$sql = preg_replace($pattern, 'bigserial', $sql);
}
// int
$pattern = '/int(\(\d+\))?([ ]*NOT NULL)?[ ]*auto_increment/i';
preg_match($pattern, $sql, $matches);
if($matches) {
$sql = preg_replace($pattern, 'serial', $sql);
}
// smallint
$pattern = '/smallint(\(\d+\))?([ ]*NOT NULL)?[ ]*auto_increment/i';
preg_match($pattern, $sql, $matches);
if($matches) {
$sql = preg_replace($pattern, 'smallserial', $sql);
}
// Handle for numeric and decimal -- being replaced with serial
$numeric_patterns = ['/numeric(\(\d+\))?([ ]*NOT NULL)?[ ]*auto_increment/i', '/decimal(\(\d+\))?([ ]*NOT NULL)?[ ]*auto_increment/i'];
foreach($numeric_patterns as $pattern) {
preg_match($pattern, $sql, $matches);
if($matches) {
$sql = preg_replace($pattern, 'serial', $sql);
}
}
return $sql;
}
}

View File

@ -3,12 +3,6 @@
class CreateTableSQLRewriter extends AbstractSQLRewriter
{
private $stringReplacements = [
' bigint(40)' => ' bigint',
' bigint(20)' => ' bigint',
' bigint(10)' => ' int',
' int(11)' => ' int',
' int(10)' => ' int',
' int(1)' => ' smallint',
' tinytext' => ' text',
' mediumtext' => ' text',
' longtext' => ' text',
@ -16,16 +10,11 @@ class CreateTableSQLRewriter extends AbstractSQLRewriter
'gmt datetime NOT NULL default \'0000-00-00 00:00:00\'' => 'gmt timestamp NOT NULL DEFAULT timezone(\'gmt\'::text, now())',
'default \'0000-00-00 00:00:00\'' => 'DEFAULT now()',
'\'0000-00-00 00:00:00\'' => 'now()',
'datetime' => 'timestamp',
' datetime' => ' timestamp',
' DEFAULT CHARACTER SET utf8mb4' => '',
' DEFAULT CHARACTER SET utf8' => '',
// WP 2.7.1 compatibility
' int(4)' => ' smallint',
// For WPMU (starting with WP 3.2)
' tinyint(2)' => ' smallint',
' tinyint(1)' => ' smallint',
" enum('0','1')" => ' smallint',
' COLLATE utf8mb4_unicode_520_ci' => '',
' COLLATE utf8_general_ci' => '',
@ -40,7 +29,6 @@ class CreateTableSQLRewriter extends AbstractSQLRewriter
{
$sql = $this->original();
$tableSQL = str_replace('CREATE TABLE IF NOT EXISTS ', 'CREATE TABLE ', $sql);
$pattern = '/CREATE TABLE [`]?(\w+)[`]?/';
preg_match($pattern, $tableSQL, $matches);
@ -66,35 +54,7 @@ class CreateTableSQLRewriter extends AbstractSQLRewriter
$sql
);
// bigint
$pattern = '/bigint(\(\d+\))?([ ]*NOT NULL)?[ ]*auto_increment/i';
preg_match($pattern, $sql, $matches);
if($matches) {
$sql = preg_replace($pattern, 'bigserial', $sql);
}
// int
$pattern = '/int(\(\d+\))?([ ]*NOT NULL)?[ ]*auto_increment/i';
preg_match($pattern, $sql, $matches);
if($matches) {
$sql = preg_replace($pattern, 'serial', $sql);
}
// smallint
$pattern = '/smallint(\(\d+\))?([ ]*NOT NULL)?[ ]*auto_increment/i';
preg_match($pattern, $sql, $matches);
if($matches) {
$sql = preg_replace($pattern, 'smallserial', $sql);
}
// Handle for numeric and decimal -- being replaced with serial
$numeric_patterns = ['/numeric(\(\d+\))?([ ]*NOT NULL)?[ ]*auto_increment/i', '/decimal(\(\d+\))?([ ]*NOT NULL)?[ ]*auto_increment/i'];
foreach($numeric_patterns as $pattern) {
preg_match($pattern, $sql, $matches);
if($matches) {
$sql = preg_replace($pattern, 'serial', $sql);
}
}
$sql = $this->rewrite_numeric_type($sql);
// Support for UNIQUE INDEX creation
$pattern = '/,\s*(UNIQUE |)KEY\s+(`[^`]+`|\w+)\s+\(((?:[^()]|\([^)]*\))*)\)/';
@ -127,4 +87,50 @@ class CreateTableSQLRewriter extends AbstractSQLRewriter
return $sql;
}
private function rewrite_numeric_type($sql){
// Numeric types in MySQL which need to be rewritten
$numeric_types = ["bigint", "int", "integer", "smallint", "mediumint", "tinyint", "double", "decimal"];
$numeric_types_imploded = implode('|', $numeric_types);
// Prepare regex pattern to match 'type(x)'
$pattern = "/(" . $numeric_types_imploded . ")\(\d+\)/";
// Execute type find & replace
$sql = preg_replace_callback($pattern, function ($matches) {
return $matches[1];
}, $sql);
// bigint
$pattern = '/bigint(\(\d+\))?([ ]*NOT NULL)?[ ]*auto_increment/i';
preg_match($pattern, $sql, $matches);
if($matches) {
$sql = preg_replace($pattern, 'bigserial', $sql);
}
// int
$pattern = '/int(\(\d+\))?([ ]*NOT NULL)?[ ]*auto_increment/i';
preg_match($pattern, $sql, $matches);
if($matches) {
$sql = preg_replace($pattern, 'serial', $sql);
}
// smallint
$pattern = '/smallint(\(\d+\))?([ ]*NOT NULL)?[ ]*auto_increment/i';
preg_match($pattern, $sql, $matches);
if($matches) {
$sql = preg_replace($pattern, 'smallserial', $sql);
}
// Handle for numeric and decimal -- being replaced with serial
$numeric_patterns = ['/numeric(\(\d+\))?([ ]*NOT NULL)?[ ]*auto_increment/i', '/decimal(\(\d+\))?([ ]*NOT NULL)?[ ]*auto_increment/i'];
foreach($numeric_patterns as $pattern) {
preg_match($pattern, $sql, $matches);
if($matches) {
$sql = preg_replace($pattern, 'serial', $sql);
}
}
return $sql;
}
}

View File

@ -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 = <<<SQL
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_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;

View File

@ -8,15 +8,6 @@ class InsertSQLRewriter extends AbstractSQLRewriter
$sql = $this->original();
$sql = str_replace('(0,', "('0',", $sql);
$sql = str_replace('(1,', "('1',", $sql);
// Fix inserts into wp_categories
if(false !== strpos($sql, 'INSERT INTO ' . $wpdb->categories)) {
$sql = str_replace('"cat_ID",', '', $sql);
$sql = str_replace("VALUES ('0',", "VALUES(", $sql);
}
// Those are used when we need to set the date to now() in gmt time
$sql = str_replace("'0000-00-00 00:00:00'", 'now() AT TIME ZONE \'gmt\'', $sql);

View File

@ -0,0 +1,107 @@
<?php
class ReplaceIntoSQLRewriter extends AbstractSQLRewriter
{
public function rewrite(): string
{
global $wpdb;
$sql = $this->original();
$splitStatements = function (string $sql): array {
$statements = [];
$buffer = '';
$quote = null;
for ($i = 0, $len = strlen($sql); $i < $len; $i++) {
$char = $sql[$i];
if ($quote) {
if ($char === $quote && $sql[$i - 1] !== '\\') {
$quote = null;
}
} elseif ($char === '"' || $char === "'") {
$quote = $char;
} elseif ($char === ';') {
$statements[] = $buffer . ';';
$buffer = '';
continue;
}
$buffer .= $char;
}
if (!empty($buffer)) {
$statements[] = $buffer;
}
return $statements;
};
$statements = $splitStatements($sql);
foreach ($statements as $statement) {
$statement = trim($statement);
// Skip empty statements
if (empty($statement)) {
continue;
}
// Replace backticks with double quotes for PostgreSQL compatibility
$statement = str_replace('`', '"', $statement);
// Find index positions for the SQL components
$insertIndex = strpos($statement, 'REPLACE INTO');
$columnsStartIndex = strpos($statement, "(");
$columnsEndIndex = strpos($statement, ")");
$valuesIndex = strpos($statement, 'VALUES');
$onDuplicateKeyIndex = strpos($statement, 'ON DUPLICATE KEY UPDATE');
// Extract SQL components
$tableSection = trim(substr($statement, $insertIndex, $columnsStartIndex - $insertIndex));
$valuesSection = trim(substr($statement, $valuesIndex, strlen($statement) - $valuesIndex));
$columnsSection = trim(substr($statement, $columnsStartIndex, $columnsEndIndex - $columnsStartIndex + 1));
// Extract and clean up column names from the update section
$updateCols = explode(',', substr($columnsSection, 1, strlen($columnsSection) - 2));
$updateCols = array_map(function ($col) {
return trim($col);
}, $updateCols);
// Choose a primary key for ON CONFLICT
$primaryKey = 'option_name';
if (!in_array($primaryKey, $updateCols)) {
$primaryKey = 'meta_name';
if (!in_array($primaryKey, $updateCols)) {
$primaryKey = $updateCols[0] ?? '';
}
}
// SWAP REPLACE INTO for INSERT INTO
$tableSection = str_replace("REPLACE INTO", "INSERT INTO", $tableSection);
// Construct the PostgreSQL ON CONFLICT DO UPDATE section
$updateSection = "";
foreach($updateCols as $col) {
if ($col !== $primaryKey) {
$updateSection .= ", ";
$updateSection .= "$col = EXCLUDED.$col";
}
}
// trim any preceding commas
$updateSection = ltrim($updateSection,", ");
// Construct the PostgreSQL query
$postgresSQL = sprintf('%s %s %s ON CONFLICT (%s) DO UPDATE SET %s', $tableSection, $columnsSection, $valuesSection, $primaryKey, $updateSection);
// Append to the converted statements list
$convertedStatements[] = $postgresSQL;
}
$sql = implode('; ', $convertedStatements);
return $sql;
}
}

View File

@ -24,6 +24,9 @@ class SelectSQLRewriter extends AbstractSQLRewriter
// Remove the LIMIT clause if it exists
$sql = preg_replace('/\s+LIMIT\s+\d+(\s*,\s*\d+)?/i', '', $sql);
// Remove the ORDER BY containing case / end clause if it exists
$sql = preg_replace('/\s+ORDER\s+BY\s+.+END\),[^)]+/is', '', $sql);
// Remove the ORDER BY clause if it exists
$sql = preg_replace('/\s+ORDER\s+BY\s+[^)]+/i', '', $sql);
@ -31,6 +34,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
@ -346,4 +359,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($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;
}
}

View File

@ -28,9 +28,10 @@ class ShowFullColumnsSQLRewriter extends AbstractSQLRewriter
* 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
@ -62,7 +63,7 @@ class ShowFullColumnsSQLRewriter extends AbstractSQLRewriter
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;

View 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;
}
}

View File

@ -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\';';
}
}

View File

@ -19,7 +19,7 @@ it replaces calls to mysqli_ with wpsqli_ which then are implemented by the driv
### Supported Wordpress Versions
This plugin has been tested against
- Wordpress 6.4.1 (v3 branch)
- Wordpress 6.4.3 (v3 branch)
- Wordpress 6.3.2 (v2 branch)
### Supported PHP versions

View File

@ -64,7 +64,7 @@ final class rewriteTest extends TestCase
lockout_host varchar(40),
lockout_user bigint ,
lockout_username varchar(60),
lockout_active smallint NOT NULL DEFAULT 1,
lockout_active int NOT NULL DEFAULT 1,
lockout_context TEXT,
PRIMARY KEY (lockout_id)
);
@ -382,6 +382,103 @@ final class rewriteTest extends TestCase
$this->assertSame(trim($expected), trim($postgresql));
}
public function test_it_will_handle_found_rows_on_queries_with_order_by_case()
{
$GLOBALS['pg4wp_numrows_query'] = <<<SQL
SELECT wp_posts.ID
FROM wp_posts
WHERE 1=1 AND
(((wp_posts.post_title LIKE '%Hello%') OR (wp_posts.post_excerpt LIKE '%Hello%') OR (wp_posts.post_content LIKE '%Hello%')) AND
((wp_posts.post_title LIKE '%world%') OR (wp_posts.post_excerpt LIKE '%world%') OR (wp_posts.post_content LIKE '%world%'))) AND
((wp_posts.post_type = 'post' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'future' OR wp_posts.post_status = 'draft' OR wp_posts.post_status = 'pending' OR wp_posts.post_status = 'private')))
ORDER BY (CASE
WHEN wp_posts.post_title LIKE '%Hello world%' THEN 1
WHEN wp_posts.post_title LIKE '%Hello%' AND wp_posts.post_title LIKE '%world%' THEN 2
WHEN wp_posts.post_title LIKE '%Hello%' OR wp_posts.post_title LIKE '%world%' THEN 3
WHEN wp_posts.post_excerpt LIKE '%Hello world%' THEN 4
WHEN wp_posts.post_content LIKE '%Hello world%' THEN 5 ELSE 6 END), wp_posts.post_date
DESC
LIMIT 0, 20
SQL;
$sql = "SELECT FOUND_ROWS()";
$expected = <<<SQL
SELECT COUNT(*) FROM wp_posts
WHERE 1=1 AND
(((wp_posts.post_title ILIKE '%Hello%') OR (wp_posts.post_excerpt ILIKE '%Hello%') OR (wp_posts.post_content ILIKE '%Hello%')) AND
((wp_posts.post_title ILIKE '%world%') OR (wp_posts.post_excerpt ILIKE '%world%') OR (wp_posts.post_content ILIKE '%world%'))) AND
((wp_posts.post_type = 'post' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'future' OR wp_posts.post_status = 'draft' OR wp_posts.post_status = 'pending' OR wp_posts.post_status = 'private')))
SQL;
$postgresql = pg4wp_rewrite($sql);
$this->assertSame(trim($expected), trim($postgresql));
}
public function test_it_can_handle_replacement_sql()
{
$sql = "REPLACE INTO test2 (column1, column2, column3) VALUES (1, 'Old', '2014-08-20 18:47:00')";
$expected = "INSERT INTO test2 (column1, column2, column3) VALUES (1, 'Old', '2014-08-20 18:47:00') ON CONFLICT (column1) DO UPDATE SET column2 = EXCLUDED.column2, column3 = EXCLUDED.column3";
$postgresql = pg4wp_rewrite($sql);
$this->assertSame(trim($expected), trim($postgresql));
}
public function test_it_can_handle_insert_sql_containing_nested_parathesis_with_numbers()
{
$sql = <<<SQL
REPLACE INTO `wp_options` (`option_name`, `option_value`, `autoload`) VALUES ('_site_transient_wp_remote_block_patterns_b815a6cec4e03bb064328ac11645ce66', 'a:43:{i:0;O:8:"stdClass":7:{s:2:"id";i:309935;s:5:"title";O:8:"stdClass":1:{s:8:"rendered";s:45:"Centered image with two-tone background color";}s:7:"content";O:8:"stdClass":2:{s:8:"rendered";s
<div class="wp-block-cover alignfull is-light" style="margin-top:0;padding-top:5vw;padding-right:5vw;padding-bottom:5vw;padding-left:5vw;min-height:66vh;aspect-ratio:unset;aspect-ratio:unset;"><span aria-hidden="true" class="wp-block-cover__background has-background-dim-100 has-background-dim has-background-gradient" style="background:linear-grad
<div class="wp-block-group wp-container-content-2 is-layout-constrained wp-container-core-group-is-layout-1 wp-block-group-is-layout-constrained">
!-- /wp:image -->
<!-- wp:paragraph {"align":"right","style":{"typography":{"fontSize":"148px","textTransform":"uppercase","fontStyle":"normal","fontWeight":"700","lineHeight":"0.8","letterSpacing":"-4px"}},"textColor":"white"} -->
<p class="has-text-align-right has-white-color has-text-color" style="font-size:148px;font-style:normal;font-weight:700;letter-spacing:-4px;line-height:0.8;text-transform:uppercase">Big<br>John<br>Patton</p>
<!-- /wp:paragraph --></div>
<!-- /wp:group --></div>
<!-- /wp:group --></div></div>
<!-- /wp:cover -->";}i:4;O:8:"stdClass":7:{s:2:"id";i:309236;s:5:"title";O:8:"stdClass":1:{s:8:"rendered";s:60:"Fullwidth headline with links and gradient offset background";}s:7:"content";O:8:"stdClass":2:{s:8:"rendered";s:1972:"
<div class="wp-block-cover alignfull is-light" style="margin-top:0;padding-top:48px;padding-right:5vw;padding-bottom:48px;padding-left:5vw"><span aria-hidden="true" class="wp-block-cover__background has-background-dim-100 has-background-dim has-background-gradient" style="background:linear-gradient(180deg,rgb(0,0,0) 39%,rgb(83,80,123) 39%)"></spa
<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- wp:image {"sizeSlug":"large","linkDestination":"none"} -->
<figure class="wp-block-image size-large"><img src="https://s.w.org/images/core/5.8/nature-above-02.jpg" alt="An aerial view of a field. A road runs through the upper right corner." /></figure>
<!-- /wp:image --></figure>
<!-- /wp:gallery -->";}}', 'no')
SQL;
$expected = <<<SQL
INSERT INTO "wp_options" ("option_name", "option_value", "autoload") VALUES ('_site_transient_wp_remote_block_patterns_b815a6cec4e03bb064328ac11645ce66', 'a:43:{i:0;O:8:"stdClass":7:{s:2:"id";i:309935;s:5:"title";O:8:"stdClass":1:{s:8:"rendered";s:45:"Centered image with two-tone background color";}s:7:"content";O:8:"stdClass":2:{s:8:"rendered";s
<div class="wp-block-cover alignfull is-light" style="margin-top:0;padding-top:5vw;padding-right:5vw;padding-bottom:5vw;padding-left:5vw;min-height:66vh;aspect-ratio:unset;aspect-ratio:unset;"><span aria-hidden="true" class="wp-block-cover__background has-background-dim-100 has-background-dim has-background-gradient" style="background:linear-grad
<div class="wp-block-group wp-container-content-2 is-layout-constrained wp-container-core-group-is-layout-1 wp-block-group-is-layout-constrained">
!-- /wp:image -->
<!-- wp:paragraph {"align":"right","style":{"typography":{"fontSize":"148px","textTransform":"uppercase","fontStyle":"normal","fontWeight":"700","lineHeight":"0.8","letterSpacing":"-4px"}},"textColor":"white"} -->
<p class="has-text-align-right has-white-color has-text-color" style="font-size:148px;font-style:normal;font-weight:700;letter-spacing:-4px;line-height:0.8;text-transform:uppercase">Big<br>John<br>Patton</p>
<!-- /wp:paragraph --></div>
<!-- /wp:group --></div>
<!-- /wp:group --></div></div>
<!-- /wp:cover -->";}i:4;O:8:"stdClass":7:{s:2:"id";i:309236;s:5:"title";O:8:"stdClass":1:{s:8:"rendered";s:60:"Fullwidth headline with links and gradient offset background";}s:7:"content";O:8:"stdClass":2:{s:8:"rendered";s:1972:"
<div class="wp-block-cover alignfull is-light" style="margin-top:0;padding-top:48px;padding-right:5vw;padding-bottom:48px;padding-left:5vw"><span aria-hidden="true" class="wp-block-cover__background has-background-dim-100 has-background-dim has-background-gradient" style="background:linear-gradient(180deg,rgb(0,0,0) 39%,rgb(83,80,123) 39%)"></spa
<div style="height:100px" aria-hidden="true" class="wp-block-spacer"></div>
<!-- wp:image {"sizeSlug":"large","linkDestination":"none"} -->
<figure class="wp-block-image size-large"><img src="https://s.w.org/images/core/5.8/nature-above-02.jpg" alt="An aerial view of a field. A road runs through the upper right corner." /></figure>
<!-- /wp:image --></figure>
<!-- /wp:gallery -->";}}', 'no') ON CONFLICT ("option_name") DO UPDATE SET "option_value" = EXCLUDED."option_value", "autoload" = EXCLUDED."autoload"
SQL;
$postgresql = pg4wp_rewrite($sql);
$this->assertSame(trim($expected), trim($postgresql));
}
public function test_it_doesnt_rewrite_when_it_doesnt_need_to()
{
$sql = <<<SQL

View File

@ -1 +1 @@
{"mysql":"INSERT INTO `wp_sitemeta` (`site_id`, `meta_key`, `meta_value`) VALUES (1, '_site_transient_wp_remote_block_patterns_03fe7d7ccb043466cdff46c6061da4a5', 'O:8:\"WP_Error\":3:{s:6:\"errors\";a:1:{s:19:\"http_request_failed\";a:1:{i:0;s:95:\"cURL error 35: OpenSSL\/3.1.4: error:0A000152:SSL routines::unsafe legacy renegotiation disabled\";}}s:10:\"error_data\";a:0:{}s:18:\"')","postgresql":"INSERT INTO wp_sitemeta (site_id, meta_key, meta_value) VALUES ('1', '_site_transient_wp_remote_block_patterns_03fe7d7ccb043466cdff46c6061da4a5', 'O:8:\"WP_Error\":3:{s:6:\"errors\";a:1:{s:19:\"http_request_failed\";a:1:{i:0;s:95:\"cURL error 35: OpenSSL\/3.1.4: error:0A000152:SSL routines::unsafe legacy renegotiation disabled\";}}s:10:\"error_data\";a:0:{}s:18:\"')"}
{"mysql":"INSERT INTO `wp_sitemeta` (`site_id`, `meta_key`, `meta_value`) VALUES (1, '_site_transient_wp_remote_block_patterns_03fe7d7ccb043466cdff46c6061da4a5', 'O:8:\"WP_Error\":3:{s:6:\"errors\";a:1:{s:19:\"http_request_failed\";a:1:{i:0;s:95:\"cURL error 35: OpenSSL\/3.1.4: error:0A000152:SSL routines::unsafe legacy renegotiation disabled\";}}s:10:\"error_data\";a:0:{}s:18:\"')","postgresql":"INSERT INTO wp_sitemeta (site_id, meta_key, meta_value) VALUES (1, '_site_transient_wp_remote_block_patterns_03fe7d7ccb043466cdff46c6061da4a5', 'O:8:\"WP_Error\":3:{s:6:\"errors\";a:1:{s:19:\"http_request_failed\";a:1:{i:0;s:95:\"cURL error 35: OpenSSL\/3.1.4: error:0A000152:SSL routines::unsafe legacy renegotiation disabled\";}}s:10:\"error_data\";a:0:{}s:18:\"')"}

View File

@ -1 +1 @@
{"mysql":"INSERT INTO `wp_sitemeta` (`site_id`, `meta_key`, `meta_value`) VALUES (1, '_site_transient_wp_remote_block_patterns_0dc4db57500f00dee60778de7fb84b69', 'O:8:\"WP_Error\":3:{s:6:\"errors\";a:1:{s:19:\"http_request_failed\";a:1:{i:0;s:95:\"cURL error 35: OpenSSL\/3.1.4: error:0A000152:SSL routines::unsafe legacy renegotiation disabled\";}}s:10:\"error_data\";a:0:{}s:18:\"')","postgresql":"INSERT INTO wp_sitemeta (site_id, meta_key, meta_value) VALUES ('1', '_site_transient_wp_remote_block_patterns_0dc4db57500f00dee60778de7fb84b69', 'O:8:\"WP_Error\":3:{s:6:\"errors\";a:1:{s:19:\"http_request_failed\";a:1:{i:0;s:95:\"cURL error 35: OpenSSL\/3.1.4: error:0A000152:SSL routines::unsafe legacy renegotiation disabled\";}}s:10:\"error_data\";a:0:{}s:18:\"')"}
{"mysql":"INSERT INTO `wp_sitemeta` (`site_id`, `meta_key`, `meta_value`) VALUES (1, '_site_transient_wp_remote_block_patterns_0dc4db57500f00dee60778de7fb84b69', 'O:8:\"WP_Error\":3:{s:6:\"errors\";a:1:{s:19:\"http_request_failed\";a:1:{i:0;s:95:\"cURL error 35: OpenSSL\/3.1.4: error:0A000152:SSL routines::unsafe legacy renegotiation disabled\";}}s:10:\"error_data\";a:0:{}s:18:\"')","postgresql":"INSERT INTO wp_sitemeta (site_id, meta_key, meta_value) VALUES (1, '_site_transient_wp_remote_block_patterns_0dc4db57500f00dee60778de7fb84b69', 'O:8:\"WP_Error\":3:{s:6:\"errors\";a:1:{s:19:\"http_request_failed\";a:1:{i:0;s:95:\"cURL error 35: OpenSSL\/3.1.4: error:0A000152:SSL routines::unsafe legacy renegotiation disabled\";}}s:10:\"error_data\";a:0:{}s:18:\"')"}

View File

@ -1 +1 @@
{"mysql":"INSERT INTO `wp_posts` (`post_author`, `post_date`, `post_date_gmt`, `post_content`, `post_content_filtered`, `post_title`, `post_excerpt`, `post_status`, `post_type`, `comment_status`, `ping_status`, `post_password`, `post_name`, `to_ping`, `pinged`, `post_modified`, `post_modified_gmt`, `post_parent`, `menu_order`, `post_mime_type`, `guid`) VALUES (1, '2023-10-30 15:31:24', '2023-10-30 15:31:24', '', '', 'New Post 123', '', 'inherit', 'revision', 'closed', 'closed', '', '55-revision-v1', '', '', '2023-10-30 15:31:24', '2023-10-30 15:31:24', 55, 0, '', '')","postgresql":"INSERT INTO wp_posts (post_author, post_date, post_date_gmt, post_content, post_content_filtered, post_title, post_excerpt, post_status, post_type, comment_status, ping_status, post_password, post_name, to_ping, pinged, post_modified, post_modified_gmt, post_parent, menu_order, post_mime_type, guid) VALUES ('1', '2023-10-30 15:31:24', '2023-10-30 15:31:24', '', '', 'New Post 123', '', 'inherit', 'revision', 'closed', 'closed', '', '55-revision-v1', '', '', '2023-10-30 15:31:24', '2023-10-30 15:31:24', 55, 0, '', '')"}
{"mysql":"INSERT INTO `wp_posts` (`post_author`, `post_date`, `post_date_gmt`, `post_content`, `post_content_filtered`, `post_title`, `post_excerpt`, `post_status`, `post_type`, `comment_status`, `ping_status`, `post_password`, `post_name`, `to_ping`, `pinged`, `post_modified`, `post_modified_gmt`, `post_parent`, `menu_order`, `post_mime_type`, `guid`) VALUES (1, '2023-10-30 15:31:24', '2023-10-30 15:31:24', '', '', 'New Post 123', '', 'inherit', 'revision', 'closed', 'closed', '', '55-revision-v1', '', '', '2023-10-30 15:31:24', '2023-10-30 15:31:24', 55, 0, '', '')","postgresql":"INSERT INTO wp_posts (post_author, post_date, post_date_gmt, post_content, post_content_filtered, post_title, post_excerpt, post_status, post_type, comment_status, ping_status, post_password, post_name, to_ping, pinged, post_modified, post_modified_gmt, post_parent, menu_order, post_mime_type, guid) VALUES (1, '2023-10-30 15:31:24', '2023-10-30 15:31:24', '', '', 'New Post 123', '', 'inherit', 'revision', 'closed', 'closed', '', '55-revision-v1', '', '', '2023-10-30 15:31:24', '2023-10-30 15:31:24', 55, 0, '', '')"}

View File

@ -1 +1 @@
{"mysql":"INSERT INTO `wp_sitemeta` (`site_id`, `meta_key`, `meta_value`) VALUES (1, '_site_transient_wp_remote_block_patterns_0dc4db57500f00dee60778de7fb84b69', 'O:8:\"WP_Error\":3:{s:6:\"errors\";a:1:{s:19:\"http_request_failed\";a:1:{i:0;s:95:\"cURL error 35: OpenSSL\/3.1.4: error:0A000152:SSL routines::unsafe legacy renegotiation disabled\";}}s:10:\"error_data\";a:0:{}s:18:\"')","postgresql":"INSERT INTO wp_sitemeta (site_id, meta_key, meta_value) VALUES ('1', '_site_transient_wp_remote_block_patterns_0dc4db57500f00dee60778de7fb84b69', 'O:8:\"WP_Error\":3:{s:6:\"errors\";a:1:{s:19:\"http_request_failed\";a:1:{i:0;s:95:\"cURL error 35: OpenSSL\/3.1.4: error:0A000152:SSL routines::unsafe legacy renegotiation disabled\";}}s:10:\"error_data\";a:0:{}s:18:\"')"}
{"mysql":"INSERT INTO `wp_sitemeta` (`site_id`, `meta_key`, `meta_value`) VALUES (1, '_site_transient_wp_remote_block_patterns_0dc4db57500f00dee60778de7fb84b69', 'O:8:\"WP_Error\":3:{s:6:\"errors\";a:1:{s:19:\"http_request_failed\";a:1:{i:0;s:95:\"cURL error 35: OpenSSL\/3.1.4: error:0A000152:SSL routines::unsafe legacy renegotiation disabled\";}}s:10:\"error_data\";a:0:{}s:18:\"')","postgresql":"INSERT INTO wp_sitemeta (site_id, meta_key, meta_value) VALUES (1, '_site_transient_wp_remote_block_patterns_0dc4db57500f00dee60778de7fb84b69', 'O:8:\"WP_Error\":3:{s:6:\"errors\";a:1:{s:19:\"http_request_failed\";a:1:{i:0;s:95:\"cURL error 35: OpenSSL\/3.1.4: error:0A000152:SSL routines::unsafe legacy renegotiation disabled\";}}s:10:\"error_data\";a:0:{}s:18:\"')"}

View File

@ -1 +1 @@
{"mysql":"INSERT INTO `wp_posts` (`post_author`, `post_date`, `post_date_gmt`, `post_content`, `post_content_filtered`, `post_title`, `post_excerpt`, `post_status`, `post_type`, `comment_status`, `ping_status`, `post_password`, `post_name`, `to_ping`, `pinged`, `post_modified`, `post_modified_gmt`, `post_parent`, `menu_order`, `post_mime_type`, `guid`) VALUES (1, '2023-10-30 15:32:03', '2023-10-30 15:32:03', '', '', 'Test Page', '', 'inherit', 'revision', 'closed', 'closed', '', '57-revision-v1', '', '', '2023-10-30 15:32:03', '2023-10-30 15:32:03', 57, 0, '', '')","postgresql":"INSERT INTO wp_posts (post_author, post_date, post_date_gmt, post_content, post_content_filtered, post_title, post_excerpt, post_status, post_type, comment_status, ping_status, post_password, post_name, to_ping, pinged, post_modified, post_modified_gmt, post_parent, menu_order, post_mime_type, guid) VALUES ('1', '2023-10-30 15:32:03', '2023-10-30 15:32:03', '', '', 'Test Page', '', 'inherit', 'revision', 'closed', 'closed', '', '57-revision-v1', '', '', '2023-10-30 15:32:03', '2023-10-30 15:32:03', 57, 0, '', '')"}
{"mysql":"INSERT INTO `wp_posts` (`post_author`, `post_date`, `post_date_gmt`, `post_content`, `post_content_filtered`, `post_title`, `post_excerpt`, `post_status`, `post_type`, `comment_status`, `ping_status`, `post_password`, `post_name`, `to_ping`, `pinged`, `post_modified`, `post_modified_gmt`, `post_parent`, `menu_order`, `post_mime_type`, `guid`) VALUES (1, '2023-10-30 15:32:03', '2023-10-30 15:32:03', '', '', 'Test Page', '', 'inherit', 'revision', 'closed', 'closed', '', '57-revision-v1', '', '', '2023-10-30 15:32:03', '2023-10-30 15:32:03', 57, 0, '', '')","postgresql":"INSERT INTO wp_posts (post_author, post_date, post_date_gmt, post_content, post_content_filtered, post_title, post_excerpt, post_status, post_type, comment_status, ping_status, post_password, post_name, to_ping, pinged, post_modified, post_modified_gmt, post_parent, menu_order, post_mime_type, guid) VALUES (1, '2023-10-30 15:32:03', '2023-10-30 15:32:03', '', '', 'Test Page', '', 'inherit', 'revision', 'closed', 'closed', '', '57-revision-v1', '', '', '2023-10-30 15:32:03', '2023-10-30 15:32:03', 57, 0, '', '')"}

View File

@ -1 +1 @@
{"mysql":"INSERT INTO `wp_sitemeta` (`site_id`, `meta_key`, `meta_value`) VALUES (1, '_site_transient_wp_remote_block_patterns_03fe7d7ccb043466cdff46c6061da4a5', 'O:8:\"WP_Error\":3:{s:6:\"errors\";a:1:{s:19:\"http_request_failed\";a:1:{i:0;s:95:\"cURL error 35: OpenSSL\/3.1.4: error:0A000152:SSL routines::unsafe legacy renegotiation disabled\";}}s:10:\"error_data\";a:0:{}s:18:\"')","postgresql":"INSERT INTO wp_sitemeta (site_id, meta_key, meta_value) VALUES ('1', '_site_transient_wp_remote_block_patterns_03fe7d7ccb043466cdff46c6061da4a5', 'O:8:\"WP_Error\":3:{s:6:\"errors\";a:1:{s:19:\"http_request_failed\";a:1:{i:0;s:95:\"cURL error 35: OpenSSL\/3.1.4: error:0A000152:SSL routines::unsafe legacy renegotiation disabled\";}}s:10:\"error_data\";a:0:{}s:18:\"')"}
{"mysql":"INSERT INTO `wp_sitemeta` (`site_id`, `meta_key`, `meta_value`) VALUES (1, '_site_transient_wp_remote_block_patterns_03fe7d7ccb043466cdff46c6061da4a5', 'O:8:\"WP_Error\":3:{s:6:\"errors\";a:1:{s:19:\"http_request_failed\";a:1:{i:0;s:95:\"cURL error 35: OpenSSL\/3.1.4: error:0A000152:SSL routines::unsafe legacy renegotiation disabled\";}}s:10:\"error_data\";a:0:{}s:18:\"')","postgresql":"INSERT INTO wp_sitemeta (site_id, meta_key, meta_value) VALUES (1, '_site_transient_wp_remote_block_patterns_03fe7d7ccb043466cdff46c6061da4a5', 'O:8:\"WP_Error\":3:{s:6:\"errors\";a:1:{s:19:\"http_request_failed\";a:1:{i:0;s:95:\"cURL error 35: OpenSSL\/3.1.4: error:0A000152:SSL routines::unsafe legacy renegotiation disabled\";}}s:10:\"error_data\";a:0:{}s:18:\"')"}

View File

@ -1 +1 @@
{"mysql":"INSERT INTO `wp_sitemeta` (`site_id`, `meta_key`, `meta_value`) VALUES (1, '_site_transient_wp_remote_block_patterns_0dc4db57500f00dee60778de7fb84b69', 'O:8:\"WP_Error\":3:{s:6:\"errors\";a:1:{s:19:\"http_request_failed\";a:1:{i:0;s:95:\"cURL error 35: OpenSSL\/3.1.4: error:0A000152:SSL routines::unsafe legacy renegotiation disabled\";}}s:10:\"error_data\";a:0:{}s:18:\"')","postgresql":"INSERT INTO wp_sitemeta (site_id, meta_key, meta_value) VALUES ('1', '_site_transient_wp_remote_block_patterns_0dc4db57500f00dee60778de7fb84b69', 'O:8:\"WP_Error\":3:{s:6:\"errors\";a:1:{s:19:\"http_request_failed\";a:1:{i:0;s:95:\"cURL error 35: OpenSSL\/3.1.4: error:0A000152:SSL routines::unsafe legacy renegotiation disabled\";}}s:10:\"error_data\";a:0:{}s:18:\"')"}
{"mysql":"INSERT INTO `wp_sitemeta` (`site_id`, `meta_key`, `meta_value`) VALUES (1, '_site_transient_wp_remote_block_patterns_0dc4db57500f00dee60778de7fb84b69', 'O:8:\"WP_Error\":3:{s:6:\"errors\";a:1:{s:19:\"http_request_failed\";a:1:{i:0;s:95:\"cURL error 35: OpenSSL\/3.1.4: error:0A000152:SSL routines::unsafe legacy renegotiation disabled\";}}s:10:\"error_data\";a:0:{}s:18:\"')","postgresql":"INSERT INTO wp_sitemeta (site_id, meta_key, meta_value) VALUES (1, '_site_transient_wp_remote_block_patterns_0dc4db57500f00dee60778de7fb84b69', 'O:8:\"WP_Error\":3:{s:6:\"errors\";a:1:{s:19:\"http_request_failed\";a:1:{i:0;s:95:\"cURL error 35: OpenSSL\/3.1.4: error:0A000152:SSL routines::unsafe legacy renegotiation disabled\";}}s:10:\"error_data\";a:0:{}s:18:\"')"}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long