PostgreSQL Source Code  git master
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 PageXLogRecPtrGet(val)   ((uint64) (val).xlogid << 32 | (val).xrecoff)
 
#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 PageIsValid(page)   PointerIsValid(page)
 
#define SizeOfPageHeaderData   (offsetof(PageHeaderData, pd_linp))
 
#define PageIsEmpty(page)   (((PageHeader) (page))->pd_lower <= SizeOfPageHeaderData)
 
#define PageIsNew(page)   (((PageHeader) (page))->pd_upper == 0)
 
#define PageGetItemId(page, offsetNumber)   ((ItemId) (&((PageHeader) (page))->pd_linp[(offsetNumber) - 1]))
 
#define PageGetContents(page)   ((char *) (page) + MAXALIGN(SizeOfPageHeaderData))
 
#define PageSizeIsValid(pageSize)   ((pageSize) == BLCKSZ)
 
#define PageGetPageSize(page)   ((Size) (((PageHeader) (page))->pd_pagesize_version & (uint16) 0xFF00))
 
#define PageGetPageLayoutVersion(page)   (((PageHeader) (page))->pd_pagesize_version & 0x00FF)
 
#define PageSetPageSizeAndVersion(page, size, version)
 
#define PageGetSpecialSize(page)   ((uint16) (PageGetPageSize(page) - ((PageHeader)(page))->pd_special))
 
#define PageGetSpecialPointer(page)
 
#define PageGetItem(page, itemId)
 
#define PageGetMaxOffsetNumber(page)
 
#define PageGetLSN(page)   PageXLogRecPtrGet(((PageHeader) (page))->pd_lsn)
 
#define PageSetLSN(page, lsn)   PageXLogRecPtrSet(((PageHeader) (page))->pd_lsn, lsn)
 
#define PageHasFreeLinePointers(page)   (((PageHeader) (page))->pd_flags & PD_HAS_FREE_LINES)
 
#define PageSetHasFreeLinePointers(page)   (((PageHeader) (page))->pd_flags |= PD_HAS_FREE_LINES)
 
#define PageClearHasFreeLinePointers(page)   (((PageHeader) (page))->pd_flags &= ~PD_HAS_FREE_LINES)
 
#define PageIsFull(page)   (((PageHeader) (page))->pd_flags & PD_PAGE_FULL)
 
#define PageSetFull(page)   (((PageHeader) (page))->pd_flags |= PD_PAGE_FULL)
 
#define PageClearFull(page)   (((PageHeader) (page))->pd_flags &= ~PD_PAGE_FULL)
 
#define PageIsAllVisible(page)   (((PageHeader) (page))->pd_flags & PD_ALL_VISIBLE)
 
#define PageSetAllVisible(page)   (((PageHeader) (page))->pd_flags |= PD_ALL_VISIBLE)
 
#define PageClearAllVisible(page)   (((PageHeader) (page))->pd_flags &= ~PD_ALL_VISIBLE)
 
#define PageIsPrunable(page, oldestxmin)
 
#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 PageAddItem(page, item, size, offsetNumber, overwrite, is_heap)
 

Typedefs

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

Functions

static bool PageValidateSpecialPointer (Page page)
 
void PageInit (Page page, Size pageSize, Size specialSize)
 
bool PageIsVerified (Page page, BlockNumber blkno)
 
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)
 
Size PageGetFreeSpace (Page page)
 
Size PageGetFreeSpaceForMultipleTuples (Page page, int ntups)
 
Size PageGetExactFreeSpace (Page page)
 
Size PageGetHeapFreeSpace (Page page)
 
void PageIndexTupleDelete (Page page, OffsetNumber offset)
 
void PageIndexMultiDelete (Page page, OffsetNumber *itemnos, int nitems)
 
void PageIndexTupleDeleteNoCompact (Page page, OffsetNumber offset)
 
bool PageIndexTupleOverwrite (Page page, OffsetNumber offnum, Item newtup, Size newsize)
 
char * PageSetChecksumCopy (Page page, BlockNumber blkno)
 
void PageSetChecksumInplace (Page page, BlockNumber blkno)
 

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))
#define PAI_OVERWRITE
Definition: bufpage.h:413
OffsetNumber PageAddItemExtended(Page page, Item item, Size size, OffsetNumber offsetNumber, int flags)
Definition: bufpage.c:193
static void overwrite(PGconn *conn, Oid lobjId, int start, int len)
Definition: testlo.c:108
#define PAI_IS_HEAP
Definition: bufpage.h:414

Definition at line 416 of file bufpage.h.

Referenced by _bt_newroot(), _bt_pgaddtup(), _bt_restore_page(), _bt_sortaddtup(), _bt_split(), _hash_pgaddmultitup(), _hash_pgaddtup(), addLeafTuple(), addOrReplaceTuple(), brin_doinsert(), brin_doupdate(), brin_xlog_insert_update(), btree_xlog_insert(), btree_xlog_mark_page_halfdead(), btree_xlog_split(), btree_xlog_unlink_page(), doPickSplit(), entryExecPlaceToPage(), entrySplitPage(), fill_seq_with_data(), ginEntryFillRoot(), ginHeapTupleFastInsert(), ginRedoInsertEntry(), ginRedoInsertListPage(), ginRedoUpdateMetapage(), ginVacuumEntryPage(), gistfillbuffer(), gistplacetopage(), gistRedoPageUpdateRecord(), hash_xlog_insert(), hash_xlog_move_page_contents(), hash_xlog_squeeze_page(), heap_xlog_insert(), heap_xlog_multi_insert(), heap_xlog_update(), raw_heap_insert(), RelationPutHeapTuple(), seq_redo(), spgAddNodeAction(), SpGistPageAddNewItem(), spgPageIndexMultiDelete(), spgRedoAddLeaf(), spgRedoAddNode(), spgRedoSplitTuple(), spgSplitNodeAction(), and writeListPage().

◆ PageClearAllVisible

#define PageClearAllVisible (   page)    (((PageHeader) (page))->pd_flags &= ~PD_ALL_VISIBLE)

◆ PageClearFull

#define PageClearFull (   page)    (((PageHeader) (page))->pd_flags &= ~PD_PAGE_FULL)

Definition at line 382 of file bufpage.h.

Referenced by heap_page_prune(), and mask_page_hint_bits().

◆ PageClearHasFreeLinePointers

#define PageClearHasFreeLinePointers (   page)    (((PageHeader) (page))->pd_flags &= ~PD_HAS_FREE_LINES)

Definition at line 375 of file bufpage.h.

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

◆ PageClearPrunable

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

Definition at line 405 of file bufpage.h.

◆ PageGetContents

◆ PageGetItem

#define PageGetItem (   page,
  itemId 
)
Value:
( \
AssertMacro(PageIsValid(page)), \
AssertMacro(ItemIdHasStorage(itemId)), \
(Item)(((char *)(page)) + ItemIdGetOffset(itemId)) \
)
Pointer Item
Definition: item.h:17
#define PageIsValid(page)
Definition: bufpage.h:211
#define ItemIdGetOffset(itemId)
Definition: itemid.h:65
#define ItemIdHasStorage(itemId)
Definition: itemid.h:120

Definition at line 340 of file bufpage.h.

Referenced by _bt_afternewitemoff(), _bt_buildadd(), _bt_check_natts(), _bt_check_unique(), _bt_compare(), _bt_get_endpoint(), _bt_getstackbuf(), _bt_insert_parent(), _bt_killitems(), _bt_mark_page_halfdead(), _bt_newroot(), _bt_pagedel(), _bt_readpage(), _bt_search(), _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_splitbucket(), _hash_squeezebucket(), addLeafTuple(), addOrReplaceTuple(), brin_doupdate(), brin_evacuate_page(), brin_page_items(), brinGetTupleForHeapBlock(), brinRevmapDesummarizeRange(), bt_check_level_from_leftmost(), bt_downlink_missing_check(), bt_page_print_tuples(), bt_right_page_check_scankey(), bt_target_page_check(), btree_xlog_mark_page_halfdead(), btree_xlog_split(), btvacuumpage(), checkSplitConditions(), collect_corrupt_items(), collectMatchBitmap(), collectMatchesForHeapRow(), doPickSplit(), entryFindChildPtr(), entryGetLeftMostPage(), entryIsEnoughSpace(), entryLocateEntry(), entryLocateLeafEntry(), entryPreparePage(), entrySplitPage(), GetBTPageStatistics(), getRightMostTuple(), ginbulkdelete(), ginEntryInsert(), ginRedoInsertEntry(), ginVacuumEntryPage(), 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_compute_xid_horizon_for_tuples(), heap_delete(), heap_fetch(), heap_finish_speculative(), heap_get_latest_tid(), heap_get_root_tuples(), heap_hot_search_buffer(), heap_inplace_update(), heap_lock_tuple(), heap_page_is_all_visible(), heap_page_items(), heap_prune_chain(), heap_update(), heap_xlog_confirm(), heap_xlog_delete(), heap_xlog_freeze_page(), heap_xlog_inplace(), heap_xlog_lock(), heap_xlog_lock_updated(), heap_xlog_update(), heapam_scan_analyze_next_tuple(), heapam_scan_bitmap_next_block(), heapam_scan_bitmap_next_tuple(), heapam_scan_sample_next_tuple(), heapgetpage(), heapgettup(), heapgettup_pagemode(), index_compute_xid_horizon_for_tuples(), invariant_l_nontarget_offset(), invariant_l_offset(), lazy_check_needs_freeze(), lazy_scan_heap(), matchPartialInPendingList(), moveLeafs(), PageIndexTupleOverwrite(), processPendingPage(), raw_heap_insert(), read_seq_tuple(), RelationPutHeapTuple(), saveNodeLink(), scanGetCandidate(), setRedirectionTuple(), spgdoinsert(), SpGistPageAddNewItem(), spgprocesspending(), spgRedoAddLeaf(), spgRedoAddNode(), spgRedoMoveLeafs(), spgRedoPickSplit(), spgRedoVacuumLeaf(), spgRedoVacuumRedirect(), spgSplitNodeAction(), spgTestLeafTuple(), spgWalk(), startScanEntry(), statapprox_heap(), vacuumLeafPage(), vacuumLeafRoot(), and vacuumRedirectAndPlaceholder().

