Re: Support tab completion for upper character inputs in psql
Tom Lane <tgl@sss.pgh.pa.us>
From: Tom Lane <tgl@sss.pgh.pa.us>
To: "tanghy.fnst@fujitsu.com" <tanghy.fnst@fujitsu.com>
Cc: Peter Eisentraut <peter.eisentraut@enterprisedb.com>,
Japin Li <japinli@hotmail.com>,
Kyotaro Horiguchi <horikyota.ntt@gmail.com>,
Laurenz Albe <laurenz.albe@cybertec.at>,
"smithpb2250@gmail.com" <smithpb2250@gmail.com>,
"david.zhang@highgo.ca" <david.zhang@highgo.ca>,
"pgsql-hackers@lists.postgresql.org"
<pgsql-hackers@lists.postgresql.org>
Date: 2022-01-28T21:25:57Z
Lists: pgsql-hackers
Attachments
- v15-0001-rethink-tab-completion-quoting.patch (text/x-diff) patch v15-0001
- v15-0002-fix-up-completion-info.patch (text/x-diff) patch v15-0002
- v15-0003-re-pgindent.patch (text/x-diff) patch v15-0003
- v15-0004-add-test-cases.patch (text/x-diff) patch v15-0004
- v15-0005-use-LIKE-not-substring.patch (text/x-diff) patch v15-0005
I wrote:
> It's certainly arguable that the first case is right as-is and we
> shouldn't change it. I think that could be handled by tweaking my
> patch so that it wouldn't offer completions that start with a quote
> unless the input word does. That would also cause I<TAB> to complete
> immediately to id, which is arguably fine.
Here's a patch series that does it like that. I have to admit that
after playing with it, this is probably better. There's less
magic-looking behavior involved, and it lets me drop an ugly hack
I had to work around a case where Readline didn't want to play along.
0001 also cleans up one oversight in the previous version, which
is to beware of multibyte characters in parse_identifier(). I'm
not sure there is any actual hazard there, since we weren't looking
for backslashes, but it's better to be sure. I added the keyword
handling I'd left out before, too.
0002-0004 are largely as before.
I've also added 0005, which changes the prefix-matching clauses
in the SQL queries from "substring(foo,1,%d)='%s'" to
"foo LIKE '%s'". This simplifies reading the queries a little bit,
but the real reason to do it is that the planner can optimize the
catalog searches a lot better. It knows a lot about LIKE prefix
queries and exactly nothing about substring(). For example,
DROP TYPE foo<TAB> now produces a query like this:
explain SELECT t.typname, NULL::pg_catalog.text FROM pg_catalog.pg_type t WHERE (t.typrelid = 0 OR (SELECT c.relkind = 'c' FROM pg_catalog.pg_class c WHERE c.oid = t.typrelid)) AND t.typname !~ '^_' AND (t.typname) LIKE 'foo%' AND pg_catalog.pg_type_is_visible(t.oid);
QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------------------
Index Scan using pg_type_typname_nsp_index on pg_type t (cost=0.28..16.63 rows=1 width=96)
Index Cond: ((typname >= 'foo'::text) AND (typname < 'fop'::text))
Filter: ((typname !~ '^_'::text) AND (typname ~~ 'foo%'::text) AND pg_type_is_visible(oid) AND ((typrelid = '0'::oid) OR (SubPlan 1)))
SubPlan 1
-> Index Scan using pg_class_oid_index on pg_class c (cost=0.28..8.30 rows=1 width=1)
Index Cond: (oid = t.typrelid)
(6 rows)
where before you got a seqscan:
explain SELECT pg_catalog.format_type(t.oid, NULL) FROM pg_catalog.pg_type t WHERE (t.typrelid = 0 OR (SELECT c.relkind = 'c' FROM pg_catalog.pg_class c WHERE c.oid = t.typrelid)) AND t.typname !~ '^_' AND substring(pg_catalog.format_type(t.oid, NULL),1,3)='foo' AND pg_catalog.pg_type_is_visible(t.oid);
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Seq Scan on pg_type t (cost=0.00..16691.86 rows=1 width=32)
Filter: ((typname !~ '^_'::text) AND ("substring"(format_type(oid, NULL::integer), 1, 3) = 'foo'::text) AND pg_type_is_visible(oid) AND ((typrelid = '0'::oid) OR (SubPlan 1)))
SubPlan 1
-> Index Scan using pg_class_oid_index on pg_class c (cost=0.28..8.30 rows=1 width=1)
Index Cond: (oid = t.typrelid)
(5 rows)
Again, while these queries only have to run at human speed, that doesn't
mean it's okay to be wasteful. I seem to recall hearing complaints that
they are noticeably slow in installations with many thousand tables, too.
This should help.
regards, tom lane
Commits
-
Fix minor memory leaks in psql's tab completion.
- 90474c16a7d2 16.0 landed
- 00cf40328a31 15.0 landed
-
Further tweaks for psql's new tab-completion logic.
- f0cd9097cfac 15.0 landed
-
Treat case of tab-completion keywords a bit more carefully.
- 020258fbd30d 15.0 landed
-
psql: improve tab-complete's handling of variant SQL names.
- 02b8048ba5dc 15.0 landed
-
Make PQcancel use the PGconn's tcp_user_timeout and keepalives settings.
- 5987feb70b5b 15.0 cited
-
Use a WaitLatch for vacuum/autovacuum sleeping
- 4753ef37e0ed 14.0 cited