]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Back-patch fix for subselect in targetlist of Append node.
authorTom Lane <tgl@sss.pgh.pa.us>
Sat, 23 Sep 2000 23:41:05 +0000 (23:41 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sat, 23 Sep 2000 23:41:05 +0000 (23:41 +0000)
src/backend/optimizer/plan/setrefs.c

index a72fa0e74f00f578baa9e5d5e1fdff619ff7ebe2..0d4dc0845ff2ea582f2100f11d48c9ad34cb4561 100644 (file)
@@ -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 $
  *
  *-------------------------------------------------------------------------
  */
 
 #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,