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

Definition at line 416 of file bufpage.h.

Referenced by _bt_dedup_finish_pending(), _bt_dedup_pass(), _bt_insertonpg(), _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_dedup(), 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

◆ 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 399 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_binsrch_posting(), _bt_bottomupdel_finish_pending(), _bt_bottomupdel_pass(), _bt_buildadd(), _bt_check_natts(), _bt_check_unique(), _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_newroot(), _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_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_get_latest_tid(), heap_get_root_tuples(), heap_hot_search_buffer(), heap_index_delete_tuples(), 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(), vacuumRedirectAndPlaceholder(), and verify_heapam().

◆ 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_binsrch_posting(), _bt_bottomupdel_finish_pending(), _bt_bottomupdel_pass(), _bt_buildadd(), _bt_check_natts(), _bt_check_unique(), _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_newroot(), _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_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_get_latest_tid(), heap_get_root_tuples(), heap_hot_search_buffer(), heap_index_delete_tuples(), 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(), vacuumRedirectAndPlaceholder(), and verify_heapam().

◆ 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_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_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_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(), RelationGetBufferForTuple(), scanGetCandidate(), SpGistPageAddNewItem(), spgRedoVacuumRedirect(), spgWalk(), statapprox_heap(), vacuumLeafPage(), vacuumLeafRoot(), vacuumRedirectAndPlaceholder(), and verify_heapam().

◆ PageGetPageLayoutVersion

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

Definition at line 275 of file bufpage.h.

Referenced by page_header().

◆ PageGetPageSize

◆ 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_bottomupdel_pass(), _bt_buildadd(), _bt_check_natts(), _bt_check_third_page(), _bt_check_unique(), _bt_clear_incomplete_split(), _bt_compare(), _bt_dedup_pass(), _bt_delete_or_dedup_one_page(), _bt_delitems_delete(), _bt_delitems_vacuum(), _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_killitems(), _bt_leftsib_splitflag(), _bt_lock_subtree_parent(), _bt_mark_page_halfdead(), _bt_moveright(), _bt_newroot(), _bt_page_recyclable(), _bt_pagedel(), _bt_readnextpage(), _bt_readpage(), _bt_restore_meta(), _bt_rightsib_halfdeadflag(), _bt_search(), _bt_search_insert(), _bt_split(), _bt_stepright(), _bt_unlink_halfdead_page(), _bt_upgrademetapage(), _bt_uppershutdown(), _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_child_check(), bt_child_highkey_check(), bt_downlink_missing_check(), bt_page_items_bytea(), bt_page_items_internal(), bt_recheck_sibling_links(), bt_right_page_check_scankey(), bt_target_page_check(), btree_mask(), btree_xlog_dedup(), 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(), gist_page_opaque_info(), 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

◆ PageIsValid

#define PageIsValid (   page)    PointerIsValid(page)

Definition at line 211 of file bufpage.h.

Referenced by PageValidateSpecialPointer().

◆ PageIsVerified

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

Definition at line 421 of file bufpage.h.

◆ PageSetAllVisible

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

◆ 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_dedup_pass(), _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_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_with_data(), generic_redo(), GenericXLogFinish(), ginDeletePage(), ginHeapTupleFastInsert(), ginPlaceToPage(), ginRedoClearIncompleteSplit(), ginRedoCreatePTree(), ginRedoDeleteListPages(), ginRedoDeletePage(), ginRedoInsert(), ginRedoInsertListPage(), ginRedoUpdateMetapage(), ginRedoVacuumDataLeafPage(), ginUpdateStats(), ginVacuumPostingTreeLeaf(), gist_indexsortbuild(), gist_indexsortbuild_flush_ready_pages(), 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_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

#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 392 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 410 of file bufpage.h.

Referenced by PageAddItemExtended().

◆ PAI_OVERWRITE

#define PAI_OVERWRITE   (1 << 0)

Definition at line 409 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 PageIsVerifiedExtended().

◆ 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().

◆ PIV_LOG_WARNING

#define PIV_LOG_WARNING   (1 << 0)

Definition at line 413 of file bufpage.h.

Referenced by PageIsVerifiedExtended(), ReadBuffer_common(), and RelationCopyStorage().

◆ PIV_REPORT_STAT

#define PIV_REPORT_STAT   (1 << 1)

Definition at line 414 of file bufpage.h.

Referenced by PageIsVerifiedExtended(), ReadBuffer_common(), and RelationCopyStorage().

◆ SizeOfPageHeaderData

Typedef Documentation

◆ LocationIndex

Definition at line 87 of file bufpage.h.

◆ Page

typedef Pointer 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 194 of file bufpage.c.

References elog, ereport, errcode(), ERRCODE_DATA_CORRUPTED, errmsg(), 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, SizeOfPageHeaderData, upper(), VALGRIND_CHECK_MEM_IS_DEFINED, and WARNING.

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

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

842 {
843  int space;
844 
845  /*
846  * Use signed arithmetic here so that we behave sensibly if pd_lower >
847  * pd_upper.
848  */
849  space = (int) ((PageHeader) page)->pd_upper -
850  (int) ((PageHeader) page)->pd_lower;
851 
852  if (space < 0)
853  return 0;
854 
855  return (Size) space;
856 }
PageHeaderData * PageHeader
Definition: bufpage.h:166
size_t Size
Definition: c.h:528

◆ PageGetFreeSpace()

Size PageGetFreeSpace ( Page  page)

Definition at line 790 of file bufpage.c.

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_pagestate_add(), gistnospace(), heap_xlog_visible(), PageGetHeapFreeSpace(), pgstat_index_page(), pgstatindex_impl(), and terminate_brin_buildstate().

791 {
792  int space;
793 
794  /*
795  * Use signed arithmetic here so that we behave sensibly if pd_lower >
796  * pd_upper.
797  */
798  space = (int) ((PageHeader) page)->pd_upper -
799  (int) ((PageHeader) page)->pd_lower;
800 
801  if (space < (int) sizeof(ItemIdData))
802  return 0;
803  space -= sizeof(ItemIdData);
804 
805  return (Size) space;
806 }
struct ItemIdData ItemIdData
PageHeaderData * PageHeader
Definition: bufpage.h:166
size_t Size
Definition: c.h:528

◆ PageGetFreeSpaceForMultipleTuples()

Size PageGetFreeSpaceForMultipleTuples ( Page  page,
int  ntups 
)

Definition at line 817 of file bufpage.c.

Referenced by _hash_splitbucket(), and _hash_squeezebucket().

818 {
819  int space;
820 
821  /*
822  * Use signed arithmetic here so that we behave sensibly if pd_lower >
823  * pd_upper.
824  */
825  space = (int) ((PageHeader) page)->pd_upper -
826  (int) ((PageHeader) page)->pd_lower;
827 
828  if (space < (int) (ntups * sizeof(ItemIdData)))
829  return 0;
830  space -= ntups * sizeof(ItemIdData);
831 
832  return (Size) space;
833 }
struct ItemIdData ItemIdData
PageHeaderData * PageHeader
Definition: bufpage.h:166
size_t Size
Definition: c.h:528

◆ PageGetHeapFreeSpace()

Size PageGetHeapFreeSpace ( Page  page)

Definition at line 874 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().

875 {
876  Size space;
877 
878  space = PageGetFreeSpace(page);
879  if (space > 0)
880  {
881  OffsetNumber offnum,
882  nline;
883 
884  /*
885  * Are there already MaxHeapTuplesPerPage line pointers in the page?
886  */
887  nline = PageGetMaxOffsetNumber(page);
888  if (nline >= MaxHeapTuplesPerPage)
889  {
891  {
892  /*
893  * Since this is just a hint, we must confirm that there is
894  * indeed a free line pointer
895  */
896  for (offnum = FirstOffsetNumber; offnum <= nline; offnum = OffsetNumberNext(offnum))
897  {
898  ItemId lp = PageGetItemId(page, offnum);
899 
900  if (!ItemIdIsUsed(lp))
901  break;
902  }
903 
904  if (offnum > nline)
905  {
906  /*
907  * The hint is wrong, but we can't clear it here since we
908  * don't have the ability to mark the page dirty.
909  */
910  space = 0;
911  }
912  }
913  else
914  {
915  /*
916  * Although the hint might be wrong, PageAddItem will believe
917  * it anyway, so we must believe it too.
918  */
919  space = 0;
920  }
921  }
922  }
923  return space;
924 }
#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:790
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:528
#define PageHasFreeLinePointers(page)
Definition: bufpage.h:371

◆ PageGetTempPage()

Page PageGetTempPage ( Page  page)

Definition at line 352 of file bufpage.c.

References PageGetPageSize, and palloc().

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

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

◆ PageGetTempPageCopy()

Page PageGetTempPageCopy ( Page  page)

Definition at line 369 of file bufpage.c.

References PageGetPageSize, and palloc().

Referenced by entrySplitPage(), and ginVacuumEntryPage().

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

◆ PageGetTempPageCopySpecial()

Page PageGetTempPageCopySpecial ( Page  page)

Definition at line 389 of file bufpage.c.

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

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

390 {
391  Size pageSize;
392  Page temp;
393 
394  pageSize = PageGetPageSize(page);
395  temp = (Page) palloc(pageSize);
396 
397  PageInit(temp, pageSize, PageGetSpecialSize(page));
398  memcpy(PageGetSpecialPointer(temp),
399  PageGetSpecialPointer(page),
400  PageGetSpecialSize(page));
401 
402  return temp;
403 }
#define PageGetPageSize(page)
Definition: bufpage.h:268
size_t Size
Definition: c.h:528
#define PageGetSpecialPointer(page)
Definition: bufpage.h:326
#define PageGetSpecialSize(page)
Definition: bufpage.h:300
void * palloc(Size size)
Definition: mcxt.c:950
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 1044 of file bufpage.c.

References itemIdCompactData::alignedlen, Assert, compactify_tuples(), elog, ereport, errcode(), ERRCODE_DATA_CORRUPTED, errmsg(), ERROR, FirstOffsetNumber, ItemIdGetLength, ItemIdGetOffset, ItemIdHasStorage, itemIdCompactData::itemoff, MAXALIGN, MaxIndexTuplesPerPage, itemIdCompactData::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().

