In SELECT FOR UPDATE, silently ignore null CTIDs, rather than generating

an error as we used to.  In an OUTER JOIN scenario, retrieving a null
CTID from one of the input relations is entirely expected.  We still
want to lock the input rows from the other relations, so just ignore
the null and keep going.
This commit is contained in:
Tom Lane 2000-12-05 22:03:57 +00:00
parent 981a7d32d1
commit 614d951a54

View File

@ -27,7 +27,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.132 2000/11/12 00:36:57 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.133 2000/12/05 22:03:57 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -994,6 +994,7 @@ lnext: ;
&isNull)) &isNull))
elog(ERROR, "ExecutePlan: NO (junk) `ctid' was found!"); elog(ERROR, "ExecutePlan: NO (junk) `ctid' was found!");
/* shouldn't ever get a null result... */
if (isNull) if (isNull)
elog(ERROR, "ExecutePlan: (junk) `ctid' is NULL!"); elog(ERROR, "ExecutePlan: (junk) `ctid' is NULL!");
@ -1023,9 +1024,13 @@ lnext: ;
elog(ERROR, "ExecutePlan: NO (junk) `%s' was found!", elog(ERROR, "ExecutePlan: NO (junk) `%s' was found!",
erm->resname); erm->resname);
/*
* Unlike the UPDATE/DELETE case, a null result is
* possible here, when the referenced table is on the
* nullable side of an outer join. Ignore nulls.
*/
if (isNull) if (isNull)
elog(ERROR, "ExecutePlan: (junk) `%s' is NULL!", continue;
erm->resname);
tuple.t_self = *((ItemPointer) DatumGetPointer(datum)); tuple.t_self = *((ItemPointer) DatumGetPointer(datum));
test = heap_mark4update(erm->relation, &tuple, &buffer); test = heap_mark4update(erm->relation, &tuple, &buffer);
@ -1038,11 +1043,8 @@ lnext: ;
case HeapTupleUpdated: case HeapTupleUpdated:
if (XactIsoLevel == XACT_SERIALIZABLE) if (XactIsoLevel == XACT_SERIALIZABLE)
{
elog(ERROR, "Can't serialize access due to concurrent update"); elog(ERROR, "Can't serialize access due to concurrent update");
return (NULL); if (!(ItemPointerEquals(&(tuple.t_self),
}
else if (!(ItemPointerEquals(&(tuple.t_self),
(ItemPointer) DatumGetPointer(datum)))) (ItemPointer) DatumGetPointer(datum))))
{ {
newSlot = EvalPlanQual(estate, erm->rti, &(tuple.t_self)); newSlot = EvalPlanQual(estate, erm->rti, &(tuple.t_self));