99 *
1010 *
1111 * IDENTIFICATION
12- * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.63 2000/05/30 00:49:47 momjian Exp $
12+ * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/setrefs.c,v 1.64 2000/06/04 20:50:50 tgl Exp $
1313 *
1414 *-------------------------------------------------------------------------
1515 */
@@ -35,6 +35,7 @@ typedef struct
3535List * subplanTargetList ;
3636}replace_vars_with_subplan_refs_context ;
3737
38+ static void fix_expr_references (Plan * plan ,Node * node );
3839static void set_join_references (Join * join );
3940static void set_uppernode_references (Plan * plan ,Index subvarno );
4041static Node * join_references_mutator (Node * node ,
@@ -86,34 +87,39 @@ set_plan_references(Plan *plan)
8687switch (nodeTag (plan ))
8788{
8889case T_SeqScan :
89- /* nothing special */
90+ fix_expr_references (plan , (Node * )plan -> targetlist );
91+ fix_expr_references (plan , (Node * )plan -> qual );
9092break ;
9193case T_IndexScan :
92- fix_opids ((Node * ) ((IndexScan * )plan )-> indxqual );
93- fix_opids ((Node * ) ((IndexScan * )plan )-> indxqualorig );
94- plan -> subPlan =
95- nconc (plan -> subPlan ,
96- pull_subplans ((Node * ) ((IndexScan * )plan )-> indxqual ));
97- plan -> subPlan =
98- nconc (plan -> subPlan ,
99- 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 );
100104break ;
101105case T_NestLoop :
102106set_join_references ((Join * )plan );
107+ fix_expr_references (plan , (Node * )plan -> targetlist );
108+ fix_expr_references (plan , (Node * )plan -> qual );
103109break ;
104110case T_MergeJoin :
105111set_join_references ((Join * )plan );
106- fix_opids ( (Node * )(( MergeJoin * ) plan ) -> mergeclauses );
107- plan -> subPlan =
108- nconc (plan -> subPlan ,
109- 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 );
110116break ;
111117case T_HashJoin :
112118set_join_references ((Join * )plan );
113- fix_opids ( (Node * )(( HashJoin * ) plan ) -> hashclauses );
114- plan -> subPlan =
115- nconc (plan -> subPlan ,
116- 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 );
117123break ;
118124case T_Material :
119125case T_Sort :
@@ -125,12 +131,17 @@ set_plan_references(Plan *plan)
125131 * targetlists or quals (because they just return their
126132 * unmodified input tuples). The optimizer is lazy about
127133 * creating really valid targetlists for them.Best to just
128- * 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!
129138 */
130139break ;
131140case T_Agg :
132141case T_Group :
133142set_uppernode_references (plan , (Index )0 );
143+ fix_expr_references (plan , (Node * )plan -> targetlist );
144+ fix_expr_references (plan , (Node * )plan -> qual );
134145break ;
135146case T_Result :
136147
@@ -142,37 +153,25 @@ set_plan_references(Plan *plan)
142153 */
143154if (plan -> lefttree != NULL )
144155set_uppernode_references (plan , (Index )OUTER );
145- fix_opids (((Result * )plan )-> resconstantqual );
146- plan -> subPlan =
147- nconc (plan -> subPlan ,
148- 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 );
149159break ;
150160case 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+ */
151166foreach (pl , ((Append * )plan )-> appendplans )
152167set_plan_references ((Plan * )lfirst (pl ));
153168break ;
154- case T_TidScan :
155- /* nothing special */
156- break ;
157169default :
158170elog (ERROR ,"set_plan_references: unknown plan type %d" ,
159171nodeTag (plan ));
160172break ;
161173}
162174
163- /*
164- * For all plan types, fix operators in targetlist and qual
165- * expressions, and find subplans therein.
166- */
167- fix_opids ((Node * )plan -> targetlist );
168- fix_opids ((Node * )plan -> qual );
169- plan -> subPlan =
170- nconc (plan -> subPlan ,
171- pull_subplans ((Node * )plan -> targetlist ));
172- plan -> subPlan =
173- nconc (plan -> subPlan ,
174- pull_subplans ((Node * )plan -> qual ));
175-
176175/*
177176 * Now recurse into subplans, if any
178177 *
@@ -200,6 +199,20 @@ set_plan_references(Plan *plan)
200199}
201200}
202201
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+
203216/*
204217 * set_join_references
205218 * Modifies the target list of a join node to reference its subplans,