make_sort_from_pathkeys()'s method for choosing which of several
authorTom Lane <[email protected]>
Sun, 29 Feb 2004 17:36:48 +0000 (17:36 +0000)
committerTom Lane <[email protected]>
Sun, 29 Feb 2004 17:36:48 +0000 (17:36 +0000)
equivalent sort expressions to use was broken: you can't just look
at the relation membership, you have to actually grovel over the
individual Vars in each expression.  I think this did work when it
was written, but it was broken by subsequent optimizations that made
join relations not propagate every single input variable upward.
Must find the Var that got propagated, not choose one at random.
Per bug report from Daniel O'Neill.

src/backend/optimizer/plan/createplan.c

index ecd3b7116081ea5d69e6f2f635a934eba0a12ab3..9b7493b93e740a2d77a0cf03ebd998047d634dd4 100644 (file)
@@ -101,7 +101,7 @@ static MergeJoin *make_mergejoin(List *tlist,
 static Sort *make_sort(Query *root, List *tlist, Plan *lefttree, int numCols,
                  AttrNumber *sortColIdx, Oid *sortOperators);
 static Sort *make_sort_from_pathkeys(Query *root, Plan *lefttree,
-                                               Relids relids, List *pathkeys);
+                                               List *pathkeys);
 
 
 /*
@@ -1015,7 +1015,6 @@ create_mergejoin_plan(Query *root,
                outer_plan = (Plan *)
                        make_sort_from_pathkeys(root,
                                                                        outer_plan,
-                                                 best_path->jpath.outerjoinpath->parent->relids,
                                                                        best_path->outersortkeys);
        }
 
@@ -1025,7 +1024,6 @@ create_mergejoin_plan(Query *root,
                inner_plan = (Plan *)
                        make_sort_from_pathkeys(root,
                                                                        inner_plan,
-                                                 best_path->jpath.innerjoinpath->parent->relids,
                                                                        best_path->innersortkeys);
        }
 
@@ -1793,7 +1791,6 @@ add_sort_column(AttrNumber colIdx, Oid sortOp,
  *       Create sort plan to sort according to given pathkeys
  *
  *       'lefttree' is the node which yields input tuples
- *       'relids' is the set of relids represented by the input node
  *       'pathkeys' is the list of pathkeys by which the result is to be sorted
  *
  * We must convert the pathkey information into arrays of sort key column
@@ -1806,8 +1803,7 @@ add_sort_column(AttrNumber colIdx, Oid sortOp,
  * adding a Result node just to do the projection.
  */
 static Sort *
-make_sort_from_pathkeys(Query *root, Plan *lefttree,
-                                               Relids relids, List *pathkeys)
+make_sort_from_pathkeys(Query *root, Plan *lefttree, List *pathkeys)
 {
        List       *tlist = lefttree->targetlist;
        List       *sort_tlist;
@@ -1852,12 +1848,22 @@ make_sort_from_pathkeys(Query *root, Plan *lefttree,
                }
                if (!resdom)
                {
-                       /* No matching Var; look for an expression */
+                       /* No matching Var; look for a computable expression */
                        foreach(j, keysublist)
                        {
+                               List   *exprvars;
+                               List   *k;
+
                                pathkey = lfirst(j);
-                               if (bms_is_subset(pull_varnos(pathkey->key), relids))
-                                       break;
+                               exprvars = pull_var_clause(pathkey->key, false);
+                               foreach(k, exprvars)
+                               {
+                                       if (!tlist_member(lfirst(k), tlist))
+                                               break;
+                               }
+                               freeList(exprvars);
+                               if (!k)
+                                       break;          /* found usable expression */
                        }
                        if (!j)
                                elog(ERROR, "could not find pathkey item to sort");