PostgreSQL Source Code  git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
bufpage.h File Reference
#include "access/xlogdefs.h"
#include "storage/block.h"
#include "storage/item.h"
#include "storage/off.h"
Include dependency graph for bufpage.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  PageXLogRecPtr
 
struct  PageHeaderData
 

Macros

#define PageXLogRecPtrSet(ptr, lsn)    ((ptr).xlogid = (uint32) ((lsn) >> 32), (ptr).xrecoff = (uint32) (lsn))
 
#define PD_HAS_FREE_LINES   0x0001 /* are there any unused line pointers? */
 
#define PD_PAGE_FULL   0x0002 /* not enough free space for new tuple? */
 
#define PD_ALL_VISIBLE
 
#define PD_VALID_FLAG_BITS   0x0007 /* OR of all valid pd_flags bits */
 
#define PG_PAGE_LAYOUT_VERSION   4
 
#define PG_DATA_CHECKSUM_VERSION   1
 
#define SizeOfPageHeaderData   (offsetof(PageHeaderData, pd_linp))
 
#define PageSetPrunable(page, xid)
 
#define PageClearPrunable(page)    (((PageHeader) (page))->pd_prune_xid = InvalidTransactionId)
 
#define PAI_OVERWRITE   (1 << 0)
 
#define PAI_IS_HEAP   (1 << 1)
 
#define PIV_LOG_WARNING   (1 << 0)
 
#define PIV_REPORT_STAT   (1 << 1)
 
#define PageAddItem(page, item, size, offsetNumber, overwrite, is_heap)
 
#define PageIsVerified(page, blkno)
 

Typedefs

typedef Pointer Page
 
typedef uint16 LocationIndex
 
typedef struct PageHeaderData PageHeaderData
 
typedef PageHeaderDataPageHeader
 

Functions

static XLogRecPtr PageXLogRecPtrGet (PageXLogRecPtr val)
 
static bool PageIsEmpty (Page page)
 
static bool PageIsNew (Page page)
 
static ItemId PageGetItemId (Page page, OffsetNumber offsetNumber)
 
static char * PageGetContents (Page page)
 
static Size PageGetPageSize (Page page)
 
static uint8 PageGetPageLayoutVersion (Page page)
 
static void PageSetPageSizeAndVersion (Page page, Size size, uint8 version)
 
static uint16 PageGetSpecialSize (Page page)
 
static void PageValidateSpecialPointer (Page page)
 
static char * PageGetSpecialPointer (Page page)
 
static Item PageGetItem (Page page, ItemId itemId)
 
static OffsetNumber PageGetMaxOffsetNumber (Page page)
 
static XLogRecPtr PageGetLSN (const char *page)
 
static void PageSetLSN (Page page, XLogRecPtr lsn)
 
static bool PageHasFreeLinePointers (Page page)
 
static void PageSetHasFreeLinePointers (Page page)
 
static void PageClearHasFreeLinePointers (Page page)
 
static bool PageIsFull (Page page)
 
static void PageSetFull (Page page)
 
static void PageClearFull (Page page)
 
static bool PageIsAllVisible (Page page)
 
static void PageSetAllVisible (Page page)
 
static void PageClearAllVisible (Page page)
 
 StaticAssertDecl (BLCKSZ==((BLCKSZ/sizeof(size_t)) *sizeof(size_t)), "BLCKSZ has to be a multiple of sizeof(size_t)")
 
void PageInit (Page page, Size pageSize, Size specialSize)
 
bool PageIsVerifiedExtended (Page page, BlockNumber blkno, int flags)
 
OffsetNumber PageAddItemExtended (Page page, Item item, Size size, OffsetNumber offsetNumber, int flags)
 
Page PageGetTempPage (Page page)
 
Page PageGetTempPageCopy (Page page)
 
Page PageGetTempPageCopySpecial (Page page)
 
void PageRestoreTempPage (Page tempPage, Page oldPage)
 
void PageRepairFragmentation (Page page)
 
void PageTruncateLinePointerArray (Page page)
 
Size PageGetFreeSpace (Page page)
 
Size PageGetFreeSpaceForMultipleTuples (Page page, int ntups)
 
Size PageGetExactFreeSpace (Page page)
 
Size PageGetHeapFreeSpace (Page page)
 
void PageIndexTupleDelete (Page page, OffsetNumber offnum)
 
void PageIndexMultiDelete (Page page, OffsetNumber *itemnos, int nitems)
 
void PageIndexTupleDeleteNoCompact (Page page, OffsetNumber offnum)
 
bool PageIndexTupleOverwrite (Page page, OffsetNumber offnum, Item newtup, Size newsize)
 
char * PageSetChecksumCopy (Page page, BlockNumber blkno)
 
void PageSetChecksumInplace (Page page, BlockNumber blkno)
 

Variables

PGDLLIMPORT bool ignore_checksum_failure
 

Macro Definition Documentation

◆ PageAddItem

#define PageAddItem (   page,
  item,
  size,
  offsetNumber,
  overwrite,
  is_heap 
)
Value:
PageAddItemExtended(page, item, size, offsetNumber, \
((overwrite) ? PAI_OVERWRITE : 0) | \
((is_heap) ? PAI_IS_HEAP : 0))
OffsetNumber PageAddItemExtended(Page page, Item item, Size size, OffsetNumber offsetNumber, int flags)
Definition: bufpage.c:183
#define PAI_IS_HEAP
Definition: bufpage.h:465
#define PAI_OVERWRITE
Definition: bufpage.h:464
static pg_noinline void Size size
Definition: slab.c:607
static void overwrite(PGconn *conn, Oid lobjId, int start, int len)
Definition: testlo.c:108

Definition at line 471 of file bufpage.h.

◆ PageClearPrunable

#define PageClearPrunable (   page)     (((PageHeader) (page))->pd_prune_xid = InvalidTransactionId)

Definition at line 454 of file bufpage.h.

◆ PageIsVerified

#define PageIsVerified (   page,
  blkno 
)
Value:
PageIsVerifiedExtended(page, blkno, \
#define PIV_LOG_WARNING
Definition: bufpage.h:468
bool PageIsVerifiedExtended(Page page, BlockNumber blkno, int flags)
Definition: bufpage.c:88
#define PIV_REPORT_STAT
Definition: bufpage.h:469

Definition at line 476 of file bufpage.h.

◆ PageSetPrunable

#define PageSetPrunable (   page,
  xid 
)
Value:
do { \
Assert(TransactionIdIsNormal(xid)); \
if (!TransactionIdIsValid(((PageHeader) (page))->pd_prune_xid) || \
TransactionIdPrecedes(xid, ((PageHeader) (page))->pd_prune_xid)) \
((PageHeader) (page))->pd_prune_xid = (xid); \
} while (0)
PageHeaderData * PageHeader
Definition: bufpage.h:173
bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
Definition: transam.c:280
#define TransactionIdIsValid(xid)
Definition: transam.h:41
#define TransactionIdIsNormal(xid)
Definition: transam.h:42

Definition at line 447 of file bufpage.h.

◆ PageXLogRecPtrSet

#define PageXLogRecPtrSet (   ptr,
  lsn 
)     ((ptr).xlogid = (uint32) ((lsn) >> 32), (ptr).xrecoff = (uint32) (lsn))

Definition at line 109 of file bufpage.h.

◆ PAI_IS_HEAP

#define PAI_IS_HEAP   (1 << 1)

Definition at line 465 of file bufpage.h.

◆ PAI_OVERWRITE

#define PAI_OVERWRITE   (1 << 0)

Definition at line 464 of file bufpage.h.

◆ PD_ALL_VISIBLE

#define PD_ALL_VISIBLE
Value:
0x0004 /* all tuples on page are visible to
* everyone */

Definition at line 189 of file bufpage.h.

◆ PD_HAS_FREE_LINES

#define PD_HAS_FREE_LINES   0x0001 /* are there any unused line pointers? */

Definition at line 187 of file bufpage.h.

◆ PD_PAGE_FULL

#define PD_PAGE_FULL   0x0002 /* not enough free space for new tuple? */

Definition at line 188 of file bufpage.h.

◆ PD_VALID_FLAG_BITS

#define PD_VALID_FLAG_BITS   0x0007 /* OR of all valid pd_flags bits */

Definition at line 191 of file bufpage.h.

◆ PG_DATA_CHECKSUM_VERSION

#define PG_DATA_CHECKSUM_VERSION   1

Definition at line 206 of file bufpage.h.

◆ PG_PAGE_LAYOUT_VERSION

#define PG_PAGE_LAYOUT_VERSION   4

Definition at line 205 of file bufpage.h.

◆ PIV_LOG_WARNING

#define PIV_LOG_WARNING   (1 << 0)

Definition at line 468 of file bufpage.h.

◆ PIV_REPORT_STAT

#define PIV_REPORT_STAT   (1 << 1)

Definition at line 469 of file bufpage.h.

◆ SizeOfPageHeaderData

#define SizeOfPageHeaderData   (offsetof(PageHeaderData, pd_linp))

Definition at line 216 of file bufpage.h.

Typedef Documentation

◆ LocationIndex

Definition at line 90 of file bufpage.h.

◆ Page

typedef Pointer Page

Definition at line 81 of file bufpage.h.

◆ PageHeader

Definition at line 173 of file bufpage.h.

◆ PageHeaderData

Function Documentation

◆ PageAddItemExtended()

OffsetNumber PageAddItemExtended ( Page  page,
Item  item,
Size  size,
OffsetNumber  offsetNumber,
int  flags 
)

Definition at line 183 of file bufpage.c.

