Skip to content

Commit ddbb641

Browse files
committed
Merge branch '4.3.x' into 5.0.x
2 parents 9879c92 + 719f131 commit ddbb641

File tree

5 files changed

+102
-73
lines changed

5 files changed

+102
-73
lines changed

UPGRADE.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,11 @@ all drivers and middleware.
217217

218218
# Upgrade to 4.3
219219

220+
## Deprecated automatic drop of `auto-increment` column attribute
221+
222+
Relying on the auto-increment attribute of a MySQL column being automatically dropped once the column is no longer part
223+
of the primary key constraint is deprecated. Instead, drop the auto-increment attribute explicitly.
224+
220225
## Deprecated handling of modified indexes in `TableDiff`
221226

222227
Passing a non-empty `$modifiedIndexes` value to the `TableDiff` constructor is deprecated. Instead, pass dropped

src/Platforms/AbstractMySQLPlatform.php

Lines changed: 51 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
use Doctrine\DBAL\Connection;
88
use Doctrine\DBAL\Exception\InvalidColumnType\ColumnValuesRequired;
9-
use Doctrine\DBAL\Schema\AbstractAsset;
109
use Doctrine\DBAL\Schema\ForeignKeyConstraint;
1110
use Doctrine\DBAL\Schema\ForeignKeyConstraint\MatchType;
1211
use Doctrine\DBAL\Schema\Index;
@@ -16,10 +15,11 @@
1615
use Doctrine\DBAL\Schema\TableDiff;
1716
use Doctrine\DBAL\TransactionIsolationLevel;
1817
use Doctrine\DBAL\Types\Types;
18+
use Doctrine\Deprecations\Deprecation;
1919

20+
use function array_diff;
2021
use function array_map;
2122
use function array_merge;
22-
use function array_values;
2323
use function count;
2424
use function implode;
2525
use function is_array;
@@ -354,28 +354,51 @@ public function getAlterTableSQL(TableDiff $diff): array
354354
. $this->getColumnDeclarationSQL($newColumnProperties);
355355
}
356356

357-
$addedIndexes = $this->indexAssetsByLowerCaseName($diff->getAddedIndexes());
357+
$droppedIndexes = $this->indexIndexesByLowerCaseName($diff->getDroppedIndexes());
358+
$addedIndexes = $this->indexIndexesByLowerCaseName($diff->getAddedIndexes());
359+
360+
$noLongerPrimaryKeyColumns = [];
361+
362+
if (isset($droppedIndexes['primary'])) {
363+
$queryParts[] = 'DROP PRIMARY KEY';
364+
365+
$noLongerPrimaryKeyColumns = $droppedIndexes['primary']->getColumns();
366+
}
358367

