@@ -28,11 +28,31 @@ PG_FUNCTION_INFO_V1(gin_metapage_info);
2828PG_FUNCTION_INFO_V1 (gin_page_opaque_info );
2929PG_FUNCTION_INFO_V1 (gin_leafpage_items );
3030
31+
32+ static Page
33+ get_page_from_raw (bytea * raw_page )
34+ {
35+ int raw_page_size ;
36+ Page page ;
37+
38+ raw_page_size = VARSIZE (raw_page )- VARHDRSZ ;
39+ if (raw_page_size < BLCKSZ )
40+ ereport (ERROR ,
41+ (errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
42+ errmsg ("input page too small (%d bytes)" ,raw_page_size )));
43+
44+ /* make a copy so that the page is properly aligned for struct access */
45+ page = palloc (raw_page_size );
46+ memcpy (page ,VARDATA (raw_page ),raw_page_size );
47+
48+ return page ;
49+ }
50+
51+
3152Datum
3253gin_metapage_info (PG_FUNCTION_ARGS )
3354{
3455bytea * raw_page = PG_GETARG_BYTEA_P (0 );
35- int raw_page_size ;
3656TupleDesc tupdesc ;
3757Page page ;
3858GinPageOpaque opaq ;
@@ -46,12 +66,7 @@ gin_metapage_info(PG_FUNCTION_ARGS)
4666(errcode (ERRCODE_INSUFFICIENT_PRIVILEGE ),
4767 (errmsg ("must be superuser to use raw page functions" ))));
4868
49- raw_page_size = VARSIZE (raw_page )- VARHDRSZ ;
50- if (raw_page_size < BLCKSZ )
51- ereport (ERROR ,
52- (errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
53- errmsg ("input page too small (%d bytes)" ,raw_page_size )));
54- page = VARDATA (raw_page );
69+ page = get_page_from_raw (raw_page );
5570
5671opaq = (GinPageOpaque )PageGetSpecialPointer (page );
5772if (opaq -> flags != GIN_META )
94109gin_page_opaque_info (PG_FUNCTION_ARGS )
95110{
96111bytea * raw_page = PG_GETARG_BYTEA_P (0 );
97- int raw_page_size ;
98112TupleDesc tupdesc ;
99113Page page ;
100114GinPageOpaque opaq ;
@@ -110,12 +124,7 @@ gin_page_opaque_info(PG_FUNCTION_ARGS)
110124(errcode (ERRCODE_INSUFFICIENT_PRIVILEGE ),
111125 (errmsg ("must be superuser to use raw page functions" ))));
112126
113- raw_page_size = VARSIZE (raw_page )- VARHDRSZ ;
114- if (raw_page_size < BLCKSZ )
115- ereport (ERROR ,
116- (errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
117- errmsg ("input page too small (%d bytes)" ,raw_page_size )));
118- page = VARDATA (raw_page );
127+ page = get_page_from_raw (raw_page );
119128
120129opaq = (GinPageOpaque )PageGetSpecialPointer (page );
121130
@@ -173,7 +182,6 @@ Datum
173182gin_leafpage_items (PG_FUNCTION_ARGS )
174183{
175184bytea * raw_page = PG_GETARG_BYTEA_P (0 );
176- int raw_page_size ;
177185FuncCallContext * fctx ;
178186gin_leafpage_items_state * inter_call_data ;
179187
@@ -182,20 +190,17 @@ gin_leafpage_items(PG_FUNCTION_ARGS)
182190(errcode (ERRCODE_INSUFFICIENT_PRIVILEGE ),
183191 (errmsg ("must be superuser to use raw page functions" ))));
184192
185- raw_page_size = VARSIZE (raw_page )- VARHDRSZ ;
186-
187193if (SRF_IS_FIRSTCALL ())
188194{
189195TupleDesc tupdesc ;
190196MemoryContext mctx ;
191197Page page ;
192198GinPageOpaque opaq ;
193199
194- if (raw_page_size < BLCKSZ )
195- ereport (ERROR ,
196- (errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
197- errmsg ("input page too small (%d bytes)" ,raw_page_size )));
198- page = VARDATA (raw_page );
200+ fctx = SRF_FIRSTCALL_INIT ();
201+ mctx = MemoryContextSwitchTo (fctx -> multi_call_memory_ctx );
202+
203+ page = get_page_from_raw (raw_page );
199204
200205if (PageGetSpecialSize (page )!= MAXALIGN (sizeof (GinPageOpaqueData )))
201206ereport (ERROR ,
@@ -214,9 +219,6 @@ gin_leafpage_items(PG_FUNCTION_ARGS)
214219opaq -> flags ,
215220 (GIN_DATA |GIN_LEAF |GIN_COMPRESSED ))));
216221
217- fctx = SRF_FIRSTCALL_INIT ();
218- mctx = MemoryContextSwitchTo (fctx -> multi_call_memory_ctx );
219-
220222inter_call_data = palloc (sizeof (gin_leafpage_items_state ));
221223
222224/* Build a tuple descriptor for our result type */