◆ PageGetItemId

#define PageGetItemId (   page,
  offsetNumber 
)    ((ItemId) (&((PageHeader) (page))->pd_linp[(offsetNumber) - 1]))

Definition at line 235 of file bufpage.h.

Referenced by _bt_afternewitemoff(), _bt_buildadd(), _bt_check_natts(), _bt_check_unique(), _bt_compare(), _bt_findsplitloc(), _bt_get_endpoint(), _bt_getstackbuf(), _bt_insert_parent(), _bt_killitems(), _bt_mark_page_halfdead(), _bt_newroot(), _bt_pagedel(), _bt_readpage(), _bt_search(), _bt_slideleft(), _bt_split(), _bt_split_firstright(), _bt_split_lastleft(), _bt_split_penalty(), _bt_strategy(), _bt_unlink_halfdead_page(), _bt_vacuum_one_page(), _hash_binsearch(), _hash_binsearch_last(), _hash_finish_split(), _hash_kill_items(), _hash_load_qualified_items(), _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_mark_page_halfdead(), btree_xlog_split(), 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(), 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_compute_xid_horizon_for_tuples(), heap_delete(), heap_fetch(), heap_finish_speculative(), heap_get_latest_tid(), heap_get_root_tuples(), heap_hot_search_buffer(), heap_inplace_update(), heap_lock_tuple(), heap_mask(), heap_page_is_all_visible(), heap_page_items(), heap_page_prune(), heap_page_prune_execute(), heap_prune_chain(), heap_update(), heap_xlog_confirm(), heap_xlog_delete(), heap_xlog_freeze_page(), heap_xlog_inplace(), heap_xlog_lock(), heap_xlog_lock_updated(), heap_xlog_update(), heapam_scan_analyze_next_tuple(), heapam_scan_bitmap_next_block(), heapam_scan_bitmap_next_tuple(), heapam_scan_sample_next_tuple(), heapgetpage(), heapgettup(), heapgettup_pagemode(), index_compute_xid_horizon_for_tuples(), lazy_check_needs_freeze(), lazy_scan_heap(), lazy_vacuum_page(), mask_lp_flags(), matchPartialInPendingList(), moveLeafs(), PageAddItemExtended(), PageGetHeapFreeSpace(), PageGetItemIdCareful(), PageIndexMultiDelete(), PageIndexTupleDelete(), PageIndexTupleDeleteNoCompact(), PageIndexTupleOverwrite(), PageRepairFragmentation(), pgstat_index_page(), processPendingPage(), raw_heap_insert(), read_seq_tuple(), RelationPutHeapTuple(), saveNodeLink(), scanGetCandidate(), setRedirectionTuple(), spgdoinsert(), SpGistPageAddNewItem(), spgprocesspending(), spgRedoAddLeaf(), spgRedoAddNode(), spgRedoMoveLeafs(), spgRedoPickSplit(), spgRedoVacuumLeaf(), spgRedoVacuumRedirect(), spgSplitNodeAction(), spgTestLeafTuple(), spgWalk(), startScanEntry(), statapprox_heap(), vacuumLeafPage(), vacuumLeafRoot(), and vacuumRedirectAndPlaceholder().

◆ PageGetLSN

◆ PageGetMaxOffsetNumber

#define PageGetMaxOffsetNumber (   page)
Value:
(((PageHeader) (page))->pd_lower <= SizeOfPageHeaderData ? 0 : \
((((PageHeader) (page))->pd_lower - SizeOfPageHeaderData) \
/ sizeof(ItemIdData)))
#define SizeOfPageHeaderData
Definition: bufpage.h:216
PageHeaderData * PageHeader
Definition: bufpage.h:166

Definition at line 357 of file bufpage.h.

Referenced by _bt_binsrch(), _bt_binsrch_insert(), _bt_check_natts(), _bt_check_unique(), _bt_doinsert(), _bt_endpoint(), _bt_findinsertloc(), _bt_findsplitloc(), _bt_get_endpoint(), _bt_getstackbuf(), _bt_killitems(), _bt_lock_branch_parent(), _bt_mark_page_halfdead(), _bt_pagedel(), _bt_readnextpage(), _bt_readpage(), _bt_slideleft(), _bt_split(), _bt_unlink_halfdead_page(), _bt_vacuum_one_page(), _hash_binsearch(), _hash_binsearch_last(), _hash_finish_split(), _hash_kill_items(), _hash_load_qualified_items(), _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_downlink_check(), bt_page_items(), bt_page_items_bytea(), bt_right_page_check_scankey(), bt_rootdescend(), bt_target_page_check(), btvacuumpage(), checkSplitConditions(), collect_corrupt_items(), count_nondeletable_pages(), doPickSplit(), entryFindChildPtr(), entryGetLeftMostPage(), entryLocateEntry(), entryLocateLeafEntry(), entrySplitPage(), GetBTPageStatistics(), GetHashPageStatistics(), GetHashPageStats(), getRightMostTuple(), ginbulkdelete(), ginHeapTupleFastInsert(), ginInsertCleanup(), ginRedoInsertEntry(), ginRedoUpdateMetapage(), ginvacuumcleanup(), ginVacuumEntryPage(), ginVacuumPostingTreeLeaves(), 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_get_latest_tid(), heap_get_root_tuples(), heap_hot_search_buffer(), heap_inplace_update(), heap_insert(), heap_mask(), heap_multi_insert(), heap_page_is_all_visible(), heap_page_items(), heap_page_prune(), heap_prune_chain(), 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(), heapgetpage(), heapgettup(), lazy_check_needs_freeze(), lazy_scan_heap(), log_heap_update(), mask_lp_flags(), moveLeafs(), moveRightIfItNeeded(), PageAddItemExtended(), PageGetHeapFreeSpace(), PageIndexMultiDelete(), PageIndexTupleDelete(), PageIndexTupleDeleteNoCompact(), PageIndexTupleOverwrite(), PageRepairFragmentation(), palloc_btree_page(), pgstat_btree_page(), pgstat_gist_page(), pgstat_hash_page(), processPendingPage(), scanGetCandidate(), SpGistPageAddNewItem(), spgRedoVacuumRedirect(), spgWalk(), statapprox_heap(), vacuumLeafPage(), vacuumLeafRoot(), and vacuumRedirectAndPlaceholder().

◆ PageGetPageLayoutVersion

#define PageGetPageLayoutVersion (   page)    (((PageHeader) (page))->pd_pagesize_version & 0x00FF)

Definition at line 275 of file bufpage.h.

Referenced by page_header().

◆ PageGetPageSize

#define PageGetPageSize (   page)    ((Size) (((PageHeader) (page))->pd_pagesize_version & (uint16) 0xFF00))

◆ PageGetSpecialPointer

#define PageGetSpecialPointer (   page)
Value:
( \
AssertMacro(PageValidateSpecialPointer(page)), \
(char *) ((char *) (page) + ((PageHeader) (page))->pd_special) \
)
static bool PageValidateSpecialPointer(Page page)
Definition: bufpage.h:313

Definition at line 326 of file bufpage.h.

