Optimizer fix for samekeys() and cost fixes for longer optimizer keys.

This commit is contained in:
Bruce Momjian 1999-02-11 04:08:44 +00:00
parent 403b3eff79
commit dbd80c97f4
3 changed files with 64 additions and 37 deletions

View file

@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * 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 $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -106,7 +106,7 @@ extract_join_subkey(JoinKey *jk, int which_subkey)
} }
/* /*
* samekeys-- * pathkeys_match--
* 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.
* *
@ -118,7 +118,7 @@ extract_join_subkey(JoinKey *jk, int which_subkey)
* *
*/ */
bool bool
samekeys(List *keys1, List *keys2) pathkeys_match(List *keys1, List *keys2, int *longer_key)
{ {
List *key1, List *key1,
*key2, *key2,
@ -133,9 +133,20 @@ samekeys(List *keys1, List *keys2)
key1a != NIL && key2a != NIL; key1a != NIL && key2a != NIL;
key1a = lnext(key1a), key2a = lnext(key2a)) key1a = lnext(key1a), key2a = lnext(key2a))
if (!equal(lfirst(key1a), lfirst(key2a))) if (!equal(lfirst(key1a), lfirst(key2a)))
{
*longer_key = 0;
return false; 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 /* Now the result should be true if list keys2 has at least as many
@ -143,10 +154,18 @@ samekeys(List *keys1, List *keys2)
* If key1 is now NIL then we hit the end of keys1 before or at the * If key1 is now NIL then we hit the end of keys1 before or at the
* same time as the end of keys2. * same time as the end of keys2.
*/ */
if (key1 == NIL) if (key1 != NIL && key2 == NIL)
{
*longer_key = 1;
return true; return true;
else }
return false; if (key1 == NIL && key2 != NIL)
{
*longer_key = 2;
return true;
}
*longer_key = 0;
return true;
} }
/* /*

View file

@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * 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 $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -29,7 +29,7 @@
#include "parser/parsetree.h" /* for getrelid() */ #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);
/***************************************************************************** /*****************************************************************************
@ -107,16 +107,16 @@ add_pathlist(RelOptInfo *parent_rel, List *unique_paths, List *new_paths)
{ {
Path *new_path = (Path *) lfirst(p1); Path *new_path = (Path *) lfirst(p1);
Path *old_path; Path *old_path;
bool noOther; bool is_new;
/* Is this new path already in unique_paths? */ /* Is this new path already in unique_paths? */
if (member(new_path, unique_paths)) if (member(new_path, unique_paths))
continue; continue;
/* Find best matching path */ /* 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. */ /* This is a brand new path. */
new_path->parent = parent_rel; new_path->parent = parent_rel;
@ -153,19 +153,19 @@ add_pathlist(RelOptInfo *parent_rel, List *unique_paths, List *new_paths)
* *
*/ */
static Path * 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; Path *path = (Path *) NULL;
List *temp = NIL; List *temp = NIL;
Path *retval = NULL; int longer_key;
foreach(temp, unique_paths) foreach(temp, unique_paths)
{ {
path = (Path *) lfirst(temp); path = (Path *) lfirst(temp);
#ifdef OPTDUP_DEBUG #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"); printf("oldpath\n");
pprint(path->pathkeys); pprint(path->pathkeys);
@ -176,8 +176,7 @@ better_path(Path *new_path, List *unique_paths, bool *noOther)
length(lfirst(path->pathkeys)) < length(lfirst(new_path->pathkeys))) length(lfirst(path->pathkeys)) < length(lfirst(new_path->pathkeys)))
sleep(0); /* set breakpoint here */ sleep(0); /* set breakpoint here */
} }
if (!equal_path_ordering(path->path_order, if (!equal_path_ordering(new_path->path_order, path->path_order))
new_path->path_order))
{ {
printf("oldord\n"); printf("oldord\n");
pprint(path->path_order); pprint(path->path_order);
@ -185,26 +184,35 @@ better_path(Path *new_path, List *unique_paths, bool *noOther)
pprint(new_path->path_order); pprint(new_path->path_order);
} }
#endif #endif
if (samekeys(path->pathkeys, new_path->pathkeys) && if (pathkeys_match(new_path->pathkeys, path->pathkeys, &longer_key))
equal_path_ordering(path->path_order,
new_path->path_order))
{ {
old_path = path; if (equal_path_ordering(new_path->path_order, path->path_order))
break; {
/*
* 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) *is_new = true;
*noOther = true; return NULL;
else
{
*noOther = false;
if (path_is_cheaper(new_path, old_path))
retval = old_path;
}
return retval;
} }

View file

@ -6,7 +6,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * 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 $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -18,7 +18,7 @@
extern bool match_indexkey_operand(int indexkey, Var *operand, RelOptInfo *rel); extern bool match_indexkey_operand(int indexkey, Var *operand, RelOptInfo *rel);
extern Var *extract_join_subkey(JoinKey *jk, int which_subkey); 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); extern List *collect_index_pathkeys(int *index_keys, List *tlist);
#endif /* KEYS_H */ #endif /* KEYS_H */