Skip to content

Commit a1fd650

Browse files
committed
Fix contrib/pageinspect to not create an ABI breakage between 8.3 and 8.4.
The original implementation of the 3-argument form of get_raw_page() risked core dumps if the 8.3 SQL function definition was mistakenly used with the 8.4 module, which is entirely likely after a dump-and-reload upgrade. To protect 8.4 beta testers against upgrade problems, add a check on PG_NARGS. In passing, fix missed additions to the uninstall script, and polish the docs a trifle.
1 parent 506183e commit a1fd650

File tree

4 files changed

+67
-17
lines changed

4 files changed

+67
-17
lines changed

contrib/pageinspect/pageinspect.sql.in

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
1-
/* $PostgreSQL: pgsql/contrib/pageinspect/pageinspect.sql.in,v 1.6 2008/10/06 14:13:17 heikki Exp $ */
1+
/* $PostgreSQL: pgsql/contrib/pageinspect/pageinspect.sql.in,v 1.7 2009/06/08 16:22:44 tgl Exp $ */
22

33
-- Adjust this setting to control where the objects get created.
44
SET search_path = public;
55

66
--
77
-- get_raw_page()
88
--
9-
CREATE OR REPLACE FUNCTION get_raw_page(text, text, int4)
9+
CREATE OR REPLACE FUNCTION get_raw_page(text, int4)
1010
RETURNS bytea
1111
AS 'MODULE_PATHNAME', 'get_raw_page'
1212
LANGUAGE C STRICT;
1313

14-
CREATE OR REPLACE FUNCTION get_raw_page(text, int4)
14+
CREATE OR REPLACE FUNCTION get_raw_page(text, text, int4)
1515
RETURNS bytea
16-
AS $$ SELECT get_raw_page($1, 'main', $2); $$
17-
LANGUAGE SQL STRICT;
16+
AS 'MODULE_PATHNAME', 'get_raw_page_fork'
17+
LANGUAGE C STRICT;
1818

1919
--
2020
-- page_header()

contrib/pageinspect/rawpage.c

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Copyright (c) 2007-2009, PostgreSQL Global Development Group
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/contrib/pageinspect/rawpage.c,v 1.11 2009/03/31 22:54:31 tgl Exp $
11+
* $PostgreSQL: pgsql/contrib/pageinspect/rawpage.c,v 1.12 2009/06/08 16:22:44 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -29,8 +29,13 @@
2929
PG_MODULE_MAGIC;
3030

3131
Datum get_raw_page(PG_FUNCTION_ARGS);
32+
Datum get_raw_page_fork(PG_FUNCTION_ARGS);
3233
Datum page_header(PG_FUNCTION_ARGS);
3334

35+
static bytea *get_raw_page_internal(text *relname, ForkNumber forknum,
36+
BlockNumber blkno);
37+
38+
3439
/*
3540
* get_raw_page
3641
*
@@ -40,15 +45,58 @@ PG_FUNCTION_INFO_V1(get_raw_page);
4045

4146
Datum
4247
get_raw_page(PG_FUNCTION_ARGS)
48+
{
49+
text *relname = PG_GETARG_TEXT_P(0);
50+
uint32 blkno = PG_GETARG_UINT32(1);
51+
bytea *raw_page;
52+
53+
/*
54+
* We don't normally bother to check the number of arguments to a C
55+
* function, but here it's needed for safety because early 8.4 beta
56+
* releases mistakenly redefined get_raw_page() as taking three arguments.
57+
*/
58+
if (PG_NARGS() != 2)
59+
ereport(ERROR,
60+
(errmsg("wrong number of arguments to get_raw_page()"),
61+
errhint("Run the updated pageinspect.sql script.")));
62+
63+
raw_page = get_raw_page_internal(relname, MAIN_FORKNUM, blkno);
64+
65+
PG_RETURN_BYTEA_P(raw_page);
66+
}
67+
68+
/*
69+
* get_raw_page_fork
70+
*
71+
* Same, for any fork
72+
*/
73+
PG_FUNCTION_INFO_V1(get_raw_page_fork);
74+
75+
Datum
76+
get_raw_page_fork(PG_FUNCTION_ARGS)
4377
{
4478
text *relname = PG_GETARG_TEXT_P(0);
4579
text *forkname = PG_GETARG_TEXT_P(1);
4680
uint32 blkno = PG_GETARG_UINT32(2);
81+
bytea *raw_page;
4782
ForkNumber forknum;
4883

49-
Relation rel;
50-
RangeVar *relrv;
84+
forknum = forkname_to_number(text_to_cstring(forkname));
85+
86+
raw_page = get_raw_page_internal(relname, forknum, blkno);
87+
88+
PG_RETURN_BYTEA_P(raw_page);
89+
}
90+
91+
/*
92+
* workhorse
93+
*/
94+
static bytea *
95+
get_raw_page_internal(text *relname, ForkNumber forknum, BlockNumber blkno)
96+
{
5197
bytea *raw_page;
98+
RangeVar *relrv;
99+
Relation rel;
52100
char *raw_page_data;
53101
Buffer buf;
54102

@@ -57,8 +105,6 @@ get_raw_page(PG_FUNCTION_ARGS)
57105
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
58106
(errmsg("must be superuser to use raw functions"))));
59107

