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

Commit4a1c5cb

Browse files
committed
Revise create_nestloop_node's handling of inner indexscan to
work under a wider range of scenarios than it did --- it formerly did nothandle a multi-pass inner scan, nor cases in which the inner scan'sindxqualorig or non-index qual contained outer var references. I am notsure that these limitations could be hit in the existing optimizer, butthey need to be fixed for future expansion.
1 parent158fd5f commit4a1c5cb

File tree

1 file changed

+57
-53
lines changed

1 file changed

+57
-53
lines changed

‎src/backend/optimizer/plan/createplan.c

Lines changed: 57 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.68 1999/08/09 06:20:26 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.69 1999/08/10 02:58:56 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -426,55 +426,55 @@ create_nestloop_node(NestPath *best_path,
426426
Plan*inner_node,
427427
List*inner_tlist)
428428
{
429-
NestLoop*join_node= (NestLoop*)NULL;
429+
NestLoop*join_node;
430430

431431
if (IsA(inner_node,IndexScan))
432432
{
433-
434433
/*
435434
* An index is being used to reduce the number of tuples scanned
436-
* in the inner relation.There will never be more than one index
437-
*used intheinner scan path, soweneed only consider the first
438-
*set of qualifications in indxqual.
435+
* in the inner relation. If there are join clauses being used
436+
*withtheindex,wemust update their outer-rel var nodes to
437+
*refer to the outer relation.
439438
*
440-
* But there may be more than one clause in this "first set" in the
441-
* case of multi-column indices. - vadim 03/18/97
442-
*/
443-
444-
List*inner_indxqual=lfirst(((IndexScan*)inner_node)->indxqual);
445-
List*inner_qual;
446-
boolfound= false;
447-
448-
foreach(inner_qual,inner_indxqual)
449-
{
450-
if (!qual_clause_p((Node*)lfirst(inner_qual)))
451-
{
452-
found= true;
453-
break;
454-
}
455-
}
456-
457-
/*
458-
* If we have in fact found a join index qualification, remove
459-
* these index clauses from the nestloop's join clauses and reset
460-
* the inner(index) scan's qualification so that the var nodes
461-
* refer to the proper outer join relation attributes.
439+
* We can also remove those join clauses from the list of clauses
440+
* that have to be checked as qpquals at the join node, but only
441+
* if there's just one indexscan in the inner path (otherwise,
442+
* several different sets of clauses are being ORed together).
443+
*
444+
* Note: if the index is lossy, the same clauses may also be getting
445+
* checked as qpquals in the indexscan. We can still remove them
446+
* from the nestloop's qpquals, but we gotta update the outer-rel
447+
* vars in the indexscan's qpquals too...
462448
*
463-
* XXXRemoving index clausesdoesn't work properly: 1.
464-
*fix_indxqual_references may change varattno-s in
465-
*inner_indxqual; 2. clauses may be commuted Ihavn't timetofix
466-
*it at the moment. - vadim 04/24/97
449+
* XXXas of 8/99, removal of redundant joinclausesdoesn't work
450+
*all the time, since it will fail to recognize clauses that have
451+
*been commuted in the indexqual. Ihopetomake this problem go
452+
*away soon by not commuting indexqual clauses --- tgl.
467453
*/
468-
if (found)
454+
IndexScan*innerscan= (IndexScan*)inner_node;
455+
List*indxqualorig=innerscan->indxqualorig;
456+
457+
/* No work needed if indxqual refers only to its own relation... */
458+
if (NumRelids((Node*)indxqualorig)>1)
469459
{
470-
List*new_inner_qual;
460+
/* Remove redundant tests from my clauses, if possible.
461+
* Note we must compare against indxqualorig not the "fixed"
462+
* indxqual (which has index attnos instead of relation attnos).
463+
*/
464+
if (length(indxqualorig)==1)/* single indexscan? */
465+
clauses=set_difference(clauses,lfirst(indxqualorig));
471466

472-
clauses=set_difference(clauses,inner_indxqual);/* XXX */
473467
/* only refs to outer vars get changed in the inner indexqual */
474-
new_inner_qual=join_references(inner_indxqual,
475-
outer_tlist,
476-
NIL);
477-
((IndexScan*)inner_node)->indxqual=lcons(new_inner_qual,NIL);
468+
innerscan->indxqualorig=join_references(indxqualorig,
469+
outer_tlist,
470+
NIL);
471+
innerscan->indxqual=join_references(innerscan->indxqual,
472+
outer_tlist,
473+
NIL);
474+
if (NumRelids((Node*)inner_node->qual)>1)
475+
inner_node->qual=join_references(inner_node->qual,
476+
outer_tlist,
477+
NIL);
478478
}
479479
}
480480
elseif (IsA_Join(inner_node))
@@ -512,10 +512,10 @@ create_mergejoin_node(MergePath *best_path,
512512
*mergeclauses;
513513
MergeJoin*join_node;
514514

515-
516515
/*
517-
* Separate the mergeclauses from the other join qualification clauses
518-
* and set those clauses to contain references to lower attributes.
516+
* Remove the mergeclauses from the list of join qual clauses,
517+
* leaving the list of quals that must be checked as qpquals.
518+
* Set those clauses to contain INNER/OUTER var references.
519519
*/
520520
qpqual=join_references(set_difference(clauses,
521521
best_path->path_mergeclauses),
@@ -571,14 +571,6 @@ create_mergejoin_node(MergePath *best_path,
571571
returnjoin_node;
572572
}
573573

574-
/*
575-
* create_hashjoin_node--XXX HASH
576-
*
577-
* Returns a new hashjoin node.
578-
*
579-
* XXX hash join ops are totally bogus -- how the hell do we choose
580-
*these?? at runtime? what about a hash index?
581-
*/
582574
staticHashJoin*
583575
create_hashjoin_node(HashPath*best_path,
584576
List*tlist,
@@ -595,8 +587,16 @@ create_hashjoin_node(HashPath *best_path,
595587
Var*innerhashkey;
596588

597589
/*
598-
* Separate the hashclauses from the other join qualification clauses
599-
* and set those clauses to contain references to lower attributes.
590+
* NOTE: there will always be exactly one hashclause in the list
591+
* best_path->path_hashclauses (cf. hash_inner_and_outer()).
592+
* We represent it as a list anyway for convenience with routines
593+
* that want to work on lists of clauses.
594+
*/
595+
596+
/*
597+
* Remove the hashclauses from the list of join qual clauses,
598+
* leaving the list of quals that must be checked as qpquals.
599+
* Set those clauses to contain INNER/OUTER var references.
600600
*/
601601
qpqual=join_references(set_difference(clauses,
602602
best_path->path_hashclauses),
@@ -611,8 +611,12 @@ create_hashjoin_node(HashPath *best_path,
611611
outer_tlist,
612612
inner_tlist));
613613

614+
/* Now the righthand op of the sole hashclause is the inner hash key. */
614615
innerhashkey=get_rightop(lfirst(hashclauses));
615616

617+
/*
618+
* Build the hash node and hash join node.
619+
*/
616620
hash_node=make_hash(inner_tlist,innerhashkey,inner_node);
617621
join_node=make_hashjoin(tlist,
618622
qpqual,
@@ -791,7 +795,7 @@ switch_outer(List *clauses)
791795
Assert(is_opclause((Node*)clause));
792796
op= (Node*)get_rightop(clause);
793797
Assert(op!= (Node*)NULL);
794-
if (IsA(op,ArrayRef))
798+
if (IsA(op,ArrayRef))/* I think this test is dead code ... tgl */
795799
op= ((ArrayRef*)op)->refexpr;
796800
Assert(IsA(op,Var));
797801
if (var_is_outer((Var*)op))

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp