aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--contrib/pageinspect/brinfuncs.c36
-rw-r--r--contrib/pageinspect/btreefuncs.c28
-rw-r--r--contrib/pageinspect/expected/brin.out4
-rw-r--r--contrib/pageinspect/expected/btree.out15
-rw-r--r--contrib/pageinspect/expected/gin.out11
-rw-r--r--contrib/pageinspect/expected/hash.out17
-rw-r--r--contrib/pageinspect/expected/page.out11
-rw-r--r--contrib/pageinspect/fsmfuncs.c4
-rw-r--r--contrib/pageinspect/hashfuncs.c6
-rw-r--r--contrib/pageinspect/rawpage.c29
-rw-r--r--contrib/pageinspect/sql/brin.sql4
-rw-r--r--contrib/pageinspect/sql/btree.sql13
-rw-r--r--contrib/pageinspect/sql/gin.sql9
-rw-r--r--contrib/pageinspect/sql/hash.sql13
-rw-r--r--contrib/pageinspect/sql/page.sql9
15 files changed, 142 insertions, 67 deletions
diff --git a/contrib/pageinspect/brinfuncs.c b/contrib/pageinspect/brinfuncs.c
index fb32d74a66a..733e1856614 100644
--- a/contrib/pageinspect/brinfuncs.c
+++ b/contrib/pageinspect/brinfuncs.c
@@ -16,6 +16,7 @@
#include "access/brin_tuple.h"
#include "access/htup_details.h"
#include "catalog/index.h"
+#include "catalog/pg_am_d.h"
#include "catalog/pg_type.h"
#include "funcapi.h"
#include "lib/stringinfo.h"
@@ -31,6 +32,8 @@ PG_FUNCTION_INFO_V1(brin_page_items);
PG_FUNCTION_INFO_V1(brin_metapage_info);
PG_FUNCTION_INFO_V1(brin_revmap_data);
+#define IS_BRIN(r) ((r)->rd_rel->relam == BRIN_AM_OID)
+
typedef struct brin_column_state
{
int nstored;
@@ -45,8 +48,7 @@ Datum
brin_page_type(PG_FUNCTION_ARGS)
{
bytea *raw_page = PG_GETARG_BYTEA_P(0);
- Page page = VARDATA(raw_page);
- int raw_page_size;
+ Page page;
char *type;
if (!superuser())
@@ -54,14 +56,7 @@ brin_page_type(PG_FUNCTION_ARGS)
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("must be superuser to use raw page functions")));
- raw_page_size = VARSIZE(raw_page) - VARHDRSZ;
-
- if (raw_page_size != BLCKSZ)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("input page too small"),
- errdetail("Expected size %d, got %d",
- BLCKSZ, raw_page_size)));
+ page = get_page_from_raw(raw_page);
switch (BrinPageType(page))
{
@@ -89,19 +84,7 @@ brin_page_type(PG_FUNCTION_ARGS)
static Page
verify_brin_page(bytea *raw_page, uint16 type, const char *strtype)
{
- Page page;
- int raw_page_size;
-
- raw_page_size = VARSIZE(raw_page) - VARHDRSZ;
-
- if (raw_page_size != BLCKSZ)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("input page too small"),
- errdetail("Expected size %d, got %d",
- BLCKSZ, raw_page_size)));
-
- page = VARDATA(raw_page);
+ Page page = get_page_from_raw(raw_page);
/* verify the special space says this page is what we want */
if (BrinPageType(page) != type)
@@ -169,6 +152,13 @@ brin_page_items(PG_FUNCTION_ARGS)
MemoryContextSwitchTo(oldcontext);
indexRel = index_open(indexRelid, AccessShareLock);
+
+ if (!IS_BRIN(indexRel))
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is not a %s index",
+ RelationGetRelationName(indexRel), "BRIN")));
+
bdesc = brin_build_desc(indexRel);
/* minimally verify the page we got */
diff --git a/contrib/pageinspect/btreefuncs.c b/contrib/pageinspect/btreefuncs.c
index e7a323044bf..d6a277684d9 100644
--- a/contrib/pageinspect/btreefuncs.c
+++ b/contrib/pageinspect/btreefuncs.c
@@ -184,8 +184,10 @@ bt_page_stats(PG_FUNCTION_ARGS)
rel = relation_openrv(relrv, AccessShareLock);
if (!IS_INDEX(rel) || !IS_BTREE(rel))
- elog(ERROR, "relation \"%s\" is not a btree index",
- RelationGetRelationName(rel));
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is not a %s index",
+ RelationGetRelationName(rel), "btree")));
/*
* Reject attempts to read non-local temporary relations; we would be
@@ -434,8 +436,10 @@ bt_page_items(PG_FUNCTION_ARGS)
rel = relation_openrv(relrv, AccessShareLock);
if (!IS_INDEX(rel) || !IS_BTREE(rel))
- elog(ERROR, "relation \"%s\" is not a btree index",
- RelationGetRelationName(rel));
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is not a %s index",
+ RelationGetRelationName(rel), "btree")));
/*
* Reject attempts to read non-local temporary relations; we would be
@@ -522,7 +526,6 @@ bt_page_items_bytea(PG_FUNCTION_ARGS)
Datum result;
FuncCallContext *fctx;
struct user_args *uargs;
- int raw_page_size;
if (!superuser())
ereport(ERROR,
@@ -535,19 +538,12 @@ bt_page_items_bytea(PG_FUNCTION_ARGS)
MemoryContext mctx;
TupleDesc tupleDesc;
- raw_page_size = VARSIZE(raw_page) - VARHDRSZ;
-
- if (raw_page_size < SizeOfPageHeaderData)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("input page too small (%d bytes)", raw_page_size)));
-
fctx = SRF_FIRSTCALL_INIT();
mctx = MemoryContextSwitchTo(fctx->multi_call_memory_ctx);
uargs = palloc(sizeof(struct user_args));
- uargs->page = VARDATA(raw_page);
+ uargs->page = get_page_from_raw(raw_page);
uargs->offset = FirstOffsetNumber;
@@ -625,8 +621,10 @@ bt_metap(PG_FUNCTION_ARGS)
rel = relation_openrv(relrv, AccessShareLock);
if (!IS_INDEX(rel) || !IS_BTREE(rel))
- elog(ERROR, "relation \"%s\" is not a btree index",
- RelationGetRelationName(rel));
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is not a %s index",
+ RelationGetRelationName(rel), "btree")));
/*
* Reject attempts to read non-local temporary relations; we would be
diff --git a/contrib/pageinspect/expected/brin.out b/contrib/pageinspect/expected/brin.out
index 71eb190380c..10cd36c1778 100644
--- a/contrib/pageinspect/expected/brin.out
+++ b/contrib/pageinspect/expected/brin.out
@@ -48,4 +48,8 @@ SELECT * FROM brin_page_items(get_raw_page('test1_a_idx', 2), 'test1_a_idx')
1 | 0 | 1 | f | f | f | {1 .. 1}
(1 row)
+-- Failure for non-BRIN index.
+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
DROP TABLE test1;
diff --git a/contrib/pageinspect/expected/btree.out b/contrib/pageinspect/expected/btree.out
index 17bf0c54708..3e431ce3c58 100644
--- a/contrib/pageinspect/expected/btree.out
+++ b/contrib/pageinspect/expected/btree.out
@@ -64,4 +64,19 @@ tids |
SELECT * FROM bt_page_items(get_raw_page('test1_a_idx', 2));
ERROR: block number 2 is out of range for relation "test1_a_idx"
+-- Failure when using a non-btree index.
+CREATE INDEX test1_a_hash ON test1 USING hash(a);
+SELECT bt_metap('test1_a_hash');
+ERROR: "test1_a_hash" is not a btree index
+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
+-- Suppress the DETAIL message, to allow the tests to work across various
+-- page sizes.
+\set VERBOSITY terse
+SELECT bt_page_items('aaa'::bytea);
+ERROR: invalid page size
+\set VERBOSITY default
DROP TABLE test1;
diff --git a/contrib/pageinspect/expected/gin.out b/contrib/pageinspect/expected/gin.out
index 82f63b23b19..c0f75950987 100644
--- a/contrib/pageinspect/expected/gin.out
+++ b/contrib/pageinspect/expected/gin.out
@@ -35,3 +35,14 @@ FROM gin_leafpage_items(get_raw_page('test1_y_idx',
-[ RECORD 1 ]
?column? | t
+-- Failure with incorrect page size
+-- Suppress the DETAIL message, to allow the tests to work across various
+-- page sizes.
+\set VERBOSITY terse
+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
+\set VERBOSITY default
diff --git a/contrib/pageinspect/expected/hash.out b/contrib/pageinspect/expected/hash.out
index 75d7bcfad5f..12369ddfa29 100644
--- a/contrib/pageinspect/expected/hash.out
+++ b/contrib/pageinspect/expected/hash.out
@@ -159,4 +159,21 @@ SELECT * FROM hash_page_items(get_raw_page('test_hash_a_idx', 4));
SELECT * FROM hash_page_items(get_raw_page('test_hash_a_idx', 5));
ERROR: page is not a hash bucket or overflow page
+-- Failure with non-hash index
+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
+-- Suppress the DETAIL message, to allow the tests to work across various
+-- page sizes.
+\set VERBOSITY terse
+SELECT hash_metapage_info('aaa'::bytea);
+ERROR: invalid page size
+SELECT hash_page_items('bbb'::bytea);
+ERROR: invalid page size
+SELECT hash_page_stats('ccc'::bytea);
+ERROR: invalid page size
+SELECT hash_page_type('ddd'::bytea);
+ERROR: invalid page size
+\set VERBOSITY default
DROP TABLE test_hash;
diff --git a/contrib/pageinspect/expected/page.out b/contrib/pageinspect/expected/page.out
index 29ea91135be..74deb23c598 100644
--- a/contrib/pageinspect/expected/page.out
+++ b/contrib/pageinspect/expected/page.out
@@ -201,3 +201,14 @@ select tuple_data_split('test8'::regclass, t_data, t_infomask, t_infomask2, t_bi
(1 row)
drop table test8;
+-- Failure with incorrect page size
+-- Suppress the DETAIL message, to allow the tests to work across various
+-- page sizes.
+\set VERBOSITY terse
+SELECT fsm_page_contents('aaa'::bytea);
+ERROR: invalid page size
+SELECT page_checksum('bbb'::bytea, 0);
+ERROR: invalid page size
+SELECT page_header('ccc'::bytea);
+ERROR: invalid page size
+\set VERBOSITY default
diff --git a/contrib/pageinspect/fsmfuncs.c b/contrib/pageinspect/fsmfuncs.c
index 099acbb2fe4..9f596d26fdf 100644
--- a/contrib/pageinspect/fsmfuncs.c
+++ b/contrib/pageinspect/fsmfuncs.c
@@ -36,6 +36,7 @@ fsm_page_contents(PG_FUNCTION_ARGS)
{
bytea *raw_page = PG_GETARG_BYTEA_P(0);
StringInfoData sinfo;
+ Page page;
FSMPage fsmpage;
int i;
@@ -44,7 +45,8 @@ fsm_page_contents(PG_FUNCTION_ARGS)
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("must be superuser to use raw page functions")));
- fsmpage = (FSMPage) PageGetContents(VARDATA(raw_page));
+ page = get_page_from_raw(raw_page);
+ fsmpage = (FSMPage) PageGetContents(page);
initStringInfo(&sinfo);
diff --git a/contrib/pageinspect/hashfuncs.c b/contrib/pageinspect/hashfuncs.c
index 3b2f0339cfe..ed6154f23e4 100644
--- a/contrib/pageinspect/hashfuncs.c
+++ b/contrib/pageinspect/hashfuncs.c
@@ -417,8 +417,10 @@ hash_bitmap_info(PG_FUNCTION_ARGS)
indexRel = index_open(indexRelid, AccessShareLock);
if (!IS_HASH(indexRel))
- elog(ERROR, "relation \"%s\" is not a hash index",
- RelationGetRelationName(indexRel));
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("\"%s\" is not a %s index",
+ RelationGetRelationName(indexRel), "hash")));
if (RELATION_IS_OTHER_TEMP(indexRel))
ereport(ERROR,
diff --git a/contrib/pageinspect/rawpage.c b/contrib/pageinspect/rawpage.c
index c0181506a5d..32400616219 100644
--- a/contrib/pageinspect/rawpage.c
+++ b/contrib/pageinspect/rawpage.c
@@ -218,7 +218,6 @@ Datum
page_header(PG_FUNCTION_ARGS)
{
bytea *raw_page = PG_GETARG_BYTEA_P(0);
- int raw_page_size;
TupleDesc tupdesc;
@@ -235,18 +234,7 @@ page_header(PG_FUNCTION_ARGS)
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("must be superuser to use raw page functions")));
- raw_page_size = VARSIZE(raw_page) - VARHDRSZ;
-
- /*
- * Check that enough data was supplied, so that we don't try to access
- * fields outside the supplied buffer.
- */
- if (raw_page_size < SizeOfPageHeaderData)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("input page too small (%d bytes)", raw_page_size)));
-
- page = (PageHeader) VARDATA(raw_page);
+ page = (PageHeader) get_page_from_raw(raw_page);
/* Build a tuple descriptor for our result type */
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
@@ -299,25 +287,14 @@ page_checksum(PG_FUNCTION_ARGS)
{
bytea *raw_page = PG_GETARG_BYTEA_P(0);
uint32 blkno = PG_GETARG_INT32(1);
- int raw_page_size;
- PageHeader page;
+ Page page;
if (!superuser())
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("must be superuser to use raw page functions")));
- raw_page_size = VARSIZE(raw_page) - VARHDRSZ;
-
- /*
- * Check that the supplied page is of the right size.
- */
- if (raw_page_size != BLCKSZ)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("incorrect size of input page (%d bytes)", raw_page_size)));
-
- page = (PageHeader) VARDATA(raw_page);
+ page = get_page_from_raw(raw_page);
PG_RETURN_INT16(pg_checksum_page((char *) page, blkno));
}
diff --git a/contrib/pageinspect/sql/brin.sql b/contrib/pageinspect/sql/brin.sql
index 735bc3b6733..8717229c5d2 100644
--- a/contrib/pageinspect/sql/brin.sql
+++ b/contrib/pageinspect/sql/brin.sql
@@ -15,4 +15,8 @@ SELECT * FROM brin_revmap_data(get_raw_page('test1_a_idx', 1)) LIMIT 5;
SELECT * FROM brin_page_items(get_raw_page('test1_a_idx', 2), 'test1_a_idx')
ORDER BY blknum, attnum LIMIT 5;
+-- Failure for non-BRIN index.
+CREATE INDEX test1_a_btree ON test1 (a);
+SELECT brin_page_items(get_raw_page('test1_a_btree', 0), 'test1_a_btree');
+
DROP TABLE test1;
diff --git a/contrib/pageinspect/sql/btree.sql b/contrib/pageinspect/sql/btree.sql
index 8eac64c7b3c..174814fb7a4 100644
--- a/contrib/pageinspect/sql/btree.sql
+++ b/contrib/pageinspect/sql/btree.sql
@@ -18,4 +18,17 @@ SELECT * FROM bt_page_items(get_raw_page('test1_a_idx', 0));
SELECT * FROM bt_page_items(get_raw_page('test1_a_idx', 1));
SELECT * FROM bt_page_items(get_raw_page('test1_a_idx', 2));
+-- Failure when using a non-btree index.
+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);
+
+-- Failure with incorrect page size
+-- Suppress the DETAIL message, to allow the tests to work across various
+-- page sizes.
+\set VERBOSITY terse
+SELECT bt_page_items('aaa'::bytea);
+\set VERBOSITY default
+
DROP TABLE test1;
diff --git a/contrib/pageinspect/sql/gin.sql b/contrib/pageinspect/sql/gin.sql
index d516ed3cbd4..2a653609750 100644
--- a/contrib/pageinspect/sql/gin.sql
+++ b/contrib/pageinspect/sql/gin.sql
@@ -17,3 +17,12 @@ SELECT COUNT(*) > 0
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
+-- Suppress the DETAIL message, to allow the tests to work across various
+-- page sizes.
+\set VERBOSITY terse
+SELECT gin_leafpage_items('aaa'::bytea);
+SELECT gin_metapage_info('bbb'::bytea);
+SELECT gin_page_opaque_info('ccc'::bytea);
+\set VERBOSITY default
diff --git a/contrib/pageinspect/sql/hash.sql b/contrib/pageinspect/sql/hash.sql
index 87ee549a7b4..546c780e0e4 100644
--- a/contrib/pageinspect/sql/hash.sql
+++ b/contrib/pageinspect/sql/hash.sql
@@ -76,5 +76,18 @@ SELECT * FROM hash_page_items(get_raw_page('test_hash_a_idx', 3));
SELECT * FROM hash_page_items(get_raw_page('test_hash_a_idx', 4));
SELECT * FROM hash_page_items(get_raw_page('test_hash_a_idx', 5));
+-- Failure with non-hash index
+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
+-- Suppress the DETAIL message, to allow the tests to work across various
+-- page sizes.
+\set VERBOSITY terse
+SELECT hash_metapage_info('aaa'::bytea);
+SELECT hash_page_items('bbb'::bytea);
+SELECT hash_page_stats('ccc'::bytea);
+SELECT hash_page_type('ddd'::bytea);
+\set VERBOSITY default
DROP TABLE test_hash;
diff --git a/contrib/pageinspect/sql/page.sql b/contrib/pageinspect/sql/page.sql
index 9a3bc953862..bb78546e177 100644
--- a/contrib/pageinspect/sql/page.sql
+++ b/contrib/pageinspect/sql/page.sql
@@ -80,3 +80,12 @@ select t_bits, t_data from heap_page_items(get_raw_page('test8', 0));
select tuple_data_split('test8'::regclass, t_data, t_infomask, t_infomask2, t_bits)
from heap_page_items(get_raw_page('test8', 0));
drop table test8;
+
+-- Failure with incorrect page size
+-- Suppress the DETAIL message, to allow the tests to work across various
+-- page sizes.
+\set VERBOSITY terse
+SELECT fsm_page_contents('aaa'::bytea);
+SELECT page_checksum('bbb'::bytea, 0);
+SELECT page_header('ccc'::bytea);
+\set VERBOSITY default