simplify_hash_bitmap_info_v3.patch
application/x-download
Filename: simplify_hash_bitmap_info_v3.patch
Type: application/x-download
Part: 0
Message:
Re: pageinspect: Hash index support
Patch
Format: unified
Series: patch v3
| File | + | − |
|---|---|---|
| contrib/pageinspect/expected/hash.out | 10 | 12 |
| contrib/pageinspect/hashfuncs.c | 12 | 23 |
| src/backend/access/hash/hashovfl.c | 11 | 2 |
diff --git a/contrib/pageinspect/expected/hash.out b/contrib/pageinspect/expected/hash.out
index 7eb1537..fb0caee 100644
--- a/contrib/pageinspect/expected/hash.out
+++ b/contrib/pageinspect/expected/hash.out
@@ -30,23 +30,21 @@ hash_page_type | bitmap
SELECT hash_page_type(get_raw_page('test_hash_a_idx', 6));
ERROR: block number 6 is out of range for relation "test_hash_a_idx"
SELECT * FROM hash_bitmap_info('test_hash_a_idx', 0);
-ERROR: page is not an overflow page
-DETAIL: Expected 00000001, got 00000008.
+ERROR: invalid overflow block number 0
SELECT * FROM hash_bitmap_info('test_hash_a_idx', 1);
-ERROR: page is not an overflow page
-DETAIL: Expected 00000001, got 00000002.
+ERROR: invalid overflow block number 1
SELECT * FROM hash_bitmap_info('test_hash_a_idx', 2);
-ERROR: page is not an overflow page
-DETAIL: Expected 00000001, got 00000002.
+ERROR: invalid overflow block number 2
SELECT * FROM hash_bitmap_info('test_hash_a_idx', 3);
-ERROR: page is not an overflow page
-DETAIL: Expected 00000001, got 00000002.
+ERROR: invalid overflow block number 3
SELECT * FROM hash_bitmap_info('test_hash_a_idx', 4);
-ERROR: page is not an overflow page
-DETAIL: Expected 00000001, got 00000002.
+ERROR: invalid overflow block number 4
SELECT * FROM hash_bitmap_info('test_hash_a_idx', 5);
-ERROR: page is not an overflow page
-DETAIL: Expected 00000001, got 00000004.
+-[ RECORD 1 ]--
+bitmapblkno | 5
+bitmapbit | 0
+bitstatus | t
+
SELECT magic, version, ntuples, bsize, bmsize, bmshift, maxbucket, highmask,
lowmask, ovflpoint, firstfree, nmaps, procid, spares, mapp FROM
hash_metapage_info(get_raw_page('test_hash_a_idx', 0));
diff --git a/contrib/pageinspect/hashfuncs.c b/contrib/pageinspect/hashfuncs.c
index 08663c1..a645e04 100644
--- a/contrib/pageinspect/hashfuncs.c
+++ b/contrib/pageinspect/hashfuncs.c
@@ -380,12 +380,11 @@ hash_bitmap_info(PG_FUNCTION_ARGS)
Oid indexRelid = PG_GETARG_OID(0);
uint64 ovflblkno = PG_GETARG_INT64(1);
HashMetaPage metap;
- Buffer buf,
- metabuf;
+ Buffer metabuf,
+ mapbuf;
BlockNumber bitmapblkno;
- Page page;
+ Page mappage;
bool bit = false;
- HashPageOpaque opaque;
TupleDesc tupleDesc;
Relation indexRel;
uint32 ovflbitno;
@@ -395,6 +394,7 @@ hash_bitmap_info(PG_FUNCTION_ARGS)
int j;
Datum values[3];
bool nulls[3];
+ uint32 *freep = NULL;
if (!superuser())
ereport(ERROR,
@@ -418,25 +418,6 @@ hash_bitmap_info(PG_FUNCTION_ARGS)
errmsg("block number " UINT64_FORMAT " is out of range for relation \"%s\"",
ovflblkno, RelationGetRelationName(indexRel))));
- buf = ReadBufferExtended(indexRel, MAIN_FORKNUM, (BlockNumber) ovflblkno,
- RBM_NORMAL, NULL);
- LockBuffer(buf, BUFFER_LOCK_SHARE);
- _hash_checkpage(indexRel, buf, LH_PAGE_TYPE);
- page = BufferGetPage(buf);
- opaque = (HashPageOpaque) PageGetSpecialPointer(page);
-
- if (opaque->hasho_flag != LH_OVERFLOW_PAGE)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("page is not an overflow page"),
- errdetail("Expected %08x, got %08x.",
- LH_OVERFLOW_PAGE, opaque->hasho_flag)));
-
- if (BlockNumberIsValid(opaque->hasho_prevblkno))
- bit = true;
-
- UnlockReleaseBuffer(buf);
-
/* Read the metapage so we can determine which bitmap page to use */
metabuf = _hash_getbuf(indexRel, HASH_METAPAGE, HASH_READ, LH_META_PAGE);
metap = HashPageGetMeta(BufferGetPage(metabuf));
@@ -456,6 +437,14 @@ hash_bitmap_info(PG_FUNCTION_ARGS)
_hash_relbuf(indexRel, metabuf);
+ /* Check the status of bitmap bit for overflow page */
+ mapbuf = _hash_getbuf(indexRel, bitmapblkno, HASH_READ, LH_BITMAP_PAGE);
+ mappage = BufferGetPage(mapbuf);
+ freep = HashPageGetBitmap(mappage);
+
+ bit = ISSET(freep, bitmapbit) != 0;
+
+ _hash_relbuf(indexRel, mapbuf);
index_close(indexRel, AccessShareLock);
/* Build a tuple descriptor for our result type */
diff --git a/src/backend/access/hash/hashovfl.c b/src/backend/access/hash/hashovfl.c
index 753c8a6..9a13f6b 100644
--- a/src/backend/access/hash/hashovfl.c
+++ b/src/backend/access/hash/hashovfl.c
@@ -69,11 +69,20 @@ _hash_ovflblkno_to_bitno(HashMetaPage metap, BlockNumber ovflblkno)
if (ovflblkno <= (BlockNumber) (1 << i))
break; /* oops */
bitnum = ovflblkno - (1 << i);
- if (bitnum <= metap->hashm_spares[i])
+ /*
+ * bitnum has to be greater than number of overflow
+ * page added in previous split point. The overflow
+ * page at this splitnum (i) if any should start from
+ * ((2 ^ i) + metap->hashm_spares[i -1] + 1).
+ */
+ if (bitnum > metap->hashm_spares[i -1] &&
+ bitnum <= metap->hashm_spares[i])
return bitnum - 1; /* -1 to convert 1-based to 0-based */
}
- elog(ERROR, "invalid overflow block number %u", ovflblkno);
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("invalid overflow block number %u", ovflblkno)));
return 0; /* keep compiler quiet */
}