Back off previous patch to skip projection step in scan plan nodes,
authorTom Lane
Sun, 16 Feb 2003 06:06:32 +0000 (06:06 +0000)
committerTom Lane
Sun, 16 Feb 2003 06:06:32 +0000 (06:06 +0000)
in the case where the node immediately above the scan is a Hash, Sort,
or Material node.  In these cases it's better to do the projection
so that we don't store unneeded columns in the hash/sort/materialize
table.  Per discussion a few days ago with Anagh Lal.

src/backend/optimizer/plan/createplan.c

index 87cfb1d8525e5d66bfd8e5bf99bf7000081d9ff6..bfc11aa004662cd6de53f7fc69e2112c7e809b50 100644 (file)
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.136 2003/02/09 06:56:27 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.137 2003/02/16 06:06:32 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -35,6 +35,7 @@
 
 static Scan *create_scan_plan(Query *root, Path *best_path);
 static bool use_physical_tlist(RelOptInfo *rel);
+static void disuse_physical_tlist(Plan *plan, Path *path);
 static Join *create_join_plan(Query *root, JoinPath *best_path);
 static Append *create_append_plan(Query *root, AppendPath *best_path);
 static Result *create_result_plan(Query *root, ResultPath *best_path);
@@ -310,6 +311,33 @@ use_physical_tlist(RelOptInfo *rel)
    return true;
 }
 
+/*
+ * disuse_physical_tlist
+ *     Switch a plan node back to emitting only Vars actually referenced.
+ *
+ * If the plan node immediately above a scan would prefer to get only
+ * needed Vars and not a physical tlist, it must call this routine to
+ * undo the decision made by use_physical_tlist().  Currently, Hash, Sort,
+ * and Material nodes want this, so they don't have to store useless columns.
+ */
+static void
+disuse_physical_tlist(Plan *plan, Path *path)
+{
+   /* Only need to undo it for path types handled by create_scan_plan() */
+   switch (path->pathtype)
+   {
+       case T_IndexScan:
+       case T_SeqScan:
+       case T_TidScan:
+       case T_SubqueryScan:
+       case T_FunctionScan:
+           plan->targetlist = path->parent->targetlist;
+           break;
+       default:
+           break;
+   }
+}
+
 /*
  * create_join_plan
  *   Create a join plan for 'best_path' and (recursively) plans for its
@@ -468,6 +496,9 @@ create_material_plan(Query *root, MaterialPath *best_path)
 
    subplan = create_plan(root, best_path->subpath);
 
+   /* We don't want any excess columns in the materialized tuples */
+   disuse_physical_tlist(subplan, best_path->subpath);
+
    plan = make_material(subplan->targetlist, subplan);
 
    copy_path_costsize(&plan->plan, (Path *) best_path);
@@ -906,20 +937,27 @@ create_mergejoin_plan(Query *root,
    /*
     * Create explicit sort nodes for the outer and inner join paths if
     * necessary.  The sort cost was already accounted for in the path.
+    * Make sure there are no excess columns in the inputs if sorting.
     */
    if (best_path->outersortkeys)
+   {
+       disuse_physical_tlist(outer_plan, best_path->jpath.outerjoinpath);
        outer_plan = (Plan *)
            make_sort_from_pathkeys(root,
                                    outer_plan,
                                    best_path->jpath.outerjoinpath->parent->relids,
                                    best_path->outersortkeys);
+   }
 
    if (best_path->innersortkeys)
+   {
+       disuse_physical_tlist(inner_plan, best_path->jpath.innerjoinpath);
        inner_plan = (Plan *)
            make_sort_from_pathkeys(root,
                                    inner_plan,
                                    best_path->jpath.innerjoinpath->parent->relids,
                                    best_path->innersortkeys);
+   }
 
    /*
     * Now we can build the mergejoin node.
@@ -976,6 +1014,9 @@ create_hashjoin_plan(Query *root,
        innerhashkeys = lappend(innerhashkeys, get_rightop(lfirst(hcl)));
    }
 
+   /* We don't want any excess columns in the hashed tuples */
+   disuse_physical_tlist(inner_plan, best_path->jpath.innerjoinpath);
+
    /*
     * Build the hash node and hash join node.
     */