Referenced by _bt_binsrch(), _bt_binsrch_insert(), _bt_blnewpage(), _bt_buildadd(), _bt_check_natts(), _bt_check_third_page(), _bt_check_unique(), _bt_clear_incomplete_split(), _bt_compare(), _bt_delitems_delete(), _bt_delitems_vacuum(), _bt_doinsert(), _bt_endpoint(), _bt_findinsertloc(), _bt_findsplitloc(), _bt_finish_split(), _bt_get_endpoint(), _bt_getbuf(), _bt_getmeta(), _bt_getroot(), _bt_getstackbuf(), _bt_gettrueroot(), _bt_initmetapage(), _bt_insert_parent(), _bt_insertonpg(), _bt_is_page_halfdead(), _bt_killitems(), _bt_lock_branch_parent(), _bt_mark_page_halfdead(), _bt_moveright(), _bt_newroot(), _bt_page_recyclable(), _bt_pagedel(), _bt_pgaddtup(), _bt_readnextpage(), _bt_readpage(), _bt_restore_meta(), _bt_search(), _bt_sortaddtup(), _bt_split(), _bt_stepright(), _bt_unlink_halfdead_page(), _bt_upgrademetapage(), _bt_uppershutdown(), _bt_vacuum_one_page(), _bt_walk_left(), _hash_addovflpage(), _hash_alloc_buckets(), _hash_checkpage(), _hash_doinsert(), _hash_expandtable(), _hash_finish_split(), _hash_first(), _hash_freeovflpage(), _hash_getbucketbuf_from_hashkey(), _hash_init_metabuffer(), _hash_initbitmapbuffer(), _hash_initbuf(), _hash_kill_items(), _hash_readnext(), _hash_readpage(), _hash_readprev(), _hash_splitbucket(), _hash_squeezebucket(), _hash_vacuum_one_page(), bt_check_level_from_leftmost(), bt_downlink_check(), bt_downlink_missing_check(), bt_page_items(), bt_page_items_bytea(), bt_right_page_check_scankey(), bt_target_page_check(), btree_mask(), btree_xlog_delete(), btree_xlog_mark_page_halfdead(), btree_xlog_newroot(), btree_xlog_split(), btree_xlog_unlink_page(), btree_xlog_vacuum(), btvacuumpage(), fill_seq_with_data(), GetBTPageStatistics(), GetHashPageStatistics(), gin_leafpage_items(), gin_metapage_info(), gin_page_opaque_info(), ginRedoRecompress(), hash_mask(), hash_page_type(), hash_xlog_add_ovfl_page(), hash_xlog_delete(), hash_xlog_split_allocate_page(), hash_xlog_split_cleanup(), hash_xlog_split_complete(), hash_xlog_squeeze_page(), hash_xlog_vacuum_one_page(), hashbucketcleanup(), hashbulkdelete(), invariant_l_nontarget_offset(), invariant_l_offset(), PageGetTempPageCopySpecial(), palloc_btree_page(), pgstat_btree_page(), pgstat_hash_page(), pgstathashindex(), pgstatindex_impl(), read_seq_tuple(), seq_redo(), and verify_hash_page().

◆ PageGetSpecialSize

#define PageGetSpecialSize (   page)    ((uint16) (PageGetPageSize(page) - ((PageHeader)(page))->pd_special))

◆ PageHasFreeLinePointers

#define PageHasFreeLinePointers (   page)    (((PageHeader) (page))->pd_flags & PD_HAS_FREE_LINES)

Definition at line 371 of file bufpage.h.

Referenced by PageAddItemExtended(), and PageGetHeapFreeSpace().

◆ PageIsAllVisible

◆ PageIsEmpty

◆ PageIsFull

#define PageIsFull (   page)    (((PageHeader) (page))->pd_flags & PD_PAGE_FULL)

Definition at line 378 of file bufpage.h.

Referenced by heap_page_prune(), heap_page_prune_opt(), and heap_update().

◆ PageIsNew

◆ PageIsPrunable

#define PageIsPrunable (   page,
  oldestxmin 
)
Value:
( \
AssertMacro(TransactionIdIsNormal(oldestxmin)), \
TransactionIdIsValid(((PageHeader) (page))->pd_prune_xid) && \
TransactionIdPrecedes(((PageHeader) (page))->pd_prune_xid, oldestxmin) \
)
#define TransactionIdIsNormal(xid)
Definition: transam.h:42

Definition at line 392 of file bufpage.h.

Referenced by heap_page_prune_opt().

◆ PageIsValid

#define PageIsValid (   page)    PointerIsValid(page)

Definition at line 211 of file bufpage.h.

Referenced by PageValidateSpecialPointer().

◆ PageSetAllVisible

#define PageSetAllVisible (   page)    (((PageHeader) (page))->pd_flags |= PD_ALL_VISIBLE)

Definition at line 387 of file bufpage.h.

Referenced by heap_xlog_visible(), lazy_scan_heap(), and lazy_vacuum_page().

◆ PageSetFull

#define PageSetFull (   page)    (((PageHeader) (page))->pd_flags |= PD_PAGE_FULL)

Definition at line 380 of file bufpage.h.

Referenced by heap_update().

◆ PageSetHasFreeLinePointers

#define PageSetHasFreeLinePointers (   page)    (((PageHeader) (page))->pd_flags |= PD_HAS_FREE_LINES)

Definition at line 373 of file bufpage.h.

Referenced by PageRepairFragmentation().

◆ PageSetLSN

#define PageSetLSN (   page,
  lsn 
)    PageXLogRecPtrSet(((PageHeader) (page))->pd_lsn, lsn)

Definition at line 368 of file bufpage.h.

Referenced by _bt_clear_incomplete_split(), _bt_delitems_delete(), _bt_delitems_vacuum(), _bt_getroot(), _bt_insertonpg(), _bt_mark_page_halfdead(), _bt_newroot(), _bt_restore_meta(), _bt_split(), _bt_unlink_halfdead_page(), _bt_update_meta_cleanup_info(), _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_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_with_data(), generic_redo(), GenericXLogFinish(), ginDeletePage(), ginHeapTupleFastInsert(), ginPlaceToPage(), ginRedoClearIncompleteSplit(), ginRedoCreatePTree(), ginRedoDeleteListPages(), ginRedoDeletePage(), ginRedoInsert(), ginRedoInsertListPage(), ginRedoUpdateMetapage(), ginRedoVacuumDataLeafPage(), ginUpdateStats(), ginVacuumPostingTreeLeaf(), 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(), heap_insert(), heap_lock_tuple(), heap_lock_updated_tuple_rec(), heap_multi_insert(), heap_page_prune(), heap_update(), heap_xlog_clean(), heap_xlog_confirm(), heap_xlog_delete(), heap_xlog_freeze_page(), heap_xlog_inplace(), heap_xlog_insert(), heap_xlog_lock(), heap_xlog_lock_updated(), heap_xlog_multi_insert(), heap_xlog_update(), lazy_scan_heap(), lazy_vacuum_page(), log_newpage(), log_newpage_range(), 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

#define PageSetPageSizeAndVersion (   page,
  size,
  version 
)
Value:
( \
AssertMacro(((size) & 0xFF00) == (size)), \
AssertMacro(((version) & 0x00FF) == (version)), \
((PageHeader) (page))->pd_pagesize_version = (size) | (version) \
)
PageHeaderData * PageHeader
Definition: bufpage.h:166

Definition at line 285 of file bufpage.h.

Referenced by PageInit().

◆ 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)
bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
Definition: transam.c:300
PageHeaderData * PageHeader
Definition: bufpage.h:166
#define TransactionIdIsValid(xid)
Definition: transam.h:41
#define TransactionIdIsNormal(xid)
Definition: transam.h:42

Definition at line 398 of file bufpage.h.

Referenced by heap_abort_speculative(), heap_delete(), heap_update(), heap_xlog_delete(), and heap_xlog_update().

◆ PageSizeIsValid

#define PageSizeIsValid (   pageSize)    ((pageSize) == BLCKSZ)

Definition at line 258 of file bufpage.h.

◆ PageXLogRecPtrGet

#define PageXLogRecPtrGet (   val)    ((uint64) (val).xlogid << 32 | (val).xrecoff)

Definition at line 100 of file bufpage.h.

◆ PageXLogRecPtrSet

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

Definition at line 102 of file bufpage.h.

Referenced by mask_page_lsn_and_checksum().

◆ PAI_IS_HEAP

#define PAI_IS_HEAP   (1 << 1)

Definition at line 414 of file bufpage.h.

Referenced by PageAddItemExtended().

◆ PAI_OVERWRITE

#define PAI_OVERWRITE   (1 << 0)

Definition at line 413 of file bufpage.h.

Referenced by PageAddItemExtended().

◆ PD_ALL_VISIBLE

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

Definition at line 182 of file bufpage.h.

◆ PD_HAS_FREE_LINES

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

Definition at line 180 of file bufpage.h.

◆ PD_PAGE_FULL

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

Definition at line 181 of file bufpage.h.

◆ PD_VALID_FLAG_BITS

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

Definition at line 185 of file bufpage.h.

Referenced by PageIsVerified().

◆ PG_DATA_CHECKSUM_VERSION

#define PG_DATA_CHECKSUM_VERSION   1

Definition at line 200 of file bufpage.h.

Referenced by AuxiliaryProcessMain(), main(), sanityChecks(), and scan_file().

