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

Go to the source code of this file.

Data Structures

struct  PageXLogRecPtr
 
struct  PageHeaderData
 

Macros

#define PageXLogRecPtrSet(ptr, lsn)    ((ptr).xlogid = (uint32) ((lsn) >> 32), (ptr).xrecoff = (uint32) (lsn))
 
#define PD_HAS_FREE_LINES   0x0001 /* are there any unused line pointers? */
 
#define PD_PAGE_FULL   0x0002 /* not enough free space for new tuple? */
 
#define PD_ALL_VISIBLE
 
#define PD_VALID_FLAG_BITS   0x0007 /* OR of all valid pd_flags bits */
 
#define PG_PAGE_LAYOUT_VERSION   4
 
#define PG_DATA_CHECKSUM_VERSION   1
 
#define SizeOfPageHeaderData   (offsetof(PageHeaderData, pd_linp))
 
#define PageGetSpecialPointer(page)
 
#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_LOG_LOG   (1 << 1)
 
#define PIV_IGNORE_CHECKSUM_FAILURE   (1 << 2)
 
#define PageAddItem(page, item, size, offsetNumber, overwrite, is_heap)
 

Typedefs

typedef char PageData
 
typedef PageDataPage
 
typedef uint16 LocationIndex
 
typedef struct PageHeaderData PageHeaderData
 
typedef PageHeaderDataPageHeader
 

Functions

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

Variables

PGDLLIMPORT bool ignore_checksum_failure
 

Macro Definition Documentation

◆ PageAddItem

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

Definition at line 472 of file bufpage.h.

◆ PageClearPrunable

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

Definition at line 454 of file bufpage.h.

◆ PageGetSpecialPointer

#define PageGetSpecialPointer (   page)
Value:
( \
PageValidateSpecialPointer(page), \
((page) + ((PageHeader) (page))->pd_special) \
)

Definition at line 339 of file bufpage.h.

◆ PageSetPrunable

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

Definition at line 447 of file bufpage.h.

◆ PageXLogRecPtrSet

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

Definition at line 110 of file bufpage.h.

◆ PAI_IS_HEAP

#define PAI_IS_HEAP   (1 << 1)

Definition at line 465 of file bufpage.h.

◆ PAI_OVERWRITE

#define PAI_OVERWRITE   (1 << 0)

Definition at line 464 of file bufpage.h.

◆ PD_ALL_VISIBLE

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

Definition at line 190 of file bufpage.h.

◆ PD_HAS_FREE_LINES

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

Definition at line 188 of file bufpage.h.

◆ PD_PAGE_FULL

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

Definition at line 189 of file bufpage.h.

◆ PD_VALID_FLAG_BITS

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

Definition at line 192 of file bufpage.h.

◆ PG_DATA_CHECKSUM_VERSION

#define PG_DATA_CHECKSUM_VERSION   1

Definition at line 207 of file bufpage.h.

◆ PG_PAGE_LAYOUT_VERSION

#define PG_PAGE_LAYOUT_VERSION   4

Definition at line 206 of file bufpage.h.

◆ PIV_IGNORE_CHECKSUM_FAILURE

#define PIV_IGNORE_CHECKSUM_FAILURE   (1 << 2)

Definition at line 470 of file bufpage.h.

◆ PIV_LOG_LOG

#define PIV_LOG_LOG   (1 << 1)

Definition at line 469 of file bufpage.h.

◆ PIV_LOG_WARNING

#define PIV_LOG_WARNING   (1 << 0)

Definition at line 468 of file bufpage.h.

◆ SizeOfPageHeaderData

#define SizeOfPageHeaderData   (offsetof(PageHeaderData, pd_linp))

Definition at line 217 of file bufpage.h.

Typedef Documentation

◆ LocationIndex

Definition at line 91 of file bufpage.h.

◆ Page

typedef PageData* Page

Definition at line 82 of file bufpage.h.

◆ PageData

typedef char PageData

Definition at line 81 of file bufpage.h.

◆ PageHeader

Definition at line 174 of file bufpage.h.

◆ PageHeaderData

