diff --git a/src/backend/access/gist/gistvacuum.c b/src/backend/access/gist/gistvacuum.c index 22181c6299..4868280ed7 100644 --- a/src/backend/access/gist/gistvacuum.c +++ b/src/backend/access/gist/gistvacuum.c @@ -16,6 +16,7 @@ #include "access/genam.h" #include "access/gist_private.h" +#include "access/htup_details.h" #include "commands/vacuum.h" #include "miscadmin.h" #include "storage/indexfsm.h" @@ -32,7 +33,9 @@ gistvacuumcleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *stats) BlockNumber npages, blkno; BlockNumber totFreePages; - bool needLock; + bool needLock, + shouldCount = false; + uint64_t tuplesCount = 0; /* No-op in ANALYZE ONLY mode */ if (info->analyze_only) @@ -45,11 +48,15 @@ gistvacuumcleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *stats) /* use heap's tuple count */ stats->num_index_tuples = info->num_heap_tuples; stats->estimated_count = info->estimated_count; - - /* - * XXX the above is wrong if index is partial. Would it be OK to just - * return NULL, or is there work we must do below? - */ + /* unless it is estimate or index is partial */ + if (rel->rd_indextuple == NULL) + RelationInitIndexAccessInfo(rel); + shouldCount = !heap_attisnull(rel->rd_indextuple, Anum_pg_index_indpred) || + info->estimated_count; + } + else + { + shouldCount = stats->estimated_count; } /* @@ -82,12 +89,27 @@ gistvacuumcleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *stats) totFreePages++; RecordFreeIndexPage(rel, blkno); } + else + { + /* Count tuples in leaf pages if needed */ + if (shouldCount && GistPageIsLeaf(page)) + { + tuplesCount += PageGetMaxOffsetNumber(page); + } + } UnlockReleaseBuffer(buffer); } /* Finally, vacuum the FSM */ IndexFreeSpaceMapVacuum(info->index); + /* Update index tuples stat to counted over leaf pages if needed */ + if (shouldCount) + { + stats->num_index_tuples = tuplesCount; + stats->estimated_count = false; + } + /* return statistics */ stats->pages_free = totFreePages; if (needLock)