PostgreSQL Source Code  git master
rawpage.c File Reference
#include "postgres.h"
#include "access/htup_details.h"
#include "access/relation.h"
#include "catalog/namespace.h"
#include "catalog/pg_type.h"
#include "funcapi.h"
#include "miscadmin.h"
#include "pageinspect.h"
#include "storage/bufmgr.h"
#include "storage/checksum.h"
#include "utils/builtins.h"
#include "utils/pg_lsn.h"
#include "utils/rel.h"
#include "utils/varlena.h"
Include dependency graph for rawpage.c:

Go to the source code of this file.

Functions

static byteaget_raw_page_internal (text *relname, ForkNumber forknum, BlockNumber blkno)
 
 PG_FUNCTION_INFO_V1 (get_raw_page_1_9)
 
Datum get_raw_page_1_9 (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (get_raw_page)
 
Datum get_raw_page (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (get_raw_page_fork_1_9)
 
Datum get_raw_page_fork_1_9 (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (get_raw_page_fork)
 
Datum get_raw_page_fork (PG_FUNCTION_ARGS)
 
Page get_page_from_raw (bytea *raw_page)
 
 PG_FUNCTION_INFO_V1 (page_header)
 
Datum page_header (PG_FUNCTION_ARGS)
 
 PG_FUNCTION_INFO_V1 (page_checksum_1_9)
 
 PG_FUNCTION_INFO_V1 (page_checksum)
 
static Datum page_checksum_internal (PG_FUNCTION_ARGS, enum pageinspect_version ext_version)
 
Datum page_checksum_1_9 (PG_FUNCTION_ARGS)
 
Datum page_checksum (PG_FUNCTION_ARGS)
 

Variables

 PG_MODULE_MAGIC
 

Function Documentation

◆ get_page_from_raw()

Page get_page_from_raw ( bytea raw_page)

Definition at line 215 of file rawpage.c.

216 {
217  Page page;
218  int raw_page_size;
219 
220  raw_page_size = VARSIZE_ANY_EXHDR(raw_page);
221 
222  if (raw_page_size != BLCKSZ)
223  ereport(ERROR,
224  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
225  errmsg("invalid page size"),
226  errdetail("Expected %d bytes, got %d.",
227  BLCKSZ, raw_page_size)));
228 
229  page = palloc(raw_page_size);
230 
231  memcpy(page, VARDATA_ANY(raw_page), raw_page_size);
232 
233  return page;
234 }
Pointer Page
Definition: bufpage.h:78
int errdetail(const char *fmt,...)
Definition: elog.c:1037
int errcode(int sqlerrcode)
Definition: elog.c:693
int errmsg(const char *fmt,...)
Definition: elog.c:904
#define ERROR
Definition: elog.h:33
#define ereport(elevel,...)
Definition: elog.h:143
void * palloc(Size size)
Definition: mcxt.c:1068
#define VARDATA_ANY(PTR)
Definition: postgres.h:361
#define VARSIZE_ANY_EXHDR(PTR)
Definition: postgres.h:354

References ereport, errcode(), errdetail(), errmsg(), ERROR, palloc(), VARDATA_ANY, and VARSIZE_ANY_EXHDR.

Referenced by brin_page_type(), bt_page_items_bytea(), fsm_page_contents(), gin_leafpage_items(), gin_metapage_info(), gin_page_opaque_info(), gist_page_items(), gist_page_items_bytea(), gist_page_opaque_info(), page_checksum_internal(), page_header(), verify_brin_page(), and verify_hash_page().

◆ get_raw_page()

Datum get_raw_page ( PG_FUNCTION_ARGS  )

Definition at line 68 of file rawpage.c.

69 {
71  uint32 blkno = PG_GETARG_UINT32(1);
72  bytea *raw_page;
73 
74  /*
75  * We don't normally bother to check the number of arguments to a C
76  * function, but here it's needed for safety because early 8.4 beta
77  * releases mistakenly redefined get_raw_page() as taking three arguments.
78  */
79  if (PG_NARGS() != 2)
80  ereport(ERROR,
81  (errmsg("wrong number of arguments to get_raw_page()"),
82  errhint("Run the updated pageinspect.sql script.")));
83 
84  raw_page = get_raw_page_internal(relname, MAIN_FORKNUM, blkno);
85 
86  PG_RETURN_BYTEA_P(raw_page);
87 }
unsigned int uint32
Definition: c.h:441
int errhint(const char *fmt,...)
Definition: elog.c:1151
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
#define PG_RETURN_BYTEA_P(x)
Definition: fmgr.h:371
#define PG_GETARG_UINT32(n)
Definition: fmgr.h:270
#define PG_NARGS()
Definition: fmgr.h:203
NameData relname
Definition: pg_class.h:38
static bytea * get_raw_page_internal(text *relname, ForkNumber forknum, BlockNumber blkno)
Definition: rawpage.c:142
@ MAIN_FORKNUM
Definition: relpath.h:43
Definition: c.h:622

References ereport, errhint(), errmsg(), ERROR, get_raw_page_internal(), MAIN_FORKNUM, PG_GETARG_TEXT_PP, PG_GETARG_UINT32, PG_NARGS, PG_RETURN_BYTEA_P, and relname.

◆ get_raw_page_1_9()

Datum get_raw_page_1_9 ( PG_FUNCTION_ARGS  )

Definition at line 46 of file rawpage.c.

47 {
49  int64 blkno = PG_GETARG_INT64(1);
50  bytea *raw_page;
51 
52  if (blkno < 0 || blkno > MaxBlockNumber)
53  ereport(ERROR,
54  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
55  errmsg("invalid block number")));
56 
57  raw_page = get_raw_page_internal(relname, MAIN_FORKNUM, blkno);
58 
59  PG_RETURN_BYTEA_P(raw_page);
60 }
#define MaxBlockNumber
Definition: block.h:35
#define PG_GETARG_INT64(n)
Definition: fmgr.h:283

References ereport, errcode(), errmsg(), ERROR, get_raw_page_internal(), MAIN_FORKNUM, MaxBlockNumber, PG_GETARG_INT64, PG_GETARG_TEXT_PP, PG_RETURN_BYTEA_P, and relname.

◆ get_raw_page_fork()

Datum get_raw_page_fork ( PG_FUNCTION_ARGS  )

Definition at line 123 of file rawpage.c.

124 {
126  text *forkname = PG_GETARG_TEXT_PP(1);
127  uint32 blkno = PG_GETARG_UINT32(2);
128  bytea *raw_page;
129  ForkNumber forknum;
130 
131  forknum = forkname_to_number(text_to_cstring(forkname));
132 
133  raw_page = get_raw_page_internal(relname, forknum, blkno);
134 
135  PG_RETURN_BYTEA_P(raw_page);
136 }
ForkNumber forkname_to_number(const char *forkName)
Definition: relpath.c:50
ForkNumber
Definition: relpath.h:41
char * text_to_cstring(const text *t)
Definition: varlena.c:221

References forkname_to_number(), get_raw_page_internal(), PG_GETARG_TEXT_PP, PG_GETARG_UINT32, PG_RETURN_BYTEA_P, relname, and text_to_cstring().

◆ get_raw_page_fork_1_9()

Datum get_raw_page_fork_1_9 ( PG_FUNCTION_ARGS  )

Definition at line 97 of file rawpage.c.

98 {
100  text *forkname = PG_GETARG_TEXT_PP(1);
101  int64 blkno = PG_GETARG_INT64(2);
102  bytea *raw_page;
103  ForkNumber forknum;
104 
105  forknum = forkname_to_number(text_to_cstring(forkname));
106 
107  if (blkno < 0 || blkno > MaxBlockNumber)
108  ereport(ERROR,
109  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
110  errmsg("invalid block number")));
111 
112  raw_page = get_raw_page_internal(relname, forknum, blkno);
113 
114  PG_RETURN_BYTEA_P(raw_page);
115 }

References ereport, errcode(), errmsg(), ERROR, forkname_to_number(), get_raw_page_internal(), MaxBlockNumber, PG_GETARG_INT64, PG_GETARG_TEXT_PP, PG_RETURN_BYTEA_P, relname, and text_to_cstring().

◆ get_raw_page_internal()

static bytea * get_raw_page_internal ( text relname,
ForkNumber  forknum,
BlockNumber  blkno 
)
static

Definition at line 142 of file rawpage.c.

143 {
144  bytea *raw_page;
145  RangeVar *relrv;
146  Relation rel;
147  char *raw_page_data;
148  Buffer buf;
149 
150  if (!superuser())
151  ereport(ERROR,
152  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
153  errmsg("must be superuser to use raw page functions")));
154 
156  rel = relation_openrv(relrv, AccessShareLock);
157 
158  if (!RELKIND_HAS_STORAGE(rel->rd_rel->relkind))
159  ereport(ERROR,
160  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
161  errmsg("cannot get raw page from relation \"%s\"",
163  errdetail_relkind_not_supported(rel->rd_rel->relkind)));
164 
165  /*
166  * Reject attempts to read non-local temporary relations; we would be
167  * likely to get wrong data since we have no visibility into the owning
168  * session's local buffers.
169  */
170  if (RELATION_IS_OTHER_TEMP(rel))
171  ereport(ERROR,
172  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
173  errmsg("cannot access temporary tables of other sessions")));
174 
175  if (blkno >= RelationGetNumberOfBlocksInFork(rel, forknum))
176  ereport(ERROR,
177  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
178  errmsg("block number %u is out of range for relation \"%s\"",
179  blkno, RelationGetRelationName(rel))));
180 
181  /* Initialize buffer to copy to */
182  raw_page = (bytea *) palloc(BLCKSZ + VARHDRSZ);
183  SET_VARSIZE(raw_page, BLCKSZ + VARHDRSZ);
184  raw_page_data = VARDATA(raw_page);
185 
186  /* Take a verbatim copy of the page */
187 
188  buf = ReadBufferExtended(rel, forknum, blkno, RBM_NORMAL, NULL);
190 
191  memcpy(raw_page_data, BufferGetPage(buf), BLCKSZ);
192 
195 
197 
198  return raw_page;
199 }
int Buffer
Definition: buf.h:23
BlockNumber RelationGetNumberOfBlocksInFork(Relation relation, ForkNumber forkNum)
Definition: bufmgr.c:2942
void ReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:3915
void LockBuffer(Buffer buffer, int mode)
Definition: bufmgr.c:4156
Buffer ReadBufferExtended(Relation reln, ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode, BufferAccessStrategy strategy)
Definition: bufmgr.c:749
#define BUFFER_LOCK_UNLOCK
Definition: bufmgr.h:96
#define BUFFER_LOCK_SHARE
Definition: bufmgr.h:97
@ RBM_NORMAL
Definition: bufmgr.h:39
#define BufferGetPage(buffer)
Definition: bufmgr.h:169
#define VARHDRSZ
Definition: c.h:627
#define AccessShareLock
Definition: lockdefs.h:36
RangeVar * makeRangeVarFromNameList(List *names)
Definition: namespace.c:3108
int errdetail_relkind_not_supported(char relkind)
Definition: pg_class.c:24
static char * buf
Definition: pg_test_fsync.c:67
#define VARDATA(PTR)
Definition: postgres.h:315
#define SET_VARSIZE(PTR, len)
Definition: postgres.h:342
#define RelationGetRelationName(relation)
Definition: rel.h:523
#define RELATION_IS_OTHER_TEMP(relation)
Definition: rel.h:643
void relation_close(Relation relation, LOCKMODE lockmode)
Definition: relation.c:206
Relation relation_openrv(const RangeVar *relation, LOCKMODE lockmode)
Definition: relation.c:138
Form_pg_class rd_rel
Definition: rel.h:109
bool superuser(void)
Definition: superuser.c:46
List * textToQualifiedNameList(text *textval)
Definition: varlena.c:3657

References AccessShareLock, buf, BUFFER_LOCK_SHARE, BUFFER_LOCK_UNLOCK, BufferGetPage, ereport, errcode(), errdetail_relkind_not_supported(), errmsg(), ERROR, LockBuffer(), makeRangeVarFromNameList(), palloc(), RBM_NORMAL, RelationData::rd_rel, ReadBufferExtended(), relation_close(), RELATION_IS_OTHER_TEMP, relation_openrv(), RelationGetNumberOfBlocksInFork(), RelationGetRelationName, ReleaseBuffer(), relname, SET_VARSIZE, superuser(), textToQualifiedNameList(), VARDATA, and VARHDRSZ.

Referenced by get_raw_page(), get_raw_page_1_9(), get_raw_page_fork(), and get_raw_page_fork_1_9().

◆ page_checksum()

Datum page_checksum ( PG_FUNCTION_ARGS  )

Definition at line 371 of file rawpage.c.

372 {
374 }
@ PAGEINSPECT_V1_8
Definition: pageinspect.h:23
static Datum page_checksum_internal(PG_FUNCTION_ARGS, enum pageinspect_version ext_version)
Definition: rawpage.c:337

References page_checksum_internal(), and PAGEINSPECT_V1_8.

◆ page_checksum_1_9()

Datum page_checksum_1_9 ( PG_FUNCTION_ARGS  )

Definition at line 362 of file rawpage.c.

363 {
365 }
@ PAGEINSPECT_V1_9
Definition: pageinspect.h:24

References page_checksum_internal(), and PAGEINSPECT_V1_9.

◆ page_checksum_internal()

static Datum page_checksum_internal ( PG_FUNCTION_ARGS  ,
enum pageinspect_version  ext_version 
)
static

Definition at line 337 of file rawpage.c.

338 {
339  bytea *raw_page = PG_GETARG_BYTEA_P(0);
340  int64 blkno = (ext_version == PAGEINSPECT_V1_8 ? PG_GETARG_UINT32(1) : PG_GETARG_INT64(1));
341  Page page;
342 
343  if (!superuser())
344  ereport(ERROR,
345  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
346  errmsg("must be superuser to use raw page functions")));
347 
348  if (blkno < 0 || blkno > MaxBlockNumber)
349  ereport(ERROR,
350  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
351  errmsg("invalid block number")));
352 
353  page = get_page_from_raw(raw_page);
354 
355  if (PageIsNew(page))
356  PG_RETURN_NULL();
357 
358  PG_RETURN_INT16(pg_checksum_page((char *) page, blkno));
359 }
#define PageIsNew(page)
Definition: bufpage.h:228
uint16 pg_checksum_page(char *page, BlockNumber blkno)
#define PG_RETURN_NULL()
Definition: fmgr.h:345
#define PG_RETURN_INT16(x)
Definition: fmgr.h:356
#define PG_GETARG_BYTEA_P(n)
Definition: fmgr.h:335
Page get_page_from_raw(bytea *raw_page)
Definition: rawpage.c:215

References ereport, errcode(), errmsg(), ERROR, get_page_from_raw(), MaxBlockNumber, PAGEINSPECT_V1_8, PageIsNew, pg_checksum_page(), PG_GETARG_BYTEA_P, PG_GETARG_INT64, PG_GETARG_UINT32, PG_RETURN_INT16, PG_RETURN_NULL, and superuser().

Referenced by page_checksum(), and page_checksum_1_9().

◆ page_header()

Datum page_header ( PG_FUNCTION_ARGS  )

Definition at line 246 of file rawpage.c.

247 {
248  bytea *raw_page = PG_GETARG_BYTEA_P(0);
249 
250  TupleDesc tupdesc;
251 
252  Datum result;
253  HeapTuple tuple;
254  Datum values[9];
255  bool nulls[9];
256 
257  PageHeader page;
258  XLogRecPtr lsn;
259 
260  if (!superuser())
261  ereport(ERROR,
262  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
263  errmsg("must be superuser to use raw page functions")));
264 
265  page = (PageHeader) get_page_from_raw(raw_page);
266 
267  /* Build a tuple descriptor for our result type */
268  if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
269  elog(ERROR, "return type must be a row type");
270 
271  /* Extract information from the page header */
272 
273  lsn = PageGetLSN(page);
274 
275  /* pageinspect >= 1.2 uses pg_lsn instead of text for the LSN field. */
276  if (TupleDescAttr(tupdesc, 0)->atttypid == TEXTOID)
277  {
278  char lsnchar[64];
279 
280  snprintf(lsnchar, sizeof(lsnchar), "%X/%X", LSN_FORMAT_ARGS(lsn));
281  values[0] = CStringGetTextDatum(lsnchar);
282  }
283  else
284  values[0] = LSNGetDatum(lsn);
285  values[1] = UInt16GetDatum(page->pd_checksum);
286  values[2] = UInt16GetDatum(page->pd_flags);
287 
288  /* pageinspect >= 1.10 uses int4 instead of int2 for those fields */
289  switch (TupleDescAttr(tupdesc, 3)->atttypid)
290  {
291  case INT2OID:
292  Assert(TupleDescAttr(tupdesc, 4)->atttypid == INT2OID &&
293  TupleDescAttr(tupdesc, 5)->atttypid == INT2OID &&
294  TupleDescAttr(tupdesc, 6)->atttypid == INT2OID);
295  values[3] = UInt16GetDatum(page->pd_lower);
296  values[4] = UInt16GetDatum(page->pd_upper);
297  values[5] = UInt16GetDatum(page->pd_special);
299  break;
300  case INT4OID:
301  Assert(TupleDescAttr(tupdesc, 4)->atttypid == INT4OID &&
302  TupleDescAttr(tupdesc, 5)->atttypid == INT4OID &&
303  TupleDescAttr(tupdesc, 6)->atttypid == INT4OID);
304  values[3] = Int32GetDatum(page->pd_lower);
305  values[4] = Int32GetDatum(page->pd_upper);
306  values[5] = Int32GetDatum(page->pd_special);
308  break;
309  default:
310  elog(ERROR, "incorrect output types");
311  break;
312  }
313 
316 
317  /* Build and return the tuple. */
318 
319  memset(nulls, 0, sizeof(nulls));
320 
321  tuple = heap_form_tuple(tupdesc, values, nulls);
322  result = HeapTupleGetDatum(tuple);
323 
324  PG_RETURN_DATUM(result);
325 }
static Datum values[MAXATTR]
Definition: bootstrap.c:156
PageHeaderData * PageHeader
Definition: bufpage.h:166
#define PageGetPageLayoutVersion(page)
Definition: bufpage.h:274
#define PageGetPageSize(page)
Definition: bufpage.h:267
#define PageGetLSN(page)
Definition: bufpage.h:365
#define CStringGetTextDatum(s)
Definition: builtins.h:85
#define elog(elevel,...)
Definition: elog.h:218
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:353
TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
Definition: funcapi.c:276
@ TYPEFUNC_COMPOSITE
Definition: funcapi.h:149
#define HeapTupleGetDatum(tuple)
Definition: funcapi.h:220
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:1020
Assert(fmt[strlen(fmt) - 1] !='\n')
#define LSNGetDatum(X)
Definition: pg_lsn.h:22
#define snprintf
Definition: port.h:225
#define TransactionIdGetDatum(X)
Definition: postgres.h:565
uintptr_t Datum
Definition: postgres.h:411
#define Int32GetDatum(X)
Definition: postgres.h:523
#define UInt16GetDatum(X)
Definition: postgres.h:509
LocationIndex pd_special
Definition: bufpage.h:160
LocationIndex pd_upper
Definition: bufpage.h:159
uint16 pd_flags
Definition: bufpage.h:157
uint16 pd_checksum
Definition: bufpage.h:156
LocationIndex pd_lower
Definition: bufpage.h:158
TransactionId pd_prune_xid
Definition: bufpage.h:162
#define TupleDescAttr(tupdesc, i)
Definition: tupdesc.h:92
#define LSN_FORMAT_ARGS(lsn)
Definition: xlogdefs.h:43
uint64 XLogRecPtr
Definition: xlogdefs.h:21

References Assert(), CStringGetTextDatum, elog, ereport, errcode(), errmsg(), ERROR, get_call_result_type(), get_page_from_raw(), heap_form_tuple(), HeapTupleGetDatum, Int32GetDatum, LSN_FORMAT_ARGS, LSNGetDatum, 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, TupleDescAttr, TYPEFUNC_COMPOSITE, UInt16GetDatum, and values.

◆ PG_FUNCTION_INFO_V1() [1/7]

PG_FUNCTION_INFO_V1 ( get_raw_page  )

◆ PG_FUNCTION_INFO_V1() [2/7]

PG_FUNCTION_INFO_V1 ( get_raw_page_1_9  )

◆ PG_FUNCTION_INFO_V1() [3/7]

PG_FUNCTION_INFO_V1 ( get_raw_page_fork  )

◆ PG_FUNCTION_INFO_V1() [4/7]

PG_FUNCTION_INFO_V1 ( get_raw_page_fork_1_9  )

◆ PG_FUNCTION_INFO_V1() [5/7]

PG_FUNCTION_INFO_V1 ( page_checksum  )

◆ PG_FUNCTION_INFO_V1() [6/7]

PG_FUNCTION_INFO_V1 ( page_checksum_1_9  )

◆ PG_FUNCTION_INFO_V1() [7/7]

PG_FUNCTION_INFO_V1 ( page_header  )

Variable Documentation

◆ PG_MODULE_MAGIC

PG_MODULE_MAGIC

Definition at line 32 of file rawpage.c.