78 bool advancenonrequired,
bool forcenonrequired,
79 bool *continuescan,
int *ikey);
82 ScanDirection dir,
bool forcenonrequired,
bool *continuescan);
86 bool readpagetup,
int sktrig,
bool *scanBehind);
91 int sktrig,
bool sktrig_required);
93 bool *skip_array_set);
99 int32 set_elem_result,
Datum tupdatum,
bool tupnull);
102 Datum tupdatum,
bool tupnull,
105 Datum tupdatum,
bool tupnull,
107 int32 *set_elem_result);
108#ifdef USE_ASSERT_CHECKING
109static bool _bt_verify_keys_with_arraykeys(
IndexScanDesc scan);
173 pstate.minoff = minoff;
174 pstate.maxoff = maxoff;
175 pstate.finaltup = NULL;
177 pstate.firstpage = firstpage;
178 pstate.forcenonrequired =
false;
179 pstate.startikey = 0;
182 pstate.continuescan =
true;
184 pstate.targetdistance = 0;
185 pstate.nskipadvances = 0;
231 if (!pstate.firstpage && minoff < maxoff)
237 offnum =
Max(offnum, minoff);
239 while (offnum <= maxoff)
258 pstate.offnum = offnum;
268 Assert(!passes_quals && pstate.continuescan);
269 Assert(offnum < pstate.skip);
270 Assert(!pstate.forcenonrequired);
272 offnum = pstate.skip;
308 if (!pstate.continuescan)
332 if (pstate.forcenonrequired)
334 pstate.forcenonrequired =
false;
335 pstate.startikey = 0;
341 if (!pstate.continuescan)
380 if (!pstate.firstpage && minoff < maxoff)
386 offnum =
Min(offnum, maxoff);
388 while (offnum >= minoff)
421 pstate.offnum = offnum;
422 if (arrayKeys && offnum == minoff && pstate.forcenonrequired)
425 pstate.forcenonrequired =
false;
426 pstate.startikey = 0;
441 Assert(!passes_quals && pstate.continuescan);
442 Assert(!pstate.forcenonrequired);
453 Assert(!passes_quals && pstate.continuescan);
454 Assert(offnum > pstate.skip);
455 Assert(!pstate.forcenonrequired);
457 offnum = pstate.skip;
462 if (passes_quals && tuple_alive)
494 if (!pstate.continuescan)
504 if (!pstate.continuescan)
525 Assert(!pstate.forcenonrequired);
604 bool start_past_saop_eq =
false;
646 bool satisfied =
false;
651 bool firstsatisfies =
false;
653 if (subkey->
sk_attno > firstchangingattnum)
661 tupdesc, &firstnull);
665 if (firstnull || lastnull)
755 if (
key->sk_attno > firstchangingattnum)
767 if (firstnull || lastnull)
777 key->sk_collation, firstdatum,
784 key->sk_collation, lastdatum,
805 if (
key->sk_attno >= firstchangingattnum)
823 key->sk_collation, firstdatum,
842 if (
key->sk_attno >= firstchangingattnum)
849 firstdatum, firstnull, array,
key,
855 start_past_saop_eq =
true;
880 if (
key->sk_attno > firstchangingattnum)
889 firstdatum, firstnull, array,
key,
896 lastdatum, lastnull, array,
key,
964 nfinaltupatts,
false, 0, &scanBehind))
1021 false, &continuescan,
1080 memcpy(base, itup, itupsz);
1082 base->
t_info &= ~INDEX_SIZE_MASK;
1116#define LOOK_AHEAD_REQUIRED_RECHECKS 3
1117#define LOOK_AHEAD_DEFAULT_DISTANCE 5
1118#define NSKIPADVANCES_THRESHOLD 3
1159 Assert(!so->needPrimScan && !so->scanBehind && !so->oppositeDirCheck);
1160 Assert(arrayKeys || so->numArrayKeys == 0);
1174#ifdef USE_ASSERT_CHECKING
1193 Assert(arrayKeys || ikey == dikey);
1314 bool advancenonrequired,
bool forcenonrequired,
1315 bool *continuescan,
int *ikey)
1319 *continuescan =
true;
1326 bool requiredSameDir =
false,
1327 requiredOppositeDirOnly =
false;
1334 if (forcenonrequired)
1340 requiredSameDir =
true;
1343 requiredOppositeDirOnly =
true;
1345 if (
key->sk_attno > tupnatts)
1366 Assert(requiredSameDir || forcenonrequired);
1373 if (forcenonrequired)
1375 tupdesc, *ikey,
false);
1377 *continuescan =
false;
1385 forcenonrequired, continuescan))
1416 if (requiredSameDir)
1417 *continuescan =
false;
1426 Assert(forcenonrequired && *ikey > 0);
1447 tupdesc, *ikey,
false);
1463 if ((requiredSameDir || requiredOppositeDirOnly) &&
1465 *continuescan =
false;
1481 if ((requiredSameDir || requiredOppositeDirOnly) &&
1483 *continuescan =
false;
1493 datum,
key->sk_argument)))
1500 if (requiredSameDir)
1501 *continuescan =
false;
1509 else if (advancenonrequired &&
1513 tupdesc, *ikey,
false);
1581 bool forcenonrequired,
bool *continuescan)
1584 int32 cmpresult = 0;
1612 if (forcenonrequired)
1618 *continuescan =
false;
1621 *continuescan =
false;
1646 if (forcenonrequired)
1684 if ((subkey->
sk_flags & reqflags) &&
1686 *continuescan =
false;
1722 if ((subkey->
sk_flags & reqflags) &&
1724 *continuescan =
false;
1754 if (!result && !forcenonrequired)
1764 *continuescan =
false;
1767 *continuescan =
false;
1790 satisfied = (cmpresult < 0);
1793 satisfied = (cmpresult <= 0);
1796 satisfied = (cmpresult >= 0);
1799 satisfied = (cmpresult > 0);
1856 bool readpagetup,
int sktrig,
bool *scanBehind)
1862 Assert(sktrig == 0 || readpagetup);
1863 Assert(!readpagetup || scanBehind == NULL);
1866 *scanBehind =
false;
1868 for (
int ikey = sktrig; ikey < so->
numberOfKeys; ikey++)
1876 Assert(!readpagetup || ikey == sktrig);
1888 Assert(ikey > sktrig || ikey == 0);
1892 if (
cur->sk_attno > tupnatts)
1977 for (
int arrayidx = 0; arrayidx < so->
numArrayKeys; arrayidx++)
1985 array,
cur, &result);
2016 if (readpagetup || result != 0)
2103 pstate->
skip = aheadoffnum + 1;
2105 pstate->
skip = aheadoffnum - 1;
2184 int sktrig,
bool sktrig_required)
2190 bool beyond_end_advance =
false,
2191 skip_array_advanced =
false,
2192 has_required_opposite_direction_only =
false,
2193 all_required_satisfied =
true,
2194 all_satisfied =
true;
2197 Assert(_bt_verify_keys_with_arraykeys(scan));
2199 if (sktrig_required)
2205 tupnatts,
false, 0, NULL));
2214 else if (sktrig < so->numberOfKeys - 1 &&
2230 false, &continuescan,
2264 has_required_opposite_direction_only =
true;
2275 if (
cur->sk_attno > tupnatts)
2304 if (ikey == sktrig && !array)
2309 beyond_end_advance =
true;
2310 all_satisfied = all_required_satisfied =
false;
2340 if (beyond_end_advance)
2367 if (!all_required_satisfied ||
cur->sk_attno > tupnatts)
2384 bool cur_elem_trig = (sktrig_required && ikey == sktrig);
2392 tupdatum, tupnull, array,
cur,
2401 tupdatum, tupnull, array,
cur,
2451 beyond_end_advance =
true;
2453 Assert(all_required_satisfied && all_satisfied);
2462 all_satisfied =
false;
2464 all_required_satisfied =
false;
2486 skip_array_advanced =
true;
2488 else if (array->
cur_elem != set_elem)
2503 if (beyond_end_advance &&
2505 goto end_toplevel_scan;
2507 Assert(_bt_verify_keys_with_arraykeys(scan));
2513 if (sktrig_required && skip_array_advanced)
2539 if ((sktrig_required && all_required_satisfied) ||
2540 (!sktrig_required && all_satisfied))
2542 int nsktrig = sktrig + 1;
2545 Assert(all_required_satisfied);
2549 !sktrig_required, &continuescan,
2554 Assert(all_satisfied && continuescan);
2589 Assert(!beyond_end_advance);
2593 tupdesc, nsktrig,
true);
2612 if (!sktrig_required)
2635 !all_required_satisfied);
2645 if (!all_required_satisfied && pstate->
finaltup == tuple)
2656 if (!all_required_satisfied && pstate->
finaltup &&
2728 else if (has_required_opposite_direction_only && pstate->
finaltup &&
2869 bool *skip_array_set)
2885 *skip_array_set =
true;
2940 Datum inc_sk_argument;
3073 Datum dec_sk_argument;
3248 else if (low_not_high)
3274 int32 set_elem_result,
Datum tupdatum,
bool tupnull)
3279 if (set_elem_result)
3345 Datum tupdatum,
bool tupnull,
3376 tupdatum, arrdatum));
3417 Datum tupdatum,
bool tupnull,
3419 int32 *set_elem_result)
3461 if (high_elem >= low_elem)
3470 *set_elem_result = result;
3473 mid_elem = low_elem;
3477 if (high_elem < low_elem)
3480 *set_elem_result = 1;
3489 if (high_elem >= low_elem)
3498 *set_elem_result = result;
3501 mid_elem = high_elem;
3505 if (high_elem < low_elem)
3508 *set_elem_result = -1;
3514 while (high_elem > low_elem)
3516 mid_elem = low_elem + ((high_elem - low_elem) / 2);
3528 low_elem = mid_elem;
3533 low_elem = mid_elem + 1;
3535 high_elem = mid_elem;
3543 if (low_elem != mid_elem)
3547 *set_elem_result = result;
3572 Datum tupdatum,
bool tupnull,
3574 int32 *set_elem_result)
3586 *set_elem_result = 0;
3593 *set_elem_result = -1;
3595 *set_elem_result = 1;
3603 *set_elem_result = 0;
3615 *set_elem_result = -1;
3621 *set_elem_result = 1;
3634 *set_elem_result = 1;
3640 *set_elem_result = -1;
3647#ifdef USE_ASSERT_CHECKING
3665#ifdef USE_ASSERT_CHECKING
3676 bool nonrequiredseen =
false;
3702 if (last_sk_attno >
cur->sk_attno)
3704 if (nonrequiredseen)
3708 nonrequiredseen =
true;
3710 last_sk_attno =
cur->sk_attno;
#define InvalidAttrNumber
BlockNumber BufferGetBlockNumber(Buffer buffer)
static Page BufferGetPage(Buffer buffer)
static void * PageGetItem(const PageData *page, const ItemIdData *itemId)
static ItemId PageGetItemId(Page page, OffsetNumber offsetNumber)
static OffsetNumber PageGetMaxOffsetNumber(const PageData *page)
#define INVERT_COMPARE_RESULT(var)
#define PG_USED_FOR_ASSERTS_ONLY
Datum datumCopy(Datum value, bool typByVal, int typLen)
Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
Assert(PointerIsAligned(start, uint64))
if(TABLE==NULL||TABLE_index==NULL)
#define ItemIdIsDead(itemId)
IndexTupleData * IndexTuple
static Datum index_getattr(IndexTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
static Size IndexTupleSize(const IndexTupleData *itup)
#define MaxIndexTuplesPerPage
void pfree(void *pointer)
static void _bt_binsrch_skiparray_skey(bool cur_elem_trig, ScanDirection dir, Datum tupdatum, bool tupnull, BTArrayKeyInfo *array, ScanKey cur, int32 *set_elem_result)
static void _bt_array_set_low_or_high(Relation rel, ScanKey skey, BTArrayKeyInfo *array, bool low_not_high)
static void _bt_saveitem(BTScanOpaque so, int itemIndex, OffsetNumber offnum, IndexTuple itup)
static void _bt_skiparray_set_element(Relation rel, ScanKey skey, BTArrayKeyInfo *array, int32 set_elem_result, Datum tupdatum, bool tupnull)
#define NSKIPADVANCES_THRESHOLD
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 int _bt_setuppostingitems(BTScanOpaque so, int itemIndex, OffsetNumber offnum, const ItemPointerData *heapTid, IndexTuple itup)
static bool _bt_advance_array_keys(IndexScanDesc scan, BTReadPageState *pstate, IndexTuple tuple, int tupnatts, TupleDesc tupdesc, int sktrig, bool sktrig_required)
#define LOOK_AHEAD_REQUIRED_RECHECKS
static bool _bt_rowcompare_cmpresult(ScanKey subkey, int cmpresult)
static bool _bt_oppodir_checkkeys(IndexScanDesc scan, ScanDirection dir, IndexTuple finaltup)
static bool _bt_scanbehind_checkkeys(IndexScanDesc scan, ScanDirection dir, IndexTuple finaltup)
#define LOOK_AHEAD_DEFAULT_DISTANCE
static bool _bt_check_rowcompare(ScanKey header, IndexTuple tuple, int tupnatts, TupleDesc tupdesc, ScanDirection dir, bool forcenonrequired, bool *continuescan)
static void _bt_savepostingitem(BTScanOpaque so, int itemIndex, OffsetNumber offnum, ItemPointer heapTid, int tupleOffset)
static bool _bt_check_compare(IndexScanDesc scan, ScanDirection dir, IndexTuple tuple, int tupnatts, TupleDesc tupdesc, bool advancenonrequired, bool forcenonrequired, bool *continuescan, int *ikey)
bool _bt_readpage(IndexScanDesc scan, ScanDirection dir, OffsetNumber offnum, bool firstpage)
static bool _bt_array_decrement(Relation rel, ScanKey skey, BTArrayKeyInfo *array)
static bool _bt_tuple_before_array_skeys(IndexScanDesc scan, ScanDirection dir, IndexTuple tuple, TupleDesc tupdesc, int tupnatts, bool readpagetup, int sktrig, bool *scanBehind)
static void _bt_set_startikey(IndexScanDesc scan, BTReadPageState *pstate)
static void _bt_skiparray_set_isnull(Relation rel, ScanKey skey, BTArrayKeyInfo *array)
static bool _bt_advance_array_keys_increment(IndexScanDesc scan, ScanDirection dir, bool *skip_array_set)
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)
void _bt_start_array_keys(IndexScanDesc scan, ScanDirection dir)
static bool _bt_checkkeys(IndexScanDesc scan, BTReadPageState *pstate, bool arrayKeys, IndexTuple tuple, int tupnatts)
static bool _bt_array_increment(Relation rel, ScanKey skey, BTArrayKeyInfo *array)
void _bt_parallel_primscan_schedule(IndexScanDesc scan, BlockNumber curr_page)
void _bt_parallel_release(IndexScanDesc scan, BlockNumber next_scan_page, BlockNumber curr_page)
#define BTScanPosIsPinned(scanpos)
static uint16 BTreeTupleGetNPosting(IndexTuple posting)
static bool BTreeTupleIsPivot(IndexTuple itup)
#define P_LEFTMOST(opaque)
#define BTPageGetOpaque(page)
#define MaxTIDsPerBTreePage
#define P_FIRSTDATAKEY(opaque)
static uint32 BTreeTupleGetPostingOffset(IndexTuple posting)
#define P_RIGHTMOST(opaque)
#define SK_BT_NULLS_FIRST
static ItemPointer BTreeTupleGetPostingN(IndexTuple posting, int n)
static bool BTreeTupleIsPosting(IndexTuple itup)
#define BTreeTupleGetNAtts(itup, rel)
BTScanOpaqueData * BTScanOpaque
int _bt_keep_natts_fast(Relation rel, IndexTuple lastleft, IndexTuple firstright)
#define InvalidOffsetNumber
#define OffsetNumberIsValid(offsetNumber)
#define OffsetNumberNext(offsetNumber)
#define OffsetNumberPrev(offsetNumber)
static bool DatumGetBool(Datum X)
static Pointer DatumGetPointer(Datum X)
static int32 DatumGetInt32(Datum X)
void PredicateLockPage(Relation relation, BlockNumber blkno, Snapshot snapshot)
#define RelationGetDescr(relation)
#define IndexRelationGetNumberOfAttributes(relation)
#define ScanDirectionIsForward(direction)
#define ScanDirectionIsBackward(direction)
#define ScanDirectionIsNoMovement(direction)
@ NoMovementScanDirection
#define BTGreaterStrategyNumber
#define BTLessStrategyNumber
#define BTEqualStrategyNumber
#define BTLessEqualStrategyNumber
#define BTGreaterEqualStrategyNumber
BTArrayKeyInfo * arrayKeys
BTScanPosItem items[MaxTIDsPerBTreePage]
LocationIndex tupleOffset
struct ParallelIndexScanDescData * parallel_scan
bool ignore_killed_tuples
struct SnapshotData * xs_snapshot
StrategyNumber sk_strategy
SkipSupportIncDec decrement
SkipSupportIncDec increment