43 Datum *elems,
int nelems);
46 Datum *elems,
int nelems);
119 key->heapkeyspace =
true;
120 key->allequalimage =
false;
122 key->anynullkeys =
false;
123 key->nextkey =
false;
124 key->pivotsearch =
false;
125 key->keysz =
Min(indnkeyatts, tupnatts);
126 key->scantid =
key->heapkeyspace && itup ?
128 skey =
key->scankeys;
129 for (
i = 0;
i < indnkeyatts;
i++)
165 key->anynullkeys =
true;
172 if (rel->
rd_index->indnullsnotdistinct)
173 key->anynullkeys =
false;
186 while (stack != NULL)
222 for (
i = 0;
i < numberOfKeys;
i++)
240 if (numArrayKeys == 0)
253 "BTree array context",
271 for (
i = 0;
i < numberOfKeys;
i++)
295 &elmlen, &elmbyval, &elmalign);
298 elmlen, elmbyval, elmalign,
299 &elem_values, &elem_nulls, &num_elems);
306 for (
j = 0;
j < num_elems;
j++)
309 elem_values[num_nonnulls++] = elem_values[
j];
315 if (num_nonnulls == 0)
326 switch (
cur->sk_strategy)
333 elem_values, num_nonnulls);
343 elem_values, num_nonnulls);
346 elog(
ERROR,
"unrecognized StrategyNumber: %d",
347 (
int)
cur->sk_strategy);
357 (indoption[
cur->sk_attno - 1] & INDOPTION_DESC) != 0,
358 elem_values, num_nonnulls);
384 Datum *elems,
int nelems)
416 elog(
ERROR,
"missing operator %d(%u,%u) in opfamily %u",
417 strat, elemtype, elemtype,
421 elog(
ERROR,
"missing oprcode for operator %u", cmp_op);
427 for (
i = 1;
i < nelems;
i++)
451 Datum *elems,
int nelems)
483 elog(
ERROR,
"missing support function %d(%u,%u) in opfamily %u",
567 int cur_elem = curArrayKey->
cur_elem;
574 cur_elem = num_elems - 1;
582 if (++cur_elem >= num_elems)
632 bool changed =
false;
642 if (curArrayKey->
cur_elem != mark_elem)
754 int new_numberOfKeys;
755 int numberOfEqualCols;
769 if (numberOfKeys < 1)
783 if (
cur->sk_attno < 1)
784 elog(
ERROR,
"btree index keys must be ordered by attribute");
787 if (numberOfKeys == 1)
795 if (
cur->sk_attno == 1)
803 new_numberOfKeys = 0;
804 numberOfEqualCols = 0;
813 memset(xform, 0,
sizeof(xform));
820 for (
i = 0;;
cur++,
i++)
822 if (
i < numberOfKeys)
837 if (
i == numberOfKeys ||
cur->sk_attno != attno)
839 int priorNumberOfEqualCols = numberOfEqualCols;
842 if (i < numberOfKeys && cur->sk_attno < attno)
843 elog(
ERROR,
"btree index keys must be ordered by attribute");
935 ScanKey outkey = &outkeys[new_numberOfKeys++];
938 if (priorNumberOfEqualCols == attno - 1)
946 if (
i == numberOfKeys)
950 attno =
cur->sk_attno;
951 memset(xform, 0,
sizeof(xform));
955 j =
cur->sk_strategy - 1;
960 ScanKey outkey = &outkeys[new_numberOfKeys++];
963 if (numberOfEqualCols == attno - 1)
975 if (xform[
j] == NULL)
1003 ScanKey outkey = &outkeys[new_numberOfKeys++];
1006 if (numberOfEqualCols == attno - 1)
1087 *result = (leftnull < rightnull);
1090 *result = (leftnull <= rightnull);
1093 *result = (leftnull == rightnull);
1096 *result = (leftnull >= rightnull);
1099 *result = (leftnull > rightnull);
1102 elog(
ERROR,
"unrecognized StrategyNumber: %d", (
int) strat);
1123 lefttype = opcintype;
1126 righttype = opcintype;
1135 if (lefttype == opcintype && righttype == optype)
1323 elog(
ERROR,
"unrecognized StrategyNumber: %d",
1373 *continuescan =
true;
1379 for (
key = so->
keyData, ikey = 0; ikey < keysz;
key++, ikey++)
1385 if (
key->sk_attno > tupnatts)
1434 *continuescan =
false;
1437 *continuescan =
false;
1461 *continuescan =
false;
1477 *continuescan =
false;
1487 datum,
key->sk_argument);
1503 *continuescan =
false;
1506 *continuescan =
false;
1533 int32 cmpresult = 0;
1585 *continuescan =
false;
1601 *continuescan =
false;
1622 *continuescan =
false;
1625 *continuescan =
false;
1656 result = (cmpresult < 0);
1659 result = (cmpresult <= 0);
1662 result = (cmpresult >= 0);
1665 result = (cmpresult > 0);
1668 elog(
ERROR,
"unrecognized RowCompareType: %d",
1684 *continuescan =
false;
1687 *continuescan =
false;
1734 bool killedsomething =
false;
1781 for (
i = 0;
i < numKilled;
i++)
1788 itemIndex <= so->currPos.lastItem);
1789 if (offnum < minoff)
1791 while (offnum <= maxoff)
1795 bool killtuple =
false;
1817 for (
j = 0;
j < nposting;
j++)
1876 killedsomething =
true;
1890 if (killedsomething)
2006 elog(
ERROR,
"multiple active vacuums for index \"%s\"",
2116 offsetof(
BTOptions, vacuum_cleanup_index_scale_factor)},
2136 bool *
res,
bool *isnull)
2162 return "initializing";
2164 return "scanning table";
2166 return "sorting live tuples";
2168 return "sorting dead tuples";
2170 return "loading tuples in tree";
2225 #ifdef DEBUG_NO_TRUNCATE
2227 keepnatts = nkeyatts + 1;
2231 Min(keepnatts, nkeyatts));
2240 Assert(keepnatts == nkeyatts || keepnatts == nkeyatts + 1);
2250 if (keepnatts <= nkeyatts)
2280 tidpivot->
t_info |= newsize;
2303 #ifndef DEBUG_NO_TRUNCATE
2378 if (isNull1 != isNull2)
2443 if (isNull1 != isNull2)
2523 return tupnatts == natts;
2539 return tupnatts == nkeyatts;
2555 return tupnatts == 0;
2569 return tupnatts == 0 ||
2581 return tupnatts == nkeyatts;
2615 return tupnatts > 0 && tupnatts <= nkeyatts;
2657 elog(
ERROR,
"cannot insert oversized tuple of size %zu on internal page of index \"%s\"",
2661 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
2662 errmsg(
"index row size %zu exceeds btree version %u maximum %zu for index \"%s\"",
2668 errdetail(
"Index row references tuple (%u,%u) in relation \"%s\".",
2672 errhint(
"Values larger than 1/3 of a buffer page cannot be indexed.\n"
2673 "Consider a function index of an MD5 hash of the value, "
2674 "or use full text indexing."),
2691 bool allequalimage =
true;
2716 allequalimage =
false;
2724 elog(
DEBUG1,
"index \"%s\" can safely use deduplication",
2727 elog(
DEBUG1,
"index \"%s\" cannot use deduplication",
2731 return allequalimage;
#define DatumGetArrayTypeP(X)
void deconstruct_array(ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
XLogRecPtr BufferGetLSNAtomic(Buffer buffer)
void MarkBufferDirtyHint(Buffer buffer, bool buffer_std)
static Page BufferGetPage(Buffer buffer)
static Item PageGetItem(Page page, ItemId itemId)
static ItemId PageGetItemId(Page page, OffsetNumber offsetNumber)
static OffsetNumber PageGetMaxOffsetNumber(Page page)
#define RegProcedureIsValid(p)
#define INVERT_COMPARE_RESULT(var)
#define PG_USED_FOR_ASSERTS_ONLY
#define FLEXIBLE_ARRAY_MEMBER
#define OidIsValid(objectId)
bool datum_image_eq(Datum value1, Datum value2, bool typByVal, int typLen)
static void PGresult * res
elog(ERROR, "%s: %s", p2, msg)
int errdetail(const char *fmt,...)
int errhint(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
Datum OidFunctionCall2Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2)
Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
void fmgr_info(Oid functionId, FmgrInfo *finfo)
Datum OidFunctionCall1Coll(Oid functionId, Oid collation, Datum arg1)
static int compare(const void *arg1, const void *arg2)
FmgrInfo * index_getprocinfo(Relation irel, AttrNumber attnum, uint16 procnum)
IndexTuple index_truncate_tuple(TupleDesc sourceDescriptor, IndexTuple source, int leavenatts)
if(TABLE==NULL||TABLE_index==NULL)
#define ItemIdMarkDead(itemId)
#define ItemIdIsDead(itemId)
int32 ItemPointerCompare(ItemPointer arg1, ItemPointer arg2)
bool ItemPointerEquals(ItemPointer pointer1, ItemPointer pointer2)
static void ItemPointerSetOffsetNumber(ItemPointerData *pointer, OffsetNumber offsetNumber)
static OffsetNumber ItemPointerGetOffsetNumber(const ItemPointerData *pointer)
static OffsetNumber ItemPointerGetOffsetNumberNoCheck(const ItemPointerData *pointer)
static BlockNumber ItemPointerGetBlockNumber(const ItemPointerData *pointer)
static void ItemPointerCopy(const ItemPointerData *fromPointer, ItemPointerData *toPointer)
IndexTupleData * IndexTuple
#define IndexTupleSize(itup)
static Datum index_getattr(IndexTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
Assert(fmt[strlen(fmt) - 1] !='\n')
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
Oid get_opfamily_proc(Oid opfamily, Oid lefttype, Oid righttype, int16 procnum)
RegProcedure get_opcode(Oid opno)
Oid get_opfamily_member(Oid opfamily, Oid lefttype, Oid righttype, int16 strategy)
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
void LWLockRelease(LWLock *lock)
void MemoryContextReset(MemoryContext context)
void pfree(void *pointer)
void * palloc0(Size size)
MemoryContext CurrentMemoryContext
#define AllocSetContextCreate
#define ALLOCSET_SMALL_SIZES
void _bt_relbuf(Relation rel, Buffer buf)
void _bt_metaversion(Relation rel, bool *heapkeyspace, bool *allequalimage)
Buffer _bt_getbuf(Relation rel, BlockNumber blkno, int access)
void _bt_unlockbuf(Relation rel, Buffer buf)
void _bt_lockbuf(Relation rel, Buffer buf, int access)
void _bt_parallel_advance_array_keys(IndexScanDesc scan)
#define BTScanPosIsPinned(scanpos)
#define BT_PIVOT_HEAP_TID_ATTR
static uint16 BTreeTupleGetNPosting(IndexTuple posting)
static bool BTreeTupleIsPivot(IndexTuple itup)
#define PROGRESS_BTREE_PHASE_PERFORMSORT_2
#define BTMaxItemSizeNoHeapTid(page)
#define PROGRESS_BTREE_PHASE_LEAF_LOAD
#define BTEQUALIMAGE_PROC
#define BTPageGetOpaque(page)
#define BTScanPosIsValid(scanpos)
#define PROGRESS_BTREE_PHASE_INDEXBUILD_TABLESCAN
#define SK_BT_INDOPTION_SHIFT
#define P_FIRSTDATAKEY(opaque)
#define PROGRESS_BTREE_PHASE_PERFORMSORT_1
static uint32 BTreeTupleGetPostingOffset(IndexTuple posting)
#define P_RIGHTMOST(opaque)
#define BTMaxItemSize(page)
#define SK_BT_NULLS_FIRST
static ItemPointer BTreeTupleGetPostingN(IndexTuple posting, int n)
#define BTCommuteStrategyNumber(strat)
static ItemPointer BTreeTupleGetMaxHeapTID(IndexTuple itup)
static bool BTreeTupleIsPosting(IndexTuple itup)
#define BTREE_NOVAC_VERSION
static ItemPointer BTreeTupleGetHeapTID(IndexTuple itup)
static void BTreeTupleSetNAtts(IndexTuple itup, uint16 nkeyatts, bool heaptid)
#define BTreeTupleGetNAtts(itup, rel)
BTScanOpaqueData * BTScanOpaque
void _bt_check_third_page(Relation rel, Relation heap, bool needheaptidspace, Page page, IndexTuple newtup)
void _bt_end_vacuum(Relation rel)
static Datum _bt_find_extreme_element(IndexScanDesc scan, ScanKey skey, StrategyNumber strat, Datum *elems, int nelems)
char * btbuildphasename(int64 phasenum)
void _bt_end_vacuum_callback(int code, Datum arg)
void _bt_freestack(BTStack stack)
void BTreeShmemInit(void)
static int _bt_sort_array_elements(IndexScanDesc scan, ScanKey skey, bool reverse, Datum *elems, int nelems)
struct BTSortArrayContext BTSortArrayContext
bytea * btoptions(Datum reloptions, bool validate)
bool _bt_advance_array_keys(IndexScanDesc scan, ScanDirection dir)
struct BTVacInfo BTVacInfo
BTCycleId _bt_vacuum_cycleid(Relation rel)
BTScanInsert _bt_mkscankey(Relation rel, IndexTuple itup)
void _bt_killitems(IndexScanDesc scan)
bool _bt_checkkeys(IndexScanDesc scan, IndexTuple tuple, int tupnatts, ScanDirection dir, bool *continuescan)
static bool _bt_fix_scankey_strategy(ScanKey skey, int16 *indoption)
void _bt_preprocess_array_keys(IndexScanDesc scan)
bool _bt_check_natts(Relation rel, bool heapkeyspace, Page page, OffsetNumber offnum)
IndexTuple _bt_truncate(Relation rel, IndexTuple lastleft, IndexTuple firstright, BTScanInsert itup_key)
int _bt_keep_natts_fast(Relation rel, IndexTuple lastleft, IndexTuple firstright)
static BTVacInfo * btvacinfo
static bool _bt_compare_scankey_args(IndexScanDesc scan, ScanKey op, ScanKey leftarg, ScanKey rightarg, bool *result)
void _bt_restore_array_keys(IndexScanDesc scan)
static void _bt_mark_scankey_required(ScanKey skey)
static int _bt_compare_array_elements(const void *a, const void *b, void *arg)
Size BTreeShmemSize(void)
void _bt_mark_array_keys(IndexScanDesc scan)
static int _bt_keep_natts(Relation rel, IndexTuple lastleft, IndexTuple firstright, BTScanInsert itup_key)
bool btproperty(Oid index_oid, int attno, IndexAMProperty prop, const char *propname, bool *res, bool *isnull)
bool _bt_allequalimage(Relation rel, bool debugmessage)
struct BTOneVacInfo BTOneVacInfo
void _bt_start_array_keys(IndexScanDesc scan, ScanDirection dir)
void _bt_preprocess_keys(IndexScanDesc scan)
static bool _bt_check_rowcompare(ScanKey skey, IndexTuple tuple, int tupnatts, TupleDesc tupdesc, ScanDirection dir, bool *continuescan)
BTCycleId _bt_start_vacuum(Relation rel)
#define OffsetNumberNext(offsetNumber)
#define FirstOffsetNumber
#define OffsetNumberPrev(offsetNumber)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
FormData_pg_attribute * Form_pg_attribute
void qsort_arg(void *base, size_t nel, size_t elsize, qsort_arg_comparator cmp, void *arg)
static bool DatumGetBool(Datum X)
static Datum ObjectIdGetDatum(Oid X)
static Pointer DatumGetPointer(Datum X)
static int32 DatumGetInt32(Datum X)
#define PROGRESS_CREATEIDX_SUBPHASE_INITIALIZE
static size_t qunique_arg(void *array, size_t elements, size_t width, int(*compare)(const void *, const void *, void *), void *arg)
#define RelationGetDescr(relation)
#define RelationGetRelationName(relation)
#define IndexRelationGetNumberOfAttributes(relation)
#define IndexRelationGetNumberOfKeyAttributes(relation)
int errtableconstraint(Relation rel, const char *conname)
void * build_reloptions(Datum reloptions, bool validate, relopt_kind kind, Size relopt_struct_size, const relopt_parse_elt *relopt_elems, int num_relopt_elems)
void ScanKeyEntryInitializeWithInfo(ScanKey entry, int flags, AttrNumber attributeNumber, StrategyNumber strategy, Oid subtype, Oid collation, FmgrInfo *finfo, Datum argument)
#define ScanDirectionIsForward(direction)
#define ScanDirectionIsBackward(direction)
Size add_size(Size s1, Size s2)
void * ShmemInitStruct(const char *name, Size size, bool *foundPtr)
Size mul_size(Size s1, Size s2)
#define BTGreaterStrategyNumber
#define BTMaxStrategyNumber
#define BTLessStrategyNumber
#define BTEqualStrategyNumber
#define BTLessEqualStrategyNumber
#define BTGreaterEqualStrategyNumber
ScanKeyData scankeys[INDEX_MAX_KEYS]
BTArrayKeyInfo * arrayKeys
MemoryContext arrayContext
BTScanPosItem items[MaxTIDsPerBTreePage]
struct BTStackData * bts_parent
BTOneVacInfo vacuums[FLEXIBLE_ARRAY_MEMBER]
struct ScanKeyData * keyData
struct ParallelIndexScanDescData * parallel_scan
StrategyNumber sk_strategy
#define TupleDescAttr(tupdesc, i)