@@ -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{
3455 bytea * raw_page = PG_GETARG_BYTEA_P (0 );
35- int raw_page_size ;
3656 TupleDesc tupdesc ;
3757 Page page ;
3858 GinPageOpaque 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
5671 opaq = (GinPageOpaque ) PageGetSpecialPointer (page );
5772 if (opaq -> flags != GIN_META )
94109gin_page_opaque_info (PG_FUNCTION_ARGS )
95110{
96111 bytea * raw_page = PG_GETARG_BYTEA_P (0 );
97- int raw_page_size ;
98112 TupleDesc tupdesc ;
99113 Page page ;
100114 GinPageOpaque 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
120129 opaq = (GinPageOpaque ) PageGetSpecialPointer (page );
121130
@@ -173,7 +182,6 @@ Datum
173182gin_leafpage_items (PG_FUNCTION_ARGS )
174183{
175184 bytea * raw_page = PG_GETARG_BYTEA_P (0 );
176- int raw_page_size ;
177185 FuncCallContext * fctx ;
178186 gin_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-
187193 if (SRF_IS_FIRSTCALL ())
188194 {
189195 TupleDesc tupdesc ;
190196 MemoryContext mctx ;
191197 Page page ;
192198 GinPageOpaque 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
200205 if (PageGetSpecialSize (page ) != MAXALIGN (sizeof (GinPageOpaqueData )))
201206 ereport (ERROR ,
@@ -214,9 +219,6 @@ gin_leafpage_items(PG_FUNCTION_ARGS)
214219 opaq -> flags ,
215220 (GIN_DATA | GIN_LEAF | GIN_COMPRESSED ))));
216221
217- fctx = SRF_FIRSTCALL_INIT ();
218- mctx = MemoryContextSwitchTo (fctx -> multi_call_memory_ctx );
219-
220222 inter_call_data = palloc (sizeof (gin_leafpage_items_state ));
221223
222224 /* Build a tuple descriptor for our result type */
0 commit comments