Skip to content

Commit 1eaa36c

Browse files
authored
Merge pull request #6757 from doctrine/3.9.x
Merge 3.9.x up into 3.10.x
2 parents 818eae9 + a1932ce commit 1eaa36c

File tree

6 files changed

+178
-174
lines changed

6 files changed

+178
-174
lines changed

src/Platforms/SQLServerPlatform.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
use function preg_match;
3939
use function preg_match_all;
4040
use function sprintf;
41+
use function str_contains;
4142
use function str_ends_with;
4243
use function str_replace;
4344
use function str_starts_with;
@@ -1777,11 +1778,17 @@ private function generateIdentifierName($identifier): string
17771778

17781779
protected function getCommentOnTableSQL(string $tableName, ?string $comment): string
17791780
{
1781+
if (str_contains($tableName, '.')) {
1782+
[$schemaName, $tableName] = explode('.', $tableName);
1783+
} else {
1784+
$schemaName = 'dbo';
1785+
}
1786+
17801787
return $this->getAddExtendedPropertySQL(
17811788
'MS_Description',
17821789
$comment,
17831790
'SCHEMA',
1784-
$this->quoteStringLiteral('dbo'),
1791+
$this->quoteStringLiteral($schemaName),
17851792
'TABLE',
17861793
$this->quoteStringLiteral($this->unquoteSingleIdentifier($tableName)),
17871794
);

src/Schema/PostgreSQLSchemaManager.php

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -294,9 +294,16 @@ protected function _getPortableTableIndexesList($tableIndexes, $tableName = null
294294
foreach ($tableIndexes as $row) {
295295
$colNumbers = array_map('intval', explode(' ', $row['indkey']));
296296
$columnNameSql = sprintf(
297-
'SELECT attnum, attname FROM pg_attribute WHERE attrelid=%d AND attnum IN (%s) ORDER BY attnum ASC',
297+
<<<'SQL'
298+
SELECT attnum,
299+
quote_ident(attname) AS attname
300+
FROM pg_attribute
301+
WHERE attrelid = %d
302+
AND attnum IN (%s)
303+
ORDER BY attnum
304+
SQL,
298305
$row['indrelid'],
299-
implode(' ,', $colNumbers),
306+
implode(', ', $colNumbers),
300307
);
301308

302309
$indexColumns = $this->_conn->fetchAllAssociative($columnNameSql);
@@ -612,7 +619,7 @@ protected function selectTableColumns(string $databaseName, ?string $tableName =
612619
$sql = 'SELECT';
613620

614621
if ($tableName === null) {
615-
$sql .= ' c.relname AS table_name, n.nspname AS schema_name,';
622+
$sql .= ' quote_ident(c.relname) AS table_name, quote_ident(n.nspname) AS schema_name,';
616623
}
617624

618625
$sql .= sprintf(<<<'SQL'
@@ -664,7 +671,7 @@ protected function selectIndexColumns(string $databaseName, ?string $tableName =
664671
$sql = 'SELECT';
665672

666673
if ($tableName === null) {
667-
$sql .= ' tc.relname AS table_name, tn.nspname AS schema_name,';
674+
$sql .= ' quote_ident(tc.relname) AS table_name, quote_ident(tn.nspname) AS schema_name,';
668675
}
669676

670677
$sql .= <<<'SQL'
@@ -698,7 +705,7 @@ protected function selectForeignKeyColumns(string $databaseName, ?string $tableN
698705
$sql = 'SELECT';
699706

700707
if ($tableName === null) {
701-
$sql .= ' tc.relname AS table_name, tn.nspname AS schema_name,';
708+
$sql .= ' quote_ident(tc.relname) AS table_name, quote_ident(tn.nspname) AS schema_name,';
702709
}
703710

704711
$sql .= <<<'SQL'
@@ -726,7 +733,8 @@ protected function selectForeignKeyColumns(string $databaseName, ?string $tableN
726733
protected function fetchTableOptionsByTable(string $databaseName, ?string $tableName = null): array
727734
{
728735
$sql = <<<'SQL'
729-
SELECT c.relname,
736+
SELECT n.nspname AS schema_name,
737+
c.relname AS table_name,
730738
CASE c.relpersistence WHEN 'u' THEN true ELSE false END as unlogged,
731739
obj_description(c.oid, 'pg_class') AS comment
732740
FROM pg_class c
@@ -738,7 +746,12 @@ protected function fetchTableOptionsByTable(string $databaseName, ?string $table
738746

739747
$sql .= ' WHERE ' . implode(' AND ', $conditions);
740748

741-
return $this->_conn->fetchAllAssociativeIndexed($sql);
749+
$tableOptions = [];
750+
foreach ($this->_conn->iterateAssociative($sql) as $row) {
751+
$tableOptions[$this->_getPortableTableDefinition($row)] = $row;
752+
}
753+
754+
return $tableOptions;
742755
}
743756

744757
/**

src/Schema/SQLServerSchemaManager.php

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -227,9 +227,15 @@ protected function _getPortableTableForeignKeysList($tableForeignKeys)
227227
$name = $tableForeignKey['ForeignKey'];
228228

229229
if (! isset($foreignKeys[$name])) {
230+
$referencedTableName = $tableForeignKey['ReferenceTableName'];
231+
232+
if ($tableForeignKey['ReferenceSchemaName'] !== 'dbo') {
233+
$referencedTableName = $tableForeignKey['ReferenceSchemaName'] . '.' . $referencedTableName;
234+
}
235+
230236
$foreignKeys[$name] = [
231237
'local_columns' => [$tableForeignKey['ColumnName']],
232-
'foreign_table' => $tableForeignKey['ReferenceTableName'],
238+
'foreign_table' => $referencedTableName,
233239
'foreign_columns' => [$tableForeignKey['ReferenceColumnName']],
234240
'name' => $name,
235241
'options' => [
@@ -556,31 +562,29 @@ protected function fetchTableOptionsByTable(string $databaseName, ?string $table
556562
{
557563
$sql = <<<'SQL'
558564
SELECT
559-
tbl.name,
565+
scm.name AS schema_name,
566+
tbl.name AS table_name,
560567
p.value AS [table_comment]
561568
FROM
562569
sys.tables AS tbl
570+
JOIN sys.schemas AS scm
571+
ON tbl.schema_id = scm.schema_id
563572
INNER JOIN sys.extended_properties AS p ON p.major_id=tbl.object_id AND p.minor_id=0 AND p.class=1
564573
SQL;
565574

566-
$conditions = ["SCHEMA_NAME(tbl.schema_id) = N'dbo'", "p.name = N'MS_Description'"];
567-
$params = [];
575+
$conditions = ["p.name = N'MS_Description'"];
568576

569577
if ($tableName !== null) {
570-
$conditions[] = "tbl.name = N'" . $tableName . "'";
578+
$conditions[] = $this->getTableWhereClause($tableName, 'scm.name', 'tbl.name');
571579
}
572580

573581
$sql .= ' WHERE ' . implode(' AND ', $conditions);
574582

575-
/** @var array<string,array<string,mixed>> $metadata */
576-
$metadata = $this->_conn->executeQuery($sql, $params)
577-
->fetchAllAssociativeIndexed();
578-
579583
$tableOptions = [];
580-
foreach ($metadata as $table => $data) {
584+
foreach ($this->_conn->iterateAssociative($sql) as $data) {
581585
$data = array_change_key_case($data, CASE_LOWER);
582586

583-
$tableOptions[$table] = [
587+
$tableOptions[$this->_getPortableTableDefinition($data)] = [
584588
'comment' => $data['table_comment'],
585589
];
586590
}

tests/Functional/Schema/OracleSchemaManagerTest.php

Lines changed: 0 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -71,122 +71,6 @@ public function testAlterTableColumnNotNull(callable $comparatorFactory): void
7171
self::assertTrue($columns['bar']->getNotnull());
7272
}
7373

74-
public function testListTableDetailsWithDifferentIdentifierQuotingRequirements(): void
75-
{
76-
$primaryTableName = '"Primary_Table"';
77-
$offlinePrimaryTable = new Table($primaryTableName);
78-
$offlinePrimaryTable->addColumn(
79-
'"Id"',
80-
Types::INTEGER,
81-
['autoincrement' => true, 'comment' => 'Explicit casing.'],
82-
);
83-
$offlinePrimaryTable->addColumn('select', Types::INTEGER, ['comment' => 'Reserved keyword.']);
84-
$offlinePrimaryTable->addColumn('foo', Types::INTEGER, ['comment' => 'Implicit uppercasing.']);
85-
$offlinePrimaryTable->addColumn('BAR', Types::INTEGER);
86-
$offlinePrimaryTable->addColumn('"BAZ"', Types::INTEGER);
87-
$offlinePrimaryTable->addIndex(['select'], 'from');
88-
$offlinePrimaryTable->addIndex(['foo'], 'foo_index');
89-
$offlinePrimaryTable->addIndex(['BAR'], 'BAR_INDEX');
90-
$offlinePrimaryTable->addIndex(['"BAZ"'], 'BAZ_INDEX');
91-
$offlinePrimaryTable->setPrimaryKey(['"Id"']);
92-
93-
$foreignTableName = 'foreign';
94-
$offlineForeignTable = new Table($foreignTableName);
95-
$offlineForeignTable->addColumn('id', Types::INTEGER, ['autoincrement' => true]);
96-
$offlineForeignTable->addColumn('"Fk"', Types::INTEGER);
97-
$offlineForeignTable->addIndex(['"Fk"'], '"Fk_index"');
98-
$offlineForeignTable->addForeignKeyConstraint(
99-
$primaryTableName,
100-
['"Fk"'],
101-
['"Id"'],
102-
[],
103-
'"Primary_Table_Fk"',
104-
);
105-
$offlineForeignTable->setPrimaryKey(['id']);
106-
107-
$this->dropTableIfExists($foreignTableName);
108-
$this->dropTableIfExists($primaryTableName);
109-
110-
$this->schemaManager->createTable($offlinePrimaryTable);
111-
$this->schemaManager->createTable($offlineForeignTable);
112-
113-
$onlinePrimaryTable = $this->schemaManager->introspectTable($primaryTableName);
114-
$onlineForeignTable = $this->schemaManager->introspectTable($foreignTableName);
115-
116-
$platform = $this->connection->getDatabasePlatform();
117-
118-
// Primary table assertions
119-
self::assertSame($primaryTableName, $onlinePrimaryTable->getQuotedName($platform));
120-
121-
self::assertTrue($onlinePrimaryTable->hasColumn('"Id"'));
122-
self::assertSame('"Id"', $onlinePrimaryTable->getColumn('"Id"')->getQuotedName($platform));
123-
self::assertTrue($onlinePrimaryTable->hasPrimaryKey());
124-
125-
$primaryKey = $onlinePrimaryTable->getPrimaryKey();
126-
127-
self::assertNotNull($primaryKey);
128-
self::assertSame(['"Id"'], $primaryKey->getQuotedColumns($platform));
129-
130-
self::assertTrue($onlinePrimaryTable->hasColumn('select'));
131-
self::assertSame('"select"', $onlinePrimaryTable->getColumn('select')->getQuotedName($platform));
132-
133-
self::assertTrue($onlinePrimaryTable->hasColumn('foo'));
134-
self::assertSame('FOO', $onlinePrimaryTable->getColumn('foo')->getQuotedName($platform));
135-
136-
self::assertTrue($onlinePrimaryTable->hasColumn('BAR'));
137-
self::assertSame('BAR', $onlinePrimaryTable->getColumn('BAR')->getQuotedName($platform));
138-
139-
self::assertTrue($onlinePrimaryTable->hasColumn('"BAZ"'));
140-
self::assertSame('BAZ', $onlinePrimaryTable->getColumn('"BAZ"')->getQuotedName($platform));
141-
142-
self::assertTrue($onlinePrimaryTable->hasIndex('from'));
143-
self::assertTrue($onlinePrimaryTable->getIndex('from')->hasColumnAtPosition('"select"'));
144-
self::assertSame(['"select"'], $onlinePrimaryTable->getIndex('from')->getQuotedColumns($platform));
145-
146-
self::assertTrue($onlinePrimaryTable->hasIndex('foo_index'));
147-
self::assertTrue($onlinePrimaryTable->getIndex('foo_index')->hasColumnAtPosition('foo'));
148-
self::assertSame(['FOO'], $onlinePrimaryTable->getIndex('foo_index')->getQuotedColumns($platform));
149-
150-
self::assertTrue($onlinePrimaryTable->hasIndex('BAR_INDEX'));
151-
self::assertTrue($onlinePrimaryTable->getIndex('BAR_INDEX')->hasColumnAtPosition('BAR'));
152-
self::assertSame(['BAR'], $onlinePrimaryTable->getIndex('BAR_INDEX')->getQuotedColumns($platform));
153-
154-
self::assertTrue($onlinePrimaryTable->hasIndex('BAZ_INDEX'));
155-
self::assertTrue($onlinePrimaryTable->getIndex('BAZ_INDEX')->hasColumnAtPosition('"BAZ"'));
156-
self::assertSame(['BAZ'], $onlinePrimaryTable->getIndex('BAZ_INDEX')->getQuotedColumns($platform));
157-
158-
// Foreign table assertions
159-
self::assertTrue($onlineForeignTable->hasColumn('id'));
160-
self::assertSame('ID', $onlineForeignTable->getColumn('id')->getQuotedName($platform));
161-
self::assertTrue($onlineForeignTable->hasPrimaryKey());
162-
163-
$primaryKey = $onlineForeignTable->getPrimaryKey();
164-
165-
self::assertNotNull($primaryKey);
166-
self::assertSame(['ID'], $primaryKey->getQuotedColumns($platform));
167-
168-
self::assertTrue($onlineForeignTable->hasColumn('"Fk"'));
169-
self::assertSame('"Fk"', $onlineForeignTable->getColumn('"Fk"')->getQuotedName($platform));
170-
171-
self::assertTrue($onlineForeignTable->hasIndex('"Fk_index"'));
172-
self::assertTrue($onlineForeignTable->getIndex('"Fk_index"')->hasColumnAtPosition('"Fk"'));
173-
self::assertSame(['"Fk"'], $onlineForeignTable->getIndex('"Fk_index"')->getQuotedColumns($platform));
174-
175-
self::assertTrue($onlineForeignTable->hasForeignKey('"Primary_Table_Fk"'));
176-
self::assertSame(
177-
$primaryTableName,
178-
$onlineForeignTable->getForeignKey('"Primary_Table_Fk"')->getQuotedForeignTableName($platform),
179-
);
180-
self::assertSame(
181-
['"Fk"'],
182-
$onlineForeignTable->getForeignKey('"Primary_Table_Fk"')->getQuotedLocalColumns($platform),
183-
);
184-
self::assertSame(
185-
['"Id"'],
186-
$onlineForeignTable->getForeignKey('"Primary_Table_Fk"')->getQuotedForeignColumns($platform),
187-
);
188-
}
189-
19074
public function testListTableColumnsSameTableNamesInDifferentSchemas(): void
19175
{
19276
$table = $this->createListTableColumns();

tests/Functional/Schema/PostgreSQLSchemaManagerTest.php

Lines changed: 0 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525

2626
use function array_map;
2727
use function array_merge;
28-
use function array_pop;
2928
use function array_unshift;
3029
use function assert;
3130
use function count;
@@ -163,44 +162,6 @@ public function testAlterTableAutoIncrementDrop(callable $comparatorFactory): vo
163162
self::assertFalse($tableFinal->getColumn('id')->getAutoincrement());
164163
}
165164

166-
public function testTableWithSchema(): void
167-
{
168-
$this->connection->executeStatement('CREATE SCHEMA nested');
169-
170-
$nestedRelatedTable = new Table('nested.schemarelated');
171-
$column = $nestedRelatedTable->addColumn('id', Types::INTEGER);
172-
$column->setAutoincrement(true);
173-
$nestedRelatedTable->setPrimaryKey(['id']);
174-
175-
$nestedSchemaTable = new Table('nested.schematable');
176-
$column = $nestedSchemaTable->addColumn('id', Types::INTEGER);
177-
$column->setAutoincrement(true);
178-
$nestedSchemaTable->setPrimaryKey(['id']);
179-
$nestedSchemaTable->addForeignKeyConstraint($nestedRelatedTable, ['id'], ['id']);
180-
181-
$this->schemaManager->createTable($nestedRelatedTable);
182-
$this->schemaManager->createTable($nestedSchemaTable);
183-
184-
$tableNames = $this->schemaManager->listTableNames();
185-
self::assertContains('nested.schematable', $tableNames);
186-
187-
$tables = $this->schemaManager->listTables();
188-
self::assertNotNull($this->findTableByName($tables, 'nested.schematable'));
189-
190-
$nestedSchemaTable = $this->schemaManager->introspectTable('nested.schematable');
191-
self::assertTrue($nestedSchemaTable->hasColumn('id'));
192-
193-
$primaryKey = $nestedSchemaTable->getPrimaryKey();
194-
195-
self::assertNotNull($primaryKey);
196-
self::assertEquals(['id'], $primaryKey->getColumns());
197-
198-
$relatedFks = $nestedSchemaTable->getForeignKeys();
199-
self::assertCount(1, $relatedFks);
200-
$relatedFk = array_pop($relatedFks);
201-
self::assertEquals('nested.schemarelated', $relatedFk->getForeignTableName());
202-
}
203-
204165
public function testListSameTableNameColumnsWithDifferentSchema(): void
205166
{
206167
$this->connection->executeStatement('CREATE SCHEMA another');

0 commit comments

Comments
 (0)