diff --git a/src/Util/ColumnParser.php b/src/Util/ColumnParser.php index 54c45151..fbfbafdc 100644 --- a/src/Util/ColumnParser.php +++ b/src/Util/ColumnParser.php @@ -46,6 +46,7 @@ class ColumnParser public function parseFields(array $arguments): array { $fields = []; + $primaryKeys = []; $arguments = $this->validArguments($arguments); foreach ($arguments as $field) { preg_match($this->regexpParseColumn, $field, $matches); @@ -90,11 +91,23 @@ public function parseFields(array $arguments): array } } + if ($isPrimaryKey) { + $primaryKeys[] = $field; + } + if ($isPrimaryKey && $type === 'integer') { $fields[$field]['options']['autoIncrement'] = true; } } + // A composite primary key (e.g. a join table) must not auto-increment. + // Only a single integer primary key column gets auto-increment. + if (count($primaryKeys) > 1) { + foreach ($primaryKeys as $field) { + unset($fields[$field]['options']['autoIncrement']); + } + } + return $fields; } diff --git a/tests/TestCase/Util/ColumnParserTest.php b/tests/TestCase/Util/ColumnParserTest.php index 5fddc479..5e332e32 100644 --- a/tests/TestCase/Util/ColumnParserTest.php +++ b/tests/TestCase/Util/ColumnParserTest.php @@ -227,6 +227,40 @@ public function testParseFields(): void $this->assertEquals($expected, $actual); } + /** + * A composite primary key (e.g. a join table) must not auto-increment its + * integer columns, otherwise MySQL rejects the table with + * "there can be only one auto column". + * + * @return void + */ + public function testParseFieldsCompositePrimaryKey(): void + { + $expected = [ + 'article_id' => [ + 'columnType' => 'integer', + 'options' => [ + 'null' => false, + 'default' => null, + 'limit' => 11, + ], + ], + 'tag_id' => [ + 'columnType' => 'integer', + 'options' => [ + 'null' => false, + 'default' => null, + 'limit' => 11, + ], + ], + ]; + $actual = $this->columnParser->parseFields([ + 'article_id:integer:primary', + 'tag_id:integer:primary', + ]); + $this->assertEquals($expected, $actual); + } + public function testParseIndexes(): void { $this->assertEquals(['UNIQUE_ID' => [