Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitb62fdc1

Browse files
committed
Correct bug in best_innerjoin(): it should check all the
rels that the inner path needs to join to, but it was only checking forthe first one. Failure could only have been observed with an OR-clausethat mentions 3 or more tables, and then only if the bogus path wasactually selected as cheapest ...
1 parent2f30d5a commitb62fdc1

File tree

3 files changed

+64
-53
lines changed

3 files changed

+64
-53
lines changed

‎src/backend/optimizer/path/joinpath.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinpath.c,v 1.41 1999/07/16 04:59:15 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinpath.c,v 1.42 1999/07/27 06:23:12 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -147,13 +147,14 @@ update_rels_pathlist_for_joins(Query *root, List *joinrels)
147147
/*
148148
* best_innerjoin
149149
* Find the cheapest index path that has already been identified by
150-
*(indexable_joinclauses) as being a possible inner path for the given
151-
* outer relation in a nestloop join.
150+
* indexable_joinclauses() as being a possible inner path for the given
151+
* outer relation(s) in a nestloop join.
152152
*
153-
* 'join_paths' is a list of joinnodes
154-
* 'outer_relid' is the relid of the outer join relation
153+
* 'join_paths' is a list ofpotential inner indexscanjoinpaths
154+
* 'outer_relids' is the relid list of the outer join relation
155155
*
156-
* Returns the pathnode of the selected path.
156+
* Returns the pathnode of the best path, or NULL if there's no
157+
* usable path.
157158
*/
158159
staticPath*
159160
best_innerjoin(List*join_paths,Relidsouter_relids)
@@ -165,7 +166,11 @@ best_innerjoin(List *join_paths, Relids outer_relids)
165166
{
166167
Path*path= (Path*)lfirst(join_path);
167168

168-
if (intMember(lfirsti(path->joinid),outer_relids)&&
169+
/* path->joinid is the set of base rels that must be part of
170+
* outer_relids in order to use this inner path, because those
171+
* rels are used in the index join quals of this inner path.
172+
*/
173+
if (is_subset(path->joinid,outer_relids)&&
169174
(cheapest==NULL||
170175
path_is_cheaper(path,cheapest)))
171176
cheapest=path;

‎src/backend/optimizer/path/joinrels.c

Lines changed: 39 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinrels.c,v 1.37 1999/07/16 04:59:15 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/joinrels.c,v 1.38 1999/07/27 06:23:12 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -21,8 +21,6 @@
2121
#include"optimizer/tlist.h"
2222

2323
staticList*new_joininfo_list(List*joininfo_list,Relidsjoin_relids);
24-
staticboolnonoverlap_sets(List*s1,List*s2);
25-
staticboolis_subset(List*s1,List*s2);
2624
staticvoidset_joinrel_size(RelOptInfo*joinrel,RelOptInfo*outer_rel,
2725
RelOptInfo*inner_rel,JoinInfo*jinfo);
2826
staticRelOptInfo*make_join_rel(RelOptInfo*outer_rel,RelOptInfo*inner_rel,
@@ -373,8 +371,8 @@ new_joininfo_list(List *joininfo_list, Relids join_relids)
373371
RelOptInfo*
374372
get_cheapest_complete_rel(List*join_rel_list)
375373
{
376-
List*xrel=NIL;
377374
RelOptInfo*final_rel=NULL;
375+
List*xrel;
378376

379377
/*
380378
* find the relations that have no further joins, i.e., its joininfos
@@ -383,8 +381,8 @@ get_cheapest_complete_rel(List *join_rel_list)
383381
foreach(xrel,join_rel_list)
384382
{
385383
RelOptInfo*rel= (RelOptInfo*)lfirst(xrel);
386-
List*xjoininfo=NIL;
387384
boolfinal= true;
385+
List*xjoininfo;
388386

389387
foreach(xjoininfo,rel->joininfo)
390388
{
@@ -405,36 +403,6 @@ get_cheapest_complete_rel(List *join_rel_list)
405403
returnfinal_rel;
406404
}
407405

408-
staticbool
409-
nonoverlap_sets(List*s1,List*s2)
410-
{
411-
List*x=NIL;
412-
413-
foreach(x,s1)
414-
{
415-
inte=lfirsti(x);
416-
417-
if (intMember(e,s2))
418-
return false;
419-
}
420-
return true;
421-
}
422-
423-
staticbool
424-
is_subset(List*s1,List*s2)
425-
{
426-
List*x=NIL;
427-
428-
foreach(x,s1)
429-
{
430-
inte=lfirsti(x);
431-
432-
if (!intMember(e,s2))
433-
return false;
434-
}
435-
return true;
436-
}
437-
438406
staticvoid
439407
set_joinrel_size(RelOptInfo*joinrel,RelOptInfo*outer_rel,RelOptInfo*inner_rel,JoinInfo*jinfo)
440408
{
@@ -466,3 +434,39 @@ set_joinrel_size(RelOptInfo *joinrel, RelOptInfo *outer_rel, RelOptInfo *inner_r
466434

467435
joinrel->tuples=ntuples;
468436
}
437+
438+
/*
439+
* Subset-inclusion tests on integer lists.
440+
*
441+
* XXX these probably ought to be in nodes/list.c or some such place.
442+
*/
443+
444+
bool
445+
nonoverlap_sets(List*s1,List*s2)
446+
{
447+
List*x;
448+
449+
foreach(x,s1)
450+
{
451+
inte=lfirsti(x);
452+
453+
if (intMember(e,s2))
454+
return false;
455+
}
456+
return true;
457+
}
458+
459+
bool
460+
is_subset(List*s1,List*s2)
461+
{
462+
List*x;
463+
464+
foreach(x,s1)
465+
{
466+
inte=lfirsti(x);
467+
468+
if (!intMember(e,s2))
469+
return false;
470+
}
471+
return true;
472+
}

‎src/include/optimizer/paths.h

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
/*-------------------------------------------------------------------------
22
*
33
* paths.h
4-
* prototypes for various files in optimizer/paths (were separate
5-
* header files
4+
* prototypes for various files in optimizer/path (were separate
5+
* header files)
66
*
77
*
88
* Copyright (c) 1994, Regents of the University of California
99
*
10-
* $Id: paths.h,v 1.32 1999/07/2703:51:01 tgl Exp $
10+
* $Id: paths.h,v 1.33 1999/07/2706:23:11 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -17,12 +17,12 @@
1717
#include"nodes/relation.h"
1818

1919
/*
20-
* allpaths.h
20+
* allpaths.c
2121
*/
2222
externRelOptInfo*make_one_rel(Query*root,List*rels);
2323

2424
/*
25-
* indxpath.h
25+
* indxpath.c
2626
* routines to generate index paths
2727
*/
2828
externList*create_index_paths(Query*root,RelOptInfo*rel,List*indices,
@@ -31,26 +31,26 @@ extern List *create_index_paths(Query *root, RelOptInfo *rel, List *indices,
3131
externList*expand_indexqual_conditions(List*indexquals);
3232

3333
/*
34-
* joinpath.h
34+
* joinpath.c
3535
* routines to create join paths
3636
*/
3737
externvoidupdate_rels_pathlist_for_joins(Query*root,List*joinrels);
3838

3939

4040
/*
41-
* orindxpath.h
41+
* orindxpath.c
4242
*/
4343
externList*create_or_index_paths(Query*root,RelOptInfo*rel,List*clauses);
4444

4545
/*
46-
* hashutils.h
46+
* hashutils.c
4747
* routines to deal with hash keys and clauses
4848
*/
4949
externList*group_clauses_by_hashop(List*restrictinfo_list,
5050
Relidsinner_relids);
5151

5252
/*
53-
* joinutils.h
53+
* joinutils.c
5454
* generic join method key/clause routines
5555
*/
5656
externboolorder_joinkeys_by_pathkeys(List*pathkeys,
@@ -65,7 +65,7 @@ extern List *new_join_pathkeys(List *outer_pathkeys,
6565
List*join_rel_tlist,List*joinclauses);
6666

6767
/*
68-
* mergeutils.h
68+
* mergeutils.c
6969
* routines to deal with merge keys and clauses
7070
*/
7171
externList*group_clauses_by_order(List*restrictinfo_list,
@@ -74,7 +74,7 @@ extern MergeInfo *match_order_mergeinfo(PathOrder *ordering,
7474
List*mergeinfo_list);
7575

7676
/*
77-
* joinrels.h
77+
* joinrels.c
7878
* routines to determine which relations to join
7979
*/
8080
externList*make_rels_by_joins(Query*root,List*old_rels);
@@ -83,6 +83,8 @@ extern List *make_rels_by_clause_joins(Query *root, RelOptInfo *old_rel,
8383
externList*make_rels_by_clauseless_joins(RelOptInfo*old_rel,
8484
List*inner_rels);
8585
externRelOptInfo*get_cheapest_complete_rel(List*join_rel_list);
86+
externboolnonoverlap_sets(List*s1,List*s2);
87+
externboolis_subset(List*s1,List*s2);
8688

8789
/*
8890
* prototypes for path/prune.c

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp