Skip to content

Commit 6428f1a

Browse files
authored
Merge pull request #6668 from morozov/unnamed-unique-constraints
Fix creation of unnamed unique constraints
2 parents 497e0e4 + 343f8a7 commit 6428f1a

File tree

3 files changed

+96
-5
lines changed

3 files changed

+96
-5
lines changed

src/Platforms/AbstractPlatform.php

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -829,7 +829,7 @@ private function buildCreateTableSQL(Table $table, bool $createForeignKeys): arr
829829

830830
foreach ($table->getIndexes() as $index) {
831831
if (! $index->isPrimary()) {
832-
$options['indexes'][$index->getQuotedName($this)] = $index;
832+
$options['indexes'][] = $index;
833833

834834
continue;
835835
}
@@ -839,7 +839,7 @@ private function buildCreateTableSQL(Table $table, bool $createForeignKeys): arr
839839
}
840840

841841
foreach ($table->getUniqueConstraints() as $uniqueConstraint) {
842-
$options['uniqueConstraints'][$uniqueConstraint->getQuotedName($this)] = $uniqueConstraint;
842+
$options['uniqueConstraints'][] = $uniqueConstraint;
843843
}
844844

845845
if ($createForeignKeys) {
@@ -1170,8 +1170,13 @@ public function getCreateSchemaSQL(string $schemaName): string
11701170
*/
11711171
public function getCreateUniqueConstraintSQL(UniqueConstraint $constraint, string $tableName): string
11721172
{
1173-
return 'ALTER TABLE ' . $tableName . ' ADD CONSTRAINT ' . $constraint->getQuotedName($this) . ' UNIQUE'
1174-
. ' (' . implode(', ', $constraint->getQuotedColumns($this)) . ')';
1173+
$sql = 'ALTER TABLE ' . $tableName . ' ADD';
1174+
1175+
if ($constraint->getName() !== '') {
1176+
$sql .= ' CONSTRAINT ' . $constraint->getQuotedName($this);
1177+
}
1178+
1179+
return $sql . ' UNIQUE (' . implode(', ', $constraint->getQuotedColumns($this)) . ')';
11751180
}
11761181

11771182
/**
@@ -1546,9 +1551,10 @@ public function getUniqueConstraintDeclarationSQL(UniqueConstraint $constraint):
15461551
throw new InvalidArgumentException('Incomplete definition. "columns" required.');
15471552
}
15481553

1549-
$chunks = ['CONSTRAINT'];
1554+
$chunks = [];
15501555

15511556
if ($constraint->getName() !== '') {
1557+
$chunks[] = 'CONSTRAINT';
15521558
$chunks[] = $constraint->getQuotedName($this);
15531559
}
15541560

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Doctrine\DBAL\Tests\Functional\Schema;
6+
7+
use Doctrine\DBAL\Schema\Column;
8+
use Doctrine\DBAL\Schema\ForeignKeyConstraint;
9+
use Doctrine\DBAL\Schema\Table;
10+
use Doctrine\DBAL\Tests\FunctionalTestCase;
11+
use Doctrine\DBAL\Types\Type;
12+
use Doctrine\DBAL\Types\Types;
13+
14+
final class ForeignKeyConstraintTest extends FunctionalTestCase
15+
{
16+
public function testUnnamedForeignKeyConstraint(): void
17+
{
18+
$this->dropTableIfExists('users');
19+
$this->dropTableIfExists('roles');
20+
$this->dropTableIfExists('teams');
21+
22+
$roles = new Table('roles');
23+
$roles->addColumn('id', Types::INTEGER);
24+
$roles->setPrimaryKey(['id']);
25+
26+
$teams = new Table('teams');
27+
$teams->addColumn('id', Types::INTEGER);
28+
$teams->setPrimaryKey(['id']);
29+
30+
$users = new Table('users', [
31+
new Column('id', Type::getType(Types::INTEGER)),
32+
new Column('role_id', Type::getType(Types::INTEGER)),
33+
new Column('team_id', Type::getType(Types::INTEGER)),
34+
], [], [], [
35+
new ForeignKeyConstraint(['role_id'], 'roles', ['id']),
36+
new ForeignKeyConstraint(['team_id'], 'teams', ['id']),
37+
]);
38+
$users->setPrimaryKey(['id']);
39+
40+
$sm = $this->connection->createSchemaManager();
41+
$sm->createTable($roles);
42+
$sm->createTable($teams);
43+
$sm->createTable($users);
44+
45+
$table = $sm->introspectTable('users');
46+
47+
self::assertCount(2, $table->getForeignKeys());
48+
}
49+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Doctrine\DBAL\Tests\Functional\Schema;
6+
7+
use Doctrine\DBAL\Schema\Column;
8+
use Doctrine\DBAL\Schema\Table;
9+
use Doctrine\DBAL\Schema\UniqueConstraint;
10+
use Doctrine\DBAL\Tests\FunctionalTestCase;
11+
use Doctrine\DBAL\Types\Type;
12+
use Doctrine\DBAL\Types\Types;
13+
14+
final class UniqueConstraintTest extends FunctionalTestCase
15+
{
16+
public function testUnnamedUniqueConstraint(): void
17+
{
18+
$this->dropTableIfExists('users');
19+
20+
$users = new Table('users', [
21+
new Column('id', Type::getType(Types::INTEGER)),
22+
new Column('username', Type::getType(Types::STRING), ['length' => 32]),
23+
new Column('email', Type::getType(Types::STRING), ['length' => 255]),
24+
], [], [
25+
new UniqueConstraint('', ['username']),
26+
new UniqueConstraint('', ['email']),
27+
], []);
28+
29+
$sm = $this->connection->createSchemaManager();
30+
$sm->createTable($users);
31+
32+
// we want to assert that the two empty names don't clash, but introspection of unique constraints is currently
33+
// not supported. for now, we just assert that the table can be created without exceptions.
34+
$this->expectNotToPerformAssertions();
35+
}
36+
}

0 commit comments

Comments
 (0)