99 *
1010 *
1111 * IDENTIFICATION
12- * $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.143 2003/05/28 22:32:49 tgl Exp $
12+ * $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.144 2003/06/15 22:51:45 tgl Exp $
1313 *
1414 *-------------------------------------------------------------------------
1515 */
@@ -59,10 +59,10 @@ static bool match_or_subclause_to_indexkey(RelOptInfo *rel,
5959 IndexOptInfo * index ,
6060 Expr * clause );
6161static List * group_clauses_by_indexkey (RelOptInfo * rel , IndexOptInfo * index );
62- static List * group_clauses_by_indexkey_for_join (RelOptInfo * rel ,
63- IndexOptInfo * index ,
64- Relids outer_relids ,
65- bool isouterjoin );
62+ static List * group_clauses_by_indexkey_for_join (Query * root ,
63+ RelOptInfo * rel , IndexOptInfo * index ,
64+ Relids outer_relids ,
65+ JoinType jointype , bool isouterjoin );
6666static bool match_clause_to_indexcol (RelOptInfo * rel , IndexOptInfo * index ,
6767 int indexcol , Oid opclass , Expr * clause );
6868static bool match_join_clause_to_indexcol (RelOptInfo * rel , IndexOptInfo * index ,
@@ -583,8 +583,10 @@ group_clauses_by_indexkey(RelOptInfo *rel, IndexOptInfo *index)
583583 * will already have been generated for it.)
584584 */
585585static List *
586- group_clauses_by_indexkey_for_join (RelOptInfo * rel , IndexOptInfo * index ,
587- Relids outer_relids , bool isouterjoin )
586+ group_clauses_by_indexkey_for_join (Query * root ,
587+ RelOptInfo * rel , IndexOptInfo * index ,
588+ Relids outer_relids ,
589+ JoinType jointype , bool isouterjoin )
588590{
589591 FastList clausegroup_list ;
590592 bool jfound = false;
@@ -629,6 +631,24 @@ group_clauses_by_indexkey_for_join(RelOptInfo *rel, IndexOptInfo *index,
629631 }
630632 }
631633
634+ /*
635+ * If we found join clauses in more than one joininfo list, we may
636+ * now have clauses that are known redundant. Get rid of 'em.
637+ * (There is no point in looking at restriction clauses, because
638+ * remove_redundant_join_clauses will never think they are
639+ * redundant, so we do this before adding restriction clauses to
640+ * the clause group.)
641+ */
642+ if (FastListValue (& clausegroup ) != NIL )
643+ {
644+ List * nl ;
645+
646+ nl = remove_redundant_join_clauses (root ,
647+ FastListValue (& clausegroup ),
648+ jointype );
649+ FastListFromList (& clausegroup , nl );
650+ }
651+
632652 /* We can also use plain restriction clauses for the rel */
633653 foreach (i , rel -> baserestrictinfo )
634654 {
@@ -1461,9 +1481,11 @@ best_inner_indexscan(Query *root, RelOptInfo *rel,
14611481 List * clausegroups ;
14621482
14631483 /* find useful clauses for this index and outerjoin set */
1464- clausegroups = group_clauses_by_indexkey_for_join (rel ,
1484+ clausegroups = group_clauses_by_indexkey_for_join (root ,
1485+ rel ,
14651486 index ,
14661487 index_outer_relids ,
1488+ jointype ,
14671489 isouterjoin );
14681490 if (clausegroups )
14691491 {
@@ -1520,7 +1542,7 @@ make_innerjoin_index_path(Query *root,
15201542 * allclauses ,
15211543 * l ;
15221544
1523- /* XXX this code ought to be merged with create_index_path? */
1545+ /* XXX perhaps this code should be merged with create_index_path? */
15241546
15251547 pathnode -> path .pathtype = T_IndexScan ;
15261548 pathnode -> path .parent = rel ;
@@ -1535,12 +1557,25 @@ make_innerjoin_index_path(Query *root,
15351557 /* Convert RestrictInfo nodes to indexquals the executor can handle */
15361558 indexquals = expand_indexqual_conditions (index , clausegroups );
15371559
1560+ /*
1561+ * Also make a flattened list of the RestrictInfo nodes; createplan.c
1562+ * will need this later. We assume here that we can destructively
1563+ * modify the passed-in clausegroups list structure.
1564+ */
1565+ allclauses = NIL ;
1566+ foreach (l , clausegroups )
1567+ {
1568+ /* nconc okay here since same clause couldn't be in two sublists */
1569+ allclauses = nconc (allclauses , (List * ) lfirst (l ));
1570+ }
1571+
15381572 /*
15391573 * Note that we are making a pathnode for a single-scan indexscan;
1540- * therefore, both indexinfo and indexqual should be single-element lists.
1574+ * therefore, indexinfo and indexqual should be single-element lists.
15411575 */
15421576 pathnode -> indexinfo = makeList1 (index );
15431577 pathnode -> indexqual = makeList1 (indexquals );
1578+ pathnode -> indexjoinclauses = makeList1 (allclauses );
15441579
15451580 /* We don't actually care what order the index scans in ... */
15461581 pathnode -> indexscandir = NoMovementScanDirection ;
@@ -1558,17 +1593,9 @@ make_innerjoin_index_path(Query *root,
15581593 * linking them into different lists, it should be sufficient to use
15591594 * pointer comparison to remove duplicates.)
15601595 *
1561- * We assume we can destructively modify the input sublists.
1562- *
15631596 * Always assume the join type is JOIN_INNER; even if some of the
15641597 * join clauses come from other contexts, that's not our problem.
15651598 */
1566- allclauses = NIL ;
1567- foreach (l , clausegroups )
1568- {
1569- /* nconc okay here since same clause couldn't be in two sublists */
1570- allclauses = nconc (allclauses , (List * ) lfirst (l ));
1571- }
15721599 allclauses = set_ptrUnion (rel -> baserestrictinfo , allclauses );
15731600 pathnode -> rows = rel -> tuples *
15741601 restrictlist_selectivity (root ,
0 commit comments