aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--contrib/pageinspect/brinfuncs.c18
-rw-r--r--contrib/pageinspect/btreefuncs.c14
-rw-r--r--contrib/pageinspect/expected/brin.out10
-rw-r--r--contrib/pageinspect/expected/btree.out22
-rw-r--r--contrib/pageinspect/expected/gin.out12
-rw-r--r--contrib/pageinspect/expected/hash.out14
-rw-r--r--contrib/pageinspect/ginfuncs.c22
-rw-r--r--contrib/pageinspect/hashfuncs.c11
-rw-r--r--contrib/pageinspect/sql/brin.sql8
-rw-r--r--contrib/pageinspect/sql/btree.sql18
-rw-r--r--contrib/pageinspect/sql/gin.sql9
-rw-r--r--contrib/pageinspect/sql/hash.sql10
12 files changed, 145 insertions, 23 deletions
diff --git a/contrib/pageinspect/brinfuncs.c b/contrib/pageinspect/brinfuncs.c
index 2db8d134fdc..95b58ac0d21 100644
--- a/contrib/pageinspect/brinfuncs.c
+++ b/contrib/pageinspect/brinfuncs.c
@@ -58,6 +58,15 @@ brin_page_type(PG_FUNCTION_ARGS)
page = get_page_from_raw(raw_page);
+ /* verify the special space has the expected size */
+ if (PageGetSpecialSize(page) != MAXALIGN(sizeof(BrinSpecialSpace)))
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("input page is not a valid %s page", "BRIN"),
+ errdetail("Expected special size %d, got %d.",
+ (int) MAXALIGN(sizeof(BrinSpecialSpace)),
+ (int) PageGetSpecialSize(page))));
+
switch (BrinPageType(page))
{
case BRIN_PAGETYPE_META:
@@ -86,6 +95,15 @@ verify_brin_page(bytea *raw_page, uint16 type, const char *strtype)
{
Page page = get_page_from_raw(raw_page);
+ /* verify the special space has the expected size */
+ if (PageGetSpecialSize(page) != MAXALIGN(sizeof(BrinSpecialSpace)))
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("input page is not a valid %s page", "BRIN"),
+ errdetail("Expected special size %d, got %d.",
+ (int) MAXALIGN(sizeof(BrinSpecialSpace)),
+ (int) PageGetSpecialSize(page))));
+
/* verify the special space says this page is what we want */
if (BrinPageType(page) != type)
ereport(ERROR,
diff --git a/contrib/pageinspect/btreefuncs.c b/contrib/pageinspect/btreefuncs.c
index d6a277684d9..447f1fae913 100644
--- a/contrib/pageinspect/btreefuncs.c
+++ b/contrib/pageinspect/btreefuncs.c
@@ -547,6 +547,15 @@ bt_page_items_bytea(PG_FUNCTION_ARGS)
uargs->offset = FirstOffsetNumber;
+ /* verify the special space has the expected size */
+ if (PageGetSpecialSize(uargs->page) != MAXALIGN(sizeof(BTPageOpaqueData)))
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("input page is not a valid %s page", "btree"),
+ errdetail("Expected special size %d, got %d.",
+ (int) MAXALIGN(sizeof(BTPageOpaqueData)),
+ (int) PageGetSpecialSize(uargs->page))));
+
opaque = (BTPageOpaque) PageGetSpecialPointer(uargs->page);
if (P_ISMETA(opaque))
@@ -554,6 +563,11 @@ bt_page_items_bytea(PG_FUNCTION_ARGS)
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("block is a meta page")));
+ if (P_ISLEAF(opaque) && opaque->btpo.level != 0)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("block is not a valid btree leaf page")));
+
if (P_ISDELETED(opaque))
elog(NOTICE, "page is deleted");
diff --git a/contrib/pageinspect/expected/brin.out b/contrib/pageinspect/expected/brin.out
index 10cd36c1778..62ee783b604 100644
--- a/contrib/pageinspect/expected/brin.out
+++ b/contrib/pageinspect/expected/brin.out
@@ -52,4 +52,14 @@ SELECT * FROM brin_page_items(get_raw_page('test1_a_idx', 2), 'test1_a_idx')
CREATE INDEX test1_a_btree ON test1 (a);
SELECT brin_page_items(get_raw_page('test1_a_btree', 0), 'test1_a_btree');
ERROR: "test1_a_btree" is not a BRIN index
+-- Mask DETAIL messages as these are not portable across architectures.
+\set VERBOSITY terse
+-- Invalid special area size
+SELECT brin_page_type(get_raw_page('test1', 0));
+ERROR: input page is not a valid BRIN page
+SELECT * FROM brin_metapage_info(get_raw_page('test1', 0));
+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
DROP TABLE test1;
diff --git a/contrib/pageinspect/expected/btree.out b/contrib/pageinspect/expected/btree.out
index 3e431ce3c58..e6c5a0f9684 100644
--- a/contrib/pageinspect/expected/btree.out
+++ b/contrib/pageinspect/expected/btree.out
@@ -1,5 +1,5 @@
-CREATE TABLE test1 (a int8, b text);
-INSERT INTO test1 VALUES (72057594037927937, 'text');
+CREATE TABLE test1 (a int8, b int4range);
+INSERT INTO test1 VALUES (72057594037927937, '[0,1)');
CREATE INDEX test1_a_idx ON test1 USING btree (a);
\x
SELECT * FROM bt_metap('test1_a_idx');
@@ -72,11 +72,25 @@ SELECT bt_page_stats('test1_a_hash', 0);
ERROR: "test1_a_hash" is not a btree index
SELECT bt_page_items('test1_a_hash', 0);
ERROR: "test1_a_hash" is not a btree index
--- Failure with incorrect page size
+SELECT bt_page_items(get_raw_page('test1_a_hash', 0));
+ERROR: block is a meta page
+CREATE INDEX test1_b_gist ON test1 USING gist(b);
+-- Special area of GiST is the same as btree, this complains about inconsistent
+-- leaf data on the page.
+SELECT bt_page_items(get_raw_page('test1_b_gist', 0));
+ERROR: block is not a valid btree leaf page
+-- Several failure modes.
-- Suppress the DETAIL message, to allow the tests to work across various
--- page sizes.
+-- page sizes and architectures.
\set VERBOSITY terse
+-- invalid page size
SELECT bt_page_items('aaa'::bytea);
ERROR: invalid page size
+-- invalid special area size
+CREATE INDEX test1_a_brin ON test1 USING brin(a);
+SELECT bt_page_items(get_raw_page('test1', 0));
+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
DROP TABLE test1;
diff --git a/contrib/pageinspect/expected/gin.out b/contrib/pageinspect/expected/gin.out
index c0f75950987..c1f93ffaa19 100644
--- a/contrib/pageinspect/expected/gin.out
+++ b/contrib/pageinspect/expected/gin.out
@@ -35,14 +35,22 @@ FROM gin_leafpage_items(get_raw_page('test1_y_idx',
-[ RECORD 1 ]
?column? | t
--- Failure with incorrect page size
+-- Failure with various modes.
-- Suppress the DETAIL message, to allow the tests to work across various
--- page sizes.
+-- page sizes and architectures.
\set VERBOSITY terse
+-- invalid page size
SELECT gin_leafpage_items('aaa'::bytea);
ERROR: invalid page size
SELECT gin_metapage_info('bbb'::bytea);
ERROR: invalid page size
SELECT gin_page_opaque_info('ccc'::bytea);
ERROR: invalid page size
+-- invalid special area size
+SELECT * FROM gin_metapage_info(get_raw_page('test1', 0));
+ERROR: input page is not a valid GIN metapage
+SELECT * FROM gin_page_opaque_info(get_raw_page('test1', 0));
+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
diff --git a/contrib/pageinspect/expected/hash.out b/contrib/pageinspect/expected/hash.out
index 12369ddfa29..7db8abe0998 100644
--- a/contrib/pageinspect/expected/hash.out
+++ b/contrib/pageinspect/expected/hash.out
@@ -163,10 +163,11 @@ ERROR: page is not a hash bucket or overflow page
CREATE INDEX test_hash_a_btree ON test_hash USING btree (a);
SELECT hash_bitmap_info('test_hash_a_btree', 0);
ERROR: "test_hash_a_btree" is not a hash index
--- Failure with incorrect page size
+-- Failure with various modes.
-- Suppress the DETAIL message, to allow the tests to work across various
--- page sizes.
+-- page sizes and architectures.
\set VERBOSITY terse
+-- invalid page size
SELECT hash_metapage_info('aaa'::bytea);
ERROR: invalid page size
SELECT hash_page_items('bbb'::bytea);
@@ -175,5 +176,14 @@ SELECT hash_page_stats('ccc'::bytea);
ERROR: invalid page size
SELECT hash_page_type('ddd'::bytea);
ERROR: invalid page size
+-- invalid special area size
+SELECT hash_metapage_info(get_raw_page('test_hash', 0));
+ERROR: input page is not a valid hash page
+SELECT hash_page_items(get_raw_page('test_hash', 0));
+ERROR: input page is not a valid hash page
+SELECT hash_page_stats(get_raw_page('test_hash', 0));
+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
DROP TABLE test_hash;
diff --git a/contrib/pageinspect/ginfuncs.c b/contrib/pageinspect/ginfuncs.c
index 711473579a8..5cecb46e2e6 100644
--- a/contrib/pageinspect/ginfuncs.c
+++ b/contrib/pageinspect/ginfuncs.c
@@ -49,6 +49,14 @@ gin_metapage_info(PG_FUNCTION_ARGS)
page = get_page_from_raw(raw_page);
+ if (PageGetSpecialSize(page) != MAXALIGN(sizeof(GinPageOpaqueData)))
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("input page is not a valid GIN metapage"),
+ errdetail("Expected special size %d, got %d.",
+ (int) MAXALIGN(sizeof(GinPageOpaqueData)),
+ (int) PageGetSpecialSize(page))));
+
opaq = (GinPageOpaque) PageGetSpecialPointer(page);
if (opaq->flags != GIN_META)
ereport(ERROR,
@@ -107,6 +115,14 @@ gin_page_opaque_info(PG_FUNCTION_ARGS)
page = get_page_from_raw(raw_page);
+ if (PageGetSpecialSize(page) != MAXALIGN(sizeof(GinPageOpaqueData)))
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("input page is not a valid GIN data leaf page"),
+ errdetail("Expected special size %d, got %d.",
+ (int) MAXALIGN(sizeof(GinPageOpaqueData)),
+ (int) PageGetSpecialSize(page))));
+
opaq = (GinPageOpaque) PageGetSpecialPointer(page);
/* Build a tuple descriptor for our result type */
@@ -188,9 +204,9 @@ gin_leafpage_items(PG_FUNCTION_ARGS)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("input page is not a valid GIN data leaf page"),
- errdetail("Special size %d, expected %d",
- (int) PageGetSpecialSize(page),
- (int) MAXALIGN(sizeof(GinPageOpaqueData)))));
+ errdetail("Expected special size %d, got %d.",
+ (int) MAXALIGN(sizeof(GinPageOpaqueData)),
+ (int) PageGetSpecialSize(page))));
opaq = (GinPageOpaque) PageGetSpecialPointer(page);
if (opaq->flags != (GIN_DATA | GIN_LEAF | GIN_COMPRESSED))
diff --git a/contrib/pageinspect/hashfuncs.c b/contrib/pageinspect/hashfuncs.c
index ed6154f23e4..e292117adbf 100644
--- a/contrib/pageinspect/hashfuncs.c
+++ b/contrib/pageinspect/hashfuncs.c
@@ -66,14 +66,17 @@ verify_hash_page(bytea *raw_page, int flags)
if (PageGetSpecialSize(page) != MAXALIGN(sizeof(HashPageOpaqueData)))
ereport(ERROR,
- (errcode(ERRCODE_INDEX_CORRUPTED),
- errmsg("index table contains corrupted page")));
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("input page is not a valid %s page", "hash"),
+ errdetail("Expected special size %d, got %d.",
+ (int) MAXALIGN(sizeof(HashPageOpaqueData)),
+ (int) PageGetSpecialSize(page))));
pageopaque = (HashPageOpaque) PageGetSpecialPointer(page);
if (pageopaque->hasho_page_id != HASHO_PAGE_ID)
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("page is not a hash page"),
+ errmsg("input page is not a valid %s page", "hash"),
errdetail("Expected %08x, got %08x.",
HASHO_PAGE_ID, pageopaque->hasho_page_id)));
@@ -134,7 +137,7 @@ verify_hash_page(bytea *raw_page, int flags)
ereport(ERROR,
(errcode(ERRCODE_INDEX_CORRUPTED),
errmsg("invalid version for metadata"),
- errdetail("Expected %d, got %d",
+ errdetail("Expected %d, got %d.",
HASH_VERSION, metap->hashm_version)));
}
diff --git a/contrib/pageinspect/sql/brin.sql b/contrib/pageinspect/sql/brin.sql
index 8717229c5d2..dc5d1661b6d 100644
--- a/contrib/pageinspect/sql/brin.sql
+++ b/contrib/pageinspect/sql/brin.sql
@@ -19,4 +19,12 @@ SELECT * FROM brin_page_items(get_raw_page('test1_a_idx', 2), 'test1_a_idx')
CREATE INDEX test1_a_btree ON test1 (a);
SELECT brin_page_items(get_raw_page('test1_a_btree', 0), 'test1_a_btree');
+-- Mask DETAIL messages as these are not portable across architectures.
+\set VERBOSITY terse
+-- Invalid special area size
+SELECT brin_page_type(get_raw_page('test1', 0));
+SELECT * FROM brin_metapage_info(get_raw_page('test1', 0));
+SELECT * FROM brin_revmap_data(get_raw_page('test1', 0));
+\set VERBOSITY default
+
DROP TABLE test1;
diff --git a/contrib/pageinspect/sql/btree.sql b/contrib/pageinspect/sql/btree.sql
index 174814fb7a4..cde0083586c 100644
--- a/contrib/pageinspect/sql/btree.sql
+++ b/contrib/pageinspect/sql/btree.sql
@@ -1,5 +1,5 @@
-CREATE TABLE test1 (a int8, b text);
-INSERT INTO test1 VALUES (72057594037927937, 'text');
+CREATE TABLE test1 (a int8, b int4range);
+INSERT INTO test1 VALUES (72057594037927937, '[0,1)');
CREATE INDEX test1_a_idx ON test1 USING btree (a);
\x
@@ -23,12 +23,22 @@ CREATE INDEX test1_a_hash ON test1 USING hash(a);
SELECT bt_metap('test1_a_hash');
SELECT bt_page_stats('test1_a_hash', 0);
SELECT bt_page_items('test1_a_hash', 0);
+SELECT bt_page_items(get_raw_page('test1_a_hash', 0));
+CREATE INDEX test1_b_gist ON test1 USING gist(b);
+-- Special area of GiST is the same as btree, this complains about inconsistent
+-- leaf data on the page.
+SELECT bt_page_items(get_raw_page('test1_b_gist', 0));
--- Failure with incorrect page size
+-- Several failure modes.
-- Suppress the DETAIL message, to allow the tests to work across various
--- page sizes.
+-- page sizes and architectures.
\set VERBOSITY terse
+-- invalid page size
SELECT bt_page_items('aaa'::bytea);
+-- invalid special area size
+CREATE INDEX test1_a_brin ON test1 USING brin(a);
+SELECT bt_page_items(get_raw_page('test1', 0));
+SELECT bt_page_items(get_raw_page('test1_a_brin', 0));
\set VERBOSITY default
DROP TABLE test1;
diff --git a/contrib/pageinspect/sql/gin.sql b/contrib/pageinspect/sql/gin.sql
index 2a653609750..342354a481f 100644
--- a/contrib/pageinspect/sql/gin.sql
+++ b/contrib/pageinspect/sql/gin.sql
@@ -18,11 +18,16 @@ FROM gin_leafpage_items(get_raw_page('test1_y_idx',
(pg_relation_size('test1_y_idx') /
current_setting('block_size')::bigint)::int - 1));
--- Failure with incorrect page size
+-- Failure with various modes.
-- Suppress the DETAIL message, to allow the tests to work across various
--- page sizes.
+-- page sizes and architectures.
\set VERBOSITY terse
+-- invalid page size
SELECT gin_leafpage_items('aaa'::bytea);
SELECT gin_metapage_info('bbb'::bytea);
SELECT gin_page_opaque_info('ccc'::bytea);
+-- invalid special area size
+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
diff --git a/contrib/pageinspect/sql/hash.sql b/contrib/pageinspect/sql/hash.sql
index 546c780e0e4..8fd209c815b 100644
--- a/contrib/pageinspect/sql/hash.sql
+++ b/contrib/pageinspect/sql/hash.sql
@@ -80,14 +80,20 @@ SELECT * FROM hash_page_items(get_raw_page('test_hash_a_idx', 5));
CREATE INDEX test_hash_a_btree ON test_hash USING btree (a);
SELECT hash_bitmap_info('test_hash_a_btree', 0);
--- Failure with incorrect page size
+-- Failure with various modes.
-- Suppress the DETAIL message, to allow the tests to work across various
--- page sizes.
+-- page sizes and architectures.
\set VERBOSITY terse
+-- invalid page size
SELECT hash_metapage_info('aaa'::bytea);
SELECT hash_page_items('bbb'::bytea);
SELECT hash_page_stats('ccc'::bytea);
SELECT hash_page_type('ddd'::bytea);
+-- invalid special area size
+SELECT hash_metapage_info(get_raw_page('test_hash', 0));
+SELECT hash_page_items(get_raw_page('test_hash', 0));
+SELECT hash_page_stats(get_raw_page('test_hash', 0));
+SELECT hash_page_type(get_raw_page('test_hash', 0));
\set VERBOSITY default
DROP TABLE test_hash;