aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer/prep/prepunion.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/prep/prepunion.c')
-rw-r--r--src/backend/optimizer/prep/prepunion.c62
1 files changed, 31 insertions, 31 deletions
diff --git a/src/backend/optimizer/prep/prepunion.c b/src/backend/optimizer/prep/prepunion.c
index a067ed36e69..09acdaca65e 100644
--- a/src/backend/optimizer/prep/prepunion.c
+++ b/src/backend/optimizer/prep/prepunion.c
@@ -22,7 +22,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/prep/prepunion.c,v 1.169 2009/05/12 00:56:05 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/prep/prepunion.c,v 1.170 2009/05/12 03:11:01 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -32,7 +32,7 @@
#include "access/heapam.h"
#include "access/sysattr.h"
#include "catalog/namespace.h"
-#include "catalog/pg_inherits.h"
+#include "catalog/pg_inherits_fn.h"
#include "catalog/pg_type.h"
#include "miscadmin.h"
#include "nodes/makefuncs.h"
@@ -1157,8 +1157,29 @@ expand_inherited_rtentry(PlannerInfo *root, RangeTblEntry *rte, Index rti)
return;
}
- /* Scan for all members of inheritance set */
- inhOIDs = find_all_inheritors(parentOID);
+ /*
+ * The rewriter should already have obtained an appropriate lock on each
+ * relation named in the query. However, for each child relation we add
+ * to the query, we must obtain an appropriate lock, because this will be
+ * the first use of those relations in the parse/rewrite/plan pipeline.
+ *
+ * If the parent relation is the query's result relation, then we need
+ * RowExclusiveLock. Otherwise, if it's accessed FOR UPDATE/SHARE, we
+ * need RowShareLock; otherwise AccessShareLock. We can't just grab
+ * AccessShareLock because then the executor would be trying to upgrade
+ * the lock, leading to possible deadlocks. (This code should match the
+ * parser and rewriter.)
+ */
+ oldrc = get_rowmark(parse, rti);
+ if (rti == parse->resultRelation)
+ lockmode = RowExclusiveLock;
+ else if (oldrc)
+ lockmode = RowShareLock;
+ else
+ lockmode = AccessShareLock;
+
+ /* Scan for all members of inheritance set, acquire needed locks */
+ inhOIDs = find_all_inheritors(parentOID, lockmode);
/*
* Check that there's at least one descendant, else treat as no-child
@@ -1173,40 +1194,19 @@ expand_inherited_rtentry(PlannerInfo *root, RangeTblEntry *rte, Index rti)
}
/*
- * Find out if parent relation is selected FOR UPDATE/SHARE. If so,
- * we need to mark its RowMarkClause as isParent = true, and generate
- * a new RowMarkClause for each child.
+ * If parent relation is selected FOR UPDATE/SHARE, we need to mark its
+ * RowMarkClause as isParent = true, and generate a new RowMarkClause for
+ * each child.
*/
- oldrc = get_rowmark(parse, rti);
if (oldrc)
oldrc->isParent = true;
/*
* Must open the parent relation to examine its tupdesc. We need not lock
- * it since the rewriter already obtained at least AccessShareLock on each
- * relation used in the query.
+ * it; we assume the rewriter already did.
*/
oldrelation = heap_open(parentOID, NoLock);
- /*
- * However, for each child relation we add to the query, we must obtain an
- * appropriate lock, because this will be the first use of those relations
- * in the parse/rewrite/plan pipeline.
- *
- * If the parent relation is the query's result relation, then we need
- * RowExclusiveLock. Otherwise, if it's accessed FOR UPDATE/SHARE, we
- * need RowShareLock; otherwise AccessShareLock. We can't just grab
- * AccessShareLock because then the executor would be trying to upgrade
- * the lock, leading to possible deadlocks. (This code should match the
- * parser and rewriter.)
- */
- if (rti == parse->resultRelation)
- lockmode = RowExclusiveLock;
- else if (oldrc)
- lockmode = RowShareLock;
- else
- lockmode = AccessShareLock;
-
/* Scan the inheritance set and expand it */
appinfos = NIL;
foreach(l, inhOIDs)
@@ -1217,9 +1217,9 @@ expand_inherited_rtentry(PlannerInfo *root, RangeTblEntry *rte, Index rti)
Index childRTindex;
AppendRelInfo *appinfo;
- /* Open rel, acquire the appropriate lock type */
+ /* Open rel if needed; we already have required locks */
if (childOID != parentOID)
- newrelation = heap_open(childOID, lockmode);
+ newrelation = heap_open(childOID, NoLock);
else
newrelation = oldrelation;