Commit 0ff27333 authored by Bruce Momjian's avatar Bruce Momjian

Update pathkeys comparison function.

parent 148ec3b1
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/pathkeys.c,v 1.3 1999/02/20 16:32:35 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/optimizer/path/pathkeys.c,v 1.4 1999/02/20 18:01:01 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -54,7 +54,7 @@ static List *new_matching_subkeys(Var *subkey, List *considered_subkeys, ...@@ -54,7 +54,7 @@ static List *new_matching_subkeys(Var *subkey, List *considered_subkeys,
* { {tab1.col1, tab2.col1} }. This allows future joins to use either Var * { {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. * 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 * They are equal, so they are both primary sort keys. This is why pathkeys
* is a List of Lists. * is a List of Lists. -- bjm
*/ */
/**************************************************************************** /****************************************************************************
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/Attic/keys.c,v 1.18 1999/02/19 02:05:16 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/Attic/keys.c,v 1.19 1999/02/20 18:01:02 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -110,62 +110,70 @@ extract_join_key(JoinKey *jk, int outer_or_inner) ...@@ -110,62 +110,70 @@ extract_join_key(JoinKey *jk, int outer_or_inner)
* Returns t iff two sets of path keys are equivalent. They are * Returns t iff two sets of path keys are equivalent. They are
* equivalent if the first Var nodes match the second Var nodes. * equivalent if the first Var nodes match the second Var nodes.
* *
* XXX It isn't necessary to check that each sublist exactly contain * See the top of optimizer/path/pathkeys.c for a description of pathkeys.
* the same elements because if the routine that built these * Each pathkey is ordered by its join order, so they not pre-ordered to
* sublists together is correct, having one element in common * match. We must search them ourselves.
* implies having all elements in common.
* Huh? bjm
* *
* This gets called a lot, so it is optimized.
*/ */
bool bool
pathkeys_match(List *keys1, List *keys2, int *better_key) pathkeys_match(List *keys1, List *keys2, int *better_key)
{ {
List *key1, List *key1,
*key2, *key2;
*key1a, bool key1_subsetof_key2 = true,
*key2a; key2_subsetof_key1 = true;
for (key1 = keys1, key2 = keys2; for (key1 = keys1, key2 = keys2;
key1 != NIL && key2 != NIL; key1 != NIL && key2 != NIL;
key1 = lnext(key1), key2 = lnext(key2)) key1 = lnext(key1), key2 = lnext(key2))
{ {
for (key1a = lfirst(key1), key2a = lfirst(key2); List *i;
key1a != NIL && key2a != NIL;
key1a = lnext(key1a), key2a = lnext(key2a)) if (key1_subsetof_key2)
if (!equal(lfirst(key1a), lfirst(key2a))) foreach(i, lfirst(key1))
{ {
*better_key = 0; Var *subkey = lfirst(i);
return false; if (!member(subkey, lfirst(key2)))
{
key1_subsetof_key2 = false;
break;
}
} }
if (key1a != NIL && key2a == NIL)
{ if (key2_subsetof_key1)
*better_key = 1; foreach(i, lfirst(key2))
return true; {
} Var *subkey = lfirst(i);
if (key1a == NIL && key2a != NIL) if (!member(subkey, lfirst(key1)))
{ {
*better_key = 2; key2_subsetof_key1 = false;
return true; break;
} }
}
if (!key1_subsetof_key2 && !key2_subsetof_key1)
break; /* no need to continue comparisons. */
} }
/* Now the result should be true if list keys2 has at least as many if (!key1_subsetof_key2 && !key2_subsetof_key1)
* entries as keys1, ie, we did not fall off the end of keys2 first.
* If key1 is now NIL then we hit the end of keys1 before or at the
* same time as the end of keys2.
*/
if (key1 != NIL && key2 == NIL)
{ {
*better_key = 1; *better_key = 0;
return true; return false;
} }
if (key1 == NIL && key2 != NIL) if (key1_subsetof_key2 && !key2_subsetof_key1)
{ {
*better_key = 2; *better_key = 2;
return true; return true;
} }
if (!key1_subsetof_key2 && key2_subsetof_key1)
{
*better_key = 1;
return true;
}
*better_key = 0; *better_key = 0;
return true; return true;
} }
/* /*
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/pathnode.c,v 1.37 1999/02/18 00:49:38 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/pathnode.c,v 1.38 1999/02/20 18:01:02 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -172,15 +172,15 @@ better_path(Path *new_path, List *unique_paths, bool *is_new) ...@@ -172,15 +172,15 @@ better_path(Path *new_path, List *unique_paths, bool *is_new)
{ {
path = (Path *) lfirst(temp); path = (Path *) lfirst(temp);
#if 0 #ifdef OPTDUP_DEBUG
/*def OPTDUP_DEBUG*/
if (!pathkeys_match(new_path->pathkeys, path->pathkeys, &better_key) || if (!pathkeys_match(new_path->pathkeys, path->pathkeys, &better_key) ||
better_key != 0) better_key != 0)
{ {
printf("oldpath\n"); printf("betterkey = %d\n", better_key);
pprint(path->pathkeys);
printf("newpath\n"); printf("newpath\n");
pprint(new_path->pathkeys); pprint(new_path->pathkeys);
printf("oldpath\n");
pprint(path->pathkeys);
if (path->pathkeys && new_path->pathkeys && if (path->pathkeys && new_path->pathkeys &&
length(lfirst(path->pathkeys)) >= 2/* && length(lfirst(path->pathkeys)) >= 2/* &&
length(lfirst(path->pathkeys)) < length(lfirst(path->pathkeys)) <
...@@ -191,10 +191,10 @@ better_path(Path *new_path, List *unique_paths, bool *is_new) ...@@ -191,10 +191,10 @@ better_path(Path *new_path, List *unique_paths, bool *is_new)
&better_sort) || &better_sort) ||
better_sort != 0) better_sort != 0)
{ {
printf("oldord\n");
pprint(path->pathorder);
printf("neword\n"); printf("neword\n");
pprint(new_path->pathorder); pprint(new_path->pathorder);
printf("oldord\n");
pprint(path->pathorder);
} }
#endif #endif
...@@ -204,8 +204,8 @@ better_path(Path *new_path, List *unique_paths, bool *is_new) ...@@ -204,8 +204,8 @@ better_path(Path *new_path, List *unique_paths, bool *is_new)
&better_sort)) &better_sort))
{ {
/* /*
* Replace pathkeys that match exactly, (1,2), (1,2). * 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 * more expensive and replace unordered path with ordered
* path if it is not more expensive. Favor sorted keys * path if it is not more expensive. Favor sorted keys
* over unsorted keys in the same way. * over unsorted keys in the same way.
...@@ -221,10 +221,10 @@ better_path(Path *new_path, List *unique_paths, bool *is_new) ...@@ -221,10 +221,10 @@ better_path(Path *new_path, List *unique_paths, bool *is_new)
{ {
#ifdef OPTDUP_DEBUG #ifdef OPTDUP_DEBUG
printf("replace with new %p old %p better key %d better sort %d\n", &new_path, &path, better_key, better_sort); printf("replace with new %p old %p better key %d better sort %d\n", &new_path, &path, better_key, better_sort);
printf("old\n");
pprint(path);
printf("new\n"); printf("new\n");
pprint(new_path); pprint(new_path);
printf("old\n");
pprint(path);
#endif #endif
*is_new = false; *is_new = false;
return path; return path;
...@@ -241,10 +241,10 @@ better_path(Path *new_path, List *unique_paths, bool *is_new) ...@@ -241,10 +241,10 @@ better_path(Path *new_path, List *unique_paths, bool *is_new)
{ {
#ifdef OPTDUP_DEBUG #ifdef OPTDUP_DEBUG
printf("skip new %p old %p better key %d better sort %d\n", &new_path, &path, better_key, better_sort); printf("skip new %p old %p better key %d better sort %d\n", &new_path, &path, better_key, better_sort);
printf("old\n");
pprint(path);
printf("new\n"); printf("new\n");
pprint(new_path); pprint(new_path);
printf("old\n");
pprint(path);
#endif #endif
*is_new = false; *is_new = false;
return NULL; return NULL;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment