diff --git a/contrib/pageinspect/brinfuncs.c b/contrib/pageinspect/brinfuncs.c index 95b58ac0d2..04a90c4782 100644 --- a/contrib/pageinspect/brinfuncs.c +++ b/contrib/pageinspect/brinfuncs.c @@ -58,6 +58,9 @@ brin_page_type(PG_FUNCTION_ARGS) page = get_page_from_raw(raw_page); + if (PageIsNew(page)) + PG_RETURN_NULL(); + /* verify the special space has the expected size */ if (PageGetSpecialSize(page) != MAXALIGN(sizeof(BrinSpecialSpace))) ereport(ERROR, @@ -95,6 +98,9 @@ verify_brin_page(bytea *raw_page, uint16 type, const char *strtype) { Page page = get_page_from_raw(raw_page); + if (PageIsNew(page)) + return page; + /* verify the special space has the expected size */ if (PageGetSpecialSize(page) != MAXALIGN(sizeof(BrinSpecialSpace))) ereport(ERROR, @@ -182,6 +188,13 @@ brin_page_items(PG_FUNCTION_ARGS) /* minimally verify the page we got */ page = verify_brin_page(raw_page, BRIN_PAGETYPE_REGULAR, "regular"); + if (PageIsNew(page)) + { + brin_free_desc(bdesc); + index_close(indexRel, AccessShareLock); + PG_RETURN_NULL(); + } + /* * Initialize output functions for all indexed datatypes; simplifies * calling them later. @@ -348,6 +361,9 @@ brin_metapage_info(PG_FUNCTION_ARGS) page = verify_brin_page(raw_page, BRIN_PAGETYPE_META, "metapage"); + if (PageIsNew(page)) + PG_RETURN_NULL(); + /* Build a tuple descriptor for our result type */ if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) elog(ERROR, "return type must be a row type"); @@ -399,6 +415,12 @@ brin_revmap_data(PG_FUNCTION_ARGS) /* minimally verify the page we got */ page = verify_brin_page(raw_page, BRIN_PAGETYPE_REVMAP, "revmap"); + if (PageIsNew(page)) + { + MemoryContextSwitchTo(mctx); + PG_RETURN_NULL(); + } + state = palloc(sizeof(*state)); state->tids = ((RevmapContents *) PageGetContents(page))->rm_tids; state->idx = 0; diff --git a/contrib/pageinspect/btreefuncs.c b/contrib/pageinspect/btreefuncs.c index 447f1fae91..3093aa894f 100644 --- a/contrib/pageinspect/btreefuncs.c +++ b/contrib/pageinspect/btreefuncs.c @@ -545,6 +545,12 @@ bt_page_items_bytea(PG_FUNCTION_ARGS) uargs->page = get_page_from_raw(raw_page); + if (PageIsNew(uargs->page)) + { + MemoryContextSwitchTo(mctx); + PG_RETURN_NULL(); + } + uargs->offset = FirstOffsetNumber; /* verify the special space has the expected size */ diff --git a/contrib/pageinspect/expected/brin.out b/contrib/pageinspect/expected/brin.out index 62ee783b60..d19cdc3b95 100644 --- a/contrib/pageinspect/expected/brin.out +++ b/contrib/pageinspect/expected/brin.out @@ -62,4 +62,29 @@ ERROR: input page is not a valid BRIN page SELECT * FROM brin_revmap_data(get_raw_page('test1', 0)); ERROR: input page is not a valid BRIN page \set VERBOSITY default +-- Tests with all-zero pages. +SHOW block_size \gset +SELECT brin_page_type(decode(repeat('00', :block_size), 'hex')); + brin_page_type +---------------- + +(1 row) + +SELECT brin_page_items(decode(repeat('00', :block_size), 'hex'), 'test1_a_idx'); + brin_page_items +----------------- +(0 rows) + +SELECT brin_metapage_info(decode(repeat('00', :block_size), 'hex')); + brin_metapage_info +-------------------- + +(1 row) + +SELECT brin_revmap_data(decode(repeat('00', :block_size), 'hex')); + brin_revmap_data +------------------ + +(1 row) + DROP TABLE test1; diff --git a/contrib/pageinspect/expected/btree.out b/contrib/pageinspect/expected/btree.out index e6c5a0f968..f6eba981e1 100644 --- a/contrib/pageinspect/expected/btree.out +++ b/contrib/pageinspect/expected/btree.out @@ -93,4 +93,10 @@ ERROR: input page is not a valid btree page SELECT bt_page_items(get_raw_page('test1_a_brin', 0)); ERROR: input page is not a valid btree page \set VERBOSITY default +-- Tests with all-zero pages. +SHOW block_size \gset +SELECT bt_page_items(decode(repeat('00', :block_size), 'hex')); +-[ RECORD 1 ]-+- +bt_page_items | + DROP TABLE test1; diff --git a/contrib/pageinspect/expected/gin.out b/contrib/pageinspect/expected/gin.out index c1f93ffaa1..5f49ff577b 100644 --- a/contrib/pageinspect/expected/gin.out +++ b/contrib/pageinspect/expected/gin.out @@ -54,3 +54,17 @@ ERROR: input page is not a valid GIN data leaf page SELECT * FROM gin_leafpage_items(get_raw_page('test1', 0)); ERROR: input page is not a valid GIN data leaf page \set VERBOSITY default +-- Tests with all-zero pages. +SHOW block_size \gset +SELECT gin_leafpage_items(decode(repeat('00', :block_size), 'hex')); +-[ RECORD 1 ]------+- +gin_leafpage_items | + +SELECT gin_metapage_info(decode(repeat('00', :block_size), 'hex')); +-[ RECORD 1 ]-----+- +gin_metapage_info | + +SELECT gin_page_opaque_info(decode(repeat('00', :block_size), 'hex')); +-[ RECORD 1 ]--------+- +gin_page_opaque_info | + diff --git a/contrib/pageinspect/expected/hash.out b/contrib/pageinspect/expected/hash.out index 7db8abe099..82f1875288 100644 --- a/contrib/pageinspect/expected/hash.out +++ b/contrib/pageinspect/expected/hash.out @@ -186,4 +186,16 @@ ERROR: input page is not a valid hash page SELECT hash_page_type(get_raw_page('test_hash', 0)); ERROR: input page is not a valid hash page \set VERBOSITY default +-- Tests with all-zero pages. +SHOW block_size \gset +SELECT hash_metapage_info(decode(repeat('00', :block_size), 'hex')); +ERROR: page is not a hash meta page +SELECT hash_page_items(decode(repeat('00', :block_size), 'hex')); +ERROR: page is not a hash bucket or overflow page +SELECT hash_page_stats(decode(repeat('00', :block_size), 'hex')); +ERROR: page is not a hash bucket or overflow page +SELECT hash_page_type(decode(repeat('00', :block_size), 'hex')); +-[ RECORD 1 ]--+------- +hash_page_type | unused + DROP TABLE test_hash; diff --git a/contrib/pageinspect/expected/page.out b/contrib/pageinspect/expected/page.out index 74deb23c59..717ceccda3 100644 --- a/contrib/pageinspect/expected/page.out +++ b/contrib/pageinspect/expected/page.out @@ -212,3 +212,23 @@ ERROR: invalid page size SELECT page_header('ccc'::bytea); ERROR: invalid page size \set VERBOSITY default +-- Tests with all-zero pages. +SHOW block_size \gset +SELECT fsm_page_contents(decode(repeat('00', :block_size), 'hex')); + fsm_page_contents +------------------- + +(1 row) + +SELECT page_header(decode(repeat('00', :block_size), 'hex')); + page_header +----------------------- + (0/0,0,0,0,0,0,0,0,0) +(1 row) + +SELECT page_checksum(decode(repeat('00', :block_size), 'hex'), 1); + page_checksum +--------------- + +(1 row) + diff --git a/contrib/pageinspect/fsmfuncs.c b/contrib/pageinspect/fsmfuncs.c index 9f596d26fd..c1d0ea351e 100644 --- a/contrib/pageinspect/fsmfuncs.c +++ b/contrib/pageinspect/fsmfuncs.c @@ -46,6 +46,10 @@ fsm_page_contents(PG_FUNCTION_ARGS) errmsg("must be superuser to use raw page functions"))); page = get_page_from_raw(raw_page); + + if (PageIsNew(page)) + PG_RETURN_NULL(); + fsmpage = (FSMPage) PageGetContents(page); initStringInfo(&sinfo); diff --git a/contrib/pageinspect/ginfuncs.c b/contrib/pageinspect/ginfuncs.c index 5cecb46e2e..1b482a0999 100644 --- a/contrib/pageinspect/ginfuncs.c +++ b/contrib/pageinspect/ginfuncs.c @@ -49,6 +49,9 @@ gin_metapage_info(PG_FUNCTION_ARGS) page = get_page_from_raw(raw_page); + if (PageIsNew(page)) + PG_RETURN_NULL(); + if (PageGetSpecialSize(page) != MAXALIGN(sizeof(GinPageOpaqueData))) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), @@ -115,6 +118,9 @@ gin_page_opaque_info(PG_FUNCTION_ARGS) page = get_page_from_raw(raw_page); + if (PageIsNew(page)) + PG_RETURN_NULL(); + if (PageGetSpecialSize(page) != MAXALIGN(sizeof(GinPageOpaqueData))) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), @@ -200,6 +206,12 @@ gin_leafpage_items(PG_FUNCTION_ARGS) page = get_page_from_raw(raw_page); + if (PageIsNew(page)) + { + MemoryContextSwitchTo(mctx); + PG_RETURN_NULL(); + } + if (PageGetSpecialSize(page) != MAXALIGN(sizeof(GinPageOpaqueData))) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), diff --git a/contrib/pageinspect/rawpage.c b/contrib/pageinspect/rawpage.c index 3240061621..0e2799bc8f 100644 --- a/contrib/pageinspect/rawpage.c +++ b/contrib/pageinspect/rawpage.c @@ -296,5 +296,8 @@ page_checksum(PG_FUNCTION_ARGS) page = get_page_from_raw(raw_page); + if (PageIsNew(page)) + PG_RETURN_NULL(); + PG_RETURN_INT16(pg_checksum_page((char *) page, blkno)); } diff --git a/contrib/pageinspect/sql/brin.sql b/contrib/pageinspect/sql/brin.sql index dc5d1661b6..45098c1ef5 100644 --- a/contrib/pageinspect/sql/brin.sql +++ b/contrib/pageinspect/sql/brin.sql @@ -27,4 +27,11 @@ SELECT * FROM brin_metapage_info(get_raw_page('test1', 0)); SELECT * FROM brin_revmap_data(get_raw_page('test1', 0)); \set VERBOSITY default +-- Tests with all-zero pages. +SHOW block_size \gset +SELECT brin_page_type(decode(repeat('00', :block_size), 'hex')); +SELECT brin_page_items(decode(repeat('00', :block_size), 'hex'), 'test1_a_idx'); +SELECT brin_metapage_info(decode(repeat('00', :block_size), 'hex')); +SELECT brin_revmap_data(decode(repeat('00', :block_size), 'hex')); + DROP TABLE test1; diff --git a/contrib/pageinspect/sql/btree.sql b/contrib/pageinspect/sql/btree.sql index cde0083586..75587c1aca 100644 --- a/contrib/pageinspect/sql/btree.sql +++ b/contrib/pageinspect/sql/btree.sql @@ -41,4 +41,8 @@ SELECT bt_page_items(get_raw_page('test1', 0)); SELECT bt_page_items(get_raw_page('test1_a_brin', 0)); \set VERBOSITY default +-- Tests with all-zero pages. +SHOW block_size \gset +SELECT bt_page_items(decode(repeat('00', :block_size), 'hex')); + DROP TABLE test1; diff --git a/contrib/pageinspect/sql/gin.sql b/contrib/pageinspect/sql/gin.sql index 342354a481..b0c20c0307 100644 --- a/contrib/pageinspect/sql/gin.sql +++ b/contrib/pageinspect/sql/gin.sql @@ -31,3 +31,9 @@ SELECT * FROM gin_metapage_info(get_raw_page('test1', 0)); SELECT * FROM gin_page_opaque_info(get_raw_page('test1', 0)); SELECT * FROM gin_leafpage_items(get_raw_page('test1', 0)); \set VERBOSITY default + +-- Tests with all-zero pages. +SHOW block_size \gset +SELECT gin_leafpage_items(decode(repeat('00', :block_size), 'hex')); +SELECT gin_metapage_info(decode(repeat('00', :block_size), 'hex')); +SELECT gin_page_opaque_info(decode(repeat('00', :block_size), 'hex')); diff --git a/contrib/pageinspect/sql/hash.sql b/contrib/pageinspect/sql/hash.sql index 8fd209c815..3acdc7d955 100644 --- a/contrib/pageinspect/sql/hash.sql +++ b/contrib/pageinspect/sql/hash.sql @@ -96,4 +96,11 @@ SELECT hash_page_stats(get_raw_page('test_hash', 0)); SELECT hash_page_type(get_raw_page('test_hash', 0)); \set VERBOSITY default +-- Tests with all-zero pages. +SHOW block_size \gset +SELECT hash_metapage_info(decode(repeat('00', :block_size), 'hex')); +SELECT hash_page_items(decode(repeat('00', :block_size), 'hex')); +SELECT hash_page_stats(decode(repeat('00', :block_size), 'hex')); +SELECT hash_page_type(decode(repeat('00', :block_size), 'hex')); + DROP TABLE test_hash; diff --git a/contrib/pageinspect/sql/page.sql b/contrib/pageinspect/sql/page.sql index bb78546e17..172f252638 100644 --- a/contrib/pageinspect/sql/page.sql +++ b/contrib/pageinspect/sql/page.sql @@ -89,3 +89,9 @@ SELECT fsm_page_contents('aaa'::bytea); SELECT page_checksum('bbb'::bytea, 0); SELECT page_header('ccc'::bytea); \set VERBOSITY default + +-- Tests with all-zero pages. +SHOW block_size \gset +SELECT fsm_page_contents(decode(repeat('00', :block_size), 'hex')); +SELECT page_header(decode(repeat('00', :block_size), 'hex')); +SELECT page_checksum(decode(repeat('00', :block_size), 'hex'), 1);