Skip to content

Commit 8c79353

Browse files
authored
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
1 parent cf6fb41 commit 8c79353

File tree

1 file changed

+55
-0
lines changed

1 file changed

+55
-0
lines changed

packages/twenty-server/src/database/commands/upgrade-version-command/1-13/1-13-rename-index.command.ts

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,12 @@ export class RenameIndexNameCommand extends ActiveOrSuspendedWorkspacesMigration
6262
'flatFieldMetadataMaps',
6363
]);
6464

65+
const indexMetadataByName = new Map(
66+
Object.values(flatIndexMaps.byId)
67+
.filter(isDefined)
68+
.map((index) => [index.name, index]),
69+
);
70+
6571
let hasIndexNameChanges = false;
6672
let hasRemovedIndexMetadata = false;
6773

@@ -87,6 +93,38 @@ export class RenameIndexNameCommand extends ActiveOrSuspendedWorkspacesMigration
8793
continue;
8894
}
8995

96+
// Check if another metadata entry already has the v2 name
97+
const existingV2Metadata = indexMetadataByName.get(indexNameV2);
98+
99+
if (isDefined(existingV2Metadata) && existingV2Metadata.id !== index.id) {
100+
// V2 metadata already exists, this v1 metadata is stale
101+
this.logger.log(
102+
`Index metadata with v2 name ${indexNameV2} already exists, removing stale v1 metadata and index ${index.name}`,
103+
);
104+
105+
if (!isDryRun) {
106+
const queryRunner = this.coreDataSource.createQueryRunner();
107+
108+
await queryRunner.connect();
109+
await queryRunner.startTransaction();
110+
111+
try {
112+
await queryRunner.manager.delete(IndexMetadataEntity, index.id);
113+
await queryRunner.query(
114+
`DROP INDEX IF EXISTS "${schemaName}"."${index.name}"`,
115+
);
116+
await queryRunner.commitTransaction();
117+
hasRemovedIndexMetadata = true;
118+
} catch (error) {
119+
await queryRunner.rollbackTransaction();
120+
throw error;
121+
} finally {
122+
await queryRunner.release();
123+
}
124+
}
125+
continue;
126+
}
127+
90128
this.logger.log(`Renaming index ${index.name} to ${indexNameV2}`);
91129

92130
if (isDryRun) {
@@ -124,6 +162,23 @@ export class RenameIndexNameCommand extends ActiveOrSuspendedWorkspacesMigration
124162
IndexMetadataEntity,
125163
index.id,
126164
);
165+
hasRemovedIndexMetadata = true;
166+
} else if (error.code === '42P07') {
167+
// PostgreSQL error code 42P07: duplicate_table (v2 index already exists)
168+
// The v2 index already exists, remove stale v1 metadata and index
169+
this.logger.log(
170+
`Index ${indexNameV2} already exists at PG level, removing stale v1 metadata and index ${index.name}`,
171+
);
172+
173+
await this.coreDataSource.manager.delete(
174+
IndexMetadataEntity,
175+
index.id,
176+
);
177+
178+
await this.coreDataSource.query(
179+
`DROP INDEX IF EXISTS "${schemaName}"."${index.name}"`,
180+
);
181+
127182
hasRemovedIndexMetadata = true;
128183
} else {
129184
this.logger.error(

0 commit comments

Comments
 (0)