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.
This commit is contained in:
Tom Lane 2001-05-14 20:25:00 +00:00
parent 7d802e07a7
commit 248182560c

View File

@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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) 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 * 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)); 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; rel->outerjoinset = outerrels;
} }
} }