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

Definition at line 410 of file bufpage.h.

Referenced by _bt_dedup_finish_pending(), _bt_dedup_one_page(), _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_buildadd(), _bt_check_natts(), _bt_check_unique(), _bt_compare(), _bt_dedup_one_page(), _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_split(), _bt_split_firstright(), _bt_split_lastleft(), _bt_strategy(), _bt_unlink_halfdead_page(), _bt_xid_horizon(), _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_vacuum(), 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_force_common(), 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_binsrch_posting(), _bt_buildadd(), _bt_check_natts(), _bt_check_unique(), _bt_compare(), _bt_dedup_one_page(), _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_slideleft(), _bt_split(), _bt_split_firstright(), _bt_split_lastleft(), _bt_split_penalty(), _bt_strategy(), _bt_unlink_halfdead_page(), _bt_vacuum_one_page(), _bt_xid_horizon(), _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_vacuum(), 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_force_common(), 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_dedup_finish_pending(), _bt_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(), _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_child_check(), bt_child_highkey_check(), bt_page_items(), bt_page_items_bytea(), 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(), 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_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

◆ 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_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_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_child_check(), bt_child_highkey_check(), bt_downlink_missing_check(), bt_page_items(), bt_page_items_bytea(), 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(), 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().

◆ 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_dedup_one_page(), _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 408 of file bufpage.h.

Referenced by PageAddItemExtended().

◆ PAI_OVERWRITE

#define PAI_OVERWRITE   (1 << 0)

Definition at line 407 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

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 186 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.

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

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

834 {
835  int space;
836 
837  /*
838  * Use signed arithmetic here so that we behave sensibly if pd_lower >
839  * pd_upper.
840  */
841  space = (int) ((PageHeader) page)->pd_upper -
842  (int) ((PageHeader) page)->pd_lower;
843 
844  if (space < 0)
845  return 0;
846 
847  return (Size) space;
848 }
PageHeaderData * PageHeader
Definition: bufpage.h:166
size_t Size
Definition: c.h:473

◆ PageGetFreeSpace()

Size PageGetFreeSpace ( Page  page)

Definition at line 782 of file bufpage.c.

Referenced by _bt_buildadd(), _bt_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().

783 {
784  int space;
785 
786  /*
787  * Use signed arithmetic here so that we behave sensibly if pd_lower >
788  * pd_upper.
789  */
790  space = (int) ((PageHeader) page)->pd_upper -
791  (int) ((PageHeader) page)->pd_lower;
792 
793  if (space < (int) sizeof(ItemIdData))
794  return 0;
795  space -= sizeof(ItemIdData);
796 
797  return (Size) space;
798 }
struct ItemIdData ItemIdData
PageHeaderData * PageHeader
Definition: bufpage.h:166
size_t Size
Definition: c.h:473

◆ PageGetFreeSpaceForMultipleTuples()

Size PageGetFreeSpaceForMultipleTuples ( Page  page,
int  ntups 
)

Definition at line 809 of file bufpage.c.

Referenced by _hash_splitbucket(), and _hash_squeezebucket().

810 {
811  int space;
812 
813  /*
814  * Use signed arithmetic here so that we behave sensibly if pd_lower >
815  * pd_upper.
816  */
817  space = (int) ((PageHeader) page)->pd_upper -
818  (int) ((PageHeader) page)->pd_lower;
819 
820  if (space < (int) (ntups * sizeof(ItemIdData)))
821  return 0;
822  space -= ntups * sizeof(ItemIdData);
823 
824  return (Size) space;
825 }
struct ItemIdData ItemIdData
PageHeaderData * PageHeader
Definition: bufpage.h:166
size_t Size
Definition: c.h:473

◆ PageGetHeapFreeSpace()

Size PageGetHeapFreeSpace ( Page  page)

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

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

◆ PageGetTempPage()

Page PageGetTempPage ( Page  page)

Definition at line 344 of file bufpage.c.

References PageGetPageSize, and palloc().

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

345 {
346  Size pageSize;
347  Page temp;
348 
349  pageSize = PageGetPageSize(page);
350  temp = (Page) palloc(pageSize);
351 
352  return temp;
353 }
#define PageGetPageSize(page)
Definition: bufpage.h:268
size_t Size
Definition: c.h:473
void * palloc(Size size)
Definition: mcxt.c:950
Pointer Page
Definition: bufpage.h:78

◆ PageGetTempPageCopy()

Page PageGetTempPageCopy ( Page  page)

Definition at line 361 of file bufpage.c.

References PageGetPageSize, and palloc().

Referenced by entrySplitPage(), and ginVacuumEntryPage().

362 {
363  Size pageSize;
364  Page temp;
365 
366  pageSize = PageGetPageSize(page);
367  temp = (Page) palloc(pageSize);
368 
369  memcpy(temp, page, pageSize);
370 
371  return temp;
372 }
#define PageGetPageSize(page)
Definition: bufpage.h:268
size_t Size
Definition: c.h:473
void * palloc(Size size)
Definition: mcxt.c:950
Pointer Page
Definition: bufpage.h:78

◆ PageGetTempPageCopySpecial()

Page PageGetTempPageCopySpecial ( Page  page)

Definition at line 381 of file bufpage.c.

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

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

382 {
383  Size pageSize;
384  Page temp;
385 
386  pageSize = PageGetPageSize(page);
387  temp = (Page) palloc(pageSize);
388 
389  PageInit(temp, pageSize, PageGetSpecialSize(page));
390  memcpy(PageGetSpecialPointer(temp),
391  PageGetSpecialPointer(page),
392  PageGetSpecialSize(page));
393 
394  return temp;
395 }
#define PageGetPageSize(page)
Definition: bufpage.h:268
size_t Size
Definition: c.h:473
#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 1036 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().

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

◆ PageIndexTupleDelete()

void PageIndexTupleDelete ( Page  page,
OffsetNumber  offset 
)

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

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

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

1282 {
1283  PageHeader phdr = (PageHeader) page;
1284  ItemId tupid;
1285  int oldsize;
1286  unsigned offset;
1287  Size alignednewsize;
1288  int size_diff;
1289  int itemcount;
1290 
1291  /*
1292  * As with PageRepairFragmentation, paranoia seems justified.
1293  */
1294  if (phdr->pd_lower < SizeOfPageHeaderData ||
1295  phdr->pd_lower > phdr->pd_upper ||
1296  phdr->pd_upper > phdr->pd_special ||
1297  phdr->pd_special > BLCKSZ ||
1298  phdr->pd_special != MAXALIGN(phdr->pd_special))
1299  ereport(ERROR,
1301  errmsg("corrupted page pointers: lower = %u, upper = %u, special = %u",
1302  phdr->pd_lower, phdr->pd_upper, phdr->pd_special)));
1303 
1304  itemcount = PageGetMaxOffsetNumber(page);
1305  if ((int) offnum <= 0 || (int) offnum > itemcount)
1306  elog(ERROR, "invalid index offnum: %u", offnum);
1307 
1308  tupid = PageGetItemId(page, offnum);
1309  Assert(ItemIdHasStorage(tupid));
1310  oldsize = ItemIdGetLength(tupid);
1311  offset = ItemIdGetOffset(tupid);
1312 
1313  if (offset < phdr->pd_upper || (offset + oldsize) > phdr->pd_special ||
1314  offset != MAXALIGN(offset))
1315  ereport(ERROR,
1317  errmsg("corrupted line pointer: offset = %u, size = %u",
1318  offset, (unsigned int) oldsize)));
1319 
1320  /*
1321  * Determine actual change in space requirement, check for page overflow.
1322  */
1323  oldsize = MAXALIGN(oldsize);
1324  alignednewsize = MAXALIGN(newsize);
1325  if (alignednewsize > oldsize + (phdr->pd_upper - phdr->pd_lower))
1326  return false;
1327 
1328  /*
1329  * Relocate existing data and update line pointers, unless the new tuple
1330  * is the same size as the old (after alignment), in which case there's
1331  * nothing to do. Notice that what we have to relocate is data before the
1332  * target tuple, not data after, so it's convenient to express size_diff
1333  * as the amount by which the tuple's size is decreasing, making it the
1334  * delta to add to pd_upper and affected line pointers.
1335  */
1336  size_diff = oldsize - (int) alignednewsize;
1337  if (size_diff != 0)
1338  {
1339  char *addr = (char *) page + phdr->pd_upper;
1340  int i;
1341 
1342  /* relocate all tuple data before the target tuple */
1343  memmove(addr + size_diff, addr, offset - phdr->pd_upper);
1344 
1345  /* adjust free space boundary pointer */
1346  phdr->pd_upper += size_diff;
1347 
1348  /* adjust affected line pointers too */
1349  for (i = FirstOffsetNumber; i <= itemcount; i++)
1350  {
1351  ItemId ii = PageGetItemId(phdr, i);
1352 
1353  /* Allow items without storage; currently only BRIN needs that */
1354  if (ItemIdHasStorage(ii) && ItemIdGetOffset(ii) <= offset)
1355  ii->lp_off += size_diff;
1356  }
1357  }
1358 
1359  /* Update the item's tuple length without changing its lp_flags field */
1360  tupid->lp_off = offset + size_diff;
1361  tupid->lp_len = newsize;
1362 
1363  /* Copy new tuple data onto page */
1364  memcpy(PageGetItem(page, tupid), newtup, newsize);
1365 
1366  return true;
1367 }
int errcode(int sqlerrcode)
Definition: elog.c:610
#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 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:144
#define ItemIdHasStorage(itemId)
Definition: itemid.h:120
PageHeaderData * PageHeader
Definition: bufpage.h:166
#define Assert(condition)
Definition: c.h:745
size_t Size
Definition: c.h:473
#define MAXALIGN(LEN)
Definition: c.h:698
int errmsg(const char *fmt,...)
Definition: elog.c:824
#define elog(elevel,...)
Definition: elog.h:214
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:949
#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:745
#define MAXALIGN(LEN)
Definition: c.h:698
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(), 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(), 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  /* Check all-zeroes case */
123  all_zeroes = true;
124  pagebytes = (size_t *) page;
125  for (i = 0; i < (BLCKSZ / sizeof(size_t)); i++)
126  {
127  if (pagebytes[i] != 0)
128  {
129  all_zeroes = false;
130  break;
131  }
132  }
133 
134  if (all_zeroes)
135  return true;
136 
137  /*
138  * Throw a WARNING if the checksum fails, but only after we've checked for
139  * the all-zeroes case.
140  */
141  if (checksum_failure)
142  {
145  errmsg("page verification failed, calculated checksum %u but expected %u",
146  checksum, p->pd_checksum)));
147 
149 
150  if (header_sane && ignore_checksum_failure)
151  return true;
152  }
153 
154  return false;
155 }
void pgstat_report_checksum_failure(void)
Definition: pgstat.c:1607
symbol * p
Definition: api.h:15
uint16 pd_flags
Definition: bufpage.h:157
bool DataChecksumsEnabled(void)
Definition: xlog.c:4931
int errcode(int sqlerrcode)
Definition: elog.c:610
static bool checksum_failure
uint16 pd_checksum
Definition: bufpage.h:156
unsigned short uint16
Definition: c.h:373
#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:144
PageHeaderData * PageHeader
Definition: bufpage.h:166
#define PD_VALID_FLAG_BITS
Definition: bufpage.h:185
#define MAXALIGN(LEN)
Definition: c.h:698
bool ignore_checksum_failure
Definition: bufpage.c:27
#define PageIsNew(page)
Definition: bufpage.h:229
int errmsg(const char *fmt,...)
Definition: elog.c:824
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 674 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().

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

◆ PageRestoreTempPage()

void PageRestoreTempPage ( Page  tempPage,
Page  oldPage 
)

Definition at line 403 of file bufpage.c.

References PageGetPageSize, and pfree().

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

404 {
405  Size pageSize;
406 
407  pageSize = PageGetPageSize(tempPage);
408  memcpy((char *) oldPage, (char *) tempPage, pageSize);
409 
410  pfree(tempPage);
411 }
void pfree(void *pointer)
Definition: mcxt.c:1057
#define PageGetPageSize(page)
Definition: bufpage.h:268
size_t Size
Definition: c.h:473

◆ PageSetChecksumCopy()

char* PageSetChecksumCopy ( Page  page,
BlockNumber  blkno 
)

Definition at line 1385 of file bufpage.c.

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

Referenced by FlushBuffer().

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

1415 {
1416  /* If we don't need a checksum, just return */
1417  if (PageIsNew(page) || !DataChecksumsEnabled())
1418  return;
1419 
1420  ((PageHeader) page)->pd_checksum = pg_checksum_page((char *) page, blkno);
1421 }
bool DataChecksumsEnabled(void)
Definition: xlog.c:4931
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:745

◆ StaticAssertDecl()

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