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