188 {
189  PageHeader phdr = (PageHeader) page;
190  Size alignedSize;
191  int lower;
192  int upper;
193  ItemId itemId;
194  OffsetNumber limit;
195  bool needshuffle = false;
196 
197  /*
198  * Be wary about corrupted page pointers
199  */
200  if (phdr->pd_lower < SizeOfPageHeaderData ||
201  phdr->pd_lower > phdr->pd_upper ||
202  phdr->pd_upper > phdr->pd_special ||
203  phdr->pd_special > BLCKSZ)
204  ereport(PANIC,
206  errmsg("corrupted page pointers: lower = %u, upper = %u, special = %u",
207  phdr->pd_lower, phdr->pd_upper, phdr->pd_special)));
208 
209  /*
210  * Select offsetNumber to place the new item at
211  */
213 
214  /* was offsetNumber passed in? */
215  if (OffsetNumberIsValid(offsetNumber))
216  {
217  /* yes, check it */
218  if ((flags & PAI_OVERWRITE) != 0)
219  {
220  if (offsetNumber < limit)
221  {
222  itemId = PageGetItemId(page, offsetNumber);
223  if (ItemIdIsUsed(itemId) || ItemIdHasStorage(itemId))
224  {
225  elog(WARNING, "will not overwrite a used ItemId");
226  return InvalidOffsetNumber;
227  }
228  }
229  }
230  else
231  {
232  if (offsetNumber < limit)
233  needshuffle = true; /* need to move existing linp's */
234  }
235  }
236  else
237  {
238  /* offsetNumber was not passed in, so find a free slot */
239  /* if no free slot, we'll put it at limit (1st open slot) */
240  if (PageHasFreeLinePointers(page))
241  {
242  /*
243  * Scan line pointer array to locate a "recyclable" (unused)
244  * ItemId.
245  *
246  * Always use earlier items first. PageTruncateLinePointerArray
247  * can only truncate unused items when they appear as a contiguous
248  * group at the end of the line pointer array.
249  */
250  for (offsetNumber = FirstOffsetNumber;
251  offsetNumber < limit; /* limit is maxoff+1 */
252  offsetNumber++)
253  {
254  itemId = PageGetItemId(page, offsetNumber);
255 
256  /*
257  * We check for no storage as well, just to be paranoid;
258  * unused items should never have storage. Assert() that the
259  * invariant is respected too.
260  */
261  Assert(ItemIdIsUsed(itemId) || !ItemIdHasStorage(itemId));
262 
263  if (!ItemIdIsUsed(itemId) && !ItemIdHasStorage(itemId))
264  break;
265  }
266  if (offsetNumber >= limit)
267  {
268  /* the hint is wrong, so reset it */
270  }
271  }
272  else
273  {
274  /* don't bother searching if hint says there's no free slot */
275  offsetNumber = limit;
276  }
277  }
278 
279  /* Reject placing items beyond the first unused line pointer */
280  if (offsetNumber > limit)
281  {
282  elog(WARNING, "specified item offset is too large");
283  return InvalidOffsetNumber;
284  }
285 
286  /* Reject placing items beyond heap boundary, if heap */
287  if ((flags & PAI_IS_HEAP) != 0 && offsetNumber > MaxHeapTuplesPerPage)
288  {
289  elog(WARNING, "can't put more than MaxHeapTuplesPerPage items in a heap page");
290  return InvalidOffsetNumber;
291  }
292 
293  /*
294  * Compute new lower and upper pointers for page, see if it'll fit.
295  *
296  * Note: do arithmetic as signed ints, to avoid mistakes if, say,
297  * alignedSize > pd_upper.
298  */
299  if (offsetNumber == limit || needshuffle)
300  lower = phdr->pd_lower + sizeof(ItemIdData);
301  else
302  lower = phdr->pd_lower;
303 
304  alignedSize = MAXALIGN(size);
305 
306  upper = (int) phdr->pd_upper - (int) alignedSize;
307 
308  if (lower > upper)
309  return InvalidOffsetNumber;
310 
311  /*
312  * OK to insert the item. First, shuffle the existing pointers if needed.
313  */
314  itemId = PageGetItemId(page, offsetNumber);
315 
316  if (needshuffle)
317  memmove(itemId + 1, itemId,
318  (limit - offsetNumber) * sizeof(ItemIdData));
319 
320  /* set the line pointer */
321  ItemIdSetNormal(itemId, upper, size);
322 
323  /*
324  * Items normally contain no uninitialized bytes. Core bufpage consumers
325  * conform, but this is not a necessary coding rule; a new index AM could
326  * opt to depart from it. However, data type input functions and other
327  * C-language functions that synthesize datums should initialize all
328  * bytes; datumIsEqual() relies on this. Testing here, along with the
329  * similar check in printtup(), helps to catch such mistakes.
330  *
331  * Values of the "name" type retrieved via index-only scans may contain
332  * uninitialized bytes; see comment in btrescan(). Valgrind will report
333  * this as an error, but it is safe to ignore.
334  */
336 
337  /* copy the item's data onto the page */
338  memcpy((char *) page + upper, item, size);
339 
340  /* adjust page header */
341  phdr->pd_lower = (LocationIndex) lower;
342  phdr->pd_upper = (LocationIndex) upper;
343 
344  return offsetNumber;
345 }
#define SizeOfPageHeaderData
Definition: bufpage.h:216
static ItemId PageGetItemId(Page page, OffsetNumber offsetNumber)
Definition: bufpage.h:243
static void PageClearHasFreeLinePointers(Page page)
Definition: bufpage.h:407
static bool PageHasFreeLinePointers(Page page)
Definition: bufpage.h:397
uint16 LocationIndex
Definition: bufpage.h:90
static OffsetNumber PageGetMaxOffsetNumber(Page page)
Definition: bufpage.h:372
#define MAXALIGN(LEN)
Definition: c.h:816
#define Assert(condition)
Definition: c.h:863
size_t Size
Definition: c.h:610
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define WARNING
Definition: elog.h:36
#define PANIC
Definition: elog.h:42
#define elog(elevel,...)
Definition: elog.h:225
#define ereport(elevel,...)
Definition: elog.h:149
#define MaxHeapTuplesPerPage
Definition: htup_details.h:572
struct ItemIdData ItemIdData
#define ItemIdSetNormal(itemId, off, len)
Definition: itemid.h:140
#define ItemIdIsUsed(itemId)
Definition: itemid.h:92
#define ItemIdHasStorage(itemId)
Definition: itemid.h:120
#define VALGRIND_CHECK_MEM_IS_DEFINED(addr, size)
Definition: memdebug.h:23
#define InvalidOffsetNumber
Definition: off.h:26
#define OffsetNumberIsValid(offsetNumber)
Definition: off.h:39
#define OffsetNumberNext(offsetNumber)
Definition: off.h:52
uint16 OffsetNumber
Definition: off.h:24
#define FirstOffsetNumber
Definition: off.h:27
Datum lower(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:49
Datum upper(PG_FUNCTION_ARGS)
Definition: oracle_compat.c:80
#define ERRCODE_DATA_CORRUPTED
Definition: pg_basebackup.c:41
LocationIndex pd_special
Definition: bufpage.h:167
LocationIndex pd_upper
Definition: bufpage.h:166
LocationIndex pd_lower
Definition: bufpage.h:165

References Assert, elog, ereport, errcode(), ERRCODE_DATA_CORRUPTED, errmsg(), FirstOffsetNumber, InvalidOffsetNumber, ItemIdHasStorage, ItemIdIsUsed, ItemIdSetNormal, lower(), MAXALIGN, MaxHeapTuplesPerPage, OffsetNumberIsValid, OffsetNumberNext, PageClearHasFreeLinePointers(), PageGetItemId(), PageGetMaxOffsetNumber(), PageHasFreeLinePointers(), PAI_IS_HEAP, PAI_OVERWRITE, PANIC, PageHeaderData::pd_lower, PageHeaderData::pd_special, PageHeaderData::pd_upper, size, SizeOfPageHeaderData, upper(), VALGRIND_CHECK_MEM_IS_DEFINED, and WARNING.

◆ PageClearAllVisible()

static void PageClearAllVisible ( Page  page)
inlinestatic

◆ PageClearFull()

static void PageClearFull ( Page  page)
inlinestatic

Definition at line 423 of file bufpage.h.

425 {
426  ((PageHeader) page)->pd_flags &= ~PD_PAGE_FULL;
#define PD_PAGE_FULL
Definition: bufpage.h:188

References PD_PAGE_FULL.

Referenced by heap_page_prune_and_freeze(), and mask_page_hint_bits().

◆ PageClearHasFreeLinePointers()

static void PageClearHasFreeLinePointers ( Page  page)
inlinestatic

Definition at line 407 of file bufpage.h.

409 {
410  ((PageHeader) page)->pd_flags &= ~PD_HAS_FREE_LINES;
#define PD_HAS_FREE_LINES
Definition: bufpage.h:187

References PD_HAS_FREE_LINES.

Referenced by mask_page_hint_bits(), PageAddItemExtended(), PageRepairFragmentation(), and PageTruncateLinePointerArray().

◆ PageGetContents()

◆ PageGetExactFreeSpace()

Size PageGetExactFreeSpace ( Page  page)

Definition at line 947 of file bufpage.c.

948 {
949  int space;
950 
951  /*
952  * Use signed arithmetic here so that we behave sensibly if pd_lower >
953  * pd_upper.
954  */
955  space = (int) ((PageHeader) page)->pd_upper -
956  (int) ((PageHeader) page)->pd_lower;
957 
958  if (space < 0)
959  return 0;
960 
961  return (Size) space;
962 }

Referenced by _bt_bottomupdel_pass(), _bt_dedup_pass(), _bt_findsplitloc(), allocNewBuffer(), brin_can_do_samepage_update(), doPickSplit(), GetHashPageStats(), ginHeapTupleFastInsert(), pgstat_heap(), pgstat_index_page(), pgstatindex_impl(), spgAddNodeAction(), SpGistGetBuffer(), SpGistPageAddNewItem(), SpGistSetLastUsedPage(), statapprox_heap(), and writeListPage().

◆ PageGetFreeSpace()

Size PageGetFreeSpace ( Page  page)

Definition at line 896 of file bufpage.c.

897 {
898  int space;
899 
900  /*
901  * Use signed arithmetic here so that we behave sensibly if pd_lower >
902  * pd_upper.
903  */
904  space = (int) ((PageHeader) page)->pd_upper -
905  (int) ((PageHeader) page)->pd_lower;
906 
907  if (space < (int) sizeof(ItemIdData))
908  return 0;
909  space -= sizeof(ItemIdData);
910 
911  return (Size) space;
912 }

Referenced by _bt_buildadd(), _bt_delete_or_dedup_one_page(), _bt_findinsertloc(), _bt_insertonpg(), _bt_search_insert(), _hash_doinsert(), br_page_get_freespace(), entryIsEnoughSpace(), GetBTPageStatistics(), GetHashPageStatistics(), gist_indexsortbuild_levelstate_add(), gistnospace(), heap_xlog_visible(), PageGetHeapFreeSpace(), and terminate_brin_buildstate().

◆ PageGetFreeSpaceForMultipleTuples()

Size PageGetFreeSpaceForMultipleTuples ( Page  page,
int  ntups 
)

Definition at line 923 of file bufpage.c.

924 {
925  int space;
926 
927  /*
928  * Use signed arithmetic here so that we behave sensibly if pd_lower >
929  * pd_upper.
930  */
931  space = (int) ((PageHeader) page)->pd_upper -
932  (int) ((PageHeader) page)->pd_lower;
933 
934  if (space < (int) (ntups * sizeof(ItemIdData)))
935  return 0;
936  space -= ntups * sizeof(ItemIdData);
937 
938  return (Size) space;
939 }

Referenced by _hash_splitbucket(), and _hash_squeezebucket().

◆ PageGetHeapFreeSpace()

Size PageGetHeapFreeSpace ( Page  page)

Definition at line 980 of file bufpage.c.

981 {
982  Size space;
983 
984  space = PageGetFreeSpace(page);
985  if (space > 0)
986  {
987  OffsetNumber offnum,
988  nline;
989 
990  /*
991  * Are there already MaxHeapTuplesPerPage line pointers in the page?
992  */
993  nline = PageGetMaxOffsetNumber(page);
994  if (nline >= MaxHeapTuplesPerPage)
995  {
996  if (PageHasFreeLinePointers(page))
997  {
998  /*
999  * Since this is just a hint, we must confirm that there is
1000  * indeed a free line pointer
1001  */
1002  for (offnum = FirstOffsetNumber; offnum <= nline; offnum = OffsetNumberNext(offnum))
1003  {
1004  ItemId lp = PageGetItemId(page, offnum);
1005 
1006  if (!ItemIdIsUsed(lp))
1007  break;
1008  }
1009 
1010  if (offnum > nline)
1011  {
1012  /*
1013  * The hint is wrong, but we can't clear it here since we
1014  * don't have the ability to mark the page dirty.
1015  */
1016  space = 0;
1017  }
1018  }
1019  else
1020  {
1021  /*
1022  * Although the hint might be wrong, PageAddItem will believe
1023  * it anyway, so we must believe it too.
1024  */
1025  space = 0;
1026  }
1027  }
1028  }
1029  return space;
1030 }
Size PageGetFreeSpace(Page page)
Definition: bufpage.c:896

References FirstOffsetNumber, ItemIdIsUsed, MaxHeapTuplesPerPage, OffsetNumberNext, PageGetFreeSpace(), PageGetItemId(), PageGetMaxOffsetNumber(), and PageHasFreeLinePointers().

Referenced by heap_multi_insert(), heap_page_prune_opt(), heap_update(), heap_xlog_insert(), heap_xlog_multi_insert(), heap_xlog_prune_freeze(), heap_xlog_update(), lazy_scan_heap(), lazy_scan_new_or_empty(), lazy_vacuum_heap_rel(), raw_heap_insert(), and RelationGetBufferForTuple().

◆ PageGetItem()

static Item PageGetItem ( Page  page,
ItemId  itemId 
)
inlinestatic

Definition at line 354 of file bufpage.h.

356 {
357  Assert(page);
358  Assert(ItemIdHasStorage(itemId));
359 
360  return (Item) (((char *) page) + ItemIdGetOffset(itemId));
Pointer Item
Definition: item.h:17
#define ItemIdGetOffset(itemId)
Definition: itemid.h:65

References Assert, ItemIdGetOffset, and ItemIdHasStorage.

Referenced by _bt_afternewitemoff(), _bt_binsrch_posting(), _bt_bottomupdel_finish_pending(), _bt_bottomupdel_pass(), _bt_buildadd(), _bt_check_natts(), _bt_check_unique(), _bt_checkkeys_look_ahead(), _bt_compare(), _bt_deadblocks(), _bt_dedup_pass(), _bt_delitems_delete_check(), _bt_do_singleval(), _bt_get_endpoint(), _bt_getstackbuf(), _bt_insert_parent(), _bt_insertonpg(), _bt_killitems(), _bt_mark_page_halfdead(), _bt_newlevel(), _bt_pagedel(), _bt_readpage(), _bt_recsplitloc(), _bt_search(), _bt_simpledel_pass(), _bt_split(), _bt_split_firstright(), _bt_split_lastleft(), _bt_strategy(), _bt_unlink_halfdead_page(), _hash_binsearch(), _hash_binsearch_last(), _hash_finish_split(), _hash_kill_items(), _hash_load_qualified_items(), _hash_pgaddtup(), _hash_splitbucket(), _hash_squeezebucket(), addLeafTuple(), addOrReplaceTuple(), brin_doupdate(), brin_evacuate_page(), brin_page_items(), brinGetTupleForHeapBlock(), bt_check_level_from_leftmost(), bt_child_check(), bt_child_highkey_check(), bt_downlink_missing_check(), bt_page_print_tuples(), bt_right_page_check_scankey(), bt_target_page_check(), btree_xlog_dedup(), btree_xlog_insert(), btree_xlog_mark_page_halfdead(), btree_xlog_split(), btree_xlog_updates(), btvacuumpage(), checkSplitConditions(), collect_corrupt_items(), collectMatchBitmap(), collectMatchesForHeapRow(), doPickSplit(), entryFindChildPtr(), entryGetLeftMostPage(), entryIsEnoughSpace(), entryLocateEntry(), entryLocateLeafEntry(), entryPreparePage(), entrySplitPage(), GetBTPageStatistics(), getRightMostTuple(), ginbulkdelete(), ginEntryInsert(), ginRedoInsertEntry(), ginVacuumEntryPage(), gist_page_items(), gist_page_items_bytea(), gistBufferingFindCorrectParent(), gistbufferinginserttuples(), gistchoose(), gistdeletepage(), gistdoinsert(), gistextractpage(), gistFindCorrectParent(), gistFindPath(), gistformdownlink(), gistGetMaxLevel(), gistMemorizeAllDownlinks(), gistnospace(), gistProcessItup(), gistScanPage(), gistvacuum_delete_empty_pages(), gistvacuumpage(), hash_page_items(), hashbucketcleanup(), heap_abort_speculative(), heap_delete(), heap_fetch(), heap_finish_speculative(), heap_force_common(), heap_freeze_prepared_tuples(), heap_get_latest_tid(), heap_get_root_tuples(), heap_hot_search_buffer(), heap_index_delete_tuples(), heap_lock_tuple(), heap_page_is_all_visible(), heap_page_items(), heap_page_prune_and_freeze(), heap_page_prune_execute(), heap_pre_freeze_checks(), heap_prune_chain(), heap_prune_record_unchanged_lp_normal(), heap_update(), heap_xlog_confirm(), heap_xlog_delete(), heap_xlog_inplace(), heap_xlog_lock(), heap_xlog_lock_updated(), heap_xlog_prune_freeze(), heap_xlog_update(), heapam_scan_analyze_next_tuple(), heapam_scan_bitmap_next_block(), heapam_scan_bitmap_next_tuple(), heapam_scan_sample_next_tuple(), heapgettup(), heapgettup_pagemode(), index_compute_xid_horizon_for_tuples(), index_delete_check_htid(), invariant_l_nontarget_offset(), invariant_l_offset(), lazy_scan_noprune(), matchPartialInPendingList(), moveLeafs(), page_collect_tuples(), page_verify_redirects(), PageIndexTupleOverwrite(), processPendingPage(), raw_heap_insert(), read_seq_tuple(), RelationPutHeapTuple(), saveNodeLink(), scanGetCandidate(), ScanSourceDatabasePgClassPage(), setRedirectionTuple(), spgdoinsert(), SpGistPageAddNewItem(), spgprocesspending(), spgRedoAddLeaf(), spgRedoAddNode(), spgRedoMoveLeafs(), spgRedoPickSplit(), spgRedoVacuumLeaf(), spgRedoVacuumRedirect(), spgSplitNodeAction(), spgTestLeafTuple(), spgWalk(), startScanEntry(), statapprox_heap(), vacuumLeafPage(), vacuumLeafRoot(), vacuumRedirectAndPlaceholder(), and verify_heapam().

◆ PageGetItemId()

static ItemId PageGetItemId ( Page  page,
OffsetNumber  offsetNumber 
)
inlinestatic

Definition at line 243 of file bufpage.h.

245 {
246  return &((PageHeader) page)->pd_linp[offsetNumber - 1];

Referenced by _bt_afternewitemoff(), _bt_binsrch_posting(), _bt_bottomupdel_finish_pending(), _bt_bottomupdel_pass(), _bt_buildadd(), _bt_check_natts(), _bt_check_unique(), _bt_checkkeys_look_ahead(), _bt_compare(), _bt_deadblocks(), _bt_dedup_pass(), _bt_delete_or_dedup_one_page(), _bt_delitems_delete_check(), _bt_do_singleval(), _bt_findsplitloc(), _bt_get_endpoint(), _bt_getstackbuf(), _bt_insert_parent(), _bt_insertonpg(), _bt_killitems(), _bt_mark_page_halfdead(), _bt_newlevel(), _bt_pagedel(), _bt_readpage(), _bt_recsplitloc(), _bt_search(), _bt_simpledel_pass(), _bt_slideleft(), _bt_split(), _bt_split_firstright(), _bt_split_lastleft(), _bt_split_penalty(), _bt_strategy(), _bt_unlink_halfdead_page(), _hash_binsearch(), _hash_binsearch_last(), _hash_finish_split(), _hash_kill_items(), _hash_load_qualified_items(), _hash_pgaddtup(), _hash_splitbucket(), _hash_squeezebucket(), _hash_vacuum_one_page(), addLeafTuple(), addOrReplaceTuple(), brin_doupdate(), brin_evacuate_page(), brin_page_items(), brin_start_evacuating_page(), brinGetTupleForHeapBlock(), brininsert(), brinRevmapDesummarizeRange(), bt_page_print_tuples(), btree_xlog_dedup(), btree_xlog_insert(), btree_xlog_mark_page_halfdead(), btree_xlog_split(), btree_xlog_updates(), btvacuumpage(), checkSplitConditions(), collect_corrupt_items(), collectMatchBitmap(), collectMatchesForHeapRow(), compactify_tuples(), count_nondeletable_pages(), doPickSplit(), entryFindChildPtr(), entryGetLeftMostPage(), entryIsEnoughSpace(), entryLocateEntry(), entryLocateLeafEntry(), entryPreparePage(), entrySplitPage(), GetBTPageStatistics(), GetHashPageStatistics(), GetHashPageStats(), getRightMostTuple(), ginbulkdelete(), ginEntryInsert(), ginRedoInsertEntry(), ginVacuumEntryPage(), gist_page_items(), gist_page_items_bytea(), gistBufferingFindCorrectParent(), gistbufferinginserttuples(), gistchoose(), gistdeletepage(), gistdoinsert(), gistextractpage(), gistFindCorrectParent(), gistFindPath(), gistformdownlink(), gistGetMaxLevel(), gistkillitems(), gistMemorizeAllDownlinks(), gistnospace(), gistProcessItup(), gistprunepage(), gistScanPage(), gistvacuum_delete_empty_pages(), gistvacuumpage(), hash_page_items(), hashbucketcleanup(), heap_abort_speculative(), heap_delete(), heap_fetch(), heap_finish_speculative(), heap_force_common(), heap_freeze_prepared_tuples(), heap_get_latest_tid(), heap_get_root_tuples(), heap_hot_search_buffer(), heap_index_delete_tuples(), heap_lock_tuple(), heap_mask(), heap_page_is_all_visible(), heap_page_items(), heap_page_prune_and_freeze(), heap_page_prune_execute(), heap_pre_freeze_checks(), heap_prune_chain(), heap_prune_record_unchanged_lp_normal(), heap_update(), heap_xlog_confirm(), heap_xlog_delete(), heap_xlog_inplace(), heap_xlog_lock(), heap_xlog_lock_updated(), heap_xlog_prune_freeze(), heap_xlog_update(), heapam_scan_analyze_next_tuple(), heapam_scan_bitmap_next_block(), heapam_scan_bitmap_next_tuple(), heapam_scan_sample_next_tuple(), heapgettup(), heapgettup_pagemode(), index_compute_xid_horizon_for_tuples(), index_delete_check_htid(), lazy_scan_noprune(), lazy_vacuum_heap_page(), mask_lp_flags(), matchPartialInPendingList(), moveLeafs(), page_collect_tuples(), page_verify_redirects(), PageAddItemExtended(), PageGetHeapFreeSpace(), PageGetItemIdCareful(), PageIndexMultiDelete(), PageIndexTupleDelete(), PageIndexTupleDeleteNoCompact(), PageIndexTupleOverwrite(), PageRepairFragmentation(), PageTruncateLinePointerArray(), pgstat_index_page(), processPendingPage(), raw_heap_insert(), read_seq_tuple(), RelationPutHeapTuple(), saveNodeLink(), scanGetCandidate(), ScanSourceDatabasePgClassPage(), setRedirectionTuple(), spgdoinsert(), SpGistPageAddNewItem(), spgprocesspending(), spgRedoAddLeaf(), spgRedoAddNode(), spgRedoMoveLeafs(), spgRedoPickSplit(), spgRedoVacuumLeaf(), spgRedoVacuumRedirect(), spgSplitNodeAction(), spgTestLeafTuple(), spgWalk(), startScanEntry(), statapprox_heap(), vacuumLeafPage(), vacuumLeafRoot(), vacuumRedirectAndPlaceholder(), and verify_heapam().

◆ PageGetLSN()

◆ PageGetMaxOffsetNumber()

static OffsetNumber PageGetMaxOffsetNumber ( Page  page)
inlinestatic

Definition at line 372 of file bufpage.h.

374 {
375  PageHeader pageheader = (PageHeader) page;
376 
377  if (pageheader->pd_lower <= SizeOfPageHeaderData)
378  return 0;
379  else
380  return (pageheader->pd_lower - SizeOfPageHeaderData) / sizeof(ItemIdData);

References PageHeaderData::pd_lower, and SizeOfPageHeaderData.

Referenced by _bt_binsrch(), _bt_binsrch_insert(), _bt_bottomupdel_pass(), _bt_check_natts(), _bt_check_unique(), _bt_dedup_finish_pending(), _bt_dedup_pass(), _bt_delete_or_dedup_one_page(), _bt_do_singleval(), _bt_endpoint(), _bt_findinsertloc(), _bt_findsplitloc(), _bt_get_endpoint(), _bt_getstackbuf(), _bt_killitems(), _bt_lock_subtree_parent(), _bt_mark_page_halfdead(), _bt_pagedel(), _bt_readnextpage(), _bt_readpage(), _bt_search_insert(), _bt_slideleft(), _bt_split(), _bt_unlink_halfdead_page(), _hash_binsearch(), _hash_binsearch_last(), _hash_finish_split(), _hash_kill_items(), _hash_load_qualified_items(), _hash_pgaddtup(), _hash_splitbucket(), _hash_squeezebucket(), _hash_vacuum_one_page(), addOrReplaceTuple(), brin_doupdate(), brin_evacuate_page(), brin_page_items(), brin_start_evacuating_page(), brin_xlog_insert_update(), brinGetTupleForHeapBlock(), brinRevmapDesummarizeRange(), bt_child_check(), bt_child_highkey_check(), bt_page_items_bytea(), bt_page_items_internal(), bt_right_page_check_scankey(), bt_rootdescend(), bt_target_page_check(), btree_xlog_dedup(), btvacuumpage(), checkSplitConditions(), collect_corrupt_items(), compactify_tuples(), count_nondeletable_pages(), doPickSplit(), entryFindChildPtr(), entryGetLeftMostPage(), entryLocateEntry(), entryLocateLeafEntry(), entrySplitPage(), GetBTPageStatistics(), GetHashPageStatistics(), GetHashPageStats(), getRightMostTuple(), ginbulkdelete(), ginHeapTupleFastInsert(), ginInsertCleanup(), ginRedoInsertEntry(), ginRedoUpdateMetapage(), ginvacuumcleanup(), ginVacuumEntryPage(), ginVacuumPostingTreeLeaves(), gist_page_items(), gist_page_items_bytea(), gistBufferingFindCorrectParent(), gistbufferinginserttuples(), gistchoose(), gistdeletepage(), gistextractpage(), gistfillbuffer(), gistFindCorrectParent(), gistFindPath(), gistformdownlink(), gistMemorizeAllDownlinks(), gistprunepage(), gistRedoPageUpdateRecord(), gistScanPage(), gistvacuum_delete_empty_pages(), gistvacuumpage(), hash_page_items(), hashbucketcleanup(), heap_fetch(), heap_finish_speculative(), heap_force_common(), heap_get_latest_tid(), heap_get_root_tuples(), heap_hot_search_buffer(), heap_index_delete_tuples(), heap_insert(), heap_mask(), heap_multi_insert(), heap_page_is_all_visible(), heap_page_items(), heap_page_prune_and_freeze(), heap_prepare_pagescan(), heap_xlog_confirm(), heap_xlog_delete(), heap_xlog_inplace(), heap_xlog_insert(), heap_xlog_lock(), heap_xlog_lock_updated(), heap_xlog_multi_insert(), heap_xlog_update(), heapam_scan_analyze_next_tuple(), heapam_scan_bitmap_next_block(), heapam_scan_sample_next_tuple(), heapgettup_continue_page(), heapgettup_start_page(), lazy_scan_noprune(), log_heap_update(), mask_lp_flags(), moveLeafs(), moveRightIfItNeeded(), page_verify_redirects(), PageAddItemExtended(), PageGetHeapFreeSpace(), PageIndexMultiDelete(), PageIndexTupleDelete(), PageIndexTupleDeleteNoCompact(), PageIndexTupleOverwrite(), PageRepairFragmentation(), PageTruncateLinePointerArray(), palloc_btree_page(), pgstat_btree_page(), pgstat_gist_page(), pgstat_hash_page(), processPendingPage(), RelationGetBufferForTuple(), scanGetCandidate(), ScanSourceDatabasePgClassPage(), SpGistPageAddNewItem(), spgRedoVacuumRedirect(), spgWalk(), statapprox_heap(), vacuumLeafPage(), vacuumLeafRoot(), vacuumRedirectAndPlaceholder(), and verify_heapam().

◆ PageGetPageLayoutVersion()

static uint8 PageGetPageLayoutVersion ( Page  page)
inlinestatic

Definition at line 286 of file bufpage.h.

288 {
289  return (((PageHeader) page)->pd_pagesize_version & 0x00FF);

Referenced by page_header().

◆ PageGetPageSize()

static Size PageGetPageSize ( Page  page)
inlinestatic

◆ PageGetSpecialPointer()

static char* PageGetSpecialPointer ( Page  page)
inlinestatic

Definition at line 339 of file bufpage.h.

341 {
343  return (char *) page + ((PageHeader) page)->pd_special;
static void PageValidateSpecialPointer(Page page)
Definition: bufpage.h:327

References PageValidateSpecialPointer().

Referenced by fill_seq_fork_with_data(), ginRedoRecompress(), PageGetTempPageCopySpecial(), read_seq_tuple(), and seq_redo().

◆ PageGetSpecialSize()

static uint16 PageGetSpecialSize ( Page  page)
inlinestatic

◆ PageGetTempPage()

Page PageGetTempPage ( Page  page)

Definition at line 354 of file bufpage.c.

355 {
356  Size pageSize;
357  Page temp;
358 
359  pageSize = PageGetPageSize(page);
360  temp = (Page) palloc(pageSize);
361 
362  return temp;
363 }
Pointer Page
Definition: bufpage.h:81
void * palloc(Size size)
Definition: mcxt.c:1317

References PageGetPageSize(), and palloc().

Referenced by _bt_split(), dataSplitPageInternal(), and ginPlaceToPage().

◆ PageGetTempPageCopy()

Page PageGetTempPageCopy ( Page  page)

Definition at line 371 of file bufpage.c.

372 {
373  Size pageSize;
374  Page temp;
375 
376  pageSize = PageGetPageSize(page);
377  temp = (Page) palloc(pageSize);
378 
379  memcpy(temp, page, pageSize);
380 
381  return temp;
382 }

References PageGetPageSize(), and palloc().

Referenced by entrySplitPage(), and ginVacuumEntryPage().

◆ PageGetTempPageCopySpecial()

Page PageGetTempPageCopySpecial ( Page  page)

Definition at line 391 of file bufpage.c.

392 {
393  Size pageSize;
394  Page temp;
395 
396  pageSize = PageGetPageSize(page);
397  temp = (Page) palloc(pageSize);
398 
399  PageInit(temp, pageSize, PageGetSpecialSize(page));
400  memcpy(PageGetSpecialPointer(temp),
401  PageGetSpecialPointer(page),
402  PageGetSpecialSize(page));
403 
404  return temp;
405 }
void PageInit(Page page, Size pageSize, Size specialSize)
Definition: bufpage.c:42
static char * PageGetSpecialPointer(Page page)
Definition: bufpage.h:339
static uint16 PageGetSpecialSize(Page page)
Definition: bufpage.h:316

References PageGetPageSize(), PageGetSpecialPointer(), PageGetSpecialSize(), PageInit(), and palloc().

Referenced by _bt_dedup_pass(), btree_xlog_dedup(), btree_xlog_split(), and gistplacetopage().

◆ PageHasFreeLinePointers()

static bool PageHasFreeLinePointers ( Page  page)
inlinestatic

Definition at line 397 of file bufpage.h.

399 {
400  return ((PageHeader) page)->pd_flags & PD_HAS_FREE_LINES;

References PD_HAS_FREE_LINES.

Referenced by PageAddItemExtended(), and PageGetHeapFreeSpace().

◆ PageIndexMultiDelete()

void PageIndexMultiDelete ( Page  page,
OffsetNumber itemnos,
int  nitems 
)

Definition at line 1150 of file bufpage.c.

1151 {
1152  PageHeader phdr = (PageHeader) page;
1153  Offset pd_lower = phdr->pd_lower;
1154  Offset pd_upper = phdr->pd_upper;
1155  Offset pd_special = phdr->pd_special;
1156  Offset last_offset;
1158  ItemIdData newitemids[MaxIndexTuplesPerPage];
1159  itemIdCompact itemidptr;
1160  ItemId lp;
1161  int nline,
1162  nused;
1163  Size totallen;
1164  Size size;
1165  unsigned offset;
1166  int nextitm;
1167  OffsetNumber offnum;
1168  bool presorted = true; /* For now */
1169 
1171 
1172  /*
1173  * If there aren't very many items to delete, then retail
1174  * PageIndexTupleDelete is the best way. Delete the items in reverse
1175  * order so we don't have to think about adjusting item numbers for
1176  * previous deletions.
1177  *
1178  * TODO: tune the magic number here
1179  */
1180  if (nitems <= 2)
1181  {
1182  while (--nitems >= 0)
1183  PageIndexTupleDelete(page, itemnos[nitems]);
1184  return;
1185  }
1186 
1187  /*
1188  * As with PageRepairFragmentation, paranoia seems justified.
1189  */
1190  if (pd_lower < SizeOfPageHeaderData ||
1191  pd_lower > pd_upper ||
1192  pd_upper > pd_special ||
1193  pd_special > BLCKSZ ||
1194  pd_special != MAXALIGN(pd_special))
1195  ereport(ERROR,
1197  errmsg("corrupted page pointers: lower = %u, upper = %u, special = %u",
1198  pd_lower, pd_upper, pd_special)));
1199 
1200  /*
1201  * Scan the line pointer array and build a list of just the ones we are
1202  * going to keep. Notice we do not modify the page yet, since we are
1203  * still validity-checking.
1204  */
1205  nline = PageGetMaxOffsetNumber(page);
1206  itemidptr = itemidbase;
1207  totallen = 0;
1208  nused = 0;
1209  nextitm = 0;
1210  last_offset = pd_special;
1211  for (offnum = FirstOffsetNumber; offnum <= nline; offnum = OffsetNumberNext(offnum))
1212  {
1213  lp = PageGetItemId(page, offnum);
1214  Assert(ItemIdHasStorage(lp));
1215  size = ItemIdGetLength(lp);
1216  offset = ItemIdGetOffset(lp);
1217  if (offset < pd_upper ||
1218  (offset + size) > pd_special ||
1219  offset != MAXALIGN(offset))
1220  ereport(ERROR,
1222  errmsg("corrupted line pointer: offset = %u, size = %u",
1223  offset, (unsigned int) size)));
1224 
1225  if (nextitm < nitems && offnum == itemnos[nextitm])
1226  {
1227  /* skip item to be deleted */
1228  nextitm++;
1229  }
1230  else
1231  {
1232  itemidptr->offsetindex = nused; /* where it will go */
1233  itemidptr->itemoff = offset;
1234 
1235  if (last_offset > itemidptr->itemoff)
1236  last_offset = itemidptr->itemoff;
1237  else
1238  presorted = false;
1239 
1240  itemidptr->alignedlen = MAXALIGN(size);
1241  totallen += itemidptr->alignedlen;
1242  newitemids[nused] = *lp;
1243  itemidptr++;
1244  nused++;
1245  }
1246  }
1247 
1248  /* this will catch invalid or out-of-order itemnos[] */
1249  if (nextitm != nitems)
1250  elog(ERROR, "incorrect index offsets supplied");
1251 
1252  if (totallen > (Size) (pd_special - pd_lower))
1253  ereport(ERROR,
1255  errmsg("corrupted item lengths: total %u, available space %u",
1256  (unsigned int) totallen, pd_special - pd_lower)));
1257 
1258  /*
1259  * Looks good. Overwrite the line pointers with the copy, from which we've
1260  * removed all the unused items.
1261  */
1262  memcpy(phdr->pd_linp, newitemids, nused * sizeof(ItemIdData));
1263  phdr->pd_lower = SizeOfPageHeaderData + nused * sizeof(ItemIdData);
1264 
1265  /* and compactify the tuple data */
1266  if (nused > 0)
1267  compactify_tuples(itemidbase, nused, page, presorted);
1268  else
1269  phdr->pd_upper = pd_special;
1270 }
static void compactify_tuples(itemIdCompact itemidbase, int nitems, Page page, bool presorted)
Definition: bufpage.c:463
void PageIndexTupleDelete(Page page, OffsetNumber offnum)
Definition: bufpage.c:1041
signed int Offset
Definition: c.h:629
#define ERROR
Definition: elog.h:39
#define nitems(x)
Definition: indent.h:31
#define ItemIdGetLength(itemId)
Definition: itemid.h:59
#define MaxIndexTuplesPerPage
Definition: itup.h:165
ItemIdData pd_linp[FLEXIBLE_ARRAY_MEMBER]
Definition: bufpage.h:170
uint16 offsetindex
Definition: bufpage.c:428
uint16 alignedlen
Definition: bufpage.c:430

References itemIdCompactData::alignedlen, Assert, compactify_tuples(), elog, ereport, errcode(), ERRCODE_DATA_CORRUPTED, errmsg(), ERROR, FirstOffsetNumber, ItemIdGetLength, ItemIdGetOffset, ItemIdHasStorage, itemIdCompactData::itemoff, MAXALIGN, MaxIndexTuplesPerPage, nitems, itemIdCompactData::offsetindex, OffsetNumberNext, PageGetItemId(), PageGetMaxOffsetNumber(), PageIndexTupleDelete(), PageHeaderData::pd_linp, PageHeaderData::pd_lower, PageHeaderData::pd_special, PageHeaderData::pd_upper, size, and SizeOfPageHeaderData.

Referenced by _bt_delitems_delete(), _bt_delitems_vacuum(), _hash_squeezebucket(), _hash_vacuum_one_page(), btree_xlog_delete(), btree_xlog_vacuum(), gistprunepage(), gistRedoDeleteRecord(), gistRedoPageUpdateRecord(), gistvacuumpage(), hash_xlog_delete(), hash_xlog_move_page_contents(), hash_xlog_vacuum_one_page(), hashbucketcleanup(), spgPageIndexMultiDelete(), spgRedoVacuumRedirect(), spgRedoVacuumRoot(), vacuumLeafRoot(), and vacuumRedirectAndPlaceholder().

◆ PageIndexTupleDelete()

void PageIndexTupleDelete ( Page  page,
OffsetNumber  offnum 
)

Definition at line 1041 of file bufpage.c.

1042 {
1043  PageHeader phdr = (PageHeader) page;
1044  char *addr;
1045  ItemId tup;
1046  Size size;
1047  unsigned offset;
1048  int nbytes;
1049  int offidx;
1050  int nline;
1051 
1052  /*
1053  * As with PageRepairFragmentation, paranoia seems justified.
1054  */
1055  if (phdr->pd_lower < SizeOfPageHeaderData ||
1056  phdr->pd_lower > phdr->pd_upper ||
1057  phdr->pd_upper > phdr->pd_special ||
1058  phdr->pd_special > BLCKSZ ||
1059  phdr->pd_special != MAXALIGN(phdr->pd_special))
1060  ereport(ERROR,
1062  errmsg("corrupted page pointers: lower = %u, upper = %u, special = %u",
1063  phdr->pd_lower, phdr->pd_upper, phdr->pd_special)));
1064 
1065  nline = PageGetMaxOffsetNumber(page);
1066  if ((int) offnum <= 0 || (int) offnum > nline)
1067  elog(ERROR, "invalid index offnum: %u", offnum);
1068 
1069  /* change offset number to offset index */
1070  offidx = offnum - 1;
1071 
1072  tup = PageGetItemId(page, offnum);
1073  Assert(ItemIdHasStorage(tup));
1074  size = ItemIdGetLength(tup);
1075  offset = ItemIdGetOffset(tup);
1076 
1077  if (offset < phdr->pd_upper || (offset + size) > phdr->pd_special ||
1078  offset != MAXALIGN(offset))
1079  ereport(ERROR,
1081  errmsg("corrupted line pointer: offset = %u, size = %u",
1082  offset, (unsigned int) size)));
1083 
1084  /* Amount of space to actually be deleted */
1085  size = MAXALIGN(size);
1086 
1087  /*
1088  * First, we want to get rid of the pd_linp entry for the index tuple. We
1089  * copy all subsequent linp's back one slot in the array. We don't use
1090  * PageGetItemId, because we are manipulating the _array_, not individual
1091  * linp's.
1092  */
1093  nbytes = phdr->pd_lower -
1094  ((char *) &phdr->pd_linp[offidx + 1] - (char *) phdr);
1095 
1096  if (nbytes > 0)
1097  memmove((char *) &(phdr->pd_linp[offidx]),
1098  (char *) &(phdr->pd_linp[offidx + 1]),
1099  nbytes);
1100 
1101  /*
1102  * Now move everything between the old upper bound (beginning of tuple
1103  * space) and the beginning of the deleted tuple forward, so that space in
1104  * the middle of the page is left free. If we've just deleted the tuple
1105  * at the beginning of tuple space, then there's no need to do the copy.
1106  */
1107 
1108  /* beginning of tuple space */
1109  addr = (char *) page + phdr->pd_upper;
1110 
1111  if (offset > phdr->pd_upper)
1112  memmove(addr + size, addr, offset - phdr->pd_upper);
1113 
1114  /* adjust free space boundary pointers */
1115  phdr->pd_upper += size;
1116  phdr->pd_lower -= sizeof(ItemIdData);
1117 
1118  /*
1119  * Finally, we need to adjust the linp entries that remain.
1120  *
1121  * Anything that used to be before the deleted tuple's data was moved
1122  * forward by the size of the deleted tuple.
1123  */
1124  if (!PageIsEmpty(page))
1125  {
1126  int i;
1127 
1128  nline--; /* there's one less than when we started */
1129  for (i = 1; i <= nline; i++)
1130  {
1131  ItemId ii = PageGetItemId(page, i);
1132 
1133  Assert(ItemIdHasStorage(ii));
1134  if (ItemIdGetOffset(ii) <= offset)
1135  ii->lp_off += size;
1136  }
1137  }
1138 }
static bool PageIsEmpty(Page page)
Definition: bufpage.h:223
int i
Definition: isn.c:72
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:76
unsigned lp_off
Definition: itemid.h:27

References Assert, elog, ereport, errcode(), ERRCODE_DATA_CORRUPTED, errmsg(), ERROR, i, if(), ItemIdGetLength, ItemIdGetOffset, ItemIdHasStorage, ItemIdData::lp_off, MAXALIGN, PageGetItemId(), PageGetMaxOffsetNumber(), PageIsEmpty(), PageHeaderData::pd_linp, PageHeaderData::pd_lower, PageHeaderData::pd_special, PageHeaderData::pd_upper, size, and SizeOfPageHeaderData.

Referenced by _bt_mark_page_halfdead(), addLeafTuple(), addOrReplaceTuple(), btree_xlog_mark_page_halfdead(), entryPreparePage(), ginRedoInsertEntry(), ginVacuumEntryPage(), gistdeletepage(), gistplacetopage(), gistRedoPageDelete(), PageIndexMultiDelete(), spgAddNodeAction(), SpGistPageAddNewItem(), spgRedoAddLeaf(), spgRedoAddNode(), spgRedoSplitTuple(), and spgSplitNodeAction().

◆ PageIndexTupleDeleteNoCompact()

void PageIndexTupleDeleteNoCompact ( Page  page,
OffsetNumber  offnum 
)

Definition at line 1284 of file bufpage.c.

1285 {
1286  PageHeader phdr = (PageHeader) page;
1287  char *addr;
1288  ItemId tup;
1289  Size size;
1290  unsigned offset;
1291  int nline;
1292 
1293  /*
1294  * As with PageRepairFragmentation, paranoia seems justified.
1295  */
1296  if (phdr->pd_lower < SizeOfPageHeaderData ||
1297  phdr->pd_lower > phdr->pd_upper ||
1298  phdr->pd_upper > phdr->pd_special ||
1299  phdr->pd_special > BLCKSZ ||
1300  phdr->pd_special != MAXALIGN(phdr->pd_special))
1301  ereport(ERROR,
1303  errmsg("corrupted page pointers: lower = %u, upper = %u, special = %u",
1304  phdr->pd_lower, phdr->pd_upper, phdr->pd_special)));
1305 
1306  nline = PageGetMaxOffsetNumber(page);
1307  if ((int) offnum <= 0 || (int) offnum > nline)
1308  elog(ERROR, "invalid index offnum: %u", offnum);
1309 
1310  tup = PageGetItemId(page, offnum);
1311  Assert(ItemIdHasStorage(tup));
1312  size = ItemIdGetLength(tup);
1313  offset = ItemIdGetOffset(tup);
1314 
1315  if (offset < phdr->pd_upper || (offset + size) > phdr->pd_special ||
1316  offset != MAXALIGN(offset))
1317  ereport(ERROR,
1319  errmsg("corrupted line pointer: offset = %u, size = %u",
1320  offset, (unsigned int) size)));
1321 
1322  /* Amount of space to actually be deleted */
1323  size = MAXALIGN(size);
1324 
1325  /*
1326  * Either set the line pointer to "unused", or zap it if it's the last
1327  * one. (Note: it's possible that the next-to-last one(s) are already
1328  * unused, but we do not trouble to try to compact them out if so.)
1329  */
1330  if ((int) offnum < nline)
1331  ItemIdSetUnused(tup);
1332  else
1333  {
1334  phdr->pd_lower -= sizeof(ItemIdData);
1335  nline--; /* there's one less than when we started */
1336  }
1337 
1338  /*
1339  * Now move everything between the old upper bound (beginning of tuple
1340  * space) and the beginning of the deleted tuple forward, so that space in
1341  * the middle of the page is left free. If we've just deleted the tuple
1342  * at the beginning of tuple space, then there's no need to do the copy.
1343  */
1344 
1345  /* beginning of tuple space */
1346  addr = (char *) page + phdr->pd_upper;
1347 
1348  if (offset > phdr->pd_upper)
1349  memmove(addr + size, addr, offset - phdr->pd_upper);
1350 
1351  /* adjust free space boundary pointer */
1352  phdr->pd_upper += size;
1353 
1354  /*
1355  * Finally, we need to adjust the linp entries that remain.
1356  *
1357  * Anything that used to be before the deleted tuple's data was moved
1358  * forward by the size of the deleted tuple.
1359  */
1360  if (!PageIsEmpty(page))
1361  {
1362  int i;
1363 
1364  for (i = 1; i <= nline; i++)
1365  {
1366  ItemId ii = PageGetItemId(page, i);
1367 
1368  if (ItemIdHasStorage(ii) && ItemIdGetOffset(ii) <= offset)
1369  ii->lp_off += size;
1370  }
1371  }
1372 }
#define ItemIdSetUnused(itemId)
Definition: itemid.h:128

References Assert, elog, ereport, errcode(), ERRCODE_DATA_CORRUPTED, errmsg(), ERROR, i, if(), ItemIdGetLength, ItemIdGetOffset, ItemIdHasStorage, ItemIdSetUnused, ItemIdData::lp_off, MAXALIGN, PageGetItemId(), PageGetMaxOffsetNumber(), PageIsEmpty(), PageHeaderData::pd_lower, PageHeaderData::pd_special, PageHeaderData::pd_upper, size, and SizeOfPageHeaderData.

Referenced by brin_doupdate(), brin_xlog_desummarize_page(), brin_xlog_update(), and brinRevmapDesummarizeRange().

◆ PageIndexTupleOverwrite()

bool PageIndexTupleOverwrite ( Page  page,
OffsetNumber  offnum,
Item  newtup,
Size  newsize 
)

Definition at line 1394 of file bufpage.c.

1396 {
1397  PageHeader phdr = (PageHeader) page;
1398  ItemId tupid;
1399  int oldsize;
1400  unsigned offset;
1401  Size alignednewsize;
1402  int size_diff;
1403  int itemcount;
1404 
1405  /*
1406  * As with PageRepairFragmentation, paranoia seems justified.
1407  */
1408  if (phdr->pd_lower < SizeOfPageHeaderData ||
1409  phdr->pd_lower > phdr->pd_upper ||
1410  phdr->pd_upper > phdr->pd_special ||
1411  phdr->pd_special > BLCKSZ ||
1412  phdr->pd_special != MAXALIGN(phdr->pd_special))
1413  ereport(ERROR,
1415  errmsg("corrupted page pointers: lower = %u, upper = %u, special = %u",
1416  phdr->pd_lower, phdr->pd_upper, phdr->pd_special)));
1417 
1418  itemcount = PageGetMaxOffsetNumber(page);
1419  if ((int) offnum <= 0 || (int) offnum > itemcount)
1420  elog(ERROR, "invalid index offnum: %u", offnum);
1421 
1422  tupid = PageGetItemId(page, offnum);
1423  Assert(ItemIdHasStorage(tupid));
1424  oldsize = ItemIdGetLength(tupid);
1425  offset = ItemIdGetOffset(tupid);
1426 
1427  if (offset < phdr->pd_upper || (offset + oldsize) > phdr->pd_special ||
1428  offset != MAXALIGN(offset))
1429  ereport(ERROR,
1431  errmsg("corrupted line pointer: offset = %u, size = %u",
1432  offset, (unsigned int) oldsize)));
1433 
1434  /*
1435  * Determine actual change in space requirement, check for page overflow.
1436  */
1437  oldsize = MAXALIGN(oldsize);
1438  alignednewsize = MAXALIGN(newsize);
1439  if (alignednewsize > oldsize + (phdr->pd_upper - phdr->pd_lower))
1440  return false;
1441 
1442  /*
1443  * Relocate existing data and update line pointers, unless the new tuple
1444  * is the same size as the old (after alignment), in which case there's
1445  * nothing to do. Notice that what we have to relocate is data before the
1446  * target tuple, not data after, so it's convenient to express size_diff
1447  * as the amount by which the tuple's size is decreasing, making it the
1448  * delta to add to pd_upper and affected line pointers.
1449  */
1450  size_diff = oldsize - (int) alignednewsize;
1451  if (size_diff != 0)
1452  {
1453  char *addr = (char *) page + phdr->pd_upper;
1454  int i;
1455 
1456  /* relocate all tuple data before the target tuple */
1457  memmove(addr + size_diff, addr, offset - phdr->pd_upper);
1458 
1459  /* adjust free space boundary pointer */
1460  phdr->pd_upper += size_diff;
1461 
1462  /* adjust affected line pointers too */
1463  for (i = FirstOffsetNumber; i <= itemcount; i++)
1464  {
1465  ItemId ii = PageGetItemId(page, i);
1466 
1467  /* Allow items without storage; currently only BRIN needs that */
1468  if (ItemIdHasStorage(ii) && ItemIdGetOffset(ii) <= offset)
1469  ii->lp_off += size_diff;
1470  }
1471  }
1472 
1473  /* Update the item's tuple length without changing its lp_flags field */
1474  tupid->lp_off = offset + size_diff;
1475  tupid->lp_len = newsize;
1476 
1477  /* Copy new tuple data onto page */
1478  memcpy(PageGetItem(page, tupid), newtup, newsize);
1479 
1480  return true;
1481 }
static Item PageGetItem(Page page, ItemId itemId)
Definition: bufpage.h:354
unsigned lp_len
Definition: itemid.h:29

References Assert, elog, ereport, errcode(), ERRCODE_DATA_CORRUPTED, errmsg(), ERROR, FirstOffsetNumber, i, ItemIdGetLength, ItemIdGetOffset, ItemIdHasStorage, ItemIdData::lp_len, ItemIdData::lp_off, MAXALIGN, PageGetItem(), PageGetItemId(), PageGetMaxOffsetNumber(), PageHeaderData::pd_lower, PageHeaderData::pd_special, PageHeaderData::pd_upper, and SizeOfPageHeaderData.

Referenced by _bt_buildadd(), _bt_delitems_delete(), _bt_delitems_vacuum(), _bt_mark_page_halfdead(), brin_doupdate(), brin_xlog_samepage_update(), btree_xlog_updates(), gistplacetopage(), and gistRedoPageUpdateRecord().

◆ PageInit()

void PageInit ( Page  page,
Size  pageSize,
Size  specialSize 
)

Definition at line 42 of file bufpage.c.

43 {
44  PageHeader p = (PageHeader) page;
45 
46  specialSize = MAXALIGN(specialSize);
47 
48  Assert(pageSize == BLCKSZ);
49  Assert(pageSize > specialSize + SizeOfPageHeaderData);
50 
51  /* Make sure all fields of page are zero, as well as unused space */
52  MemSet(p, 0, pageSize);
53 
54  p->pd_flags = 0;
56  p->pd_upper = pageSize - specialSize;
57  p->pd_special = pageSize - specialSize;
59  /* p->pd_prune_xid = InvalidTransactionId; done by above MemSet */
60 }
#define PG_PAGE_LAYOUT_VERSION
Definition: bufpage.h:205
static void PageSetPageSizeAndVersion(Page page, Size size, uint8 version)
Definition: bufpage.h:299
#define MemSet(start, val, len)
Definition: c.h:1025
uint16 pd_flags
Definition: bufpage.h:164

References Assert, MAXALIGN, MemSet, PageSetPageSizeAndVersion(), PageHeaderData::pd_flags, PageHeaderData::pd_lower, PageHeaderData::pd_special, PageHeaderData::pd_upper, PG_PAGE_LAYOUT_VERSION, and SizeOfPageHeaderData.

Referenced by _bt_pageinit(), _hash_pageinit(), BloomInitPage(), brin_page_init(), fill_seq_fork_with_data(), fsm_readbuf(), GinInitPage(), gistinitpage(), heap_xlog_insert(), heap_xlog_multi_insert(), heap_xlog_update(), heap_xlog_visible(), PageGetTempPageCopySpecial(), raw_heap_insert(), RelationAddBlocks(), RelationGetBufferForTuple(), seq_redo(), SpGistInitPage(), vm_readbuf(), and XLogRecordPageWithFreeSpace().

◆ PageIsAllVisible()

◆ PageIsEmpty()

◆ PageIsFull()

static bool PageIsFull ( Page  page)
inlinestatic

Definition at line 413 of file bufpage.h.

415 {
416  return ((PageHeader) page)->pd_flags & PD_PAGE_FULL;

References PD_PAGE_FULL.

Referenced by heap_page_prune_and_freeze(), and heap_page_prune_opt().

◆ PageIsNew()

static bool PageIsNew ( Page  page)
inlinestatic

Definition at line 233 of file bufpage.h.

235 {
236  return ((PageHeader) page)->pd_upper == 0;

Referenced by _bt_allocbuf(), _bt_checkpage(), _hash_checkpage(), blbulkdelete(), blgetbitmap(), blinsert(), BloomNewBuffer(), BloomPageAddItem(), blvacuumcleanup(), brin_metapage_info(), brin_page_cleanup(), brin_page_items(), brin_page_type(), brin_revmap_data(), brin_start_evacuating_page(), bt_page_items_bytea(), BTPageGetDeleteXid(), BTPageIsRecyclable(), btvacuumpage(), count_nondeletable_pages(), ExtendBufferedRelShared(), fsm_page_contents(), fsm_readbuf(), gin_leafpage_items(), gin_metapage_info(), gin_page_opaque_info(), GinPageIsRecyclable(), gist_page_items(), gist_page_items_bytea(), gist_page_opaque_info(), gistcheckpage(), gistdeletepage(), gistNewBuffer(), gistPageRecyclable(), gistvacuum_delete_empty_pages(), hash_page_type(), heap_xlog_visible(), lazy_scan_new_or_empty(), log_newpage(), log_newpage_range(), log_newpages(), page_checksum_internal(), PageIsVerifiedExtended(), PageSetChecksumCopy(), PageSetChecksumInplace(), pg_checksum_page(), pgstat_btree_page(), pgstathashindex(), RelationAddBlocks(), RelationGetBufferForTuple(), revmap_physical_extend(), scan_file(), ScanSourceDatabasePgClass(), SpGistGetBuffer(), SpGistNewBuffer(), spgprocesspending(), spgvacuumpage(), statapprox_heap(), verify_brin_page(), verify_gist_page(), verify_hash_page(), verify_page_checksum(), vm_readbuf(), XLogReadBufferExtended(), XLogReadBufferForRedoExtended(), and XLogRecordPageWithFreeSpace().

◆ PageIsVerifiedExtended()

bool PageIsVerifiedExtended ( Page  page,
BlockNumber  blkno,
int  flags 
)

Definition at line 88 of file bufpage.c.

89 {
90  PageHeader p = (PageHeader) page;
91  size_t *pagebytes;
92  bool checksum_failure = false;
93  bool header_sane = false;
94  uint16 checksum = 0;
95 
96  /*
97  * Don't verify page data unless the page passes basic non-zero test
98  */
99  if (!PageIsNew(page))
100  {
101  if (DataChecksumsEnabled())
102  {
103  checksum = pg_checksum_page((char *) page, blkno);
104 
105  if (checksum != p->pd_checksum)
106  checksum_failure = true;
107  }
108 
109  /*
110  * The following checks don't prove the header is correct, only that
111  * it looks sane enough to allow into the buffer pool. Later usage of
112  * the block can still reveal problems, which is why we offer the
113  * checksum option.
114  */
115  if ((p->pd_flags & ~PD_VALID_FLAG_BITS) == 0 &&
116  p->pd_lower <= p->pd_upper &&
117  p->pd_upper <= p->pd_special &&
118  p->pd_special <= BLCKSZ &&
119  p->pd_special == MAXALIGN(p->pd_special))
120  header_sane = true;
121 
122  if (header_sane && !checksum_failure)
123  return true;
124  }
125 
126  /* Check all-zeroes case */
127  pagebytes = (size_t *) page;
128 
129  if (pg_memory_is_all_zeros(pagebytes, BLCKSZ))
130  return true;
131 
132  /*
133  * Throw a WARNING if the checksum fails, but only after we've checked for
134  * the all-zeroes case.
135  */
136  if (checksum_failure)
137  {
138  if ((flags & PIV_LOG_WARNING) != 0)
141  errmsg("page verification failed, calculated checksum %u but expected %u",
142  checksum, p->pd_checksum)));
143 
144  if ((flags & PIV_REPORT_STAT) != 0)
146 
147  if (header_sane && ignore_checksum_failure)
148  return true;
149  }
150 
151  return false;
152 }
bool ignore_checksum_failure
Definition: bufpage.c:27
#define PD_VALID_FLAG_BITS
Definition: bufpage.h:191
static bool PageIsNew(Page page)
Definition: bufpage.h:233
uint16 pg_checksum_page(char *page, BlockNumber blkno)
static bool pg_memory_is_all_zeros(const void *ptr, size_t len)
Definition: memutils.h:219
static bool checksum_failure
void pgstat_report_checksum_failure(void)
uint16 pd_checksum
Definition: bufpage.h:163
bool DataChecksumsEnabled(void)
Definition: xlog.c:4588

References checksum_failure, DataChecksumsEnabled(), ereport, errcode(), ERRCODE_DATA_CORRUPTED, errmsg(), ignore_checksum_failure, MAXALIGN, PageIsNew(), PageHeaderData::pd_checksum, PageHeaderData::pd_flags, PageHeaderData::pd_lower, PageHeaderData::pd_special, PageHeaderData::pd_upper, PD_VALID_FLAG_BITS, pg_checksum_page(), pg_memory_is_all_zeros(), pgstat_report_checksum_failure(), PIV_LOG_WARNING, PIV_REPORT_STAT, and WARNING.

Referenced by RelationCopyStorage(), and WaitReadBuffers().

◆ PageRepairFragmentation()

void PageRepairFragmentation ( Page  page)

Definition at line 688 of file bufpage.c.

689 {
690  Offset pd_lower = ((PageHeader) page)->pd_lower;
691  Offset pd_upper = ((PageHeader) page)->pd_upper;
692  Offset pd_special = ((PageHeader) page)->pd_special;
693  Offset last_offset;
695  itemIdCompact itemidptr;
696  ItemId lp;
697  int nline,
698  nstorage,
699  nunused;
700  OffsetNumber finalusedlp = InvalidOffsetNumber;
701  int i;
702  Size totallen;
703  bool presorted = true; /* For now */
704 
705  /*
706  * It's worth the trouble to be more paranoid here than in most places,
707  * because we are about to reshuffle data in (what is usually) a shared
708  * disk buffer. If we aren't careful then corrupted pointers, lengths,
709  * etc could cause us to clobber adjacent disk buffers, spreading the data
710  * loss further. So, check everything.
711  */
712  if (pd_lower < SizeOfPageHeaderData ||
713  pd_lower > pd_upper ||
714  pd_upper > pd_special ||
715  pd_special > BLCKSZ ||
716  pd_special != MAXALIGN(pd_special))
717  ereport(ERROR,
719  errmsg("corrupted page pointers: lower = %u, upper = %u, special = %u",
720  pd_lower, pd_upper, pd_special)));
721 
722  /*
723  * Run through the line pointer array and collect data about live items.
724  */
725  nline = PageGetMaxOffsetNumber(page);
726  itemidptr = itemidbase;
727  nunused = totallen = 0;
728  last_offset = pd_special;
729  for (i = FirstOffsetNumber; i <= nline; i++)
730  {
731  lp = PageGetItemId(page, i);
732  if (ItemIdIsUsed(lp))
733  {
734  if (ItemIdHasStorage(lp))
735  {
736  itemidptr->offsetindex = i - 1;
737  itemidptr->itemoff = ItemIdGetOffset(lp);
738 
739  if (last_offset > itemidptr->itemoff)
740  last_offset = itemidptr->itemoff;
741  else
742  presorted = false;
743 
744  if (unlikely(itemidptr->itemoff < (int) pd_upper ||
745  itemidptr->itemoff >= (int) pd_special))
746  ereport(ERROR,
748  errmsg("corrupted line pointer: %u",
749  itemidptr->itemoff)));
750  itemidptr->alignedlen = MAXALIGN(ItemIdGetLength(lp));
751  totallen += itemidptr->alignedlen;
752  itemidptr++;
753  }
754 
755  finalusedlp = i; /* Could be the final non-LP_UNUSED item */
756  }
757  else
758  {
759  /* Unused entries should have lp_len = 0, but make sure */
760  Assert(!ItemIdHasStorage(lp));
761  ItemIdSetUnused(lp);
762  nunused++;
763  }
764  }
765 
766  nstorage = itemidptr - itemidbase;
767  if (nstorage == 0)
768  {
769  /* Page is completely empty, so just reset it quickly */
770  ((PageHeader) page)->pd_upper = pd_special;
771  }
772  else
773  {
774  /* Need to compact the page the hard way */
775  if (totallen > (Size) (pd_special - pd_lower))
776  ereport(ERROR,
778  errmsg("corrupted item lengths: total %u, available space %u",
779  (unsigned int) totallen, pd_special - pd_lower)));
780 
781  compactify_tuples(itemidbase, nstorage, page, presorted);
782  }
783 
784  if (finalusedlp != nline)
785  {
786  /* The last line pointer is not the last used line pointer */
787  int nunusedend = nline - finalusedlp;
788 
789  Assert(nunused >= nunusedend && nunusedend > 0);
790 
791  /* remove trailing unused line pointers from the count */
792  nunused -= nunusedend;
793  /* truncate the line pointer array */
794  ((PageHeader) page)->pd_lower -= (sizeof(ItemIdData) * nunusedend);
795  }
796 
797  /* Set hint bit for PageAddItemExtended */
798  if (nunused > 0)
800  else
802 }
static void PageSetHasFreeLinePointers(Page page)
Definition: bufpage.h:402
#define unlikely(x)
Definition: c.h:326

References itemIdCompactData::alignedlen, Assert, compactify_tuples(), ereport, errcode(), ERRCODE_DATA_CORRUPTED, errmsg(), ERROR, FirstOffsetNumber, i, InvalidOffsetNumber, ItemIdGetLength, ItemIdGetOffset, ItemIdHasStorage, ItemIdIsUsed, ItemIdSetUnused, itemIdCompactData::itemoff, MAXALIGN, MaxHeapTuplesPerPage, itemIdCompactData::offsetindex, PageClearHasFreeLinePointers(), PageGetItemId(), PageGetMaxOffsetNumber(), PageSetHasFreeLinePointers(), SizeOfPageHeaderData, and unlikely.

Referenced by heap_page_prune_execute().

◆ PageRestoreTempPage()

void PageRestoreTempPage ( Page  tempPage,
Page  oldPage 
)

Definition at line 413 of file bufpage.c.

414 {
415  Size pageSize;
416 
417  pageSize = PageGetPageSize(tempPage);
418  memcpy((char *) oldPage, (char *) tempPage, pageSize);
419 
420  pfree(tempPage);
421 }
void pfree(void *pointer)
Definition: mcxt.c:1521

References PageGetPageSize(), and pfree().

Referenced by _bt_dedup_pass(), _bt_split(), btree_xlog_dedup(), btree_xlog_split(), createPostingTree(), ginbulkdelete(), and gistplacetopage().

