diff --git a/src/backend/nodes/print.c b/src/backend/nodes/print.c index f26d5100e34d0270b504a8f14c0f96d805366ed1..e8837dc7570b1180834fe481dcc4b58ee630ac02 100644 --- a/src/backend/nodes/print.c +++ b/src/backend/nodes/print.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/nodes/print.c,v 1.22 1999/02/13 23:16:00 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/print.c,v 1.23 1999/02/20 19:02:40 momjian Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -213,20 +213,28 @@ print_expr(Node *expr, List *rtable) /* * print_pathkeys - - * temporary here. where is keys list of lists + * pathkeys list of list of Var's */ void print_pathkeys(List *pathkeys, List *rtable) { - List *k; + List *i, *k; printf("("); - foreach(k, pathkeys) + foreach(i, pathkeys) { - Node *var = lfirst((List *) lfirst(k)); + List pathkey = lfirst(i)); - print_expr(var, rtable); - if (lnext(k)) + printf("("); + foreach(k, pathkey) + { + Node *var = lfirst(k); + print_expr(var, rtable); + if (lnext(k)) + printf(", "); + } + printf(") "); + if (lnext(i)) printf(", "); } printf(")\n"); diff --git a/src/backend/optimizer/path/pathkeys.c b/src/backend/optimizer/path/pathkeys.c index f1ea6cbae68384b54a7967675d7b1930e148b77b..836b924ae1389ad3b735d3cadb7c4005b44bfe49 100644 --- a/src/backend/optimizer/path/pathkeys.c +++ b/src/backend/optimizer/path/pathkeys.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/path/pathkeys.c,v 1.4 1999/02/20 18:01:01 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/path/pathkeys.c,v 1.5 1999/02/20 19:02:41 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -54,7 +54,19 @@ static List *new_matching_subkeys(Var *subkey, List *considered_subkeys, * { {tab1.col1, tab2.col1} }. This allows future joins to use either Var * as a pre-sorted key to prevent Mergejoins from having to re-sort the Path. * They are equal, so they are both primary sort keys. This is why pathkeys - * is a List of Lists. -- bjm + * is a List of Lists. + * + * For multi-key sorts, if the outer is sorted by a multi-key index, the + * multi-key index remains after the join. If the inner has a multi-key + * sort, only the primary key of the inner is added to the result. + * Mergejoins only join on the primary key. Currently, non-primary keys + * in the pathkeys List are of limited value. + * + * HashJoin has similar functionality. NestJoin does not perform sorting, + * and allows non-equajoins, so it does not allow useful pathkeys. + * + * -- bjm + * */ /**************************************************************************** @@ -92,10 +104,10 @@ static List *new_matching_subkeys(Var *subkey, List *considered_subkeys, */ List * order_joinkeys_by_pathkeys(List *pathkeys, - List *joinkeys, - List *joinclauses, - int outer_or_inner, - List **matchedJoinClausesPtr) + List *joinkeys, + List *joinclauses, + int outer_or_inner, + List **matchedJoinClausesPtr) { List *matched_joinkeys = NIL; List *matched_joinclauses = NIL; @@ -103,6 +115,10 @@ order_joinkeys_by_pathkeys(List *pathkeys, List *i = NIL; int matched_joinkey_index = -1; + /* + * Reorder the joinkeys by picking out one that matches each pathkey, + * and create a new joinkey/joinclause list in pathkey order + */ foreach(i, pathkeys) { pathkey = lfirst(i); @@ -118,10 +134,18 @@ order_joinkeys_by_pathkeys(List *pathkeys, matched_joinclauses = lappend(matched_joinclauses, joinclause); } else - { + /* A pathkey could not be matched. */ + break; + } + + /* + * Did we fail to match all the joinkeys? + * Extra pathkeys are no problem. + */ + if (length(joinkeys) != length(matched_joinkeys)) + { *matchedJoinClausesPtr = NIL; return NIL; - } } *matchedJoinClausesPtr = matched_joinclauses; @@ -133,6 +157,8 @@ order_joinkeys_by_pathkeys(List *pathkeys, * match_pathkey_joinkeys * Returns the 0-based index into 'joinkeys' of the first joinkey whose * outer or inner subkey matches any subkey of 'pathkey'. + * + * All these keys are equivalent, so any of them can match. See above. */ static int match_pathkey_joinkeys(List *pathkey, @@ -141,8 +167,7 @@ match_pathkey_joinkeys(List *pathkey, { Var *path_subkey; int pos; - List *i = NIL; - List *x = NIL; + List *i, *x; JoinKey *jk; foreach(i, pathkey) @@ -152,8 +177,7 @@ match_pathkey_joinkeys(List *pathkey, foreach(x, joinkeys) { jk = (JoinKey *) lfirst(x); - if (var_equal(path_subkey, - extract_join_key(jk, outer_or_inner))) + if (var_equal(path_subkey, extract_join_key(jk, outer_or_inner))) return pos; pos++; } diff --git a/src/backend/optimizer/util/pathnode.c b/src/backend/optimizer/util/pathnode.c index d94e124193e61d3c951469680cbcd406688bfcc2..7011f053c0ae11a0f5f6e2ecab6477c98555fca0 100644 --- a/src/backend/optimizer/util/pathnode.c +++ b/src/backend/optimizer/util/pathnode.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/util/pathnode.c,v 1.38 1999/02/20 18:01:02 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/util/pathnode.c,v 1.39 1999/02/20 19:02:42 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -205,7 +205,7 @@ better_path(Path *new_path, List *unique_paths, bool *is_new) { /* * Replace pathkeys that match exactly, {{1,2}}, {{1,2}} - * Replace pathkeys {{1,2}}with {{1,2,3}}} if the latter is not + * Replace pathkeys {{1,2}} with {{1,2,3}}} if the latter is not * more expensive and replace unordered path with ordered * path if it is not more expensive. Favor sorted keys * over unsorted keys in the same way. diff --git a/src/include/nodes/relation.h b/src/include/nodes/relation.h index f9818339b0cb054fcc088c0f8d91d52aa9ce760c..bf2e59d30cbc9677d8d8b73eb2a8bf432a288dfd 100644 --- a/src/include/nodes/relation.h +++ b/src/include/nodes/relation.h @@ -6,7 +6,7 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: relation.h,v 1.27 1999/02/20 16:28:20 momjian Exp $ + * $Id: relation.h,v 1.28 1999/02/20 19:02:43 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -142,8 +142,7 @@ typedef struct Path PathOrder *pathorder; - List *pathkeys; /* - * This is a List of List of Var nodes. + List *pathkeys; /* This is a List of List of Var nodes. * See the top of optimizer/path/pathkeys.c * for more information. */