63 const Datum *bdist,
const bool *bnulls,
68 Datum *orderbyvals,
bool *orderbynulls);
103 if (scandesc == NULL)
176 Datum *lastfetched_vals;
177 bool *lastfetched_nulls;
198 if (scandesc == NULL)
284 goto next_indextuple;
309 elog(
ERROR,
"index returned tuples in wrong order");
406 const Datum *bdist,
const bool *bnulls,
421 if (anulls[
i] && !bnulls[
i])
423 else if (!anulls[
i] && bnulls[
i])
425 else if (anulls[
i] && bnulls[
i])
459 Datum *orderbyvals,
bool *orderbynulls)
475 if (!orderbynulls[
i])
500 result = topmost->
htup;
608 for (
j = 0;
j < numRuntimeKeys;
j++)
642 if (runtimeKeys[
j].key_toastable)
671 for (
j = 0;
j < numArrayKeys;
j++)
700 &elmlen, &elmbyval, &elmalign);
703 elmlen, elmbyval, elmalign,
704 &elem_values, &elem_nulls, &num_elems);
751 for (
j = numArrayKeys - 1;
j >= 0;
j--)
759 if (next_elem >= num_elems)
767 if (elem_nulls[next_elem])
801 if (indexRelationDesc)
818 if (epqstate != NULL)
837 elog(
ERROR,
"unexpected ExecIndexMarkPos call in EPQ recheck");
866 elog(
ERROR,
"unexpected ExecIndexRestrPos call in EPQ recheck");
1009 palloc(numOrderByKeys *
sizeof(
bool));
1042 palloc(numOrderByKeys *
sizeof(
bool));
1136 List *quals,
bool isorderby,
1137 ScanKey *scanKeys,
int *numScanKeys,
1147 int max_runtime_keys;
1162 runtime_keys = *runtimeKeys;
1163 n_runtime_keys = max_runtime_keys = *numRuntimeKeys;
1175 foreach(qual_cell, quals)
1178 ScanKey this_scan_key = &scan_keys[
j++];
1197 opno = ((
OpExpr *) clause)->opno;
1198 opfuncid = ((
OpExpr *) clause)->opfuncid;
1210 if (!(
IsA(leftop,
Var) &&
1212 elog(
ERROR,
"indexqual doesn't have key on left side");
1214 varattno = ((
Var *) leftop)->varattno;
1215 if (varattno < 1 || varattno > indnkeyatts)
1216 elog(
ERROR,
"bogus index qualification");
1222 opfamily =
index->rd_opfamily[varattno - 1];
1245 scanvalue = ((
Const *) rightop)->constvalue;
1246 if (((
Const *) rightop)->constisnull)
1252 if (n_runtime_keys >= max_runtime_keys)
1254 if (max_runtime_keys == 0)
1256 max_runtime_keys = 8;
1262 max_runtime_keys *= 2;
1267 runtime_keys[n_runtime_keys].
scan_key = this_scan_key;
1268 runtime_keys[n_runtime_keys].
key_expr =
1273 scanvalue = (
Datum) 0;
1284 ((
OpExpr *) clause)->inputcollid,
1307 opnos_cell, rc->opnos, collids_cell, rc->inputcollids)
1309 ScanKey this_sub_key = &first_sub_key[n_sub_key];
1327 if (!(
IsA(leftop,
Var) &&
1329 elog(
ERROR,
"indexqual doesn't have key on left side");
1331 varattno = ((
Var *) leftop)->varattno;
1337 if (
index->rd_rel->relam != BTREE_AM_OID ||
1338 varattno < 1 || varattno > indnkeyatts)
1339 elog(
ERROR,
"bogus RowCompare index qualification");
1340 opfamily =
index->rd_opfamily[varattno - 1];
1347 if (op_strategy != rc->
rctype)
1348 elog(
ERROR,
"RowCompare index qualification contains wrong operator");
1355 elog(
ERROR,
"missing support function %d(%u,%u) in opfamily %u",
1369 scanvalue = ((
Const *) rightop)->constvalue;
1370 if (((
Const *) rightop)->constisnull)
1376 if (n_runtime_keys >= max_runtime_keys)
1378 if (max_runtime_keys == 0)
1380 max_runtime_keys = 8;
1386 max_runtime_keys *= 2;
1391 runtime_keys[n_runtime_keys].
scan_key = this_sub_key;
1392 runtime_keys[n_runtime_keys].
key_expr =
1397 scanvalue = (
Datum) 0;
1439 opfuncid = saop->opfuncid;
1451 if (!(
IsA(leftop,
Var) &&
1453 elog(
ERROR,
"indexqual doesn't have key on left side");
1455 varattno = ((
Var *) leftop)->varattno;
1456 if (varattno < 1 || varattno > indnkeyatts)
1457 elog(
ERROR,
"bogus index qualification");
1463 opfamily =
index->rd_opfamily[varattno - 1];
1480 if (
index->rd_indam->amsearcharray)
1487 scanvalue = ((
Const *) rightop)->constvalue;
1488 if (((
Const *) rightop)->constisnull)
1494 if (n_runtime_keys >= max_runtime_keys)
1496 if (max_runtime_keys == 0)
1498 max_runtime_keys = 8;
1504 max_runtime_keys *= 2;
1509 runtime_keys[n_runtime_keys].
scan_key = this_scan_key;
1510 runtime_keys[n_runtime_keys].
key_expr =
1521 scanvalue = (
Datum) 0;
1527 array_keys[n_array_keys].
scan_key = this_scan_key;
1532 scanvalue = (
Datum) 0;
1558 leftop = ntest->
arg;
1565 if (!(
IsA(leftop,
Var) &&
1567 elog(
ERROR,
"NullTest indexqual has wrong key");
1569 varattno = ((
Var *) leftop)->varattno;
1583 elog(
ERROR,
"unrecognized nulltesttype: %d",
1599 elog(
ERROR,
"unsupported indexqual type: %d",
1603 Assert(n_runtime_keys <= max_runtime_keys);
1606 if (n_array_keys == 0)
1615 *scanKeys = scan_keys;
1616 *numScanKeys = n_scan_keys;
1617 *runtimeKeys = runtime_keys;
1618 *numRuntimeKeys = n_runtime_keys;
1621 *arrayKeys = array_keys;
1622 *numArrayKeys = n_array_keys;
1624 else if (n_array_keys != 0)
1625 elog(
ERROR,
"ScalarArrayOpExpr index qual found where not allowed");
#define DatumGetArrayTypeP(X)
void deconstruct_array(ArrayType *array, Oid elmtype, int elmlen, bool elmbyval, char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp)
#define RegProcedureIsValid(p)
#define Assert(condition)
#define MemSet(start, val, len)
Datum datumCopy(Datum value, bool typByVal, int typLen)
void ExecReScan(PlanState *node)
List * ExecInitExprList(List *nodes, PlanState *parent)
ExprState * ExecInitQual(List *qual, PlanState *parent)
ExprState * ExecInitExpr(Expr *node, 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)
TupleTableSlot *(* ExecScanAccessMtd)(ScanState *node)
bool(* ExecScanRecheckMtd)(ScanState *node, TupleTableSlot *slot)
static bool ExecQualAndReset(ExprState *state, ExprContext *econtext)
static Datum ExecEvalExpr(ExprState *state, ExprContext *econtext, bool *isNull)
#define EXEC_FLAG_EXPLAIN_ONLY
#define PG_DETOAST_DATUM(datum)
void heap_freetuple(HeapTuple htup)
bool index_getnext_slot(IndexScanDesc scan, ScanDirection direction, TupleTableSlot *slot)
void index_restrpos(IndexScanDesc scan)
IndexScanDesc index_beginscan_parallel(Relation heaprel, Relation indexrel, int nkeys, int norderbys, ParallelIndexScanDesc pscan)
void index_close(Relation relation, LOCKMODE lockmode)
IndexScanDesc index_beginscan(Relation heapRelation, Relation indexRelation, Snapshot snapshot, int nkeys, int norderbys)
void index_markpos(IndexScanDesc scan)
void index_endscan(IndexScanDesc scan)
Size index_parallelscan_estimate(Relation indexRelation, int nkeys, int norderbys, Snapshot snapshot)
void index_parallelscan_initialize(Relation heapRelation, Relation indexRelation, Snapshot snapshot, ParallelIndexScanDesc target)
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 pfree(void *pointer)
void * palloc0(Size size)
MemoryContext CurrentMemoryContext
void * repalloc(void *pointer, Size size)
#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 TupleTableSlot * ExecIndexScan(PlanState *pstate)
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 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 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_node * pairingheap_first(pairingheap *heap)
pairingheap * pairingheap_allocate(pairingheap_comparator compare, void *arg)
pairingheap_node * pairingheap_remove_first(pairingheap *heap)
#define pairingheap_is_empty(h)
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)
MemoryContextSwitchTo(old_ctx)
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_insert(shm_toc *toc, uint64 key, void *address)
void * shm_toc_allocate(shm_toc *toc, Size nbytes)
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
ExprState * indexqualorig
Relation iss_RelationDesc
pairingheap * iss_ReorderQueue
bool iss_RuntimeKeysReady
SortSupport iss_SortSupport
struct ScanKeyData * iss_ScanKeys
ExprContext * iss_RuntimeContext
struct ScanKeyData * iss_OrderByKeys
Datum * iss_OrderByValues
int16 * iss_OrderByTypLens
IndexRuntimeKeyInfo * iss_RuntimeKeys
NullTestType nulltesttype
shm_toc_estimator estimator
ExprContext * ps_ExprContext
ExecProcNodeMtd ExecProcNode
StrategyNumber sk_strategy
Relation ss_currentRelation
TupleTableSlot * ss_ScanTupleSlot
struct TableScanDescData * ss_currentScanDesc
int(* comparator)(Datum x, Datum y, SortSupport ssup)
const TupleTableSlotOps * table_slot_callbacks(Relation relation)
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
static HeapTuple ExecCopySlotHeapTuple(TupleTableSlot *slot)