Eu criei a seguinte consulta para obter o nome da tabela, index_type, operator_classes e exclusividade dos índices com base nas respostas principalmente de @Erwin Brandstetter:
SELECT i.indrelid::regclass::text AS table
, c.relname AS index_name
, a.amname AS index_type
, opc.operator_classes
, i.indisunique AS is_unique
, array_agg(att.attname) as column_names
FROM pg_catalog.pg_namespace n
JOIN pg_catalog.pg_class c ON c.relnamespace = n.oid
JOIN pg_catalog.pg_attribute att ON att.attrelid = c.oid
JOIN pg_catalog.pg_index i ON i.indexrelid = c.oid
JOIN pg_catalog.pg_am a ON a.oid = c.relam
CROSS JOIN LATERAL (
SELECT ARRAY (SELECT opc.opcname
FROM unnest(i.indclass::oid[]) WITH ORDINALITY o(oid, ord)
JOIN pg_opclass opc ON opc.oid = o.oid
ORDER BY o.ord)
) opc(operator_classes)
WHERE n.nspname !~ '^pg_'
AND c.relkind = ANY (ARRAY['r', 't', 'i'])
group by
i.indrelid, c.relname, a.amname, opc.operator_classes, i.indisunique
ORDER BY 1, 2, 3, 4;
Isso funciona muito bem, exceto que retorna nomes de colunas errados quando o índice é criado pela transformação de dados de outra coluna. Por exemplo, com o seguinte índice:
CREATE INDEX _ixtr_luxury_inventory_images ON public.luxury_inventory
USING gin (f_textarr2text(images) gin_trgm_ops)
retorna:
table | luxury_inventory
index_name | _ixtr_luxury_inventory_images
index_type | gin
operator_classes | ['gin_trgm_ops']
is_unique | False
column_names | ['f_textarr2text']
Obtemos f_textarr2text
o nome da coluna em vez de images
.
Como podemos obter os column_names corretos? Estou no Postgres 16.2, se isso importa.
Atualização: Aqui está o SQL de criação da tabela:
create table "luxury_inventory" (
id bigserial primary key,
images text[])
CREATE OR REPLACE FUNCTION "public".f_textarr2text(text[])
RETURNS text LANGUAGE sql IMMUTABLE AS $$SELECT array_to_string($1, ',')$$;