[RenameIndexCommand] Fix orphaned index edge case (#16539)

We've been facing orphaned metadata index that would result in alter
error, now if we encounter one we just delete it
This commit is contained in:
Paul Rastoin
2025-12-12 17:44:00 +01:00
committed by GitHub
parent 0035fc1145
commit f0af947331
@@ -63,6 +63,7 @@ export class RenameIndexNameCommand extends ActiveOrSuspendedWorkspacesMigration
]);
let hasIndexNameChanges = false;
let hasRemovedIndexMetadata = false;
for (const index of Object.values(flatIndexMaps.byId).filter(isDefined)) {
const flatObjectMetadata = findFlatEntityByIdInFlatEntityMapsOrThrow({
@@ -84,43 +85,62 @@ export class RenameIndexNameCommand extends ActiveOrSuspendedWorkspacesMigration
if (indexNameV2 === index.name) {
this.logger.log(`Index ${index.name} is V2`);
continue;
} else {
this.logger.log(`Renaming index ${index.name} to ${indexNameV2}`);
}
this.logger.log(`Renaming index ${index.name} to ${indexNameV2}`);
if (isDryRun) {
continue;
}
const queryRunner = this.coreDataSource.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction();
try {
await queryRunner.query(
`ALTER INDEX "${schemaName}"."${index.name}" RENAME TO "${indexNameV2}"`,
);
await queryRunner.manager.update(IndexMetadataEntity, index.id, {
name: indexNameV2,
});
await queryRunner.commitTransaction();
hasIndexNameChanges = true;
if (!isDryRun) {
const queryRunner = this.coreDataSource.createQueryRunner();
} catch (error) {
await queryRunner.rollbackTransaction();
await queryRunner.connect();
await queryRunner.startTransaction();
// PostgreSQL error code 42704: undefined_object (index does not exist)
if (error.code === '42704') {
this.logger.log(
`Index ${index.name} does not exist in schema ${schemaName}, removing metadata`,
);
try {
await queryRunner.query(
`ALTER INDEX "${schemaName}"."${index.name}" RENAME TO "${indexNameV2}"`,
);
await queryRunner.manager.update(IndexMetadataEntity, index.id, {
name: indexNameV2,
});
await queryRunner.commitTransaction();
} catch (error) {
await queryRunner.rollbackTransaction();
throw error;
} finally {
await queryRunner.release();
}
await this.coreDataSource.manager.delete(
IndexMetadataEntity,
index.id,
);
hasRemovedIndexMetadata = true;
} else {
throw error;
}
} finally {
await queryRunner.release();
}
}
if (hasIndexNameChanges) {
const shouldInvalidateCache =
hasIndexNameChanges || hasRemovedIndexMetadata;
if (shouldInvalidateCache) {
this.logger.log('Invalidating workspace cache');
if (!isDryRun) {
await this.workspaceCacheService.invalidateAndRecompute(workspaceId, [
'flatFieldMetadataMaps',
'flatIndexMaps',
]);
}
await this.workspaceCacheService.invalidateAndRecompute(workspaceId, [
'flatFieldMetadataMaps',
'flatIndexMaps',
]);
}
}
}