Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/lib/sql/indexes.sql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ SELECT
JOIN pg_class c ON c.oid = idx.indexrelid
JOIN pg_namespace n ON c.relnamespace = n.oid
JOIN pg_am am ON c.relam = am.oid
JOIN pg_attribute a ON a.attrelid = c.oid AND a.attnum = ANY(idx.indkey)
JOIN pg_attribute a ON a.attrelid = c.oid AND a.attnum > 0
JOIN pg_indexes ix ON c.relname = ix.indexname
WHERE
${props.schemaFilter ? `n.nspname ${props.schemaFilter}` : 'true'}
Expand Down
52 changes: 52 additions & 0 deletions test/server/indexes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,58 @@ test('list indexes', async () => {
)
})

test('index attributes for indexes not on the leading table columns', async () => {
let res = await app.inject({
method: 'POST',
path: '/query',
payload: {
query: `
drop table if exists public.index_attr_test cascade;
create table public.index_attr_test (id int, name text, email text);
create index idx_attr_single_email on public.index_attr_test (email);
create index idx_attr_composite on public.index_attr_test (email, name);
`,
},
})
if (res.json().error) {
throw new Error(res.payload)
}

res = await app.inject({ method: 'GET', path: '/indexes' })
const indexes = res.json<PostgresIndex[]>()

const single = indexes.find(
({ index_definition }) =>
index_definition ===
'CREATE INDEX idx_attr_single_email ON public.index_attr_test USING btree (email)'
)!
expect(single.index_attributes).toEqual([
{ attribute_name: 'email', attribute_number: 1, data_type: 'text' },
])

const composite = indexes.find(
({ index_definition }) =>
index_definition ===
'CREATE INDEX idx_attr_composite ON public.index_attr_test USING btree (email, name)'
)!
expect(composite.index_attributes).toEqual([
{ attribute_name: 'email', attribute_number: 1, data_type: 'text' },
{ attribute_name: 'name', attribute_number: 2, data_type: 'text' },
])

res = await app.inject({ method: 'GET', path: `/indexes/${single.id}` })
expect(res.json<PostgresIndex>().id).toBe(single.id)

res = await app.inject({
method: 'POST',
path: '/query',
payload: { query: `drop table public.index_attr_test;` },
})
if (res.json().error) {
throw new Error(res.payload)
}
})

test('retrieve index', async () => {
const res = await app.inject({ method: 'GET', path: '/indexes/16400' })
const index = res.json<PostgresIndex>()
Expand Down