Merge pull request #104 from PostgreSQL-For-Wordpress/robust-numeric

make numeric rewriters generic
This commit is contained in:
Matthew Bucci
2024-02-26 12:21:25 -08:00
committed by GitHub
3 changed files with 101 additions and 53 deletions

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'
@ -35,6 +29,8 @@ class AlterTableSQLRewriter extends AbstractSQLRewriter
{
$sql = $this->original();
$sql = $this->rewrite_numeric_type($sql);
if (str_contains($sql, 'CHANGE COLUMN')) {
$sql = $this->rewriteChangeColumn($sql);
}
@ -185,4 +181,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

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