summaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2006-04-08 21:32:25 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2006-04-08 21:32:25 +0000
commit89d75c56db27d1ee351ee806ff6fd0610e9b530f (patch)
tree2cef304066d8c92b0fc418ddb5319bd8eaa273b5 /src/backend
parentcd360f2484e64c85eec9a866a33f58cf58fbb10b (diff)
downloadpostgresql-89d75c56db27d1ee351ee806ff6fd0610e9b530f.tar.gz
Fix best_inner_indexscan to actually enforce that an "inner indexscan" use
at least one join condition as an indexqual. Before bitmap indexscans, this oversight didn't really cost much except for redundantly considering the same join paths twice; but as of 8.1 it could result in silly bitmap scans that would do the same BitmapOr twice and then BitmapAnd these together :-(
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/optimizer/path/indxpath.c52
1 files changed, 30 insertions, 22 deletions
diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c
index f3764344f1..d64161611e 100644
--- a/src/backend/optimizer/path/indxpath.c
+++ b/src/backend/optimizer/path/indxpath.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.191.2.5 2006/01/29 17:27:49 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.191.2.6 2006/04/08 21:32:25 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -243,6 +243,10 @@ find_usable_indexes(PlannerInfo *root, RelOptInfo *rel,
List *all_clauses = NIL; /* not computed till needed */
ListCell *ilist;
+ /* quick exit if no available clauses */
+ if (clauses == NIL)
+ return NIL;
+
foreach(ilist, rel->indexlist)
{
IndexOptInfo *index = (IndexOptInfo *) lfirst(ilist);
@@ -1178,16 +1182,20 @@ best_inner_indexscan(PlannerInfo *root, RelOptInfo *rel,
}
/*
- * Find all the relevant restriction and join clauses.
+ * Find all the relevant join clauses.
*/
clause_list = find_clauses_for_join(root, rel, outer_relids, isouterjoin);
/*
* Find all the index paths that are usable for this join, except for
- * stuff involving OR clauses.
+ * stuff involving OR clauses. We can use both
+ * join and restriction clauses as indexquals, but we insist the path
+ * use at least one join clause (else it'd not be an "inner indexscan"
+ * but a plain indexscan, and those have already been considered).
*/
indexpaths = find_usable_indexes(root, rel,
- clause_list, NIL,
+ clause_list,
+ rel->baserestrictinfo,
false, true,
outer_relids);
@@ -1196,7 +1204,8 @@ best_inner_indexscan(PlannerInfo *root, RelOptInfo *rel,
* clause list.
*/
bitindexpaths = generate_bitmap_or_paths(root, rel,
- clause_list, NIL,
+ clause_list,
+ rel->baserestrictinfo,
true,
outer_relids);
@@ -1246,13 +1255,12 @@ best_inner_indexscan(PlannerInfo *root, RelOptInfo *rel,
/*
* find_clauses_for_join
- * Generate a list of clauses that are potentially useful for
+ * Generate a list of join clauses that are potentially useful for
* scanning rel as the inner side of a nestloop join.
*
- * We consider both join and restriction clauses. Any joinclause that uses
- * only otherrels in the specified outer_relids is fair game. But there must
- * be at least one such joinclause in the final list, otherwise we return NIL
- * indicating that there isn't any potential win here.
+ * Any joinclause that uses only otherrels in the specified outer_relids is
+ * fair game. Note that restriction clauses on rel can also be used in
+ * forming index conditions, but we do not include those here.
*/
static List *
find_clauses_for_join(PlannerInfo *root, RelOptInfo *rel,
@@ -1280,28 +1288,28 @@ find_clauses_for_join(PlannerInfo *root, RelOptInfo *rel,
bms_free(join_relids);
- /* if no join clause was matched then forget it, per comments above */
+ /* quick exit if no join clause was matched */
if (clause_list == NIL)
return NIL;
/*
- * We can also use any plain restriction clauses for the rel. We put
- * these at the front of the clause list for the convenience of
- * remove_redundant_join_clauses, which can never remove non-join clauses
- * and hence won't be able to get rid of a non-join clause if it appears
- * after a join clause it is redundant with.
- */
- clause_list = list_concat(list_copy(rel->baserestrictinfo), clause_list);
-
- /*
* We may now have clauses that are known redundant. Get rid of 'em.
*/
if (list_length(clause_list) > 1)
- {
clause_list = remove_redundant_join_clauses(root,
clause_list,
isouterjoin);
- }
+
+ /*
+ * We might have found join clauses that are known redundant with
+ * restriction clauses on rel (due to conclusions drawn by implied
+ * equality deduction; without that, this would obviously never happen).
+ * Get rid of them too.
+ */
+ if (rel->baserestrictinfo != NIL)
+ clause_list = select_nonredundant_join_clauses(root, clause_list,
+ rel->baserestrictinfo,
+ isouterjoin);
return clause_list;
}