summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2001-05-14 20:25:36 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2001-05-14 20:25:36 +0000
commit096e865438cb28404708d1d083271729c964fc3f (patch)
tree73e876a8f0a5ab0ffd93d0787e715925459cfabc
parent2c632e62594d98a70ecc77ef4005a8aecff62d79 (diff)
downloadpostgresql-096e865438cb28404708d1d083271729c964fc3f.tar.gz
Current implementation of FOR UPDATE has no hope of working correctly
for relations on the nullable side of an OUTER JOIN. For now I think we'd better refuse such queries.
-rw-r--r--src/backend/optimizer/plan/initsplan.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c
index 7c3e15a8f8..677b98a459 100644
--- a/src/backend/optimizer/plan/initsplan.c
+++ b/src/backend/optimizer/plan/initsplan.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/initsplan.c,v 1.59 2001/04/16 19:44:10 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/initsplan.c,v 1.59.2.1 2001/05/14 20:25:36 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -297,7 +297,8 @@ mark_baserels_for_outer_join(Query *root, Relids rels, Relids outerrels)
foreach(relid, rels)
{
- RelOptInfo *rel = get_base_rel(root, lfirsti(relid));
+ int relno = lfirsti(relid);
+ RelOptInfo *rel = get_base_rel(root, relno);
/*
* Since we do this bottom-up, any outer-rels previously marked
@@ -305,6 +306,21 @@ mark_baserels_for_outer_join(Query *root, Relids rels, Relids outerrels)
*/
Assert(is_subseti(rel->outerjoinset, outerrels));
+ /*
+ * Presently the executor cannot support FOR UPDATE marking of
+ * rels appearing on the nullable side of an outer join.
+ * (It's somewhat unclear what that would mean, anyway: what should
+ * we mark when a result row is generated from no element of the
+ * nullable relation?) So, complain if target rel is FOR UPDATE.
+ * It's sufficient to make this check once per rel, so do it only
+ * if rel wasn't already known nullable.
+ */
+ if (rel->outerjoinset == NIL)
+ {
+ if (intMember(relno, root->rowMarks))
+ elog(ERROR, "SELECT FOR UPDATE cannot be applied to the nullable side of an OUTER JOIN");
+ }
+
rel->outerjoinset = outerrels;
}
}