From bb6c46adc08f3eecd8ba7190854ba6b00547c956 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Mon, 11 May 2026 12:50:02 +0200 Subject: [PATCH] fix(catalog-backend): create replacement indices before dropping in down migration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Avoids a window with no coverage on (key, value) during rollback. Signed-off-by: Fredrik Adelöw Co-authored-by: Cursor --- ...20260510000000_search_indices_and_dedup.js | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/plugins/catalog-backend/migrations/20260510000000_search_indices_and_dedup.js b/plugins/catalog-backend/migrations/20260510000000_search_indices_and_dedup.js index 10528a5347..f49b36d731 100644 --- a/plugins/catalog-backend/migrations/20260510000000_search_indices_and_dedup.js +++ b/plugins/catalog-backend/migrations/20260510000000_search_indices_and_dedup.js @@ -86,7 +86,14 @@ exports.down = async function down(knex) { const client = knex.client.config.client; if (client.includes('pg')) { - // Remove the new indices and restore the old ones + // Restore the old indices first so there is no window without coverage, + // then drop the new ones. + await knex.raw( + 'CREATE INDEX CONCURRENTLY IF NOT EXISTS search_key_value_idx ON search (key, value)', + ); + await knex.raw( + 'CREATE INDEX CONCURRENTLY IF NOT EXISTS search_key_original_value_idx ON search (key, original_value)', + ); await knex.raw( 'DROP INDEX CONCURRENTLY IF EXISTS search_entity_key_value_idx', ); @@ -96,30 +103,24 @@ exports.down = async function down(knex) { await knex.raw( 'DROP INDEX CONCURRENTLY IF EXISTS search_facets_covering_idx', ); - await knex.raw( - 'CREATE INDEX CONCURRENTLY IF NOT EXISTS search_key_value_idx ON search (key, value)', - ); - await knex.raw( - 'CREATE INDEX CONCURRENTLY IF NOT EXISTS search_key_original_value_idx ON search (key, original_value)', - ); } else if (client.includes('mysql')) { - await mysqlDropIndexIfExists(knex, 'search_entity_key_value_idx'); - await mysqlDropIndexIfExists(knex, 'search_key_value_entity_idx'); - await mysqlDropIndexIfExists(knex, 'search_facets_covering_idx'); await knex.schema.alterTable('search', table => { table.index(['key', 'value'], 'search_key_value_idx'); table.index(['key', 'original_value'], 'search_key_original_value_idx'); }); + await mysqlDropIndexIfExists(knex, 'search_entity_key_value_idx'); + await mysqlDropIndexIfExists(knex, 'search_key_value_entity_idx'); + await mysqlDropIndexIfExists(knex, 'search_facets_covering_idx'); } else { - await knex.raw('DROP INDEX IF EXISTS search_entity_key_value_idx'); - await knex.raw('DROP INDEX IF EXISTS search_key_value_entity_idx'); - await knex.raw('DROP INDEX IF EXISTS search_facets_covering_idx'); await knex.raw( 'CREATE INDEX IF NOT EXISTS search_key_value_idx ON search (key, value)', ); await knex.raw( 'CREATE INDEX IF NOT EXISTS search_key_original_value_idx ON search (key, original_value)', ); + await knex.raw('DROP INDEX IF EXISTS search_entity_key_value_idx'); + await knex.raw('DROP INDEX IF EXISTS search_key_value_entity_idx'); + await knex.raw('DROP INDEX IF EXISTS search_facets_covering_idx'); } };