◆ PageSetAllVisible()

static void PageSetAllVisible ( Page  page)
inlinestatic

◆ PageSetChecksumCopy()

char* PageSetChecksumCopy ( Page  page,
BlockNumber  blkno 
)

Definition at line 1499 of file bufpage.c.

1500 {
1501  static char *pageCopy = NULL;
1502 
1503  /* If we don't need a checksum, just return the passed-in data */
1504  if (PageIsNew(page) || !DataChecksumsEnabled())
1505  return (char *) page;
1506 
1507  /*
1508  * We allocate the copy space once and use it over on each subsequent
1509  * call. The point of palloc'ing here, rather than having a static char
1510  * array, is first to ensure adequate alignment for the checksumming code
1511  * and second to avoid wasting space in processes that never call this.
1512  */
1513  if (pageCopy == NULL)
1515  BLCKSZ,
1517  0);
1518 
1519  memcpy(pageCopy, (char *) page, BLCKSZ);
1520  ((PageHeader) pageCopy)->pd_checksum = pg_checksum_page(pageCopy, blkno);
1521  return pageCopy;
1522 }
void * MemoryContextAllocAligned(MemoryContext context, Size size, Size alignto, int flags)
Definition: mcxt.c:1409
MemoryContext TopMemoryContext
Definition: mcxt.c:149
#define PG_IO_ALIGN_SIZE

