On Mon, Feb 24, 2014 at 11:34 PM, Alvaro Herrera <alvhe...@2ndquadrant.com> wrote: > > Andres Freund escribió: > > On 2014-02-24 17:53:31 +0900, Michael Paquier wrote: > > > On Sun, Feb 23, 2014 at 6:09 AM, Alvaro Herrera > > > <alvhe...@2ndquadrant.com>wrote: > > > > > > > Michael Paquier escribió: > > > > > Hi all, > > > > > > > > > > Please find attached a patch to dump pageinspect to 1.2. This > > > > > simply changes page_header to use the new internal datatype > > > > > pg_lsn instead of text. > > > > > > > > Uhm. Does this crash if you pg_upgrade a server that has 1.1 > > > > installed? > > > > > > > Oops yes you're right., it is obviously broken. Just re-thinking > > > about that, dumping this module just to change an argument type does > > > not seem to be worth the code complication. Thoughts? > > > > It seem simple to support both, old and new type. page_header() (which > > IIRC is the only thing returning an LSN) likely uses > > get_call_result_type(). So you can just check what it's > > expecting. Either support both types or error out if it's the old > > extension version. > > Yeah, erroring out seems good enough. Particularly if you add a hint > saying "please upgrade the extension". Done this way by checking the type OID of TupleDesc returned by get_call_result_type. Supporting both formats just adds complexity for no real gain. -- Michael
diff --git a/contrib/pageinspect/Makefile b/contrib/pageinspect/Makefile index 0e267eb..ee78cb2 100644 --- a/contrib/pageinspect/Makefile +++ b/contrib/pageinspect/Makefile @@ -4,8 +4,8 @@ MODULE_big = pageinspect OBJS = rawpage.o heapfuncs.o btreefuncs.o fsmfuncs.o EXTENSION = pageinspect -DATA = pageinspect--1.1.sql pageinspect--1.0--1.1.sql \ - pageinspect--unpackaged--1.0.sql +DATA = pageinspect--1.2.sql pageinspect--1.0--1.1.sql \ + pageinspect--1.1--1.2.sql pageinspect--unpackaged--1.0.sql ifdef USE_PGXS PG_CONFIG = pg_config diff --git a/contrib/pageinspect/pageinspect--1.1--1.2.sql b/contrib/pageinspect/pageinspect--1.1--1.2.sql new file mode 100644 index 0000000..5e23ca4 --- /dev/null +++ b/contrib/pageinspect/pageinspect--1.1--1.2.sql @@ -0,0 +1,18 @@ +/* contrib/pageinspect/pageinspect--1.1--1.2.sql */ + +-- complain if script is sourced in psql, rather than via ALTER EXTENSION +\echo Use "ALTER EXTENSION pageinspect UPDATE TO 1.2" to load this file. \quit + +DROP FUNCTION page_header(bytea); +CREATE FUNCTION page_header(IN 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) +AS 'MODULE_PATHNAME', 'page_header' +LANGUAGE C STRICT; diff --git a/contrib/pageinspect/pageinspect--1.1.sql b/contrib/pageinspect/pageinspect--1.1.sql deleted file mode 100644 index 22a47d5..0000000 --- a/contrib/pageinspect/pageinspect--1.1.sql +++ /dev/null @@ -1,107 +0,0 @@ -/* contrib/pageinspect/pageinspect--1.1.sql */ - --- complain if script is sourced in psql, rather than via CREATE EXTENSION -\echo Use "CREATE EXTENSION pageinspect" to load this file. \quit - --- --- get_raw_page() --- -CREATE FUNCTION get_raw_page(text, int4) -RETURNS bytea -AS 'MODULE_PATHNAME', 'get_raw_page' -LANGUAGE C STRICT; - -CREATE FUNCTION get_raw_page(text, text, int4) -RETURNS bytea -AS 'MODULE_PATHNAME', 'get_raw_page_fork' -LANGUAGE C STRICT; - --- --- page_header() --- -CREATE FUNCTION page_header(IN page bytea, - OUT lsn text, - 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) -AS 'MODULE_PATHNAME', 'page_header' -LANGUAGE C STRICT; - --- --- heap_page_items() --- -CREATE FUNCTION heap_page_items(IN page bytea, - OUT lp smallint, - OUT lp_off smallint, - OUT lp_flags smallint, - OUT lp_len smallint, - OUT t_xmin xid, - OUT t_xmax xid, - OUT t_field3 int4, - OUT t_ctid tid, - OUT t_infomask2 integer, - OUT t_infomask integer, - OUT t_hoff smallint, - OUT t_bits text, - OUT t_oid oid) -RETURNS SETOF record -AS 'MODULE_PATHNAME', 'heap_page_items' -LANGUAGE C STRICT; - --- --- bt_metap() --- -CREATE FUNCTION bt_metap(IN relname text, - OUT magic int4, - OUT version int4, - OUT root int4, - OUT level int4, - OUT fastroot int4, - OUT fastlevel int4) -AS 'MODULE_PATHNAME', 'bt_metap' -LANGUAGE C STRICT; - --- --- bt_page_stats() --- -CREATE FUNCTION bt_page_stats(IN relname text, IN blkno int4, - OUT blkno int4, - OUT type "char", - OUT live_items int4, - OUT dead_items int4, - OUT avg_item_size int4, - OUT page_size int4, - OUT free_size int4, - OUT btpo_prev int4, - OUT btpo_next int4, - OUT btpo int4, - OUT btpo_flags int4) -AS 'MODULE_PATHNAME', 'bt_page_stats' -LANGUAGE C STRICT; - --- --- bt_page_items() --- -CREATE FUNCTION bt_page_items(IN relname text, IN blkno int4, - OUT itemoffset smallint, - OUT ctid tid, - OUT itemlen smallint, - OUT nulls bool, - OUT vars bool, - OUT data text) -RETURNS SETOF record -AS 'MODULE_PATHNAME', 'bt_page_items' -LANGUAGE C STRICT; - --- --- fsm_page_contents() --- -CREATE FUNCTION fsm_page_contents(IN page bytea) -RETURNS text -AS 'MODULE_PATHNAME', 'fsm_page_contents' -LANGUAGE C STRICT; diff --git a/contrib/pageinspect/pageinspect--1.2.sql b/contrib/pageinspect/pageinspect--1.2.sql new file mode 100644 index 0000000..15e8e1e --- /dev/null +++ b/contrib/pageinspect/pageinspect--1.2.sql @@ -0,0 +1,107 @@ +/* contrib/pageinspect/pageinspect--1.2.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION pageinspect" to load this file. \quit + +-- +-- get_raw_page() +-- +CREATE FUNCTION get_raw_page(text, int4) +RETURNS bytea +AS 'MODULE_PATHNAME', 'get_raw_page' +LANGUAGE C STRICT; + +CREATE FUNCTION get_raw_page(text, text, int4) +RETURNS bytea +AS 'MODULE_PATHNAME', 'get_raw_page_fork' +LANGUAGE C STRICT; + +-- +-- page_header() +-- +CREATE FUNCTION page_header(IN 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) +AS 'MODULE_PATHNAME', 'page_header' +LANGUAGE C STRICT; + +-- +-- heap_page_items() +-- +CREATE FUNCTION heap_page_items(IN page bytea, + OUT lp smallint, + OUT lp_off smallint, + OUT lp_flags smallint, + OUT lp_len smallint, + OUT t_xmin xid, + OUT t_xmax xid, + OUT t_field3 int4, + OUT t_ctid tid, + OUT t_infomask2 integer, + OUT t_infomask integer, + OUT t_hoff smallint, + OUT t_bits text, + OUT t_oid oid) +RETURNS SETOF record +AS 'MODULE_PATHNAME', 'heap_page_items' +LANGUAGE C STRICT; + +-- +-- bt_metap() +-- +CREATE FUNCTION bt_metap(IN relname text, + OUT magic int4, + OUT version int4, + OUT root int4, + OUT level int4, + OUT fastroot int4, + OUT fastlevel int4) +AS 'MODULE_PATHNAME', 'bt_metap' +LANGUAGE C STRICT; + +-- +-- bt_page_stats() +-- +CREATE FUNCTION bt_page_stats(IN relname text, IN blkno int4, + OUT blkno int4, + OUT type "char", + OUT live_items int4, + OUT dead_items int4, + OUT avg_item_size int4, + OUT page_size int4, + OUT free_size int4, + OUT btpo_prev int4, + OUT btpo_next int4, + OUT btpo int4, + OUT btpo_flags int4) +AS 'MODULE_PATHNAME', 'bt_page_stats' +LANGUAGE C STRICT; + +-- +-- bt_page_items() +-- +CREATE FUNCTION bt_page_items(IN relname text, IN blkno int4, + OUT itemoffset smallint, + OUT ctid tid, + OUT itemlen smallint, + OUT nulls bool, + OUT vars bool, + OUT data text) +RETURNS SETOF record +AS 'MODULE_PATHNAME', 'bt_page_items' +LANGUAGE C STRICT; + +-- +-- fsm_page_contents() +-- +CREATE FUNCTION fsm_page_contents(IN page bytea) +RETURNS text +AS 'MODULE_PATHNAME', 'fsm_page_contents' +LANGUAGE C STRICT; diff --git a/contrib/pageinspect/pageinspect.control b/contrib/pageinspect/pageinspect.control index a412cf1..aecd91a 100644 --- a/contrib/pageinspect/pageinspect.control +++ b/contrib/pageinspect/pageinspect.control @@ -1,5 +1,5 @@ # pageinspect extension comment = 'inspect the contents of database pages at a low level' -default_version = '1.1' +default_version = '1.2' module_pathname = '$libdir/pageinspect' relocatable = true diff --git a/contrib/pageinspect/rawpage.c b/contrib/pageinspect/rawpage.c index ff541ed..35a690c 100644 --- a/contrib/pageinspect/rawpage.c +++ b/contrib/pageinspect/rawpage.c @@ -18,10 +18,12 @@ #include "access/htup_details.h" #include "catalog/catalog.h" #include "catalog/namespace.h" +#include "catalog/pg_type.h" #include "funcapi.h" #include "miscadmin.h" #include "storage/bufmgr.h" #include "utils/builtins.h" +#include "utils/pg_lsn.h" #include "utils/rel.h" PG_MODULE_MAGIC; @@ -180,7 +182,6 @@ page_header(PG_FUNCTION_ARGS) PageHeader page; XLogRecPtr lsn; - char lsnchar[64]; if (!superuser()) ereport(ERROR, @@ -204,13 +205,20 @@ page_header(PG_FUNCTION_ARGS) if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) elog(ERROR, "return type must be a row type"); + /* + * Do some version-related checks. pageinspect >= 1.2 uses pg_lsn + * instead of text when using this function for the LSN field. + */ + if (tupdesc->attrs[0]->atttypid == TEXTOID) + ereport(ERROR, + (errmsg("incompatible version detected"), + errhint("Upgrade pageinspect at least to 1.2."))); + /* Extract information from the page header */ lsn = PageGetLSN(page); - snprintf(lsnchar, sizeof(lsnchar), "%X/%X", - (uint32) (lsn >> 32), (uint32) lsn); - values[0] = CStringGetTextDatum(lsnchar); + values[0] = LSNGetDatum(lsn); values[1] = UInt16GetDatum(page->pd_checksum); values[2] = UInt16GetDatum(page->pd_flags); values[3] = UInt16GetDatum(page->pd_lower);
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers