From ac49cb227a30fc8ccaf112562ffb7218d27cfb22 Mon Sep 17 00:00:00 2001 From: Sergei Morozov Date: Tue, 18 Dec 2018 20:23:57 -0800 Subject: [PATCH] Consider column lengths when comparing indices --- lib/Doctrine/DBAL/Schema/Index.php | 18 +++++++++++ .../Doctrine/Tests/DBAL/Schema/IndexTest.php | 30 +++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/lib/Doctrine/DBAL/Schema/Index.php b/lib/Doctrine/DBAL/Schema/Index.php index bae6d218cb6..91ffd472465 100644 --- a/lib/Doctrine/DBAL/Schema/Index.php +++ b/lib/Doctrine/DBAL/Schema/Index.php @@ -4,6 +4,7 @@ use Doctrine\DBAL\Platforms\AbstractPlatform; use InvalidArgumentException; +use function array_filter; use function array_keys; use function array_map; use function array_search; @@ -211,6 +212,10 @@ public function isFullfilledBy(Index $other) return false; } + if (! $this->hasSameColumnLengths($other)) { + return false; + } + if (! $this->isUnique() && ! $this->isPrimary()) { // this is a special case: If the current key is neither primary or unique, any unique or // primary key will always have the same effect for the index and there cannot be any constraint @@ -336,4 +341,17 @@ private function samePartialIndex(Index $other) return ! $this->hasOption('where') && ! $other->hasOption('where'); } + + /** + * Returns whether the index has the same column lengths as the other + */ + private function hasSameColumnLengths(self $other) : bool + { + $filter = static function (?int $length) : bool { + return $length !== null; + }; + + return array_filter($this->options['lengths'] ?? [], $filter) + === array_filter($other->options['lengths'] ?? [], $filter); + } } diff --git a/tests/Doctrine/Tests/DBAL/Schema/IndexTest.php b/tests/Doctrine/Tests/DBAL/Schema/IndexTest.php index af962f95f95..ad9e2bbbdb7 100644 --- a/tests/Doctrine/Tests/DBAL/Schema/IndexTest.php +++ b/tests/Doctrine/Tests/DBAL/Schema/IndexTest.php @@ -108,6 +108,36 @@ public function testOverrulesWithPartial() self::assertTrue($another->overrules($partial)); } + /** + * @param string[] $columns + * @param int[]|null[] $lengths1 + * @param int[]|null[] $lengths2 + * + * @dataProvider indexLengthProvider + */ + public function testFulfilledWithLength(array $columns, array $lengths1, array $lengths2, bool $expected) : void + { + $index1 = new Index('index1', $columns, false, false, [], ['lengths' => $lengths1]); + $index2 = new Index('index2', $columns, false, false, [], ['lengths' => $lengths2]); + + self::assertSame($expected, $index1->isFullfilledBy($index2)); + self::assertSame($expected, $index2->isFullfilledBy($index1)); + } + + /** + * @return mixed[][] + */ + public static function indexLengthProvider() : iterable + { + return [ + 'empty' => [['column'], [], [], true], + 'same' => [['column'], [64], [64], true], + 'different' => [['column'], [32], [64], false], + 'sparse-different-positions' => [['column1', 'column2'], [0 => 32], [1 => 32], false], + 'sparse-same-positions' => [['column1', 'column2'], [null, 32], [1 => 32], true], + ]; + } + /** * @group DBAL-220 */