optimizer cleanup
This commit is contained in:
parent
61f40ac3f2
commit
8ab72a38df
@ -5,12 +5,14 @@ The optimizer generates optimial query plans by doing several steps:
|
||||
|
||||
1) Take each relation in a query, and make a RelOptInfo structure for
|
||||
it. Find each way of accessing the relation, called a Path, including
|
||||
sequential and index scans, and add it to RelOptInfo.pathlist.
|
||||
sequential and index scans, and add it to RelOptInfo.pathlist. Also
|
||||
create RelOptInfo.joininfo that lists all the joins that involve this
|
||||
relation.
|
||||
|
||||
2) Join each RelOptInfo to each other RelOptInfo as specified in the
|
||||
WHERE clause. At this point each RelOptInfo is a single relation, so
|
||||
you are joining every relation to every relation as joined in the WHERE
|
||||
clause.
|
||||
2) Join each RelOptInfo to other RelOptInfo as specified in
|
||||
RelOptInfo.joininfo. At this point each RelOptInfo is a single
|
||||
relation, so you are joining every relation to the other relations as
|
||||
joined in the WHERE clause.
|
||||
|
||||
Joins occur using two RelOptInfos. One is outer, the other inner.
|
||||
Outers drive lookups of values in the inner. In a nested loop, lookups
|
||||
@ -137,8 +139,8 @@ Optimizer Structures
|
||||
|
||||
RelOptInfo - a relation or joined relations
|
||||
|
||||
RestrictInfo - restriction clauses
|
||||
JoinInfo - join clauses
|
||||
RestrictInfo - restriction clauses, like "x = 3"
|
||||
JoinInfo - join clauses, including the relids needed for the join
|
||||
|
||||
Path - every way to generate a RelOptInfo(sequential,index,joins)
|
||||
IndexPath - index scans
|
||||
|
@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/Attic/pathkey.c,v 1.1 1999/02/18 19:58:52 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/Attic/pathkey.c,v 1.2 1999/02/19 02:05:15 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -27,9 +27,9 @@
|
||||
|
||||
|
||||
static int match_pathkey_joinkeys(List *pathkey, List *joinkeys,
|
||||
int which_subkey);
|
||||
int outer_or_inner);
|
||||
static bool every_func(List *joinkeys, List *pathkey,
|
||||
int which_subkey);
|
||||
int outer_or_inner);
|
||||
static List *new_join_pathkey(List *subkeys, List *considered_subkeys,
|
||||
List *join_rel_tlist, List *joinclauses);
|
||||
static List *new_matching_subkeys(Var *subkey, List *considered_subkeys,
|
||||
@ -54,7 +54,7 @@ static List *new_matching_subkeys(Var *subkey, List *considered_subkeys,
|
||||
* ( (outer inner) (outer inner) ... )
|
||||
* 'joinclauses' is a list of clauses corresponding to the join keys in
|
||||
* 'joinkeys'
|
||||
* 'which_subkey' is a flag that selects the desired subkey of a join key
|
||||
* 'outer_or_inner' is a flag that selects the desired subkey of a join key
|
||||
* in 'joinkeys'
|
||||
*
|
||||
* Returns the join keys and corresponding join clauses in a list if all
|
||||
@ -72,7 +72,7 @@ List *
|
||||
match_pathkeys_joinkeys(List *pathkeys,
|
||||
List *joinkeys,
|
||||
List *joinclauses,
|
||||
int which_subkey,
|
||||
int outer_or_inner,
|
||||
List **matchedJoinClausesPtr)
|
||||
{
|
||||
List *matched_joinkeys = NIL;
|
||||
@ -84,19 +84,17 @@ match_pathkeys_joinkeys(List *pathkeys,
|
||||
foreach(i, pathkeys)
|
||||
{
|
||||
pathkey = lfirst(i);
|
||||
matched_joinkey_index = match_pathkey_joinkeys(pathkey, joinkeys, which_subkey);
|
||||
matched_joinkey_index = match_pathkey_joinkeys(pathkey, joinkeys,
|
||||
outer_or_inner);
|
||||
|
||||
if (matched_joinkey_index != -1)
|
||||
{
|
||||
List *xjoinkey = nth(matched_joinkey_index, joinkeys);
|
||||
List *joinclause = nth(matched_joinkey_index, joinclauses);
|
||||
|
||||
/* XXX was "push" function */
|
||||
matched_joinkeys = lappend(matched_joinkeys, xjoinkey);
|
||||
matched_joinkeys = nreverse(matched_joinkeys);
|
||||
matched_joinkeys = lcons(xjoinkey, matched_joinkeys);
|
||||
matched_joinclauses = lcons(joinclause, matched_joinclauses);
|
||||
|
||||
matched_joinclauses = lappend(matched_joinclauses, joinclause);
|
||||
matched_joinclauses = nreverse(matched_joinclauses);
|
||||
joinkeys = LispRemove(xjoinkey, joinkeys);
|
||||
}
|
||||
else
|
||||
@ -111,6 +109,7 @@ match_pathkeys_joinkeys(List *pathkeys,
|
||||
return nreverse(matched_joinkeys);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* match_pathkey_joinkeys
|
||||
* Returns the 0-based index into 'joinkeys' of the first joinkey whose
|
||||
@ -119,7 +118,7 @@ match_pathkeys_joinkeys(List *pathkeys,
|
||||
static int
|
||||
match_pathkey_joinkeys(List *pathkey,
|
||||
List *joinkeys,
|
||||
int which_subkey)
|
||||
int outer_or_inner)
|
||||
{
|
||||
Var *path_subkey;
|
||||
int pos;
|
||||
@ -135,7 +134,7 @@ match_pathkey_joinkeys(List *pathkey,
|
||||
{
|
||||
jk = (JoinKey *) lfirst(x);
|
||||
if (var_equal(path_subkey,
|
||||
extract_join_subkey(jk, which_subkey)))
|
||||
extract_join_key(jk, outer_or_inner)))
|
||||
return pos;
|
||||
pos++;
|
||||
}
|
||||
@ -143,6 +142,7 @@ match_pathkey_joinkeys(List *pathkey,
|
||||
return -1; /* no index found */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* match_paths_joinkeys
|
||||
* Attempts to find a path in 'paths' whose keys match a set of join
|
||||
@ -159,53 +159,16 @@ match_pathkey_joinkeys(List *pathkey,
|
||||
* must correspond
|
||||
* 'paths' is a list of(inner) paths which are to be matched against
|
||||
* each join key in 'joinkeys'
|
||||
* 'which_subkey' is a flag that selects the desired subkey of a join key
|
||||
* 'outer_or_inner' is a flag that selects the desired subkey of a join key
|
||||
* in 'joinkeys'
|
||||
*
|
||||
* Returns the matching path node if one exists, nil otherwise.
|
||||
*/
|
||||
static bool
|
||||
every_func(List *joinkeys, List *pathkey, int which_subkey)
|
||||
{
|
||||
JoinKey *xjoinkey;
|
||||
Var *temp;
|
||||
Var *tempkey = NULL;
|
||||
bool found = false;
|
||||
List *i = NIL;
|
||||
List *j = NIL;
|
||||
|
||||
foreach(i, joinkeys)
|
||||
{
|
||||
xjoinkey = (JoinKey *) lfirst(i);
|
||||
found = false;
|
||||
foreach(j, pathkey)
|
||||
{
|
||||
temp = (Var *) lfirst((List *) lfirst(j));
|
||||
if (temp == NULL)
|
||||
continue;
|
||||
tempkey = extract_join_subkey(xjoinkey, which_subkey);
|
||||
if (var_equal(tempkey, temp))
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found == false)
|
||||
return false;
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* match_paths_joinkeys -
|
||||
* find the cheapest path that matches the join keys
|
||||
* Find the cheapest path that matches the join keys
|
||||
*/
|
||||
Path *
|
||||
match_paths_joinkeys(List *joinkeys,
|
||||
PathOrder *ordering,
|
||||
List *paths,
|
||||
int which_subkey)
|
||||
int outer_or_inner)
|
||||
{
|
||||
Path *matched_path = NULL;
|
||||
bool key_match = false;
|
||||
@ -216,13 +179,12 @@ match_paths_joinkeys(List *joinkeys,
|
||||
Path *path = (Path *) lfirst(i);
|
||||
int better_sort;
|
||||
|
||||
key_match = every_func(joinkeys, path->pathkeys, which_subkey);
|
||||
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 (matched_path)
|
||||
{
|
||||
if (path->path_cost < matched_path->path_cost)
|
||||
@ -236,7 +198,6 @@ match_paths_joinkeys(List *joinkeys,
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* extract_path_keys
|
||||
* Builds a subkey list for a path by pulling one of the subkeys from
|
||||
@ -245,7 +206,7 @@ match_paths_joinkeys(List *joinkeys,
|
||||
*
|
||||
* 'joinkeys' is a list of join key pairs
|
||||
* 'tlist' is a relation target list
|
||||
* 'which_subkey' is a flag that selects the desired subkey of a join key
|
||||
* 'outer_or_inner' is a flag that selects the desired subkey of a join key
|
||||
* in 'joinkeys'
|
||||
*
|
||||
* Returns a list of pathkeys: ((tlvar1)(tlvar2)...(tlvarN)).
|
||||
@ -254,7 +215,7 @@ match_paths_joinkeys(List *joinkeys,
|
||||
List *
|
||||
extract_path_keys(List *joinkeys,
|
||||
List *tlist,
|
||||
int which_subkey)
|
||||
int outer_or_inner)
|
||||
{
|
||||
List *pathkeys = NIL;
|
||||
List *jk;
|
||||
@ -269,7 +230,7 @@ extract_path_keys(List *joinkeys,
|
||||
/*
|
||||
* find the right Var in the target list for this key
|
||||
*/
|
||||
var = (Var *) extract_join_subkey(jkey, which_subkey);
|
||||
var = (Var *) extract_join_key(jkey, outer_or_inner);
|
||||
key = (Var *) matching_tlist_var(var, tlist);
|
||||
|
||||
/*
|
||||
@ -291,6 +252,42 @@ extract_path_keys(List *joinkeys,
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* every_func
|
||||
*/
|
||||
static bool
|
||||
every_func(List *joinkeys, List *pathkey, int outer_or_inner)
|
||||
{
|
||||
JoinKey *xjoinkey;
|
||||
Var *temp;
|
||||
Var *tempkey = NULL;
|
||||
bool found = false;
|
||||
List *i = NIL;
|
||||
List *j = NIL;
|
||||
|
||||
foreach(i, joinkeys)
|
||||
{
|
||||
xjoinkey = (JoinKey *) lfirst(i);
|
||||
found = false;
|
||||
foreach(j, pathkey)
|
||||
{
|
||||
temp = (Var *) lfirst((List *) lfirst(j));
|
||||
if (temp == NULL)
|
||||
continue;
|
||||
tempkey = extract_join_key(xjoinkey, outer_or_inner);
|
||||
if (var_equal(tempkey, temp))
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found == false)
|
||||
return false;
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* NEW PATHKEY FORMATION
|
||||
****************************************************************************/
|
||||
|
@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/Attic/keys.c,v 1.17 1999/02/13 23:16:45 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/Attic/keys.c,v 1.18 1999/02/19 02:05:16 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -80,17 +80,17 @@ equal_indexkey_var(int index_key, Var *var)
|
||||
}
|
||||
|
||||
/*
|
||||
* extract_join_subkey
|
||||
* extract_join_key
|
||||
* Returns the subkey in a join key corresponding to the outer or inner
|
||||
* relation.
|
||||
*
|
||||
*/
|
||||
Var *
|
||||
extract_join_subkey(JoinKey *jk, int which_subkey)
|
||||
extract_join_key(JoinKey *jk, int outer_or_inner)
|
||||
{
|
||||
Var *retval;
|
||||
|
||||
switch (which_subkey)
|
||||
switch (outer_or_inner)
|
||||
{
|
||||
case OUTER:
|
||||
retval = jk->outer;
|
||||
@ -99,7 +99,7 @@ extract_join_subkey(JoinKey *jk, int which_subkey)
|
||||
retval = jk->inner;
|
||||
break;
|
||||
default: /* do nothing */
|
||||
elog(DEBUG, "extract_join_subkey with neither INNER or OUTER");
|
||||
elog(DEBUG, "extract_join_key with neither INNER or OUTER");
|
||||
retval = NULL;
|
||||
}
|
||||
return retval;
|
||||
|
@ -6,7 +6,7 @@
|
||||
*
|
||||
* Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: keys.h,v 1.12 1999/02/13 23:21:49 momjian Exp $
|
||||
* $Id: keys.h,v 1.13 1999/02/19 02:05:18 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -17,7 +17,7 @@
|
||||
#include "nodes/relation.h"
|
||||
|
||||
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_key(JoinKey *jk, int outer_or_inner);
|
||||
extern bool pathkeys_match(List *keys1, List *keys2, int *better_key);
|
||||
extern List *collect_index_pathkeys(int *index_keys, List *tlist);
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
*
|
||||
* Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $Id: paths.h,v 1.22 1999/02/18 04:45:36 momjian Exp $
|
||||
* $Id: paths.h,v 1.23 1999/02/19 02:05:20 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -55,12 +55,12 @@ extern List *group_clauses_by_hashop(List *restrictinfo_list,
|
||||
* generic join method key/clause routines
|
||||
*/
|
||||
extern List *match_pathkeys_joinkeys(List *pathkeys,
|
||||
List *joinkeys, List *joinclauses, int which_subkey,
|
||||
List *joinkeys, List *joinclauses, int outer_or_inner,
|
||||
List **matchedJoinClausesPtr);
|
||||
extern List *extract_path_keys(List *joinkeys, List *tlist,
|
||||
int which_subkey);
|
||||
int outer_or_inner);
|
||||
extern Path *match_paths_joinkeys(List *joinkeys, PathOrder *ordering,
|
||||
List *paths, int which_subkey);
|
||||
List *paths, int outer_or_inner);
|
||||
extern List *new_join_pathkeys(List *outer_pathkeys,
|
||||
List *join_rel_tlist, List *joinclauses);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user