99 *
1010 *
1111 * IDENTIFICATION
12- * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.62 2000/04/12 17:15:22 momjian Exp $
12+ * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.62.2.1 2000/09/23 23:41:05 tgl Exp $
1313 *
1414 *-------------------------------------------------------------------------
1515 */
1616#include <sys/types.h>
1717
1818#include "postgres.h"
1919
20- #include "nodes/makefuncs.h"
2120#include "nodes/nodeFuncs.h"
2221#include "optimizer/clauses.h"
2322#include "optimizer/planmain.h"
2423#include "optimizer/tlist.h"
25- #include "optimizer/var.h"
2624
2725typedef struct
2826{
@@ -37,6 +35,7 @@ typedef struct
3735List * subplanTargetList ;
3836}replace_vars_with_subplan_refs_context ;
3937
38+ static void fix_expr_references (Plan * plan ,Node * node );
4039static void set_join_references (Join * join );
4140static void set_uppernode_references (Plan * plan ,Index subvarno );
4241static Node * join_references_mutator (Node * node ,
@@ -88,34 +87,39 @@ set_plan_references(Plan *plan)
8887switch (nodeTag (plan ))
8988{
9089case T_SeqScan :
91- /* nothing special */
90+ fix_expr_references (plan , (Node * )plan -> targetlist );
91+ fix_expr_references (plan , (Node * )plan -> qual );
9292break ;
9393case T_IndexScan :
94- fix_opids ((Node * ) ((IndexScan * )plan )-> indxqual );
95- fix_opids ((Node * ) ((IndexScan * )plan )-> indxqualorig );
96- plan -> subPlan =
97- nconc (plan -> subPlan ,
98- pull_subplans ((Node * ) ((IndexScan * )plan )-> indxqual ));
99- plan -> subPlan =
100- nconc (plan -> subPlan ,
101- pull_subplans ((Node * ) ((IndexScan * )plan )-> indxqualorig ));
94+ fix_expr_references (plan , (Node * )plan -> targetlist );
95+ fix_expr_references (plan , (Node * )plan -> qual );
96+ fix_expr_references (plan ,
97+ (Node * ) ((IndexScan * )plan )-> indxqual );
98+ fix_expr_references (plan ,
99+ (Node * ) ((IndexScan * )plan )-> indxqualorig );
100+ break ;
101+ case T_TidScan :
102+ fix_expr_references (plan , (Node * )plan -> targetlist );
103+ fix_expr_references (plan , (Node * )plan -> qual );
102104break ;
103105case T_NestLoop :
104106set_join_references ((Join * )plan );
107+ fix_expr_references (plan , (Node * )plan -> targetlist );
108+ fix_expr_references (plan , (Node * )plan -> qual );
105109break ;
106110case T_MergeJoin :
107111set_join_references ((Join * )plan );
108- fix_opids ( (Node * )(( MergeJoin * ) plan ) -> mergeclauses );
109- plan -> subPlan =
110- nconc (plan -> subPlan ,
111- pull_subplans (( Node * ) ((MergeJoin * )plan )-> mergeclauses ) );
112+ fix_expr_references ( plan , (Node * )plan -> targetlist );
113+ fix_expr_references ( plan , ( Node * ) plan -> qual );
114+ fix_expr_references (plan ,
115+ ( Node * ) ((MergeJoin * )plan )-> mergeclauses );
112116break ;
113117case T_HashJoin :
114118set_join_references ((Join * )plan );
115- fix_opids ( (Node * )(( HashJoin * ) plan ) -> hashclauses );
116- plan -> subPlan =
117- nconc (plan -> subPlan ,
118- pull_subplans (( Node * ) ((HashJoin * )plan )-> hashclauses ) );
119+ fix_expr_references ( plan , (Node * )plan -> targetlist );
120+ fix_expr_references ( plan , ( Node * ) plan -> qual );
121+ fix_expr_references (plan ,
122+ ( Node * ) ((HashJoin * )plan )-> hashclauses );
119123break ;
120124case T_Material :
121125case T_Sort :
@@ -127,12 +131,17 @@ set_plan_references(Plan *plan)
127131 * targetlists or quals (because they just return their
128132 * unmodified input tuples). The optimizer is lazy about
129133 * creating really valid targetlists for them.Best to just
130- * leave the targetlist alone.
134+ * leave the targetlist alone. In particular, we do not want
135+ * to pull a subplan list for them, since we will likely end
136+ * up with duplicate list entries for subplans that also appear
137+ * in lower levels of the plan tree!
131138 */
132139break ;
133140case T_Agg :
134141case T_Group :
135142set_uppernode_references (plan , (Index )0 );
143+ fix_expr_references (plan , (Node * )plan -> targetlist );
144+ fix_expr_references (plan , (Node * )plan -> qual );
136145break ;
137146case T_Result :
138147
@@ -144,37 +153,25 @@ set_plan_references(Plan *plan)
144153 */
145154if (plan -> lefttree != NULL )
146155set_uppernode_references (plan , (Index )OUTER );
147- fix_opids (((Result * )plan )-> resconstantqual );
148- plan -> subPlan =
149- nconc (plan -> subPlan ,
150- pull_subplans (((Result * )plan )-> resconstantqual ));
156+ fix_expr_references (plan , (Node * )plan -> targetlist );
157+ fix_expr_references (plan , (Node * )plan -> qual );
158+ fix_expr_references (plan , ((Result * )plan )-> resconstantqual );
151159break ;
152160case T_Append :
161+ /*
162+ * Append, like Sort et al, doesn't actually evaluate its
163+ * targetlist or quals, and we haven't bothered to give it
164+ * its own tlist copy. So, don't fix targetlist/qual.
165+ */
153166foreach (pl , ((Append * )plan )-> appendplans )
154167set_plan_references ((Plan * )lfirst (pl ));
155168break ;
156- case T_TidScan :
157- /* nothing special */
158- break ;
159169default :
160170elog (ERROR ,"set_plan_references: unknown plan type %d" ,
161171nodeTag (plan ));
162172break ;
163173}
164174
165- /*
166- * For all plan types, fix operators in targetlist and qual
167- * expressions, and find subplans therein.
168- */
169- fix_opids ((Node * )plan -> targetlist );
170- fix_opids ((Node * )plan -> qual );
171- plan -> subPlan =
172- nconc (plan -> subPlan ,
173- pull_subplans ((Node * )plan -> targetlist ));
174- plan -> subPlan =
175- nconc (plan -> subPlan ,
176- pull_subplans ((Node * )plan -> qual ));
177-
178175/*
179176 * Now recurse into subplans, if any
180177 *
@@ -202,6 +199,20 @@ set_plan_references(Plan *plan)
202199}
203200}
204201
202+ /*
203+ * fix_expr_references
204+ * Do final cleanup on expressions (targetlists or quals).
205+ *
206+ * This consists of looking up operator opcode info for Oper nodes
207+ * and adding subplans to the Plan node's list of contained subplans.
208+ */
209+ static void
210+ fix_expr_references (Plan * plan ,Node * node )
211+ {
212+ fix_opids (node );
213+ plan -> subPlan = nconc (plan -> subPlan ,pull_subplans (node ));
214+ }
215+
205216/*
206217 * set_join_references
207218 * Modifies the target list of a join node to reference its subplans,