fix(server): normalize legacy index names (command) (#22053)
## TL;DR Adds a workspace upgrade command that normalizes index names to the current v2 deterministic naming convention (IDX_ prefix). This will close https://github.com/twentyhq/twenty/issues/21383 : uniqueness constraint cannot be disabled (for users who set it before v2 determinist naming is enforced). ### Background The deterministic index name embeds the table name, columns, uniqueness and where clause. The naming convention changed on **2025-09-23** (#14567 - added the `IDX_`/`IDX_UNIQUE_` prefix and folded the table name into the hash). Index rows created before that kept their old name in `core."indexMetadata"`, and nothing rewrites it (only targeted phone/relation rebuilds got new names). Code paths that locate an index by recomputing its expected name then miss these legacy-named rows. The most visible symptom is #21383: toggling a field's `isUnique` from `true` → `false` recomputes the expected unique-index name, fails to find the legacy-named index, and silently no-ops — so uniqueness can't be disabled. ### What the command does Per workspace, for each index: - recomputes the expected name with the same generator the app uses (`generateFlatIndexMetadataWithNameOrThrow`); - if the stored name differs → **rename** it (metadata `UPDATE` + a new metadata-only `ALTER INDEX … RENAME`, which preserves the unique constraint with no rebuild/lock); - if a correctly-named twin already exists (the legacy + freshly-generated duplicate case) → **drop the redundant** one (physical + metadata, field rows cascade) and keep the canonical; - invalidates the metadata cache so the running app + `isUnique` derivation reflect the new names. Honors `--dry-run`, wraps writes in a transaction (rolls back on error), and skips (with a warning) any single index whose name can't be recomputed so it can't abort the whole workspace. ### Notable changes - New `renameIndex` on `WorkspaceSchemaIndexManagerService` (`ALTER INDEX IF EXISTS … RENAME`). - Planning logic extracted into a pure, unit-tested util (`planIndexNameNormalization`).
This commit is contained in:
+16
@@ -90,4 +90,20 @@ export class WorkspaceSchemaIndexManagerService {
|
||||
|
||||
await queryRunner.query(sql);
|
||||
}
|
||||
|
||||
async renameIndexWithoutRebuild({
|
||||
queryRunner,
|
||||
schemaName,
|
||||
fromIndexName,
|
||||
toIndexName,
|
||||
}: {
|
||||
queryRunner: QueryRunner;
|
||||
schemaName: string;
|
||||
fromIndexName: string;
|
||||
toIndexName: string;
|
||||
}): Promise<void> {
|
||||
const sql = `ALTER INDEX ${escapeIdentifier(schemaName)}.${escapeIdentifier(fromIndexName)} RENAME TO ${escapeIdentifier(toIndexName)}`;
|
||||
|
||||
await queryRunner.query(sql);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user