◆ PG_PAGE_LAYOUT_VERSION

#define PG_PAGE_LAYOUT_VERSION   4

Definition at line 199 of file bufpage.h.

Referenced by PageInit().

◆ SizeOfPageHeaderData

Typedef Documentation

◆ LocationIndex

Definition at line 87 of file bufpage.h.

◆ Page

Definition at line 78 of file bufpage.h.

◆ PageHeader

Definition at line 166 of file bufpage.h.

◆ PageHeaderData

Function Documentation

◆ PageAddItemExtended()

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

Definition at line 193 of file bufpage.c.

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

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

◆ PageGetExactFreeSpace()

Size PageGetExactFreeSpace ( Page  page)

Definition at line 632 of file bufpage.c.

Referenced by _bt_findsplitloc(), allocNewBuffer(), brin_can_do_samepage_update(), doPickSplit(), GetHashPageStats(), ginHeapTupleFastInsert(), spgAddNodeAction(), SpGistGetBuffer(), SpGistPageAddNewItem(), SpGistSetLastUsedPage(), and writeListPage().

633 {
634  int space;
635 
636  /*
637  * Use signed arithmetic here so that we behave sensibly if pd_lower >
638  * pd_upper.
639  */
640  space = (int) ((PageHeader) page)->pd_upper -
641  (int) ((PageHeader) page)->pd_lower;
642 
643  if (space < 0)
644  return 0;
645 
646  return (Size) space;
647 }
PageHeaderData * PageHeader
Definition: bufpage.h:166
size_t Size
Definition: c.h:466

◆ PageGetFreeSpace()

Size PageGetFreeSpace ( Page  page)

Definition at line 581 of file bufpage.c.

Referenced by _bt_buildadd(), _bt_doinsert(), _bt_findinsertloc(), _bt_insertonpg(), _hash_doinsert(), br_page_get_freespace(), entryIsEnoughSpace(), GetBTPageStatistics(), GetHashPageStatistics(), gistnospace(), heap_xlog_visible(), PageGetHeapFreeSpace(), pgstat_index_page(), pgstatindex_impl(), and terminate_brin_buildstate().

582 {
583  int space;
584 
585  /*
586  * Use signed arithmetic here so that we behave sensibly if pd_lower >
587  * pd_upper.
588  */
589  space = (int) ((PageHeader) page)->pd_upper -
590  (int) ((PageHeader) page)->pd_lower;
591 
592  if (space < (int) sizeof(ItemIdData))
593  return 0;
594  space -= sizeof(ItemIdData);
595 
596  return (Size) space;
597 }
struct ItemIdData ItemIdData
PageHeaderData * PageHeader
Definition: bufpage.h:166
size_t Size
Definition: c.h:466

◆ PageGetFreeSpaceForMultipleTuples()

Size PageGetFreeSpaceForMultipleTuples ( Page  page,
int  ntups 
)

Definition at line 608 of file bufpage.c.

Referenced by _hash_splitbucket(), and _hash_squeezebucket().

609 {
610  int space;
611 
612  /*
613  * Use signed arithmetic here so that we behave sensibly if pd_lower >
614  * pd_upper.
615  */
616  space = (int) ((PageHeader) page)->pd_upper -
617  (int) ((PageHeader) page)->pd_lower;
618 
619  if (space < (int) (ntups * sizeof(ItemIdData)))
620  return 0;
621  space -= ntups * sizeof(ItemIdData);
622 
623  return (Size) space;
624 }
struct ItemIdData ItemIdData
PageHeaderData * PageHeader
Definition: bufpage.h:166
size_t Size
Definition: c.h:466

◆ PageGetHeapFreeSpace()

Size PageGetHeapFreeSpace ( Page  page)

Definition at line 665 of file bufpage.c.

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

Referenced by heap_multi_insert(), heap_page_prune_opt(), heap_update(), heap_xlog_clean(), heap_xlog_insert(), heap_xlog_multi_insert(), heap_xlog_update(), lazy_scan_heap(), lazy_vacuum_heap(), pgstat_heap(), raw_heap_insert(), RelationGetBufferForTuple(), and statapprox_heap().

666 {
667  Size space;
668 
669  space = PageGetFreeSpace(page);
670  if (space > 0)
671  {
672  OffsetNumber offnum,
673  nline;
674 
675  /*
676  * Are there already MaxHeapTuplesPerPage line pointers in the page?
677  */
678  nline = PageGetMaxOffsetNumber(page);
679  if (nline >= MaxHeapTuplesPerPage)
680  {
682  {
683  /*
684  * Since this is just a hint, we must confirm that there is
685  * indeed a free line pointer
686  */
687  for (offnum = FirstOffsetNumber; offnum <= nline; offnum = OffsetNumberNext(offnum))
688  {
689  ItemId lp = PageGetItemId(page, offnum);
690 
691  if (!ItemIdIsUsed(lp))
692  break;
693  }
694 
695  if (offnum > nline)
696  {
697  /*
698  * The hint is wrong, but we can't clear it here since we
699  * don't have the ability to mark the page dirty.
700  */
701  space = 0;
702  }
703  }
704  else
705  {
706  /*
707  * Although the hint might be wrong, PageAddItem will believe
708  * it anyway, so we must believe it too.
709  */
710  space = 0;
711  }
712  }
713  }
714  return space;
715 }
#define ItemIdIsUsed(itemId)
Definition: itemid.h:92
#define MaxHeapTuplesPerPage
Definition: htup_details.h:574
#define PageGetMaxOffsetNumber(page)
Definition: bufpage.h:357
Size PageGetFreeSpace(Page page)
Definition: bufpage.c:581
uint16 OffsetNumber
Definition: off.h:24
#define FirstOffsetNumber
Definition: off.h:27
#define PageGetItemId(page, offsetNumber)
Definition: bufpage.h:235
#define OffsetNumberNext(offsetNumber)
Definition: off.h:52
size_t Size
Definition: c.h:466
#define PageHasFreeLinePointers(page)
Definition: bufpage.h:371

◆ PageGetTempPage()

Page PageGetTempPage ( Page  page)

Definition at line 351 of file bufpage.c.

References PageGetPageSize, and palloc().

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

352 {
353  Size pageSize;
354  Page temp;
355 
356  pageSize = PageGetPageSize(page);
357  temp = (Page) palloc(pageSize);
358 
359  return temp;
360 }
#define PageGetPageSize(page)
Definition: bufpage.h:268
size_t Size
Definition: c.h:466
void * palloc(Size size)
Definition: mcxt.c:924
Pointer Page
Definition: bufpage.h:78

◆ PageGetTempPageCopy()

Page PageGetTempPageCopy ( Page  page)

Definition at line 368 of file bufpage.c.

References PageGetPageSize, and palloc().

Referenced by entrySplitPage(), and ginVacuumEntryPage().

369 {
370  Size pageSize;
371  Page temp;
372 
373  pageSize = PageGetPageSize(page);
374  temp = (Page) palloc(pageSize);
375 
376  memcpy(temp, page, pageSize);
377 
378  return temp;
379 }
#define PageGetPageSize(page)
Definition: bufpage.h:268
size_t Size
Definition: c.h:466
void * palloc(Size size)
Definition: mcxt.c:924
Pointer Page
Definition: bufpage.h:78

◆ PageGetTempPageCopySpecial()

Page PageGetTempPageCopySpecial ( Page  page)

Definition at line 388 of file bufpage.c.

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

Referenced by btree_xlog_split(), and gistplacetopage().

389 {
390  Size pageSize;
391  Page temp;
392 
393  pageSize = PageGetPageSize(page);
394  temp = (Page) palloc(pageSize);
395 
396  PageInit(temp, pageSize, PageGetSpecialSize(page));
397  memcpy(PageGetSpecialPointer(temp),
398  PageGetSpecialPointer(page),
399  PageGetSpecialSize(page));
400 
401  return temp;
402 }
#define PageGetPageSize(page)
Definition: bufpage.h:268
size_t Size
Definition: c.h:466
#define PageGetSpecialPointer(page)
Definition: bufpage.h:326
#define PageGetSpecialSize(page)
Definition: bufpage.h:300
void * palloc(Size size)
Definition: mcxt.c:924
Pointer Page
Definition: bufpage.h:78
void PageInit(Page page, Size pageSize, Size specialSize)
Definition: bufpage.c:42

◆ PageIndexMultiDelete()

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

Definition at line 835 of file bufpage.c.

References itemIdSortData::alignedlen, Assert, compactify_tuples(), elog, ereport, errcode(), ERRCODE_DATA_CORRUPTED, errmsg(), ERROR, FirstOffsetNumber, ItemIdGetLength, ItemIdGetOffset, ItemIdHasStorage, itemIdSortData::itemoff, MAXALIGN, MaxIndexTuplesPerPage, itemIdSortData::offsetindex, OffsetNumberNext, PageGetItemId, PageGetMaxOffsetNumber, PageIndexTupleDelete(), PageHeaderData::pd_linp, PageHeaderData::pd_lower, PageHeaderData::pd_special, PageHeaderData::pd_upper, 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().

