diff options
Diffstat (limited to 'contrib/pageinspect/sql')
-rw-r--r-- | contrib/pageinspect/sql/brin.sql | 39 | ||||
-rw-r--r-- | contrib/pageinspect/sql/btree.sql | 62 | ||||
-rw-r--r-- | contrib/pageinspect/sql/checksum.sql | 31 | ||||
-rw-r--r-- | contrib/pageinspect/sql/gin.sql | 41 | ||||
-rw-r--r-- | contrib/pageinspect/sql/gist.sql | 69 | ||||
-rw-r--r-- | contrib/pageinspect/sql/hash.sql | 113 | ||||
-rw-r--r-- | contrib/pageinspect/sql/oldextversions.sql | 26 | ||||
-rw-r--r-- | contrib/pageinspect/sql/page.sql | 100 |
8 files changed, 481 insertions, 0 deletions
diff --git a/contrib/pageinspect/sql/brin.sql b/contrib/pageinspect/sql/brin.sql new file mode 100644 index 0000000..96b4645 --- /dev/null +++ b/contrib/pageinspect/sql/brin.sql @@ -0,0 +1,39 @@ +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; + +-- Mask DETAIL messages as these are not portable across architectures. +\set VERBOSITY terse + +-- Failures 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'); +SELECT brin_page_items(get_raw_page('test1_a_btree', 0), 'test1_a_idx'); + +-- 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 + +-- 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 new file mode 100644 index 0000000..102ebde --- /dev/null +++ b/contrib/pageinspect/sql/btree.sql @@ -0,0 +1,62 @@ +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'); + +SELECT * FROM bt_page_stats('test1_a_idx', -1); +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); + +-- bt_multi_page_stats() function returns a set of records of page statistics. +CREATE TABLE test2 AS (SELECT generate_series(1, 1000)::int8 AS col1); +CREATE INDEX test2_col1_idx ON test2(col1); +SELECT * FROM bt_multi_page_stats('test2_col1_idx', 0, 1); +SELECT * FROM bt_multi_page_stats('test2_col1_idx', 1, -1); +SELECT * FROM bt_multi_page_stats('test2_col1_idx', 1, 0); +SELECT * FROM bt_multi_page_stats('test2_col1_idx', 1, 2); +SELECT * FROM bt_multi_page_stats('test2_col1_idx', 3, 2); +SELECT * FROM bt_multi_page_stats('test2_col1_idx', 7, 2); +DROP TABLE test2; + +SELECT * FROM bt_page_items('test1_a_idx', -1); +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); + +SELECT * FROM bt_page_items(get_raw_page('test1_a_idx', -1)); +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); +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)); + +-- Several failure modes. +-- Suppress the DETAIL message, to allow the tests to work across various +-- 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 + +-- 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/checksum.sql b/contrib/pageinspect/sql/checksum.sql new file mode 100644 index 0000000..b877db0 --- /dev/null +++ b/contrib/pageinspect/sql/checksum.sql @@ -0,0 +1,31 @@ +-- +-- Verify correct calculation of checksums +-- +-- Postgres' checksum algorithm produces different answers on little-endian +-- and big-endian machines. The results of this test also vary depending +-- on the configured block size. This test has several different expected +-- results files to handle the following possibilities: +-- +-- BLCKSZ end file +-- 8K LE checksum.out +-- 8K BE checksum_1.out +-- +-- In future we might provide additional expected-results files for other +-- block sizes, but there seems little point as long as so many other +-- test scripts also show false failures for non-default block sizes. +-- + +-- This is to label the results files with blocksize: +SHOW block_size; + +SHOW block_size \gset + +-- Apply page_checksum() to some different data patterns and block numbers +SELECT blkno, + page_checksum(decode(repeat('01', :block_size), 'hex'), blkno) AS checksum_01, + page_checksum(decode(repeat('04', :block_size), 'hex'), blkno) AS checksum_04, + page_checksum(decode(repeat('ff', :block_size), 'hex'), blkno) AS checksum_ff, + page_checksum(decode(repeat('abcd', :block_size / 2), 'hex'), blkno) AS checksum_abcd, + page_checksum(decode(repeat('e6d6', :block_size / 2), 'hex'), blkno) AS checksum_e6d6, + page_checksum(decode(repeat('4a5e', :block_size / 2), 'hex'), blkno) AS checksum_4a5e + FROM generate_series(0, 100, 50) AS a (blkno); diff --git a/contrib/pageinspect/sql/gin.sql b/contrib/pageinspect/sql/gin.sql new file mode 100644 index 0000000..b57466d --- /dev/null +++ b/contrib/pageinspect/sql/gin.sql @@ -0,0 +1,41 @@ +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) WITH (fastupdate = off); + +\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)); + +INSERT INTO test1 SELECT x, ARRAY[1,10] FROM generate_series(2,10000) x; + +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 various modes. +-- Suppress the DETAIL message, to allow the tests to work across various +-- 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 + +-- 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')); + +DROP TABLE test1; diff --git a/contrib/pageinspect/sql/gist.sql b/contrib/pageinspect/sql/gist.sql new file mode 100644 index 0000000..d263542 --- /dev/null +++ b/contrib/pageinspect/sql/gist.sql @@ -0,0 +1,69 @@ +-- The gist_page_opaque_info() function prints the page's LSN. Normally, +-- that's constant 1 (GistBuildLSN) on every page of a freshly built GiST +-- index. But with wal_level=minimal, the whole relation is dumped to WAL at +-- the end of the transaction if it's smaller than wal_skip_threshold, which +-- updates the LSNs. Wrap the tests on gist_page_opaque_info() in the +-- same transaction with the CREATE INDEX so that we see the LSNs before +-- they are possibly overwritten at end of transaction. +BEGIN; + +-- Create a test table and GiST index. +CREATE TABLE test_gist AS SELECT point(i,i) p, i::text t FROM + generate_series(1,1000) i; +CREATE INDEX test_gist_idx ON test_gist USING gist (p); + +-- Page 0 is the root, the rest are leaf pages +SELECT * FROM gist_page_opaque_info(get_raw_page('test_gist_idx', 0)); +SELECT * FROM gist_page_opaque_info(get_raw_page('test_gist_idx', 1)); +SELECT * FROM gist_page_opaque_info(get_raw_page('test_gist_idx', 2)); + +COMMIT; + +SELECT * FROM gist_page_items(get_raw_page('test_gist_idx', 0), 'test_gist_idx'); +SELECT * FROM gist_page_items(get_raw_page('test_gist_idx', 1), 'test_gist_idx') LIMIT 5; + +-- gist_page_items_bytea prints the raw key data as a bytea. The output of that is +-- platform-dependent (endianness), so omit the actual key data from the output. +SELECT itemoffset, ctid, itemlen FROM gist_page_items_bytea(get_raw_page('test_gist_idx', 0)); + +-- Suppress the DETAIL message, to allow the tests to work across various +-- page sizes and architectures. +\set VERBOSITY terse + +-- Failures with non-GiST index. +CREATE INDEX test_gist_btree on test_gist(t); +SELECT gist_page_items(get_raw_page('test_gist_btree', 0), 'test_gist_btree'); +SELECT gist_page_items(get_raw_page('test_gist_btree', 0), 'test_gist_idx'); + +-- Failure with various modes. +-- invalid page size +SELECT gist_page_items_bytea('aaa'::bytea); +SELECT gist_page_items('aaa'::bytea, 'test_gist_idx'::regclass); +SELECT gist_page_opaque_info('aaa'::bytea); +-- invalid special area size +SELECT * FROM gist_page_opaque_info(get_raw_page('test_gist', 0)); +SELECT gist_page_items_bytea(get_raw_page('test_gist', 0)); +SELECT gist_page_items_bytea(get_raw_page('test_gist_btree', 0)); +\set VERBOSITY default + +-- Tests with all-zero pages. +SHOW block_size \gset +SELECT gist_page_items_bytea(decode(repeat('00', :block_size), 'hex')); +SELECT gist_page_items(decode(repeat('00', :block_size), 'hex'), 'test_gist_idx'::regclass); +SELECT gist_page_opaque_info(decode(repeat('00', :block_size), 'hex')); + +-- Test gist_page_items with included columns. +-- Non-leaf pages contain only the key attributes, and leaf pages contain +-- the included attributes. +ALTER TABLE test_gist ADD COLUMN i int DEFAULT NULL; +CREATE INDEX test_gist_idx_inc ON test_gist + USING gist (p) INCLUDE (t, i); +-- Mask the value of the key attribute to avoid alignment issues. +SELECT regexp_replace(keys, '\(p\)=\("(.*?)"\)', '(p)=("<val>")') AS keys_nonleaf_1 + FROM gist_page_items(get_raw_page('test_gist_idx_inc', 0), 'test_gist_idx_inc') + WHERE itemoffset = 1; +SELECT keys AS keys_leaf_1 + FROM gist_page_items(get_raw_page('test_gist_idx_inc', 1), 'test_gist_idx_inc') + WHERE itemoffset = 1; + +DROP TABLE test_gist; diff --git a/contrib/pageinspect/sql/hash.sql b/contrib/pageinspect/sql/hash.sql new file mode 100644 index 0000000..e4b9e97 --- /dev/null +++ b/contrib/pageinspect/sql/hash.sql @@ -0,0 +1,113 @@ +CREATE TABLE test_hash (a int, b text); +INSERT INTO test_hash VALUES (1, 'one'); +CREATE INDEX test_hash_a_idx ON test_hash USING hash (a); + +CREATE TABLE test_hash_part (a int, b int) PARTITION BY RANGE (a); +CREATE INDEX test_hash_part_idx ON test_hash_part USING hash(b); + +\x + +SELECT hash_page_type(get_raw_page('test_hash_a_idx', 0)); +SELECT hash_page_type(get_raw_page('test_hash_a_idx', 1)); +SELECT hash_page_type(get_raw_page('test_hash_a_idx', 2)); +SELECT hash_page_type(get_raw_page('test_hash_a_idx', 3)); +SELECT hash_page_type(get_raw_page('test_hash_a_idx', 4)); +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', -1); +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('test_hash_a_idx', 6); +SELECT * FROM hash_bitmap_info('test_hash_part_idx', 1); -- error + + +SELECT magic, version, ntuples, bsize, bmsize, bmshift, maxbucket, highmask, +lowmask, ovflpoint, firstfree, nmaps, procid, spares, mapp FROM +hash_metapage_info(get_raw_page('test_hash_a_idx', 0)); + +SELECT magic, version, ntuples, bsize, bmsize, bmshift, maxbucket, highmask, +lowmask, ovflpoint, firstfree, nmaps, procid, spares, mapp FROM +hash_metapage_info(get_raw_page('test_hash_a_idx', 1)); + +SELECT magic, version, ntuples, bsize, bmsize, bmshift, maxbucket, highmask, +lowmask, ovflpoint, firstfree, nmaps, procid, spares, mapp FROM +hash_metapage_info(get_raw_page('test_hash_a_idx', 2)); + +SELECT magic, version, ntuples, bsize, bmsize, bmshift, maxbucket, highmask, +lowmask, ovflpoint, firstfree, nmaps, procid, spares, mapp FROM +hash_metapage_info(get_raw_page('test_hash_a_idx', 3)); + +SELECT magic, version, ntuples, bsize, bmsize, bmshift, maxbucket, highmask, +lowmask, ovflpoint, firstfree, nmaps, procid, spares, mapp FROM +hash_metapage_info(get_raw_page('test_hash_a_idx', 4)); + +SELECT magic, version, ntuples, bsize, bmsize, bmshift, maxbucket, highmask, +lowmask, ovflpoint, firstfree, nmaps, procid, spares, mapp FROM +hash_metapage_info(get_raw_page('test_hash_a_idx', 5)); + +SELECT live_items, dead_items, page_size, hasho_prevblkno, hasho_nextblkno, +hasho_bucket, hasho_flag, hasho_page_id FROM +hash_page_stats(get_raw_page('test_hash_a_idx', 0)); + +SELECT live_items, dead_items, page_size, hasho_prevblkno, hasho_nextblkno, +hasho_bucket, hasho_flag, hasho_page_id FROM +hash_page_stats(get_raw_page('test_hash_a_idx', 1)); + +SELECT live_items, dead_items, page_size, hasho_prevblkno, hasho_nextblkno, +hasho_bucket, hasho_flag, hasho_page_id FROM +hash_page_stats(get_raw_page('test_hash_a_idx', 2)); + +SELECT live_items, dead_items, page_size, hasho_prevblkno, hasho_nextblkno, +hasho_bucket, hasho_flag, hasho_page_id FROM +hash_page_stats(get_raw_page('test_hash_a_idx', 3)); + +SELECT live_items, dead_items, page_size, hasho_prevblkno, hasho_nextblkno, +hasho_bucket, hasho_flag, hasho_page_id FROM +hash_page_stats(get_raw_page('test_hash_a_idx', 4)); + +SELECT live_items, dead_items, page_size, hasho_prevblkno, hasho_nextblkno, +hasho_bucket, hasho_flag, hasho_page_id FROM +hash_page_stats(get_raw_page('test_hash_a_idx', 5)); + +SELECT * FROM hash_page_items(get_raw_page('test_hash_a_idx', 0)); +SELECT * FROM hash_page_items(get_raw_page('test_hash_a_idx', 1)); +SELECT * FROM hash_page_items(get_raw_page('test_hash_a_idx', 2)); +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 various modes. +-- Suppress the DETAIL message, to allow the tests to work across various +-- 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 + +-- 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; +DROP TABLE test_hash_part; diff --git a/contrib/pageinspect/sql/oldextversions.sql b/contrib/pageinspect/sql/oldextversions.sql new file mode 100644 index 0000000..9f95349 --- /dev/null +++ b/contrib/pageinspect/sql/oldextversions.sql @@ -0,0 +1,26 @@ +-- test old extension version entry points + +DROP EXTENSION pageinspect; +CREATE EXTENSION pageinspect VERSION '1.8'; + +CREATE TABLE test1 (a int8, b text); +INSERT INTO test1 VALUES (72057594037927937, 'text'); +CREATE INDEX test1_a_idx ON test1 USING btree (a); + +-- from page.sql +SELECT octet_length(get_raw_page('test1', 0)) AS main_0; +SELECT octet_length(get_raw_page('test1', 'main', 0)) AS main_0; +SELECT page_checksum(get_raw_page('test1', 0), 0) IS NOT NULL AS silly_checksum_test; + +-- from btree.sql +SELECT * FROM bt_page_stats('test1_a_idx', 1); +SELECT * FROM bt_page_items('test1_a_idx', 1); + +-- page_header() uses int instead of smallint for lower, upper, special and +-- pagesize in pageinspect >= 1.10. +ALTER EXTENSION pageinspect UPDATE TO '1.9'; +\df page_header +SELECT pagesize, version FROM page_header(get_raw_page('test1', 0)); + +DROP TABLE test1; +DROP EXTENSION pageinspect; diff --git a/contrib/pageinspect/sql/page.sql b/contrib/pageinspect/sql/page.sql new file mode 100644 index 0000000..5bff568 --- /dev/null +++ b/contrib/pageinspect/sql/page.sql @@ -0,0 +1,100 @@ +CREATE EXTENSION pageinspect; + +-- Use a temp table so that effects of VACUUM are predictable +CREATE TEMP TABLE test1 (a int, b int); +INSERT INTO test1 VALUES (16777217, 131584); + +VACUUM (DISABLE_PAGE_SKIPPING) 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('test1', 'main', -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 pagesize, version FROM page_header(get_raw_page('test1', 0)); + +SELECT page_checksum(get_raw_page('test1', 0), 0) IS NOT NULL AS silly_checksum_test; +SELECT page_checksum(get_raw_page('test1', 0), -1); + +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)); + +-- If we freeze the only tuple on test1, the infomask should +-- always be the same in all test runs. +VACUUM (FREEZE, DISABLE_PAGE_SKIPPING) test1; + +SELECT t_infomask, t_infomask2, raw_flags, combined_flags +FROM heap_page_items(get_raw_page('test1', 0)), + LATERAL heap_tuple_infomask_flags(t_infomask, t_infomask2); + +-- tests for decoding of combined flags +-- HEAP_XMAX_SHR_LOCK = (HEAP_XMAX_EXCL_LOCK | HEAP_XMAX_KEYSHR_LOCK) +SELECT * FROM heap_tuple_infomask_flags(x'0050'::int, 0); +-- HEAP_XMIN_FROZEN = (HEAP_XMIN_COMMITTED | HEAP_XMIN_INVALID) +SELECT * FROM heap_tuple_infomask_flags(x'0300'::int, 0); +-- HEAP_MOVED = (HEAP_MOVED_IN | HEAP_MOVED_OFF) +SELECT * FROM heap_tuple_infomask_flags(x'C000'::int, 0); +SELECT * FROM heap_tuple_infomask_flags(x'C000'::int, 0); + +-- test all flags of t_infomask and t_infomask2 +SELECT unnest(raw_flags) + FROM heap_tuple_infomask_flags(x'FFFF'::int, x'FFFF'::int) ORDER BY 1; +SELECT unnest(combined_flags) + FROM heap_tuple_infomask_flags(x'FFFF'::int, x'FFFF'::int) ORDER BY 1; + +-- no flags at all +SELECT * FROM heap_tuple_infomask_flags(0, 0); +-- no combined flags +SELECT * FROM heap_tuple_infomask_flags(x'0010'::int, 0); + +DROP TABLE test1; + +-- check that using any of these functions with a partitioned table or index +-- would fail +create table test_partitioned (a int) partition by range (a); +create index test_partitioned_index on test_partitioned (a); +select get_raw_page('test_partitioned', 0); -- error about partitioned table +select get_raw_page('test_partitioned_index', 0); -- error about partitioned index + +-- a regular table which is a member of a partition set should work though +create table test_part1 partition of test_partitioned for values from ( 1 ) to (100); +select get_raw_page('test_part1', 0); -- get farther and error about empty table +drop table test_partitioned; + +-- check null bitmap alignment for table whose number of attributes is multiple of 8 +create table test8 (f1 int, f2 int, f3 int, f4 int, f5 int, f6 int, f7 int, f8 int); +insert into test8(f1, f8) values (x'7f00007f'::int, 0); +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 + +-- 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); |