1045 {
1046  PageHeader phdr = (PageHeader) page;
1047  Offset pd_lower = phdr->pd_lower;
1048  Offset pd_upper = phdr->pd_upper;
1049  Offset pd_special = phdr->pd_special;
1050  Offset last_offset;
1052  ItemIdData newitemids[MaxIndexTuplesPerPage];
1053  itemIdCompact itemidptr;
1054  ItemId lp;
1055  int nline,
1056  nused;
1057  Size totallen;
1058  Size size;
1059  unsigned offset;
1060  int nextitm;
1061  OffsetNumber offnum;
1062  bool presorted = true; /* For now */
1063 
1064  Assert(nitems <= MaxIndexTuplesPerPage);
1065 
1066  /*
1067  * If there aren't very many items to delete, then retail
1068  * PageIndexTupleDelete is the best way. Delete the items in reverse
1069  * order so we don't have to think about adjusting item numbers for
1070  * previous deletions.
1071  *
1072  * TODO: tune the magic number here
1073  */
1074  if (nitems <= 2)
1075  {
1076  while (--nitems >= 0)
1077  PageIndexTupleDelete(page, itemnos[nitems]);
1078  return;
1079  }
1080 
1081  /*
1082  * As with PageRepairFragmentation, paranoia seems justified.
1083  */
1084  if (pd_lower < SizeOfPageHeaderData ||
1085  pd_lower > pd_upper ||
1086  pd_upper > pd_special ||
1087  pd_special > BLCKSZ ||
1088  pd_special != MAXALIGN(pd_special))
1089  ereport(ERROR,
1091  errmsg("corrupted page pointers: lower = %u, upper = %u, special = %u",
1092  pd_lower, pd_upper, pd_special)));
1093 
1094  /*
1095  * Scan the line pointer array and build a list of just the ones we are
1096  * going to keep. Notice we do not modify the page yet, since we are
1097  * still validity-checking.
1098  */
1099  nline = PageGetMaxOffsetNumber(page);
1100  itemidptr = itemidbase;
1101  totallen = 0;
1102  nused = 0;
1103  nextitm = 0;
1104  last_offset = pd_special;
1105  for (offnum = FirstOffsetNumber; offnum <= nline; offnum = OffsetNumberNext(offnum))
1106  {
1107  lp = PageGetItemId(page, offnum);
1108  Assert(ItemIdHasStorage(lp));
1109  size = ItemIdGetLength(lp);
1110  offset = ItemIdGetOffset(lp);
1111  if (offset < pd_upper ||
1112  (offset + size) > pd_special ||
1113  offset != MAXALIGN(offset))
1114  ereport(ERROR,
1116  errmsg("corrupted line pointer: offset = %u, size = %u",
1117  offset, (unsigned int) size)));
1118 
1119  if (nextitm < nitems && offnum == itemnos[nextitm])
1120  {
1121  /* skip item to be deleted */
1122  nextitm++;
1123  }
1124  else
1125  {
1126  itemidptr->offsetindex = nused; /* where it will go */
1127  itemidptr->itemoff = offset;
1128 
1129  if (last_offset > itemidptr->itemoff)
1130  last_offset = itemidptr->itemoff;
1131  else
1132  presorted = false;
1133 
1134  itemidptr->alignedlen = MAXALIGN(size);
1135  totallen += itemidptr->alignedlen;
1136  newitemids[nused] = *lp;
1137  itemidptr++;
1138  nused++;
1139  }
1140  }
1141 
1142  /* this will catch invalid or out-of-order itemnos[] */
1143  if (nextitm != nitems)
1144  elog(ERROR, "incorrect index offsets supplied");
1145 
1146  if (totallen > (Size) (pd_special - pd_lower))
1147  ereport(ERROR,
1149  errmsg("corrupted item lengths: total %u, available space %u",
1150  (unsigned int) totallen, pd_special - pd_lower)));
1151 
1152  /*
1153  * Looks good. Overwrite the line pointers with the copy, from which we've
1154  * removed all the unused items.
1155  */
1156  memcpy(phdr->pd_linp, newitemids, nused * sizeof(ItemIdData));
1157  phdr->pd_lower = SizeOfPageHeaderData + nused * sizeof(ItemIdData);
1158 
1159  /* and compactify the tuple data */
1160  if (nused > 0)
1161  compactify_tuples(itemidbase, nused, page, presorted);
1162  else
1163  phdr->pd_upper = pd_special;
1164 }
void PageIndexTupleDelete(Page page, OffsetNumber offnum)
Definition: bufpage.c:935
int errcode(int sqlerrcode)
Definition: elog.c:704
#define SizeOfPageHeaderData
Definition: bufpage.h:216
#define PageGetMaxOffsetNumber(page)
Definition: bufpage.h:357
uint16 OffsetNumber
Definition: off.h:24
#define ItemIdGetLength(itemId)
Definition: itemid.h:59
#define ERROR
Definition: elog.h:45
uint16 offsetindex
Definition: bufpage.c:426
#define FirstOffsetNumber
Definition: off.h:27
static void compactify_tuples(itemIdCompact itemidbase, int nitems, Page page, bool presorted)
Definition: bufpage.c:461
struct ItemIdData ItemIdData
#define ItemIdGetOffset(itemId)
Definition: itemid.h:65
#define ERRCODE_DATA_CORRUPTED
Definition: pg_basebackup.c:45
LocationIndex pd_special
Definition: bufpage.h:160
#define PageGetItemId(page, offsetNumber)
Definition: bufpage.h:235
#define ereport(elevel,...)
Definition: elog.h:155
#define ItemIdHasStorage(itemId)
Definition: itemid.h:120
PageHeaderData * PageHeader
Definition: bufpage.h:166
#define Assert(condition)
Definition: c.h:792
signed int Offset
Definition: c.h:547
#define OffsetNumberNext(offsetNumber)
Definition: off.h:52
size_t Size
Definition: c.h:528
#define MAXALIGN(LEN)
Definition: c.h:745
#define MaxIndexTuplesPerPage
Definition: itup.h:145
int errmsg(const char *fmt,...)
Definition: elog.c:915
#define elog(elevel,...)
Definition: elog.h:228
ItemIdData pd_linp[FLEXIBLE_ARRAY_MEMBER]
Definition: bufpage.h:163
uint16 alignedlen
Definition: bufpage.c:428
LocationIndex pd_upper
Definition: bufpage.h:159
LocationIndex pd_lower
Definition: bufpage.h:158

