diff --git a/src/Database/Trait/Attributes.php b/src/Database/Trait/Attributes.php index 1300dd4a3..a6334e00c 100644 --- a/src/Database/Trait/Attributes.php +++ b/src/Database/Trait/Attributes.php @@ -915,13 +915,22 @@ private static function withoutIndexedAttribute(array $indexes, string $key): ar continue; } - $attributes = \array_values(\array_filter( - $index->attributes, - static fn (string $attribute): bool => $attribute !== $key, - )); + // Lengths and orders are positional, so drop the entry at each removed attribute's position too. + $document = $index->toDocument(); + $attributes = $index->attributes; + $lengths = (array) $document->getAttribute('lengths', []); + $orders = (array) $document->getAttribute('orders', []); + foreach (\array_reverse(\array_keys($attributes, $key, true)) as $position) { + \array_splice($attributes, $position, 1); + \array_splice($lengths, $position, 1); + \array_splice($orders, $position, 1); + } if ($attributes !== []) { - $remaining[] = self::withIndexedAttributes($index, $attributes); + $remaining[] = Index::fromDocument($document + ->setAttribute(self::INDEX_ATTRIBUTES, $attributes) + ->setAttribute('lengths', $lengths) + ->setAttribute('orders', $orders)); } } diff --git a/tests/e2e/Adapter/Scopes/IndexTests.php b/tests/e2e/Adapter/Scopes/IndexTests.php index 1abe440ff..458778830 100644 --- a/tests/e2e/Adapter/Scopes/IndexTests.php +++ b/tests/e2e/Adapter/Scopes/IndexTests.php @@ -137,6 +137,29 @@ public function testCreateDeleteIndex(): void $database->deleteCollection('indexes'); } + public function testDeleteAttributeKeepsIndexLengthsAligned(): void + { + /** @var Database $database */ + $database = $this->getDatabase(); + + $database->createCollection(Collection::create(id: 'indexLengths', attributes: [ + Attribute::string(key: 'first', size: 128), + Attribute::string(key: 'second', size: 128), + ], indexes: [ + Index::key(key: 'pair', attributes: ['first', 'second'], lengths: [64, 32], orders: [OrderDirection::Asc, OrderDirection::Desc]), + ])); + + $database->deleteAttribute('indexLengths', 'first'); + + $index = $database->getCollection('indexLengths')->indexes()[0]; + $this->assertSame([32], $index->lengths); + $this->assertSame([OrderDirection::Desc], $index->orders); + + $database->updateAttribute('indexLengths', 'second', new Update(size: 256)); + + $database->deleteCollection('indexLengths'); + } + public function testCreateUniqueIndexOverDuplicates(): void { $database = $this->getDatabase();