Skip to content

Commit 127404f

Browse files
committed
pageinspect: Improve page_header() for pages of 32kB
ld_upper, ld_lower, pd_special and the page size have been using smallint as return type, which could cause those fields to return negative values in certain cases for builds configures with a page size of 32kB. Bump pageinspect to 1.10. page_header() is able to handle the correct return type of those fields at runtime when using an older version of the extension, with some tests are added to cover that. Author: Quan Zongliang Reviewed-by: Michael Paquier, Bharath Rupireddy Discussion: https://postgr.es/m/8b8ec36e-61fe-14f9-005d-07bc85aa4eed@yeah.net
1 parent 626731d commit 127404f

File tree

6 files changed

+72
-6
lines changed

6 files changed

+72
-6
lines changed

contrib/pageinspect/Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ OBJS = \
1313
rawpage.o
1414

1515
EXTENSION = pageinspect
16-
DATA = pageinspect--1.8--1.9.sql \
16+
DATA = pageinspect--1.9--1.10.sql pageinspect--1.8--1.9.sql \
1717
pageinspect--1.7--1.8.sql pageinspect--1.6--1.7.sql \
1818
pageinspect--1.5.sql pageinspect--1.5--1.6.sql \
1919
pageinspect--1.4--1.5.sql pageinspect--1.3--1.4.sql \

contrib/pageinspect/expected/oldextversions.out

+16
Original file line numberDiff line numberDiff line change
@@ -36,5 +36,21 @@ SELECT * FROM bt_page_items('test1_a_idx', 1);
3636
1 | (0,1) | 16 | f | f | 01 00 00 00 00 00 00 01 | f | (0,1) |
3737
(1 row)
3838

39+
-- page_header() uses int instead of smallint for lower, upper, special and
40+
-- pagesize in pageinspect >= 1.10.
41+
ALTER EXTENSION pageinspect UPDATE TO '1.9';
42+
\df page_header
43+
List of functions
44+
Schema | Name | Result data type | Argument data types | Type
45+
--------+-------------+------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------
46+
public | page_header | record | page bytea, OUT lsn pg_lsn, OUT checksum smallint, OUT flags smallint, OUT lower smallint, OUT upper smallint, OUT special smallint, OUT pagesize smallint, OUT version smallint, OUT prune_xid xid | func
47+
(1 row)
48+
49+
SELECT pagesize, version FROM page_header(get_raw_page('test1', 0));
50+
pagesize | version
51+
----------+---------
52+
8192 | 4
53+
(1 row)
54+
3955
DROP TABLE test1;
4056
DROP EXTENSION pageinspect;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/* contrib/pageinspect/pageinspect--1.9--1.10.sql */
2+
3+
-- complain if script is sourced in psql, rather than via ALTER EXTENSION
4+
\echo Use "ALTER EXTENSION pageinspect UPDATE TO '1.10'" to load this file. \quit
5+
6+
--
7+
-- page_header()
8+
--
9+
DROP FUNCTION page_header(IN page bytea);
10+
CREATE FUNCTION page_header(IN page bytea,
11+
OUT lsn pg_lsn,
12+
OUT checksum smallint,
13+
OUT flags smallint,
14+
OUT lower int,
15+
OUT upper int,
16+
OUT special int,
17+
OUT pagesize int,
18+
OUT version smallint,
19+
OUT prune_xid xid)
20+
AS 'MODULE_PATHNAME', 'page_header'
21+
LANGUAGE C STRICT PARALLEL SAFE;
+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# pageinspect extension
22
comment = 'inspect the contents of database pages at a low level'
3-
default_version = '1.9'
3+
default_version = '1.10'
44
module_pathname = '$libdir/pageinspect'
55
relocatable = true

contrib/pageinspect/rawpage.c

+27-4
Original file line numberDiff line numberDiff line change
@@ -296,10 +296,33 @@ page_header(PG_FUNCTION_ARGS)
296296
values[0] = LSNGetDatum(lsn);
297297
values[1] = UInt16GetDatum(page->pd_checksum);
298298
values[2] = UInt16GetDatum(page->pd_flags);
299-
values[3] = UInt16GetDatum(page->pd_lower);
300-
values[4] = UInt16GetDatum(page->pd_upper);
301-
values[5] = UInt16GetDatum(page->pd_special);
302-
values[6] = UInt16GetDatum(PageGetPageSize(page));
299+
300+
/* pageinspect >= 1.10 uses int4 instead of int2 for those fields */
301+
switch (TupleDescAttr(tupdesc, 3)->atttypid)
302+
{
303+
case INT2OID:
304+
Assert(TupleDescAttr(tupdesc, 4)->atttypid == INT2OID &&
305+
TupleDescAttr(tupdesc, 5)->atttypid == INT2OID &&
306+
TupleDescAttr(tupdesc, 6)->atttypid == INT2OID);
307+
values[3] = UInt16GetDatum(page->pd_lower);
308+
values[4] = UInt16GetDatum(page->pd_upper);
309+
values[5] = UInt16GetDatum(page->pd_special);
310+
values[6] = UInt16GetDatum(PageGetPageSize(page));
311+
break;
312+
case INT4OID:
313+
Assert(TupleDescAttr(tupdesc, 4)->atttypid == INT4OID &&
314+
TupleDescAttr(tupdesc, 5)->atttypid == INT4OID &&
315+
TupleDescAttr(tupdesc, 6)->atttypid == INT4OID);
316+
values[3] = Int32GetDatum(page->pd_lower);
317+
values[4] = Int32GetDatum(page->pd_upper);
318+
values[5] = Int32GetDatum(page->pd_special);
319+
values[6] = Int32GetDatum(PageGetPageSize(page));
320+
break;
321+
default:
322+
elog(ERROR, "incorrect output types");
323+
break;
324+
}
325+
303326
values[7] = UInt16GetDatum(PageGetPageLayoutVersion(page));
304327
values[8] = TransactionIdGetDatum(page->pd_prune_xid);
305328

contrib/pageinspect/sql/oldextversions.sql

+6
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,11 @@ SELECT page_checksum(get_raw_page('test1', 0), 0) IS NOT NULL AS silly_checksum_
1616
SELECT * FROM bt_page_stats('test1_a_idx', 1);
1717
SELECT * FROM bt_page_items('test1_a_idx', 1);
1818

19+
-- page_header() uses int instead of smallint for lower, upper, special and
20+
-- pagesize in pageinspect >= 1.10.
21+
ALTER EXTENSION pageinspect UPDATE TO '1.9';
22+
\df page_header
23+
SELECT pagesize, version FROM page_header(get_raw_page('test1', 0));
24+
1925
DROP TABLE test1;
2026
DROP EXTENSION pageinspect;

0 commit comments

Comments
 (0)