836 {
837  PageHeader phdr = (PageHeader) page;
838  Offset pd_lower = phdr->pd_lower;
839  Offset pd_upper = phdr->pd_upper;
840  Offset pd_special = phdr->pd_special;
842  ItemIdData newitemids[MaxIndexTuplesPerPage];
843  itemIdSort itemidptr;
844  ItemId lp;
845  int nline,
846  nused;
847  Size totallen;
848  Size size;
849  unsigned offset;
850  int nextitm;
851  OffsetNumber offnum;
852 
853  Assert(nitems <= MaxIndexTuplesPerPage);
854 
855  /*
856  * If there aren't very many items to delete, then retail
857  * PageIndexTupleDelete is the best way. Delete the items in reverse
858  * order so we don't have to think about adjusting item numbers for
859  * previous deletions.
860  *
861  * TODO: tune the magic number here
862  */
863  if (nitems <= 2)
864  {
865  while (--nitems >= 0)
866  PageIndexTupleDelete(page, itemnos[nitems]);
867  return;
868  }
869 
870  /*
871  * As with PageRepairFragmentation, paranoia seems justified.
872  */
873  if (pd_lower < SizeOfPageHeaderData ||
874  pd_lower > pd_upper ||
875  pd_upper > pd_special ||
876  pd_special > BLCKSZ ||
877  pd_special != MAXALIGN(pd_special))
878  ereport(ERROR,
880  errmsg("corrupted page pointers: lower = %u, upper = %u, special = %u",
881  pd_lower, pd_upper, pd_special)));
882 
883  /*
884  * Scan the line pointer array and build a list of just the ones we are
885  * going to keep. Notice we do not modify the page yet, since we are
886  * still validity-checking.
887  */
888  nline = PageGetMaxOffsetNumber(page);
889  itemidptr = itemidbase;
890  totallen = 0;
891  nused = 0;
892  nextitm = 0;
893  for (offnum = FirstOffsetNumber; offnum <= nline; offnum = OffsetNumberNext(offnum))
894  {
895  lp = PageGetItemId(page, offnum);
897  size = ItemIdGetLength(lp);
898  offset = ItemIdGetOffset(lp);
899  if (offset < pd_upper ||
900  (offset + size) > pd_special ||
901  offset != MAXALIGN(offset))
902  ereport(ERROR,
904  errmsg("corrupted line pointer: offset = %u, size = %u",
905  offset, (unsigned int) size)));
906 
907  if (nextitm < nitems && offnum == itemnos[nextitm])
908  {
909  /* skip item to be deleted */
910  nextitm++;
911  }
912  else
913  {
914  itemidptr->offsetindex = nused; /* where it will go */
915  itemidptr->itemoff = offset;
916  itemidptr->alignedlen = MAXALIGN(size);
917  totallen += itemidptr->alignedlen;
918  newitemids[nused] = *lp;
919  itemidptr++;
920  nused++;
921  }
922  }
923 
924  /* this will catch invalid or out-of-order itemnos[] */
925  if (nextitm != nitems)
926  elog(ERROR, "incorrect index offsets supplied");
927 
928  if (totallen > (Size) (pd_special - pd_lower))
929  ereport(ERROR,
931  errmsg("corrupted item lengths: total %u, available space %u",
932  (unsigned int) totallen, pd_special - pd_lower)));
933 
934  /*
935  * Looks good. Overwrite the line pointers with the copy, from which we've
936  * removed all the unused items.
937  */
938  memcpy(phdr->pd_linp, newitemids, nused * sizeof(ItemIdData));
939  phdr->pd_lower = SizeOfPageHeaderData + nused * sizeof(ItemIdData);
940 
941  /* and compactify the tuple data */
942  compactify_tuples(itemidbase, nused, page);
943 }
int16 itemoff
Definition: bufpage.c:426
void PageIndexTupleDelete(Page page, OffsetNumber offnum)
Definition: bufpage.c:726
int errcode(int sqlerrcode)
Definition: elog.c:570
#define SizeOfPageHeaderData
Definition: bufpage.h:216
#define PageGetMaxOffsetNumber(page)
Definition: bufpage.h:357
uint16 alignedlen
Definition: bufpage.c:427
uint16 offsetindex
Definition: bufpage.c:425
uint16 OffsetNumber
Definition: off.h:24
#define ItemIdGetLength(itemId)
Definition: itemid.h:59
#define ERROR
Definition: elog.h:43
#define FirstOffsetNumber
Definition: off.h:27
struct ItemIdData ItemIdData
#define ItemIdGetOffset(itemId)
Definition: itemid.h:65
#define ereport(elevel, rest)
Definition: elog.h:141
static void compactify_tuples(itemIdSort itemidbase, int nitems, Page page)
Definition: bufpage.c:444
#define ERRCODE_DATA_CORRUPTED
Definition: pg_basebackup.c:44
LocationIndex pd_special
Definition: bufpage.h:160
#define PageGetItemId(page, offsetNumber)
Definition: bufpage.h:235
#define ItemIdHasStorage(itemId)
Definition: itemid.h:120
PageHeaderData * PageHeader
Definition: bufpage.h:166
#define Assert(condition)
Definition: c.h:732
signed int Offset
Definition: c.h:485
#define OffsetNumberNext(offsetNumber)
Definition: off.h:52
size_t Size
Definition: c.h:466
#define MAXALIGN(LEN)
Definition: c.h:685
#define MaxIndexTuplesPerPage
Definition: itup.h:145
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226
ItemIdData pd_linp[FLEXIBLE_ARRAY_MEMBER]
Definition: bufpage.h:163
LocationIndex pd_upper
Definition: bufpage.h:159
LocationIndex pd_lower
Definition: bufpage.h:158

◆ PageIndexTupleDelete()

void PageIndexTupleDelete ( Page  page,
OffsetNumber  offset 
)

Definition at line 726 of file bufpage.c.

References Assert, elog, ereport, errcode(), ERRCODE_DATA_CORRUPTED, errmsg(), ERROR, i, ItemIdGetLength, ItemIdGetOffset, ItemIdHasStorage, ItemIdData::lp_off, MAXALIGN, memmove, PageGetItemId, PageGetMaxOffsetNumber, PageIsEmpty, PageHeaderData::pd_linp, PageHeaderData::pd_lower, PageHeaderData::pd_special, PageHeaderData::pd_upper, 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().

