diff --git a/contrib/pageinspect/expected/hash.out b/contrib/pageinspect/expected/hash.out index 7eb1537..9630c60 100644 --- a/contrib/pageinspect/expected/hash.out +++ b/contrib/pageinspect/expected/hash.out @@ -29,22 +29,28 @@ 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); +SELECT * FROM hash_bitmap_info(get_raw_page('test_hash_a_idx', 0), + 'test_hash_a_idx', 0); ERROR: page is not an overflow page DETAIL: Expected 00000001, got 00000008. -SELECT * FROM hash_bitmap_info('test_hash_a_idx', 1); +SELECT * FROM hash_bitmap_info(get_raw_page('test_hash_a_idx', 0), + 'test_hash_a_idx', 1); ERROR: page is not an overflow page DETAIL: Expected 00000001, got 00000002. -SELECT * FROM hash_bitmap_info('test_hash_a_idx', 2); +SELECT * FROM hash_bitmap_info(get_raw_page('test_hash_a_idx', 0), + 'test_hash_a_idx', 2); ERROR: page is not an overflow page DETAIL: Expected 00000001, got 00000002. -SELECT * FROM hash_bitmap_info('test_hash_a_idx', 3); +SELECT * FROM hash_bitmap_info(get_raw_page('test_hash_a_idx', 0), + 'test_hash_a_idx', 3); ERROR: page is not an overflow page DETAIL: Expected 00000001, got 00000002. -SELECT * FROM hash_bitmap_info('test_hash_a_idx', 4); +SELECT * FROM hash_bitmap_info(get_raw_page('test_hash_a_idx', 0), + 'test_hash_a_idx', 4); ERROR: page is not an overflow page DETAIL: Expected 00000001, got 00000002. -SELECT * FROM hash_bitmap_info('test_hash_a_idx', 5); +SELECT * FROM hash_bitmap_info(get_raw_page('test_hash_a_idx', 0), + 'test_hash_a_idx', 5); ERROR: page is not an overflow page DETAIL: Expected 00000001, got 00000004. SELECT magic, version, ntuples, bsize, bmsize, bmshift, maxbucket, highmask, diff --git a/contrib/pageinspect/hashfuncs.c b/contrib/pageinspect/hashfuncs.c index 08663c1..ab5ca632 100644 --- a/contrib/pageinspect/hashfuncs.c +++ b/contrib/pageinspect/hashfuncs.c @@ -371,19 +371,22 @@ hash_page_items(PG_FUNCTION_ARGS) * * Get bitmap information for a particular overflow page * - * Usage: SELECT * FROM hash_bitmap_info('con_hash_index'::regclass, 5); + * Usage: SELECT * FROM hash_bitmap_info(get_raw_page('con_hash_index', 0), + * 'con_hash_index'::regclass, 5); * ------------------------------------------------ */ Datum hash_bitmap_info(PG_FUNCTION_ARGS) { - Oid indexRelid = PG_GETARG_OID(0); - uint64 ovflblkno = PG_GETARG_INT64(1); + bytea *raw_page = PG_GETARG_BYTEA_P(0); + Oid indexRelid = PG_GETARG_OID(1); + uint64 ovflblkno = PG_GETARG_INT64(2); HashMetaPage metap; Buffer buf, - metabuf; + mapbuf; BlockNumber bitmapblkno; - Page page; + Page page, + metapage, mappage; bool bit = false; HashPageOpaque opaque; TupleDesc tupleDesc; @@ -395,12 +398,14 @@ hash_bitmap_info(PG_FUNCTION_ARGS) int j; Datum values[3]; bool nulls[3]; + uint32 *freep = NULL; if (!superuser()) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), (errmsg("must be superuser to use raw page functions")))); + metapage = verify_hash_page(raw_page, LH_META_PAGE); indexRel = index_open(indexRelid, AccessShareLock); if (!IS_HASH(indexRel)) @@ -438,8 +443,7 @@ hash_bitmap_info(PG_FUNCTION_ARGS) 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)); + metap = HashPageGetMeta(metapage); /* Identify overflow bit number */ ovflbitno = _hash_ovflblkno_to_bitno(metap, (BlockNumber) ovflblkno); @@ -454,8 +458,15 @@ hash_bitmap_info(PG_FUNCTION_ARGS) bitmapblkno = metap->hashm_mapp[bitmappage]; - _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); + + if (ISSET(freep, bitmapbit)) + bit = 1; + _hash_relbuf(indexRel, mapbuf); index_close(indexRel, AccessShareLock); /* Build a tuple descriptor for our result type */ diff --git a/contrib/pageinspect/pageinspect--1.5--1.6.sql b/contrib/pageinspect/pageinspect--1.5--1.6.sql index ac39568..a0cff81 100644 --- a/contrib/pageinspect/pageinspect--1.5--1.6.sql +++ b/contrib/pageinspect/pageinspect--1.5--1.6.sql @@ -45,7 +45,9 @@ LANGUAGE C STRICT PARALLEL SAFE; -- -- hash_bitmap_info() -- -CREATE FUNCTION hash_bitmap_info(IN index_oid regclass, IN blkno int8, +CREATE FUNCTION hash_bitmap_info(IN page bytea, + IN index_oid regclass, + IN blkno int8, OUT bitmapblkno int8, OUT bitmapbit int4, OUT bitstatus bool) diff --git a/contrib/pageinspect/sql/hash.sql b/contrib/pageinspect/sql/hash.sql index 87ee549..40be988 100644 --- a/contrib/pageinspect/sql/hash.sql +++ b/contrib/pageinspect/sql/hash.sql @@ -13,12 +13,23 @@ SELECT hash_page_type(get_raw_page('test_hash_a_idx', 5)); SELECT hash_page_type(get_raw_page('test_hash_a_idx', 6)); -SELECT * FROM hash_bitmap_info('test_hash_a_idx', 0); -SELECT * FROM hash_bitmap_info('test_hash_a_idx', 1); -SELECT * FROM hash_bitmap_info('test_hash_a_idx', 2); -SELECT * FROM hash_bitmap_info('test_hash_a_idx', 3); -SELECT * FROM hash_bitmap_info('test_hash_a_idx', 4); -SELECT * FROM hash_bitmap_info('test_hash_a_idx', 5); +SELECT * FROM hash_bitmap_info(get_raw_page('test_hash_a_idx', 0), + 'test_hash_a_idx', 0); + +SELECT * FROM hash_bitmap_info(get_raw_page('test_hash_a_idx', 0), + 'test_hash_a_idx', 1); + +SELECT * FROM hash_bitmap_info(get_raw_page('test_hash_a_idx', 0), + 'test_hash_a_idx', 2); + +SELECT * FROM hash_bitmap_info(get_raw_page('test_hash_a_idx', 0), + 'test_hash_a_idx', 3); + +SELECT * FROM hash_bitmap_info(get_raw_page('test_hash_a_idx', 0), + 'test_hash_a_idx', 4); + +SELECT * FROM hash_bitmap_info(get_raw_page('test_hash_a_idx', 0), + 'test_hash_a_idx', 5); SELECT magic, version, ntuples, bsize, bmsize, bmshift, maxbucket, highmask, diff --git a/doc/src/sgml/pageinspect.sgml b/doc/src/sgml/pageinspect.sgml index 5e6712f..eef6746 100644 --- a/doc/src/sgml/pageinspect.sgml +++ b/doc/src/sgml/pageinspect.sgml @@ -578,7 +578,7 @@ test=# SELECT * FROM hash_page_items(get_raw_page('con_hash_index', 1)) LIMIT 5; - hash_bitmap_info(index oid, blkno int) returns record + hash_bitmap_info(page bytea, index oid, blkno int) returns record hash_bitmap_info @@ -590,10 +590,10 @@ test=# SELECT * FROM hash_page_items(get_raw_page('con_hash_index', 1)) LIMIT 5; in the bitmap page for a particular overflow page of HASH index. For example: -test=# SELECT * FROM hash_bitmap_info('con_hash_index', 2052); +test=# SELECT * FROM hash_bitmap_info(get_raw_page('con_hash_index', 0), 'con_hash_index', 516); bitmapblkno | bitmapbit | bitstatus -------------+-----------+----------- - 65 | 3 | t + 33 | 3 | t