From 437cb2fd12ae6d879615a5132ea28f82acc6be18 Mon Sep 17 00:00:00 2001 From: davidxkurka <130223030+davidxkurka@users.noreply.github.com> Date: Sun, 24 Nov 2024 17:21:30 +0100 Subject: [PATCH] =?UTF-8?q?fix:=20max=20string=20length=20resolution=20in?= =?UTF-8?q?=20AbstractPlatform::getEnumDeclara=E2=80=A6=20(#6579)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit | Q | A |------------- | ----------- | Type | bug | Fixed issues | N/A #### Summary Fixes a situation where an enum type only contains 1 case. This results in passing only a single integer argument to the max() method, which is not valid and returns the error "max(): Argument 1 ($value) must be of type array, int given". Co-authored-by: David Kurka --- src/Platforms/AbstractPlatform.php | 7 +++- .../AbstractMySQLPlatformTestCase.php | 9 +++++ tests/Platforms/AbstractPlatformTestCase.php | 35 +++++++++++++++++++ tests/Platforms/OraclePlatformTest.php | 9 +++++ tests/Platforms/SQLServerPlatformTest.php | 9 +++++ 5 files changed, 68 insertions(+), 1 deletion(-) diff --git a/src/Platforms/AbstractPlatform.php b/src/Platforms/AbstractPlatform.php index 53b71a8dcd5..2c49c7d185a 100644 --- a/src/Platforms/AbstractPlatform.php +++ b/src/Platforms/AbstractPlatform.php @@ -52,6 +52,7 @@ use function is_float; use function is_int; use function is_string; +use function key; use function max; use function mb_strlen; use function preg_quote; @@ -209,7 +210,11 @@ public function getEnumDeclarationSQL(array $column): string throw ColumnValuesRequired::new($this, 'ENUM'); } - return $this->getStringTypeDeclarationSQL(['length' => max(...array_map(mb_strlen(...), $column['values']))]); + $length = count($column['values']) > 1 + ? max(...array_map(mb_strlen(...), $column['values'])) + : mb_strlen($column['values'][key($column['values'])]); + + return $this->getStringTypeDeclarationSQL(['length' => $length]); } /** diff --git a/tests/Platforms/AbstractMySQLPlatformTestCase.php b/tests/Platforms/AbstractMySQLPlatformTestCase.php index 9c569cece8d..266fa2c48b5 100644 --- a/tests/Platforms/AbstractMySQLPlatformTestCase.php +++ b/tests/Platforms/AbstractMySQLPlatformTestCase.php @@ -694,4 +694,13 @@ protected function createComparator(): Comparator new DefaultTableOptions('utf8mb4', 'utf8mb4_general_ci'), ); } + + /** @return array, string}> */ + public static function getEnumDeclarationSQLProvider(): array + { + return [ + 'single value' => [['foo'], "ENUM('foo')"], + 'multiple values' => [['foo', 'bar1'], "ENUM('foo', 'bar1')"], + ]; + } } diff --git a/tests/Platforms/AbstractPlatformTestCase.php b/tests/Platforms/AbstractPlatformTestCase.php index 67b9afdd9a8..b560d54ee3d 100644 --- a/tests/Platforms/AbstractPlatformTestCase.php +++ b/tests/Platforms/AbstractPlatformTestCase.php @@ -6,6 +6,7 @@ use Doctrine\DBAL\Exception; use Doctrine\DBAL\Exception\InvalidColumnDeclaration; +use Doctrine\DBAL\Exception\InvalidColumnType\ColumnValuesRequired; use Doctrine\DBAL\Platforms\AbstractPlatform; use Doctrine\DBAL\Schema\Column; use Doctrine\DBAL\Schema\ColumnDiff; @@ -1030,4 +1031,38 @@ public static function asciiStringSqlDeclarationDataProvider(): array ['CHAR(12)', ['length' => 12, 'fixed' => true]], ]; } + + /** @param array $values */ + #[DataProvider('getEnumDeclarationSQLProvider')] + public function testGetEnumDeclarationSQL(array $values, string $expectedSQL): void + { + self::assertSame($expectedSQL, $this->platform->getEnumDeclarationSQL(['values' => $values])); + } + + /** @return array, string}> */ + public static function getEnumDeclarationSQLProvider(): array + { + return [ + 'single value' => [['foo'], 'VARCHAR(3)'], + 'multiple values' => [['foo', 'bar1'], 'VARCHAR(4)'], + ]; + } + + /** @param array $column */ + #[DataProvider('getEnumDeclarationSQLWithInvalidValuesProvider')] + public function testGetEnumDeclarationSQLWithInvalidValues(array $column): void + { + self::expectException(ColumnValuesRequired::class); + $this->platform->getEnumDeclarationSQL($column); + } + + /** @return array}> */ + public static function getEnumDeclarationSQLWithInvalidValuesProvider(): array + { + return [ + "field 'values' does not exist" => [[]], + "field 'values' is not an array" => [['values' => 'foo']], + "field 'values' is an empty array" => [['values' => []]], + ]; + } } diff --git a/tests/Platforms/OraclePlatformTest.php b/tests/Platforms/OraclePlatformTest.php index dfb5b85036b..c8187d5fc21 100644 --- a/tests/Platforms/OraclePlatformTest.php +++ b/tests/Platforms/OraclePlatformTest.php @@ -595,4 +595,13 @@ public static function asciiStringSqlDeclarationDataProvider(): array ['CHAR(12)', ['length' => 12, 'fixed' => true]], ]; } + + /** @return array, string}> */ + public static function getEnumDeclarationSQLProvider(): array + { + return [ + 'single value' => [['foo'], 'VARCHAR2(3)'], + 'multiple values' => [['foo', 'bar1'], 'VARCHAR2(4)'], + ]; + } } diff --git a/tests/Platforms/SQLServerPlatformTest.php b/tests/Platforms/SQLServerPlatformTest.php index 285f2bbb9bb..dd83c2b4013 100644 --- a/tests/Platforms/SQLServerPlatformTest.php +++ b/tests/Platforms/SQLServerPlatformTest.php @@ -1124,4 +1124,13 @@ public function testGeneratesTypeDeclarationForDateTimeTz(): void { self::assertEquals('DATETIMEOFFSET(6)', $this->platform->getDateTimeTzTypeDeclarationSQL([])); } + + /** @return array, string}> */ + public static function getEnumDeclarationSQLProvider(): array + { + return [ + 'single value' => [['foo'], 'NVARCHAR(3)'], + 'multiple values' => [['foo', 'bar1'], 'NVARCHAR(4)'], + ]; + } }