727 {
728  PageHeader phdr = (PageHeader) page;
729  char *addr;
730  ItemId tup;
731  Size size;
732  unsigned offset;
733  int nbytes;
734  int offidx;
735  int nline;
736 
737  /*
738  * As with PageRepairFragmentation, paranoia seems justified.
739  */
740  if (phdr->pd_lower < SizeOfPageHeaderData ||
741  phdr->pd_lower > phdr->pd_upper ||
742  phdr->pd_upper > phdr->pd_special ||
743  phdr->pd_special > BLCKSZ ||
744  phdr->pd_special != MAXALIGN(phdr->pd_special))
745  ereport(ERROR,
747  errmsg("corrupted page pointers: lower = %u, upper = %u, special = %u",
748  phdr->pd_lower, phdr->pd_upper, phdr->pd_special)));
749 
750  nline = PageGetMaxOffsetNumber(page);
751  if ((int) offnum <= 0 || (int) offnum > nline)
752  elog(ERROR, "invalid index offnum: %u", offnum);
753 
754  /* change offset number to offset index */
755  offidx = offnum - 1;
756 
757  tup = PageGetItemId(page, offnum);
758  Assert(ItemIdHasStorage(tup));
759  size = ItemIdGetLength(tup);
760  offset = ItemIdGetOffset(tup);
761 
762  if (offset < phdr->pd_upper || (offset + size) > phdr->pd_special ||
763  offset != MAXALIGN(offset))
764  ereport(ERROR,
766  errmsg("corrupted line pointer: offset = %u, size = %u",
767  offset, (unsigned int) size)));
768 
769  /* Amount of space to actually be deleted */
770  size = MAXALIGN(size);
771 
772  /*
773  * First, we want to get rid of the pd_linp entry for the index tuple. We
774  * copy all subsequent linp's back one slot in the array. We don't use
775  * PageGetItemId, because we are manipulating the _array_, not individual
776  * linp's.
777  */
778  nbytes = phdr->pd_lower -
779  ((char *) &phdr->pd_linp[offidx + 1] - (char *) phdr);
780 
781  if (nbytes > 0)
782  memmove((char *) &(phdr->pd_linp[offidx]),
783  (char *) &(phdr->pd_linp[offidx + 1]),
784  nbytes);
785 
786  /*
787  * Now move everything between the old upper bound (beginning of tuple
788  * space) and the beginning of the deleted tuple forward, so that space in
789  * the middle of the page is left free. If we've just deleted the tuple
790  * at the beginning of tuple space, then there's no need to do the copy.
791  */
792 
793  /* beginning of tuple space */
794  addr = (char *) page + phdr->pd_upper;
795 
796  if (offset > phdr->pd_upper)
797  memmove(addr + size, addr, offset - phdr->pd_upper);
798 
799  /* adjust free space boundary pointers */
800  phdr->pd_upper += size;
801  phdr->pd_lower -= sizeof(ItemIdData);
802 
803  /*
804  * Finally, we need to adjust the linp entries that remain.
805  *
806  * Anything that used to be before the deleted tuple's data was moved
807  * forward by the size of the deleted tuple.
808  */
809  if (!PageIsEmpty(page))
810  {
811  int i;
812 
813  nline--; /* there's one less than when we started */
814  for (i = 1; i <= nline; i++)
815  {
816  ItemId ii = PageGetItemId(phdr, i);
817 
819  if (ItemIdGetOffset(ii) <= offset)
820  ii->lp_off += size;
821  }
822  }
823 }
#define PageIsEmpty(page)
Definition: bufpage.h:222
int errcode(int sqlerrcode)
Definition: elog.c:570
#define SizeOfPageHeaderData
Definition: bufpage.h:216
#define PageGetMaxOffsetNumber(page)
Definition: bufpage.h:357
#define ItemIdGetLength(itemId)
Definition: itemid.h:59
#define ERROR
Definition: elog.h:43
#define memmove(d, s, c)
Definition: c.h:1238
struct ItemIdData ItemIdData
#define ItemIdGetOffset(itemId)
Definition: itemid.h:65
#define ereport(elevel, rest)
Definition: elog.h:141
#define ERRCODE_DATA_CORRUPTED
Definition: pg_basebackup.c:44
LocationIndex pd_special
Definition: bufpage.h:160
#define PageGetItemId(page, offsetNumber)
Definition: bufpage.h:235
unsigned lp_off
Definition: itemid.h:27
#define ItemIdHasStorage(itemId)
Definition: itemid.h:120
PageHeaderData * PageHeader
Definition: bufpage.h:166
#define Assert(condition)
Definition: c.h:732
size_t Size
Definition: c.h:466
#define MAXALIGN(LEN)
Definition: c.h:685
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226
int i
ItemIdData pd_linp[FLEXIBLE_ARRAY_MEMBER]
Definition: bufpage.h:163
LocationIndex pd_upper
Definition: bufpage.h:159
LocationIndex pd_lower
Definition: bufpage.h:158

◆ PageIndexTupleDeleteNoCompact()

void PageIndexTupleDeleteNoCompact ( Page  page,
OffsetNumber  offset 
)

Definition at line 957 of file bufpage.c.

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

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

958 {
959  PageHeader phdr = (PageHeader) page;
960  char *addr;
961  ItemId tup;
962  Size size;
963  unsigned offset;
964  int nline;
965 
966  /*
967  * As with PageRepairFragmentation, paranoia seems justified.
968  */
969  if (phdr->pd_lower < SizeOfPageHeaderData ||
970  phdr->pd_lower > phdr->pd_upper ||
971  phdr->pd_upper > phdr->pd_special ||
972  phdr->pd_special > BLCKSZ ||
973  phdr->pd_special != MAXALIGN(phdr->pd_special))
974  ereport(ERROR,
976  errmsg("corrupted page pointers: lower = %u, upper = %u, special = %u",
977  phdr->pd_lower, phdr->pd_upper, phdr->pd_special)));
978 
979  nline = PageGetMaxOffsetNumber(page);
980  if ((int) offnum <= 0 || (int) offnum > nline)
981  elog(ERROR, "invalid index offnum: %u", offnum);
982 
983  tup = PageGetItemId(page, offnum);
984  Assert(ItemIdHasStorage(tup));
985  size = ItemIdGetLength(tup);
986  offset = ItemIdGetOffset(tup);
987 
988  if (offset < phdr->pd_upper || (offset + size) > phdr->pd_special ||
989  offset != MAXALIGN(offset))
990  ereport(ERROR,
992  errmsg("corrupted line pointer: offset = %u, size = %u",
993  offset, (unsigned int) size)));
994 
995  /* Amount of space to actually be deleted */
996  size = MAXALIGN(size);
997 
998  /*
999  * Either set the line pointer to "unused", or zap it if it's the last
1000  * one. (Note: it's possible that the next-to-last one(s) are already
1001  * unused, but we do not trouble to try to compact them out if so.)
1002  */
1003  if ((int) offnum < nline)
1004  ItemIdSetUnused(tup);
1005  else
1006  {
1007  phdr->pd_lower -= sizeof(ItemIdData);
1008  nline--; /* there's one less than when we started */
1009  }
1010 
1011  /*
1012  * Now move everything between the old upper bound (beginning of tuple
1013  * space) and the beginning of the deleted tuple forward, so that space in
1014  * the middle of the page is left free. If we've just deleted the tuple
1015  * at the beginning of tuple space, then there's no need to do the copy.
1016  */
1017 
1018  /* beginning of tuple space */
1019  addr = (char *) page + phdr->pd_upper;
1020 
1021  if (offset > phdr->pd_upper)
1022  memmove(addr + size, addr, offset - phdr->pd_upper);
1023 
1024  /* adjust free space boundary pointer */
1025  phdr->pd_upper += size;
1026 
1027  /*
1028  * Finally, we need to adjust the linp entries that remain.
1029  *
1030  * Anything that used to be before the deleted tuple's data was moved
1031  * forward by the size of the deleted tuple.
1032  */
1033  if (!PageIsEmpty(page))
1034  {
1035  int i;
1036 
1037  for (i = 1; i <= nline; i++)
1038  {
1039  ItemId ii = PageGetItemId(phdr, i);
1040 
1041  if (ItemIdHasStorage(ii) && ItemIdGetOffset(ii) <= offset)
1042  ii->lp_off += size;
1043  }
1044  }
1045 }
#define PageIsEmpty(page)
Definition: bufpage.h:222
int errcode(int sqlerrcode)
Definition: elog.c:570
#define SizeOfPageHeaderData
Definition: bufpage.h:216
#define PageGetMaxOffsetNumber(page)
Definition: bufpage.h:357
#define ItemIdGetLength(itemId)
Definition: itemid.h:59
#define ERROR
Definition: elog.h:43
#define memmove(d, s, c)
Definition: c.h:1238
struct ItemIdData ItemIdData
#define ItemIdGetOffset(itemId)
Definition: itemid.h:65
#define ereport(elevel, rest)
Definition: elog.h:141
#define ERRCODE_DATA_CORRUPTED
Definition: pg_basebackup.c:44
LocationIndex pd_special
Definition: bufpage.h:160
#define PageGetItemId(page, offsetNumber)
Definition: bufpage.h:235
unsigned lp_off
Definition: itemid.h:27
#define ItemIdHasStorage(itemId)
Definition: itemid.h:120
PageHeaderData * PageHeader
Definition: bufpage.h:166
#define Assert(condition)
Definition: c.h:732
size_t Size
Definition: c.h:466
#define MAXALIGN(LEN)
Definition: c.h:685
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226
int i
LocationIndex pd_upper
Definition: bufpage.h:159
#define ItemIdSetUnused(itemId)
Definition: itemid.h:128
LocationIndex pd_lower
Definition: bufpage.h:158

◆ PageIndexTupleOverwrite()

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

Definition at line 1065 of file bufpage.c.

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

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

