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 Datum *orderbyvals, 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 Datum *orderbyvals, bool *orderbynulls)
462{
467 int i;
468
476 {
477 if (!orderbynulls[i])
481 else
484 }
486
488}
489
490
491
492
495{
498 int i;
499
501
502 result = topmost->htup;
504 {
507 }
511
512 return result;
513}
514
515
516
517
518
519
522{
524
525
526
527
530
535 else
539}
540
541
542
543
544
545
546
547
548
549
550
551
552void
554{
555
556
557
558
559
560
561
563 {
565
570 }
572
573
575 {
577
579 {
582 }
583 }
584
585
591
593}
594
595
596
597
598
599
600void
603{
604 int j;
606
607
609
610 for (j = 0; j < numRuntimeKeys; j++)
611 {
615 bool isNull;
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
635 econtext,
636 &isNull);
637 if (isNull)
638 {
641 }
642 else
643 {
644 if (runtimeKeys[j].key_toastable)
647 scan_key->sk_flags &= ~SK_ISNULL;
648 }
649 }
650
652}
653
654
655
656
657
658
659
660
661
662bool
665{
666 bool result = true;
667 int j;
669
670
672
673 for (j = 0; j < numArrayKeys; j++)
674 {
677 Datum arraydatum;
678 bool isNull;
681 bool elmbyval;
682 char elmalign;
683 int num_elems;
684 Datum *elem_values;
685 bool *elem_nulls;
686
687
688
689
690
692 econtext,
693 &isNull);
694 if (isNull)
695 {
696 result = false;
697 break;
698 }
700
702 &elmlen, &elmbyval, &elmalign);
705 elmlen, elmbyval, elmalign,
706 &elem_values, &elem_nulls, &num_elems);
707 if (num_elems <= 0)
708 {
709 result = false;
710 break;
711 }
712
713
714
715
716
717
722 if (elem_nulls[0])
724 else
725 scan_key->sk_flags &= ~SK_ISNULL;
727 }
728
730
731 return result;
732}
733
734
735
736
737
738
739
740
741bool
743{
744 bool found = false;
745 int j;
746
747
748
749
750
751
752
753 for (j = numArrayKeys - 1; j >= 0; j--)
754 {
756 int next_elem = arrayKeys[j].next_elem;
757 int num_elems = arrayKeys[j].num_elems;
759 bool *elem_nulls = arrayKeys[j].elem_nulls;
760
761 if (next_elem >= num_elems)
762 {
763 next_elem = 0;
764 found = false;
765 }
766 else
767 found = true;
768 scan_key->sk_argument = elem_values[next_elem];
769 if (elem_nulls[next_elem])
771 else
772 scan_key->sk_flags &= ~SK_ISNULL;
773 arrayKeys[j].next_elem = next_elem + 1;
774 if (found)
775 break;
776 }
777
778 return found;
779}
780
781
782
783
784
785
786void
788{
791
792
793
794
797
798
799
800
801
802
804 {
806
807 Assert(ParallelWorkerNumber <= node->iss_SharedInfo->num_workers);
809
810
811
812
813
814
815
817 }
818
819
820
821
822 if (indexScanDesc)
824 if (indexRelationDesc)
826}
827
828
829
830
831
832
833
834
835void
837{
840
841 if (epqstate != NULL)
842 {
843
844
845
846
847
848
849
850
851
853
854 Assert(scanrelid > 0);
855 if (epqstate->relsubs_slot[scanrelid - 1] != NULL ||
857 {
858
860 elog(ERROR, "unexpected ExecIndexMarkPos call in EPQ recheck");
861 return;
862 }
863 }
864
866}
867
868
869
870
871
872void
874{
877
879 {
880
882
883 Assert(scanrelid > 0);
884 if (epqstate->relsubs_slot[scanrelid - 1] != NULL ||
886 {
887
889 elog(ERROR, "unexpected ExecIndexRestrPos call in EPQ recheck");
890 return;
891 }
892 }
893
895}
896
897
898
899
900
901
902
903
904
905
906
907
910{
914
915
916
917
920 indexstate->ss.ps.state = estate;
922
923
924
925
926
927
929
930
931
932
934
937
938
939
940
944
945
946
947
950
951
952
953
954
955
956
957
958
959
960
967
968
969
970
971
972
974 return indexstate;
975
976
979
980
981
982
986
987
988
989
993 false,
998 NULL,
999 NULL);
1000
1001
1002
1003
1007 true,
1012 NULL,
1013 NULL);
1014
1015
1017 {
1019 int i;
1022
1023
1024
1025
1026
1032 palloc(numOrderByKeys * sizeof(bool));
1035 i = 0;
1037 {
1040 Oid orderbyType = exprType(orderbyexpr);
1043
1044
1047
1049
1051
1054
1058 i++;
1059 }
1060
1061
1065 palloc(numOrderByKeys * sizeof(bool));
1066
1067
1069 indexstate);
1070 }
1071
1072
1073
1074
1075
1076
1077
1079 {
1081
1085 }
1086 else
1087 {
1089 }
1090
1091
1092
1093
1094 return indexstate;
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
1155
1156
1157void
1159 List *quals, bool isorderby,
1160 ScanKey *scanKeys, int *numScanKeys,
1163{
1168 int n_scan_keys;
1169 int n_runtime_keys;
1170 int max_runtime_keys;
1171 int n_array_keys;
1172 int j;
1173
1174
1177
1178
1179
1180
1181
1182
1183
1184
1185 runtime_keys = *runtimeKeys;
1186 n_runtime_keys = max_runtime_keys = *numRuntimeKeys;
1187
1188
1191 n_array_keys = 0;
1192
1193
1194
1195
1196
1197 j = 0;
1198 foreach(qual_cell, quals)
1199 {
1201 ScanKey this_scan_key = &scan_keys[j++];
1202 Oid opno;
1203 RegProcedure opfuncid;
1204 Oid opfamily;
1205 int op_strategy;
1206 Oid op_lefttype;
1207 Oid op_righttype;
1208 Expr *leftop;
1209 Expr *rightop;
1210 AttrNumber varattno;
1211 int indnkeyatts;
1212
1215 {
1216
1217 int flags = 0;
1218 Datum scanvalue;
1219
1220 opno = ((OpExpr *) clause)->opno;
1221 opfuncid = ((OpExpr *) clause)->opfuncid;
1222
1223
1224
1225
1227
1230
1231 Assert(leftop != NULL);
1232
1233 if (!(IsA(leftop, Var) &&
1235 elog(ERROR, "indexqual doesn't have key on left side");
1236
1237 varattno = ((Var *) leftop)->varattno;
1238 if (varattno < 1 || varattno > indnkeyatts)
1239 elog(ERROR, "bogus index qualification");
1240
1241
1242
1243
1244
1245 opfamily = index->rd_opfamily[varattno - 1];
1246
1248 &op_strategy,
1249 &op_lefttype,
1250 &op_righttype);
1251
1252 if (isorderby)
1254
1255
1256
1257
1259
1262
1263 Assert(rightop != NULL);
1264
1266 {
1267
1268 scanvalue = ((Const *) rightop)->constvalue;
1269 if (((Const *) rightop)->constisnull)
1271 }
1272 else
1273 {
1274
1275 if (n_runtime_keys >= max_runtime_keys)
1276 {
1277 if (max_runtime_keys == 0)
1278 {
1279 max_runtime_keys = 8;
1282 }
1283 else
1284 {
1285 max_runtime_keys *= 2;
1288 }
1289 }
1290 runtime_keys[n_runtime_keys].scan_key = this_scan_key;
1291 runtime_keys[n_runtime_keys].key_expr =
1295 n_runtime_keys++;
1296 scanvalue = (Datum) 0;
1297 }
1298
1299
1300
1301
1303 flags,
1304 varattno,
1305 op_strategy,
1306 op_righttype,
1307 ((OpExpr *) clause)->inputcollid,
1308 opfuncid,
1309 scanvalue);
1310 }
1312 {
1313
1316 int n_sub_key;
1321
1323
1324 first_sub_key = (ScanKey)
1326 n_sub_key = 0;
1327
1328
1330 opnos_cell, rc->opnos, collids_cell, rc->inputcollids)
1331 {
1332 ScanKey this_sub_key = &first_sub_key[n_sub_key];
1334 Datum scanvalue;
1335 Oid inputcollation;
1336
1337 leftop = (Expr *) lfirst(largs_cell);
1338 rightop = (Expr *) lfirst(rargs_cell);
1340 inputcollation = lfirst_oid(collids_cell);
1341
1342
1343
1344
1347
1348 Assert(leftop != NULL);
1349
1350 if (!(IsA(leftop, Var) &&
1352 elog(ERROR, "indexqual doesn't have key on left side");
1353
1354 varattno = ((Var *) leftop)->varattno;
1355
1356
1357
1358
1359
1360 if (->rd_indam->amcanorder ||
1361 varattno < 1 || varattno > indnkeyatts)
1362 elog(ERROR, "bogus RowCompare index qualification");
1363 opfamily = index->rd_opfamily[varattno - 1];
1364
1366 &op_strategy,
1367 &op_lefttype,
1368 &op_righttype);
1369
1370 if (op_strategy != rc->cmptype)
1371 elog(ERROR, "RowCompare index qualification contains wrong operator");
1372
1374 op_lefttype,
1375 op_righttype,
1378 elog(ERROR, "missing support function %d(%u,%u) in opfamily %u",
1379 BTORDER_PROC, op_lefttype, op_righttype, opfamily);
1380
1381
1382
1383
1385 rightop = ((RelabelType *) rightop)->arg;
1386
1387 Assert(rightop != NULL);
1388
1390 {
1391
1392 scanvalue = ((Const *) rightop)->constvalue;
1393 if (((Const *) rightop)->constisnull)
1395 }
1396 else
1397 {
1398
1399 if (n_runtime_keys >= max_runtime_keys)
1400 {
1401 if (max_runtime_keys == 0)
1402 {
1403 max_runtime_keys = 8;
1406 }
1407 else
1408 {
1409 max_runtime_keys *= 2;
1412 }
1413 }
1414 runtime_keys[n_runtime_keys].scan_key = this_sub_key;
1415 runtime_keys[n_runtime_keys].key_expr =
1419 n_runtime_keys++;
1420 scanvalue = (Datum) 0;
1421 }
1422
1423
1424
1425
1427 flags,
1428 varattno,
1429 op_strategy,
1430 op_righttype,
1431 inputcollation,
1432 opfuncid,
1433 scanvalue);
1434 n_sub_key++;
1435 }
1436
1437
1439
1440
1441
1442
1443
1448
1450 }
1452 {
1453
1455 int flags = 0;
1456 Datum scanvalue;
1457
1459
1461 opno = saop->opno;
1462 opfuncid = saop->opfuncid;
1463
1464
1465
1466
1468
1471
1472 Assert(leftop != NULL);
1473
1474 if (!(IsA(leftop, Var) &&
1476 elog(ERROR, "indexqual doesn't have key on left side");
1477
1478 varattno = ((Var *) leftop)->varattno;
1479 if (varattno < 1 || varattno > indnkeyatts)
1480 elog(ERROR, "bogus index qualification");
1481
1482
1483
1484
1485
1486 opfamily = index->rd_opfamily[varattno - 1];
1487
1489 &op_strategy,
1490 &op_lefttype,
1491 &op_righttype);
1492
1493
1494
1495
1497
1500
1501 Assert(rightop != NULL);
1502
1503 if (index->rd_indam->amsearcharray)
1504 {
1505
1508 {
1509
1510 scanvalue = ((Const *) rightop)->constvalue;
1511 if (((Const *) rightop)->constisnull)
1513 }
1514 else
1515 {
1516
1517 if (n_runtime_keys >= max_runtime_keys)
1518 {
1519 if (max_runtime_keys == 0)
1520 {
1521 max_runtime_keys = 8;
1524 }
1525 else
1526 {
1527 max_runtime_keys *= 2;
1530 }
1531 }
1532 runtime_keys[n_runtime_keys].scan_key = this_scan_key;
1533 runtime_keys[n_runtime_keys].key_expr =
1535
1536
1537
1538
1539
1540
1541
1542 runtime_keys[n_runtime_keys].key_toastable = true;
1543 n_runtime_keys++;
1544 scanvalue = (Datum) 0;
1545 }
1546 }
1547 else
1548 {
1549
1550 array_keys[n_array_keys].scan_key = this_scan_key;
1551 array_keys[n_array_keys].array_expr =
1553
1554 n_array_keys++;
1555 scanvalue = (Datum) 0;
1556 }
1557
1558
1559
1560
1562 flags,
1563 varattno,
1564 op_strategy,
1565 op_righttype,
1566 saop->inputcollid,
1567 opfuncid,
1568 scanvalue);
1569 }
1571 {
1572
1574 int flags;
1575
1577
1578
1579
1580
1581 leftop = ntest->arg;
1582
1585
1586 Assert(leftop != NULL);
1587
1588 if (!(IsA(leftop, Var) &&
1590 elog(ERROR, "NullTest indexqual has wrong key");
1591
1592 varattno = ((Var *) leftop)->varattno;
1593
1594
1595
1596
1598 {
1601 break;
1604 break;
1605 default:
1606 elog(ERROR, "unrecognized nulltesttype: %d",
1608 flags = 0;
1609 break;
1610 }
1611
1613 flags,
1614 varattno,
1616 InvalidOid,
1618 InvalidOid,
1619 (Datum) 0);
1620 }
1621 else
1622 elog(ERROR, "unsupported indexqual type: %d",
1624 }
1625
1626 Assert(n_runtime_keys <= max_runtime_keys);
1627
1628
1629 if (n_array_keys == 0)
1630 {
1631 pfree(array_keys);
1632 array_keys = NULL;
1633 }
1634
1635
1636
1637
1638 *scanKeys = scan_keys;
1639 *numScanKeys = n_scan_keys;
1640 *runtimeKeys = runtime_keys;
1641 *numRuntimeKeys = n_runtime_keys;
1642 if (arrayKeys)
1643 {
1644 *arrayKeys = array_keys;
1645 *numArrayKeys = n_array_keys;
1646 }
1647 else if (n_array_keys != 0)
1648 elog(ERROR, "ScalarArrayOpExpr index qual found where not allowed");
1649}
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663void
1666{
1670
1671 if (!instrument && !parallel_aware)
1672 {
1673
1674 return;
1675 }
1676
1681 instrument, parallel_aware,
1685}
1686
1687
1688
1689
1690
1691
1692
1693void
1696{
1701
1702 if (!instrument && !parallel_aware)
1703 {
1704
1705 return;
1706 }
1707
1712 instrument, parallel_aware, pcxt->nworkers,
1715
1716 if (!parallel_aware)
1717 {
1718
1719 return;
1720 }
1721
1728 piscan);
1729
1730
1731
1732
1733
1738}
1739
1740
1741
1742
1743
1744
1745
1746void
1749{
1752}
1753
1754
1755
1756
1757
1758
1759
1760void
1763{
1767
1768 if (!instrument && !parallel_aware)
1769 {
1770
1771 return;
1772 }
1773
1775
1776 if (instrument)
1779
1780 if (!parallel_aware)
1781 {
1782
1783 return;
1784 }
1785
1792 piscan);
1793
1794
1795
1796
1797
1802}
1803
1804
1805
1806
1807
1808
1809
1810void
1812{
1814 size_t size;
1815
1816 if (SharedInfo == NULL)
1817 return;
1818
1819
1824}
#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
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)