From a1fd650d2be769cdc0b163177b938e07ddad8ddb Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 8 Jun 2009 16:22:44 +0000 Subject: 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. --- contrib/pageinspect/rawpage.c | 58 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 52 insertions(+), 6 deletions(-) (limited to 'contrib/pageinspect/rawpage.c') diff --git a/contrib/pageinspect/rawpage.c b/contrib/pageinspect/rawpage.c index 91b6a1915f0..00e2535eae6 100644 --- a/contrib/pageinspect/rawpage.c +++ b/contrib/pageinspect/rawpage.c @@ -8,7 +8,7 @@ * Copyright (c) 2007-2009, PostgreSQL Global Development Group * * 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; Datum get_raw_page(PG_FUNCTION_ARGS); +Datum get_raw_page_fork(PG_FUNCTION_ARGS); Datum page_header(PG_FUNCTION_ARGS); +static bytea *get_raw_page_internal(text *relname, ForkNumber forknum, + BlockNumber blkno); + + /* * get_raw_page * @@ -40,15 +45,58 @@ PG_FUNCTION_INFO_V1(get_raw_page); Datum 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 *forkname = PG_GETARG_TEXT_P(1); uint32 blkno = PG_GETARG_UINT32(2); + bytea *raw_page; ForkNumber forknum; - Relation rel; - RangeVar *relrv; + forknum = forkname_to_number(text_to_cstring(forkname)); + + 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; + RangeVar *relrv; + Relation rel; char *raw_page_data; Buffer buf; @@ -57,8 +105,6 @@ get_raw_page(PG_FUNCTION_ARGS) (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), (errmsg("must be superuser to use raw functions")))); - forknum = forkname_to_number(text_to_cstring(forkname)); - relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname)); rel = relation_openrv(relrv, AccessShareLock); @@ -105,7 +151,7 @@ get_raw_page(PG_FUNCTION_ARGS) relation_close(rel, AccessShareLock); - PG_RETURN_BYTEA_P(raw_page); + return raw_page; } /* -- cgit v1.2.3