1067 {
1068  PageHeader phdr = (PageHeader) page;
1069  ItemId tupid;
1070  int oldsize;
1071  unsigned offset;
1072  Size alignednewsize;
1073  int size_diff;
1074  int itemcount;
1075 
1076  /*
1077  * As with PageRepairFragmentation, paranoia seems justified.
1078  */
1079  if (phdr->pd_lower < SizeOfPageHeaderData ||
1080  phdr->pd_lower > phdr->pd_upper ||
1081  phdr->pd_upper > phdr->pd_special ||
1082  phdr->pd_special > BLCKSZ ||
1083  phdr->pd_special != MAXALIGN(phdr->pd_special))
1084  ereport(ERROR,
1086  errmsg("corrupted page pointers: lower = %u, upper = %u, special = %u",
1087  phdr->pd_lower, phdr->pd_upper, phdr->pd_special)));
1088 
1089  itemcount = PageGetMaxOffsetNumber(page);
1090  if ((int) offnum <= 0 || (int) offnum > itemcount)
1091  elog(ERROR, "invalid index offnum: %u", offnum);
1092 
1093  tupid = PageGetItemId(page, offnum);
1094  Assert(ItemIdHasStorage(tupid));
1095  oldsize = ItemIdGetLength(tupid);
1096  offset = ItemIdGetOffset(tupid);
1097 
1098  if (offset < phdr->pd_upper || (offset + oldsize) > phdr->pd_special ||
1099  offset != MAXALIGN(offset))
1100  ereport(ERROR,
1102  errmsg("corrupted line pointer: offset = %u, size = %u",
1103  offset, (unsigned int) oldsize)));
1104 
1105  /*
1106  * Determine actual change in space requirement, check for page overflow.
1107  */
1108  oldsize = MAXALIGN(oldsize);
1109  alignednewsize = MAXALIGN(newsize);
1110  if (alignednewsize > oldsize + (phdr->pd_upper - phdr->pd_lower))
1111  return false;
1112 
1113  /*
1114  * Relocate existing data and update line pointers, unless the new tuple
1115  * is the same size as the old (after alignment), in which case there's
1116  * nothing to do. Notice that what we have to relocate is data before the
1117  * target tuple, not data after, so it's convenient to express size_diff
1118  * as the amount by which the tuple's size is decreasing, making it the
1119  * delta to add to pd_upper and affected line pointers.
1120  */
1121  size_diff = oldsize - (int) alignednewsize;
1122  if (size_diff != 0)
1123  {
1124  char *addr = (char *) page + phdr->pd_upper;
1125  int i;
1126 
1127  /* relocate all tuple data before the target tuple */
1128  memmove(addr + size_diff, addr, offset - phdr->pd_upper);
1129 
1130  /* adjust free space boundary pointer */
1131  phdr->pd_upper += size_diff;
1132 
1133  /* adjust affected line pointers too */
1134  for (i = FirstOffsetNumber; i <= itemcount; i++)
1135  {
1136  ItemId ii = PageGetItemId(phdr, i);
1137 
1138  /* Allow items without storage; currently only BRIN needs that */
1139  if (ItemIdHasStorage(ii) && ItemIdGetOffset(ii) <= offset)
1140  ii->lp_off += size_diff;
1141  }
1142  }
1143 
1144  /* Update the item's tuple length (other fields shouldn't change) */
1145  ItemIdSetNormal(tupid, offset + size_diff, newsize);
1146 
1147  /* Copy new tuple data onto page */
1148  memcpy(PageGetItem(page, tupid), newtup, newsize);
1149 
1150  return true;
1151 }
int errcode(int sqlerrcode)
Definition: elog.c:570
#define SizeOfPageHeaderData
Definition: bufpage.h:216
#define PageGetMaxOffsetNumber(page)
Definition: bufpage.h:357
#define ItemIdGetLength(itemId)
Definition: itemid.h:59
#define ERROR
Definition: elog.h:43
#define ItemIdSetNormal(itemId, off, len)
Definition: itemid.h:140
#define memmove(d, s, c)
Definition: c.h:1238
#define FirstOffsetNumber
Definition: off.h:27
#define ItemIdGetOffset(itemId)
Definition: itemid.h:65
#define ereport(elevel, rest)
Definition: elog.h:141
#define ERRCODE_DATA_CORRUPTED
Definition: pg_basebackup.c:44
LocationIndex pd_special
Definition: bufpage.h:160
#define PageGetItemId(page, offsetNumber)
Definition: bufpage.h:235
unsigned lp_off
Definition: itemid.h:27
#define ItemIdHasStorage(itemId)
Definition: itemid.h:120
PageHeaderData * PageHeader
Definition: bufpage.h:166
#define Assert(condition)
Definition: c.h:732
size_t Size
Definition: c.h:466
#define MAXALIGN(LEN)
Definition: c.h:685
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define elog(elevel,...)
Definition: elog.h:226
int i
LocationIndex pd_upper
Definition: bufpage.h:159
#define PageGetItem(page, itemId)
Definition: bufpage.h:340
LocationIndex pd_lower
Definition: bufpage.h:158

◆ PageInit()

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

Definition at line 42 of file bufpage.c.

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_with_data(), fsm_extend(), fsm_readbuf(), GinInitPage(), GISTInitBuffer(), heap_xlog_insert(), heap_xlog_multi_insert(), heap_xlog_update(), heap_xlog_visible(), PageGetTempPageCopySpecial(), raw_heap_insert(), RelationGetBufferForTuple(), seq_redo(), SpGistInitPage(), vm_extend(), vm_readbuf(), and XLogRecordPageWithFreeSpace().

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 }
symbol * p
Definition: api.h:15
uint16 pd_flags
Definition: bufpage.h:157
#define PageSetPageSizeAndVersion(page, size, version)
Definition: bufpage.h:285
#define MemSet(start, val, len)
Definition: c.h:955
#define SizeOfPageHeaderData
Definition: bufpage.h:216
#define PG_PAGE_LAYOUT_VERSION
Definition: bufpage.h:199
LocationIndex pd_special
Definition: bufpage.h:160
PageHeaderData * PageHeader
Definition: bufpage.h:166
#define Assert(condition)
Definition: c.h:732
#define MAXALIGN(LEN)
Definition: c.h:685
LocationIndex pd_upper
Definition: bufpage.h:159
LocationIndex pd_lower
Definition: bufpage.h:158

◆ PageIsVerified()

bool PageIsVerified ( Page  page,
BlockNumber  blkno 
)

Definition at line 82 of file bufpage.c.

References checksum_failure, DataChecksumsEnabled(), ereport, ERRCODE_DATA_CORRUPTED, errmsg(), i, 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(), pgstat_report_checksum_failure(), StaticAssertStmt, and WARNING.

Referenced by ReadBuffer_common(), and RelationCopyStorage().

83 {
84  PageHeader p = (PageHeader) page;
85  size_t *pagebytes;
86  int i;
87  bool checksum_failure = false;
88  bool header_sane = false;
89  bool all_zeroes = false;
90  uint16 checksum = 0;
91 
92  /*
93  * Don't verify page data unless the page passes basic non-zero test
94  */
95  if (!PageIsNew(page))
96  {
98  {
99  checksum = pg_checksum_page((char *) page, blkno);
100 
101  if (checksum != p->pd_checksum)
102  checksum_failure = true;
103  }
104 
105  /*
106  * The following checks don't prove the header is correct, only that
107  * it looks sane enough to allow into the buffer pool. Later usage of
108  * the block can still reveal problems, which is why we offer the
109  * checksum option.
110  */
111  if ((p->pd_flags & ~PD_VALID_FLAG_BITS) == 0 &&
112  p->pd_lower <= p->pd_upper &&
113  p->pd_upper <= p->pd_special &&
114  p->pd_special <= BLCKSZ &&
115  p->pd_special == MAXALIGN(p->pd_special))
116  header_sane = true;
117 
118  if (header_sane && !checksum_failure)
119  return true;
120  }
121 
122  /*
123  * Check all-zeroes case. Luckily BLCKSZ is guaranteed to always be a
124  * multiple of size_t - and it's much faster to compare memory using the
125  * native word size.
126  */
127  StaticAssertStmt(BLCKSZ == (BLCKSZ / sizeof(size_t)) * sizeof(size_t),
128  "BLCKSZ has to be a multiple of sizeof(size_t)");
129 
130  all_zeroes = true;
131  pagebytes = (size_t *) page;
132  for (i = 0; i < (BLCKSZ / sizeof(size_t)); i++)
133  {
134  if (pagebytes[i] != 0)
135  {
136  all_zeroes = false;
137  break;
138  }
139  }
140 
141  if (all_zeroes)
142  return true;
143 
144  /*
145  * Throw a WARNING if the checksum fails, but only after we've checked for
146  * the all-zeroes case.
147  */
148  if (checksum_failure)
149  {
152  errmsg("page verification failed, calculated checksum %u but expected %u",
153  checksum, p->pd_checksum)));
154 
156 
157  if (header_sane && ignore_checksum_failure)
158  return true;
159  }
160 
161  return false;
162 }
void pgstat_report_checksum_failure(void)
Definition: pgstat.c:1554
symbol * p
Definition: api.h:15
uint16 pd_flags
Definition: bufpage.h:157
bool DataChecksumsEnabled(void)
Definition: xlog.c:4822
static bool checksum_failure
Definition: pg_basebackup.c:92
uint16 pd_checksum
Definition: bufpage.h:156
#define StaticAssertStmt(condition, errmessage)
Definition: c.h:842
unsigned short uint16
Definition: c.h:357
#define ereport(elevel, rest)
Definition: elog.h:141
#define ERRCODE_DATA_CORRUPTED
Definition: pg_basebackup.c:44
LocationIndex pd_special
Definition: bufpage.h:160
#define WARNING
Definition: elog.h:40
PageHeaderData * PageHeader
Definition: bufpage.h:166
#define PD_VALID_FLAG_BITS
Definition: bufpage.h:185
#define MAXALIGN(LEN)
Definition: c.h:685
bool ignore_checksum_failure
Definition: bufpage.c:27
#define PageIsNew(page)
Definition: bufpage.h:229
int errmsg(const char *fmt,...)
Definition: elog.c:784
int i
LocationIndex pd_upper
Definition: bufpage.h:159
uint16 pg_checksum_page(char *page, BlockNumber blkno)
LocationIndex pd_lower
Definition: bufpage.h:158

