22#include "catalog/pg_am_d.h"
74#define BTPageGetOpaque(page) ((BTPageOpaque) PageGetSpecialPointer(page))
77#define BTP_LEAF (1 << 0)
78#define BTP_ROOT (1 << 1)
79#define BTP_DELETED (1 << 2)
80#define BTP_META (1 << 3)
81#define BTP_HALF_DEAD (1 << 4)
82#define BTP_SPLIT_END (1 << 5)
83#define BTP_HAS_GARBAGE (1 << 6)
84#define BTP_INCOMPLETE_SPLIT (1 << 7)
85#define BTP_HAS_FULLXID (1 << 8)
94#define MAX_BT_CYCLE_ID 0xFF7F
122#define BTPageGetMeta(p) \
123 ((BTMetaPageData *) PageGetContents(p))
149#define BTREE_METAPAGE 0
150#define BTREE_MAGIC 0x053162
151#define BTREE_VERSION 4
152#define BTREE_MIN_VERSION 2
153#define BTREE_NOVAC_VERSION 3
165#define BTMaxItemSize \
166 (MAXALIGN_DOWN((BLCKSZ - \
167 MAXALIGN(SizeOfPageHeaderData + 3*sizeof(ItemIdData)) - \
168 MAXALIGN(sizeof(BTPageOpaqueData))) / 3) - \
169 MAXALIGN(sizeof(ItemPointerData)))
170#define BTMaxItemSizeNoHeapTid \
171 MAXALIGN_DOWN((BLCKSZ - \
172 MAXALIGN(SizeOfPageHeaderData + 3*sizeof(ItemIdData)) - \
173 MAXALIGN(sizeof(BTPageOpaqueData))) / 3)
186#define MaxTIDsPerBTreePage \
187 (int) ((BLCKSZ - SizeOfPageHeaderData - sizeof(BTPageOpaqueData)) / \
188 sizeof(ItemPointerData))
200#define BTREE_MIN_FILLFACTOR 10
201#define BTREE_DEFAULT_FILLFACTOR 90
202#define BTREE_NONLEAF_FILLFACTOR 70
203#define BTREE_SINGLEVAL_FILLFACTOR 96
219#define P_LEFTMOST(opaque) ((opaque)->btpo_prev == P_NONE)
220#define P_RIGHTMOST(opaque) ((opaque)->btpo_next == P_NONE)
221#define P_ISLEAF(opaque) (((opaque)->btpo_flags & BTP_LEAF) != 0)
222#define P_ISROOT(opaque) (((opaque)->btpo_flags & BTP_ROOT) != 0)
223#define P_ISDELETED(opaque) (((opaque)->btpo_flags & BTP_DELETED) != 0)
224#define P_ISMETA(opaque) (((opaque)->btpo_flags & BTP_META) != 0)
225#define P_ISHALFDEAD(opaque) (((opaque)->btpo_flags & BTP_HALF_DEAD) != 0)
226#define P_IGNORE(opaque) (((opaque)->btpo_flags & (BTP_DELETED|BTP_HALF_DEAD)) != 0)
227#define P_HAS_GARBAGE(opaque) (((opaque)->btpo_flags & BTP_HAS_GARBAGE) != 0)
228#define P_INCOMPLETE_SPLIT(opaque) (((opaque)->btpo_flags & BTP_INCOMPLETE_SPLIT) != 0)
229#define P_HAS_FULLXID(opaque) (((opaque)->btpo_flags & BTP_HAS_FULLXID) != 0)
368#define P_HIKEY ((OffsetNumber) 1)
369#define P_FIRSTKEY ((OffsetNumber) 2)
370#define P_FIRSTDATAKEY(opaque) (P_RIGHTMOST(opaque) ? P_HIKEY : P_FIRSTKEY)
460#define INDEX_ALT_TID_MASK INDEX_AM_RESERVED_BIT
463#define BT_OFFSET_MASK 0x0FFF
464#define BT_STATUS_OFFSET_MASK 0xF000
466#define BT_PIVOT_HEAP_TID_ATTR 0x1000
467#define BT_IS_POSTING 0x2000
474 "BT_OFFSET_MASK can't fit INDEX_MAX_KEYS");
578#define BTreeTupleGetNAtts(itup, rel) \
580 (BTreeTupleIsPivot(itup)) ? \
582 ItemPointerGetOffsetNumberNoCheck(&(itup)->t_tid) & BT_OFFSET_MASK \
585 IndexRelationGetNumberOfAttributes(rel) \
600 Assert(!heaptid || nkeyatts > 0);
686#define BTCommuteStrategyNumber(strat) (BTMaxStrategyNumber + 1 - (strat))
717#define BTORDER_PROC 1
718#define BTSORTSUPPORT_PROC 2
719#define BTINRANGE_PROC 3
720#define BTEQUALIMAGE_PROC 4
721#define BTOPTIONS_PROC 5
722#define BTSKIPSUPPORT_PROC 6
730#define BT_READ BUFFER_LOCK_SHARE
731#define BT_WRITE BUFFER_LOCK_EXCLUSIVE
1004#define BTScanPosIsPinned(scanpos) \
1006 AssertMacro(BlockNumberIsValid((scanpos).currPage) || \
1007 !BufferIsValid((scanpos).buf)), \
1008 BufferIsValid((scanpos).buf) \
1010#define BTScanPosUnpin(scanpos) \
1012 ReleaseBuffer((scanpos).buf); \
1013 (scanpos).buf = InvalidBuffer; \
1015#define BTScanPosUnpinIfPinned(scanpos) \
1017 if (BTScanPosIsPinned(scanpos)) \
1018 BTScanPosUnpin(scanpos); \
1021#define BTScanPosIsValid(scanpos) \
1023 AssertMacro(BlockNumberIsValid((scanpos).currPage) || \
1024 !BufferIsValid((scanpos).buf)), \
1025 BlockNumberIsValid((scanpos).currPage) \
1027#define BTScanPosInvalidate(scanpos) \
1029 (scanpos).buf = InvalidBuffer; \
1030 (scanpos).currPage = InvalidBlockNumber; \
1134#define SK_BT_REQFWD 0x00010000
1135#define SK_BT_REQBKWD 0x00020000
1136#define SK_BT_SKIP 0x00040000
1139#define SK_BT_MINVAL 0x00080000
1140#define SK_BT_MAXVAL 0x00100000
1141#define SK_BT_NEXT 0x00200000
1142#define SK_BT_PRIOR 0x00400000
1145#define SK_BT_INDOPTION_SHIFT 24
1146#define SK_BT_DESC (INDOPTION_DESC << SK_BT_INDOPTION_SHIFT)
1147#define SK_BT_NULLS_FIRST (INDOPTION_NULLS_FIRST << SK_BT_INDOPTION_SHIFT)
1157#define BTGetFillFactor(relation) \
1158 (AssertMacro(relation->rd_rel->relkind == RELKIND_INDEX && \
1159 relation->rd_rel->relam == BTREE_AM_OID), \
1160 (relation)->rd_options ? \
1161 ((BTOptions *) (relation)->rd_options)->fillfactor : \
1162 BTREE_DEFAULT_FILLFACTOR)
1163#define BTGetTargetPageFreeSpace(relation) \
1164 (BLCKSZ * (100 - BTGetFillFactor(relation)) / 100)
1165#define BTGetDeduplicateItems(relation) \
1166 (AssertMacro(relation->rd_rel->relkind == RELKIND_INDEX && \
1167 relation->rd_rel->relam == BTREE_AM_OID), \
1168 ((relation)->rd_options ? \
1169 ((BTOptions *) (relation)->rd_options)->deduplicate_items : true))
1176#define PROGRESS_BTREE_PHASE_INDEXBUILD_TABLESCAN 2
1177#define PROGRESS_BTREE_PHASE_PERFORMSORT_1 3
1178#define PROGRESS_BTREE_PHASE_PERFORMSORT_2 4
1179#define PROGRESS_BTREE_PHASE_LEAF_LOAD 5
1188 bool indexUnchanged,
1196 ScanKey orderbys,
int norderbys);
1204 void *callback_state);
1229 Size newitemsz,
bool bottomupdedup);
1258 bool *newitemonleft);
1264 bool allequalimage);
1272 bool *allequalimage);
1319 Datum tupdatum,
bool tupnull,
1321 int32 *set_elem_result);
1338 bool *res,
bool *isnull);
static bool validate(Port *port, const char *auth)
static Datum values[MAXATTR]
PageHeaderData * PageHeader
static bool PageIsNew(const PageData *page)
#define SizeOfPageHeaderData
static char * PageGetContents(Page page)
#define FLEXIBLE_ARRAY_MEMBER
bool(* IndexBulkDeleteCallback)(ItemPointer itemptr, void *state)
Assert(PointerIsAligned(start, uint64))
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
static Size IndexTupleSize(const IndexTupleData *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)
void _bt_parallel_primscan_schedule(IndexScanDesc scan, BlockNumber curr_page)
bool btcanreturn(Relation index, int attno)
bool _bt_scanbehind_checkkeys(IndexScanDesc scan, ScanDirection dir, IndexTuple finaltup)
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)
bool _bt_parallel_seize(IndexScanDesc scan, BlockNumber *next_scan_page, BlockNumber *last_curr_page, bool first)
void _bt_update_posting(BTVacuumPosting vacposting)
bool _bt_bottomupdel_pass(Relation rel, Buffer buf, Relation heapRel, Size newitemsz)
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
StrategyNumber bttranslatecmptype(CompareType cmptype, Oid opfamily)
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
int _bt_binsrch_array_skey(FmgrInfo *orderproc, bool cur_elem_trig, ScanDirection dir, Datum tupdatum, bool tupnull, BTArrayKeyInfo *array, ScanKey cur, int32 *set_elem_result)
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)
Size btestimateparallelscan(Relation rel, int nkeys, int norderbys)
void BTreeShmemInit(void)
void _bt_parallel_done(IndexScanDesc scan)
void _bt_dedup_start_pending(BTDedupState state, IndexTuple base, OffsetNumber baseoff)
#define BTPageGetOpaque(page)
#define P_ISDELETED(opaque)
static ItemPointer BTreeTupleGetPosting(IndexTuple posting)
void _bt_checkpage(Relation rel, Buffer buf)
IndexBulkDeleteResult * btvacuumcleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *stats)
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)
IndexTuple _bt_form_posting(IndexTuple base, ItemPointer htids, int nhtids)
bool _bt_doinsert(Relation rel, IndexTuple itup, IndexUniqueCheck checkUnique, bool indexUnchanged, Relation heapRel)
CompareType bttranslatestrategy(StrategyNumber strategy, Oid opfamily)
#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)
void btinitparallelscan(void *target)
IndexBulkDeleteResult * btbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, IndexBulkDeleteCallback callback, void *callback_state)
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_set_startikey(IndexScanDesc scan, BTReadPageState *pstate)
IndexBuildResult * btbuild(Relation heap, Relation index, struct IndexInfo *indexInfo)
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)
char * btbuildphasename(int64 phasenum)
struct BTDedupInterval BTDedupInterval
int32 _bt_compare(Relation rel, BTScanInsert key, Page page, OffsetNumber offnum)
struct BTScanPosItem BTScanPosItem
bytea * btoptions(Datum reloptions, bool validate)
static ItemPointer BTreeTupleGetMaxHeapTID(IndexTuple itup)
static bool BTreeTupleIsPosting(IndexTuple itup)
Size BTreeShmemSize(void)
static void BTPageSetDeleted(Page page, FullTransactionId safexid)
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_parallel_release(IndexScanDesc scan, BlockNumber next_scan_page, BlockNumber curr_page)
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 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
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
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