References DataChecksumsEnabled(), MemoryContextAllocAligned(), PageIsNew(), pg_checksum_page(), PG_IO_ALIGN_SIZE, and TopMemoryContext.

Referenced by FlushBuffer().

◆ PageSetChecksumInplace()

void PageSetChecksumInplace ( Page  page,
BlockNumber  blkno 
)

Definition at line 1531 of file bufpage.c.

1532 {
1533  /* If we don't need a checksum, just return */
1534  if (PageIsNew(page) || !DataChecksumsEnabled())
1535  return;
1536 
1537  ((PageHeader) page)->pd_checksum = pg_checksum_page((char *) page, blkno);
1538 }

References DataChecksumsEnabled(), PageIsNew(), and pg_checksum_page().

Referenced by _hash_alloc_buckets(), FlushRelationBuffers(), GetLocalVictimBuffer(), and smgr_bulk_flush().

◆ PageSetFull()

static void PageSetFull ( Page  page)
inlinestatic

Definition at line 418 of file bufpage.h.

420 {
421  ((PageHeader) page)->pd_flags |= PD_PAGE_FULL;

References PD_PAGE_FULL.

Referenced by heap_update().

◆ PageSetHasFreeLinePointers()

static void PageSetHasFreeLinePointers ( Page  page)
inlinestatic

Definition at line 402 of file bufpage.h.

404 {
405  ((PageHeader) page)->pd_flags |= PD_HAS_FREE_LINES;

References PD_HAS_FREE_LINES.

Referenced by PageRepairFragmentation(), and PageTruncateLinePointerArray().

◆ PageSetLSN()

static void PageSetLSN ( Page  page,
XLogRecPtr  lsn 
)
inlinestatic

Definition at line 391 of file bufpage.h.

393 {
394  PageXLogRecPtrSet(((PageHeader) page)->pd_lsn, lsn);
#define PageXLogRecPtrSet(ptr, lsn)
Definition: bufpage.h:109

References PageXLogRecPtrSet.

Referenced by _bt_clear_incomplete_split(), _bt_dedup_pass(), _bt_delitems_delete(), _bt_delitems_vacuum(), _bt_getroot(), _bt_insertonpg(), _bt_mark_page_halfdead(), _bt_newlevel(), _bt_restore_meta(), _bt_set_cleanup_info(), _bt_split(), _bt_unlink_halfdead_page(), _hash_addovflpage(), _hash_doinsert(), _hash_expandtable(), _hash_freeovflpage(), _hash_init(), _hash_splitbucket(), _hash_squeezebucket(), _hash_vacuum_one_page(), addLeafTuple(), brin_doinsert(), brin_doupdate(), brin_xlog_createidx(), brin_xlog_desummarize_page(), brin_xlog_insert_update(), brin_xlog_revmap_extend(), brin_xlog_samepage_update(), brin_xlog_update(), brinbuild(), brinRevmapDesummarizeRange(), btree_xlog_dedup(), btree_xlog_delete(), btree_xlog_insert(), btree_xlog_mark_page_halfdead(), btree_xlog_newroot(), btree_xlog_split(), btree_xlog_unlink_page(), btree_xlog_vacuum(), createPostingTree(), do_setval(), doPickSplit(), fill_seq_fork_with_data(), generic_redo(), GenericXLogFinish(), ginDeletePage(), ginHeapTupleFastInsert(), ginPlaceToPage(), ginRedoClearIncompleteSplit(), ginRedoCreatePTree(), ginRedoDeleteListPages(), ginRedoDeletePage(), ginRedoInsert(), ginRedoInsertListPage(), ginRedoUpdateMetapage(), ginRedoVacuumDataLeafPage(), ginUpdateStats(), ginVacuumPostingTreeLeaf(), gist_indexsortbuild(), gist_indexsortbuild_levelstate_flush(), gistbuild(), gistdeletepage(), gistplacetopage(), gistprunepage(), gistRedoClearFollowRight(), gistRedoDeleteRecord(), gistRedoPageDelete(), gistRedoPageSplitRecord(), gistRedoPageUpdateRecord(), gistvacuumpage(), hash_xlog_add_ovfl_page(), hash_xlog_delete(), hash_xlog_init_bitmap_page(), hash_xlog_init_meta_page(), hash_xlog_insert(), hash_xlog_move_page_contents(), hash_xlog_split_allocate_page(), hash_xlog_split_cleanup(), hash_xlog_split_complete(), hash_xlog_squeeze_page(), hash_xlog_update_meta_page(), hash_xlog_vacuum_one_page(), hashbucketcleanup(), hashbulkdelete(), heap_abort_speculative(), heap_delete(), heap_finish_speculative(), heap_inplace_update_and_unlock(), heap_insert(), heap_lock_tuple(), heap_lock_updated_tuple_rec(), heap_multi_insert(), heap_update(), heap_xlog_confirm(), heap_xlog_delete(), heap_xlog_inplace(), heap_xlog_insert(), heap_xlog_lock(), heap_xlog_lock_updated(), heap_xlog_multi_insert(), heap_xlog_prune_freeze(), heap_xlog_update(), heap_xlog_visible(), log_heap_prune_and_freeze(), log_newpage(), log_newpage_range(), log_newpages(), log_split_page(), MarkBufferDirtyHint(), moveLeafs(), nextval_internal(), revmap_physical_extend(), seq_redo(), shiftList(), spgAddNodeAction(), spgRedoAddLeaf(), spgRedoAddNode(), spgRedoMoveLeafs(), spgRedoPickSplit(), spgRedoSplitTuple(), spgRedoVacuumLeaf(), spgRedoVacuumRedirect(), spgRedoVacuumRoot(), spgSplitNodeAction(), vacuumLeafPage(), vacuumLeafRoot(), vacuumRedirectAndPlaceholder(), visibilitymap_set(), writeListPage(), XLogReadBufferForRedoExtended(), and xlogVacuumPage().

◆ PageSetPageSizeAndVersion()

static void PageSetPageSizeAndVersion ( Page  page,
Size  size,
uint8  version 
)
inlinestatic

Definition at line 299 of file bufpage.h.

301 {
302  Assert((size & 0xFF00) == size);
303  Assert((version & 0x00FF) == version);
304 
305  ((PageHeader) page)->pd_pagesize_version = size | version;

References Assert, and size.

Referenced by PageInit().

◆ PageTruncateLinePointerArray()

void PageTruncateLinePointerArray ( Page  page)

Definition at line 824 of file bufpage.c.

825 {
826  PageHeader phdr = (PageHeader) page;
827  bool countdone = false,
828  sethint = false;
829  int nunusedend = 0;
830 
831  /* Scan line pointer array back-to-front */
832  for (int i = PageGetMaxOffsetNumber(page); i >= FirstOffsetNumber; i--)
833  {
834  ItemId lp = PageGetItemId(page, i);
835 
836  if (!countdone && i > FirstOffsetNumber)
837  {
838  /*
839  * Still determining which line pointers from the end of the array
840  * will be truncated away. Either count another line pointer as
841  * safe to truncate, or notice that it's not safe to truncate
842  * additional line pointers (stop counting line pointers).
843  */
844  if (!ItemIdIsUsed(lp))
845  nunusedend++;
846  else
847  countdone = true;
848  }
849  else
850  {
851  /*
852  * Once we've stopped counting we still need to figure out if
853  * there are any remaining LP_UNUSED line pointers somewhere more
854  * towards the front of the array.
855  */
856  if (!ItemIdIsUsed(lp))
857  {
858  /*
859  * This is an unused line pointer that we won't be truncating
860  * away -- so there is at least one. Set hint on page.
861  */
862  sethint = true;
863  break;
864  }
865  }
866  }
867 
868  if (nunusedend > 0)
869  {
870  phdr->pd_lower -= sizeof(ItemIdData) * nunusedend;
871 
872 #ifdef CLOBBER_FREED_MEMORY
873  memset((char *) page + phdr->pd_lower, 0x7F,
874  sizeof(ItemIdData) * nunusedend);
875 #endif
876  }
877  else
878  Assert(sethint);
879 
880  /* Set hint bit for PageAddItemExtended */
881  if (sethint)
883  else
885 }

References Assert, FirstOffsetNumber, i, ItemIdIsUsed, PageClearHasFreeLinePointers(), PageGetItemId(), PageGetMaxOffsetNumber(), PageSetHasFreeLinePointers(), and PageHeaderData::pd_lower.

Referenced by heap_page_prune_execute(), and lazy_vacuum_heap_page().

◆ PageValidateSpecialPointer()

static void PageValidateSpecialPointer ( Page  page)
inlinestatic

Definition at line 327 of file bufpage.h.

329 {
330  Assert(page);
331  Assert(((PageHeader) page)->pd_special <= BLCKSZ);
332  Assert(((PageHeader) page)->pd_special >= SizeOfPageHeaderData);

References Assert, and SizeOfPageHeaderData.

Referenced by PageGetSpecialPointer().

◆ PageXLogRecPtrGet()

static XLogRecPtr PageXLogRecPtrGet ( PageXLogRecPtr  val)
inlinestatic

Definition at line 104 of file bufpage.h.

105 {
106  return (uint64) val.xlogid << 32 | val.xrecoff;
107 }
long val
Definition: informix.c:689

References val.

Referenced by PageGetLSN().

◆ StaticAssertDecl()

StaticAssertDecl ( BLCKSZ  = =((BLCKSZ/sizeof(size_t)) *sizeof(size_t)),
"BLCKSZ has to be a multiple of sizeof(size_t)"   
)

Variable Documentation

◆ ignore_checksum_failure

PGDLLIMPORT bool ignore_checksum_failure
extern

Definition at line 27 of file bufpage.c.

Referenced by PageIsVerifiedExtended().