summaryrefslogtreecommitdiff
path: root/contrib/pageinspect/rawpage.c
diff options
context:
space:
mode:
authorPavan Deolasee2017-06-14 05:42:18 +0000
committerPavan Deolasee2017-06-14 05:42:18 +0000
commit15dd5274c323fb93e4e3ea9ad2185aaaec10f79c (patch)
tree9dafb4c7f735d9429ea461dc792933af87493c33 /contrib/pageinspect/rawpage.c
parentdfbb88e3bbb526dcb204b456b9e5cfd9d10d0d0a (diff)
parentd5cb3bab564e0927ffac7c8729eacf181a12dd40 (diff)
Merge from PG master upto d5cb3bab564e0927ffac7c8729eacf181a12dd40
This is the result of the "git merge remotes/PGSQL/master" upto the said commit point. We have done some basic analysis, fixed compilation problems etc, but bulk of the logical problems in conflict resolution etc will be handled by subsequent commits.
Diffstat (limited to 'contrib/pageinspect/rawpage.c')
-rw-r--r--contrib/pageinspect/rawpage.c89
1 files changed, 85 insertions, 4 deletions
diff --git a/contrib/pageinspect/rawpage.c b/contrib/pageinspect/rawpage.c
index 71d0c8d2ca..f273dfa7cb 100644
--- a/contrib/pageinspect/rawpage.c
+++ b/contrib/pageinspect/rawpage.c
@@ -5,7 +5,7 @@
*
* Access-method specific inspection functions are in separate files.
*
- * Copyright (c) 2007-2016, PostgreSQL Global Development Group
+ * Copyright (c) 2007-2017, PostgreSQL Global Development Group
*
* IDENTIFICATION
* contrib/pageinspect/rawpage.c
@@ -15,6 +15,8 @@
#include "postgres.h"
+#include "pageinspect.h"
+
#include "access/htup_details.h"
#include "catalog/catalog.h"
#include "catalog/namespace.h"
@@ -22,9 +24,11 @@
#include "funcapi.h"
#include "miscadmin.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"
PG_MODULE_MAGIC;
@@ -42,7 +46,7 @@ PG_FUNCTION_INFO_V1(get_raw_page);
Datum
get_raw_page(PG_FUNCTION_ARGS)
{
- text *relname = PG_GETARG_TEXT_P(0);
+ text *relname = PG_GETARG_TEXT_PP(0);
uint32 blkno = PG_GETARG_UINT32(1);
bytea *raw_page;
@@ -71,8 +75,8 @@ PG_FUNCTION_INFO_V1(get_raw_page_fork);
Datum
get_raw_page_fork(PG_FUNCTION_ARGS)
{
- text *relname = PG_GETARG_TEXT_P(0);
- text *forkname = PG_GETARG_TEXT_P(1);
+ text *relname = PG_GETARG_TEXT_PP(0);
+ text *forkname = PG_GETARG_TEXT_PP(1);
uint32 blkno = PG_GETARG_UINT32(2);
bytea *raw_page;
ForkNumber forknum;
@@ -120,6 +124,11 @@ get_raw_page_internal(text *relname, ForkNumber forknum, BlockNumber blkno)
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
errmsg("cannot get raw page from foreign table \"%s\"",
RelationGetRelationName(rel))));
+ if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
+ ereport(ERROR,
+ (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+ errmsg("cannot get raw page from partitioned table \"%s\"",
+ RelationGetRelationName(rel))));
/*
* Reject attempts to read non-local temporary relations; we would be
@@ -157,6 +166,42 @@ get_raw_page_internal(text *relname, ForkNumber forknum, BlockNumber blkno)
return raw_page;
}
+
+/*
+ * get_page_from_raw
+ *
+ * Get a palloc'd, maxalign'ed page image from the result of get_raw_page()
+ *
+ * On machines with MAXALIGN = 8, the payload of a bytea is not maxaligned,
+ * since it will start 4 bytes into a palloc'd value. On alignment-picky
+ * machines, this will cause failures in accesses to 8-byte-wide values
+ * within the page. We don't need to worry if accessing only 4-byte or
+ * smaller fields, but when examining a struct that contains 8-byte fields,
+ * use this function for safety.
+ */
+Page
+get_page_from_raw(bytea *raw_page)
+{
+ Page page;
+ int raw_page_size;
+
+ raw_page_size = VARSIZE_ANY_EXHDR(raw_page);
+
+ if (raw_page_size != BLCKSZ)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("invalid page size"),
+ errdetail("Expected %d bytes, got %d.",
+ BLCKSZ, raw_page_size)));
+
+ page = palloc(raw_page_size);
+
+ memcpy(page, VARDATA_ANY(raw_page), raw_page_size);
+
+ return page;
+}
+
+
/*
* page_header
*
@@ -236,3 +281,39 @@ page_header(PG_FUNCTION_ARGS)
PG_RETURN_DATUM(result);
}
+
+/*
+ * page_checksum
+ *
+ * Compute checksum of a raw page
+ */
+
+PG_FUNCTION_INFO_V1(page_checksum);
+
+Datum
+page_checksum(PG_FUNCTION_ARGS)
+{
+ bytea *raw_page = PG_GETARG_BYTEA_P(0);
+ uint32 blkno = PG_GETARG_INT32(1);
+ int raw_page_size;
+ PageHeader page;
+
+ 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 the supplied page is of the right size.
+ */
+ if (raw_page_size != BLCKSZ)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("incorrect size of input page (%d bytes)", raw_page_size)));
+
+ page = (PageHeader) VARDATA(raw_page);
+
+ PG_RETURN_INT16(pg_checksum_page((char *) page, blkno));
+}