Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add explicit renameColumn method for Table #6080

Merged
merged 1 commit into from
Jan 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions psalm.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,13 @@
<!-- TODO for PHPUnit 10 -->
<referencedMethod name="PHPUnit\Framework\MockObject\Builder\InvocationMocker::withConsecutive"/>

<!--
TODO: remove in 4.0.0
See https://github.com/doctrine/dbal/pull/6080
-->
<referencedMethod name="Doctrine\DBAL\Schema\TableDiff::getModifiedColumns"/>
<referencedMethod name="Doctrine\DBAL\Schema\TableDiff::getRenamedColumns"/>

<!-- TODO: remove in 4.0.0 -->
<referencedMethod name="Doctrine\DBAL\Platforms\DB2Platform::getForUpdateSQL"/>
</errorLevel>
Expand Down
34 changes: 11 additions & 23 deletions src/Platforms/AbstractMySQLPlatform.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
use Doctrine\DBAL\Exception;
use Doctrine\DBAL\Schema\AbstractAsset;
use Doctrine\DBAL\Schema\ForeignKeyConstraint;
use Doctrine\DBAL\Schema\Identifier;
use Doctrine\DBAL\Schema\Index;
use Doctrine\DBAL\Schema\MySQLSchemaManager;
use Doctrine\DBAL\Schema\Table;
Expand Down Expand Up @@ -684,36 +683,26 @@ public function getAlterTableSQL(TableDiff $diff)
$queryParts[] = 'DROP ' . $column->getQuotedName($this);
}

foreach ($diff->getModifiedColumns() as $columnDiff) {
if ($this->onSchemaAlterTableChangeColumn($columnDiff, $diff, $columnSql)) {
continue;
}

foreach ($diff->getChangedColumns() as $columnDiff) {
$newColumn = $columnDiff->getNewColumn();

$newColumnProperties = array_merge($newColumn->toArray(), [
'comment' => $this->getColumnComment($newColumn),
]);

$oldColumn = $columnDiff->getOldColumn() ?? $columnDiff->getOldColumnName();

$queryParts[] = 'CHANGE ' . $oldColumn->getQuotedName($this) . ' '
. $this->getColumnDeclarationSQL($newColumn->getQuotedName($this), $newColumnProperties);
}
$oldColumn = $columnDiff->getOldColumn() ?? $columnDiff->getOldColumnName();
$oldColumnName = $oldColumn->getName();

foreach ($diff->getRenamedColumns() as $oldColumnName => $column) {
if ($this->onSchemaAlterTableRenameColumn($oldColumnName, $column, $diff, $columnSql)) {
if ($columnDiff->hasNameChanged()) {
if ($this->onSchemaAlterTableRenameColumn($oldColumnName, $newColumn, $diff, $columnSql)) {
continue;
}
} elseif ($this->onSchemaAlterTableChangeColumn($columnDiff, $diff, $columnSql)) {
continue;
}

$oldColumnName = new Identifier($oldColumnName);

$columnProperties = array_merge($column->toArray(), [
'comment' => $this->getColumnComment($column),
]);

$queryParts[] = 'CHANGE ' . $oldColumnName->getQuotedName($this) . ' '
. $this->getColumnDeclarationSQL($column->getQuotedName($this), $columnProperties);
$queryParts[] = 'CHANGE ' . $oldColumn->getQuotedName($this) . ' '
. $this->getColumnDeclarationSQL($newColumn->getQuotedName($this), $newColumnProperties);
}

$addedIndexes = $this->indexAssetsByLowerCaseName($diff->getAddedIndexes());
Expand Down Expand Up @@ -745,7 +734,7 @@ public function getAlterTableSQL(TableDiff $diff)
$diff = new TableDiff(
$diff->name,
$diff->getAddedColumns(),
$diff->getModifiedColumns(),
$diff->getChangedColumns(),
$diff->getDroppedColumns(),
array_values($addedIndexes),
array_values($modifiedIndexes),
Expand All @@ -754,7 +743,6 @@ public function getAlterTableSQL(TableDiff $diff)
$diff->getAddedForeignKeys(),
$diff->getModifiedForeignKeys(),
$diff->getDroppedForeignKeys(),
$diff->getRenamedColumns(),
$diff->getRenamedIndexes(),
);
}
Expand Down
14 changes: 14 additions & 0 deletions src/Platforms/AbstractPlatform.php
Original file line number Diff line number Diff line change
Expand Up @@ -2940,6 +2940,20 @@ protected function getRenameIndexSQL($oldIndexName, Index $index, $tableName)
];
}

