psql \d: Display table where trigger is defined, if inherited

It's important to know that a trigger is cloned from a parent table,
because of the behavior that the trigger is dropped on detach.  Make
psql's \d display it.

We'd like to backpatch, but lack of the pg_trigger.tgparentid column
makes it more difficult.  Punt for now.  If somebody wants to volunteer
an implementation that reads pg_depend on older versions, that can
probably be backpatched.

Authors: Justin Pryzby, Amit Langote, Álvaro Herrera
Discussion: https://postgr.es/m/20200419002206.GM26953@telsasoft.com
This commit is contained in:
Alvaro Herrera 2020-04-21 18:37:26 -04:00
parent 27dbe1a184
commit c33869cc3b
No known key found for this signature in database
GPG Key ID: 1C20ACB9D5C564AE
2 changed files with 17 additions and 3 deletions

View File

@ -2939,14 +2939,22 @@ describeOneTableDetails(const char *schemaname,
printfPQExpBuffer(&buf,
"SELECT t.tgname, "
"pg_catalog.pg_get_triggerdef(t.oid%s), "
"t.tgenabled, %s\n"
"t.tgenabled, %s, %s\n"
"FROM pg_catalog.pg_trigger t\n"
"WHERE t.tgrelid = '%s' AND ",
(pset.sversion >= 90000 ? ", true" : ""),
(pset.sversion >= 90000 ? "t.tgisinternal" :
pset.sversion >= 80300 ?
"t.tgconstraint <> 0 AS tgisinternal" :
"false AS tgisinternal"), oid);
"false AS tgisinternal"),
(pset.sversion >= 130000 ?
"(SELECT (NULLIF(a.relid, t.tgrelid))::pg_catalog.regclass"
" FROM pg_catalog.pg_trigger AS u, "
" pg_catalog.pg_partition_ancestors(t.tgrelid) AS a"
" WHERE u.tgname = t.tgname AND u.tgrelid = a.relid"
" AND u.tgparentid = 0) AS parent" :
"NULL AS parent"),
oid);
if (pset.sversion >= 110000)
appendPQExpBufferStr(&buf, "(NOT t.tgisinternal OR (t.tgisinternal AND t.tgenabled = 'D') \n"
" OR EXISTS (SELECT 1 FROM pg_catalog.pg_depend WHERE objid = t.oid \n"
@ -3062,6 +3070,12 @@ describeOneTableDetails(const char *schemaname,
tgdef = usingpos + 9;
printfPQExpBuffer(&buf, " %s", tgdef);
/* Visually distinguish inherited triggers */
if (!PQgetisnull(result, i, 4))
appendPQExpBuffer(&buf, ", ON TABLE %s",
PQgetvalue(result, i, 4));
printTableAddFooter(&cont, buf.data);
}
}

View File

@ -2033,7 +2033,7 @@ create trigger trg1 after insert on trigpart for each row execute procedure trig
b | integer | | |
Partition of: trigpart FOR VALUES FROM (2000) TO (3000)
Triggers:
trg1 AFTER INSERT ON trigpart3 FOR EACH ROW EXECUTE FUNCTION trigger_nothing()
trg1 AFTER INSERT ON trigpart3 FOR EACH ROW EXECUTE FUNCTION trigger_nothing(), ON TABLE trigpart
alter table trigpart detach partition trigpart3;
drop trigger trg1 on trigpart3; -- fail due to "does not exist"