Simple
Just use the System Catalog Information Function pg_get_indexdef(index oid)
:
Reconstructs the creating command for an index. (This is a decompiled reconstruction, not the original text of the command.)
So just:
SELECT pg_get_indexdef(indexrelid) AS index_definition
FROM pg_catalog.pg_index;
index_definition
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
CREATE UNIQUE INDEX pg_foreign_data_wrapper_oid_index ON pg_catalog.pg_foreign_data_wrapper USING btree (oid)
CREATE UNIQUE INDEX pg_foreign_server_oid_index ON pg_catalog.pg_foreign_server USING btree (oid)
CREATE UNIQUE INDEX pg_user_mapping_oid_index ON pg_catalog.pg_user_mapping USING btree (oid)
...
This includes the index method (what you are asking for). The manual for Postgres 14:
method
The name of the index method to be used. Choices are btree
, hash
,
gist
, spgist
, gin
, and brin
. The default method is btree
.
... as well as: operator class (only if not default), collation (only if not default), schema (table is always schema-qualified), table, and index name.
Everything you might possibly need. Maybe even more than that, because the simple query above includes the many indexes of system catalogs.
Only indexes from user-land
SELECT pg_get_indexdef(i.indexrelid) AS index_definition
FROM pg_catalog.pg_namespace n
JOIN pg_catalog.pg_class c ON c.relnamespace = n.oid
JOIN pg_catalog.pg_index i ON i.indexrelid = c.oid
WHERE n.nspname !~ '^pg_'
AND c.relkind = 'i';
index_definition
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
CREATE UNIQUE INDEX b2_pkey ON public.b2 USING btree (big_id)
CREATE INDEX big_big_fts_gin_idx ON public.big USING gin (to_tsvector('simple'::regconfig, big))
...
The filter AND c.relkind = 'i'
is redundant, but makes the query faster.
(Related queries typically also add AND n.nspname <> 'information_schema'
. But since there are no indexes in information_schema
, we can skip that.)
Deluxe version
You may want data in dedicated columns and a meaningful order on top:
SELECT n.nspname AS schema
, i.indrelid::regclass::text AS table
, c.relname AS index
, a.amname AS index_method
, opc.operator_classes
, pg_get_indexdef(i.indexrelid) AS index_definition
FROM pg_catalog.pg_namespace n
JOIN pg_catalog.pg_class c ON c.relnamespace = n.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 = 'i'
ORDER BY 1, 2, 3, 4;
schema | table | index | index_method | operator_classes | index_definition
--------+-------------------+-------------------------------+--------------+-------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
public | b2 | b2_pkey | btree | {int4_ops} | CREATE UNIQUE INDEX b2_pkey ON public.b2 USING btree (big_id)
public | big | big_big_fts_gin_idx | gin | {tsvector_ops} | CREATE INDEX big_big_fts_gin_idx ON public.big USING gin (to_tsvector('simple'::regconfig, big))
...
Fetching the index method from the catalog table pg_am
, and operator classes from pg_opclass
. You might add collations ...
db<>fiddle here