aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--contrib/pageinspect/ginfuncs.c46
1 files changed, 24 insertions, 22 deletions
diff --git a/contrib/pageinspect/ginfuncs.c b/contrib/pageinspect/ginfuncs.c
index 145e2ce709c..6e4103df6a9 100644
--- a/contrib/pageinspect/ginfuncs.c
+++ b/contrib/pageinspect/ginfuncs.c
@@ -28,11 +28,31 @@ PG_FUNCTION_INFO_V1(gin_metapage_info);
PG_FUNCTION_INFO_V1(gin_page_opaque_info);
PG_FUNCTION_INFO_V1(gin_leafpage_items);
+
+static Page
+get_page_from_raw(bytea *raw_page)
+{
+ int raw_page_size;
+ Page page;
+
+ raw_page_size = VARSIZE(raw_page) - VARHDRSZ;
+ if (raw_page_size < BLCKSZ)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("input page too small (%d bytes)", raw_page_size)));
+
+ /* make a copy so that the page is properly aligned for struct access */
+ page = palloc(raw_page_size);
+ memcpy(page, VARDATA(raw_page), raw_page_size);
+
+ return page;
+}
+
+
Datum
gin_metapage_info(PG_FUNCTION_ARGS)
{
bytea *raw_page = PG_GETARG_BYTEA_P(0);
- int raw_page_size;
TupleDesc tupdesc;
Page page;
GinPageOpaque opaq;
@@ -46,12 +66,7 @@ gin_metapage_info(PG_FUNCTION_ARGS)
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
(errmsg("must be superuser to use raw page functions"))));
- raw_page_size = VARSIZE(raw_page) - VARHDRSZ;
- if (raw_page_size < BLCKSZ)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("input page too small (%d bytes)", raw_page_size)));
- page = VARDATA(raw_page);
+ page = get_page_from_raw(raw_page);
opaq = (GinPageOpaque) PageGetSpecialPointer(page);
if (opaq->flags != GIN_META)
@@ -94,7 +109,6 @@ Datum
gin_page_opaque_info(PG_FUNCTION_ARGS)
{
bytea *raw_page = PG_GETARG_BYTEA_P(0);
- int raw_page_size;
TupleDesc tupdesc;
Page page;
GinPageOpaque opaq;
@@ -110,12 +124,7 @@ gin_page_opaque_info(PG_FUNCTION_ARGS)
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
(errmsg("must be superuser to use raw page functions"))));
- raw_page_size = VARSIZE(raw_page) - VARHDRSZ;
- if (raw_page_size < BLCKSZ)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("input page too small (%d bytes)", raw_page_size)));
- page = VARDATA(raw_page);
+ page = get_page_from_raw(raw_page);
opaq = (GinPageOpaque) PageGetSpecialPointer(page);
@@ -173,7 +182,6 @@ Datum
gin_leafpage_items(PG_FUNCTION_ARGS)
{
bytea *raw_page = PG_GETARG_BYTEA_P(0);
- int raw_page_size;
FuncCallContext *fctx;
gin_leafpage_items_state *inter_call_data;
@@ -182,8 +190,6 @@ gin_leafpage_items(PG_FUNCTION_ARGS)
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
(errmsg("must be superuser to use raw page functions"))));
- raw_page_size = VARSIZE(raw_page) - VARHDRSZ;
-
if (SRF_IS_FIRSTCALL())
{
TupleDesc tupdesc;
@@ -191,11 +197,7 @@ gin_leafpage_items(PG_FUNCTION_ARGS)
Page page;
GinPageOpaque opaq;
- if (raw_page_size < BLCKSZ)
- ereport(ERROR,
- (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
- errmsg("input page too small (%d bytes)", raw_page_size)));
- page = VARDATA(raw_page);
+ page = get_page_from_raw(raw_page);
if (PageGetSpecialSize(page) != MAXALIGN(sizeof(GinPageOpaqueData)))
ereport(ERROR,