mirror of
https://github.com/postgres/postgres.git
synced 2025-07-07 00:36:50 +03:00
Remove the Query structure from the executor's API. This allows us to stop
storing mostly-redundant Query trees in prepared statements, portals, etc. To replace Query, a new node type called PlannedStmt is inserted by the planner at the top of a completed plan tree; this carries just the fields of Query that are still needed at runtime. The statement lists kept in portals etc. now consist of intermixed PlannedStmt and bare utility-statement nodes --- no Query. This incidentally allows us to remove some fields from Query and Plan nodes that shouldn't have been there in the first place. Still to do: simplify the execution-time range table; at the moment the range table passed to the executor still contains Query trees for subqueries. initdb forced due to change of stored rules.
This commit is contained in:
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.159 2007/02/19 07:03:28 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.160 2007/02/20 17:32:15 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -444,8 +444,8 @@ set_subquery_pathlist(PlannerInfo *root, RelOptInfo *rel,
|
||||
Query *subquery = rte->subquery;
|
||||
bool *differentTypes;
|
||||
double tuple_fraction;
|
||||
PlannerInfo *subroot;
|
||||
List *pathkeys;
|
||||
List *subquery_pathkeys;
|
||||
|
||||
/* We need a workspace for keeping track of set-op type coercions */
|
||||
differentTypes = (bool *)
|
||||
@ -520,7 +520,7 @@ set_subquery_pathlist(PlannerInfo *root, RelOptInfo *rel,
|
||||
rel->subplan = subquery_planner(root->glob, subquery,
|
||||
root->query_level + 1,
|
||||
tuple_fraction,
|
||||
&subquery_pathkeys);
|
||||
&subroot);
|
||||
|
||||
/* Copy number of output rows from subplan */
|
||||
rel->tuples = rel->subplan->plan_rows;
|
||||
@ -529,7 +529,7 @@ set_subquery_pathlist(PlannerInfo *root, RelOptInfo *rel,
|
||||
set_baserel_size_estimates(root, rel);
|
||||
|
||||
/* Convert subquery pathkeys to outer representation */
|
||||
pathkeys = convert_subquery_pathkeys(root, rel, subquery_pathkeys);
|
||||
pathkeys = convert_subquery_pathkeys(root, rel, subroot->query_pathkeys);
|
||||
|
||||
/* Generate appropriate path */
|
||||
add_path(rel, create_subqueryscan_path(rel, pathkeys));
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/plan/planagg.c,v 1.27 2007/02/19 07:03:29 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/plan/planagg.c,v 1.28 2007/02/20 17:32:15 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -453,8 +453,7 @@ make_agg_subplan(PlannerInfo *root, MinMaxAggInfo *info)
|
||||
subroot.init_plans = NIL;
|
||||
subparse->commandType = CMD_SELECT;
|
||||
subparse->resultRelation = 0;
|
||||
subparse->resultRelations = NIL;
|
||||
subparse->returningLists = NIL;
|
||||
subparse->returningList = NIL;
|
||||
subparse->into = NULL;
|
||||
subparse->hasAggs = false;
|
||||
subparse->groupClause = NIL;
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/plan/planner.c,v 1.213 2007/02/19 07:03:29 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/plan/planner.c,v 1.214 2007/02/20 17:32:15 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -79,13 +79,15 @@ static List *postprocess_setop_tlist(List *new_tlist, List *orig_tlist);
|
||||
* Query optimizer entry point
|
||||
*
|
||||
*****************************************************************************/
|
||||
Plan *
|
||||
PlannedStmt *
|
||||
planner(Query *parse, bool isCursor, int cursorOptions,
|
||||
ParamListInfo boundParams)
|
||||
{
|
||||
PlannedStmt *result;
|
||||
PlannerGlobal *glob;
|
||||
double tuple_fraction;
|
||||
Plan *result_plan;
|
||||
PlannerInfo *root;
|
||||
Plan *top_plan;
|
||||
|
||||
/*
|
||||
* Set up global state for this planner invocation. This data is needed
|
||||
@ -117,7 +119,7 @@ planner(Query *parse, bool isCursor, int cursorOptions,
|
||||
}
|
||||
|
||||
/* primary planning entry point (may recurse for subqueries) */
|
||||
result_plan = subquery_planner(glob, parse, 1, tuple_fraction, NULL);
|
||||
top_plan = subquery_planner(glob, parse, 1, tuple_fraction, &root);
|
||||
|
||||
/*
|
||||
* If creating a plan for a scrollable cursor, make sure it can run
|
||||
@ -125,17 +127,27 @@ planner(Query *parse, bool isCursor, int cursorOptions,
|
||||
*/
|
||||
if (isCursor && (cursorOptions & CURSOR_OPT_SCROLL))
|
||||
{
|
||||
if (!ExecSupportsBackwardScan(result_plan))
|
||||
result_plan = materialize_finished_plan(result_plan);
|
||||
if (!ExecSupportsBackwardScan(top_plan))
|
||||
top_plan = materialize_finished_plan(top_plan);
|
||||
}
|
||||
|
||||
/* final cleanup of the plan */
|
||||
result_plan = set_plan_references(result_plan, parse->rtable);
|
||||
top_plan = set_plan_references(top_plan, parse->rtable);
|
||||
|
||||
/* executor wants to know total number of Params used overall */
|
||||
result_plan->nParamExec = list_length(glob->paramlist);
|
||||
/* build the PlannedStmt result */
|
||||
result = makeNode(PlannedStmt);
|
||||
|
||||
return result_plan;
|
||||
result->commandType = parse->commandType;
|
||||
result->canSetTag = parse->canSetTag;
|
||||
result->planTree = top_plan;
|
||||
result->rtable = parse->rtable;
|
||||
result->resultRelations = root->resultRelations;
|
||||
result->into = parse->into;
|
||||
result->returningLists = root->returningLists;
|
||||
result->rowMarks = parse->rowMarks;
|
||||
result->nParamExec = list_length(glob->paramlist);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@ -150,8 +162,8 @@ planner(Query *parse, bool isCursor, int cursorOptions,
|
||||
* tuple_fraction is the fraction of tuples we expect will be retrieved.
|
||||
* tuple_fraction is interpreted as explained for grouping_planner, below.
|
||||
*
|
||||
* If subquery_pathkeys isn't NULL, it receives a list of pathkeys indicating
|
||||
* the output sort ordering of the completed plan.
|
||||
* If subroot isn't NULL, we pass back the query's final PlannerInfo struct;
|
||||
* among other things this tells the output sort ordering of the plan.
|
||||
*
|
||||
* Basically, this routine does the stuff that should only be done once
|
||||
* per Query object. It then calls grouping_planner. At one time,
|
||||
@ -168,7 +180,7 @@ planner(Query *parse, bool isCursor, int cursorOptions,
|
||||
Plan *
|
||||
subquery_planner(PlannerGlobal *glob, Query *parse,
|
||||
Index level, double tuple_fraction,
|
||||
List **subquery_pathkeys)
|
||||
PlannerInfo **subroot)
|
||||
{
|
||||
int saved_plan_id = glob->next_plan_id;
|
||||
PlannerInfo *root;
|
||||
@ -375,9 +387,9 @@ subquery_planner(PlannerGlobal *glob, Query *parse,
|
||||
if (root->glob->next_plan_id != saved_plan_id || root->query_level > 1)
|
||||
SS_finalize_plan(root, plan);
|
||||
|
||||
/* Return sort ordering info if caller wants it */
|
||||
if (subquery_pathkeys)
|
||||
*subquery_pathkeys = root->query_pathkeys;
|
||||
/* Return internal info if caller wants it */
|
||||
if (subroot)
|
||||
*subroot = root;
|
||||
|
||||
return plan;
|
||||
}
|
||||
@ -593,14 +605,14 @@ inheritance_planner(PlannerInfo *root)
|
||||
/* Build list of per-relation RETURNING targetlists */
|
||||
if (parse->returningList)
|
||||
{
|
||||
Assert(list_length(subroot.parse->returningLists) == 1);
|
||||
Assert(list_length(subroot.returningLists) == 1);
|
||||
returningLists = list_concat(returningLists,
|
||||
subroot.parse->returningLists);
|
||||
subroot.returningLists);
|
||||
}
|
||||
}
|
||||
|
||||
parse->resultRelations = resultRelations;
|
||||
parse->returningLists = returningLists;
|
||||
root->resultRelations = resultRelations;
|
||||
root->returningLists = returningLists;
|
||||
|
||||
/* Mark result as unordered (probably unnecessary) */
|
||||
root->query_pathkeys = NIL;
|
||||
@ -1101,8 +1113,16 @@ grouping_planner(PlannerInfo *root, double tuple_fraction)
|
||||
rlist = set_returning_clause_references(parse->returningList,
|
||||
result_plan,
|
||||
parse->resultRelation);
|
||||
parse->returningLists = list_make1(rlist);
|
||||
root->returningLists = list_make1(rlist);
|
||||
}
|
||||
else
|
||||
root->returningLists = NIL;
|
||||
|
||||
/* Compute result-relations list if needed */
|
||||
if (parse->resultRelation)
|
||||
root->resultRelations = list_make1_int(parse->resultRelation);
|
||||
else
|
||||
root->resultRelations = NIL;
|
||||
|
||||
/*
|
||||
* Return the actual output ordering in query_pathkeys for possible use by
|
||||
|
Reference in New Issue
Block a user