Обсуждение: page macros cleanup

Поиск
Список
Период
Сортировка

page macros cleanup

От
Zdenek Kotala
Дата:
I attached code cleanup which is related to in-place upgrade. I replace direct
access to PageHeader structure with already existing macros and I removed also
unnecessary retyping. There still lot of places which directly access to
PageHeader structure which require new macros/fuction in page API. I will fix it
in next patch.

        Zdenek
diff -cr pgsql.orig.da8c485e0e2a/src/backend/access/gist/gistutil.c pgsql.orig/src/backend/access/gist/gistutil.c
*** pgsql.orig.da8c485e0e2a/src/backend/access/gist/gistutil.c    pá črn 13 18:00:35 2008
--- pgsql.orig/src/backend/access/gist/gistutil.c    pá črn 13 18:00:35 2008
***************
*** 592,598 ****
      /*
       * Additionally check that the special area looks sane.
       */
!     if (((PageHeader) (page))->pd_special !=
          (BLCKSZ - MAXALIGN(sizeof(GISTPageOpaqueData))))
          ereport(ERROR,
                  (errcode(ERRCODE_INDEX_CORRUPTED),
--- 592,598 ----
      /*
       * Additionally check that the special area looks sane.
       */
!     if ( PageGetSpecialPointer(page) - page !=
          (BLCKSZ - MAXALIGN(sizeof(GISTPageOpaqueData))))
          ereport(ERROR,
                  (errcode(ERRCODE_INDEX_CORRUPTED),
diff -cr pgsql.orig.da8c485e0e2a/src/backend/access/hash/hashpage.c pgsql.orig/src/backend/access/hash/hashpage.c
*** pgsql.orig.da8c485e0e2a/src/backend/access/hash/hashpage.c    pá črn 13 18:00:35 2008
--- pgsql.orig/src/backend/access/hash/hashpage.c    pá črn 13 18:00:35 2008
***************
*** 407,413 ****
      for (i = _hash_log2(metap->hashm_bsize); i > 0; --i)
      {
          if ((1 << i) <= (metap->hashm_bsize -
!                          (MAXALIGN(sizeof(PageHeaderData)) +
                            MAXALIGN(sizeof(HashPageOpaqueData)))))
              break;
      }
--- 407,413 ----
      for (i = _hash_log2(metap->hashm_bsize); i > 0; --i)
      {
          if ((1 << i) <= (metap->hashm_bsize -
!                          (MAXALIGN(SizeOfPageHeaderData) +
                            MAXALIGN(sizeof(HashPageOpaqueData)))))
              break;
      }
diff -cr pgsql.orig.da8c485e0e2a/src/backend/access/hash/hashutil.c pgsql.orig/src/backend/access/hash/hashutil.c
*** pgsql.orig.da8c485e0e2a/src/backend/access/hash/hashutil.c    pá črn 13 18:00:35 2008
--- pgsql.orig/src/backend/access/hash/hashutil.c    pá črn 13 18:00:35 2008
***************
*** 164,170 ****
      /*
       * Additionally check that the special area looks sane.
       */
!     if (((PageHeader) (page))->pd_special !=
          (BLCKSZ - MAXALIGN(sizeof(HashPageOpaqueData))))
          ereport(ERROR,
                  (errcode(ERRCODE_INDEX_CORRUPTED),
--- 164,170 ----
      /*
       * Additionally check that the special area looks sane.
       */
!     if ( PageGetSpecialPointer(page) - page !=
          (BLCKSZ - MAXALIGN(sizeof(HashPageOpaqueData))))
          ereport(ERROR,
                  (errcode(ERRCODE_INDEX_CORRUPTED),
diff -cr pgsql.orig.da8c485e0e2a/src/backend/access/heap/heapam.c pgsql.orig/src/backend/access/heap/heapam.c
*** pgsql.orig.da8c485e0e2a/src/backend/access/heap/heapam.c    pá črn 13 18:00:35 2008
--- pgsql.orig/src/backend/access/heap/heapam.c    pá črn 13 18:00:35 2008
***************
*** 1342,1348 ****
      ItemPointer tid = &(tuple->t_self);
      ItemId        lp;
      Buffer        buffer;
!     PageHeader    dp;
      OffsetNumber offnum;
      bool        valid;

--- 1342,1348 ----
      ItemPointer tid = &(tuple->t_self);
      ItemId        lp;
      Buffer        buffer;
!     Page        page;
      OffsetNumber offnum;
      bool        valid;

***************
*** 1355,1361 ****
       * Need share lock on buffer to examine tuple commit status.
       */
      LockBuffer(buffer, BUFFER_LOCK_SHARE);
!     dp = (PageHeader) BufferGetPage(buffer);

      /*
       * We'd better check for out-of-range offnum in case of VACUUM since the
--- 1355,1361 ----
       * Need share lock on buffer to examine tuple commit status.
       */
      LockBuffer(buffer, BUFFER_LOCK_SHARE);
!     page = BufferGetPage(buffer);

      /*
       * We'd better check for out-of-range offnum in case of VACUUM since the
***************
*** 1362,1368 ****
       * TID was obtained.
       */
      offnum = ItemPointerGetOffsetNumber(tid);
!     if (offnum < FirstOffsetNumber || offnum > PageGetMaxOffsetNumber(dp))
      {
          LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
          if (keep_buf)
--- 1362,1368 ----
       * TID was obtained.
       */
      offnum = ItemPointerGetOffsetNumber(tid);
!     if (offnum < FirstOffsetNumber || offnum > PageGetMaxOffsetNumber(page))
      {
          LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
          if (keep_buf)
***************
*** 1379,1385 ****
      /*
       * get the item line pointer corresponding to the requested tid
       */
!     lp = PageGetItemId(dp, offnum);

      /*
       * Must check for deleted tuple.
--- 1379,1385 ----
      /*
       * get the item line pointer corresponding to the requested tid
       */
!     lp = PageGetItemId(page, offnum);

      /*
       * Must check for deleted tuple.
***************
*** 1401,1407 ****
      /*
       * fill in *tuple fields
       */
!     tuple->t_data = (HeapTupleHeader) PageGetItem((Page) dp, lp);
      tuple->t_len = ItemIdGetLength(lp);
      tuple->t_tableOid = RelationGetRelid(relation);

--- 1401,1407 ----
      /*
       * fill in *tuple fields
       */
!     tuple->t_data = (HeapTupleHeader) PageGetItem(page, lp);
      tuple->t_len = ItemIdGetLength(lp);
      tuple->t_tableOid = RelationGetRelid(relation);

***************
*** 1626,1632 ****
      for (;;)
      {
          Buffer        buffer;
!         PageHeader    dp;
          OffsetNumber offnum;
          ItemId        lp;
          HeapTupleData tp;
--- 1626,1632 ----
      for (;;)
      {
          Buffer        buffer;
!         Page        page;
          OffsetNumber offnum;
          ItemId        lp;
          HeapTupleData tp;
***************
*** 1637,1643 ****
           */
          buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(&ctid));
          LockBuffer(buffer, BUFFER_LOCK_SHARE);
!         dp = (PageHeader) BufferGetPage(buffer);

          /*
           * Check for bogus item number.  This is not treated as an error
--- 1637,1643 ----
           */
          buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(&ctid));
          LockBuffer(buffer, BUFFER_LOCK_SHARE);
!         page = BufferGetPage(buffer);

          /*
           * Check for bogus item number.  This is not treated as an error
***************
*** 1645,1656 ****
           * just assume that the prior tid is OK and return it unchanged.
           */
          offnum = ItemPointerGetOffsetNumber(&ctid);
!         if (offnum < FirstOffsetNumber || offnum > PageGetMaxOffsetNumber(dp))
          {
              UnlockReleaseBuffer(buffer);
              break;
          }
!         lp = PageGetItemId(dp, offnum);
          if (!ItemIdIsNormal(lp))
          {
              UnlockReleaseBuffer(buffer);
--- 1645,1656 ----
           * just assume that the prior tid is OK and return it unchanged.
           */
          offnum = ItemPointerGetOffsetNumber(&ctid);
!         if (offnum < FirstOffsetNumber || offnum > PageGetMaxOffsetNumber(page))
          {
              UnlockReleaseBuffer(buffer);
              break;
          }
!         lp = PageGetItemId(page, offnum);
          if (!ItemIdIsNormal(lp))
          {
              UnlockReleaseBuffer(buffer);
***************
*** 1659,1665 ****

          /* OK to access the tuple */
          tp.t_self = ctid;
!         tp.t_data = (HeapTupleHeader) PageGetItem(dp, lp);
          tp.t_len = ItemIdGetLength(lp);

          /*
--- 1659,1665 ----

          /* OK to access the tuple */
          tp.t_self = ctid;
!         tp.t_data = (HeapTupleHeader) PageGetItem(page, lp);
          tp.t_len = ItemIdGetLength(lp);

          /*
***************
*** 1963,1969 ****
      TransactionId xid = GetCurrentTransactionId();
      ItemId        lp;
      HeapTupleData tp;
!     PageHeader    dp;
      Buffer        buffer;
      bool        have_tuple_lock = false;
      bool        iscombo;
--- 1963,1969 ----
      TransactionId xid = GetCurrentTransactionId();
      ItemId        lp;
      HeapTupleData tp;
!     Page        page;
      Buffer        buffer;
      bool        have_tuple_lock = false;
      bool        iscombo;
***************
*** 1973,1983 ****
      buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));
      LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);

!     dp = (PageHeader) BufferGetPage(buffer);
!     lp = PageGetItemId(dp, ItemPointerGetOffsetNumber(tid));
      Assert(ItemIdIsNormal(lp));

!     tp.t_data = (HeapTupleHeader) PageGetItem(dp, lp);
      tp.t_len = ItemIdGetLength(lp);
      tp.t_self = *tid;

--- 1973,1983 ----
      buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));
      LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);

!     page = BufferGetPage(buffer);
!     lp = PageGetItemId(page, ItemPointerGetOffsetNumber(tid));
      Assert(ItemIdIsNormal(lp));

!     tp.t_data = (HeapTupleHeader) PageGetItem(page, lp);
      tp.t_len = ItemIdGetLength(lp);
      tp.t_self = *tid;

***************
*** 2111,2117 ****
       * the subsequent page pruning will be a no-op and the hint will be
       * cleared.
       */
!     PageSetPrunable(dp, xid);

      /* store transaction information of xact deleting the tuple */
      tp.t_data->t_infomask &= ~(HEAP_XMAX_COMMITTED |
--- 2111,2117 ----
       * the subsequent page pruning will be a no-op and the hint will be
       * cleared.
       */
!     PageSetPrunable(page, xid);

      /* store transaction information of xact deleting the tuple */
      tp.t_data->t_infomask &= ~(HEAP_XMAX_COMMITTED |
***************
*** 2149,2156 ****

          recptr = XLogInsert(RM_HEAP_ID, XLOG_HEAP_DELETE, rdata);

!         PageSetLSN(dp, recptr);
!         PageSetTLI(dp, ThisTimeLineID);
      }

      END_CRIT_SECTION();
--- 2149,2156 ----

          recptr = XLogInsert(RM_HEAP_ID, XLOG_HEAP_DELETE, rdata);

!         PageSetLSN(page, recptr);
!         PageSetTLI(page, ThisTimeLineID);
      }

      END_CRIT_SECTION();
***************
*** 2275,2281 ****
      ItemId        lp;
      HeapTupleData oldtup;
      HeapTuple    heaptup;
!     PageHeader    dp;
      Buffer        buffer,
                  newbuf;
      bool        need_toast,
--- 2275,2281 ----
      ItemId        lp;
      HeapTupleData oldtup;
      HeapTuple    heaptup;
!     Page        page;
      Buffer        buffer,
                  newbuf;
      bool        need_toast,
***************
*** 2305,2315 ****
      buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(otid));
      LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);

!     dp = (PageHeader) BufferGetPage(buffer);
!     lp = PageGetItemId(dp, ItemPointerGetOffsetNumber(otid));
      Assert(ItemIdIsNormal(lp));

!     oldtup.t_data = (HeapTupleHeader) PageGetItem(dp, lp);
      oldtup.t_len = ItemIdGetLength(lp);
      oldtup.t_self = *otid;

--- 2305,2315 ----
      buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(otid));
      LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);

!     page = BufferGetPage(buffer);
!     lp = PageGetItemId(page, ItemPointerGetOffsetNumber(otid));
      Assert(ItemIdIsNormal(lp));

!     oldtup.t_data = (HeapTupleHeader) PageGetItem(page, lp);
      oldtup.t_len = ItemIdGetLength(lp);
      oldtup.t_self = *otid;

***************
*** 2490,2496 ****
                        HeapTupleHasExternal(newtup) ||
                        newtup->t_len > TOAST_TUPLE_THRESHOLD);

!     pagefree = PageGetHeapFreeSpace((Page) dp);

      newtupsize = MAXALIGN(newtup->t_len);

--- 2490,2496 ----
                        HeapTupleHasExternal(newtup) ||
                        newtup->t_len > TOAST_TUPLE_THRESHOLD);

!     pagefree = PageGetHeapFreeSpace(page);

      newtupsize = MAXALIGN(newtup->t_len);

***************
*** 2556,2562 ****
              /* Re-acquire the lock on the old tuple's page. */
              LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);
              /* Re-check using the up-to-date free space */
!             pagefree = PageGetHeapFreeSpace((Page) dp);
              if (newtupsize > pagefree)
              {
                  /*
--- 2556,2562 ----
              /* Re-acquire the lock on the old tuple's page. */
              LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);
              /* Re-check using the up-to-date free space */
!             pagefree = PageGetHeapFreeSpace(page);
              if (newtupsize > pagefree)
              {
                  /*
***************
*** 2602,2608 ****
      else
      {
          /* Set a hint that the old page could use prune/defrag */
!         PageSetFull(dp);
      }

      /* NO EREPORT(ERROR) from here till changes are logged */
--- 2602,2608 ----
      else
      {
          /* Set a hint that the old page could use prune/defrag */
!         PageSetFull(page);
      }

      /* NO EREPORT(ERROR) from here till changes are logged */
***************
*** 2620,2626 ****
       * not to optimize for aborts.    Note that heap_xlog_update must be kept in
       * sync if this decision changes.
       */
!     PageSetPrunable(dp, xid);

      if (use_hot_update)
      {
--- 2620,2626 ----
       * not to optimize for aborts.    Note that heap_xlog_update must be kept in
       * sync if this decision changes.
       */
!     PageSetPrunable(page, xid);

      if (use_hot_update)
      {
***************
*** 2945,2951 ****
      HTSU_Result result;
      ItemPointer tid = &(tuple->t_self);
      ItemId        lp;
!     PageHeader    dp;
      TransactionId xid;
      TransactionId xmax;
      uint16        old_infomask;
--- 2945,2951 ----
      HTSU_Result result;
      ItemPointer tid = &(tuple->t_self);
      ItemId        lp;
!     Page        page;
      TransactionId xid;
      TransactionId xmax;
      uint16        old_infomask;
***************
*** 2958,2968 ****
      *buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));
      LockBuffer(*buffer, BUFFER_LOCK_EXCLUSIVE);

!     dp = (PageHeader) BufferGetPage(*buffer);
!     lp = PageGetItemId(dp, ItemPointerGetOffsetNumber(tid));
      Assert(ItemIdIsNormal(lp));

!     tuple->t_data = (HeapTupleHeader) PageGetItem((Page) dp, lp);
      tuple->t_len = ItemIdGetLength(lp);
      tuple->t_tableOid = RelationGetRelid(relation);

--- 2958,2968 ----
      *buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));
      LockBuffer(*buffer, BUFFER_LOCK_EXCLUSIVE);

!     page = BufferGetPage(*buffer);
!     lp = PageGetItemId(page, ItemPointerGetOffsetNumber(tid));
      Assert(ItemIdIsNormal(lp));

!     tuple->t_data = (HeapTupleHeader) PageGetItem(page, lp);
      tuple->t_len = ItemIdGetLength(lp);
      tuple->t_tableOid = RelationGetRelid(relation);

***************
*** 3301,3308 ****

          recptr = XLogInsert(RM_HEAP_ID, XLOG_HEAP_LOCK, rdata);

!         PageSetLSN(dp, recptr);
!         PageSetTLI(dp, ThisTimeLineID);
      }

      END_CRIT_SECTION();
--- 3301,3308 ----

          recptr = XLogInsert(RM_HEAP_ID, XLOG_HEAP_LOCK, rdata);

!         PageSetLSN(page, recptr);
!         PageSetTLI(page, ThisTimeLineID);
      }

      END_CRIT_SECTION();
diff -cr pgsql.orig.da8c485e0e2a/src/backend/access/heap/hio.c pgsql.orig/src/backend/access/heap/hio.c
*** pgsql.orig.da8c485e0e2a/src/backend/access/heap/hio.c    pá črn 13 18:00:35 2008
--- pgsql.orig/src/backend/access/heap/hio.c    pá črn 13 18:00:35 2008
***************
*** 107,113 ****
                            Buffer otherBuffer, bool use_fsm)
  {
      Buffer        buffer = InvalidBuffer;
!     Page        pageHeader;
      Size        pageFreeSpace,
                  saveFreeSpace;
      BlockNumber targetBlock,
--- 107,113 ----
                            Buffer otherBuffer, bool use_fsm)
  {
      Buffer        buffer = InvalidBuffer;
!     Page        page;
      Size        pageFreeSpace,
                  saveFreeSpace;
      BlockNumber targetBlock,
***************
*** 218,225 ****
           * Now we can check to see if there's enough free space here. If so,
           * we're done.
           */
!         pageHeader = (Page) BufferGetPage(buffer);
!         pageFreeSpace = PageGetHeapFreeSpace(pageHeader);
          if (len + saveFreeSpace <= pageFreeSpace)
          {
              /* use this page as future insert target, too */
--- 218,225 ----
           * Now we can check to see if there's enough free space here. If so,
           * we're done.
           */
!         page = BufferGetPage(buffer);
!         pageFreeSpace = PageGetHeapFreeSpace(page);
          if (len + saveFreeSpace <= pageFreeSpace)
          {
              /* use this page as future insert target, too */
***************
*** 303,318 ****
       * is empty (this should never happen, but if it does we don't want to
       * risk wiping out valid data).
       */
!     pageHeader = (Page) BufferGetPage(buffer);

!     if (!PageIsNew((PageHeader) pageHeader))
          elog(ERROR, "page %u of relation \"%s\" should be empty but is not",
               BufferGetBlockNumber(buffer),
               RelationGetRelationName(relation));

!     PageInit(pageHeader, BufferGetPageSize(buffer), 0);

!     if (len > PageGetHeapFreeSpace(pageHeader))
      {
          /* We should not get here given the test at the top */
          elog(PANIC, "tuple is too big: size %lu", (unsigned long) len);
--- 303,318 ----
       * is empty (this should never happen, but if it does we don't want to
       * risk wiping out valid data).
       */
!     page = BufferGetPage(buffer);

!     if (!PageIsNew(page))
          elog(ERROR, "page %u of relation \"%s\" should be empty but is not",
               BufferGetBlockNumber(buffer),
               RelationGetRelationName(relation));

!     PageInit(page, BufferGetPageSize(buffer), 0);

!     if (len > PageGetHeapFreeSpace(page))
      {
          /* We should not get here given the test at the top */
          elog(PANIC, "tuple is too big: size %lu", (unsigned long) len);
diff -cr pgsql.orig.da8c485e0e2a/src/backend/access/heap/pruneheap.c pgsql.orig/src/backend/access/heap/pruneheap.c
*** pgsql.orig.da8c485e0e2a/src/backend/access/heap/pruneheap.c    pá črn 13 18:00:35 2008
--- pgsql.orig/src/backend/access/heap/pruneheap.c    pá črn 13 18:00:35 2008
***************
*** 71,77 ****
  void
  heap_page_prune_opt(Relation relation, Buffer buffer, TransactionId OldestXmin)
  {
!     PageHeader    dp = (PageHeader) BufferGetPage(buffer);
      Size        minfree;

      /*
--- 71,77 ----
  void
  heap_page_prune_opt(Relation relation, Buffer buffer, TransactionId OldestXmin)
  {
!     Page        page = BufferGetPage(buffer);
      Size        minfree;

      /*
***************
*** 80,86 ****
       * Forget it if page is not hinted to contain something prunable that's
       * older than OldestXmin.
       */
!     if (!PageIsPrunable(dp, OldestXmin))
          return;

      /*
--- 80,86 ----
       * Forget it if page is not hinted to contain something prunable that's
       * older than OldestXmin.
       */
!     if (!PageIsPrunable(page, OldestXmin))
          return;

      /*
***************
*** 99,105 ****
                                               HEAP_DEFAULT_FILLFACTOR);
      minfree = Max(minfree, BLCKSZ / 10);

!     if (PageIsFull(dp) || PageGetHeapFreeSpace((Page) dp) < minfree)
      {
          /* OK, try to get exclusive buffer lock */
          if (!ConditionalLockBufferForCleanup(buffer))
--- 99,105 ----
                                               HEAP_DEFAULT_FILLFACTOR);
      minfree = Max(minfree, BLCKSZ / 10);

!     if (PageIsFull(page) || PageGetHeapFreeSpace(page) < minfree)
      {
          /* OK, try to get exclusive buffer lock */
          if (!ConditionalLockBufferForCleanup(buffer))
***************
*** 111,117 ****
           * prune. (We needn't recheck PageIsPrunable, since no one else could
           * have pruned while we hold pin.)
           */
!         if (PageIsFull(dp) || PageGetHeapFreeSpace((Page) dp) < minfree)
          {
              /* OK to prune (though not to remove redirects) */
              (void) heap_page_prune(relation, buffer, OldestXmin, false, true);
--- 111,117 ----
           * prune. (We needn't recheck PageIsPrunable, since no one else could
           * have pruned while we hold pin.)
           */
!         if (PageIsFull(page) || PageGetHeapFreeSpace(page) < minfree)
          {
              /* OK to prune (though not to remove redirects) */
              (void) heap_page_prune(relation, buffer, OldestXmin, false, true);
diff -cr pgsql.orig.da8c485e0e2a/src/backend/access/nbtree/nbtpage.c pgsql.orig/src/backend/access/nbtree/nbtpage.c
*** pgsql.orig.da8c485e0e2a/src/backend/access/nbtree/nbtpage.c    pá črn 13 18:00:35 2008
--- pgsql.orig/src/backend/access/nbtree/nbtpage.c    pá črn 13 18:00:35 2008
***************
*** 436,448 ****
      /*
       * Additionally check that the special area looks sane.
       */
!     if (((PageHeader) (page))->pd_special !=
          (BLCKSZ - MAXALIGN(sizeof(BTPageOpaqueData))))
          ereport(ERROR,
                  (errcode(ERRCODE_INDEX_CORRUPTED),
                   errmsg("index \"%s\" contains corrupted page at block %u",
                          RelationGetRelationName(rel),
!                         BufferGetBlockNumber(buf)),
                   errhint("Please REINDEX it.")));
  }

--- 436,448 ----
      /*
       * Additionally check that the special area looks sane.
       */
!     if ( (PageGetSpecialPointer(page) - page) !=
          (BLCKSZ - MAXALIGN(sizeof(BTPageOpaqueData))))
          ereport(ERROR,
                  (errcode(ERRCODE_INDEX_CORRUPTED),
                   errmsg("index \"%s\" contains corrupted page at block %u",
                          RelationGetRelationName(rel),
!                         BufferGetBlockNumber(buf)),
                   errhint("Please REINDEX it.")));
  }

***************
*** 555,561 ****

          /* Initialize the new page before returning it */
          page = BufferGetPage(buf);
!         Assert(PageIsNew((PageHeader) page));
          _bt_pageinit(page, BufferGetPageSize(buf));
      }

--- 555,561 ----

          /* Initialize the new page before returning it */
          page = BufferGetPage(buf);
!         Assert(PageIsNew(page));
          _bt_pageinit(page, BufferGetPageSize(buf));
      }

diff -cr pgsql.orig.da8c485e0e2a/src/backend/access/transam/xlog.c pgsql.orig/src/backend/access/transam/xlog.c
*** pgsql.orig.da8c485e0e2a/src/backend/access/transam/xlog.c    pá črn 13 18:00:35 2008
--- pgsql.orig/src/backend/access/transam/xlog.c    pá črn 13 18:00:35 2008
***************
*** 1017,1025 ****
  XLogCheckBuffer(XLogRecData *rdata, bool doPageWrites,
                  XLogRecPtr *lsn, BkpBlock *bkpb)
  {
!     PageHeader    page;

!     page = (PageHeader) BufferGetBlock(rdata->buffer);

      /*
       * XXX We assume page LSN is first data on *every* page that can be passed
--- 1017,1025 ----
  XLogCheckBuffer(XLogRecData *rdata, bool doPageWrites,
                  XLogRecPtr *lsn, BkpBlock *bkpb)
  {
!     Page    page;

!     page = BufferGetBlock(rdata->buffer);

      /*
       * XXX We assume page LSN is first data on *every* page that can be passed
***************
*** 1026,1035 ****
       * to XLogInsert, whether it otherwise has the standard page layout or
       * not.
       */
!     *lsn = page->pd_lsn;

      if (doPageWrites &&
!         XLByteLE(page->pd_lsn, RedoRecPtr))
      {
          /*
           * The page needs to be backed up, so set up *bkpb
--- 1026,1035 ----
       * to XLogInsert, whether it otherwise has the standard page layout or
       * not.
       */
!     *lsn = PageGetLSN(page);

      if (doPageWrites &&
!         XLByteLE(PageGetLSN(page), RedoRecPtr))
      {
          /*
           * The page needs to be backed up, so set up *bkpb
diff -cr pgsql.orig.da8c485e0e2a/src/backend/access/transam/xlogutils.c
pgsql.orig/src/backend/access/transam/xlogutils.c
*** pgsql.orig.da8c485e0e2a/src/backend/access/transam/xlogutils.c    pá črn 13 18:00:35 2008
--- pgsql.orig/src/backend/access/transam/xlogutils.c    pá črn 13 18:00:35 2008
***************
*** 262,268 ****
          /* check that page has been initialized */
          Page        page = (Page) BufferGetPage(buffer);

!         if (PageIsNew((PageHeader) page))
          {
              UnlockReleaseBuffer(buffer);
              log_invalid_page(reln->rd_node, blkno, true);
--- 262,268 ----
          /* check that page has been initialized */
          Page        page = (Page) BufferGetPage(buffer);

!         if (PageIsNew(page))
          {
              UnlockReleaseBuffer(buffer);
              log_invalid_page(reln->rd_node, blkno, true);
diff -cr pgsql.orig.da8c485e0e2a/src/backend/commands/sequence.c pgsql.orig/src/backend/commands/sequence.c
*** pgsql.orig.da8c485e0e2a/src/backend/commands/sequence.c    pá črn 13 18:00:35 2008
--- pgsql.orig/src/backend/commands/sequence.c    pá črn 13 18:00:35 2008
***************
*** 109,115 ****
      Oid            seqoid;
      Relation    rel;
      Buffer        buf;
!     PageHeader    page;
      sequence_magic *sm;
      HeapTuple    tuple;
      TupleDesc    tupDesc;
--- 109,115 ----
      Oid            seqoid;
      Relation    rel;
      Buffer        buf;
!     Page        page;
      sequence_magic *sm;
      HeapTuple    tuple;
      TupleDesc    tupDesc;
***************
*** 212,220 ****
      buf = ReadBuffer(rel, P_NEW);
      Assert(BufferGetBlockNumber(buf) == 0);

!     page = (PageHeader) BufferGetPage(buf);

!     PageInit((Page) page, BufferGetPageSize(buf), sizeof(sequence_magic));
      sm = (sequence_magic *) PageGetSpecialPointer(page);
      sm->magic = SEQ_MAGIC;

--- 212,220 ----
      buf = ReadBuffer(rel, P_NEW);
      Assert(BufferGetBlockNumber(buf) == 0);

!     page = BufferGetPage(buf);

!     PageInit(page, BufferGetPageSize(buf), sizeof(sequence_magic));
      sm = (sequence_magic *) PageGetSpecialPointer(page);
      sm->magic = SEQ_MAGIC;

***************
*** 954,960 ****
  static Form_pg_sequence
  read_info(SeqTable elm, Relation rel, Buffer *buf)
  {
!     PageHeader    page;
      ItemId        lp;
      HeapTupleData tuple;
      sequence_magic *sm;
--- 954,960 ----
  static Form_pg_sequence
  read_info(SeqTable elm, Relation rel, Buffer *buf)
  {
!     Page    page;
      ItemId        lp;
      HeapTupleData tuple;
      sequence_magic *sm;
***************
*** 963,969 ****
      *buf = ReadBuffer(rel, 0);
      LockBuffer(*buf, BUFFER_LOCK_EXCLUSIVE);

!     page = (PageHeader) BufferGetPage(*buf);
      sm = (sequence_magic *) PageGetSpecialPointer(page);

      if (sm->magic != SEQ_MAGIC)
--- 963,969 ----
      *buf = ReadBuffer(rel, 0);
      LockBuffer(*buf, BUFFER_LOCK_EXCLUSIVE);

!     page = BufferGetPage(*buf);
      sm = (sequence_magic *) PageGetSpecialPointer(page);

      if (sm->magic != SEQ_MAGIC)
***************
*** 972,978 ****

      lp = PageGetItemId(page, FirstOffsetNumber);
      Assert(ItemIdIsNormal(lp));
!     tuple.t_data = (HeapTupleHeader) PageGetItem((Page) page, lp);

      seq = (Form_pg_sequence) GETSTRUCT(&tuple);

--- 972,978 ----

      lp = PageGetItemId(page, FirstOffsetNumber);
      Assert(ItemIdIsNormal(lp));
!     tuple.t_data = (HeapTupleHeader) PageGetItem(page, lp);

      seq = (Form_pg_sequence) GETSTRUCT(&tuple);

diff -cr pgsql.orig.da8c485e0e2a/src/backend/commands/trigger.c pgsql.orig/src/backend/commands/trigger.c
*** pgsql.orig.da8c485e0e2a/src/backend/commands/trigger.c    pá črn 13 18:00:35 2008
--- pgsql.orig/src/backend/commands/trigger.c    pá črn 13 18:00:35 2008
***************
*** 2203,2219 ****
      }
      else
      {
!         PageHeader    dp;
          ItemId        lp;

          buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));

!         dp = (PageHeader) BufferGetPage(buffer);
!         lp = PageGetItemId(dp, ItemPointerGetOffsetNumber(tid));

          Assert(ItemIdIsNormal(lp));

!         tuple.t_data = (HeapTupleHeader) PageGetItem((Page) dp, lp);
          tuple.t_len = ItemIdGetLength(lp);
          tuple.t_self = *tid;
          tuple.t_tableOid = RelationGetRelid(relation);
--- 2203,2219 ----
      }
      else
      {
!         Page        page;
          ItemId        lp;

          buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));

!         page = BufferGetPage(buffer);
!         lp = PageGetItemId(page, ItemPointerGetOffsetNumber(tid));

          Assert(ItemIdIsNormal(lp));

!         tuple.t_data = (HeapTupleHeader) PageGetItem(page, lp);
          tuple.t_len = ItemIdGetLength(lp);
          tuple.t_self = *tid;
          tuple.t_tableOid = RelationGetRelid(relation);
diff -cr pgsql.orig.da8c485e0e2a/src/backend/optimizer/util/plancat.c pgsql.orig/src/backend/optimizer/util/plancat.c
*** pgsql.orig.da8c485e0e2a/src/backend/optimizer/util/plancat.c    pá črn 13 18:00:35 2008
--- pgsql.orig/src/backend/optimizer/util/plancat.c    pá črn 13 18:00:35 2008
***************
*** 429,435 ****
                  tuple_width += sizeof(HeapTupleHeaderData);
                  tuple_width += sizeof(ItemPointerData);
                  /* note: integer division is intentional here */
!                 density = (BLCKSZ - sizeof(PageHeaderData)) / tuple_width;
              }
              *tuples = rint(density * (double) curpages);
              break;
--- 429,435 ----
                  tuple_width += sizeof(HeapTupleHeaderData);
                  tuple_width += sizeof(ItemPointerData);
                  /* note: integer division is intentional here */
!                 density = (BLCKSZ - SizeOfPageHeaderData) / tuple_width;
              }
              *tuples = rint(density * (double) curpages);
              break;
diff -cr pgsql.orig.da8c485e0e2a/src/backend/storage/buffer/bufmgr.c pgsql.orig/src/backend/storage/buffer/bufmgr.c
*** pgsql.orig.da8c485e0e2a/src/backend/storage/buffer/bufmgr.c    pá črn 13 18:00:35 2008
--- pgsql.orig/src/backend/storage/buffer/bufmgr.c    pá črn 13 18:00:35 2008
***************
*** 223,229 ****
           * always have left a zero-filled buffer, complain if not PageIsNew.
           */
          bufBlock = isLocalBuf ? LocalBufHdrGetBlock(bufHdr) : BufHdrGetBlock(bufHdr);
!         if (!PageIsNew((PageHeader) bufBlock))
              ereport(ERROR,
                      (errmsg("unexpected data beyond EOF in block %u of relation \"%s\"",
                              blockNum, RelationGetRelationName(reln)),
--- 223,229 ----
           * always have left a zero-filled buffer, complain if not PageIsNew.
           */
          bufBlock = isLocalBuf ? LocalBufHdrGetBlock(bufHdr) : BufHdrGetBlock(bufHdr);
!         if (!PageIsNew((Page) bufBlock))
              ereport(ERROR,
                      (errmsg("unexpected data beyond EOF in block %u of relation \"%s\"",
                              blockNum, RelationGetRelationName(reln)),
***************
*** 292,298 ****
          else
              smgrread(reln->rd_smgr, blockNum, (char *) bufBlock);
          /* check for garbage data */
!         if (!PageHeaderIsValid((PageHeader) bufBlock))
          {
              if (zero_damaged_pages)
              {
--- 292,298 ----
          else
              smgrread(reln->rd_smgr, blockNum, (char *) bufBlock);
          /* check for garbage data */
!         if (!PageHeaderIsValid((Page) bufBlock))
          {
              if (zero_damaged_pages)
              {
diff -cr pgsql.orig.da8c485e0e2a/src/include/access/hash.h pgsql.orig/src/include/access/hash.h
*** pgsql.orig.da8c485e0e2a/src/include/access/hash.h    pá črn 13 18:00:35 2008
--- pgsql.orig/src/include/access/hash.h    pá črn 13 18:00:35 2008
***************
*** 166,174 ****
   */
  #define HashMaxItemSize(page) \
      (PageGetPageSize(page) - \
!      sizeof(PageHeaderData) - \
!      MAXALIGN(sizeof(HashPageOpaqueData)) - \
!      sizeof(ItemIdData))

  #define HASH_MIN_FILLFACTOR            10
  #define HASH_DEFAULT_FILLFACTOR        75
--- 166,173 ----
   */
  #define HashMaxItemSize(page) \
      (PageGetPageSize(page) - \
!      (SizeOfPageHeaderData) - \
!      MAXALIGN(sizeof(HashPageOpaqueData)))

  #define HASH_MIN_FILLFACTOR            10
  #define HASH_DEFAULT_FILLFACTOR        75
***************
*** 191,197 ****
  #define BMPG_SHIFT(metap)        ((metap)->hashm_bmshift)
  #define BMPG_MASK(metap)        (BMPGSZ_BIT(metap) - 1)
  #define HashPageGetBitmap(pg) \
!     ((uint32 *) (((char *) (pg)) + MAXALIGN(sizeof(PageHeaderData))))

  /*
   * The number of bits in an ovflpage bitmap word.
--- 190,196 ----
  #define BMPG_SHIFT(metap)        ((metap)->hashm_bmshift)
  #define BMPG_MASK(metap)        (BMPGSZ_BIT(metap) - 1)
  #define HashPageGetBitmap(pg) \
!     ((uint32 *) (((char *) (pg)) + MAXALIGN(SizeOfPageHeaderData + sizeof(ItemIdData))))

  /*
   * The number of bits in an ovflpage bitmap word.
diff -cr pgsql.orig.da8c485e0e2a/src/include/access/htup.h pgsql.orig/src/include/access/htup.h
*** pgsql.orig.da8c485e0e2a/src/include/access/htup.h    pá črn 13 18:00:35 2008
--- pgsql.orig/src/include/access/htup.h    pá črn 13 18:00:35 2008
***************
*** 367,373 ****
   * of assuming that, say, you can fit 2 tuples of size MaxHeapTupleSize/2
   * on the same page.
   */
! #define MaxHeapTupleSize  (BLCKSZ - MAXALIGN(sizeof(PageHeaderData)))

  /*
   * MaxHeapTuplesPerPage is an upper bound on the number of tuples that can
--- 367,373 ----
   * of assuming that, say, you can fit 2 tuples of size MaxHeapTupleSize/2
   * on the same page.
   */
! #define MaxHeapTupleSize  (BLCKSZ - MAXALIGN( (SizeOfPageHeaderData) + sizeof(ItemIdData)))

  /*
   * MaxHeapTuplesPerPage is an upper bound on the number of tuples that can
***************
*** 381,387 ****
   * require increases in the size of work arrays.
   */
  #define MaxHeapTuplesPerPage    \
!     ((int) ((BLCKSZ - offsetof(PageHeaderData, pd_linp)) / \
              (MAXALIGN(offsetof(HeapTupleHeaderData, t_bits)) + sizeof(ItemIdData))))

  /*
--- 381,387 ----
   * require increases in the size of work arrays.
   */
  #define MaxHeapTuplesPerPage    \
!     ((int) ((BLCKSZ - SizeOfPageHeaderData) / \
              (MAXALIGN(offsetof(HeapTupleHeaderData, t_bits)) + sizeof(ItemIdData))))

  /*
diff -cr pgsql.orig.da8c485e0e2a/src/include/access/itup.h pgsql.orig/src/include/access/itup.h
*** pgsql.orig.da8c485e0e2a/src/include/access/itup.h    pá črn 13 18:00:35 2008
--- pgsql.orig/src/include/access/itup.h    pá črn 13 18:00:35 2008
***************
*** 134,140 ****
   * must be maxaligned, and it must have an associated item pointer.
   */
  #define MaxIndexTuplesPerPage    \
!     ((int) ((BLCKSZ - offsetof(PageHeaderData, pd_linp)) / \
              (MAXALIGN(sizeof(IndexTupleData) + 1) + sizeof(ItemIdData))))


--- 134,140 ----
   * must be maxaligned, and it must have an associated item pointer.
   */
  #define MaxIndexTuplesPerPage    \
!     ((int) ((BLCKSZ - SizeOfPageHeaderData) / \
              (MAXALIGN(sizeof(IndexTupleData) + 1) + sizeof(ItemIdData))))


diff -cr pgsql.orig.da8c485e0e2a/src/include/access/nbtree.h pgsql.orig/src/include/access/nbtree.h
*** pgsql.orig.da8c485e0e2a/src/include/access/nbtree.h    pá črn 13 18:00:35 2008
--- pgsql.orig/src/include/access/nbtree.h    pá črn 13 18:00:35 2008
***************
*** 119,125 ****
   */
  #define BTMaxItemSize(page) \
      MAXALIGN_DOWN((PageGetPageSize(page) - \
!                    MAXALIGN(sizeof(PageHeaderData) + 2*sizeof(ItemIdData)) - \
                     MAXALIGN(sizeof(BTPageOpaqueData))) / 3)

  /*
--- 119,125 ----
   */
  #define BTMaxItemSize(page) \
      MAXALIGN_DOWN((PageGetPageSize(page) - \
!                    MAXALIGN(SizeOfPageHeaderData + 3*sizeof(ItemIdData)) - \
                     MAXALIGN(sizeof(BTPageOpaqueData))) / 3)

  /*
diff -cr pgsql.orig.da8c485e0e2a/src/include/access/tuptoaster.h pgsql.orig/src/include/access/tuptoaster.h
*** pgsql.orig.da8c485e0e2a/src/include/access/tuptoaster.h    pá črn 13 18:00:35 2008
--- pgsql.orig/src/include/access/tuptoaster.h    pá črn 13 18:00:35 2008
***************
*** 49,55 ****
  /* Note: sizeof(PageHeaderData) includes the first ItemId on the page */
  #define TOAST_TUPLE_THRESHOLD    \
      MAXALIGN_DOWN((BLCKSZ - \
!                    MAXALIGN(sizeof(PageHeaderData) + (TOAST_TUPLES_PER_PAGE-1) * sizeof(ItemIdData))) \
                    / TOAST_TUPLES_PER_PAGE)

  #define TOAST_TUPLE_TARGET        TOAST_TUPLE_THRESHOLD
--- 49,55 ----
  /* Note: sizeof(PageHeaderData) includes the first ItemId on the page */
  #define TOAST_TUPLE_THRESHOLD    \
      MAXALIGN_DOWN((BLCKSZ - \
!                    MAXALIGN(SizeOfPageHeaderData + (TOAST_TUPLES_PER_PAGE) * sizeof(ItemIdData))) \
                    / TOAST_TUPLES_PER_PAGE)

  #define TOAST_TUPLE_TARGET        TOAST_TUPLE_THRESHOLD
***************
*** 76,82 ****
  /* Note: sizeof(PageHeaderData) includes the first ItemId on the page */
  #define EXTERN_TUPLE_MAX_SIZE    \
      MAXALIGN_DOWN((BLCKSZ - \
!                    MAXALIGN(sizeof(PageHeaderData) + (EXTERN_TUPLES_PER_PAGE-1) * sizeof(ItemIdData))) \
                    / EXTERN_TUPLES_PER_PAGE)

  #define TOAST_MAX_CHUNK_SIZE    \
--- 76,82 ----
  /* Note: sizeof(PageHeaderData) includes the first ItemId on the page */
  #define EXTERN_TUPLE_MAX_SIZE    \
      MAXALIGN_DOWN((BLCKSZ - \
!                    MAXALIGN(SizeOfPageHeaderData + (EXTERN_TUPLES_PER_PAGE) * sizeof(ItemIdData))) \
                    / EXTERN_TUPLES_PER_PAGE)

  #define TOAST_MAX_CHUNK_SIZE    \

Re: page macros cleanup

От
"Pavan Deolasee"
Дата:
On Fri, Jun 13, 2008 at 9:38 PM, Zdenek Kotala <Zdenek.Kotala@sun.com> wrote:
> I attached code cleanup which is related to in-place upgrade. I replace
> direct access to PageHeader structure with already existing macros and I
> removed also unnecessary retyping.

A quick review comment:

One thing I noticed is that the modified definition of HashMaxItemSize
now does not account for the size of ItemId which may not be the right
thing. Please recheck that.

Apart from that the patch looks good to me. As you said, we should
probably replace the other direct usage of PageHeader with appropriate
macros.

Thanks,
Pavan


--
Pavan Deolasee
EnterpriseDB http://www.enterprisedb.com

Re: page macros cleanup

От
"Heikki Linnakangas"
Дата:
Just one quick note:

Zdenek Kotala wrote:
> *** pgsql.orig.da8c485e0e2a/src/backend/access/gist/gistutil.c    pá črn 13 18:00:35 2008
> --- pgsql.orig/src/backend/access/gist/gistutil.c    pá črn 13 18:00:35 2008
> ***************
> *** 592,598 ****
>       /*
>        * Additionally check that the special area looks sane.
>        */
> !     if (((PageHeader) (page))->pd_special !=
>           (BLCKSZ - MAXALIGN(sizeof(GISTPageOpaqueData))))
>           ereport(ERROR,
>                   (errcode(ERRCODE_INDEX_CORRUPTED),
> --- 592,598 ----
>       /*
>        * Additionally check that the special area looks sane.
>        */
> !     if ( PageGetSpecialPointer(page) - page !=
>           (BLCKSZ - MAXALIGN(sizeof(GISTPageOpaqueData))))
>           ereport(ERROR,
>                   (errcode(ERRCODE_INDEX_CORRUPTED),

Should probably use PageGetSpecialSize here. Much simpler, and doesn't
assume that the special area is always at the end of page (not that I
see us changing that anytime soon).

--
   Heikki Linnakangas
   EnterpriseDB   http://www.enterprisedb.com

Re: page macros cleanup

От
Zdenek Kotala
Дата:
Pavan Deolasee napsal(a):
> On Fri, Jun 13, 2008 at 9:38 PM, Zdenek Kotala <Zdenek.Kotala@sun.com> wrote:
>> I attached code cleanup which is related to in-place upgrade. I replace
>> direct access to PageHeader structure with already existing macros and I
>> removed also unnecessary retyping.
>
> A quick review comment:

Thanks you for your review,

>
> One thing I noticed is that the modified definition of HashMaxItemSize
> now does not account for the size of ItemId which may not be the right
> thing. Please recheck that.

Good catch. I lost in basic arithmetic. What I see now that original definition
count sizeof(ItemIdData) twice and on other side it does not take care about
MAXALING correctly. I think correct formula is:

#define HashMaxItemSize(page) \
         (PageGetPageSize(page) - \
           ( MAXALIGN(SizeOfPageHeaderData + sizeof(ItemIdData))+ \
             MAXALIGN(sizeof(HashPageOpaqueData)) \
           )\
          )

What do you think?

    Thanks for your comments Zdenek


--
Zdenek Kotala              Sun Microsystems
Prague, Czech Republic     http://sun.com/postgresql


Re: page macros cleanup

От
Zdenek Kotala
Дата:
Heikki Linnakangas napsal(a):
> Just one quick note:

> Should probably use PageGetSpecialSize here. Much simpler, and doesn't
> assume that the special area is always at the end of page (not that I
> see us changing that anytime soon).
>

Thanks for review,
good catch. I found similar example also in nbtree and hash. I attached updated
patch version which also contains fix for Pavan's observation. Patch modifies
HashMaxItemSize. It should require reindex on all hash indexes. Should we bump
catalog version?

        thanks Zdenek


--
Zdenek Kotala              Sun Microsystems
Prague, Czech Republic     http://sun.com/postgresql

diff -cr pgsql.orig.da8c485e0e2a/src/backend/access/gist/gistutil.c pgsql.orig/src/backend/access/gist/gistutil.c
*** pgsql.orig.da8c485e0e2a/src/backend/access/gist/gistutil.c    pá črc  4 10:23:41 2008
--- pgsql.orig/src/backend/access/gist/gistutil.c    pá črc  4 10:23:41 2008
***************
*** 592,599 ****
      /*
       * Additionally check that the special area looks sane.
       */
!     if (((PageHeader) (page))->pd_special !=
!         (BLCKSZ - MAXALIGN(sizeof(GISTPageOpaqueData))))
          ereport(ERROR,
                  (errcode(ERRCODE_INDEX_CORRUPTED),
                   errmsg("index \"%s\" contains corrupted page at block %u",
--- 592,598 ----
      /*
       * Additionally check that the special area looks sane.
       */
!     if ( PageGetSpecialSize(page) != MAXALIGN(sizeof(GISTPageOpaqueData)))
          ereport(ERROR,
                  (errcode(ERRCODE_INDEX_CORRUPTED),
                   errmsg("index \"%s\" contains corrupted page at block %u",
diff -cr pgsql.orig.da8c485e0e2a/src/backend/access/hash/hashpage.c pgsql.orig/src/backend/access/hash/hashpage.c
*** pgsql.orig.da8c485e0e2a/src/backend/access/hash/hashpage.c    pá črc  4 10:23:41 2008
--- pgsql.orig/src/backend/access/hash/hashpage.c    pá črc  4 10:23:41 2008
***************
*** 407,413 ****
      for (i = _hash_log2(metap->hashm_bsize); i > 0; --i)
      {
          if ((1 << i) <= (metap->hashm_bsize -
!                          (MAXALIGN(sizeof(PageHeaderData)) +
                            MAXALIGN(sizeof(HashPageOpaqueData)))))
              break;
      }
--- 407,413 ----
      for (i = _hash_log2(metap->hashm_bsize); i > 0; --i)
      {
          if ((1 << i) <= (metap->hashm_bsize -
!                          (MAXALIGN(SizeOfPageHeaderData) +
                            MAXALIGN(sizeof(HashPageOpaqueData)))))
              break;
      }
diff -cr pgsql.orig.da8c485e0e2a/src/backend/access/hash/hashutil.c pgsql.orig/src/backend/access/hash/hashutil.c
*** pgsql.orig.da8c485e0e2a/src/backend/access/hash/hashutil.c    pá črc  4 10:23:41 2008
--- pgsql.orig/src/backend/access/hash/hashutil.c    pá črc  4 10:23:41 2008
***************
*** 164,171 ****
      /*
       * Additionally check that the special area looks sane.
       */
!     if (((PageHeader) (page))->pd_special !=
!         (BLCKSZ - MAXALIGN(sizeof(HashPageOpaqueData))))
          ereport(ERROR,
                  (errcode(ERRCODE_INDEX_CORRUPTED),
                   errmsg("index \"%s\" contains corrupted page at block %u",
--- 164,170 ----
      /*
       * Additionally check that the special area looks sane.
       */
!     if ( PageGetSpecialSize(page) != MAXALIGN(sizeof(HashPageOpaqueData)))
          ereport(ERROR,
                  (errcode(ERRCODE_INDEX_CORRUPTED),
                   errmsg("index \"%s\" contains corrupted page at block %u",
diff -cr pgsql.orig.da8c485e0e2a/src/backend/access/heap/heapam.c pgsql.orig/src/backend/access/heap/heapam.c
*** pgsql.orig.da8c485e0e2a/src/backend/access/heap/heapam.c    pá črc  4 10:23:41 2008
--- pgsql.orig/src/backend/access/heap/heapam.c    pá črc  4 10:23:41 2008
***************
*** 1342,1348 ****
      ItemPointer tid = &(tuple->t_self);
      ItemId        lp;
      Buffer        buffer;
!     PageHeader    dp;
      OffsetNumber offnum;
      bool        valid;

--- 1342,1348 ----
      ItemPointer tid = &(tuple->t_self);
      ItemId        lp;
      Buffer        buffer;
!     Page        page;
      OffsetNumber offnum;
      bool        valid;

***************
*** 1355,1361 ****
       * Need share lock on buffer to examine tuple commit status.
       */
      LockBuffer(buffer, BUFFER_LOCK_SHARE);
!     dp = (PageHeader) BufferGetPage(buffer);

      /*
       * We'd better check for out-of-range offnum in case of VACUUM since the
--- 1355,1361 ----
       * Need share lock on buffer to examine tuple commit status.
       */
      LockBuffer(buffer, BUFFER_LOCK_SHARE);
!     page = BufferGetPage(buffer);

      /*
       * We'd better check for out-of-range offnum in case of VACUUM since the
***************
*** 1362,1368 ****
       * TID was obtained.
       */
      offnum = ItemPointerGetOffsetNumber(tid);
!     if (offnum < FirstOffsetNumber || offnum > PageGetMaxOffsetNumber(dp))
      {
          LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
          if (keep_buf)
--- 1362,1368 ----
       * TID was obtained.
       */
      offnum = ItemPointerGetOffsetNumber(tid);
!     if (offnum < FirstOffsetNumber || offnum > PageGetMaxOffsetNumber(page))
      {
          LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
          if (keep_buf)
***************
*** 1379,1385 ****
      /*
       * get the item line pointer corresponding to the requested tid
       */
!     lp = PageGetItemId(dp, offnum);

      /*
       * Must check for deleted tuple.
--- 1379,1385 ----
      /*
       * get the item line pointer corresponding to the requested tid
       */
!     lp = PageGetItemId(page, offnum);

      /*
       * Must check for deleted tuple.
***************
*** 1401,1407 ****
      /*
       * fill in *tuple fields
       */
!     tuple->t_data = (HeapTupleHeader) PageGetItem((Page) dp, lp);
      tuple->t_len = ItemIdGetLength(lp);
      tuple->t_tableOid = RelationGetRelid(relation);

--- 1401,1407 ----
      /*
       * fill in *tuple fields
       */
!     tuple->t_data = (HeapTupleHeader) PageGetItem(page, lp);
      tuple->t_len = ItemIdGetLength(lp);
      tuple->t_tableOid = RelationGetRelid(relation);

***************
*** 1626,1632 ****
      for (;;)
      {
          Buffer        buffer;
!         PageHeader    dp;
          OffsetNumber offnum;
          ItemId        lp;
          HeapTupleData tp;
--- 1626,1632 ----
      for (;;)
      {
          Buffer        buffer;
!         Page        page;
          OffsetNumber offnum;
          ItemId        lp;
          HeapTupleData tp;
***************
*** 1637,1643 ****
           */
          buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(&ctid));
          LockBuffer(buffer, BUFFER_LOCK_SHARE);
!         dp = (PageHeader) BufferGetPage(buffer);

          /*
           * Check for bogus item number.  This is not treated as an error
--- 1637,1643 ----
           */
          buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(&ctid));
          LockBuffer(buffer, BUFFER_LOCK_SHARE);
!         page = BufferGetPage(buffer);

          /*
           * Check for bogus item number.  This is not treated as an error
***************
*** 1645,1656 ****
           * just assume that the prior tid is OK and return it unchanged.
           */
          offnum = ItemPointerGetOffsetNumber(&ctid);
!         if (offnum < FirstOffsetNumber || offnum > PageGetMaxOffsetNumber(dp))
          {
              UnlockReleaseBuffer(buffer);
              break;
          }
!         lp = PageGetItemId(dp, offnum);
          if (!ItemIdIsNormal(lp))
          {
              UnlockReleaseBuffer(buffer);
--- 1645,1656 ----
           * just assume that the prior tid is OK and return it unchanged.
           */
          offnum = ItemPointerGetOffsetNumber(&ctid);
!         if (offnum < FirstOffsetNumber || offnum > PageGetMaxOffsetNumber(page))
          {
              UnlockReleaseBuffer(buffer);
              break;
          }
!         lp = PageGetItemId(page, offnum);
          if (!ItemIdIsNormal(lp))
          {
              UnlockReleaseBuffer(buffer);
***************
*** 1659,1665 ****

          /* OK to access the tuple */
          tp.t_self = ctid;
!         tp.t_data = (HeapTupleHeader) PageGetItem(dp, lp);
          tp.t_len = ItemIdGetLength(lp);

          /*
--- 1659,1665 ----

          /* OK to access the tuple */
          tp.t_self = ctid;
!         tp.t_data = (HeapTupleHeader) PageGetItem(page, lp);
          tp.t_len = ItemIdGetLength(lp);

          /*
***************
*** 1963,1969 ****
      TransactionId xid = GetCurrentTransactionId();
      ItemId        lp;
      HeapTupleData tp;
!     PageHeader    dp;
      Buffer        buffer;
      bool        have_tuple_lock = false;
      bool        iscombo;
--- 1963,1969 ----
      TransactionId xid = GetCurrentTransactionId();
      ItemId        lp;
      HeapTupleData tp;
!     Page        page;
      Buffer        buffer;
      bool        have_tuple_lock = false;
      bool        iscombo;
***************
*** 1973,1983 ****
      buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));
      LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);

!     dp = (PageHeader) BufferGetPage(buffer);
!     lp = PageGetItemId(dp, ItemPointerGetOffsetNumber(tid));
      Assert(ItemIdIsNormal(lp));

!     tp.t_data = (HeapTupleHeader) PageGetItem(dp, lp);
      tp.t_len = ItemIdGetLength(lp);
      tp.t_self = *tid;

--- 1973,1983 ----
      buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));
      LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);

!     page = BufferGetPage(buffer);
!     lp = PageGetItemId(page, ItemPointerGetOffsetNumber(tid));
      Assert(ItemIdIsNormal(lp));

!     tp.t_data = (HeapTupleHeader) PageGetItem(page, lp);
      tp.t_len = ItemIdGetLength(lp);
      tp.t_self = *tid;

***************
*** 2111,2117 ****
       * the subsequent page pruning will be a no-op and the hint will be
       * cleared.
       */
!     PageSetPrunable(dp, xid);

      /* store transaction information of xact deleting the tuple */
      tp.t_data->t_infomask &= ~(HEAP_XMAX_COMMITTED |
--- 2111,2117 ----
       * the subsequent page pruning will be a no-op and the hint will be
       * cleared.
       */
!     PageSetPrunable(page, xid);

      /* store transaction information of xact deleting the tuple */
      tp.t_data->t_infomask &= ~(HEAP_XMAX_COMMITTED |
***************
*** 2149,2156 ****

          recptr = XLogInsert(RM_HEAP_ID, XLOG_HEAP_DELETE, rdata);

!         PageSetLSN(dp, recptr);
!         PageSetTLI(dp, ThisTimeLineID);
      }

      END_CRIT_SECTION();
--- 2149,2156 ----

          recptr = XLogInsert(RM_HEAP_ID, XLOG_HEAP_DELETE, rdata);

!         PageSetLSN(page, recptr);
!         PageSetTLI(page, ThisTimeLineID);
      }

      END_CRIT_SECTION();
***************
*** 2275,2281 ****
      ItemId        lp;
      HeapTupleData oldtup;
      HeapTuple    heaptup;
!     PageHeader    dp;
      Buffer        buffer,
                  newbuf;
      bool        need_toast,
--- 2275,2281 ----
      ItemId        lp;
      HeapTupleData oldtup;
      HeapTuple    heaptup;
!     Page        page;
      Buffer        buffer,
                  newbuf;
      bool        need_toast,
***************
*** 2305,2315 ****
      buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(otid));
      LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);

!     dp = (PageHeader) BufferGetPage(buffer);
!     lp = PageGetItemId(dp, ItemPointerGetOffsetNumber(otid));
      Assert(ItemIdIsNormal(lp));

!     oldtup.t_data = (HeapTupleHeader) PageGetItem(dp, lp);
      oldtup.t_len = ItemIdGetLength(lp);
      oldtup.t_self = *otid;

--- 2305,2315 ----
      buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(otid));
      LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);

!     page = BufferGetPage(buffer);
!     lp = PageGetItemId(page, ItemPointerGetOffsetNumber(otid));
      Assert(ItemIdIsNormal(lp));

!     oldtup.t_data = (HeapTupleHeader) PageGetItem(page, lp);
      oldtup.t_len = ItemIdGetLength(lp);
      oldtup.t_self = *otid;

***************
*** 2490,2496 ****
                        HeapTupleHasExternal(newtup) ||
                        newtup->t_len > TOAST_TUPLE_THRESHOLD);

!     pagefree = PageGetHeapFreeSpace((Page) dp);

      newtupsize = MAXALIGN(newtup->t_len);

--- 2490,2496 ----
                        HeapTupleHasExternal(newtup) ||
                        newtup->t_len > TOAST_TUPLE_THRESHOLD);

!     pagefree = PageGetHeapFreeSpace(page);

      newtupsize = MAXALIGN(newtup->t_len);

***************
*** 2556,2562 ****
              /* Re-acquire the lock on the old tuple's page. */
              LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);
              /* Re-check using the up-to-date free space */
!             pagefree = PageGetHeapFreeSpace((Page) dp);
              if (newtupsize > pagefree)
              {
                  /*
--- 2556,2562 ----
              /* Re-acquire the lock on the old tuple's page. */
              LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);
              /* Re-check using the up-to-date free space */
!             pagefree = PageGetHeapFreeSpace(page);
              if (newtupsize > pagefree)
              {
                  /*
***************
*** 2602,2608 ****
      else
      {
          /* Set a hint that the old page could use prune/defrag */
!         PageSetFull(dp);
      }

      /* NO EREPORT(ERROR) from here till changes are logged */
--- 2602,2608 ----
      else
      {
          /* Set a hint that the old page could use prune/defrag */
!         PageSetFull(page);
      }

      /* NO EREPORT(ERROR) from here till changes are logged */
***************
*** 2620,2626 ****
       * not to optimize for aborts.    Note that heap_xlog_update must be kept in
       * sync if this decision changes.
       */
!     PageSetPrunable(dp, xid);

      if (use_hot_update)
      {
--- 2620,2626 ----
       * not to optimize for aborts.    Note that heap_xlog_update must be kept in
       * sync if this decision changes.
       */
!     PageSetPrunable(page, xid);

      if (use_hot_update)
      {
***************
*** 2945,2951 ****
      HTSU_Result result;
      ItemPointer tid = &(tuple->t_self);
      ItemId        lp;
!     PageHeader    dp;
      TransactionId xid;
      TransactionId xmax;
      uint16        old_infomask;
--- 2945,2951 ----
      HTSU_Result result;
      ItemPointer tid = &(tuple->t_self);
      ItemId        lp;
!     Page        page;
      TransactionId xid;
      TransactionId xmax;
      uint16        old_infomask;
***************
*** 2958,2968 ****
      *buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));
      LockBuffer(*buffer, BUFFER_LOCK_EXCLUSIVE);

!     dp = (PageHeader) BufferGetPage(*buffer);
!     lp = PageGetItemId(dp, ItemPointerGetOffsetNumber(tid));
      Assert(ItemIdIsNormal(lp));

!     tuple->t_data = (HeapTupleHeader) PageGetItem((Page) dp, lp);
      tuple->t_len = ItemIdGetLength(lp);
      tuple->t_tableOid = RelationGetRelid(relation);

--- 2958,2968 ----
      *buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));
      LockBuffer(*buffer, BUFFER_LOCK_EXCLUSIVE);

!     page = BufferGetPage(*buffer);
!     lp = PageGetItemId(page, ItemPointerGetOffsetNumber(tid));
      Assert(ItemIdIsNormal(lp));

!     tuple->t_data = (HeapTupleHeader) PageGetItem(page, lp);
      tuple->t_len = ItemIdGetLength(lp);
      tuple->t_tableOid = RelationGetRelid(relation);

***************
*** 3301,3308 ****

          recptr = XLogInsert(RM_HEAP_ID, XLOG_HEAP_LOCK, rdata);

!         PageSetLSN(dp, recptr);
!         PageSetTLI(dp, ThisTimeLineID);
      }

      END_CRIT_SECTION();
--- 3301,3308 ----

          recptr = XLogInsert(RM_HEAP_ID, XLOG_HEAP_LOCK, rdata);

!         PageSetLSN(page, recptr);
!         PageSetTLI(page, ThisTimeLineID);
      }

      END_CRIT_SECTION();
diff -cr pgsql.orig.da8c485e0e2a/src/backend/access/heap/hio.c pgsql.orig/src/backend/access/heap/hio.c
*** pgsql.orig.da8c485e0e2a/src/backend/access/heap/hio.c    pá črc  4 10:23:41 2008
--- pgsql.orig/src/backend/access/heap/hio.c    pá črc  4 10:23:41 2008
***************
*** 107,113 ****
                            Buffer otherBuffer, bool use_fsm)
  {
      Buffer        buffer = InvalidBuffer;
!     Page        pageHeader;
      Size        pageFreeSpace,
                  saveFreeSpace;
      BlockNumber targetBlock,
--- 107,113 ----
                            Buffer otherBuffer, bool use_fsm)
  {
      Buffer        buffer = InvalidBuffer;
!     Page        page;
      Size        pageFreeSpace,
                  saveFreeSpace;
      BlockNumber targetBlock,
***************
*** 218,225 ****
           * Now we can check to see if there's enough free space here. If so,
           * we're done.
           */
!         pageHeader = (Page) BufferGetPage(buffer);
!         pageFreeSpace = PageGetHeapFreeSpace(pageHeader);
          if (len + saveFreeSpace <= pageFreeSpace)
          {
              /* use this page as future insert target, too */
--- 218,225 ----
           * Now we can check to see if there's enough free space here. If so,
           * we're done.
           */
!         page = BufferGetPage(buffer);
!         pageFreeSpace = PageGetHeapFreeSpace(page);
          if (len + saveFreeSpace <= pageFreeSpace)
          {
              /* use this page as future insert target, too */
***************
*** 303,318 ****
       * is empty (this should never happen, but if it does we don't want to
       * risk wiping out valid data).
       */
!     pageHeader = (Page) BufferGetPage(buffer);

!     if (!PageIsNew((PageHeader) pageHeader))
          elog(ERROR, "page %u of relation \"%s\" should be empty but is not",
               BufferGetBlockNumber(buffer),
               RelationGetRelationName(relation));

!     PageInit(pageHeader, BufferGetPageSize(buffer), 0);

!     if (len > PageGetHeapFreeSpace(pageHeader))
      {
          /* We should not get here given the test at the top */
          elog(PANIC, "tuple is too big: size %lu", (unsigned long) len);
--- 303,318 ----
       * is empty (this should never happen, but if it does we don't want to
       * risk wiping out valid data).
       */
!     page = BufferGetPage(buffer);

!     if (!PageIsNew(page))
          elog(ERROR, "page %u of relation \"%s\" should be empty but is not",
               BufferGetBlockNumber(buffer),
               RelationGetRelationName(relation));

!     PageInit(page, BufferGetPageSize(buffer), 0);

!     if (len > PageGetHeapFreeSpace(page))
      {
          /* We should not get here given the test at the top */
          elog(PANIC, "tuple is too big: size %lu", (unsigned long) len);
diff -cr pgsql.orig.da8c485e0e2a/src/backend/access/heap/pruneheap.c pgsql.orig/src/backend/access/heap/pruneheap.c
*** pgsql.orig.da8c485e0e2a/src/backend/access/heap/pruneheap.c    pá črc  4 10:23:41 2008
--- pgsql.orig/src/backend/access/heap/pruneheap.c    pá črc  4 10:23:41 2008
***************
*** 71,77 ****
  void
  heap_page_prune_opt(Relation relation, Buffer buffer, TransactionId OldestXmin)
  {
!     PageHeader    dp = (PageHeader) BufferGetPage(buffer);
      Size        minfree;

      /*
--- 71,77 ----
  void
  heap_page_prune_opt(Relation relation, Buffer buffer, TransactionId OldestXmin)
  {
!     Page        page = BufferGetPage(buffer);
      Size        minfree;

      /*
***************
*** 80,86 ****
       * Forget it if page is not hinted to contain something prunable that's
       * older than OldestXmin.
       */
!     if (!PageIsPrunable(dp, OldestXmin))
          return;

      /*
--- 80,86 ----
       * Forget it if page is not hinted to contain something prunable that's
       * older than OldestXmin.
       */
!     if (!PageIsPrunable(page, OldestXmin))
          return;

      /*
***************
*** 99,105 ****
                                               HEAP_DEFAULT_FILLFACTOR);
      minfree = Max(minfree, BLCKSZ / 10);

!     if (PageIsFull(dp) || PageGetHeapFreeSpace((Page) dp) < minfree)
      {
          /* OK, try to get exclusive buffer lock */
          if (!ConditionalLockBufferForCleanup(buffer))
--- 99,105 ----
                                               HEAP_DEFAULT_FILLFACTOR);
      minfree = Max(minfree, BLCKSZ / 10);

!     if (PageIsFull(page) || PageGetHeapFreeSpace(page) < minfree)
      {
          /* OK, try to get exclusive buffer lock */
          if (!ConditionalLockBufferForCleanup(buffer))
***************
*** 111,117 ****
           * prune. (We needn't recheck PageIsPrunable, since no one else could
           * have pruned while we hold pin.)
           */
!         if (PageIsFull(dp) || PageGetHeapFreeSpace((Page) dp) < minfree)
          {
              /* OK to prune (though not to remove redirects) */
              (void) heap_page_prune(relation, buffer, OldestXmin, false, true);
--- 111,117 ----
           * prune. (We needn't recheck PageIsPrunable, since no one else could
           * have pruned while we hold pin.)
           */
!         if (PageIsFull(page) || PageGetHeapFreeSpace(page) < minfree)
          {
              /* OK to prune (though not to remove redirects) */
              (void) heap_page_prune(relation, buffer, OldestXmin, false, true);
diff -cr pgsql.orig.da8c485e0e2a/src/backend/access/nbtree/nbtpage.c pgsql.orig/src/backend/access/nbtree/nbtpage.c
*** pgsql.orig.da8c485e0e2a/src/backend/access/nbtree/nbtpage.c    pá črc  4 10:23:41 2008
--- pgsql.orig/src/backend/access/nbtree/nbtpage.c    pá črc  4 10:23:41 2008
***************
*** 436,448 ****
      /*
       * Additionally check that the special area looks sane.
       */
!     if (((PageHeader) (page))->pd_special !=
!         (BLCKSZ - MAXALIGN(sizeof(BTPageOpaqueData))))
          ereport(ERROR,
                  (errcode(ERRCODE_INDEX_CORRUPTED),
                   errmsg("index \"%s\" contains corrupted page at block %u",
                          RelationGetRelationName(rel),
!                         BufferGetBlockNumber(buf)),
                   errhint("Please REINDEX it.")));
  }

--- 436,447 ----
      /*
       * Additionally check that the special area looks sane.
       */
!     if ( (PageGetSpecialSize(page)) != MAXALIGN(sizeof(BTPageOpaqueData)))
          ereport(ERROR,
                  (errcode(ERRCODE_INDEX_CORRUPTED),
                   errmsg("index \"%s\" contains corrupted page at block %u",
                          RelationGetRelationName(rel),
!                         BufferGetBlockNumber(buf)),
                   errhint("Please REINDEX it.")));
  }

***************
*** 555,561 ****

          /* Initialize the new page before returning it */
          page = BufferGetPage(buf);
!         Assert(PageIsNew((PageHeader) page));
          _bt_pageinit(page, BufferGetPageSize(buf));
      }

--- 554,560 ----

          /* Initialize the new page before returning it */
          page = BufferGetPage(buf);
!         Assert(PageIsNew(page));
          _bt_pageinit(page, BufferGetPageSize(buf));
      }

diff -cr pgsql.orig.da8c485e0e2a/src/backend/access/transam/xlog.c pgsql.orig/src/backend/access/transam/xlog.c
*** pgsql.orig.da8c485e0e2a/src/backend/access/transam/xlog.c    pá črc  4 10:23:41 2008
--- pgsql.orig/src/backend/access/transam/xlog.c    pá črc  4 10:23:41 2008
***************
*** 1017,1025 ****
  XLogCheckBuffer(XLogRecData *rdata, bool doPageWrites,
                  XLogRecPtr *lsn, BkpBlock *bkpb)
  {
!     PageHeader    page;

!     page = (PageHeader) BufferGetBlock(rdata->buffer);

      /*
       * XXX We assume page LSN is first data on *every* page that can be passed
--- 1017,1025 ----
  XLogCheckBuffer(XLogRecData *rdata, bool doPageWrites,
                  XLogRecPtr *lsn, BkpBlock *bkpb)
  {
!     Page    page;

!     page = BufferGetBlock(rdata->buffer);

      /*
       * XXX We assume page LSN is first data on *every* page that can be passed
***************
*** 1026,1035 ****
       * to XLogInsert, whether it otherwise has the standard page layout or
       * not.
       */
!     *lsn = page->pd_lsn;

      if (doPageWrites &&
!         XLByteLE(page->pd_lsn, RedoRecPtr))
      {
          /*
           * The page needs to be backed up, so set up *bkpb
--- 1026,1035 ----
       * to XLogInsert, whether it otherwise has the standard page layout or
       * not.
       */
!     *lsn = PageGetLSN(page);

      if (doPageWrites &&
!         XLByteLE(PageGetLSN(page), RedoRecPtr))
      {
          /*
           * The page needs to be backed up, so set up *bkpb
diff -cr pgsql.orig.da8c485e0e2a/src/backend/access/transam/xlogutils.c
pgsql.orig/src/backend/access/transam/xlogutils.c
*** pgsql.orig.da8c485e0e2a/src/backend/access/transam/xlogutils.c    pá črc  4 10:23:41 2008
--- pgsql.orig/src/backend/access/transam/xlogutils.c    pá črc  4 10:23:41 2008
***************
*** 262,268 ****
          /* check that page has been initialized */
          Page        page = (Page) BufferGetPage(buffer);

!         if (PageIsNew((PageHeader) page))
          {
              UnlockReleaseBuffer(buffer);
              log_invalid_page(reln->rd_node, blkno, true);
--- 262,268 ----
          /* check that page has been initialized */
          Page        page = (Page) BufferGetPage(buffer);

!         if (PageIsNew(page))
          {
              UnlockReleaseBuffer(buffer);
              log_invalid_page(reln->rd_node, blkno, true);
diff -cr pgsql.orig.da8c485e0e2a/src/backend/commands/sequence.c pgsql.orig/src/backend/commands/sequence.c
*** pgsql.orig.da8c485e0e2a/src/backend/commands/sequence.c    pá črc  4 10:23:41 2008
--- pgsql.orig/src/backend/commands/sequence.c    pá črc  4 10:23:41 2008
***************
*** 109,115 ****
      Oid            seqoid;
      Relation    rel;
      Buffer        buf;
!     PageHeader    page;
      sequence_magic *sm;
      HeapTuple    tuple;
      TupleDesc    tupDesc;
--- 109,115 ----
      Oid            seqoid;
      Relation    rel;
      Buffer        buf;
!     Page        page;
      sequence_magic *sm;
      HeapTuple    tuple;
      TupleDesc    tupDesc;
***************
*** 212,220 ****
      buf = ReadBuffer(rel, P_NEW);
      Assert(BufferGetBlockNumber(buf) == 0);

!     page = (PageHeader) BufferGetPage(buf);

!     PageInit((Page) page, BufferGetPageSize(buf), sizeof(sequence_magic));
      sm = (sequence_magic *) PageGetSpecialPointer(page);
      sm->magic = SEQ_MAGIC;

--- 212,220 ----
      buf = ReadBuffer(rel, P_NEW);
      Assert(BufferGetBlockNumber(buf) == 0);

!     page = BufferGetPage(buf);

!     PageInit(page, BufferGetPageSize(buf), sizeof(sequence_magic));
      sm = (sequence_magic *) PageGetSpecialPointer(page);
      sm->magic = SEQ_MAGIC;

***************
*** 954,960 ****
  static Form_pg_sequence
  read_info(SeqTable elm, Relation rel, Buffer *buf)
  {
!     PageHeader    page;
      ItemId        lp;
      HeapTupleData tuple;
      sequence_magic *sm;
--- 954,960 ----
  static Form_pg_sequence
  read_info(SeqTable elm, Relation rel, Buffer *buf)
  {
!     Page    page;
      ItemId        lp;
      HeapTupleData tuple;
      sequence_magic *sm;
***************
*** 963,969 ****
      *buf = ReadBuffer(rel, 0);
      LockBuffer(*buf, BUFFER_LOCK_EXCLUSIVE);

!     page = (PageHeader) BufferGetPage(*buf);
      sm = (sequence_magic *) PageGetSpecialPointer(page);

      if (sm->magic != SEQ_MAGIC)
--- 963,969 ----
      *buf = ReadBuffer(rel, 0);
      LockBuffer(*buf, BUFFER_LOCK_EXCLUSIVE);

!     page = BufferGetPage(*buf);
      sm = (sequence_magic *) PageGetSpecialPointer(page);

      if (sm->magic != SEQ_MAGIC)
***************
*** 972,978 ****

      lp = PageGetItemId(page, FirstOffsetNumber);
      Assert(ItemIdIsNormal(lp));
!     tuple.t_data = (HeapTupleHeader) PageGetItem((Page) page, lp);

      seq = (Form_pg_sequence) GETSTRUCT(&tuple);

--- 972,978 ----

      lp = PageGetItemId(page, FirstOffsetNumber);
      Assert(ItemIdIsNormal(lp));
!     tuple.t_data = (HeapTupleHeader) PageGetItem(page, lp);

      seq = (Form_pg_sequence) GETSTRUCT(&tuple);

diff -cr pgsql.orig.da8c485e0e2a/src/backend/commands/trigger.c pgsql.orig/src/backend/commands/trigger.c
*** pgsql.orig.da8c485e0e2a/src/backend/commands/trigger.c    pá črc  4 10:23:41 2008
--- pgsql.orig/src/backend/commands/trigger.c    pá črc  4 10:23:41 2008
***************
*** 2203,2219 ****
      }
      else
      {
!         PageHeader    dp;
          ItemId        lp;

          buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));

!         dp = (PageHeader) BufferGetPage(buffer);
!         lp = PageGetItemId(dp, ItemPointerGetOffsetNumber(tid));

          Assert(ItemIdIsNormal(lp));

!         tuple.t_data = (HeapTupleHeader) PageGetItem((Page) dp, lp);
          tuple.t_len = ItemIdGetLength(lp);
          tuple.t_self = *tid;
          tuple.t_tableOid = RelationGetRelid(relation);
--- 2203,2219 ----
      }
      else
      {
!         Page        page;
          ItemId        lp;

          buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));

!         page = BufferGetPage(buffer);
!         lp = PageGetItemId(page, ItemPointerGetOffsetNumber(tid));

          Assert(ItemIdIsNormal(lp));

!         tuple.t_data = (HeapTupleHeader) PageGetItem(page, lp);
          tuple.t_len = ItemIdGetLength(lp);
          tuple.t_self = *tid;
          tuple.t_tableOid = RelationGetRelid(relation);
diff -cr pgsql.orig.da8c485e0e2a/src/backend/optimizer/util/plancat.c pgsql.orig/src/backend/optimizer/util/plancat.c
*** pgsql.orig.da8c485e0e2a/src/backend/optimizer/util/plancat.c    pá črc  4 10:23:41 2008
--- pgsql.orig/src/backend/optimizer/util/plancat.c    pá črc  4 10:23:41 2008
***************
*** 429,435 ****
                  tuple_width += sizeof(HeapTupleHeaderData);
                  tuple_width += sizeof(ItemPointerData);
                  /* note: integer division is intentional here */
!                 density = (BLCKSZ - sizeof(PageHeaderData)) / tuple_width;
              }
              *tuples = rint(density * (double) curpages);
              break;
--- 429,435 ----
                  tuple_width += sizeof(HeapTupleHeaderData);
                  tuple_width += sizeof(ItemPointerData);
                  /* note: integer division is intentional here */
!                 density = (BLCKSZ - SizeOfPageHeaderData) / tuple_width;
              }
              *tuples = rint(density * (double) curpages);
              break;
diff -cr pgsql.orig.da8c485e0e2a/src/backend/storage/buffer/bufmgr.c pgsql.orig/src/backend/storage/buffer/bufmgr.c
*** pgsql.orig.da8c485e0e2a/src/backend/storage/buffer/bufmgr.c    pá črc  4 10:23:41 2008
--- pgsql.orig/src/backend/storage/buffer/bufmgr.c    pá črc  4 10:23:41 2008
***************
*** 223,229 ****
           * always have left a zero-filled buffer, complain if not PageIsNew.
           */
          bufBlock = isLocalBuf ? LocalBufHdrGetBlock(bufHdr) : BufHdrGetBlock(bufHdr);
!         if (!PageIsNew((PageHeader) bufBlock))
              ereport(ERROR,
                      (errmsg("unexpected data beyond EOF in block %u of relation \"%s\"",
                              blockNum, RelationGetRelationName(reln)),
--- 223,229 ----
           * always have left a zero-filled buffer, complain if not PageIsNew.
           */
          bufBlock = isLocalBuf ? LocalBufHdrGetBlock(bufHdr) : BufHdrGetBlock(bufHdr);
!         if (!PageIsNew((Page) bufBlock))
              ereport(ERROR,
                      (errmsg("unexpected data beyond EOF in block %u of relation \"%s\"",
                              blockNum, RelationGetRelationName(reln)),
***************
*** 292,298 ****
          else
              smgrread(reln->rd_smgr, blockNum, (char *) bufBlock);
          /* check for garbage data */
!         if (!PageHeaderIsValid((PageHeader) bufBlock))
          {
              if (zero_damaged_pages)
              {
--- 292,298 ----
          else
              smgrread(reln->rd_smgr, blockNum, (char *) bufBlock);
          /* check for garbage data */
!         if (!PageHeaderIsValid((Page) bufBlock))
          {
              if (zero_damaged_pages)
              {
diff -cr pgsql.orig.da8c485e0e2a/src/include/access/hash.h pgsql.orig/src/include/access/hash.h
*** pgsql.orig.da8c485e0e2a/src/include/access/hash.h    pá črc  4 10:23:41 2008
--- pgsql.orig/src/include/access/hash.h    pá črc  4 10:23:41 2008
***************
*** 166,174 ****
   */
  #define HashMaxItemSize(page) \
      (PageGetPageSize(page) - \
!      sizeof(PageHeaderData) - \
!      MAXALIGN(sizeof(HashPageOpaqueData)) - \
!      sizeof(ItemIdData))

  #define HASH_MIN_FILLFACTOR            10
  #define HASH_DEFAULT_FILLFACTOR        75
--- 166,173 ----
   */
  #define HashMaxItemSize(page) \
      (PageGetPageSize(page) - \
!      ( MAXALIGN(SizeOfPageHeaderData + sizeof(ItemId)) + \
!        MAXALIGN(sizeof(HashPageOpaqueData)) ))

  #define HASH_MIN_FILLFACTOR            10
  #define HASH_DEFAULT_FILLFACTOR        75
***************
*** 191,197 ****
  #define BMPG_SHIFT(metap)        ((metap)->hashm_bmshift)
  #define BMPG_MASK(metap)        (BMPGSZ_BIT(metap) - 1)
  #define HashPageGetBitmap(pg) \
!     ((uint32 *) (((char *) (pg)) + MAXALIGN(sizeof(PageHeaderData))))

  /*
   * The number of bits in an ovflpage bitmap word.
--- 190,196 ----
  #define BMPG_SHIFT(metap)        ((metap)->hashm_bmshift)
  #define BMPG_MASK(metap)        (BMPGSZ_BIT(metap) - 1)
  #define HashPageGetBitmap(pg) \
!     ((uint32 *) (((char *) (pg)) + MAXALIGN(SizeOfPageHeaderData + sizeof(ItemIdData))))

  /*
   * The number of bits in an ovflpage bitmap word.
diff -cr pgsql.orig.da8c485e0e2a/src/include/access/htup.h pgsql.orig/src/include/access/htup.h
*** pgsql.orig.da8c485e0e2a/src/include/access/htup.h    pá črc  4 10:23:41 2008
--- pgsql.orig/src/include/access/htup.h    pá črc  4 10:23:41 2008
***************
*** 367,373 ****
   * of assuming that, say, you can fit 2 tuples of size MaxHeapTupleSize/2
   * on the same page.
   */
! #define MaxHeapTupleSize  (BLCKSZ - MAXALIGN(sizeof(PageHeaderData)))

  /*
   * MaxHeapTuplesPerPage is an upper bound on the number of tuples that can
--- 367,373 ----
   * of assuming that, say, you can fit 2 tuples of size MaxHeapTupleSize/2
   * on the same page.
   */
! #define MaxHeapTupleSize  (BLCKSZ - MAXALIGN( (SizeOfPageHeaderData) + sizeof(ItemIdData)))

  /*
   * MaxHeapTuplesPerPage is an upper bound on the number of tuples that can
***************
*** 381,387 ****
   * require increases in the size of work arrays.
   */
  #define MaxHeapTuplesPerPage    \
!     ((int) ((BLCKSZ - offsetof(PageHeaderData, pd_linp)) / \
              (MAXALIGN(offsetof(HeapTupleHeaderData, t_bits)) + sizeof(ItemIdData))))

  /*
--- 381,387 ----
   * require increases in the size of work arrays.
   */
  #define MaxHeapTuplesPerPage    \
!     ((int) ((BLCKSZ - SizeOfPageHeaderData) / \
              (MAXALIGN(offsetof(HeapTupleHeaderData, t_bits)) + sizeof(ItemIdData))))

  /*
diff -cr pgsql.orig.da8c485e0e2a/src/include/access/itup.h pgsql.orig/src/include/access/itup.h
*** pgsql.orig.da8c485e0e2a/src/include/access/itup.h    pá črc  4 10:23:41 2008
--- pgsql.orig/src/include/access/itup.h    pá črc  4 10:23:41 2008
***************
*** 134,140 ****
   * must be maxaligned, and it must have an associated item pointer.
   */
  #define MaxIndexTuplesPerPage    \
!     ((int) ((BLCKSZ - offsetof(PageHeaderData, pd_linp)) / \
              (MAXALIGN(sizeof(IndexTupleData) + 1) + sizeof(ItemIdData))))


--- 134,140 ----
   * must be maxaligned, and it must have an associated item pointer.
   */
  #define MaxIndexTuplesPerPage    \
!     ((int) ((BLCKSZ - SizeOfPageHeaderData) / \
              (MAXALIGN(sizeof(IndexTupleData) + 1) + sizeof(ItemIdData))))


diff -cr pgsql.orig.da8c485e0e2a/src/include/access/nbtree.h pgsql.orig/src/include/access/nbtree.h
*** pgsql.orig.da8c485e0e2a/src/include/access/nbtree.h    pá črc  4 10:23:41 2008
--- pgsql.orig/src/include/access/nbtree.h    pá črc  4 10:23:41 2008
***************
*** 119,125 ****
   */
  #define BTMaxItemSize(page) \
      MAXALIGN_DOWN((PageGetPageSize(page) - \
!                    MAXALIGN(sizeof(PageHeaderData) + 2*sizeof(ItemIdData)) - \
                     MAXALIGN(sizeof(BTPageOpaqueData))) / 3)

  /*
--- 119,125 ----
   */
  #define BTMaxItemSize(page) \
      MAXALIGN_DOWN((PageGetPageSize(page) - \
!                    MAXALIGN(SizeOfPageHeaderData + 3*sizeof(ItemIdData)) - \
                     MAXALIGN(sizeof(BTPageOpaqueData))) / 3)

  /*
diff -cr pgsql.orig.da8c485e0e2a/src/include/access/tuptoaster.h pgsql.orig/src/include/access/tuptoaster.h
*** pgsql.orig.da8c485e0e2a/src/include/access/tuptoaster.h    pá črc  4 10:23:41 2008
--- pgsql.orig/src/include/access/tuptoaster.h    pá črc  4 10:23:41 2008
***************
*** 49,55 ****
  /* Note: sizeof(PageHeaderData) includes the first ItemId on the page */
  #define TOAST_TUPLE_THRESHOLD    \
      MAXALIGN_DOWN((BLCKSZ - \
!                    MAXALIGN(sizeof(PageHeaderData) + (TOAST_TUPLES_PER_PAGE-1) * sizeof(ItemIdData))) \
                    / TOAST_TUPLES_PER_PAGE)

  #define TOAST_TUPLE_TARGET        TOAST_TUPLE_THRESHOLD
--- 49,55 ----
  /* Note: sizeof(PageHeaderData) includes the first ItemId on the page */
  #define TOAST_TUPLE_THRESHOLD    \
      MAXALIGN_DOWN((BLCKSZ - \
!                    MAXALIGN(SizeOfPageHeaderData + (TOAST_TUPLES_PER_PAGE) * sizeof(ItemIdData))) \
                    / TOAST_TUPLES_PER_PAGE)

  #define TOAST_TUPLE_TARGET        TOAST_TUPLE_THRESHOLD
***************
*** 76,82 ****
  /* Note: sizeof(PageHeaderData) includes the first ItemId on the page */
  #define EXTERN_TUPLE_MAX_SIZE    \
      MAXALIGN_DOWN((BLCKSZ - \
!                    MAXALIGN(sizeof(PageHeaderData) + (EXTERN_TUPLES_PER_PAGE-1) * sizeof(ItemIdData))) \
                    / EXTERN_TUPLES_PER_PAGE)

  #define TOAST_MAX_CHUNK_SIZE    \
--- 76,82 ----
  /* Note: sizeof(PageHeaderData) includes the first ItemId on the page */
  #define EXTERN_TUPLE_MAX_SIZE    \
      MAXALIGN_DOWN((BLCKSZ - \
!                    MAXALIGN(SizeOfPageHeaderData + (EXTERN_TUPLES_PER_PAGE) * sizeof(ItemIdData))) \
                    / EXTERN_TUPLES_PER_PAGE)

  #define TOAST_MAX_CHUNK_SIZE    \

Re: page macros cleanup

От
"Pavan Deolasee"
Дата:
On Fri, Jul 4, 2008 at 1:01 PM, Zdenek Kotala <Zdenek.Kotala@sun.com> wrote:
>
>
> Good catch. I lost in basic arithmetic. What I see now that original
> definition count sizeof(ItemIdData) twice and on other side it does not take
> care about MAXALING correctly. I think correct formula is:
>
> #define HashMaxItemSize(page) \
>        (PageGetPageSize(page) - \
>          ( MAXALIGN(SizeOfPageHeaderData + sizeof(ItemIdData))+ \
>            MAXALIGN(sizeof(HashPageOpaqueData)) \
>          )\
>         )
>
> What do you think?
>


Yes. I think that's the correct way.


Thanks,
Pavan

--
Pavan Deolasee
EnterpriseDB http://www.enterprisedb.com

Re: page macros cleanup

От
"Pavan Deolasee"
Дата:
On Fri, Jul 4, 2008 at 2:08 PM, Zdenek Kotala <Zdenek.Kotala@sun.com> wrote:
>  Patch
> modifies HashMaxItemSize. It should require reindex on all hash indexes.
> Should we bump catalog version?
>

Do we really need that ? Even if the new HashMaxItemSize comes out to
be lower than the current limit (because of MAXALIGN), I don't see how
existing hash indexes can have a larger item than the new limit.

Thanks,
Pavan

--
Pavan Deolasee
EnterpriseDB http://www.enterprisedb.com

Re: page macros cleanup (ver 03)

От
Zdenek Kotala
Дата:
Pavan Deolasee napsal(a):
> On Fri, Jul 4, 2008 at 2:08 PM, Zdenek Kotala <Zdenek.Kotala@sun.com> wrote:
>>  Patch
>> modifies HashMaxItemSize. It should require reindex on all hash indexes.
>> Should we bump catalog version?
>>
>
> Do we really need that ? Even if the new HashMaxItemSize comes out to
> be lower than the current limit (because of MAXALIGN), I don't see how
> existing hash indexes can have a larger item than the new limit.

Yeah, I performed calculation and situation is following (for MAXALIGN 4 and 8):

     4         8
Orig    8144        8144
New    8148        8144

It should be OK for all cases.

I fixed also one typo (ItemId -> ItemIdData) and new revision is attached.

        Zdenek


--
Zdenek Kotala              Sun Microsystems
Prague, Czech Republic     http://sun.com/postgresql

diff -cr pgsql.orig.da8c485e0e2a/src/backend/access/gist/gistutil.c pgsql.orig/src/backend/access/gist/gistutil.c
*** pgsql.orig.da8c485e0e2a/src/backend/access/gist/gistutil.c    pá črc  4 10:23:41 2008
--- pgsql.orig/src/backend/access/gist/gistutil.c    pá črc  4 10:23:41 2008
***************
*** 592,599 ****
      /*
       * Additionally check that the special area looks sane.
       */
!     if (((PageHeader) (page))->pd_special !=
!         (BLCKSZ - MAXALIGN(sizeof(GISTPageOpaqueData))))
          ereport(ERROR,
                  (errcode(ERRCODE_INDEX_CORRUPTED),
                   errmsg("index \"%s\" contains corrupted page at block %u",
--- 592,598 ----
      /*
       * Additionally check that the special area looks sane.
       */
!     if ( PageGetSpecialSize(page) != MAXALIGN(sizeof(GISTPageOpaqueData)))
          ereport(ERROR,
                  (errcode(ERRCODE_INDEX_CORRUPTED),
                   errmsg("index \"%s\" contains corrupted page at block %u",
diff -cr pgsql.orig.da8c485e0e2a/src/backend/access/hash/hashpage.c pgsql.orig/src/backend/access/hash/hashpage.c
*** pgsql.orig.da8c485e0e2a/src/backend/access/hash/hashpage.c    pá črc  4 10:23:41 2008
--- pgsql.orig/src/backend/access/hash/hashpage.c    pá črc  4 10:23:41 2008
***************
*** 407,413 ****
      for (i = _hash_log2(metap->hashm_bsize); i > 0; --i)
      {
          if ((1 << i) <= (metap->hashm_bsize -
!                          (MAXALIGN(sizeof(PageHeaderData)) +
                            MAXALIGN(sizeof(HashPageOpaqueData)))))
              break;
      }
--- 407,413 ----
      for (i = _hash_log2(metap->hashm_bsize); i > 0; --i)
      {
          if ((1 << i) <= (metap->hashm_bsize -
!                          (MAXALIGN(SizeOfPageHeaderData) +
                            MAXALIGN(sizeof(HashPageOpaqueData)))))
              break;
      }
diff -cr pgsql.orig.da8c485e0e2a/src/backend/access/hash/hashutil.c pgsql.orig/src/backend/access/hash/hashutil.c
*** pgsql.orig.da8c485e0e2a/src/backend/access/hash/hashutil.c    pá črc  4 10:23:41 2008
--- pgsql.orig/src/backend/access/hash/hashutil.c    pá črc  4 10:23:41 2008
***************
*** 164,171 ****
      /*
       * Additionally check that the special area looks sane.
       */
!     if (((PageHeader) (page))->pd_special !=
!         (BLCKSZ - MAXALIGN(sizeof(HashPageOpaqueData))))
          ereport(ERROR,
                  (errcode(ERRCODE_INDEX_CORRUPTED),
                   errmsg("index \"%s\" contains corrupted page at block %u",
--- 164,170 ----
      /*
       * Additionally check that the special area looks sane.
       */
!     if ( PageGetSpecialSize(page) != MAXALIGN(sizeof(HashPageOpaqueData)))
          ereport(ERROR,
                  (errcode(ERRCODE_INDEX_CORRUPTED),
                   errmsg("index \"%s\" contains corrupted page at block %u",
diff -cr pgsql.orig.da8c485e0e2a/src/backend/access/heap/heapam.c pgsql.orig/src/backend/access/heap/heapam.c
*** pgsql.orig.da8c485e0e2a/src/backend/access/heap/heapam.c    pá črc  4 10:23:41 2008
--- pgsql.orig/src/backend/access/heap/heapam.c    pá črc  4 10:23:41 2008
***************
*** 1342,1348 ****
      ItemPointer tid = &(tuple->t_self);
      ItemId        lp;
      Buffer        buffer;
!     PageHeader    dp;
      OffsetNumber offnum;
      bool        valid;

--- 1342,1348 ----
      ItemPointer tid = &(tuple->t_self);
      ItemId        lp;
      Buffer        buffer;
!     Page        page;
      OffsetNumber offnum;
      bool        valid;

***************
*** 1355,1361 ****
       * Need share lock on buffer to examine tuple commit status.
       */
      LockBuffer(buffer, BUFFER_LOCK_SHARE);
!     dp = (PageHeader) BufferGetPage(buffer);

      /*
       * We'd better check for out-of-range offnum in case of VACUUM since the
--- 1355,1361 ----
       * Need share lock on buffer to examine tuple commit status.
       */
      LockBuffer(buffer, BUFFER_LOCK_SHARE);
!     page = BufferGetPage(buffer);

      /*
       * We'd better check for out-of-range offnum in case of VACUUM since the
***************
*** 1362,1368 ****
       * TID was obtained.
       */
      offnum = ItemPointerGetOffsetNumber(tid);
!     if (offnum < FirstOffsetNumber || offnum > PageGetMaxOffsetNumber(dp))
      {
          LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
          if (keep_buf)
--- 1362,1368 ----
       * TID was obtained.
       */
      offnum = ItemPointerGetOffsetNumber(tid);
!     if (offnum < FirstOffsetNumber || offnum > PageGetMaxOffsetNumber(page))
      {
          LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
          if (keep_buf)
***************
*** 1379,1385 ****
      /*
       * get the item line pointer corresponding to the requested tid
       */
!     lp = PageGetItemId(dp, offnum);

      /*
       * Must check for deleted tuple.
--- 1379,1385 ----
      /*
       * get the item line pointer corresponding to the requested tid
       */
!     lp = PageGetItemId(page, offnum);

      /*
       * Must check for deleted tuple.
***************
*** 1401,1407 ****
      /*
       * fill in *tuple fields
       */
!     tuple->t_data = (HeapTupleHeader) PageGetItem((Page) dp, lp);
      tuple->t_len = ItemIdGetLength(lp);
      tuple->t_tableOid = RelationGetRelid(relation);

--- 1401,1407 ----
      /*
       * fill in *tuple fields
       */
!     tuple->t_data = (HeapTupleHeader) PageGetItem(page, lp);
      tuple->t_len = ItemIdGetLength(lp);
      tuple->t_tableOid = RelationGetRelid(relation);

***************
*** 1626,1632 ****
      for (;;)
      {
          Buffer        buffer;
!         PageHeader    dp;
          OffsetNumber offnum;
          ItemId        lp;
          HeapTupleData tp;
--- 1626,1632 ----
      for (;;)
      {
          Buffer        buffer;
!         Page        page;
          OffsetNumber offnum;
          ItemId        lp;
          HeapTupleData tp;
***************
*** 1637,1643 ****
           */
          buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(&ctid));
          LockBuffer(buffer, BUFFER_LOCK_SHARE);
!         dp = (PageHeader) BufferGetPage(buffer);

          /*
           * Check for bogus item number.  This is not treated as an error
--- 1637,1643 ----
           */
          buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(&ctid));
          LockBuffer(buffer, BUFFER_LOCK_SHARE);
!         page = BufferGetPage(buffer);

          /*
           * Check for bogus item number.  This is not treated as an error
***************
*** 1645,1656 ****
           * just assume that the prior tid is OK and return it unchanged.
           */
          offnum = ItemPointerGetOffsetNumber(&ctid);
!         if (offnum < FirstOffsetNumber || offnum > PageGetMaxOffsetNumber(dp))
          {
              UnlockReleaseBuffer(buffer);
              break;
          }
!         lp = PageGetItemId(dp, offnum);
          if (!ItemIdIsNormal(lp))
          {
              UnlockReleaseBuffer(buffer);
--- 1645,1656 ----
           * just assume that the prior tid is OK and return it unchanged.
           */
          offnum = ItemPointerGetOffsetNumber(&ctid);
!         if (offnum < FirstOffsetNumber || offnum > PageGetMaxOffsetNumber(page))
          {
              UnlockReleaseBuffer(buffer);
              break;
          }
!         lp = PageGetItemId(page, offnum);
          if (!ItemIdIsNormal(lp))
          {
              UnlockReleaseBuffer(buffer);
***************
*** 1659,1665 ****

          /* OK to access the tuple */
          tp.t_self = ctid;
!         tp.t_data = (HeapTupleHeader) PageGetItem(dp, lp);
          tp.t_len = ItemIdGetLength(lp);

          /*
--- 1659,1665 ----

          /* OK to access the tuple */
          tp.t_self = ctid;
!         tp.t_data = (HeapTupleHeader) PageGetItem(page, lp);
          tp.t_len = ItemIdGetLength(lp);

          /*
***************
*** 1963,1969 ****
      TransactionId xid = GetCurrentTransactionId();
      ItemId        lp;
      HeapTupleData tp;
!     PageHeader    dp;
      Buffer        buffer;
      bool        have_tuple_lock = false;
      bool        iscombo;
--- 1963,1969 ----
      TransactionId xid = GetCurrentTransactionId();
      ItemId        lp;
      HeapTupleData tp;
!     Page        page;
      Buffer        buffer;
      bool        have_tuple_lock = false;
      bool        iscombo;
***************
*** 1973,1983 ****
      buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));
      LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);

!     dp = (PageHeader) BufferGetPage(buffer);
!     lp = PageGetItemId(dp, ItemPointerGetOffsetNumber(tid));
      Assert(ItemIdIsNormal(lp));

!     tp.t_data = (HeapTupleHeader) PageGetItem(dp, lp);
      tp.t_len = ItemIdGetLength(lp);
      tp.t_self = *tid;

--- 1973,1983 ----
      buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));
      LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);

!     page = BufferGetPage(buffer);
!     lp = PageGetItemId(page, ItemPointerGetOffsetNumber(tid));
      Assert(ItemIdIsNormal(lp));

!     tp.t_data = (HeapTupleHeader) PageGetItem(page, lp);
      tp.t_len = ItemIdGetLength(lp);
      tp.t_self = *tid;

***************
*** 2111,2117 ****
       * the subsequent page pruning will be a no-op and the hint will be
       * cleared.
       */
!     PageSetPrunable(dp, xid);

      /* store transaction information of xact deleting the tuple */
      tp.t_data->t_infomask &= ~(HEAP_XMAX_COMMITTED |
--- 2111,2117 ----
       * the subsequent page pruning will be a no-op and the hint will be
       * cleared.
       */
!     PageSetPrunable(page, xid);

      /* store transaction information of xact deleting the tuple */
      tp.t_data->t_infomask &= ~(HEAP_XMAX_COMMITTED |
***************
*** 2149,2156 ****

          recptr = XLogInsert(RM_HEAP_ID, XLOG_HEAP_DELETE, rdata);

!         PageSetLSN(dp, recptr);
!         PageSetTLI(dp, ThisTimeLineID);
      }

      END_CRIT_SECTION();
--- 2149,2156 ----

          recptr = XLogInsert(RM_HEAP_ID, XLOG_HEAP_DELETE, rdata);

!         PageSetLSN(page, recptr);
!         PageSetTLI(page, ThisTimeLineID);
      }

      END_CRIT_SECTION();
***************
*** 2275,2281 ****
      ItemId        lp;
      HeapTupleData oldtup;
      HeapTuple    heaptup;
!     PageHeader    dp;
      Buffer        buffer,
                  newbuf;
      bool        need_toast,
--- 2275,2281 ----
      ItemId        lp;
      HeapTupleData oldtup;
      HeapTuple    heaptup;
!     Page        page;
      Buffer        buffer,
                  newbuf;
      bool        need_toast,
***************
*** 2305,2315 ****
      buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(otid));
      LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);

!     dp = (PageHeader) BufferGetPage(buffer);
!     lp = PageGetItemId(dp, ItemPointerGetOffsetNumber(otid));
      Assert(ItemIdIsNormal(lp));

!     oldtup.t_data = (HeapTupleHeader) PageGetItem(dp, lp);
      oldtup.t_len = ItemIdGetLength(lp);
      oldtup.t_self = *otid;

--- 2305,2315 ----
      buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(otid));
      LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);

!     page = BufferGetPage(buffer);
!     lp = PageGetItemId(page, ItemPointerGetOffsetNumber(otid));
      Assert(ItemIdIsNormal(lp));

!     oldtup.t_data = (HeapTupleHeader) PageGetItem(page, lp);
      oldtup.t_len = ItemIdGetLength(lp);
      oldtup.t_self = *otid;

***************
*** 2490,2496 ****
                        HeapTupleHasExternal(newtup) ||
                        newtup->t_len > TOAST_TUPLE_THRESHOLD);

!     pagefree = PageGetHeapFreeSpace((Page) dp);

      newtupsize = MAXALIGN(newtup->t_len);

--- 2490,2496 ----
                        HeapTupleHasExternal(newtup) ||
                        newtup->t_len > TOAST_TUPLE_THRESHOLD);

!     pagefree = PageGetHeapFreeSpace(page);

      newtupsize = MAXALIGN(newtup->t_len);

***************
*** 2556,2562 ****
              /* Re-acquire the lock on the old tuple's page. */
              LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);
              /* Re-check using the up-to-date free space */
!             pagefree = PageGetHeapFreeSpace((Page) dp);
              if (newtupsize > pagefree)
              {
                  /*
--- 2556,2562 ----
              /* Re-acquire the lock on the old tuple's page. */
              LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);
              /* Re-check using the up-to-date free space */
!             pagefree = PageGetHeapFreeSpace(page);
              if (newtupsize > pagefree)
              {
                  /*
***************
*** 2602,2608 ****
      else
      {
          /* Set a hint that the old page could use prune/defrag */
!         PageSetFull(dp);
      }

      /* NO EREPORT(ERROR) from here till changes are logged */
--- 2602,2608 ----
      else
      {
          /* Set a hint that the old page could use prune/defrag */
!         PageSetFull(page);
      }

      /* NO EREPORT(ERROR) from here till changes are logged */
***************
*** 2620,2626 ****
       * not to optimize for aborts.    Note that heap_xlog_update must be kept in
       * sync if this decision changes.
       */
!     PageSetPrunable(dp, xid);

      if (use_hot_update)
      {
--- 2620,2626 ----
       * not to optimize for aborts.    Note that heap_xlog_update must be kept in
       * sync if this decision changes.
       */
!     PageSetPrunable(page, xid);

      if (use_hot_update)
      {
***************
*** 2945,2951 ****
      HTSU_Result result;
      ItemPointer tid = &(tuple->t_self);
      ItemId        lp;
!     PageHeader    dp;
      TransactionId xid;
      TransactionId xmax;
      uint16        old_infomask;
--- 2945,2951 ----
      HTSU_Result result;
      ItemPointer tid = &(tuple->t_self);
      ItemId        lp;
!     Page        page;
      TransactionId xid;
      TransactionId xmax;
      uint16        old_infomask;
***************
*** 2958,2968 ****
      *buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));
      LockBuffer(*buffer, BUFFER_LOCK_EXCLUSIVE);

!     dp = (PageHeader) BufferGetPage(*buffer);
!     lp = PageGetItemId(dp, ItemPointerGetOffsetNumber(tid));
      Assert(ItemIdIsNormal(lp));

!     tuple->t_data = (HeapTupleHeader) PageGetItem((Page) dp, lp);
      tuple->t_len = ItemIdGetLength(lp);
      tuple->t_tableOid = RelationGetRelid(relation);

--- 2958,2968 ----
      *buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));
      LockBuffer(*buffer, BUFFER_LOCK_EXCLUSIVE);

!     page = BufferGetPage(*buffer);
!     lp = PageGetItemId(page, ItemPointerGetOffsetNumber(tid));
      Assert(ItemIdIsNormal(lp));

!     tuple->t_data = (HeapTupleHeader) PageGetItem(page, lp);
      tuple->t_len = ItemIdGetLength(lp);
      tuple->t_tableOid = RelationGetRelid(relation);

***************
*** 3301,3308 ****

          recptr = XLogInsert(RM_HEAP_ID, XLOG_HEAP_LOCK, rdata);

!         PageSetLSN(dp, recptr);
!         PageSetTLI(dp, ThisTimeLineID);
      }

      END_CRIT_SECTION();
--- 3301,3308 ----

          recptr = XLogInsert(RM_HEAP_ID, XLOG_HEAP_LOCK, rdata);

!         PageSetLSN(page, recptr);
!         PageSetTLI(page, ThisTimeLineID);
      }

      END_CRIT_SECTION();
diff -cr pgsql.orig.da8c485e0e2a/src/backend/access/heap/hio.c pgsql.orig/src/backend/access/heap/hio.c
*** pgsql.orig.da8c485e0e2a/src/backend/access/heap/hio.c    pá črc  4 10:23:41 2008
--- pgsql.orig/src/backend/access/heap/hio.c    pá črc  4 10:23:41 2008
***************
*** 107,113 ****
                            Buffer otherBuffer, bool use_fsm)
  {
      Buffer        buffer = InvalidBuffer;
!     Page        pageHeader;
      Size        pageFreeSpace,
                  saveFreeSpace;
      BlockNumber targetBlock,
--- 107,113 ----
                            Buffer otherBuffer, bool use_fsm)
  {
      Buffer        buffer = InvalidBuffer;
!     Page        page;
      Size        pageFreeSpace,
                  saveFreeSpace;
      BlockNumber targetBlock,
***************
*** 218,225 ****
           * Now we can check to see if there's enough free space here. If so,
           * we're done.
           */
!         pageHeader = (Page) BufferGetPage(buffer);
!         pageFreeSpace = PageGetHeapFreeSpace(pageHeader);
          if (len + saveFreeSpace <= pageFreeSpace)
          {
              /* use this page as future insert target, too */
--- 218,225 ----
           * Now we can check to see if there's enough free space here. If so,
           * we're done.
           */
!         page = BufferGetPage(buffer);
!         pageFreeSpace = PageGetHeapFreeSpace(page);
          if (len + saveFreeSpace <= pageFreeSpace)
          {
              /* use this page as future insert target, too */
***************
*** 303,318 ****
       * is empty (this should never happen, but if it does we don't want to
       * risk wiping out valid data).
       */
!     pageHeader = (Page) BufferGetPage(buffer);

!     if (!PageIsNew((PageHeader) pageHeader))
          elog(ERROR, "page %u of relation \"%s\" should be empty but is not",
               BufferGetBlockNumber(buffer),
               RelationGetRelationName(relation));

!     PageInit(pageHeader, BufferGetPageSize(buffer), 0);

!     if (len > PageGetHeapFreeSpace(pageHeader))
      {
          /* We should not get here given the test at the top */
          elog(PANIC, "tuple is too big: size %lu", (unsigned long) len);
--- 303,318 ----
       * is empty (this should never happen, but if it does we don't want to
       * risk wiping out valid data).
       */
!     page = BufferGetPage(buffer);

!     if (!PageIsNew(page))
          elog(ERROR, "page %u of relation \"%s\" should be empty but is not",
               BufferGetBlockNumber(buffer),
               RelationGetRelationName(relation));

!     PageInit(page, BufferGetPageSize(buffer), 0);

!     if (len > PageGetHeapFreeSpace(page))
      {
          /* We should not get here given the test at the top */
          elog(PANIC, "tuple is too big: size %lu", (unsigned long) len);
diff -cr pgsql.orig.da8c485e0e2a/src/backend/access/heap/pruneheap.c pgsql.orig/src/backend/access/heap/pruneheap.c
*** pgsql.orig.da8c485e0e2a/src/backend/access/heap/pruneheap.c    pá črc  4 10:23:41 2008
--- pgsql.orig/src/backend/access/heap/pruneheap.c    pá črc  4 10:23:41 2008
***************
*** 71,77 ****
  void
  heap_page_prune_opt(Relation relation, Buffer buffer, TransactionId OldestXmin)
  {
!     PageHeader    dp = (PageHeader) BufferGetPage(buffer);
      Size        minfree;

      /*
--- 71,77 ----
  void
  heap_page_prune_opt(Relation relation, Buffer buffer, TransactionId OldestXmin)
  {
!     Page        page = BufferGetPage(buffer);
      Size        minfree;

      /*
***************
*** 80,86 ****
       * Forget it if page is not hinted to contain something prunable that's
       * older than OldestXmin.
       */
!     if (!PageIsPrunable(dp, OldestXmin))
          return;

      /*
--- 80,86 ----
       * Forget it if page is not hinted to contain something prunable that's
       * older than OldestXmin.
       */
!     if (!PageIsPrunable(page, OldestXmin))
          return;

      /*
***************
*** 99,105 ****
                                               HEAP_DEFAULT_FILLFACTOR);
      minfree = Max(minfree, BLCKSZ / 10);

!     if (PageIsFull(dp) || PageGetHeapFreeSpace((Page) dp) < minfree)
      {
          /* OK, try to get exclusive buffer lock */
          if (!ConditionalLockBufferForCleanup(buffer))
--- 99,105 ----
                                               HEAP_DEFAULT_FILLFACTOR);
      minfree = Max(minfree, BLCKSZ / 10);

!     if (PageIsFull(page) || PageGetHeapFreeSpace(page) < minfree)
      {
          /* OK, try to get exclusive buffer lock */
          if (!ConditionalLockBufferForCleanup(buffer))
***************
*** 111,117 ****
           * prune. (We needn't recheck PageIsPrunable, since no one else could
           * have pruned while we hold pin.)
           */
!         if (PageIsFull(dp) || PageGetHeapFreeSpace((Page) dp) < minfree)
          {
              /* OK to prune (though not to remove redirects) */
              (void) heap_page_prune(relation, buffer, OldestXmin, false, true);
--- 111,117 ----
           * prune. (We needn't recheck PageIsPrunable, since no one else could
           * have pruned while we hold pin.)
           */
!         if (PageIsFull(page) || PageGetHeapFreeSpace(page) < minfree)
          {
              /* OK to prune (though not to remove redirects) */
              (void) heap_page_prune(relation, buffer, OldestXmin, false, true);
diff -cr pgsql.orig.da8c485e0e2a/src/backend/access/nbtree/nbtpage.c pgsql.orig/src/backend/access/nbtree/nbtpage.c
*** pgsql.orig.da8c485e0e2a/src/backend/access/nbtree/nbtpage.c    pá črc  4 10:23:41 2008
--- pgsql.orig/src/backend/access/nbtree/nbtpage.c    pá črc  4 10:23:41 2008
***************
*** 436,448 ****
      /*
       * Additionally check that the special area looks sane.
       */
!     if (((PageHeader) (page))->pd_special !=
!         (BLCKSZ - MAXALIGN(sizeof(BTPageOpaqueData))))
          ereport(ERROR,
                  (errcode(ERRCODE_INDEX_CORRUPTED),
                   errmsg("index \"%s\" contains corrupted page at block %u",
                          RelationGetRelationName(rel),
!                         BufferGetBlockNumber(buf)),
                   errhint("Please REINDEX it.")));
  }

--- 436,447 ----
      /*
       * Additionally check that the special area looks sane.
       */
!     if ( (PageGetSpecialSize(page)) != MAXALIGN(sizeof(BTPageOpaqueData)))
          ereport(ERROR,
                  (errcode(ERRCODE_INDEX_CORRUPTED),
                   errmsg("index \"%s\" contains corrupted page at block %u",
                          RelationGetRelationName(rel),
!                         BufferGetBlockNumber(buf)),
                   errhint("Please REINDEX it.")));
  }

***************
*** 555,561 ****

          /* Initialize the new page before returning it */
          page = BufferGetPage(buf);
!         Assert(PageIsNew((PageHeader) page));
          _bt_pageinit(page, BufferGetPageSize(buf));
      }

--- 554,560 ----

          /* Initialize the new page before returning it */
          page = BufferGetPage(buf);
!         Assert(PageIsNew(page));
          _bt_pageinit(page, BufferGetPageSize(buf));
      }

diff -cr pgsql.orig.da8c485e0e2a/src/backend/access/transam/xlog.c pgsql.orig/src/backend/access/transam/xlog.c
*** pgsql.orig.da8c485e0e2a/src/backend/access/transam/xlog.c    pá črc  4 10:23:41 2008
--- pgsql.orig/src/backend/access/transam/xlog.c    pá črc  4 10:23:41 2008
***************
*** 1017,1025 ****
  XLogCheckBuffer(XLogRecData *rdata, bool doPageWrites,
                  XLogRecPtr *lsn, BkpBlock *bkpb)
  {
!     PageHeader    page;

!     page = (PageHeader) BufferGetBlock(rdata->buffer);

      /*
       * XXX We assume page LSN is first data on *every* page that can be passed
--- 1017,1025 ----
  XLogCheckBuffer(XLogRecData *rdata, bool doPageWrites,
                  XLogRecPtr *lsn, BkpBlock *bkpb)
  {
!     Page    page;

!     page = BufferGetBlock(rdata->buffer);

      /*
       * XXX We assume page LSN is first data on *every* page that can be passed
***************
*** 1026,1035 ****
       * to XLogInsert, whether it otherwise has the standard page layout or
       * not.
       */
!     *lsn = page->pd_lsn;

      if (doPageWrites &&
!         XLByteLE(page->pd_lsn, RedoRecPtr))
      {
          /*
           * The page needs to be backed up, so set up *bkpb
--- 1026,1035 ----
       * to XLogInsert, whether it otherwise has the standard page layout or
       * not.
       */
!     *lsn = PageGetLSN(page);

      if (doPageWrites &&
!         XLByteLE(PageGetLSN(page), RedoRecPtr))
      {
          /*
           * The page needs to be backed up, so set up *bkpb
diff -cr pgsql.orig.da8c485e0e2a/src/backend/access/transam/xlogutils.c
pgsql.orig/src/backend/access/transam/xlogutils.c
*** pgsql.orig.da8c485e0e2a/src/backend/access/transam/xlogutils.c    pá črc  4 10:23:41 2008
--- pgsql.orig/src/backend/access/transam/xlogutils.c    pá črc  4 10:23:41 2008
***************
*** 262,268 ****
          /* check that page has been initialized */
          Page        page = (Page) BufferGetPage(buffer);

!         if (PageIsNew((PageHeader) page))
          {
              UnlockReleaseBuffer(buffer);
              log_invalid_page(reln->rd_node, blkno, true);
--- 262,268 ----
          /* check that page has been initialized */
          Page        page = (Page) BufferGetPage(buffer);

!         if (PageIsNew(page))
          {
              UnlockReleaseBuffer(buffer);
              log_invalid_page(reln->rd_node, blkno, true);
diff -cr pgsql.orig.da8c485e0e2a/src/backend/commands/sequence.c pgsql.orig/src/backend/commands/sequence.c
*** pgsql.orig.da8c485e0e2a/src/backend/commands/sequence.c    pá črc  4 10:23:41 2008
--- pgsql.orig/src/backend/commands/sequence.c    pá črc  4 10:23:41 2008
***************
*** 109,115 ****
      Oid            seqoid;
      Relation    rel;
      Buffer        buf;
!     PageHeader    page;
      sequence_magic *sm;
      HeapTuple    tuple;
      TupleDesc    tupDesc;
--- 109,115 ----
      Oid            seqoid;
      Relation    rel;
      Buffer        buf;
!     Page        page;
      sequence_magic *sm;
      HeapTuple    tuple;
      TupleDesc    tupDesc;
***************
*** 212,220 ****
      buf = ReadBuffer(rel, P_NEW);
      Assert(BufferGetBlockNumber(buf) == 0);

!     page = (PageHeader) BufferGetPage(buf);

!     PageInit((Page) page, BufferGetPageSize(buf), sizeof(sequence_magic));
      sm = (sequence_magic *) PageGetSpecialPointer(page);
      sm->magic = SEQ_MAGIC;

--- 212,220 ----
      buf = ReadBuffer(rel, P_NEW);
      Assert(BufferGetBlockNumber(buf) == 0);

!     page = BufferGetPage(buf);

!     PageInit(page, BufferGetPageSize(buf), sizeof(sequence_magic));
      sm = (sequence_magic *) PageGetSpecialPointer(page);
      sm->magic = SEQ_MAGIC;

***************
*** 954,960 ****
  static Form_pg_sequence
  read_info(SeqTable elm, Relation rel, Buffer *buf)
  {
!     PageHeader    page;
      ItemId        lp;
      HeapTupleData tuple;
      sequence_magic *sm;
--- 954,960 ----
  static Form_pg_sequence
  read_info(SeqTable elm, Relation rel, Buffer *buf)
  {
!     Page    page;
      ItemId        lp;
      HeapTupleData tuple;
      sequence_magic *sm;
***************
*** 963,969 ****
      *buf = ReadBuffer(rel, 0);
      LockBuffer(*buf, BUFFER_LOCK_EXCLUSIVE);

!     page = (PageHeader) BufferGetPage(*buf);
      sm = (sequence_magic *) PageGetSpecialPointer(page);

      if (sm->magic != SEQ_MAGIC)
--- 963,969 ----
      *buf = ReadBuffer(rel, 0);
      LockBuffer(*buf, BUFFER_LOCK_EXCLUSIVE);

!     page = BufferGetPage(*buf);
      sm = (sequence_magic *) PageGetSpecialPointer(page);

      if (sm->magic != SEQ_MAGIC)
***************
*** 972,978 ****

      lp = PageGetItemId(page, FirstOffsetNumber);
      Assert(ItemIdIsNormal(lp));
!     tuple.t_data = (HeapTupleHeader) PageGetItem((Page) page, lp);

      seq = (Form_pg_sequence) GETSTRUCT(&tuple);

--- 972,978 ----

      lp = PageGetItemId(page, FirstOffsetNumber);
      Assert(ItemIdIsNormal(lp));
!     tuple.t_data = (HeapTupleHeader) PageGetItem(page, lp);

      seq = (Form_pg_sequence) GETSTRUCT(&tuple);

diff -cr pgsql.orig.da8c485e0e2a/src/backend/commands/trigger.c pgsql.orig/src/backend/commands/trigger.c
*** pgsql.orig.da8c485e0e2a/src/backend/commands/trigger.c    pá črc  4 10:23:41 2008
--- pgsql.orig/src/backend/commands/trigger.c    pá črc  4 10:23:41 2008
***************
*** 2203,2219 ****
      }
      else
      {
!         PageHeader    dp;
          ItemId        lp;

          buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));

!         dp = (PageHeader) BufferGetPage(buffer);
!         lp = PageGetItemId(dp, ItemPointerGetOffsetNumber(tid));

          Assert(ItemIdIsNormal(lp));

!         tuple.t_data = (HeapTupleHeader) PageGetItem((Page) dp, lp);
          tuple.t_len = ItemIdGetLength(lp);
          tuple.t_self = *tid;
          tuple.t_tableOid = RelationGetRelid(relation);
--- 2203,2219 ----
      }
      else
      {
!         Page        page;
          ItemId        lp;

          buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));

!         page = BufferGetPage(buffer);
!         lp = PageGetItemId(page, ItemPointerGetOffsetNumber(tid));

          Assert(ItemIdIsNormal(lp));

!         tuple.t_data = (HeapTupleHeader) PageGetItem(page, lp);
          tuple.t_len = ItemIdGetLength(lp);
          tuple.t_self = *tid;
          tuple.t_tableOid = RelationGetRelid(relation);
diff -cr pgsql.orig.da8c485e0e2a/src/backend/optimizer/util/plancat.c pgsql.orig/src/backend/optimizer/util/plancat.c
*** pgsql.orig.da8c485e0e2a/src/backend/optimizer/util/plancat.c    pá črc  4 10:23:41 2008
--- pgsql.orig/src/backend/optimizer/util/plancat.c    pá črc  4 10:23:41 2008
***************
*** 429,435 ****
                  tuple_width += sizeof(HeapTupleHeaderData);
                  tuple_width += sizeof(ItemPointerData);
                  /* note: integer division is intentional here */
!                 density = (BLCKSZ - sizeof(PageHeaderData)) / tuple_width;
              }
              *tuples = rint(density * (double) curpages);
              break;
--- 429,435 ----
                  tuple_width += sizeof(HeapTupleHeaderData);
                  tuple_width += sizeof(ItemPointerData);
                  /* note: integer division is intentional here */
!                 density = (BLCKSZ - SizeOfPageHeaderData) / tuple_width;
              }
              *tuples = rint(density * (double) curpages);
              break;
diff -cr pgsql.orig.da8c485e0e2a/src/backend/storage/buffer/bufmgr.c pgsql.orig/src/backend/storage/buffer/bufmgr.c
*** pgsql.orig.da8c485e0e2a/src/backend/storage/buffer/bufmgr.c    pá črc  4 10:23:41 2008
--- pgsql.orig/src/backend/storage/buffer/bufmgr.c    pá črc  4 10:23:41 2008
***************
*** 223,229 ****
           * always have left a zero-filled buffer, complain if not PageIsNew.
           */
          bufBlock = isLocalBuf ? LocalBufHdrGetBlock(bufHdr) : BufHdrGetBlock(bufHdr);
!         if (!PageIsNew((PageHeader) bufBlock))
              ereport(ERROR,
                      (errmsg("unexpected data beyond EOF in block %u of relation \"%s\"",
                              blockNum, RelationGetRelationName(reln)),
--- 223,229 ----
           * always have left a zero-filled buffer, complain if not PageIsNew.
           */
          bufBlock = isLocalBuf ? LocalBufHdrGetBlock(bufHdr) : BufHdrGetBlock(bufHdr);
!         if (!PageIsNew((Page) bufBlock))
              ereport(ERROR,
                      (errmsg("unexpected data beyond EOF in block %u of relation \"%s\"",
                              blockNum, RelationGetRelationName(reln)),
***************
*** 292,298 ****
          else
              smgrread(reln->rd_smgr, blockNum, (char *) bufBlock);
          /* check for garbage data */
!         if (!PageHeaderIsValid((PageHeader) bufBlock))
          {
              if (zero_damaged_pages)
              {
--- 292,298 ----
          else
              smgrread(reln->rd_smgr, blockNum, (char *) bufBlock);
          /* check for garbage data */
!         if (!PageHeaderIsValid((Page) bufBlock))
          {
              if (zero_damaged_pages)
              {
diff -cr pgsql.orig.da8c485e0e2a/src/include/access/hash.h pgsql.orig/src/include/access/hash.h
*** pgsql.orig.da8c485e0e2a/src/include/access/hash.h    pá črc  4 10:23:41 2008
--- pgsql.orig/src/include/access/hash.h    pá črc  4 10:23:41 2008
***************
*** 166,174 ****
   */
  #define HashMaxItemSize(page) \
      (PageGetPageSize(page) - \
!      sizeof(PageHeaderData) - \
!      MAXALIGN(sizeof(HashPageOpaqueData)) - \
!      sizeof(ItemIdData))

  #define HASH_MIN_FILLFACTOR            10
  #define HASH_DEFAULT_FILLFACTOR        75
--- 166,173 ----
   */
  #define HashMaxItemSize(page) \
      (PageGetPageSize(page) - \
!      ( MAXALIGN(SizeOfPageHeaderData + sizeof(ItemIdData)) + \
!        MAXALIGN(sizeof(HashPageOpaqueData)) ))

  #define HASH_MIN_FILLFACTOR            10
  #define HASH_DEFAULT_FILLFACTOR        75
***************
*** 191,197 ****
  #define BMPG_SHIFT(metap)        ((metap)->hashm_bmshift)
  #define BMPG_MASK(metap)        (BMPGSZ_BIT(metap) - 1)
  #define HashPageGetBitmap(pg) \
!     ((uint32 *) (((char *) (pg)) + MAXALIGN(sizeof(PageHeaderData))))

  /*
   * The number of bits in an ovflpage bitmap word.
--- 190,196 ----
  #define BMPG_SHIFT(metap)        ((metap)->hashm_bmshift)
  #define BMPG_MASK(metap)        (BMPGSZ_BIT(metap) - 1)
  #define HashPageGetBitmap(pg) \
!     ((uint32 *) (((char *) (pg)) + MAXALIGN(SizeOfPageHeaderData + sizeof(ItemIdData))))

  /*
   * The number of bits in an ovflpage bitmap word.
diff -cr pgsql.orig.da8c485e0e2a/src/include/access/htup.h pgsql.orig/src/include/access/htup.h
*** pgsql.orig.da8c485e0e2a/src/include/access/htup.h    pá črc  4 10:23:41 2008
--- pgsql.orig/src/include/access/htup.h    pá črc  4 10:23:41 2008
***************
*** 367,373 ****
   * of assuming that, say, you can fit 2 tuples of size MaxHeapTupleSize/2
   * on the same page.
   */
! #define MaxHeapTupleSize  (BLCKSZ - MAXALIGN(sizeof(PageHeaderData)))

  /*
   * MaxHeapTuplesPerPage is an upper bound on the number of tuples that can
--- 367,373 ----
   * of assuming that, say, you can fit 2 tuples of size MaxHeapTupleSize/2
   * on the same page.
   */
! #define MaxHeapTupleSize  (BLCKSZ - MAXALIGN( (SizeOfPageHeaderData) + sizeof(ItemIdData)))

  /*
   * MaxHeapTuplesPerPage is an upper bound on the number of tuples that can
***************
*** 381,387 ****
   * require increases in the size of work arrays.
   */
  #define MaxHeapTuplesPerPage    \
!     ((int) ((BLCKSZ - offsetof(PageHeaderData, pd_linp)) / \
              (MAXALIGN(offsetof(HeapTupleHeaderData, t_bits)) + sizeof(ItemIdData))))

  /*
--- 381,387 ----
   * require increases in the size of work arrays.
   */
  #define MaxHeapTuplesPerPage    \
!     ((int) ((BLCKSZ - SizeOfPageHeaderData) / \
              (MAXALIGN(offsetof(HeapTupleHeaderData, t_bits)) + sizeof(ItemIdData))))

  /*
diff -cr pgsql.orig.da8c485e0e2a/src/include/access/itup.h pgsql.orig/src/include/access/itup.h
*** pgsql.orig.da8c485e0e2a/src/include/access/itup.h    pá črc  4 10:23:41 2008
--- pgsql.orig/src/include/access/itup.h    pá črc  4 10:23:41 2008
***************
*** 134,140 ****
   * must be maxaligned, and it must have an associated item pointer.
   */
  #define MaxIndexTuplesPerPage    \
!     ((int) ((BLCKSZ - offsetof(PageHeaderData, pd_linp)) / \
              (MAXALIGN(sizeof(IndexTupleData) + 1) + sizeof(ItemIdData))))


--- 134,140 ----
   * must be maxaligned, and it must have an associated item pointer.
   */
  #define MaxIndexTuplesPerPage    \
!     ((int) ((BLCKSZ - SizeOfPageHeaderData) / \
              (MAXALIGN(sizeof(IndexTupleData) + 1) + sizeof(ItemIdData))))


diff -cr pgsql.orig.da8c485e0e2a/src/include/access/nbtree.h pgsql.orig/src/include/access/nbtree.h
*** pgsql.orig.da8c485e0e2a/src/include/access/nbtree.h    pá črc  4 10:23:41 2008
--- pgsql.orig/src/include/access/nbtree.h    pá črc  4 10:23:41 2008
***************
*** 119,125 ****
   */
  #define BTMaxItemSize(page) \
      MAXALIGN_DOWN((PageGetPageSize(page) - \
!                    MAXALIGN(sizeof(PageHeaderData) + 2*sizeof(ItemIdData)) - \
                     MAXALIGN(sizeof(BTPageOpaqueData))) / 3)

  /*
--- 119,125 ----
   */
  #define BTMaxItemSize(page) \
      MAXALIGN_DOWN((PageGetPageSize(page) - \
!                    MAXALIGN(SizeOfPageHeaderData + 3*sizeof(ItemIdData)) - \
                     MAXALIGN(sizeof(BTPageOpaqueData))) / 3)

  /*
diff -cr pgsql.orig.da8c485e0e2a/src/include/access/tuptoaster.h pgsql.orig/src/include/access/tuptoaster.h
*** pgsql.orig.da8c485e0e2a/src/include/access/tuptoaster.h    pá črc  4 10:23:41 2008
--- pgsql.orig/src/include/access/tuptoaster.h    pá črc  4 10:23:41 2008
***************
*** 49,55 ****
  /* Note: sizeof(PageHeaderData) includes the first ItemId on the page */
  #define TOAST_TUPLE_THRESHOLD    \
      MAXALIGN_DOWN((BLCKSZ - \
!                    MAXALIGN(sizeof(PageHeaderData) + (TOAST_TUPLES_PER_PAGE-1) * sizeof(ItemIdData))) \
                    / TOAST_TUPLES_PER_PAGE)

  #define TOAST_TUPLE_TARGET        TOAST_TUPLE_THRESHOLD
--- 49,55 ----
  /* Note: sizeof(PageHeaderData) includes the first ItemId on the page */
  #define TOAST_TUPLE_THRESHOLD    \
      MAXALIGN_DOWN((BLCKSZ - \
!                    MAXALIGN(SizeOfPageHeaderData + (TOAST_TUPLES_PER_PAGE) * sizeof(ItemIdData))) \
                    / TOAST_TUPLES_PER_PAGE)

  #define TOAST_TUPLE_TARGET        TOAST_TUPLE_THRESHOLD
***************
*** 76,82 ****
  /* Note: sizeof(PageHeaderData) includes the first ItemId on the page */
  #define EXTERN_TUPLE_MAX_SIZE    \
      MAXALIGN_DOWN((BLCKSZ - \
!                    MAXALIGN(sizeof(PageHeaderData) + (EXTERN_TUPLES_PER_PAGE-1) * sizeof(ItemIdData))) \
                    / EXTERN_TUPLES_PER_PAGE)

  #define TOAST_MAX_CHUNK_SIZE    \
--- 76,82 ----
  /* Note: sizeof(PageHeaderData) includes the first ItemId on the page */
  #define EXTERN_TUPLE_MAX_SIZE    \
      MAXALIGN_DOWN((BLCKSZ - \
!                    MAXALIGN(SizeOfPageHeaderData + (EXTERN_TUPLES_PER_PAGE) * sizeof(ItemIdData))) \
                    / EXTERN_TUPLES_PER_PAGE)

  #define TOAST_MAX_CHUNK_SIZE    \

Re: page macros cleanup

От
"Heikki Linnakangas"
Дата:
Pavan Deolasee wrote:
> On Fri, Jul 4, 2008 at 1:01 PM, Zdenek Kotala <Zdenek.Kotala@sun.com> wrote:
>>
>> Good catch. I lost in basic arithmetic. What I see now that original
>> definition count sizeof(ItemIdData) twice and on other side it does not take
>> care about MAXALING correctly. I think correct formula is:
>>
>> #define HashMaxItemSize(page) \
>>        (PageGetPageSize(page) - \
>>          ( MAXALIGN(SizeOfPageHeaderData + sizeof(ItemIdData))+ \
>>            MAXALIGN(sizeof(HashPageOpaqueData)) \
>>          )\
>>         )
>>
>> What do you think?
>
> Yes. I think that's the correct way.

Doesn't look right to me. There's no padding after the first line
pointer, hence the first MAXALIGN shouldn't be there.

BTW, looking at hashinsert.c where it's used, we're actually passing a
pointer to the meta page to HashMaxItemSize(). So the PageGetPageSize()
call on that is quite bogus, since it's not the meta page that the tuple
is going to be inserted to. It's academical, because all pages are the
same size anyway, but doesn't look right. I think I'd go with BLKCSZ
instead.

I think this is the way it should be:

#define HashMaxItemSize \
    (BLCKSZ - \
     SizeOfPageHeaderData - \
     MAXALIGN(sizeof(HashPageOpaqueData)) - \
     sizeof(ItemIdData))

--
   Heikki Linnakangas
   EnterpriseDB   http://www.enterprisedb.com

Re: page macros cleanup

От
"Pavan Deolasee"
Дата:
On Fri, Jul 4, 2008 at 3:37 PM, Heikki Linnakangas
<heikki@enterprisedb.com> wrote:
>
>
> I think this is the way it should be:
>
> #define HashMaxItemSize \
>        (BLCKSZ - \
>         SizeOfPageHeaderData - \
>         MAXALIGN(sizeof(HashPageOpaqueData)) - \
>         sizeof(ItemIdData))
>

I am wondering if this would fail for corner case if HashMaxItemSize
happened to be unaligned. For example, if (itemsz < HashMaxItemSize <
MAXALIGN(itemsz), PageAddItem() would later fail with a not-so-obvious
error. Should we just MAXALIGN_DOWN the HashMaxItemSize ?

Thanks,
Pavan


--
Pavan Deolasee
EnterpriseDB http://www.enterprisedb.com

Re: page macros cleanup

От
Zdenek Kotala
Дата:
Heikki Linnakangas napsal(a):
> Pavan Deolasee wrote:
>> On Fri, Jul 4, 2008 at 1:01 PM, Zdenek Kotala <Zdenek.Kotala@sun.com>
>> wrote:
>>>
>>> Good catch. I lost in basic arithmetic. What I see now that original
>>> definition count sizeof(ItemIdData) twice and on other side it does
>>> not take
>>> care about MAXALING correctly. I think correct formula is:
>>>
>>> #define HashMaxItemSize(page) \
>>>        (PageGetPageSize(page) - \
>>>          ( MAXALIGN(SizeOfPageHeaderData + sizeof(ItemIdData))+ \
>>>            MAXALIGN(sizeof(HashPageOpaqueData)) \
>>>          )\
>>>         )
>>>
>>> What do you think?
>>
>> Yes. I think that's the correct way.
>
> Doesn't look right to me. There's no padding after the first line
> pointer, hence the first MAXALIGN shouldn't be there.

Are you sure? I expecting that tupleheader must be aligned to MAXALIGN. If it is
not required than you are right.

Look on PageAddItem:

00226     alignedSize = MAXALIGN(size);
00227
00228     upper = (int) phdr->pd_upper - (int) alignedSize;

By my opinion first place where tuple should be placed is:

MAXALIGN(SizeOfPageHeaderData + sizeof(ItemIdData))


> BTW, looking at hashinsert.c where it's used, we're actually passing a
> pointer to the meta page to HashMaxItemSize(). So the PageGetPageSize()
> call on that is quite bogus, since it's not the meta page that the tuple
> is going to be inserted to. It's academical, because all pages are the
> same size anyway, but doesn't look right. I think I'd go with BLKCSZ
> instead.
>

Yeah, BLKCSZ looks good. Anyway, I plan to reorganize all *MaxItemSize staff to
be compatible with in-place upgrade.

        thanks Zdenek


--
Zdenek Kotala              Sun Microsystems
Prague, Czech Republic     http://sun.com/postgresql


Re: page macros cleanup

От
"Heikki Linnakangas"
Дата:
Pavan Deolasee wrote:
> On Fri, Jul 4, 2008 at 3:37 PM, Heikki Linnakangas
> <heikki@enterprisedb.com> wrote:
>>
>> I think this is the way it should be:
>>
>> #define HashMaxItemSize \
>>        (BLCKSZ - \
>>         SizeOfPageHeaderData - \
>>         MAXALIGN(sizeof(HashPageOpaqueData)) - \
>>         sizeof(ItemIdData))
>>
>
> I am wondering if this would fail for corner case if HashMaxItemSize
> happened to be unaligned. For example, if (itemsz < HashMaxItemSize <
> MAXALIGN(itemsz), PageAddItem() would later fail with a not-so-obvious
> error. Should we just MAXALIGN_DOWN the HashMaxItemSize ?

No, there's a itemsz = MAXALIGN(itemsz) call before the check against
HashMaxItemSize.

--
   Heikki Linnakangas
   EnterpriseDB   http://www.enterprisedb.com

Re: page macros cleanup

От
"Pavan Deolasee"
Дата:
On Fri, Jul 4, 2008 at 4:25 PM, Heikki Linnakangas
<heikki@enterprisedb.com> wrote:
>
>
> No, there's a itemsz = MAXALIGN(itemsz) call before the check against
> HashMaxItemSize.
>

Ah, right. Still should we just not MAXALIGN_DOWN the Max size to
reflect the practical limit on the itemsz ? It's more academical
though, so not a big deal.

Thanks,
Pavan

--
Pavan Deolasee
EnterpriseDB http://www.enterprisedb.com

Re: page macros cleanup

От
"Pavan Deolasee"
Дата:
On Fri, Jul 4, 2008 at 4:20 PM, Zdenek Kotala <Zdenek.Kotala@sun.com> wrote:
>
>
>
> By my opinion first place where tuple should be placed is:
>
> MAXALIGN(SizeOfPageHeaderData + sizeof(ItemIdData))
>

Tuple actually starts from the other end of the block.

Thanks,
Pavan

--
Pavan Deolasee
EnterpriseDB http://www.enterprisedb.com

Re: page macros cleanup

От
Zdenek Kotala
Дата:
Heikki Linnakangas napsal(a):
> Pavan Deolasee wrote:
>> On Fri, Jul 4, 2008 at 3:37 PM, Heikki Linnakangas
>> <heikki@enterprisedb.com> wrote:
>>>
>>> I think this is the way it should be:
>>>
>>> #define HashMaxItemSize \
>>>        (BLCKSZ - \
>>>         SizeOfPageHeaderData - \
>>>         MAXALIGN(sizeof(HashPageOpaqueData)) - \
>>>         sizeof(ItemIdData))
>>>
>>
>> I am wondering if this would fail for corner case if HashMaxItemSize
>> happened to be unaligned. For example, if (itemsz < HashMaxItemSize <
>> MAXALIGN(itemsz), PageAddItem() would later fail with a not-so-obvious
>> error. Should we just MAXALIGN_DOWN the HashMaxItemSize ?
>
> No, there's a itemsz = MAXALIGN(itemsz) call before the check against
> HashMaxItemSize.

It is tru, but id somebody will use HashMaxItemSize in different place in the
future he could omit to use same approach. See tuptoaster.h how TOAST_MAX_CHUNK
is defined or BTMaxItemSize in nbtree.h.

Pavan's comments is correct. It should give same result as my implementation
(because BLCKSZ is aligned), but it is better readable and consistent with other.

    Zdenek

--
Zdenek Kotala              Sun Microsystems
Prague, Czech Republic     http://sun.com/postgresql


Re: page macros cleanup

От
Zdenek Kotala
Дата:
Pavan Deolasee napsal(a):
> On Fri, Jul 4, 2008 at 4:20 PM, Zdenek Kotala <Zdenek.Kotala@sun.com> wrote:
>>
>>
>> By my opinion first place where tuple should be placed is:
>>
>> MAXALIGN(SizeOfPageHeaderData + sizeof(ItemIdData))
>>
>
> Tuple actually starts from the other end of the block.

Yes, but I meant first from offset point of view which is opposite to insert order.

        Zdenek


--
Zdenek Kotala              Sun Microsystems
Prague, Czech Republic     http://sun.com/postgresql


Re: page macros cleanup

От
"Heikki Linnakangas"
Дата:
Zdenek Kotala wrote:
> By my opinion first place where tuple should be placed is:
>
> MAXALIGN(SizeOfPageHeaderData + sizeof(ItemIdData))

Yeah, but we don't enforce that directly. We enforce it by MAXALIGNing
size in PageAddItem, and with the rule that special-size is MAXALIGNed.

To put it another way, it's possible that there's an unaligned amount of
free space on a page, as returned by PageGetExactFreeSpace. But since
item size is always MAXALIGNed, it's impossible to use it all.


Come to think of it, why do we require MAXALIGN alignment of tuples? I
must be missing something, but AFAICS the widest fields in
HeapTupleHeaderData are 4-bytes wide, so it should be possible to get
away with 4-byte alignment.

--
   Heikki Linnakangas
   EnterpriseDB   http://www.enterprisedb.com

Re: page macros cleanup

От
Zdenek Kotala
Дата:
Heikki Linnakangas napsal(a):
> Zdenek Kotala wrote:
>> By my opinion first place where tuple should be placed is:
>>
>> MAXALIGN(SizeOfPageHeaderData + sizeof(ItemIdData))
>
> Yeah, but we don't enforce that directly. We enforce it by MAXALIGNing
> size in PageAddItem, and with the rule that special-size is MAXALIGNed.

Yeah, it is implication from other rules. But how Pavan mentioned and I agree
with him. We should have *MaxItemSize value maxaligned, because tuple is
maxaligned anyway and *MaxItemSize defines real limit.

>
> Come to think of it, why do we require MAXALIGN alignment of tuples? I
> must be missing something, but AFAICS the widest fields in
> HeapTupleHeaderData are 4-bytes wide, so it should be possible to get
> away with 4-byte alignment.
>

I think that you have problem to make correct decision about padding between
header and first data item on platform where MAXALIGN is 8. Padding will depends
   on align of offset - if it is max aligned or not. It will have effect for
example on SPARC but it adds extra complexity to code. ... Maybe only set hoff
correctly when new tuple is created ...

Another improvement should be reorder column to got best space allocation during
create table (of course it affect select * from).


        Zdenek

--
Zdenek Kotala              Sun Microsystems
Prague, Czech Republic     http://sun.com/postgresql


Re: page macros cleanup (ver 04)

От
Zdenek Kotala
Дата:
Pavan Deolasee napsal(a):
> On Fri, Jul 4, 2008 at 4:25 PM, Heikki Linnakangas
> <heikki@enterprisedb.com> wrote:
>>
>> No, there's a itemsz = MAXALIGN(itemsz) call before the check against
>> HashMaxItemSize.
>>
>
> Ah, right. Still should we just not MAXALIGN_DOWN the Max size to
> reflect the practical limit on the itemsz ? It's more academical
> though, so not a big deal.

Finally I use following formula:

#define HashMaxItemSize(page) \
      MAXALIGN_DOWN(PageGetPageSize(page) - \
        ( SizeOfPageHeaderData + sizeof(ItemIdData) ) - \
         MAXALIGN(sizeof(HashPageOpaqueData)) )


I did not replace PageGetPageSize(page), because other *MaxItemSize has same
interface.

Revised patch is attached.

        Zdenek

--
Zdenek Kotala              Sun Microsystems
Prague, Czech Republic     http://sun.com/postgresql

diff -cr pgsql.orig.da8c485e0e2a/src/backend/access/gist/gistutil.c pgsql.orig/src/backend/access/gist/gistutil.c
*** pgsql.orig.da8c485e0e2a/src/backend/access/gist/gistutil.c    pá črc  4 14:04:20 2008
--- pgsql.orig/src/backend/access/gist/gistutil.c    pá črc  4 14:04:20 2008
***************
*** 592,599 ****
      /*
       * Additionally check that the special area looks sane.
       */
!     if (((PageHeader) (page))->pd_special !=
!         (BLCKSZ - MAXALIGN(sizeof(GISTPageOpaqueData))))
          ereport(ERROR,
                  (errcode(ERRCODE_INDEX_CORRUPTED),
                   errmsg("index \"%s\" contains corrupted page at block %u",
--- 592,598 ----
      /*
       * Additionally check that the special area looks sane.
       */
!     if ( PageGetSpecialSize(page) != MAXALIGN(sizeof(GISTPageOpaqueData)))
          ereport(ERROR,
                  (errcode(ERRCODE_INDEX_CORRUPTED),
                   errmsg("index \"%s\" contains corrupted page at block %u",
diff -cr pgsql.orig.da8c485e0e2a/src/backend/access/hash/hashpage.c pgsql.orig/src/backend/access/hash/hashpage.c
*** pgsql.orig.da8c485e0e2a/src/backend/access/hash/hashpage.c    pá črc  4 14:04:20 2008
--- pgsql.orig/src/backend/access/hash/hashpage.c    pá črc  4 14:04:20 2008
***************
*** 407,413 ****
      for (i = _hash_log2(metap->hashm_bsize); i > 0; --i)
      {
          if ((1 << i) <= (metap->hashm_bsize -
!                          (MAXALIGN(sizeof(PageHeaderData)) +
                            MAXALIGN(sizeof(HashPageOpaqueData)))))
              break;
      }
--- 407,413 ----
      for (i = _hash_log2(metap->hashm_bsize); i > 0; --i)
      {
          if ((1 << i) <= (metap->hashm_bsize -
!                          (MAXALIGN(SizeOfPageHeaderData) +
                            MAXALIGN(sizeof(HashPageOpaqueData)))))
              break;
      }
diff -cr pgsql.orig.da8c485e0e2a/src/backend/access/hash/hashutil.c pgsql.orig/src/backend/access/hash/hashutil.c
*** pgsql.orig.da8c485e0e2a/src/backend/access/hash/hashutil.c    pá črc  4 14:04:20 2008
--- pgsql.orig/src/backend/access/hash/hashutil.c    pá črc  4 14:04:20 2008
***************
*** 164,171 ****
      /*
       * Additionally check that the special area looks sane.
       */
!     if (((PageHeader) (page))->pd_special !=
!         (BLCKSZ - MAXALIGN(sizeof(HashPageOpaqueData))))
          ereport(ERROR,
                  (errcode(ERRCODE_INDEX_CORRUPTED),
                   errmsg("index \"%s\" contains corrupted page at block %u",
--- 164,170 ----
      /*
       * Additionally check that the special area looks sane.
       */
!     if ( PageGetSpecialSize(page) != MAXALIGN(sizeof(HashPageOpaqueData)))
          ereport(ERROR,
                  (errcode(ERRCODE_INDEX_CORRUPTED),
                   errmsg("index \"%s\" contains corrupted page at block %u",
diff -cr pgsql.orig.da8c485e0e2a/src/backend/access/heap/heapam.c pgsql.orig/src/backend/access/heap/heapam.c
*** pgsql.orig.da8c485e0e2a/src/backend/access/heap/heapam.c    pá črc  4 14:04:20 2008
--- pgsql.orig/src/backend/access/heap/heapam.c    pá črc  4 14:04:20 2008
***************
*** 1342,1348 ****
      ItemPointer tid = &(tuple->t_self);
      ItemId        lp;
      Buffer        buffer;
!     PageHeader    dp;
      OffsetNumber offnum;
      bool        valid;

--- 1342,1348 ----
      ItemPointer tid = &(tuple->t_self);
      ItemId        lp;
      Buffer        buffer;
!     Page        page;
      OffsetNumber offnum;
      bool        valid;

***************
*** 1355,1361 ****
       * Need share lock on buffer to examine tuple commit status.
       */
      LockBuffer(buffer, BUFFER_LOCK_SHARE);
!     dp = (PageHeader) BufferGetPage(buffer);

      /*
       * We'd better check for out-of-range offnum in case of VACUUM since the
--- 1355,1361 ----
       * Need share lock on buffer to examine tuple commit status.
       */
      LockBuffer(buffer, BUFFER_LOCK_SHARE);
!     page = BufferGetPage(buffer);

      /*
       * We'd better check for out-of-range offnum in case of VACUUM since the
***************
*** 1362,1368 ****
       * TID was obtained.
       */
      offnum = ItemPointerGetOffsetNumber(tid);
!     if (offnum < FirstOffsetNumber || offnum > PageGetMaxOffsetNumber(dp))
      {
          LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
          if (keep_buf)
--- 1362,1368 ----
       * TID was obtained.
       */
      offnum = ItemPointerGetOffsetNumber(tid);
!     if (offnum < FirstOffsetNumber || offnum > PageGetMaxOffsetNumber(page))
      {
          LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
          if (keep_buf)
***************
*** 1379,1385 ****
      /*
       * get the item line pointer corresponding to the requested tid
       */
!     lp = PageGetItemId(dp, offnum);

      /*
       * Must check for deleted tuple.
--- 1379,1385 ----
      /*
       * get the item line pointer corresponding to the requested tid
       */
!     lp = PageGetItemId(page, offnum);

      /*
       * Must check for deleted tuple.
***************
*** 1401,1407 ****
      /*
       * fill in *tuple fields
       */
!     tuple->t_data = (HeapTupleHeader) PageGetItem((Page) dp, lp);
      tuple->t_len = ItemIdGetLength(lp);
      tuple->t_tableOid = RelationGetRelid(relation);

--- 1401,1407 ----
      /*
       * fill in *tuple fields
       */
!     tuple->t_data = (HeapTupleHeader) PageGetItem(page, lp);
      tuple->t_len = ItemIdGetLength(lp);
      tuple->t_tableOid = RelationGetRelid(relation);

***************
*** 1626,1632 ****
      for (;;)
      {
          Buffer        buffer;
!         PageHeader    dp;
          OffsetNumber offnum;
          ItemId        lp;
          HeapTupleData tp;
--- 1626,1632 ----
      for (;;)
      {
          Buffer        buffer;
!         Page        page;
          OffsetNumber offnum;
          ItemId        lp;
          HeapTupleData tp;
***************
*** 1637,1643 ****
           */
          buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(&ctid));
          LockBuffer(buffer, BUFFER_LOCK_SHARE);
!         dp = (PageHeader) BufferGetPage(buffer);

          /*
           * Check for bogus item number.  This is not treated as an error
--- 1637,1643 ----
           */
          buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(&ctid));
          LockBuffer(buffer, BUFFER_LOCK_SHARE);
!         page = BufferGetPage(buffer);

          /*
           * Check for bogus item number.  This is not treated as an error
***************
*** 1645,1656 ****
           * just assume that the prior tid is OK and return it unchanged.
           */
          offnum = ItemPointerGetOffsetNumber(&ctid);
!         if (offnum < FirstOffsetNumber || offnum > PageGetMaxOffsetNumber(dp))
          {
              UnlockReleaseBuffer(buffer);
              break;
          }
!         lp = PageGetItemId(dp, offnum);
          if (!ItemIdIsNormal(lp))
          {
              UnlockReleaseBuffer(buffer);
--- 1645,1656 ----
           * just assume that the prior tid is OK and return it unchanged.
           */
          offnum = ItemPointerGetOffsetNumber(&ctid);
!         if (offnum < FirstOffsetNumber || offnum > PageGetMaxOffsetNumber(page))
          {
              UnlockReleaseBuffer(buffer);
              break;
          }
!         lp = PageGetItemId(page, offnum);
          if (!ItemIdIsNormal(lp))
          {
              UnlockReleaseBuffer(buffer);
***************
*** 1659,1665 ****

          /* OK to access the tuple */
          tp.t_self = ctid;
!         tp.t_data = (HeapTupleHeader) PageGetItem(dp, lp);
          tp.t_len = ItemIdGetLength(lp);

          /*
--- 1659,1665 ----

          /* OK to access the tuple */
          tp.t_self = ctid;
!         tp.t_data = (HeapTupleHeader) PageGetItem(page, lp);
          tp.t_len = ItemIdGetLength(lp);

          /*
***************
*** 1963,1969 ****
      TransactionId xid = GetCurrentTransactionId();
      ItemId        lp;
      HeapTupleData tp;
!     PageHeader    dp;
      Buffer        buffer;
      bool        have_tuple_lock = false;
      bool        iscombo;
--- 1963,1969 ----
      TransactionId xid = GetCurrentTransactionId();
      ItemId        lp;
      HeapTupleData tp;
!     Page        page;
      Buffer        buffer;
      bool        have_tuple_lock = false;
      bool        iscombo;
***************
*** 1973,1983 ****
      buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));
      LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);

!     dp = (PageHeader) BufferGetPage(buffer);
!     lp = PageGetItemId(dp, ItemPointerGetOffsetNumber(tid));
      Assert(ItemIdIsNormal(lp));

!     tp.t_data = (HeapTupleHeader) PageGetItem(dp, lp);
      tp.t_len = ItemIdGetLength(lp);
      tp.t_self = *tid;

--- 1973,1983 ----
      buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));
      LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);

!     page = BufferGetPage(buffer);
!     lp = PageGetItemId(page, ItemPointerGetOffsetNumber(tid));
      Assert(ItemIdIsNormal(lp));

!     tp.t_data = (HeapTupleHeader) PageGetItem(page, lp);
      tp.t_len = ItemIdGetLength(lp);
      tp.t_self = *tid;

***************
*** 2111,2117 ****
       * the subsequent page pruning will be a no-op and the hint will be
       * cleared.
       */
!     PageSetPrunable(dp, xid);

      /* store transaction information of xact deleting the tuple */
      tp.t_data->t_infomask &= ~(HEAP_XMAX_COMMITTED |
--- 2111,2117 ----
       * the subsequent page pruning will be a no-op and the hint will be
       * cleared.
       */
!     PageSetPrunable(page, xid);

      /* store transaction information of xact deleting the tuple */
      tp.t_data->t_infomask &= ~(HEAP_XMAX_COMMITTED |
***************
*** 2149,2156 ****

          recptr = XLogInsert(RM_HEAP_ID, XLOG_HEAP_DELETE, rdata);

!         PageSetLSN(dp, recptr);
!         PageSetTLI(dp, ThisTimeLineID);
      }

      END_CRIT_SECTION();
--- 2149,2156 ----

          recptr = XLogInsert(RM_HEAP_ID, XLOG_HEAP_DELETE, rdata);

!         PageSetLSN(page, recptr);
!         PageSetTLI(page, ThisTimeLineID);
      }

      END_CRIT_SECTION();
***************
*** 2275,2281 ****
      ItemId        lp;
      HeapTupleData oldtup;
      HeapTuple    heaptup;
!     PageHeader    dp;
      Buffer        buffer,
                  newbuf;
      bool        need_toast,
--- 2275,2281 ----
      ItemId        lp;
      HeapTupleData oldtup;
      HeapTuple    heaptup;
!     Page        page;
      Buffer        buffer,
                  newbuf;
      bool        need_toast,
***************
*** 2305,2315 ****
      buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(otid));
      LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);

!     dp = (PageHeader) BufferGetPage(buffer);
!     lp = PageGetItemId(dp, ItemPointerGetOffsetNumber(otid));
      Assert(ItemIdIsNormal(lp));

!     oldtup.t_data = (HeapTupleHeader) PageGetItem(dp, lp);
      oldtup.t_len = ItemIdGetLength(lp);
      oldtup.t_self = *otid;

--- 2305,2315 ----
      buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(otid));
      LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);

!     page = BufferGetPage(buffer);
!     lp = PageGetItemId(page, ItemPointerGetOffsetNumber(otid));
      Assert(ItemIdIsNormal(lp));

!     oldtup.t_data = (HeapTupleHeader) PageGetItem(page, lp);
      oldtup.t_len = ItemIdGetLength(lp);
      oldtup.t_self = *otid;

***************
*** 2490,2496 ****
                        HeapTupleHasExternal(newtup) ||
                        newtup->t_len > TOAST_TUPLE_THRESHOLD);

!     pagefree = PageGetHeapFreeSpace((Page) dp);

      newtupsize = MAXALIGN(newtup->t_len);

--- 2490,2496 ----
                        HeapTupleHasExternal(newtup) ||
                        newtup->t_len > TOAST_TUPLE_THRESHOLD);

!     pagefree = PageGetHeapFreeSpace(page);

      newtupsize = MAXALIGN(newtup->t_len);

***************
*** 2556,2562 ****
              /* Re-acquire the lock on the old tuple's page. */
              LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);
              /* Re-check using the up-to-date free space */
!             pagefree = PageGetHeapFreeSpace((Page) dp);
              if (newtupsize > pagefree)
              {
                  /*
--- 2556,2562 ----
              /* Re-acquire the lock on the old tuple's page. */
              LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);
              /* Re-check using the up-to-date free space */
!             pagefree = PageGetHeapFreeSpace(page);
              if (newtupsize > pagefree)
              {
                  /*
***************
*** 2602,2608 ****
      else
      {
          /* Set a hint that the old page could use prune/defrag */
!         PageSetFull(dp);
      }

      /* NO EREPORT(ERROR) from here till changes are logged */
--- 2602,2608 ----
      else
      {
          /* Set a hint that the old page could use prune/defrag */
!         PageSetFull(page);
      }

      /* NO EREPORT(ERROR) from here till changes are logged */
***************
*** 2620,2626 ****
       * not to optimize for aborts.    Note that heap_xlog_update must be kept in
       * sync if this decision changes.
       */
!     PageSetPrunable(dp, xid);

      if (use_hot_update)
      {
--- 2620,2626 ----
       * not to optimize for aborts.    Note that heap_xlog_update must be kept in
       * sync if this decision changes.
       */
!     PageSetPrunable(page, xid);

      if (use_hot_update)
      {
***************
*** 2945,2951 ****
      HTSU_Result result;
      ItemPointer tid = &(tuple->t_self);
      ItemId        lp;
!     PageHeader    dp;
      TransactionId xid;
      TransactionId xmax;
      uint16        old_infomask;
--- 2945,2951 ----
      HTSU_Result result;
      ItemPointer tid = &(tuple->t_self);
      ItemId        lp;
!     Page        page;
      TransactionId xid;
      TransactionId xmax;
      uint16        old_infomask;
***************
*** 2958,2968 ****
      *buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));
      LockBuffer(*buffer, BUFFER_LOCK_EXCLUSIVE);

!     dp = (PageHeader) BufferGetPage(*buffer);
!     lp = PageGetItemId(dp, ItemPointerGetOffsetNumber(tid));
      Assert(ItemIdIsNormal(lp));

!     tuple->t_data = (HeapTupleHeader) PageGetItem((Page) dp, lp);
      tuple->t_len = ItemIdGetLength(lp);
      tuple->t_tableOid = RelationGetRelid(relation);

--- 2958,2968 ----
      *buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));
      LockBuffer(*buffer, BUFFER_LOCK_EXCLUSIVE);

!     page = BufferGetPage(*buffer);
!     lp = PageGetItemId(page, ItemPointerGetOffsetNumber(tid));
      Assert(ItemIdIsNormal(lp));

!     tuple->t_data = (HeapTupleHeader) PageGetItem(page, lp);
      tuple->t_len = ItemIdGetLength(lp);
      tuple->t_tableOid = RelationGetRelid(relation);

***************
*** 3301,3308 ****

          recptr = XLogInsert(RM_HEAP_ID, XLOG_HEAP_LOCK, rdata);

!         PageSetLSN(dp, recptr);
!         PageSetTLI(dp, ThisTimeLineID);
      }

      END_CRIT_SECTION();
--- 3301,3308 ----

          recptr = XLogInsert(RM_HEAP_ID, XLOG_HEAP_LOCK, rdata);

!         PageSetLSN(page, recptr);
!         PageSetTLI(page, ThisTimeLineID);
      }

      END_CRIT_SECTION();
diff -cr pgsql.orig.da8c485e0e2a/src/backend/access/heap/hio.c pgsql.orig/src/backend/access/heap/hio.c
*** pgsql.orig.da8c485e0e2a/src/backend/access/heap/hio.c    pá črc  4 14:04:20 2008
--- pgsql.orig/src/backend/access/heap/hio.c    pá črc  4 14:04:20 2008
***************
*** 107,113 ****
                            Buffer otherBuffer, bool use_fsm)
  {
      Buffer        buffer = InvalidBuffer;
!     Page        pageHeader;
      Size        pageFreeSpace,
                  saveFreeSpace;
      BlockNumber targetBlock,
--- 107,113 ----
                            Buffer otherBuffer, bool use_fsm)
  {
      Buffer        buffer = InvalidBuffer;
!     Page        page;
      Size        pageFreeSpace,
                  saveFreeSpace;
      BlockNumber targetBlock,
***************
*** 218,225 ****
           * Now we can check to see if there's enough free space here. If so,
           * we're done.
           */
!         pageHeader = (Page) BufferGetPage(buffer);
!         pageFreeSpace = PageGetHeapFreeSpace(pageHeader);
          if (len + saveFreeSpace <= pageFreeSpace)
          {
              /* use this page as future insert target, too */
--- 218,225 ----
           * Now we can check to see if there's enough free space here. If so,
           * we're done.
           */
!         page = BufferGetPage(buffer);
!         pageFreeSpace = PageGetHeapFreeSpace(page);
          if (len + saveFreeSpace <= pageFreeSpace)
          {
              /* use this page as future insert target, too */
***************
*** 303,318 ****
       * is empty (this should never happen, but if it does we don't want to
       * risk wiping out valid data).
       */
!     pageHeader = (Page) BufferGetPage(buffer);

!     if (!PageIsNew((PageHeader) pageHeader))
          elog(ERROR, "page %u of relation \"%s\" should be empty but is not",
               BufferGetBlockNumber(buffer),
               RelationGetRelationName(relation));

!     PageInit(pageHeader, BufferGetPageSize(buffer), 0);

!     if (len > PageGetHeapFreeSpace(pageHeader))
      {
          /* We should not get here given the test at the top */
          elog(PANIC, "tuple is too big: size %lu", (unsigned long) len);
--- 303,318 ----
       * is empty (this should never happen, but if it does we don't want to
       * risk wiping out valid data).
       */
!     page = BufferGetPage(buffer);

!     if (!PageIsNew(page))
          elog(ERROR, "page %u of relation \"%s\" should be empty but is not",
               BufferGetBlockNumber(buffer),
               RelationGetRelationName(relation));

!     PageInit(page, BufferGetPageSize(buffer), 0);

!     if (len > PageGetHeapFreeSpace(page))
      {
          /* We should not get here given the test at the top */
          elog(PANIC, "tuple is too big: size %lu", (unsigned long) len);
diff -cr pgsql.orig.da8c485e0e2a/src/backend/access/heap/pruneheap.c pgsql.orig/src/backend/access/heap/pruneheap.c
*** pgsql.orig.da8c485e0e2a/src/backend/access/heap/pruneheap.c    pá črc  4 14:04:20 2008
--- pgsql.orig/src/backend/access/heap/pruneheap.c    pá črc  4 14:04:20 2008
***************
*** 71,77 ****
  void
  heap_page_prune_opt(Relation relation, Buffer buffer, TransactionId OldestXmin)
  {
!     PageHeader    dp = (PageHeader) BufferGetPage(buffer);
      Size        minfree;

      /*
--- 71,77 ----
  void
  heap_page_prune_opt(Relation relation, Buffer buffer, TransactionId OldestXmin)
  {
!     Page        page = BufferGetPage(buffer);
      Size        minfree;

      /*
***************
*** 80,86 ****
       * Forget it if page is not hinted to contain something prunable that's
       * older than OldestXmin.
       */
!     if (!PageIsPrunable(dp, OldestXmin))
          return;

      /*
--- 80,86 ----
       * Forget it if page is not hinted to contain something prunable that's
       * older than OldestXmin.
       */
!     if (!PageIsPrunable(page, OldestXmin))
          return;

      /*
***************
*** 99,105 ****
                                               HEAP_DEFAULT_FILLFACTOR);
      minfree = Max(minfree, BLCKSZ / 10);

!     if (PageIsFull(dp) || PageGetHeapFreeSpace((Page) dp) < minfree)
      {
          /* OK, try to get exclusive buffer lock */
          if (!ConditionalLockBufferForCleanup(buffer))
--- 99,105 ----
                                               HEAP_DEFAULT_FILLFACTOR);
      minfree = Max(minfree, BLCKSZ / 10);

!     if (PageIsFull(page) || PageGetHeapFreeSpace(page) < minfree)
      {
          /* OK, try to get exclusive buffer lock */
          if (!ConditionalLockBufferForCleanup(buffer))
***************
*** 111,117 ****
           * prune. (We needn't recheck PageIsPrunable, since no one else could
           * have pruned while we hold pin.)
           */
!         if (PageIsFull(dp) || PageGetHeapFreeSpace((Page) dp) < minfree)
          {
              /* OK to prune (though not to remove redirects) */
              (void) heap_page_prune(relation, buffer, OldestXmin, false, true);
--- 111,117 ----
           * prune. (We needn't recheck PageIsPrunable, since no one else could
           * have pruned while we hold pin.)
           */
!         if (PageIsFull(page) || PageGetHeapFreeSpace(page) < minfree)
          {
              /* OK to prune (though not to remove redirects) */
              (void) heap_page_prune(relation, buffer, OldestXmin, false, true);
diff -cr pgsql.orig.da8c485e0e2a/src/backend/access/nbtree/nbtpage.c pgsql.orig/src/backend/access/nbtree/nbtpage.c
*** pgsql.orig.da8c485e0e2a/src/backend/access/nbtree/nbtpage.c    pá črc  4 14:04:20 2008
--- pgsql.orig/src/backend/access/nbtree/nbtpage.c    pá črc  4 14:04:20 2008
***************
*** 436,448 ****
      /*
       * Additionally check that the special area looks sane.
       */
!     if (((PageHeader) (page))->pd_special !=
!         (BLCKSZ - MAXALIGN(sizeof(BTPageOpaqueData))))
          ereport(ERROR,
                  (errcode(ERRCODE_INDEX_CORRUPTED),
                   errmsg("index \"%s\" contains corrupted page at block %u",
                          RelationGetRelationName(rel),
!                         BufferGetBlockNumber(buf)),
                   errhint("Please REINDEX it.")));
  }

--- 436,447 ----
      /*
       * Additionally check that the special area looks sane.
       */
!     if ( (PageGetSpecialSize(page)) != MAXALIGN(sizeof(BTPageOpaqueData)))
          ereport(ERROR,
                  (errcode(ERRCODE_INDEX_CORRUPTED),
                   errmsg("index \"%s\" contains corrupted page at block %u",
                          RelationGetRelationName(rel),
!                         BufferGetBlockNumber(buf)),
                   errhint("Please REINDEX it.")));
  }

***************
*** 555,561 ****

          /* Initialize the new page before returning it */
          page = BufferGetPage(buf);
!         Assert(PageIsNew((PageHeader) page));
          _bt_pageinit(page, BufferGetPageSize(buf));
      }

--- 554,560 ----

          /* Initialize the new page before returning it */
          page = BufferGetPage(buf);
!         Assert(PageIsNew(page));
          _bt_pageinit(page, BufferGetPageSize(buf));
      }

diff -cr pgsql.orig.da8c485e0e2a/src/backend/access/transam/xlog.c pgsql.orig/src/backend/access/transam/xlog.c
*** pgsql.orig.da8c485e0e2a/src/backend/access/transam/xlog.c    pá črc  4 14:04:20 2008
--- pgsql.orig/src/backend/access/transam/xlog.c    pá črc  4 14:04:20 2008
***************
*** 1017,1025 ****
  XLogCheckBuffer(XLogRecData *rdata, bool doPageWrites,
                  XLogRecPtr *lsn, BkpBlock *bkpb)
  {
!     PageHeader    page;

!     page = (PageHeader) BufferGetBlock(rdata->buffer);

      /*
       * XXX We assume page LSN is first data on *every* page that can be passed
--- 1017,1025 ----
  XLogCheckBuffer(XLogRecData *rdata, bool doPageWrites,
                  XLogRecPtr *lsn, BkpBlock *bkpb)
  {
!     Page    page;

!     page = BufferGetBlock(rdata->buffer);

      /*
       * XXX We assume page LSN is first data on *every* page that can be passed
***************
*** 1026,1035 ****
       * to XLogInsert, whether it otherwise has the standard page layout or
       * not.
       */
!     *lsn = page->pd_lsn;

      if (doPageWrites &&
!         XLByteLE(page->pd_lsn, RedoRecPtr))
      {
          /*
           * The page needs to be backed up, so set up *bkpb
--- 1026,1035 ----
       * to XLogInsert, whether it otherwise has the standard page layout or
       * not.
       */
!     *lsn = PageGetLSN(page);

      if (doPageWrites &&
!         XLByteLE(PageGetLSN(page), RedoRecPtr))
      {
          /*
           * The page needs to be backed up, so set up *bkpb
diff -cr pgsql.orig.da8c485e0e2a/src/backend/access/transam/xlogutils.c
pgsql.orig/src/backend/access/transam/xlogutils.c
*** pgsql.orig.da8c485e0e2a/src/backend/access/transam/xlogutils.c    pá črc  4 14:04:20 2008
--- pgsql.orig/src/backend/access/transam/xlogutils.c    pá črc  4 14:04:20 2008
***************
*** 262,268 ****
          /* check that page has been initialized */
          Page        page = (Page) BufferGetPage(buffer);

!         if (PageIsNew((PageHeader) page))
          {
              UnlockReleaseBuffer(buffer);
              log_invalid_page(reln->rd_node, blkno, true);
--- 262,268 ----
          /* check that page has been initialized */
          Page        page = (Page) BufferGetPage(buffer);

!         if (PageIsNew(page))
          {
              UnlockReleaseBuffer(buffer);
              log_invalid_page(reln->rd_node, blkno, true);
diff -cr pgsql.orig.da8c485e0e2a/src/backend/commands/sequence.c pgsql.orig/src/backend/commands/sequence.c
*** pgsql.orig.da8c485e0e2a/src/backend/commands/sequence.c    pá črc  4 14:04:20 2008
--- pgsql.orig/src/backend/commands/sequence.c    pá črc  4 14:04:20 2008
***************
*** 109,115 ****
      Oid            seqoid;
      Relation    rel;
      Buffer        buf;
!     PageHeader    page;
      sequence_magic *sm;
      HeapTuple    tuple;
      TupleDesc    tupDesc;
--- 109,115 ----
      Oid            seqoid;
      Relation    rel;
      Buffer        buf;
!     Page        page;
      sequence_magic *sm;
      HeapTuple    tuple;
      TupleDesc    tupDesc;
***************
*** 212,220 ****
      buf = ReadBuffer(rel, P_NEW);
      Assert(BufferGetBlockNumber(buf) == 0);

!     page = (PageHeader) BufferGetPage(buf);

!     PageInit((Page) page, BufferGetPageSize(buf), sizeof(sequence_magic));
      sm = (sequence_magic *) PageGetSpecialPointer(page);
      sm->magic = SEQ_MAGIC;

--- 212,220 ----
      buf = ReadBuffer(rel, P_NEW);
      Assert(BufferGetBlockNumber(buf) == 0);

!     page = BufferGetPage(buf);

!     PageInit(page, BufferGetPageSize(buf), sizeof(sequence_magic));
      sm = (sequence_magic *) PageGetSpecialPointer(page);
      sm->magic = SEQ_MAGIC;

***************
*** 954,960 ****
  static Form_pg_sequence
  read_info(SeqTable elm, Relation rel, Buffer *buf)
  {
!     PageHeader    page;
      ItemId        lp;
      HeapTupleData tuple;
      sequence_magic *sm;
--- 954,960 ----
  static Form_pg_sequence
  read_info(SeqTable elm, Relation rel, Buffer *buf)
  {
!     Page    page;
      ItemId        lp;
      HeapTupleData tuple;
      sequence_magic *sm;
***************
*** 963,969 ****
      *buf = ReadBuffer(rel, 0);
      LockBuffer(*buf, BUFFER_LOCK_EXCLUSIVE);

!     page = (PageHeader) BufferGetPage(*buf);
      sm = (sequence_magic *) PageGetSpecialPointer(page);

      if (sm->magic != SEQ_MAGIC)
--- 963,969 ----
      *buf = ReadBuffer(rel, 0);
      LockBuffer(*buf, BUFFER_LOCK_EXCLUSIVE);

!     page = BufferGetPage(*buf);
      sm = (sequence_magic *) PageGetSpecialPointer(page);

      if (sm->magic != SEQ_MAGIC)
***************
*** 972,978 ****

      lp = PageGetItemId(page, FirstOffsetNumber);
      Assert(ItemIdIsNormal(lp));
!     tuple.t_data = (HeapTupleHeader) PageGetItem((Page) page, lp);

      seq = (Form_pg_sequence) GETSTRUCT(&tuple);

--- 972,978 ----

      lp = PageGetItemId(page, FirstOffsetNumber);
      Assert(ItemIdIsNormal(lp));
!     tuple.t_data = (HeapTupleHeader) PageGetItem(page, lp);

      seq = (Form_pg_sequence) GETSTRUCT(&tuple);

diff -cr pgsql.orig.da8c485e0e2a/src/backend/commands/trigger.c pgsql.orig/src/backend/commands/trigger.c
*** pgsql.orig.da8c485e0e2a/src/backend/commands/trigger.c    pá črc  4 14:04:20 2008
--- pgsql.orig/src/backend/commands/trigger.c    pá črc  4 14:04:20 2008
***************
*** 2203,2219 ****
      }
      else
      {
!         PageHeader    dp;
          ItemId        lp;

          buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));

!         dp = (PageHeader) BufferGetPage(buffer);
!         lp = PageGetItemId(dp, ItemPointerGetOffsetNumber(tid));

          Assert(ItemIdIsNormal(lp));

!         tuple.t_data = (HeapTupleHeader) PageGetItem((Page) dp, lp);
          tuple.t_len = ItemIdGetLength(lp);
          tuple.t_self = *tid;
          tuple.t_tableOid = RelationGetRelid(relation);
--- 2203,2219 ----
      }
      else
      {
!         Page        page;
          ItemId        lp;

          buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));

!         page = BufferGetPage(buffer);
!         lp = PageGetItemId(page, ItemPointerGetOffsetNumber(tid));

          Assert(ItemIdIsNormal(lp));

!         tuple.t_data = (HeapTupleHeader) PageGetItem(page, lp);
          tuple.t_len = ItemIdGetLength(lp);
          tuple.t_self = *tid;
          tuple.t_tableOid = RelationGetRelid(relation);
diff -cr pgsql.orig.da8c485e0e2a/src/backend/optimizer/util/plancat.c pgsql.orig/src/backend/optimizer/util/plancat.c
*** pgsql.orig.da8c485e0e2a/src/backend/optimizer/util/plancat.c    pá črc  4 14:04:20 2008
--- pgsql.orig/src/backend/optimizer/util/plancat.c    pá črc  4 14:04:20 2008
***************
*** 429,435 ****
                  tuple_width += sizeof(HeapTupleHeaderData);
                  tuple_width += sizeof(ItemPointerData);
                  /* note: integer division is intentional here */
!                 density = (BLCKSZ - sizeof(PageHeaderData)) / tuple_width;
              }
              *tuples = rint(density * (double) curpages);
              break;
--- 429,435 ----
                  tuple_width += sizeof(HeapTupleHeaderData);
                  tuple_width += sizeof(ItemPointerData);
                  /* note: integer division is intentional here */
!                 density = (BLCKSZ - SizeOfPageHeaderData) / tuple_width;
              }
              *tuples = rint(density * (double) curpages);
              break;
diff -cr pgsql.orig.da8c485e0e2a/src/backend/storage/buffer/bufmgr.c pgsql.orig/src/backend/storage/buffer/bufmgr.c
*** pgsql.orig.da8c485e0e2a/src/backend/storage/buffer/bufmgr.c    pá črc  4 14:04:20 2008
--- pgsql.orig/src/backend/storage/buffer/bufmgr.c    pá črc  4 14:04:20 2008
***************
*** 223,229 ****
           * always have left a zero-filled buffer, complain if not PageIsNew.
           */
          bufBlock = isLocalBuf ? LocalBufHdrGetBlock(bufHdr) : BufHdrGetBlock(bufHdr);
!         if (!PageIsNew((PageHeader) bufBlock))
              ereport(ERROR,
                      (errmsg("unexpected data beyond EOF in block %u of relation \"%s\"",
                              blockNum, RelationGetRelationName(reln)),
--- 223,229 ----
           * always have left a zero-filled buffer, complain if not PageIsNew.
           */
          bufBlock = isLocalBuf ? LocalBufHdrGetBlock(bufHdr) : BufHdrGetBlock(bufHdr);
!         if (!PageIsNew((Page) bufBlock))
              ereport(ERROR,
                      (errmsg("unexpected data beyond EOF in block %u of relation \"%s\"",
                              blockNum, RelationGetRelationName(reln)),
***************
*** 292,298 ****
          else
              smgrread(reln->rd_smgr, blockNum, (char *) bufBlock);
          /* check for garbage data */
!         if (!PageHeaderIsValid((PageHeader) bufBlock))
          {
              if (zero_damaged_pages)
              {
--- 292,298 ----
          else
              smgrread(reln->rd_smgr, blockNum, (char *) bufBlock);
          /* check for garbage data */
!         if (!PageHeaderIsValid((Page) bufBlock))
          {
              if (zero_damaged_pages)
              {
diff -cr pgsql.orig.da8c485e0e2a/src/include/access/hash.h pgsql.orig/src/include/access/hash.h
*** pgsql.orig.da8c485e0e2a/src/include/access/hash.h    pá črc  4 14:04:20 2008
--- pgsql.orig/src/include/access/hash.h    pá črc  4 14:04:20 2008
***************
*** 165,174 ****
   * Maximum size of a hash index item (it's okay to have only one per page)
   */
  #define HashMaxItemSize(page) \
!     (PageGetPageSize(page) - \
!      sizeof(PageHeaderData) - \
!      MAXALIGN(sizeof(HashPageOpaqueData)) - \
!      sizeof(ItemIdData))

  #define HASH_MIN_FILLFACTOR            10
  #define HASH_DEFAULT_FILLFACTOR        75
--- 165,173 ----
   * Maximum size of a hash index item (it's okay to have only one per page)
   */
  #define HashMaxItemSize(page) \
!     MAXALIGN_DOWN(PageGetPageSize(page) - \
!       ( SizeOfPageHeaderData + sizeof(ItemIdData) ) - \
!        MAXALIGN(sizeof(HashPageOpaqueData)) )

  #define HASH_MIN_FILLFACTOR            10
  #define HASH_DEFAULT_FILLFACTOR        75
***************
*** 191,197 ****
  #define BMPG_SHIFT(metap)        ((metap)->hashm_bmshift)
  #define BMPG_MASK(metap)        (BMPGSZ_BIT(metap) - 1)
  #define HashPageGetBitmap(pg) \
!     ((uint32 *) (((char *) (pg)) + MAXALIGN(sizeof(PageHeaderData))))

  /*
   * The number of bits in an ovflpage bitmap word.
--- 190,196 ----
  #define BMPG_SHIFT(metap)        ((metap)->hashm_bmshift)
  #define BMPG_MASK(metap)        (BMPGSZ_BIT(metap) - 1)
  #define HashPageGetBitmap(pg) \
!     ((uint32 *) (((char *) (pg)) + MAXALIGN(SizeOfPageHeaderData + sizeof(ItemIdData))))

  /*
   * The number of bits in an ovflpage bitmap word.
diff -cr pgsql.orig.da8c485e0e2a/src/include/access/htup.h pgsql.orig/src/include/access/htup.h
*** pgsql.orig.da8c485e0e2a/src/include/access/htup.h    pá črc  4 14:04:20 2008
--- pgsql.orig/src/include/access/htup.h    pá črc  4 14:04:20 2008
***************
*** 367,373 ****
   * of assuming that, say, you can fit 2 tuples of size MaxHeapTupleSize/2
   * on the same page.
   */
! #define MaxHeapTupleSize  (BLCKSZ - MAXALIGN(sizeof(PageHeaderData)))

  /*
   * MaxHeapTuplesPerPage is an upper bound on the number of tuples that can
--- 367,373 ----
   * of assuming that, say, you can fit 2 tuples of size MaxHeapTupleSize/2
   * on the same page.
   */
! #define MaxHeapTupleSize  (BLCKSZ - MAXALIGN( (SizeOfPageHeaderData) + sizeof(ItemIdData)))

  /*
   * MaxHeapTuplesPerPage is an upper bound on the number of tuples that can
***************
*** 381,387 ****
   * require increases in the size of work arrays.
   */
  #define MaxHeapTuplesPerPage    \
!     ((int) ((BLCKSZ - offsetof(PageHeaderData, pd_linp)) / \
              (MAXALIGN(offsetof(HeapTupleHeaderData, t_bits)) + sizeof(ItemIdData))))

  /*
--- 381,387 ----
   * require increases in the size of work arrays.
   */
  #define MaxHeapTuplesPerPage    \
!     ((int) ((BLCKSZ - SizeOfPageHeaderData) / \
              (MAXALIGN(offsetof(HeapTupleHeaderData, t_bits)) + sizeof(ItemIdData))))

  /*
diff -cr pgsql.orig.da8c485e0e2a/src/include/access/itup.h pgsql.orig/src/include/access/itup.h
*** pgsql.orig.da8c485e0e2a/src/include/access/itup.h    pá črc  4 14:04:20 2008
--- pgsql.orig/src/include/access/itup.h    pá črc  4 14:04:20 2008
***************
*** 134,140 ****
   * must be maxaligned, and it must have an associated item pointer.
   */
  #define MaxIndexTuplesPerPage    \
!     ((int) ((BLCKSZ - offsetof(PageHeaderData, pd_linp)) / \
              (MAXALIGN(sizeof(IndexTupleData) + 1) + sizeof(ItemIdData))))


--- 134,140 ----
   * must be maxaligned, and it must have an associated item pointer.
   */
  #define MaxIndexTuplesPerPage    \
!     ((int) ((BLCKSZ - SizeOfPageHeaderData) / \
              (MAXALIGN(sizeof(IndexTupleData) + 1) + sizeof(ItemIdData))))


diff -cr pgsql.orig.da8c485e0e2a/src/include/access/nbtree.h pgsql.orig/src/include/access/nbtree.h
*** pgsql.orig.da8c485e0e2a/src/include/access/nbtree.h    pá črc  4 14:04:20 2008
--- pgsql.orig/src/include/access/nbtree.h    pá črc  4 14:04:20 2008
***************
*** 119,125 ****
   */
  #define BTMaxItemSize(page) \
      MAXALIGN_DOWN((PageGetPageSize(page) - \
!                    MAXALIGN(sizeof(PageHeaderData) + 2*sizeof(ItemIdData)) - \
                     MAXALIGN(sizeof(BTPageOpaqueData))) / 3)

  /*
--- 119,125 ----
   */
  #define BTMaxItemSize(page) \
      MAXALIGN_DOWN((PageGetPageSize(page) - \
!                    MAXALIGN(SizeOfPageHeaderData + 3*sizeof(ItemIdData)) - \
                     MAXALIGN(sizeof(BTPageOpaqueData))) / 3)

  /*
diff -cr pgsql.orig.da8c485e0e2a/src/include/access/tuptoaster.h pgsql.orig/src/include/access/tuptoaster.h
*** pgsql.orig.da8c485e0e2a/src/include/access/tuptoaster.h    pá črc  4 14:04:20 2008
--- pgsql.orig/src/include/access/tuptoaster.h    pá črc  4 14:04:20 2008
***************
*** 49,55 ****
  /* Note: sizeof(PageHeaderData) includes the first ItemId on the page */
  #define TOAST_TUPLE_THRESHOLD    \
      MAXALIGN_DOWN((BLCKSZ - \
!                    MAXALIGN(sizeof(PageHeaderData) + (TOAST_TUPLES_PER_PAGE-1) * sizeof(ItemIdData))) \
                    / TOAST_TUPLES_PER_PAGE)

  #define TOAST_TUPLE_TARGET        TOAST_TUPLE_THRESHOLD
--- 49,55 ----
  /* Note: sizeof(PageHeaderData) includes the first ItemId on the page */
  #define TOAST_TUPLE_THRESHOLD    \
      MAXALIGN_DOWN((BLCKSZ - \
!                    MAXALIGN(SizeOfPageHeaderData + (TOAST_TUPLES_PER_PAGE) * sizeof(ItemIdData))) \
                    / TOAST_TUPLES_PER_PAGE)

  #define TOAST_TUPLE_TARGET        TOAST_TUPLE_THRESHOLD
***************
*** 76,82 ****
  /* Note: sizeof(PageHeaderData) includes the first ItemId on the page */
  #define EXTERN_TUPLE_MAX_SIZE    \
      MAXALIGN_DOWN((BLCKSZ - \
!                    MAXALIGN(sizeof(PageHeaderData) + (EXTERN_TUPLES_PER_PAGE-1) * sizeof(ItemIdData))) \
                    / EXTERN_TUPLES_PER_PAGE)

  #define TOAST_MAX_CHUNK_SIZE    \
--- 76,82 ----
  /* Note: sizeof(PageHeaderData) includes the first ItemId on the page */
  #define EXTERN_TUPLE_MAX_SIZE    \
      MAXALIGN_DOWN((BLCKSZ - \
!                    MAXALIGN(SizeOfPageHeaderData + (EXTERN_TUPLES_PER_PAGE) * sizeof(ItemIdData))) \
                    / EXTERN_TUPLES_PER_PAGE)

  #define TOAST_MAX_CHUNK_SIZE    \

Re: page macros cleanup (ver 04)

От
Zdenek Kotala
Дата:
Pavan, Heikki,

Is it OK now or do you have any comments?

    Thanks Zdenek

Zdenek Kotala napsal(a):
> Pavan Deolasee napsal(a):
>> On Fri, Jul 4, 2008 at 4:25 PM, Heikki Linnakangas
>> <heikki@enterprisedb.com> wrote:
>>>
>>> No, there's a itemsz = MAXALIGN(itemsz) call before the check against
>>> HashMaxItemSize.
>>>
>>
>> Ah, right. Still should we just not MAXALIGN_DOWN the Max size to
>> reflect the practical limit on the itemsz ? It's more academical
>> though, so not a big deal.
>
> Finally I use following formula:
>
> #define HashMaxItemSize(page) \
>      MAXALIGN_DOWN(PageGetPageSize(page) - \
>        ( SizeOfPageHeaderData + sizeof(ItemIdData) ) - \
>         MAXALIGN(sizeof(HashPageOpaqueData)) )
>
>
> I did not replace PageGetPageSize(page), because other *MaxItemSize has
> same interface.
>
> Revised patch is attached.
>
>         Zdenek
>
>
> ------------------------------------------------------------------------
>
>

Re: page macros cleanup (ver 04)

От
"Heikki Linnakangas"
Дата:
Zdenek Kotala wrote:
> Pavan Deolasee napsal(a):
>> On Fri, Jul 4, 2008 at 4:25 PM, Heikki Linnakangas
>> <heikki@enterprisedb.com> wrote:
>>>
>>> No, there's a itemsz = MAXALIGN(itemsz) call before the check against
>>> HashMaxItemSize.
>>>
>>
>> Ah, right. Still should we just not MAXALIGN_DOWN the Max size to
>> reflect the practical limit on the itemsz ? It's more academical
>> though, so not a big deal.
>
> Finally I use following formula:
>
> #define HashMaxItemSize(page) \
>      MAXALIGN_DOWN(PageGetPageSize(page) - \
>        ( SizeOfPageHeaderData + sizeof(ItemIdData) ) - \
>         MAXALIGN(sizeof(HashPageOpaqueData)) )
>
>
> I did not replace PageGetPageSize(page), because other *MaxItemSize has
> same interface.

Ok, fair enough.

There's another academical discrepancy between these two hunks:

> *** src/backend/access/hash/hashpage.c  12 May 2008 00:00:44 -0000      1.75
> --- src/backend/access/hash/hashpage.c  9 Jul 2008 11:30:09 -0000
> ***************
> *** 407,413 ****
>         for (i = _hash_log2(metap->hashm_bsize); i > 0; --i)
>         {
>                 if ((1 << i) <= (metap->hashm_bsize -
> !                                                (MAXALIGN(sizeof(PageHeaderData)) +
>                                                   MAXALIGN(sizeof(HashPageOpaqueData)))))
>                         break;
>         }
> --- 407,413 ----
>         for (i = _hash_log2(metap->hashm_bsize); i > 0; --i)
>         {
>                 if ((1 << i) <= (metap->hashm_bsize -
> !                                                (MAXALIGN(SizeOfPageHeaderData) +
>                                                   MAXALIGN(sizeof(HashPageOpaqueData)))))
>                         break;
>         }

and

> *** src/include/access/hash.h   19 Jun 2008 00:46:05 -0000      1.88
> --- src/include/access/hash.h   9 Jul 2008 11:30:10 -0000
> ***************
> *** 192,198 ****
>   #define BMPG_SHIFT(metap)             ((metap)->hashm_bmshift)
>   #define BMPG_MASK(metap)              (BMPGSZ_BIT(metap) - 1)
>   #define HashPageGetBitmap(pg) \
> !       ((uint32 *) (((char *) (pg)) + MAXALIGN(sizeof(PageHeaderData))))
>
>   /*
>    * The number of bits in an ovflpage bitmap word.
> --- 191,197 ----
>   #define BMPG_SHIFT(metap)             ((metap)->hashm_bmshift)
>   #define BMPG_MASK(metap)              (BMPGSZ_BIT(metap) - 1)
>   #define HashPageGetBitmap(pg) \
> !       ((uint32 *) (((char *) (pg)) + MAXALIGN(SizeOfPageHeaderData + sizeof(ItemIdData))))
>
>   /*
>    * The number of bits in an ovflpage bitmap word.

I admit I don't understand what that bitmap is, it looks like we're
assuming it can take up all the space between page header and the
special portion, without any line pointers, but in HashPageGetBitmap,
we're reserving space for one pointer. It looks like the actual size of
the bitmap is only the largest power of 2 below the maximum size, so
that won't be an issue in practice. That macro is actually doing the
same thing as PageGetContents, so I switched to using that. As that
moves the data sligthly on those bitmap pages, I guess we'll need a
catversion bump.

Attached is an updated patch. I also fixed some whitespace and comments
that were no longer valid. How does it look to you now?

--
   Heikki Linnakangas
   EnterpriseDB   http://www.enterprisedb.com
? DEADJOE
? GNUmakefile
? buildlog
? config.log
? config.status
? page_04-heikki-1.patch
? contrib/pg_standby/.deps
? contrib/pg_standby/pg_standby
? contrib/spi/.deps
? doc/src/sgml/cvsmsg
? src/Makefile.global
? src/backend/postgres
? src/backend/access/common/.deps
? src/backend/access/gin/.deps
? src/backend/access/gist/.deps
? src/backend/access/hash/.deps
? src/backend/access/heap/.deps
? src/backend/access/index/.deps
? src/backend/access/nbtree/.deps
? src/backend/access/transam/.deps
? src/backend/bootstrap/.deps
? src/backend/catalog/.deps
? src/backend/catalog/postgres.bki
? src/backend/catalog/postgres.description
? src/backend/catalog/postgres.shdescription
? src/backend/commands/.deps
? src/backend/executor/.deps
? src/backend/lib/.deps
? src/backend/libpq/.deps
? src/backend/main/.deps
? src/backend/nodes/.deps
? src/backend/optimizer/geqo/.deps
? src/backend/optimizer/path/.deps
? src/backend/optimizer/plan/.deps
? src/backend/optimizer/prep/.deps
? src/backend/optimizer/util/.deps
? src/backend/parser/.deps
? src/backend/port/.deps
? src/backend/postmaster/.deps
? src/backend/regex/.deps
? src/backend/rewrite/.deps
? src/backend/snowball/.deps
? src/backend/snowball/snowball_create.sql
? src/backend/storage/buffer/.deps
? src/backend/storage/file/.deps
? src/backend/storage/freespace/.deps
? src/backend/storage/ipc/.deps
? src/backend/storage/large_object/.deps
? src/backend/storage/lmgr/.deps
? src/backend/storage/page/.deps
? src/backend/storage/smgr/.deps
? src/backend/tcop/.deps
? src/backend/tsearch/.deps
? src/backend/utils/.deps
? src/backend/utils/probes.h
? src/backend/utils/adt/.deps
? src/backend/utils/cache/.deps
? src/backend/utils/error/.deps
? src/backend/utils/fmgr/.deps
? src/backend/utils/hash/.deps
? src/backend/utils/init/.deps
? src/backend/utils/mb/.deps
? src/backend/utils/mb/conversion_procs/conversion_create.sql
? src/backend/utils/mb/conversion_procs/ascii_and_mic/.deps
? src/backend/utils/mb/conversion_procs/cyrillic_and_mic/.deps
? src/backend/utils/mb/conversion_procs/euc_cn_and_mic/.deps
? src/backend/utils/mb/conversion_procs/euc_jis_2004_and_shift_jis_2004/.deps
? src/backend/utils/mb/conversion_procs/euc_jp_and_sjis/.deps
? src/backend/utils/mb/conversion_procs/euc_kr_and_mic/.deps
? src/backend/utils/mb/conversion_procs/euc_tw_and_big5/.deps
? src/backend/utils/mb/conversion_procs/latin2_and_win1250/.deps
? src/backend/utils/mb/conversion_procs/latin_and_mic/.deps
? src/backend/utils/mb/conversion_procs/utf8_and_ascii/.deps
? src/backend/utils/mb/conversion_procs/utf8_and_big5/.deps
? src/backend/utils/mb/conversion_procs/utf8_and_cyrillic/.deps
? src/backend/utils/mb/conversion_procs/utf8_and_euc_cn/.deps
? src/backend/utils/mb/conversion_procs/utf8_and_euc_jis_2004/.deps
? src/backend/utils/mb/conversion_procs/utf8_and_euc_jp/.deps
? src/backend/utils/mb/conversion_procs/utf8_and_euc_kr/.deps
? src/backend/utils/mb/conversion_procs/utf8_and_euc_tw/.deps
? src/backend/utils/mb/conversion_procs/utf8_and_gb18030/.deps
? src/backend/utils/mb/conversion_procs/utf8_and_gbk/.deps
? src/backend/utils/mb/conversion_procs/utf8_and_iso8859/.deps
? src/backend/utils/mb/conversion_procs/utf8_and_iso8859_1/.deps
? src/backend/utils/mb/conversion_procs/utf8_and_johab/.deps
? src/backend/utils/mb/conversion_procs/utf8_and_shift_jis_2004/.deps
? src/backend/utils/mb/conversion_procs/utf8_and_sjis/.deps
? src/backend/utils/mb/conversion_procs/utf8_and_uhc/.deps
? src/backend/utils/mb/conversion_procs/utf8_and_win/.deps
? src/backend/utils/misc/.deps
? src/backend/utils/mmgr/.deps
? src/backend/utils/resowner/.deps
? src/backend/utils/sort/.deps
? src/backend/utils/time/.deps
? src/bin/initdb/.deps
? src/bin/initdb/initdb
? src/bin/pg_config/.deps
? src/bin/pg_config/pg_config
? src/bin/pg_controldata/.deps
? src/bin/pg_controldata/pg_controldata
? src/bin/pg_ctl/.deps
? src/bin/pg_ctl/pg_ctl
? src/bin/pg_dump/.deps
? src/bin/pg_dump/pg_dump
? src/bin/pg_dump/pg_dumpall
? src/bin/pg_dump/pg_restore
? src/bin/pg_resetxlog/.deps
? src/bin/pg_resetxlog/pg_resetxlog
? src/bin/psql/.deps
? src/bin/psql/d.c
? src/bin/psql/psql
? src/bin/scripts/.deps
? src/bin/scripts/clusterdb
? src/bin/scripts/createdb
? src/bin/scripts/createlang
? src/bin/scripts/createuser
? src/bin/scripts/dropdb
? src/bin/scripts/droplang
? src/bin/scripts/dropuser
? src/bin/scripts/reindexdb
? src/bin/scripts/vacuumdb
? src/include/pg_config.h
? src/include/stamp-h
? src/interfaces/ecpg/compatlib/.deps
? src/interfaces/ecpg/compatlib/exports.list
? src/interfaces/ecpg/compatlib/libecpg_compat.so.3.1
? src/interfaces/ecpg/ecpglib/.deps
? src/interfaces/ecpg/ecpglib/exports.list
? src/interfaces/ecpg/ecpglib/libecpg.so.6.1
? src/interfaces/ecpg/include/ecpg_config.h
? src/interfaces/ecpg/pgtypeslib/.deps
? src/interfaces/ecpg/pgtypeslib/exports.list
? src/interfaces/ecpg/pgtypeslib/libpgtypes.so.3.1
? src/interfaces/ecpg/preproc/.deps
? src/interfaces/ecpg/preproc/ecpg
? src/interfaces/libpq/.deps
? src/interfaces/libpq/exports.list
? src/interfaces/libpq/libpq.so.5.2
? src/pl/plpgsql/src/.deps
? src/port/.deps
? src/port/pg_config_paths.h
? src/test/regress/.deps
? src/test/regress/log
? src/test/regress/pg_regress
? src/test/regress/results
? src/test/regress/testtablespace
? src/test/regress/expected/constraints.out
? src/test/regress/expected/copy.out
? src/test/regress/expected/create_function_1.out
? src/test/regress/expected/create_function_2.out
? src/test/regress/expected/largeobject.out
? src/test/regress/expected/largeobject_1.out
? src/test/regress/expected/misc.out
? src/test/regress/expected/tablespace.out
? src/test/regress/sql/constraints.sql
? src/test/regress/sql/copy.sql
? src/test/regress/sql/create_function_1.sql
? src/test/regress/sql/create_function_2.sql
? src/test/regress/sql/largeobject.sql
? src/test/regress/sql/misc.sql
? src/test/regress/sql/tablespace.sql
? src/timezone/.deps
? src/timezone/zic
Index: src/backend/access/gist/gistutil.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/access/gist/gistutil.c,v
retrieving revision 1.29
diff -c -r1.29 gistutil.c
*** src/backend/access/gist/gistutil.c    19 Jun 2008 00:46:03 -0000    1.29
--- src/backend/access/gist/gistutil.c    9 Jul 2008 11:49:34 -0000
***************
*** 591,598 ****
      /*
       * Additionally check that the special area looks sane.
       */
!     if (((PageHeader) (page))->pd_special !=
!         (BLCKSZ - MAXALIGN(sizeof(GISTPageOpaqueData))))
          ereport(ERROR,
                  (errcode(ERRCODE_INDEX_CORRUPTED),
                   errmsg("index \"%s\" contains corrupted page at block %u",
--- 591,597 ----
      /*
       * Additionally check that the special area looks sane.
       */
!     if (PageGetSpecialSize(page) != MAXALIGN(sizeof(GISTPageOpaqueData)))
          ereport(ERROR,
                  (errcode(ERRCODE_INDEX_CORRUPTED),
                   errmsg("index \"%s\" contains corrupted page at block %u",
Index: src/backend/access/hash/hashpage.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/access/hash/hashpage.c,v
retrieving revision 1.75
diff -c -r1.75 hashpage.c
*** src/backend/access/hash/hashpage.c    12 May 2008 00:00:44 -0000    1.75
--- src/backend/access/hash/hashpage.c    9 Jul 2008 11:49:34 -0000
***************
*** 407,413 ****
      for (i = _hash_log2(metap->hashm_bsize); i > 0; --i)
      {
          if ((1 << i) <= (metap->hashm_bsize -
!                          (MAXALIGN(sizeof(PageHeaderData)) +
                            MAXALIGN(sizeof(HashPageOpaqueData)))))
              break;
      }
--- 407,413 ----
      for (i = _hash_log2(metap->hashm_bsize); i > 0; --i)
      {
          if ((1 << i) <= (metap->hashm_bsize -
!                          (MAXALIGN(SizeOfPageHeaderData) +
                            MAXALIGN(sizeof(HashPageOpaqueData)))))
              break;
      }
Index: src/backend/access/hash/hashutil.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/access/hash/hashutil.c,v
retrieving revision 1.55
diff -c -r1.55 hashutil.c
*** src/backend/access/hash/hashutil.c    19 Jun 2008 00:46:03 -0000    1.55
--- src/backend/access/hash/hashutil.c    9 Jul 2008 11:49:34 -0000
***************
*** 164,171 ****
      /*
       * Additionally check that the special area looks sane.
       */
!     if (((PageHeader) (page))->pd_special !=
!         (BLCKSZ - MAXALIGN(sizeof(HashPageOpaqueData))))
          ereport(ERROR,
                  (errcode(ERRCODE_INDEX_CORRUPTED),
                   errmsg("index \"%s\" contains corrupted page at block %u",
--- 164,170 ----
      /*
       * Additionally check that the special area looks sane.
       */
!     if (PageGetSpecialSize(page) != MAXALIGN(sizeof(HashPageOpaqueData)))
          ereport(ERROR,
                  (errcode(ERRCODE_INDEX_CORRUPTED),
                   errmsg("index \"%s\" contains corrupted page at block %u",
Index: src/backend/access/heap/heapam.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v
retrieving revision 1.260
diff -c -r1.260 heapam.c
*** src/backend/access/heap/heapam.c    19 Jun 2008 00:46:03 -0000    1.260
--- src/backend/access/heap/heapam.c    9 Jul 2008 11:49:34 -0000
***************
*** 1343,1349 ****
      ItemPointer tid = &(tuple->t_self);
      ItemId        lp;
      Buffer        buffer;
!     PageHeader    dp;
      OffsetNumber offnum;
      bool        valid;

--- 1343,1349 ----
      ItemPointer tid = &(tuple->t_self);
      ItemId        lp;
      Buffer        buffer;
!     Page        page;
      OffsetNumber offnum;
      bool        valid;

***************
*** 1356,1369 ****
       * Need share lock on buffer to examine tuple commit status.
       */
      LockBuffer(buffer, BUFFER_LOCK_SHARE);
!     dp = (PageHeader) BufferGetPage(buffer);

      /*
       * We'd better check for out-of-range offnum in case of VACUUM since the
       * TID was obtained.
       */
      offnum = ItemPointerGetOffsetNumber(tid);
!     if (offnum < FirstOffsetNumber || offnum > PageGetMaxOffsetNumber(dp))
      {
          LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
          if (keep_buf)
--- 1356,1369 ----
       * Need share lock on buffer to examine tuple commit status.
       */
      LockBuffer(buffer, BUFFER_LOCK_SHARE);
!     page = BufferGetPage(buffer);

      /*
       * We'd better check for out-of-range offnum in case of VACUUM since the
       * TID was obtained.
       */
      offnum = ItemPointerGetOffsetNumber(tid);
!     if (offnum < FirstOffsetNumber || offnum > PageGetMaxOffsetNumber(page))
      {
          LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
          if (keep_buf)
***************
*** 1380,1386 ****
      /*
       * get the item line pointer corresponding to the requested tid
       */
!     lp = PageGetItemId(dp, offnum);

      /*
       * Must check for deleted tuple.
--- 1380,1386 ----
      /*
       * get the item line pointer corresponding to the requested tid
       */
!     lp = PageGetItemId(page, offnum);

      /*
       * Must check for deleted tuple.
***************
*** 1402,1408 ****
      /*
       * fill in *tuple fields
       */
!     tuple->t_data = (HeapTupleHeader) PageGetItem((Page) dp, lp);
      tuple->t_len = ItemIdGetLength(lp);
      tuple->t_tableOid = RelationGetRelid(relation);

--- 1402,1408 ----
      /*
       * fill in *tuple fields
       */
!     tuple->t_data = (HeapTupleHeader) PageGetItem(page, lp);
      tuple->t_len = ItemIdGetLength(lp);
      tuple->t_tableOid = RelationGetRelid(relation);

***************
*** 1627,1633 ****
      for (;;)
      {
          Buffer        buffer;
!         PageHeader    dp;
          OffsetNumber offnum;
          ItemId        lp;
          HeapTupleData tp;
--- 1627,1633 ----
      for (;;)
      {
          Buffer        buffer;
!         Page        page;
          OffsetNumber offnum;
          ItemId        lp;
          HeapTupleData tp;
***************
*** 1638,1644 ****
           */
          buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(&ctid));
          LockBuffer(buffer, BUFFER_LOCK_SHARE);
!         dp = (PageHeader) BufferGetPage(buffer);

          /*
           * Check for bogus item number.  This is not treated as an error
--- 1638,1644 ----
           */
          buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(&ctid));
          LockBuffer(buffer, BUFFER_LOCK_SHARE);
!         page = BufferGetPage(buffer);

          /*
           * Check for bogus item number.  This is not treated as an error
***************
*** 1646,1657 ****
           * just assume that the prior tid is OK and return it unchanged.
           */
          offnum = ItemPointerGetOffsetNumber(&ctid);
!         if (offnum < FirstOffsetNumber || offnum > PageGetMaxOffsetNumber(dp))
          {
              UnlockReleaseBuffer(buffer);
              break;
          }
!         lp = PageGetItemId(dp, offnum);
          if (!ItemIdIsNormal(lp))
          {
              UnlockReleaseBuffer(buffer);
--- 1646,1657 ----
           * just assume that the prior tid is OK and return it unchanged.
           */
          offnum = ItemPointerGetOffsetNumber(&ctid);
!         if (offnum < FirstOffsetNumber || offnum > PageGetMaxOffsetNumber(page))
          {
              UnlockReleaseBuffer(buffer);
              break;
          }
!         lp = PageGetItemId(page, offnum);
          if (!ItemIdIsNormal(lp))
          {
              UnlockReleaseBuffer(buffer);
***************
*** 1660,1666 ****

          /* OK to access the tuple */
          tp.t_self = ctid;
!         tp.t_data = (HeapTupleHeader) PageGetItem(dp, lp);
          tp.t_len = ItemIdGetLength(lp);

          /*
--- 1660,1666 ----

          /* OK to access the tuple */
          tp.t_self = ctid;
!         tp.t_data = (HeapTupleHeader) PageGetItem(page, lp);
          tp.t_len = ItemIdGetLength(lp);

          /*
***************
*** 1964,1970 ****
      TransactionId xid = GetCurrentTransactionId();
      ItemId        lp;
      HeapTupleData tp;
!     PageHeader    dp;
      Buffer        buffer;
      bool        have_tuple_lock = false;
      bool        iscombo;
--- 1964,1970 ----
      TransactionId xid = GetCurrentTransactionId();
      ItemId        lp;
      HeapTupleData tp;
!     Page        page;
      Buffer        buffer;
      bool        have_tuple_lock = false;
      bool        iscombo;
***************
*** 1974,1984 ****
      buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));
      LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);

!     dp = (PageHeader) BufferGetPage(buffer);
!     lp = PageGetItemId(dp, ItemPointerGetOffsetNumber(tid));
      Assert(ItemIdIsNormal(lp));

!     tp.t_data = (HeapTupleHeader) PageGetItem(dp, lp);
      tp.t_len = ItemIdGetLength(lp);
      tp.t_self = *tid;

--- 1974,1984 ----
      buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));
      LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);

!     page = BufferGetPage(buffer);
!     lp = PageGetItemId(page, ItemPointerGetOffsetNumber(tid));
      Assert(ItemIdIsNormal(lp));

!     tp.t_data = (HeapTupleHeader) PageGetItem(page, lp);
      tp.t_len = ItemIdGetLength(lp);
      tp.t_self = *tid;

***************
*** 2112,2118 ****
       * the subsequent page pruning will be a no-op and the hint will be
       * cleared.
       */
!     PageSetPrunable(dp, xid);

      /* store transaction information of xact deleting the tuple */
      tp.t_data->t_infomask &= ~(HEAP_XMAX_COMMITTED |
--- 2112,2118 ----
       * the subsequent page pruning will be a no-op and the hint will be
       * cleared.
       */
!     PageSetPrunable(page, xid);

      /* store transaction information of xact deleting the tuple */
      tp.t_data->t_infomask &= ~(HEAP_XMAX_COMMITTED |
***************
*** 2150,2157 ****

          recptr = XLogInsert(RM_HEAP_ID, XLOG_HEAP_DELETE, rdata);

!         PageSetLSN(dp, recptr);
!         PageSetTLI(dp, ThisTimeLineID);
      }

      END_CRIT_SECTION();
--- 2150,2157 ----

          recptr = XLogInsert(RM_HEAP_ID, XLOG_HEAP_DELETE, rdata);

!         PageSetLSN(page, recptr);
!         PageSetTLI(page, ThisTimeLineID);
      }

      END_CRIT_SECTION();
***************
*** 2276,2282 ****
      ItemId        lp;
      HeapTupleData oldtup;
      HeapTuple    heaptup;
!     PageHeader    dp;
      Buffer        buffer,
                  newbuf;
      bool        need_toast,
--- 2276,2282 ----
      ItemId        lp;
      HeapTupleData oldtup;
      HeapTuple    heaptup;
!     Page        page;
      Buffer        buffer,
                  newbuf;
      bool        need_toast,
***************
*** 2306,2316 ****
      buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(otid));
      LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);

!     dp = (PageHeader) BufferGetPage(buffer);
!     lp = PageGetItemId(dp, ItemPointerGetOffsetNumber(otid));
      Assert(ItemIdIsNormal(lp));

!     oldtup.t_data = (HeapTupleHeader) PageGetItem(dp, lp);
      oldtup.t_len = ItemIdGetLength(lp);
      oldtup.t_self = *otid;

--- 2306,2316 ----
      buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(otid));
      LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);

!     page = BufferGetPage(buffer);
!     lp = PageGetItemId(page, ItemPointerGetOffsetNumber(otid));
      Assert(ItemIdIsNormal(lp));

!     oldtup.t_data = (HeapTupleHeader) PageGetItem(page, lp);
      oldtup.t_len = ItemIdGetLength(lp);
      oldtup.t_self = *otid;

***************
*** 2491,2497 ****
                        HeapTupleHasExternal(newtup) ||
                        newtup->t_len > TOAST_TUPLE_THRESHOLD);

!     pagefree = PageGetHeapFreeSpace((Page) dp);

      newtupsize = MAXALIGN(newtup->t_len);

--- 2491,2497 ----
                        HeapTupleHasExternal(newtup) ||
                        newtup->t_len > TOAST_TUPLE_THRESHOLD);

!     pagefree = PageGetHeapFreeSpace(page);

      newtupsize = MAXALIGN(newtup->t_len);

***************
*** 2557,2563 ****
              /* Re-acquire the lock on the old tuple's page. */
              LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);
              /* Re-check using the up-to-date free space */
!             pagefree = PageGetHeapFreeSpace((Page) dp);
              if (newtupsize > pagefree)
              {
                  /*
--- 2557,2563 ----
              /* Re-acquire the lock on the old tuple's page. */
              LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);
              /* Re-check using the up-to-date free space */
!             pagefree = PageGetHeapFreeSpace(page);
              if (newtupsize > pagefree)
              {
                  /*
***************
*** 2603,2609 ****
      else
      {
          /* Set a hint that the old page could use prune/defrag */
!         PageSetFull(dp);
      }

      /* NO EREPORT(ERROR) from here till changes are logged */
--- 2603,2609 ----
      else
      {
          /* Set a hint that the old page could use prune/defrag */
!         PageSetFull(page);
      }

      /* NO EREPORT(ERROR) from here till changes are logged */
***************
*** 2621,2627 ****
       * not to optimize for aborts.    Note that heap_xlog_update must be kept in
       * sync if this decision changes.
       */
!     PageSetPrunable(dp, xid);

      if (use_hot_update)
      {
--- 2621,2627 ----
       * not to optimize for aborts.    Note that heap_xlog_update must be kept in
       * sync if this decision changes.
       */
!     PageSetPrunable(page, xid);

      if (use_hot_update)
      {
***************
*** 2946,2952 ****
      HTSU_Result result;
      ItemPointer tid = &(tuple->t_self);
      ItemId        lp;
!     PageHeader    dp;
      TransactionId xid;
      TransactionId xmax;
      uint16        old_infomask;
--- 2946,2952 ----
      HTSU_Result result;
      ItemPointer tid = &(tuple->t_self);
      ItemId        lp;
!     Page        page;
      TransactionId xid;
      TransactionId xmax;
      uint16        old_infomask;
***************
*** 2959,2969 ****
      *buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));
      LockBuffer(*buffer, BUFFER_LOCK_EXCLUSIVE);

!     dp = (PageHeader) BufferGetPage(*buffer);
!     lp = PageGetItemId(dp, ItemPointerGetOffsetNumber(tid));
      Assert(ItemIdIsNormal(lp));

!     tuple->t_data = (HeapTupleHeader) PageGetItem((Page) dp, lp);
      tuple->t_len = ItemIdGetLength(lp);
      tuple->t_tableOid = RelationGetRelid(relation);

--- 2959,2969 ----
      *buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));
      LockBuffer(*buffer, BUFFER_LOCK_EXCLUSIVE);

!     page = BufferGetPage(*buffer);
!     lp = PageGetItemId(page, ItemPointerGetOffsetNumber(tid));
      Assert(ItemIdIsNormal(lp));

!     tuple->t_data = (HeapTupleHeader) PageGetItem(page, lp);
      tuple->t_len = ItemIdGetLength(lp);
      tuple->t_tableOid = RelationGetRelid(relation);

***************
*** 3302,3309 ****

          recptr = XLogInsert(RM_HEAP_ID, XLOG_HEAP_LOCK, rdata);

!         PageSetLSN(dp, recptr);
!         PageSetTLI(dp, ThisTimeLineID);
      }

      END_CRIT_SECTION();
--- 3302,3309 ----

          recptr = XLogInsert(RM_HEAP_ID, XLOG_HEAP_LOCK, rdata);

!         PageSetLSN(page, recptr);
!         PageSetTLI(page, ThisTimeLineID);
      }

      END_CRIT_SECTION();
Index: src/backend/access/heap/hio.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/access/heap/hio.c,v
retrieving revision 1.71
diff -c -r1.71 hio.c
*** src/backend/access/heap/hio.c    8 Jun 2008 22:00:47 -0000    1.71
--- src/backend/access/heap/hio.c    9 Jul 2008 11:49:34 -0000
***************
*** 107,113 ****
                            Buffer otherBuffer, bool use_fsm)
  {
      Buffer        buffer = InvalidBuffer;
!     Page        pageHeader;
      Size        pageFreeSpace,
                  saveFreeSpace;
      BlockNumber targetBlock,
--- 107,113 ----
                            Buffer otherBuffer, bool use_fsm)
  {
      Buffer        buffer = InvalidBuffer;
!     Page        page;
      Size        pageFreeSpace,
                  saveFreeSpace;
      BlockNumber targetBlock,
***************
*** 218,225 ****
           * Now we can check to see if there's enough free space here. If so,
           * we're done.
           */
!         pageHeader = (Page) BufferGetPage(buffer);
!         pageFreeSpace = PageGetHeapFreeSpace(pageHeader);
          if (len + saveFreeSpace <= pageFreeSpace)
          {
              /* use this page as future insert target, too */
--- 218,225 ----
           * Now we can check to see if there's enough free space here. If so,
           * we're done.
           */
!         page = BufferGetPage(buffer);
!         pageFreeSpace = PageGetHeapFreeSpace(page);
          if (len + saveFreeSpace <= pageFreeSpace)
          {
              /* use this page as future insert target, too */
***************
*** 303,318 ****
       * is empty (this should never happen, but if it does we don't want to
       * risk wiping out valid data).
       */
!     pageHeader = (Page) BufferGetPage(buffer);

!     if (!PageIsNew((PageHeader) pageHeader))
          elog(ERROR, "page %u of relation \"%s\" should be empty but is not",
               BufferGetBlockNumber(buffer),
               RelationGetRelationName(relation));

!     PageInit(pageHeader, BufferGetPageSize(buffer), 0);

!     if (len > PageGetHeapFreeSpace(pageHeader))
      {
          /* We should not get here given the test at the top */
          elog(PANIC, "tuple is too big: size %lu", (unsigned long) len);
--- 303,318 ----
       * is empty (this should never happen, but if it does we don't want to
       * risk wiping out valid data).
       */
!     page = BufferGetPage(buffer);

!     if (!PageIsNew(page))
          elog(ERROR, "page %u of relation \"%s\" should be empty but is not",
               BufferGetBlockNumber(buffer),
               RelationGetRelationName(relation));

!     PageInit(page, BufferGetPageSize(buffer), 0);

!     if (len > PageGetHeapFreeSpace(page))
      {
          /* We should not get here given the test at the top */
          elog(PANIC, "tuple is too big: size %lu", (unsigned long) len);
Index: src/backend/access/heap/pruneheap.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/access/heap/pruneheap.c,v
retrieving revision 1.15
diff -c -r1.15 pruneheap.c
*** src/backend/access/heap/pruneheap.c    19 Jun 2008 00:46:03 -0000    1.15
--- src/backend/access/heap/pruneheap.c    9 Jul 2008 11:49:34 -0000
***************
*** 72,78 ****
  void
  heap_page_prune_opt(Relation relation, Buffer buffer, TransactionId OldestXmin)
  {
!     PageHeader    dp = (PageHeader) BufferGetPage(buffer);
      Size        minfree;

      /*
--- 72,78 ----
  void
  heap_page_prune_opt(Relation relation, Buffer buffer, TransactionId OldestXmin)
  {
!     Page        page = BufferGetPage(buffer);
      Size        minfree;

      /*
***************
*** 81,87 ****
       * Forget it if page is not hinted to contain something prunable that's
       * older than OldestXmin.
       */
!     if (!PageIsPrunable(dp, OldestXmin))
          return;

      /*
--- 81,87 ----
       * Forget it if page is not hinted to contain something prunable that's
       * older than OldestXmin.
       */
!     if (!PageIsPrunable(page, OldestXmin))
          return;

      /*
***************
*** 100,106 ****
                                               HEAP_DEFAULT_FILLFACTOR);
      minfree = Max(minfree, BLCKSZ / 10);

!     if (PageIsFull(dp) || PageGetHeapFreeSpace((Page) dp) < minfree)
      {
          /* OK, try to get exclusive buffer lock */
          if (!ConditionalLockBufferForCleanup(buffer))
--- 100,106 ----
                                               HEAP_DEFAULT_FILLFACTOR);
      minfree = Max(minfree, BLCKSZ / 10);

!     if (PageIsFull(page) || PageGetHeapFreeSpace(page) < minfree)
      {
          /* OK, try to get exclusive buffer lock */
          if (!ConditionalLockBufferForCleanup(buffer))
***************
*** 112,118 ****
           * prune. (We needn't recheck PageIsPrunable, since no one else could
           * have pruned while we hold pin.)
           */
!         if (PageIsFull(dp) || PageGetHeapFreeSpace((Page) dp) < minfree)
          {
              /* OK to prune (though not to remove redirects) */
              (void) heap_page_prune(relation, buffer, OldestXmin, false, true);
--- 112,118 ----
           * prune. (We needn't recheck PageIsPrunable, since no one else could
           * have pruned while we hold pin.)
           */
!         if (PageIsFull(page) || PageGetHeapFreeSpace(page) < minfree)
          {
              /* OK to prune (though not to remove redirects) */
              (void) heap_page_prune(relation, buffer, OldestXmin, false, true);
Index: src/backend/access/nbtree/nbtpage.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/access/nbtree/nbtpage.c,v
retrieving revision 1.109
diff -c -r1.109 nbtpage.c
*** src/backend/access/nbtree/nbtpage.c    12 May 2008 00:00:45 -0000    1.109
--- src/backend/access/nbtree/nbtpage.c    9 Jul 2008 11:49:34 -0000
***************
*** 436,443 ****
      /*
       * Additionally check that the special area looks sane.
       */
!     if (((PageHeader) (page))->pd_special !=
!         (BLCKSZ - MAXALIGN(sizeof(BTPageOpaqueData))))
          ereport(ERROR,
                  (errcode(ERRCODE_INDEX_CORRUPTED),
                   errmsg("index \"%s\" contains corrupted page at block %u",
--- 436,442 ----
      /*
       * Additionally check that the special area looks sane.
       */
!     if ( (PageGetSpecialSize(page)) != MAXALIGN(sizeof(BTPageOpaqueData)))
          ereport(ERROR,
                  (errcode(ERRCODE_INDEX_CORRUPTED),
                   errmsg("index \"%s\" contains corrupted page at block %u",
***************
*** 555,561 ****

          /* Initialize the new page before returning it */
          page = BufferGetPage(buf);
!         Assert(PageIsNew((PageHeader) page));
          _bt_pageinit(page, BufferGetPageSize(buf));
      }

--- 554,560 ----

          /* Initialize the new page before returning it */
          page = BufferGetPage(buf);
!         Assert(PageIsNew(page));
          _bt_pageinit(page, BufferGetPageSize(buf));
      }

Index: src/backend/access/transam/xlog.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v
retrieving revision 1.315
diff -c -r1.315 xlog.c
*** src/backend/access/transam/xlog.c    30 Jun 2008 22:10:43 -0000    1.315
--- src/backend/access/transam/xlog.c    9 Jul 2008 11:49:34 -0000
***************
*** 1017,1035 ****
  XLogCheckBuffer(XLogRecData *rdata, bool doPageWrites,
                  XLogRecPtr *lsn, BkpBlock *bkpb)
  {
!     PageHeader    page;

!     page = (PageHeader) BufferGetBlock(rdata->buffer);

      /*
       * XXX We assume page LSN is first data on *every* page that can be passed
       * to XLogInsert, whether it otherwise has the standard page layout or
       * not.
       */
!     *lsn = page->pd_lsn;

      if (doPageWrites &&
!         XLByteLE(page->pd_lsn, RedoRecPtr))
      {
          /*
           * The page needs to be backed up, so set up *bkpb
--- 1017,1035 ----
  XLogCheckBuffer(XLogRecData *rdata, bool doPageWrites,
                  XLogRecPtr *lsn, BkpBlock *bkpb)
  {
!     Page    page;

!     page = BufferGetPage(rdata->buffer);

      /*
       * XXX We assume page LSN is first data on *every* page that can be passed
       * to XLogInsert, whether it otherwise has the standard page layout or
       * not.
       */
!     *lsn = PageGetLSN(page);

      if (doPageWrites &&
!         XLByteLE(PageGetLSN(page), RedoRecPtr))
      {
          /*
           * The page needs to be backed up, so set up *bkpb
Index: src/backend/access/transam/xlogutils.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/access/transam/xlogutils.c,v
retrieving revision 1.56
diff -c -r1.56 xlogutils.c
*** src/backend/access/transam/xlogutils.c    19 Jun 2008 00:46:03 -0000    1.56
--- src/backend/access/transam/xlogutils.c    9 Jul 2008 11:49:34 -0000
***************
*** 279,285 ****
          /* check that page has been initialized */
          Page        page = (Page) BufferGetPage(buffer);

!         if (PageIsNew((PageHeader) page))
          {
              UnlockReleaseBuffer(buffer);
              log_invalid_page(rnode, blkno, true);
--- 279,285 ----
          /* check that page has been initialized */
          Page        page = (Page) BufferGetPage(buffer);

!         if (PageIsNew(page))
          {
              UnlockReleaseBuffer(buffer);
              log_invalid_page(rnode, blkno, true);
Index: src/backend/commands/sequence.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/commands/sequence.c,v
retrieving revision 1.153
diff -c -r1.153 sequence.c
*** src/backend/commands/sequence.c    12 Jun 2008 09:12:30 -0000    1.153
--- src/backend/commands/sequence.c    9 Jul 2008 11:49:34 -0000
***************
*** 109,115 ****
      Oid            seqoid;
      Relation    rel;
      Buffer        buf;
!     PageHeader    page;
      sequence_magic *sm;
      HeapTuple    tuple;
      TupleDesc    tupDesc;
--- 109,115 ----
      Oid            seqoid;
      Relation    rel;
      Buffer        buf;
!     Page        page;
      sequence_magic *sm;
      HeapTuple    tuple;
      TupleDesc    tupDesc;
***************
*** 212,220 ****
      buf = ReadBuffer(rel, P_NEW);
      Assert(BufferGetBlockNumber(buf) == 0);

!     page = (PageHeader) BufferGetPage(buf);

!     PageInit((Page) page, BufferGetPageSize(buf), sizeof(sequence_magic));
      sm = (sequence_magic *) PageGetSpecialPointer(page);
      sm->magic = SEQ_MAGIC;

--- 212,220 ----
      buf = ReadBuffer(rel, P_NEW);
      Assert(BufferGetBlockNumber(buf) == 0);

!     page = BufferGetPage(buf);

!     PageInit(page, BufferGetPageSize(buf), sizeof(sequence_magic));
      sm = (sequence_magic *) PageGetSpecialPointer(page);
      sm->magic = SEQ_MAGIC;

***************
*** 954,960 ****
  static Form_pg_sequence
  read_info(SeqTable elm, Relation rel, Buffer *buf)
  {
!     PageHeader    page;
      ItemId        lp;
      HeapTupleData tuple;
      sequence_magic *sm;
--- 954,960 ----
  static Form_pg_sequence
  read_info(SeqTable elm, Relation rel, Buffer *buf)
  {
!     Page    page;
      ItemId        lp;
      HeapTupleData tuple;
      sequence_magic *sm;
***************
*** 963,969 ****
      *buf = ReadBuffer(rel, 0);
      LockBuffer(*buf, BUFFER_LOCK_EXCLUSIVE);

!     page = (PageHeader) BufferGetPage(*buf);
      sm = (sequence_magic *) PageGetSpecialPointer(page);

      if (sm->magic != SEQ_MAGIC)
--- 963,969 ----
      *buf = ReadBuffer(rel, 0);
      LockBuffer(*buf, BUFFER_LOCK_EXCLUSIVE);

!     page = BufferGetPage(*buf);
      sm = (sequence_magic *) PageGetSpecialPointer(page);

      if (sm->magic != SEQ_MAGIC)
***************
*** 972,978 ****

      lp = PageGetItemId(page, FirstOffsetNumber);
      Assert(ItemIdIsNormal(lp));
!     tuple.t_data = (HeapTupleHeader) PageGetItem((Page) page, lp);

      seq = (Form_pg_sequence) GETSTRUCT(&tuple);

--- 972,978 ----

      lp = PageGetItemId(page, FirstOffsetNumber);
      Assert(ItemIdIsNormal(lp));
!     tuple.t_data = (HeapTupleHeader) PageGetItem(page, lp);

      seq = (Form_pg_sequence) GETSTRUCT(&tuple);

Index: src/backend/commands/trigger.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/commands/trigger.c,v
retrieving revision 1.234
diff -c -r1.234 trigger.c
*** src/backend/commands/trigger.c    15 May 2008 00:17:39 -0000    1.234
--- src/backend/commands/trigger.c    9 Jul 2008 11:49:34 -0000
***************
*** 2203,2219 ****
      }
      else
      {
!         PageHeader    dp;
          ItemId        lp;

          buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));

!         dp = (PageHeader) BufferGetPage(buffer);
!         lp = PageGetItemId(dp, ItemPointerGetOffsetNumber(tid));

          Assert(ItemIdIsNormal(lp));

!         tuple.t_data = (HeapTupleHeader) PageGetItem((Page) dp, lp);
          tuple.t_len = ItemIdGetLength(lp);
          tuple.t_self = *tid;
          tuple.t_tableOid = RelationGetRelid(relation);
--- 2203,2219 ----
      }
      else
      {
!         Page        page;
          ItemId        lp;

          buffer = ReadBuffer(relation, ItemPointerGetBlockNumber(tid));

!         page = BufferGetPage(buffer);
!         lp = PageGetItemId(page, ItemPointerGetOffsetNumber(tid));

          Assert(ItemIdIsNormal(lp));

!         tuple.t_data = (HeapTupleHeader) PageGetItem(page, lp);
          tuple.t_len = ItemIdGetLength(lp);
          tuple.t_self = *tid;
          tuple.t_tableOid = RelationGetRelid(relation);
Index: src/backend/optimizer/util/plancat.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/optimizer/util/plancat.c,v
retrieving revision 1.147
diff -c -r1.147 plancat.c
*** src/backend/optimizer/util/plancat.c    19 Jun 2008 00:46:04 -0000    1.147
--- src/backend/optimizer/util/plancat.c    9 Jul 2008 11:49:34 -0000
***************
*** 429,435 ****
                  tuple_width += sizeof(HeapTupleHeaderData);
                  tuple_width += sizeof(ItemPointerData);
                  /* note: integer division is intentional here */
!                 density = (BLCKSZ - sizeof(PageHeaderData)) / tuple_width;
              }
              *tuples = rint(density * (double) curpages);
              break;
--- 429,435 ----
                  tuple_width += sizeof(HeapTupleHeaderData);
                  tuple_width += sizeof(ItemPointerData);
                  /* note: integer division is intentional here */
!                 density = (BLCKSZ - SizeOfPageHeaderData) / tuple_width;
              }
              *tuples = rint(density * (double) curpages);
              break;
Index: src/backend/storage/buffer/bufmgr.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v
retrieving revision 1.233
diff -c -r1.233 bufmgr.c
*** src/backend/storage/buffer/bufmgr.c    19 Jun 2008 00:46:05 -0000    1.233
--- src/backend/storage/buffer/bufmgr.c    9 Jul 2008 11:49:34 -0000
***************
*** 263,269 ****
           * always have left a zero-filled buffer, complain if not PageIsNew.
           */
          bufBlock = isLocalBuf ? LocalBufHdrGetBlock(bufHdr) : BufHdrGetBlock(bufHdr);
!         if (!PageIsNew((PageHeader) bufBlock))
              ereport(ERROR,
                      (errmsg("unexpected data beyond EOF in block %u of relation %u/%u/%u",
                              blockNum, smgr->smgr_rnode.spcNode, smgr->smgr_rnode.dbNode, smgr->smgr_rnode.relNode),
--- 263,269 ----
           * always have left a zero-filled buffer, complain if not PageIsNew.
           */
          bufBlock = isLocalBuf ? LocalBufHdrGetBlock(bufHdr) : BufHdrGetBlock(bufHdr);
!         if (!PageIsNew((Page) bufBlock))
              ereport(ERROR,
                      (errmsg("unexpected data beyond EOF in block %u of relation %u/%u/%u",
                              blockNum, smgr->smgr_rnode.spcNode, smgr->smgr_rnode.dbNode, smgr->smgr_rnode.relNode),
Index: src/include/access/hash.h
===================================================================
RCS file: /cvsroot/pgsql/src/include/access/hash.h,v
retrieving revision 1.88
diff -c -r1.88 hash.h
*** src/include/access/hash.h    19 Jun 2008 00:46:05 -0000    1.88
--- src/include/access/hash.h    9 Jul 2008 11:49:35 -0000
***************
*** 166,175 ****
   * Maximum size of a hash index item (it's okay to have only one per page)
   */
  #define HashMaxItemSize(page) \
!     (PageGetPageSize(page) - \
!      sizeof(PageHeaderData) - \
!      MAXALIGN(sizeof(HashPageOpaqueData)) - \
!      sizeof(ItemIdData))

  #define HASH_MIN_FILLFACTOR            10
  #define HASH_DEFAULT_FILLFACTOR        75
--- 166,175 ----
   * Maximum size of a hash index item (it's okay to have only one per page)
   */
  #define HashMaxItemSize(page) \
!     MAXALIGN_DOWN(PageGetPageSize(page) - \
!                   SizeOfPageHeaderData - \
!                   sizeof(ItemIdData) - \
!                   MAXALIGN(sizeof(HashPageOpaqueData)))

  #define HASH_MIN_FILLFACTOR            10
  #define HASH_DEFAULT_FILLFACTOR        75
***************
*** 191,198 ****
  #define BMPGSZ_BIT(metap)        ((metap)->hashm_bmsize << BYTE_TO_BIT)
  #define BMPG_SHIFT(metap)        ((metap)->hashm_bmshift)
  #define BMPG_MASK(metap)        (BMPGSZ_BIT(metap) - 1)
! #define HashPageGetBitmap(pg) \
!     ((uint32 *) (((char *) (pg)) + MAXALIGN(sizeof(PageHeaderData))))

  /*
   * The number of bits in an ovflpage bitmap word.
--- 191,197 ----
  #define BMPGSZ_BIT(metap)        ((metap)->hashm_bmsize << BYTE_TO_BIT)
  #define BMPG_SHIFT(metap)        ((metap)->hashm_bmshift)
  #define BMPG_MASK(metap)        (BMPGSZ_BIT(metap) - 1)
! #define HashPageGetBitmap(pg)    ((uint32 *) PageGetContents(pg))

  /*
   * The number of bits in an ovflpage bitmap word.
Index: src/include/access/htup.h
===================================================================
RCS file: /cvsroot/pgsql/src/include/access/htup.h,v
retrieving revision 1.99
diff -c -r1.99 htup.h
*** src/include/access/htup.h    12 May 2008 00:00:53 -0000    1.99
--- src/include/access/htup.h    9 Jul 2008 11:49:35 -0000
***************
*** 362,373 ****
   * other stuff that has to be on a disk page.  Since heap pages use no
   * "special space", there's no deduction for that.
   *
!  * NOTE: we do not need to count an ItemId for the tuple because
!  * sizeof(PageHeaderData) includes the first ItemId on the page.  But beware
!  * of assuming that, say, you can fit 2 tuples of size MaxHeapTupleSize/2
!  * on the same page.
   */
! #define MaxHeapTupleSize  (BLCKSZ - MAXALIGN(sizeof(PageHeaderData)))

  /*
   * MaxHeapTuplesPerPage is an upper bound on the number of tuples that can
--- 362,371 ----
   * other stuff that has to be on a disk page.  Since heap pages use no
   * "special space", there's no deduction for that.
   *
!  * NOTE: we include the size of the ItemId for the tuple, so don't assume that
!  * you can, say, fit 2 tuples of size MaxHeapTupleSize/2 on the same page.
   */
! #define MaxHeapTupleSize  (BLCKSZ - MAXALIGN(SizeOfPageHeaderData + sizeof(ItemIdData)))

  /*
   * MaxHeapTuplesPerPage is an upper bound on the number of tuples that can
***************
*** 381,387 ****
   * require increases in the size of work arrays.
   */
  #define MaxHeapTuplesPerPage    \
!     ((int) ((BLCKSZ - offsetof(PageHeaderData, pd_linp)) / \
              (MAXALIGN(offsetof(HeapTupleHeaderData, t_bits)) + sizeof(ItemIdData))))

  /*
--- 379,385 ----
   * require increases in the size of work arrays.
   */
  #define MaxHeapTuplesPerPage    \
!     ((int) ((BLCKSZ - SizeOfPageHeaderData) / \
              (MAXALIGN(offsetof(HeapTupleHeaderData, t_bits)) + sizeof(ItemIdData))))

  /*
Index: src/include/access/itup.h
===================================================================
RCS file: /cvsroot/pgsql/src/include/access/itup.h,v
retrieving revision 1.49
diff -c -r1.49 itup.h
*** src/include/access/itup.h    1 Jan 2008 19:45:56 -0000    1.49
--- src/include/access/itup.h    9 Jul 2008 11:49:35 -0000
***************
*** 134,140 ****
   * must be maxaligned, and it must have an associated item pointer.
   */
  #define MaxIndexTuplesPerPage    \
!     ((int) ((BLCKSZ - offsetof(PageHeaderData, pd_linp)) / \
              (MAXALIGN(sizeof(IndexTupleData) + 1) + sizeof(ItemIdData))))


--- 134,140 ----
   * must be maxaligned, and it must have an associated item pointer.
   */
  #define MaxIndexTuplesPerPage    \
!     ((int) ((BLCKSZ - SizeOfPageHeaderData) / \
              (MAXALIGN(sizeof(IndexTupleData) + 1) + sizeof(ItemIdData))))


Index: src/include/access/nbtree.h
===================================================================
RCS file: /cvsroot/pgsql/src/include/access/nbtree.h,v
retrieving revision 1.120
diff -c -r1.120 nbtree.h
*** src/include/access/nbtree.h    19 Jun 2008 00:46:06 -0000    1.120
--- src/include/access/nbtree.h    9 Jul 2008 11:49:35 -0000
***************
*** 113,125 ****
   *
   * We actually need to be able to fit three items on every page,
   * so restrict any one item to 1/3 the per-page available space.
-  *
-  * Note: sizeof(PageHeaderData) includes the first ItemId, but we have
-  * to allow for 2 more, as well as the end-of-page special space.
   */
  #define BTMaxItemSize(page) \
      MAXALIGN_DOWN((PageGetPageSize(page) - \
!                    MAXALIGN(sizeof(PageHeaderData) + 2*sizeof(ItemIdData)) - \
                     MAXALIGN(sizeof(BTPageOpaqueData))) / 3)

  /*
--- 113,122 ----
   *
   * We actually need to be able to fit three items on every page,
   * so restrict any one item to 1/3 the per-page available space.
   */
  #define BTMaxItemSize(page) \
      MAXALIGN_DOWN((PageGetPageSize(page) - \
!                    MAXALIGN(SizeOfPageHeaderData + 3*sizeof(ItemIdData)) - \
                     MAXALIGN(sizeof(BTPageOpaqueData))) / 3)

  /*
Index: src/include/access/tuptoaster.h
===================================================================
RCS file: /cvsroot/pgsql/src/include/access/tuptoaster.h,v
retrieving revision 1.40
diff -c -r1.40 tuptoaster.h
*** src/include/access/tuptoaster.h    19 Jun 2008 00:46:06 -0000    1.40
--- src/include/access/tuptoaster.h    9 Jul 2008 11:49:35 -0000
***************
*** 46,55 ****
   */
  #define TOAST_TUPLES_PER_PAGE    4

- /* Note: sizeof(PageHeaderData) includes the first ItemId on the page */
  #define TOAST_TUPLE_THRESHOLD    \
      MAXALIGN_DOWN((BLCKSZ - \
!                    MAXALIGN(sizeof(PageHeaderData) + (TOAST_TUPLES_PER_PAGE-1) * sizeof(ItemIdData))) \
                    / TOAST_TUPLES_PER_PAGE)

  #define TOAST_TUPLE_TARGET        TOAST_TUPLE_THRESHOLD
--- 46,54 ----
   */
  #define TOAST_TUPLES_PER_PAGE    4

  #define TOAST_TUPLE_THRESHOLD    \
      MAXALIGN_DOWN((BLCKSZ - \
!                    MAXALIGN(SizeOfPageHeaderData + (TOAST_TUPLES_PER_PAGE) * sizeof(ItemIdData))) \
                    / TOAST_TUPLES_PER_PAGE)

  #define TOAST_TUPLE_TARGET        TOAST_TUPLE_THRESHOLD
***************
*** 73,82 ****
   */
  #define EXTERN_TUPLES_PER_PAGE    4        /* tweak only this */

- /* Note: sizeof(PageHeaderData) includes the first ItemId on the page */
  #define EXTERN_TUPLE_MAX_SIZE    \
      MAXALIGN_DOWN((BLCKSZ - \
!                    MAXALIGN(sizeof(PageHeaderData) + (EXTERN_TUPLES_PER_PAGE-1) * sizeof(ItemIdData))) \
                    / EXTERN_TUPLES_PER_PAGE)

  #define TOAST_MAX_CHUNK_SIZE    \
--- 72,80 ----
   */
  #define EXTERN_TUPLES_PER_PAGE    4        /* tweak only this */

  #define EXTERN_TUPLE_MAX_SIZE    \
      MAXALIGN_DOWN((BLCKSZ - \
!                    MAXALIGN(SizeOfPageHeaderData + (EXTERN_TUPLES_PER_PAGE) * sizeof(ItemIdData))) \
                    / EXTERN_TUPLES_PER_PAGE)

  #define TOAST_MAX_CHUNK_SIZE    \

Re: page macros cleanup (ver 04)

От
Zdenek Kotala
Дата:
Heikki Linnakangas napsal(a):
> Zdenek Kotala wrote:
>> Pavan Deolasee napsal(a):

> There's another academical discrepancy between these two hunks:

<snip>

> I admit I don't understand what that bitmap is, it looks like we're
> assuming it can take up all the space between page header and the
> special portion, without any line pointers, but in HashPageGetBitmap,
> we're reserving space for one pointer. It looks like the actual size of
> the bitmap is only the largest power of 2 below the maximum size, so
> that won't be an issue in practice. That macro is actually doing the
> same thing as PageGetContents, so I switched to using that. As that
> moves the data sligthly on those bitmap pages, I guess we'll need a
> catversion bump.

Good catch. if we have to bump catalog version then I have there small patch
which introduce following macro and remove PageHeaderData stucture from
HashMetaPageData:

#define HashPageGetMeta(page) ((HashMetaPage) (PageGetContents(page)))

It also needs bump a catalog version and if we do it now I think it is better to
connect both these patches and do bump only once.

> Attached is an updated patch. I also fixed some whitespace and comments
> that were no longer valid. How does it look to you now?

Perfect. Thanks

        Zdenek





diff -rc pgsql_hash.851ed84fb6aa/src/backend/access/hash/hash.c pgsql_hash/src/backend/access/hash/hash.c
*** pgsql_hash.851ed84fb6aa/src/backend/access/hash/hash.c    út črc  8 21:31:38 2008
--- pgsql_hash/src/backend/access/hash/hash.c    út črc  8 21:31:38 2008
***************
*** 527,533 ****
       * each bucket.
       */
      metabuf = _hash_getbuf(rel, HASH_METAPAGE, HASH_READ, LH_META_PAGE);
!     metap = (HashMetaPage) BufferGetPage(metabuf);
      orig_maxbucket = metap->hashm_maxbucket;
      orig_ntuples = metap->hashm_ntuples;
      memcpy(&local_metapage, metap, sizeof(local_metapage));
--- 527,533 ----
       * each bucket.
       */
      metabuf = _hash_getbuf(rel, HASH_METAPAGE, HASH_READ, LH_META_PAGE);
!     metap =  HashPageGetMeta(BufferGetPage(metabuf));
      orig_maxbucket = metap->hashm_maxbucket;
      orig_ntuples = metap->hashm_ntuples;
      memcpy(&local_metapage, metap, sizeof(local_metapage));
***************
*** 629,635 ****

      /* Write-lock metapage and check for split since we started */
      metabuf = _hash_getbuf(rel, HASH_METAPAGE, HASH_WRITE, LH_META_PAGE);
!     metap = (HashMetaPage) BufferGetPage(metabuf);

      if (cur_maxbucket != metap->hashm_maxbucket)
      {
--- 629,635 ----

      /* Write-lock metapage and check for split since we started */
      metabuf = _hash_getbuf(rel, HASH_METAPAGE, HASH_WRITE, LH_META_PAGE);
!     metap = HashPageGetMeta(BufferGetPage(metabuf));

      if (cur_maxbucket != metap->hashm_maxbucket)
      {
diff -rc pgsql_hash.851ed84fb6aa/src/backend/access/hash/hashinsert.c pgsql_hash/src/backend/access/hash/hashinsert.c
*** pgsql_hash.851ed84fb6aa/src/backend/access/hash/hashinsert.c    út črc  8 21:31:38 2008
--- pgsql_hash/src/backend/access/hash/hashinsert.c    út črc  8 21:31:38 2008
***************
*** 69,75 ****

      /* Read the metapage */
      metabuf = _hash_getbuf(rel, HASH_METAPAGE, HASH_READ, LH_META_PAGE);
!     metap = (HashMetaPage) BufferGetPage(metabuf);

      /*
       * Check whether the item can fit on a hash page at all. (Eventually, we
--- 69,75 ----

      /* Read the metapage */
      metabuf = _hash_getbuf(rel, HASH_METAPAGE, HASH_READ, LH_META_PAGE);
!     metap = HashPageGetMeta(BufferGetPage(metabuf));

      /*
       * Check whether the item can fit on a hash page at all. (Eventually, we
diff -rc pgsql_hash.851ed84fb6aa/src/backend/access/hash/hashovfl.c pgsql_hash/src/backend/access/hash/hashovfl.c
*** pgsql_hash.851ed84fb6aa/src/backend/access/hash/hashovfl.c    út črc  8 21:31:38 2008
--- pgsql_hash/src/backend/access/hash/hashovfl.c    út črc  8 21:31:38 2008
***************
*** 187,193 ****
      _hash_chgbufaccess(rel, metabuf, HASH_NOLOCK, HASH_WRITE);

      _hash_checkpage(rel, metabuf, LH_META_PAGE);
!     metap = (HashMetaPage) BufferGetPage(metabuf);

      /* start search at hashm_firstfree */
      orig_firstfree = metap->hashm_firstfree;
--- 187,193 ----
      _hash_chgbufaccess(rel, metabuf, HASH_NOLOCK, HASH_WRITE);

      _hash_checkpage(rel, metabuf, LH_META_PAGE);
!     metap = HashPageGetMeta(BufferGetPage(metabuf));

      /* start search at hashm_firstfree */
      orig_firstfree = metap->hashm_firstfree;
***************
*** 450,456 ****

      /* Read the metapage so we can determine which bitmap page to use */
      metabuf = _hash_getbuf(rel, HASH_METAPAGE, HASH_READ, LH_META_PAGE);
!     metap = (HashMetaPage) BufferGetPage(metabuf);

      /* Identify which bit to set */
      ovflbitno = blkno_to_bitno(metap, ovflblkno);
--- 450,456 ----

      /* Read the metapage so we can determine which bitmap page to use */
      metabuf = _hash_getbuf(rel, HASH_METAPAGE, HASH_READ, LH_META_PAGE);
!     metap = HashPageGetMeta(BufferGetPage(metabuf));

      /* Identify which bit to set */
      ovflbitno = blkno_to_bitno(metap, ovflblkno);
diff -rc pgsql_hash.851ed84fb6aa/src/backend/access/hash/hashpage.c pgsql_hash/src/backend/access/hash/hashpage.c
*** pgsql_hash.851ed84fb6aa/src/backend/access/hash/hashpage.c    út črc  8 21:31:38 2008
--- pgsql_hash/src/backend/access/hash/hashpage.c    út črc  8 21:31:38 2008
***************
*** 395,401 ****
      pageopaque->hasho_flag = LH_META_PAGE;
      pageopaque->hasho_page_id = HASHO_PAGE_ID;

!     metap = (HashMetaPage) pg;

      metap->hashm_magic = HASH_MAGIC;
      metap->hashm_version = HASH_VERSION;
--- 395,401 ----
      pageopaque->hasho_flag = LH_META_PAGE;
      pageopaque->hasho_page_id = HASHO_PAGE_ID;

!     metap = HashPageGetMeta(pg);

      metap->hashm_magic = HASH_MAGIC;
      metap->hashm_version = HASH_VERSION;
***************
*** 532,538 ****
      _hash_chgbufaccess(rel, metabuf, HASH_NOLOCK, HASH_WRITE);

      _hash_checkpage(rel, metabuf, LH_META_PAGE);
!     metap = (HashMetaPage) BufferGetPage(metabuf);

      /*
       * Check to see if split is still needed; someone else might have already
--- 532,538 ----
      _hash_chgbufaccess(rel, metabuf, HASH_NOLOCK, HASH_WRITE);

      _hash_checkpage(rel, metabuf, LH_META_PAGE);
!     metap = HashPageGetMeta(BufferGetPage(metabuf));

      /*
       * Check to see if split is still needed; someone else might have already
diff -rc pgsql_hash.851ed84fb6aa/src/backend/access/hash/hashsearch.c pgsql_hash/src/backend/access/hash/hashsearch.c
*** pgsql_hash.851ed84fb6aa/src/backend/access/hash/hashsearch.c    út črc  8 21:31:38 2008
--- pgsql_hash/src/backend/access/hash/hashsearch.c    út črc  8 21:31:38 2008
***************
*** 186,192 ****

      /* Read the metapage */
      metabuf = _hash_getbuf(rel, HASH_METAPAGE, HASH_READ, LH_META_PAGE);
!     metap = (HashMetaPage) BufferGetPage(metabuf);

      /*
       * Compute the target bucket number, and convert to block number.
--- 186,192 ----

      /* Read the metapage */
      metabuf = _hash_getbuf(rel, HASH_METAPAGE, HASH_READ, LH_META_PAGE);
!     metap = HashPageGetMeta(BufferGetPage(metabuf));

      /*
       * Compute the target bucket number, and convert to block number.
diff -rc pgsql_hash.851ed84fb6aa/src/backend/access/hash/hashutil.c pgsql_hash/src/backend/access/hash/hashutil.c
*** pgsql_hash.851ed84fb6aa/src/backend/access/hash/hashutil.c    út črc  8 21:31:38 2008
--- pgsql_hash/src/backend/access/hash/hashutil.c    út črc  8 21:31:38 2008
***************
*** 191,197 ****
       */
      if (flags == LH_META_PAGE)
      {
!         HashMetaPage metap = (HashMetaPage) page;

          if (metap->hashm_magic != HASH_MAGIC)
              ereport(ERROR,
--- 191,197 ----
       */
      if (flags == LH_META_PAGE)
      {
!         HashMetaPage metap = HashPageGetMeta(page);

          if (metap->hashm_magic != HASH_MAGIC)
              ereport(ERROR,
diff -rc pgsql_hash.851ed84fb6aa/src/include/access/hash.h pgsql_hash/src/include/access/hash.h
*** pgsql_hash.851ed84fb6aa/src/include/access/hash.h    út črc  8 21:31:38 2008
--- pgsql_hash/src/include/access/hash.h    út črc  8 21:31:38 2008
***************
*** 138,144 ****

  typedef struct HashMetaPageData
  {
-     PageHeaderData hashm_phdr;    /* pad for page header (do not use) */
      uint32        hashm_magic;    /* magic no. for hash tables */
      uint32        hashm_version;    /* version ID */
      double        hashm_ntuples;    /* number of tuples stored in the table */
--- 138,143 ----
***************
*** 162,167 ****
--- 161,168 ----

  typedef HashMetaPageData *HashMetaPage;

+ #define HashPageGetMeta(page) ((HashMetaPage) (PageGetContents(page)))
+
  /*
   * Maximum size of a hash index item (it's okay to have only one per page)
   */

Re: page macros cleanup (ver 04)

От
Tom Lane
Дата:
Zdenek Kotala <Zdenek.Kotala@Sun.COM> writes:
> Good catch. if we have to bump catalog version then I have there small patch
> which introduce following macro and remove PageHeaderData stucture from
> HashMetaPageData:

Seems like a bad idea --- PageGetContents is not guaranteed to deliver
a maxaligned pointer, so at least in principle this could result in
alignment violations.  It would accidentally fail to fail as of CVS
HEAD, but any future rearrangement of PageHeaderData or HashMetaPageData
could create a problem.

(Possibly PageGetContents *should* guarantee a maxaligned result,
but the current coding does not.)

            regards, tom lane

Re: page macros cleanup (ver 04)

От
Tom Lane
Дата:
"Heikki Linnakangas" <heikki@enterprisedb.com> writes:
> ...  That macro is actually doing the
> same thing as PageGetContents, so I switched to using that. As that
> moves the data sligthly on those bitmap pages, I guess we'll need a
> catversion bump.

I'm amazed that Zdenek didn't scream bloody murder about that.  You're
creating a work item for in-place-upgrade that would not otherwise
exist, in exchange for a completely trivial bit of code beautification.
(The same can be said of his proposed change to hash meta pages.)

I'm planning to go over this patch today and apply it sans the parts
that would require catversion bump.  We can argue later about whether
those are really worth doing, but I'm leaning to "not" --- unless Zdenek
says that he has no intention of making in-place-upgrade handle hash
indexes any time soon.

BTW, after further thought about the PageGetContents() situation:
right now we can change it to guarantee maxalignment "for free",
since SizeOfPageHeaderData happens to be maxaligned on all platforms
(this wasn't the case as recently as 8.2).  So I'm thinking we should
do that.  There's at least one place that thinks that PageGetContents
is the same as page + SizeOfPageHeaderData, but that's easily fixed.
On balance it seems like hidden assumptions about alignment are a bigger
risk than assumptions about that offset --- anyone want to argue the
contrary?

            regards, tom lane

Re: page macros cleanup (ver 04)

От
Zdenek Kotala
Дата:
Tom Lane napsal(a):
> "Heikki Linnakangas" <heikki@enterprisedb.com> writes:
>> ...  That macro is actually doing the
>> same thing as PageGetContents, so I switched to using that. As that
>> moves the data sligthly on those bitmap pages, I guess we'll need a
>> catversion bump.
>
> I'm amazed that Zdenek didn't scream bloody murder about that.  You're
> creating a work item for in-place-upgrade that would not otherwise
> exist, in exchange for a completely trivial bit of code beautification.
> (The same can be said of his proposed change to hash meta pages.)

:-) Yeah, These changes break in-place-upgrade on hash indexes and invokes
reindexing request. I have had several reasons why I didn't complaint about it:

1) IIRC, hash function for double has been change
2) there is ongoing project to improve hash index performance -> completely
redesigned content
3) hash index is not much used (by my opinion) and it affect only small group of
users

> I'm planning to go over this patch today and apply it sans the parts
> that would require catversion bump.  We can argue later about whether
> those are really worth doing, but I'm leaning to "not" --- unless Zdenek
> says that he has no intention of making in-place-upgrade handle hash
> indexes any time soon.

Thanks for applying patch. I think that hash index "upgradebility" is currently
broken or it will be with new hash index improvement. But if I think about it it
does not make sense to break compatibility by this patch first. I will prepare
patch which will be upgrade friendly. And if we will reimplement hash index
soon, than we can clean a code.

> BTW, after further thought about the PageGetContents() situation:
> right now we can change it to guarantee maxalignment "for free",
> since SizeOfPageHeaderData happens to be maxaligned on all platforms
> (this wasn't the case as recently as 8.2).  So I'm thinking we should
> do that.  There's at least one place that thinks that PageGetContents
> is the same as page + SizeOfPageHeaderData, but that's easily fixed.
> On balance it seems like hidden assumptions about alignment are a bigger
> risk than assumptions about that offset --- anyone want to argue the
> contrary?

I think it is OK and I seen that you already applied a patch.

        Thanks Zdenek



--
Zdenek Kotala              Sun Microsystems
Prague, Czech Republic     http://sun.com/postgresql


Re: page macros cleanup (ver 04)

От
Tom Lane
Дата:
Zdenek Kotala <Zdenek.Kotala@Sun.COM> writes:
> Thanks for applying patch. I think that hash index "upgradebility" is
> currently broken or it will be with new hash index improvement. But if
> I think about it it does not make sense to break compatibility by this
> patch first.

Right, my point exactly.  Those necessarily-incompatible changes might
or might not ever get applied --- if they are, we can do cosmetic
cleanups afterwards.

            regards, tom lane