From a4acac04d125cae2eb8f2358dd196dbe029a813e Mon Sep 17 00:00:00 2001 From: Julien Rouhaud Date: Wed, 24 Mar 2021 16:27:40 +0800 Subject: [PATCH] Fix hash size estimation compatbility for PG11 and below. Thanks to github user nikhil-postgres for the report. While at it also fix a thinko in the size estimation which lead to greatly overestimated hypothetical hash index sizes. --- CONTRIBUTORS.md | 1 + hypopg_index.c | 20 +++++++++++++++++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 1da12f9..7c96ed9 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -16,3 +16,4 @@ People who contributed to hypopg: * Extortioner01 * nagaraju11 * ibrahim edib kokdemir + * github user nikhil-postgres diff --git a/hypopg_index.c b/hypopg_index.c index 0680585..dbf445d 100644 --- a/hypopg_index.c +++ b/hypopg_index.c @@ -57,6 +57,9 @@ #endif #include "parser/parse_utilcmd.h" #include "parser/parser.h" +#if PG_VERSION_NUM >= 120000 +#include "port/pg_bitutils.h" +#endif #include "storage/bufmgr.h" #include "utils/builtins.h" #include "utils/lsyscache.h" @@ -1907,6 +1910,7 @@ hypo_estimate_index(hypoIndex * entry, RelOptInfo *rel) uint32 num_buckets; uint32 num_overflow; uint32 num_bitmap; + uint32 lshift; /* * Determine the target fill factor (in tuples per bucket) for this index. @@ -1947,12 +1951,22 @@ hypo_estimate_index(hypoIndex * entry, RelOptInfo *rel) num_overflow = Max(0, ((entry->tuples - (num_buckets * ffactor)) / ffactor) + 1); + /* find largest bitmap array size that will fit in page size */ +#if PG_VERSION_NUM >= 120000 + lshift = pg_leftmost_one_pos32(HypoHashGetMaxBitmapSize()); +#else + for (lshift = _hash_log2(HypoHashGetMaxBitmapSize()); lshift > 0; --lshift) + { + if ((1 << lshift) <= HypoHashGetMaxBitmapSize()) + break; + } +#endif + /* - * Naive estimate of bitmap pages, using the previously computed number of + * Naive estimate of bitmap pages, using the previously computed number of * overflow pages. */ - num_bitmap = Max(1, num_overflow / - pg_leftmost_one_pos32(HypoHashGetMaxBitmapSize())); + num_bitmap = Max(1, num_overflow / (1 <pages = num_buckets + num_overflow + num_bitmap + 1;