88 *
99 *
1010 * IDENTIFICATION
11- * $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.144 2000/03/17 02:36:06 tgl Exp $
11+ * $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.145 2000/04/06 00:29:51 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -1510,6 +1510,8 @@ vc_repair_frag(VRelStats *vacrelstats, Relation onerel,
15101510ItemPointerSetInvalid (& Ctid );
15111511for (ti = 0 ;ti < num_vtmove ;ti ++ )
15121512{
1513+ VPageDescr destvpd = vtmove [ti ].vpd ;
1514+
15131515/* Get tuple from chain */
15141516tuple .t_self = vtmove [ti ].tid ;
15151517Cbuf = ReadBuffer (onerel ,
@@ -1521,7 +1523,7 @@ vc_repair_frag(VRelStats *vacrelstats, Relation onerel,
15211523tuple .t_data = (HeapTupleHeader )PageGetItem (Cpage ,Citemid );
15221524tuple_len = tuple .t_len = ItemIdGetLength (Citemid );
15231525/* Get page to move in */
1524- cur_buffer = ReadBuffer (onerel ,vtmove [ ti ]. vpd -> vpd_blkno );
1526+ cur_buffer = ReadBuffer (onerel ,destvpd -> vpd_blkno );
15251527
15261528/*
15271529 * We should LockBuffer(cur_buffer) but don't, at the
@@ -1530,9 +1532,24 @@ vc_repair_frag(VRelStats *vacrelstats, Relation onerel,
15301532 * to get t_infomask of inserted heap tuple !!!
15311533 */
15321534ToPage = BufferGetPage (cur_buffer );
1533- /* if this page was not used before - clean it */
1535+ /*
1536+ * If this page was not used before - clean it.
1537+ *
1538+ * This path is different from the other callers of
1539+ * vc_vacpage, because we have already incremented the
1540+ * vpd's vpd_offsets_used field to account for the
1541+ * tuple(s) we expect to move onto the page. Therefore
1542+ * vc_vacpage's check for vpd_offsets_used == 0 is wrong.
1543+ * But since that's a good debugging check for all other
1544+ * callers, we work around it here rather than remove it.
1545+ */
15341546if (!PageIsEmpty (ToPage )&& vtmove [ti ].cleanVpd )
1535- vc_vacpage (ToPage ,vtmove [ti ].vpd );
1547+ {
1548+ int sv_offsets_used = destvpd -> vpd_offsets_used ;
1549+ destvpd -> vpd_offsets_used = 0 ;
1550+ vc_vacpage (ToPage ,destvpd );
1551+ destvpd -> vpd_offsets_used = sv_offsets_used ;
1552+ }
15361553heap_copytuple_with_tuple (& tuple ,& newtup );
15371554RelationInvalidateHeapTuple (onerel ,& tuple );
15381555TransactionIdStore (myXID , (TransactionId * )& (newtup .t_data -> t_cmin ));
@@ -1543,17 +1560,16 @@ vc_repair_frag(VRelStats *vacrelstats, Relation onerel,
15431560InvalidOffsetNumber ,LP_USED );
15441561if (newoff == InvalidOffsetNumber )
15451562{
1546- elog (ERROR ,"\
1547- moving chain: failed to add item with len = %u to page %u" ,
1548- tuple_len ,vtmove [ti ].vpd -> vpd_blkno );
1563+ elog (ERROR ,"moving chain: failed to add item with len = %u to page %u" ,
1564+ tuple_len ,destvpd -> vpd_blkno );
15491565}
15501566newitemid = PageGetItemId (ToPage ,newoff );
15511567pfree (newtup .t_data );
15521568newtup .t_datamcxt = NULL ;
15531569newtup .t_data = (HeapTupleHeader )PageGetItem (ToPage ,newitemid );
1554- ItemPointerSet (& (newtup .t_self ),vtmove [ ti ]. vpd -> vpd_blkno ,newoff );
1555- if (((int )vtmove [ ti ]. vpd -> vpd_blkno )> last_move_dest_block )
1556- last_move_dest_block = vtmove [ ti ]. vpd -> vpd_blkno ;
1570+ ItemPointerSet (& (newtup .t_self ),destvpd -> vpd_blkno ,newoff );
1571+ if (((int )destvpd -> vpd_blkno )> last_move_dest_block )
1572+ last_move_dest_block = destvpd -> vpd_blkno ;
15571573
15581574/*
15591575 * Set t_ctid pointing to itself for last tuple in