1 /*-------------------------------------------------------------------------
4 * Routines to process redundant paths and relations
6 * Copyright (c) 1994, Regents of the University of California
8 * $Id: geqo_paths.c,v 1.13 1999/02/08 04:29:06 momjian Exp $
10 *-------------------------------------------------------------------------
15 #include "nodes/pg_list.h"
16 #include "nodes/relation.h"
17 #include "nodes/primnodes.h"
19 #include "utils/palloc.h"
20 #include "utils/elog.h"
22 #include "optimizer/internal.h"
23 #include "optimizer/paths.h"
24 #include "optimizer/pathnode.h"
25 #include "optimizer/clauses.h"
26 #include "optimizer/cost.h"
28 #include "optimizer/geqo_paths.h"
31 static List *geqo_prune_rel(RelOptInfo * rel, List *other_rels);
32 static Path *set_paths(RelOptInfo * rel, Path *unorderedpath);
36 * Removes any redundant relation entries from a list of rel nodes
39 * Returns the resulting list.
43 geqo_prune_rels(List *rel_list)
45 List *temp_list = NIL;
49 temp_list = lcons(lfirst(rel_list),
50 geqo_prune_rels(geqo_prune_rel((RelOptInfo *) lfirst(rel_list),
58 * Prunes those relations from 'other-rels' that are redundant with
59 * 'rel'. A relation is redundant if it is built up of the same
60 * relations as 'rel'. Paths for the redundant relation are merged into
61 * the pathlist of 'rel'.
63 * Returns a list of non-redundant relations, and sets the pathlist field
64 * of 'rel' appropriately.
68 geqo_prune_rel(RelOptInfo * rel, List *other_rels)
72 List *temp_node = NIL;
73 RelOptInfo *other_rel = (RelOptInfo *) NULL;
75 foreach(i, other_rels)
77 other_rel = (RelOptInfo *) lfirst(i);
78 if (same(rel->relids, other_rel->relids))
80 rel->pathlist = add_pathlist(rel,
83 t_list = nconc(t_list, NIL); /* XXX is this right ? */
87 temp_node = lcons(other_rel, NIL);
88 t_list = nconc(t_list, temp_node);
96 * For a relation 'rel' (which corresponds to a join
97 * relation), set pointers to the unordered path and cheapest paths
98 * (if the unordered path isn't the cheapest, it is pruned), and
99 * reset the relation's size field to reflect the join.
101 * Returns nothing of interest.
105 geqo_rel_paths(RelOptInfo * rel)
108 Path *path = (Path *) NULL;
109 JoinPath *cheapest = (JoinPath *) NULL;
112 foreach(y, rel->pathlist)
114 path = (Path *) lfirst(y);
116 if (!path->path_order.ord.sortop)
120 cheapest = (JoinPath *) set_paths(rel, path);
121 if (IsA_JoinPath(cheapest))
122 rel->size = compute_joinrel_size(cheapest);
128 * Compares the unordered path for a relation with the cheapest path. If
129 * the unordered path is not cheapest, it is pruned.
131 * Resets the pointers in 'rel' for unordered and cheapest paths.
133 * Returns the cheapest path.
137 set_paths(RelOptInfo * rel, Path *unorderedpath)
139 Path *cheapest = set_cheapest(rel, rel->pathlist);
141 /* don't prune if not pruneable -- JMH, 11/23/92 */
142 if (unorderedpath != cheapest
146 rel->unorderedpath = (Path *) NULL;
147 rel->pathlist = lremove(unorderedpath, rel->pathlist);
150 rel->unorderedpath = (Path *) unorderedpath;