63 const Datum *bdist,
const bool *bnulls,
68 Datum *orderbyvals,
bool *orderbynulls);
103 if (scandesc == NULL)
177 Datum *lastfetched_vals;
178 bool *lastfetched_nulls;
199 if (scandesc == NULL)
286 goto next_indextuple;
311 elog(
ERROR,
"index returned tuples in wrong order");
408 const Datum *bdist,
const bool *bnulls,
423 if (anulls[
i] && !bnulls[
i])
425 else if (!anulls[
i] && bnulls[
i])
427 else if (anulls[
i] && bnulls[
i])
461 Datum *orderbyvals,
bool *orderbynulls)
477 if (!orderbynulls[
i])
502 result = topmost->
htup;
610 for (
j = 0;
j < numRuntimeKeys;
j++)
644 if (runtimeKeys[
j].key_toastable)
673 for (
j = 0;
j < numArrayKeys;
j++)
702 &elmlen, &elmbyval, &elmalign);
705 elmlen, elmbyval, elmalign,
706 &elem_values, &elem_nulls, &num_elems);
753 for (
j = numArrayKeys - 1;
j >= 0;
j--)
761 if (next_elem >= num_elems)
769 if (elem_nulls[next_elem])
807 Assert(ParallelWorkerNumber <= node->iss_SharedInfo->num_workers);
824 if (indexRelationDesc)
841 if (epqstate != NULL)
860 elog(
ERROR,
"unexpected ExecIndexMarkPos call in EPQ recheck");
889 elog(
ERROR,
"unexpected ExecIndexRestrPos call in EPQ recheck");
1032 palloc(numOrderByKeys *
sizeof(
bool));
1065 palloc(numOrderByKeys *
sizeof(
bool));
1159 List *quals,
bool isorderby,
1160 ScanKey *scanKeys,
int *numScanKeys,
1170 int max_runtime_keys;
1185 runtime_keys = *runtimeKeys;
1186 n_runtime_keys = max_runtime_keys = *numRuntimeKeys;
1198 foreach(qual_cell, quals)
1201 ScanKey this_scan_key = &scan_keys[
j++];
1220 opno = ((
OpExpr *) clause)->opno;
1221 opfuncid = ((
OpExpr *) clause)->opfuncid;
1233 if (!(
IsA(leftop,
Var) &&
1235 elog(
ERROR,
"indexqual doesn't have key on left side");
1237 varattno = ((
Var *) leftop)->varattno;
1238 if (varattno < 1 || varattno > indnkeyatts)
1239 elog(
ERROR,
"bogus index qualification");
1245 opfamily =
index->rd_opfamily[varattno - 1];
1268 scanvalue = ((
Const *) rightop)->constvalue;
1269 if (((
Const *) rightop)->constisnull)
1275 if (n_runtime_keys >= max_runtime_keys)
1277 if (max_runtime_keys == 0)
1279 max_runtime_keys = 8;
1285 max_runtime_keys *= 2;
1290 runtime_keys[n_runtime_keys].
scan_key = this_scan_key;
1291 runtime_keys[n_runtime_keys].
key_expr =
1296 scanvalue = (
Datum) 0;
1307 ((
OpExpr *) clause)->inputcollid,
1330 opnos_cell, rc->opnos, collids_cell, rc->inputcollids)
1332 ScanKey this_sub_key = &first_sub_key[n_sub_key];
1350 if (!(
IsA(leftop,
Var) &&
1352 elog(
ERROR,
"indexqual doesn't have key on left side");
1354 varattno = ((
Var *) leftop)->varattno;
1360 if (!
index->rd_indam->amcanorder ||
1361 varattno < 1 || varattno > indnkeyatts)
1362 elog(
ERROR,
"bogus RowCompare index qualification");
1363 opfamily =
index->rd_opfamily[varattno - 1];
1370 if (op_strategy != rc->
cmptype)
1371 elog(
ERROR,
"RowCompare index qualification contains wrong operator");
1378 elog(
ERROR,
"missing support function %d(%u,%u) in opfamily %u",
1392 scanvalue = ((
Const *) rightop)->constvalue;
1393 if (((
Const *) rightop)->constisnull)
1399 if (n_runtime_keys >= max_runtime_keys)
1401 if (max_runtime_keys == 0)
1403 max_runtime_keys = 8;
1409 max_runtime_keys *= 2;
1414 runtime_keys[n_runtime_keys].
scan_key = this_sub_key;
1415 runtime_keys[n_runtime_keys].
key_expr =
1420 scanvalue = (
Datum) 0;
1462 opfuncid = saop->opfuncid;
1474 if (!(
IsA(leftop,
Var) &&
1476 elog(
ERROR,
"indexqual doesn't have key on left side");
1478 varattno = ((
Var *) leftop)->varattno;
1479 if (varattno < 1 || varattno > indnkeyatts)
1480 elog(
ERROR,
"bogus index qualification");
1486 opfamily =
index->rd_opfamily[varattno - 1];
1503 if (
index->rd_indam->amsearcharray)
1510 scanvalue = ((
Const *) rightop)->constvalue;
1511 if (((
Const *) rightop)->constisnull)
1517 if (n_runtime_keys >= max_runtime_keys)
1519 if (max_runtime_keys == 0)
1521 max_runtime_keys = 8;
1527 max_runtime_keys *= 2;
1532 runtime_keys[n_runtime_keys].
scan_key = this_scan_key;
1533 runtime_keys[n_runtime_keys].
key_expr =
1544 scanvalue = (
Datum) 0;
1550 array_keys[n_array_keys].
scan_key = this_scan_key;
1555 scanvalue = (
Datum) 0;
1581 leftop = ntest->
arg;
1588 if (!(
IsA(leftop,
Var) &&
1590 elog(
ERROR,
"NullTest indexqual has wrong key");
1592 varattno = ((
Var *) leftop)->varattno;
1606 elog(
ERROR,
"unrecognized nulltesttype: %d",
1622 elog(
ERROR,
"unsupported indexqual type: %d",
1626 Assert(n_runtime_keys <= max_runtime_keys);
1629 if (n_array_keys == 0)
1638 *scanKeys = scan_keys;
1639 *numScanKeys = n_scan_keys;
1640 *runtimeKeys = runtime_keys;
1641 *numRuntimeKeys = n_runtime_keys;
1644 *arrayKeys = array_keys;
1645 *numArrayKeys = n_array_keys;
1647 else if (n_array_keys != 0)
1648 elog(
ERROR,
"ScalarArrayOpExpr index qual found where not allowed");
1671 if (!instrument && !parallel_aware)
1681 instrument, parallel_aware,
1702 if (!instrument && !parallel_aware)
1712 instrument, parallel_aware, pcxt->
nworkers,
1716 if (!parallel_aware)
1768 if (!instrument && !parallel_aware)
1780 if (!parallel_aware)
1816 if (SharedInfo == NULL)
#define DatumGetArrayTypeP(X)
void deconstruct_array(ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
#define OffsetToPointer(base, offset)
#define RegProcedureIsValid(p)
#define MemSet(start, val, len)
Datum datumCopy(Datum value, bool typByVal, int typLen)
void ExecReScan(PlanState *node)
ExprState * ExecInitExpr(Expr *node, PlanState *parent)
ExprState * ExecInitQual(List *qual, PlanState *parent)
List * ExecInitExprList(List *nodes, PlanState *parent)
TupleTableSlot * ExecScan(ScanState *node, ExecScanAccessMtd accessMtd, ExecScanRecheckMtd recheckMtd)
void ExecAssignScanProjectionInfo(ScanState *node)
void ExecScanReScan(ScanState *node)
void ExecInitScanTupleSlot(EState *estate, ScanState *scanstate, TupleDesc tupledesc, const TupleTableSlotOps *tts_ops)
void ExecInitResultTypeTL(PlanState *planstate)
void ExecForceStoreHeapTuple(HeapTuple tuple, TupleTableSlot *slot, bool shouldFree)
void ExecAssignExprContext(EState *estate, PlanState *planstate)
Relation ExecOpenScanRelation(EState *estate, Index scanrelid, int eflags)
#define InstrCountFiltered2(node, delta)
static RangeTblEntry * exec_rt_fetch(Index rti, EState *estate)
#define ResetExprContext(econtext)
bool(* ExecScanRecheckMtd)(ScanState *node, TupleTableSlot *slot)
static bool ExecQualAndReset(ExprState *state, ExprContext *econtext)
TupleTableSlot *(* ExecScanAccessMtd)(ScanState *node)
static Datum ExecEvalExpr(ExprState *state, ExprContext *econtext, bool *isNull)
#define EXEC_FLAG_EXPLAIN_ONLY
#define PG_DETOAST_DATUM(datum)
struct IndexScanInstrumentation IndexScanInstrumentation
Assert(PointerIsAligned(start, uint64))
void heap_freetuple(HeapTuple htup)
#define IsParallelWorker()
void index_parallelscan_initialize(Relation heapRelation, Relation indexRelation, Snapshot snapshot, bool instrument, bool parallel_aware, int nworkers, SharedIndexScanInstrumentation **sharedinfo, ParallelIndexScanDesc target)
bool index_getnext_slot(IndexScanDesc scan, ScanDirection direction, TupleTableSlot *slot)
IndexScanDesc index_beginscan_parallel(Relation heaprel, Relation indexrel, IndexScanInstrumentation *instrument, int nkeys, int norderbys, ParallelIndexScanDesc pscan)
void index_restrpos(IndexScanDesc scan)
IndexScanDesc index_beginscan(Relation heapRelation, Relation indexRelation, Snapshot snapshot, IndexScanInstrumentation *instrument, int nkeys, int norderbys)
void index_close(Relation relation, LOCKMODE lockmode)
void index_markpos(IndexScanDesc scan)
void index_endscan(IndexScanDesc scan)
Size index_parallelscan_estimate(Relation indexRelation, int nkeys, int norderbys, Snapshot snapshot, bool instrument, bool parallel_aware, int nworkers)
Relation index_open(Oid relationId, LOCKMODE lockmode)
void index_parallelrescan(IndexScanDesc scan)
void index_rescan(IndexScanDesc scan, ScanKey keys, int nkeys, ScanKey orderbys, int norderbys)
void get_op_opfamily_properties(Oid opno, Oid opfamily, bool ordering_op, int *strategy, Oid *lefttype, Oid *righttype)
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
Oid get_opfamily_proc(Oid opfamily, Oid lefttype, Oid righttype, int16 procnum)
void get_typlenbyval(Oid typid, int16 *typlen, bool *typbyval)
#define TypeIsToastable(typid)
void * repalloc(void *pointer, Size size)
void pfree(void *pointer)
void * palloc0(Size size)
MemoryContext CurrentMemoryContext
#define CHECK_FOR_INTERRUPTS()
Oid exprType(const Node *expr)
Oid exprCollation(const Node *expr)
static Node * get_rightop(const void *clause)
static Node * get_leftop(const void *clause)
static void reorderqueue_push(IndexScanState *node, TupleTableSlot *slot, Datum *orderbyvals, bool *orderbynulls)
void ExecIndexBuildScanKeys(PlanState *planstate, Relation index, List *quals, bool isorderby, ScanKey *scanKeys, int *numScanKeys, IndexRuntimeKeyInfo **runtimeKeys, int *numRuntimeKeys, IndexArrayKeyInfo **arrayKeys, int *numArrayKeys)
void ExecIndexScanRetrieveInstrumentation(IndexScanState *node)
void ExecIndexScanEstimate(IndexScanState *node, ParallelContext *pcxt)
static void EvalOrderByExpressions(IndexScanState *node, ExprContext *econtext)
bool ExecIndexEvalArrayKeys(ExprContext *econtext, IndexArrayKeyInfo *arrayKeys, int numArrayKeys)
void ExecIndexEvalRuntimeKeys(ExprContext *econtext, IndexRuntimeKeyInfo *runtimeKeys, int numRuntimeKeys)
void ExecIndexScanReInitializeDSM(IndexScanState *node, ParallelContext *pcxt)
static int cmp_orderbyvals(const Datum *adist, const bool *anulls, const Datum *bdist, const bool *bnulls, IndexScanState *node)
void ExecReScanIndexScan(IndexScanState *node)
void ExecIndexScanInitializeDSM(IndexScanState *node, ParallelContext *pcxt)
IndexScanState * ExecInitIndexScan(IndexScan *node, EState *estate, int eflags)
static TupleTableSlot * IndexNextWithReorder(IndexScanState *node)
void ExecIndexScanInitializeWorker(IndexScanState *node, ParallelWorkerContext *pwcxt)
void ExecEndIndexScan(IndexScanState *node)
static bool IndexRecheck(IndexScanState *node, TupleTableSlot *slot)
void ExecIndexRestrPos(IndexScanState *node)
static TupleTableSlot * ExecIndexScan(PlanState *pstate)
static int reorderqueue_cmp(const pairingheap_node *a, const pairingheap_node *b, void *arg)
void ExecIndexMarkPos(IndexScanState *node)
static HeapTuple reorderqueue_pop(IndexScanState *node)
bool ExecIndexAdvanceArrayKeys(IndexArrayKeyInfo *arrayKeys, int numArrayKeys)
static TupleTableSlot * IndexNext(IndexScanState *node)
#define IsA(nodeptr, _type_)
#define castNode(_type_, nodeptr)
void pairingheap_add(pairingheap *heap, pairingheap_node *node)
pairingheap * pairingheap_allocate(pairingheap_comparator compare, void *arg)
pairingheap_node * pairingheap_remove_first(pairingheap *heap)
pairingheap_node * pairingheap_first(pairingheap *heap)
#define pairingheap_is_empty(h)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
static int list_length(const List *l)
#define forboth(cell1, list1, cell2, list2)
#define forfour(cell1, list1, cell2, list2, cell3, list3, cell4, list4)
static Datum PointerGetDatum(const void *X)
static Pointer DatumGetPointer(Datum X)
static int cmp(const chr *x, const chr *y, size_t len)
#define RelationGetDescr(relation)
#define IndexRelationGetNumberOfKeyAttributes(relation)
void ScanKeyEntryInitialize(ScanKey entry, int flags, AttrNumber attributeNumber, StrategyNumber strategy, Oid subtype, Oid collation, RegProcedure procedure, Datum argument)
#define ScanDirectionIsForward(direction)
#define ScanDirectionCombine(a, b)
#define ScanDirectionIsBackward(direction)
void * shm_toc_allocate(shm_toc *toc, Size nbytes)
void shm_toc_insert(shm_toc *toc, uint64 key, void *address)
void * shm_toc_lookup(shm_toc *toc, uint64 key, bool noError)
#define shm_toc_estimate_chunk(e, sz)
#define shm_toc_estimate_keys(e, cnt)
struct ScanKeyData ScanKeyData
void PrepareSortSupportFromOrderingOp(Oid orderingOp, SortSupport ssup)
ExecAuxRowMark ** relsubs_rowmark
TupleTableSlot ** relsubs_slot
MemoryContext es_query_cxt
ScanDirection es_direction
struct EPQState * es_epq_active
MemoryContext ecxt_per_tuple_memory
TupleTableSlot * ecxt_scantuple
struct ScanKeyData * scan_key
struct ScanKeyData * scan_key
bool * iss_OrderByTypByVals
struct IndexScanDescData * iss_ScanDesc
IndexScanInstrumentation iss_Instrument
ExprState * indexqualorig
Relation iss_RelationDesc
pairingheap * iss_ReorderQueue
bool iss_RuntimeKeysReady
SortSupport iss_SortSupport
struct ScanKeyData * iss_ScanKeys
SharedIndexScanInstrumentation * iss_SharedInfo
ExprContext * iss_RuntimeContext
struct ScanKeyData * iss_OrderByKeys
Datum * iss_OrderByValues
int16 * iss_OrderByTypLens
IndexRuntimeKeyInfo * iss_RuntimeKeys
NullTestType nulltesttype
shm_toc_estimator estimator
Instrumentation * instrument
ExprContext * ps_ExprContext
ExecProcNodeMtd ExecProcNode
StrategyNumber sk_strategy
Relation ss_currentRelation
TupleTableSlot * ss_ScanTupleSlot
struct TableScanDescData * ss_currentScanDesc
IndexScanInstrumentation winstrument[FLEXIBLE_ARRAY_MEMBER]
int(* comparator)(Datum x, Datum y, SortSupport ssup)
const TupleTableSlotOps * table_slot_callbacks(Relation relation)
static HeapTuple ExecCopySlotHeapTuple(TupleTableSlot *slot)
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)