32 #define LOOK_AHEAD_REQUIRED_RECHECKS 3
33 #define LOOK_AHEAD_DEFAULT_DISTANCE 5
53 Datum *elems,
int nelems);
55 bool reverse,
Datum *elems,
int nelems);
58 Oid origelemtype,
Oid nextelemtype,
59 Datum *elems_orig,
int *nelems_orig,
60 Datum *elems_next,
int nelems_next);
69 Datum tupdatum,
bool tupnull,
73 Datum tupdatum,
bool tupnull,
75 int32 *set_elem_result);
80 bool readpagetup,
int sktrig,
bool *scanBehind);
83 int sktrig,
bool sktrig_required);
84 #ifdef USE_ASSERT_CHECKING
86 static bool _bt_verify_keys_with_arraykeys(
IndexScanDesc scan);
96 bool advancenonrequired,
bool prechecked,
bool firstmatch,
97 bool *continuescan,
int *ikey);
158 key->heapkeyspace =
true;
159 key->allequalimage =
false;
161 key->anynullkeys =
false;
162 key->nextkey =
false;
163 key->backward =
false;
164 key->keysz =
Min(indnkeyatts, tupnatts);
165 key->scantid =
key->heapkeyspace && itup ?
167 skey =
key->scankeys;
168 for (
i = 0;
i < indnkeyatts;
i++)
204 key->anynullkeys =
true;
211 if (rel->
rd_index->indnullsnotdistinct)
212 key->anynullkeys =
false;
225 while (stack != NULL)
274 int16 *indoption = rel->rd_indoption;
287 for (
int i = 0;
i < numberOfKeys;
i++)
304 if (numArrayKeys == 0)
313 "BTree array context",
332 for (
int i = 0;
i < numberOfKeys;
i++)
348 cur = &arrayKeyData[
i];
360 &elmlen, &elmbyval, &elmalign);
363 elmlen, elmbyval, elmalign,
364 &elem_values, &elem_nulls, &num_elems);
371 for (
j = 0;
j < num_elems;
j++)
374 elem_values[num_nonnulls++] = elem_values[
j];
380 if (num_nonnulls == 0)
392 elemtype =
cur->sk_subtype;
394 elemtype = rel->rd_opcintype[
cur->sk_attno - 1];
401 switch (
cur->sk_strategy)
408 elem_values, num_nonnulls);
418 elem_values, num_nonnulls);
421 elog(
ERROR,
"unrecognized StrategyNumber: %d",
422 (
int)
cur->sk_strategy);
443 reverse = (indoption[
cur->sk_attno - 1] & INDOPTION_DESC) != 0;
445 elem_values, num_nonnulls);
447 if (origarrayatt ==
cur->sk_attno)
462 origelemtype, elemtype,
464 elem_values, num_elems))
503 origarrayatt =
cur->sk_attno;
504 origarraykey = numArrayKeys;
505 origelemtype = elemtype;
567 for (
int output_ikey = 0; output_ikey < so->
numberOfKeys; output_ikey++)
578 input_ikey = keyDataMap[output_ikey];
580 Assert(last_equal_output_ikey < output_ikey);
581 Assert(last_equal_output_ikey < input_ikey);
582 last_equal_output_ikey = output_ikey;
605 elemtype = rel->rd_opcintype[outkey->
sk_attno - 1];
651 memmove(array, array + 1,
683 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
684 errmsg_internal(
"number of array scan keys left by preprocessing (%d) exceeds the maximum allowed by parallel btree index scans (%d)",
727 if (elemtype == opcintype)
732 *sortprocp = orderproc;
751 elog(
ERROR,
"missing support function %d(%u,%u) for attribute %d of index \"%s\"",
773 elog(
ERROR,
"missing support function %d(%u,%u) for attribute %d of index \"%s\"",
791 Datum *elems,
int nelems)
815 elog(
ERROR,
"missing operator %d(%u,%u) in opfamily %u",
816 strat, elemtype, elemtype,
820 elog(
ERROR,
"missing oprcode for operator %u", cmp_op);
826 for (
i = 1;
i < nelems;
i++)
850 Datum *elems,
int nelems)
894 bool reverse,
Oid origelemtype,
Oid nextelemtype,
895 Datum *elems_orig,
int *nelems_orig,
896 Datum *elems_next,
int nelems_next)
901 int nelems_orig_start = *nelems_orig,
902 nelems_orig_merged = 0;
909 if (origelemtype != nextelemtype)
926 mergeproc = &crosstypeproc;
930 cxt.sortproc = mergeproc;
932 cxt.reverse = reverse;
934 for (
int i = 0,
j = 0;
i < nelems_orig_start &&
j < nelems_next;)
936 Datum *oelem = elems_orig +
i,
937 *nelem = elems_next +
j;
942 elems_orig[nelems_orig_merged++] = *oelem;
952 *nelems_orig = nelems_orig_merged;
1013 Oid arraysk_elemtype;
1036 orderprocp = &crosstypeproc;
1043 arraysk, &cmpresult);
1051 if (cmpresult >= cmpexact)
1054 new_nelems = matchelem;
1073 if (cmpresult >= cmpexact)
1076 new_nelems = array->
num_elems - matchelem;
1078 sizeof(
Datum) * new_nelems);
1081 elog(
ERROR,
"unrecognized StrategyNumber: %d",
1087 Assert(new_nelems <= array->num_elems);
1090 *qual_ok = new_nelems > 0;
1132 Datum tupdatum,
bool tupnull,
1162 tupdatum, arrdatum));
1203 Datum tupdatum,
bool tupnull,
1205 int32 *set_elem_result)
1245 if (high_elem >= low_elem)
1254 *set_elem_result = result;
1257 mid_elem = low_elem;
1261 if (high_elem < low_elem)
1264 *set_elem_result = 1;
1273 if (high_elem >= low_elem)
1282 *set_elem_result = result;
1285 mid_elem = high_elem;
1289 if (high_elem < low_elem)
1292 *set_elem_result = -1;
1298 while (high_elem > low_elem)
1300 mid_elem = low_elem + ((high_elem - low_elem) / 2);
1312 low_elem = mid_elem;
1317 low_elem = mid_elem + 1;
1319 high_elem = mid_elem;
1327 if (low_elem != mid_elem)
1331 *set_elem_result = result;
1394 int cur_elem = curArrayKey->
cur_elem;
1396 bool rolled =
false;
1405 cur_elem = num_elems - 1;
1493 if (array->
cur_elem != first_elem_dir)
1546 bool readpagetup,
int sktrig,
bool *scanBehind)
1552 Assert(sktrig == 0 || readpagetup);
1553 Assert(!readpagetup || scanBehind == NULL);
1556 *scanBehind =
false;
1558 for (
int ikey = sktrig; ikey < so->
numberOfKeys; ikey++)
1566 Assert(!readpagetup || ikey == sktrig);
1578 Assert(ikey > sktrig || ikey == 0);
1582 if (
cur->sk_attno > tupnatts)
1638 if (readpagetup || result != 0)
1713 Assert(_bt_verify_arrays_bt_first(scan, dir));
1791 int sktrig,
bool sktrig_required)
1797 bool beyond_end_advance =
false,
1798 has_required_opposite_direction_only =
false,
1799 oppodir_inequality_sktrig =
false,
1800 all_required_satisfied =
true,
1801 all_satisfied =
true;
1803 if (sktrig_required)
1809 tupnatts,
false, 0, NULL));
1832 Assert(_bt_verify_keys_with_arraykeys(scan));
1840 required_opposite_direction_only =
false,
1864 has_required_opposite_direction_only =
1865 required_opposite_direction_only =
true;
1878 if (
cur->sk_attno > tupnatts)
1907 if (ikey == sktrig && !array)
1912 beyond_end_advance =
true;
1913 all_satisfied = all_required_satisfied =
false;
1924 if (
unlikely(required_opposite_direction_only))
1925 oppodir_inequality_sktrig =
true;
1955 if (beyond_end_advance)
1964 if (array && array->
cur_elem != final_elem_dir)
1991 if (!all_required_satisfied ||
cur->sk_attno > tupnatts)
2000 if (array && array->
cur_elem != first_elem_dir)
2017 bool cur_elem_trig = (sktrig_required && ikey == sktrig);
2024 tupdatum, tupnull, array,
cur,
2027 Assert(set_elem >= 0 && set_elem < array->num_elems);
2076 beyond_end_advance =
true;
2078 Assert(all_required_satisfied && all_satisfied);
2087 all_satisfied =
false;
2089 all_required_satisfied =
false;
2104 if (array && array->
cur_elem != set_elem)
2118 goto end_toplevel_scan;
2120 Assert(_bt_verify_keys_with_arraykeys(scan));
2139 if ((sktrig_required && all_required_satisfied) ||
2140 (!sktrig_required && all_satisfied))
2142 int nsktrig = sktrig + 1;
2145 Assert(all_required_satisfied);
2149 false,
false,
false,
2150 &continuescan, &nsktrig) &&
2154 Assert(all_satisfied && continuescan);
2189 Assert(!beyond_end_advance);
2193 tupdesc, nsktrig,
true);
2212 if (!sktrig_required)
2238 !all_required_satisfied);
2248 if (!all_required_satisfied && pstate->
finaltup == tuple)
2259 if (!all_required_satisfied && pstate->
finaltup &&
2293 if (so->
scanBehind && has_required_opposite_direction_only)
2346 if (has_required_opposite_direction_only && pstate->
finaltup &&
2347 (all_required_satisfied || oppodir_inequality_sktrig))
2351 bool continuescanflip;
2366 pstate->
finaltup, nfinaltupatts, tupdesc,
2367 false,
false,
false,
2368 &continuescanflip, &opsktrig);
2389 Assert(all_required_satisfied != oppodir_inequality_sktrig);
2391 ((all_required_satisfied && opsktrig > sktrig) ||
2392 (oppodir_inequality_sktrig && opsktrig >= sktrig))))
2561 int new_numberOfKeys;
2562 int numberOfEqualCols;
2572 int *keyDataMap = NULL;
2585 Assert(_bt_verify_keys_with_arraykeys(scan));
2593 if (numberOfKeys < 1)
2611 inkeys = arrayKeyData;
2615 numberOfKeys *
sizeof(
int));
2623 if (
cur->sk_attno < 1)
2624 elog(
ERROR,
"btree index keys must be ordered by attribute");
2627 if (numberOfKeys == 1)
2635 if (
cur->sk_attno == 1)
2656 new_numberOfKeys = 0;
2657 numberOfEqualCols = 0;
2666 memset(xform, 0,
sizeof(xform));
2673 for (
i = 0;;
cur++,
i++)
2675 if (
i < numberOfKeys)
2690 if (
i == numberOfKeys ||
cur->sk_attno != attno)
2692 int priorNumberOfEqualCols = numberOfEqualCols;
2695 if (i < numberOfKeys && cur->sk_attno < attno)
2696 elog(
ERROR,
"btree index keys must be ordered by attribute");
2722 array = &so->
arrayKeys[eq_arrayidx - 1];
2755 xform[
j].skey = NULL;
2761 numberOfEqualCols++;
2807 ScanKey outkey = &outkeys[new_numberOfKeys++];
2811 keyDataMap[new_numberOfKeys - 1] = xform[
j].ikey;
2812 if (priorNumberOfEqualCols == attno - 1)
2820 if (
i == numberOfKeys)
2824 attno =
cur->sk_attno;
2825 memset(xform, 0,
sizeof(xform));
2829 j =
cur->sk_strategy - 1;
2834 ScanKey outkey = &outkeys[new_numberOfKeys++];
2838 keyDataMap[new_numberOfKeys - 1] =
i;
2839 if (numberOfEqualCols == attno - 1)
2873 if (xform[
j].skey == NULL)
2876 xform[
j].skey =
cur;
2878 xform[
j].arrayidx = arrayidx;
2904 array = &so->
arrayKeys[xform[
j].arrayidx - 1];
2923 array, orderproc, &test_result))
2936 xform[
j].skey =
cur;
2938 xform[
j].arrayidx = arrayidx;
2972 ScanKey outkey = &outkeys[new_numberOfKeys++];
2976 keyDataMap[new_numberOfKeys - 1] = xform[
j].ikey;
2977 if (numberOfEqualCols == attno - 1)
2979 xform[
j].skey =
cur;
2981 xform[
j].arrayidx = arrayidx;
3000 #ifdef USE_ASSERT_CHECKING
3036 if (array->
cur_elem != first_elem_dir)
3040 return _bt_verify_keys_with_arraykeys(scan);
3075 if (last_sk_attno >
cur->sk_attno)
3077 last_sk_attno =
cur->sk_attno;
3175 *result = (leftnull < rightnull);
3178 *result = (leftnull <= rightnull);
3181 *result = (leftnull == rightnull);
3184 *result = (leftnull >= rightnull);
3187 *result = (leftnull > rightnull);
3190 elog(
ERROR,
"unrecognized StrategyNumber: %d", (
int) strat);
3217 if (leftarray && rightarray)
3231 orderproc, array, result);
3232 else if (rightarray)
3234 orderproc, array, result);
3253 lefttype = opcintype;
3256 righttype = opcintype;
3265 if (lefttype == opcintype && righttype == optype)
3460 elog(
ERROR,
"unrecognized StrategyNumber: %d",
3527 #ifdef USE_ASSERT_CHECKING
3537 tupnatts,
false, 0, NULL));
3549 false,
false,
false,
3550 &dcontinuescan, &dikey));
3688 bool advancenonrequired,
bool prechecked,
bool firstmatch,
3689 bool *continuescan,
int *ikey)
3693 *continuescan =
true;
3700 bool requiredSameDir =
false,
3701 requiredOppositeDirOnly =
false;
3709 requiredSameDir =
true;
3712 requiredOppositeDirOnly =
true;
3731 (requiredSameDir || (requiredOppositeDirOnly && firstmatch)) &&
3735 if (
key->sk_attno > tupnatts)
3781 if (requiredSameDir)
3782 *continuescan =
false;
3808 *continuescan =
false;
3826 *continuescan =
false;
3842 if (!(requiredOppositeDirOnly && firstmatch) &&
3844 datum,
key->sk_argument)))
3856 if (requiredSameDir)
3857 *continuescan =
false;
3865 else if (advancenonrequired &&
3869 tupdesc, *ikey,
false);
3896 int32 cmpresult = 0;
3949 *continuescan =
false;
3967 *continuescan =
false;
3988 *continuescan =
false;
3991 *continuescan =
false;
4022 result = (cmpresult < 0);
4025 result = (cmpresult <= 0);
4028 result = (cmpresult >= 0);
4031 result = (cmpresult > 0);
4034 elog(
ERROR,
"unrecognized RowCompareType: %d",
4050 *continuescan =
false;
4053 *continuescan =
false;
4125 pstate->
skip = aheadoffnum + 1;
4127 pstate->
skip = aheadoffnum - 1;
4184 bool killedsomething =
false;
4231 for (
i = 0;
i < numKilled;
i++)
4238 itemIndex <= so->currPos.lastItem);
4239 if (offnum < minoff)
4241 while (offnum <= maxoff)
4245 bool killtuple =
false;
4267 for (
j = 0;
j < nposting;
j++)
4326 killedsomething =
true;
4340 if (killedsomething)
4456 elog(
ERROR,
"multiple active vacuums for index \"%s\"",
4566 offsetof(
BTOptions, vacuum_cleanup_index_scale_factor)},
4586 bool *
res,
bool *isnull)
4612 return "initializing";
4614 return "scanning table";
4616 return "sorting live tuples";
4618 return "sorting dead tuples";
4620 return "loading tuples in tree";
4675 #ifdef DEBUG_NO_TRUNCATE
4677 keepnatts = nkeyatts + 1;
4681 Min(keepnatts, nkeyatts));
4690 Assert(keepnatts == nkeyatts || keepnatts == nkeyatts + 1);
4700 if (keepnatts <= nkeyatts)
4730 tidpivot->
t_info |= newsize;
4753 #ifndef DEBUG_NO_TRUNCATE
4828 if (isNull1 != isNull2)
4893 if (isNull1 != isNull2)
4973 return tupnatts == natts;
4989 return tupnatts == nkeyatts;
5005 return tupnatts == 0;
5019 return tupnatts == 0 ||
5031 return tupnatts == nkeyatts;
5065 return tupnatts > 0 && tupnatts <= nkeyatts;
5107 elog(
ERROR,
"cannot insert oversized tuple of size %zu on internal page of index \"%s\"",
5111 (
errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
5112 errmsg(
"index row size %zu exceeds btree version %u maximum %zu for index \"%s\"",
5118 errdetail(
"Index row references tuple (%u,%u) in relation \"%s\".",
5122 errhint(
"Values larger than 1/3 of a buffer page cannot be indexed.\n"
5123 "Consider a function index of an MD5 hash of the value, "
5124 "or use full text indexing."),
5141 bool allequalimage =
true;
5166 allequalimage =
false;
5174 elog(
DEBUG1,
"index \"%s\" can safely use deduplication",
5177 elog(
DEBUG1,
"index \"%s\" cannot use deduplication",
5181 return allequalimage;
#define DatumGetArrayTypeP(X)
void deconstruct_array(ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
#define InvalidAttrNumber
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 Assert(condition)
#define FLEXIBLE_ARRAY_MEMBER
#define OidIsValid(objectId)
bool datum_image_eq(Datum value1, Datum value2, bool typByVal, int typLen)
static void PGresult * res
int errmsg_internal(const char *fmt,...)
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)
void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
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)
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
void * MemoryContextAlloc(MemoryContext context, Size size)
#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_done(IndexScanDesc scan)
void _bt_parallel_primscan_schedule(IndexScanDesc scan, BlockNumber prev_scan_page)
#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
static bool _bt_merge_arrays(IndexScanDesc scan, ScanKey skey, FmgrInfo *sortproc, bool reverse, Oid origelemtype, Oid nextelemtype, Datum *elems_orig, int *nelems_orig, Datum *elems_next, int nelems_next)
static void _bt_rewind_nonrequired_arrays(IndexScanDesc scan, ScanDirection dir)
void _bt_check_third_page(Relation rel, Relation heap, bool needheaptidspace, Page page, IndexTuple newtup)
static bool _bt_check_compare(IndexScanDesc scan, ScanDirection dir, IndexTuple tuple, int tupnatts, TupleDesc tupdesc, bool advancenonrequired, bool prechecked, bool firstmatch, bool *continuescan, int *ikey)
void _bt_end_vacuum(Relation rel)
static ScanKey _bt_preprocess_array_keys(IndexScanDesc scan)
char * btbuildphasename(int64 phasenum)
bool _bt_checkkeys(IndexScanDesc scan, BTReadPageState *pstate, bool arrayKeys, IndexTuple tuple, int tupnatts)
void _bt_end_vacuum_callback(int code, Datum arg)
static 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)
struct BTScanKeyPreproc BTScanKeyPreproc
void _bt_freestack(BTStack stack)
void BTreeShmemInit(void)
struct BTSortArrayContext BTSortArrayContext
static Datum _bt_find_extreme_element(IndexScanDesc scan, ScanKey skey, Oid elemtype, StrategyNumber strat, Datum *elems, int nelems)
bytea * btoptions(Datum reloptions, bool validate)
struct BTVacInfo BTVacInfo
BTCycleId _bt_vacuum_cycleid(Relation rel)
BTScanInsert _bt_mkscankey(Relation rel, IndexTuple itup)
void _bt_killitems(IndexScanDesc scan)
static bool _bt_advance_array_keys(IndexScanDesc scan, BTReadPageState *pstate, IndexTuple tuple, int tupnatts, TupleDesc tupdesc, int sktrig, bool sktrig_required)
bool _bt_start_prim_scan(IndexScanDesc scan, ScanDirection dir)
static bool _bt_fix_scankey_strategy(ScanKey skey, int16 *indoption)
bool _bt_check_natts(Relation rel, bool heapkeyspace, Page page, OffsetNumber offnum)
IndexTuple _bt_truncate(Relation rel, IndexTuple lastleft, IndexTuple firstright, BTScanInsert itup_key)
#define LOOK_AHEAD_REQUIRED_RECHECKS
int _bt_keep_natts_fast(Relation rel, IndexTuple lastleft, IndexTuple firstright)
#define LOOK_AHEAD_DEFAULT_DISTANCE
static BTVacInfo * btvacinfo
static void _bt_mark_scankey_required(ScanKey skey)
static int _bt_compare_array_elements(const void *a, const void *b, void *arg)
static void _bt_preprocess_array_keys_final(IndexScanDesc scan, int *keyDataMap)
static bool _bt_tuple_before_array_skeys(IndexScanDesc scan, ScanDirection dir, IndexTuple tuple, TupleDesc tupdesc, int tupnatts, bool readpagetup, int sktrig, bool *scanBehind)
static bool _bt_advance_array_keys_increment(IndexScanDesc scan, ScanDirection dir)
Size BTreeShmemSize(void)
static void _bt_setup_array_cmp(IndexScanDesc scan, ScanKey skey, Oid elemtype, FmgrInfo *orderproc, FmgrInfo **sortprocp)
static int _bt_keep_natts(Relation rel, IndexTuple lastleft, IndexTuple firstright, BTScanInsert itup_key)
static int _bt_sort_array_elements(ScanKey skey, FmgrInfo *sortproc, bool reverse, Datum *elems, int nelems)
bool btproperty(Oid index_oid, int attno, IndexAMProperty prop, const char *propname, bool *res, bool *isnull)
static bool _bt_compare_scankey_args(IndexScanDesc scan, ScanKey op, ScanKey leftarg, ScanKey rightarg, BTArrayKeyInfo *array, FmgrInfo *orderproc, bool *result)
bool _bt_allequalimage(Relation rel, bool debugmessage)
static bool _bt_compare_array_scankey_args(IndexScanDesc scan, ScanKey arraysk, ScanKey skey, FmgrInfo *orderproc, BTArrayKeyInfo *array, bool *qual_ok)
static void _bt_checkkeys_look_ahead(IndexScanDesc scan, BTReadPageState *pstate, int tupnatts, TupleDesc tupdesc)
static int32 _bt_compare_array_skey(FmgrInfo *orderproc, Datum tupdatum, bool tupnull, Datum arrdatum, ScanKey cur)
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)
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)
MemoryContextSwitchTo(old_ctx)
#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)
#define ScanDirectionIsNoMovement(direction)
@ NoMovementScanDirection
Size add_size(Size s1, Size s2)
void * ShmemInitStruct(const char *name, Size size, bool *foundPtr)
Size mul_size(Size s1, Size s2)
static pg_noinline void Size size
#define BTGreaterStrategyNumber
#define BTMaxStrategyNumber
#define BTLessStrategyNumber
#define BTEqualStrategyNumber
#define BTLessEqualStrategyNumber
#define BTGreaterEqualStrategyNumber
BlockNumber prev_scan_page
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)