60-
forknum = forkname_to_number(text_to_cstring(forkname));
61-
62108
relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname));
63109
rel = relation_openrv(relrv, AccessShareLock);
64110

@@ -105,7 +151,7 @@ get_raw_page(PG_FUNCTION_ARGS)
105151

106152
relation_close(rel, AccessShareLock);
107153

108-
PG_RETURN_BYTEA_P(raw_page);
154+
return raw_page;
109155
}
110156

111157
/*
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1-
/* $PostgreSQL: pgsql/contrib/pageinspect/uninstall_pageinspect.sql,v 1.4 2007/11/13 04:24:28 momjian Exp $ */
1+
/* $PostgreSQL: pgsql/contrib/pageinspect/uninstall_pageinspect.sql,v 1.5 2009/06/08 16:22:44 tgl Exp $ */
22

33
-- Adjust this setting to control where the objects get dropped.
44
SET search_path = public;
55

66
DROP FUNCTION get_raw_page(text, int4);
7+
DROP FUNCTION get_raw_page(text, text, int4);
78
DROP FUNCTION page_header(bytea);
89
DROP FUNCTION heap_page_items(bytea);
910
DROP FUNCTION bt_metap(text);
1011
DROP FUNCTION bt_page_stats(text, int4);
1112
DROP FUNCTION bt_page_items(text, int4);
13+
DROP FUNCTION fsm_page_contents(bytea);

doc/src/sgml/pageinspect.sgml

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!-- $PostgreSQL: pgsql/doc/src/sgml/pageinspect.sgml,v 1.5 2008/10/06 14:13:17 heikki Exp $ -->
1+
<!-- $PostgreSQL: pgsql/doc/src/sgml/pageinspect.sgml,v 1.6 2009/06/08 16:22:44 tgl Exp $ -->
22

33
<sect1 id="pageinspect">
44
<title>pageinspect</title>
@@ -27,8 +27,9 @@
2727
<function>get_raw_page</function> reads the specified block of the named
2828
table and returns a copy as a <type>bytea</> value. This allows a
2929
single time-consistent copy of the block to be obtained.
30-
<literal>fork</literal> should be <literal>'main'</literal> for the main
31-
data fork, or <literal>'fsm'</literal> for the FSM.
30+
<replaceable>fork</replaceable> should be <literal>'main'</literal> for
31+
the main data fork, or <literal>'fsm'</literal> for the free space map,
32+
or <literal>'vm'</literal> for the visibility map.
3233
</para>
3334
</listitem>
3435
</varlistentry>
@@ -40,8 +41,9 @@
4041

4142
<listitem>
4243
<para>
43-
A shorthand of above, for reading from the main fork. Equal to
44-
<literal>get_raw_page(relname, 0, blkno)</literal>
44+
A shorthand version of <function>get_raw_page</function>, for reading
45+
from the main fork. Equivalent to
46+
<literal>get_raw_page(relname, 'main', blkno)</literal>
4547
</para>
4648
</listitem>
4749
</varlistentry>

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