Skip to main content
1 of 5

Thinking on this for a moment, perhaps better than pg_get_indexdef is pulling column ordinals out of the indexprs column noted in the first answer, and specifically the varattno field. regexp_matches for that (and only that :)) I threw together the following, going back to the definition in the columns table of information_schema:

SELECT (SELECT JSON_AGG(columns.column_name)
          FROM information_schema.columns
         WHERE table_schema = 'public'
           AND table_name   = i.indrelid::regclass::text
           AND ordinal_position IN (SELECT matches[1]::INTEGER 
                                    FROM regexp_matches(i.indexprs::TEXT,
                                                        'varattno (\d)',
                                                        'g') as matches)) AS argument_columns
     , pg_get_indexdef(att.attrelid, att.attnum, true) 
     , i.indrelid::regclass::text AS table
     , c.relname AS index_nameq
     , i.indisunique AS is_unique
     , 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
WHERE  n.nspname !~ '^pg_'
AND    c.relkind IN ('r', 't', 'i')

and that produces:

argument_columns pg_get_indexdef table index_nameq is_unique column_names
["content"] "substring"(content, 1, 5) file_lookup_4k date5_index 0 substring
["file_id", "sequence_no"] abs(file_id - sequence_no) file_lookup_4k date6_index 0 abs
["file_id"] abs(file_id) file_lookup_4k date2_index 0 abs
["sequence_no"] round(sequence_no::double precision) file_lookup_4k date3_index 0 round
["sequence_no"] round(sequence_no::double precision) file_lookup_4k date4_index 0 round

I feel that this is far more in line with what we would both want.

Note that I joined only to the attname table, because that is really all I need