diff --git a/src/lib/sql/table.sql.ts b/src/lib/sql/table.sql.ts index d7f70331..446c1f40 100644 --- a/src/lib/sql/table.sql.ts +++ b/src/lib/sql/table.sql.ts @@ -32,29 +32,26 @@ FROM JOIN pg_class c ON nc.oid = c.relnamespace left join ( select - table_id, - jsonb_agg(_pk.*) as primary_keys - from ( - select - n.nspname as schema, - c.relname as table_name, - a.attname as name, - c.oid :: int8 as table_id - from - pg_index i, - pg_class c, - pg_attribute a, - pg_namespace n - where - ${props.schemaFilter ? `n.nspname ${props.schemaFilter} AND` : ''} - ${props.tableIdentifierFilter ? `n.nspname || '.' || c.relname ${props.tableIdentifierFilter} AND` : ''} - i.indrelid = c.oid - and c.relnamespace = n.oid - and a.attrelid = c.oid - and a.attnum = any (i.indkey) - and i.indisprimary - ) as _pk - group by table_id + c.oid::int8 as table_id, + jsonb_agg( + jsonb_build_object( + 'table_id', c.oid::int8, + 'schema', n.nspname, + 'table_name', c.relname, + 'name', a.attname + ) + order by array_position(i.indkey, a.attnum) + ) as primary_keys + from + pg_index i + join pg_class c on i.indrelid = c.oid + join pg_namespace n on c.relnamespace = n.oid + join pg_attribute a on a.attrelid = c.oid and a.attnum = any(i.indkey) + where + ${props.schemaFilter ? `n.nspname ${props.schemaFilter} AND` : ''} + ${props.tableIdentifierFilter ? `n.nspname || '.' || c.relname ${props.tableIdentifierFilter} AND` : ''} + i.indisprimary + group by c.oid ) as pk on pk.table_id = c.oid left join ( diff --git a/test/lib/tables.ts b/test/lib/tables.ts index 00230ab4..677204fc 100644 --- a/test/lib/tables.ts +++ b/test/lib/tables.ts @@ -525,3 +525,20 @@ test('primary keys', async () => { ) await pgMeta.tables.remove(res.data!.id) }) + +test('composite primary keys preserve order', async () => { + let res = await pgMeta.tables.create({ name: 't_pk_order' }) + await pgMeta.columns.create({ table_id: res.data!.id, name: 'col_a', type: 'int8' }) + await pgMeta.columns.create({ table_id: res.data!.id, name: 'col_b', type: 'text' }) + await pgMeta.columns.create({ table_id: res.data!.id, name: 'col_c', type: 'int4' }) + + // Set primary keys in specific order: col_c, col_a, col_b + res = await pgMeta.tables.update(res.data!.id, { + primary_keys: [{ name: 'col_c' }, { name: 'col_a' }, { name: 'col_b' }], + }) + + // Verify the order is preserved + expect(res.data!.primary_keys.map((pk: any) => pk.name)).toEqual(['col_c', 'col_a', 'col_b']) + + await pgMeta.tables.remove(res.data!.id) +})