359368
if (isset($addedIndexes['primary'])) {
360369
$keyColumns = $addedIndexes['primary']->getQuotedColumns($this);
361370
$queryParts[] = 'ADD PRIMARY KEY (' . implode(', ', $keyColumns) . ')';
362-
unset($addedIndexes['primary']);
363-
364-
$diff = new TableDiff(
365-
$diff->getOldTable(),
366-
addedColumns: $diff->getAddedColumns(),
367-
changedColumns: $diff->getChangedColumns(),
368-
droppedColumns: $diff->getDroppedColumns(),
369-
addedIndexes: array_values($addedIndexes),
370-
droppedIndexes: $diff->getDroppedIndexes(),
371-
renamedIndexes: $diff->getRenamedIndexes(),
372-
addedForeignKeys: $diff->getAddedForeignKeys(),
373-
droppedForeignKeys: $diff->getDroppedForeignKeys(),
371+
372+
$noLongerPrimaryKeyColumns = array_diff(
373+
$noLongerPrimaryKeyColumns,
374+
$addedIndexes['primary']->getColumns(),
374375
);
376+
377+
$diff->unsetAddedIndex($addedIndexes['primary']);
375378
}
376379

377380
$tableSql = [];
378381

382+
if (isset($droppedIndexes['primary'])) {
383+
$oldTable = $diff->getOldTable();
384+
foreach ($noLongerPrimaryKeyColumns as $columnName) {
385+
if (! $oldTable->hasColumn($columnName)) {
386+
continue;
387+
}
388+
389+
$column = $oldTable->getColumn($columnName);
390+
if ($column->getAutoincrement()) {
391+
$tableSql = array_merge(
392+
$tableSql,
393+
$this->getPreAlterTableAlterPrimaryKeySQL($diff, $droppedIndexes['primary']),
394+
);
395+
break;
396+
}
397+
}
398+
399+
$diff->unsetDroppedIndex($droppedIndexes['primary']);
400+
}
401+
379402
if (count($queryParts) > 0) {
380403
$tableSql[] = 'ALTER TABLE ' . $diff->getOldTable()->getObjectName()->toSQL($this) . ' '
381404
. implode(', ', $queryParts);
@@ -458,6 +481,14 @@ private function getPreAlterTableAlterPrimaryKeySQL(TableDiff $diff, Index $inde
458481
continue;
459482
}
460483

484+
Deprecation::trigger(
485+
'doctrine/dbal',
486+
'https://github.com/doctrine/dbal/pull/6841',
487+
'Relying on the auto-increment attribute of a column being automatically dropped once a column'
488+
. ' is no longer part of the primary key constraint is deprecated. Instead, drop the auto-increment'
489+
. ' attribute explicitly.',
490+
);
491+
461492
$column->setAutoincrement(false);
462493

463494
$sql[] = 'ALTER TABLE ' . $tableNameSQL . ' MODIFY ' .
@@ -723,18 +754,16 @@ public function createSchemaManager(Connection $connection): MySQLSchemaManager
723754
}
724755

725756
/**
726-
* @param array<T> $assets
727-
*
728-
* @return array<string,T>
757+
* @param array<Index> $indexes
729758
*
730-
* @template T of AbstractAsset
759+
* @return array<string,Index>
731760
*/
732-
private function indexAssetsByLowerCaseName(array $assets): array
761+
private function indexIndexesByLowerCaseName(array $indexes): array
733762
{
734763
$result = [];
735764

736-
foreach ($assets as $asset) {
737-
$result[strtolower($asset->getName())] = $asset;
765+
foreach ($indexes as $index) {
766+
$result[strtolower($index->getName())] = $index;
738767
}
739768

740769
return $result;

src/Platforms/SQLitePlatform.php

Lines changed: 39 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -474,7 +474,7 @@ protected function getPostAlterTableIndexForeignKeySQL(TableDiff $diff): array
474474

475475
$sql = [];
476476

477-
foreach ($this->getIndexesInAlteredTable($diff, $table) as $index) {
477+
foreach ($this->getIndexesInAlteredTable($diff) as $index) {
478478
if ($index->isPrimary()) {
479479
continue;
480480
}
@@ -647,9 +647,9 @@ public function getAlterTableSQL(TableDiff $diff): array
647647
$newTable = new Table(
648648
$table->getObjectName()->toSQL($this),
649649
$columns,
650-
$this->getPrimaryIndexInAlteredTable($diff, $table),
650+
$this->getPrimaryIndexInAlteredTable($diff),
651651
[],
652-
$this->getForeignKeysInAlteredTable($diff, $table),
652+
$this->getForeignKeysInAlteredTable($diff),
653653
$table->getOptions(),
654654
);
655655

@@ -743,45 +743,46 @@ private function getSimpleAlterTableSQL(TableDiff $diff): array|false
743743
return $sql;
744744
}
745745

746-
/** @return string[] */
747-
private function getColumnNamesInAlteredTable(TableDiff $diff, Table $oldTable): array
746+
/**
747+
* Based on the table diff, returns a map where the keys are the lower-case old column names and the values are the
748+
* new column names. If the column was dropped, it is not present in the map.
749+
*
750+
* @return array<string, string>
751+
*/
752+
private function getDiffColumnNameMap(TableDiff $diff): array
748753
{
749-
$columns = [];
754+
$oldTable = $diff->getOldTable();
755+
756+
$map = [];
750757

751758
foreach ($oldTable->getColumns() as $column) {
752-
$columnName = $column->getName();
753-
$columns[strtolower($columnName)] = $columnName;
759+
$columnName = $column->getName();
760+
$map[strtolower($columnName)] = $columnName;
754761
}
755762

756763
foreach ($diff->getDroppedColumns() as $column) {
757-
$columnName = strtolower($column->getName());
758-
if (! isset($columns[$columnName])) {
759-
continue;
760-
}
761-
762-
unset($columns[$columnName]);
764+
unset($map[strtolower($column->getName())]);
763765
}
764766

765767
foreach ($diff->getChangedColumns() as $columnDiff) {
766-
$oldColumnName = $columnDiff->getOldColumn()->getName();
767-
$newColumnName = $columnDiff->getNewColumn()->getName();
768-
$columns[strtolower($oldColumnName)] = $newColumnName;
769-
$columns[strtolower($newColumnName)] = $newColumnName;
768+
$columnName = $columnDiff->getOldColumn()->getName();
769+
$map[strtolower($columnName)] = $columnDiff->getNewColumn()->getName();
770770
}
771771

772772
foreach ($diff->getAddedColumns() as $column) {
773-
$columnName = $column->getName();
774-
$columns[strtolower($columnName)] = $columnName;
773+
$columnName = $column->getName();
774+
$map[strtolower($columnName)] = $columnName;
775775
}
776776

777-
return $columns;
777+
return $map;
778778
}
779779

780-
/** @return Index[] */
781-
private function getIndexesInAlteredTable(TableDiff $diff, Table $oldTable): array
780+
/** @return array<Index> */
781+
private function getIndexesInAlteredTable(TableDiff $diff): array
782782
{
783-
$indexes = $oldTable->getIndexes();
784-
$columnNames = $this->getColumnNamesInAlteredTable($diff, $oldTable);
783+
$oldTable = $diff->getOldTable();
784+
$indexes = $oldTable->getIndexes();
785+
$nameMap = $this->getDiffColumnNameMap($diff);
785786

786787
foreach ($indexes as $key => $index) {
787788
foreach ($diff->getRenamedIndexes() as $oldIndexName => $renamedIndex) {
@@ -796,13 +797,13 @@ private function getIndexesInAlteredTable(TableDiff $diff, Table $oldTable): arr
796797
$indexColumns = [];
797798
foreach ($index->getColumns() as $columnName) {
798799
$normalizedColumnName = strtolower($columnName);
799-
if (! isset($columnNames[$normalizedColumnName])) {
800+
if (! isset($nameMap[$normalizedColumnName])) {
800801
unset($indexes[$key]);
801802
continue 2;
802803
}
803804

804-
$indexColumns[] = $columnNames[$normalizedColumnName];
805-
if ($columnName === $columnNames[$normalizedColumnName]) {
805+
$indexColumns[] = $nameMap[$normalizedColumnName];
806+
if ($columnName === $nameMap[$normalizedColumnName]) {
806807
continue;
807808
}
808809

@@ -850,11 +851,12 @@ private function getIndexesInAlteredTable(TableDiff $diff, Table $oldTable): arr
850851
return $indexes;
851852
}
852853

853-
/** @return ForeignKeyConstraint[] */
854-
private function getForeignKeysInAlteredTable(TableDiff $diff, Table $oldTable): array
854+
/** @return array<ForeignKeyConstraint> */
855+
private function getForeignKeysInAlteredTable(TableDiff $diff): array
855856
{
857+
$oldTable = $diff->getOldTable();
856858
$foreignKeys = $oldTable->getForeignKeys();
857-
$columnNames = $this->getColumnNamesInAlteredTable($diff, $oldTable);
859+
$nameMap = $this->getDiffColumnNameMap($diff);
858860

859861
foreach ($foreignKeys as $key => $constraint) {
860862
$changed = false;
@@ -863,14 +865,14 @@ private function getForeignKeysInAlteredTable(TableDiff $diff, Table $oldTable):
863865
foreach ($constraint->getReferencingColumnNames() as $columnName) {
864866
$originalColumnName = $columnName->getIdentifier()->getValue();
865867
$normalizedColumnName = strtolower($originalColumnName);
866-
if (! isset($columnNames[$normalizedColumnName])) {
868+
if (! isset($nameMap[$normalizedColumnName])) {
867869
unset($foreignKeys[$key]);
868870
continue 2;
869871
}
870872

871-
$referencingColumnNames[] = UnqualifiedName::unquoted($columnNames[$normalizedColumnName]);
873+
$referencingColumnNames[] = UnqualifiedName::unquoted($nameMap[$normalizedColumnName]);
872874

873-
if ($originalColumnName === $columnNames[$normalizedColumnName]) {
875+
if ($originalColumnName === $nameMap[$normalizedColumnName]) {
874876
continue;
875877
}
876878

@@ -909,12 +911,12 @@ private function getForeignKeysInAlteredTable(TableDiff $diff, Table $oldTable):
909911
return $foreignKeys;
910912
}
911913

912-
/** @return Index[] */
913-
private function getPrimaryIndexInAlteredTable(TableDiff $diff, Table $oldTable): array
914+
/** @return array<string, Index> */
915+
private function getPrimaryIndexInAlteredTable(TableDiff $diff): array
914916
{
915917
$primaryIndex = [];
916918

917-
foreach ($this->getIndexesInAlteredTable($diff, $oldTable) as $index) {
919+
foreach ($this->getIndexesInAlteredTable($diff) as $index) {
918920
if (! $index->isPrimary()) {
919921
continue;
920922
}

tests/Functional/Schema/AlterTableTest.php

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -111,13 +111,6 @@ public function testDropPrimaryKeyWithAutoincrementColumn(): void
111111

112112
public function testDropNonAutoincrementColumnFromCompositePrimaryKeyWithAutoincrementColumn(): void
113113
{
114-
if ($this->connection->getDatabasePlatform() instanceof AbstractMySQLPlatform) {
115-
self::markTestIncomplete(
116-
'DBAL does not restore the auto-increment attribute after dropping and adding the constraint,'
117-
. ' which is a bug.',
118-
);
119-
}
120-
121114
$this->ensureDroppingPrimaryKeyConstraintIsSupported();
122115

123116
$table = new Table('alter_pk');
@@ -135,13 +128,6 @@ public function testAddNonAutoincrementColumnToPrimaryKeyWithAutoincrementColumn
135128
{
136129
$platform = $this->connection->getDatabasePlatform();
137130

138-
if ($platform instanceof AbstractMySQLPlatform) {
139-
self::markTestIncomplete(
140-
'DBAL does not restore the auto-increment attribute after dropping and adding the constraint,'
141-
. ' which is a bug.',
142-
);
143-
}
144-
145131
if ($platform instanceof SQLitePlatform) {
146132
self::markTestSkipped(
147133
'SQLite does not support auto-increment columns as part of composite primary key constraint',
@@ -244,6 +230,8 @@ private function testMigration(Table $oldTable, callable $migration): void
244230
$diff = $schemaManager->createComparator()
245231
->compareTables($oldTable, $newTable);
246232

233+
self::assertFalse($diff->isEmpty());
234+
247235
$schemaManager->alterTable($diff);
248236

249237
$introspectedTable = $schemaManager->introspectTable($newTable->getName());

tests/Functional/Schema/MySQLSchemaManagerTest.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,14 @@
2020
use Doctrine\DBAL\Types\SmallFloatType;
2121
use Doctrine\DBAL\Types\Type;
2222
use Doctrine\DBAL\Types\Types;
23+
use Doctrine\Deprecations\PHPUnit\VerifyDeprecations;
2324

2425
use function array_keys;
2526

2627
class MySQLSchemaManagerTest extends SchemaManagerFunctionalTestCase
2728
{
29+
use VerifyDeprecations;
30+
2831
public static function setUpBeforeClass(): void
2932
{
3033
Type::addType('point', PointType::class);
@@ -150,6 +153,8 @@ public function testDropPrimaryKeyWithAutoincrementColumn(): void
150153
$diff = $this->schemaManager->createComparator()
151154
->compareTables($table, $diffTable);
152155

156+
$this->expectDeprecationWithIdentifier('https://github.com/doctrine/dbal/pull/6841');
157+
153158
$this->schemaManager->alterTable($diff);
154159

155160
$table = $this->schemaManager->introspectTable('drop_primary_key');

0 commit comments

Comments
 (0)