mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-27 08:39:28 +08:00
Fix inheritance_planner() to delete dummy subplans from its Append plan
list, when some of the child rels have been excluded by constraint exclusion. This doesn't save a huge amount of time but it'll save some, and it makes the EXPLAIN output look saner. We already did the equivalent thing in set_append_rel_pathlist(), but not here.
This commit is contained in:
parent
1d28bf2589
commit
635d42e9c3
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/plan/planner.c,v 1.206 2006/08/02 01:59:46 joe Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/plan/planner.c,v 1.207 2006/08/05 17:21:52 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -58,6 +58,7 @@ static Node *preprocess_expression(PlannerInfo *root, Node *expr, int kind);
|
||||
static void preprocess_qual_conditions(PlannerInfo *root, Node *jtnode);
|
||||
static Plan *inheritance_planner(PlannerInfo *root);
|
||||
static Plan *grouping_planner(PlannerInfo *root, double tuple_fraction);
|
||||
static bool is_dummy_plan(Plan *plan);
|
||||
static double preprocess_limit(PlannerInfo *root,
|
||||
double tuple_fraction,
|
||||
int64 *offset_est, int64 *count_est);
|
||||
@ -553,12 +554,11 @@ inheritance_planner(PlannerInfo *root)
|
||||
Query *parse = root->parse;
|
||||
int parentRTindex = parse->resultRelation;
|
||||
List *subplans = NIL;
|
||||
List *rtable = NIL;
|
||||
List *tlist = NIL;
|
||||
PlannerInfo subroot;
|
||||
ListCell *l;
|
||||
|
||||
subroot.parse = NULL; /* catch it if no matches in loop */
|
||||
|
||||
parse->resultRelations = NIL;
|
||||
|
||||
foreach(l, root->append_rel_list)
|
||||
@ -570,10 +570,6 @@ inheritance_planner(PlannerInfo *root)
|
||||
if (appinfo->parent_relid != parentRTindex)
|
||||
continue;
|
||||
|
||||
/* Build target-relations list for the executor */
|
||||
parse->resultRelations = lappend_int(parse->resultRelations,
|
||||
appinfo->child_relid);
|
||||
|
||||
/*
|
||||
* Generate modified query with this rel as target. We have to be
|
||||
* prepared to translate varnos in in_info_list as well as in the
|
||||
@ -592,13 +588,39 @@ inheritance_planner(PlannerInfo *root)
|
||||
/* Generate plan */
|
||||
subplan = grouping_planner(&subroot, 0.0 /* retrieve all tuples */ );
|
||||
|
||||
/*
|
||||
* If this child rel was excluded by constraint exclusion, exclude
|
||||
* it from the plan.
|
||||
*/
|
||||
if (is_dummy_plan(subplan))
|
||||
continue;
|
||||
|
||||
/* Save rtable and tlist from first rel for use below */
|
||||
if (subplans == NIL)
|
||||
{
|
||||
rtable = subroot.parse->rtable;
|
||||
tlist = subplan->targetlist;
|
||||
}
|
||||
|
||||
subplans = lappend(subplans, subplan);
|
||||
|
||||
/* Save preprocessed tlist from first rel for use in Append */
|
||||
if (tlist == NIL)
|
||||
tlist = subplan->targetlist;
|
||||
/* Build target-relations list for the executor */
|
||||
parse->resultRelations = lappend_int(parse->resultRelations,
|
||||
appinfo->child_relid);
|
||||
}
|
||||
|
||||
/* Mark result as unordered (probably unnecessary) */
|
||||
root->query_pathkeys = NIL;
|
||||
|
||||
/*
|
||||
* If we managed to exclude every child rel, return a dummy plan
|
||||
*/
|
||||
if (subplans == NIL)
|
||||
return (Plan *) make_result(tlist,
|
||||
(Node *) list_make1(makeBoolConst(false,
|
||||
false)),
|
||||
NULL);
|
||||
|
||||
/*
|
||||
* Planning might have modified the rangetable, due to changes of the
|
||||
* Query structures inside subquery RTEs. We have to ensure that this
|
||||
@ -610,10 +632,7 @@ inheritance_planner(PlannerInfo *root)
|
||||
*
|
||||
* XXX should clean this up someday
|
||||
*/
|
||||
parse->rtable = subroot.parse->rtable;
|
||||
|
||||
/* Mark result as unordered (probably unnecessary) */
|
||||
root->query_pathkeys = NIL;
|
||||
parse->rtable = rtable;
|
||||
|
||||
return (Plan *) make_append(subplans, true, tlist);
|
||||
}
|
||||
@ -1072,6 +1091,35 @@ grouping_planner(PlannerInfo *root, double tuple_fraction)
|
||||
return result_plan;
|
||||
}
|
||||
|
||||
/*
|
||||
* Detect whether a plan node is a "dummy" plan created when a relation
|
||||
* is deemed not to need scanning due to constraint exclusion.
|
||||
*
|
||||
* Currently, such dummy plans are Result nodes with constant FALSE
|
||||
* filter quals.
|
||||
*/
|
||||
static bool
|
||||
is_dummy_plan(Plan *plan)
|
||||
{
|
||||
if (IsA(plan, Result))
|
||||
{
|
||||
List *rcqual = (List *) ((Result *) plan)->resconstantqual;
|
||||
|
||||
if (list_length(rcqual) == 1)
|
||||
{
|
||||
Const *constqual = (Const *) linitial(rcqual);
|
||||
|
||||
if (constqual && IsA(constqual, Const))
|
||||
{
|
||||
if (!constqual->constisnull &&
|
||||
!DatumGetBool(constqual->constvalue))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* preprocess_limit - do pre-estimation for LIMIT and/or OFFSET clauses
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user