Re: page macros cleanup (ver 03) - Mailing list pgsql-patches

From Zdenek Kotala
Subject Re: page macros cleanup (ver 03)
Date
Msg-id 486DF41B.1060000@sun.com
Whole thread Raw
In response to Re: page macros cleanup  ("Pavan Deolasee" <pavan.deolasee@gmail.com>)
List pgsql-patches
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    \

pgsql-patches by date:

Previous
From: "Heikki Linnakangas"
Date:
Subject: Re: Relation forks & FSM rewrite patches
Next
From: "Pavel Stehule"
Date:
Subject: Re: variadic function support