◆ PageIndexTupleDelete()

void PageIndexTupleDelete ( Page  page,
OffsetNumber  offset 
)

Definition at line 935 of file bufpage.c.

References Assert, elog, ereport, errcode(), ERRCODE_DATA_CORRUPTED, errmsg(), ERROR, i, ItemIdGetLength, ItemIdGetOffset, ItemIdHasStorage, ItemIdData::lp_off, MAXALIGN, 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().

936 {
937  PageHeader phdr = (PageHeader) page;
938  char *addr;
939  ItemId tup;
940  Size size;
941  unsigned offset;
942  int nbytes;
943  int offidx;
944  int nline;
945 
946  /*
947  * As with PageRepairFragmentation, paranoia seems justified.
948  */
949  if (phdr->pd_lower < SizeOfPageHeaderData ||
950  phdr->pd_lower > phdr->pd_upper ||
951  phdr->pd_upper > phdr->pd_special ||
952  phdr->pd_special > BLCKSZ ||
953  phdr->pd_special != MAXALIGN(phdr->pd_special))
954  ereport(ERROR,
956  errmsg("corrupted page pointers: lower = %u, upper = %u, special = %u",
957  phdr->pd_lower, phdr->pd_upper, phdr->pd_special)));
958 
959  nline = PageGetMaxOffsetNumber(page);
960  if ((int) offnum <= 0 || (int) offnum > nline)
961  elog(ERROR, "invalid index offnum: %u", offnum);
962 
963  /* change offset number to offset index */
964  offidx = offnum - 1;
965 
966  tup = PageGetItemId(page, offnum);
967  Assert(ItemIdHasStorage(tup));
968  size = ItemIdGetLength(tup);
969  offset = ItemIdGetOffset(tup);
970 
971  if (offset < phdr->pd_upper || (offset + size) > phdr->pd_special ||
972  offset != MAXALIGN(offset))
973  ereport(ERROR,
975  errmsg("corrupted line pointer: offset = %u, size = %u",
976  offset, (unsigned int) size)));
977 
978  /* Amount of space to actually be deleted */
979  size = MAXALIGN(size);
980 
981  /*
982  * First, we want to get rid of the pd_linp entry for the index tuple. We
983  * copy all subsequent linp's back one slot in the array. We don't use
984  * PageGetItemId, because we are manipulating the _array_, not individual
985  * linp's.
986  */
987  nbytes = phdr->pd_lower -
988  ((char *) &phdr->pd_linp[offidx + 1] - (char *) phdr);
989 
990  if (nbytes > 0)
991  memmove((char *) &(phdr->pd_linp[offidx]),
992  (char *) &(phdr->pd_linp[offidx + 1]),
993  nbytes);
994 
995  /*
996  * Now move everything between the old upper bound (beginning of tuple
997  * space) and the beginning of the deleted tuple forward, so that space in
998  * the middle of the page is left free. If we've just deleted the tuple
999  * at the beginning of tuple space, then there's no need to do the copy.
1000  */
1001 
1002  /* beginning of tuple space */
1003  addr = (char *) page + phdr->pd_upper;
1004 
1005  if (offset > phdr->pd_upper)
1006  memmove(addr + size, addr, offset - phdr->pd_upper);
1007 
1008  /* adjust free space boundary pointers */
1009  phdr->pd_upper += size;
1010  phdr->pd_lower -= sizeof(ItemIdData);
1011 
1012  /*
1013  * Finally, we need to adjust the linp entries that remain.
1014  *
1015  * Anything that used to be before the deleted tuple's data was moved
1016  * forward by the size of the deleted tuple.
1017  */
1018  if (!PageIsEmpty(page))
1019  {
1020  int i;
1021 
1022  nline--; /* there's one less than when we started */
1023  for (i = 1; i <= nline; i++)
1024  {
1025  ItemId ii = PageGetItemId(phdr, i);
1026 
1027  Assert(ItemIdHasStorage(ii));
1028  if (ItemIdGetOffset(ii) <= offset)
1029  ii->lp_off += size;
1030  }
1031  }
1032 }
#define PageIsEmpty(page)
Definition: bufpage.h:222
int errcode(int sqlerrcode)
Definition: elog.c:704
#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:45
struct ItemIdData ItemIdData
#define ItemIdGetOffset(itemId)
Definition: itemid.h:65
#define ERRCODE_DATA_CORRUPTED
Definition: pg_basebackup.c:45
LocationIndex pd_special
Definition: bufpage.h:160
#define PageGetItemId(page, offsetNumber)
Definition: bufpage.h:235
unsigned lp_off
Definition: itemid.h:27
#define ereport(elevel,...)
Definition: elog.h:155
#define ItemIdHasStorage(itemId)
Definition: itemid.h:120
PageHeaderData * PageHeader
Definition: bufpage.h:166
#define Assert(condition)
Definition: c.h:792
size_t Size
Definition: c.h:528
#define MAXALIGN(LEN)
Definition: c.h:745
int errmsg(const char *fmt,...)
Definition: elog.c:915
#define elog(elevel,...)
Definition: elog.h:228
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 1178 of file bufpage.c.

