From d6798d76ce2d4ff07dd268000ee2f6f03d233a89 Mon Sep 17 00:00:00 2001 From: Sergei Morozov Date: Sat, 20 Aug 2022 16:09:51 -0700 Subject: [PATCH 1/2] Do not drop schemas in DropSchemaObjectsSQLBuilder Although `CreateSchemaSqlCollector` creates the namespaces declared in the schema, `DropSchemaObjectsSQLBuilder` does not drop them. We will keep it the same in `DropSchemaObjectsSQLBuilder` for backward compatibility. --- .../Builder/DropSchemaObjectsSQLBuilder.php | 21 ------------------- 1 file changed, 21 deletions(-) diff --git a/src/SQL/Builder/DropSchemaObjectsSQLBuilder.php b/src/SQL/Builder/DropSchemaObjectsSQLBuilder.php index 488775552c4..06cc8a4d5cf 100644 --- a/src/SQL/Builder/DropSchemaObjectsSQLBuilder.php +++ b/src/SQL/Builder/DropSchemaObjectsSQLBuilder.php @@ -29,7 +29,6 @@ public function buildSQL(Schema $schema): array return array_merge( $this->buildTableStatements($schema->getTables()), $this->buildSequenceStatements($schema->getSequences()), - $this->buildNamespaceStatements($schema->getNamespaces()), ); } @@ -60,24 +59,4 @@ private function buildSequenceStatements(array $sequences): array return $statements; } - - /** - * @param list $namespaces - * - * @return list - * - * @throws Exception - */ - private function buildNamespaceStatements(array $namespaces): array - { - $statements = []; - - if ($this->platform->supportsSchemas()) { - foreach ($namespaces as $namespace) { - $statements[] = $this->platform->getDropSchemaSQL($namespace); - } - } - - return $statements; - } } From 645ea4e19d506421ac049617c737c1669e3d0600 Mon Sep 17 00:00:00 2001 From: Sergei Morozov Date: Sat, 20 Aug 2022 15:13:22 -0700 Subject: [PATCH 2/2] When dropping schema, drop sequences before tables When dropping a schema, the DBAL explicitly drops all schema sequences, even if they are owned by one of the tables being dropped. As a workaround for the regression, we will drop sequences first, which is how it is implemented in `DropSchemaSqlCollector`. Co-authored-by: HypeMC --- .../Builder/DropSchemaObjectsSQLBuilder.php | 2 +- .../Schema/PostgreSQLSchemaManagerTest.php | 35 +++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/SQL/Builder/DropSchemaObjectsSQLBuilder.php b/src/SQL/Builder/DropSchemaObjectsSQLBuilder.php index 06cc8a4d5cf..8de742a317b 100644 --- a/src/SQL/Builder/DropSchemaObjectsSQLBuilder.php +++ b/src/SQL/Builder/DropSchemaObjectsSQLBuilder.php @@ -27,8 +27,8 @@ public function __construct(AbstractPlatform $platform) public function buildSQL(Schema $schema): array { return array_merge( - $this->buildTableStatements($schema->getTables()), $this->buildSequenceStatements($schema->getSequences()), + $this->buildTableStatements($schema->getTables()), ); } diff --git a/tests/Functional/Schema/PostgreSQLSchemaManagerTest.php b/tests/Functional/Schema/PostgreSQLSchemaManagerTest.php index a7e75cc6b58..0f3c37f5363 100644 --- a/tests/Functional/Schema/PostgreSQLSchemaManagerTest.php +++ b/tests/Functional/Schema/PostgreSQLSchemaManagerTest.php @@ -9,6 +9,7 @@ use Doctrine\DBAL\Schema\Comparator; use Doctrine\DBAL\Schema\ForeignKeyConstraint; use Doctrine\DBAL\Schema\PostgreSQLSchemaManager; +use Doctrine\DBAL\Schema\Schema; use Doctrine\DBAL\Schema\Table; use Doctrine\DBAL\Schema\TableDiff; use Doctrine\DBAL\Schema\View; @@ -304,6 +305,40 @@ protected function assertVarBinaryColumnIsValid(Table $table, string $columnName self::assertInstanceOf(BlobType::class, $table->getColumn($columnName)->getType()); } + /** + * Although this test would pass in isolation on any platform, we keep it here for the following reasons: + * + * 1. The DBAL currently doesn't properly drop tables in the namespaces that need to be quoted + * (@see testListTableDetailsWhenCurrentSchemaNameQuoted()). + * 2. The schema returned by {@see AbstractSchemaManager::createSchema()} doesn't contain views, so + * {@see AbstractSchemaManager::dropSchemaObjects()} cannot drop the tables that have dependent views + * (@see testListTablesExcludesViews()). + * 3. In the case of inheritance, PHPUnit runs the tests declared immediately in the test class + * and then runs the tests declared in the parent. + * + * This test needs to be executed before the ones it conflicts with, so it has to be declared in the same class. + */ + public function testDropWithAutoincrement(): void + { + $this->dropTableIfExists('test_autoincrement'); + + $schema = new Schema(); + $table = $schema->createTable('test_autoincrement'); + $table->addColumn('id', 'integer', [ + 'notnull' => true, + 'autoincrement' => true, + ]); + $table->setPrimaryKey(['id']); + + $schemaManager = $this->connection->createSchemaManager(); + $schemaManager->createSchemaObjects($schema); + + $schema = $schemaManager->createSchema(); + $schemaManager->dropSchemaObjects($schema); + + self::assertFalse($schemaManager->tablesExist(['test_autoincrement'])); + } + public function testListTableDetailsWhenCurrentSchemaNameQuoted(): void { $this->connection->executeStatement('CREATE SCHEMA "001_test"');