OSDN Git Service

Current implementation of FOR UPDATE has no hope of working correctly
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 14 May 2001 20:25:00 +0000 (20:25 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 14 May 2001 20:25:00 +0000 (20:25 +0000)
for relations on the nullable side of an OUTER JOIN.  For now I think
we'd better refuse such queries.

src/backend/optimizer/plan/initsplan.c

index 5d67e02..c62fd5e 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/optimizer/plan/initsplan.c,v 1.60 2001/05/07 00:43:21 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/optimizer/plan/initsplan.c,v 1.61 2001/05/14 20:25:00 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -298,7 +298,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
@@ -306,6 +307,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;
        }
 }