References Assert, elog, ereport, errcode(), ERRCODE_DATA_CORRUPTED, errmsg(), ERROR, i, ItemIdGetLength, ItemIdGetOffset, ItemIdHasStorage, ItemIdSetUnused, ItemIdData::lp_off, MAXALIGN, 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().

1179 {
1180  PageHeader phdr = (PageHeader) page;
1181  char *addr;
1182  ItemId tup;
1183  Size size;
1184  unsigned offset;
1185  int nline;
1186 
1187  /*
1188  * As with PageRepairFragmentation, paranoia seems justified.
1189  */
1190  if (phdr->pd_lower < SizeOfPageHeaderData ||
1191  phdr->pd_lower > phdr->pd_upper ||
1192  phdr->pd_upper > phdr->pd_special ||
1193  phdr->pd_special > BLCKSZ ||
1194  phdr->pd_special != MAXALIGN(phdr->pd_special))
1195  ereport(ERROR,
1197  errmsg("corrupted page pointers: lower = %u, upper = %u, special = %u",
1198  phdr->pd_lower, phdr->pd_upper, phdr->pd_special)));
1199 
1200  nline = PageGetMaxOffsetNumber(page);
1201  if ((int) offnum <= 0 || (int) offnum > nline)
1202  elog(ERROR, "invalid index offnum: %u", offnum);
1203 
1204  tup = PageGetItemId(page, offnum);
1205  Assert(ItemIdHasStorage(tup));
1206  size = ItemIdGetLength(tup);
1207  offset = ItemIdGetOffset(tup);
1208 
1209  if (offset < phdr->pd_upper || (offset + size) > phdr->pd_special ||
1210  offset != MAXALIGN(offset))
1211  ereport(ERROR,
1213  errmsg("corrupted line pointer: offset = %u, size = %u",
1214  offset, (unsigned int) size)));
1215 
1216  /* Amount of space to actually be deleted */
1217  size = MAXALIGN(size);
1218 
1219  /*
1220  * Either set the line pointer to "unused", or zap it if it's the last
1221  * one. (Note: it's possible that the next-to-last one(s) are already
1222  * unused, but we do not trouble to try to compact them out if so.)
1223  */
1224  if ((int) offnum < nline)
1225  ItemIdSetUnused(tup);
1226  else
1227  {
1228  phdr->pd_lower -= sizeof(ItemIdData);
1229  nline--; /* there's one less than when we started */
1230  }
1231 
1232  /*
1233  * Now move everything between the old upper bound (beginning of tuple
1234  * space) and the beginning of the deleted tuple forward, so that space in
1235  * the middle of the page is left free. If we've just deleted the tuple
1236  * at the beginning of tuple space, then there's no need to do the copy.
1237  */
1238 
1239  /* beginning of tuple space */
1240  addr = (char *) page + phdr->pd_upper;
1241 
1242  if (offset > phdr->pd_upper)
1243  memmove(addr + size, addr, offset - phdr->pd_upper);
1244 
1245  /* adjust free space boundary pointer */
1246  phdr->pd_upper += size;
1247 
1248  /*
1249  * Finally, we need to adjust the linp entries that remain.
1250  *
1251  * Anything that used to be before the deleted tuple's data was moved
1252  * forward by the size of the deleted tuple.
1253  */
1254  if (!PageIsEmpty(page))
1255  {
1256  int i;
1257 
1258  for (i = 1; i <= nline; i++)
1259  {
1260  ItemId ii = PageGetItemId(phdr, i);
1261 
1262  if (ItemIdHasStorage(ii) && ItemIdGetOffset(ii) <= offset)
1263  ii->lp_off += size;
1264  }
1265  }
1266 }
#define PageIsEmpty(page)
Definition: bufpage.h:222
int errcode(int sqlerrcode)
Definition: elog.c:704
#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:45
struct ItemIdData ItemIdData
#define ItemIdGetOffset(itemId)
Definition: itemid.h:65
#define ERRCODE_DATA_CORRUPTED
Definition: pg_basebackup.c:45
LocationIndex pd_special
Definition: bufpage.h:160
#define PageGetItemId(page, offsetNumber)
Definition: bufpage.h:235
unsigned lp_off
Definition: itemid.h:27
#define ereport(elevel,...)
Definition: elog.h:155
#define ItemIdHasStorage(itemId)
Definition: itemid.h:120
PageHeaderData * PageHeader
Definition: bufpage.h:166
#define Assert(condition)
Definition: c.h:792
size_t Size
Definition: c.h:528
#define MAXALIGN(LEN)
Definition: c.h:745
int errmsg(const char *fmt,...)
Definition: elog.c:915
#define elog(elevel,...)
Definition: elog.h:228
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 1288 of file bufpage.c.

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().

