Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 7c5e543

Browse files
committed
Get rid of some old and crufty global variables in the planner. When
this code was last gone over, there wasn't really any alternative to globals because we didn't have the PlannerInfo struct being passed all through the planner code. Now that we do, we can restructure things to avoid non-reentrancy. I'm fooling with this because otherwise I'd have had to add another global variable for the planned compact range table list.
1 parent 90c301a commit 7c5e543

File tree

18 files changed

+293
-223
lines changed

18 files changed

+293
-223
lines changed

src/backend/nodes/outfuncs.c

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.298 2007/02/19 02:23:12 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.299 2007/02/19 07:03:27 tgl Exp $
1212
*
1313
* NOTES
1414
* Every node type that can appear in stored rules' parsetrees *must*
@@ -1225,14 +1225,27 @@ _outHashPath(StringInfo str, HashPath *node)
12251225
WRITE_NODE_FIELD(path_hashclauses);
12261226
}
12271227

1228+
static void
1229+
_outPlannerGlobal(StringInfo str, PlannerGlobal *node)
1230+
{
1231+
WRITE_NODE_TYPE("PLANNERGLOBAL");
1232+
1233+
/* NB: this isn't a complete set of fields */
1234+
WRITE_NODE_FIELD(paramlist);
1235+
WRITE_INT_FIELD(next_plan_id);
1236+
}
1237+
12281238
static void
12291239
_outPlannerInfo(StringInfo str, PlannerInfo *node)
12301240
{
12311241
WRITE_NODE_TYPE("PLANNERINFO");
12321242

12331243
/* NB: this isn't a complete set of fields */
12341244
WRITE_NODE_FIELD(parse);
1245+
WRITE_NODE_FIELD(glob);
1246+
WRITE_UINT_FIELD(query_level);
12351247
WRITE_NODE_FIELD(join_rel_list);
1248+
WRITE_NODE_FIELD(init_plans);
12361249
WRITE_NODE_FIELD(eq_classes);
12371250
WRITE_NODE_FIELD(canon_pathkeys);
12381251
WRITE_NODE_FIELD(left_join_clauses);
@@ -1416,6 +1429,15 @@ _outAppendRelInfo(StringInfo str, AppendRelInfo *node)
14161429
WRITE_OID_FIELD(parent_reloid);
14171430
}
14181431

