Skip to content

Commit 0aeceb2

Browse files
authored
fix(tables): ensure order of composite pks preserved (#996)
* fix(tables): ensure order of composite pks preserved * test: add test for preserving composite pk order
1 parent 09155b0 commit 0aeceb2

File tree

2 files changed

+37
-23
lines changed

2 files changed

+37
-23
lines changed

src/lib/sql/table.sql.ts

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -32,29 +32,26 @@ FROM
3232
JOIN pg_class c ON nc.oid = c.relnamespace
3333
left join (
3434
select
35-
table_id,
36-
jsonb_agg(_pk.*) as primary_keys
37-
from (
38-
select
39-
n.nspname as schema,
40-
c.relname as table_name,
41-
a.attname as name,
42-
c.oid :: int8 as table_id
43-
from
44-
pg_index i,
45-
pg_class c,
46-
pg_attribute a,
47-
pg_namespace n
48-
where
49-
${props.schemaFilter ? `n.nspname ${props.schemaFilter} AND` : ''}
50-
${props.tableIdentifierFilter ? `n.nspname || '.' || c.relname ${props.tableIdentifierFilter} AND` : ''}
51-
i.indrelid = c.oid
52-
and c.relnamespace = n.oid
53-
and a.attrelid = c.oid
54-
and a.attnum = any (i.indkey)
55-
and i.indisprimary
56-
) as _pk
57-
group by table_id
35+
c.oid::int8 as table_id,
36+
jsonb_agg(
37+
jsonb_build_object(
38+
'table_id', c.oid::int8,
39+
'schema', n.nspname,
40+
'table_name', c.relname,
41+
'name', a.attname
42+
)
43+
order by array_position(i.indkey, a.attnum)
44+
) as primary_keys
45+
from
46+
pg_index i
47+
join pg_class c on i.indrelid = c.oid
48+
join pg_namespace n on c.relnamespace = n.oid
49+
join pg_attribute a on a.attrelid = c.oid and a.attnum = any(i.indkey)
50+
where
51+
${props.schemaFilter ? `n.nspname ${props.schemaFilter} AND` : ''}
52+
${props.tableIdentifierFilter ? `n.nspname || '.' || c.relname ${props.tableIdentifierFilter} AND` : ''}
53+
i.indisprimary
54+
group by c.oid
5855
) as pk
5956
on pk.table_id = c.oid
6057
left join (

test/lib/tables.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,3 +525,20 @@ test('primary keys', async () => {
525525
)
526526
await pgMeta.tables.remove(res.data!.id)
527527
})
528+
529+
test('composite primary keys preserve order', async () => {
530+
let res = await pgMeta.tables.create({ name: 't_pk_order' })
531+
await pgMeta.columns.create({ table_id: res.data!.id, name: 'col_a', type: 'int8' })
532+
await pgMeta.columns.create({ table_id: res.data!.id, name: 'col_b', type: 'text' })
533+
await pgMeta.columns.create({ table_id: res.data!.id, name: 'col_c', type: 'int4' })
534+
535+
// Set primary keys in specific order: col_c, col_a, col_b
536+
res = await pgMeta.tables.update(res.data!.id, {
537+
primary_keys: [{ name: 'col_c' }, { name: 'col_a' }, { name: 'col_b' }],
538+
})
539+
540+
// Verify the order is preserved
541+
expect(res.data!.primary_keys.map((pk: any) => pk.name)).toEqual(['col_c', 'col_a', 'col_b'])
542+
543+
await pgMeta.tables.remove(res.data!.id)
544+
})

0 commit comments

Comments
 (0)