Skip to content

Commit

Permalink
Merge pull request #67 from graze/remove-int-display-width-zerofill
Browse files Browse the repository at this point in the history
Remove int width and zerofill for > MySQL 8.0.19
  • Loading branch information
rick-lam authored May 1, 2024
2 parents a89058f + a278ab8 commit 8aea35e
Show file tree
Hide file tree
Showing 16 changed files with 175 additions and 190 deletions.
4 changes: 2 additions & 2 deletions example/schema/ingredient.sql
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
CREATE TABLE `ingredient` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` int(11) NOT NULL,
`id` int NOT NULL AUTO_INCREMENT,
`name` int NOT NULL,
`is_active` tinyint(1) NOT NULL,
PRIMARY KEY (`id`),
CONSTRAINT `is_active_binary` CHECK (is_active IN (0,1))
Expand Down
4 changes: 2 additions & 2 deletions example/schema/product.sql
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
CREATE TABLE `product` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`id` int unsigned NOT NULL AUTO_INCREMENT,
`name` text NOT NULL,
`description` int(11) unsigned NOT NULL,
`description` int unsigned NOT NULL,
`weight` decimal(11,2) NOT NULL,
`launch_date` date DEFAULT NULL,
`internal_note` text,
Expand Down
6 changes: 3 additions & 3 deletions example/schema/product_ingredient_map.sql
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
CREATE TABLE `product_ingredient_map` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`product_id` int(11) unsigned NOT NULL,
`ingredient_id` int(11) NOT NULL,
`id` int unsigned NOT NULL AUTO_INCREMENT,
`product_id` int unsigned NOT NULL,
`ingredient_id` int NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
72 changes: 30 additions & 42 deletions src/Parse/ColumnDefinition.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,12 @@ class ColumnDefinition
private static $typeInfoMap = [
// format default allow allow allow uninitialised
// datatype kind Spec Lengths Autoinc Binary Charset Value
'bit' => [ 'bit', [0,1 ], [1], false, false, false, 0, ],
'tinyint' => [ 'int', [0,1 ], [3,4], true, false, false, 0, ],
'smallint' => [ 'int', [0,1 ], [5,6], true, false, false, 0, ],
'mediumint' => [ 'int', [0,1 ], [8,9], true, false, false, 0, ],
'int' => [ 'int', [0,1 ], [10,11], true, false, false, 0, ],
'bigint' => [ 'int', [0,1 ], [20,20], true, false, false, 0, ],
'bit' => [ 'bit', [0,1 ], null, false, false, false, 0, ],
'tinyint' => [ 'int', [0,1 ], null, true, false, false, 0, ],
'smallint' => [ 'int', [0,1 ], null, true, false, false, 0, ],
'mediumint' => [ 'int', [0,1 ], null, true, false, false, 0, ],
'int' => [ 'int', [0,1 ], null, true, false, false, 0, ],
'bigint' => [ 'int', [0,1 ], null, true, false, false, 0, ],
'double' => [ 'decimal', [0, 2], null, true, false, false, 0, ], // prec = 22
'float' => [ 'decimal', [0, 2], null, true, false, false, 0, ], // prec = 12
'decimal' => [ 'decimal', [0,1,2], [10,10], false, false, false, 0, ],
Expand Down Expand Up @@ -181,7 +181,7 @@ private function getTypeInfo()
'allowDefault' => !is_null($data[6]),
'uninitialisedValue' => $data[6],
];
$typeInfo->allowSign = $typeInfo->allowZerofill = in_array($typeInfo->kind, ['int', 'decimal']);
$typeInfo->allowSign = in_array($typeInfo->kind, ['int', 'decimal']);
self::$typeInfoCache[$this->type] = $typeInfo;

return $typeInfo;
Expand All @@ -206,7 +206,6 @@ private function parseColumnDatatype(TokenStream $stream)
case 'serial':
// SERIAL is an alias for BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE
$this->type = 'bigint';
$this->length = 20;
$this->unsigned = true;
$this->nullable = false;
$this->autoIncrement = true;
Expand Down Expand Up @@ -277,13 +276,31 @@ private function parseColumnDatatype(TokenStream $stream)

case 'bool':
case 'boolean':
$format = [1];
/* Take a copy so that edits don't make it back into the runtime cache. */
$typeInfo = clone $typeInfo;
$typeInfo->allowSign = false;
$typeInfo->allowZerofill = false;
break;

case 'tinyint':
case 'smallint':
case 'mediumint':
case 'int':
case 'bigint':
case 'int1':
case 'int2':
case 'int3':
case 'int4':
case 'int8':
case 'middleint':
case 'integer':
$spec = $typeInfo->formatSpec;
// Skip for display width spec for integer data types was deprecated after 8.0.19
if ($stream->consume([[Token::SYMBOL, '(']])) {
$stream->nextToken();
$stream->nextToken();
}
break;

default:
$spec = $typeInfo->formatSpec;
if ($stream->consume([[Token::SYMBOL, '(']])) {
Expand Down Expand Up @@ -318,10 +335,7 @@ private function parseColumnDatatype(TokenStream $stream)
}

if ($token1->eq(Token::IDENTIFIER, 'ZEROFILL')) {
if (!$typeInfo->allowZerofill) {
throw new RuntimeException("Unexpected ZEROFILL");
}
$this->zerofill = true;
throw new RuntimeException("Unexpected ZEROFILL");
} elseif ($token1->eq(Token::IDENTIFIER, 'UNSIGNED')) {
if (!$typeInfo->allowSign) {
throw new RuntimeException("Unexpected UNSIGNED");
Expand All @@ -338,10 +352,6 @@ private function parseColumnDatatype(TokenStream $stream)
}
}

if ($this->zerofill) {
$this->unsigned = true;
}

$defaultLengths = $typeInfo->defaultLengths;
if (!is_null($defaultLengths)) {
if (count($format) === 0) {
Expand Down Expand Up @@ -522,18 +532,10 @@ public function getUninitialisedValue()
return $this->elements[0];

case 'int':
if ($this->zerofill) {
$length = $this->length;
return sprintf("%0{$length}d", 0);
}
return '0';

case 'decimal':
$decimals = is_null($this->decimals) ? 0 : $this->decimals;
if ($this->zerofill) {
$length = $this->length;
return sprintf("%0{$length}.{$decimals}f", 0);
}
return sprintf("%.{$decimals}f", 0);

default:
Expand Down Expand Up @@ -575,25 +577,15 @@ private function defaultValue(Token $token)
return $token->asNumber();

case 'int':
if ($this->zerofill) {
$length = $this->length;
return sprintf("%0{$length}d", $token->asNumber());
} else {
return $token->asNumber();
}
return $token->asNumber();
// Comment to appease this phpcs rule:
// PSR2.ControlStructures.SwitchDeclaration.TerminatingComment
// There must be a comment when fall-through is intentional
// in a non-empty case body

case 'decimal':
$decimals = is_null($this->decimals) ? 0 : $this->decimals;
if ($this->zerofill) {
$length = $this->length;
return sprintf("%0{$length}.{$decimals}f", $token->asNumber());
} else {
return sprintf("%.{$decimals}f", $token->asNumber());
}
return sprintf("%.{$decimals}f", $token->asNumber());
// Comment to appease this phpcs rule:
// PSR2.ControlStructures.SwitchDeclaration.TerminatingComment
// There must be a comment when fall-through is intentional
Expand Down Expand Up @@ -747,10 +739,6 @@ public function toString(CollationInfo $tableCollation)
$text .= " unsigned";
}

if ($this->zerofill) {
$text .= " zerofill";
}

if ($typeInfo->allowCharset) {
$collation = $this->collation;
if ($collation->isSpecified()) {
Expand Down
13 changes: 12 additions & 1 deletion src/Parse/CreateTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,18 @@ private function diffColumns(CreateTable $that)
$thisDefinition = $this->columns[$columnName]->toString($this->getCollation());
$thatDefinition = $that->columns[$columnName]->toString($that->getCollation());

// Display width specification for integer data types was deprecated after 8.0.19
$patterns = [
'/tinyint\(\d+\)/',
'/smallint\(\d+\)/',
'/mediumint\(\d+\)/',
'/int\(\d+\)/',
'/bigint\(\d+\)/'
];
$replacements = ['tinyint', 'smallint', 'mediumint', 'int', 'bigint'];
$thisDefinition = preg_replace($patterns, $replacements, $thisDefinition);
$thatDefinition = preg_replace($patterns, $replacements, $thatDefinition);

if (str_contains($thisDefinition, 'utf8mb3')) {
$thisDefinition = str_replace('utf8mb3', 'utf8', $thisDefinition);
}
Expand All @@ -495,7 +507,6 @@ private function diffColumns(CreateTable $that)
$thisPosition !== $thatPosition
) {
$alter = "MODIFY COLUMN " . $thatDefinition;

// position has changed
if ($thisPosition !== $thatPosition) {
$alter .= $thatPosition;
Expand Down
114 changes: 55 additions & 59 deletions tests/Parse/ColumnDefinitionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,40 +30,36 @@ public function testParseDatatypes($text, $expected)
public function parseDatatypesProvider()
{
return [
["x int", "`x` int(11) DEFAULT NULL"],
["x int signed", "`x` int(11) DEFAULT NULL"],
["x int unsigned", "`x` int(10) unsigned DEFAULT NULL"],
["x int(5)", "`x` int(5) DEFAULT NULL"],
["x int(5) default null", "`x` int(5) DEFAULT NULL"],
["x int not null default 1", "`x` int(11) NOT NULL DEFAULT '1'"],
["x int zerofill", "`x` int(10) unsigned zerofill DEFAULT NULL"],
["x int zerofill unsigned", "`x` int(10) unsigned zerofill DEFAULT NULL"],
["x int unsigned zerofill", "`x` int(10) unsigned zerofill DEFAULT NULL"],
["x int default 1", "`x` int(11) DEFAULT '1'"],
["x int(4) zerofill default 1", "`x` int(4) unsigned zerofill DEFAULT '0001'"],
["x int auto_increment", "`x` int(11) NOT NULL AUTO_INCREMENT"],
["x int comment 'blah'", "`x` int(11) DEFAULT NULL COMMENT 'blah'"],
["x int serial default value", "`x` int(11) NOT NULL AUTO_INCREMENT"],

["x int primary key", "`x` int(11) NOT NULL"],
["x int key", "`x` int(11) NOT NULL"],
["x int unique", "`x` int(11) DEFAULT NULL"],
["x int unique key", "`x` int(11) DEFAULT NULL"],

["x bit", "`x` bit(1) DEFAULT NULL"],
["x int", "`x` int DEFAULT NULL"],
["x int signed", "`x` int DEFAULT NULL"],
["x int unsigned", "`x` int unsigned DEFAULT NULL"],
["x int(5)", "`x` int DEFAULT NULL"],
["x int(5) default null", "`x` int DEFAULT NULL"],
["x int not null default 1", "`x` int NOT NULL DEFAULT '1'"],
["x int default 1", "`x` int DEFAULT '1'"],
["x int auto_increment", "`x` int NOT NULL AUTO_INCREMENT"],
["x int comment 'blah'", "`x` int DEFAULT NULL COMMENT 'blah'"],
["x int serial default value", "`x` int NOT NULL AUTO_INCREMENT"],

["x int primary key", "`x` int NOT NULL"],
["x int key", "`x` int NOT NULL"],
["x int unique", "`x` int DEFAULT NULL"],
["x int unique key", "`x` int DEFAULT NULL"],

["x bit", "`x` bit DEFAULT NULL"],
["x bit(4)", "`x` bit(4) DEFAULT NULL"],
["x bit(4) default 4", "`x` bit(4) DEFAULT b'100'"],
["x bit(4) default b'0101'", "`x` bit(4) DEFAULT b'101'"],
["x bit(8) default x'e4'", "`x` bit(8) DEFAULT b'11100100'"],

["x tinyint", "`x` tinyint(4) DEFAULT NULL"],
["x tinyint unsigned", "`x` tinyint(3) unsigned DEFAULT NULL"],
["x smallint", "`x` smallint(6) DEFAULT NULL"],
["x smallint unsigned", "`x` smallint(5) unsigned DEFAULT NULL"],
["x mediumint", "`x` mediumint(9) DEFAULT NULL"],
["x mediumint unsigned", "`x` mediumint(8) unsigned DEFAULT NULL"],
["x bigint", "`x` bigint(20) DEFAULT NULL"],
["x bigint unsigned", "`x` bigint(20) unsigned DEFAULT NULL"],
["x tinyint", "`x` tinyint DEFAULT NULL"],
["x tinyint unsigned", "`x` tinyint unsigned DEFAULT NULL"],
["x smallint", "`x` smallint DEFAULT NULL"],
["x smallint unsigned", "`x` smallint unsigned DEFAULT NULL"],
["x mediumint", "`x` mediumint DEFAULT NULL"],
["x mediumint unsigned", "`x` mediumint unsigned DEFAULT NULL"],
["x bigint", "`x` bigint DEFAULT NULL"],
["x bigint unsigned", "`x` bigint unsigned DEFAULT NULL"],

["x double", "`x` double DEFAULT NULL"],
["x double unsigned", "`x` double unsigned DEFAULT NULL"],
Expand All @@ -79,7 +75,7 @@ public function parseDatatypesProvider()
["x decimal(8,3)", "`x` decimal(8,3) DEFAULT NULL"],
["x decimal default 1", "`x` decimal(10,0) DEFAULT '1'"],
["x decimal(5,3) default 1", "`x` decimal(5,3) DEFAULT '1.000'"],
["x decimal(7,3) zerofill default 1", "`x` decimal(7,3) unsigned zerofill DEFAULT '001.000'"],
["x decimal(7,3) unsigned default 1", "`x` decimal(7,3) unsigned DEFAULT '1.000'"],

["x date", "`x` date DEFAULT NULL"],
["x date default 0", "`x` date DEFAULT '0000-00-00'"],
Expand Down Expand Up @@ -182,7 +178,7 @@ public function parseDatatypesProvider()
["x set('a', 'b', 'c') NOT NULL", "`x` set('a','b','c') NOT NULL"],
["x set('a', 'b', 'c') default ''", "`x` set('a','b','c') DEFAULT ''"],

["x serial", "`x` bigint(20) unsigned NOT NULL AUTO_INCREMENT"],
["x serial", "`x` bigint unsigned NOT NULL AUTO_INCREMENT"],

["x character", "`x` char(1) DEFAULT NULL"],
["x character(10)", "`x` char(10) DEFAULT NULL"],
Expand All @@ -196,38 +192,38 @@ public function parseDatatypesProvider()
["x long varchar", "`x` mediumtext"],
["x long", "`x` mediumtext"],

["x bool", "`x` tinyint(1) DEFAULT NULL"],
["x boolean", "`x` tinyint(1) DEFAULT NULL"],
["x bool NOT NULL", "`x` tinyint(1) NOT NULL"],
["x boolean NOT NULL", "`x` tinyint(1) NOT NULL"],
["x bool", "`x` tinyint DEFAULT NULL"],
["x boolean", "`x` tinyint DEFAULT NULL"],
["x bool NOT NULL", "`x` tinyint NOT NULL"],
["x boolean NOT NULL", "`x` tinyint NOT NULL"],

["x int1", "`x` tinyint(4) DEFAULT NULL"],
["x int1(3)", "`x` tinyint(3) DEFAULT NULL"],
["x int1 NOT NULL", "`x` tinyint(4) NOT NULL"],
["x int1", "`x` tinyint DEFAULT NULL"],
["x int1(3)", "`x` tinyint DEFAULT NULL"],
["x int1 NOT NULL", "`x` tinyint NOT NULL"],

["x int2", "`x` smallint(6) DEFAULT NULL"],
["x int2(3)", "`x` smallint(3) DEFAULT NULL"],
["x int2 NOT NULL", "`x` smallint(6) NOT NULL"],
["x int2", "`x` smallint DEFAULT NULL"],
["x int2(3)", "`x` smallint DEFAULT NULL"],
["x int2 NOT NULL", "`x` smallint NOT NULL"],

["x int3", "`x` mediumint(9) DEFAULT NULL"],
["x int3(3)", "`x` mediumint(3) DEFAULT NULL"],
["x int3 NOT NULL", "`x` mediumint(9) NOT NULL"],
["x int3", "`x` mediumint DEFAULT NULL"],
["x int3(3)", "`x` mediumint DEFAULT NULL"],
["x int3 NOT NULL", "`x` mediumint NOT NULL"],

["x middleint", "`x` mediumint(9) DEFAULT NULL"],
["x middleint(3)", "`x` mediumint(3) DEFAULT NULL"],
["x middleint NOT NULL", "`x` mediumint(9) NOT NULL"],
["x middleint", "`x` mediumint DEFAULT NULL"],
["x middleint(3)", "`x` mediumint DEFAULT NULL"],
["x middleint NOT NULL", "`x` mediumint NOT NULL"],

["x int4", "`x` int(11) DEFAULT NULL"],
["x int4(3)", "`x` int(3) DEFAULT NULL"],
["x int4 NOT NULL", "`x` int(11) NOT NULL"],
["x int4", "`x` int DEFAULT NULL"],
["x int4(3)", "`x` int DEFAULT NULL"],
["x int4 NOT NULL", "`x` int NOT NULL"],

["x integer", "`x` int(11) DEFAULT NULL"],
["x integer(3)", "`x` int(3) DEFAULT NULL"],
["x integer NOT NULL", "`x` int(11) NOT NULL"],
["x integer", "`x` int DEFAULT NULL"],
["x integer(3)", "`x` int DEFAULT NULL"],
["x integer NOT NULL", "`x` int NOT NULL"],

["x int8", "`x` bigint(20) DEFAULT NULL"],
["x int8(3)", "`x` bigint(3) DEFAULT NULL"],
["x int8 NOT NULL", "`x` bigint(20) NOT NULL"],
["x int8", "`x` bigint DEFAULT NULL"],
["x int8(3)", "`x` bigint DEFAULT NULL"],
["x int8 NOT NULL", "`x` bigint NOT NULL"],

["x dec", "`x` decimal(10,0) DEFAULT NULL"],
["x dec(8)", "`x` decimal(8,0) DEFAULT NULL"],
Expand All @@ -252,7 +248,7 @@ public function parseDatatypesProvider()
["x json NOT NULL", "`x` json NOT NULL"],

// Ignore unrecognised column options
["x int foo", "`x` int(11) DEFAULT NULL"],
["x int foo", "`x` int DEFAULT NULL"],
];
}

Expand Down Expand Up @@ -280,6 +276,8 @@ public function parseInvalidDatatypesProvider()
["x null"],
// No identifier
["int"],
// Unexpected ZEROFILL keyword
["x int zerofill"],
// No comma separator
["x set('a'|'b')"],
// Unexpected parentheses
Expand Down Expand Up @@ -408,10 +406,8 @@ public function getUninitialisedValuesProvider()
// [ Column definition, uninitialised value ]
["x enum('a', 'b', 'c')", "a"],
["x int", "0"],
["x int(5) zerofill", "00000"],
["x decimal", "0"],
["x decimal(5,3)", "0.000"],
["x decimal(5,1) zerofill", "000.0"],
["x char", ""],
["x blob", null],
];
Expand Down
Loading

0 comments on commit 8aea35e

Please sign in to comment.