diff --git a/phpcs.xml.dist b/phpcs.xml.dist
index 44dfb1315e4..c96c52b066f 100644
--- a/phpcs.xml.dist
+++ b/phpcs.xml.dist
@@ -102,9 +102,7 @@
- src/Connection.php
- src/Schema/Comparator.php
- src/SQLParserUtils.php
+ src/Schema/Table.php
diff --git a/src/Schema/Exception/PrimaryKeyAlreadyExists.php b/src/Schema/Exception/PrimaryKeyAlreadyExists.php
new file mode 100644
index 00000000000..70fd1f82436
--- /dev/null
+++ b/src/Schema/Exception/PrimaryKeyAlreadyExists.php
@@ -0,0 +1,21 @@
+ keys are new names, values are old names */
protected array $renamedColumns = [];
/** @var Index[] */
protected array $_indexes = [];
+ /**
+ * The keys of this array are the names of the indexes that were implicitly created as backing for foreign key
+ * constraints. The values are not used but must be non-null for {@link isset()} to work correctly.
+ *
+ * @var array
+ */
+ private array $implicitIndexNames = [];
+
protected ?string $_primaryKeyName = null;
/** @var UniqueConstraint[] */
@@ -606,36 +611,41 @@ protected function _addColumn(Column $column): void
/**
* Adds an index to the table.
*/
- protected function _addIndex(Index $indexCandidate): self
+ protected function _addIndex(Index $index): self
{
- $indexName = $indexCandidate->getName();
- $indexName = $this->normalizeIdentifier($indexName);
- $replacedImplicitIndexes = [];
+ $indexName = $this->normalizeIdentifier($index->getName());
- foreach ($this->implicitIndexes as $name => $implicitIndex) {
- if (! $implicitIndex->isFulfilledBy($indexCandidate) || ! isset($this->_indexes[$name])) {
+ $replacedImplicitIndexNames = [];
+
+ foreach ($this->implicitIndexNames as $implicitIndexName => $_) {
+ if (! isset($this->_indexes[$implicitIndexName])) {
+ continue;
+ }
+
+ if (! $this->_indexes[$implicitIndexName]->isFulfilledBy($index)) {
continue;
}
- $replacedImplicitIndexes[] = $name;
+ $replacedImplicitIndexNames[$implicitIndexName] = true;
}
- if (
- (isset($this->_indexes[$indexName]) && ! in_array($indexName, $replacedImplicitIndexes, true)) ||
- ($this->_primaryKeyName !== null && $indexCandidate->isPrimary())
- ) {
+ if (isset($this->_indexes[$indexName]) && ! isset($replacedImplicitIndexNames[$indexName])) {
throw IndexAlreadyExists::new($indexName, $this->_name);
}
- foreach ($replacedImplicitIndexes as $name) {
- unset($this->_indexes[$name], $this->implicitIndexes[$name]);
+ if ($this->_primaryKeyName !== null && $index->isPrimary()) {
+ throw PrimaryKeyAlreadyExists::new($this->_name);
+ }
+
+ foreach ($replacedImplicitIndexNames as $name => $_) {
+ unset($this->_indexes[$name], $this->implicitIndexNames[$name]);
}
- if ($indexCandidate->isPrimary()) {
+ if ($index->isPrimary()) {
$this->_primaryKeyName = $indexName;
}
- $this->_indexes[$indexName] = $indexCandidate;
+ $this->_indexes[$indexName] = $index;
return $this;
}
@@ -671,7 +681,7 @@ protected function _addUniqueConstraint(UniqueConstraint $constraint): self
}
}
- $this->implicitIndexes[$this->normalizeIdentifier($indexName)] = $indexCandidate;
+ $this->implicitIndexNames[$this->normalizeIdentifier($indexName)] = true;
return $this;
}
@@ -709,7 +719,7 @@ protected function _addForeignKeyConstraint(ForeignKeyConstraint $constraint): s
}
$this->_addIndex($indexCandidate);
- $this->implicitIndexes[$this->normalizeIdentifier($indexName)] = $indexCandidate;
+ $this->implicitIndexNames[$this->normalizeIdentifier($indexName)] = true;
return $this;
}