| From: | surya poondla <suryapoondla4(at)gmail(dot)com> |
|---|---|
| To: | Peter Smith <smithpb2250(at)gmail(dot)com> |
| Cc: | PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>, "jiaoshuntian(at)gmail(dot)com" <jiaoshuntian(at)gmail(dot)com>, "nishant(dot)sharma(at)enterprisedb(dot)com" <nishant(dot)sharma(at)enterprisedb(dot)com>, "jim(dot)jones(at)uni-muenster(dot)de" <jim(dot)jones(at)uni-muenster(dot)de>, "niushiji(at)gmail(dot)com" <niushiji(at)gmail(dot)com> |
| Subject: | Re: PSQL schema "describe" \dn is not escaping quotes |
| Date: | 2026-09-01 23:48:09 |
| Message-ID: | CAOVWO5oUGhq-h1uMEx+hgnv+72Srn6tDn5Mk55Z_dfhgANjeUw@mail.gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
Hi Peter,
Thanks for the patch. Nice review comments.
I applied v3 on master and did some testing of my own. A few observations.
1) The patch fixes more than the reported case, which I think is worth
calling out in the commit message. Because the old code compared
n.nspname against the raw pattern text, the footer was silently missing for
*any* double-quoted pattern, not just ones containing an embedded single
quote:
-- unpatched
test=# \dn sch_a
List of schemas
Name | Owner
-------+----------
sch_a | postgres
Included in publications:
"pub_a"
test=# \dn "sch_a"
List of schemas
Name | Owner
-------+----------
sch_a | postgres
(1 row) <-- footer silently missing
FWIW I checked describe.c for other places where a user-supplied pattern is
interpolated into query text, and this is the only one
every other use of 'pattern' is either a pg_log_error() message or goes
through validateSQLNamePattern().
2) I'm less sure about switching this query to pattern matching.
processSQLNamePattern() turns it into a regex match, so it can now
match several schemas, but the footer belongs to the whole table rather
than to any one row:
-- v3
test=# \dn sch*
List of schemas
Name | Owner
-------+----------
sch_a | postgres
sch_b | postgres
Included in publications:
"pub_a"
"pub_b"
There's no way to tell which publication goes with which schema, and with
"\dn *" you get every schema publication in the database lumped
into one footer.
Unpatched, "\dn sch*" prints no footer at all (nspname = 'sch*' matches
nothing), so this is new behaviour.
Since the footer only really makes sense for a single schema, how about
keying off the row the main query already returned, rather than
re-interpreting the pattern?
if (pattern && PQntuples(res) == 1 && pset.sversion >= 150000)
{
...
appendPQExpBufferStr(&buf,
"SELECT pubname \n"
"FROM pg_catalog.pg_publication p\n"
" JOIN
pg_catalog.pg_publication_namespace pn ON p.oid = pn.pnpubid\n"
" JOIN pg_catalog.pg_namespace n ON
n.oid = pn.pnnspid \n"
"WHERE n.nspname = ");
appendStringLiteralConn(&buf, PQgetvalue(res, 0, 0), pset.db);
appendPQExpBufferStr(&buf, "\nORDER BY 1");
That is exactly escaped, can't drift from what's actually displayed, and
skips the second query entirely when it wouldn't be meaningful.
Minor nit:
- One test line has a stray trailing semicolon:
\d "it's my public table";
psql strips it so it's harmless, but the neighbouring lines don't have one.
Regards,
Surya Poondla
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Michael Paquier | 2026-09-01 23:53:47 | Re: LockHasWaiters() crashes on fast-path locks |
| Previous Message | Michael Paquier | 2026-09-01 23:45:15 | Re: Remove fcinfo from statistics update internal functions |