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` over the 'indexprs' (converting `pg_tree_node` to `text`) for `varattno`) 

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
     , 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 |column\_names |
| --- | --- | --- | --- | --- |
| *NULL* |content\_tsv |file\_lookup\_16k |fl\_16k\_tsv\_idx |content\_tsv |
| *NULL* |content\_tsv |file\_lookup\_4k |fl\_4k\_tsv\_idx |content\_tsv |
| *NULL* |file\_id |file\_lookup\_4k |date\_index |file\_id |
| \["file\_id"\] |abs\(file\_id\) |file\_lookup\_4k |date2\_index |abs |
| \["sequence\_no"\] |round\(sequence\_no::double precision\) |file\_lookup\_4k |date3\_index |round |
| \["sequence\_no"\] |round\(sequence\_no::double precision\) |file\_lookup\_4k |date4\_index |round |
| \["content"\] |"substring"\(content, 1, 5\) |file\_lookup\_4k |date5\_index |substring |
| \["file\_id", "sequence\_no"\] |abs\(file\_id \- sequence\_no\) |file\_lookup\_4k |date6\_index |abs |
| *NULL* |content\_tsv |file\_lookup\_8k |fl\_8k\_tsv\_idx |content\_tsv |



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
- `JSON_AGG(columns.column_name)` can be replaced with `JSON_AGG(columns.*)` or the like to select the entire row for the columns.
-  `ANY (ARRAY['r', 't', 'i']` was updated to `IN  ANY ('r', 't', 'i')` 
---------------------------
EDIT:

In order to bring this into a single column, Let's `COALESCE`, and whenever the new function returns `NULL`, we will insert an array containing the result of the `pg_get_indexdef`, and prefer `ARRAY_AGG` to `JSON_AGG`. All together:

```
SELECT COALESCE((SELECT ARRAY_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)), 
                ARRAY[(pg_get_indexdef(att.attrelid, att.attnum, true))]) AS argument_columns
     , i.indrelid::regclass::text AS table
     , c.relname AS index_nameq
     , 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');
```

This produces:

| argument\_columns |table |index\_nameq |column\_names |
| --- | --- | --- | --- |
| \{file\_id\} |file\_lookup\_4k |date\_index |file\_id |
| \{file\_id\} |file\_lookup\_4k |date2\_index |abs |
| \{sequence\_no\} |file\_lookup\_4k |date3\_index |round |
| \{sequence\_no\} |file\_lookup\_4k |date4\_index |round |
| \{content\} |file\_lookup\_4k |date5\_index |substring |
| \{file\_id,sequence\_no\} |file\_lookup\_4k |date6\_index |abs |