Skip to content

Commit d344505

Browse files
author
Neil Conway
committed
This patch moves some code for preprocessing FOR UPDATE from
grouping_planner() to preprocess_targetlist(), according to a comment in grouping_planner(). I think the refactoring makes sense, and moves some extraneous details out of grouping_planner().
1 parent 5955ebe commit d344505

File tree

3 files changed

+67
-69
lines changed

3 files changed

+67
-69
lines changed

src/backend/optimizer/plan/planner.c

Lines changed: 3 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/optimizer/plan/planner.c,v 1.179 2005/03/10 23:21:22 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/optimizer/plan/planner.c,v 1.180 2005/03/17 23:44:26 neilc Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -36,7 +36,6 @@
3636
#include "optimizer/subselect.h"
3737
#include "optimizer/tlist.h"
3838
#include "optimizer/var.h"
39-
#include "parser/analyze.h"
4039
#include "parser/parsetree.h"
4140
#include "parser/parse_expr.h"
4241
#include "parser/parse_oper.h"
@@ -698,65 +697,8 @@ grouping_planner(Query *parse, double tuple_fraction)
698697

699698
MemSet(&agg_counts, 0, sizeof(AggClauseCounts));
700699

701-
/* Preprocess targetlist in case we are inside an INSERT/UPDATE. */
702-
tlist = preprocess_targetlist(tlist,
703-
parse->commandType,
704-
parse->resultRelation,
705-
parse->rtable);
706-
707-
/*
708-
* Add TID targets for rels selected FOR UPDATE (should this be
709-
* done in preprocess_targetlist?). The executor uses the TID to
710-
* know which rows to lock, much as for UPDATE or DELETE.
711-
*/
712-
if (parse->rowMarks)
713-
{
714-
ListCell *l;
715-
716-
/*
717-
* We've got trouble if the FOR UPDATE appears inside
718-
* grouping, since grouping renders a reference to individual
719-
* tuple CTIDs invalid. This is also checked at parse time,
720-
* but that's insufficient because of rule substitution, query
721-
* pullup, etc.
722-
*/
723-
CheckSelectForUpdate(parse);
724-
725-
/*
726-
* Currently the executor only supports FOR UPDATE at top
727-
* level
728-
*/
729-
if (PlannerQueryLevel > 1)
730-
ereport(ERROR,
731-
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
732-
errmsg("SELECT FOR UPDATE is not allowed in subqueries")));
733-
734-
foreach(l, parse->rowMarks)
735-
{
736-
Index rti = lfirst_int(l);
737-
char *resname;
738-
Resdom *resdom;
739-
Var *var;
740-
TargetEntry *ctid;
741-
742-
resname = (char *) palloc(32);
743-
snprintf(resname, 32, "ctid%u", rti);
744-
resdom = makeResdom(list_length(tlist) + 1,
745-
TIDOID,
746-
-1,
747-
resname,
748-
true);
749-
750-
var = makeVar(rti,
751-
SelfItemPointerAttributeNumber,
752-
TIDOID,
753-
-1,
754-
0);
755-
756-
ctid = makeTargetEntry(resdom, (Expr *) var);
757-
tlist = lappend(tlist, ctid);
758-
}
759-
}
700+
/* Preprocess targetlist */
701+
tlist = preprocess_targetlist(parse, tlist);
760702

761703
/*
762704
* Generate appropriate target list for subplan; may be different

src/backend/optimizer/prep/preptlist.c

Lines changed: 62 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* Portions Copyright (c) 1994, Regents of the University of California
1616
*
1717
* IDENTIFICATION
18-
* $PostgreSQL: pgsql/src/backend/optimizer/prep/preptlist.c,v 1.72 2004/12/31 22:00:20 pgsql Exp $
18+
* $PostgreSQL: pgsql/src/backend/optimizer/prep/preptlist.c,v 1.73 2005/03/17 23:44:52 neilc Exp $
1919
*
2020
*-------------------------------------------------------------------------
2121
*/
@@ -26,6 +26,8 @@
2626
#include "catalog/pg_type.h"
2727
#include "nodes/makefuncs.h"
2828
#include "optimizer/prep.h"
29+
#include "optimizer/subselect.h"
30+
#include "parser/analyze.h"
2931
#include "parser/parsetree.h"
3032
#include "parser/parse_coerce.h"
3133

@@ -41,11 +43,12 @@ static List *expand_targetlist(List *tlist, int command_type,
4143
* Returns the new targetlist.
4244
*/
4345
List *
44-
preprocess_targetlist(List *tlist,
45-
int command_type,
46-
Index result_relation,
47-
List *range_table)
46+
preprocess_targetlist(Query *parse, List *tlist)
4847
{
48+
int result_relation = parse->resultRelation;
49+
List *range_table = parse->rtable;
50+
CmdType command_type = parse->commandType;
51+
4952
/*
5053
* Sanity check: if there is a result relation, it'd better be a real
5154
* relation not a subquery. Else parser or rewriter messed up.
@@ -99,6 +102,60 @@ preprocess_targetlist(List *tlist,
99102
tlist = lappend(tlist, makeTargetEntry(resdom, (Expr *) var));
100103
}
101104

105+
/*
106+
* Add TID targets for rels selected FOR UPDATE. The executor
107+
* uses the TID to know which rows to lock, much as for UPDATE or
108+
* DELETE.
109+
*/
110+
if (parse->rowMarks)
111+
{
112+
ListCell *l;
113+
114+
/*
115+
* We've got trouble if the FOR UPDATE appears inside
116+
* grouping, since grouping renders a reference to individual
117+
* tuple CTIDs invalid. This is also checked at parse time,
118+
* but that's insufficient because of rule substitution, query
119+
* pullup, etc.
120+
*/
121+
CheckSelectForUpdate(parse);
122+
123+
/*
124+
* Currently the executor only supports FOR UPDATE at top
125+
* level
126+
*/
127+
if (PlannerQueryLevel > 1)
128+
ereport(ERROR,
129+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
130+
errmsg("SELECT FOR UPDATE is not allowed in subqueries")));
131+
132+
foreach(l, parse->rowMarks)
133+
{
134+
Index rti = lfirst_int(l);
135+
char *resname;
136+
Resdom *resdom;
137+
Var *var;
138+
TargetEntry *ctid;
139+
140+
resname = (char *) palloc(32);
141+
snprintf(resname, 32, "ctid%u", rti);
142+
resdom = makeResdom(list_length(tlist) + 1,
143+
TIDOID,
144+
-1,
145+
resname,
146+
true);
147+
148+
var = makeVar(rti,
149+
SelfItemPointerAttributeNumber,
150+
TIDOID,
151+
-1,
152+
0);
153+
154+
ctid = makeTargetEntry(resdom, (Expr *) var);
155+
tlist = lappend(tlist, ctid);
156+
}
157+
}
158+
102159
return tlist;
103160
}
104161

src/include/optimizer/prep.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/optimizer/prep.h,v 1.47 2004/12/31 22:03:36 pgsql Exp $
10+
* $PostgreSQL: pgsql/src/include/optimizer/prep.h,v 1.48 2005/03/17 23:45:09 neilc Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -42,8 +42,7 @@ extern Node *flatten_andors(Node *node);
4242
/*
4343
* prototypes for preptlist.c
4444
*/
45-
extern List *preprocess_targetlist(List *tlist, int command_type,
46-
Index result_relation, List *range_table);
45+
extern List *preprocess_targetlist(Query *parse, List *tlist);
4746

4847
/*
4948
* prototypes for prepunion.c

0 commit comments

Comments
 (0)