diff -cpr pgsql-orig/src/backend/commands/vacuum.c pgsql/src/backend/commands/vacuum.c *** pgsql-orig/src/backend/commands/vacuum.c 2005-08-31 19:31:59.000000000 +0900 --- pgsql/src/backend/commands/vacuum.c 2005-09-01 09:19:50.868589816 +0900 *************** scan_heap(VRelStats *vacrelstats, Relati *** 1357,1363 **** TransactionIdPrecedes(HeapTupleHeaderGetXmin(tuple.t_data), FreezeLimit)) { ! HeapTupleHeaderSetXmin(tuple.t_data, FrozenTransactionId); /* infomask should be okay already */ Assert(tuple.t_data->t_infomask & HEAP_XMIN_COMMITTED); pgchanged = true; --- 1357,1363 ---- TransactionIdPrecedes(HeapTupleHeaderGetXmin(tuple.t_data), FreezeLimit)) { ! tuple.t_data->t_infomask |= HEAP_FROZEN; /* infomask should be okay already */ Assert(tuple.t_data->t_infomask & HEAP_XMIN_COMMITTED); pgchanged = true; diff -cpr pgsql-orig/src/backend/commands/vacuumlazy.c pgsql/src/backend/commands/vacuumlazy.c *** pgsql-orig/src/backend/commands/vacuumlazy.c 2005-08-31 19:31:59.000000000 +0900 --- pgsql/src/backend/commands/vacuumlazy.c 2005-09-01 09:19:50.786602280 +0900 *************** lazy_scan_heap(Relation onerel, LVRelSta *** 381,387 **** TransactionIdPrecedes(HeapTupleHeaderGetXmin(tuple.t_data), FreezeLimit)) { ! HeapTupleHeaderSetXmin(tuple.t_data, FrozenTransactionId); /* infomask should be okay already */ Assert(tuple.t_data->t_infomask & HEAP_XMIN_COMMITTED); pgchanged = true; --- 381,387 ---- TransactionIdPrecedes(HeapTupleHeaderGetXmin(tuple.t_data), FreezeLimit)) { ! tuple.t_data->t_infomask |= HEAP_FROZEN; /* infomask should be okay already */ Assert(tuple.t_data->t_infomask & HEAP_XMIN_COMMITTED); pgchanged = true; diff -cpr pgsql-orig/src/backend/storage/page/bufpage.c pgsql/src/backend/storage/page/bufpage.c *** pgsql-orig/src/backend/storage/page/bufpage.c 2005-08-31 19:31:59.000000000 +0900 --- pgsql/src/backend/storage/page/bufpage.c 2005-09-01 09:28:36.192728408 +0900 *************** *** 15,20 **** --- 15,21 ---- #include "postgres.h" #include "storage/bufpage.h" + #include "access/htup.h" /* ---------------------------------------------------------------- *************** typedef struct itemIdSortData *** 281,287 **** int offsetindex; /* linp array index */ int itemoff; /* page offset of item data */ Size alignedlen; /* MAXALIGN(item data len) */ ! ItemIdData olditemid; /* used only in PageIndexMultiDelete */ } itemIdSortData; typedef itemIdSortData *itemIdSort; --- 282,292 ---- int offsetindex; /* linp array index */ int itemoff; /* page offset of item data */ Size alignedlen; /* MAXALIGN(item data len) */ ! union ! { ! int cutlen; /* used only in PageRepairFragmentation */ ! ItemIdData olditemid; /* used only in PageIndexMultiDelete */ ! } extra; } itemIdSortData; typedef itemIdSortData *itemIdSort; *************** PageRepairFragmentation(Page page, Offse *** 372,385 **** { itemidptr->offsetindex = i; itemidptr->itemoff = lp->lp_off; ! if (itemidptr->itemoff < (int) pd_upper || itemidptr->itemoff >= (int) pd_special) ereport(ERROR, (errcode(ERRCODE_DATA_CORRUPTED), errmsg("corrupted item pointer: %u", itemidptr->itemoff))); itemidptr->alignedlen = MAXALIGN(lp->lp_len); ! totallen += itemidptr->alignedlen; itemidptr++; } else --- 377,400 ---- { itemidptr->offsetindex = i; itemidptr->itemoff = lp->lp_off; ! if (MAXIMUM_ALIGNOF <= offsetof(HeapTupleFields, t_xmax) && ! ((HeapTupleHeader) PageGetItem(page, lp))->t_infomask & HEAP_FROZEN) ! { ! /* assume offsetof(xmax) == sizeof(xmin) + sizeof(cmin) */ ! itemidptr->extra.cutlen = offsetof(HeapTupleFields, t_xmax); ! } ! else ! { ! itemidptr->extra.cutlen = 0; ! } ! if (itemidptr->itemoff + itemidptr->extra.cutlen < (int) pd_upper || itemidptr->itemoff >= (int) pd_special) ereport(ERROR, (errcode(ERRCODE_DATA_CORRUPTED), errmsg("corrupted item pointer: %u", itemidptr->itemoff))); itemidptr->alignedlen = MAXALIGN(lp->lp_len); ! totallen += itemidptr->alignedlen - itemidptr->extra.cutlen; itemidptr++; } else *************** PageRepairFragmentation(Page page, Offse *** 404,414 **** for (i = 0, itemidptr = itemidbase; i < nused; i++, itemidptr++) { lp = PageGetItemId(page, itemidptr->offsetindex + 1); ! upper -= itemidptr->alignedlen; memmove((char *) page + upper, ! (char *) page + itemidptr->itemoff, ! itemidptr->alignedlen); ! lp->lp_off = upper; } ((PageHeader) page)->pd_upper = upper; --- 419,429 ---- for (i = 0, itemidptr = itemidbase; i < nused; i++, itemidptr++) { lp = PageGetItemId(page, itemidptr->offsetindex + 1); ! lp->lp_off = upper - itemidptr->alignedlen; ! upper = lp->lp_off + itemidptr->extra.cutlen; memmove((char *) page + upper, ! (char *) page + itemidptr->itemoff + itemidptr->extra.cutlen, ! itemidptr->alignedlen - itemidptr->extra.cutlen); } ((PageHeader) page)->pd_upper = upper; *************** PageIndexMultiDelete(Page page, OffsetNu *** 636,642 **** { itemidptr->offsetindex = nused; /* where it will go */ itemidptr->itemoff = offset; ! itemidptr->olditemid = *lp; itemidptr->alignedlen = MAXALIGN(size); totallen += itemidptr->alignedlen; itemidptr++; --- 651,657 ---- { itemidptr->offsetindex = nused; /* where it will go */ itemidptr->itemoff = offset; ! itemidptr->extra.olditemid = *lp; itemidptr->alignedlen = MAXALIGN(size); totallen += itemidptr->alignedlen; itemidptr++; *************** PageIndexMultiDelete(Page page, OffsetNu *** 668,674 **** memmove((char *) page + upper, (char *) page + itemidptr->itemoff, itemidptr->alignedlen); ! *lp = itemidptr->olditemid; lp->lp_off = upper; } --- 683,689 ---- memmove((char *) page + upper, (char *) page + itemidptr->itemoff, itemidptr->alignedlen); ! *lp = itemidptr->extra.olditemid; lp->lp_off = upper; } diff -cpr pgsql-orig/src/include/access/htup.h pgsql/src/include/access/htup.h *** pgsql-orig/src/include/access/htup.h 2005-08-31 19:31:59.000000000 +0900 --- pgsql/src/include/access/htup.h 2005-08-31 19:33:18.000000000 +0900 *************** typedef HeapTupleHeaderData *HeapTupleHe *** 167,173 **** * attribute(s) */ #define HEAP_HASEXTENDED 0x000C /* the two above combined */ #define HEAP_HASOID 0x0010 /* has an object-id field */ ! /* 0x0020 is presently unused */ #define HEAP_XMAX_EXCL_LOCK 0x0040 /* xmax is exclusive locker */ #define HEAP_XMAX_SHARED_LOCK 0x0080 /* xmax is shared locker */ /* if either LOCK bit is set, xmax hasn't deleted the tuple, only locked it */ --- 167,173 ---- * attribute(s) */ #define HEAP_HASEXTENDED 0x000C /* the two above combined */ #define HEAP_HASOID 0x0010 /* has an object-id field */ ! #define HEAP_FROZEN 0x0020 /* no xmin and cmin */ #define HEAP_XMAX_EXCL_LOCK 0x0040 /* xmax is exclusive locker */ #define HEAP_XMAX_SHARED_LOCK 0x0080 /* xmax is shared locker */ /* if either LOCK bit is set, xmax hasn't deleted the tuple, only locked it */ *************** typedef HeapTupleHeaderData *HeapTupleHe *** 184,190 **** * VACUUM FULL */ #define HEAP_MOVED (HEAP_MOVED_OFF | HEAP_MOVED_IN) ! #define HEAP_XACT_MASK 0xFFC0 /* visibility-related bits */ /* --- 184,190 ---- * VACUUM FULL */ #define HEAP_MOVED (HEAP_MOVED_OFF | HEAP_MOVED_IN) ! #define HEAP_XACT_MASK 0xFFE0 /* visibility-related bits */ /* *************** typedef HeapTupleHeaderData *HeapTupleHe *** 196,202 **** #define HeapTupleHeaderGetXmin(tup) \ ( \ ! (tup)->t_choice.t_heap.t_xmin \ ) #define HeapTupleHeaderSetXmin(tup, xid) \ --- 196,205 ---- #define HeapTupleHeaderGetXmin(tup) \ ( \ ! ((tup)->t_infomask & HEAP_FROZEN) ? \ ! FrozenTransactionId \ ! : \ ! (tup)->t_choice.t_heap.t_xmin \ ) #define HeapTupleHeaderSetXmin(tup, xid) \