diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2009-10-12 18:10:51 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2009-10-12 18:10:51 +0000 |
commit | 0adaf4cb312fe3eff83e786d6a0b53ae2cdc9302 (patch) | |
tree | 177cf2ea668d6fcabbafc37db4741813ea3f685d /src/backend/nodes | |
parent | 05d249717d652f0b16960d8a58611e222f1f907b (diff) | |
download | postgresql-0adaf4cb312fe3eff83e786d6a0b53ae2cdc9302.tar.gz |
Move the handling of SELECT FOR UPDATE locking and rechecking out of
execMain.c and into a new plan node type LockRows. Like the recent change
to put table updating into a ModifyTable plan node, this increases planning
flexibility by allowing the operations to occur below the top level of the
plan tree. It's necessary in any case to restore the previous behavior of
having FOR UPDATE locking occur before ModifyTable does.
This partially refactors EvalPlanQual to allow multiple rows-under-test
to be inserted into the EPQ machinery before starting an EPQ test query.
That isn't sufficient to fix EPQ's general bogosity in the face of plans
that return multiple rows per test row, though. Since this patch is
mostly about getting some plan node infrastructure in place and not about
fixing ten-year-old bugs, I will leave EPQ improvements for another day.
Another behavioral change that we could now think about is doing FOR UPDATE
before LIMIT, but that too seems like it should be treated as a followon
patch.
Diffstat (limited to 'src/backend/nodes')
-rw-r--r-- | src/backend/nodes/copyfuncs.c | 28 | ||||
-rw-r--r-- | src/backend/nodes/equalfuncs.c | 3 | ||||
-rw-r--r-- | src/backend/nodes/outfuncs.c | 21 | ||||
-rw-r--r-- | src/backend/nodes/readfuncs.c | 3 |
4 files changed, 51 insertions, 4 deletions
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index cee7cb8ded..eef333b718 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -15,7 +15,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.443 2009/10/10 01:43:49 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.444 2009/10/12 18:10:45 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -423,6 +423,7 @@ _copySubqueryScan(SubqueryScan *from) */ COPY_NODE_FIELD(subplan); COPY_NODE_FIELD(subrtable); + COPY_NODE_FIELD(subrowmark); return newnode; } @@ -795,6 +796,27 @@ _copySetOp(SetOp *from) } /* + * _copyLockRows + */ +static LockRows * +_copyLockRows(LockRows *from) +{ + LockRows *newnode = makeNode(LockRows); + + /* + * copy node superclass fields + */ + CopyPlanFields((Plan *) from, (Plan *) newnode); + + /* + * copy remainder of node + */ + COPY_NODE_FIELD(rowMarks); + + return newnode; +} + +/* * _copyLimit */ static Limit * @@ -1813,6 +1835,7 @@ _copyRowMarkClause(RowMarkClause *from) COPY_SCALAR_FIELD(rti); COPY_SCALAR_FIELD(prti); + COPY_SCALAR_FIELD(rowmarkId); COPY_SCALAR_FIELD(forUpdate); COPY_SCALAR_FIELD(noWait); COPY_SCALAR_FIELD(isParent); @@ -3589,6 +3612,9 @@ copyObject(void *from) case T_SetOp: retval = _copySetOp(from); break; + case T_LockRows: + retval = _copyLockRows(from); + break; case T_Limit: retval = _copyLimit(from); break; diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index 5766f37c14..ef8abc4773 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -22,7 +22,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.365 2009/10/08 02:39:20 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.366 2009/10/12 18:10:45 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -2194,6 +2194,7 @@ _equalRowMarkClause(RowMarkClause *a, RowMarkClause *b) { COMPARE_SCALAR_FIELD(rti); COMPARE_SCALAR_FIELD(prti); + COMPARE_SCALAR_FIELD(rowmarkId); COMPARE_SCALAR_FIELD(forUpdate); COMPARE_SCALAR_FIELD(noWait); COMPARE_SCALAR_FIELD(isParent); diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c index a776f9fe3e..e6952737c4 100644 --- a/src/backend/nodes/outfuncs.c +++ b/src/backend/nodes/outfuncs.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.367 2009/10/10 01:43:49 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.368 2009/10/12 18:10:45 tgl Exp $ * * NOTES * Every node type that can appear in stored rules' parsetrees *must* @@ -454,6 +454,7 @@ _outSubqueryScan(StringInfo str, SubqueryScan *node) WRITE_NODE_FIELD(subplan); WRITE_NODE_FIELD(subrtable); + WRITE_NODE_FIELD(subrowmark); } static void @@ -721,6 +722,16 @@ _outSetOp(StringInfo str, SetOp *node) } static void +_outLockRows(StringInfo str, LockRows *node) +{ + WRITE_NODE_TYPE("LOCKROWS"); + + _outPlanInfo(str, (Plan *) node); + + WRITE_NODE_FIELD(rowMarks); +} + +static void _outLimit(StringInfo str, Limit *node) { WRITE_NODE_TYPE("LIMIT"); @@ -1494,11 +1505,14 @@ _outPlannerGlobal(StringInfo str, PlannerGlobal *node) WRITE_NODE_FIELD(paramlist); WRITE_NODE_FIELD(subplans); WRITE_NODE_FIELD(subrtables); + WRITE_NODE_FIELD(subrowmarks); WRITE_BITMAPSET_FIELD(rewindPlanIDs); WRITE_NODE_FIELD(finalrtable); + WRITE_NODE_FIELD(finalrowmarks); WRITE_NODE_FIELD(relationOids); WRITE_NODE_FIELD(invalItems); WRITE_UINT_FIELD(lastPHId); + WRITE_UINT_FIELD(lastRowmarkId); WRITE_BOOL_FIELD(transientPlan); } @@ -1561,6 +1575,7 @@ _outRelOptInfo(StringInfo str, RelOptInfo *node) WRITE_FLOAT_FIELD(tuples, "%.0f"); WRITE_NODE_FIELD(subplan); WRITE_NODE_FIELD(subrtable); + WRITE_NODE_FIELD(subrowmark); WRITE_NODE_FIELD(baserestrictinfo); WRITE_NODE_FIELD(joininfo); WRITE_BOOL_FIELD(has_eclass_joins); @@ -2001,6 +2016,7 @@ _outRowMarkClause(StringInfo str, RowMarkClause *node) WRITE_UINT_FIELD(rti); WRITE_UINT_FIELD(prti); + WRITE_UINT_FIELD(rowmarkId); WRITE_BOOL_FIELD(forUpdate); WRITE_BOOL_FIELD(noWait); WRITE_BOOL_FIELD(isParent); @@ -2503,6 +2519,9 @@ _outNode(StringInfo str, void *obj) case T_SetOp: _outSetOp(str, obj); break; + case T_LockRows: + _outLockRows(str, obj); + break; case T_Limit: _outLimit(str, obj); break; diff --git a/src/backend/nodes/readfuncs.c b/src/backend/nodes/readfuncs.c index 205b6da4cd..7cffedb73b 100644 --- a/src/backend/nodes/readfuncs.c +++ b/src/backend/nodes/readfuncs.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/nodes/readfuncs.c,v 1.224 2009/10/08 02:39:21 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/nodes/readfuncs.c,v 1.225 2009/10/12 18:10:45 tgl Exp $ * * NOTES * Path and Plan nodes do not have any readfuncs support, because we @@ -294,6 +294,7 @@ _readRowMarkClause(void) READ_UINT_FIELD(rti); READ_UINT_FIELD(prti); + READ_UINT_FIELD(rowmarkId); READ_BOOL_FIELD(forUpdate); READ_BOOL_FIELD(noWait); READ_BOOL_FIELD(isParent); |