@@ -109,13 +109,15 @@ spgRedoAddLeaf(XLogRecPtr lsn, XLogRecord *record)
109109{
110110 char * ptr = XLogRecGetData (record );
111111 spgxlogAddLeaf * xldata = (spgxlogAddLeaf * ) ptr ;
112- SpGistLeafTuple leafTuple ;
112+ char * leafTuple ;
113+ SpGistLeafTupleData leafTupleHdr ;
113114 Buffer buffer ;
114115 Page page ;
115116
116- /* we assume this is adequately aligned */
117117 ptr += 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)
142144 if (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 ,
146148 xldata -> offnumLeaf );
147149
148150 /* update head tuple's chain link if needed */
@@ -152,7 +154,7 @@ spgRedoAddLeaf(XLogRecPtr lsn, XLogRecord *record)
152154
153155 head = (SpGistLeafTuple ) PageGetItem (page ,
154156 PageGetItemId (page , xldata -> offnumHeadLeaf ));
155- Assert (head -> nextOffset == leafTuple -> nextOffset );
157+ Assert (head -> nextOffset == leafTupleHdr . nextOffset );
156158 head -> nextOffset = xldata -> offnumLeaf ;
157159 }
158160 }
@@ -161,10 +163,10 @@ spgRedoAddLeaf(XLogRecPtr lsn, XLogRecord *record)
161163 /* replacing a DEAD tuple */
162164 PageIndexTupleDelete (page , xldata -> offnumLeaf );
163165 if (PageAddItem (page ,
164- (Item ) leafTuple , leafTuple -> size ,
166+ (Item ) leafTuple , leafTupleHdr . size ,
165167 xldata -> offnumLeaf , false, false) != xldata -> offnumLeaf )
166168 elog (ERROR , "failed to add item of size %u to SPGiST index page" ,
167- leafTuple -> size );
169+ leafTupleHdr . size );
168170 }
169171
170172 PageSetLSN (page , lsn );
@@ -217,11 +219,11 @@ spgRedoMoveLeafs(XLogRecPtr lsn, XLogRecord *record)
217219
218220 nInsert = xldata -> replaceDead ? 1 : xldata -> nMoves + 1 ;
219221
220- ptr += MAXALIGN ( sizeof ( spgxlogMoveLeafs )) ;
222+ ptr += SizeOfSpgxlogMoveLeafs ;
221223 toDelete = (OffsetNumber * ) ptr ;
222- ptr += MAXALIGN ( sizeof (OffsetNumber ) * xldata -> nMoves ) ;
224+ ptr += sizeof (OffsetNumber ) * xldata -> nMoves ;
223225 toInsert = (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
253255 for (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
261273 PageSetLSN (page , lsn );
@@ -321,15 +333,17 @@ spgRedoAddNode(XLogRecPtr lsn, XLogRecord *record)
321333{
322334 char * ptr = XLogRecGetData (record );
323335 spgxlogAddNode * xldata = (spgxlogAddNode * ) ptr ;
324- SpGistInnerTuple innerTuple ;
336+ char * innerTuple ;
337+ SpGistInnerTupleData innerTupleHdr ;
325338 SpGistState state ;
326339 Buffer buffer ;
327340 Page page ;
328341 int bbi ;
329342
330- /* we assume this is adequately aligned */
331343 ptr += 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
334348 fillFakeState (& state , xldata -> stateSrc );
335349
@@ -348,11 +362,11 @@ spgRedoAddNode(XLogRecPtr lsn, XLogRecord *record)
348362 if (lsn > PageGetLSN (page ))
349363 {
350364 PageIndexTupleDelete (page , xldata -> offnum );
351- if (PageAddItem (page , (Item ) innerTuple , innerTuple -> size ,
365+ if (PageAddItem (page , (Item ) innerTuple , innerTupleHdr . size ,
352366 xldata -> offnum ,
353367 false, false) != xldata -> offnum )
354368 elog (ERROR , "failed to add item of size %u to SPGiST index page" ,
355- innerTuple -> size );
369+ innerTupleHdr . size );
356370
357371 PageSetLSN (page , lsn );
358372 MarkBufferDirty (buffer );
@@ -393,7 +407,7 @@ spgRedoAddNode(XLogRecPtr lsn, XLogRecord *record)
393407 if (lsn > PageGetLSN (page ))
394408 {
395409 addOrReplaceTuple (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{
509523 char * ptr = XLogRecGetData (record );
510524 spgxlogSplitTuple * xldata = (spgxlogSplitTuple * ) ptr ;
511- SpGistInnerTuple prefixTuple ;
512- SpGistInnerTuple postfixTuple ;
525+ char * prefixTuple ;
526+ SpGistInnerTupleData prefixTupleHdr ;
527+ char * postfixTuple ;
528+ SpGistInnerTupleData postfixTupleHdr ;
513529 Buffer buffer ;
514530 Page page ;
515531
516- /* we assume this is adequately aligned */
517532 ptr += 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)
543562 if (lsn > PageGetLSN (page ))
544563 {
545564 addOrReplaceTuple (page , (Item ) postfixTuple ,
546- postfixTuple -> size , xldata -> offnumPostfix );
565+ postfixTupleHdr . size , xldata -> offnumPostfix );
547566
548567 PageSetLSN (page , lsn );
549568 MarkBufferDirty (buffer );
@@ -564,14 +583,14 @@ spgRedoSplitTuple(XLogRecPtr lsn, XLogRecord *record)
564583 if (lsn > PageGetLSN (page ))
565584 {
566585 PageIndexTupleDelete (page , xldata -> offnumPrefix );
567- if (PageAddItem (page , (Item ) prefixTuple , prefixTuple -> size ,
586+ if (PageAddItem (page , (Item ) prefixTuple , prefixTupleHdr . size ,
568587 xldata -> offnumPrefix , false, false) != xldata -> offnumPrefix )
569588 elog (ERROR , "failed to add item of size %u to SPGiST index page" ,
570- prefixTuple -> size );
589+ prefixTupleHdr . size );
571590
572591 if (xldata -> blknoPostfix == xldata -> blknoPrefix )
573592 addOrReplaceTuple (page , (Item ) postfixTuple ,
574- postfixTuple -> size ,
593+ postfixTupleHdr . size ,
575594 xldata -> offnumPostfix );
576595
577596 PageSetLSN (page , lsn );
@@ -587,7 +606,8 @@ spgRedoPickSplit(XLogRecPtr lsn, XLogRecord *record)
587606{
588607 char * ptr = XLogRecGetData (record );
589608 spgxlogPickSplit * xldata = (spgxlogPickSplit * ) ptr ;
590- SpGistInnerTuple innerTuple ;
609+ char * innerTuple ;
610+ SpGistInnerTupleData innerTupleHdr ;
591611 SpGistState state ;
592612 OffsetNumber * toDelete ;
593613 OffsetNumber * toInsert ;
@@ -602,15 +622,18 @@ spgRedoPickSplit(XLogRecPtr lsn, XLogRecord *record)
602622
603623 fillFakeState (& state , xldata -> stateSrc );
604624
605- ptr += MAXALIGN (sizeof (spgxlogPickSplit ));
606- innerTuple = (SpGistInnerTuple ) ptr ;
607- ptr += innerTuple -> size ;
625+ ptr += SizeOfSpgxlogPickSplit ;
608626 toDelete = (OffsetNumber * ) ptr ;
609- ptr += MAXALIGN ( sizeof (OffsetNumber ) * xldata -> nDelete ) ;
627+ ptr += sizeof (OffsetNumber ) * xldata -> nDelete ;
610628 toInsert = (OffsetNumber * ) ptr ;
611- ptr += MAXALIGN ( sizeof (OffsetNumber ) * xldata -> nInsert ) ;
629+ ptr += sizeof (OffsetNumber ) * xldata -> nInsert ;
612630 leafPageSelect = (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 */
736759 for (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
742769 page = leafPageSelect [i ] ? destPage : srcPage ;
743770 if (page == NULL )
744771 continue ; /* 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
777805 if (lsn > PageGetLSN (page ))
778806 {
779- addOrReplaceTuple (page , (Item ) innerTuple , innerTuple -> size ,
807+ addOrReplaceTuple (page , (Item ) innerTuple , innerTupleHdr . size ,
780808 xldata -> offnumInner );
781809
782810 /* if inner is also parent, update link while we're here */
@@ -861,7 +889,7 @@ spgRedoVacuumLeaf(XLogRecPtr lsn, XLogRecord *record)
861889
862890 fillFakeState (& state , xldata -> stateSrc );
863891
864- ptr += sizeof ( spgxlogVacuumLeaf ) ;
892+ ptr += SizeOfSpgxlogVacuumLeaf ;
865893 toDead = (OffsetNumber * ) ptr ;
866894 ptr += sizeof (OffsetNumber ) * xldata -> nDead ;
867895 toPlaceholder = (OffsetNumber * ) ptr ;
@@ -941,8 +969,7 @@ spgRedoVacuumRoot(XLogRecPtr lsn, XLogRecord *record)
941969 Buffer buffer ;
942970 Page page ;
943971
944- ptr += sizeof (spgxlogVacuumRoot );
945- toDelete = (OffsetNumber * ) ptr ;
972+ toDelete = xldata -> offsets ;
946973
947974 if (record -> xl_info & XLR_BKP_BLOCK (0 ))
948975 (void ) RestoreBackupBlock (lsn , record , 0 , false, false);
@@ -974,8 +1001,7 @@ spgRedoVacuumRedirect(XLogRecPtr lsn, XLogRecord *record)
9741001 Buffer buffer ;
9751002 Page 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
0 commit comments