diff --git a/src/backend/optimizer/plan/setrefs.c b/src/backend/optimizer/plan/setrefs.c index 0cd41d6f1e69b6095da9500fc05afb2bc58b5295..fe01555a3c40963a44570eb92454ee171f945276 100644 --- a/src/backend/optimizer/plan/setrefs.c +++ b/src/backend/optimizer/plan/setrefs.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/optimizer/plan/setrefs.c,v 1.113 2005/09/05 17:25:01 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/plan/setrefs.c,v 1.114 2005/09/05 18:59:38 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -130,7 +130,6 @@ static void set_sa_opfuncid(ScalarArrayOpExpr *opexpr); Plan * set_plan_references(Plan *plan, List *rtable) { - bool copy_lefttree_tlist = false; ListCell *l; if (plan == NULL) @@ -219,13 +218,14 @@ set_plan_references(Plan *plan, List *rtable) /* * These plan types don't actually bother to evaluate their - * targetlists, because they just return their unmodified - * input tuples; so their targetlists should just be copies - * of their input plan nodes' targetlists. The actual copying - * has to be done after we've finalized the input node. - */ - copy_lefttree_tlist = true; - /* + * targetlists (because they just return their unmodified + * input tuples). The optimizer is lazy about creating really + * valid targetlists for them --- it tends to just put in a + * pointer to the child plan node's tlist. Hence, we leave + * the tlist alone. In particular, we do not want to process + * subplans in the tlist, since we will likely end up reprocessing + * subplans that also appear in lower levels of the plan tree! + * * Since these plan types don't check quals either, we should * not find any qual expression attached to them. */ @@ -238,7 +238,6 @@ set_plan_references(Plan *plan, List *rtable) * or quals. It does have live expressions for limit/offset, * however. */ - copy_lefttree_tlist = true; Assert(plan->qual == NIL); fix_expr_references(plan, ((Limit *) plan)->limitOffset); fix_expr_references(plan, ((Limit *) plan)->limitCount); @@ -267,10 +266,9 @@ set_plan_references(Plan *plan, List *rtable) /* * Append, like Sort et al, doesn't actually evaluate its - * targetlist or check quals, so don't fix targetlist/qual. - * But do recurse into child plans. (Unlike Sort et al, the - * correct tlist was made by createplan.c and we shouldn't - * replace it.) + * targetlist or check quals, and we haven't bothered to give it + * its own tlist copy. So, don't fix targetlist/qual. But do + * recurse into child plans. */ Assert(plan->qual == NIL); foreach(l, ((Append *) plan)->appendplans) @@ -317,20 +315,6 @@ set_plan_references(Plan *plan, List *rtable) sp->plan = set_plan_references(sp->plan, sp->rtable); } - /* - * If this is a non-projecting plan node, create a minimally valid - * targetlist for it. Someday we might need to make this look really - * real, with Vars referencing the input node's outputs, but for now - * the executor only cares that the tlist has the right TargetEntry - * fields (resname, resjunk etc) and exprType results. So we can - * get away with just copying the input node's tlist. (Note: - * createplan.c already did copy the input, but we have to do it - * over in case we removed a SubqueryScan node: the new input plan - * node might have extra resjunk fields.) - */ - if (copy_lefttree_tlist) - plan->targetlist = copyObject(plan->lefttree->targetlist); - return plan; } @@ -430,6 +414,10 @@ trivial_subqueryscan(SubqueryScan *plan) if (plan->scan.plan.qual != NIL) return false; + if (list_length(plan->scan.plan.targetlist) != + list_length(plan->subplan->targetlist)) + return false; /* tlists not same length */ + attrno = 1; forboth(lp, plan->scan.plan.targetlist, lc, plan->subplan->targetlist) { @@ -448,18 +436,6 @@ trivial_subqueryscan(SubqueryScan *plan) attrno++; } - if (lp) - return false; /* parent tlist longer than child */ - - /* extra child items are OK only if all are resjunk */ - for_each_cell(lc, lc) - { - TargetEntry *ctle = (TargetEntry *) lfirst(lc); - - if (!ctle->resjunk) - return false; - } - return true; }