1290 {
1291  PageHeader phdr = (PageHeader) page;
1292  ItemId tupid;
1293  int oldsize;
1294  unsigned offset;
1295  Size alignednewsize;
1296  int size_diff;
1297  int itemcount;
1298 
1299  /*
1300  * As with PageRepairFragmentation, paranoia seems justified.
1301  */
1302  if (phdr->pd_lower < SizeOfPageHeaderData ||
1303  phdr->pd_lower > phdr->pd_upper ||
1304  phdr->pd_upper > phdr->pd_special ||
1305  phdr->pd_special > BLCKSZ ||
1306  phdr->pd_special != MAXALIGN(phdr->pd_special))
1307  ereport(ERROR,
1309  errmsg("corrupted page pointers: lower = %u, upper = %u, special = %u",
1310  phdr->pd_lower, phdr->pd_upper, phdr->pd_special)));
1311 
1312  itemcount = PageGetMaxOffsetNumber(page);
1313  if ((int) offnum <= 0 || (int) offnum > itemcount)
1314  elog(ERROR, "invalid index offnum: %u", offnum);
1315 
1316  tupid = PageGetItemId(page, offnum);
1317  Assert(ItemIdHasStorage(tupid));
1318  oldsize = ItemIdGetLength(tupid);
1319  offset = ItemIdGetOffset(tupid);
1320 
1321  if (offset < phdr->pd_upper || (offset + oldsize) > phdr->pd_special ||
1322  offset != MAXALIGN(offset))
1323  ereport(ERROR,
1325  errmsg("corrupted line pointer: offset = %u, size = %u",
1326  offset, (unsigned int) oldsize)));
1327 
1328  /*
1329  * Determine actual change in space requirement, check for page overflow.
1330  */
1331  oldsize = MAXALIGN(oldsize);
1332  alignednewsize = MAXALIGN(newsize);
1333  if (alignednewsize > oldsize + (phdr->pd_upper - phdr->pd_lower))
1334  return false;
1335 
1336  /*
1337  * Relocate existing data and update line pointers, unless the new tuple
1338  * is the same size as the old (after alignment), in which case there's
1339  * nothing to do. Notice that what we have to relocate is data before the
1340  * target tuple, not data after, so it's convenient to express size_diff
1341  * as the amount by which the tuple's size is decreasing, making it the
1342  * delta to add to pd_upper and affected line pointers.
1343  */
1344  size_diff = oldsize - (int) alignednewsize;
1345  if (size_diff != 0)
1346  {
1347  char *addr = (char *) page + phdr->pd_upper;
1348  int i;
1349 
1350  /* relocate all tuple data before the target tuple */
1351  memmove(addr + size_diff, addr, offset - phdr->pd_upper);
1352 
1353  /* adjust free space boundary pointer */
1354  phdr->pd_upper += size_diff;
1355 
1356  /* adjust affected line pointers too */
1357  for (i = FirstOffsetNumber; i <= itemcount; i++)
1358  {
1359  ItemId ii = PageGetItemId(phdr, i);
1360 
1361  /* Allow items without storage; currently only BRIN needs that */
1362  if (ItemIdHasStorage(ii) && ItemIdGetOffset(ii) <= offset)
1363  ii->lp_off += size_diff;
1364  }
1365  }
1366 
1367  /* Update the item's tuple length without changing its lp_flags field */
1368  tupid->lp_off = offset + size_diff;
1369  tupid->lp_len = newsize;
1370 
1371  /* Copy new tuple data onto page */
1372  memcpy(PageGetItem(page, tupid), newtup, newsize);
1373 
1374  return true;
1375 }
int errcode(int sqlerrcode)
Definition: elog.c:704
#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:45
#define FirstOffsetNumber
Definition: off.h:27
#define ItemIdGetOffset(itemId)
Definition: itemid.h:65
#define ERRCODE_DATA_CORRUPTED
Definition: pg_basebackup.c:45
LocationIndex pd_special
Definition: bufpage.h:160
#define PageGetItemId(page, offsetNumber)
Definition: bufpage.h:235
unsigned lp_off
Definition: itemid.h:27
unsigned lp_len
Definition: itemid.h:27
#define ereport(elevel,...)
Definition: elog.h:155
#define ItemIdHasStorage(itemId)
Definition: itemid.h:120
PageHeaderData * PageHeader
Definition: bufpage.h:166
#define Assert(condition)
Definition: c.h:792
size_t Size
Definition: c.h:528
#define MAXALIGN(LEN)
Definition: c.h:745
int errmsg(const char *fmt,...)
Definition: elog.c:915
#define elog(elevel,...)
Definition: elog.h:228
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(), gistinitpage(), 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:996
#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:792
#define MAXALIGN(LEN)
Definition: c.h:745
LocationIndex pd_upper
Definition: bufpage.h:159
LocationIndex pd_lower
Definition: bufpage.h:158

◆ PageIsVerifiedExtended()

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

Definition at line 88 of file bufpage.c.

References checksum_failure, DataChecksumsEnabled(), ereport, errcode(), 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(), PIV_LOG_WARNING, PIV_REPORT_STAT, and WARNING.

