Re: PATCH: psql tab completion for SELECT

From: Edmund Horner <ejrh00(at)gmail(dot)com>
To: Heikki Linnakangas <hlinnaka(at)iki(dot)fi>
Cc: PostgreSQL Developers <pgsql-hackers(at)lists(dot)postgresql(dot)org>
Subject: Re: PATCH: psql tab completion for SELECT
Date: 2018-07-17 01:31:20
Views: Raw Message | Whole Thread | Download mbox
Lists: pgsql-hackers

On 17 July 2018 at 00:00, Heikki Linnakangas <hlinnaka(at)iki(dot)fi> wrote:
> Playing around with this a little bit, I'm not very satisfied with the
> completions. Sometimes this completes too much, and sometimes too little.
> All of this has been mentioned in this and the other thread [1] already,
> this just my opinion on all this.

Hi Heikki, thanks for getting this thread active again.

I do actually have another patch, which I didn't post yet because
everyone was busy with v11, and I wanted to wait for more feedback
about inclusions/exclusions. Holding it back now seems like a mistake
(especially since the last patch had a bug) so here it is.

There's also a patch, to be applied on top, that adds completion after commas.

> Too much:
> postgres=# \d lp
> Table "public.lp"
> Column | Type | Collation | Nullable | Default
> ----------+---------+-----------+----------+---------
> id | integer | | |
> partkey | text | | |
> partcol1 | text | | |
> partcol2 | text | | |
> Partition key: LIST (partkey)
> Number of partitions: 1000 (Use \d+ to list them.)
> postgres=# select pa[TAB]
> pad_attribute parameter_default parameter_style partattrs partcol2
> partexprs partrelid
> page parameter_mode parameter_types partclass
> partcollation partkey partstrat
> pageno parameter_name parse_ident( partcol1 partdefid
> partnatts passwd

I agree that there is too much. I don't know what the best way to
reduce it is, short of specifically excluding certain things. In
theory, I think the query could be sensitive to how much text is
entered, for example, let pa[TAB] not show partrelid and other columns
from pg_partition, but part[TAB] show them; the general rule could be
"only show attributes for system tables if 3 or more letters entered".
But I'm wary of overcomplicating a patch that is (IMHO) a useful
improvement even if simple.

> Too little:
> postgres=# select partkey, p[TAB]
> [no completions]
> Then there's the multi-column case, which seems weird (to a user - I know
> the implementation and understand why):
> postgres=# select partkey, partc[TAB]
> [no completions]

Yep, there was no completion after commas in the previous patches.

> And I'd love this case, where go back to edit the SELECT list, after already
> typing the FROM part, to be smarter:
> postgres=# select p[TAB] FROM lp;
> Display all 370 possibilities? (y or n)

I don't know enough about readline to estimate how easy this would be.
I think all our current completions use only the text up to the

> There's something weird going on with system columns, from a user's point of
> view:
> oid oidvectortypes(
> postgres=# select xm[TAB]
> xmin xmlcomment( xml_is_well_formed_content(
> xmlvalidate(
> xmlagg( xml_is_well_formed(
> xml_is_well_formed_document(
> So oid and xmin are completed. But "xmax" and "ctid" are not. I think this
> is because in fact none of the system columns are completed, but there
> happen to be some tables with regular columns named "oid" and "xmin". So it
> makes sense once you know that, but it's pretty confusing to a user.
> Tab-completion is a great way for a user to explore what's available, so
> it's weird that some system columns are effectively completed while others
> are not.

You are correct, system columns are excluded, but of course there are
always the same column names in other tables. Do you think we should
just include all columns?

> I'd like to not include set-returning functions from the list. Although you
> can do "SELECT generate_series(1,10)", I'd like to discourage people from
> doing that, since using set-returning functions in the target list is a
> PostgreSQL extension to the SQL standard, and IMHO the "SELECT * FROM
> generate_series(1,10)" syntax is easier to understand and works more sanely
> with joins etc. Conversely, it would be really nice to include set-returning
> function in the completions after FROM.

I'm happy to exclude SRFs after SELECT if others agree. Including
them after FROM seems worthwhile, but best left for a different patch?

> I understand that there isn't much you can do about some of those things,
> short of adding a ton of new context information about previous queries and
> heuristics. I think the completion needs to be smarter to be acceptable. I
> don't know what exactly to do, but perhaps someone else has ideas.
> I'm also worried about performance, especially of the query to get all the
> column names. It's pretty much guaranteed to do perform a
> SeqScan+Sort+Unique on pg_attribute. pg_attribute can be very large. In my
> little test database, with the above 1000-partition table, hitting tab after
> "SELECT " takes about 1 second, until you get the "Display all 1000
> possibilities" prompt. And that's not a particularly large schema.

The indexes on pg_attribute both start with attrelid; unless we know
what small set of relations we want attributes for, I don't think we
can avoid a SeqScan. Maybe there's a way to extract the attribute
name part from the text entered and use it in a "WHERE attname LIKE
'%s' " qualifier, to encourage an IndexOnlyScan for some cases.

> PS. All the references to "pg_attribute" and other system tables, and
> functions, need to be schema-qualified, as "pg_catalog.pg_attribute" and so
> forth.

(Thanks for the advice. I managed to sneak this into the updated patch.)

Attachment Content-Type Size
psql-select-tab-completion-v7.patch application/octet-stream 4.2 KB
select-comma-completion-v1.patch application/octet-stream 2.8 KB

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Edmund Horner 2018-07-17 01:44:59 Re: PATCH: psql tab completion for SELECT
Previous Message Michael Paquier 2018-07-17 00:29:34 Re: patch to allow disable of WAL recycling