aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/trigger.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands/trigger.c')
-rw-r--r--src/backend/commands/trigger.c28
1 files changed, 23 insertions, 5 deletions
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c
index 86449a641cc..fa74bd2cf10 100644
--- a/src/backend/commands/trigger.c
+++ b/src/backend/commands/trigger.c
@@ -43,6 +43,7 @@
#include "pgstat.h"
#include "rewrite/rewriteManip.h"
#include "storage/bufmgr.h"
+#include "storage/lmgr.h"
#include "tcop/utility.h"
#include "utils/acl.h"
#include "utils/builtins.h"
@@ -96,6 +97,13 @@ static void AfterTriggerSaveEvent(EState *estate, ResultRelInfo *relinfo,
* queryString is the source text of the CREATE TRIGGER command.
* This must be supplied if a whenClause is specified, else it can be NULL.
*
+ * relOid, if nonzero, is the relation on which the trigger should be
+ * created. If zero, the name provided in the statement will be looked up.
+ *
+ * refRelOid, if nonzero, is the relation to which the constraint trigger
+ * refers. If zero, the constraint relation name provided in the statement
+ * will be looked up as needed.
+ *
* constraintOid, if nonzero, says that this trigger is being created
* internally to implement that constraint. A suitable pg_depend entry will
* be made to link the trigger to that constraint. constraintOid is zero when
@@ -118,7 +126,7 @@ static void AfterTriggerSaveEvent(EState *estate, ResultRelInfo *relinfo,
*/
Oid
CreateTrigger(CreateTrigStmt *stmt, const char *queryString,
- Oid constraintOid, Oid indexOid,
+ Oid relOid, Oid refRelOid, Oid constraintOid, Oid indexOid,
bool isInternal)
{
int16 tgtype;
@@ -147,7 +155,10 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString,
ObjectAddress myself,
referenced;
- rel = heap_openrv(stmt->relation, AccessExclusiveLock);
+ if (OidIsValid(relOid))
+ rel = heap_open(relOid, AccessExclusiveLock);
+ else
+ rel = heap_openrv(stmt->relation, AccessExclusiveLock);
/*
* Triggers must be on tables or views, and there are additional
@@ -196,7 +207,7 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString,
errmsg("permission denied: \"%s\" is a system catalog",
RelationGetRelationName(rel))));
- if (stmt->isconstraint && stmt->constrrel != NULL)
+ if (stmt->isconstraint)
{
/*
* We must take a lock on the target relation to protect against
@@ -205,7 +216,14 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString,
* might end up creating a pg_constraint entry referencing a
* nonexistent table.
*/
- constrrelid = RangeVarGetRelid(stmt->constrrel, AccessShareLock, false);
+ if (OidIsValid(refRelOid))
+ {
+ LockRelationOid(refRelOid, AccessShareLock);
+ constrrelid = refRelOid;
+ }
+ else if (stmt->constrrel != NULL)
+ constrrelid = RangeVarGetRelid(stmt->constrrel, AccessShareLock,
+ false);
}
/* permission checks */
@@ -501,7 +519,7 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString,
ereport(ERROR,
(errcode(ERRCODE_DUPLICATE_OBJECT),
errmsg("trigger \"%s\" for relation \"%s\" already exists",
- trigname, stmt->relation->relname)));
+ trigname, RelationGetRelationName(rel))));
}
systable_endscan(tgscan);
}