#include "postgres.h"#include "access/htup_details.h"#include "catalog/catalog.h"#include "catalog/namespace.h"#include "funcapi.h"#include "miscadmin.h"#include "storage/bufmgr.h"#include "utils/builtins.h"#include "utils/rel.h"
Go to the source code of this file.
Functions | |
| 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) |
| PG_FUNCTION_INFO_V1 (get_raw_page) | |
| PG_FUNCTION_INFO_V1 (get_raw_page_fork) | |
| PG_FUNCTION_INFO_V1 (page_header) | |
Variables | |
| PG_MODULE_MAGIC | |
| Datum get_raw_page | ( | PG_FUNCTION_ARGS | ) |
Definition at line 45 of file rawpage.c.
References ereport, errhint(), errmsg(), ERROR, get_raw_page_internal(), MAIN_FORKNUM, PG_GETARG_TEXT_P, PG_GETARG_UINT32, PG_NARGS, and PG_RETURN_BYTEA_P.
{
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);
}
| Datum get_raw_page_fork | ( | PG_FUNCTION_ARGS | ) |
Definition at line 74 of file rawpage.c.
References forkname_to_number(), get_raw_page_internal(), PG_GETARG_TEXT_P, PG_GETARG_UINT32, PG_RETURN_BYTEA_P, and text_to_cstring().
{
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;
forknum = forkname_to_number(text_to_cstring(forkname));
raw_page = get_raw_page_internal(relname, forknum, blkno);
PG_RETURN_BYTEA_P(raw_page);
}
| static bytea * get_raw_page_internal | ( | text * | relname, | |
| ForkNumber | forknum, | |||
| BlockNumber | blkno | |||
| ) | [static] |
Definition at line 93 of file rawpage.c.
References AccessShareLock, buf, BUFFER_LOCK_SHARE, BUFFER_LOCK_UNLOCK, BufferGetPage, elog, ereport, errcode(), errmsg(), ERROR, LockBuffer(), makeRangeVarFromNameList(), NULL, palloc(), RBM_NORMAL, RelationData::rd_rel, ReadBufferExtended(), relation_close(), RELATION_IS_OTHER_TEMP, relation_openrv(), RelationGetNumberOfBlocks, RelationGetRelationName, ReleaseBuffer(), RELKIND_COMPOSITE_TYPE, RELKIND_FOREIGN_TABLE, RELKIND_VIEW, SET_VARSIZE, superuser(), textToQualifiedNameList(), VARDATA, and VARHDRSZ.
Referenced by get_raw_page(), and get_raw_page_fork().
{
bytea *raw_page;
RangeVar *relrv;
Relation rel;
char *raw_page_data;
Buffer buf;
if (!superuser())
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
(errmsg("must be superuser to use raw functions"))));
relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname));
rel = relation_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 (rel->rd_rel->relkind == RELKIND_COMPOSITE_TYPE)
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("cannot get raw page from composite type \"%s\"",
RelationGetRelationName(rel))));
if (rel->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
ereport(ERROR,
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("cannot get raw page from foreign table \"%s\"",
RelationGetRelationName(rel))));
/*
* Reject attempts to read non-local temporary relations; we would be
* likely to get wrong data since we have no visibility into the owning
* session's local buffers.
*/
if (RELATION_IS_OTHER_TEMP(rel))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("cannot access temporary tables of other sessions")));
if (blkno >= RelationGetNumberOfBlocks(rel))
elog(ERROR, "block number %u is out of range for relation \"%s\"",
blkno, RelationGetRelationName(rel));
/* Initialize buffer to copy to */
raw_page = (bytea *) palloc(BLCKSZ + VARHDRSZ);
SET_VARSIZE(raw_page, BLCKSZ + VARHDRSZ);
raw_page_data = VARDATA(raw_page);
/* Take a verbatim copy of the page */
buf = ReadBufferExtended(rel, forknum, blkno, RBM_NORMAL, NULL);
LockBuffer(buf, BUFFER_LOCK_SHARE);
memcpy(raw_page_data, BufferGetPage(buf), BLCKSZ);
LockBuffer(buf, BUFFER_LOCK_UNLOCK);
ReleaseBuffer(buf);
relation_close(rel, AccessShareLock);
return raw_page;
}
| Datum page_header | ( | PG_FUNCTION_ARGS | ) |
Definition at line 169 of file rawpage.c.
References CStringGetTextDatum, elog, ereport, errcode(), errmsg(), ERROR, get_call_result_type(), heap_form_tuple(), HeapTupleGetDatum, NULL, PageGetLSN, PageGetPageLayoutVersion, PageGetPageSize, PageHeaderData::pd_checksum, PageHeaderData::pd_flags, PageHeaderData::pd_lower, PageHeaderData::pd_prune_xid, PageHeaderData::pd_special, PageHeaderData::pd_upper, PG_GETARG_BYTEA_P, PG_RETURN_DATUM, snprintf(), superuser(), TransactionIdGetDatum, UInt16GetDatum, values, VARDATA, and VARSIZE.
{
bytea *raw_page = PG_GETARG_BYTEA_P(0);
int raw_page_size;
TupleDesc tupdesc;
Datum result;
HeapTuple tuple;
Datum values[9];
bool nulls[9];
PageHeader page;
XLogRecPtr lsn;
char lsnchar[64];
if (!superuser())
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
(errmsg("must be superuser to use raw page functions"))));
raw_page_size = VARSIZE(raw_page) - VARHDRSZ;
/*
* Check that enough data was supplied, so that we don't try to access
* fields outside the supplied buffer.
*/
if (raw_page_size < sizeof(PageHeaderData))
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("input page too small (%d bytes)", raw_page_size)));
page = (PageHeader) VARDATA(raw_page);
/* Build a tuple descriptor for our result type */
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
elog(ERROR, "return type must be a row type");
/* 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[1] = UInt16GetDatum(page->pd_checksum);
values[2] = UInt16GetDatum(page->pd_flags);
values[3] = UInt16GetDatum(page->pd_lower);
values[4] = UInt16GetDatum(page->pd_upper);
values[5] = UInt16GetDatum(page->pd_special);
values[6] = UInt16GetDatum(PageGetPageSize(page));
values[7] = UInt16GetDatum(PageGetPageLayoutVersion(page));
values[8] = TransactionIdGetDatum(page->pd_prune_xid);
/* Build and return the tuple. */
memset(nulls, 0, sizeof(nulls));
tuple = heap_form_tuple(tupdesc, values, nulls);
result = HeapTupleGetDatum(tuple);
PG_RETURN_DATUM(result);
}
| PG_FUNCTION_INFO_V1 | ( | page_header | ) |
| PG_FUNCTION_INFO_V1 | ( | get_raw_page | ) |
| PG_FUNCTION_INFO_V1 | ( | get_raw_page_fork | ) |
1.7.1