From 4fe00f6f4123c75c42f7828f13d1281cca696c9a Mon Sep 17 00:00:00 2001 From: Sergei Morozov Date: Wed, 13 Nov 2024 19:51:14 -0800 Subject: [PATCH 1/4] Index columns by their literal name, not quoted name --- src/Schema/AbstractSchemaManager.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Schema/AbstractSchemaManager.php b/src/Schema/AbstractSchemaManager.php index 9b192ddd674..00010c057f4 100644 --- a/src/Schema/AbstractSchemaManager.php +++ b/src/Schema/AbstractSchemaManager.php @@ -671,8 +671,7 @@ protected function _getPortableTableColumnList(string $table, string $database, foreach ($tableColumns as $tableColumn) { $column = $this->_getPortableTableColumnDefinition($tableColumn); - $name = strtolower($column->getQuotedName($this->platform)); - $list[$name] = $column; + $list[strtolower($column->getName())] = $column; } return $list; From 24473ed6bb7c3c6a5250779210db6c7edef691d0 Mon Sep 17 00:00:00 2001 From: Sergei Morozov Date: Sun, 10 Nov 2024 10:39:11 -0800 Subject: [PATCH 2/4] Remove SQL-based assertions from functional tests The SQL being used by a component is an implementation detail. It should be tested in unit tests. --- .../Schema/MySQLSchemaManagerTest.php | 13 ++------ .../Schema/OracleSchemaManagerTest.php | 31 ------------------- .../Schema/PostgreSQLSchemaManagerTest.php | 29 ++--------------- 3 files changed, 6 insertions(+), 67 deletions(-) diff --git a/tests/Functional/Schema/MySQLSchemaManagerTest.php b/tests/Functional/Schema/MySQLSchemaManagerTest.php index 893f673ca3a..5ecf41d278b 100644 --- a/tests/Functional/Schema/MySQLSchemaManagerTest.php +++ b/tests/Functional/Schema/MySQLSchemaManagerTest.php @@ -596,11 +596,6 @@ public function testSchemaDiffWithCustomColumnTypeWhileDatabaseTypeDiffers(): vo $metadataTable = new Table('table_with_custom_type'); $metadataTable->addColumn('col1', 'custom_type'); - self::assertSame( - ['CREATE TABLE table_with_custom_type (col1 INT NOT NULL)'], - $this->connection->getDatabasePlatform()->getCreateTableSQL($metadataTable), - ); - $this->connection->executeStatement('DROP TABLE IF EXISTS table_with_custom_type'); $this->connection->executeStatement('CREATE TABLE table_with_custom_type (col1 VARCHAR(255) NOT NULL)'); @@ -609,10 +604,8 @@ public function testSchemaDiffWithCustomColumnTypeWhileDatabaseTypeDiffers(): vo $comparator = $this->schemaManager->createComparator(); $tablesDiff = $comparator->compareTables($onlineTable, $metadataTable); - self::assertSame( - ['ALTER TABLE table_with_custom_type CHANGE col1 col1 INT NOT NULL'], - $this->connection->getDatabasePlatform()->getAlterTableSQL($tablesDiff), - ' The column should be changed from VARCAHR TO INT', - ); + $columns = $tablesDiff->getChangedColumns(); + self::assertArrayHasKey('col1', $columns); + self::assertInstanceOf(CustomType::class, $columns['col1']->getNewColumn()->getType()); } } diff --git a/tests/Functional/Schema/OracleSchemaManagerTest.php b/tests/Functional/Schema/OracleSchemaManagerTest.php index 8f57cd0f74a..b8ae736a434 100644 --- a/tests/Functional/Schema/OracleSchemaManagerTest.php +++ b/tests/Functional/Schema/OracleSchemaManagerTest.php @@ -124,61 +124,30 @@ public function testListTableDetailsWithDifferentIdentifierQuotingRequirements() self::assertSame(['"Id"'], $onlinePrimaryTablePrimaryKey->getQuotedColumns($platform)); self::assertTrue($onlinePrimaryTable->hasColumn('select')); - self::assertSame('"select"', $onlinePrimaryTable->getColumn('select')->getQuotedName($platform)); - self::assertTrue($onlinePrimaryTable->hasColumn('foo')); - self::assertSame('FOO', $onlinePrimaryTable->getColumn('foo')->getQuotedName($platform)); - self::assertTrue($onlinePrimaryTable->hasColumn('BAR')); - self::assertSame('BAR', $onlinePrimaryTable->getColumn('BAR')->getQuotedName($platform)); - self::assertTrue($onlinePrimaryTable->hasColumn('"BAZ"')); - self::assertSame('BAZ', $onlinePrimaryTable->getColumn('"BAZ"')->getQuotedName($platform)); - self::assertTrue($onlinePrimaryTable->hasIndex('from')); self::assertTrue($onlinePrimaryTable->getIndex('from')->hasColumnAtPosition('"select"')); - self::assertSame(['"select"'], $onlinePrimaryTable->getIndex('from')->getQuotedColumns($platform)); self::assertTrue($onlinePrimaryTable->hasIndex('foo_index')); self::assertTrue($onlinePrimaryTable->getIndex('foo_index')->hasColumnAtPosition('foo')); - self::assertSame(['FOO'], $onlinePrimaryTable->getIndex('foo_index')->getQuotedColumns($platform)); - self::assertTrue($onlinePrimaryTable->hasIndex('BAR_INDEX')); self::assertTrue($onlinePrimaryTable->getIndex('BAR_INDEX')->hasColumnAtPosition('BAR')); - self::assertSame(['BAR'], $onlinePrimaryTable->getIndex('BAR_INDEX')->getQuotedColumns($platform)); - self::assertTrue($onlinePrimaryTable->hasIndex('BAZ_INDEX')); self::assertTrue($onlinePrimaryTable->getIndex('BAZ_INDEX')->hasColumnAtPosition('"BAZ"')); - self::assertSame(['BAZ'], $onlinePrimaryTable->getIndex('BAZ_INDEX')->getQuotedColumns($platform)); // Foreign table assertions self::assertTrue($onlineForeignTable->hasColumn('id')); - self::assertSame('ID', $onlineForeignTable->getColumn('id')->getQuotedName($platform)); $onlineForeignTablePrimaryKey = $onlineForeignTable->getPrimaryKey(); self::assertNotNull($onlineForeignTablePrimaryKey); - self::assertSame(['ID'], $onlineForeignTablePrimaryKey->getQuotedColumns($platform)); self::assertTrue($onlineForeignTable->hasColumn('"Fk"')); - self::assertSame('"Fk"', $onlineForeignTable->getColumn('"Fk"')->getQuotedName($platform)); - self::assertTrue($onlineForeignTable->hasIndex('"Fk_index"')); self::assertTrue($onlineForeignTable->getIndex('"Fk_index"')->hasColumnAtPosition('"Fk"')); - self::assertSame(['"Fk"'], $onlineForeignTable->getIndex('"Fk_index"')->getQuotedColumns($platform)); self::assertTrue($onlineForeignTable->hasForeignKey('"Primary_Table_Fk"')); - self::assertSame( - $primaryTableName, - $onlineForeignTable->getForeignKey('"Primary_Table_Fk"')->getQuotedForeignTableName($platform), - ); - self::assertSame( - ['"Fk"'], - $onlineForeignTable->getForeignKey('"Primary_Table_Fk"')->getQuotedLocalColumns($platform), - ); - self::assertSame( - ['"Id"'], - $onlineForeignTable->getForeignKey('"Primary_Table_Fk"')->getQuotedForeignColumns($platform), - ); } public function testListTableColumnsSameTableNamesInDifferentSchemas(): void diff --git a/tests/Functional/Schema/PostgreSQLSchemaManagerTest.php b/tests/Functional/Schema/PostgreSQLSchemaManagerTest.php index 6c59bd81d76..c4ab362e5ac 100644 --- a/tests/Functional/Schema/PostgreSQLSchemaManagerTest.php +++ b/tests/Functional/Schema/PostgreSQLSchemaManagerTest.php @@ -86,9 +86,6 @@ public function testAlterTableAutoIncrementAdd(): void $diff = $this->schemaManager->createComparator() ->compareTables($tableFrom, $tableTo); - $sql = $platform->getAlterTableSQL($diff); - self::assertEquals(['ALTER TABLE autoinc_table_add ALTER id ADD GENERATED BY DEFAULT AS IDENTITY'], $sql); - $this->schemaManager->alterTable($diff); $tableFinal = $this->schemaManager->introspectTable('autoinc_table_add'); self::assertTrue($tableFinal->getColumn('id')->getAutoincrement()); @@ -110,11 +107,6 @@ public function testAlterTableAutoIncrementDrop(): void $diff = $this->schemaManager->createComparator() ->compareTables($tableFrom, $tableTo); - self::assertEquals( - ['ALTER TABLE autoinc_table_drop ALTER id DROP IDENTITY'], - $platform->getAlterTableSQL($diff), - ); - $this->schemaManager->alterTable($diff); $tableFinal = $this->schemaManager->introspectTable('autoinc_table_drop'); self::assertFalse($tableFinal->getColumn('id')->getAutoincrement()); @@ -196,17 +188,10 @@ public function testReturnQuotedAssets(): void . ' FOREIGN KEY( "table" ) REFERENCES dbal91_something ON UPDATE CASCADE;'; $this->connection->executeStatement($sql); - $table = $this->schemaManager->introspectTable('dbal91_something'); + $table = $this->schemaManager->introspectTable('dbal91_something'); + $column = $table->getColumn('table'); - self::assertEquals( - [ - 'CREATE TABLE dbal91_something (id INT NOT NULL, "table" INT DEFAULT NULL, PRIMARY KEY(id))', - 'CREATE INDEX IDX_A9401304ECA7352B ON dbal91_something ("table")', - 'ALTER TABLE dbal91_something ADD CONSTRAINT something_input FOREIGN KEY ("table")' - . ' REFERENCES dbal91_something (id) ON UPDATE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE', - ], - $this->connection->getDatabasePlatform()->getCreateTableSQL($table), - ); + self::assertTrue($column->isQuoted()); } public function testListForeignKeys(): void @@ -515,11 +500,6 @@ public function testAlterTableAutoIncrementIntToBigInt(string $from, string $to, $diff = $this->schemaManager->createComparator() ->compareTables($oldTable, $newTable); - self::assertSame( - ['ALTER TABLE autoinc_type_modification ALTER id TYPE ' . $expected], - $this->connection->getDatabasePlatform()->getAlterTableSQL($diff), - ); - $this->schemaManager->alterTable($diff); $tableFinal = $this->schemaManager->introspectTable('autoinc_type_modification'); self::assertTrue($tableFinal->getColumn('id')->getAutoincrement()); @@ -617,9 +597,6 @@ public function testPartitionTable(): void $platform = $this->connection->getDatabasePlatform(); $diff = $this->schemaManager->createComparator()->compareTables($tableFrom, $tableTo); - $sql = $platform->getAlterTableSQL($diff); - self::assertSame(['ALTER TABLE partitioned_table ADD foo INT NOT NULL'], $sql); - $this->schemaManager->alterTable($diff); $tableFinal = $this->schemaManager->introspectTable('partitioned_table'); From 8f4a76fb8a03dade028d62f48a3003633b9ca8cc Mon Sep 17 00:00:00 2001 From: Sergei Morozov Date: Sat, 9 Nov 2024 18:17:44 -0800 Subject: [PATCH 3/4] Use new name parser in AbstractAsset::_setName() --- src/Schema/AbstractAsset.php | 129 +++---------- src/Schema/Exception/IndexNameInvalid.php | 5 +- src/Schema/Exception/InvalidObjectName.php | 25 +++ src/Schema/Exception/InvalidTableName.php | 5 +- .../Functional/Platform/RenameColumnTest.php | 28 --- .../Schema/SQLiteSchemaManagerTest.php | 32 +--- .../SchemaManagerFunctionalTestCase.php | 12 +- .../AbstractMySQLPlatformTestCase.php | 120 +++++++------ tests/Platforms/AbstractPlatformTestCase.php | 22 +-- tests/Platforms/DB2PlatformTest.php | 101 +++++------ tests/Platforms/MariaDBPlatformTest.php | 6 +- tests/Platforms/MySQLPlatformTest.php | 6 +- tests/Platforms/OraclePlatformTest.php | 93 +++++----- tests/Platforms/PostgreSQLPlatformTest.php | 132 +++++++------- tests/Platforms/SQLServerPlatformTest.php | 88 +++++---- tests/Platforms/SQLitePlatformTest.php | 169 ++++++++++-------- tests/Schema/AbstractAssetTest.php | 81 ++------- tests/Schema/MySQLInheritCharsetTest.php | 4 +- tests/Schema/Platforms/MySQLSchemaTest.php | 6 +- 19 files changed, 465 insertions(+), 599 deletions(-) create mode 100644 src/Schema/Exception/InvalidObjectName.php diff --git a/src/Schema/AbstractAsset.php b/src/Schema/AbstractAsset.php index 9e6f2738008..5f2d4755ff6 100644 --- a/src/Schema/AbstractAsset.php +++ b/src/Schema/AbstractAsset.php @@ -5,18 +5,15 @@ namespace Doctrine\DBAL\Schema; use Doctrine\DBAL\Platforms\AbstractPlatform; +use Doctrine\DBAL\Schema\Exception\InvalidObjectName; use Doctrine\DBAL\Schema\Name\Parser; use Doctrine\DBAL\Schema\Name\Parser\Identifier; -use Doctrine\Deprecations\Deprecation; use function array_map; use function count; use function crc32; use function dechex; -use function explode; use function implode; -use function sprintf; -use function str_contains; use function str_replace; use function strtolower; use function strtoupper; @@ -43,44 +40,18 @@ abstract class AbstractAsset /** @var list */ private array $identifiers = []; - private bool $validateFuture = false; - /** * Sets the name of this asset. */ protected function _setName(string $name): void { - $input = $name; - - if ($this->isIdentifierQuoted($name)) { - $this->_quoted = true; - $name = $this->trimQuotes($name); - } - - if (str_contains($name, '.')) { - $parts = explode('.', $name); - $this->_namespace = $parts[0]; - $name = $parts[1]; - } - - $this->_name = $name; - - $this->validateFuture = false; - - if ($input !== '') { + if ($name !== '') { $parser = new Parser(); try { - $identifiers = $parser->parse($input); + $identifiers = $parser->parse($name); } catch (Parser\Exception $e) { - Deprecation::trigger( - 'doctrine/dbal', - 'https://github.com/doctrine/dbal/pull/6592', - 'Unable to parse object name: %s.', - $e->getMessage(), - ); - - return; + throw InvalidObjectName::fromParserException($name, $e); } } else { $identifiers = []; @@ -88,6 +59,9 @@ protected function _setName(string $name): void switch (count($identifiers)) { case 0: + $this->_name = ''; + $this->_quoted = false; + $this->_namespace = null; $this->identifiers = []; return; @@ -102,43 +76,13 @@ protected function _setName(string $name): void break; default: - Deprecation::trigger( - 'doctrine/dbal', - 'https://github.com/doctrine/dbal/pull/6592', - 'An object name may consist of at most 2 identifiers (.), %d given.', - count($identifiers), - ); - - return; - } - - $this->identifiers = $identifiers; - $this->validateFuture = true; - - $futureName = $name->getValue(); - $futureNamespace = $namespace?->getValue(); - - if ($this->_name !== $futureName) { - Deprecation::trigger( - 'doctrine/dbal', - 'https://github.com/doctrine/dbal/pull/6592', - 'Instead of "%s", this name will be interpreted as "%s" in 5.0', - $this->_name, - $futureName, - ); + throw InvalidObjectName::tooManyQualifiers($name, count($identifiers) - 1); } - if ($this->_namespace === $futureNamespace) { - return; - } - - Deprecation::trigger( - 'doctrine/dbal', - 'https://github.com/doctrine/dbal/pull/6592', - 'Instead of %s, the namespace in this name will be interpreted as %s in 5.0.', - $this->_namespace !== null ? sprintf('"%s"', $this->_namespace) : 'null', - $futureNamespace !== null ? sprintf('"%s"', $futureNamespace) : 'null', - ); + $this->_name = $name->getValue(); + $this->_quoted = $name->isQuoted(); + $this->_namespace = $namespace?->getValue(); + $this->identifiers = $identifiers; } /** @@ -210,53 +154,22 @@ public function getName(): string } /** - * Gets the quoted representation of this asset but only if it was defined with one. Otherwise - * return the plain unquoted value as inserted. + * Returns the quoted representation of this asset's name. If the name is unquoted, it is normalized according to + * the platform's unquoted name normalization rules. */ public function getQuotedName(AbstractPlatform $platform): string { - $keywords = $platform->getReservedKeywordsList(); - $parts = $normalizedParts = []; - - foreach (explode('.', $this->getName()) as $identifier) { - $isQuoted = $this->_quoted || $keywords->isKeyword($identifier); + $parts = array_map(static function (Identifier $identifier) use ($platform): string { + $value = $identifier->getValue(); - if (! $isQuoted) { - $parts[] = $identifier; - $normalizedParts[] = $platform->normalizeUnquotedIdentifier($identifier); - } else { - $parts[] = $platform->quoteSingleIdentifier($identifier); - $normalizedParts[] = $identifier; + if (! $identifier->isQuoted()) { + $value = $platform->normalizeUnquotedIdentifier($value); } - } - $name = implode('.', $parts); - - if ($this->validateFuture) { - $futureParts = array_map(static function (Identifier $identifier) use ($platform): string { - $value = $identifier->getValue(); - - if (! $identifier->isQuoted()) { - $value = $platform->normalizeUnquotedIdentifier($value); - } - - return $value; - }, $this->identifiers); - - if ($normalizedParts !== $futureParts) { - Deprecation::trigger( - 'doctrine/dbal', - 'https://github.com/doctrine/dbal/pull/6592', - 'Relying on implicitly quoted identifiers preserving their original case is deprecated. ' - . 'The current name %s will become %s in 5.0. ' - . 'Please quote the name if the case needs to be preserved.', - $name, - implode('.', array_map([$platform, 'quoteSingleIdentifier'], $futureParts)), - ); - } - } + return $platform->quoteSingleIdentifier($value); + }, $this->identifiers); - return $name; + return implode('.', $parts); } /** diff --git a/src/Schema/Exception/IndexNameInvalid.php b/src/Schema/Exception/IndexNameInvalid.php index d295eb8a276..efacce18bab 100644 --- a/src/Schema/Exception/IndexNameInvalid.php +++ b/src/Schema/Exception/IndexNameInvalid.php @@ -4,13 +4,10 @@ namespace Doctrine\DBAL\Schema\Exception; -use Doctrine\DBAL\Schema\SchemaException; -use InvalidArgumentException; - use function sprintf; /** @psalm-immutable */ -final class IndexNameInvalid extends InvalidArgumentException implements SchemaException +final class IndexNameInvalid extends InvalidObjectName { public static function new(string $indexName): self { diff --git a/src/Schema/Exception/InvalidObjectName.php b/src/Schema/Exception/InvalidObjectName.php new file mode 100644 index 00000000000..3e5be3cc3d0 --- /dev/null +++ b/src/Schema/Exception/InvalidObjectName.php @@ -0,0 +1,25 @@ +addColumn('c1', Types::INTEGER); - - $this->dropAndCreateTable($table); - - $table->dropColumn('c1') - ->addColumn('"c2"', Types::INTEGER); - - $schemaManager = $this->connection->createSchemaManager(); - $comparator = $schemaManager->createComparator(); - - $diff = $comparator->compareTables($schemaManager->introspectTable('test_rename'), $table); - self::assertFalse($diff->isEmpty()); - - $schemaManager->alterTable($diff); - - $platform = $this->connection->getDatabasePlatform(); - - self::assertEquals(1, $this->connection->insert( - 'test_rename', - [$platform->quoteSingleIdentifier('c2') => 1], - )); - } } diff --git a/tests/Functional/Schema/SQLiteSchemaManagerTest.php b/tests/Functional/Schema/SQLiteSchemaManagerTest.php index d9d57f4a1fa..d0c07edab5a 100644 --- a/tests/Functional/Schema/SQLiteSchemaManagerTest.php +++ b/tests/Functional/Schema/SQLiteSchemaManagerTest.php @@ -384,33 +384,15 @@ public function testShorthandInForeignKeyReferenceWithMultipleColumns(): void self::assertSame( [ - 'CREATE TABLE track (trackid INTEGER DEFAULT NULL, trackname CLOB DEFAULT NULL COLLATE "BINARY",' - . ' trackartist INTEGER DEFAULT NULL, FOREIGN KEY (trackartist) REFERENCES artist (artistid, isrc) ON' - . ' UPDATE NO ACTION ON DELETE NO ACTION NOT DEFERRABLE INITIALLY IMMEDIATE)', - 'CREATE INDEX IDX_D6E3F8A6FB96D8BC ON track (trackartist)', + 'CREATE TABLE "track" (' + . '"trackid" INTEGER DEFAULT NULL,' + . ' "trackname" CLOB DEFAULT NULL COLLATE "BINARY",' + . ' "trackartist" INTEGER DEFAULT NULL,' + . ' FOREIGN KEY ("trackartist") REFERENCES "artist" ("artistid", "isrc")' + . ' ON UPDATE NO ACTION ON DELETE NO ACTION NOT DEFERRABLE INITIALLY IMMEDIATE)', + 'CREATE INDEX "IDX_D6E3F8A6FB96D8BC" ON "track" ("trackartist")', ], $createTableTrackSql, ); } - - /** - * This test duplicates {@see parent::testCommentInTable()} with the only difference that the name of the table - * being created is quoted. It is only meant to cover the logic of parsing the SQLite CREATE TABLE statement - * when the table name is quoted. - * - * Running the same test for all platforms, on the one hand, won't produce additional coverage, and on the other, - * is not feasible due to the differences in case sensitivity depending on whether the name is quoted. - * - * Once all identifiers are quoted by default, this test can be removed. - */ - public function testCommentInQuotedTable(): void - { - $table = new Table('"table_with_comment"'); - $table->addColumn('id', Types::INTEGER); - $table->setComment('This is a comment'); - $this->dropAndCreateTable($table); - - $table = $this->schemaManager->introspectTable('table_with_comment'); - self::assertSame('This is a comment', $table->getComment()); - } } diff --git a/tests/Functional/Schema/SchemaManagerFunctionalTestCase.php b/tests/Functional/Schema/SchemaManagerFunctionalTestCase.php index a2b01d7c5e8..0b5051a467e 100644 --- a/tests/Functional/Schema/SchemaManagerFunctionalTestCase.php +++ b/tests/Functional/Schema/SchemaManagerFunctionalTestCase.php @@ -1293,7 +1293,7 @@ public function testIntrospectReservedKeywordTableViaListTableDetails(): void { $this->createReservedKeywordTables(); - $user = $this->schemaManager->introspectTable('"user"'); + $user = $this->schemaManager->introspectTable('user'); self::assertCount(2, $user->getColumns()); self::assertCount(2, $user->getIndexes()); self::assertCount(1, $user->getForeignKeys()); @@ -1314,11 +1314,6 @@ public function testIntrospectReservedKeywordTableViaListTables(): void private function createReservedKeywordTables(): void { - $platform = $this->connection->getDatabasePlatform(); - - $this->dropTableIfExists($platform->quoteSingleIdentifier('user')); - $this->dropTableIfExists($platform->quoteSingleIdentifier('group')); - $schema = new Schema(); $user = $schema->createTable('user'); @@ -1331,6 +1326,11 @@ private function createReservedKeywordTables(): void $group->addColumn('id', Types::INTEGER); $group->setPrimaryKey(['id']); + $platform = $this->connection->getDatabasePlatform(); + + $this->dropTableIfExists($user->getQuotedName($platform)); + $this->dropTableIfExists($group->getQuotedName($platform)); + $schemaManager = $this->connection->createSchemaManager(); $schemaManager->createSchemaObjects($schema); } diff --git a/tests/Platforms/AbstractMySQLPlatformTestCase.php b/tests/Platforms/AbstractMySQLPlatformTestCase.php index 50633a2a80a..8a7db6bc7e7 100644 --- a/tests/Platforms/AbstractMySQLPlatformTestCase.php +++ b/tests/Platforms/AbstractMySQLPlatformTestCase.php @@ -34,23 +34,23 @@ public function testGenerateMixedCaseTableCreate(): void $sql = $this->platform->getCreateTableSQL($table); self::assertEquals( - 'CREATE TABLE Foo (Bar INT NOT NULL)', + 'CREATE TABLE `Foo` (`Bar` INT NOT NULL)', array_shift($sql), ); } public function getGenerateTableSql(): string { - return 'CREATE TABLE test (id INT AUTO_INCREMENT NOT NULL, test VARCHAR(255) DEFAULT NULL, ' - . 'PRIMARY KEY(id))'; + return 'CREATE TABLE `test` (`id` INT AUTO_INCREMENT NOT NULL, `test` VARCHAR(255) DEFAULT NULL, ' + . 'PRIMARY KEY(`id`))'; } /** @return string[] */ public function getGenerateTableWithMultiColumnUniqueIndexSql(): array { return [ - 'CREATE TABLE test (foo VARCHAR(255) DEFAULT NULL, bar VARCHAR(255) DEFAULT NULL, ' - . 'UNIQUE INDEX UNIQ_D87F7E0C8C73652176FF8CAA (foo, bar))', + 'CREATE TABLE `test` (`foo` VARCHAR(255) DEFAULT NULL, `bar` VARCHAR(255) DEFAULT NULL, ' + . 'UNIQUE INDEX `UNIQ_D87F7E0C8C73652176FF8CAA` (`foo`, `bar`))', ]; } @@ -122,17 +122,17 @@ public function testDoesSupportSavePoints(): void public function getGenerateIndexSql(): string { - return 'CREATE INDEX my_idx ON mytable (user_name, last_login)'; + return 'CREATE INDEX `my_idx` ON mytable (`user_name`, `last_login`)'; } public function getGenerateUniqueIndexSql(): string { - return 'CREATE UNIQUE INDEX index_name ON test (test, test2)'; + return 'CREATE UNIQUE INDEX `index_name` ON test (`test`, `test2`)'; } protected function getGenerateForeignKeySql(): string { - return 'ALTER TABLE test ADD FOREIGN KEY (fk_name_id) REFERENCES other_table (id)'; + return 'ALTER TABLE test ADD FOREIGN KEY (`fk_name_id`) REFERENCES `other_table` (`id`)'; } public function testUniquePrimaryKey(): void @@ -153,8 +153,8 @@ public function testUniquePrimaryKey(): void $sql = $this->platform->getAlterTableSQL($diff); self::assertEquals([ - 'ALTER TABLE foo ADD PRIMARY KEY (bar)', - 'CREATE UNIQUE INDEX UNIQ_8C73652178240498 ON foo (baz)', + 'ALTER TABLE `foo` ADD PRIMARY KEY (bar)', + 'CREATE UNIQUE INDEX `UNIQ_8C73652178240498` ON `foo` (`baz`)', ], $sql); } @@ -190,7 +190,7 @@ protected function getQuotedColumnInIndexSQL(): array { return [ 'CREATE TABLE `quoted` (`create` VARCHAR(255) NOT NULL, ' - . 'INDEX IDX_22660D028FD6E0FB (`create`))', + . 'INDEX `IDX_22660D028FD6E0FB` (`create`))', ]; } @@ -198,8 +198,8 @@ protected function getQuotedColumnInIndexSQL(): array protected function getQuotedNameInIndexSQL(): array { return [ - 'CREATE TABLE test (column1 VARCHAR(255) NOT NULL, ' - . 'INDEX `key` (column1))', + 'CREATE TABLE `test` (`column1` VARCHAR(255) NOT NULL, ' + . 'INDEX `key` (`column1`))', ]; } @@ -207,14 +207,14 @@ protected function getQuotedNameInIndexSQL(): array protected function getQuotedColumnInForeignKeySQL(): array { return [ - 'CREATE TABLE `quoted` (`create` VARCHAR(255) NOT NULL, foo VARCHAR(255) NOT NULL, ' - . '`bar` VARCHAR(255) NOT NULL, INDEX IDX_22660D028FD6E0FB8C736521D79164E3 (`create`, foo, `bar`))', - 'ALTER TABLE `quoted` ADD CONSTRAINT FK_WITH_RESERVED_KEYWORD FOREIGN KEY (`create`, foo, `bar`)' - . ' REFERENCES `foreign` (`create`, bar, `foo-bar`)', - 'ALTER TABLE `quoted` ADD CONSTRAINT FK_WITH_NON_RESERVED_KEYWORD FOREIGN KEY (`create`, foo, `bar`)' - . ' REFERENCES foo (`create`, bar, `foo-bar`)', - 'ALTER TABLE `quoted` ADD CONSTRAINT FK_WITH_INTENDED_QUOTATION FOREIGN KEY (`create`, foo, `bar`)' - . ' REFERENCES `foo-bar` (`create`, bar, `foo-bar`)', + 'CREATE TABLE `quoted` (`create` VARCHAR(255) NOT NULL, `foo` VARCHAR(255) NOT NULL, ' + . '`bar` VARCHAR(255) NOT NULL, INDEX `IDX_22660D028FD6E0FB8C736521D79164E3` (`create`, `foo`, `bar`))', + 'ALTER TABLE `quoted` ADD CONSTRAINT `FK_WITH_RESERVED_KEYWORD` FOREIGN KEY (`create`, `foo`, `bar`)' + . ' REFERENCES `foreign` (`create`, `bar`, `foo-bar`)', + 'ALTER TABLE `quoted` ADD CONSTRAINT `FK_WITH_NON_RESERVED_KEYWORD` FOREIGN KEY (`create`, `foo`, `bar`)' + . ' REFERENCES `foo` (`create`, `bar`, `foo-bar`)', + 'ALTER TABLE `quoted` ADD CONSTRAINT `FK_WITH_INTENDED_QUOTATION` FOREIGN KEY (`create`, `foo`, `bar`)' + . ' REFERENCES `foo-bar` (`create`, `bar`, `foo-bar`)', ]; } @@ -231,8 +231,8 @@ public function testCreateTableWithFulltextIndex(): void $sql = $this->platform->getCreateTableSQL($table); self::assertEquals( [ - 'CREATE TABLE fulltext_table (text LONGTEXT NOT NULL, ' - . 'FULLTEXT INDEX fulltext_text (text)) ' + 'CREATE TABLE `fulltext_table` (`text` LONGTEXT NOT NULL, ' + . 'FULLTEXT INDEX `fulltext_text` (`text`)) ' . 'ENGINE = MyISAM', ], $sql, @@ -252,7 +252,7 @@ public function testCreateTableWithSpatialIndex(): void $sql = $this->platform->getCreateTableSQL($table); self::assertEquals( [ - 'CREATE TABLE spatial_table (point LONGTEXT NOT NULL, SPATIAL INDEX spatial_text (point)) ' + 'CREATE TABLE `spatial_table` (`point` LONGTEXT NOT NULL, SPATIAL INDEX `spatial_text` (`point`)) ' . 'ENGINE = MyISAM', ], $sql, @@ -299,7 +299,7 @@ public function testAlterTableAddPrimaryKey(): void ->compareTables($table, $diffTable); self::assertEquals( - ['DROP INDEX idx_id ON alter_table_add_pk', 'ALTER TABLE alter_table_add_pk ADD PRIMARY KEY (id)'], + ['DROP INDEX `idx_id` ON `alter_table_add_pk`', 'ALTER TABLE `alter_table_add_pk` ADD PRIMARY KEY (id)'], $this->platform->getAlterTableSQL($diff), ); } @@ -321,9 +321,9 @@ public function testAlterPrimaryKeyWithAutoincrementColumn(): void self::assertEquals( [ - 'ALTER TABLE alter_primary_key MODIFY id INT NOT NULL', - 'DROP INDEX `primary` ON alter_primary_key', - 'ALTER TABLE alter_primary_key ADD PRIMARY KEY (foo)', + 'ALTER TABLE `alter_primary_key` MODIFY `id` INT NOT NULL', + 'DROP INDEX `primary` ON `alter_primary_key`', + 'ALTER TABLE `alter_primary_key` ADD PRIMARY KEY (`foo`)', ], $this->platform->getAlterTableSQL($diff), ); @@ -346,8 +346,8 @@ public function testDropPrimaryKeyWithAutoincrementColumn(): void self::assertEquals( [ - 'ALTER TABLE drop_primary_key MODIFY id INT NOT NULL', - 'DROP INDEX `primary` ON drop_primary_key', + 'ALTER TABLE `drop_primary_key` MODIFY `id` INT NOT NULL', + 'DROP INDEX `primary` ON `drop_primary_key`', ], $this->platform->getAlterTableSQL($diff), ); @@ -371,9 +371,9 @@ public function testDropNonAutoincrementColumnFromCompositePrimaryKeyWithAutoinc self::assertSame( [ - 'ALTER TABLE tbl MODIFY id INT NOT NULL', - 'DROP INDEX `primary` ON tbl', - 'ALTER TABLE tbl ADD PRIMARY KEY (id)', + 'ALTER TABLE `tbl` MODIFY `id` INT NOT NULL', + 'DROP INDEX `primary` ON `tbl`', + 'ALTER TABLE `tbl` ADD PRIMARY KEY (`id`)', ], $this->platform->getAlterTableSQL($diff), ); @@ -397,9 +397,9 @@ public function testAddNonAutoincrementColumnToPrimaryKeyWithAutoincrementColumn self::assertSame( [ - 'ALTER TABLE tbl MODIFY id INT NOT NULL', - 'DROP INDEX `primary` ON tbl', - 'ALTER TABLE tbl ADD PRIMARY KEY (id, foo)', + 'ALTER TABLE `tbl` MODIFY `id` INT NOT NULL', + 'DROP INDEX `primary` ON `tbl`', + 'ALTER TABLE `tbl` ADD PRIMARY KEY (`id`, `foo`)', ], $this->platform->getAlterTableSQL($diff), ); @@ -420,7 +420,7 @@ public function testAddAutoIncrementPrimaryKey(): void $sql = $this->platform->getAlterTableSQL($diff); - self::assertEquals(['ALTER TABLE foo ADD id INT AUTO_INCREMENT NOT NULL, ADD PRIMARY KEY (id)'], $sql); + self::assertEquals(['ALTER TABLE `foo` ADD `id` INT AUTO_INCREMENT NOT NULL, ADD PRIMARY KEY (id)'], $sql); } public function testAlterPrimaryKeyWithNewColumn(): void @@ -441,9 +441,9 @@ public function testAlterPrimaryKeyWithNewColumn(): void self::assertSame( [ - 'DROP INDEX `primary` ON yolo', - 'ALTER TABLE yolo ADD pkc2 INT NOT NULL', - 'ALTER TABLE yolo ADD PRIMARY KEY (pkc1, pkc2)', + 'DROP INDEX `primary` ON `yolo`', + 'ALTER TABLE `yolo` ADD `pkc2` INT NOT NULL', + 'ALTER TABLE `yolo` ADD PRIMARY KEY (`pkc1`, `pkc2`)', ], $this->platform->getAlterTableSQL($diff), ); @@ -496,8 +496,8 @@ protected function getQuotedAlterTableRenameIndexSQL(): array protected function getAlterTableRenameIndexInSchemaSQL(): array { return [ - 'DROP INDEX idx_foo ON myschema.mytable', - 'CREATE INDEX idx_bar ON myschema.mytable (id)', + 'DROP INDEX `idx_foo` ON `myschema`.`mytable`', + 'CREATE INDEX idx_bar ON `myschema`.`mytable` (`id`)', ]; } @@ -512,6 +512,16 @@ protected function getQuotedAlterTableRenameIndexInSchemaSQL(): array ]; } + protected function getQuotedCommentOnColumnSQLWithoutQuoteCharacter(): string + { + return "COMMENT ON COLUMN `mytable`.`id` IS 'This is a comment'"; + } + + protected function getQuotedCommentOnColumnSQLWithQuoteCharacter(): string + { + return "COMMENT ON COLUMN `mytable`.`id` IS 'It''s a quote !'"; + } + public function testIgnoresDifferenceInDefaultValuesForUnsupportedColumnTypes(): void { $table = new Table('text_blob_default_value'); @@ -522,10 +532,10 @@ public function testIgnoresDifferenceInDefaultValuesForUnsupportedColumnTypes(): self::assertSame( [ - 'CREATE TABLE text_blob_default_value (def_text LONGTEXT NOT NULL, ' - . 'def_text_null LONGTEXT DEFAULT NULL, ' - . 'def_blob LONGBLOB NOT NULL, ' - . 'def_blob_null LONGBLOB DEFAULT NULL' + 'CREATE TABLE `text_blob_default_value` (`def_text` LONGTEXT NOT NULL, ' + . '`def_text_null` LONGTEXT DEFAULT NULL, ' + . '`def_blob` LONGBLOB NOT NULL, ' + . '`def_blob_null` LONGBLOB DEFAULT NULL' . ')', ], $this->platform->getCreateTableSQL($table), @@ -554,7 +564,7 @@ public function testReturnsGuidTypeDeclarationSQL(): void protected function getCommentOnColumnSQL(): array { return [ - "COMMENT ON COLUMN foo.bar IS 'comment'", + "COMMENT ON COLUMN `foo`.`bar` IS 'comment'", "COMMENT ON COLUMN `Foo`.`BAR` IS 'comment'", "COMMENT ON COLUMN `select`.`from` IS 'comment'", ]; @@ -567,7 +577,7 @@ protected function getQuotesReservedKeywordInUniqueConstraintDeclarationSQL(): s protected function getQuotesReservedKeywordInIndexDeclarationSQL(): string { - return 'INDEX `select` (foo)'; + return 'INDEX `select` (`foo`)'; } protected function getQuotesReservedKeywordInTruncateTableSQL(): string @@ -580,7 +590,7 @@ protected function getQuotesReservedKeywordInTruncateTableSQL(): string */ protected function getAlterStringToFixedStringSQL(): array { - return ['ALTER TABLE mytable CHANGE name name CHAR(2) NOT NULL']; + return ['ALTER TABLE `mytable` CHANGE `name` `name` CHAR(2) NOT NULL']; } /** @@ -589,10 +599,10 @@ protected function getAlterStringToFixedStringSQL(): array protected function getGeneratesAlterTableRenameIndexUsedByForeignKeySQL(): array { return [ - 'ALTER TABLE mytable DROP FOREIGN KEY fk_foo', - 'DROP INDEX idx_foo ON mytable', - 'CREATE INDEX idx_foo_renamed ON mytable (foo)', - 'ALTER TABLE mytable ADD CONSTRAINT fk_foo FOREIGN KEY (foo) REFERENCES foreign_table (id)', + 'ALTER TABLE `mytable` DROP FOREIGN KEY fk_foo', + 'DROP INDEX `idx_foo` ON `mytable`', + 'CREATE INDEX `idx_foo_renamed` ON mytable (foo)', + 'ALTER TABLE `mytable` ADD CONSTRAINT `fk_foo` FOREIGN KEY (`foo`) REFERENCES foreign_table (id)', ]; } @@ -674,8 +684,8 @@ public function testGetCreateTableSQLWithColumnCollation(): void self::assertSame( [ - 'CREATE TABLE foo (no_collation VARCHAR(255) NOT NULL, ' - . 'column_collation VARCHAR(255) NOT NULL COLLATE `ascii_general_ci`)', + 'CREATE TABLE `foo` (`no_collation` VARCHAR(255) NOT NULL, ' + . '`column_collation` VARCHAR(255) NOT NULL COLLATE `ascii_general_ci`)', ], $this->platform->getCreateTableSQL($table), ); diff --git a/tests/Platforms/AbstractPlatformTestCase.php b/tests/Platforms/AbstractPlatformTestCase.php index 78d85cba5f1..4d45a8eb18b 100644 --- a/tests/Platforms/AbstractPlatformTestCase.php +++ b/tests/Platforms/AbstractPlatformTestCase.php @@ -398,16 +398,16 @@ public function testQuotedColumnInForeignKeyPropagation(): void 'FK_WITH_RESERVED_KEYWORD', ); - // Foreign table with non-reserved keyword as name (does not need quotation). + // Foreign table with non-reserved keyword as name $foreignTable = new Table('foo'); - // Foreign column with reserved keyword as name (needs quotation). + // Foreign column with reserved keyword as name $foreignTable->addColumn('create', Types::STRING); - // Foreign column with non-reserved keyword as name (does not need quotation). + // Foreign column with non-reserved keyword as name $foreignTable->addColumn('bar', Types::STRING); - // Foreign table with special character in name (needs quotation on some platforms, e.g. Sqlite). + // Foreign table with special character in name $foreignTable->addColumn('`foo-bar`', Types::STRING); $table->addForeignKeyConstraint( @@ -519,7 +519,7 @@ public function testAlterTableChangeQuotedColumn(): void ]); self::assertStringContainsString( - $this->platform->quoteSingleIdentifier('select'), + $this->platform->quoteSingleIdentifier($this->platform->normalizeUnquotedIdentifier('select')), implode(';', $this->platform->getAlterTableSQL($tableDiff)), ); } @@ -680,8 +680,8 @@ public function testAlterTableRenameIndex(): void protected function getAlterTableRenameIndexSQL(): array { return [ - 'DROP INDEX idx_foo', - 'CREATE INDEX idx_bar ON mytable (id)', + 'DROP INDEX `idx_foo`', + 'CREATE INDEX `idx_bar` ON mytable (`id`)', ]; } @@ -693,7 +693,7 @@ public function testQuotesAlterTableRenameIndex(): void $tableDiff = new TableDiff($table, renamedIndexes: [ 'create' => new Index('select', ['id']), - '`foo`' => new Index('`bar`', ['id']), + 'foo' => new Index('bar', ['id']), ]); self::assertSame( @@ -744,7 +744,7 @@ public function testQuotesAlterTableRenameIndexInSchema(): void $tableDiff = new TableDiff($table, renamedIndexes: [ 'create' => new Index('select', ['id']), - '`foo`' => new Index('`bar`', ['id']), + 'foo' => new Index('bar', ['id']), ]); self::assertSame( @@ -766,7 +766,7 @@ protected function getQuotedAlterTableRenameIndexInSchemaSQL(): array protected function getQuotedCommentOnColumnSQLWithoutQuoteCharacter(): string { - return "COMMENT ON COLUMN mytable.id IS 'This is a comment'"; + return "COMMENT ON COLUMN \"MYTABLE\".\"ID\" IS 'This is a comment'"; } public function testGetCommentOnColumnSQLWithoutQuoteCharacter(): void @@ -779,7 +779,7 @@ public function testGetCommentOnColumnSQLWithoutQuoteCharacter(): void protected function getQuotedCommentOnColumnSQLWithQuoteCharacter(): string { - return "COMMENT ON COLUMN mytable.id IS 'It''s a quote !'"; + return "COMMENT ON COLUMN \"MYTABLE\".\"ID\" IS 'It''s a quote !'"; } public function testGetCommentOnColumnSQLWithQuoteCharacter(): void diff --git a/tests/Platforms/DB2PlatformTest.php b/tests/Platforms/DB2PlatformTest.php index 4000b3f4cca..4d9fa4adb40 100644 --- a/tests/Platforms/DB2PlatformTest.php +++ b/tests/Platforms/DB2PlatformTest.php @@ -26,18 +26,18 @@ public function createPlatform(): AbstractPlatform protected function getGenerateForeignKeySql(): string { - return 'ALTER TABLE test ADD FOREIGN KEY (fk_name_id) REFERENCES other_table (id)'; + return 'ALTER TABLE test ADD FOREIGN KEY ("FK_NAME_ID") REFERENCES "OTHER_TABLE" ("ID")'; } public function getGenerateIndexSql(): string { - return 'CREATE INDEX my_idx ON mytable (user_name, last_login)'; + return 'CREATE INDEX "MY_IDX" ON mytable ("USER_NAME", "LAST_LOGIN")'; } public function getGenerateTableSql(): string { - return 'CREATE TABLE test (id INTEGER GENERATED BY DEFAULT AS IDENTITY NOT NULL, ' - . 'test VARCHAR(255) DEFAULT NULL, PRIMARY KEY(id))'; + return 'CREATE TABLE "TEST" ("ID" INTEGER GENERATED BY DEFAULT AS IDENTITY NOT NULL, ' + . '"TEST" VARCHAR(255) DEFAULT NULL, PRIMARY KEY("ID"))'; } /** @@ -46,14 +46,14 @@ public function getGenerateTableSql(): string public function getGenerateTableWithMultiColumnUniqueIndexSql(): array { return [ - 'CREATE TABLE test (foo VARCHAR(255) DEFAULT NULL, bar VARCHAR(255) DEFAULT NULL)', - 'CREATE UNIQUE INDEX UNIQ_D87F7E0C8C73652176FF8CAA ON test (foo, bar)', + 'CREATE TABLE "TEST" ("FOO" VARCHAR(255) DEFAULT NULL, "BAR" VARCHAR(255) DEFAULT NULL)', + 'CREATE UNIQUE INDEX "UNIQ_D87F7E0C8C73652176FF8CAA" ON "TEST" ("FOO", "BAR")', ]; } public function getGenerateUniqueIndexSql(): string { - return 'CREATE UNIQUE INDEX index_name ON test (test, test2)'; + return 'CREATE UNIQUE INDEX "INDEX_NAME" ON test ("TEST", "TEST2")'; } /** @@ -62,15 +62,15 @@ public function getGenerateUniqueIndexSql(): string protected function getQuotedColumnInForeignKeySQL(): array { return [ - 'CREATE TABLE "quoted" ("create" VARCHAR(255) NOT NULL, foo VARCHAR(255) NOT NULL, ' - . '"bar" VARCHAR(255) NOT NULL)', - 'ALTER TABLE "quoted" ADD CONSTRAINT FK_WITH_RESERVED_KEYWORD FOREIGN KEY ("create", foo, "bar")' - . ' REFERENCES "foreign" ("create", bar, "foo-bar")', - 'ALTER TABLE "quoted" ADD CONSTRAINT FK_WITH_NON_RESERVED_KEYWORD FOREIGN KEY ("create", foo, "bar")' - . ' REFERENCES foo ("create", bar, "foo-bar")', - 'ALTER TABLE "quoted" ADD CONSTRAINT FK_WITH_INTENDED_QUOTATION FOREIGN KEY ("create", foo, "bar")' - . ' REFERENCES "foo-bar" ("create", bar, "foo-bar")', - 'CREATE INDEX IDX_22660D028FD6E0FB8C736521D79164E3 ON "quoted" ("create", foo, "bar")', + 'CREATE TABLE "quoted" ("CREATE" VARCHAR(255) NOT NULL, "FOO" VARCHAR(255) NOT NULL, ' + . '"bar" VARCHAR(255) NOT NULL)', + 'ALTER TABLE "quoted" ADD CONSTRAINT "FK_WITH_RESERVED_KEYWORD" FOREIGN KEY ("CREATE", "FOO", "bar")' + . ' REFERENCES "FOREIGN" ("CREATE", "BAR", "foo-bar")', + 'ALTER TABLE "quoted" ADD CONSTRAINT "FK_WITH_NON_RESERVED_KEYWORD" FOREIGN KEY ("CREATE", "FOO", "bar")' + . ' REFERENCES "FOO" ("CREATE", "BAR", "foo-bar")', + 'ALTER TABLE "quoted" ADD CONSTRAINT "FK_WITH_INTENDED_QUOTATION" FOREIGN KEY ("CREATE", "FOO", "bar")' + . ' REFERENCES "foo-bar" ("CREATE", "BAR", "foo-bar")', + 'CREATE INDEX "IDX_22660D028FD6E0FB8C736521D79164E3" ON "quoted" ("CREATE", "FOO", "bar")', ]; } @@ -80,8 +80,8 @@ protected function getQuotedColumnInForeignKeySQL(): array protected function getQuotedColumnInIndexSQL(): array { return [ - 'CREATE TABLE "quoted" ("create" VARCHAR(255) NOT NULL)', - 'CREATE INDEX IDX_22660D028FD6E0FB ON "quoted" ("create")', + 'CREATE TABLE "quoted" ("CREATE" VARCHAR(255) NOT NULL)', + 'CREATE INDEX "IDX_22660D028FD6E0FB" ON "quoted" ("CREATE")', ]; } @@ -91,8 +91,8 @@ protected function getQuotedColumnInIndexSQL(): array protected function getQuotedNameInIndexSQL(): array { return [ - 'CREATE TABLE test (column1 VARCHAR(255) NOT NULL)', - 'CREATE INDEX "key" ON test (column1)', + 'CREATE TABLE "TEST" ("COLUMN1" VARCHAR(255) NOT NULL)', + 'CREATE INDEX "key" ON "TEST" ("COLUMN1")', ]; } @@ -101,7 +101,7 @@ protected function getQuotedNameInIndexSQL(): array */ protected function getQuotedColumnInPrimaryKeySQL(): array { - return ['CREATE TABLE "quoted" ("create" VARCHAR(255) NOT NULL, PRIMARY KEY("create"))']; + return ['CREATE TABLE "quoted" ("CREATE" VARCHAR(255) NOT NULL, PRIMARY KEY("CREATE"))']; } protected function getBitAndComparisonExpressionSql(string $value1, string $value2): string @@ -125,9 +125,9 @@ public function testGeneratesCreateTableSQLWithCommonIndexes(): void self::assertEquals( [ - 'CREATE TABLE test (id INTEGER NOT NULL, name VARCHAR(50) NOT NULL, PRIMARY KEY(id))', - 'CREATE INDEX IDX_D87F7E0C5E237E06 ON test (name)', - 'CREATE INDEX composite_idx ON test (id, name)', + 'CREATE TABLE "TEST" ("ID" INTEGER NOT NULL, "NAME" VARCHAR(50) NOT NULL, PRIMARY KEY("ID"))', + 'CREATE INDEX "IDX_D87F7E0C5E237E06" ON "TEST" ("NAME")', + 'CREATE INDEX "COMPOSITE_IDX" ON "TEST" ("ID", "NAME")', ], $this->platform->getCreateTableSQL($table), ); @@ -151,13 +151,13 @@ public function testGeneratesCreateTableSQLWithForeignKeyConstraints(): void self::assertEquals( [ - 'CREATE TABLE test (id INTEGER NOT NULL, fk_1 INTEGER NOT NULL, fk_2 INTEGER NOT NULL' - . ', PRIMARY KEY(id))', - 'ALTER TABLE test ADD CONSTRAINT FK_D87F7E0C177612A38E7F4319 FOREIGN KEY (fk_1, fk_2)' - . ' REFERENCES foreign_table (pk_1, pk_2)', - 'ALTER TABLE test ADD CONSTRAINT named_fk FOREIGN KEY (fk_1, fk_2)' - . ' REFERENCES foreign_table2 (pk_1, pk_2)', - 'CREATE INDEX IDX_D87F7E0C177612A38E7F4319 ON test (fk_1, fk_2)', + 'CREATE TABLE "TEST" ("ID" INTEGER NOT NULL, "FK_1" INTEGER NOT NULL, "FK_2" INTEGER NOT NULL' + . ', PRIMARY KEY("ID"))', + 'ALTER TABLE "TEST" ADD CONSTRAINT "FK_D87F7E0C177612A38E7F4319" FOREIGN KEY ("FK_1", "FK_2")' + . ' REFERENCES "FOREIGN_TABLE" ("PK_1", "PK_2")', + 'ALTER TABLE "TEST" ADD CONSTRAINT "NAMED_FK" FOREIGN KEY ("FK_1", "FK_2")' + . ' REFERENCES "FOREIGN_TABLE2" ("PK_1", "PK_2")', + 'CREATE INDEX "IDX_D87F7E0C177612A38E7F4319" ON "TEST" ("FK_1", "FK_2")', ], $this->platform->getCreateTableSQL($table), ); @@ -173,8 +173,9 @@ public function testGeneratesCreateTableSQLWithCheckConstraints(): void self::assertEquals( [ - 'CREATE TABLE test (id INTEGER NOT NULL, check_max INTEGER NOT NULL, ' - . 'check_min INTEGER NOT NULL, PRIMARY KEY(id), CHECK (check_max <= 10), CHECK (check_min >= 10))', + 'CREATE TABLE "TEST" ("ID" INTEGER NOT NULL, "CHECK_MAX" INTEGER NOT NULL, ' + . '"CHECK_MIN" INTEGER NOT NULL, PRIMARY KEY("ID"), CHECK ("CHECK_MAX" <= 10), ' + . 'CHECK ("CHECK_MIN" >= 10))', ], $this->platform->getCreateTableSQL($table), ); @@ -230,7 +231,7 @@ public function testGeneratesColumnTypesDeclarationSQL(): void public function testGeneratesDDLSnippets(): void { self::assertEquals('DECLARE GLOBAL TEMPORARY TABLE', $this->platform->getCreateTemporaryTableSnippetSQL()); - self::assertEquals('TRUNCATE foobar IMMEDIATE', $this->platform->getTruncateTableSQL('foobar')); + self::assertEquals('TRUNCATE "FOOBAR" IMMEDIATE', $this->platform->getTruncateTableSQL('foobar')); $viewSql = 'SELECT * FROM footable'; @@ -245,7 +246,7 @@ public function testGeneratesDDLSnippets(): void public function testGeneratesCreateUnnamedPrimaryKeySQL(): void { self::assertEquals( - 'ALTER TABLE foo ADD PRIMARY KEY (a, b)', + 'ALTER TABLE foo ADD PRIMARY KEY ("A", "B")', $this->platform->getCreatePrimaryKeySQL( new Index('any_pk_name', ['a', 'b'], true, true), 'foo', @@ -391,7 +392,7 @@ public function getExpectedVariableLengthBinaryTypeDeclarationSQLWithLength(): s */ protected function getAlterTableRenameIndexSQL(): array { - return ['RENAME INDEX idx_foo TO idx_bar']; + return ['RENAME INDEX "IDX_FOO" TO "IDX_BAR"']; } /** @@ -400,8 +401,8 @@ protected function getAlterTableRenameIndexSQL(): array protected function getQuotedAlterTableRenameIndexSQL(): array { return [ - 'RENAME INDEX "create" TO "select"', - 'RENAME INDEX "foo" TO "bar"', + 'RENAME INDEX "CREATE" TO "SELECT"', + 'RENAME INDEX "FOO" TO "BAR"', ]; } @@ -410,7 +411,7 @@ protected function getQuotedAlterTableRenameIndexSQL(): array */ protected function getAlterTableRenameIndexInSchemaSQL(): array { - return ['RENAME INDEX myschema.idx_foo TO idx_bar']; + return ['RENAME INDEX "MYSCHEMA"."IDX_FOO" TO "IDX_BAR"']; } /** @@ -419,8 +420,8 @@ protected function getAlterTableRenameIndexInSchemaSQL(): array protected function getQuotedAlterTableRenameIndexInSchemaSQL(): array { return [ - 'RENAME INDEX "schema"."create" TO "select"', - 'RENAME INDEX "schema"."foo" TO "bar"', + 'RENAME INDEX "schema"."CREATE" TO "SELECT"', + 'RENAME INDEX "schema"."FOO" TO "BAR"', ]; } @@ -435,9 +436,9 @@ public function testReturnsGuidTypeDeclarationSQL(): void protected function getCommentOnColumnSQL(): array { return [ - 'COMMENT ON COLUMN foo.bar IS \'comment\'', + 'COMMENT ON COLUMN "FOO"."BAR" IS \'comment\'', 'COMMENT ON COLUMN "Foo"."BAR" IS \'comment\'', - 'COMMENT ON COLUMN "select"."from" IS \'comment\'', + 'COMMENT ON COLUMN "SELECT"."FROM" IS \'comment\'', ]; } @@ -455,11 +456,11 @@ public function testGeneratesAlterColumnSQL( $expectedSQL = []; if ($expectedSQLClause !== null) { - $expectedSQL[] = 'ALTER TABLE foo ALTER COLUMN bar ' . $expectedSQLClause; + $expectedSQL[] = 'ALTER TABLE "FOO" ALTER COLUMN "BAR" ' . $expectedSQLClause; } if ($shouldReorg) { - $expectedSQL[] = "CALL SYSPROC.ADMIN_CMD ('REORG TABLE foo')"; + $expectedSQL[] = "CALL SYSPROC.ADMIN_CMD ('REORG TABLE \"FOO\"')"; } self::assertSame($expectedSQL, $this->platform->getAlterTableSQL($tableDiff)); @@ -530,7 +531,7 @@ public static function getGeneratesAlterColumnSQL(): iterable protected function getQuotesReservedKeywordInUniqueConstraintDeclarationSQL(): string { - return 'CONSTRAINT "select" UNIQUE (foo)'; + return 'CONSTRAINT "SELECT" UNIQUE (foo)'; } protected function getQuotesReservedKeywordInIndexDeclarationSQL(): string @@ -540,7 +541,7 @@ protected function getQuotesReservedKeywordInIndexDeclarationSQL(): string protected function getQuotesReservedKeywordInTruncateTableSQL(): string { - return 'TRUNCATE "select" IMMEDIATE'; + return 'TRUNCATE "SELECT" IMMEDIATE'; } protected function supportsInlineIndexDeclaration(): bool @@ -559,8 +560,8 @@ protected function supportsCommentOnStatement(): bool protected function getAlterStringToFixedStringSQL(): array { return [ - 'ALTER TABLE mytable ALTER COLUMN name SET DATA TYPE CHAR(2)', - 'CALL SYSPROC.ADMIN_CMD (\'REORG TABLE mytable\')', + 'ALTER TABLE "MYTABLE" ALTER COLUMN "NAME" SET DATA TYPE CHAR(2)', + 'CALL SYSPROC.ADMIN_CMD (\'REORG TABLE "MYTABLE"\')', ]; } @@ -569,6 +570,6 @@ protected function getAlterStringToFixedStringSQL(): array */ protected function getGeneratesAlterTableRenameIndexUsedByForeignKeySQL(): array { - return ['RENAME INDEX idx_foo TO idx_foo_renamed']; + return ['RENAME INDEX "IDX_FOO" TO "IDX_FOO_RENAMED"']; } } diff --git a/tests/Platforms/MariaDBPlatformTest.php b/tests/Platforms/MariaDBPlatformTest.php index 612fa7b6a5b..a0402422deb 100644 --- a/tests/Platforms/MariaDBPlatformTest.php +++ b/tests/Platforms/MariaDBPlatformTest.php @@ -18,7 +18,7 @@ public function createPlatform(): AbstractPlatform /** @return string[] */ protected function getAlterTableRenameIndexSQL(): array { - return ['ALTER TABLE mytable RENAME INDEX idx_foo TO idx_bar']; + return ['ALTER TABLE `mytable` RENAME INDEX `idx_foo` TO `idx_bar`']; } /** @return string[] */ @@ -33,7 +33,7 @@ protected function getQuotedAlterTableRenameIndexSQL(): array /** @return string[] */ protected function getAlterTableRenameIndexInSchemaSQL(): array { - return ['ALTER TABLE myschema.mytable RENAME INDEX idx_foo TO idx_bar']; + return ['ALTER TABLE `myschema`.`mytable` RENAME INDEX `idx_foo` TO `idx_bar`']; } /** @return string[] */ @@ -50,7 +50,7 @@ protected function getQuotedAlterTableRenameIndexInSchemaSQL(): array */ protected function getGeneratesAlterTableRenameIndexUsedByForeignKeySQL(): array { - return ['ALTER TABLE mytable RENAME INDEX idx_foo TO idx_foo_renamed']; + return ['ALTER TABLE `mytable` RENAME INDEX `idx_foo` TO `idx_foo_renamed`']; } /** diff --git a/tests/Platforms/MySQLPlatformTest.php b/tests/Platforms/MySQLPlatformTest.php index db7276e64f2..7233da7e2d8 100644 --- a/tests/Platforms/MySQLPlatformTest.php +++ b/tests/Platforms/MySQLPlatformTest.php @@ -34,7 +34,7 @@ public function testInitializesJsonTypeMapping(): void /** @return string[] */ protected function getAlterTableRenameIndexSQL(): array { - return ['ALTER TABLE mytable RENAME INDEX idx_foo TO idx_bar']; + return ['ALTER TABLE `mytable` RENAME INDEX `idx_foo` TO `idx_bar`']; } /** @return string[] */ @@ -49,7 +49,7 @@ protected function getQuotedAlterTableRenameIndexSQL(): array /** @return string[] */ protected function getAlterTableRenameIndexInSchemaSQL(): array { - return ['ALTER TABLE myschema.mytable RENAME INDEX idx_foo TO idx_bar']; + return ['ALTER TABLE `myschema`.`mytable` RENAME INDEX `idx_foo` TO `idx_bar`']; } /** @return string[] */ @@ -66,7 +66,7 @@ protected function getQuotedAlterTableRenameIndexInSchemaSQL(): array */ protected function getGeneratesAlterTableRenameIndexUsedByForeignKeySQL(): array { - return ['ALTER TABLE mytable RENAME INDEX idx_foo TO idx_foo_renamed']; + return ['ALTER TABLE `mytable` RENAME INDEX `idx_foo` TO `idx_foo_renamed`']; } public function testHasCorrectDefaultTransactionIsolationLevel(): void diff --git a/tests/Platforms/OraclePlatformTest.php b/tests/Platforms/OraclePlatformTest.php index dfb5b85036b..70b63626f8f 100644 --- a/tests/Platforms/OraclePlatformTest.php +++ b/tests/Platforms/OraclePlatformTest.php @@ -31,7 +31,8 @@ public function createPlatform(): AbstractPlatform public function getGenerateTableSql(): string { - return 'CREATE TABLE test (id NUMBER(10) NOT NULL, test VARCHAR2(255) DEFAULT NULL NULL, PRIMARY KEY(id))'; + return 'CREATE TABLE "TEST" ("ID" NUMBER(10) NOT NULL, ' + . '"TEST" VARCHAR2(255) DEFAULT NULL NULL, PRIMARY KEY("ID"))'; } /** @@ -40,8 +41,8 @@ public function getGenerateTableSql(): string public function getGenerateTableWithMultiColumnUniqueIndexSql(): array { return [ - 'CREATE TABLE test (foo VARCHAR2(255) DEFAULT NULL NULL, bar VARCHAR2(255) DEFAULT NULL NULL)', - 'CREATE UNIQUE INDEX UNIQ_D87F7E0C8C73652176FF8CAA ON test (foo, bar)', + 'CREATE TABLE "TEST" ("FOO" VARCHAR2(255) DEFAULT NULL NULL, "BAR" VARCHAR2(255) DEFAULT NULL NULL)', + 'CREATE UNIQUE INDEX "UNIQ_D87F7E0C8C73652176FF8CAA" ON "TEST" ("FOO", "BAR")', ]; } @@ -130,17 +131,17 @@ protected function supportsCommentOnStatement(): bool public function getGenerateIndexSql(): string { - return 'CREATE INDEX my_idx ON mytable (user_name, last_login)'; + return 'CREATE INDEX "MY_IDX" ON mytable ("USER_NAME", "LAST_LOGIN")'; } public function getGenerateUniqueIndexSql(): string { - return 'CREATE UNIQUE INDEX index_name ON test (test, test2)'; + return 'CREATE UNIQUE INDEX "INDEX_NAME" ON test ("TEST", "TEST2")'; } protected function getGenerateForeignKeySql(): string { - return 'ALTER TABLE test ADD FOREIGN KEY (fk_name_id) REFERENCES other_table (id)'; + return 'ALTER TABLE test ADD FOREIGN KEY ("FK_NAME_ID") REFERENCES "OTHER_TABLE" ("ID")'; } /** @param mixed[] $options */ @@ -189,7 +190,7 @@ public function testGenerateTableWithAutoincrement(): void $column->setAutoincrement(true); self::assertSame([ - sprintf('CREATE TABLE %s (%s NUMBER(10) NOT NULL)', $tableName, $columnName), + sprintf('CREATE TABLE "%s" ("%s" NUMBER(10) NOT NULL)', $tableName, $columnName), sprintf( <<<'SQL' DECLARE @@ -200,7 +201,7 @@ public function testGenerateTableWithAutoincrement(): void WHERE TABLE_NAME = '%s' AND CONSTRAINT_TYPE = 'P'; IF constraints_Count = 0 OR constraints_Count = '' THEN - EXECUTE IMMEDIATE 'ALTER TABLE %s ADD CONSTRAINT %s_AI_PK PRIMARY KEY (%s)'; + EXECUTE IMMEDIATE 'ALTER TABLE "%s" ADD CONSTRAINT "%s_AI_PK" PRIMARY KEY ("%s")'; END IF; END; SQL @@ -210,28 +211,28 @@ public function testGenerateTableWithAutoincrement(): void $tableName, $columnName, ), - sprintf('CREATE SEQUENCE %s_SEQ START WITH 1 MINVALUE 1 INCREMENT BY 1', $tableName), + sprintf('CREATE SEQUENCE "%s_SEQ" START WITH 1 MINVALUE 1 INCREMENT BY 1', $tableName), sprintf( <<<'SQL' -CREATE TRIGGER %s_AI_PK +CREATE TRIGGER "%s_AI_PK" BEFORE INSERT - ON %s + ON "%s" FOR EACH ROW DECLARE last_Sequence NUMBER; last_InsertID NUMBER; BEGIN - IF (:NEW.%s IS NULL OR :NEW.%s = 0) THEN - SELECT %s_SEQ.NEXTVAL INTO :NEW.%s FROM DUAL; + IF (:NEW."%s" IS NULL OR :NEW."%s" = 0) THEN + SELECT "%s_SEQ".NEXTVAL INTO :NEW."%s" FROM DUAL; ELSE SELECT NVL(Last_Number, 0) INTO last_Sequence FROM User_Sequences WHERE Sequence_Name = '%s_SEQ'; - SELECT :NEW.%s INTO last_InsertID FROM DUAL; + SELECT :NEW."%s" INTO last_InsertID FROM DUAL; WHILE (last_InsertID > last_Sequence) LOOP - SELECT %s_SEQ.NEXTVAL INTO last_Sequence FROM DUAL; + SELECT "%s_SEQ".NEXTVAL INTO last_Sequence FROM DUAL; END LOOP; - SELECT %s_SEQ.NEXTVAL INTO last_Sequence FROM DUAL; + SELECT "%s_SEQ".NEXTVAL INTO last_Sequence FROM DUAL; END IF; END; SQL @@ -267,7 +268,7 @@ public function getBitOrComparisonExpressionSql(string $value1, string $value2): */ protected function getQuotedColumnInPrimaryKeySQL(): array { - return ['CREATE TABLE "quoted" ("create" VARCHAR2(255) NOT NULL, PRIMARY KEY("create"))']; + return ['CREATE TABLE "quoted" ("CREATE" VARCHAR2(255) NOT NULL, PRIMARY KEY("CREATE"))']; } /** @@ -276,8 +277,8 @@ protected function getQuotedColumnInPrimaryKeySQL(): array protected function getQuotedColumnInIndexSQL(): array { return [ - 'CREATE TABLE "quoted" ("create" VARCHAR2(255) NOT NULL)', - 'CREATE INDEX IDX_22660D028FD6E0FB ON "quoted" ("create")', + 'CREATE TABLE "quoted" ("CREATE" VARCHAR2(255) NOT NULL)', + 'CREATE INDEX "IDX_22660D028FD6E0FB" ON "quoted" ("CREATE")', ]; } @@ -287,8 +288,8 @@ protected function getQuotedColumnInIndexSQL(): array protected function getQuotedNameInIndexSQL(): array { return [ - 'CREATE TABLE test (column1 VARCHAR2(255) NOT NULL)', - 'CREATE INDEX "key" ON test (column1)', + 'CREATE TABLE "TEST" ("COLUMN1" VARCHAR2(255) NOT NULL)', + 'CREATE INDEX "key" ON "TEST" ("COLUMN1")', ]; } @@ -298,15 +299,15 @@ protected function getQuotedNameInIndexSQL(): array protected function getQuotedColumnInForeignKeySQL(): array { return [ - 'CREATE TABLE "quoted" ("create" VARCHAR2(255) NOT NULL, foo VARCHAR2(255) NOT NULL, ' - . '"bar" VARCHAR2(255) NOT NULL)', - 'ALTER TABLE "quoted" ADD CONSTRAINT FK_WITH_RESERVED_KEYWORD FOREIGN KEY ("create", foo, "bar")' - . ' REFERENCES foreign ("create", bar, "foo-bar")', - 'ALTER TABLE "quoted" ADD CONSTRAINT FK_WITH_NON_RESERVED_KEYWORD FOREIGN KEY ("create", foo, "bar")' - . ' REFERENCES foo ("create", bar, "foo-bar")', - 'ALTER TABLE "quoted" ADD CONSTRAINT FK_WITH_INTENDED_QUOTATION FOREIGN KEY ("create", foo, "bar")' - . ' REFERENCES "foo-bar" ("create", bar, "foo-bar")', - 'CREATE INDEX IDX_22660D028FD6E0FB8C736521D79164E3 ON "quoted" ("create", foo, "bar")', + 'CREATE TABLE "quoted" ("CREATE" VARCHAR2(255) NOT NULL, "FOO" VARCHAR2(255) NOT NULL, ' + . '"bar" VARCHAR2(255) NOT NULL)', + 'ALTER TABLE "quoted" ADD CONSTRAINT "FK_WITH_RESERVED_KEYWORD" FOREIGN KEY ("CREATE", "FOO", "bar")' + . ' REFERENCES "FOREIGN" ("CREATE", "BAR", "foo-bar")', + 'ALTER TABLE "quoted" ADD CONSTRAINT "FK_WITH_NON_RESERVED_KEYWORD" FOREIGN KEY ("CREATE", "FOO", "bar")' + . ' REFERENCES "FOO" ("CREATE", "BAR", "foo-bar")', + 'ALTER TABLE "quoted" ADD CONSTRAINT "FK_WITH_INTENDED_QUOTATION" FOREIGN KEY ("CREATE", "FOO", "bar")' + . ' REFERENCES "foo-bar" ("CREATE", "BAR", "foo-bar")', + 'CREATE INDEX "IDX_22660D028FD6E0FB8C736521D79164E3" ON "quoted" ("CREATE", "FOO", "bar")', ]; } @@ -406,7 +407,7 @@ public static function dataCreateSequenceWithCache(): iterable */ protected function getAlterTableRenameIndexSQL(): array { - return ['ALTER INDEX idx_foo RENAME TO idx_bar']; + return ['ALTER INDEX "IDX_FOO" RENAME TO "IDX_BAR"']; } /** @@ -415,8 +416,8 @@ protected function getAlterTableRenameIndexSQL(): array protected function getQuotedAlterTableRenameIndexSQL(): array { return [ - 'ALTER INDEX "create" RENAME TO "select"', - 'ALTER INDEX "foo" RENAME TO "bar"', + 'ALTER INDEX "CREATE" RENAME TO "SELECT"', + 'ALTER INDEX "FOO" RENAME TO "BAR"', ]; } @@ -425,7 +426,7 @@ protected function getQuotedAlterTableRenameIndexSQL(): array */ protected function getAlterTableRenameIndexInSchemaSQL(): array { - return ['ALTER INDEX myschema.idx_foo RENAME TO idx_bar']; + return ['ALTER INDEX "MYSCHEMA"."IDX_FOO" RENAME TO "IDX_BAR"']; } /** @@ -434,8 +435,8 @@ protected function getAlterTableRenameIndexInSchemaSQL(): array protected function getQuotedAlterTableRenameIndexInSchemaSQL(): array { return [ - 'ALTER INDEX "schema"."create" RENAME TO "select"', - 'ALTER INDEX "schema"."foo" RENAME TO "bar"', + 'ALTER INDEX "schema"."CREATE" RENAME TO "SELECT"', + 'ALTER INDEX "schema"."FOO" RENAME TO "BAR"', ]; } @@ -459,8 +460,8 @@ public static function getReturnsDropAutoincrementSQL(): iterable 'myTable', [ 'DROP TRIGGER MYTABLE_AI_PK', - 'DROP SEQUENCE MYTABLE_SEQ', - 'ALTER TABLE MYTABLE DROP CONSTRAINT MYTABLE_AI_PK', + 'DROP SEQUENCE "MYTABLE_SEQ"', + 'ALTER TABLE "MYTABLE" DROP CONSTRAINT MYTABLE_AI_PK', ], ], [ @@ -475,7 +476,7 @@ public static function getReturnsDropAutoincrementSQL(): iterable 'table', [ 'DROP TRIGGER TABLE_AI_PK', - 'DROP SEQUENCE TABLE_SEQ', + 'DROP SEQUENCE "TABLE_SEQ"', 'ALTER TABLE "TABLE" DROP CONSTRAINT TABLE_AI_PK', ], ], @@ -488,9 +489,9 @@ public static function getReturnsDropAutoincrementSQL(): iterable protected function getCommentOnColumnSQL(): array { return [ - 'COMMENT ON COLUMN foo.bar IS \'comment\'', + 'COMMENT ON COLUMN "FOO"."BAR" IS \'comment\'', 'COMMENT ON COLUMN "Foo"."BAR" IS \'comment\'', - 'COMMENT ON COLUMN "select"."from" IS \'comment\'', + 'COMMENT ON COLUMN "SELECT"."FROM" IS \'comment\'', ]; } @@ -550,17 +551,17 @@ public function testQuotedTableNames(): void protected function getQuotesReservedKeywordInUniqueConstraintDeclarationSQL(): string { - return 'CONSTRAINT "select" UNIQUE (foo)'; + return 'CONSTRAINT "SELECT" UNIQUE (foo)'; } protected function getQuotesReservedKeywordInIndexDeclarationSQL(): string { - return 'INDEX "select" (foo)'; + return 'INDEX "SELECT" ("FOO")'; } protected function getQuotesReservedKeywordInTruncateTableSQL(): string { - return 'TRUNCATE TABLE "select"'; + return 'TRUNCATE TABLE "SELECT"'; } /** @@ -568,7 +569,7 @@ protected function getQuotesReservedKeywordInTruncateTableSQL(): string */ protected function getAlterStringToFixedStringSQL(): array { - return ['ALTER TABLE mytable MODIFY (name CHAR(2) DEFAULT NULL)']; + return ['ALTER TABLE "MYTABLE" MODIFY ("NAME" CHAR(2) DEFAULT NULL)']; } /** @@ -576,7 +577,7 @@ protected function getAlterStringToFixedStringSQL(): array */ protected function getGeneratesAlterTableRenameIndexUsedByForeignKeySQL(): array { - return ['ALTER INDEX idx_foo RENAME TO idx_foo_renamed']; + return ['ALTER INDEX "IDX_FOO" RENAME TO "IDX_FOO_RENAMED"']; } public function testQuotesDatabaseNameInListSequencesSQL(): void diff --git a/tests/Platforms/PostgreSQLPlatformTest.php b/tests/Platforms/PostgreSQLPlatformTest.php index 9a5ebe16183..52be8a40b93 100644 --- a/tests/Platforms/PostgreSQLPlatformTest.php +++ b/tests/Platforms/PostgreSQLPlatformTest.php @@ -28,8 +28,8 @@ public function createPlatform(): AbstractPlatform public function getGenerateTableSql(): string { - return 'CREATE TABLE test (id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL, test VARCHAR(255) DEFAULT NULL' - . ', PRIMARY KEY(id))'; + return 'CREATE TABLE "test" ("id" INT GENERATED BY DEFAULT AS IDENTITY NOT NULL' + . ', "test" VARCHAR(255) DEFAULT NULL, PRIMARY KEY("id"))'; } /** @@ -38,20 +38,20 @@ public function getGenerateTableSql(): string public function getGenerateTableWithMultiColumnUniqueIndexSql(): array { return [ - 'CREATE TABLE test (foo VARCHAR(255) DEFAULT NULL, bar VARCHAR(255) DEFAULT NULL)', - 'CREATE UNIQUE INDEX UNIQ_D87F7E0C8C73652176FF8CAA ON test (foo, bar)', + 'CREATE TABLE "test" ("foo" VARCHAR(255) DEFAULT NULL, "bar" VARCHAR(255) DEFAULT NULL)', + 'CREATE UNIQUE INDEX "uniq_d87f7e0c8c73652176ff8caa" ON "test" ("foo", "bar")', ]; } public function getGenerateIndexSql(): string { - return 'CREATE INDEX my_idx ON mytable (user_name, last_login)'; + return 'CREATE INDEX "my_idx" ON mytable ("user_name", "last_login")'; } protected function getGenerateForeignKeySql(): string { - return 'ALTER TABLE test ADD FOREIGN KEY (fk_name_id)' - . ' REFERENCES other_table (id) NOT DEFERRABLE INITIALLY IMMEDIATE'; + return 'ALTER TABLE test ADD FOREIGN KEY ("fk_name_id")' + . ' REFERENCES "other_table" ("id") NOT DEFERRABLE INITIALLY IMMEDIATE'; } public function testGeneratesForeignKeySqlForNonStandardOptions(): void @@ -64,8 +64,8 @@ public function testGeneratesForeignKeySqlForNonStandardOptions(): void ['onDelete' => 'CASCADE'], ); self::assertEquals( - 'CONSTRAINT my_fk FOREIGN KEY (foreign_id)' - . ' REFERENCES my_table (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE', + 'CONSTRAINT "my_fk" FOREIGN KEY ("foreign_id")' + . ' REFERENCES "my_table" ("id") ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE', $this->platform->getForeignKeyDeclarationSQL($foreignKey), ); @@ -77,8 +77,8 @@ public function testGeneratesForeignKeySqlForNonStandardOptions(): void ['match' => 'full'], ); self::assertEquals( - 'CONSTRAINT my_fk FOREIGN KEY (foreign_id)' - . ' REFERENCES my_table (id) MATCH full NOT DEFERRABLE INITIALLY IMMEDIATE', + 'CONSTRAINT "my_fk" FOREIGN KEY ("foreign_id")' + . ' REFERENCES "my_table" ("id") MATCH full NOT DEFERRABLE INITIALLY IMMEDIATE', $this->platform->getForeignKeyDeclarationSQL($foreignKey), ); @@ -90,8 +90,8 @@ public function testGeneratesForeignKeySqlForNonStandardOptions(): void ['deferrable' => true], ); self::assertEquals( - 'CONSTRAINT my_fk FOREIGN KEY (foreign_id)' - . ' REFERENCES my_table (id) DEFERRABLE INITIALLY IMMEDIATE', + 'CONSTRAINT "my_fk" FOREIGN KEY ("foreign_id")' + . ' REFERENCES "my_table" ("id") DEFERRABLE INITIALLY IMMEDIATE', $this->platform->getForeignKeyDeclarationSQL($foreignKey), ); @@ -103,8 +103,8 @@ public function testGeneratesForeignKeySqlForNonStandardOptions(): void ['deferred' => true], ); self::assertEquals( - 'CONSTRAINT my_fk FOREIGN KEY (foreign_id)' - . ' REFERENCES my_table (id) NOT DEFERRABLE INITIALLY DEFERRED', + 'CONSTRAINT "my_fk" FOREIGN KEY ("foreign_id")' + . ' REFERENCES "my_table" ("id") NOT DEFERRABLE INITIALLY DEFERRED', $this->platform->getForeignKeyDeclarationSQL($foreignKey), ); @@ -116,8 +116,8 @@ public function testGeneratesForeignKeySqlForNonStandardOptions(): void ['deferred' => true], ); self::assertEquals( - 'CONSTRAINT my_fk FOREIGN KEY (foreign_id)' - . ' REFERENCES my_table (id) NOT DEFERRABLE INITIALLY DEFERRED', + 'CONSTRAINT "my_fk" FOREIGN KEY ("foreign_id")' + . ' REFERENCES "my_table" ("id") NOT DEFERRABLE INITIALLY DEFERRED', $this->platform->getForeignKeyDeclarationSQL($foreignKey), ); @@ -129,8 +129,8 @@ public function testGeneratesForeignKeySqlForNonStandardOptions(): void ['deferrable' => true, 'deferred' => true, 'match' => 'full'], ); self::assertEquals( - 'CONSTRAINT my_fk FOREIGN KEY (foreign_id)' - . ' REFERENCES my_table (id) MATCH full DEFERRABLE INITIALLY DEFERRED', + 'CONSTRAINT "my_fk" FOREIGN KEY ("foreign_id")' + . ' REFERENCES "my_table" ("id") MATCH full DEFERRABLE INITIALLY DEFERRED', $this->platform->getForeignKeyDeclarationSQL($foreignKey), ); } @@ -186,7 +186,7 @@ public function testGenerateTableWithAutoincrement(): void $column->setAutoincrement(true); self::assertEquals( - ['CREATE TABLE autoinc_table (id INT GENERATED BY DEFAULT AS IDENTITY NOT NULL)'], + ['CREATE TABLE "autoinc_table" ("id" INT GENERATED BY DEFAULT AS IDENTITY NOT NULL)'], $this->platform->getCreateTableSQL($table), ); } @@ -198,7 +198,7 @@ public function testGenerateUnloggedTable(): void $table->addColumn('foo', 'string'); self::assertEquals( - ['CREATE UNLOGGED TABLE mytable (foo VARCHAR NOT NULL)'], + ['CREATE UNLOGGED TABLE "mytable" ("foo" VARCHAR NOT NULL)'], $this->platform->getCreateTableSQL($table), ); } @@ -222,7 +222,7 @@ public function testGenerateTableWithAutoincrementDoesNotSetDefault(string $type $sql = $this->platform->getCreateTableSQL($table); - self::assertEquals([sprintf('CREATE TABLE autoinc_table_notnull (id %s)', $definition)], $sql); + self::assertEquals([sprintf('CREATE TABLE "autoinc_table_notnull" ("id" %s)', $definition)], $sql); } #[DataProvider('serialTypes')] @@ -235,7 +235,10 @@ public function testCreateTableWithAutoincrementAndNotNullAddsConstraint(string $sql = $this->platform->getCreateTableSQL($table); - self::assertEquals([sprintf('CREATE TABLE autoinc_table_notnull_enabled (id %s NOT NULL)', $definition)], $sql); + self::assertEquals( + [sprintf('CREATE TABLE "autoinc_table_notnull_enabled" ("id" %s NOT NULL)', $definition)], + $sql, + ); } #[DataProvider('serialTypes')] @@ -272,19 +275,19 @@ public function testGeneratesTypeDeclarationForIntegers(): void public function getGenerateUniqueIndexSql(): string { - return 'CREATE UNIQUE INDEX index_name ON test (test, test2)'; + return 'CREATE UNIQUE INDEX "index_name" ON test ("test", "test2")'; } public function testGeneratesSequenceSqlCommands(): void { $sequence = new Sequence('myseq', 20, 1); self::assertEquals( - 'CREATE SEQUENCE myseq INCREMENT BY 20 MINVALUE 1 START 1', + 'CREATE SEQUENCE "myseq" INCREMENT BY 20 MINVALUE 1 START 1', $this->platform->getCreateSequenceSQL($sequence), ); self::assertEquals( - 'DROP SEQUENCE myseq CASCADE', - $this->platform->getDropSequenceSQL('myseq'), + 'DROP SEQUENCE "myseq" CASCADE', + $this->platform->getDropSequenceSQL($sequence->getQuotedName($this->platform)), ); self::assertEquals( "SELECT NEXTVAL('myseq')", @@ -339,7 +342,7 @@ protected function getQuotedColumnInIndexSQL(): array { return [ 'CREATE TABLE "quoted" ("create" VARCHAR(255) NOT NULL)', - 'CREATE INDEX IDX_22660D028FD6E0FB ON "quoted" ("create")', + 'CREATE INDEX "idx_22660d028fd6e0fb" ON "quoted" ("create")', ]; } @@ -349,8 +352,8 @@ protected function getQuotedColumnInIndexSQL(): array protected function getQuotedNameInIndexSQL(): array { return [ - 'CREATE TABLE test (column1 VARCHAR(255) NOT NULL)', - 'CREATE INDEX "key" ON test (column1)', + 'CREATE TABLE "test" ("column1" VARCHAR(255) NOT NULL)', + 'CREATE INDEX "key" ON "test" ("column1")', ]; } @@ -361,14 +364,14 @@ protected function getQuotedColumnInForeignKeySQL(): array { return [ 'CREATE TABLE "quoted" ("create" VARCHAR(255) NOT NULL, ' - . 'foo VARCHAR(255) NOT NULL, "bar" VARCHAR(255) NOT NULL)', - 'CREATE INDEX IDX_22660D028FD6E0FB8C736521D79164E3 ON "quoted" ("create", foo, "bar")', - 'ALTER TABLE "quoted" ADD CONSTRAINT FK_WITH_RESERVED_KEYWORD FOREIGN KEY ("create", foo, "bar")' - . ' REFERENCES "foreign" ("create", bar, "foo-bar") NOT DEFERRABLE INITIALLY IMMEDIATE', - 'ALTER TABLE "quoted" ADD CONSTRAINT FK_WITH_NON_RESERVED_KEYWORD FOREIGN KEY ("create", foo, "bar")' - . ' REFERENCES foo ("create", bar, "foo-bar") NOT DEFERRABLE INITIALLY IMMEDIATE', - 'ALTER TABLE "quoted" ADD CONSTRAINT FK_WITH_INTENDED_QUOTATION FOREIGN KEY ("create", foo, "bar")' - . ' REFERENCES "foo-bar" ("create", bar, "foo-bar") NOT DEFERRABLE INITIALLY IMMEDIATE', + . '"foo" VARCHAR(255) NOT NULL, "bar" VARCHAR(255) NOT NULL)', + 'CREATE INDEX "idx_22660d028fd6e0fb8c736521d79164e3" ON "quoted" ("create", "foo", "bar")', + 'ALTER TABLE "quoted" ADD CONSTRAINT "fk_with_reserved_keyword" FOREIGN KEY ("create", "foo", "bar")' + . ' REFERENCES "foreign" ("create", "bar", "foo-bar") NOT DEFERRABLE INITIALLY IMMEDIATE', + 'ALTER TABLE "quoted" ADD CONSTRAINT "fk_with_non_reserved_keyword" FOREIGN KEY ("create", "foo", "bar")' + . ' REFERENCES "foo" ("create", "bar", "foo-bar") NOT DEFERRABLE INITIALLY IMMEDIATE', + 'ALTER TABLE "quoted" ADD CONSTRAINT "fk_with_intended_quotation" FOREIGN KEY ("create", "foo", "bar")' + . ' REFERENCES "foo-bar" ("create", "bar", "foo-bar") NOT DEFERRABLE INITIALLY IMMEDIATE', ]; } @@ -450,19 +453,17 @@ public function testDroppingConstraintsBeforeColumns(): void $sql = $this->platform->getAlterTableSQL($diff); $expectedSql = [ - 'ALTER TABLE mytable DROP CONSTRAINT FK_6B2BD609727ACA70', - 'DROP INDEX IDX_6B2BD609727ACA70', - 'ALTER TABLE mytable DROP parent_id', + 'ALTER TABLE "mytable" DROP CONSTRAINT "fk_6b2bd609727aca70"', + 'DROP INDEX "idx_6b2bd609727aca70"', + 'ALTER TABLE "mytable" DROP "parent_id"', ]; self::assertEquals($expectedSql, $sql); } - /** @param list $expectedSql */ - #[DataProvider('dropPrimaryKeyProvider')] - public function testDroppingPrimaryKey(string $tableName, array $expectedSql): void + public function testDroppingPrimaryKey(): void { - $oldTable = new Table($tableName); + $oldTable = new Table('test'); $oldTable->addColumn('id', 'integer'); $oldTable->setPrimaryKey(['id']); @@ -474,16 +475,9 @@ public function testDroppingPrimaryKey(string $tableName, array $expectedSql): v $sql = $this->platform->getAlterTableSQL($diff); - self::assertEquals($expectedSql, $sql); - } + $expectedSql = ['ALTER TABLE "test" DROP CONSTRAINT "test_pkey"']; - /** @return iterable}> */ - public static function dropPrimaryKeyProvider(): iterable - { - return [ - ['test', ['ALTER TABLE test DROP CONSTRAINT test_pkey']], - ['"test"', ['ALTER TABLE "test" DROP CONSTRAINT "test_pkey"']], - ]; + self::assertEquals($expectedSql, $sql); } #[DataProvider('dataCreateSequenceWithCache')] @@ -575,7 +569,7 @@ public function testDoesNotPropagateUnnecessaryTableAlterationOnBinaryType(): vo */ protected function getAlterTableRenameIndexSQL(): array { - return ['ALTER INDEX idx_foo RENAME TO idx_bar']; + return ['ALTER INDEX "idx_foo" RENAME TO "idx_bar"']; } /** @@ -619,7 +613,7 @@ public static function pgBooleanProvider(): iterable */ protected function getAlterTableRenameIndexInSchemaSQL(): array { - return ['ALTER INDEX myschema.idx_foo RENAME TO idx_bar']; + return ['ALTER INDEX "myschema"."idx_foo" RENAME TO "idx_bar"']; } /** @@ -633,6 +627,16 @@ protected function getQuotedAlterTableRenameIndexInSchemaSQL(): array ]; } + protected function getQuotedCommentOnColumnSQLWithoutQuoteCharacter(): string + { + return "COMMENT ON COLUMN \"mytable\".\"id\" IS 'This is a comment'"; + } + + protected function getQuotedCommentOnColumnSQLWithQuoteCharacter(): string + { + return "COMMENT ON COLUMN \"mytable\".\"id\" IS 'It''s a quote !'"; + } + public function testReturnsGuidTypeDeclarationSQL(): void { self::assertSame('UUID', $this->platform->getGuidTypeDeclarationSQL([])); @@ -644,7 +648,7 @@ public function testReturnsGuidTypeDeclarationSQL(): void protected function getCommentOnColumnSQL(): array { return [ - 'COMMENT ON COLUMN foo.bar IS \'comment\'', + 'COMMENT ON COLUMN "foo"."bar" IS \'comment\'', 'COMMENT ON COLUMN "Foo"."BAR" IS \'comment\'', 'COMMENT ON COLUMN "select"."from" IS \'comment\'', ]; @@ -671,7 +675,7 @@ protected function getQuotesReservedKeywordInUniqueConstraintDeclarationSQL(): s protected function getQuotesReservedKeywordInIndexDeclarationSQL(): string { - return 'INDEX "select" (foo)'; + return 'INDEX "select" ("foo")'; } protected function getQuotesReservedKeywordInTruncateTableSQL(): string @@ -684,7 +688,7 @@ protected function getQuotesReservedKeywordInTruncateTableSQL(): string */ protected function getAlterStringToFixedStringSQL(): array { - return ['ALTER TABLE mytable ALTER name TYPE CHAR(2)']; + return ['ALTER TABLE "mytable" ALTER "name" TYPE CHAR(2)']; } /** @@ -692,7 +696,7 @@ protected function getAlterStringToFixedStringSQL(): array */ protected function getGeneratesAlterTableRenameIndexUsedByForeignKeySQL(): array { - return ['ALTER INDEX idx_foo RENAME TO idx_foo_renamed']; + return ['ALTER INDEX "idx_foo" RENAME TO "idx_foo_renamed"']; } public function testInitializesTsvectorTypeMapping(): void @@ -713,8 +717,8 @@ public function testGetCreateTableSQLWithUniqueConstraints(): void $table->addUniqueConstraint(['id'], 'test_unique_constraint'); self::assertSame( [ - 'CREATE TABLE foo (id VARCHAR NOT NULL)', - 'ALTER TABLE foo ADD CONSTRAINT test_unique_constraint UNIQUE (id)', + 'CREATE TABLE "foo" ("id" VARCHAR NOT NULL)', + 'ALTER TABLE "foo" ADD CONSTRAINT "test_unique_constraint" UNIQUE ("id")', ], $this->platform->getCreateTableSQL($table), 'Unique constraints are added to table.', @@ -728,8 +732,8 @@ public function testGetCreateTableSQLWithColumnCollation(): void $table->addOption('comment', 'foo'); self::assertSame( [ - 'CREATE TABLE foo (id VARCHAR NOT NULL)', - "COMMENT ON TABLE foo IS 'foo'", + 'CREATE TABLE "foo" ("id" VARCHAR NOT NULL)', + "COMMENT ON TABLE \"foo\" IS 'foo'", ], $this->platform->getCreateTableSQL($table), 'Comments are added to table.', diff --git a/tests/Platforms/SQLServerPlatformTest.php b/tests/Platforms/SQLServerPlatformTest.php index 5635f3ed572..f6c6d90d005 100644 --- a/tests/Platforms/SQLServerPlatformTest.php +++ b/tests/Platforms/SQLServerPlatformTest.php @@ -38,7 +38,7 @@ protected function createComparator(): Comparator public function getGenerateTableSql(): string { - return 'CREATE TABLE test (id INT IDENTITY NOT NULL, test NVARCHAR(255), PRIMARY KEY (id))'; + return 'CREATE TABLE [test] ([id] INT IDENTITY NOT NULL, [test] NVARCHAR(255), PRIMARY KEY ([id]))'; } /** @@ -47,9 +47,9 @@ public function getGenerateTableSql(): string public function getGenerateTableWithMultiColumnUniqueIndexSql(): array { return [ - 'CREATE TABLE test (foo NVARCHAR(255), bar NVARCHAR(255))', - 'CREATE UNIQUE INDEX UNIQ_D87F7E0C8C73652176FF8CAA ON test (foo, bar)' - . ' WHERE foo IS NOT NULL AND bar IS NOT NULL', + 'CREATE TABLE [test] ([foo] NVARCHAR(255), [bar] NVARCHAR(255))', + 'CREATE UNIQUE INDEX [UNIQ_D87F7E0C8C73652176FF8CAA] ON [test] ([foo], [bar])' + . ' WHERE [foo] IS NOT NULL AND [bar] IS NOT NULL', ]; } @@ -165,17 +165,18 @@ public function testDoesNotSupportSavePoints(): void public function getGenerateIndexSql(): string { - return 'CREATE INDEX my_idx ON mytable (user_name, last_login)'; + return 'CREATE INDEX [my_idx] ON mytable ([user_name], [last_login])'; } public function getGenerateUniqueIndexSql(): string { - return 'CREATE UNIQUE INDEX index_name ON test (test, test2) WHERE test IS NOT NULL AND test2 IS NOT NULL'; + return 'CREATE UNIQUE INDEX [index_name] ON test ([test], [test2]) WHERE [test] IS NOT NULL' + . ' AND [test2] IS NOT NULL'; } protected function getGenerateForeignKeySql(): string { - return 'ALTER TABLE test ADD FOREIGN KEY (fk_name_id) REFERENCES other_table (id)'; + return 'ALTER TABLE test ADD FOREIGN KEY ([fk_name_id]) REFERENCES [other_table] ([id])'; } public function testModifyLimitQuery(): void @@ -557,7 +558,10 @@ public function testCreateClusteredIndex(): void { $idx = new Index('idx', ['id']); $idx->addFlag('clustered'); - self::assertEquals('CREATE CLUSTERED INDEX idx ON tbl (id)', $this->platform->getCreateIndexSQL($idx, 'tbl')); + self::assertEquals( + 'CREATE CLUSTERED INDEX [idx] ON tbl ([id])', + $this->platform->getCreateIndexSQL($idx, 'tbl'), + ); } public function testCreateNonClusteredPrimaryKeyInTable(): void @@ -568,7 +572,7 @@ public function testCreateNonClusteredPrimaryKeyInTable(): void $table->getIndex('primary')->addFlag('nonclustered'); self::assertEquals( - ['CREATE TABLE tbl (id INT NOT NULL, PRIMARY KEY NONCLUSTERED (id))'], + ['CREATE TABLE [tbl] ([id] INT NOT NULL, PRIMARY KEY NONCLUSTERED ([id]))'], $this->platform->getCreateTableSQL($table), ); } @@ -578,7 +582,7 @@ public function testCreateNonClusteredPrimaryKey(): void $idx = new Index('idx', ['id'], false, true); $idx->addFlag('nonclustered'); self::assertEquals( - 'ALTER TABLE tbl ADD PRIMARY KEY NONCLUSTERED (id)', + 'ALTER TABLE tbl ADD PRIMARY KEY NONCLUSTERED ([id])', $this->platform->getCreatePrimaryKeySQL($idx, 'tbl'), ); } @@ -586,7 +590,7 @@ public function testCreateNonClusteredPrimaryKey(): void public function testAlterAddPrimaryKey(): void { $idx = new Index('idx', ['id'], false, true); - self::assertEquals('ALTER TABLE tbl ADD PRIMARY KEY (id)', $this->platform->getCreateIndexSQL($idx, 'tbl')); + self::assertEquals('ALTER TABLE tbl ADD PRIMARY KEY ([id])', $this->platform->getCreateIndexSQL($idx, 'tbl')); } /** @@ -604,7 +608,7 @@ protected function getQuotedColumnInIndexSQL(): array { return [ 'CREATE TABLE [quoted] ([create] NVARCHAR(255) NOT NULL)', - 'CREATE INDEX IDX_22660D028FD6E0FB ON [quoted] ([create])', + 'CREATE INDEX [IDX_22660D028FD6E0FB] ON [quoted] ([create])', ]; } @@ -614,8 +618,8 @@ protected function getQuotedColumnInIndexSQL(): array protected function getQuotedNameInIndexSQL(): array { return [ - 'CREATE TABLE test (column1 NVARCHAR(255) NOT NULL)', - 'CREATE INDEX [key] ON test (column1)', + 'CREATE TABLE [test] ([column1] NVARCHAR(255) NOT NULL)', + 'CREATE INDEX [key] ON [test] ([column1])', ]; } @@ -626,14 +630,14 @@ protected function getQuotedColumnInForeignKeySQL(): array { return [ 'CREATE TABLE [quoted] ([create] NVARCHAR(255) NOT NULL, ' - . 'foo NVARCHAR(255) NOT NULL, [bar] NVARCHAR(255) NOT NULL)', - 'CREATE INDEX IDX_22660D028FD6E0FB8C736521D79164E3 ON [quoted] ([create], foo, [bar])', - 'ALTER TABLE [quoted] ADD CONSTRAINT FK_WITH_RESERVED_KEYWORD' - . ' FOREIGN KEY ([create], foo, [bar]) REFERENCES [foreign] ([create], bar, [foo-bar])', - 'ALTER TABLE [quoted] ADD CONSTRAINT FK_WITH_NON_RESERVED_KEYWORD' - . ' FOREIGN KEY ([create], foo, [bar]) REFERENCES foo ([create], bar, [foo-bar])', - 'ALTER TABLE [quoted] ADD CONSTRAINT FK_WITH_INTENDED_QUOTATION' - . ' FOREIGN KEY ([create], foo, [bar]) REFERENCES [foo-bar] ([create], bar, [foo-bar])', + . '[foo] NVARCHAR(255) NOT NULL, [bar] NVARCHAR(255) NOT NULL)', + 'CREATE INDEX [IDX_22660D028FD6E0FB8C736521D79164E3] ON [quoted] ([create], [foo], [bar])', + 'ALTER TABLE [quoted] ADD CONSTRAINT [FK_WITH_RESERVED_KEYWORD]' + . ' FOREIGN KEY ([create], [foo], [bar]) REFERENCES [foreign] ([create], [bar], [foo-bar])', + 'ALTER TABLE [quoted] ADD CONSTRAINT [FK_WITH_NON_RESERVED_KEYWORD]' + . ' FOREIGN KEY ([create], [foo], [bar]) REFERENCES [foo] ([create], [bar], [foo-bar])', + 'ALTER TABLE [quoted] ADD CONSTRAINT [FK_WITH_INTENDED_QUOTATION]' + . ' FOREIGN KEY ([create], [foo], [bar]) REFERENCES [foo-bar] ([create], [bar], [foo-bar])', ]; } @@ -651,7 +655,7 @@ public function testCreateTableWithSchemaColumnComments(): void $table->setPrimaryKey(['id']); $expectedSql = [ - 'CREATE TABLE testschema.test (id INT NOT NULL, PRIMARY KEY (id))', + 'CREATE TABLE [testschema].[test] ([id] INT NOT NULL, PRIMARY KEY ([id]))', "EXEC sp_addextendedproperty N'MS_Description', N'This is a comment', " . "N'SCHEMA', 'testschema', N'TABLE', 'test', N'COLUMN', 'id'", ]; @@ -672,7 +676,7 @@ public function testAlterTableWithSchemaColumnComments(): void ]); $expectedSql = [ - 'ALTER TABLE testschema.mytable ADD quota INT NOT NULL', + 'ALTER TABLE [testschema].[mytable] ADD [quota] INT NOT NULL', "EXEC sp_addextendedproperty N'MS_Description', N'A comment', " . "N'SCHEMA', 'testschema', N'TABLE', 'mytable', N'COLUMN', 'quota'", ]; @@ -835,7 +839,7 @@ public function testGetVariableLengthBinaryTypeDeclarationSQLNoLength(): void */ protected function getAlterTableRenameIndexSQL(): array { - return ["EXEC sp_rename N'mytable.idx_foo', N'idx_bar', N'INDEX'"]; + return ["EXEC sp_rename N'[mytable].[idx_foo]', N'idx_bar', N'INDEX'"]; } /** @@ -849,12 +853,22 @@ protected function getQuotedAlterTableRenameIndexSQL(): array ]; } + protected function getQuotedCommentOnColumnSQLWithoutQuoteCharacter(): string + { + return "COMMENT ON COLUMN [mytable].[id] IS 'This is a comment'"; + } + + protected function getQuotedCommentOnColumnSQLWithQuoteCharacter(): string + { + return "COMMENT ON COLUMN [mytable].[id] IS 'It''s a quote !'"; + } + /** * {@inheritDoc} */ protected function getAlterTableRenameIndexInSchemaSQL(): array { - return ["EXEC sp_rename N'myschema.mytable.idx_foo', N'idx_bar', N'INDEX'"]; + return ["EXEC sp_rename N'[myschema].[mytable].[idx_foo]', N'idx_bar', N'INDEX'"]; } /** @@ -879,7 +893,7 @@ public function testReturnsGuidTypeDeclarationSQL(): void protected function getCommentOnColumnSQL(): array { return [ - "COMMENT ON COLUMN foo.bar IS 'comment'", + "COMMENT ON COLUMN [foo].[bar] IS 'comment'", "COMMENT ON COLUMN [Foo].[BAR] IS 'comment'", "COMMENT ON COLUMN [select].[from] IS 'comment'", ]; @@ -907,7 +921,7 @@ protected function getQuotesReservedKeywordInUniqueConstraintDeclarationSQL(): s protected function getQuotesReservedKeywordInIndexDeclarationSQL(): string { - return 'INDEX [select] (foo)'; + return 'INDEX [select] ([foo])'; } protected function getQuotesReservedKeywordInTruncateTableSQL(): string @@ -920,7 +934,7 @@ protected function getQuotesReservedKeywordInTruncateTableSQL(): string */ protected function getAlterStringToFixedStringSQL(): array { - return ['ALTER TABLE mytable ALTER COLUMN name NCHAR(2) NOT NULL']; + return ['ALTER TABLE [mytable] ALTER COLUMN [name] NCHAR(2) NOT NULL']; } /** @@ -928,7 +942,7 @@ protected function getAlterStringToFixedStringSQL(): array */ protected function getGeneratesAlterTableRenameIndexUsedByForeignKeySQL(): array { - return ["EXEC sp_rename N'mytable.idx_foo', N'idx_foo_renamed', N'INDEX'"]; + return ["EXEC sp_rename N'[mytable].[idx_foo]', N'idx_foo_renamed', N'INDEX'"]; } protected function getLimitOffsetCastToIntExpectedQuery(): string @@ -1047,8 +1061,8 @@ public function testGetCreateTableSQLWithColumnCollation(): void ->setPlatformOption('collation', 'Latin1_General_CS_AS_KS_WS'); self::assertSame( - ['CREATE TABLE foo (no_collation NVARCHAR(255) NOT NULL, ' - . 'column_collation NVARCHAR(255) COLLATE Latin1_General_CS_AS_KS_WS NOT NULL)', + ['CREATE TABLE [foo] ([no_collation] NVARCHAR(255) NOT NULL, ' + . '[column_collation] NVARCHAR(255) COLLATE Latin1_General_CS_AS_KS_WS NOT NULL)', ], $this->platform->getCreateTableSQL($table), ); @@ -1063,16 +1077,16 @@ public function testGeneratesSequenceSqlCommands(): void { $sequence = new Sequence('myseq', 20, 1); self::assertEquals( - 'CREATE SEQUENCE myseq START WITH 1 INCREMENT BY 20 MINVALUE 1', + 'CREATE SEQUENCE [myseq] START WITH 1 INCREMENT BY 20 MINVALUE 1', $this->platform->getCreateSequenceSQL($sequence), ); self::assertEquals( - 'ALTER SEQUENCE myseq INCREMENT BY 20', + 'ALTER SEQUENCE [myseq] INCREMENT BY 20', $this->platform->getAlterSequenceSQL($sequence), ); self::assertEquals( - 'DROP SEQUENCE myseq', - $this->platform->getDropSequenceSQL('myseq'), + 'DROP SEQUENCE [myseq]', + $this->platform->getDropSequenceSQL($sequence->getQuotedName($this->platform)), ); self::assertEquals( 'SELECT NEXT VALUE FOR myseq', @@ -1091,7 +1105,7 @@ public function testAlterTableWithSchemaSameColumnComments(): void ), ]); - $expectedSql = ['ALTER TABLE testschema.mytable ALTER COLUMN quota INT NOT NULL']; + $expectedSql = ['ALTER TABLE [testschema].[mytable] ALTER COLUMN [quota] INT NOT NULL']; self::assertEquals($expectedSql, $this->platform->getAlterTableSQL($tableDiff)); } diff --git a/tests/Platforms/SQLitePlatformTest.php b/tests/Platforms/SQLitePlatformTest.php index 2724026f92f..4ee351e896b 100644 --- a/tests/Platforms/SQLitePlatformTest.php +++ b/tests/Platforms/SQLitePlatformTest.php @@ -36,7 +36,8 @@ protected function createComparator(): Comparator public function getGenerateTableSql(): string { - return 'CREATE TABLE test (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, test VARCHAR(255) DEFAULT NULL)'; + return 'CREATE TABLE "test" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL' + . ', "test" VARCHAR(255) DEFAULT NULL)'; } /** @@ -45,8 +46,8 @@ public function getGenerateTableSql(): string public function getGenerateTableWithMultiColumnUniqueIndexSql(): array { return [ - 'CREATE TABLE test (foo VARCHAR(255) DEFAULT NULL, bar VARCHAR(255) DEFAULT NULL)', - 'CREATE UNIQUE INDEX UNIQ_D87F7E0C8C73652176FF8CAA ON test (foo, bar)', + 'CREATE TABLE "test" ("foo" VARCHAR(255) DEFAULT NULL, "bar" VARCHAR(255) DEFAULT NULL)', + 'CREATE UNIQUE INDEX "UNIQ_D87F7E0C8C73652176FF8CAA" ON "test" ("foo", "bar")', ]; } @@ -173,12 +174,12 @@ public function testGeneratesTypeDeclarationForBigIntegers(): void public function getGenerateIndexSql(): string { - return 'CREATE INDEX my_idx ON mytable (user_name, last_login)'; + return 'CREATE INDEX "my_idx" ON mytable ("user_name", "last_login")'; } public function getGenerateUniqueIndexSql(): string { - return 'CREATE UNIQUE INDEX index_name ON test (test, test2)'; + return 'CREATE UNIQUE INDEX "index_name" ON test ("test", "test2")'; } public function testGeneratesIndexCreationSqlWithSchema(): void @@ -186,7 +187,7 @@ public function testGeneratesIndexCreationSqlWithSchema(): void $indexDef = new Index('i', ['a', 'b']); self::assertSame( - 'CREATE INDEX main.i ON mytable (a, b)', + 'CREATE INDEX main."i" ON mytable ("a", "b")', $this->platform->getCreateIndexSQL($indexDef, 'main.mytable'), ); } @@ -245,7 +246,7 @@ public function testGenerateTableSqlShouldNotAutoQuotePrimaryKey(): void $createTableSQL = $this->platform->getCreateTableSQL($table); self::assertEquals( - 'CREATE TABLE test ("like" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)', + 'CREATE TABLE "test" ("like" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)', $createTableSQL[0], ); } @@ -263,8 +264,8 @@ public function testAlterTableAddColumns(): void ]); $expected = [ - 'ALTER TABLE user ADD COLUMN foo VARCHAR NOT NULL', - 'ALTER TABLE user ADD COLUMN count INTEGER DEFAULT 1', + 'ALTER TABLE "user" ADD COLUMN "foo" VARCHAR NOT NULL', + 'ALTER TABLE "user" ADD COLUMN "count" INTEGER DEFAULT 1', ]; self::assertEquals($expected, $this->platform->getAlterTableSQL($diff)); @@ -299,19 +300,19 @@ public function testCreateTableWithDeferredForeignKeys(): void $table->addForeignKeyConstraint('user', ['parent'], ['id'], ['deferrable' => true, 'deferred' => true]); $sql = [ - 'CREATE TABLE user (' - . 'id INTEGER NOT NULL, article INTEGER NOT NULL, post INTEGER NOT NULL, parent INTEGER NOT NULL' - . ', PRIMARY KEY(id)' - . ', CONSTRAINT FK_8D93D64923A0E66 FOREIGN KEY (article)' - . ' REFERENCES article (id) DEFERRABLE INITIALLY IMMEDIATE' - . ', CONSTRAINT FK_8D93D6495A8A6C8D FOREIGN KEY (post)' - . ' REFERENCES post (id) NOT DEFERRABLE INITIALLY DEFERRED' - . ', CONSTRAINT FK_8D93D6493D8E604F FOREIGN KEY (parent)' - . ' REFERENCES user (id) DEFERRABLE INITIALLY DEFERRED' + 'CREATE TABLE "user" (' + . '"id" INTEGER NOT NULL, "article" INTEGER NOT NULL, "post" INTEGER NOT NULL' + . ', "parent" INTEGER NOT NULL, PRIMARY KEY("id")' + . ', CONSTRAINT "FK_8D93D64923A0E66" FOREIGN KEY ("article")' + . ' REFERENCES "article" ("id") DEFERRABLE INITIALLY IMMEDIATE' + . ', CONSTRAINT "FK_8D93D6495A8A6C8D" FOREIGN KEY ("post")' + . ' REFERENCES "post" ("id") NOT DEFERRABLE INITIALLY DEFERRED' + . ', CONSTRAINT "FK_8D93D6493D8E604F" FOREIGN KEY ("parent")' + . ' REFERENCES "user" ("id") DEFERRABLE INITIALLY DEFERRED' . ')', - 'CREATE INDEX IDX_8D93D64923A0E66 ON user (article)', - 'CREATE INDEX IDX_8D93D6495A8A6C8D ON user (post)', - 'CREATE INDEX IDX_8D93D6493D8E604F ON user (parent)', + 'CREATE INDEX "IDX_8D93D64923A0E66" ON "user" ("article")', + 'CREATE INDEX "IDX_8D93D6495A8A6C8D" ON "user" ("post")', + 'CREATE INDEX "IDX_8D93D6493D8E604F" ON "user" ("parent")', ]; self::assertEquals($sql, $this->platform->getCreateTableSQL($table)); @@ -351,20 +352,20 @@ public function testAlterTable(): void ); $sql = [ - 'CREATE TEMPORARY TABLE __temp__user AS SELECT id, article, post FROM user', - 'DROP TABLE user', - 'CREATE TABLE user (' - . '"key" INTEGER NOT NULL, article INTEGER NOT NULL, comment INTEGER NOT NULL' + 'CREATE TEMPORARY TABLE "__temp__user" AS SELECT "id", "article", "post" FROM "user"', + 'DROP TABLE "user"', + 'CREATE TABLE "user" (' + . '"key" INTEGER NOT NULL, "article" INTEGER NOT NULL, "comment" INTEGER NOT NULL' . ', PRIMARY KEY("key")' - . ', CONSTRAINT FK_8D93D64923A0E66 FOREIGN KEY (article)' - . ' REFERENCES article (id) DEFERRABLE INITIALLY IMMEDIATE' - . ', CONSTRAINT FK_8D93D6495A8A6C8D FOREIGN KEY (comment)' - . ' REFERENCES post (id) NOT DEFERRABLE INITIALLY DEFERRED' + . ', CONSTRAINT "FK_8D93D64923A0E66" FOREIGN KEY ("article")' + . ' REFERENCES "article" ("id") DEFERRABLE INITIALLY IMMEDIATE' + . ', CONSTRAINT "FK_8D93D6495A8A6C8D" FOREIGN KEY ("comment")' + . ' REFERENCES "post" ("id") NOT DEFERRABLE INITIALLY DEFERRED' . ')', - 'INSERT INTO user ("key", article, comment) SELECT id, article, post FROM __temp__user', - 'DROP TABLE __temp__user', - 'CREATE INDEX IDX_8D93D64923A0E66 ON user (article)', - 'CREATE INDEX IDX_8D93D6495A8A6C8D ON user (comment)', + 'INSERT INTO "user" ("key", "article", "comment") SELECT "id", "article", "post" FROM "__temp__user"', + 'DROP TABLE "__temp__user"', + 'CREATE INDEX "IDX_8D93D64923A0E66" ON "user" ("article")', + 'CREATE INDEX "IDX_8D93D6495A8A6C8D" ON "user" ("comment")', ]; self::assertEquals($sql, $this->platform->getAlterTableSQL($diff)); @@ -385,7 +386,7 @@ protected function getQuotedColumnInIndexSQL(): array { return [ 'CREATE TABLE "quoted" ("create" VARCHAR(255) NOT NULL)', - 'CREATE INDEX IDX_22660D028FD6E0FB ON "quoted" ("create")', + 'CREATE INDEX "IDX_22660D028FD6E0FB" ON "quoted" ("create")', ]; } @@ -395,8 +396,8 @@ protected function getQuotedColumnInIndexSQL(): array protected function getQuotedNameInIndexSQL(): array { return [ - 'CREATE TABLE test (column1 VARCHAR(255) NOT NULL)', - 'CREATE INDEX "key" ON test (column1)', + 'CREATE TABLE "test" ("column1" VARCHAR(255) NOT NULL)', + 'CREATE INDEX "key" ON "test" ("column1")', ]; } @@ -407,14 +408,14 @@ protected function getQuotedColumnInForeignKeySQL(): array { return [ 'CREATE TABLE "quoted" (' . - '"create" VARCHAR(255) NOT NULL, foo VARCHAR(255) NOT NULL, "bar" VARCHAR(255) NOT NULL, ' . - 'CONSTRAINT FK_WITH_RESERVED_KEYWORD FOREIGN KEY ("create", foo, "bar") ' . - 'REFERENCES "foreign" ("create", bar, "foo-bar") NOT DEFERRABLE INITIALLY IMMEDIATE, ' . - 'CONSTRAINT FK_WITH_NON_RESERVED_KEYWORD FOREIGN KEY ("create", foo, "bar") ' . - 'REFERENCES foo ("create", bar, "foo-bar") NOT DEFERRABLE INITIALLY IMMEDIATE, ' . - 'CONSTRAINT FK_WITH_INTENDED_QUOTATION FOREIGN KEY ("create", foo, "bar") ' . - 'REFERENCES "foo-bar" ("create", bar, "foo-bar") NOT DEFERRABLE INITIALLY IMMEDIATE)', - 'CREATE INDEX IDX_22660D028FD6E0FB8C736521D79164E3 ON "quoted" ("create", foo, "bar")', + '"create" VARCHAR(255) NOT NULL, "foo" VARCHAR(255) NOT NULL, "bar" VARCHAR(255) NOT NULL, ' . + 'CONSTRAINT "FK_WITH_RESERVED_KEYWORD" FOREIGN KEY ("create", "foo", "bar") ' . + 'REFERENCES "foreign" ("create", "bar", "foo-bar") NOT DEFERRABLE INITIALLY IMMEDIATE, ' . + 'CONSTRAINT "FK_WITH_NON_RESERVED_KEYWORD" FOREIGN KEY ("create", "foo", "bar") ' . + 'REFERENCES "foo" ("create", "bar", "foo-bar") NOT DEFERRABLE INITIALLY IMMEDIATE, ' . + 'CONSTRAINT "FK_WITH_INTENDED_QUOTATION" FOREIGN KEY ("create", "foo", "bar") ' . + 'REFERENCES "foo-bar" ("create", "bar", "foo-bar") NOT DEFERRABLE INITIALLY IMMEDIATE)', + 'CREATE INDEX "IDX_22660D028FD6E0FB8C736521D79164E3" ON "quoted" ("create", "foo", "bar")', ]; } @@ -444,12 +445,12 @@ public function getExpectedVariableLengthBinaryTypeDeclarationSQLWithLength(): s protected function getAlterTableRenameIndexSQL(): array { return [ - 'CREATE TEMPORARY TABLE __temp__mytable AS SELECT id FROM mytable', - 'DROP TABLE mytable', - 'CREATE TABLE mytable (id INTEGER NOT NULL, PRIMARY KEY(id))', - 'INSERT INTO mytable (id) SELECT id FROM __temp__mytable', - 'DROP TABLE __temp__mytable', - 'CREATE INDEX idx_bar ON mytable (id)', + 'CREATE TEMPORARY TABLE "__temp__mytable" AS SELECT "id" FROM "mytable"', + 'DROP TABLE "mytable"', + 'CREATE TABLE "mytable" ("id" INTEGER NOT NULL, PRIMARY KEY("id"))', + 'INSERT INTO "mytable" ("id") SELECT "id" FROM "__temp__mytable"', + 'DROP TABLE "__temp__mytable"', + 'CREATE INDEX "idx_bar" ON "mytable" ("id")', ]; } @@ -459,16 +460,26 @@ protected function getAlterTableRenameIndexSQL(): array protected function getQuotedAlterTableRenameIndexSQL(): array { return [ - 'CREATE TEMPORARY TABLE __temp__table AS SELECT id FROM "table"', + 'CREATE TEMPORARY TABLE "__temp__table" AS SELECT "id" FROM "table"', 'DROP TABLE "table"', - 'CREATE TABLE "table" (id INTEGER NOT NULL, PRIMARY KEY(id))', - 'INSERT INTO "table" (id) SELECT id FROM __temp__table', - 'DROP TABLE __temp__table', - 'CREATE INDEX "select" ON "table" (id)', - 'CREATE INDEX "bar" ON "table" (id)', + 'CREATE TABLE "table" ("id" INTEGER NOT NULL, PRIMARY KEY("id"))', + 'INSERT INTO "table" ("id") SELECT "id" FROM "__temp__table"', + 'DROP TABLE "__temp__table"', + 'CREATE INDEX "select" ON "table" ("id")', + 'CREATE INDEX "bar" ON "table" ("id")', ]; } + protected function getQuotedCommentOnColumnSQLWithoutQuoteCharacter(): string + { + return "COMMENT ON COLUMN \"mytable\".\"id\" IS 'This is a comment'"; + } + + protected function getQuotedCommentOnColumnSQLWithQuoteCharacter(): string + { + return "COMMENT ON COLUMN \"mytable\".\"id\" IS 'It''s a quote !'"; + } + public function testAlterTableRenameIndexInSchema(): void { self::markTestIncomplete( @@ -503,11 +514,11 @@ public function testGeneratesAlterTableRenameColumnSQLWithSchema(): void ]); self::assertSame([ - 'CREATE TEMPORARY TABLE __temp__t AS SELECT a FROM main.t', - 'DROP TABLE main.t', - 'CREATE TABLE main.t (b INTEGER NOT NULL)', - 'INSERT INTO main.t (b) SELECT a FROM __temp__t', - 'DROP TABLE __temp__t', + 'CREATE TEMPORARY TABLE "__temp__t" AS SELECT "a" FROM "main"."t"', + 'DROP TABLE "main"."t"', + 'CREATE TABLE "main"."t" ("b" INTEGER NOT NULL)', + 'INSERT INTO "main"."t" ("b") SELECT "a" FROM "__temp__t"', + 'DROP TABLE "__temp__t"', ], $this->platform->getAlterTableSQL($tableDiff)); } @@ -517,7 +528,7 @@ public function testGeneratesAlterTableRenameColumnSQLWithSchema(): void protected function getCommentOnColumnSQL(): array { return [ - 'COMMENT ON COLUMN foo.bar IS \'comment\'', + 'COMMENT ON COLUMN "foo"."bar" IS \'comment\'', 'COMMENT ON COLUMN "Foo"."BAR" IS \'comment\'', 'COMMENT ON COLUMN "select"."from" IS \'comment\'', ]; @@ -550,7 +561,7 @@ protected function getQuotesReservedKeywordInUniqueConstraintDeclarationSQL(): s protected function getQuotesReservedKeywordInIndexDeclarationSQL(): string { - return 'INDEX "select" (foo)'; + return 'INDEX "select" ("foo")'; } protected function getQuotesReservedKeywordInTruncateTableSQL(): string @@ -564,11 +575,11 @@ protected function getQuotesReservedKeywordInTruncateTableSQL(): string protected function getAlterStringToFixedStringSQL(): array { return [ - 'CREATE TEMPORARY TABLE __temp__mytable AS SELECT name FROM mytable', - 'DROP TABLE mytable', - 'CREATE TABLE mytable (name CHAR(2) NOT NULL)', - 'INSERT INTO mytable (name) SELECT name FROM __temp__mytable', - 'DROP TABLE __temp__mytable', + 'CREATE TEMPORARY TABLE "__temp__mytable" AS SELECT "name" FROM "mytable"', + 'DROP TABLE "mytable"', + 'CREATE TABLE "mytable" ("name" CHAR(2) NOT NULL)', + 'INSERT INTO "mytable" ("name") SELECT "name" FROM "__temp__mytable"', + 'DROP TABLE "__temp__mytable"', ]; } @@ -578,17 +589,17 @@ protected function getAlterStringToFixedStringSQL(): array protected function getGeneratesAlterTableRenameIndexUsedByForeignKeySQL(): array { return [ - 'CREATE TEMPORARY TABLE __temp__mytable AS SELECT foo, bar, baz FROM mytable', - 'DROP TABLE mytable', - 'CREATE TABLE mytable (foo INTEGER NOT NULL, bar INTEGER NOT NULL, baz INTEGER NOT NULL, ' - . 'CONSTRAINT fk_foo FOREIGN KEY (foo) REFERENCES foreign_table (id)' + 'CREATE TEMPORARY TABLE "__temp__mytable" AS SELECT "foo", "bar", "baz" FROM "mytable"', + 'DROP TABLE "mytable"', + 'CREATE TABLE "mytable" ("foo" INTEGER NOT NULL, "bar" INTEGER NOT NULL, "baz" INTEGER NOT NULL, ' + . 'CONSTRAINT "fk_foo" FOREIGN KEY ("foo") REFERENCES "foreign_table" ("id")' . ' NOT DEFERRABLE INITIALLY IMMEDIATE, ' - . 'CONSTRAINT fk_bar FOREIGN KEY (bar) REFERENCES foreign_table (id)' + . 'CONSTRAINT "fk_bar" FOREIGN KEY ("bar") REFERENCES "foreign_table" ("id")' . ' NOT DEFERRABLE INITIALLY IMMEDIATE)', - 'INSERT INTO mytable (foo, bar, baz) SELECT foo, bar, baz FROM __temp__mytable', - 'DROP TABLE __temp__mytable', - 'CREATE INDEX idx_bar ON mytable (bar)', - 'CREATE INDEX idx_foo_renamed ON mytable (foo)', + 'INSERT INTO "mytable" ("foo", "bar", "baz") SELECT "foo", "bar", "baz" FROM "__temp__mytable"', + 'DROP TABLE "__temp__mytable"', + 'CREATE INDEX "idx_bar" ON "mytable" ("bar")', + 'CREATE INDEX "idx_foo_renamed" ON "mytable" ("foo")', ]; } @@ -630,8 +641,8 @@ public function testGetCreateTableSQLWithColumnCollation(): void self::assertSame( [ - 'CREATE TABLE foo (no_collation VARCHAR(255) NOT NULL, ' - . 'column_collation VARCHAR(255) NOT NULL COLLATE "NOCASE")', + 'CREATE TABLE "foo" ("no_collation" VARCHAR(255) NOT NULL, ' + . '"column_collation" VARCHAR(255) NOT NULL COLLATE "NOCASE")', ], $this->platform->getCreateTableSQL($table), ); diff --git a/tests/Schema/AbstractAssetTest.php b/tests/Schema/AbstractAssetTest.php index 09a405a7251..8feb6326271 100644 --- a/tests/Schema/AbstractAssetTest.php +++ b/tests/Schema/AbstractAssetTest.php @@ -4,90 +4,29 @@ namespace Doctrine\DBAL\Tests\Schema; -use Doctrine\DBAL\Platforms\AbstractPlatform; -use Doctrine\DBAL\Platforms\MySQLPlatform; -use Doctrine\DBAL\Platforms\OraclePlatform; -use Doctrine\DBAL\Platforms\PostgreSQLPlatform; +use Doctrine\DBAL\Schema\Exception\InvalidObjectName; use Doctrine\DBAL\Schema\Identifier; -use Doctrine\Deprecations\PHPUnit\VerifyDeprecations; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; class AbstractAssetTest extends TestCase { - use VerifyDeprecations; - - #[DataProvider('nameParsingDeprecationProvider')] - public function testNameParsingDeprecation(string $name, AbstractPlatform $platform): void + #[DataProvider('invalidNameProvider')] + public function testInvalidName(string $name): void { - $this->expectDeprecationWithIdentifier('https://github.com/doctrine/dbal/pull/6592'); - - $identifier = new Identifier($name); - $identifier->getQuotedName($platform); + $this->expectException(InvalidObjectName::class); + new Identifier($name); } - /** @return iterable */ - public static function nameParsingDeprecationProvider(): iterable + /** @return iterable */ + public static function invalidNameProvider(): iterable { return [ - // unquoted keywords not in normal case - ['select', new OraclePlatform()], - ['SELECT', new PostgreSQLPlatform()], - - // unquoted name not in normal case qualified by quoted name - ['"_".id', new OraclePlatform()], - ['"_".ID', new PostgreSQLPlatform()], - - // name with more than one qualifier - ['i.am.overqualified', new MySQLPlatform()], - // parse error - ['table.', new MySQLPlatform()], - ['"table', new MySQLPlatform()], - ['table"', new MySQLPlatform()], - [' ', new MySQLPlatform()], - - // incompatible parser behavior - ['"example.com"', new MySQLPlatform()], - ]; - } - - #[DataProvider('noNameParsingDeprecationProvider')] - public function testNoNameParsingDeprecation(string $name, AbstractPlatform $platform): void - { - $identifier = new Identifier($name); - - $this->expectNoDeprecationWithIdentifier('https://github.com/doctrine/dbal/pull/XXXX'); - $identifier->getQuotedName($platform); - } - - /** @return iterable */ - public static function noNameParsingDeprecationProvider(): iterable - { - return [ - // empty name - ['', new MySQLPlatform()], - - // name with one qualifier - ['schema.table', new MySQLPlatform()], - - // quoted keywords - ['"select"', new OraclePlatform()], - ['"SELECT"', new PostgreSQLPlatform()], - - // unquoted keywords in normal case - ['SELECT', new OraclePlatform()], - ['select', new PostgreSQLPlatform()], - - // unquoted keywords in any case on a platform that does not force a case - ['SELECT', new MySQLPlatform()], - ['select', new MySQLPlatform()], + [' '], - // non-keywords in any case - ['id', new OraclePlatform()], - ['ID', new OraclePlatform()], - ['id', new PostgreSQLPlatform()], - ['ID', new PostgreSQLPlatform()], + // too many qualifiers + ['i.am.overqualified'], ]; } } diff --git a/tests/Schema/MySQLInheritCharsetTest.php b/tests/Schema/MySQLInheritCharsetTest.php index e5eb64ea495..a33838fb243 100644 --- a/tests/Schema/MySQLInheritCharsetTest.php +++ b/tests/Schema/MySQLInheritCharsetTest.php @@ -43,7 +43,7 @@ public function testTableOptions(): void // no options $table = new Table('foobar', [new Column('aa', Type::getType(Types::INTEGER))]); self::assertSame( - ['CREATE TABLE foobar (aa INT NOT NULL)'], + ['CREATE TABLE `foobar` (`aa` INT NOT NULL)'], $platform->getCreateTableSQL($table), ); @@ -51,7 +51,7 @@ public function testTableOptions(): void $table = new Table('foobar', [new Column('aa', Type::getType(Types::INTEGER))]); $table->addOption('charset', 'utf8'); self::assertSame( - ['CREATE TABLE foobar (aa INT NOT NULL) DEFAULT CHARACTER SET utf8'], + ['CREATE TABLE `foobar` (`aa` INT NOT NULL) DEFAULT CHARACTER SET utf8'], $platform->getCreateTableSQL($table), ); } diff --git a/tests/Schema/Platforms/MySQLSchemaTest.php b/tests/Schema/Platforms/MySQLSchemaTest.php index 252808c2a00..2916c17daa2 100644 --- a/tests/Schema/Platforms/MySQLSchemaTest.php +++ b/tests/Schema/Platforms/MySQLSchemaTest.php @@ -38,8 +38,8 @@ public function testGenerateForeignKeySQL(): void self::assertEquals( [ - 'ALTER TABLE test ADD CONSTRAINT FK_D87F7E0C8E48560F FOREIGN KEY (foo_id)' - . ' REFERENCES test_foreign (foo_id)', + 'ALTER TABLE `test` ADD CONSTRAINT `FK_D87F7E0C8E48560F` FOREIGN KEY (`foo_id`)' + . ' REFERENCES `test_foreign` (`foo_id`)', ], $sqls, ); @@ -60,7 +60,7 @@ public function testClobNoAlterTable(): void $sql = $this->platform->getAlterTableSQL($diff); self::assertEquals( - ['ALTER TABLE test ADD PRIMARY KEY (id)'], + ['ALTER TABLE `test` ADD PRIMARY KEY (id)'], $sql, ); } From ef3791ded373786211f97470d59bab8473d4d4bf Mon Sep 17 00:00:00 2001 From: Sergei Morozov Date: Sun, 10 Nov 2024 10:51:29 -0800 Subject: [PATCH 4/4] Remove keywords lists --- UPGRADE.md | 22 + psalm.xml.dist | 34 -- src/Driver/AbstractMySQLDriver.php | 5 - src/Platforms/AbstractMySQLPlatform.php | 16 - src/Platforms/AbstractPlatform.php | 34 -- src/Platforms/DB2Platform.php | 16 - src/Platforms/Keywords/DB2Keywords.php | 416 ------------------ src/Platforms/Keywords/KeywordList.php | 56 --- src/Platforms/Keywords/MariaDBKeywords.php | 265 ----------- src/Platforms/Keywords/MySQL84Keywords.php | 48 -- src/Platforms/Keywords/MySQLKeywords.php | 290 ------------ src/Platforms/Keywords/OracleKeywords.php | 135 ------ src/Platforms/Keywords/PostgreSQLKeywords.php | 121 ----- src/Platforms/Keywords/SQLServerKeywords.php | 209 --------- src/Platforms/Keywords/SQLiteKeywords.php | 143 ------ src/Platforms/MariaDBPlatform.php | 16 - src/Platforms/MySQL84Platform.php | 30 -- src/Platforms/MySQLPlatform.php | 16 - src/Platforms/OraclePlatform.php | 16 - src/Platforms/PostgreSQLPlatform.php | 16 - src/Platforms/SQLServerPlatform.php | 16 - src/Platforms/SQLitePlatform.php | 16 - .../Driver/VersionAwarePlatformDriverTest.php | 3 - tests/Platforms/AbstractPlatformTestCase.php | 7 - tests/Platforms/MySQL84PlatformTest.php | 25 -- 25 files changed, 22 insertions(+), 1949 deletions(-) delete mode 100644 src/Platforms/Keywords/DB2Keywords.php delete mode 100644 src/Platforms/Keywords/KeywordList.php delete mode 100644 src/Platforms/Keywords/MariaDBKeywords.php delete mode 100644 src/Platforms/Keywords/MySQL84Keywords.php delete mode 100644 src/Platforms/Keywords/MySQLKeywords.php delete mode 100644 src/Platforms/Keywords/OracleKeywords.php delete mode 100644 src/Platforms/Keywords/PostgreSQLKeywords.php delete mode 100644 src/Platforms/Keywords/SQLServerKeywords.php delete mode 100644 src/Platforms/Keywords/SQLiteKeywords.php delete mode 100644 src/Platforms/MySQL84Platform.php delete mode 100644 tests/Platforms/MySQL84PlatformTest.php diff --git a/UPGRADE.md b/UPGRADE.md index 55e58922b37..4c163695feb 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -8,6 +8,28 @@ awareness about deprecated code. # Upgrade to 5.0 +## BC BREAK: Removed Reserved Keyword Lists + +The following components have been removed: + +1. The `KeywordList` class and all its subclasses. +2. The methods `AbstractPlatform::createReservedKeywordsList()` and `::getReservedKeywordsList()`. +3. The `AbstractPlatform::$_keywords` property. + +Prior to this change, DBAL would automatically quote reserved keywords and, as a side effect, preserve their case +on platforms that adhere to the SQL-92 standard (i.e., preserve lowercase identifiers on Oracle and IBM DB2, +and uppercase ones on PostgreSQL). + +With this change, DBAL will: +1. Normalize the case of unquoted identifiers to match the behavior of the target database platform: + - Oracle and IBM DB2 – uppercase. + - PostgreSQL – lowercase. + - All other platforms – no modification. +2. Consistently quote all identifiers in SQL, regardless of whether they are keywords or not. + +To preserve lowercase identifiers on Oracle and IBM DB2 or uppercase identifiers on PostgreSQL, quote the identifiers +explicitly. + ## BC BREAK: Removed `AbstractPlatform::quoteIdentifier()` and `Connection::quoteIdentifier()` The `AbstractPlatform::quoteIdentifier()` and `Connection::quoteIdentifier()` methods have been removed. diff --git a/psalm.xml.dist b/psalm.xml.dist index 93988f8c640..b5358bb294e 100644 --- a/psalm.xml.dist +++ b/psalm.xml.dist @@ -42,24 +42,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - -