PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
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

 PG_MODULE_MAGIC_EXT (.name="pageinspect",.version=PG_VERSION)
 
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)
 

Function Documentation

◆ get_page_from_raw()

Page get_page_from_raw ( bytea raw_page)

Definition at line 218 of file rawpage.c.

219{
220 Page page;
221 int raw_page_size;
222
223 raw_page_size = VARSIZE_ANY_EXHDR(raw_page);
224
225 if (raw_page_size != BLCKSZ)
227 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
228 errmsg("invalid page size"),
229 errdetail("Expected %d bytes, got %d.",
230 BLCKSZ, raw_page_size)));
231
232 page = palloc(raw_page_size);
233
234 memcpy(page, VARDATA_ANY(raw_page), raw_page_size);
235
236 return page;
237}
PageData * Page
Definition: bufpage.h:82
int errdetail(const char *fmt,...)
Definition: elog.c:1204
int errcode(int sqlerrcode)
Definition: elog.c:854
int errmsg(const char *fmt,...)
Definition: elog.c:1071
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
void * palloc(Size size)
Definition: mcxt.c:1943
#define VARDATA_ANY(PTR)
Definition: varatt.h:324
#define VARSIZE_ANY_EXHDR(PTR)
Definition: varatt.h:317

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(), page_checksum_internal(), page_header(), verify_brin_page(), verify_gist_page(), and verify_hash_page().

◆ get_raw_page()

Datum get_raw_page ( PG_FUNCTION_ARGS  )

Definition at line 71 of file rawpage.c.

72{
74 uint32 blkno = PG_GETARG_UINT32(1);
75 bytea *raw_page;
76
77 /*
78 * We don't normally bother to check the number of arguments to a C
79 * function, but here it's needed for safety because early 8.4 beta
80 * releases mistakenly redefined get_raw_page() as taking three arguments.
81 */
82 if (PG_NARGS() != 2)
84 (errmsg("wrong number of arguments to get_raw_page()"),
85 errhint("Run the updated pageinspect.sql script.")));
86
87 raw_page = get_raw_page_internal(relname, MAIN_FORKNUM, blkno);
88
89 PG_RETURN_BYTEA_P(raw_page);
90}
uint32_t uint32
Definition: c.h:502
int errhint(const char *fmt,...)
Definition: elog.c:1318
#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:145
@ MAIN_FORKNUM
Definition: relpath.h:58
Definition: c.h:658

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 49 of file rawpage.c.

50{
52 int64 blkno = PG_GETARG_INT64(1);
53 bytea *raw_page;
54
55 if (blkno < 0 || blkno > MaxBlockNumber)
57 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
58 errmsg("invalid block number")));
59
60 raw_page = get_raw_page_internal(relname, MAIN_FORKNUM, blkno);
61
62 PG_RETURN_BYTEA_P(raw_page);
63}
#define MaxBlockNumber
Definition: block.h:35
int64_t int64
Definition: c.h:499
#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 126 of file rawpage.c.

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

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 100 of file rawpage.c.

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

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 145 of file rawpage.c.

146{
147 bytea *raw_page;
148 RangeVar *relrv;
149 Relation rel;
150 char *raw_page_data;
151 Buffer buf;
152
153 if (!superuser())
155 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
156 errmsg("must be superuser to use raw page functions")));
157
159 rel = relation_openrv(relrv, AccessShareLock);
160
161 if (!RELKIND_HAS_STORAGE(rel->rd_rel->relkind))
163 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
164 errmsg("cannot get raw page from relation \"%s\"",
167
168 /*
169 * Reject attempts to read non-local temporary relations; we would be
170 * likely to get wrong data since we have no visibility into the owning
171 * session's local buffers.
172 */
173 if (RELATION_IS_OTHER_TEMP(rel))
175 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
176 errmsg("cannot access temporary tables of other sessions")));
177
178 if (blkno >= RelationGetNumberOfBlocksInFork(rel, forknum))
180 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
181 errmsg("block number %u is out of range for relation \"%s\"",
182 blkno, RelationGetRelationName(rel))));
183
184 /* Initialize buffer to copy to */
185 raw_page = (bytea *) palloc(BLCKSZ + VARHDRSZ);
186 SET_VARSIZE(raw_page, BLCKSZ + VARHDRSZ);
187 raw_page_data = VARDATA(raw_page);
188
189 /* Take a verbatim copy of the page */
190
191 buf = ReadBufferExtended(rel, forknum, blkno, RBM_NORMAL, NULL);
193
194 memcpy(raw_page_data, BufferGetPage(buf), BLCKSZ);
195
198
200
201 return raw_page;
202}
int Buffer
Definition: buf.h:23
BlockNumber RelationGetNumberOfBlocksInFork(Relation relation, ForkNumber forkNum)
Definition: bufmgr.c:4431
void ReleaseBuffer(Buffer buffer)
Definition: bufmgr.c:5373
void LockBuffer(Buffer buffer, int mode)
Definition: bufmgr.c:5607
Buffer ReadBufferExtended(Relation reln, ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode, BufferAccessStrategy strategy)
Definition: bufmgr.c:805
#define BUFFER_LOCK_UNLOCK
Definition: bufmgr.h:196
#define BUFFER_LOCK_SHARE
Definition: bufmgr.h:197
static Page BufferGetPage(Buffer buffer)
Definition: bufmgr.h:417
@ RBM_NORMAL
Definition: bufmgr.h:46
#define VARHDRSZ
Definition: c.h:663
#define AccessShareLock
Definition: lockdefs.h:36
RangeVar * makeRangeVarFromNameList(const List *names)
Definition: namespace.c:3554
int errdetail_relkind_not_supported(char relkind)
Definition: pg_class.c:24
static char * buf
Definition: pg_test_fsync.c:72
#define RelationGetRelationName(relation)
Definition: rel.h:550
#define RELATION_IS_OTHER_TEMP(relation)
Definition: rel.h:669
void relation_close(Relation relation, LOCKMODE lockmode)
Definition: relation.c:205
Relation relation_openrv(const RangeVar *relation, LOCKMODE lockmode)
Definition: relation.c:137
Form_pg_class rd_rel
Definition: rel.h:111
bool superuser(void)
Definition: superuser.c:46
#define VARDATA(PTR)
Definition: varatt.h:278
#define SET_VARSIZE(PTR, len)
Definition: varatt.h:305
List * textToQualifiedNameList(text *textval)
Definition: varlena.c:3467

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 376 of file rawpage.c.

377{
379}
@ PAGEINSPECT_V1_8
Definition: pageinspect.h:23
static Datum page_checksum_internal(PG_FUNCTION_ARGS, enum pageinspect_version ext_version)
Definition: rawpage.c:342

References page_checksum_internal(), and PAGEINSPECT_V1_8.

◆ page_checksum_1_9()

Datum page_checksum_1_9 ( PG_FUNCTION_ARGS  )

Definition at line 367 of file rawpage.c.

368{
370}
@ 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 342 of file rawpage.c.

343{
344 bytea *raw_page = PG_GETARG_BYTEA_P(0);
345 int64 blkno = (ext_version == PAGEINSPECT_V1_8 ? PG_GETARG_UINT32(1) : PG_GETARG_INT64(1));
346 Page page;
347
348 if (!superuser())
350 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
351 errmsg("must be superuser to use raw page functions")));
352
353 if (blkno < 0 || blkno > MaxBlockNumber)
355 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
356 errmsg("invalid block number")));
357
358 page = get_page_from_raw(raw_page);
359
360 if (PageIsNew(page))
362
363 PG_RETURN_INT16(pg_checksum_page(page, blkno));
364}
static bool PageIsNew(const PageData *page)
Definition: bufpage.h:234
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:218

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 249 of file rawpage.c.

250{
251 bytea *raw_page = PG_GETARG_BYTEA_P(0);
252
253 TupleDesc tupdesc;
254
255 Datum result;
256 HeapTuple tuple;
257 Datum values[9];
258 bool nulls[9];
259
260 Page page;
261 PageHeader pageheader;
262 XLogRecPtr lsn;
263
264 if (!superuser())
266 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
267 errmsg("must be superuser to use raw page functions")));
268
269 page = get_page_from_raw(raw_page);
270 pageheader = (PageHeader) page;
271
272 /* Build a tuple descriptor for our result type */
273 if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
274 elog(ERROR, "return type must be a row type");
275
276 /* Extract information from the page header */
277
278 lsn = PageGetLSN(page);
279
280 /* pageinspect >= 1.2 uses pg_lsn instead of text for the LSN field. */
281 if (TupleDescAttr(tupdesc, 0)->atttypid == TEXTOID)
282 {
283 char lsnchar[64];
284
285 snprintf(lsnchar, sizeof(lsnchar), "%X/%X", LSN_FORMAT_ARGS(lsn));
286 values[0] = CStringGetTextDatum(lsnchar);
287 }
288 else
289 values[0] = LSNGetDatum(lsn);
290 values[1] = UInt16GetDatum(pageheader->pd_checksum);
291 values[2] = UInt16GetDatum(pageheader->pd_flags);
292
293 /* pageinspect >= 1.10 uses int4 instead of int2 for those fields */
294 switch (TupleDescAttr(tupdesc, 3)->atttypid)
295 {
296 case INT2OID:
297 Assert(TupleDescAttr(tupdesc, 4)->atttypid == INT2OID &&
298 TupleDescAttr(tupdesc, 5)->atttypid == INT2OID &&
299 TupleDescAttr(tupdesc, 6)->atttypid == INT2OID);
300 values[3] = UInt16GetDatum(pageheader->pd_lower);
301 values[4] = UInt16GetDatum(pageheader->pd_upper);
302 values[5] = UInt16GetDatum(pageheader->pd_special);
304 break;
305 case INT4OID:
306 Assert(TupleDescAttr(tupdesc, 4)->atttypid == INT4OID &&
307 TupleDescAttr(tupdesc, 5)->atttypid == INT4OID &&
308 TupleDescAttr(tupdesc, 6)->atttypid == INT4OID);
309 values[3] = Int32GetDatum(pageheader->pd_lower);
310 values[4] = Int32GetDatum(pageheader->pd_upper);
311 values[5] = Int32GetDatum(pageheader->pd_special);
313 break;
314 default:
315 elog(ERROR, "incorrect output types");
316 break;
317 }
318
320 values[8] = TransactionIdGetDatum(pageheader->pd_prune_xid);
321
322 /* Build and return the tuple. */
323
324 memset(nulls, 0, sizeof(nulls));
325
326 tuple = heap_form_tuple(tupdesc, values, nulls);
327 result = HeapTupleGetDatum(tuple);
328
329 PG_RETURN_DATUM(result);
330}
static Datum values[MAXATTR]
Definition: bootstrap.c:151
PageHeaderData * PageHeader
Definition: bufpage.h:174
static Size PageGetPageSize(const PageData *page)
Definition: bufpage.h:277
static uint8 PageGetPageLayoutVersion(const PageData *page)
Definition: bufpage.h:287
static XLogRecPtr PageGetLSN(const PageData *page)
Definition: bufpage.h:386
#define CStringGetTextDatum(s)
Definition: builtins.h:97
#define elog(elevel,...)
Definition: elog.h:225
#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
static Datum HeapTupleGetDatum(const HeapTupleData *tuple)
Definition: funcapi.h:230
Assert(PointerIsAligned(start, uint64))
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
Definition: heaptuple.c:1117
static Datum LSNGetDatum(XLogRecPtr X)
Definition: pg_lsn.h:28
#define snprintf
Definition: port.h:239
static Datum TransactionIdGetDatum(TransactionId X)
Definition: postgres.h:277
uintptr_t Datum
Definition: postgres.h:69
static Datum UInt16GetDatum(uint16 X)
Definition: postgres.h:197
static Datum Int32GetDatum(int32 X)
Definition: postgres.h:217
LocationIndex pd_special
Definition: bufpage.h:168
LocationIndex pd_upper
Definition: bufpage.h:167
uint16 pd_flags
Definition: bufpage.h:165
uint16 pd_checksum
Definition: bufpage.h:164
LocationIndex pd_lower
Definition: bufpage.h:166
TransactionId pd_prune_xid
Definition: bufpage.h:170
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
Definition: tupdesc.h:160
#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  )

◆ PG_MODULE_MAGIC_EXT()

PG_MODULE_MAGIC_EXT ( name = "pageinspect",
version = PG_VERSION 
)