22 #include "catalog/pg_am_d.h"
73 #define BTPageGetOpaque(page) ((BTPageOpaque) PageGetSpecialPointer(page))
76 #define BTP_LEAF (1 << 0)
77 #define BTP_ROOT (1 << 1)
78 #define BTP_DELETED (1 << 2)
79 #define BTP_META (1 << 3)
80 #define BTP_HALF_DEAD (1 << 4)
81 #define BTP_SPLIT_END (1 << 5)
82 #define BTP_HAS_GARBAGE (1 << 6)
83 #define BTP_INCOMPLETE_SPLIT (1 << 7)
84 #define BTP_HAS_FULLXID (1 << 8)
93 #define MAX_BT_CYCLE_ID 0xFF7F
121 #define BTPageGetMeta(p) \
122 ((BTMetaPageData *) PageGetContents(p))
148 #define BTREE_METAPAGE 0
149 #define BTREE_MAGIC 0x053162
150 #define BTREE_VERSION 4
151 #define BTREE_MIN_VERSION 2
152 #define BTREE_NOVAC_VERSION 3
164 #define BTMaxItemSize(page) \
165 (MAXALIGN_DOWN((PageGetPageSize(page) - \
166 MAXALIGN(SizeOfPageHeaderData + 3*sizeof(ItemIdData)) - \
167 MAXALIGN(sizeof(BTPageOpaqueData))) / 3) - \
168 MAXALIGN(sizeof(ItemPointerData)))
169 #define BTMaxItemSizeNoHeapTid(page) \
170 MAXALIGN_DOWN((PageGetPageSize(page) - \
171 MAXALIGN(SizeOfPageHeaderData + 3*sizeof(ItemIdData)) - \
172 MAXALIGN(sizeof(BTPageOpaqueData))) / 3)
185 #define MaxTIDsPerBTreePage \
186 (int) ((BLCKSZ - SizeOfPageHeaderData - sizeof(BTPageOpaqueData)) / \
187 sizeof(ItemPointerData))
199 #define BTREE_MIN_FILLFACTOR 10
200 #define BTREE_DEFAULT_FILLFACTOR 90
201 #define BTREE_NONLEAF_FILLFACTOR 70
202 #define BTREE_SINGLEVAL_FILLFACTOR 96
218 #define P_LEFTMOST(opaque) ((opaque)->btpo_prev == P_NONE)
219 #define P_RIGHTMOST(opaque) ((opaque)->btpo_next == P_NONE)
220 #define P_ISLEAF(opaque) (((opaque)->btpo_flags & BTP_LEAF) != 0)
221 #define P_ISROOT(opaque) (((opaque)->btpo_flags & BTP_ROOT) != 0)
222 #define P_ISDELETED(opaque) (((opaque)->btpo_flags & BTP_DELETED) != 0)
223 #define P_ISMETA(opaque) (((opaque)->btpo_flags & BTP_META) != 0)
224 #define P_ISHALFDEAD(opaque) (((opaque)->btpo_flags & BTP_HALF_DEAD) != 0)
225 #define P_IGNORE(opaque) (((opaque)->btpo_flags & (BTP_DELETED|BTP_HALF_DEAD)) != 0)
226 #define P_HAS_GARBAGE(opaque) (((opaque)->btpo_flags & BTP_HAS_GARBAGE) != 0)
227 #define P_INCOMPLETE_SPLIT(opaque) (((opaque)->btpo_flags & BTP_INCOMPLETE_SPLIT) != 0)
228 #define P_HAS_FULLXID(opaque) (((opaque)->btpo_flags & BTP_HAS_FULLXID) != 0)
367 #define P_HIKEY ((OffsetNumber) 1)
368 #define P_FIRSTKEY ((OffsetNumber) 2)
369 #define P_FIRSTDATAKEY(opaque) (P_RIGHTMOST(opaque) ? P_HIKEY : P_FIRSTKEY)
459 #define INDEX_ALT_TID_MASK INDEX_AM_RESERVED_BIT
462 #define BT_OFFSET_MASK 0x0FFF
463 #define BT_STATUS_OFFSET_MASK 0xF000
465 #define BT_PIVOT_HEAP_TID_ATTR 0x1000
466 #define BT_IS_POSTING 0x2000
473 "BT_OFFSET_MASK can't fit INDEX_MAX_KEYS");
577 #define BTreeTupleGetNAtts(itup, rel) \
579 (BTreeTupleIsPivot(itup)) ? \
581 ItemPointerGetOffsetNumberNoCheck(&(itup)->t_tid) & BT_OFFSET_MASK \
584 IndexRelationGetNumberOfAttributes(rel) \
599 Assert(!heaptid || nkeyatts > 0);
685 #define BTCommuteStrategyNumber(strat) (BTMaxStrategyNumber + 1 - (strat))
707 #define BTORDER_PROC 1
708 #define BTSORTSUPPORT_PROC 2
709 #define BTINRANGE_PROC 3
710 #define BTEQUALIMAGE_PROC 4
711 #define BTOPTIONS_PROC 5
719 #define BT_READ BUFFER_LOCK_SHARE
720 #define BT_WRITE BUFFER_LOCK_EXCLUSIVE
999 #define BTScanPosIsPinned(scanpos) \
1001 AssertMacro(BlockNumberIsValid((scanpos).currPage) || \
1002 !BufferIsValid((scanpos).buf)), \
1003 BufferIsValid((scanpos).buf) \
1005 #define BTScanPosUnpin(scanpos) \
1007 ReleaseBuffer((scanpos).buf); \
1008 (scanpos).buf = InvalidBuffer; \
1010 #define BTScanPosUnpinIfPinned(scanpos) \
1012 if (BTScanPosIsPinned(scanpos)) \
1013 BTScanPosUnpin(scanpos); \
1016 #define BTScanPosIsValid(scanpos) \
1018 AssertMacro(BlockNumberIsValid((scanpos).currPage) || \
1019 !BufferIsValid((scanpos).buf)), \
1020 BlockNumberIsValid((scanpos).currPage) \
1022 #define BTScanPosInvalidate(scanpos) \
1024 (scanpos).currPage = InvalidBlockNumber; \
1025 (scanpos).nextPage = InvalidBlockNumber; \
1026 (scanpos).buf = InvalidBuffer; \
1027 (scanpos).lsn = InvalidXLogRecPtr; \
1028 (scanpos).nextTupleOffset = 0; \
1124 #define SK_BT_REQFWD 0x00010000
1125 #define SK_BT_REQBKWD 0x00020000
1126 #define SK_BT_INDOPTION_SHIFT 24
1127 #define SK_BT_DESC (INDOPTION_DESC << SK_BT_INDOPTION_SHIFT)
1128 #define SK_BT_NULLS_FIRST (INDOPTION_NULLS_FIRST << SK_BT_INDOPTION_SHIFT)
1138 #define BTGetFillFactor(relation) \
1139 (AssertMacro(relation->rd_rel->relkind == RELKIND_INDEX && \
1140 relation->rd_rel->relam == BTREE_AM_OID), \
1141 (relation)->rd_options ? \
1142 ((BTOptions *) (relation)->rd_options)->fillfactor : \
1143 BTREE_DEFAULT_FILLFACTOR)
1144 #define BTGetTargetPageFreeSpace(relation) \
1145 (BLCKSZ * (100 - BTGetFillFactor(relation)) / 100)
1146 #define BTGetDeduplicateItems(relation) \
1147 (AssertMacro(relation->rd_rel->relkind == RELKIND_INDEX && \
1148 relation->rd_rel->relam == BTREE_AM_OID), \
1149 ((relation)->rd_options ? \
1150 ((BTOptions *) (relation)->rd_options)->deduplicate_items : true))
1157 #define PROGRESS_BTREE_PHASE_INDEXBUILD_TABLESCAN 2
1158 #define PROGRESS_BTREE_PHASE_PERFORMSORT_1 3
1159 #define PROGRESS_BTREE_PHASE_PERFORMSORT_2 4
1160 #define PROGRESS_BTREE_PHASE_LEAF_LOAD 5
1169 bool indexUnchanged,
1177 ScanKey orderbys,
int norderbys);
1185 void *callback_state);
1205 Size newitemsz,
bool bottomupdedup);
1234 bool *newitemonleft);
1240 bool allequalimage);
1248 bool *allequalimage);
1302 bool *
res,
bool *isnull);
static Datum values[MAXATTR]
PageHeaderData * PageHeader
static char * PageGetContents(Page page)
#define SizeOfPageHeaderData
static bool PageIsNew(Page page)
#define Assert(condition)
#define FLEXIBLE_ARRAY_MEMBER
static void PGresult * res
bool(* IndexBulkDeleteCallback)(ItemPointer itemptr, void *state)
static void ItemPointerSetOffsetNumber(ItemPointerData *pointer, OffsetNumber offsetNumber)
static void ItemPointerSetBlockNumber(ItemPointerData *pointer, BlockNumber blockNumber)
static OffsetNumber ItemPointerGetOffsetNumberNoCheck(const ItemPointerData *pointer)
static BlockNumber ItemPointerGetBlockNumberNoCheck(const ItemPointerData *pointer)
struct ItemPointerData ItemPointerData
#define IndexTupleSize(itup)
#define MaxIndexTuplesPerPage
#define P_HAS_FULLXID(opaque)
bool btinsert(Relation rel, Datum *values, bool *isnull, ItemPointer ht_ctid, Relation heapRel, IndexUniqueCheck checkUnique, bool indexUnchanged, struct IndexInfo *indexInfo)
Buffer _bt_get_endpoint(Relation rel, uint32 level, bool rightmost)
Buffer _bt_relandgetbuf(Relation rel, Buffer obuf, BlockNumber blkno, int access)
void _bt_check_third_page(Relation rel, Relation heap, bool needheaptidspace, Page page, IndexTuple newtup)
bool btcanreturn(Relation index, int attno)
void _bt_parallel_release(IndexScanDesc scan, BlockNumber scan_page)
BTPageOpaqueData * BTPageOpaque
#define BT_PIVOT_HEAP_TID_ATTR
static uint16 BTreeTupleGetNPosting(IndexTuple posting)
void _bt_upgrademetapage(Page page)
void _bt_relbuf(Relation rel, Buffer buf)
IndexTuple _bt_swap_posting(IndexTuple newitem, IndexTuple oposting, int postingoff)
static bool BTreeTupleIsPivot(IndexTuple itup)
Buffer _bt_gettrueroot(Relation rel)
int _bt_getrootheight(Relation rel)
void _bt_end_vacuum(Relation rel)
bool btvalidate(Oid opclassoid)
void _bt_pageinit(Page page, Size size)
bool _bt_first(IndexScanDesc scan, ScanDirection dir)
void _bt_dedup_pass(Relation rel, Buffer buf, IndexTuple newitem, Size newitemsz, bool bottomupdedup)
OffsetNumber _bt_findsplitloc(Relation rel, Page origpage, OffsetNumber newitemoff, Size newitemsz, IndexTuple newitem, bool *newitemonleft)
static FullTransactionId BTPageGetDeleteXid(Page page)
void _bt_update_posting(BTVacuumPosting vacposting)
bool _bt_bottomupdel_pass(Relation rel, Buffer buf, Relation heapRel, Size newitemsz)
char * btbuildphasename(int64 phasenum)
bool _bt_checkkeys(IndexScanDesc scan, BTReadPageState *pstate, bool arrayKeys, IndexTuple tuple, int tupnatts)
bool _bt_dedup_save_htid(BTDedupState state, IndexTuple itup)
void _bt_end_vacuum_callback(int code, Datum arg)
void _bt_pagedel(Relation rel, Buffer leafbuf, BTVacState *vstate)
Buffer _bt_allocbuf(Relation rel, Relation heaprel)
struct BTPageOpaqueData BTPageOpaqueData
IndexScanDesc btbeginscan(Relation rel, int nkeys, int norderbys)
void _bt_delitems_vacuum(Relation rel, Buffer buf, OffsetNumber *deletable, int ndeletable, BTVacuumPosting *updatable, int nupdatable)
struct BTReadPageState BTReadPageState
static void BTreeTupleSetTopParent(IndexTuple leafhikey, BlockNumber blkno)
void _bt_freestack(BTStack stack)
static void BTreeTupleSetPosting(IndexTuple itup, uint16 nhtids, int postingoffset)
Buffer _bt_getstackbuf(Relation rel, Relation heaprel, BTStack stack, BlockNumber child)
void BTreeShmemInit(void)
void _bt_parallel_done(IndexScanDesc scan)
IndexBulkDeleteResult * btbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, IndexBulkDeleteCallback callback, void *callback_state)
void _bt_dedup_start_pending(BTDedupState state, IndexTuple base, OffsetNumber baseoff)
#define BTPageGetOpaque(page)
#define P_ISDELETED(opaque)
bytea * btoptions(Datum reloptions, bool validate)
static ItemPointer BTreeTupleGetPosting(IndexTuple posting)
void _bt_checkpage(Relation rel, Buffer buf)
BTCycleId _bt_vacuum_cycleid(Relation rel)
void _bt_metaversion(Relation rel, bool *heapkeyspace, bool *allequalimage)
static BlockNumber BTreeTupleGetTopParent(IndexTuple leafhikey)
struct BTArrayKeyInfo BTArrayKeyInfo
void btadjustmembers(Oid opfamilyoid, Oid opclassoid, List *operators, List *functions)
BTScanInsert _bt_mkscankey(Relation rel, IndexTuple itup)
struct BTPendingFSM BTPendingFSM
void _bt_killitems(IndexScanDesc scan)
IndexBulkDeleteResult * btvacuumcleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *stats)
IndexTuple _bt_form_posting(IndexTuple base, ItemPointer htids, int nhtids)
bool _bt_doinsert(Relation rel, IndexTuple itup, IndexUniqueCheck checkUnique, bool indexUnchanged, Relation heapRel)
#define MaxTIDsPerBTreePage
static void BTreeTupleSetDownLink(IndexTuple pivot, BlockNumber blkno)
bool btgettuple(IndexScanDesc scan, ScanDirection dir)
void btparallelrescan(IndexScanDesc scan)
bool _bt_start_prim_scan(IndexScanDesc scan, ScanDirection dir)
struct BTVacState BTVacState
bool _bt_check_natts(Relation rel, bool heapkeyspace, Page page, OffsetNumber offnum)
IndexTuple _bt_truncate(Relation rel, IndexTuple lastleft, IndexTuple firstright, BTScanInsert itup_key)
void _bt_set_cleanup_info(Relation rel, BlockNumber num_delpages)
#define BT_STATUS_OFFSET_MASK
static uint32 BTreeTupleGetPostingOffset(IndexTuple posting)
struct BTScanInsertData BTScanInsertData
void btbuildempty(Relation index)
struct BTMetaPageData BTMetaPageData
bool _bt_conditionallockbuf(Relation rel, Buffer buf)
Buffer _bt_getbuf(Relation rel, BlockNumber blkno, int access)
BTScanInsertData * BTScanInsert
int _bt_keep_natts_fast(Relation rel, IndexTuple lastleft, IndexTuple firstright)
static ItemPointer BTreeTupleGetPostingN(IndexTuple posting, int n)
int btgettreeheight(Relation rel)
void _bt_finish_split(Relation rel, Relation heaprel, Buffer lbuf, BTStack stack)
IndexBuildResult * btbuild(Relation heap, Relation index, struct IndexInfo *indexInfo)
void btinitparallelscan(void *target)
void _bt_parallel_build_main(dsm_segment *seg, shm_toc *toc)
static bool BTPageIsRecyclable(Page page, Relation heaprel)
void _bt_unlockbuf(Relation rel, Buffer buf)
static BlockNumber BTreeTupleGetDownLink(IndexTuple pivot)
#define INDEX_ALT_TID_MASK
BTStack _bt_search(Relation rel, Relation heaprel, BTScanInsert key, Buffer *bufP, int access)
void _bt_upgradelockbufcleanup(Relation rel, Buffer buf)
void _bt_initmetapage(Page page, BlockNumber rootbknum, uint32 level, bool allequalimage)
BTVacuumPostingData * BTVacuumPosting
void _bt_delitems_delete_check(Relation rel, Buffer buf, Relation heapRel, TM_IndexDeleteOp *delstate)
struct BTDeletedPageData BTDeletedPageData
bool _bt_vacuum_needs_cleanup(Relation rel)
OffsetNumber _bt_binsrch_insert(Relation rel, BTInsertState insertstate)
bool _bt_next(IndexScanDesc scan, ScanDirection dir)
struct BTDedupInterval BTDedupInterval
int32 _bt_compare(Relation rel, BTScanInsert key, Page page, OffsetNumber offnum)
struct BTScanPosItem BTScanPosItem
bool _bt_parallel_seize(IndexScanDesc scan, BlockNumber *pageno, bool first)
static ItemPointer BTreeTupleGetMaxHeapTID(IndexTuple itup)
static bool BTreeTupleIsPosting(IndexTuple itup)
Size BTreeShmemSize(void)
static void BTPageSetDeleted(Page page, FullTransactionId safexid)
Size btestimateparallelscan(int nkeys, int norderbys)
int64 btgetbitmap(IndexScanDesc scan, TIDBitmap *tbm)
void btmarkpos(IndexScanDesc scan)
BTDedupStateData * BTDedupState
void btendscan(IndexScanDesc scan)
void _bt_pendingfsm_finalize(Relation rel, BTVacState *vstate)
void _bt_lockbuf(Relation rel, Buffer buf, int access)
struct BTOptions BTOptions
void btrescan(IndexScanDesc scan, ScanKey scankey, int nscankeys, ScanKey orderbys, int norderbys)
bool btproperty(Oid index_oid, int attno, IndexAMProperty prop, const char *propname, bool *res, bool *isnull)
Buffer _bt_getroot(Relation rel, Relation heaprel, int access)
struct BTScanPosData BTScanPosData
static ItemPointer BTreeTupleGetHeapTID(IndexTuple itup)
void _bt_pendingfsm_init(Relation rel, BTVacState *vstate, bool cleanuponly)
Size _bt_dedup_finish_pending(Page newpage, BTDedupState state)
struct BTScanOpaqueData BTScanOpaqueData
BTInsertStateData * BTInsertState
static void BTreeTupleSetNAtts(IndexTuple itup, uint16 nkeyatts, bool heaptid)
void _bt_parallel_primscan_schedule(IndexScanDesc scan, BlockNumber prev_scan_page)
void btrestrpos(IndexScanDesc scan)
bool _bt_allequalimage(Relation rel, bool debugmessage)
struct BTDedupStateData BTDedupStateData
StaticAssertDecl(BT_OFFSET_MASK >=INDEX_MAX_KEYS, "BT_OFFSET_MASK can't fit INDEX_MAX_KEYS")
void _bt_start_array_keys(IndexScanDesc scan, ScanDirection dir)
void _bt_preprocess_keys(IndexScanDesc scan)
struct BTStackData BTStackData
BTCycleId _bt_start_vacuum(Relation rel)
BTScanPosData * BTScanPos
struct BTInsertStateData BTInsertStateData
struct BTVacuumPostingData BTVacuumPostingData
BTScanOpaqueData * BTScanOpaque
bool GlobalVisCheckRemovableFullXid(Relation rel, FullTransactionId fxid)
static const struct fns functions
static pg_noinline void Size size
BTDedupInterval intervals[MaxIndexTuplesPerPage]
FullTransactionId safexid
uint32 btm_last_cleanup_num_delpages
float8 btm_last_cleanup_num_heap_tuples
float8 vacuum_cleanup_index_scale_factor
FullTransactionId safexid
BlockNumber prev_scan_page
ScanKeyData scankeys[INDEX_MAX_KEYS]
BTArrayKeyInfo * arrayKeys
MemoryContext arrayContext
BTScanPosItem items[MaxTIDsPerBTreePage]
LocationIndex tupleOffset
struct BTStackData * bts_parent
IndexBulkDeleteResult * stats
BTPendingFSM * pendingpages
IndexBulkDeleteCallback callback
MemoryContext pagedelcontext
uint16 deletetids[FLEXIBLE_ARRAY_MEMBER]
OffsetNumber updatedoffset
static void callback(struct sockaddr *addr, struct sockaddr *mask, void *unused)
#define FirstNormalFullTransactionId