Commit a195e3c3 authored by Tom Lane's avatar Tom Lane

Finish disabling reduced-lock-levels-for-DDL feature.

Previous patch only covered the ALTER TABLE changes, not changes in other
commands; and it neglected to revert the documentation changes.
parent 928408d9
...@@ -878,9 +878,8 @@ ERROR: could not serialize access due to read/write dependencies among transact ...@@ -878,9 +878,8 @@ ERROR: could not serialize access due to read/write dependencies among transact
</para> </para>
<para> <para>
Acquired by <command>CREATE TRIGGER</command>, This lock mode is not automatically acquired by any
<command>CREATE RULE</command> (except for <literal>ON SELECT</> <productname>PostgreSQL</productname> command.
rules) and some forms of <command>ALTER TABLE</command>.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
...@@ -925,10 +924,10 @@ ERROR: could not serialize access due to read/write dependencies among transact ...@@ -925,10 +924,10 @@ ERROR: could not serialize access due to read/write dependencies among transact
</para> </para>
<para> <para>
Acquired by the <command>DROP TABLE</command>, Acquired by the <command>ALTER TABLE</>, <command>DROP TABLE</>,
<command>TRUNCATE</command>, <command>REINDEX</command>, <command>TRUNCATE</command>, <command>REINDEX</command>,
<command>CLUSTER</command>, and <command>VACUUM FULL</command> <command>CLUSTER</command>, and <command>VACUUM FULL</command>
commands, and some forms of <command>ALTER TABLE</>. commands.
This is also the default lock mode for <command>LOCK TABLE</command> This is also the default lock mode for <command>LOCK TABLE</command>
statements that do not specify a mode explicitly. statements that do not specify a mode explicitly.
</para> </para>
......
...@@ -3425,14 +3425,12 @@ ATRewriteTables(List **wqueue, LOCKMODE lockmode) ...@@ -3425,14 +3425,12 @@ ATRewriteTables(List **wqueue, LOCKMODE lockmode)
Relation refrel; Relation refrel;
if (rel == NULL) if (rel == NULL)
{
/* Long since locked, no need for another */ /* Long since locked, no need for another */
rel = heap_open(tab->relid, NoLock); rel = heap_open(tab->relid, NoLock);
}
/* refrel = heap_open(con->refrelid, RowShareLock);
* We're adding a trigger to both tables, so the lock level
* here should sensibly reflect that.
*/
refrel = heap_open(con->refrelid, ShareRowExclusiveLock);
validateForeignKeyConstraint(fkconstraint->conname, rel, refrel, validateForeignKeyConstraint(fkconstraint->conname, rel, refrel,
con->refindid, con->refindid,
...@@ -5529,7 +5527,14 @@ ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel, ...@@ -5529,7 +5527,14 @@ ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel,
Oid indexOid; Oid indexOid;
Oid constrOid; 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 * Validity checks (permission checks wait till we have the column
......
...@@ -144,14 +144,7 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString, ...@@ -144,14 +144,7 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString,
ObjectAddress myself, ObjectAddress myself,
referenced; referenced;
/* rel = heap_openrv(stmt->relation, AccessExclusiveLock);
* 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);
/* /*
* Triggers must be on tables or views, and there are additional * Triggers must be on tables or views, and there are additional
...@@ -481,7 +474,7 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString, ...@@ -481,7 +474,7 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString,
* can skip this for internally generated triggers, since the name * can skip this for internally generated triggers, since the name
* modification above should be sufficient. * 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. * the relation, so the trigger set won't be changing underneath us.
*/ */
if (!isInternal) if (!isInternal)
...@@ -1085,14 +1078,11 @@ RemoveTriggerById(Oid trigOid) ...@@ -1085,14 +1078,11 @@ RemoveTriggerById(Oid trigOid)
elog(ERROR, "could not find tuple for trigger %u", trigOid); elog(ERROR, "could not find tuple for trigger %u", trigOid);
/* /*
* Open and lock the relation the trigger belongs to. As in * Open and exclusive-lock the relation the trigger belongs to.
* 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.
*/ */
relid = ((Form_pg_trigger) GETSTRUCT(tup))->tgrelid; relid = ((Form_pg_trigger) GETSTRUCT(tup))->tgrelid;
rel = heap_open(relid, ShareRowExclusiveLock); rel = heap_open(relid, AccessExclusiveLock);
if (rel->rd_rel->relkind != RELKIND_RELATION && if (rel->rd_rel->relkind != RELKIND_RELATION &&
rel->rd_rel->relkind != RELKIND_VIEW) rel->rd_rel->relkind != RELKIND_VIEW)
......
...@@ -238,14 +238,12 @@ DefineQueryRewrite(char *rulename, ...@@ -238,14 +238,12 @@ DefineQueryRewrite(char *rulename,
/* /*
* If we are installing an ON SELECT rule, we had better grab * If we are installing an ON SELECT rule, we had better grab
* AccessExclusiveLock to ensure no SELECTs are currently running on the * AccessExclusiveLock to ensure no SELECTs are currently running on the
* event relation. For other types of rules, it is sufficient to grab * event relation. For other types of rules, it would be sufficient to
* ShareRowExclusiveLock to lock out insert/update/delete actions and to * grab ShareRowExclusiveLock to lock out insert/update/delete actions and
* ensure that we lock out current CREATE RULE statements. * 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); event_relation = heap_open(event_relid, AccessExclusiveLock);
else
event_relation = heap_open(event_relid, ShareRowExclusiveLock);
/* /*
* Verify relation is of a type that rules can sensibly be applied to. * Verify relation is of a type that rules can sensibly be applied to.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment