From d6c2e4658a5c4a7999ef8fb7e5bef23e7f8ed374 Mon Sep 17 00:00:00 2001 From: oniani1 Date: Tue, 9 Jun 2026 23:54:36 +0400 Subject: [PATCH] fix: escape replica_identity_index with ident() In tables.update(), replica_identity_index is interpolated into the `REPLICA IDENTITY USING INDEX` clause without ident(), while every other identifier in the same function is escaped. Index names that need quoting produce invalid SQL, and the value is not safely escaped before it reaches the database. Wrap it with ident() to match the surrounding code. --- src/lib/PostgresMetaTables.ts | 2 +- test/lib/tables.ts | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/lib/PostgresMetaTables.ts b/src/lib/PostgresMetaTables.ts index d4304645..c2e324ce 100644 --- a/src/lib/PostgresMetaTables.ts +++ b/src/lib/PostgresMetaTables.ts @@ -171,7 +171,7 @@ export default class PostgresMetaTables { if (replica_identity === undefined) { // skip } else if (replica_identity === 'INDEX') { - replicaSql = `${alter} REPLICA IDENTITY USING INDEX ${replica_identity_index};` + replicaSql = `${alter} REPLICA IDENTITY USING INDEX ${ident(replica_identity_index)};` } else { replicaSql = `${alter} REPLICA IDENTITY ${replica_identity};` } diff --git a/test/lib/tables.ts b/test/lib/tables.ts index 752b9e96..85043151 100644 --- a/test/lib/tables.ts +++ b/test/lib/tables.ts @@ -577,3 +577,25 @@ test('composite primary keys preserve order', async () => { await pgMeta.tables.remove(res.data!.id) }) + +test('update replica identity using an index whose name needs quoting', async () => { + // The index name contains a space and uppercase letters, so it only resolves + // if it is passed through ident(). An unquoted name would make the generated + // ALTER TABLE ... USING INDEX statement invalid. + await pgMeta.query(` + CREATE TABLE public.t_replica_idx (id int8 NOT NULL); + CREATE UNIQUE INDEX "Weird Index" ON public.t_replica_idx (id); + `) + const { data: tables } = await pgMeta.tables.list() + const tableId = tables!.find((t) => t.name === 't_replica_idx')!.id + + const res = await pgMeta.tables.update(tableId, { + replica_identity: 'INDEX', + replica_identity_index: 'Weird Index', + }) + + expect(res.error).toBeNull() + expect(res.data!.replica_identity).toBe('INDEX') + + await pgMeta.tables.remove(tableId) +})