it. Find each way of accessing the relation, called a Path, including
sequential and index scans, and add it to RelOptInfo.pathlist. Also
create RelOptInfo.joininfo that lists all the joins that involve this
-relation.
+relation. For example, the WHERE clause "tab1.col1 = tab2.col1"
+generates a JoinInfo for tab1 listing tab2 as an unjoined relation, and
+tab2's joininfo shows tab1 as an unjoined relation.
2) Join each RelOptInfo to other RelOptInfo as specified in
RelOptInfo.joininfo. At this point each RelOptInfo is a single
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinpath.c,v 1.29 1999/02/18 19:58:52 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinpath.c,v 1.30 1999/02/19 05:18:04 momjian Exp $
*
*-------------------------------------------------------------------------
*/
List *pathlist = NIL;
/* flatten out relids later in this function */
- innerrelids = lsecond(joinrel->relids);
outerrelids = lfirst(joinrel->relids);
+ innerrelids = lsecond(joinrel->relids);
/*
* base relation id is an integer and join relation relid is a
outerrel,
innerrel,
outerrel->pathlist,
- (Path *) innerrel->cheapestpath,
+ innerrel->cheapestpath,
bestinnerjoin,
mergeinfo_list));
&& ((cheapest == NULL ||
path_is_cheaper((Path *) lfirst(join_path), cheapest))))
{
-
cheapest = (Path *) lfirst(join_path);
}
}
List *clauses = NIL;
List *matchedJoinKeys = NIL;
List *matchedJoinClauses = NIL;
- MergeInfo *xmergeinfo = (MergeInfo *) NULL;
+ MergeInfo *xmergeinfo = NULL;
outerpath = (Path *) lfirst(i);
if (clauses)
{
List *jmkeys = xmergeinfo->jmethod.jmkeys;
- List *clauses = xmergeinfo->jmethod.clauses;
- matchedJoinKeys = match_pathkeys_joinkeys(outerpath->pathkeys,
+ matchedJoinKeys = order_joinkeys_by_pathkeys(outerpath->pathkeys,
jmkeys,
clauses,
OUTER,
{
bool path_is_cheaper_than_sort;
List *varkeys = NIL;
- Path *mergeinnerpath = match_paths_joinkeys(matchedJoinKeys,
- outerpath_ordering,
- innerrel->pathlist,
- INNER);
+ Path *mergeinnerpath = get_cheapest_path_for_joinkeys(
+ matchedJoinKeys,
+ outerpath_ordering,
+ innerrel->pathlist,
+ INNER);
/* Should we use the mergeinner, or sort the cheapest inner? */
path_is_cheaper_than_sort = (bool) (mergeinnerpath &&
- (mergeinnerpath->path_cost <
- (cheapest_inner->path_cost +
- cost_sort(matchedJoinKeys,
- innerrel->size,
- innerrel->width,
- false))));
+ (mergeinnerpath->path_cost <
+ (cheapest_inner->path_cost +
+ cost_sort(matchedJoinKeys, innerrel->size,
+ innerrel->width, false))));
if (!path_is_cheaper_than_sort)
{
varkeys = extract_path_keys(matchedJoinKeys,
if (clauses)
{
List *jmkeys = xmergeinfo->jmethod.jmkeys;
- List *cls = xmergeinfo->jmethod.clauses;
- matchedJoinKeys = match_pathkeys_joinkeys(innerpath->pathkeys,
+ matchedJoinKeys = order_joinkeys_by_pathkeys(innerpath->pathkeys,
jmkeys,
- cls,
+ clauses,
INNER,
&matchedJoinClauses);
}
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/path/Attic/pathkey.c,v 1.2 1999/02/19 02:05:15 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/path/Attic/pathkey.c,v 1.3 1999/02/19 05:18:05 momjian Exp $
*
*-------------------------------------------------------------------------
*/
static int match_pathkey_joinkeys(List *pathkey, List *joinkeys,
int outer_or_inner);
-static bool every_func(List *joinkeys, List *pathkey,
+static bool joinkeys_pathkeys_match(List *joinkeys, List *pathkey,
int outer_or_inner);
static List *new_join_pathkey(List *subkeys, List *considered_subkeys,
List *join_rel_tlist, List *joinclauses);
****************************************************************************/
/*
- * match_pathkeys_joinkeys
+ * order_joinkeys_by_pathkeys
* Attempts to match the keys of a path against the keys of join clauses.
* This is done by looking for a matching join key in 'joinkeys' for
* every path key in the list 'path.keys'. If there is a matching join key
* in matchedJoinClausesPtr. - ay 11/94
*/
List *
-match_pathkeys_joinkeys(List *pathkeys,
+order_joinkeys_by_pathkeys(List *pathkeys,
List *joinkeys,
List *joinclauses,
int outer_or_inner,
List *xjoinkey = nth(matched_joinkey_index, joinkeys);
List *joinclause = nth(matched_joinkey_index, joinclauses);
- matched_joinkeys = lcons(xjoinkey, matched_joinkeys);
- matched_joinclauses = lcons(joinclause, matched_joinclauses);
-
- joinkeys = LispRemove(xjoinkey, joinkeys);
+ matched_joinkeys = lappend(matched_joinkeys, xjoinkey);
+ matched_joinclauses = lappend(matched_joinclauses, joinclause);
}
else
+ {
+ *matchedJoinClausesPtr = NIL;
return NIL;
-
+ }
}
- if (matched_joinkeys == NULL ||
- length(matched_joinkeys) != length(pathkeys))
- return NIL;
- *matchedJoinClausesPtr = nreverse(matched_joinclauses);
- return nreverse(matched_joinkeys);
+ *matchedJoinClausesPtr = matched_joinclauses;
+ return matched_joinkeys;
}
/*
- * match_paths_joinkeys
+ * get_cheapest_path_for_joinkeys
* Attempts to find a path in 'paths' whose keys match a set of join
* keys 'joinkeys'. To match,
* 1. the path node ordering must equal 'ordering'.
* Find the cheapest path that matches the join keys
*/
Path *
-match_paths_joinkeys(List *joinkeys,
- PathOrder *ordering,
- List *paths,
- int outer_or_inner)
+get_cheapest_path_for_joinkeys(List *joinkeys,
+ PathOrder *ordering,
+ List *paths,
+ int outer_or_inner)
{
Path *matched_path = NULL;
- bool key_match = false;
List *i = NIL;
foreach(i, paths)
{
Path *path = (Path *) lfirst(i);
- int better_sort;
+ int better_sort, better_key;
- key_match = every_func(joinkeys, path->pathkeys, outer_or_inner);
-
- if (pathorder_match(ordering, path->pathorder, &better_sort) &&
- better_sort == 0 &&
- length(joinkeys) == length(path->pathkeys) && key_match)
+ if (joinkeys_pathkeys_match(joinkeys, path->pathkeys, outer_or_inner) &&
+ length(joinkeys) == length(path->pathkeys) &&
+ pathorder_match(ordering, path->pathorder, &better_sort) &&
+ better_sort == 0)
{
if (matched_path)
- {
if (path->path_cost < matched_path->path_cost)
matched_path = path;
- }
else
matched_path = path;
}
/*
- * every_func
+ * joinkeys_pathkeys_match
*/
static bool
-every_func(List *joinkeys, List *pathkey, int outer_or_inner)
+joinkeys_pathkeys_match(List *joinkeys, List *pathkey, int outer_or_inner)
{
JoinKey *xjoinkey;
Var *temp;
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: paths.h,v 1.23 1999/02/19 02:05:20 momjian Exp $
+ * $Id: paths.h,v 1.24 1999/02/19 05:18:06 momjian Exp $
*
*-------------------------------------------------------------------------
*/
* joinutils.h
* generic join method key/clause routines
*/
-extern List *match_pathkeys_joinkeys(List *pathkeys,
+extern List *order_joinkeys_by_pathkeys(List *pathkeys,
List *joinkeys, List *joinclauses, int outer_or_inner,
List **matchedJoinClausesPtr);
extern List *extract_path_keys(List *joinkeys, List *tlist,
int outer_or_inner);
-extern Path *match_paths_joinkeys(List *joinkeys, PathOrder *ordering,
- List *paths, int outer_or_inner);
+extern Path *get_cheapest_path_for_joinkeys(List *joinkeys,
+ PathOrder *ordering, List *paths, int outer_or_inner);
extern List *new_join_pathkeys(List *outer_pathkeys,
List *join_rel_tlist, List *joinclauses);