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.
This commit is contained in:
parent
506183e485
commit
a1fd650d2b
|
@ -1,4 +1,4 @@
|
||||||
/* $PostgreSQL: pgsql/contrib/pageinspect/pageinspect.sql.in,v 1.6 2008/10/06 14:13:17 heikki Exp $ */
|
/* $PostgreSQL: pgsql/contrib/pageinspect/pageinspect.sql.in,v 1.7 2009/06/08 16:22:44 tgl Exp $ */
|
||||||
|
|
||||||
-- Adjust this setting to control where the objects get created.
|
-- Adjust this setting to control where the objects get created.
|
||||||
SET search_path = public;
|
SET search_path = public;
|
||||||
|
@ -6,15 +6,15 @@ SET search_path = public;
|
||||||
--
|
--
|
||||||
-- get_raw_page()
|
-- get_raw_page()
|
||||||
--
|
--
|
||||||
CREATE OR REPLACE FUNCTION get_raw_page(text, text, int4)
|
CREATE OR REPLACE FUNCTION get_raw_page(text, int4)
|
||||||
RETURNS bytea
|
RETURNS bytea
|
||||||
AS 'MODULE_PATHNAME', 'get_raw_page'
|
AS 'MODULE_PATHNAME', 'get_raw_page'
|
||||||
LANGUAGE C STRICT;
|
LANGUAGE C STRICT;
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION get_raw_page(text, int4)
|
CREATE OR REPLACE FUNCTION get_raw_page(text, text, int4)
|
||||||
RETURNS bytea
|
RETURNS bytea
|
||||||
AS $$ SELECT get_raw_page($1, 'main', $2); $$
|
AS 'MODULE_PATHNAME', 'get_raw_page_fork'
|
||||||
LANGUAGE SQL STRICT;
|
LANGUAGE C STRICT;
|
||||||
|
|
||||||
--
|
--
|
||||||
-- page_header()
|
-- page_header()
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
* Copyright (c) 2007-2009, PostgreSQL Global Development Group
|
* Copyright (c) 2007-2009, PostgreSQL Global Development Group
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/contrib/pageinspect/rawpage.c,v 1.11 2009/03/31 22:54:31 tgl Exp $
|
* $PostgreSQL: pgsql/contrib/pageinspect/rawpage.c,v 1.12 2009/06/08 16:22:44 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -29,8 +29,13 @@
|
||||||
PG_MODULE_MAGIC;
|
PG_MODULE_MAGIC;
|
||||||
|
|
||||||
Datum get_raw_page(PG_FUNCTION_ARGS);
|
Datum get_raw_page(PG_FUNCTION_ARGS);
|
||||||
|
Datum get_raw_page_fork(PG_FUNCTION_ARGS);
|
||||||
Datum page_header(PG_FUNCTION_ARGS);
|
Datum page_header(PG_FUNCTION_ARGS);
|
||||||
|
|
||||||
|
static bytea *get_raw_page_internal(text *relname, ForkNumber forknum,
|
||||||
|
BlockNumber blkno);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* get_raw_page
|
* get_raw_page
|
||||||
*
|
*
|
||||||
|
@ -40,15 +45,58 @@ PG_FUNCTION_INFO_V1(get_raw_page);
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
get_raw_page(PG_FUNCTION_ARGS)
|
get_raw_page(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
text *relname = PG_GETARG_TEXT_P(0);
|
||||||
|
uint32 blkno = PG_GETARG_UINT32(1);
|
||||||
|
bytea *raw_page;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We don't normally bother to check the number of arguments to a C
|
||||||
|
* function, but here it's needed for safety because early 8.4 beta
|
||||||
|
* releases mistakenly redefined get_raw_page() as taking three arguments.
|
||||||
|
*/
|
||||||
|
if (PG_NARGS() != 2)
|
||||||
|
ereport(ERROR,
|
||||||
|
(errmsg("wrong number of arguments to get_raw_page()"),
|
||||||
|
errhint("Run the updated pageinspect.sql script.")));
|
||||||
|
|
||||||
|
raw_page = get_raw_page_internal(relname, MAIN_FORKNUM, blkno);
|
||||||
|
|
||||||
|
PG_RETURN_BYTEA_P(raw_page);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* get_raw_page_fork
|
||||||
|
*
|
||||||
|
* Same, for any fork
|
||||||
|
*/
|
||||||
|
PG_FUNCTION_INFO_V1(get_raw_page_fork);
|
||||||
|
|
||||||
|
Datum
|
||||||
|
get_raw_page_fork(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
text *relname = PG_GETARG_TEXT_P(0);
|
text *relname = PG_GETARG_TEXT_P(0);
|
||||||
text *forkname = PG_GETARG_TEXT_P(1);
|
text *forkname = PG_GETARG_TEXT_P(1);
|
||||||
uint32 blkno = PG_GETARG_UINT32(2);
|
uint32 blkno = PG_GETARG_UINT32(2);
|
||||||
|
bytea *raw_page;
|
||||||
ForkNumber forknum;
|
ForkNumber forknum;
|
||||||
|
|
||||||
Relation rel;
|
forknum = forkname_to_number(text_to_cstring(forkname));
|
||||||
RangeVar *relrv;
|
|
||||||
|
raw_page = get_raw_page_internal(relname, forknum, blkno);
|
||||||
|
|
||||||
|
PG_RETURN_BYTEA_P(raw_page);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* workhorse
|
||||||
|
*/
|
||||||
|
static bytea *
|
||||||
|
get_raw_page_internal(text *relname, ForkNumber forknum, BlockNumber blkno)
|
||||||
|
{
|
||||||
bytea *raw_page;
|
bytea *raw_page;
|
||||||
|
RangeVar *relrv;
|
||||||
|
Relation rel;
|
||||||
char *raw_page_data;
|
char *raw_page_data;
|
||||||
Buffer buf;
|
Buffer buf;
|
||||||
|
|
||||||
|
@ -57,8 +105,6 @@ get_raw_page(PG_FUNCTION_ARGS)
|
||||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
||||||
(errmsg("must be superuser to use raw functions"))));
|
(errmsg("must be superuser to use raw functions"))));
|
||||||
|
|
||||||
forknum = forkname_to_number(text_to_cstring(forkname));
|
|
||||||
|
|
||||||
relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname));
|
relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname));
|
||||||
rel = relation_openrv(relrv, AccessShareLock);
|
rel = relation_openrv(relrv, AccessShareLock);
|
||||||
|
|
||||||
|
@ -105,7 +151,7 @@ get_raw_page(PG_FUNCTION_ARGS)
|
||||||
|
|
||||||
relation_close(rel, AccessShareLock);
|
relation_close(rel, AccessShareLock);
|
||||||
|
|
||||||
PG_RETURN_BYTEA_P(raw_page);
|
return raw_page;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
/* $PostgreSQL: pgsql/contrib/pageinspect/uninstall_pageinspect.sql,v 1.4 2007/11/13 04:24:28 momjian Exp $ */
|
/* $PostgreSQL: pgsql/contrib/pageinspect/uninstall_pageinspect.sql,v 1.5 2009/06/08 16:22:44 tgl Exp $ */
|
||||||
|
|
||||||
-- Adjust this setting to control where the objects get dropped.
|
-- Adjust this setting to control where the objects get dropped.
|
||||||
SET search_path = public;
|
SET search_path = public;
|
||||||
|
|
||||||
DROP FUNCTION get_raw_page(text, int4);
|
DROP FUNCTION get_raw_page(text, int4);
|
||||||
|
DROP FUNCTION get_raw_page(text, text, int4);
|
||||||
DROP FUNCTION page_header(bytea);
|
DROP FUNCTION page_header(bytea);
|
||||||
DROP FUNCTION heap_page_items(bytea);
|
DROP FUNCTION heap_page_items(bytea);
|
||||||
DROP FUNCTION bt_metap(text);
|
DROP FUNCTION bt_metap(text);
|
||||||
DROP FUNCTION bt_page_stats(text, int4);
|
DROP FUNCTION bt_page_stats(text, int4);
|
||||||
DROP FUNCTION bt_page_items(text, int4);
|
DROP FUNCTION bt_page_items(text, int4);
|
||||||
|
DROP FUNCTION fsm_page_contents(bytea);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/pageinspect.sgml,v 1.5 2008/10/06 14:13:17 heikki Exp $ -->
|
<!-- $PostgreSQL: pgsql/doc/src/sgml/pageinspect.sgml,v 1.6 2009/06/08 16:22:44 tgl Exp $ -->
|
||||||
|
|
||||||
<sect1 id="pageinspect">
|
<sect1 id="pageinspect">
|
||||||
<title>pageinspect</title>
|
<title>pageinspect</title>
|
||||||
|
@ -27,8 +27,9 @@
|
||||||
<function>get_raw_page</function> reads the specified block of the named
|
<function>get_raw_page</function> reads the specified block of the named
|
||||||
table and returns a copy as a <type>bytea</> value. This allows a
|
table and returns a copy as a <type>bytea</> value. This allows a
|
||||||
single time-consistent copy of the block to be obtained.
|
single time-consistent copy of the block to be obtained.
|
||||||
<literal>fork</literal> should be <literal>'main'</literal> for the main
|
<replaceable>fork</replaceable> should be <literal>'main'</literal> for
|
||||||
data fork, or <literal>'fsm'</literal> for the FSM.
|
the main data fork, or <literal>'fsm'</literal> for the free space map,
|
||||||
|
or <literal>'vm'</literal> for the visibility map.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
@ -40,8 +41,9 @@
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
A shorthand of above, for reading from the main fork. Equal to
|
A shorthand version of <function>get_raw_page</function>, for reading
|
||||||
<literal>get_raw_page(relname, 0, blkno)</literal>
|
from the main fork. Equivalent to
|
||||||
|
<literal>get_raw_page(relname, 'main', blkno)</literal>
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
Loading…
Reference in New Issue