diff --git a/src/backend/executor/nodeBitmapAnd.c b/src/backend/executor/nodeBitmapAnd.c index 1d5d94fc3f82c9e2b4617a252f0e5bd229acfc58..939062d4d6c1d52a59d0da6b7efc2933cbda215e 100644 --- a/src/backend/executor/nodeBitmapAnd.c +++ b/src/backend/executor/nodeBitmapAnd.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/executor/nodeBitmapAnd.c,v 1.2 2005/04/20 15:48:36 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/executor/nodeBitmapAnd.c,v 1.3 2005/08/28 22:47:20 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -143,6 +143,16 @@ MultiExecBitmapAnd(BitmapAndState *node) tbm_intersect(result, subresult); tbm_free(subresult); } + + /* + * If at any stage we have a completely empty bitmap, we can fall + * out without evaluating the remaining subplans, since ANDing them + * can no longer change the result. (Note: the fact that indxpath.c + * orders the subplans by selectivity should make this case more + * likely to occur.) + */ + if (tbm_is_empty(result)) + break; } if (result == NULL) diff --git a/src/backend/nodes/tidbitmap.c b/src/backend/nodes/tidbitmap.c index 777bf6482d203401efba36a56e045ec8d0716db9..e36a8d9806aca5131b15d55d9afec8834647053c 100644 --- a/src/backend/nodes/tidbitmap.c +++ b/src/backend/nodes/tidbitmap.c @@ -23,7 +23,7 @@ * Copyright (c) 2003-2005, PostgreSQL Global Development Group * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/nodes/tidbitmap.c,v 1.5 2005/07/24 02:25:26 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/nodes/tidbitmap.c,v 1.6 2005/08/28 22:47:20 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -510,6 +510,15 @@ tbm_intersect_page(TIDBitmap *a, PagetableEntry *apage, const TIDBitmap *b) } } +/* + * tbm_is_empty - is a TIDBitmap completely empty? + */ +bool +tbm_is_empty(const TIDBitmap *tbm) +{ + return (tbm->nentries == 0); +} + /* * tbm_begin_iterate - prepare to iterate through a TIDBitmap * diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c index bd0b09fcfe9f9baf14a4191e7eadce6a2a806669..c689d1461e9e59db7f8ad2e473a1aa01b97cb4da 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.187 2005/07/28 20:26:20 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.188 2005/08/28 22:47:20 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -538,6 +538,11 @@ choose_bitmap_and(PlannerInfo *root, RelOptInfo *rel, List *paths) * cases, the partial index will sort before competing non-partial * indexes and so it makes the right choice, but perhaps we need to * work harder. + * + * Note: outputting the selected sub-paths in selectivity order is a good + * thing even if we weren't using that as part of the selection method, + * because it makes the short-circuit case in MultiExecBitmapAnd() more + * likely to apply. */ /* Convert list to array so we can apply qsort */ diff --git a/src/include/nodes/tidbitmap.h b/src/include/nodes/tidbitmap.h index 2c90c01d8152a22b055c5bdb72cb7523d7d28e17..ea5673e6f27c6741e17229c3e894ca0369d27edc 100644 --- a/src/include/nodes/tidbitmap.h +++ b/src/include/nodes/tidbitmap.h @@ -15,7 +15,7 @@ * * Copyright (c) 2003-2005, PostgreSQL Global Development Group * - * $PostgreSQL: pgsql/src/include/nodes/tidbitmap.h,v 1.1 2005/04/17 22:24:02 tgl Exp $ + * $PostgreSQL: pgsql/src/include/nodes/tidbitmap.h,v 1.2 2005/08/28 22:47:20 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -49,6 +49,8 @@ extern void tbm_add_tuples(TIDBitmap *tbm, const ItemPointer tids, int ntids); extern void tbm_union(TIDBitmap *a, const TIDBitmap *b); extern void tbm_intersect(TIDBitmap *a, const TIDBitmap *b); +extern bool tbm_is_empty(const TIDBitmap *tbm); + extern void tbm_begin_iterate(TIDBitmap *tbm); extern TBMIterateResult *tbm_iterate(TIDBitmap *tbm);