From: Tom Lane Date: Sat, 23 Sep 2000 23:41:05 +0000 (+0000) Subject: Back-patch fix for subselect in targetlist of Append node. X-Git-Tag: REL7_0_3~19 X-Git-Url: http://git.postgresql.org/gitweb/?a=commitdiff_plain;h=783af51cb1fc27218bec7137c7a138eefb1d76e4;p=postgresql.git Back-patch fix for subselect in targetlist of Append node. --- diff --git a/src/backend/optimizer/plan/setrefs.c b/src/backend/optimizer/plan/setrefs.c index a72fa0e74f0..0d4dc0845ff 100644 --- a/src/backend/optimizer/plan/setrefs.c +++ b/src/backend/optimizer/plan/setrefs.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.62 2000/04/12 17:15:22 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.62.2.1 2000/09/23 23:41:05 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -17,12 +17,10 @@ #include "postgres.h" -#include "nodes/makefuncs.h" #include "nodes/nodeFuncs.h" #include "optimizer/clauses.h" #include "optimizer/planmain.h" #include "optimizer/tlist.h" -#include "optimizer/var.h" typedef struct { @@ -37,6 +35,7 @@ typedef struct List *subplanTargetList; } replace_vars_with_subplan_refs_context; +static void fix_expr_references(Plan *plan, Node *node); static void set_join_references(Join *join); static void set_uppernode_references(Plan *plan, Index subvarno); static Node *join_references_mutator(Node *node, @@ -88,34 +87,39 @@ set_plan_references(Plan *plan) switch (nodeTag(plan)) { case T_SeqScan: - /* nothing special */ + fix_expr_references(plan, (Node *) plan->targetlist); + fix_expr_references(plan, (Node *) plan->qual); break; case T_IndexScan: - fix_opids((Node *) ((IndexScan *) plan)->indxqual); - fix_opids((Node *) ((IndexScan *) plan)->indxqualorig); - plan->subPlan = - nconc(plan->subPlan, - pull_subplans((Node *) ((IndexScan *) plan)->indxqual)); - plan->subPlan = - nconc(plan->subPlan, - pull_subplans((Node *) ((IndexScan *) plan)->indxqualorig)); + fix_expr_references(plan, (Node *) plan->targetlist); + fix_expr_references(plan, (Node *) plan->qual); + fix_expr_references(plan, + (Node *) ((IndexScan *) plan)->indxqual); + fix_expr_references(plan, + (Node *) ((IndexScan *) plan)->indxqualorig); + break; + case T_TidScan: + fix_expr_references(plan, (Node *) plan->targetlist); + fix_expr_references(plan, (Node *) plan->qual); break; case T_NestLoop: set_join_references((Join *) plan); + fix_expr_references(plan, (Node *) plan->targetlist); + fix_expr_references(plan, (Node *) plan->qual); break; case T_MergeJoin: set_join_references((Join *) plan); - fix_opids((Node *) ((MergeJoin *) plan)->mergeclauses); - plan->subPlan = - nconc(plan->subPlan, - pull_subplans((Node *) ((MergeJoin *) plan)->mergeclauses)); + fix_expr_references(plan, (Node *) plan->targetlist); + fix_expr_references(plan, (Node *) plan->qual); + fix_expr_references(plan, + (Node *) ((MergeJoin *) plan)->mergeclauses); break; case T_HashJoin: set_join_references((Join *) plan); - fix_opids((Node *) ((HashJoin *) plan)->hashclauses); - plan->subPlan = - nconc(plan->subPlan, - pull_subplans((Node *) ((HashJoin *) plan)->hashclauses)); + fix_expr_references(plan, (Node *) plan->targetlist); + fix_expr_references(plan, (Node *) plan->qual); + fix_expr_references(plan, + (Node *) ((HashJoin *) plan)->hashclauses); break; case T_Material: case T_Sort: @@ -127,12 +131,17 @@ set_plan_references(Plan *plan) * targetlists or quals (because they just return their * unmodified input tuples). The optimizer is lazy about * creating really valid targetlists for them. Best to just - * leave the targetlist alone. + * leave the targetlist alone. In particular, we do not want + * to pull a subplan list for them, since we will likely end + * up with duplicate list entries for subplans that also appear + * in lower levels of the plan tree! */ break; case T_Agg: case T_Group: set_uppernode_references(plan, (Index) 0); + fix_expr_references(plan, (Node *) plan->targetlist); + fix_expr_references(plan, (Node *) plan->qual); break; case T_Result: @@ -144,37 +153,25 @@ set_plan_references(Plan *plan) */ if (plan->lefttree != NULL) set_uppernode_references(plan, (Index) OUTER); - fix_opids(((Result *) plan)->resconstantqual); - plan->subPlan = - nconc(plan->subPlan, - pull_subplans(((Result *) plan)->resconstantqual)); + fix_expr_references(plan, (Node *) plan->targetlist); + fix_expr_references(plan, (Node *) plan->qual); + fix_expr_references(plan, ((Result *) plan)->resconstantqual); break; case T_Append: + /* + * Append, like Sort et al, doesn't actually evaluate its + * targetlist or quals, and we haven't bothered to give it + * its own tlist copy. So, don't fix targetlist/qual. + */ foreach(pl, ((Append *) plan)->appendplans) set_plan_references((Plan *) lfirst(pl)); break; - case T_TidScan: - /* nothing special */ - break; default: elog(ERROR, "set_plan_references: unknown plan type %d", nodeTag(plan)); break; } - /* - * For all plan types, fix operators in targetlist and qual - * expressions, and find subplans therein. - */ - fix_opids((Node *) plan->targetlist); - fix_opids((Node *) plan->qual); - plan->subPlan = - nconc(plan->subPlan, - pull_subplans((Node *) plan->targetlist)); - plan->subPlan = - nconc(plan->subPlan, - pull_subplans((Node *) plan->qual)); - /* * Now recurse into subplans, if any * @@ -202,6 +199,20 @@ set_plan_references(Plan *plan) } } +/* + * fix_expr_references + * Do final cleanup on expressions (targetlists or quals). + * + * This consists of looking up operator opcode info for Oper nodes + * and adding subplans to the Plan node's list of contained subplans. + */ +static void +fix_expr_references(Plan *plan, Node *node) +{ + fix_opids(node); + plan->subPlan = nconc(plan->subPlan, pull_subplans(node)); +} + /* * set_join_references * Modifies the target list of a join node to reference its subplans,