Referenced by ReadBuffer_common(), and RelationCopyStorage().

89 {
90  PageHeader p = (PageHeader) page;
91  size_t *pagebytes;
92  int i;
93  bool checksum_failure = false;
94  bool header_sane = false;
95  bool all_zeroes = false;
96  uint16 checksum = 0;
97 
98  /*
99  * Don't verify page data unless the page passes basic non-zero test
100  */
101  if (!PageIsNew(page))
102  {
103  if (DataChecksumsEnabled())
104  {
105  checksum = pg_checksum_page((char *) page, blkno);
106 
107  if (checksum != p->pd_checksum)
108  checksum_failure = true;
109  }
110 
111  /*
112  * The following checks don't prove the header is correct, only that
113  * it looks sane enough to allow into the buffer pool. Later usage of
114  * the block can still reveal problems, which is why we offer the
115  * checksum option.
116  */
117  if ((p->pd_flags & ~PD_VALID_FLAG_BITS) == 0 &&
118  p->pd_lower <= p->pd_upper &&
119  p->pd_upper <= p->pd_special &&
120  p->pd_special <= BLCKSZ &&
121  p->pd_special == MAXALIGN(p->pd_special))
122  header_sane = true;
123 
124  if (header_sane && !checksum_failure)
125  return true;
126  }
127 
128  /* Check all-zeroes case */
129  all_zeroes = true;
130  pagebytes = (size_t *) page;
131  for (i = 0; i < (BLCKSZ / sizeof(size_t)); i++)
132  {
133  if (pagebytes[i] != 0)
134  {
135  all_zeroes = false;
136  break;
137  }
138  }
139 
140  if (all_zeroes)
141  return true;
142 
143  /*
144  * Throw a WARNING if the checksum fails, but only after we've checked for
145  * the all-zeroes case.
146  */
147  if (checksum_failure)
148  {
149  if ((flags & PIV_LOG_WARNING) != 0)
152  errmsg("page verification failed, calculated checksum %u but expected %u",
153  checksum, p->pd_checksum)));
154 
155  if ((flags & PIV_REPORT_STAT) != 0)
157 
158  if (header_sane && ignore_checksum_failure)
159  return true;
160  }
161 
162  return false;
163 }
void pgstat_report_checksum_failure(void)
Definition: pgstat.c:1744
symbol * p
Definition: api.h:15
uint16 pd_flags
Definition: bufpage.h:157
bool DataChecksumsEnabled(void)
Definition: xlog.c:4961
int errcode(int sqlerrcode)
Definition: elog.c:704
static bool checksum_failure
uint16 pd_checksum
Definition: bufpage.h:156
unsigned short uint16
Definition: c.h:428
#define PIV_LOG_WARNING
Definition: bufpage.h:413
#define PIV_REPORT_STAT
Definition: bufpage.h:414
#define ERRCODE_DATA_CORRUPTED
Definition: pg_basebackup.c:45
LocationIndex pd_special
Definition: bufpage.h:160
#define WARNING
Definition: elog.h:40
#define ereport(elevel,...)
Definition: elog.h:155
PageHeaderData * PageHeader
Definition: bufpage.h:166
#define PD_VALID_FLAG_BITS
Definition: bufpage.h:185
#define MAXALIGN(LEN)
Definition: c.h:745
bool ignore_checksum_failure
Definition: bufpage.c:27
#define PageIsNew(page)
Definition: bufpage.h:229
int errmsg(const char *fmt,...)
Definition: elog.c:915
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 682 of file bufpage.c.

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

Referenced by heap_page_prune_execute(), and lazy_vacuum_page().

