aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/commands/tablecmds.c17
-rw-r--r--src/backend/commands/trigger.c18
-rw-r--r--src/backend/rewrite/rewriteDefine.c12
3 files changed, 20 insertions, 27 deletions
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 142419f2cca..4d4d4069ee8 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -3409,14 +3409,12 @@ ATRewriteTables(List **wqueue, LOCKMODE lockmode)
Relation refrel;
if (rel == NULL)
+ {
/* Long since locked, no need for another */
rel = heap_open(tab->relid, NoLock);
+ }
- /*
- * We're adding a trigger to both tables, so the lock level
- * here should sensibly reflect that.
- */
- refrel = heap_open(con->refrelid, ShareRowExclusiveLock);
+ refrel = heap_open(con->refrelid, RowShareLock);
validateForeignKeyConstraint(fkconstraint->conname, rel, refrel,
con->refindid,
@@ -5508,7 +5506,14 @@ ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel,
Oid indexOid;
Oid constrOid;
- pkrel = heap_openrv(fkconstraint->pktable, lockmode);
+ /*
+ * Grab an exclusive lock on the pk table, so that someone doesn't delete
+ * rows out from under us. (Although a lesser lock would do for that
+ * purpose, we'll need exclusive lock anyway to add triggers to the pk
+ * table; trying to start with a lesser lock will just create a risk of
+ * deadlock.)
+ */
+ pkrel = heap_openrv(fkconstraint->pktable, AccessExclusiveLock);
/*
* Validity checks (permission checks wait till we have the column
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c
index 798d8a85a4f..2464626637d 100644
--- a/src/backend/commands/trigger.c
+++ b/src/backend/commands/trigger.c
@@ -143,14 +143,7 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString,
ObjectAddress myself,
referenced;
- /*
- * ShareRowExclusiveLock is sufficient to prevent concurrent write
- * activity to the relation, and thus to lock out any operations that
- * might want to fire triggers on the relation. If we had ON SELECT
- * triggers we would need to take an AccessExclusiveLock to add one of
- * those, just as we do with ON SELECT rules.
- */
- rel = heap_openrv(stmt->relation, ShareRowExclusiveLock);
+ rel = heap_openrv(stmt->relation, AccessExclusiveLock);
/*
* Triggers must be on tables or views, and there are additional
@@ -480,7 +473,7 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString,
* can skip this for internally generated triggers, since the name
* modification above should be sufficient.
*
- * NOTE that this is cool only because we have ShareRowExclusiveLock on
+ * NOTE that this is cool only because we have AccessExclusiveLock on
* the relation, so the trigger set won't be changing underneath us.
*/
if (!isInternal)
@@ -1084,14 +1077,11 @@ RemoveTriggerById(Oid trigOid)
elog(ERROR, "could not find tuple for trigger %u", trigOid);
/*
- * Open and lock the relation the trigger belongs to. As in
- * CreateTrigger, this is sufficient to lock out all operations that could
- * fire or add triggers; but it would need to be revisited if we had ON
- * SELECT triggers.
+ * Open and exclusive-lock the relation the trigger belongs to.
*/
relid = ((Form_pg_trigger) GETSTRUCT(tup))->tgrelid;
- rel = heap_open(relid, ShareRowExclusiveLock);
+ rel = heap_open(relid, AccessExclusiveLock);
if (rel->rd_rel->relkind != RELKIND_RELATION &&
rel->rd_rel->relkind != RELKIND_VIEW)
diff --git a/src/backend/rewrite/rewriteDefine.c b/src/backend/rewrite/rewriteDefine.c
index 52c55def155..5a4c5695946 100644
--- a/src/backend/rewrite/rewriteDefine.c
+++ b/src/backend/rewrite/rewriteDefine.c
@@ -240,14 +240,12 @@ DefineQueryRewrite(char *rulename,
/*
* If we are installing an ON SELECT rule, we had better grab
* AccessExclusiveLock to ensure no SELECTs are currently running on the
- * event relation. For other types of rules, it is sufficient to grab
- * ShareRowExclusiveLock to lock out insert/update/delete actions and to
- * ensure that we lock out current CREATE RULE statements.
+ * event relation. For other types of rules, it would be sufficient to
+ * grab ShareRowExclusiveLock to lock out insert/update/delete actions and
+ * to ensure that we lock out current CREATE RULE statements; but because
+ * of race conditions in access to catalog entries, we can't do that yet.
*/
- if (event_type == CMD_SELECT)
- event_relation = heap_open(event_relid, AccessExclusiveLock);
- else
- event_relation = heap_open(event_relid, ShareRowExclusiveLock);
+ event_relation = heap_open(event_relid, AccessExclusiveLock);
/*
* Verify relation is of a type that rules can sensibly be applied to.