43 Datum *elems,
int nelems);
46 Datum *elems,
int nelems);
125 key->
keysz =
Min(indnkeyatts, tupnatts);
129 for (i = 0; i < indnkeyatts; i++)
179 while (stack != NULL)
215 for (
i = 0;
i < numberOfKeys;
i++)
233 if (numArrayKeys == 0)
246 "BTree array context",
264 for (
i = 0;
i < numberOfKeys;
i++)
288 &elmlen, &elmbyval, &elmalign);
291 elmlen, elmbyval, elmalign,
292 &elem_values, &elem_nulls, &num_elems);
299 for (j = 0; j < num_elems; j++)
302 elem_values[num_nonnulls++] = elem_values[j];
308 if (num_nonnulls == 0)
319 switch (
cur->sk_strategy)
326 elem_values, num_nonnulls);
336 elem_values, num_nonnulls);
339 elog(
ERROR,
"unrecognized StrategyNumber: %d",
340 (
int)
cur->sk_strategy);
350 (indoption[
cur->sk_attno - 1] & INDOPTION_DESC) != 0,
351 elem_values, num_nonnulls);
377 Datum *elems,
int nelems)
409 elog(
ERROR,
"missing operator %d(%u,%u) in opfamily %u",
410 strat, elemtype, elemtype,
414 elog(
ERROR,
"missing oprcode for operator %u", cmp_op);
420 for (i = 1; i < nelems; i++)
444 Datum *elems,
int nelems)
476 elog(
ERROR,
"missing support function %d(%u,%u) in opfamily %u",
560 int cur_elem = curArrayKey->
cur_elem;
567 cur_elem = num_elems - 1;
575 if (++cur_elem >= num_elems)
625 bool changed =
false;
635 if (curArrayKey->
cur_elem != mark_elem)
747 int new_numberOfKeys;
748 int numberOfEqualCols;
762 if (numberOfKeys < 1)
776 if (
cur->sk_attno < 1)
777 elog(
ERROR,
"btree index keys must be ordered by attribute");
780 if (numberOfKeys == 1)
788 if (
cur->sk_attno == 1)
796 new_numberOfKeys = 0;
797 numberOfEqualCols = 0;
806 memset(xform, 0,
sizeof(xform));
813 for (i = 0;;
cur++, i++)
815 if (i < numberOfKeys)
830 if (i == numberOfKeys ||
cur->sk_attno != attno)
832 int priorNumberOfEqualCols = numberOfEqualCols;
835 if (i < numberOfKeys && cur->sk_attno < attno)
836 elog(
ERROR,
"btree index keys must be ordered by attribute");
928 ScanKey outkey = &outkeys[new_numberOfKeys++];
931 if (priorNumberOfEqualCols == attno - 1)
939 if (i == numberOfKeys)
943 attno =
cur->sk_attno;
944 memset(xform, 0,
sizeof(xform));
948 j =
cur->sk_strategy - 1;
953 ScanKey outkey = &outkeys[new_numberOfKeys++];
956 if (numberOfEqualCols == attno - 1)
968 if (xform[j] == NULL)
996 ScanKey outkey = &outkeys[new_numberOfKeys++];
999 if (numberOfEqualCols == attno - 1)
1080 *result = (leftnull < rightnull);
1083 *result = (leftnull <= rightnull);
1086 *result = (leftnull == rightnull);
1089 *result = (leftnull >= rightnull);
1092 *result = (leftnull > rightnull);
1095 elog(
ERROR,
"unrecognized StrategyNumber: %d", (
int) strat);
1116 lefttype = opcintype;
1119 righttype = opcintype;
1128 if (lefttype == opcintype && righttype == optype)
1270 if ((addflags & SK_BT_DESC) && !(subkey->
sk_flags & SK_BT_DESC))
1316 elog(
ERROR,
"unrecognized StrategyNumber: %d",
1366 *continuescan =
true;
1372 for (key = so->
keyData, ikey = 0; ikey < keysz; key++, ikey++)
1427 *continuescan =
false;
1430 *continuescan =
false;
1454 *continuescan =
false;
1470 *continuescan =
false;
1496 *continuescan =
false;
1499 *continuescan =
false;
1526 int32 cmpresult = 0;
1578 *continuescan =
false;
1594 *continuescan =
false;
1615 *continuescan =
false;
1618 *continuescan =
false;
1649 result = (cmpresult < 0);
1652 result = (cmpresult <= 0);
1655 result = (cmpresult >= 0);
1658 result = (cmpresult > 0);
1661 elog(
ERROR,
"unrecognized RowCompareType: %d",
1677 *continuescan =
false;
1680 *continuescan =
false;
1727 bool killedsomething =
false;
1774 for (
i = 0;
i < numKilled;
i++)
1781 itemIndex <= so->currPos.lastItem);
1782 if (offnum < minoff)
1784 while (offnum <= maxoff)
1788 bool killtuple =
false;
1810 for (j = 0; j < nposting; j++)
1869 killedsomething =
true;
1883 if (killedsomething)
1999 elog(
ERROR,
"multiple active vacuums for index \"%s\"",
2131 bool *res,
bool *isnull)
2157 return "initializing";
2159 return "scanning table";
2161 return "sorting live tuples";
2163 return "sorting dead tuples";
2165 return "loading tuples in tree";
2220 #ifdef DEBUG_NO_TRUNCATE 2222 keepnatts = nkeyatts + 1;
2226 Min(keepnatts, nkeyatts));
2235 Assert(keepnatts == nkeyatts || keepnatts == nkeyatts + 1);
2245 if (keepnatts <= nkeyatts)
2275 tidpivot->
t_info |= newsize;
2298 #ifndef DEBUG_NO_TRUNCATE 2373 if (isNull1 != isNull2)
2438 if (isNull1 != isNull2)
2489 "BT_OFFSET_MASK can't fit INDEX_MAX_KEYS");
2525 return tupnatts == natts;
2541 return tupnatts == nkeyatts;
2557 return tupnatts == 0;
2571 return tupnatts == 0 ||
2583 return tupnatts == nkeyatts;
2618 return tupnatts > 0 && tupnatts <= nkeyatts;
2660 elog(
ERROR,
"cannot insert oversized tuple of size %zu on internal page of index \"%s\"",
2664 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
2665 errmsg(
"index row size %zu exceeds btree version %u maximum %zu for index \"%s\"",
2671 errdetail(
"Index row references tuple (%u,%u) in relation \"%s\".",
2675 errhint(
"Values larger than 1/3 of a buffer page cannot be indexed.\n" 2676 "Consider a function index of an MD5 hash of the value, " 2677 "or use full text indexing."),
2694 bool allequalimage =
true;
2731 allequalimage =
false;
2743 elog(
DEBUG1,
"index \"%s\" can safely use deduplication",
2746 elog(
DEBUG1,
"index \"%s\" cannot use deduplication",
2750 return allequalimage;
#define SK_BT_INDOPTION_SHIFT
static int _bt_keep_natts(Relation rel, IndexTuple lastleft, IndexTuple firstright, BTScanInsert itup_key)
int32 ItemPointerCompare(ItemPointer arg1, ItemPointer arg2)
#define ItemPointerGetOffsetNumberNoCheck(pointer)
static void _bt_mark_scankey_required(ScanKey skey)
void _bt_freestack(BTStack stack)
BTCycleId _bt_vacuum_cycleid(Relation rel)
bool _bt_advance_array_keys(IndexScanDesc scan, ScanDirection dir)
#define AllocSetContextCreate
#define PROGRESS_BTREE_PHASE_INDEXBUILD_TABLESCAN
void BTreeShmemInit(void)
int errhint(const char *fmt,...)
static BTVacInfo * btvacinfo
#define BTGreaterStrategyNumber
FmgrInfo * index_getprocinfo(Relation irel, AttrNumber attnum, uint16 procnum)
static bool BTreeTupleIsPivot(IndexTuple itup)
bool IsSystemRelation(Relation relation)
#define ScanDirectionIsForward(direction)
static size_t qunique_arg(void *array, size_t elements, size_t width, int(*compare)(const void *, const void *, void *), void *arg)
static ItemPointer BTreeTupleGetHeapTID(IndexTuple itup)
void ScanKeyEntryInitializeWithInfo(ScanKey entry, int flags, AttrNumber attributeNumber, StrategyNumber strategy, Oid subtype, Oid collation, FmgrInfo *finfo, Datum argument)
void MarkBufferDirtyHint(Buffer buffer, bool buffer_std)
#define RelationGetDescr(relation)
#define ItemIdMarkDead(itemId)
BTScanInsert _bt_mkscankey(Relation rel, IndexTuple itup)
#define BTEQUALIMAGE_PROC
void _bt_start_array_keys(IndexScanDesc scan, ScanDirection dir)
Buffer _bt_getbuf(Relation rel, BlockNumber blkno, int access)
MemoryContext arrayContext
static int _bt_sort_array_elements(IndexScanDesc scan, ScanKey skey, bool reverse, Datum *elems, int nelems)
#define PROGRESS_BTREE_PHASE_PERFORMSORT_1
char * btbuildphasename(int64 phasenum)
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
struct BTVacInfo BTVacInfo
#define TupleDescAttr(tupdesc, i)
struct BTSortArrayContext BTSortArrayContext
#define P_FIRSTDATAKEY(opaque)
#define ALLOCSET_SMALL_SIZES
struct BTOneVacInfo BTOneVacInfo
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
#define BTMaxItemSizeNoHeapTid(page)
#define FLEXIBLE_ARRAY_MEMBER
int errcode(int sqlerrcode)
double vacuum_cleanup_index_scale_factor
BTOneVacInfo vacuums[FLEXIBLE_ARRAY_MEMBER]
#define BTScanPosIsValid(scanpos)
void MemoryContextReset(MemoryContext context)
void _bt_end_vacuum_callback(int code, Datum arg)
Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
#define ItemIdIsDead(itemId)
#define BTreeTupleGetNAtts(itup, rel)
#define OidIsValid(objectId)
#define PageGetMaxOffsetNumber(page)
BTPageOpaqueData * BTPageOpaque
void * build_reloptions(Datum reloptions, bool validate, relopt_kind kind, Size relopt_struct_size, const relopt_parse_elt *relopt_elems, int num_relopt_elems)
Size BTreeShmemSize(void)
#define BTLessEqualStrategyNumber
void LWLockRelease(LWLock *lock)
#define BTCommuteStrategyNumber(strat)
static void BTreeTupleSetNAtts(IndexTuple itup, uint16 nkeyatts, bool heaptid)
IndexTuple _bt_truncate(Relation rel, IndexTuple lastleft, IndexTuple firstright, BTScanInsert itup_key)
#define ScanDirectionIsBackward(direction)
void _bt_restore_array_keys(IndexScanDesc scan)
#define StaticAssertStmt(condition, errmessage)
int errtableconstraint(Relation rel, const char *conname)
static Datum _bt_find_extreme_element(IndexScanDesc scan, ScanKey skey, StrategyNumber strat, Datum *elems, int nelems)
void _bt_killitems(IndexScanDesc scan)
void pfree(void *pointer)
static int compare(const void *arg1, const void *arg2)
#define ObjectIdGetDatum(X)
BTScanOpaqueData * BTScanOpaque
void * ShmemInitStruct(const char *name, Size size, bool *foundPtr)
void fmgr_info(Oid functionId, FmgrInfo *finfo)
StrategyNumber sk_strategy
#define PROGRESS_BTREE_PHASE_PERFORMSORT_2
void _bt_end_vacuum(Relation rel)
XLogRecPtr BufferGetLSNAtomic(Buffer buffer)
#define BTScanPosIsPinned(scanpos)
#define RegProcedureIsValid(p)
#define FirstOffsetNumber
IndexTupleData * IndexTuple
int errdetail(const char *fmt,...)
Oid get_opfamily_member(Oid opfamily, Oid lefttype, Oid righttype, int16 strategy)
void _bt_mark_array_keys(IndexScanDesc scan)
#define IndexRelationGetNumberOfAttributes(relation)
IndexTuple index_truncate_tuple(TupleDesc sourceDescriptor, IndexTuple source, int leavenatts)
#define RelationGetRelationName(relation)
FormData_pg_attribute * Form_pg_attribute
MemoryContext CurrentMemoryContext
#define IndexRelationGetNumberOfKeyAttributes(relation)
#define BTREE_NOVAC_VERSION
#define BufferGetPage(buffer)
Datum OidFunctionCall2Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2)
void _bt_metaversion(Relation rel, bool *heapkeyspace, bool *allequalimage)
static int _bt_compare_array_elements(const void *a, const void *b, void *arg)
static bool _bt_fix_scankey_strategy(ScanKey skey, int16 *indoption)
void _bt_preprocess_keys(IndexScanDesc scan)
void qsort_arg(void *base, size_t nel, size_t elsize, qsort_arg_comparator cmp, void *arg)
#define PROGRESS_CREATEIDX_SUBPHASE_INITIALIZE
#define PageGetItemId(page, offsetNumber)
#define SK_BT_NULLS_FIRST
static ItemPointer BTreeTupleGetMaxHeapTID(IndexTuple itup)
Size mul_size(Size s1, Size s2)
struct ParallelIndexScanDescData * parallel_scan
void * palloc0(Size size)
void _bt_lockbuf(Relation rel, Buffer buf, int access)
Size add_size(Size s1, Size s2)
static bool _bt_check_rowcompare(ScanKey skey, IndexTuple tuple, int tupnatts, TupleDesc tupdesc, ScanDirection dir, bool *continuescan)
bool _bt_checkkeys(IndexScanDesc scan, IndexTuple tuple, int tupnatts, ScanDirection dir, bool *continuescan)
RegProcedure get_opcode(Oid opno)
void _bt_relbuf(Relation rel, Buffer buf)
#define ereport(elevel,...)
Datum OidFunctionCall1Coll(Oid functionId, Oid collation, Datum arg1)
static ItemPointer BTreeTupleGetPostingN(IndexTuple posting, int n)
static bool BTreeTupleIsPosting(IndexTuple itup)
static uint32 BTreeTupleGetPostingOffset(IndexTuple posting)
bool _bt_check_natts(Relation rel, bool heapkeyspace, Page page, OffsetNumber offnum)
#define Assert(condition)
Oid get_opfamily_proc(Oid opfamily, Oid lefttype, Oid righttype, int16 procnum)
bool btproperty(Oid index_oid, int attno, IndexAMProperty prop, const char *propname, bool *res, bool *isnull)
#define OffsetNumberNext(offsetNumber)
#define PageGetSpecialPointer(page)
#define OffsetNumberPrev(offsetNumber)
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
#define index_getattr(tup, attnum, tupleDesc, isnull)
#define ItemPointerGetOffsetNumber(pointer)
struct BTStackData * bts_parent
ScanKeyData scankeys[INDEX_MAX_KEYS]
bool ItemPointerEquals(ItemPointer pointer1, ItemPointer pointer2)
void _bt_check_third_page(Relation rel, Relation heap, bool needheaptidspace, Page page, IndexTuple newtup)
#define PROGRESS_BTREE_PHASE_LEAF_LOAD
BTScanPosItem items[MaxTIDsPerBTreePage]
#define DatumGetPointer(X)
struct ScanKeyData * keyData
#define ItemPointerSetOffsetNumber(pointer, offsetNumber)
#define BTMaxItemSize(page)
void _bt_unlockbuf(Relation rel, Buffer buf)
void _bt_parallel_advance_array_keys(IndexScanDesc scan)
void deconstruct_array(ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
int _bt_keep_natts_fast(Relation rel, IndexTuple lastleft, IndexTuple firstright)
int errmsg(const char *fmt,...)
BTArrayKeyInfo * arrayKeys
void _bt_preprocess_array_keys(IndexScanDesc scan)
static uint16 BTreeTupleGetNPosting(IndexTuple posting)
bool datum_image_eq(Datum value1, Datum value2, bool typByVal, int typLen)
bytea * btoptions(Datum reloptions, bool validate)
#define BTMaxStrategyNumber
static bool _bt_compare_scankey_args(IndexScanDesc scan, ScanKey op, ScanKey leftarg, ScanKey rightarg, bool *result)
#define ItemPointerGetBlockNumber(pointer)
BTCycleId _bt_start_vacuum(Relation rel)
#define BTLessStrategyNumber
#define BT_PIVOT_HEAP_TID_ATTR
bool _bt_allequalimage(Relation rel, bool debugmessage)
#define P_RIGHTMOST(opaque)
#define INVERT_COMPARE_RESULT(var)
#define BTEqualStrategyNumber
#define offsetof(type, field)
#define BTGreaterEqualStrategyNumber
#define PageGetItem(page, itemId)
#define IndexTupleSize(itup)
#define ItemPointerCopy(fromPointer, toPointer)
#define PG_USED_FOR_ASSERTS_ONLY
#define DatumGetArrayTypeP(X)