diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c index 024f325eb02..26a2e3bb8b8 100644 --- a/src/backend/utils/adt/selfuncs.c +++ b/src/backend/utils/adt/selfuncs.c @@ -102,6 +102,7 @@ #include #include "access/brin.h" +#include "access/brin_page.h" #include "access/gin.h" #include "access/table.h" #include "access/tableam.h" @@ -6865,12 +6866,34 @@ brincostestimate(PlannerInfo *root, IndexPath *path, double loop_count, &spc_seq_page_cost); /* - * Obtain some data from the index itself. A lock should have already - * been obtained on the index in plancat.c. + * Obtain some data from the index itself, if possible. Otherwise invent + * some plausible internal statistics based on the relation page count. */ - indexRel = index_open(index->indexoid, NoLock); - brinGetStats(indexRel, &statsData); - index_close(indexRel, NoLock); + if (!index->hypothetical) + { + /* + * A lock should have already been obtained on the index in plancat.c. + */ + indexRel = index_open(index->indexoid, NoLock); + brinGetStats(indexRel, &statsData); + index_close(indexRel, NoLock); + + /* work out the actual number of ranges in the index */ + indexRanges = Max(ceil((double) baserel->pages / + statsData.pagesPerRange), 1.0); + } + else + { + /* + * Assume default number of pages per range, and estimate the number + * of ranges based on that. + */ + indexRanges = Max(ceil((double) baserel->pages / + BRIN_DEFAULT_PAGES_PER_RANGE), 1.0); + + statsData.pagesPerRange = BRIN_DEFAULT_PAGES_PER_RANGE; + statsData.revmapNumPages = (indexRanges / REVMAP_PAGE_MAXITEMS) + 1; + } /* * Compute index correlation @@ -6970,10 +6993,6 @@ brincostestimate(PlannerInfo *root, IndexPath *path, double loop_count, baserel->relid, JOIN_INNER, NULL); - /* work out the actual number of ranges in the index */ - indexRanges = Max(ceil((double) baserel->pages / statsData.pagesPerRange), - 1.0); - /* * Now calculate the minimum possible ranges we could match with if all of * the rows were in the perfect order in the table's heap.