◆ PageRepairFragmentation()

void PageRepairFragmentation ( Page  page)

Definition at line 482 of file bufpage.c.

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

Referenced by heap_page_prune_execute(), and lazy_vacuum_page().

483 {
484  Offset pd_lower = ((PageHeader) page)->pd_lower;
485  Offset pd_upper = ((PageHeader) page)->pd_upper;
486  Offset pd_special = ((PageHeader) page)->pd_special;
488  itemIdSort itemidptr;
489  ItemId lp;
490  int nline,
491  nstorage,
492  nunused;
493  int i;
494  Size totallen;
495 
496  /*
497  * It's worth the trouble to be more paranoid here than in most places,
498  * because we are about to reshuffle data in (what is usually) a shared
499  * disk buffer. If we aren't careful then corrupted pointers, lengths,
500  * etc could cause us to clobber adjacent disk buffers, spreading the data
501  * loss further. So, check everything.
502  */
503  if (pd_lower < SizeOfPageHeaderData ||
504  pd_lower > pd_upper ||
505  pd_upper > pd_special ||
506  pd_special > BLCKSZ ||
507  pd_special != MAXALIGN(pd_special))
508  ereport(ERROR,
510  errmsg("corrupted page pointers: lower = %u, upper = %u, special = %u",
511  pd_lower, pd_upper, pd_special)));
512 
513  /*
514  * Run through the line pointer array and collect data about live items.
515  */
516  nline = PageGetMaxOffsetNumber(page);
517  itemidptr = itemidbase;
518  nunused = totallen = 0;
519  for (i = FirstOffsetNumber; i <= nline; i++)
520  {
521  lp = PageGetItemId(page, i);
522  if (ItemIdIsUsed(lp))
523  {
524  if (ItemIdHasStorage(lp))
525  {
526  itemidptr->offsetindex = i - 1;
527  itemidptr->itemoff = ItemIdGetOffset(lp);
528  if (unlikely(itemidptr->itemoff < (int) pd_upper ||
529  itemidptr->itemoff >= (int) pd_special))
530  ereport(ERROR,
532  errmsg("corrupted line pointer: %u",
533  itemidptr->itemoff)));
534  itemidptr->alignedlen = MAXALIGN(ItemIdGetLength(lp));
535  totallen += itemidptr->alignedlen;
536  itemidptr++;
537  }
538  }
539  else
540  {
541  /* Unused entries should have lp_len = 0, but make sure */
542  ItemIdSetUnused(lp);
543  nunused++;
544  }
545  }
546 
547  nstorage = itemidptr - itemidbase;
548  if (nstorage == 0)
549  {
550  /* Page is completely empty, so just reset it quickly */
551  ((PageHeader) page)->pd_upper = pd_special;
552  }
553  else
554  {
555  /* Need to compact the page the hard way */
556  if (totallen > (Size) (pd_special - pd_lower))
557  ereport(ERROR,
559  errmsg("corrupted item lengths: total %u, available space %u",
560  (unsigned int) totallen, pd_special - pd_lower)));
561 
562  compactify_tuples(itemidbase, nstorage, page);
563  }
564 
565  /* Set hint bit for PageAddItem */
566  if (nunused > 0)
568  else
570 }
#define PageClearHasFreeLinePointers(page)
Definition: bufpage.h:375
int16 itemoff
Definition: bufpage.c:426
#define ItemIdIsUsed(itemId)
Definition: itemid.h:92
#define MaxHeapTuplesPerPage
Definition: htup_details.h:574
int errcode(int sqlerrcode)
Definition: elog.c:570
#define SizeOfPageHeaderData
Definition: bufpage.h:216
#define PageGetMaxOffsetNumber(page)
Definition: bufpage.h:357
uint16 alignedlen
Definition: bufpage.c:427
uint16 offsetindex
Definition: bufpage.c:425
#define ItemIdGetLength(itemId)
Definition: itemid.h:59
#define ERROR
Definition: elog.h:43
#define FirstOffsetNumber
Definition: off.h:27
#define ItemIdGetOffset(itemId)
Definition: itemid.h:65
#define ereport(elevel, rest)
Definition: elog.h:141
static void compactify_tuples(itemIdSort itemidbase, int nitems, Page page)
Definition: bufpage.c:444
#define ERRCODE_DATA_CORRUPTED
Definition: pg_basebackup.c:44
#define PageGetItemId(page, offsetNumber)
Definition: bufpage.h:235
#define ItemIdHasStorage(itemId)
Definition: itemid.h:120
PageHeaderData * PageHeader
Definition: bufpage.h:166
signed int Offset
Definition: c.h:485
size_t Size
Definition: c.h:466
#define MAXALIGN(LEN)
Definition: c.h:685
int errmsg(const char *fmt,...)
Definition: elog.c:784
#define PageSetHasFreeLinePointers(page)
Definition: bufpage.h:373
int i
#define unlikely(x)
Definition: c.h:208
#define ItemIdSetUnused(itemId)
Definition: itemid.h:128

◆ PageRestoreTempPage()

void PageRestoreTempPage ( Page  tempPage,
Page  oldPage 
)

Definition at line 410 of file bufpage.c.

References PageGetPageSize, and pfree().

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

411 {
412  Size pageSize;
413 
414  pageSize = PageGetPageSize(tempPage);
415  memcpy((char *) oldPage, (char *) tempPage, pageSize);
416 
417  pfree(tempPage);
418 }
void pfree(void *pointer)
Definition: mcxt.c:1031
#define PageGetPageSize(page)
Definition: bufpage.h:268
size_t Size
Definition: c.h:466

◆ PageSetChecksumCopy()

char* PageSetChecksumCopy ( Page  page,
BlockNumber  blkno 
)

Definition at line 1169 of file bufpage.c.

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

Referenced by FlushBuffer().

1170 {
1171  static char *pageCopy = NULL;
1172 
1173  /* If we don't need a checksum, just return the passed-in data */
1174  if (PageIsNew(page) || !DataChecksumsEnabled())
1175  return (char *) page;
1176 
1177  /*
1178  * We allocate the copy space once and use it over on each subsequent
1179  * call. The point of palloc'ing here, rather than having a static char
1180  * array, is first to ensure adequate alignment for the checksumming code
1181  * and second to avoid wasting space in processes that never call this.
1182  */
1183  if (pageCopy == NULL)
1184  pageCopy = MemoryContextAlloc(TopMemoryContext, BLCKSZ);
1185 
1186  memcpy(pageCopy, (char *) page, BLCKSZ);
1187  ((PageHeader) pageCopy)->pd_checksum = pg_checksum_page(pageCopy, blkno);
1188  return pageCopy;
1189 }
bool DataChecksumsEnabled(void)
Definition: xlog.c:4822
MemoryContext TopMemoryContext
Definition: mcxt.c:44
PageHeaderData * PageHeader
Definition: bufpage.h:166
#define PageIsNew(page)
Definition: bufpage.h:229
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:771
uint16 pg_checksum_page(char *page, BlockNumber blkno)

◆ PageSetChecksumInplace()

void PageSetChecksumInplace ( Page  page,
BlockNumber  blkno 
)

Definition at line 1198 of file bufpage.c.

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

Referenced by _bt_blwritepage(), _hash_alloc_buckets(), blbuildempty(), btbuildempty(), end_heap_rewrite(), FlushRelationBuffers(), fsm_extend(), LocalBufferAlloc(), raw_heap_insert(), RelationCopyStorage(), spgbuildempty(), and vm_extend().

1199 {
1200  /* If we don't need a checksum, just return */
1201  if (PageIsNew(page) || !DataChecksumsEnabled())
1202  return;
1203 
1204  ((PageHeader) page)->pd_checksum = pg_checksum_page((char *) page, blkno);
1205 }
bool DataChecksumsEnabled(void)
Definition: xlog.c:4822
PageHeaderData * PageHeader
Definition: bufpage.h:166
#define PageIsNew(page)
Definition: bufpage.h:229
uint16 pg_checksum_page(char *page, BlockNumber blkno)

◆ PageValidateSpecialPointer()

static bool PageValidateSpecialPointer ( Page  page)
inlinestatic

Definition at line 313 of file bufpage.h.

References Assert, PageIsValid, PageHeaderData::pd_special, and SizeOfPageHeaderData.

314 {
315  Assert(PageIsValid(page));
316  Assert(((PageHeader) (page))->pd_special <= BLCKSZ);
317  Assert(((PageHeader) (page))->pd_special >= SizeOfPageHeaderData);
318 
319  return true;
320 }
#define PageIsValid(page)
Definition: bufpage.h:211
#define SizeOfPageHeaderData
Definition: bufpage.h:216
#define Assert(condition)
Definition: c.h:732