1 /*-------------------------------------------------------------------------
4 * Routines to prune redundant paths and relations
6 * Copyright (c) 1994, Regents of the University of California
10 * $Header: /cvsroot/pgsql/src/backend/optimizer/path/Attic/prune.c,v 1.27 1999/02/11 14:58:54 momjian Exp $
12 *-------------------------------------------------------------------------
16 #include "nodes/pg_list.h"
17 #include "nodes/relation.h"
19 #include "optimizer/internal.h"
20 #include "optimizer/cost.h"
21 #include "optimizer/paths.h"
22 #include "optimizer/pathnode.h"
24 #include "utils/elog.h"
27 static List *prune_joinrel(RelOptInfo *rel, List *other_rels);
31 * Removes any redundant relation entries from a list of rel nodes
32 * 'rel-list'. Obviously, the first relation can't be a duplicate.
34 * Returns the resulting list.
38 prune_joinrels(List *rel_list)
43 * rel_list can shorten while running as duplicate relations are
47 lnext(i) = prune_joinrel((RelOptInfo *) lfirst(i), lnext(i));
52 * Prunes those relations from 'other-rels' that are redundant with
53 * 'rel'. A relation is redundant if it is built up of the same
54 * relations as 'rel'. Paths for the redundant relation are merged into
55 * the pathlist of 'rel'.
57 * Returns a list of non-redundant relations, and sets the pathlist field
58 * of 'rel' appropriately.
62 prune_joinrel(RelOptInfo *rel, List *other_rels)
67 foreach(i, other_rels)
69 RelOptInfo *other_rel = (RelOptInfo *) lfirst(i);
71 if (same(rel->relids, other_rel->relids))
73 * This are on the same relations,
74 * so get the best of their pathlists.
76 rel->pathlist = add_pathlist(rel,
80 result = nconc(result, lcons(other_rel, NIL));
87 * For each relation entry in 'rel-list' (which corresponds to a join
88 * relation), set pointers to the unordered path and cheapest paths
89 * (if the unordered path isn't the cheapest, it is pruned), and
90 * reset the relation's size field to reflect the join.
92 * Returns nothing of interest.
96 prune_rel_paths(List *rel_list)
101 RelOptInfo *rel = (RelOptInfo *) NULL;
102 JoinPath *cheapest = (JoinPath *) NULL;
106 rel = (RelOptInfo *) lfirst(x);
108 foreach(y, rel->pathlist)
110 path = (Path *) lfirst(y);
112 if (!path->pathorder->ord.sortop)
115 cheapest = (JoinPath *) prune_rel_path(rel, path);
116 if (IsA_JoinPath(cheapest))
117 rel->size = compute_joinrel_size(cheapest);
119 elog(ERROR, "non JoinPath called");
126 * Compares the unordered path for a relation with the cheapest path. If
127 * the unordered path is not cheapest, it is pruned.
129 * Resets the pointers in 'rel' for unordered and cheapest paths.
131 * Returns the cheapest path.
135 prune_rel_path(RelOptInfo *rel, Path *unorderedpath)
137 Path *cheapest = set_cheapest(rel, rel->pathlist);
139 /* don't prune if not pruneable -- JMH, 11/23/92 */
140 if (unorderedpath != cheapest && rel->pruneable)
142 rel->unorderedpath = (Path *) NULL;
143 rel->pathlist = lremove(unorderedpath, rel->pathlist);
146 rel->unorderedpath = (Path *) unorderedpath;
153 * Given two lists of rel nodes that are already
154 * pruned, merge them into one pruned rel node list
157 * 'rel-list2' are the rel node lists
159 * Returns one pruned rel node list
162 merge_joinrels(List *rel_list1, List *rel_list2)
166 foreach(xrel, rel_list1)
168 RelOptInfo *rel = (RelOptInfo *) lfirst(xrel);
170 rel_list2 = prune_joinrel(rel, rel_list2);
172 return append(rel_list1, rel_list2);
177 * If all the joininfo's in a rel node are inactive,
178 * that means that this node has been joined into
179 * other nodes in all possible ways, therefore
180 * this node can be discarded. If not, it will cause
181 * extra complexity of the optimizer.
183 * old_rels is a list of rel nodes
185 * Returns a new list of rel nodes
188 prune_oldrels(List *old_rels)
198 rel = (RelOptInfo *) lfirst(i);
199 joininfo_list = rel->joininfo;
201 if (joininfo_list == NIL)
202 temp_list = lcons(rel, temp_list);
205 foreach(xjoininfo, joininfo_list)
207 JoinInfo *joininfo = (JoinInfo *) lfirst(xjoininfo);
209 if (!joininfo->inactive)
211 temp_list = lcons(rel, temp_list);