1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-07 19:06:32 +03:00

Improve the representation of FOR UPDATE/FOR SHARE so that we can

support both FOR UPDATE and FOR SHARE in one command, as well as both
NOWAIT and normal WAIT behavior.  The more general code is actually
simpler and cleaner.
This commit is contained in:
Tom Lane
2006-04-30 18:30:40 +00:00
parent 931bfc9664
commit 986085a7f0
29 changed files with 320 additions and 245 deletions

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.144 2006/03/05 15:58:28 momjian Exp $
* $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.145 2006/04/30 18:30:39 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -268,7 +268,7 @@ set_append_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
* currently supposes that every rowMark relation is involved in every
* row returned by the query.)
*/
if (list_member_int(root->parse->rowMarks, parentRTindex))
if (get_rowmark(root->parse, parentRTindex))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("SELECT FOR UPDATE/SHARE is not supported for inheritance queries")));

View File

@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.209 2006/04/25 16:54:09 tgl Exp $
* $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.210 2006/04/30 18:30:39 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -843,7 +843,7 @@ create_indexscan_plan(PlannerInfo *root,
if (best_path->indexinfo->indpred)
{
if (baserelid != root->parse->resultRelation &&
!list_member_int(root->parse->rowMarks, baserelid))
get_rowmark(root->parse, baserelid) == NULL)
if (predicate_implied_by(clausel,
best_path->indexinfo->indpred))
continue;
@@ -962,7 +962,7 @@ create_bitmap_scan_plan(PlannerInfo *root,
if (ipath->indexinfo->indpred)
{
if (baserelid != root->parse->resultRelation &&
!list_member_int(root->parse->rowMarks, baserelid))
get_rowmark(root->parse, baserelid) == NULL)
if (predicate_implied_by(clausel,
ipath->indexinfo->indpred))
continue;

View File

@@ -15,7 +15,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/optimizer/prep/prepjointree.c,v 1.37 2006/03/07 01:00:15 tgl Exp $
* $PostgreSQL: pgsql/src/backend/optimizer/prep/prepjointree.c,v 1.38 2006/04/30 18:30:39 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -409,29 +409,9 @@ pull_up_simple_subquery(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte,
/*
* Pull up any FOR UPDATE/SHARE markers, too. (OffsetVarNodes
* already adjusted the marker values, so just list_concat the
* list.)
*
* Executor can't handle multiple FOR UPDATE/SHARE/NOWAIT flags,
* so complain if they are valid but different
* already adjusted the marker rtindexes, so just concat the lists.)
*/
if (parse->rowMarks && subquery->rowMarks)
{
if (parse->forUpdate != subquery->forUpdate)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("cannot use both FOR UPDATE and FOR SHARE in one query")));
if (parse->rowNoWait != subquery->rowNoWait)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("cannot use both wait and NOWAIT in one query")));
}
parse->rowMarks = list_concat(parse->rowMarks, subquery->rowMarks);
if (subquery->rowMarks)
{
parse->forUpdate = subquery->forUpdate;
parse->rowNoWait = subquery->rowNoWait;
}
/*
* We also have to fix the relid sets of any parent InClauseInfo

View File

@@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/optimizer/prep/preptlist.c,v 1.81 2006/04/05 22:11:55 tgl Exp $
* $PostgreSQL: pgsql/src/backend/optimizer/prep/preptlist.c,v 1.82 2006/04/30 18:30:39 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -116,7 +116,7 @@ preprocess_targetlist(PlannerInfo *root, List *tlist)
* invalid. This is also checked at parse time, but that's
* insufficient because of rule substitution, query pullup, etc.
*/
CheckSelectLocking(parse, parse->forUpdate);
CheckSelectLocking(parse);
/*
* Currently the executor only supports FOR UPDATE/SHARE at top level
@@ -128,19 +128,19 @@ preprocess_targetlist(PlannerInfo *root, List *tlist)
foreach(l, parse->rowMarks)
{
Index rti = lfirst_int(l);
RowMarkClause *rc = (RowMarkClause *) lfirst(l);
Var *var;
char *resname;
TargetEntry *tle;
var = makeVar(rti,
var = makeVar(rc->rti,
SelfItemPointerAttributeNumber,
TIDOID,
-1,
0);
resname = (char *) palloc(32);
snprintf(resname, 32, "ctid%u", rti);
snprintf(resname, 32, "ctid%u", rc->rti);
tle = makeTargetEntry((Expr *) var,
list_length(tlist) + 1,

View File

@@ -22,7 +22,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/optimizer/prep/prepunion.c,v 1.131 2006/03/05 15:58:31 momjian Exp $
* $PostgreSQL: pgsql/src/backend/optimizer/prep/prepunion.c,v 1.132 2006/04/30 18:30:39 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -816,7 +816,7 @@ expand_inherited_rtentry(PlannerInfo *root, RangeTblEntry *rte, Index rti)
*/
if (rti == parse->resultRelation)
lockmode = RowExclusiveLock;
else if (list_member_int(parse->rowMarks, rti))
else if (get_rowmark(parse, rti))
lockmode = RowShareLock;
else
lockmode = AccessShareLock;