From adfb81d9e1d60a6b69c128537b69a46b7761d749 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Thu, 29 Sep 2016 12:00:00 -0400 Subject: [PATCH] pageinspect: Add tests --- contrib/pageinspect/.gitignore | 4 ++ contrib/pageinspect/Makefile | 2 + contrib/pageinspect/expected/brin.out | 51 ++++++++++++++++++ contrib/pageinspect/expected/btree.out | 45 ++++++++++++++++ contrib/pageinspect/expected/gin.out | 30 +++++++++++ contrib/pageinspect/expected/page.out | 73 ++++++++++++++++++++++++++ contrib/pageinspect/sql/brin.sql | 18 +++++++ contrib/pageinspect/sql/btree.sql | 17 ++++++ contrib/pageinspect/sql/gin.sql | 14 +++++ contrib/pageinspect/sql/page.sql | 30 +++++++++++ 10 files changed, 284 insertions(+) create mode 100644 contrib/pageinspect/.gitignore create mode 100644 contrib/pageinspect/expected/brin.out create mode 100644 contrib/pageinspect/expected/btree.out create mode 100644 contrib/pageinspect/expected/gin.out create mode 100644 contrib/pageinspect/expected/page.out create mode 100644 contrib/pageinspect/sql/brin.sql create mode 100644 contrib/pageinspect/sql/btree.sql create mode 100644 contrib/pageinspect/sql/gin.sql create mode 100644 contrib/pageinspect/sql/page.sql diff --git a/contrib/pageinspect/.gitignore b/contrib/pageinspect/.gitignore new file mode 100644 index 0000000000..5dcb3ff972 --- /dev/null +++ b/contrib/pageinspect/.gitignore @@ -0,0 +1,4 @@ +# Generated subdirectories +/log/ +/results/ +/tmp_check/ diff --git a/contrib/pageinspect/Makefile b/contrib/pageinspect/Makefile index a98237ecbd..87a28e98c2 100644 --- a/contrib/pageinspect/Makefile +++ b/contrib/pageinspect/Makefile @@ -11,6 +11,8 @@ DATA = pageinspect--1.5.sql pageinspect--1.4--1.5.sql \ pageinspect--unpackaged--1.0.sql PGFILEDESC = "pageinspect - functions to inspect contents of database pages" +REGRESS = page btree brin gin + ifdef USE_PGXS PG_CONFIG = pg_config PGXS := $(shell $(PG_CONFIG) --pgxs) diff --git a/contrib/pageinspect/expected/brin.out b/contrib/pageinspect/expected/brin.out new file mode 100644 index 0000000000..71eb190380 --- /dev/null +++ b/contrib/pageinspect/expected/brin.out @@ -0,0 +1,51 @@ +CREATE TABLE test1 (a int, b text); +INSERT INTO test1 VALUES (1, 'one'); +CREATE INDEX test1_a_idx ON test1 USING brin (a); +SELECT brin_page_type(get_raw_page('test1_a_idx', 0)); + brin_page_type +---------------- + meta +(1 row) + +SELECT brin_page_type(get_raw_page('test1_a_idx', 1)); + brin_page_type +---------------- + revmap +(1 row) + +SELECT brin_page_type(get_raw_page('test1_a_idx', 2)); + brin_page_type +---------------- + regular +(1 row) + +SELECT * FROM brin_metapage_info(get_raw_page('test1_a_idx', 0)); + magic | version | pagesperrange | lastrevmappage +------------+---------+---------------+---------------- + 0xA8109CFA | 1 | 128 | 1 +(1 row) + +SELECT * FROM brin_metapage_info(get_raw_page('test1_a_idx', 1)); +ERROR: page is not a BRIN page of type "metapage" +DETAIL: Expected special type 0000f091, got 0000f092. +SELECT * FROM brin_revmap_data(get_raw_page('test1_a_idx', 0)) LIMIT 5; +ERROR: page is not a BRIN page of type "revmap" +DETAIL: Expected special type 0000f092, got 0000f091. +SELECT * FROM brin_revmap_data(get_raw_page('test1_a_idx', 1)) LIMIT 5; + pages +------- + (2,1) + (0,0) + (0,0) + (0,0) + (0,0) +(5 rows) + +SELECT * FROM brin_page_items(get_raw_page('test1_a_idx', 2), 'test1_a_idx') + ORDER BY blknum, attnum LIMIT 5; + itemoffset | blknum | attnum | allnulls | hasnulls | placeholder | value +------------+--------+--------+----------+----------+-------------+---------- + 1 | 0 | 1 | f | f | f | {1 .. 1} +(1 row) + +DROP TABLE test1; diff --git a/contrib/pageinspect/expected/btree.out b/contrib/pageinspect/expected/btree.out new file mode 100644 index 0000000000..ef7f86e885 --- /dev/null +++ b/contrib/pageinspect/expected/btree.out @@ -0,0 +1,45 @@ +CREATE TABLE test1 (a int, b text); +INSERT INTO test1 VALUES (1, 'one'); +CREATE INDEX test1_a_idx ON test1 USING btree (a); +\x +SELECT * FROM bt_metap('test1_a_idx'); +-[ RECORD 1 ]----- +magic | 340322 +version | 2 +root | 1 +level | 0 +fastroot | 1 +fastlevel | 0 + +SELECT * FROM bt_page_stats('test1_a_idx', 0); +ERROR: block 0 is a meta page +SELECT * FROM bt_page_stats('test1_a_idx', 1); +-[ RECORD 1 ]-+----- +blkno | 1 +type | l +live_items | 1 +dead_items | 0 +avg_item_size | 16 +page_size | 8192 +free_size | 8128 +btpo_prev | 0 +btpo_next | 0 +btpo | 0 +btpo_flags | 3 + +SELECT * FROM bt_page_stats('test1_a_idx', 2); +ERROR: block number out of range +SELECT * FROM bt_page_items('test1_a_idx', 0); +ERROR: block 0 is a meta page +SELECT * FROM bt_page_items('test1_a_idx', 1); +-[ RECORD 1 ]----------------------- +itemoffset | 1 +ctid | (0,1) +itemlen | 16 +nulls | f +vars | f +data | 01 00 00 00 00 00 00 00 + +SELECT * FROM bt_page_items('test1_a_idx', 2); +ERROR: block number out of range +DROP TABLE test1; diff --git a/contrib/pageinspect/expected/gin.out b/contrib/pageinspect/expected/gin.out new file mode 100644 index 0000000000..4f341e18d2 --- /dev/null +++ b/contrib/pageinspect/expected/gin.out @@ -0,0 +1,30 @@ +CREATE TABLE test1 (x int, y int[]); +INSERT INTO test1 VALUES (1, ARRAY[11, 111]); +CREATE INDEX test1_y_idx ON test1 USING gin (y); +\x +SELECT * FROM gin_metapage_info(get_raw_page('test1_y_idx', 0)); +-[ RECORD 1 ]----+----------- +pending_head | 4294967295 +pending_tail | 4294967295 +tail_free_size | 0 +n_pending_pages | 0 +n_pending_tuples | 0 +n_total_pages | 2 +n_entry_pages | 1 +n_data_pages | 0 +n_entries | 2 +version | 2 + +SELECT * FROM gin_metapage_info(get_raw_page('test1_y_idx', 1)); +ERROR: input page is not a GIN metapage +DETAIL: Flags 0002, expected 0008 +SELECT * FROM gin_page_opaque_info(get_raw_page('test1_y_idx', 1)); +-[ RECORD 1 ]--------- +rightlink | 4294967295 +maxoff | 0 +flags | {leaf} + +SELECT * FROM gin_leafpage_items(get_raw_page('test1_y_idx', 1)); +ERROR: input page is not a compressed GIN data leaf page +DETAIL: Flags 0002, expected 0083 +DROP TABLE test1; diff --git a/contrib/pageinspect/expected/page.out b/contrib/pageinspect/expected/page.out new file mode 100644 index 0000000000..673a8529a6 --- /dev/null +++ b/contrib/pageinspect/expected/page.out @@ -0,0 +1,73 @@ +CREATE EXTENSION pageinspect; +CREATE TABLE test1 (a int, b text); +INSERT INTO test1 VALUES (1, 'one'); +VACUUM test1; -- set up FSM +-- The page contents can vary, so just test that it can be read +-- successfully, but don't keep the output. +SELECT octet_length(get_raw_page('test1', 'main', 0)) AS main_0; + main_0 +-------- + 8192 +(1 row) + +SELECT octet_length(get_raw_page('test1', 'main', 1)) AS main_1; +ERROR: block number 1 is out of range for relation "test1" +SELECT octet_length(get_raw_page('test1', 'fsm', 0)) AS fsm_0; + fsm_0 +------- + 8192 +(1 row) + +SELECT octet_length(get_raw_page('test1', 'fsm', 1)) AS fsm_1; + fsm_1 +------- + 8192 +(1 row) + +SELECT octet_length(get_raw_page('test1', 'vm', 0)) AS vm_0; + vm_0 +------ + 8192 +(1 row) + +SELECT octet_length(get_raw_page('test1', 'vm', 1)) AS vm_1; +ERROR: block number 1 is out of range for relation "test1" +SELECT octet_length(get_raw_page('xxx', 'main', 0)); +ERROR: relation "xxx" does not exist +SELECT octet_length(get_raw_page('test1', 'xxx', 0)); +ERROR: invalid fork name +HINT: Valid fork names are "main", "fsm", "vm", and "init". +SELECT get_raw_page('test1', 0) = get_raw_page('test1', 'main', 0); + ?column? +---------- + t +(1 row) + +SELECT tuple_data_split('test1'::regclass, t_data, t_infomask, t_infomask2, t_bits) + FROM heap_page_items(get_raw_page('test1', 0)); + tuple_data_split +------------------------------- + {"\\x01000000","\\x096f6e65"} +(1 row) + +SELECT * FROM fsm_page_contents(get_raw_page('test1', 'fsm', 0)); + fsm_page_contents +------------------- + 0: 254 + + 1: 254 + + 3: 254 + + 7: 254 + + 15: 254 + + 31: 254 + + 63: 254 + + 127: 254 + + 255: 254 + + 511: 254 + + 1023: 254 + + 2047: 254 + + 4095: 254 + + fp_next_slot: 0 + + +(1 row) + +DROP TABLE test1; diff --git a/contrib/pageinspect/sql/brin.sql b/contrib/pageinspect/sql/brin.sql new file mode 100644 index 0000000000..735bc3b673 --- /dev/null +++ b/contrib/pageinspect/sql/brin.sql @@ -0,0 +1,18 @@ +CREATE TABLE test1 (a int, b text); +INSERT INTO test1 VALUES (1, 'one'); +CREATE INDEX test1_a_idx ON test1 USING brin (a); + +SELECT brin_page_type(get_raw_page('test1_a_idx', 0)); +SELECT brin_page_type(get_raw_page('test1_a_idx', 1)); +SELECT brin_page_type(get_raw_page('test1_a_idx', 2)); + +SELECT * FROM brin_metapage_info(get_raw_page('test1_a_idx', 0)); +SELECT * FROM brin_metapage_info(get_raw_page('test1_a_idx', 1)); + +SELECT * FROM brin_revmap_data(get_raw_page('test1_a_idx', 0)) LIMIT 5; +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; + +DROP TABLE test1; diff --git a/contrib/pageinspect/sql/btree.sql b/contrib/pageinspect/sql/btree.sql new file mode 100644 index 0000000000..4fa3416c73 --- /dev/null +++ b/contrib/pageinspect/sql/btree.sql @@ -0,0 +1,17 @@ +CREATE TABLE test1 (a int, b text); +INSERT INTO test1 VALUES (1, 'one'); +CREATE INDEX test1_a_idx ON test1 USING btree (a); + +\x + +SELECT * FROM bt_metap('test1_a_idx'); + +SELECT * FROM bt_page_stats('test1_a_idx', 0); +SELECT * FROM bt_page_stats('test1_a_idx', 1); +SELECT * FROM bt_page_stats('test1_a_idx', 2); + +SELECT * FROM bt_page_items('test1_a_idx', 0); +SELECT * FROM bt_page_items('test1_a_idx', 1); +SELECT * FROM bt_page_items('test1_a_idx', 2); + +DROP TABLE test1; diff --git a/contrib/pageinspect/sql/gin.sql b/contrib/pageinspect/sql/gin.sql new file mode 100644 index 0000000000..ba79ff2108 --- /dev/null +++ b/contrib/pageinspect/sql/gin.sql @@ -0,0 +1,14 @@ +CREATE TABLE test1 (x int, y int[]); +INSERT INTO test1 VALUES (1, ARRAY[11, 111]); +CREATE INDEX test1_y_idx ON test1 USING gin (y); + +\x + +SELECT * FROM gin_metapage_info(get_raw_page('test1_y_idx', 0)); +SELECT * FROM gin_metapage_info(get_raw_page('test1_y_idx', 1)); + +SELECT * FROM gin_page_opaque_info(get_raw_page('test1_y_idx', 1)); + +SELECT * FROM gin_leafpage_items(get_raw_page('test1_y_idx', 1)); + +DROP TABLE test1; diff --git a/contrib/pageinspect/sql/page.sql b/contrib/pageinspect/sql/page.sql new file mode 100644 index 0000000000..a304151f07 --- /dev/null +++ b/contrib/pageinspect/sql/page.sql @@ -0,0 +1,30 @@ +CREATE EXTENSION pageinspect; + +CREATE TABLE test1 (a int, b text); +INSERT INTO test1 VALUES (1, 'one'); + +VACUUM test1; -- set up FSM + +-- The page contents can vary, so just test that it can be read +-- successfully, but don't keep the output. + +SELECT octet_length(get_raw_page('test1', 'main', 0)) AS main_0; +SELECT octet_length(get_raw_page('test1', 'main', 1)) AS main_1; + +SELECT octet_length(get_raw_page('test1', 'fsm', 0)) AS fsm_0; +SELECT octet_length(get_raw_page('test1', 'fsm', 1)) AS fsm_1; + +SELECT octet_length(get_raw_page('test1', 'vm', 0)) AS vm_0; +SELECT octet_length(get_raw_page('test1', 'vm', 1)) AS vm_1; + +SELECT octet_length(get_raw_page('xxx', 'main', 0)); +SELECT octet_length(get_raw_page('test1', 'xxx', 0)); + +SELECT get_raw_page('test1', 0) = get_raw_page('test1', 'main', 0); + +SELECT tuple_data_split('test1'::regclass, t_data, t_infomask, t_infomask2, t_bits) + FROM heap_page_items(get_raw_page('test1', 0)); + +SELECT * FROM fsm_page_contents(get_raw_page('test1', 'fsm', 0)); + +DROP TABLE test1;