1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-07 00:36:50 +03:00

Get rid of the separate EState for subplans, and just let them share the

parent query's EState.  Now that there's a single flat rangetable for both
the main plan and subplans, there's no need anymore for a separate EState,
and removing it allows cleaning up some crufty code in nodeSubplan.c and
nodeSubqueryscan.c.  Should be a tad faster too, although any difference
will probably be hard to measure.  This is the last bit of subsidiary
mop-up work from changing to a flat rangetable.
This commit is contained in:
Tom Lane
2007-02-27 01:11:26 +00:00
parent 4756ff3dca
commit c7ff7663e4
15 changed files with 258 additions and 358 deletions

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/optimizer/plan/planner.c,v 1.215 2007/02/22 22:00:24 tgl Exp $
* $PostgreSQL: pgsql/src/backend/optimizer/plan/planner.c,v 1.216 2007/02/27 01:11:25 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -103,6 +103,7 @@ planner(Query *parse, bool isCursor, int cursorOptions,
glob->paramlist = NIL;
glob->subplans = NIL;
glob->subrtables = NIL;
glob->rewindPlanIDs = NULL;
glob->finalrtable = NIL;
/* Determine what fraction of the plan is likely to be scanned */
@ -158,6 +159,7 @@ planner(Query *parse, bool isCursor, int cursorOptions,
result->resultRelations = root->resultRelations;
result->into = parse->into;
result->subplans = glob->subplans;
result->rewindPlanIDs = glob->rewindPlanIDs;
result->returningLists = root->returningLists;
result->rowMarks = parse->rowMarks;
result->nParamExec = list_length(glob->paramlist);

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/optimizer/plan/subselect.c,v 1.121 2007/02/22 22:00:24 tgl Exp $
* $PostgreSQL: pgsql/src/backend/optimizer/plan/subselect.c,v 1.122 2007/02/27 01:11:25 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -241,9 +241,10 @@ make_subplan(PlannerInfo *root, SubLink *slink, Node *testexpr, bool isTopQual)
{
Query *subquery = (Query *) (slink->subselect);
double tuple_fraction;
SubPlan *node;
SubPlan *splan;
Plan *plan;
PlannerInfo *subroot;
bool isInitPlan;
Bitmapset *tmpset;
int paramid;
Node *result;
@ -295,17 +296,17 @@ make_subplan(PlannerInfo *root, SubLink *slink, Node *testexpr, bool isTopQual)
/*
* Initialize the SubPlan node. Note plan_id isn't set yet.
*/
node = makeNode(SubPlan);
node->subLinkType = slink->subLinkType;
node->testexpr = NULL;
node->paramIds = NIL;
node->firstColType = get_first_col_type(plan);
node->useHashTable = false;
splan = makeNode(SubPlan);
splan->subLinkType = slink->subLinkType;
splan->testexpr = NULL;
splan->paramIds = NIL;
splan->firstColType = get_first_col_type(plan);
splan->useHashTable = false;
/* At top level of a qual, can treat UNKNOWN the same as FALSE */
node->unknownEqFalse = isTopQual;
node->setParam = NIL;
node->parParam = NIL;
node->args = NIL;
splan->unknownEqFalse = isTopQual;
splan->setParam = NIL;
splan->parParam = NIL;
splan->args = NIL;
/*
* Make parParam list of params that current query level will pass to this
@ -317,7 +318,7 @@ make_subplan(PlannerInfo *root, SubLink *slink, Node *testexpr, bool isTopQual)
PlannerParamItem *pitem = list_nth(root->glob->paramlist, paramid);
if (pitem->abslevel == root->query_level)
node->parParam = lappend_int(node->parParam, paramid);
splan->parParam = lappend_int(splan->parParam, paramid);
}
bms_free(tmpset);
@ -329,16 +330,16 @@ make_subplan(PlannerInfo *root, SubLink *slink, Node *testexpr, bool isTopQual)
* PARAM_EXEC Params instead of the PARAM_SUBLINK Params emitted by the
* parser.
*/
if (node->parParam == NIL && slink->subLinkType == EXISTS_SUBLINK)
if (splan->parParam == NIL && slink->subLinkType == EXISTS_SUBLINK)
{
Param *prm;
prm = generate_new_param(root, BOOLOID, -1);
node->setParam = list_make1_int(prm->paramid);
root->init_plans = lappend(root->init_plans, node);
splan->setParam = list_make1_int(prm->paramid);
isInitPlan = true;
result = (Node *) prm;
}
else if (node->parParam == NIL && slink->subLinkType == EXPR_SUBLINK)
else if (splan->parParam == NIL && slink->subLinkType == EXPR_SUBLINK)
{
TargetEntry *te = linitial(plan->targetlist);
Param *prm;
@ -347,11 +348,11 @@ make_subplan(PlannerInfo *root, SubLink *slink, Node *testexpr, bool isTopQual)
prm = generate_new_param(root,
exprType((Node *) te->expr),
exprTypmod((Node *) te->expr));
node->setParam = list_make1_int(prm->paramid);
root->init_plans = lappend(root->init_plans, node);
splan->setParam = list_make1_int(prm->paramid);
isInitPlan = true;
result = (Node *) prm;
}
else if (node->parParam == NIL && slink->subLinkType == ARRAY_SUBLINK)
else if (splan->parParam == NIL && slink->subLinkType == ARRAY_SUBLINK)
{
TargetEntry *te = linitial(plan->targetlist);
Oid arraytype;
@ -365,19 +366,19 @@ make_subplan(PlannerInfo *root, SubLink *slink, Node *testexpr, bool isTopQual)
prm = generate_new_param(root,
arraytype,
exprTypmod((Node *) te->expr));
node->setParam = list_make1_int(prm->paramid);
root->init_plans = lappend(root->init_plans, node);
splan->setParam = list_make1_int(prm->paramid);
isInitPlan = true;
result = (Node *) prm;
}
else if (node->parParam == NIL && slink->subLinkType == ROWCOMPARE_SUBLINK)
else if (splan->parParam == NIL && slink->subLinkType == ROWCOMPARE_SUBLINK)
{
/* Adjust the Params */
result = convert_testexpr(root,
testexpr,
0,
&node->paramIds);
node->setParam = list_copy(node->paramIds);
root->init_plans = lappend(root->init_plans, node);
&splan->paramIds);
splan->setParam = list_copy(splan->paramIds);
isInitPlan = true;
/*
* The executable expression is returned to become part of the outer
@ -390,10 +391,10 @@ make_subplan(PlannerInfo *root, SubLink *slink, Node *testexpr, bool isTopQual)
ListCell *l;
/* Adjust the Params */
node->testexpr = convert_testexpr(root,
testexpr,
0,
&node->paramIds);
splan->testexpr = convert_testexpr(root,
testexpr,
0,
&splan->paramIds);
/*
* We can't convert subplans of ALL_SUBLINK or ANY_SUBLINK types to
@ -402,8 +403,8 @@ make_subplan(PlannerInfo *root, SubLink *slink, Node *testexpr, bool isTopQual)
* tuple. But if it's an IN (= ANY) test, we might be able to use a
* hashtable to avoid comparing all the tuples.
*/
if (subplan_is_hashable(slink, node, plan))
node->useHashTable = true;
if (subplan_is_hashable(slink, splan, plan))
splan->useHashTable = true;
/*
* Otherwise, we have the option to tack a MATERIAL node onto the top
@ -413,7 +414,7 @@ make_subplan(PlannerInfo *root, SubLink *slink, Node *testexpr, bool isTopQual)
* correlated subplans, we add MATERIAL unless the subplan's top plan
* node would materialize its output anyway.
*/
else if (node->parParam == NIL)
else if (splan->parParam == NIL)
{
bool use_material;
@ -433,10 +434,10 @@ make_subplan(PlannerInfo *root, SubLink *slink, Node *testexpr, bool isTopQual)
}
/*
* Make node->args from parParam.
* Make splan->args from parParam.
*/
args = NIL;
foreach(l, node->parParam)
foreach(l, splan->parParam)
{
PlannerParamItem *pitem = list_nth(root->glob->paramlist,
lfirst_int(l));
@ -448,9 +449,10 @@ make_subplan(PlannerInfo *root, SubLink *slink, Node *testexpr, bool isTopQual)
*/
args = lappend(args, copyObject(pitem->item));
}
node->args = args;
splan->args = args;
result = (Node *) node;
result = (Node *) splan;
isInitPlan = false;
}
/*
@ -460,7 +462,22 @@ make_subplan(PlannerInfo *root, SubLink *slink, Node *testexpr, bool isTopQual)
plan);
root->glob->subrtables = lappend(root->glob->subrtables,
subroot->parse->rtable);
node->plan_id = list_length(root->glob->subplans);
splan->plan_id = list_length(root->glob->subplans);
if (isInitPlan)
root->init_plans = lappend(root->init_plans, splan);
/*
* A parameterless subplan (not initplan) should be prepared to handle
* REWIND efficiently. If it has direct parameters then there's no point
* since it'll be reset on each scan anyway; and if it's an initplan
* then there's no point since it won't get re-run without parameter
* changes anyway. The input of a hashed subplan doesn't need REWIND
* either.
*/
if (splan->parParam == NIL && !isInitPlan && !splan->useHashTable)
root->glob->rewindPlanIDs = bms_add_member(root->glob->rewindPlanIDs,
splan->plan_id);
return result;
}