PostgreSQL Source Code: src/backend/executor/nodeIndexscan.c Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
31
45
46
47
48
49
50typedef struct
51{
57
63 const Datum *bdist, const bool *bnulls,
68 const Datum *orderbyvals, const bool *orderbynulls);
70
71
72
73
74
75
76
77
78
81{
87
88
89
90
92
93
94
95
96
102
103 if (scandesc == NULL)
104 {
105
106
107
108
115
117
118
119
120
121
126 }
127
128
129
130
132 {
134
135
136
137
138
140 {
143 {
144
146 continue;
147 }
148 }
149
150 return slot;
151 }
152
153
154
155
156
159}
160
161
162
163
164
165
166
167
170{
176 bool was_exact;
177 Datum *lastfetched_vals;
178 bool *lastfetched_nulls;
180
182
183
184
185
186
187
188
189
190
191
194
198
199 if (scandesc == NULL)
200 {
201
202
203
204
211
213
214
215
216
217
222 }
223
224 for (;;)
225 {
227
228
229
230
231
232
234 {
236
242 node) <= 0)
243 {
245
247
248
250 return slot;
251 }
252 }
254 {
255
257 }
258
259
260
261
262next_indextuple:
264 {
265
266
267
268
270 continue;
271 }
272
273
274
275
276
278 {
281 {
282
284
286 goto next_indextuple;
287 }
288 }
289
291 {
295
296
297
298
299
300
301
302
303
304
309 node);
310 if (cmp < 0)
311 elog(ERROR, "index returned tuples in wrong order");
312 else if (cmp == 0)
313 was_exact = true;
314 else
315 was_exact = false;
318 }
319 else
320 {
321 was_exact = true;
324 }
325
326
327
328
329
330
331
332
333
334 if (!was_exact || (topmost && cmp_orderbyvals(lastfetched_vals,
335 lastfetched_nulls,
338 node) > 0))
339 {
340
341 reorderqueue_push(node, slot, lastfetched_vals, lastfetched_nulls);
342 continue;
343 }
344 else
345 {
346
347 return slot;
348 }
349 }
350
351
352
353
354
356}
357
358
359
360
361static void
363{
364 int i;
367
369
370 i = 0;
372 {
374
376 econtext,
378 i++;
379 }
380
382}
383
384
385
386
387static bool
389{
391
392
393
394
396
397
400}
401
402
403
404
405
406static int
408 const Datum *bdist, const bool *bnulls,
410{
411 int i;
412 int result;
413
415 {
417
418
419
420
421
422
423 if (anulls[i] && !bnulls[i])
424 return 1;
425 else if (!anulls[i] && bnulls[i])
426 return -1;
427 else if (anulls[i] && bnulls[i])
428 return 0;
429
430 result = ssup->comparator(adist[i], bdist[i], ssup);
431 if (result != 0)
432 return result;
433 }
434
435 return 0;
436}
437
438
439
440
441
442static int
444 void *arg)
445{
449
450
453 node);
454}
455
456
457
458
459static void
461 const Datum *orderbyvals, const bool *orderbynulls)
462{
467 int i;
468
474 {
475 if (!orderbynulls[i])
479 else
482 }
484
486}
487
488
489
490
493{
496 int i;
497
499
500 result = topmost->htup;
502 {
505 }
509
510 return result;
511}
512
513
514
515
516
517
520{
522
523
524
525
528
533 else
537}
538
539
540
541
542
543
544
545
546
547
548
549
550void
552{
553
554
555
556
557
558
559
561 {
563
568 }
570
571
573 {
575
577 {
580 }
581 }
582
583
589
591}
592
593
594
595
596
597
598void
601{
602 int j;
604
605
607
608 for (j = 0; j < numRuntimeKeys; j++)
609 {
613 bool isNull;
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
633 econtext,
634 &isNull);
635 if (isNull)
636 {
639 }
640 else
641 {
642 if (runtimeKeys[j].key_toastable)
645 scan_key->sk_flags &= ~SK_ISNULL;
646 }
647 }
648
650}
651
652
653
654
655
656
657
658
659
660bool
663{
664 bool result = true;
665 int j;
667
668
670
671 for (j = 0; j < numArrayKeys; j++)
672 {
675 Datum arraydatum;
676 bool isNull;
679 bool elmbyval;
680 char elmalign;
681 int num_elems;
682 Datum *elem_values;
683 bool *elem_nulls;
684
685
686
687
688
690 econtext,
691 &isNull);
692 if (isNull)
693 {
694 result = false;
695 break;
696 }
698
700 &elmlen, &elmbyval, &elmalign);
703 elmlen, elmbyval, elmalign,
704 &elem_values, &elem_nulls, &num_elems);
705 if (num_elems <= 0)
706 {
707 result = false;
708 break;
709 }
710
711
712
713
714
715
720 if (elem_nulls[0])
722 else
723 scan_key->sk_flags &= ~SK_ISNULL;
725 }
726
728
729 return result;
730}
731
732
733
734
735
736
737
738
739bool
741{
742 bool found = false;
743 int j;
744
745
746
747
748
749
750
751 for (j = numArrayKeys - 1; j >= 0; j--)
752 {
754 int next_elem = arrayKeys[j].next_elem;
755 int num_elems = arrayKeys[j].num_elems;
757 bool *elem_nulls = arrayKeys[j].elem_nulls;
758
759 if (next_elem >= num_elems)
760 {
761 next_elem = 0;
762 found = false;
763 }
764 else
765 found = true;
766 scan_key->sk_argument = elem_values[next_elem];
767 if (elem_nulls[next_elem])
769 else
770 scan_key->sk_flags &= ~SK_ISNULL;
771 arrayKeys[j].next_elem = next_elem + 1;
772 if (found)
773 break;
774 }
775
776 return found;
777}
778
779
780
781
782
783
784void
786{
789
790
791
792
795
796
797
798
799
800
802 {
804
805 Assert(ParallelWorkerNumber <= node->iss_SharedInfo->num_workers);
807
808
809
810
811
812
813
815 }
816
817
818
819
820 if (indexScanDesc)
822 if (indexRelationDesc)
824}
825
826
827
828
829
830
831
832
833void
835{
838
839 if (epqstate != NULL)
840 {
841
842
843
844
845
846
847
848
849
851
852 Assert(scanrelid > 0);
853 if (epqstate->relsubs_slot[scanrelid - 1] != NULL ||
855 {
856
858 elog(ERROR, "unexpected ExecIndexMarkPos call in EPQ recheck");
859 return;
860 }
861 }
862
864}
865
866
867
868
869
870void
872{
875
877 {
878
880
881 Assert(scanrelid > 0);
882 if (epqstate->relsubs_slot[scanrelid - 1] != NULL ||
884 {
885
887 elog(ERROR, "unexpected ExecIndexRestrPos call in EPQ recheck");
888 return;
889 }
890 }
891
893}
894
895
896
897
898
899
900
901
902
903
904
905
908{
912
913
914
915
918 indexstate->ss.ps.state = estate;
920
921
922
923
924
925
927
928
929
930
932
935
936
937
938
942
943
944
945
948
949
950
951
952
953
954
955
956
957
958
965
966
967
968
969
970
972 return indexstate;
973
974
977
978
979
980
984
985
986
987
991 false,
996 NULL,
997 NULL);
998
999
1000
1001
1005 true,
1010 NULL,
1011 NULL);
1012
1013
1015 {
1017 int i;
1020
1021
1022
1023
1024
1030 palloc(numOrderByKeys * sizeof(bool));
1033 i = 0;
1035 {
1038 Oid orderbyType = exprType(orderbyexpr);
1041
1042
1045
1047
1049
1052
1056 i++;
1057 }
1058
1059
1063 palloc(numOrderByKeys * sizeof(bool));
1064
1065
1067 indexstate);
1068 }
1069
1070
1071
1072
1073
1074
1075
1077 {
1079
1083 }
1084 else
1085 {
1087 }
1088
1089
1090
1091
1092 return indexstate;
1093}
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155void
1157 List *quals, bool isorderby,
1158 ScanKey *scanKeys, int *numScanKeys,
1161{
1166 int n_scan_keys;
1167 int n_runtime_keys;
1168 int max_runtime_keys;
1169 int n_array_keys;
1170 int j;
1171
1172
1175
1176
1177
1178
1179
1180
1181
1182
1183 runtime_keys = *runtimeKeys;
1184 n_runtime_keys = max_runtime_keys = *numRuntimeKeys;
1185
1186
1189 n_array_keys = 0;
1190
1191
1192
1193
1194
1195 j = 0;
1196 foreach(qual_cell, quals)
1197 {
1199 ScanKey this_scan_key = &scan_keys[j++];
1200 Oid opno;
1201 RegProcedure opfuncid;
1202 Oid opfamily;
1203 int op_strategy;
1204 Oid op_lefttype;
1205 Oid op_righttype;
1206 Expr *leftop;
1207 Expr *rightop;
1208 AttrNumber varattno;
1209 int indnkeyatts;
1210
1213 {
1214
1215 int flags = 0;
1216 Datum scanvalue;
1217
1218 opno = ((OpExpr *) clause)->opno;
1219 opfuncid = ((OpExpr *) clause)->opfuncid;
1220
1221
1222
1223
1225
1228
1229 Assert(leftop != NULL);
1230
1231 if (!(IsA(leftop, Var) &&
1233 elog(ERROR, "indexqual doesn't have key on left side");
1234
1235 varattno = ((Var *) leftop)->varattno;
1236 if (varattno < 1 || varattno > indnkeyatts)
1237 elog(ERROR, "bogus index qualification");
1238
1239
1240
1241
1242
1243 opfamily = index->rd_opfamily[varattno - 1];
1244
1246 &op_strategy,
1247 &op_lefttype,
1248 &op_righttype);
1249
1250 if (isorderby)
1252
1253
1254
1255
1257
1260
1261 Assert(rightop != NULL);
1262
1264 {
1265
1266 scanvalue = ((Const *) rightop)->constvalue;
1267 if (((Const *) rightop)->constisnull)
1269 }
1270 else
1271 {
1272
1273 if (n_runtime_keys >= max_runtime_keys)
1274 {
1275 if (max_runtime_keys == 0)
1276 {
1277 max_runtime_keys = 8;
1280 }
1281 else
1282 {
1283 max_runtime_keys *= 2;
1286 }
1287 }
1288 runtime_keys[n_runtime_keys].scan_key = this_scan_key;
1289 runtime_keys[n_runtime_keys].key_expr =
1293 n_runtime_keys++;
1294 scanvalue = (Datum) 0;
1295 }
1296
1297
1298
1299
1301 flags,
1302 varattno,
1303 op_strategy,
1304 op_righttype,
1305 ((OpExpr *) clause)->inputcollid,
1306 opfuncid,
1307 scanvalue);
1308 }
1310 {
1311
1314 int n_sub_key;
1319
1321
1322 first_sub_key = (ScanKey)
1324 n_sub_key = 0;
1325
1326
1328 opnos_cell, rc->opnos, collids_cell, rc->inputcollids)
1329 {
1330 ScanKey this_sub_key = &first_sub_key[n_sub_key];
1332 Datum scanvalue;
1333 Oid inputcollation;
1334
1335 leftop = (Expr *) lfirst(largs_cell);
1336 rightop = (Expr *) lfirst(rargs_cell);
1338 inputcollation = lfirst_oid(collids_cell);
1339
1340
1341
1342
1345
1346 Assert(leftop != NULL);
1347
1348 if (!(IsA(leftop, Var) &&
1350 elog(ERROR, "indexqual doesn't have key on left side");
1351
1352 varattno = ((Var *) leftop)->varattno;
1353
1354
1355
1356
1357
1358 if (->rd_indam->amcanorder ||
1359 varattno < 1 || varattno > indnkeyatts)
1360 elog(ERROR, "bogus RowCompare index qualification");
1361 opfamily = index->rd_opfamily[varattno - 1];
1362
1364 &op_strategy,
1365 &op_lefttype,
1366 &op_righttype);
1367
1368 if (op_strategy != rc->cmptype)
1369 elog(ERROR, "RowCompare index qualification contains wrong operator");
1370
1372 op_lefttype,
1373 op_righttype,
1376 elog(ERROR, "missing support function %d(%u,%u) in opfamily %u",
1377 BTORDER_PROC, op_lefttype, op_righttype, opfamily);
1378
1379
1380
1381
1383 rightop = ((RelabelType *) rightop)->arg;
1384
1385 Assert(rightop != NULL);
1386
1388 {
1389
1390 scanvalue = ((Const *) rightop)->constvalue;
1391 if (((Const *) rightop)->constisnull)
1393 }
1394 else
1395 {
1396
1397 if (n_runtime_keys >= max_runtime_keys)
1398 {
1399 if (max_runtime_keys == 0)
1400 {
1401 max_runtime_keys = 8;
1404 }
1405 else
1406 {
1407 max_runtime_keys *= 2;
1410 }
1411 }
1412 runtime_keys[n_runtime_keys].scan_key = this_sub_key;
1413 runtime_keys[n_runtime_keys].key_expr =
1417 n_runtime_keys++;
1418 scanvalue = (Datum) 0;
1419 }
1420
1421
1422
1423
1425 flags,
1426 varattno,
1427 op_strategy,
1428 op_righttype,
1429 inputcollation,
1430 opfuncid,
1431 scanvalue);
1432 n_sub_key++;
1433 }
1434
1435
1437
1438
1439
1440
1441
1446
1448 }
1450 {
1451
1453 int flags = 0;
1454 Datum scanvalue;
1455
1457
1459 opno = saop->opno;
1460 opfuncid = saop->opfuncid;
1461
1462
1463
1464
1466
1469
1470 Assert(leftop != NULL);
1471
1472 if (!(IsA(leftop, Var) &&
1474 elog(ERROR, "indexqual doesn't have key on left side");
1475
1476 varattno = ((Var *) leftop)->varattno;
1477 if (varattno < 1 || varattno > indnkeyatts)
1478 elog(ERROR, "bogus index qualification");
1479
1480
1481
1482
1483
1484 opfamily = index->rd_opfamily[varattno - 1];
1485
1487 &op_strategy,
1488 &op_lefttype,
1489 &op_righttype);
1490
1491
1492
1493
1495
1498
1499 Assert(rightop != NULL);
1500
1501 if (index->rd_indam->amsearcharray)
1502 {
1503
1506 {
1507
1508 scanvalue = ((Const *) rightop)->constvalue;
1509 if (((Const *) rightop)->constisnull)
1511 }
1512 else
1513 {
1514
1515 if (n_runtime_keys >= max_runtime_keys)
1516 {
1517 if (max_runtime_keys == 0)
1518 {
1519 max_runtime_keys = 8;
1522 }
1523 else
1524 {
1525 max_runtime_keys *= 2;
1528 }
1529 }
1530 runtime_keys[n_runtime_keys].scan_key = this_scan_key;
1531 runtime_keys[n_runtime_keys].key_expr =
1533
1534
1535
1536
1537
1538
1539
1540 runtime_keys[n_runtime_keys].key_toastable = true;
1541 n_runtime_keys++;
1542 scanvalue = (Datum) 0;
1543 }
1544 }
1545 else
1546 {
1547
1548 array_keys[n_array_keys].scan_key = this_scan_key;
1549 array_keys[n_array_keys].array_expr =
1551
1552 n_array_keys++;
1553 scanvalue = (Datum) 0;
1554 }
1555
1556
1557
1558
1560 flags,
1561 varattno,
1562 op_strategy,
1563 op_righttype,
1564 saop->inputcollid,
1565 opfuncid,
1566 scanvalue);
1567 }
1569 {
1570
1572 int flags;
1573
1575
1576
1577
1578
1579 leftop = ntest->arg;
1580
1583
1584 Assert(leftop != NULL);
1585
1586 if (!(IsA(leftop, Var) &&
1588 elog(ERROR, "NullTest indexqual has wrong key");
1589
1590 varattno = ((Var *) leftop)->varattno;
1591
1592
1593
1594
1596 {
1599 break;
1602 break;
1603 default:
1604 elog(ERROR, "unrecognized nulltesttype: %d",
1606 flags = 0;
1607 break;
1608 }
1609
1611 flags,
1612 varattno,
1614 InvalidOid,
1616 InvalidOid,
1617 (Datum) 0);
1618 }
1619 else
1620 elog(ERROR, "unsupported indexqual type: %d",
1622 }
1623
1624 Assert(n_runtime_keys <= max_runtime_keys);
1625
1626
1627 if (n_array_keys == 0)
1628 {
1629 pfree(array_keys);
1630 array_keys = NULL;
1631 }
1632
1633
1634
1635
1636 *scanKeys = scan_keys;
1637 *numScanKeys = n_scan_keys;
1638 *runtimeKeys = runtime_keys;
1639 *numRuntimeKeys = n_runtime_keys;
1640 if (arrayKeys)
1641 {
1642 *arrayKeys = array_keys;
1643 *numArrayKeys = n_array_keys;
1644 }
1645 else if (n_array_keys != 0)
1646 elog(ERROR, "ScalarArrayOpExpr index qual found where not allowed");
1647}
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661void
1664{
1668
1669 if (!instrument && !parallel_aware)
1670 {
1671
1672 return;
1673 }
1674
1679 instrument, parallel_aware,
1683}
1684
1685
1686
1687
1688
1689
1690
1691void
1694{
1699
1700 if (!instrument && !parallel_aware)
1701 {
1702
1703 return;
1704 }
1705
1710 instrument, parallel_aware, pcxt->nworkers,
1713
1714 if (!parallel_aware)
1715 {
1716
1717 return;
1718 }
1719
1726 piscan);
1727
1728
1729
1730
1731
1736}
1737
1738
1739
1740
1741
1742
1743
1744void
1747{
1750}
1751
1752
1753
1754
1755
1756
1757
1758void
1761{
1765
1766 if (!instrument && !parallel_aware)
1767 {
1768
1769 return;
1770 }
1771
1773
1774 if (instrument)
1777
1778 if (!parallel_aware)
1779 {
1780
1781 return;
1782 }
1783
1790 piscan);
1791
1792
1793
1794
1795
1800}
1801
1802
1803
1804
1805
1806
1807
1808void
1810{
1812 size_t size;
1813
1814 if (SharedInfo == NULL)
1815 return;
1816
1817
1822}
#define DatumGetArrayTypeP(X)
void deconstruct_array(const 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 palloc_object(type)
#define palloc_array(type, count)
#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)
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)
static void reorderqueue_push(IndexScanState *node, TupleTableSlot *slot, const Datum *orderbyvals, const bool *orderbynulls)
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
bool * iss_OrderByTypByVals
struct IndexScanDescData * iss_ScanDesc
IndexScanInstrumentation iss_Instrument
ExprState * indexqualorig
Relation iss_RelationDesc
pairingheap * iss_ReorderQueue
bool iss_RuntimeKeysReady
ScanKeyData * iss_ScanKeys
ScanKeyData * iss_OrderByKeys
SortSupport iss_SortSupport
SharedIndexScanInstrumentation * iss_SharedInfo
ExprContext * iss_RuntimeContext
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
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)