From 068954fbbdd0b72bf55fa9c8c9588d0fa40a31e9 Mon Sep 17 00:00:00 2001 From: Daniel Kesselberg Date: Fri, 24 Oct 2025 00:28:19 +0200 Subject: [PATCH] fix(db): drop index on mail_mailboxes by columns instead of name Signed-off-by: Daniel Kesselberg --- appinfo/info.xml | 2 +- .../Version3500Date20231115184458.php | 30 ++++++---- .../Version5006Date20250927130132.php | 21 +++++-- .../Version5006Date20251015082003.php | 9 ++- .../Version5006Date20251023191023.php | 60 +++++++++++++++++++ 5 files changed, 104 insertions(+), 18 deletions(-) create mode 100644 lib/Migration/Version5006Date20251023191023.php diff --git a/appinfo/info.xml b/appinfo/info.xml index e7f0650681..d8aa382cd2 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -34,7 +34,7 @@ The rating depends on the installed text processing backend. See [the rating ove Learn more about the Nextcloud Ethical AI Rating [in our blog](https://nextcloud.com/blog/nextcloud-ethical-ai-rating/). ]]> - 5.6.0-alpha.3 + 5.6.0-alpha.4 agpl Christoph Wurst GretaD diff --git a/lib/Migration/Version3500Date20231115184458.php b/lib/Migration/Version3500Date20231115184458.php index 9b37678220..396a693860 100644 --- a/lib/Migration/Version3500Date20231115184458.php +++ b/lib/Migration/Version3500Date20231115184458.php @@ -28,22 +28,28 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt $mailboxesTable = $schema->getTable('mail_mailboxes'); - $indexNew = 'mail_mb_account_id_name_hash'; - /** - * Variant 1 - with table prefix + * The migration "Version0161Date20190902103701" created a unique index for account_id and name without + * specifying a name. Unfortunately, this resulted in different index names depending on the table + * prefix, which means we now have to loop through the indexes to find the correct one. + * + * This migration is from 2023-11 and, by now, most people should already have it. Although it is not + * recommended to change migrations after they have been released, we are still updating this + * one for correctness as it was supposed to drop the index here. + * + * On newer versions, this will be a no-op, as creating the index + * in "Version0161Date20190902103701" is commented out. + * + * @see \OCA\Mail\Migration\Version0161Date20190902103701::changeSchema */ - if ($mailboxesTable->hasIndex('UNIQ_22DEBD839B6B5FBA5E237E06')) { - $mailboxesTable->dropIndex('UNIQ_22DEBD839B6B5FBA5E237E06'); - } - /** - * Variant 2 - without table prefix - * @see \OCA\Mail\Migration\Version5006Date20250927130132::changeSchema - */ - if ($mailboxesTable->hasIndex('UNIQ_45754FF89B6B5FBA5E237E06')) { - $mailboxesTable->dropIndex('UNIQ_45754FF89B6B5FBA5E237E06'); + foreach ($mailboxesTable->getIndexes() as $index) { + if ($index->isUnique() && $index->spansColumns(['account_id', 'name'])) { + $mailboxesTable->dropIndex($index->getName()); + } } + $indexNew = 'mail_mb_account_id_name_hash'; + if (!$mailboxesTable->hasIndex($indexNew)) { $mailboxesTable->addUniqueIndex(['account_id', 'name_hash'], $indexNew); } diff --git a/lib/Migration/Version5006Date20250927130132.php b/lib/Migration/Version5006Date20250927130132.php index 7dcd6b67d1..9e0fc65c77 100644 --- a/lib/Migration/Version5006Date20250927130132.php +++ b/lib/Migration/Version5006Date20250927130132.php @@ -20,6 +20,9 @@ #[ModifyColumn(table: 'mail_mailboxes', name: 'name', type: ColumnType::STRING, description: 'Increase the column length from 255 to 1024')] class Version5006Date20250927130132 extends SimpleMigrationStep { + /** + * @psalm-param Closure():ISchemaWrapper $schemaClosure + */ #[Override] public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper { $schema = $schemaClosure(); @@ -27,13 +30,23 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt $mailboxes = $schema->getTable('mail_mailboxes'); /** - * Make sure the old account_id+name index is gone. The DB won't allow - * the name length increase otherwise + * The migration "Version0161Date20190902103701" created a unique index for account_id and name without + * specifying a name. Unfortunately, this resulted in different index names depending on the table + * prefix, which means we now have to loop through the indexes to find the correct one. * + * The index on account_id and name were supposed to be dropped in "Version3500Date20231115184458", + * but this did not work on every setup due to the name mismatch caused by different table prefixes. + * + * Although it is not recommended to change migrations after release, + * we are updating this one with a safeguard to drop any existing index on account_id and name. + * + * @see \OCA\Mail\Migration\Version0161Date20190902103701::changeSchema * @see \OCA\Mail\Migration\Version3500Date20231115184458::changeSchema */ - if ($mailboxes->hasIndex('UNIQ_45754FF89B6B5FBA5E237E06')) { - $mailboxes->dropIndex('UNIQ_45754FF89B6B5FBA5E237E06'); + foreach ($mailboxes->getIndexes() as $index) { + if ($index->isUnique() && $index->spansColumns(['account_id', 'name'])) { + $mailboxes->dropIndex($index->getName()); + } } $mailboxes->modifyColumn( diff --git a/lib/Migration/Version5006Date20251015082003.php b/lib/Migration/Version5006Date20251015082003.php index a3a4b21216..49f21eecfb 100644 --- a/lib/Migration/Version5006Date20251015082003.php +++ b/lib/Migration/Version5006Date20251015082003.php @@ -28,9 +28,16 @@ public function changeSchema(IOutput $output, Closure $schemaClosure, array $opt $schema = $schemaClosure(); /** - * Make sure the old account_id+name index is gone for good + * The migration "Version0161Date20190902103701" created a unique index for account_id and name without + * specifying a name. Unfortunately, this resulted in different index names depending on the table + * prefix, which means we now have to loop through the indexes to find the correct one. * + * The index on account_id and name were supposed to be dropped in "Version3500Date20231115184458", + * but this did not work on every setup due to the name mismatch caused by different table prefixes. + * + * @see \OCA\Mail\Migration\Version0161Date20190902103701::changeSchema * @see \OCA\Mail\Migration\Version3500Date20231115184458::changeSchema + * @see \OCA\Mail\Migration\Version5006Date20250927130132::changeSchema */ $mailboxesTable = $schema->getTable('mail_mailboxes'); if (!$mailboxesTable->hasIndex('UNIQ_45754FF89B6B5FBA5E237E06')) { diff --git a/lib/Migration/Version5006Date20251023191023.php b/lib/Migration/Version5006Date20251023191023.php new file mode 100644 index 0000000000..ad7b0cb5cb --- /dev/null +++ b/lib/Migration/Version5006Date20251023191023.php @@ -0,0 +1,60 @@ +getTable('mail_mailboxes'); + + /** + * The migration "Version0161Date20190902103701" created a unique index for account_id and name without + * specifying a name. Unfortunately, this resulted in different index names depending on the table + * prefix, which means we now have to loop through the indexes to find the correct one. + * + * The index on account_id and name were supposed to be dropped in "Version3500Date20231115184458", + * but this did not work on every setup due to the name mismatch caused by different table prefixes. + * + * On MySQL or MariaDB versions before 10.5, changing the length of the name column to 1024 fails if the + * index on account_id and name still exists, with the error "Specified key was too long; max key length is 3072 bytes." + * However, this change works on MariaDB 10.5 or newer. + * + * The reason is that MariaDB automatically converts a unique index using btree to hash if the key exceeds + * the maximum length and is supported by the storage engine: https://mariadb.com/docs/server/mariadb-quickstart-guides/mariadb-indexes-guide#unique-index + * + * This means that on setups with a different table prefix using MariaDB 10.5, the index on account_id and name + * might still exist. Since we don't need it, we will make another attempt to drop it here. + * + * @see \OCA\Mail\Migration\Version0161Date20190902103701::changeSchema + * @see \OCA\Mail\Migration\Version3500Date20231115184458::changeSchema + * @see \OCA\Mail\Migration\Version5006Date20250927130132::changeSchema + * @see \OCA\Mail\Migration\Version5006Date20251015082003::changeSchema + */ + foreach ($mailboxes->getIndexes() as $index) { + if ($index->isUnique() && $index->spansColumns(['account_id', 'name'])) { + $mailboxes->dropIndex($index->getName()); + } + } + + return $schema; + } +}