From b6a65d9ef8663ea2788ad7acd487e84922e695b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vo=C5=99=C3=AD=C5=A1ek?= Date: Wed, 29 May 2024 12:28:05 +0200 Subject: [PATCH] Fix "bigint" type for PK with AI introspection for SQLite --- src/Schema/SqliteSchemaManager.php | 6 +++ .../SchemaManagerFunctionalTestCase.php | 40 ++++++++++++++++++- 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/src/Schema/SqliteSchemaManager.php b/src/Schema/SqliteSchemaManager.php index 0419e934b32..218ea5ae951 100644 --- a/src/Schema/SqliteSchemaManager.php +++ b/src/Schema/SqliteSchemaManager.php @@ -379,6 +379,12 @@ protected function _getPortableTableColumnDefinition($tableColumn) $default = null; } + // https://github.com/doctrine/dbal/blob/3.8.4/src/Platforms/SqlitePlatform.php#L271-L274 + // https://dbfiddle.uk/yyXvHV-6 + if (strtolower($type) === 'integer' && ($tableColumn['pk'] !== 0 && $tableColumn['pk'] !== '0')) { + $type = 'bigint'; + } + if ($default !== null) { // SQLite returns the default value as a literal expression, so we need to parse it if (preg_match('/^\'(.*)\'$/s', $default, $matches) === 1) { diff --git a/tests/Functional/Schema/SchemaManagerFunctionalTestCase.php b/tests/Functional/Schema/SchemaManagerFunctionalTestCase.php index b88bcdec901..0e03af9a396 100644 --- a/tests/Functional/Schema/SchemaManagerFunctionalTestCase.php +++ b/tests/Functional/Schema/SchemaManagerFunctionalTestCase.php @@ -25,6 +25,7 @@ use Doctrine\DBAL\Schema\View; use Doctrine\DBAL\Tests\FunctionalTestCase; use Doctrine\DBAL\Types\ArrayType; +use Doctrine\DBAL\Types\BigIntType; use Doctrine\DBAL\Types\BinaryType; use Doctrine\DBAL\Types\BlobType; use Doctrine\DBAL\Types\DateIntervalType; @@ -298,7 +299,12 @@ public function testListTableColumns(): void self::assertArrayHasKey('id', $columns); self::assertEquals(0, array_search('id', $columnsKeys, true)); self::assertEquals('id', strtolower($columns['id']->getName())); - self::assertInstanceOf(IntegerType::class, $columns['id']->getType()); + self::assertInstanceOf( + $this->connection->getDatabasePlatform() instanceof SqlitePlatform + ? BigIntType::class + : IntegerType::class, + $columns['id']->getType(), + ); self::assertEquals(false, $columns['id']->getUnsigned()); self::assertEquals(true, $columns['id']->getNotnull()); self::assertEquals(null, $columns['id']->getDefault()); @@ -363,6 +369,33 @@ public function testListTableColumns(): void self::assertIsArray($columns['baz3']->getPlatformOptions()); } + public function testListTableColumnsWithBigintColumnsAndAutoincrement(): void + { + if (! $this->connection->getDatabasePlatform()->supportsIdentityColumns()) { + self::markTestSkipped('This test is only supported on platforms that have autoincrement'); + } + + $tableName = 'test_list_table_bigint'; + + $table = new Table($tableName); + $table->addColumn('id_with_ai', Types::BIGINT, ['autoincrement' => true]); + $table->setPrimaryKey(['id_with_ai']); + $table->addColumn('foo', Types::BIGINT); + $table->addColumn('bar', Types::INTEGER); + + $this->schemaManager->createTable($table); + + $columns = $this->schemaManager->listTableColumns($tableName); + + self::assertCount(3, $columns); + self::assertArrayHasKey('id_with_ai', $columns); + self::assertInstanceOf(BigIntType::class, $columns['id_with_ai']->getType()); + self::assertArrayHasKey('foo', $columns); + self::assertInstanceOf(BigIntType::class, $columns['foo']->getType()); + self::assertArrayHasKey('bar', $columns); + self::assertInstanceOf(IntegerType::class, $columns['bar']->getType()); + } + public function testListTableColumnsWithFixedStringColumn(): void { $tableName = 'test_list_table_fixed_string'; @@ -457,6 +490,11 @@ public function testDiffListTableColumns(callable $comparatorFactory): void } $offlineTable = $this->createListTableColumns(); + + if ($this->connection->getDatabasePlatform() instanceof SqlitePlatform) { + $offlineTable->getColumn('id')->setType(Type::getType(Types::BIGINT)); + } + $this->dropAndCreateTable($offlineTable); $onlineTable = $this->schemaManager->introspectTable('list_table_columns');