@@ -109,13 +109,15 @@ spgRedoAddLeaf(XLogRecPtr lsn, XLogRecord *record)
109109{
110110char * ptr = XLogRecGetData (record );
111111spgxlogAddLeaf * xldata = (spgxlogAddLeaf * )ptr ;
112- SpGistLeafTuple leafTuple ;
112+ char * leafTuple ;
113+ SpGistLeafTupleData leafTupleHdr ;
113114Buffer buffer ;
114115Page page ;
115116
116- /* we assume this is adequately aligned */
117117ptr += sizeof (spgxlogAddLeaf );
118- leafTuple = (SpGistLeafTuple )ptr ;
118+ leafTuple = ptr ;
119+ /* the leaf tuple is unaligned, so make a copy to access its header */
120+ memcpy (& leafTupleHdr ,leafTuple ,sizeof (SpGistLeafTupleData ));
119121
120122/*
121123 * In normal operation we would have both current and parent pages locked
@@ -142,7 +144,7 @@ spgRedoAddLeaf(XLogRecPtr lsn, XLogRecord *record)
142144if (xldata -> offnumLeaf != xldata -> offnumHeadLeaf )
143145{
144146/* normal cases, tuple was added by SpGistPageAddNewItem */
145- addOrReplaceTuple (page , (Item )leafTuple ,leafTuple -> size ,
147+ addOrReplaceTuple (page , (Item )leafTuple ,leafTupleHdr . size ,
146148xldata -> offnumLeaf );
147149
148150/* update head tuple's chain link if needed */
@@ -152,7 +154,7 @@ spgRedoAddLeaf(XLogRecPtr lsn, XLogRecord *record)
152154
153155head = (SpGistLeafTuple )PageGetItem (page ,
154156PageGetItemId (page ,xldata -> offnumHeadLeaf ));
155- Assert (head -> nextOffset == leafTuple -> nextOffset );
157+ Assert (head -> nextOffset == leafTupleHdr . nextOffset );
156158head -> nextOffset = xldata -> offnumLeaf ;
157159}
158160}
@@ -161,10 +163,10 @@ spgRedoAddLeaf(XLogRecPtr lsn, XLogRecord *record)
161163/* replacing a DEAD tuple */
162164PageIndexTupleDelete (page ,xldata -> offnumLeaf );
163165if (PageAddItem (page ,
164- (Item )leafTuple ,leafTuple -> size ,
166+ (Item )leafTuple ,leafTupleHdr . size ,
165167xldata -> offnumLeaf , false, false)!= xldata -> offnumLeaf )
166168elog (ERROR ,"failed to add item of size %u to SPGiST index page" ,
167- leafTuple -> size );
169+ leafTupleHdr . size );
168170}
169171
170172PageSetLSN (page ,lsn );
@@ -217,11 +219,11 @@ spgRedoMoveLeafs(XLogRecPtr lsn, XLogRecord *record)
217219
218220nInsert = xldata -> replaceDead ?1 :xldata -> nMoves + 1 ;
219221
220- ptr += MAXALIGN ( sizeof ( spgxlogMoveLeafs )) ;
222+ ptr += SizeOfSpgxlogMoveLeafs ;
221223toDelete = (OffsetNumber * )ptr ;
222- ptr += MAXALIGN ( sizeof (OffsetNumber )* xldata -> nMoves ) ;
224+ ptr += sizeof (OffsetNumber )* xldata -> nMoves ;
223225toInsert = (OffsetNumber * )ptr ;
224- ptr += MAXALIGN ( sizeof (OffsetNumber )* nInsert ) ;
226+ ptr += sizeof (OffsetNumber )* nInsert ;
225227
226228/* now ptr points to the list of leaf tuples */
227229
@@ -252,10 +254,20 @@ spgRedoMoveLeafs(XLogRecPtr lsn, XLogRecord *record)
252254
253255for (i = 0 ;i < nInsert ;i ++ )
254256{
255- SpGistLeafTuple lt = (SpGistLeafTuple )ptr ;
257+ char * leafTuple ;
258+ SpGistLeafTupleData leafTupleHdr ;
256259
257- addOrReplaceTuple (page , (Item )lt ,lt -> size ,toInsert [i ]);
258- ptr += lt -> size ;
260+ /*
261+ * the tuples are not aligned, so must copy to access
262+ * the size field.
263+ */
264+ leafTuple = ptr ;
265+ memcpy (& leafTupleHdr ,leafTuple ,
266+ sizeof (SpGistLeafTupleData ));
267+
268+ addOrReplaceTuple (page , (Item )leafTuple ,
269+ leafTupleHdr .size ,toInsert [i ]);
270+ ptr += leafTupleHdr .size ;
259271}
260272
261273PageSetLSN (page ,lsn );
@@ -321,15 +333,17 @@ spgRedoAddNode(XLogRecPtr lsn, XLogRecord *record)
321333{
322334char * ptr = XLogRecGetData (record );
323335spgxlogAddNode * xldata = (spgxlogAddNode * )ptr ;
324- SpGistInnerTuple innerTuple ;
336+ char * innerTuple ;
337+ SpGistInnerTupleData innerTupleHdr ;
325338SpGistState state ;
326339Buffer buffer ;
327340Page page ;
328341int bbi ;
329342
330- /* we assume this is adequately aligned */
331343ptr += sizeof (spgxlogAddNode );
332- innerTuple = (SpGistInnerTuple )ptr ;
344+ innerTuple = ptr ;
345+ /* the tuple is unaligned, so make a copy to access its header */
346+ memcpy (& innerTupleHdr ,innerTuple ,sizeof (SpGistInnerTupleData ));
333347
334348fillFakeState (& state ,xldata -> stateSrc );
335349
@@ -348,11 +362,11 @@ spgRedoAddNode(XLogRecPtr lsn, XLogRecord *record)
348362if (lsn > PageGetLSN (page ))
349363{
350364PageIndexTupleDelete (page ,xldata -> offnum );
351- if (PageAddItem (page , (Item )innerTuple ,innerTuple -> size ,
365+ if (PageAddItem (page , (Item )innerTuple ,innerTupleHdr . size ,
352366xldata -> offnum ,
353367false, false)!= xldata -> offnum )
354368elog (ERROR ,"failed to add item of size %u to SPGiST index page" ,
355- innerTuple -> size );
369+ innerTupleHdr . size );
356370
357371PageSetLSN (page ,lsn );
358372MarkBufferDirty (buffer );
@@ -393,7 +407,7 @@ spgRedoAddNode(XLogRecPtr lsn, XLogRecord *record)
393407if (lsn > PageGetLSN (page ))
394408{
395409addOrReplaceTuple (page , (Item )innerTuple ,
396- innerTuple -> size ,xldata -> offnumNew );
410+ innerTupleHdr . size ,xldata -> offnumNew );
397411
398412/*
399413 * If parent is in this same page, don't advance LSN;
@@ -508,16 +522,21 @@ spgRedoSplitTuple(XLogRecPtr lsn, XLogRecord *record)
508522{
509523char * ptr = XLogRecGetData (record );
510524spgxlogSplitTuple * xldata = (spgxlogSplitTuple * )ptr ;
511- SpGistInnerTuple prefixTuple ;
512- SpGistInnerTuple postfixTuple ;
525+ char * prefixTuple ;
526+ SpGistInnerTupleData prefixTupleHdr ;
527+ char * postfixTuple ;
528+ SpGistInnerTupleData postfixTupleHdr ;
513529Buffer buffer ;
514530Page page ;
515531
516- /* we assume this is adequately aligned */
517532ptr += sizeof (spgxlogSplitTuple );
518- prefixTuple = (SpGistInnerTuple )ptr ;
519- ptr += prefixTuple -> size ;
520- postfixTuple = (SpGistInnerTuple )ptr ;
533+ prefixTuple = ptr ;
534+ /* the prefix tuple is unaligned, so make a copy to access its header */
535+ memcpy (& prefixTupleHdr ,prefixTuple ,sizeof (SpGistInnerTupleData ));
536+ ptr += prefixTupleHdr .size ;
537+ postfixTuple = ptr ;
538+ /* postfix tuple is also unaligned */
539+ memcpy (& postfixTupleHdr ,postfixTuple ,sizeof (SpGistInnerTupleData ));
521540
522541/*
523542 * In normal operation we would have both pages locked simultaneously; but
@@ -543,7 +562,7 @@ spgRedoSplitTuple(XLogRecPtr lsn, XLogRecord *record)
543562if (lsn > PageGetLSN (page ))
544563{
545564addOrReplaceTuple (page , (Item )postfixTuple ,
546- postfixTuple -> size ,xldata -> offnumPostfix );
565+ postfixTupleHdr . size ,xldata -> offnumPostfix );
547566
548567PageSetLSN (page ,lsn );
549568MarkBufferDirty (buffer );
@@ -564,14 +583,14 @@ spgRedoSplitTuple(XLogRecPtr lsn, XLogRecord *record)
564583if (lsn > PageGetLSN (page ))
565584{
566585PageIndexTupleDelete (page ,xldata -> offnumPrefix );
567- if (PageAddItem (page , (Item )prefixTuple ,prefixTuple -> size ,
586+ if (PageAddItem (page , (Item )prefixTuple ,prefixTupleHdr . size ,
568587xldata -> offnumPrefix , false, false)!= xldata -> offnumPrefix )
569588elog (ERROR ,"failed to add item of size %u to SPGiST index page" ,
570- prefixTuple -> size );
589+ prefixTupleHdr . size );
571590
572591if (xldata -> blknoPostfix == xldata -> blknoPrefix )
573592addOrReplaceTuple (page , (Item )postfixTuple ,
574- postfixTuple -> size ,
593+ postfixTupleHdr . size ,
575594xldata -> offnumPostfix );
576595
577596PageSetLSN (page ,lsn );
@@ -587,7 +606,8 @@ spgRedoPickSplit(XLogRecPtr lsn, XLogRecord *record)
587606{
588607char * ptr = XLogRecGetData (record );
589608spgxlogPickSplit * xldata = (spgxlogPickSplit * )ptr ;
590- SpGistInnerTuple innerTuple ;
609+ char * innerTuple ;
610+ SpGistInnerTupleData innerTupleHdr ;
591611SpGistState state ;
592612OffsetNumber * toDelete ;
593613OffsetNumber * toInsert ;
@@ -602,15 +622,18 @@ spgRedoPickSplit(XLogRecPtr lsn, XLogRecord *record)
602622
603623fillFakeState (& state ,xldata -> stateSrc );
604624
605- ptr += MAXALIGN (sizeof (spgxlogPickSplit ));
606- innerTuple = (SpGistInnerTuple )ptr ;
607- ptr += innerTuple -> size ;
625+ ptr += SizeOfSpgxlogPickSplit ;
608626toDelete = (OffsetNumber * )ptr ;
609- ptr += MAXALIGN ( sizeof (OffsetNumber )* xldata -> nDelete ) ;
627+ ptr += sizeof (OffsetNumber )* xldata -> nDelete ;
610628toInsert = (OffsetNumber * )ptr ;
611- ptr += MAXALIGN ( sizeof (OffsetNumber )* xldata -> nInsert ) ;
629+ ptr += sizeof (OffsetNumber )* xldata -> nInsert ;
612630leafPageSelect = (uint8 * )ptr ;
613- ptr += MAXALIGN (sizeof (uint8 )* xldata -> nInsert );
631+ ptr += sizeof (uint8 )* xldata -> nInsert ;
632+
633+ innerTuple = ptr ;
634+ /* the inner tuple is unaligned, so make a copy to access its header */
635+ memcpy (& innerTupleHdr ,innerTuple ,sizeof (SpGistInnerTupleData ));
636+ ptr += innerTupleHdr .size ;
614637
615638/* now ptr points to the list of leaf tuples */
616639
@@ -735,15 +758,20 @@ spgRedoPickSplit(XLogRecPtr lsn, XLogRecord *record)
735758/* restore leaf tuples to src and/or dest page */
736759for (i = 0 ;i < xldata -> nInsert ;i ++ )
737760{
738- SpGistLeafTuple lt = (SpGistLeafTuple )ptr ;
761+ char * leafTuple ;
762+ SpGistLeafTupleData leafTupleHdr ;
739763
740- ptr += lt -> size ;
764+ /* the tuples are not aligned, so must copy to access the size field. */
765+ leafTuple = ptr ;
766+ memcpy (& leafTupleHdr ,leafTuple ,sizeof (SpGistLeafTupleData ));
767+ ptr += leafTupleHdr .size ;
741768
742769page = leafPageSelect [i ] ?destPage :srcPage ;
743770if (page == NULL )
744771continue ;/* no need to touch this page */
745772
746- addOrReplaceTuple (page , (Item )lt ,lt -> size ,toInsert [i ]);
773+ addOrReplaceTuple (page , (Item )leafTuple ,leafTupleHdr .size ,
774+ toInsert [i ]);
747775}
748776
749777/* Now update src and dest page LSNs if needed */
@@ -776,7 +804,7 @@ spgRedoPickSplit(XLogRecPtr lsn, XLogRecord *record)
776804
777805if (lsn > PageGetLSN (page ))
778806{
779- addOrReplaceTuple (page , (Item )innerTuple ,innerTuple -> size ,
807+ addOrReplaceTuple (page , (Item )innerTuple ,innerTupleHdr . size ,
780808xldata -> offnumInner );
781809
782810/* if inner is also parent, update link while we're here */
@@ -861,7 +889,7 @@ spgRedoVacuumLeaf(XLogRecPtr lsn, XLogRecord *record)
861889
862890fillFakeState (& state ,xldata -> stateSrc );
863891
864- ptr += sizeof ( spgxlogVacuumLeaf ) ;
892+ ptr += SizeOfSpgxlogVacuumLeaf ;
865893toDead = (OffsetNumber * )ptr ;
866894ptr += sizeof (OffsetNumber )* xldata -> nDead ;
867895toPlaceholder = (OffsetNumber * )ptr ;
@@ -941,8 +969,7 @@ spgRedoVacuumRoot(XLogRecPtr lsn, XLogRecord *record)
941969Buffer buffer ;
942970Page page ;
943971
944- ptr += sizeof (spgxlogVacuumRoot );
945- toDelete = (OffsetNumber * )ptr ;
972+ toDelete = xldata -> offsets ;
946973
947974if (record -> xl_info & XLR_BKP_BLOCK (0 ))
948975(void )RestoreBackupBlock (lsn ,record ,0 , false, false);
@@ -974,8 +1001,7 @@ spgRedoVacuumRedirect(XLogRecPtr lsn, XLogRecord *record)
9741001Buffer buffer ;
9751002Page page ;
9761003
977- ptr += sizeof (spgxlogVacuumRedirect );
978- itemToPlaceholder = (OffsetNumber * )ptr ;
1004+ itemToPlaceholder = xldata -> offsets ;
9791005
9801006/*
9811007 * If any redirection tuples are being removed, make sure there are no