From: Alvaro Herrera <alvherre@2ndquadrant.com>
To: Pg Hackers <pgsql-hackers@lists.postgresql.org>
Cc: Amit Langote <amitlangote09@gmail.com>
Subject: pg_trigger.tgparentid
Date: Mon, 17 Feb 2020 18:56:41 -0300
Message-ID: <20200217215641.GA29784@alvherre.pgsql> (raw)
As mentioned in https://postgr.es/m/20191231194759.GA24692@alvherre.pgsql
I propose to add a new column to pg_trigger, which allows us to remove a
pg_depend scan when cloning triggers when adding/attaching partitions.
(It's not that I think the scan is a performance problem, but rather
than notionally we try not to depend on pg_depend contents for this kind
of semantic derivation.)
--
Álvaro Herrera 39°49'30"S 73°17'W
Attachments:
[text/x-diff] 0001-Record-parents-of-triggers.patch (4.8K, ../20200217215641.GA29784@alvherre.pgsql/2-0001-Record-parents-of-triggers.patch)
download | inline diff:
From 8f1be4b2c24385bbfe2ecba941545ffa84f60b47 Mon Sep 17 00:00:00 2001
From: Alvaro Herrera <alvherre@alvh.no-ip.org>
Date: Mon, 17 Feb 2020 17:34:47 -0300
Subject: [PATCH] Record parents of triggers
This let us get rid of a recently introduced ugly hack (commit
1fa846f1c9af).
---
doc/src/sgml/catalogs.sgml | 7 +++++
src/backend/commands/tablecmds.c | 52 ++------------------------------
src/backend/commands/trigger.c | 1 +
src/include/catalog/pg_trigger.h | 1 +
4 files changed, 11 insertions(+), 50 deletions(-)
diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgmlindex a10b66569b..0bba96ee52 100644--- a/doc/src/sgml/catalogs.sgml+++ b/doc/src/sgml/catalogs.sgml@@ -6951,6 +6951,13 @@ SCRAM-SHA-256$<replaceable><iteration count></replaceable>:<replaceable>&l
<entry>The table this trigger is on</entry>
</row>
+ <row>+ <entry><structfield>tgparentid</structfield></entry>+ <entry><type>oid</type></entry>+ <entry><literal><link linkend="catalog-pg-trigger"><structname>pg_trigger</structname></link>.oid</literal></entry>+ <entry>Parent trigger of this trigger, if any</entry>+ </row>+
<row>
<entry><structfield>tgname</structfield></entry>
<entry><type>name</type></entry>
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.cindex b7c8d663fc..ae39bf1056 100644--- a/src/backend/commands/tablecmds.c+++ b/src/backend/commands/tablecmds.c@@ -16447,54 +16447,6 @@ out:
MemoryContextDelete(cxt);
}
-/*- * isPartitionTrigger- * Subroutine for CloneRowTriggersToPartition: determine whether- * the given trigger has been cloned from another one.- *- * We use pg_depend as a proxy for this, since we don't have any direct- * evidence. This is an ugly hack to cope with a catalog deficiency.- * Keep away from children. Do not stare with naked eyes. Do not propagate.- */-static bool-isPartitionTrigger(Oid trigger_oid)-{- Relation pg_depend;- ScanKeyData key[2];- SysScanDesc scan;- HeapTuple tup;- bool found = false;-- pg_depend = table_open(DependRelationId, AccessShareLock);-- ScanKeyInit(&key[0], Anum_pg_depend_classid,- BTEqualStrategyNumber,- F_OIDEQ,- ObjectIdGetDatum(TriggerRelationId));- ScanKeyInit(&key[1], Anum_pg_depend_objid,- BTEqualStrategyNumber,- F_OIDEQ,- ObjectIdGetDatum(trigger_oid));-- scan = systable_beginscan(pg_depend, DependDependerIndexId,- true, NULL, 2, key);- while ((tup = systable_getnext(scan)) != NULL)- {- Form_pg_depend dep = (Form_pg_depend) GETSTRUCT(tup);-- if (dep->refclassid == TriggerRelationId)- {- found = true;- break;- }- }-- systable_endscan(scan);- table_close(pg_depend, AccessShareLock);-- return found;-}-
/*
* CloneRowTriggersToPartition
* subroutine for ATExecAttachPartition/DefineRelation to create row
@@ -16541,7 +16493,7 @@ CloneRowTriggersToPartition(Relation parent, Relation partition)
*
* However, if our parent is a partitioned relation, there might be
* internal triggers that need cloning. In that case, we must skip
- * clone it if the trigger on parent depends on another trigger.+ * cloning it if the trigger on parent depends on another trigger.
*
* Note we dare not verify that the other trigger belongs to an
* ancestor relation of our parent, because that creates deadlock
@@ -16549,7 +16501,7 @@ CloneRowTriggersToPartition(Relation parent, Relation partition)
*/
if (trigForm->tgisinternal &&
(!parent->rd_rel->relispartition ||
- !isPartitionTrigger(trigForm->oid)))+ !OidIsValid(trigForm->tgparentid)))
continue;
/*
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.cindex b9b1262e30..6e8b7223fe 100644--- a/src/backend/commands/trigger.c+++ b/src/backend/commands/trigger.c@@ -847,6 +847,7 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString,
values[Anum_pg_trigger_oid - 1] = ObjectIdGetDatum(trigoid);
values[Anum_pg_trigger_tgrelid - 1] = ObjectIdGetDatum(RelationGetRelid(rel));
+ values[Anum_pg_trigger_tgparentid - 1] = ObjectIdGetDatum(parentTriggerOid);
values[Anum_pg_trigger_tgname - 1] = DirectFunctionCall1(namein,
CStringGetDatum(trigname));
values[Anum_pg_trigger_tgfoid - 1] = ObjectIdGetDatum(funcoid);
diff --git a/src/include/catalog/pg_trigger.h b/src/include/catalog/pg_trigger.hindex 2f30c7c2f9..9612b9bdd6 100644--- a/src/include/catalog/pg_trigger.h+++ b/src/include/catalog/pg_trigger.h@@ -35,6 +35,7 @@ CATALOG(pg_trigger,2620,TriggerRelationId)
{
Oid oid; /* oid */
Oid tgrelid; /* relation trigger is attached to */
+ Oid tgparentid; /* OID of parent trigger, if any */
NameData tgname; /* trigger's name */
Oid tgfoid; /* OID of function to be called */
int16 tgtype; /* BEFORE/AFTER/INSTEAD, UPDATE/DELETE/INSERT,
--
2.20.1
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: pgsql-hackers@postgresql.org
Cc: alvherre@2ndquadrant.com, pgsql-hackers@lists.postgresql.org, amitlangote09@gmail.com
Subject: Re: pg_trigger.tgparentid
In-Reply-To: <20200217215641.GA29784@alvherre.pgsql>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox