*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/util/Attic/keys.c,v 1.14 1999/02/10 21:02:41 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/Attic/keys.c,v 1.15 1999/02/11 04:08:42 momjian Exp $
*
*-------------------------------------------------------------------------
*/
}
/*
- * samekeys--
+ * pathkeys_match--
* Returns t iff two sets of path keys are equivalent. They are
* equivalent if the first Var nodes match the second Var nodes.
*
*
*/
bool
-samekeys(List *keys1, List *keys2)
+pathkeys_match(List *keys1, List *keys2, int *longer_key)
{
List *key1,
*key2,
key1a != NIL && key2a != NIL;
key1a = lnext(key1a), key2a = lnext(key2a))
if (!equal(lfirst(key1a), lfirst(key2a)))
+ {
+ *longer_key = 0;
return false;
- if (key1a != NIL)
- return false;
+ }
+ if (key1a != NIL && key2a == NIL)
+ {
+ *longer_key = 1;
+ return true;
+ }
+ if (key1a == NIL && key2a != NIL)
+ {
+ *longer_key = 2;
+ return true;
+ }
}
/* Now the result should be true if list keys2 has at least as many
* 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)
+ if (key1 != NIL && key2 == NIL)
+ {
+ *longer_key = 1;
return true;
- else
- return false;
+ }
+ if (key1 == NIL && key2 != NIL)
+ {
+ *longer_key = 2;
+ return true;
+ }
+ *longer_key = 0;
+ return true;
}
/*
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/util/pathnode.c,v 1.23 1999/02/10 21:02:43 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/util/pathnode.c,v 1.24 1999/02/11 04:08:43 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#include "parser/parsetree.h" /* for getrelid() */
-static Path *better_path(Path *new_path, List *unique_paths, bool *noOther);
+static Path *better_path(Path *new_path, List *unique_paths, bool *isNew);
/*****************************************************************************
{
Path *new_path = (Path *) lfirst(p1);
Path *old_path;
- bool noOther;
+ bool is_new;
/* Is this new path already in unique_paths? */
if (member(new_path, unique_paths))
continue;
/* Find best matching path */
- old_path = better_path(new_path, unique_paths, &noOther);
+ old_path = better_path(new_path, unique_paths, &is_new);
- if (noOther)
+ if (is_new)
{
/* This is a brand new path. */
new_path->parent = parent_rel;
*
*/
static Path *
-better_path(Path *new_path, List *unique_paths, bool *noOther)
+better_path(Path *new_path, List *unique_paths, bool *is_new)
{
- Path *old_path = (Path *) NULL;
Path *path = (Path *) NULL;
List *temp = NIL;
- Path *retval = NULL;
+ int longer_key;
foreach(temp, unique_paths)
{
path = (Path *) lfirst(temp);
#ifdef OPTDUP_DEBUG
- if (!samekeys(path->pathkeys, new_path->pathkeys))
+ if (!pathkeys_match(new_path->pathkeys, path->pathkeys, &longer_key) ||
+ longer_key != 0)
{
printf("oldpath\n");
pprint(path->pathkeys);
length(lfirst(path->pathkeys)) < length(lfirst(new_path->pathkeys)))
sleep(0); /* set breakpoint here */
}
- if (!equal_path_ordering(path->path_order,
- new_path->path_order))
+ if (!equal_path_ordering(new_path->path_order, path->path_order))
{
printf("oldord\n");
pprint(path->path_order);
pprint(new_path->path_order);
}
#endif
-
- if (samekeys(path->pathkeys, new_path->pathkeys) &&
- equal_path_ordering(path->path_order,
- new_path->path_order))
+
+ if (pathkeys_match(new_path->pathkeys, path->pathkeys, &longer_key))
{
- old_path = path;
- break;
+ if (equal_path_ordering(new_path->path_order, path->path_order))
+ {
+ /*
+ * Replace pathkeys that match exactly, (1,2), (1,2).
+ * 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.
+ */
+ if ((longer_key == 0 && new_path->path_cost < path->path_cost) ||
+ (longer_key == 1 && new_path->path_cost <= path->path_cost) ||
+ (longer_key == 2 && new_path->path_cost >= path->path_cost))
+ {
+ *is_new = false;
+ return new_path;
+ }
+ else
+ {
+ *is_new = false;
+ return NULL;
+ }
+ }
}
}
- if (old_path == NULL)
- *noOther = true;
- else
- {
- *noOther = false;
- if (path_is_cheaper(new_path, old_path))
- retval = old_path;
- }
-
- return retval;
+ *is_new = true;
+ return NULL;
}
*
* Copyright (c) 1994, Regents of the University of California
*
- * $Id: keys.h,v 1.9 1999/02/10 21:02:48 momjian Exp $
+ * $Id: keys.h,v 1.10 1999/02/11 04:08:44 momjian Exp $
*
*-------------------------------------------------------------------------
*/
extern bool match_indexkey_operand(int indexkey, Var *operand, RelOptInfo *rel);
extern Var *extract_join_subkey(JoinKey *jk, int which_subkey);
-extern bool samekeys(List *keys1, List *keys2);
+extern bool pathkeys_match(List *keys1, List *keys2, int *longer_key);
extern List *collect_index_pathkeys(int *index_keys, List *tlist);
#endif /* KEYS_H */