Function Documentation

◆ PageAddItemExtended()

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

Definition at line 193 of file bufpage.c.

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

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

◆ PageClearAllVisible()

static void PageClearAllVisible ( Page  page)
inlinestatic

◆ PageClearFull()

static void PageClearFull ( Page  page)
inlinestatic

Definition at line 423 of file bufpage.h.

425{
426 ((PageHeader) page)->pd_flags &= ~PD_PAGE_FULL;

Referenced by heap_page_prune_and_freeze(), and mask_page_hint_bits().

◆ PageClearHasFreeLinePointers()

static void PageClearHasFreeLinePointers ( Page  page)
inlinestatic

Definition at line 407 of file bufpage.h.

409{
410 ((PageHeader) page)->pd_flags &= ~PD_HAS_FREE_LINES;

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

◆ PageGetContents()

◆ PageGetExactFreeSpace()

Size PageGetExactFreeSpace ( const PageData page)

Definition at line 957 of file bufpage.c.

958{
959 const PageHeaderData *phdr = (const PageHeaderData *) page;
960 int space;
961
962 /*
963 * Use signed arithmetic here so that we behave sensibly if pd_lower >
964 * pd_upper.
965 */
966 space = (int) phdr->pd_upper - (int) phdr->pd_lower;
967
968 if (space < 0)
969 return 0;
970
971 return (Size) space;
972}

References PageHeaderData::pd_lower, and PageHeaderData::pd_upper.

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

◆ PageGetFreeSpace()

Size PageGetFreeSpace ( const PageData page)

Definition at line 906 of file bufpage.c.

907{
908 const PageHeaderData *phdr = (const PageHeaderData *) page;
909 int space;
910
911 /*
912 * Use signed arithmetic here so that we behave sensibly if pd_lower >
913 * pd_upper.
914 */
915 space = (int) phdr->pd_upper - (int) phdr->pd_lower;
916
917 if (space < (int) sizeof(ItemIdData))
918 return 0;
919 space -= sizeof(ItemIdData);
920
921 return (Size) space;
922}

References PageHeaderData::pd_lower, and PageHeaderData::pd_upper.

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

◆ PageGetFreeSpaceForMultipleTuples()

Size PageGetFreeSpaceForMultipleTuples ( const PageData page,
int  ntups 
)

Definition at line 933 of file bufpage.c.

934{
935 const PageHeaderData *phdr = (const PageHeaderData *) page;
936 int space;
937
938 /*
939 * Use signed arithmetic here so that we behave sensibly if pd_lower >
940 * pd_upper.
941 */
942 space = (int) phdr->pd_upper - (int) phdr->pd_lower;
943
944 if (space < (int) (ntups * sizeof(ItemIdData)))
945 return 0;
946 space -= ntups * sizeof(ItemIdData);
947
948 return (Size) space;
949}

References PageHeaderData::pd_lower, and PageHeaderData::pd_upper.

Referenced by _hash_splitbucket(), and _hash_squeezebucket().

◆ PageGetHeapFreeSpace()

Size PageGetHeapFreeSpace ( const PageData page)

Definition at line 990 of file bufpage.c.

991{
992 Size space;
993
994 space = PageGetFreeSpace(page);
995 if (space > 0)
996 {
997 OffsetNumber offnum,
998 nline;
999
1000 /*
1001 * Are there already MaxHeapTuplesPerPage line pointers in the page?
1002 */
1003 nline = PageGetMaxOffsetNumber(page);
1004 if (nline >= MaxHeapTuplesPerPage)
1005 {
1006 if (PageHasFreeLinePointers(page))
1007 {
1008 /*
1009 * Since this is just a hint, we must confirm that there is
1010 * indeed a free line pointer
1011 */
1012 for (offnum = FirstOffsetNumber; offnum <= nline; offnum = OffsetNumberNext(offnum))
1013 {
1014 ItemId lp = PageGetItemId(unconstify(PageData *, page), offnum);
1015
1016 if (!ItemIdIsUsed(lp))
1017 break;
1018 }
1019
1020 if (offnum > nline)
1021 {
1022 /*
1023 * The hint is wrong, but we can't clear it here since we
1024 * don't have the ability to mark the page dirty.
1025 */
1026 space = 0;
1027 }
1028 }
1029 else
1030 {
1031 /*
1032 * Although the hint might be wrong, PageAddItem will believe
1033 * it anyway, so we must believe it too.
1034 */
1035 space = 0;
1036 }
1037 }
1038 }
1039 return space;
1040}
Size PageGetFreeSpace(const PageData *page)
Definition: bufpage.c:906
char PageData
Definition: bufpage.h:81
#define unconstify(underlying_type, expr)
Definition: c.h:1216

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

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

◆ PageGetItem()

static Item PageGetItem ( const PageData page,
const ItemIdData itemId 
)
inlinestatic

Definition at line 354 of file bufpage.h.

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

References Assert(), ItemIdGetOffset, and ItemIdHasStorage.

Referenced by _bt_afternewitemoff(), _bt_binsrch_posting(), _bt_bottomupdel_finish_pending(), _bt_bottomupdel_pass(), _bt_buildadd(), _bt_check_natts(), _bt_check_unique(), _bt_checkkeys_look_ahead(), _bt_compare(), _bt_deadblocks(), _bt_dedup_pass(), _bt_delitems_delete_check(), _bt_do_singleval(), _bt_get_endpoint(), _bt_getstackbuf(), _bt_insert_parent(), _bt_insertonpg(), _bt_killitems(), _bt_mark_page_halfdead(), _bt_newlevel(), _bt_pagedel(), _bt_readpage(), _bt_recsplitloc(), _bt_search(), _bt_set_startikey(), _bt_simpledel_pass(), _bt_split(), _bt_split_firstright(), _bt_split_lastleft(), _bt_strategy(), _bt_unlink_halfdead_page(), _hash_binsearch(), _hash_binsearch_last(), _hash_finish_split(), _hash_kill_items(), _hash_load_qualified_items(), _hash_pgaddtup(), _hash_splitbucket(), _hash_squeezebucket(), addLeafTuple(), addOrReplaceTuple(), BitmapHeapScanNextBlock(), 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(), gin_check_parent_keys_consistency(), gin_refind_parent(), ginbulkdelete(), ginEntryInsert(), ginRedoInsertEntry(), ginVacuumEntryPage(), gist_page_items(), gist_page_items_bytea(), gistBufferingFindCorrectParent(), gistbufferinginserttuples(), gistchoose(), gistdeletepage(), gistdoinsert(), gistextractpage(), gistFindCorrectParent(), gistFindPath(), gistformdownlink(), gistGetMaxLevel(), gistMemorizeAllDownlinks(), gistnospace(), gistProcessItup(), gistScanPage(), gistvacuum_delete_empty_pages(), gistvacuumpage(), hash_page_items(), hashbucketcleanup(), heap_abort_speculative(), heap_delete(), heap_fetch(), heap_finish_speculative(), heap_force_common(), heap_freeze_prepared_tuples(), heap_get_latest_tid(), heap_get_root_tuples(), heap_hot_search_buffer(), heap_index_delete_tuples(), heap_lock_tuple(), heap_page_is_all_visible(), heap_page_items(), heap_page_prune_and_freeze(), heap_page_prune_execute(), heap_pre_freeze_checks(), heap_prune_chain(), heap_prune_record_unchanged_lp_normal(), heap_update(), heap_xlog_confirm(), heap_xlog_delete(), heap_xlog_inplace(), heap_xlog_lock(), heap_xlog_lock_updated(), heap_xlog_prune_freeze(), heap_xlog_update(), heapam_scan_analyze_next_tuple(), heapam_scan_bitmap_next_tuple(), heapam_scan_sample_next_tuple(), heapgettup(), heapgettup_pagemode(), index_compute_xid_horizon_for_tuples(), index_delete_check_htid(), invariant_l_nontarget_offset(), invariant_l_offset(), lazy_scan_noprune(), matchPartialInPendingList(), moveLeafs(), page_collect_tuples(), page_verify_redirects(), PageIndexTupleOverwrite(), processPendingPage(), raw_heap_insert(), read_seq_tuple(), RelationPutHeapTuple(), saveNodeLink(), scanGetCandidate(), ScanSourceDatabasePgClassPage(), setRedirectionTuple(), spgdoinsert(), SpGistPageAddNewItem(), spgprocesspending(), spgRedoAddLeaf(), spgRedoAddNode(), spgRedoMoveLeafs(), spgRedoPickSplit(), spgRedoVacuumLeaf(), spgRedoVacuumRedirect(), spgSplitNodeAction(), spgTestLeafTuple(), spgWalk(), startScanEntry(), statapprox_heap(), vacuumLeafPage(), vacuumLeafRoot(), vacuumRedirectAndPlaceholder(), and verify_heapam().

◆ PageGetItemId()

static ItemId PageGetItemId ( Page  page,
OffsetNumber  offsetNumber 
)
inlinestatic

Definition at line 244 of file bufpage.h.

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

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

◆ PageGetLSN()

◆ PageGetMaxOffsetNumber()

static OffsetNumber PageGetMaxOffsetNumber ( const PageData page)
inlinestatic

Definition at line 372 of file bufpage.h.

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

References PageHeaderData::pd_lower, and SizeOfPageHeaderData.

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

◆ PageGetPageLayoutVersion()

static uint8 PageGetPageLayoutVersion ( const PageData page)
inlinestatic

Definition at line 287 of file bufpage.h.

289{
290 return (((const PageHeaderData *) page)->pd_pagesize_version & 0x00FF);

Referenced by page_header().

◆ PageGetPageSize()

static Size PageGetPageSize ( const PageData page)
inlinestatic

◆ PageGetSpecialSize()

static uint16 PageGetSpecialSize ( const PageData page)
inlinestatic

◆ PageGetTempPage()

Page PageGetTempPage ( const PageData page)

Definition at line 364 of file bufpage.c.

365{
366 Size pageSize;
367 Page temp;
368
369 pageSize = PageGetPageSize(page);
370 temp = (Page) palloc(pageSize);
371
372 return temp;
373}
PageData * Page
Definition: bufpage.h:82
void * palloc(Size size)
Definition: mcxt.c:1940

References PageGetPageSize(), and palloc().

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

◆ PageGetTempPageCopy()

Page PageGetTempPageCopy ( const PageData page)

Definition at line 381 of file bufpage.c.

382{
383 Size pageSize;
384 Page temp;
385
386 pageSize = PageGetPageSize(page);
387 temp = (Page) palloc(pageSize);
388
389 memcpy(temp, page, pageSize);
390
391 return temp;
392}

References PageGetPageSize(), and palloc().

Referenced by entrySplitPage(), and ginVacuumEntryPage().

◆ PageGetTempPageCopySpecial()

Page PageGetTempPageCopySpecial ( const PageData page)

Definition at line 401 of file bufpage.c.

402{
403 Size pageSize;
404 Page temp;
405
406 pageSize = PageGetPageSize(page);
407 temp = (Page) palloc(pageSize);
408
409 PageInit(temp, pageSize, PageGetSpecialSize(page));
410 memcpy(PageGetSpecialPointer(temp),
412 PageGetSpecialSize(page));
413
414 return temp;
415}
void PageInit(Page page, Size pageSize, Size specialSize)
Definition: bufpage.c:42
static uint16 PageGetSpecialSize(const PageData *page)
Definition: bufpage.h:317
#define PageGetSpecialPointer(page)
Definition: bufpage.h:339

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

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

◆ PageHasFreeLinePointers()

static bool PageHasFreeLinePointers ( const PageData page)
inlinestatic

Definition at line 397 of file bufpage.h.

399{
400 return ((const PageHeaderData *) page)->pd_flags & PD_HAS_FREE_LINES;
#define PD_HAS_FREE_LINES
Definition: bufpage.h:188

References PD_HAS_FREE_LINES.

Referenced by PageAddItemExtended(), and PageGetHeapFreeSpace().

◆ PageIndexMultiDelete()

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

Definition at line 1160 of file bufpage.c.

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

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

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

◆ PageIndexTupleDelete()

void PageIndexTupleDelete ( Page  page,
OffsetNumber  offnum 
)

Definition at line 1051 of file bufpage.c.

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

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

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

◆ PageIndexTupleDeleteNoCompact()

void PageIndexTupleDeleteNoCompact ( Page  page,
OffsetNumber  offnum 
)

Definition at line 1294 of file bufpage.c.

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

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

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

◆ PageIndexTupleOverwrite()

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

Definition at line 1404 of file bufpage.c.

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

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

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

◆ PageInit()

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

Definition at line 42 of file bufpage.c.

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

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

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

◆ PageIsAllVisible()

◆ PageIsEmpty()

◆ PageIsFull()

static bool PageIsFull ( const PageData page)
inlinestatic

Definition at line 413 of file bufpage.h.

415{
416 return ((const PageHeaderData *) page)->pd_flags & PD_PAGE_FULL;
#define PD_PAGE_FULL
Definition: bufpage.h:189

References PD_PAGE_FULL.

Referenced by heap_page_prune_and_freeze(), and heap_page_prune_opt().

◆ PageIsNew()

static bool PageIsNew ( const PageData page)
inlinestatic

Definition at line 234 of file bufpage.h.

236{
237 return ((const PageHeaderData *) page)->pd_upper == 0;

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

◆ PageIsVerified()

bool PageIsVerified ( PageData page,
BlockNumber  blkno,
int  flags,
bool *  checksum_failure_p 
)

Definition at line 94 of file bufpage.c.

95{
96 const PageHeaderData *p = (const PageHeaderData *) page;
97 size_t *pagebytes;
98 bool checksum_failure = false;
99 bool header_sane = false;
100 uint16 checksum = 0;
101
102 if (checksum_failure_p)
103 *checksum_failure_p = false;
104
105 /*
106 * Don't verify page data unless the page passes basic non-zero test
107 */
108 if (!PageIsNew(page))
109 {
111 {
112 checksum = pg_checksum_page(page, blkno);
113
114 if (checksum != p->pd_checksum)
115 {
116 checksum_failure = true;
117 if (checksum_failure_p)
118 *checksum_failure_p = true;
119 }
120 }
121
122 /*
123 * The following checks don't prove the header is correct, only that
124 * it looks sane enough to allow into the buffer pool. Later usage of
125 * the block can still reveal problems, which is why we offer the
126 * checksum option.
127 */
128 if ((p->pd_flags & ~PD_VALID_FLAG_BITS) == 0 &&
129 p->pd_lower <= p->pd_upper &&
130 p->pd_upper <= p->pd_special &&
131 p->pd_special <= BLCKSZ &&
133 header_sane = true;
134
135 if (header_sane && !checksum_failure)
136 return true;
137 }
138
139 /* Check all-zeroes case */
140 pagebytes = (size_t *) page;
141
142 if (pg_memory_is_all_zeros(pagebytes, BLCKSZ))
143 return true;
144
145 /*
146 * Throw a WARNING/LOG, as instructed by PIV_LOG_*, if the checksum fails,
147 * but only after we've checked for the all-zeroes case.
148 */
150 {
151 if ((flags & (PIV_LOG_WARNING | PIV_LOG_LOG)) != 0)
154 errmsg("page verification failed, calculated checksum %u but expected %u",
155 checksum, p->pd_checksum)));
156
157 if (header_sane && (flags & PIV_IGNORE_CHECKSUM_FAILURE))
158 return true;
159 }
160
161 return false;
162}
#define PD_VALID_FLAG_BITS
Definition: bufpage.h:192
#define PIV_LOG_LOG
Definition: bufpage.h:469
#define PIV_LOG_WARNING
Definition: bufpage.h:468
static bool PageIsNew(const PageData *page)
Definition: bufpage.h:234
#define PIV_IGNORE_CHECKSUM_FAILURE
Definition: bufpage.h:470
uint16 pg_checksum_page(char *page, BlockNumber blkno)
#define LOG
Definition: elog.h:31
static bool pg_memory_is_all_zeros(const void *ptr, size_t len)
Definition: memutils.h:239
static bool checksum_failure
uint16 pd_checksum
Definition: bufpage.h:164
bool DataChecksumsEnabled(void)
Definition: xlog.c:4754

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

Referenced by buffer_readv_complete_one(), and RelationCopyStorage().

◆ PageRepairFragmentation()

void PageRepairFragmentation ( Page  page)

Definition at line 698 of file bufpage.c.

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

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

Referenced by heap_page_prune_execute().

◆ PageRestoreTempPage()

void PageRestoreTempPage ( Page  tempPage,
Page  oldPage 
)

Definition at line 423 of file bufpage.c.

424{
425 Size pageSize;
426
427 pageSize = PageGetPageSize(tempPage);
428 memcpy(oldPage, tempPage, pageSize);
429
430 pfree(tempPage);
431}
void pfree(void *pointer)
Definition: mcxt.c:2147

References PageGetPageSize(), and pfree().

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

◆ PageSetAllVisible()

static void PageSetAllVisible ( Page  page)
inlinestatic

◆ PageSetChecksumCopy()

char * PageSetChecksumCopy ( Page  page,
BlockNumber  blkno 
)

Definition at line 1509 of file bufpage.c.

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

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

Referenced by FlushBuffer().

◆ PageSetChecksumInplace()

void PageSetChecksumInplace ( Page  page,
BlockNumber  blkno 
)

Definition at line 1541 of file bufpage.c.

1542{
1543 /* If we don't need a checksum, just return */
1544 if (PageIsNew(page) || !DataChecksumsEnabled())
1545 return;
1546
1547 ((PageHeader) page)->pd_checksum = pg_checksum_page(page, blkno);
1548}

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

Referenced by _hash_alloc_buckets(), FlushLocalBuffer(), modify_rel_block(), and smgr_bulk_flush().

◆ PageSetFull()

static void PageSetFull ( Page  page)
inlinestatic

Definition at line 418 of file bufpage.h.

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

References PD_PAGE_FULL.

Referenced by heap_update().

◆ PageSetHasFreeLinePointers()

static void PageSetHasFreeLinePointers ( Page  page)
inlinestatic

Definition at line 402 of file bufpage.h.

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

References PD_HAS_FREE_LINES.

Referenced by PageRepairFragmentation(), and PageTruncateLinePointerArray().

◆ PageSetLSN()

static void PageSetLSN ( Page  page,
XLogRecPtr  lsn 
)
inlinestatic

Definition at line 391 of file bufpage.h.

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

References PageXLogRecPtrSet.

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

◆ PageSetPageSizeAndVersion()

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

Definition at line 300 of file bufpage.h.

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

References Assert().

Referenced by PageInit().

◆ PageTruncateLinePointerArray()

void PageTruncateLinePointerArray ( Page  page)

Definition at line 834 of file bufpage.c.

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

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

Referenced by heap_page_prune_execute(), and lazy_vacuum_heap_page().

◆ PageValidateSpecialPointer()

static void PageValidateSpecialPointer ( const PageData page)
inlinestatic

Definition at line 328 of file bufpage.h.

330{
331 Assert(page);
332 Assert(((const PageHeaderData *) page)->pd_special <= BLCKSZ);
333 Assert(((const PageHeaderData *) page)->pd_special >= SizeOfPageHeaderData);

References Assert(), and SizeOfPageHeaderData.

◆ PageXLogRecPtrGet()

static XLogRecPtr PageXLogRecPtrGet ( PageXLogRecPtr  val)
inlinestatic

Definition at line 105 of file bufpage.h.

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

References val.

Referenced by PageGetLSN().

◆ StaticAssertDecl()

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

Variable Documentation

◆ ignore_checksum_failure

PGDLLIMPORT bool ignore_checksum_failure
extern

Definition at line 27 of file bufpage.c.

Referenced by AsyncReadBuffers(), read_rel_block_ll(), and RelationCopyStorage().