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 (index->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)