/**
* Returns the SQL for renaming a column
*
* @param string $tableName The table to rename the column on.
* @param string $oldColumnName The name of the column we want to rename.
* @param string $newColumnName The name we should rename it to.
*
* @return string[] The sequence of SQL statements for renaming the given column.
*/
protected function getRenameColumnSQL(string $tableName, string $oldColumnName, string $newColumnName): array
{
return [sprintf('ALTER TABLE %s RENAME COLUMN %s TO %s', $tableName, $oldColumnName, $newColumnName)];
}

/**
* Gets declaration of a number of columns in bulk.
*
Expand Down
35 changes: 24 additions & 11 deletions src/Platforms/DB2Platform.php
Original file line number Diff line number Diff line change
Expand Up @@ -623,16 +623,27 @@ public function getAlterTableSQL(TableDiff $diff)
);
}

$needsReorg = false;
foreach ($diff->getDroppedColumns() as $column) {
if ($this->onSchemaAlterTableRemoveColumn($column, $diff, $columnSql)) {
continue;
}

$queryParts[] = 'DROP COLUMN ' . $column->getQuotedName($this);
$needsReorg = true;
}

foreach ($diff->getModifiedColumns() as $columnDiff) {
if ($this->onSchemaAlterTableChangeColumn($columnDiff, $diff, $columnSql)) {
foreach ($diff->getChangedColumns() as $columnDiff) {
$newColumn = $columnDiff->getNewColumn();
$oldColumn = $columnDiff->getOldColumn() ?? $columnDiff->getOldColumnName();

$oldColumnName = $oldColumn->getQuotedName($this);

if ($columnDiff->hasNameChanged()) {
if ($this->onSchemaAlterTableRenameColumn($oldColumnName, $newColumn, $diff, $columnSql)) {
continue;
}
} elseif ($this->onSchemaAlterTableChangeColumn($columnDiff, $diff, $columnSql)) {
continue;
}

Expand All @@ -650,17 +661,12 @@ public function getAlterTableSQL(TableDiff $diff)
$sql,
$queryParts,
);
}

foreach ($diff->getRenamedColumns() as $oldColumnName => $column) {
if ($this->onSchemaAlterTableRenameColumn($oldColumnName, $column, $diff, $columnSql)) {
if (empty($columnDiff->changedProperties)) {
continue;
}

$oldColumnName = new Identifier($oldColumnName);

$queryParts[] = 'RENAME COLUMN ' . $oldColumnName->getQuotedName($this) .
' TO ' . $column->getQuotedName($this);
$needsReorg = true;
}

$tableSql = [];
Expand All @@ -671,7 +677,7 @@ public function getAlterTableSQL(TableDiff $diff)
}

// Some table alteration operations require a table reorganization.
if (count($diff->getDroppedColumns()) > 0 || count($diff->getModifiedColumns()) > 0) {
if ($needsReorg) {
$sql[] = "CALL SYSPROC.ADMIN_CMD ('REORG TABLE " . $tableNameSQL . "')";
}

Expand Down Expand Up @@ -758,14 +764,21 @@ private function getAlterColumnClausesSQL(ColumnDiff $columnDiff): array
{
$newColumn = $columnDiff->getNewColumn()->toArray();

$alterClause = 'ALTER COLUMN ' . $columnDiff->getNewColumn()->getQuotedName($this);
$newName = $columnDiff->getNewColumn()->getQuotedName($this);
$oldName = ($columnDiff->getOldColumn() ?? $columnDiff->getOldColumnName())->getQuotedName($this);

$alterClause = 'ALTER COLUMN ' . $newName;

if ($newColumn['columnDefinition'] !== null) {
return [$alterClause . ' ' . $newColumn['columnDefinition']];
}

$clauses = [];

if ($columnDiff->hasNameChanged()) {
$clauses[] = 'RENAME COLUMN ' . $oldName . ' TO ' . $newName;
}

if (
$columnDiff->hasTypeChanged() ||
$columnDiff->hasLengthChanged() ||
Expand Down
35 changes: 19 additions & 16 deletions src/Platforms/OraclePlatform.php
Original file line number Diff line number Diff line change
Expand Up @@ -897,13 +897,27 @@ public function getAlterTableSQL(TableDiff $diff)
}

$fields = [];
foreach ($diff->getModifiedColumns() as $columnDiff) {
if ($this->onSchemaAlterTableChangeColumn($columnDiff, $diff, $columnSql)) {
foreach ($diff->getChangedColumns() as $columnDiff) {
$newColumn = $columnDiff->getNewColumn();
$newColumnName = $newColumn->getQuotedName($this);
$oldColumn = $columnDiff->getOldColumn() ?? $columnDiff->getOldColumnName();

$oldColumnName = $oldColumn->getQuotedName($this);

// Column names in Oracle are case insensitive and automatically uppercased on the server.
if ($columnDiff->hasNameChanged()) {
if ($this->onSchemaAlterTableRenameColumn($oldColumnName, $newColumn, $diff, $columnSql)) {
continue;
}

$sql = array_merge(
$sql,
$this->getRenameColumnSQL($tableNameSQL, $oldColumnName, $newColumnName),
);
} elseif ($this->onSchemaAlterTableChangeColumn($columnDiff, $diff, $columnSql)) {
continue;
}

$newColumn = $columnDiff->getNewColumn();

// Do not generate column alteration clause if type is binary and only fixed property has changed.
// Oracle only supports binary type columns with variable length.
// Avoids unnecessary table alteration statements.
Expand All @@ -920,7 +934,7 @@ public function getAlterTableSQL(TableDiff $diff)
/**
* Do not add query part if only comment has changed
*/
if (! ($columnHasChangedComment && count($columnDiff->changedProperties) === 1)) {
if (count($columnDiff->changedProperties) > ($columnHasChangedComment ? 1 : 0)) {
$newColumnProperties = $newColumn->toArray();

if (! $columnDiff->hasNotNullChanged()) {
Expand All @@ -945,17 +959,6 @@ public function getAlterTableSQL(TableDiff $diff)
$sql[] = 'ALTER TABLE ' . $tableNameSQL . ' MODIFY (' . implode(', ', $fields) . ')';
}

foreach ($diff->getRenamedColumns() as $oldColumnName => $column) {
if ($this->onSchemaAlterTableRenameColumn($oldColumnName, $column, $diff, $columnSql)) {
continue;
}

$oldColumnName = new Identifier($oldColumnName);

$sql[] = 'ALTER TABLE ' . $tableNameSQL . ' RENAME COLUMN ' . $oldColumnName->getQuotedName($this)
. ' TO ' . $column->getQuotedName($this);
}

$fields = [];
foreach ($diff->getDroppedColumns() as $column) {
if ($this->onSchemaAlterTableRemoveColumn($column, $diff, $columnSql)) {
Expand Down
45 changes: 22 additions & 23 deletions src/Platforms/PostgreSQLPlatform.php
Original file line number Diff line number Diff line change
Expand Up @@ -569,11 +569,7 @@ public function getAlterTableSQL(TableDiff $diff)
$sql[] = 'ALTER TABLE ' . $tableNameSQL . ' ' . $query;
}

foreach ($diff->getModifiedColumns() as $columnDiff) {
if ($this->onSchemaAlterTableChangeColumn($columnDiff, $diff, $columnSql)) {
continue;
}

foreach ($diff->getChangedColumns() as $columnDiff) {
if ($this->isUnchangedBinaryColumn($columnDiff)) {
continue;
}
Expand All @@ -582,6 +578,20 @@ public function getAlterTableSQL(TableDiff $diff)
$newColumn = $columnDiff->getNewColumn();

$oldColumnName = $oldColumn->getQuotedName($this);
$newColumnName = $newColumn->getQuotedName($this);

if ($columnDiff->hasNameChanged()) {
if ($this->onSchemaAlterTableRenameColumn($oldColumnName, $newColumn, $diff, $columnSql)) {
continue;
}

$sql = array_merge(
$sql,
$this->getRenameColumnSQL($tableNameSQL, $oldColumnName, $newColumnName),
);
} elseif ($this->onSchemaAlterTableChangeColumn($columnDiff, $diff, $columnSql)) {
continue;
}

if (
$columnDiff->hasTypeChanged()
Expand All @@ -596,7 +606,7 @@ public function getAlterTableSQL(TableDiff $diff)
$columnDefinition['autoincrement'] = false;

// here was a server version check before, but DBAL API does not support this anymore.
$query = 'ALTER ' . $oldColumnName . ' TYPE ' . $type->getSQLDeclaration($columnDefinition, $this);
$query = 'ALTER ' . $newColumnName . ' TYPE ' . $type->getSQLDeclaration($columnDefinition, $this);
$sql[] = 'ALTER TABLE ' . $tableNameSQL . ' ' . $query;
}

Expand All @@ -605,12 +615,12 @@ public function getAlterTableSQL(TableDiff $diff)
? ' DROP DEFAULT'
: ' SET' . $this->getDefaultValueDeclarationSQL($newColumn->toArray());

$query = 'ALTER ' . $oldColumnName . $defaultClause;
$query = 'ALTER ' . $newColumnName . $defaultClause;
$sql[] = 'ALTER TABLE ' . $tableNameSQL . ' ' . $query;
}

if ($columnDiff->hasNotNullChanged()) {
$query = 'ALTER ' . $oldColumnName . ' ' . ($newColumn->getNotnull() ? 'SET' : 'DROP') . ' NOT NULL';
$query = 'ALTER ' . $newColumnName . ' ' . ($newColumn->getNotnull() ? 'SET' : 'DROP') . ' NOT NULL';
$sql[] = 'ALTER TABLE ' . $tableNameSQL . ' ' . $query;
}

Expand All @@ -619,16 +629,16 @@ public function getAlterTableSQL(TableDiff $diff)
// add autoincrement
$seqName = $this->getIdentitySequenceName(
$table->getName(),
$oldColumnName,
$newColumnName,
);

$sql[] = 'CREATE SEQUENCE ' . $seqName;
$sql[] = "SELECT setval('" . $seqName . "', (SELECT MAX(" . $oldColumnName . ') FROM '
$sql[] = "SELECT setval('" . $seqName . "', (SELECT MAX(" . $newColumnName . ') FROM '
. $tableNameSQL . '))';
$query = 'ALTER ' . $oldColumnName . " SET DEFAULT nextval('" . $seqName . "')";
$query = 'ALTER ' . $newColumnName . " SET DEFAULT nextval('" . $seqName . "')";
} else {
// Drop autoincrement, but do NOT drop the sequence. It might be re-used by other tables or have
$query = 'ALTER ' . $oldColumnName . ' DROP DEFAULT';
$query = 'ALTER ' . $newColumnName . ' DROP DEFAULT';
}

$sql[] = 'ALTER TABLE ' . $tableNameSQL . ' ' . $query;
Expand Down Expand Up @@ -657,17 +667,6 @@ public function getAlterTableSQL(TableDiff $diff)
$sql[] = 'ALTER TABLE ' . $tableNameSQL . ' ' . $query;
}

foreach ($diff->getRenamedColumns() as $oldColumnName => $column) {
if ($this->onSchemaAlterTableRenameColumn($oldColumnName, $column, $diff, $columnSql)) {
continue;
}

$oldColumnName = new Identifier($oldColumnName);

$sql[] = 'ALTER TABLE ' . $tableNameSQL . ' RENAME COLUMN ' . $oldColumnName->getQuotedName($this)
. ' TO ' . $column->getQuotedName($this);
}

$tableSql = [];

if (! $this->onSchemaAlterTable($diff, $tableSql)) {
Expand Down
Loading