|
|
@ -7,7 +7,7 @@ |
|
|
|
* |
|
|
|
* |
|
|
|
* |
|
|
|
* |
|
|
|
* IDENTIFICATION |
|
|
|
* IDENTIFICATION |
|
|
|
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinpath.c,v 1.11 1999/02/03 20:15:33 momjian Exp $ |
|
|
|
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinpath.c,v 1.12 1999/02/03 21:16:27 momjian Exp $ |
|
|
|
* |
|
|
|
* |
|
|
|
*------------------------------------------------------------------------- |
|
|
|
*------------------------------------------------------------------------- |
|
|
|
*/ |
|
|
|
*/ |
|
|
@ -96,15 +96,13 @@ find_all_join_paths(Query *root, List *joinrels) |
|
|
|
outerrel->relids); |
|
|
|
outerrel->relids); |
|
|
|
if (_enable_mergejoin_) |
|
|
|
if (_enable_mergejoin_) |
|
|
|
{ |
|
|
|
{ |
|
|
|
mergeinfo_list = |
|
|
|
mergeinfo_list = group_clauses_by_order(joinrel->restrictinfo, |
|
|
|
group_clauses_by_order(joinrel->restrictinfo, |
|
|
|
|
|
|
|
lfirsti(innerrel->relids)); |
|
|
|
lfirsti(innerrel->relids)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (_enable_hashjoin_) |
|
|
|
if (_enable_hashjoin_) |
|
|
|
{ |
|
|
|
{ |
|
|
|
hashinfo_list = |
|
|
|
hashinfo_list = group_clauses_by_hashop(joinrel->restrictinfo, |
|
|
|
group_clauses_by_hashop(joinrel->restrictinfo, |
|
|
|
|
|
|
|
lfirsti(innerrel->relids)); |
|
|
|
lfirsti(innerrel->relids)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -123,8 +121,7 @@ find_all_join_paths(Query *root, List *joinrels) |
|
|
|
* explicitly sorted. This may include either nestloops and |
|
|
|
* explicitly sorted. This may include either nestloops and |
|
|
|
* mergejoins where the outer path is already ordered. |
|
|
|
* mergejoins where the outer path is already ordered. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
pathlist = |
|
|
|
pathlist = add_pathlist(joinrel, pathlist, |
|
|
|
add_pathlist(joinrel, pathlist, |
|
|
|
|
|
|
|
match_unsorted_outer(joinrel, |
|
|
|
match_unsorted_outer(joinrel, |
|
|
|
outerrel, |
|
|
|
outerrel, |
|
|
|
innerrel, |
|
|
|
innerrel, |
|
|
@ -139,8 +136,7 @@ find_all_join_paths(Query *root, List *joinrels) |
|
|
|
* the actual nestloop nodes were constructed in |
|
|
|
* the actual nestloop nodes were constructed in |
|
|
|
* (match-unsorted-outer). |
|
|
|
* (match-unsorted-outer). |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
pathlist = |
|
|
|
pathlist = add_pathlist(joinrel, pathlist, |
|
|
|
add_pathlist(joinrel, pathlist, |
|
|
|
|
|
|
|
match_unsorted_inner(joinrel, outerrel, |
|
|
|
match_unsorted_inner(joinrel, outerrel, |
|
|
|
innerrel, |
|
|
|
innerrel, |
|
|
|
innerrel->pathlist, |
|
|
|
innerrel->pathlist, |
|
|
@ -151,8 +147,7 @@ find_all_join_paths(Query *root, List *joinrels) |
|
|
|
* hashed before being joined. |
|
|
|
* hashed before being joined. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
pathlist = |
|
|
|
pathlist = add_pathlist(joinrel, pathlist, |
|
|
|
add_pathlist(joinrel, pathlist, |
|
|
|
|
|
|
|
hash_inner_and_outer(joinrel, outerrel, |
|
|
|
hash_inner_and_outer(joinrel, outerrel, |
|
|
|
innerrel, hashinfo_list)); |
|
|
|
innerrel, hashinfo_list)); |
|
|
|
|
|
|
|
|
|
|
@ -251,22 +246,18 @@ sort_inner_and_outer(RelOptInfo * joinrel, |
|
|
|
{ |
|
|
|
{ |
|
|
|
xmergeinfo = (MInfo *) lfirst(i); |
|
|
|
xmergeinfo = (MInfo *) lfirst(i); |
|
|
|
|
|
|
|
|
|
|
|
outerkeys = |
|
|
|
outerkeys = extract_path_keys(xmergeinfo->jmethod.jmkeys, |
|
|
|
extract_path_keys(xmergeinfo->jmethod.jmkeys, |
|
|
|
|
|
|
|
outerrel->targetlist, |
|
|
|
outerrel->targetlist, |
|
|
|
OUTER); |
|
|
|
OUTER); |
|
|
|
|
|
|
|
|
|
|
|
innerkeys = |
|
|
|
innerkeys = extract_path_keys(xmergeinfo->jmethod.jmkeys, |
|
|
|
extract_path_keys(xmergeinfo->jmethod.jmkeys, |
|
|
|
|
|
|
|
innerrel->targetlist, |
|
|
|
innerrel->targetlist, |
|
|
|
INNER); |
|
|
|
INNER); |
|
|
|
|
|
|
|
|
|
|
|
merge_pathkeys = |
|
|
|
merge_pathkeys = new_join_pathkeys(outerkeys, joinrel->targetlist, |
|
|
|
new_join_pathkeys(outerkeys, joinrel->targetlist, |
|
|
|
|
|
|
|
xmergeinfo->jmethod.clauses); |
|
|
|
xmergeinfo->jmethod.clauses); |
|
|
|
|
|
|
|
|
|
|
|
temp_node = |
|
|
|
temp_node = create_mergejoin_path(joinrel, |
|
|
|
create_mergejoin_path(joinrel, |
|
|
|
|
|
|
|
outerrel->size, |
|
|
|
outerrel->size, |
|
|
|
innerrel->size, |
|
|
|
innerrel->size, |
|
|
|
outerrel->width, |
|
|
|
outerrel->width, |
|
|
@ -342,8 +333,7 @@ match_unsorted_outer(RelOptInfo * joinrel, |
|
|
|
|
|
|
|
|
|
|
|
if (outerpath_ordering) |
|
|
|
if (outerpath_ordering) |
|
|
|
{ |
|
|
|
{ |
|
|
|
xmergeinfo = |
|
|
|
xmergeinfo = match_order_mergeinfo(outerpath_ordering, |
|
|
|
match_order_mergeinfo(outerpath_ordering, |
|
|
|
|
|
|
|
mergeinfo_list); |
|
|
|
mergeinfo_list); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -355,14 +345,12 @@ match_unsorted_outer(RelOptInfo * joinrel, |
|
|
|
List *keys = xmergeinfo->jmethod.jmkeys; |
|
|
|
List *keys = xmergeinfo->jmethod.jmkeys; |
|
|
|
List *clauses = xmergeinfo->jmethod.clauses; |
|
|
|
List *clauses = xmergeinfo->jmethod.clauses; |
|
|
|
|
|
|
|
|
|
|
|
matchedJoinKeys = |
|
|
|
matchedJoinKeys = match_pathkeys_joinkeys(outerpath->keys, |
|
|
|
match_pathkeys_joinkeys(outerpath->keys, |
|
|
|
|
|
|
|
keys, |
|
|
|
keys, |
|
|
|
clauses, |
|
|
|
clauses, |
|
|
|
OUTER, |
|
|
|
OUTER, |
|
|
|
&matchedJoinClauses); |
|
|
|
&matchedJoinClauses); |
|
|
|
merge_pathkeys = |
|
|
|
merge_pathkeys = new_join_pathkeys(outerpath->keys, |
|
|
|
new_join_pathkeys(outerpath->keys, |
|
|
|
|
|
|
|
joinrel->targetlist, clauses); |
|
|
|
joinrel->targetlist, clauses); |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
else |
|
|
@ -385,14 +373,12 @@ match_unsorted_outer(RelOptInfo * joinrel, |
|
|
|
{ |
|
|
|
{ |
|
|
|
bool path_is_cheaper_than_sort; |
|
|
|
bool path_is_cheaper_than_sort; |
|
|
|
List *varkeys = NIL; |
|
|
|
List *varkeys = NIL; |
|
|
|
Path *mergeinnerpath = |
|
|
|
Path *mergeinnerpath = match_paths_joinkeys(matchedJoinKeys, |
|
|
|
match_paths_joinkeys(matchedJoinKeys, |
|
|
|
|
|
|
|
outerpath_ordering, |
|
|
|
outerpath_ordering, |
|
|
|
innerrel->pathlist, |
|
|
|
innerrel->pathlist, |
|
|
|
INNER); |
|
|
|
INNER); |
|
|
|
|
|
|
|
|
|
|
|
path_is_cheaper_than_sort = |
|
|
|
path_is_cheaper_than_sort = (bool) (mergeinnerpath && |
|
|
|
(bool) (mergeinnerpath && |
|
|
|
|
|
|
|
(mergeinnerpath->path_cost < |
|
|
|
(mergeinnerpath->path_cost < |
|
|
|
(cheapest_inner->path_cost + |
|
|
|
(cheapest_inner->path_cost + |
|
|
|
cost_sort(matchedJoinKeys, |
|
|
|
cost_sort(matchedJoinKeys, |
|
|
@ -401,8 +387,7 @@ match_unsorted_outer(RelOptInfo * joinrel, |
|
|
|
false)))); |
|
|
|
false)))); |
|
|
|
if (!path_is_cheaper_than_sort) |
|
|
|
if (!path_is_cheaper_than_sort) |
|
|
|
{ |
|
|
|
{ |
|
|
|
varkeys = |
|
|
|
varkeys = extract_path_keys(matchedJoinKeys, |
|
|
|
extract_path_keys(matchedJoinKeys, |
|
|
|
|
|
|
|
innerrel->targetlist, |
|
|
|
innerrel->targetlist, |
|
|
|
INNER); |
|
|
|
INNER); |
|
|
|
} |
|
|
|
} |
|
|
@ -419,8 +404,7 @@ match_unsorted_outer(RelOptInfo * joinrel, |
|
|
|
else |
|
|
|
else |
|
|
|
mergeinnerpath = cheapest_inner; |
|
|
|
mergeinnerpath = cheapest_inner; |
|
|
|
|
|
|
|
|
|
|
|
temp_node = |
|
|
|
temp_node = lcons(create_mergejoin_path(joinrel, |
|
|
|
lcons(create_mergejoin_path(joinrel, |
|
|
|
|
|
|
|
outerrel->size, |
|
|
|
outerrel->size, |
|
|
|
innerrel->size, |
|
|
|
innerrel->size, |
|
|
|
outerrel->width, |
|
|
|
outerrel->width, |
|
|
@ -492,8 +476,7 @@ match_unsorted_inner(RelOptInfo * joinrel, |
|
|
|
|
|
|
|
|
|
|
|
if (innerpath_ordering) |
|
|
|
if (innerpath_ordering) |
|
|
|
{ |
|
|
|
{ |
|
|
|
xmergeinfo = |
|
|
|
xmergeinfo = match_order_mergeinfo(innerpath_ordering, |
|
|
|
match_order_mergeinfo(innerpath_ordering, |
|
|
|
|
|
|
|
mergeinfo_list); |
|
|
|
mergeinfo_list); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -505,8 +488,7 @@ match_unsorted_inner(RelOptInfo * joinrel, |
|
|
|
List *keys = xmergeinfo->jmethod.jmkeys; |
|
|
|
List *keys = xmergeinfo->jmethod.jmkeys; |
|
|
|
List *cls = xmergeinfo->jmethod.clauses; |
|
|
|
List *cls = xmergeinfo->jmethod.clauses; |
|
|
|
|
|
|
|
|
|
|
|
matchedJoinKeys = |
|
|
|
matchedJoinKeys = match_pathkeys_joinkeys(innerpath->keys, |
|
|
|
match_pathkeys_joinkeys(innerpath->keys, |
|
|
|
|
|
|
|
keys, |
|
|
|
keys, |
|
|
|
cls, |
|
|
|
cls, |
|
|
|
INNER, |
|
|
|
INNER, |
|
|
@ -528,17 +510,14 @@ match_unsorted_inner(RelOptInfo * joinrel, |
|
|
|
|
|
|
|
|
|
|
|
if (temp2) |
|
|
|
if (temp2) |
|
|
|
{ |
|
|
|
{ |
|
|
|
List *outerkeys = |
|
|
|
List *outerkeys = extract_path_keys(matchedJoinKeys, |
|
|
|
extract_path_keys(matchedJoinKeys, |
|
|
|
|
|
|
|
outerrel->targetlist, |
|
|
|
outerrel->targetlist, |
|
|
|
OUTER); |
|
|
|
OUTER); |
|
|
|
List *merge_pathkeys = |
|
|
|
List *merge_pathkeys = new_join_pathkeys(outerkeys, |
|
|
|
new_join_pathkeys(outerkeys, |
|
|
|
|
|
|
|
joinrel->targetlist, |
|
|
|
joinrel->targetlist, |
|
|
|
clauses); |
|
|
|
clauses); |
|
|
|
|
|
|
|
|
|
|
|
temp_node = |
|
|
|
temp_node = lcons(create_mergejoin_path(joinrel, |
|
|
|
lcons(create_mergejoin_path(joinrel, |
|
|
|
|
|
|
|
outerrel->size, |
|
|
|
outerrel->size, |
|
|
|
innerrel->size, |
|
|
|
innerrel->size, |
|
|
|
outerrel->width, |
|
|
|
outerrel->width, |
|
|
@ -611,16 +590,13 @@ hash_inner_and_outer(RelOptInfo * joinrel, |
|
|
|
foreach(i, hashinfo_list) |
|
|
|
foreach(i, hashinfo_list) |
|
|
|
{ |
|
|
|
{ |
|
|
|
xhashinfo = (HInfo *) lfirst(i); |
|
|
|
xhashinfo = (HInfo *) lfirst(i); |
|
|
|
outerkeys = |
|
|
|
outerkeys = extract_path_keys(((JoinMethod *) xhashinfo)->jmkeys, |
|
|
|
extract_path_keys(((JoinMethod *) xhashinfo)->jmkeys, |
|
|
|
|
|
|
|
outerrel->targetlist, |
|
|
|
outerrel->targetlist, |
|
|
|
OUTER); |
|
|
|
OUTER); |
|
|
|
innerkeys = |
|
|
|
innerkeys = extract_path_keys(((JoinMethod *) xhashinfo)->jmkeys, |
|
|
|
extract_path_keys(((JoinMethod *) xhashinfo)->jmkeys, |
|
|
|
|
|
|
|
innerrel->targetlist, |
|
|
|
innerrel->targetlist, |
|
|
|
INNER); |
|
|
|
INNER); |
|
|
|
hash_pathkeys = |
|
|
|
hash_pathkeys = new_join_pathkeys(outerkeys, |
|
|
|
new_join_pathkeys(outerkeys, |
|
|
|
|
|
|
|
joinrel->targetlist, |
|
|
|
joinrel->targetlist, |
|
|
|
((JoinMethod *) xhashinfo)->clauses); |
|
|
|
((JoinMethod *) xhashinfo)->clauses); |
|
|
|
|
|
|
|
|
|
|
|