683 {
684  Offset pd_lower = ((PageHeader) page)->pd_lower;
685  Offset pd_upper = ((PageHeader) page)->pd_upper;
686  Offset pd_special = ((PageHeader) page)->pd_special;
687  Offset last_offset;
689  itemIdCompact itemidptr;
690  ItemId lp;
691  int nline,
692  nstorage,
693  nunused;
694  int i;
695  Size totallen;
696  bool presorted = true; /* For now */
697 
698  /*
699  * It's worth the trouble to be more paranoid here than in most places,
700  * because we are about to reshuffle data in (what is usually) a shared
701  * disk buffer. If we aren't careful then corrupted pointers, lengths,
702  * etc could cause us to clobber adjacent disk buffers, spreading the data
703  * loss further. So, check everything.
704  */
705  if (pd_lower < SizeOfPageHeaderData ||
706  pd_lower > pd_upper ||
707  pd_upper > pd_special ||
708  pd_special > BLCKSZ ||
709  pd_special != MAXALIGN(pd_special))
710  ereport(ERROR,
712  errmsg("corrupted page pointers: lower = %u, upper = %u, special = %u",
713  pd_lower, pd_upper, pd_special)));
714 
715  /*
716  * Run through the line pointer array and collect data about live items.
717  */
718  nline = PageGetMaxOffsetNumber(page);
719  itemidptr = itemidbase;
720  nunused = totallen = 0;
721  last_offset = pd_special;
722  for (i = FirstOffsetNumber; i <= nline; i++)
723  {
724  lp = PageGetItemId(page, i);
725  if (ItemIdIsUsed(lp))
726  {
727  if (ItemIdHasStorage(lp))
728  {
729  itemidptr->offsetindex = i - 1;
730  itemidptr->itemoff = ItemIdGetOffset(lp);
731 
732  if (last_offset > itemidptr->itemoff)
733  last_offset = itemidptr->itemoff;
734  else
735  presorted = false;
736 
737  if (unlikely(itemidptr->itemoff < (int) pd_upper ||
738  itemidptr->itemoff >= (int) pd_special))
739  ereport(ERROR,
741  errmsg("corrupted line pointer: %u",
742  itemidptr->itemoff)));
743  itemidptr->alignedlen = MAXALIGN(ItemIdGetLength(lp));
744  totallen += itemidptr->alignedlen;
745  itemidptr++;
746  }
747  }
748  else
749  {
750  /* Unused entries should have lp_len = 0, but make sure */
751  ItemIdSetUnused(lp);
752  nunused++;
753  }
754  }
755 
756  nstorage = itemidptr - itemidbase;
757  if (nstorage == 0)
758  {
759  /* Page is completely empty, so just reset it quickly */
760  ((PageHeader) page)->pd_upper = pd_special;
761  }
762  else
763  {
764  /* Need to compact the page the hard way */
765  if (totallen > (Size) (pd_special - pd_lower))
766  ereport(ERROR,
768  errmsg("corrupted item lengths: total %u, available space %u",
769  (unsigned int) totallen, pd_special - pd_lower)));
770 
771  compactify_tuples(itemidbase, nstorage, page, presorted);
772  }
773 
774  /* Set hint bit for PageAddItem */
775  if (nunused > 0)
777  else
779 }
#define PageClearHasFreeLinePointers(page)
Definition: bufpage.h:375
#define ItemIdIsUsed(itemId)
Definition: itemid.h:92
#define MaxHeapTuplesPerPage
Definition: htup_details.h:574
int errcode(int sqlerrcode)
Definition: elog.c:704
#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:45
uint16 offsetindex
Definition: bufpage.c:426
#define FirstOffsetNumber
Definition: off.h:27
static void compactify_tuples(itemIdCompact itemidbase, int nitems, Page page, bool presorted)
Definition: bufpage.c:461
#define ItemIdGetOffset(itemId)
Definition: itemid.h:65
#define ERRCODE_DATA_CORRUPTED
Definition: pg_basebackup.c:45
#define PageGetItemId(page, offsetNumber)
Definition: bufpage.h:235
#define ereport(elevel,...)
Definition: elog.h:155
#define ItemIdHasStorage(itemId)
Definition: itemid.h:120
PageHeaderData * PageHeader
Definition: bufpage.h:166
signed int Offset
Definition: c.h:547
size_t Size
Definition: c.h:528
#define MAXALIGN(LEN)
Definition: c.h:745
int errmsg(const char *fmt,...)
Definition: elog.c:915
#define PageSetHasFreeLinePointers(page)
Definition: bufpage.h:373
int i
#define unlikely(x)
Definition: c.h:261
uint16 alignedlen
Definition: bufpage.c:428
#define ItemIdSetUnused(itemId)
Definition: itemid.h:128

◆ PageRestoreTempPage()

void PageRestoreTempPage ( Page  tempPage,
Page  oldPage 
)

Definition at line 411 of file bufpage.c.

References PageGetPageSize, and pfree().

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

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

◆ PageSetChecksumCopy()

char* PageSetChecksumCopy ( Page  page,
BlockNumber  blkno 
)

Definition at line 1393 of file bufpage.c.

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

Referenced by FlushBuffer().

1394 {
1395  static char *pageCopy = NULL;
1396 
1397  /* If we don't need a checksum, just return the passed-in data */
1398  if (PageIsNew(page) || !DataChecksumsEnabled())
1399  return (char *) page;
1400 
1401  /*
1402  * We allocate the copy space once and use it over on each subsequent
1403  * call. The point of palloc'ing here, rather than having a static char
1404  * array, is first to ensure adequate alignment for the checksumming code
1405  * and second to avoid wasting space in processes that never call this.
1406  */
1407  if (pageCopy == NULL)
1408  pageCopy = MemoryContextAlloc(TopMemoryContext, BLCKSZ);
1409 
1410  memcpy(pageCopy, (char *) page, BLCKSZ);
1411  ((PageHeader) pageCopy)->pd_checksum = pg_checksum_page(pageCopy, blkno);
1412  return pageCopy;
1413 }
bool DataChecksumsEnabled(void)
Definition: xlog.c:4961
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:797
uint16 pg_checksum_page(char *page, BlockNumber blkno)

◆ PageSetChecksumInplace()

void PageSetChecksumInplace ( Page  page,
BlockNumber  blkno 
)

Definition at line 1422 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(), gist_indexsortbuild(), gist_indexsortbuild_flush_ready_pages(), LocalBufferAlloc(), raw_heap_insert(), RelationCopyStorage(), spgbuildempty(), and vm_extend().

1423 {
1424  /* If we don't need a checksum, just return */
1425  if (PageIsNew(page) || !DataChecksumsEnabled())
1426  return;
1427 
1428  ((PageHeader) page)->pd_checksum = pg_checksum_page((char *) page, blkno);
1429 }
bool DataChecksumsEnabled(void)
Definition: xlog.c:4961
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:792

◆ StaticAssertDecl()

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