1432+
static void
1433+
_outPlannerParamItem(StringInfo str, PlannerParamItem *node)
1434+
{
1435+
WRITE_NODE_TYPE("PLANNERPARAMITEM");
1436+
1437+
WRITE_NODE_FIELD(item);
1438+
WRITE_UINT_FIELD(abslevel);
1439+
}
1440+
14191441
/*****************************************************************************
14201442
*
14211443
* Stuff from parsenodes.h.
@@ -2195,6 +2217,9 @@ _outNode(StringInfo str, void *obj)
21952217
case T_HashPath:
21962218
_outHashPath(str, obj);
21972219
break;
2220+
case T_PlannerGlobal:
2221+
_outPlannerGlobal(str, obj);
2222+
break;
21982223
case T_PlannerInfo:
21992224
_outPlannerInfo(str, obj);
22002225
break;
@@ -2228,6 +2253,9 @@ _outNode(StringInfo str, void *obj)
22282253
case T_AppendRelInfo:
22292254
_outAppendRelInfo(str, obj);
22302255
break;
2256+
case T_PlannerParamItem:
2257+
_outPlannerParamItem(str, obj);
2258+
break;
22312259

22322260
case T_CreateStmt:
22332261
_outCreateStmt(str, obj);

src/backend/optimizer/README

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,10 @@ planner()
317317
Optimizer Data Structures
318318
-------------------------
319319

320-
PlannerInfo - global information for planning a particular Query
320+
PlannerGlobal - global information for a single planner invocation
321+
322+
PlannerInfo - information for planning a particular Query (we make
323+
a separate PlannerInfo node for each sub-Query)
321324

322325
RelOptInfo - a relation or joined relations
323326

src/backend/optimizer/path/allpaths.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.158 2007/01/28 18:50:40 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.159 2007/02/19 07:03:28 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -517,7 +517,9 @@ set_subquery_pathlist(PlannerInfo *root, RelOptInfo *rel,
517517
tuple_fraction = root->tuple_fraction;
518518

519519
/* Generate the plan for the subquery */
520-
rel->subplan = subquery_planner(subquery, tuple_fraction,
520+
rel->subplan = subquery_planner(root->glob, subquery,
521+
root->query_level + 1,
522+
tuple_fraction,
521523
&subquery_pathkeys);
522524

523525
/* Copy number of output rows from subplan */

src/backend/optimizer/path/clausesel.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/optimizer/path/clausesel.c,v 1.83 2007/01/05 22:19:31 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/optimizer/path/clausesel.c,v 1.84 2007/02/19 07:03:28 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -537,7 +537,7 @@ clause_selectivity(PlannerInfo *root,
537537
else if (IsA(clause, Param))
538538
{
539539
/* see if we can replace the Param */
540-
Node *subst = estimate_expression_value(clause);
540+
Node *subst = estimate_expression_value(root, clause);
541541

542542
if (IsA(subst, Const))
543543
{

src/backend/optimizer/plan/planagg.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/optimizer/plan/planagg.c,v 1.26 2007/02/06 06:50:26 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/optimizer/plan/planagg.c,v 1.27 2007/02/19 07:03:29 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -450,6 +450,7 @@ make_agg_subplan(PlannerInfo *root, MinMaxAggInfo *info)
450450
*/
451451
memcpy(&subroot, root, sizeof(PlannerInfo));
452452
subroot.parse = subparse = (Query *) copyObject(root->parse);
453+
subroot.init_plans = NIL;
453454
subparse->commandType = CMD_SELECT;
454455
subparse->resultRelation = 0;
455456
subparse->resultRelations = NIL;
@@ -524,6 +525,9 @@ make_agg_subplan(PlannerInfo *root, MinMaxAggInfo *info)
524525
info->param = SS_make_initplan_from_plan(&subroot, plan,
525526
exprType((Node *) tle->expr),
526527
-1);
528+
529+
/* Make sure the InitPlan gets into the outer list */
530+
root->init_plans = list_concat(root->init_plans, subroot.init_plans);
527531
}
528532

529533
/*

src/backend/optimizer/plan/planner.c

Lines changed: 32 additions & 57 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.212 2007/01/20 20:45:39 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/optimizer/plan/planner.c,v 1.213 2007/02/19 07:03:29 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -42,9 +42,6 @@
4242
#include "utils/syscache.h"
4343

4444

45-
ParamListInfo PlannerBoundParamList = NULL; /* current boundParams */
46-
47-
4845
/* Expression kind codes for preprocess_expression */
4946
#define EXPRKIND_QUAL 0
5047
#define EXPRKIND_TARGET 1
@@ -86,35 +83,21 @@ Plan *
8683
planner(Query *parse, bool isCursor, int cursorOptions,
8784
ParamListInfo boundParams)
8885
{
86+
PlannerGlobal *glob;
8987
double tuple_fraction;
9088
Plan *result_plan;
91-
Index save_PlannerQueryLevel;
92-
List *save_PlannerParamList;
93-
ParamListInfo save_PlannerBoundParamList;
9489

9590
/*
96-
* The planner can be called recursively (an example is when
97-
* eval_const_expressions tries to pre-evaluate an SQL function). So,
98-
* these global state variables must be saved and restored.
99-
*
100-
* Query level and the param list cannot be moved into the per-query
101-
* PlannerInfo structure since their whole purpose is communication across
102-
* multiple sub-queries. Also, boundParams is explicitly info from outside
103-
* the query, and so is likewise better handled as a global variable.
104-
*
105-
* Note we do NOT save and restore PlannerPlanId: it exists to assign
106-
* unique IDs to SubPlan nodes, and we want those IDs to be unique for the
107-
* life of a backend. Also, PlannerInitPlan is saved/restored in
108-
* subquery_planner, not here.
91+
* Set up global state for this planner invocation. This data is needed
92+
* across all levels of sub-Query that might exist in the given command,
93+
* so we keep it in a separate struct that's linked to by each per-Query
94+
* PlannerInfo.
10995
*/
110-
save_PlannerQueryLevel = PlannerQueryLevel;
111-
save_PlannerParamList = PlannerParamList;
112-
save_PlannerBoundParamList = PlannerBoundParamList;
96+
glob = makeNode(PlannerGlobal);
11397

114-
/* Initialize state for handling outer-level references and params */
115-
PlannerQueryLevel = 0; /* will be 1 in top-level subquery_planner */
116-
PlannerParamList = NIL;
117-
PlannerBoundParamList = boundParams;
98+
glob->boundParams = boundParams;
99+
glob->paramlist = NIL;
100+
glob->next_plan_id = 0;
118101

119102
/* Determine what fraction of the plan is likely to be scanned */
120103
if (isCursor)
@@ -134,10 +117,7 @@ planner(Query *parse, bool isCursor, int cursorOptions,
134117
}
135118

136119
/* primary planning entry point (may recurse for subqueries) */
137-
result_plan = subquery_planner(parse, tuple_fraction, NULL);
138-
139-
/* check we popped out the right number of levels */
140-
Assert(PlannerQueryLevel == 0);
120+
result_plan = subquery_planner(glob, parse, 1, tuple_fraction, NULL);
141121

142122
/*
143123
* If creating a plan for a scrollable cursor, make sure it can run
@@ -153,12 +133,7 @@ planner(Query *parse, bool isCursor, int cursorOptions,
153133
result_plan = set_plan_references(result_plan, parse->rtable);
154134

155135
/* executor wants to know total number of Params used overall */
156-
result_plan->nParamExec = list_length(PlannerParamList);
157-
158-
/* restore state for outer planner, if any */
159-
PlannerQueryLevel = save_PlannerQueryLevel;
160-
PlannerParamList = save_PlannerParamList;
161-
PlannerBoundParamList = save_PlannerBoundParamList;
136+
result_plan->nParamExec = list_length(glob->paramlist);
162137

163138
return result_plan;
164139
}
@@ -169,7 +144,9 @@ planner(Query *parse, bool isCursor, int cursorOptions,
169144
* Invokes the planner on a subquery. We recurse to here for each
170145
* sub-SELECT found in the query tree.
171146
*
147+
* glob is the global state for the current planner run.
172148
* parse is the querytree produced by the parser & rewriter.
149+
* level is the current recursion depth (1 at the top-level Query).
173150
* tuple_fraction is the fraction of tuples we expect will be retrieved.
174151
* tuple_fraction is interpreted as explained for grouping_planner, below.
175152
*
@@ -189,24 +166,23 @@ planner(Query *parse, bool isCursor, int cursorOptions,
189166
*--------------------
190167
*/
191168
Plan *
192-
subquery_planner(Query *parse, double tuple_fraction,
169+
subquery_planner(PlannerGlobal *glob, Query *parse,
170+
Index level, double tuple_fraction,
193171
List **subquery_pathkeys)
194172
{
195-
List *saved_initplan = PlannerInitPlan;
196-
int saved_planid = PlannerPlanId;
173+
int saved_plan_id = glob->next_plan_id;
197174
PlannerInfo *root;
198175
Plan *plan;
199176
List *newHaving;
200177
ListCell *l;
201178

202-
/* Set up for a new level of subquery */
203-
PlannerQueryLevel++;
204-
PlannerInitPlan = NIL;
205-
206179
/* Create a PlannerInfo data structure for this subquery */
207180
root = makeNode(PlannerInfo);
208181
root->parse = parse;
182+
root->glob = glob;
183+
root->query_level = level;
209184
root->planner_cxt = CurrentMemoryContext;
185+
root->init_plans = NIL;
210186
root->eq_classes = NIL;
211187
root->in_info_list = NIL;
212188
root->append_rel_list = NIL;
@@ -396,18 +372,13 @@ subquery_planner(Query *parse, double tuple_fraction,
396372
* initPlan list and extParam/allParam sets for plan nodes, and attach the
397373
* initPlans to the top plan node.
398374
*/
399-
if (PlannerPlanId != saved_planid || PlannerQueryLevel > 1)
400-
SS_finalize_plan(plan, parse->rtable);
375+
if (root->glob->next_plan_id != saved_plan_id || root->query_level > 1)
376+
SS_finalize_plan(root, plan);
401377

402378
/* Return sort ordering info if caller wants it */
403379
if (subquery_pathkeys)
404380
*subquery_pathkeys = root->query_pathkeys;
405381

406-
/* Return to outer subquery context */
407-
PlannerQueryLevel--;
408-
PlannerInitPlan = saved_initplan;
409-
/* we do NOT restore PlannerPlanId; that's not an oversight! */
410-
411382
return plan;
412383
}
413384

@@ -460,7 +431,7 @@ preprocess_expression(PlannerInfo *root, Node *expr, int kind)
460431
if (kind != EXPRKIND_VALUES &&
461432
(root->parse->jointree->fromlist != NIL ||
462433
kind == EXPRKIND_QUAL ||
463-
PlannerQueryLevel > 1))
434+
root->query_level > 1))
464435
expr = eval_const_expressions(expr);
465436

466437
/*
@@ -478,16 +449,16 @@ preprocess_expression(PlannerInfo *root, Node *expr, int kind)
478449

479450
/* Expand SubLinks to SubPlans */
480451
if (root->parse->hasSubLinks)
481-
expr = SS_process_sublinks(expr, (kind == EXPRKIND_QUAL));
452+
expr = SS_process_sublinks(root, expr, (kind == EXPRKIND_QUAL));
482453

483454
/*
484455
* XXX do not insert anything here unless you have grokked the comments in
485456
* SS_replace_correlation_vars ...
486457
*/
487458

488459
/* Replace uplevel vars with Param nodes (this IS possible in VALUES) */
489-
if (PlannerQueryLevel > 1)
490-
expr = SS_replace_correlation_vars(expr);
460+
if (root->query_level > 1)
461+
expr = SS_replace_correlation_vars(root, expr);
491462

492463
/*
493464
* If it's a qual or havingQual, convert it to implicit-AND format. (We
@@ -590,6 +561,7 @@ inheritance_planner(PlannerInfo *root)
590561
subroot.in_info_list = (List *)
591562
adjust_appendrel_attrs((Node *) root->in_info_list,
592563
appinfo);
564+
subroot.init_plans = NIL;
593565
/* There shouldn't be any OJ info to translate, as yet */
594566
Assert(subroot.oj_info_list == NIL);
595567

@@ -612,6 +584,9 @@ inheritance_planner(PlannerInfo *root)
612584

613585
subplans = lappend(subplans, subplan);
614586

587+
/* Make sure any initplans from this rel get into the outer list */
588+
root->init_plans = list_concat(root->init_plans, subroot.init_plans);
589+
615590
/* Build target-relations list for the executor */
616591
resultRelations = lappend_int(resultRelations, appinfo->child_relid);
617592

@@ -1201,7 +1176,7 @@ preprocess_limit(PlannerInfo *root, double tuple_fraction,
12011176
*/
12021177
if (parse->limitCount)
12031178
{
1204-
est = estimate_expression_value(parse->limitCount);
1179+
est = estimate_expression_value(root, parse->limitCount);
12051180
if (est && IsA(est, Const))
12061181
{
12071182
if (((Const *) est)->constisnull)
@@ -1224,7 +1199,7 @@ preprocess_limit(PlannerInfo *root, double tuple_fraction,
12241199

12251200
if (parse->limitOffset)
12261201
{
1227-
est = estimate_expression_value(parse->limitOffset);
1202+
est = estimate_expression_value(root, parse->limitOffset);
12281203
if (est && IsA(est, Const))
12291204
{
12301205
if (((Const *) est)->constisnull)

0 commit comments

Comments
 (0)