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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 16 additions & 0 deletions
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;
Lines changed: 21 additions & 0 deletions
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;
Lines changed: 1 addition & 1 deletion
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

Lines changed: 27 additions & 4 deletions
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

Lines changed: 6 additions & 0 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy