Index: doc/src/sgml/func.sgml
===================================================================
RCS file: /projects/cvsroot/pgsql/doc/src/sgml/func.sgml,v
retrieving revision 1.369
diff -c -r1.369 func.sgml
*** doc/src/sgml/func.sgml 20 Feb 2007 19:59:04 -0000 1.369
--- doc/src/sgml/func.sgml 8 Mar 2007 15:34:26 -0000
***************
*** 10854,10859 ****
--- 10854,11064 ----
at session end, even if the client disconnects ungracefully.)
+
+ Diagnostic Functions
+
+
+ Name Return Type Description
+
+
+
+
+
+
+ heap_get_raw_page(RelName> text>, blockId> int>)
+
+ bytea(BLCKSZ)
+ Get binary copy of a shared buffer page
+
+
+
+
+ raw_page_header(rawpage> bytea>)
+
+ record
+ Show page header fields of a raw page
+
+
+
+
+ raw_page_heap_tuple_headers(rawpage> bytea>)
+
+ setof record
+ Show all tuple headers on heap raw page
+
+
+
+
+
+
+ heap_get_raw_page
+
+
+ heap_get_raw_page> reads one block of the named table and
+ returns a copy as a bytea field. This allows a single time-consistent
+ copy of the block to be made for diagnostic purposes. The block
+ is read from shared memory, so the block is already known Valid
+ when it is read in from disk. Use of this functions is restricted to
+ superusers.
+
+
+
+ raw_page_header
+
+
+ raw_page_header> shows fields which are common to all types
+ of PostgreSQL page, so can be used with both heap and index pages. Use of
+ this function is not restricted to superusers, though a raw page must be
+ provided as input, which can only be gained by a superuser executing
+ heap_get_raw_page>.
+
+ postgres=# select * from raw_page_header(heap_get_raw_page('foo',0));
+
+ lsn | tli | pd_lower | pd_upper | pd_special | version
+ ----------+-----+----------+----------+------------+---------
+ 0/47FC08 | 1 | 420 | 5392 | 8192 | 4
+ (1 row)
+
+ The fields are defined in src/include/storage/bufpage.h>
+
+
+
+ raw_page_heap_tuple_headers
+
+
+ raw_page_heap_tuple_headers> shows all line pointers on a heap page.
+ Most or all of these will be filled with tuples and, when present,
+ tuple headers are shown. All tuples are shown, whether or not
+ the tuples were visible to an MVCC snapshot at the time the raw page
+ was copied. Use of this function is not restricted to superusers, though
+ a raw page must be provided as input, which can only be gained by a
+ superuser executing heap_get_raw_page>.
+
+ postgres=# select * from raw_page_heap_tuple_headers(heap_get_raw_page('foo',0)) limit 1;
+
+ id | ok | lpoff | len | tctid | xmn | cb | xmx | cx | cid | natts | toid | info | hdrsz
+ -----+----+-------+-----+---------+------+----+------+----+-----+-------+------+-------+-------
+ 1 | t | 5420 | 28 | (0,1) | 2223 | c | 0 | i | 0 | 1 | | 10496 | 24
+ 2 | t | 5364 | 28 | (0,2) | 2464 | | 0 | i | 0 | 1 | | 10240 | 24
+ 3 | f | | | | | | | | | | | |
+ 4 | t | 8164 | 28 | (0,2) | 602 | c | 2464 | | 0 | 1 | | 256 | 24
+ 5 | t | 8136 | 28 | (0,5) | 602 | c | 0 | i | 0 | 1 | | 2304 | 24
+
+ The fields shown are defined in detail in
+ src/include/storage/bufpage.h>, some of which are formatted
+ for easier interpretation as shown in the table below.
+
+
+
+
+
+ The infomask field can be accessed using bitwise operators. Fields
+ from t_infomask can be accessed directly using the values shown in
+ src/include/storage/bufpage.h>, as shown below:
+
+ postgres=# select ((~info & 256) = 0) as HEAP_XMIN_COMMITTED from raw_page_heap_tuple_headers(heap_get_raw_page('foo',0)) limit 1;
+ heap_xmin_committed
+ ---------------------
+ t
+ (1 row)
+
+ Values of infomask2 will be 65536 higher than shown in
+ src/include/storage/bufpage.h>, since they have are
+ stored in the high order bits of the info result field.
+
+
***************
*** 11262,11268 ****
...
]]>
! If no table name is avaible, that is, when mapping a query or a
cursor, the string table is used in the first
format, row in the second format.
--- 11467,11473 ----
...
]]>
! If no table name is available, that is, when mapping a query or a
cursor, the string table is used in the first
format, row in the second format.
Index: src/backend/access/heap/heapam.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/access/heap/heapam.c,v
retrieving revision 1.228
diff -c -r1.228 heapam.c
*** src/backend/access/heap/heapam.c 9 Feb 2007 03:35:33 -0000 1.228
--- src/backend/access/heap/heapam.c 8 Mar 2007 15:34:30 -0000
***************
*** 39,44 ****
--- 39,45 ----
*/
#include "postgres.h"
+ #include "funcapi.h"
#include "access/heapam.h"
#include "access/hio.h"
#include "access/multixact.h"
***************
*** 48,57 ****
--- 49,61 ----
#include "access/xact.h"
#include "catalog/catalog.h"
#include "catalog/namespace.h"
+ #include "catalog/pg_type.h"
#include "miscadmin.h"
#include "pgstat.h"
+ #include "storage/bufpage.h"
#include "storage/procarray.h"
#include "storage/smgr.h"
+ #include "utils/builtins.h"
#include "utils/inval.h"
#include "utils/lsyscache.h"
#include "utils/relcache.h"
***************
*** 4008,4010 ****
--- 4012,4448 ----
smgrimmedsync(rel->rd_smgr);
}
}
+
+ /* ----------------------------------------------------------------
+ * Diagnostic functions
+ * ----------------------------------------------------------------
+ */
+
+ /*
+ * heap_get_raw_page
+ *
+ * reads a page from shared buffers into a bytea data blob
+ *
+ * This then allows that page to be analysed in various ways
+ * secure in the knowledge that this is a fully consistent
+ * snapshot of the page.
+ */
+ PG_FUNCTION_INFO_V1(heap_get_raw_page);
+
+ Datum
+ heap_get_raw_page(PG_FUNCTION_ARGS)
+ {
+ text *relname = PG_GETARG_TEXT_P(0);
+ uint32 blkno = PG_GETARG_UINT32(1);
+
+ Relation rel;
+ RangeVar *relrv;
+ bytea *raw_page;
+ char *raw_page_data;
+ Page bufpage;
+ Buffer buf;
+
+ if (!superuser())
+ ereport(ERROR,
+ (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+ (errmsg("must be superuser to get raw page"))));
+
+ relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname));
+ rel = heap_openrv(relrv, AccessShareLock);
+
+ /* check that this relation has storage */
+ if (rel->rd_rel->relkind == RELKIND_VIEW)
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("cannot get raw page from view \"%s\"",
+ RelationGetRelationName(rel))));
+
+ if (blkno >= RelationGetNumberOfBlocks(rel))
+ elog(ERROR, "block number %u is out of range for relation \"%s\"",
+ blkno, RelationGetRelationName(rel));
+
+ /* work on relation */
+ {
+ buf = ReadBuffer(rel, blkno);
+
+ /* work on buffer */
+ {
+ bufpage = BufferGetPage(buf);
+
+ raw_page = (bytea *) palloc(BLCKSZ + VARHDRSZ);
+ SET_VARSIZE(raw_page, BLCKSZ + VARHDRSZ);
+ raw_page_data = VARDATA(raw_page);
+
+ LockBuffer(buf, BUFFER_LOCK_SHARE);
+
+ /* SnapshotEverything */
+ {
+ memcpy(raw_page_data, bufpage, BLCKSZ);
+ }
+ LockBuffer(buf, BUFFER_LOCK_UNLOCK);
+ }
+ ReleaseBuffer(buf);
+ }
+ relation_close(rel, AccessShareLock);
+
+ PG_RETURN_BYTEA_P(raw_page);
+ }
+
+
+ struct page_item_srf_args
+ {
+ TupleDesc tupd;
+ Page page;
+ uint16 offset;
+ };
+
+ /*
+ * raw_page_heap_tuple_headers
+ *
+ * Allow inspection of heap page tuple header fields of a raw page
+ *
+ * raw page must be valid
+ */
+ PG_FUNCTION_INFO_V1(raw_page_heap_tuple_headers);
+
+
+ #define TUPLE_HEADER_ID 0
+ #define TUPLE_HEADER_OK 1
+ #define TUPLE_HEADER_LPOFF 2
+ #define TUPLE_HEADER_LEN 3
+ #define TUPLE_HEADER_TCTID 4
+ #define TUPLE_HEADER_XMN 5
+ #define TUPLE_HEADER_CN 6
+ #define TUPLE_HEADER_XMX 7
+ #define TUPLE_HEADER_CX 8
+ #define TUPLE_HEADER_CID 9
+ #define TUPLE_HEADER_NATTS 10
+ #define TUPLE_HEADER_TOID 11
+ #define TUPLE_HEADER_INFO 12
+ #define TUPLE_HEADER_HDRSZ 13
+ #define TUPLE_HEADER_NUM_FIELDS 14
+
+ #define GET_TEXT(str_) \
+ DirectFunctionCall1(textin, CStringGetDatum(str_))
+
+ Datum
+ raw_page_heap_tuple_headers(PG_FUNCTION_ARGS)
+ {
+ bytea *raw_page = PG_GETARG_BYTEA_P(0);
+
+ FuncCallContext *fctx;
+ MemoryContext mctx;
+ struct page_item_srf_args *inter_call_data = NULL;
+
+ validate_raw_page(raw_page);
+
+ if (SRF_IS_FIRSTCALL())
+ {
+ TupleDesc resultTupleDesc;
+
+ fctx = SRF_FIRSTCALL_INIT();
+ mctx = MemoryContextSwitchTo(fctx->multi_call_memory_ctx);
+
+ inter_call_data = palloc(sizeof(struct page_item_srf_args));
+
+ /*
+ * Construct a tuple descriptor for the result row. This must match this
+ * function's pg_proc entry!
+ */
+ resultTupleDesc = CreateTemplateTupleDesc(TUPLE_HEADER_NUM_FIELDS, false);
+
+ TupleDescInitEntry(resultTupleDesc, (AttrNumber) 1, "id",
+ INT2OID, -1, 0);
+ TupleDescInitEntry(resultTupleDesc, (AttrNumber) 2, "ok",
+ BOOLOID, -1, 0);
+ TupleDescInitEntry(resultTupleDesc, (AttrNumber) 3, "lpoff",
+ INT2OID, -1, 0);
+ TupleDescInitEntry(resultTupleDesc, (AttrNumber) 4, "len",
+ INT2OID, -1, 0);
+ TupleDescInitEntry(resultTupleDesc, (AttrNumber) 5, "tctid",
+ TEXTOID, -1, 0);
+ TupleDescInitEntry(resultTupleDesc, (AttrNumber) 6, "xmn",
+ INT4OID, -1, 0);
+ TupleDescInitEntry(resultTupleDesc, (AttrNumber) 7, "cn",
+ TEXTOID, -1, 0);
+ TupleDescInitEntry(resultTupleDesc, (AttrNumber) 8, "xmx",
+ INT4OID, -1, 0);
+ TupleDescInitEntry(resultTupleDesc, (AttrNumber) 9, "cx",
+ TEXTOID, -1, 0);
+ TupleDescInitEntry(resultTupleDesc, (AttrNumber) 10, "cid",
+ INT4OID, -1, 0);
+ TupleDescInitEntry(resultTupleDesc, (AttrNumber) 11, "natts",
+ INT2OID, -1, 0);
+ TupleDescInitEntry(resultTupleDesc, (AttrNumber) 12, "toid",
+ INT4OID, -1, 0);
+ TupleDescInitEntry(resultTupleDesc, (AttrNumber) 13, "info",
+ INT4OID, -1, 0);
+ TupleDescInitEntry(resultTupleDesc, (AttrNumber) 14, "hdrsz",
+ INT2OID, -1, 0);
+
+ inter_call_data->tupd = BlessTupleDesc(resultTupleDesc);
+
+ inter_call_data->offset = FirstOffsetNumber;
+
+ inter_call_data->page = VARDATA(raw_page);
+
+ fctx->max_calls = PageGetMaxOffsetNumber(inter_call_data->page);
+ fctx->user_fctx = inter_call_data;
+
+ MemoryContextSwitchTo(mctx);
+ }
+
+ fctx = SRF_PERCALL_SETUP();
+ inter_call_data = fctx->user_fctx;
+
+ if (fctx->call_cntr < fctx->max_calls)
+ {
+ HeapTuple tuple;
+ Datum result;
+ ItemId id;
+ bool id_IsValid;
+ Datum values[TUPLE_HEADER_NUM_FIELDS];
+ bool nulls[TUPLE_HEADER_NUM_FIELDS];
+
+ id = PageGetItemId(inter_call_data->page, inter_call_data->offset);
+
+ id_IsValid = ItemIdIsValid(id);
+
+ if (id_IsValid)
+ {
+ HeapTupleData tup;
+ HeapTupleHeader tuphdr;
+ char t_ctid[20];
+ BlockNumber blkno;
+ uint32 infomask;
+
+ tuphdr = (HeapTupleHeader) PageGetItem((Page) inter_call_data->page, id);
+ tup.t_len = ItemIdGetLength(id);
+
+ values[TUPLE_HEADER_ID] = UInt32GetDatum(inter_call_data->offset);
+ nulls[TUPLE_HEADER_ID] = false;
+ if (tup.t_len > 0)
+ {
+ values[TUPLE_HEADER_OK] = BoolGetDatum(true);
+ nulls[TUPLE_HEADER_OK] = false;
+
+ values[TUPLE_HEADER_LPOFF] = UInt16GetDatum(ItemIdGetOffset(id));
+ nulls[TUPLE_HEADER_LPOFF] = false;
+
+ values[TUPLE_HEADER_LEN] = UInt32GetDatum(tup.t_len);
+ nulls[TUPLE_HEADER_LEN] = false;
+
+ blkno = BlockIdGetBlockNumber(&(tuphdr->t_ctid.ip_blkid));
+ snprintf(t_ctid, sizeof(t_ctid), "(%u,%u)", blkno, tuphdr->t_ctid.ip_posid);
+ values[TUPLE_HEADER_TCTID] = GET_TEXT(t_ctid);
+ nulls[TUPLE_HEADER_TCTID] = false;
+
+ values[TUPLE_HEADER_XMN] = UInt32GetDatum(HeapTupleHeaderGetXmin(tuphdr));
+ nulls[TUPLE_HEADER_XMN] = false;
+
+ if (tuphdr->t_infomask & HEAP_XMIN_COMMITTED)
+ values[TUPLE_HEADER_CN] = GET_TEXT("c");
+ else if (tuphdr->t_infomask & HEAP_XMIN_INVALID)
+ values[TUPLE_HEADER_CN] = GET_TEXT("i");
+ else
+ values[TUPLE_HEADER_CN] = GET_TEXT(" "); /* blank, rather than NULL */
+ nulls[TUPLE_HEADER_CN] = false;
+
+ values[TUPLE_HEADER_XMX] = UInt32GetDatum(HeapTupleHeaderGetXmax(tuphdr));
+ nulls[TUPLE_HEADER_XMX] = false;
+
+ if (tuphdr->t_infomask & HEAP_XMAX_COMMITTED)
+ values[TUPLE_HEADER_CX] = GET_TEXT("c");
+ else if (tuphdr->t_infomask & HEAP_XMAX_INVALID)
+ values[TUPLE_HEADER_CX] = GET_TEXT("i");
+ else if (tuphdr->t_infomask & HEAP_XMAX_IS_MULTI)
+ values[TUPLE_HEADER_CX] = GET_TEXT("m");
+ else if (tuphdr->t_infomask & HEAP_XMAX_EXCL_LOCK)
+ values[TUPLE_HEADER_CX] = GET_TEXT("x");
+ else if (tuphdr->t_infomask & HEAP_XMAX_SHARED_LOCK)
+ values[TUPLE_HEADER_CX] = GET_TEXT("s");
+ else
+ values[TUPLE_HEADER_CX] = GET_TEXT(" "); /* blank, rather than NULL */
+ nulls[TUPLE_HEADER_CX] = false;
+
+ values[TUPLE_HEADER_CID] = UInt32GetDatum(HeapTupleHeaderGetRawCommandId(tuphdr));
+ nulls[TUPLE_HEADER_CID] = false;
+
+ values[TUPLE_HEADER_NATTS] = UInt16GetDatum(HeapTupleHeaderGetNatts(tuphdr));
+ nulls[TUPLE_HEADER_NATTS] = false;
+
+ values[TUPLE_HEADER_TOID] = UInt32GetDatum(HeapTupleHeaderGetOid(tuphdr));
+ if (values[TUPLE_HEADER_TOID] != InvalidOid)
+ nulls[TUPLE_HEADER_TOID] = false;
+ else
+ nulls[TUPLE_HEADER_TOID] = true;
+
+ infomask = (uint32) tuphdr->t_infomask2;
+ infomask = infomask << 16;
+ infomask = infomask | ((uint32) tuphdr->t_infomask);
+ values[TUPLE_HEADER_INFO] = UInt16GetDatum(infomask);
+ nulls[TUPLE_HEADER_INFO] = false;
+
+ values[TUPLE_HEADER_HDRSZ] = UInt8GetDatum(tuphdr->t_hoff);
+ nulls[TUPLE_HEADER_HDRSZ] = false;
+ }
+ else
+ {
+ /* ItemId is valid, but tuple is zero length so show as invalid */
+ values[TUPLE_HEADER_OK] = BoolGetDatum(false);
+ nulls[TUPLE_HEADER_OK] = false;
+
+ /* Remainder are NULL */
+ nulls[TUPLE_HEADER_LPOFF] = true;
+ nulls[TUPLE_HEADER_LEN] = true;
+ nulls[TUPLE_HEADER_TCTID] = true;
+ nulls[TUPLE_HEADER_XMN] = true;
+ nulls[TUPLE_HEADER_CN] = true;
+ nulls[TUPLE_HEADER_XMX] = true;
+ nulls[TUPLE_HEADER_CX] = true;
+ nulls[TUPLE_HEADER_CID] = true;
+ nulls[TUPLE_HEADER_NATTS] = true;
+ nulls[TUPLE_HEADER_TOID] = true;
+ nulls[TUPLE_HEADER_INFO] = true;
+ nulls[TUPLE_HEADER_HDRSZ] = true;
+ }
+ }
+ else
+ {
+ values[TUPLE_HEADER_ID] = UInt32GetDatum(inter_call_data->offset);
+ nulls[TUPLE_HEADER_ID] = false;
+
+ /* ItemId is invalid */
+ values[TUPLE_HEADER_OK] = BoolGetDatum(false);
+ nulls[TUPLE_HEADER_OK] = false;
+
+ /* Remainder are NULL */
+ nulls[TUPLE_HEADER_LPOFF] = true;
+ nulls[TUPLE_HEADER_LEN] = true;
+ nulls[TUPLE_HEADER_TCTID] = true;
+ nulls[TUPLE_HEADER_XMN] = true;
+ nulls[TUPLE_HEADER_CN] = true;
+ nulls[TUPLE_HEADER_XMX] = true;
+ nulls[TUPLE_HEADER_CX] = true;
+ nulls[TUPLE_HEADER_CID] = true;
+ nulls[TUPLE_HEADER_NATTS] = true;
+ nulls[TUPLE_HEADER_TOID] = true;
+ nulls[TUPLE_HEADER_INFO] = true;
+ nulls[TUPLE_HEADER_HDRSZ] = true;
+ }
+
+ /* Build and return the tuple. */
+ tuple = heap_form_tuple(inter_call_data->tupd, values, nulls);
+ result = HeapTupleGetDatum(tuple);
+
+ inter_call_data->offset += 1;
+
+ SRF_RETURN_NEXT(fctx, result);
+ }
+ else
+ SRF_RETURN_DONE(fctx);
+ }
+
+ /* ----------------------------------------------------------------
+ * Generic page diagnostic functions
+ * ----------------------------------------------------------------
+ */
+
+ /*
+ * validate_raw_page
+ *
+ * validates a raw page - shouldnt be necessary, but somebody may try and
+ * run the raw page functions on arbitrary data, so all raw page
+ * functions should call this to ensure they have good input
+ */
+ void
+ validate_raw_page(bytea *raw_page)
+ {
+ if ((VARSIZE(raw_page) - VARHDRSZ) != BLCKSZ)
+ elog(ERROR,"Invalid raw_page: data length %d does not match BLCKSZ",
+ VARSIZE(raw_page) - VARHDRSZ);
+ }
+
+ /*
+ * raw_page_header
+ *
+ * Allow inspection of page header fields of a raw page
+ *
+ * raw page must be valid
+ */
+
+ #define PAGE_HEADER_LSN 0
+ #define PAGE_HEADER_TLI 1
+ #define PAGE_HEADER_OFFSET_LO 2
+ #define PAGE_HEADER_OFFSET_HI 3
+ #define PAGE_HEADER_OFFSET_SPECIAL 4
+ #define PAGE_HEADER_VERSION 5
+ #define PAGE_HEADER_NUM_FIELDS 6
+
+ PG_FUNCTION_INFO_V1(raw_page_header);
+
+ Datum
+ raw_page_header(PG_FUNCTION_ARGS)
+ {
+ bytea *raw_page = PG_GETARG_BYTEA_P(0);
+
+ Page page;
+
+ Datum values[PAGE_HEADER_NUM_FIELDS];
+ bool nulls[PAGE_HEADER_NUM_FIELDS];
+
+ TupleDesc resultTupleDesc;
+
+ HeapTuple tuple;
+ Datum result;
+ XLogRecPtr lsn;
+ char lsnchar[20];
+
+ validate_raw_page(raw_page);
+
+ page = VARDATA(raw_page);
+
+ /*
+ * Construct a tuple descriptor for the result row. This must match this
+ * function's pg_proc entry!
+ */
+ resultTupleDesc = CreateTemplateTupleDesc(PAGE_HEADER_NUM_FIELDS, false);
+
+ TupleDescInitEntry(resultTupleDesc, (AttrNumber) 1, "lsn",
+ TEXTOID, -1, 0);
+ TupleDescInitEntry(resultTupleDesc, (AttrNumber) 2, "tli",
+ INT4OID, -1, 0);
+ TupleDescInitEntry(resultTupleDesc, (AttrNumber) 3, "pd_lower",
+ INT2OID, -1, 0);
+ TupleDescInitEntry(resultTupleDesc, (AttrNumber) 4, "pd_upper",
+ INT2OID, -1, 0);
+ TupleDescInitEntry(resultTupleDesc, (AttrNumber) 5, "pd_special",
+ INT2OID, -1, 0);
+ TupleDescInitEntry(resultTupleDesc, (AttrNumber) 6, "version",
+ INT2OID, -1, 0);
+
+ resultTupleDesc = BlessTupleDesc(resultTupleDesc);
+
+ lsn = PageGetLSN(page);
+ snprintf(lsnchar, sizeof(lsnchar), "%X/%X", lsn.xlogid, lsn.xrecoff);
+
+ values[PAGE_HEADER_LSN] = DirectFunctionCall1(textin, CStringGetDatum(lsnchar));
+ values[PAGE_HEADER_TLI] = UInt32GetDatum(PageGetTLI(page));
+ values[PAGE_HEADER_OFFSET_LO] = UInt16GetDatum(((PageHeader) (page))->pd_lower);
+ values[PAGE_HEADER_OFFSET_HI] = UInt16GetDatum(((PageHeader) (page))->pd_upper);
+ values[PAGE_HEADER_OFFSET_SPECIAL] = UInt16GetDatum(((PageHeader) (page))->pd_special);
+ values[PAGE_HEADER_VERSION] = UInt16GetDatum(PageGetPageLayoutVersion(page));
+
+ nulls[PAGE_HEADER_LSN] = false;
+ nulls[PAGE_HEADER_TLI] = false;
+ nulls[PAGE_HEADER_OFFSET_LO] = false;
+ nulls[PAGE_HEADER_OFFSET_HI] = false;
+ nulls[PAGE_HEADER_OFFSET_SPECIAL] = false;
+ nulls[PAGE_HEADER_VERSION] = false;
+
+ /* Build and return the tuple. */
+ tuple = heap_form_tuple(resultTupleDesc, values, nulls);
+ result = HeapTupleGetDatum(tuple);
+
+ PG_RETURN_DATUM(result);
+ }
Index: src/include/access/heapam.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/access/heapam.h,v
retrieving revision 1.120
diff -c -r1.120 heapam.h
*** src/include/access/heapam.h 25 Jan 2007 02:17:26 -0000 1.120
--- src/include/access/heapam.h 8 Mar 2007 15:34:31 -0000
***************
*** 241,244 ****
--- 241,254 ----
extern void heap_sync(Relation relation);
+ /* generic raw page functions */
+ extern void validate_raw_page(bytea *raw_page);
+ extern Datum raw_page_header(PG_FUNCTION_ARGS);
+
+ /* raw page functions in other access methods */
+
+ /* heap */
+ extern Datum heap_get_raw_page(PG_FUNCTION_ARGS);
+ extern Datum raw_page_heap_tuple_headers(PG_FUNCTION_ARGS);
+
#endif /* HEAPAM_H */
Index: src/include/catalog/pg_proc.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/catalog/pg_proc.h,v
retrieving revision 1.447
diff -c -r1.447 pg_proc.h
*** src/include/catalog/pg_proc.h 3 Mar 2007 19:52:46 -0000 1.447
--- src/include/catalog/pg_proc.h 8 Mar 2007 15:34:35 -0000
***************
*** 3178,3183 ****
--- 3178,3190 ----
DATA(insert OID = 2851 ( pg_xlogfile_name PGNSP PGUID 12 1 0 f f t f i 1 25 "25" _null_ _null_ _null_ pg_xlogfile_name - _null_ ));
DESCR("xlog filename, given an xlog location");
+ DATA(insert OID = 2931 ( heap_get_raw_page PGNSP PGUID 12 1 0 f f t f v 2 17 "25 23" _null_ _null_ _null_ heap_get_raw_page - _null_ ));
+ DESCR("Get a raw page from shared buffers");
+ DATA(insert OID = 2932 ( raw_page_header PGNSP PGUID 12 1 100 f f t f i 1 2249 "17" "{17,25,23,21,21,21,21}" "{i,o,o,o,o,o,o}" "{rawpage,lsn,tli,pd_lower,pd_upper,pd_special,version}" raw_page_header - _null_ ));
+ DESCR("page header, given a raw page");
+ DATA(insert OID = 2933 ( raw_page_heap_tuple_headers PGNSP PGUID 12 1 100 f f t t i 1 2249 "17" "{17,21,16,21,21,25,23,25,23,25,23,21,23,23,21}" "{i,o,o,o,o,o,o,o,o,o,o,o,o,o,o}" "{rawpage,id,ok,lpoff,len,tctid,xmn,cn,xmx,cx,cid,natts,toid,info,hdrsz}" raw_page_heap_tuple_headers - _null_ ));
+ DESCR("page header, given a raw page");
+
DATA(insert OID = 2621 ( pg_reload_conf PGNSP PGUID 12 1 0 f f t f v 0 16 "" _null_ _null_ _null_ pg_reload_conf - _null_ ));
DESCR("Reload configuration files");
DATA(insert OID = 2622 ( pg_rotate_logfile PGNSP PGUID 12 1 0 f f t f v 0 16 "" _null_ _null_ _null_ pg_rotate_logfile - _null_ ));