Fix rename index collides with existing v2 index (#16560)

## Introduction
When migrating a v1 index name to v2 it might collide with an existing
v2 index
In this case we remove both the v1 metadata and pg index

In case of a metadata and pg_index desync this might occur too late in
the process that's why we have two fallback
One computing the v1 deletion from the metadata and another one in the
catch block of the v1 to migration transaction commit
This commit is contained in:
Paul Rastoin
2025-12-15 11:06:55 +01:00
committed by prastoin
parent f339912f7d
commit c8adb664a7
@@ -62,6 +62,12 @@ export class RenameIndexNameCommand extends ActiveOrSuspendedWorkspacesMigration
'flatFieldMetadataMaps',
]);
const indexMetadataByName = new Map(
Object.values(flatIndexMaps.byId)
.filter(isDefined)
.map((index) => [index.name, index]),
);
let hasIndexNameChanges = false;
let hasRemovedIndexMetadata = false;
@@ -87,6 +93,38 @@ export class RenameIndexNameCommand extends ActiveOrSuspendedWorkspacesMigration
continue;
}
// Check if another metadata entry already has the v2 name
const existingV2Metadata = indexMetadataByName.get(indexNameV2);
if (isDefined(existingV2Metadata) && existingV2Metadata.id !== index.id) {
// V2 metadata already exists, this v1 metadata is stale
this.logger.log(
`Index metadata with v2 name ${indexNameV2} already exists, removing stale v1 metadata and index ${index.name}`,
);
if (!isDryRun) {
const queryRunner = this.coreDataSource.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();
try {
await queryRunner.manager.delete(IndexMetadataEntity, index.id);
await queryRunner.query(
`DROP INDEX IF EXISTS "${schemaName}"."${index.name}"`,
);
await queryRunner.commitTransaction();
hasRemovedIndexMetadata = true;
} catch (error) {
await queryRunner.rollbackTransaction();
throw error;
} finally {
await queryRunner.release();
}
}
continue;
}
this.logger.log(`Renaming index ${index.name} to ${indexNameV2}`);
if (isDryRun) {
@@ -124,6 +162,23 @@ export class RenameIndexNameCommand extends ActiveOrSuspendedWorkspacesMigration
IndexMetadataEntity,
index.id,
);
hasRemovedIndexMetadata = true;
} else if (error.code === '42P07') {
// PostgreSQL error code 42P07: duplicate_table (v2 index already exists)
// The v2 index already exists, remove stale v1 metadata and index
this.logger.log(
`Index ${indexNameV2} already exists at PG level, removing stale v1 metadata and index ${index.name}`,
);
await this.coreDataSource.manager.delete(
IndexMetadataEntity,
index.id,
);
await this.coreDataSource.query(
`DROP INDEX IF EXISTS "${schemaName}"."${index.name}"`,
);
hasRemovedIndexMetadata = true;
} else {
this.logger.error(