PostgreSQL Source Code: src/backend/optimizer/plan/createplan.c Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

18

19#include <math.h>

20

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70#define CP_EXACT_TLIST 0x0001

71#define CP_SMALL_TLIST 0x0002

72#define CP_LABEL_TLIST 0x0004

73#define CP_IGNORE_TLIST 0x0008

74

75

77 int flags);

79 int flags);

84 List *gating_quals);

88 int flags);

90 int flags);

95 int flags);

97 int flags);

99 int flags);

103 int flags);

110 int flags);

116 int flags);

119 int flags);

122 int flags);

124 List *tlist, List *scan_clauses);

126 List *tlist, List *scan_clauses);

128 List *tlist, List *scan_clauses, bool indexonly);

131 List *tlist, List *scan_clauses);

133 List **qual, List **indexqual, List **indexECs);

136 List *tlist, List *scan_clauses);

140 List *scan_clauses);

143 List *tlist, List *scan_clauses);

145 List *tlist, List *scan_clauses);

147 List *tlist, List *scan_clauses);

149 List *tlist, List *scan_clauses);

151 List *tlist, List *scan_clauses);

153 Path *best_path, List *tlist, List *scan_clauses);

155 List *tlist, List *scan_clauses);

157 List *tlist, List *scan_clauses);

159 List *tlist, List *scan_clauses);

162 List *tlist, List *scan_clauses);

169 List **stripped_indexquals_p,

170 List **fixed_indexquals_p);

174 Node *clause, List *indexcolnos);

181 double limit_tuples);

183 List *pathkeys, double limit_tuples);

188 Oid indexid, List *indexqual, List *indexqualorig,

189 List *indexorderby, List *indexorderbyorig,

190 List *indexorderbyops,

193 Index scanrelid, Oid indexid,

194 List *indexqual, List *recheckqual,

195 List *indexorderby,

196 List *indextlist,

199 List *indexqual,

200 List *indexqualorig);

202 List *qpqual,

203 Plan *lefttree,

204 List *bitmapqualorig,

205 Index scanrelid);

207 List *tidquals);

209 Index scanrelid, List *tidrangequals);

211 List *qpqual,

213 Plan *subplan);

217 Index scanrelid, List *values_lists);

221 Index scanrelid, int ctePlanId, int cteParam);

223 Index scanrelid, char *enrname);

225 Index scanrelid, int wtParam);

227 Plan *lefttree,

228 Plan *righttree,

229 int wtParam,

230 List *distinctList,

231 long numGroups);

235 List *joinclauses, List *otherclauses, List *nestParams,

236 Plan *lefttree, Plan *righttree,

237 JoinType jointype, bool inner_unique);

239 List *joinclauses, List *otherclauses,

240 List *hashclauses,

241 List *hashoperators, List *hashcollations,

242 List *hashkeys,

243 Plan *lefttree, Plan *righttree,

244 JoinType jointype, bool inner_unique);

246 List *hashkeys,

247 Oid skewTable,

249 bool skewInherit);

251 List *joinclauses, List *otherclauses,

252 List *mergeclauses,

253 Oid *mergefamilies,

254 Oid *mergecollations,

255 bool *mergereversals,

256 bool *mergenullsfirst,

257 Plan *lefttree, Plan *righttree,

258 JoinType jointype, bool inner_unique,

259 bool skip_mark_restore);

262 Oid *collations, bool *nullsFirst);

264 int numCols, int nPresortedCols,

266 Oid *collations, bool *nullsFirst);

270 bool adjust_tlist_in_place,

271 int *p_numsortkeys,

273 Oid **p_sortOperators,

274 Oid **p_collations,

275 bool **p_nullsFirst);

279 List *pathkeys, Relids relids, int nPresortedCols);

282 Plan *lefttree);

285 Oid *collations, List *param_exprs,

286 bool singlerow, bool binary_mode,

289 int partNumCols, AttrNumber *partColIdx, Oid *partOperators, Oid *partCollations,

290 int ordNumCols, AttrNumber *ordColIdx, Oid *ordOperators, Oid *ordCollations,

291 List *runCondition, List *qual, bool topWindow,

292 Plan *lefttree);

294 AttrNumber *grpColIdx, Oid *grpOperators, Oid *grpCollations,

295 Plan *lefttree);

298 List *pathkeys, int numCols);

300 int nworkers, int rescan_param, bool single_copy, Plan *subplan);

302 List *tlist, Plan *lefttree, Plan *righttree,

303 List *groupList, long numGroups);

308 CmdType operation, bool canSetTag,

309 Index nominalRelation, Index rootRelation,

310 bool partColsUpdated,

311 List *resultRelations,

312 List *updateColnosLists,

313 List *withCheckOptionLists, List *returningLists,

315 List *mergeActionLists, List *mergeJoinConditions,

316 int epqParam);

319

320

321

322

323

324

325

326

327

328

329

330

331

332

333

334

335

338{

340

341

343

344

345 root->curOuterRels = NULL;

346 root->curOuterParams = NIL;

347

348

350

351

352

353

354

355

356

357

360

361

362

363

364

365

366

367

369

370

371 if (root->curOuterParams != NIL)

372 elog(ERROR, "failed to assign all NestLoopParams to plan nodes");

373

374

375

376

377

379

381}

382

383

384

385

386

389{

391

392

394

396 {

397 case T_SeqScan:

398 case T_SampleScan:

399 case T_IndexScan:

400 case T_IndexOnlyScan:

401 case T_BitmapHeapScan:

402 case T_TidScan:

403 case T_TidRangeScan:

404 case T_SubqueryScan:

405 case T_FunctionScan:

406 case T_TableFuncScan:

407 case T_ValuesScan:

408 case T_CteScan:

409 case T_WorkTableScan:

410 case T_NamedTuplestoreScan:

411 case T_ForeignScan:

412 case T_CustomScan:

414 break;

415 case T_HashJoin:

416 case T_MergeJoin:

417 case T_NestLoop:

420 break;

421 case T_Append:

424 flags);

425 break;

426 case T_MergeAppend:

429 flags);

430 break;

431 case T_Result:

433 {

436 flags);

437 }

439 {

442 }

444 {

447 }

448 else

449 {

450

453 }

454 break;

455 case T_ProjectSet:

458 break;

459 case T_Material:

462 flags);

463 break;

464 case T_Memoize:

467 flags);

468 break;

469 case T_Unique:

471 {

474 flags);

475 }

476 else

477 {

481 flags);

482 }

483 break;

484 case T_Gather:

487 break;

488 case T_Sort:

491 flags);

492 break;

493 case T_IncrementalSort:

496 flags);

497 break;

498 case T_Group:

501 break;

502 case T_Agg:

506 else

507 {

511 }

512 break;

513 case T_WindowAgg:

516 break;

517 case T_SetOp:

520 flags);

521 break;

522 case T_RecursiveUnion:

525 break;

526 case T_LockRows:

529 flags);

530 break;

531 case T_ModifyTable:

534 break;

535 case T_Limit:

538 flags);

539 break;

540 case T_GatherMerge:

543 break;

544 default:

545 elog(ERROR, "unrecognized node type: %d",

546 (int) best_path->pathtype);

547 plan = NULL;

548 break;

549 }

550

552}

553

554

555

556

557

560{

562 List *scan_clauses;

563 List *gating_clauses;

566

567

568

569

570

571

572

573

574

575

576

577

578

580 {

581 case T_IndexScan:

582 case T_IndexOnlyScan:

583 scan_clauses = castNode(IndexPath, best_path)->indexinfo->indrestrictinfo;

584 break;

585 default:

587 break;

588 }

589

590

591

592

593

594

595

596 if (best_path->param_info)

598 best_path->param_info->ppi_clauses);

599

600

601

602

603

604

605

606

607

608

609

611 {

612 List *join_clauses;

613

615 best_path->pathtype == T_CustomScan);

616 if (best_path->pathtype == T_ForeignScan)

617 join_clauses = ((ForeignPath *) best_path)->fdw_restrictinfo;

618 else

619 join_clauses = ((CustomPath *) best_path)->custom_restrictinfo;

620

622 }

623 else

625 if (gating_clauses)

626 flags = 0;

627

628

629

630

631

632

633

634

635

636

637

639 {

640 tlist = NULL;

641 }

643 {

644 if (best_path->pathtype == T_IndexOnlyScan)

645 {

646

648

649

650

651

652

655 }

656 else

657 {

659 if (tlist == NIL)

660 {

661

663 }

664 else

665 {

666

669 }

670 }

671 }

672 else

673 {

675 }

676

678 {

679 case T_SeqScan:

681 best_path,

682 tlist,

683 scan_clauses);

684 break;

685

686 case T_SampleScan:

688 best_path,

689 tlist,

690 scan_clauses);

691 break;

692

693 case T_IndexScan:

696 tlist,

697 scan_clauses,

698 false);

699 break;

700

701 case T_IndexOnlyScan:

704 tlist,

705 scan_clauses,

706 true);

707 break;

708

709 case T_BitmapHeapScan:

712 tlist,

713 scan_clauses);

714 break;

715

716 case T_TidScan:

719 tlist,

720 scan_clauses);

721 break;

722

723 case T_TidRangeScan:

726 tlist,

727 scan_clauses);

728 break;

729

730 case T_SubqueryScan:

733 tlist,

734 scan_clauses);

735 break;

736

737 case T_FunctionScan:

739 best_path,

740 tlist,

741 scan_clauses);

742 break;

743

744 case T_TableFuncScan:

746 best_path,

747 tlist,

748 scan_clauses);

749 break;

750

751 case T_ValuesScan:

753 best_path,

754 tlist,

755 scan_clauses);

756 break;

757

758 case T_CteScan:

760 best_path,

761 tlist,

762 scan_clauses);

763 break;

764

765 case T_NamedTuplestoreScan:

767 best_path,

768 tlist,

769 scan_clauses);

770 break;

771

772 case T_Result:

774 best_path,

775 tlist,

776 scan_clauses);

777 break;

778

779 case T_WorkTableScan:

781 best_path,

782 tlist,

783 scan_clauses);

784 break;

785

786 case T_ForeignScan:

789 tlist,

790 scan_clauses);

791 break;

792

793 case T_CustomScan:

796 tlist,

797 scan_clauses);

798 break;

799

800 default:

801 elog(ERROR, "unrecognized node type: %d",

803 plan = NULL;

804 break;

805 }

806

807

808

809

810

811

812 if (gating_clauses)

814

816}

817

818

819

820

821

822

823

826{

828 Index *sortgrouprefs = path->pathtarget->sortgrouprefs;

829 int resno = 1;

831

832 foreach(v, path->pathtarget->exprs)

833 {

836

837

838

839

840

841

842

843 if (path->param_info)

845

847 resno,

848 NULL,

849 false);

850 if (sortgrouprefs)

852

853 tlist = lappend(tlist, tle);

854 resno++;

855 }

856 return tlist;

857}

858

859

860

861

862

863

864static bool

866{

868 int i;

870

871

872

873

875 return false;

876

877

878

879

880

887 return false;

888

889

890

891

892

893

895 return false;

896

897

898

899

900

901

902

904 return false;

905

906

907

908

909

910

912 path->pathtarget->exprs == NIL)

913 return false;

914

915

916

917

918

919

921 {

923 return false;

924 }

925

926

927

928

929

930 foreach(lc, root->placeholder_list)

931 {

933

936 return false;

937 }

938

939

940

941

942

943

944 if (path->pathtype == T_IndexOnlyScan)

945 {

947

948 for (i = 0; i < indexinfo->ncolumns; i++)

949 {

950 if (!indexinfo->canreturn[i])

951 return false;

952 }

953 }

954

955

956

957

958

959

960

961

962

963

964 if ((flags & CP_LABEL_TLIST) && path->pathtarget->sortgrouprefs)

965 {

967

968 i = 0;

969 foreach(lc, path->pathtarget->exprs)

970 {

972

973 if (path->pathtarget->sortgrouprefs[i])

974 {

975 if (expr && IsA(expr, Var))

976 {

977 int attno = ((Var *) expr)->varattno;

978

981 return false;

982 sortgroupatts = bms_add_member(sortgroupatts, attno);

983 }

984 else

985 return false;

986 }

987 i++;

988 }

989 }

990

991 return true;

992}

993

994

995

996

997

998

999

1000

1001static List *

1003{

1004

1005 if (root->hasPseudoConstantQuals)

1006 return NIL;

1007

1008

1010

1011

1013}

1014

1015

1016

1017

1018

1019

1020

1021static Plan *

1023 List *gating_quals)

1024{

1025 Plan *gplan;

1026 Plan *splan;

1027

1028 Assert(gating_quals);

1029

1030

1031

1032

1033

1034

1035

1036 splan = plan;

1038 {

1040

1043 splan = NULL;

1044 }

1045

1046

1047

1048

1049

1050

1052 (Node *) gating_quals,

1053 splan);

1054

1055

1056

1057

1058

1059

1060

1061

1062

1063

1064

1065

1066

1068

1069

1071

1072 return gplan;

1073}

1074

1075

1076

1077

1078

1079

1080static Plan *

1082{

1084 List *gating_clauses;

1085

1086 switch (best_path->path.pathtype)

1087 {

1088 case T_MergeJoin:

1091 break;

1092 case T_HashJoin:

1095 break;

1096 case T_NestLoop:

1099 break;

1100 default:

1101 elog(ERROR, "unrecognized node type: %d",

1102 (int) best_path->path.pathtype);

1103 plan = NULL;

1104 break;

1105 }

1106

1107

1108

1109

1110

1111

1113 if (gating_clauses)

1115 gating_clauses);

1116

1117#ifdef NOT_USED

1118

1119

1120

1121

1122

1123

1124 if (get_loc_restrictinfo(best_path) != NIL)

1128#endif

1129

1130 return plan;

1131}

1132

1133

1134

1135

1136

1137

1138

1139static bool

1141{

1143 {

1144 case T_SubqueryScanPath:

1145 {

1147

1148

1149

1150

1151

1153 return false;

1154

1155

1156

1157

1158

1162 break;

1163 return false;

1164 }

1165 case T_ForeignPath:

1166 {

1167 FdwRoutine *fdwroutine = path->parent->fdwroutine;

1168

1169

1170

1171

1172

1174 return false;

1175

1176 Assert(fdwroutine != NULL);

1179 break;

1180 return false;

1181 }

1182 case T_ProjectionPath:

1183

1184

1185

1186

1187

1189 return false;

1190

1191

1192

1193

1194

1197 return true;

1198 return false;

1199 default:

1200 return false;

1201 }

1202

1203 plan->async_capable = true;

1204

1205 return true;

1206}

1207

1208

1209

1210

1211

1212

1213

1214

1215static Plan *

1217{

1220 int orig_tlist_length = list_length(tlist);

1221 bool tlist_was_changed = false;

1225 int nasyncplans = 0;

1227 int nodenumsortkeys = 0;

1229 Oid *nodeSortOperators = NULL;

1230 Oid *nodeCollations = NULL;

1231 bool *nodeNullsFirst = NULL;

1232 bool consider_async = false;

1233

1234

1235

1236

1237

1238

1239

1240

1241

1242

1244 {

1245

1247

1250 false)),

1251 NULL);

1252

1254

1255 return plan;

1256 }

1257

1258

1259

1260

1261

1262

1263

1264

1265

1266

1267

1268

1270 plan->plan.targetlist = tlist;

1272 plan->plan.lefttree = NULL;

1273 plan->plan.righttree = NULL;

1275

1276 if (pathkeys != NIL)

1277 {

1278

1279

1280

1281

1282

1283

1285 best_path->path.parent->relids,

1286 NULL,

1287 true,

1288 &nodenumsortkeys,

1289 &nodeSortColIdx,

1290 &nodeSortOperators,

1291 &nodeCollations,

1292 &nodeNullsFirst);

1293 tlist_was_changed = (orig_tlist_length != list_length(plan->plan.targetlist));

1294 }

1295

1296

1300

1301

1302 foreach(subpaths, best_path->subpaths)

1303 {

1305 Plan *subplan;

1306

1307

1309

1310

1311

1312

1313

1314 if (pathkeys != NIL)

1315 {

1316 int numsortkeys;

1318 Oid *sortOperators;

1319 Oid *collations;

1320 bool *nullsFirst;

1321

1322

1323

1324

1325

1326

1327

1329 subpath->parent->relids,

1330 nodeSortColIdx,

1331 false,

1332 &numsortkeys,

1333 &sortColIdx,

1334 &sortOperators,

1335 &collations,

1336 &nullsFirst);

1337

1338

1339

1340

1341

1342

1343

1344 Assert(numsortkeys == nodenumsortkeys);

1345 if (memcmp(sortColIdx, nodeSortColIdx,

1346 numsortkeys * sizeof(AttrNumber)) != 0)

1347 elog(ERROR, "Append child's targetlist doesn't match Append");

1348 Assert(memcmp(sortOperators, nodeSortOperators,

1349 numsortkeys * sizeof(Oid)) == 0);

1350 Assert(memcmp(collations, nodeCollations,

1351 numsortkeys * sizeof(Oid)) == 0);

1352 Assert(memcmp(nullsFirst, nodeNullsFirst,

1353 numsortkeys * sizeof(bool)) == 0);

1354

1355

1357 {

1359 sortColIdx, sortOperators,

1360 collations, nullsFirst);

1361

1364 }

1365 }

1366

1367

1369 {

1371 ++nasyncplans;

1372 }

1373

1374 subplans = lappend(subplans, subplan);

1375 }

1376

1377

1378 plan->part_prune_index = -1;

1379

1380

1381

1382

1383

1384

1386 {

1387 List *prunequal;

1388

1390

1391 if (best_path->path.param_info)

1392 {

1393 List *prmquals = best_path->path.param_info->ppi_clauses;

1394

1397 (Node *) prmquals);

1398

1399 prunequal = list_concat(prunequal, prmquals);

1400 }

1401

1402 if (prunequal != NIL)

1405 prunequal);

1406 }

1407

1408 plan->appendplans = subplans;

1409 plan->nasyncplans = nasyncplans;

1411

1413

1414

1415

1416

1417

1418

1420 {

1423 plan->plan.parallel_safe);

1424 }

1425 else

1427}

1428

1429

1430

1431

1432

1433

1434

1435

1436static Plan *

1438 int flags)

1439{

1443 int orig_tlist_length = list_length(tlist);

1444 bool tlist_was_changed;

1449

1450

1451

1452

1453

1454

1455

1457 plan->targetlist = tlist;

1459 plan->lefttree = NULL;

1460 plan->righttree = NULL;

1462

1463

1464

1465

1466

1467

1468

1470 best_path->path.parent->relids,

1471 NULL,

1472 true,

1474 &node->sortColIdx,

1475 &node->sortOperators,

1476 &node->collations,

1477 &node->nullsFirst);

1478 tlist_was_changed = (orig_tlist_length != list_length(plan->targetlist));

1479

1480

1481

1482

1483

1484

1485 foreach(subpaths, best_path->subpaths)

1486 {

1488 Plan *subplan;

1489 int numsortkeys;

1491 Oid *sortOperators;

1492 Oid *collations;

1493 bool *nullsFirst;

1494

1495

1496

1498

1499

1501 subpath->parent->relids,

1502 node->sortColIdx,

1503 false,

1504 &numsortkeys,

1505 &sortColIdx,

1506 &sortOperators,

1507 &collations,

1508 &nullsFirst);

1509

1510

1511

1512

1513

1514

1515

1517 if (memcmp(sortColIdx, node->sortColIdx,

1518 numsortkeys * sizeof(AttrNumber)) != 0)

1519 elog(ERROR, "MergeAppend child's targetlist doesn't match MergeAppend");

1520 Assert(memcmp(sortOperators, node->sortOperators,

1521 numsortkeys * sizeof(Oid)) == 0);

1522 Assert(memcmp(collations, node->collations,

1523 numsortkeys * sizeof(Oid)) == 0);

1524 Assert(memcmp(nullsFirst, node->nullsFirst,

1525 numsortkeys * sizeof(bool)) == 0);

1526

1527

1529 {

1531 sortColIdx, sortOperators,

1532 collations, nullsFirst);

1533

1536 }

1537

1538 subplans = lappend(subplans, subplan);

1539 }

1540

1541

1543

1544

1545

1546

1547

1548

1550 {

1551 List *prunequal;

1552

1554

1555

1556 Assert(best_path->path.param_info == NULL);

1557

1558 if (prunequal != NIL)

1561 prunequal);

1562 }

1563

1565

1566

1567

1568

1569

1570

1572 {

1575 }

1576 else

1577 return plan;

1578}

1579

1580

1581

1582

1583

1584

1585

1586

1589{

1591 List *tlist;

1592 List *quals;

1593

1595

1596

1598

1600

1602

1603 return plan;

1604}

1605

1606

1607

1608

1609

1610

1611

1614{

1616 Plan *subplan;

1617 List *tlist;

1618

1619

1621

1623

1625

1627

1628 return plan;

1629}

1630

1631

1632

1633

1634

1635

1636

1637

1640{

1642 Plan *subplan;

1643

1644

1645

1646

1647

1648

1651

1653

1655

1656 return plan;

1657}

1658

1659

1660

1661

1662

1663

1664

1665

1668{

1671 Plan *subplan;

1672 Oid *operators;

1673 Oid *collations;

1674 List *param_exprs = NIL;

1677 int nkeys;

1678 int i;

1679

1682

1685

1688 operators = palloc(nkeys * sizeof(Oid));

1689 collations = palloc(nkeys * sizeof(Oid));

1690

1691 i = 0;

1693 {

1696

1697 operators[i] = opno;

1699 i++;

1700 }

1701

1703

1704 plan = make_memoize(subplan, operators, collations, param_exprs,

1707

1709

1710 return plan;

1711}

1712

1713

1714

1715

1716

1717

1718

1719

1720static Plan *

1722{

1724 Plan *subplan;

1725 List *in_operators;

1726 List *uniq_exprs;

1727 List *newtlist;

1728 int nextresno;

1729 bool newitems;

1730 int numGroupCols;

1732 Oid *groupCollations;

1733 int groupColPos;

1735

1736

1738

1739

1741 return subplan;

1742

1743

1744

1745

1746

1747

1748

1749

1750

1751

1752

1753

1754

1755

1756

1757

1758

1761

1762

1765 newitems = false;

1766

1767 foreach(l, uniq_exprs)

1768 {

1771

1773 if (!tle)

1774 {

1776 nextresno,

1777 NULL,

1778 false);

1779 newtlist = lappend(newtlist, tle);

1780 nextresno++;

1781 newitems = true;

1782 }

1783 }

1784

1785

1789

1790

1791

1792

1793

1794

1795

1799 groupCollations = (Oid *) palloc(numGroupCols * sizeof(Oid));

1800

1801 groupColPos = 0;

1802 foreach(l, uniq_exprs)

1803 {

1806

1808 if (!tle)

1809 elog(ERROR, "failed to find unique expression in subplan tlist");

1810 groupColIdx[groupColPos] = tle->resno;

1812 groupColPos++;

1813 }

1814

1816 {

1817 Oid *groupOperators;

1818

1819

1820

1821

1822

1823

1824

1825 groupOperators = (Oid *) palloc(numGroupCols * sizeof(Oid));

1826 groupColPos = 0;

1827 foreach(l, in_operators)

1828 {

1830 Oid eq_oper;

1831

1833 elog(ERROR, "could not find compatible hash operator for operator %u",

1834 in_oper);

1835 groupOperators[groupColPos++] = eq_oper;

1836 }

1837

1838

1839

1840

1841

1842

1847 numGroupCols,

1848 groupColIdx,

1849 groupOperators,

1850 groupCollations,

1854 0,

1855 subplan);

1856 }

1857 else

1858 {

1861

1862

1863 groupColPos = 0;

1864 foreach(l, in_operators)

1865 {

1867 Oid sortop;

1868 Oid eqop;

1871

1873 if (OidIsValid(sortop))

1874 elog(ERROR, "could not find ordering operator for equality operator %u",

1875 in_oper);

1876

1877

1878

1879

1880

1881

1882

1884 if (OidIsValid(eqop))

1885 elog(ERROR, "could not find equality operator for ordering operator %u",

1886 sortop);

1887

1889 groupColIdx[groupColPos]);

1890 Assert(tle != NULL);

1891

1895 sortcl->eqop = eqop;

1896 sortcl->sortop = sortop;

1899 sortcl->hashable = false;

1900 sortList = lappend(sortList, sortcl);

1901 groupColPos++;

1902 }

1906 }

1907

1908

1910

1911 return plan;

1912}

1913

1914

1915

1916

1917

1918

1919

1922{

1923 Gather *gather_plan;

1924 Plan *subplan;

1925 List *tlist;

1926

1927

1928

1929

1930

1931

1932

1934

1936

1942 subplan);

1943

1945

1946

1947 root->glob->parallelModeNeeded = true;

1948

1949 return gather_plan;

1950}

1951

1952

1953

1954

1955

1956

1957

1960{

1962 Plan *subplan;

1965

1966

1968

1969

1974

1975

1977

1978

1980

1981

1983 best_path->subpath->parent->relids,

1984 gm_plan->sortColIdx,

1985 false,

1987 &gm_plan->sortColIdx,

1988 &gm_plan->sortOperators,

1989 &gm_plan->collations,

1990 &gm_plan->nullsFirst);

1991

1992

1993

1994

1995

1997

1998

2000

2001

2002 root->glob->parallelModeNeeded = true;

2003

2004 return gm_plan;

2005}

2006

2007

2008

2009

2010

2011

2012

2013

2014static Plan *

2016{

2018 Plan *subplan;

2019 List *tlist;

2020 bool needs_result_node = false;

2021

2022

2023

2024

2025

2026

2027

2028

2029

2030

2031

2032

2033

2034

2036 {

2037

2038

2039

2040

2041

2046 best_path->path.pathtarget);

2047 }

2049 {

2050

2051

2052

2053

2054

2055

2060 }

2061 else

2062 {

2063

2064

2065

2066

2070 }

2071

2072

2073

2074

2075

2076

2077

2078

2079

2080 if (!needs_result_node)

2081 {

2082

2083 plan = subplan;

2084 plan->targetlist = tlist;

2085

2086

2090 plan->plan_width = best_path->path.pathtarget->width;

2092

2093 }

2094 else

2095 {

2096

2098

2100 }

2101

2102 return plan;

2103}

2104

2105

2106

2107

2108

2109

2110

2111

2112

2113

2114

2115

2116static Plan *

2118{

2120

2122

2123

2124

2125

2126

2127

2128

2129

2131 plan->parallel_safe = parallel_safe;

2132

2133 return plan;

2134}

2135

2136

2137

2138

2139

2140

2141

2142

2143

2144

2145

2146

2147

2150{

2151

2152

2153

2154

2155

2160 tlist_parallel_safe);

2161 else

2162 {

2163

2166 }

2167 return subplan;

2168}

2169

2170

2171

2172

2173

2174

2175

2176static Sort *

2178{

2180 Plan *subplan;

2181

2182

2183

2184

2185

2186

2189

2190

2191

2192

2193

2194

2195

2198 best_path->path.parent->relids : NULL);

2199

2201

2202 return plan;

2203}

2204

2205

2206

2207

2208

2209

2212 int flags)

2213{

2215 Plan *subplan;

2216

2217

2223 best_path->spath.path.parent->relids : NULL,

2225

2227

2228 return plan;

2229}

2230

2231

2232

2233

2234

2235

2236

2239{

2241 Plan *subplan;

2242 List *tlist;

2243 List *quals;

2244

2245

2246

2247

2248

2250

2252

2254

2256 quals,

2263 subplan);

2264

2266

2267 return plan;

2268}

2269

2270

2271

2272

2273

2274

2275

2278{

2280 Plan *subplan;

2281

2282

2283

2284

2285

2288

2292

2294

2295 return plan;

2296}

2297

2298

2299

2300

2301

2302

2303

2304static Agg *

2306{

2308 Plan *subplan;

2309 List *tlist;

2310 List *quals;

2311

2312

2313

2314

2315

2317

2319

2321

2335 subplan);

2336

2338

2339 return plan;

2340}

2341

2342

2343

2344

2345

2346

2347

2348

2349

2352{

2356 int i;

2357

2358 Assert(grouping_map);

2359

2361

2362 i = 0;

2363 foreach(lc, groupClause)

2364 {

2366

2368 }

2369

2370 return new_grpColIdx;

2371}

2372

2373

2374

2375

2376

2377

2378

2379

2380

2381

2382

2383

2384

2385

2386

2387

2388static Plan *

2390{

2392 Plan *subplan;

2395 int maxref;

2396 List *chain;

2398

2399

2402

2403

2404

2405

2406

2408

2409

2410

2411

2412

2413

2414 maxref = 0;

2415 foreach(lc, root->processed_groupClause)

2416 {

2418

2421 }

2422

2424

2425

2426 foreach(lc, root->processed_groupClause)

2427 {

2430

2432 }

2433

2434

2435

2436

2437

2439 root->grouping_map = grouping_map;

2440

2441

2442

2443

2444

2445

2446

2447 chain = NIL;

2449 {

2451

2453 {

2456 Plan *sort_plan = NULL;

2457 Plan *agg_plan;

2459

2461

2462 if (!rollup->is_hashed && !is_first_sort)

2463 {

2464 sort_plan = (Plan *)

2466 new_grpColIdx,

2467 subplan);

2468 }

2469

2471 is_first_sort = false;

2472

2477 else

2479

2482 strat,

2485 new_grpColIdx,

2492 sort_plan);

2493

2494

2495

2496

2497 if (sort_plan)

2498 {

2501 }

2502

2503 chain = lappend(chain, agg_plan);

2504 }

2505 }

2506

2507

2508

2509

2510 {

2513 int numGroupCols;

2514

2516

2518

2520 best_path->qual,

2523 numGroupCols,

2524 top_grpColIdx,

2528 chain,

2531 subplan);

2532

2533

2535 }

2536

2538}

2539

2540

2541

2542

2543

2544

2545

2548{

2550 List *tlist;

2552

2553

2555 {

2560

2561

2562

2563

2564

2565

2566

2568

2573 0, NULL, NULL, NULL);

2574

2575

2579 plan->plan_rows = 1;

2580 plan->plan_width = mminfo->path->pathtarget->width;

2581 plan->parallel_aware = false;

2583

2584

2586 }

2587

2588

2590

2592

2594

2595

2596

2597

2598

2599

2600

2603

2604 return plan;

2605}

2606

2607

2608

2609

2610

2611

2612

2615{

2620 Plan *subplan;

2621 List *tlist;

2622 int partNumCols;

2624 Oid *partOperators;

2625 Oid *partCollations;

2626 int ordNumCols;

2628 Oid *ordOperators;

2629 Oid *ordCollations;

2631

2632

2633

2634

2635

2636

2637

2640

2642

2643

2644

2645

2646

2648 partOperators = (Oid *) palloc(sizeof(Oid) * numPart);

2649 partCollations = (Oid *) palloc(sizeof(Oid) * numPart);

2650

2651 partNumCols = 0;

2653 {

2656

2658 partColIdx[partNumCols] = tle->resno;

2659 partOperators[partNumCols] = sgc->eqop;

2661 partNumCols++;

2662 }

2663

2665 ordOperators = (Oid *) palloc(sizeof(Oid) * numOrder);

2666 ordCollations = (Oid *) palloc(sizeof(Oid) * numOrder);

2667

2668 ordNumCols = 0;

2670 {

2673

2675 ordColIdx[ordNumCols] = tle->resno;

2676 ordOperators[ordNumCols] = sgc->eqop;

2678 ordNumCols++;

2679 }

2680

2681

2683 wc,

2684 partNumCols,

2685 partColIdx,

2686 partOperators,

2687 partCollations,

2688 ordNumCols,

2689 ordColIdx,

2690 ordOperators,

2691 ordCollations,

2693 best_path->qual,

2695 subplan);

2696

2698

2699 return plan;

2700}

2701

2702

2703

2704

2705

2706

2707

2710{

2713 Plan *leftplan;

2714 Plan *rightplan;

2715 long numGroups;

2716

2717

2718

2719

2720

2725

2726

2728

2731 tlist,

2732 leftplan,

2733 rightplan,

2735 numGroups);

2736

2738

2739 return plan;

2740}

2741

2742

2743

2744

2745

2746

2747

2750{

2752 Plan *leftplan;

2753 Plan *rightplan;

2754 List *tlist;

2755 long numGroups;

2756

2757

2760

2762

2763

2765

2767 leftplan,

2768 rightplan,

2771 numGroups);

2772

2774

2775 return plan;

2776}

2777

2778

2779

2780

2781

2782

2783

2786 int flags)

2787{

2789 Plan *subplan;

2790

2791

2793

2795

2797

2798 return plan;

2799}

2800

2801

2802

2803

2804

2805

2806

2809{

2812 Plan *subplan;

2813

2814

2816

2817

2819

2821 subplan,

2836

2838

2839 return plan;

2840}

2841

2842

2843

2844

2845

2846

2847

2850{

2852 Plan *subplan;

2853 int numUniqkeys = 0;

2855 Oid *uniqOperators = NULL;

2856 Oid *uniqCollations = NULL;

2857

2858

2860

2861

2863 {

2866

2869 uniqOperators = (Oid *) palloc(numUniqkeys * sizeof(Oid));

2870 uniqCollations = (Oid *) palloc(numUniqkeys * sizeof(Oid));

2871

2872 numUniqkeys = 0;

2873 foreach(l, parse->sortClause)

2874 {

2877

2878 uniqColIdx[numUniqkeys] = tle->resno;

2879 uniqOperators[numUniqkeys] = sortcl->eqop;

2881 numUniqkeys++;

2882 }

2883 }

2884

2889 numUniqkeys, uniqColIdx, uniqOperators, uniqCollations);

2890

2892

2893 return plan;

2894}

2895

2896

2897

2898

2899

2900

2901

2902

2903

2904

2905

2906

2907

2908

2911 List *tlist, List *scan_clauses)

2912{

2914 Index scan_relid = best_path->parent->relid;

2915

2916

2917 Assert(scan_relid > 0);

2919

2920

2922

2923

2925

2926

2927 if (best_path->param_info)

2928 {

2929 scan_clauses = (List *)

2931 }

2932

2934 scan_clauses,

2935 scan_relid);

2936

2938

2939 return scan_plan;

2940}

2941

2942

2943

2944

2945

2946

2949 List *tlist, List *scan_clauses)

2950{

2952 Index scan_relid = best_path->parent->relid;

2955

2956

2957 Assert(scan_relid > 0);

2961 Assert(tsc != NULL);

2962

2963

2965

2966

2968

2969

2970 if (best_path->param_info)

2971 {

2972 scan_clauses = (List *)

2976 }

2977

2979 scan_clauses,

2980 scan_relid,

2981 tsc);

2982

2984

2985 return scan_plan;

2986}

2987

2988

2989

2990

2991

2992

2993

2994

2995

2996

2997

2998static Scan *

3001 List *tlist,

3002 List *scan_clauses,

3003 bool indexonly)

3004{

3005 Scan *scan_plan;

3008 Index baserelid = best_path->path.parent->relid;

3011 List *qpqual;

3012 List *stripped_indexquals;

3013 List *fixed_indexquals;

3014 List *fixed_indexorderbys;

3015 List *indexorderbyops = NIL;

3017

3018

3019 Assert(baserelid > 0);

3021

3024

3025

3026

3027

3028

3029

3030

3032 &stripped_indexquals,

3033 &fixed_indexquals);

3034

3035

3036

3037

3039

3040

3041

3042

3043

3044

3045

3046

3047

3048

3049

3050

3051

3052

3053

3054

3055

3056

3057

3058

3059

3060

3061

3062

3063

3064

3065

3066

3067

3068 qpqual = NIL;

3069 foreach(l, scan_clauses)

3070 {

3072

3073 if (rinfo->pseudoconstant)

3074 continue;

3076 continue;

3079 false))

3080 continue;

3081 qpqual = lappend(qpqual, rinfo);

3082 }

3083

3084

3086

3087

3089

3090

3091

3092

3093

3094

3095

3096

3097

3098

3099 if (best_path->path.param_info)

3100 {

3101 stripped_indexquals = (List *)

3103 qpqual = (List *)

3105 indexorderbys = (List *)

3107 }

3108

3109

3110

3111

3112

3113 if (indexorderbys)

3114 {

3116 *exprCell;

3117

3118

3119

3120

3121

3122

3125 {

3129 Oid sortop;

3130

3131

3133 exprtype,

3134 exprtype,

3137 elog(ERROR, "missing operator %d(%u,%u) in opfamily %u",

3139 indexorderbyops = lappend_oid(indexorderbyops, sortop);

3140 }

3141 }

3142

3143

3144

3145

3146

3147

3148 if (indexonly)

3149 {

3150 int i = 0;

3151

3153 {

3155

3156 indextle->resjunk = !indexinfo->canreturn[i];

3157 i++;

3158 }

3159 }

3160

3161

3162 if (indexonly)

3164 qpqual,

3165 baserelid,

3166 indexoid,

3167 fixed_indexquals,

3168 stripped_indexquals,

3169 fixed_indexorderbys,

3172 else

3174 qpqual,

3175 baserelid,

3176 indexoid,

3177 fixed_indexquals,

3178 stripped_indexquals,

3179 fixed_indexorderbys,

3180 indexorderbys,

3181 indexorderbyops,

3183

3185

3186 return scan_plan;

3187}

3188

3189

3190

3191

3192

3193

3197 List *tlist,

3198 List *scan_clauses)

3199{

3200 Index baserelid = best_path->path.parent->relid;

3201 Plan *bitmapqualplan;

3202 List *bitmapqualorig;

3203 List *indexquals;

3204 List *indexECs;

3205 List *qpqual;

3208

3209

3210 Assert(baserelid > 0);

3212

3213

3215 &bitmapqualorig, &indexquals,

3216 &indexECs);

3217

3220

3221

3222

3223

3224

3225

3226

3227

3228

3229

3230

3231

3232

3233

3234

3235

3236

3237

3238

3239

3240

3241

3242

3243

3244

3245

3246

3247 qpqual = NIL;

3248 foreach(l, scan_clauses)

3249 {

3252

3253 if (rinfo->pseudoconstant)

3254 continue;

3256 continue;

3257 if (rinfo->parent_ec && list_member_ptr(indexECs, rinfo->parent_ec))

3258 continue;

3261 continue;

3262 qpqual = lappend(qpqual, rinfo);

3263 }

3264

3265

3267

3268

3270

3271

3272

3273

3274

3275

3276

3278

3279

3280

3281

3282

3283

3284 if (best_path->path.param_info)

3285 {

3286 qpqual = (List *)

3288 bitmapqualorig = (List *)

3290 }

3291

3292

3294 qpqual,

3295 bitmapqualplan,

3296 bitmapqualorig,

3297 baserelid);

3298

3300

3301 return scan_plan;

3302}

3303

3304

3305

3306

3307

3308

3309

3310

3311

3312

3313

3314

3315

3316

3317

3318

3319

3320

3321

3322

3323

3324static Plan *

3326 List **qual, List **indexqual, List **indexECs)

3327{

3329

3331 {

3335 List *subindexquals = NIL;

3336 List *subindexECs = NIL;

3338

3339

3340

3341

3342

3343

3344

3345

3347 {

3348 Plan *subplan;

3349 List *subqual;

3350 List *subindexqual;

3351 List *subindexEC;

3352

3354 &subqual, &subindexqual,

3355 &subindexEC);

3356 subplans = lappend(subplans, subplan);

3359

3360 subindexECs = list_concat(subindexECs, subindexEC);

3361 }

3365 plan->plan_rows =

3367 plan->plan_width = 0;

3368 plan->parallel_aware = false;

3370 *qual = subquals;

3371 *indexqual = subindexquals;

3372 *indexECs = subindexECs;

3373 }

3375 {

3379 List *subindexquals = NIL;

3380 bool const_true_subqual = false;

3381 bool const_true_subindexqual = false;

3383

3384

3385

3386

3387

3388

3389

3390

3391

3392

3394 {

3395 Plan *subplan;

3396 List *subqual;

3397 List *subindexqual;

3398 List *subindexEC;

3399

3401 &subqual, &subindexqual,

3402 &subindexEC);

3403 subplans = lappend(subplans, subplan);

3404 if (subqual == NIL)

3405 const_true_subqual = true;

3406 else if (!const_true_subqual)

3407 subquals = lappend(subquals,

3409 if (subindexqual == NIL)

3410 const_true_subindexqual = true;

3411 else if (!const_true_subindexqual)

3412 subindexquals = lappend(subindexquals,

3414 }

3415

3416

3417

3418

3419

3421 {

3423 }

3424 else

3425 {

3429 plan->plan_rows =

3431 plan->plan_width = 0;

3432 plan->parallel_aware = false;

3434 }

3435

3436

3437

3438

3439

3440

3441 if (const_true_subqual)

3442 *qual = NIL;

3444 *qual = subquals;

3445 else

3447 if (const_true_subindexqual)

3448 *indexqual = NIL;

3449 else if (list_length(subindexquals) <= 1)

3450 *indexqual = subindexquals;

3451 else

3453 *indexECs = NIL;

3454 }

3456 {

3459 List *subquals;

3460 List *subindexquals;

3461 List *subindexECs;

3463

3464

3468

3473

3474 plan->startup_cost = 0.0;

3476 plan->plan_rows =

3478 plan->plan_width = 0;

3479 plan->parallel_aware = false;

3481

3482 subquals = NIL;

3483 subindexquals = NIL;

3484 subindexECs = NIL;

3486 {

3489

3490 Assert(!rinfo->pseudoconstant);

3492 subindexquals = list_concat(subindexquals,

3494 if (rinfo->parent_ec)

3495 subindexECs = lappend(subindexECs, rinfo->parent_ec);

3496 }

3497

3499 {

3501

3502

3503

3504

3505

3506

3507

3509 {

3510 subquals = lappend(subquals, pred);

3511 subindexquals = lappend(subindexquals, pred);

3512 }

3513 }

3514 *qual = subquals;

3515 *indexqual = subindexquals;

3516 *indexECs = subindexECs;

3517 }

3518 else

3519 {

3520 elog(ERROR, "unrecognized node type: %d", nodeTag(bitmapqual));

3521 plan = NULL;

3522 }

3523

3524 return plan;

3525}

3526

3527

3528

3529

3530

3531

3534 List *tlist, List *scan_clauses)

3535{

3537 Index scan_relid = best_path->path.parent->relid;

3539

3540

3541 Assert(scan_relid > 0);

3543

3544

3545

3546

3547

3548

3549

3550

3551

3552

3553

3554

3555

3556

3557

3558

3559

3560

3561

3562

3564 {

3567

3568 foreach(l, scan_clauses)

3569 {

3571

3572 if (rinfo->pseudoconstant)

3573 continue;

3575 continue;

3577 continue;

3578 qpqual = lappend(qpqual, rinfo);

3579 }

3580 scan_clauses = qpqual;

3581 }

3582

3583

3585

3586

3589

3590

3591

3592

3593

3594

3595

3596

3597

3598

3599

3600

3604

3605

3606 if (best_path->path.param_info)

3607 {

3608 tidquals = (List *)

3610 scan_clauses = (List *)

3612 }

3613

3615 scan_clauses,

3616 scan_relid,

3617 tidquals);

3618

3620

3621 return scan_plan;

3622}

3623

3624

3625

3626

3627

3628

3631 List *tlist, List *scan_clauses)

3632{

3634 Index scan_relid = best_path->path.parent->relid;

3636

3637

3638 Assert(scan_relid > 0);

3640

3641

3642

3643

3644

3645

3646 {

3649

3650 foreach(l, scan_clauses)

3651 {

3653

3654 if (rinfo->pseudoconstant)

3655 continue;

3657 continue;

3658 qpqual = lappend(qpqual, rinfo);

3659 }

3660 scan_clauses = qpqual;

3661 }

3662

3663

3665

3666

3669

3670

3671 if (best_path->path.param_info)

3672 {

3673 tidrangequals = (List *)

3675 scan_clauses = (List *)

3677 }

3678

3680 scan_clauses,

3681 scan_relid,

3682 tidrangequals);

3683

3685

3686 return scan_plan;

3687}

3688

3689

3690

3691

3692

3693

3696 List *tlist, List *scan_clauses)

3697{

3701 Plan *subplan;

3702

3703

3704 Assert(scan_relid > 0);

3706

3707

3708

3709

3710

3711

3713

3714

3716

3717

3719

3720

3721

3722

3723

3724

3725

3726

3727

3728

3729

3730 if (best_path->path.param_info)

3731 {

3734 scan_clauses = (List *)

3736 }

3737

3739 scan_clauses,

3740 scan_relid,

3741 subplan);

3742

3744

3745 return scan_plan;

3746}

3747

3748

3749

3750

3751

3752

3755 List *tlist, List *scan_clauses)

3756{

3758 Index scan_relid = best_path->parent->relid;

3761

3762

3763 Assert(scan_relid > 0);

3767

3768

3770

3771

3773

3774

3775 if (best_path->param_info)

3776 {

3777 scan_clauses = (List *)

3779

3781 }

3782

3785

3787

3788 return scan_plan;

3789}

3790

3791

3792

3793

3794

3795

3798 List *tlist, List *scan_clauses)

3799{

3801 Index scan_relid = best_path->parent->relid;

3804

3805

3806 Assert(scan_relid > 0);

3810

3811

3813

3814

3816

3817

3818 if (best_path->param_info)

3819 {

3820 scan_clauses = (List *)

3822

3824 }

3825

3827 tablefunc);

3828

3830

3831 return scan_plan;

3832}

3833

3834

3835

3836

3837

3838

3841 List *tlist, List *scan_clauses)

3842{

3844 Index scan_relid = best_path->parent->relid;

3846 List *values_lists;

3847

3848

3849 Assert(scan_relid > 0);

3853

3854

3856

3857

3859

3860

3861 if (best_path->param_info)

3862 {

3863 scan_clauses = (List *)

3865

3866 values_lists = (List *)

3868 }

3869

3870 scan_plan = make_valuesscan(tlist, scan_clauses, scan_relid,

3871 values_lists);

3872

3874

3875 return scan_plan;

3876}

3877

3878

3879

3880

3881

3882

3885 List *tlist, List *scan_clauses)

3886{

3888 Index scan_relid = best_path->parent->relid;

3890 SubPlan *ctesplan = NULL;

3891 int plan_id;

3892 int cte_param_id;

3895 int ndx;

3897

3898 Assert(scan_relid > 0);

3901 Assert(!rte->self_reference);

3902

3903

3904

3905

3907 cteroot = root;

3908 while (levelsup-- > 0)

3909 {

3910 cteroot = cteroot->parent_root;

3911 if (!cteroot)

3913 }

3914

3915

3916

3917

3918

3919

3920 ndx = 0;

3922 {

3924

3926 break;

3927 ndx++;

3928 }

3929 if (lc == NULL)

3932 elog(ERROR, "could not find plan for CTE \"%s\"", rte->ctename);

3934 if (plan_id <= 0)

3935 elog(ERROR, "no plan was made for CTE \"%s\"", rte->ctename);

3937 {

3939 if (ctesplan->plan_id == plan_id)

3940 break;

3941 }

3942 if (lc == NULL)

3943 elog(ERROR, "could not find plan for CTE \"%s\"", rte->ctename);

3944

3945

3946

3947

3948

3950

3951

3953

3954

3956

3957

3958 if (best_path->param_info)

3959 {

3960 scan_clauses = (List *)

3962 }

3963

3964 scan_plan = make_ctescan(tlist, scan_clauses, scan_relid,

3965 plan_id, cte_param_id);

3966

3968

3969 return scan_plan;

3970}

3971

3972

3973

3974

3975

3976

3977

3980 List *tlist, List *scan_clauses)

3981{

3983 Index scan_relid = best_path->parent->relid;

3985

3986 Assert(scan_relid > 0);

3989

3990

3992

3993

3995

3996

3997 if (best_path->param_info)

3998 {

3999 scan_clauses = (List *)

4001 }

4002

4005

4007

4008 return scan_plan;

4009}

4010

4011

4012

4013

4014

4015

4016

4019 List *tlist, List *scan_clauses)

4020{

4022 Index scan_relid = best_path->parent->relid;

4024

4025 Assert(scan_relid > 0);

4028

4029

4031

4032

4034

4035

4036 if (best_path->param_info)

4037 {

4038 scan_clauses = (List *)

4040 }

4041

4042 scan_plan = make_result(tlist, (Node *) scan_clauses, NULL);

4043

4045

4046 return scan_plan;

4047}

4048

4049

4050

4051

4052

4053

4056 List *tlist, List *scan_clauses)

4057{

4059 Index scan_relid = best_path->parent->relid;

4063

4064 Assert(scan_relid > 0);

4067 Assert(rte->self_reference);

4068

4069

4070

4071

4072

4073

4075 if (levelsup == 0)

4077 levelsup--;

4078 cteroot = root;

4079 while (levelsup-- > 0)

4080 {

4081 cteroot = cteroot->parent_root;

4082 if (!cteroot)

4084 }

4085 if (cteroot->wt_param_id < 0)

4086 elog(ERROR, "could not find param ID for CTE \"%s\"", rte->ctename);

4087

4088

4090

4091

4093

4094

4095 if (best_path->param_info)

4096 {

4097 scan_clauses = (List *)

4099 }

4100

4103

4105

4106 return scan_plan;

4107}

4108

4109

4110

4111

4112

4113

4116 List *tlist, List *scan_clauses)

4117{

4122 Plan *outer_plan = NULL;

4123

4124 Assert(rel->fdwroutine != NULL);

4125

4126

4130

4131

4132

4133

4134

4135 if (scan_relid > 0)

4136 {

4138

4142 rel_oid = rte->relid;

4143 }

4144

4145

4146

4147

4148

4150

4151

4152

4153

4154

4155

4156

4157

4158 scan_plan = rel->fdwroutine->GetForeignPlan(root, rel, rel_oid,

4159 best_path,

4160 tlist, scan_clauses,

4161 outer_plan);

4162

4163

4165

4166

4168

4169

4171

4172

4173

4174

4175

4176

4179 else

4180 scan_plan->fs_relids = best_path->path.parent->relids;

4181

4182

4183

4184

4185

4186

4188 root->outer_join_rels);

4189

4190

4191

4192

4193

4194

4196 root->glob->dependsOnRole = true;

4197

4198

4199

4200

4201

4202

4203

4204

4205

4206 if (best_path->path.param_info)

4207 {

4208 scan_plan->scan.plan.qual = (List *)

4215 }

4216

4217

4218

4219

4220

4221

4222

4223

4224

4225

4227 if (scan_relid > 0)

4228 {

4231 int i;

4232

4233

4234

4235

4236

4237

4239

4240

4242 {

4244

4246 }

4247

4248

4250 {

4252 {

4254 break;

4255 }

4256 }

4257

4259 }

4260

4261 return scan_plan;

4262}

4263

4264

4265

4266

4267

4268

4271 List *tlist, List *scan_clauses)

4272{

4275 List *custom_plans = NIL;

4277

4278

4280 {

4283

4284 custom_plans = lappend(custom_plans, plan);

4285 }

4286

4287

4288

4289

4290

4292

4293

4294

4295

4296

4299 rel,

4300 best_path,

4301 tlist,

4302 scan_clauses,

4303 custom_plans));

4304

4305

4306

4307

4308

4310

4311

4313

4314

4315

4316

4317

4318

4319

4320

4321

4322 if (best_path->path.param_info)

4323 {

4324 cplan->scan.plan.qual = (List *)

4328 }

4329

4330 return cplan;

4331}

4332

4333

4334

4335

4336

4337

4338

4339

4343{

4345 Plan *outer_plan;

4346 Plan *inner_plan;

4349 List *joinclauses;

4350 List *otherclauses;

4352 List *nestParams;

4353 Relids saveOuterRels = root->curOuterRels;

4354

4355

4356

4357

4358

4359

4364

4365

4366

4367

4368

4370

4371

4373

4374

4377

4379

4380

4382 root->curOuterRels = saveOuterRels;

4383

4384

4386

4387

4388

4390 {

4392 best_path->jpath.path.parent->relids,

4393 &joinclauses, &otherclauses);

4394 }

4395 else

4396 {

4397

4399 otherclauses = NIL;

4400 }

4401

4402

4403 if (best_path->jpath.path.param_info)

4404 {

4405 joinclauses = (List *)

4407 otherclauses = (List *)

4409 }

4410

4411

4412

4413

4414

4417

4419 joinclauses,

4420 otherclauses,

4421 nestParams,

4422 outer_plan,

4423 inner_plan,

4426

4428

4429 return join_plan;

4430}

4431

4435{

4437 Plan *outer_plan;

4438 Plan *inner_plan;

4440 List *joinclauses;

4441 List *otherclauses;

4442 List *mergeclauses;

4443 List *outerpathkeys;

4444 List *innerpathkeys;

4445 int nClauses;

4446 Oid *mergefamilies;

4447 Oid *mergecollations;

4448 bool *mergereversals;

4449 bool *mergenullsfirst;

4452 int i;

4458

4459

4460

4461

4462

4463

4464

4467

4470

4471

4472

4474

4475

4476

4478 {

4480 best_path->jpath.path.parent->relids,

4481 &joinclauses, &otherclauses);

4482 }

4483 else

4484 {

4485

4487 otherclauses = NIL;

4488 }

4489

4490

4491

4492

4493

4495 joinclauses = list_difference(joinclauses, mergeclauses);

4496

4497

4498

4499

4500

4501 if (best_path->jpath.path.param_info)

4502 {

4503 joinclauses = (List *)

4505 otherclauses = (List *)

4507 }

4508

4509

4510

4511

4512

4513

4516

4517

4518

4519

4521 {

4522 Relids outer_relids = outer_path->parent->relids;

4523 Plan *sort_plan;

4524

4525

4526

4527

4528

4529

4532

4533

4534

4535

4536

4538 {

4539 sort_plan = (Plan *)

4542 outer_relids,

4544

4548 -1.0);

4549 }

4550 else

4551 {

4552 sort_plan = (Plan *)

4555 outer_relids);

4556

4558 }

4559

4560 outer_plan = sort_plan;

4562 }

4563 else

4565

4567 {

4568

4569

4570

4571

4572

4573 Relids inner_relids = inner_path->parent->relids;

4575

4576

4577

4578

4579

4580

4583

4586 inner_relids);

4587

4591 }

4592 else

4594

4595

4596

4597

4598

4600 {

4602

4603

4604

4605

4606

4607

4610

4611 inner_plan = matplan;

4612 }

4613

4614

4615

4616

4617

4618

4619

4620

4623 mergefamilies = (Oid *) palloc(nClauses * sizeof(Oid));

4624 mergecollations = (Oid *) palloc(nClauses * sizeof(Oid));

4625 mergereversals = (bool *) palloc(nClauses * sizeof(bool));

4626 mergenullsfirst = (bool *) palloc(nClauses * sizeof(bool));

4627

4628 opathkey = NULL;

4629 opeclass = NULL;

4632 i = 0;

4634 {

4638 PathKey *ipathkey = NULL;

4640 bool first_inner_match = false;

4641

4642

4643 if (rinfo->outer_is_left)

4644 {

4645 oeclass = rinfo->left_ec;

4646 ieclass = rinfo->right_ec;

4647 }

4648 else

4649 {

4650 oeclass = rinfo->right_ec;

4651 ieclass = rinfo->left_ec;

4652 }

4653 Assert(oeclass != NULL);

4654 Assert(ieclass != NULL);

4655

4656

4657

4658

4659

4660

4661

4662

4663

4664

4665

4666

4667

4668

4669

4670

4671 if (oeclass != opeclass)

4672 {

4673

4674 if (lop == NULL)

4675 elog(ERROR, "outer pathkeys do not match mergeclauses");

4677 opeclass = opathkey->pk_eclass;

4678 lop = lnext(outerpathkeys, lop);

4679 if (oeclass != opeclass)

4680 elog(ERROR, "outer pathkeys do not match mergeclauses");

4681 }

4682

4683

4684

4685

4686

4687

4688

4689

4690

4691

4692

4693

4694

4695

4696

4697

4698 if (lip)

4699 {

4701 ipeclass = ipathkey->pk_eclass;

4702 if (ieclass == ipeclass)

4703 {

4704

4705 lip = lnext(innerpathkeys, lip);

4706 first_inner_match = true;

4707 }

4708 }

4709 if (!first_inner_match)

4710 {

4711

4713

4714 foreach(l2, innerpathkeys)

4715 {

4716 if (l2 == lip)

4717 break;

4719 ipeclass = ipathkey->pk_eclass;

4720 if (ieclass == ipeclass)

4721 break;

4722 }

4723 if (ieclass != ipeclass)

4724 elog(ERROR, "inner pathkeys do not match mergeclauses");

4725 }

4726

4727

4728

4729

4730

4731

4732

4733

4734

4735

4736

4737

4738

4739

4740

4742 opathkey->pk_eclass->ec_collation != ipathkey->pk_eclass->ec_collation)

4743 elog(ERROR, "left and right pathkeys do not match in mergejoin");

4744 if (first_inner_match &&

4747 elog(ERROR, "left and right pathkeys do not match in mergejoin");

4748

4749

4751 mergecollations[i] = opathkey->pk_eclass->ec_collation;

4754 i++;

4755 }

4756

4757

4758

4759

4760

4761

4762

4763

4764

4765

4767 joinclauses,

4768 otherclauses,

4769 mergeclauses,

4770 mergefamilies,

4771 mergecollations,

4772 mergereversals,

4773 mergenullsfirst,

4774 outer_plan,

4775 inner_plan,

4779

4780

4782

4783 return join_plan;

4784}

4785

4789{

4791 Hash *hash_plan;

4792 Plan *outer_plan;

4793 Plan *inner_plan;

4795 List *joinclauses;

4796 List *otherclauses;

4797 List *hashclauses;

4798 List *hashoperators = NIL;

4799 List *hashcollations = NIL;

4800 List *inner_hashkeys = NIL;

4801 List *outer_hashkeys = NIL;

4804 bool skewInherit = false;

4806

4807

4808

4809

4810

4811

4812

4813

4816

4819

4820

4822

4823

4824

4825

4827 {

4829 best_path->jpath.path.parent->relids,

4830 &joinclauses, &otherclauses);

4831 }

4832 else

4833 {

4834

4836 otherclauses = NIL;

4837 }

4838

4839

4840

4841

4842

4844 joinclauses = list_difference(joinclauses, hashclauses);

4845

4846

4847

4848

4849

4850 if (best_path->jpath.path.param_info)

4851 {

4852 joinclauses = (List *)

4854 otherclauses = (List *)

4856 }

4857

4858

4859

4860

4861

4864

4865

4866

4867

4868

4869

4870

4871

4872

4874 {

4877

4883 {

4884 Var *var = (Var *) node;

4886

4887 rte = root->simple_rte_array[var->varno];

4889 {

4890 skewTable = rte->relid;

4892 skewInherit = rte->inh;

4893 }

4894 }

4895 }

4896

4897

4898

4899

4900

4901

4902

4903

4904

4905 foreach(lc, hashclauses)

4906 {

4908

4909 hashoperators = lappend_oid(hashoperators, hclause->opno);

4910 hashcollations = lappend_oid(hashcollations, hclause->inputcollid);

4913 }

4914

4915

4916

4917

4918 hash_plan = make_hash(inner_plan,

4919 inner_hashkeys,

4920 skewTable,

4921 skewColumn,

4922 skewInherit);

4923

4924

4925

4926

4927

4930

4931

4932

4933

4934

4935

4936 if (best_path->jpath.path.parallel_aware)

4937 {

4940 }

4941

4943 joinclauses,

4944 otherclauses,

4945 hashclauses,

4946 hashoperators,

4947 hashcollations,

4948 outer_hashkeys,

4949 outer_plan,

4950 (Plan *) hash_plan,

4953

4955

4956 return join_plan;

4957}

4958

4959

4960

4961

4962

4963

4964

4965

4966

4967

4968

4969

4970

4971

4972

4973

4974

4975static Node *

4977{

4978

4980}

4981

4982static Node *

4984{

4985 if (node == NULL)

4986 return NULL;

4988 {

4989 Var *var = (Var *) node;

4990

4991

4993

4996 return node;

4997

4999 }

5001 {

5003

5004

5006

5007

5009 root->curOuterRels))

5010 {

5011

5012

5013

5014

5015

5016

5017

5018

5019

5020

5021

5022

5023

5024

5025

5027

5029 newphv->phexpr = (Expr *)

5032 return (Node *) newphv;

5033 }

5034

5036 }

5038}

5039

5040

5041

5042

5043

5044

5045

5046

5047

5048

5049

5050

5051

5052

5053

5054

5055

5056

5057

5058

5059

5060static void

5062 List **stripped_indexquals_p, List **fixed_indexquals_p)

5063{

5065 List *stripped_indexquals;

5066 List *fixed_indexquals;

5068

5069 stripped_indexquals = fixed_indexquals = NIL;

5070

5072 {

5074 int indexcol = iclause->indexcol;

5076

5078 {

5081

5082 stripped_indexquals = lappend(stripped_indexquals, clause);

5085 fixed_indexquals = lappend(fixed_indexquals, clause);

5086 }

5087 }

5088

5089 *stripped_indexquals_p = stripped_indexquals;

5090 *fixed_indexquals_p = fixed_indexquals;

5091}

5092

5093

5094

5095

5096

5097

5098

5099

5100

5101static List *

5103{

5105 List *fixed_indexorderbys;

5107 *lci;

5108

5109 fixed_indexorderbys = NIL;

5110

5112 {

5115

5117 fixed_indexorderbys = lappend(fixed_indexorderbys, clause);

5118 }

5119

5120 return fixed_indexorderbys;

5121}

5122

5123

5124

5125

5126

5127

5128

5129

5130static Node *

5132 Node *clause, List *indexcolnos)

5133{

5134

5135

5136

5137

5138

5139

5141

5143 {

5145

5146

5149 indexcol);

5150 }

5152 {

5155 *lcai;

5156

5157

5160 {

5164 }

5165 }

5167 {

5169

5170

5173 indexcol);

5174 }

5176 {

5178

5179

5182 indexcol);

5183 }

5184 else

5185 elog(ERROR, "unsupported indexqual type: %d",

5187

5188 return clause;

5189}

5190

5191

5192

5193

5194

5195

5196

5197

5198

5199

5200

5201static Node *

5203{

5204 Var *result;

5205 int pos;

5207

5208

5209

5210

5213

5214 Assert(indexcol >= 0 && indexcol < index->ncolumns);

5215

5216 if (index->indexkeys[indexcol] != 0)

5217 {

5218

5219 if (IsA(node, Var) &&

5220 ((Var *) node)->varno == index->rel->relid &&

5221 ((Var *) node)->varattno == index->indexkeys[indexcol])

5222 {

5225 result->varattno = indexcol + 1;

5226 return (Node *) result;

5227 }

5228 else

5229 elog(ERROR, "index key does not match expected index column");

5230 }

5231

5232

5234 for (pos = 0; pos < index->ncolumns; pos++)

5235 {

5236 if (index->indexkeys[pos] == 0)

5237 {

5238 if (indexpr_item == NULL)

5239 elog(ERROR, "too few entries in indexprs list");

5240 if (pos == indexcol)

5241 {

5242 Node *indexkey;

5243

5244 indexkey = (Node *) lfirst(indexpr_item);

5247 if (equal(node, indexkey))

5248 {

5252 0);

5253 return (Node *) result;

5254 }

5255 else

5256 elog(ERROR, "index key does not match expected index column");

5257 }

5258 indexpr_item = lnext(index->indexprs, indexpr_item);

5259 }

5260 }

5261

5262

5263 elog(ERROR, "index key does not match expected index column");

5264 return NULL;

5265}

5266

5267

5268

5269

5270

5271

5272

5273

5274

5275

5276static List *

5278{

5281

5282 foreach(l, clauses)

5283 {

5286

5288 if (bms_is_subset(restrictinfo->right_relids, outerrelids))

5289 {

5290

5291

5292

5293

5294

5296

5299 temp->opresulttype = clause->opresulttype;

5300 temp->opretset = clause->opretset;

5301 temp->opcollid = clause->opcollid;

5302 temp->inputcollid = clause->inputcollid;

5305

5307 t_list = lappend(t_list, temp);

5308 restrictinfo->outer_is_left = false;

5309 }

5310 else

5311 {

5313 t_list = lappend(t_list, clause);

5314 restrictinfo->outer_is_left = true;

5315 }

5316 }

5317 return t_list;

5318}

5319

5320

5321

5322

5323

5324

5325

5326

5327

5328

5329

5330

5331

5332

5333

5334

5335

5336

5337

5338

5339

5340

5341

5342

5343

5344

5345

5346

5347

5348

5349

5350

5351

5352

5353static List *

5355{

5356 typedef struct

5357 {

5358 Node *clause;

5360 Index security_level;

5361 } QualItem;

5363 QualItem *items;

5365 int i;

5366 List *result;

5367

5368

5370 return clauses;

5371

5372

5373

5374

5375

5377 i = 0;

5378 foreach(lc, clauses)

5379 {

5382

5384 items[i].clause = clause;

5387 {

5389

5390

5391

5392

5393

5394

5395

5396

5397

5398

5399

5401 items[i].security_level = 0;

5402 else

5404 }

5405 else

5406 items[i].security_level = 0;

5407 i++;

5408 }

5409

5410

5411

5412

5413

5414

5416 {

5417 QualItem newitem = items[i];

5418 int j;

5419

5420

5421 for (j = i; j > 0; j--)

5422 {

5423 QualItem *olditem = &items[j - 1];

5424

5425 if (newitem.security_level > olditem->security_level ||

5426 (newitem.security_level == olditem->security_level &&

5427 newitem.cost >= olditem->cost))

5428 break;

5429 items[j] = *olditem;

5430 }

5432 }

5433

5434

5435 result = NIL;

5438

5439 return result;

5440}

5441

5442

5443

5444

5445

5446

5447static void

5449{

5453 dest->plan_rows = src->rows;

5454 dest->plan_width = src->pathtarget->width;

5457}

5458

5459

5460

5461

5462

5463static void

5465{

5471

5472 dest->parallel_aware = false;

5473

5475}

5476

5477

5478

5479

5480

5481

5482

5483

5484

5485

5486static void

5488{

5489 Plan *lefttree = plan->plan.lefttree;

5490 Path sort_path;

5491

5493

5495 plan->plan.disabled_nodes,

5499 0.0,

5501 limit_tuples);

5506 plan->plan.parallel_aware = false;

5508}

5509

5510

5511

5512

5513

5514static void

5516 List *pathkeys, double limit_tuples)

5517{

5518 Plan *lefttree = plan->sort.plan.lefttree;

5519 Path sort_path;

5520

5522

5524 plan->nPresortedCols,

5525 plan->sort.plan.disabled_nodes,

5530 0.0,

5532 limit_tuples);

5535 plan->sort.plan.plan_rows = lefttree->plan_rows;

5537 plan->sort.plan.parallel_aware = false;

5539}

5540

5541

5542

5543

5544

5545

5546static void

5548{

5552 {

5555 }

5558 else

5560}

5561

5562

5563

5564

5565

5566

5567

5568

5569

5570

5571

5572

5573

5574

5575

5578 List *qpqual,

5579 Index scanrelid)

5580{

5583

5584 plan->targetlist = qptlist;

5585 plan->qual = qpqual;

5586 plan->lefttree = NULL;

5587 plan->righttree = NULL;

5589

5590 return node;

5591}

5592

5595 List *qpqual,

5596 Index scanrelid,

5598{

5601

5602 plan->targetlist = qptlist;

5603 plan->qual = qpqual;

5604 plan->lefttree = NULL;

5605 plan->righttree = NULL;

5608

5609 return node;

5610}

5611

5614 List *qpqual,

5615 Index scanrelid,

5616 Oid indexid,

5617 List *indexqual,

5618 List *indexqualorig,

5619 List *indexorderby,

5620 List *indexorderbyorig,

5621 List *indexorderbyops,

5623{

5626

5627 plan->targetlist = qptlist;

5628 plan->qual = qpqual;

5629 plan->lefttree = NULL;

5630 plan->righttree = NULL;

5632 node->indexid = indexid;

5639

5640 return node;

5641}

5642

5645 List *qpqual,

5646 Index scanrelid,

5647 Oid indexid,

5648 List *indexqual,

5649 List *recheckqual,

5650 List *indexorderby,

5651 List *indextlist,

5653{

5656

5657 plan->targetlist = qptlist;

5658 plan->qual = qpqual;

5659 plan->lefttree = NULL;

5660 plan->righttree = NULL;

5662 node->indexid = indexid;

5668

5669 return node;

5670}

5671

5674 Oid indexid,

5675 List *indexqual,

5676 List *indexqualorig)

5677{

5680

5681 plan->targetlist = NIL;

5682 plan->qual = NIL;

5683 plan->lefttree = NULL;

5684 plan->righttree = NULL;

5686 node->indexid = indexid;

5689

5690 return node;

5691}

5692

5695 List *qpqual,

5696 Plan *lefttree,

5697 List *bitmapqualorig,

5698 Index scanrelid)

5699{

5702

5703 plan->targetlist = qptlist;

5704 plan->qual = qpqual;

5705 plan->lefttree = lefttree;

5706 plan->righttree = NULL;

5709

5710 return node;

5711}

5712

5715 List *qpqual,

5716 Index scanrelid,

5717 List *tidquals)

5718{

5721

5722 plan->targetlist = qptlist;

5723 plan->qual = qpqual;

5724 plan->lefttree = NULL;

5725 plan->righttree = NULL;

5728

5729 return node;

5730}

5731

5734 List *qpqual,

5735 Index scanrelid,

5736 List *tidrangequals)

5737{

5740

5741 plan->targetlist = qptlist;

5742 plan->qual = qpqual;

5743 plan->lefttree = NULL;

5744 plan->righttree = NULL;

5747

5748 return node;

5749}

5750

5753 List *qpqual,

5754 Index scanrelid,

5755 Plan *subplan)

5756{

5759

5760 plan->targetlist = qptlist;

5761 plan->qual = qpqual;

5762 plan->lefttree = NULL;

5763 plan->righttree = NULL;

5765 node->subplan = subplan;

5767

5768 return node;

5769}

5770

5773 List *qpqual,

5774 Index scanrelid,

5776 bool funcordinality)

5777{

5780

5781 plan->targetlist = qptlist;

5782 plan->qual = qpqual;

5783 plan->lefttree = NULL;

5784 plan->righttree = NULL;

5788

5789 return node;

5790}

5791

5794 List *qpqual,

5795 Index scanrelid,

5797{

5800

5801 plan->targetlist = qptlist;

5802 plan->qual = qpqual;

5803 plan->lefttree = NULL;

5804 plan->righttree = NULL;

5807

5808 return node;

5809}

5810

5813 List *qpqual,

5814 Index scanrelid,

5815 List *values_lists)

5816{

5819

5820 plan->targetlist = qptlist;

5821 plan->qual = qpqual;

5822 plan->lefttree = NULL;

5823 plan->righttree = NULL;

5826

5827 return node;

5828}

5829

5832 List *qpqual,

5833 Index scanrelid,

5834 int ctePlanId,

5835 int cteParam)

5836{

5839

5840 plan->targetlist = qptlist;

5841 plan->qual = qpqual;

5842 plan->lefttree = NULL;

5843 plan->righttree = NULL;

5847

5848 return node;

5849}

5850

5853 List *qpqual,

5854 Index scanrelid,

5855 char *enrname)

5856{

5859

5860

5861 plan->targetlist = qptlist;

5862 plan->qual = qpqual;

5863 plan->lefttree = NULL;

5864 plan->righttree = NULL;

5866 node->enrname = enrname;

5867

5868 return node;

5869}

5870

5873 List *qpqual,

5874 Index scanrelid,

5875 int wtParam)

5876{

5879

5880 plan->targetlist = qptlist;

5881 plan->qual = qpqual;

5882 plan->lefttree = NULL;

5883 plan->righttree = NULL;

5885 node->wtParam = wtParam;

5886

5887 return node;

5888}

5889

5892 List *qpqual,

5893 Index scanrelid,

5894 List *fdw_exprs,

5895 List *fdw_private,

5896 List *fdw_scan_tlist,

5897 List *fdw_recheck_quals,

5898 Plan *outer_plan)

5899{

5902

5903

5904 plan->targetlist = qptlist;

5905 plan->qual = qpqual;

5906 plan->lefttree = outer_plan;

5907 plan->righttree = NULL;

5909

5910

5913

5914

5921

5924

5926

5927 return node;

5928}

5929

5932 Plan *lefttree,

5933 Plan *righttree,

5934 int wtParam,

5935 List *distinctList,

5936 long numGroups)

5937{

5940 int numCols = list_length(distinctList);

5941

5942 plan->targetlist = tlist;

5944 plan->lefttree = lefttree;

5945 plan->righttree = righttree;

5946 node->wtParam = wtParam;

5947

5948

5949

5950

5951

5952 node->numCols = numCols;

5953 if (numCols > 0)

5954 {

5955 int keyno = 0;

5957 Oid *dupOperators;

5958 Oid *dupCollations;

5960

5962 dupOperators = (Oid *) palloc(sizeof(Oid) * numCols);

5963 dupCollations = (Oid *) palloc(sizeof(Oid) * numCols);

5964

5965 foreach(slitem, distinctList)

5966 {

5969 plan->targetlist);

5970

5971 dupColIdx[keyno] = tle->resno;

5972 dupOperators[keyno] = sortcl->eqop;

5975 keyno++;

5976 }

5977 node->dupColIdx = dupColIdx;

5978 node->dupOperators = dupOperators;

5979 node->dupCollations = dupCollations;

5980 }

5982

5983 return node;

5984}

5985

5988{

5991

5994 plan->lefttree = NULL;

5995 plan->righttree = NULL;

5997

5998 return node;

5999}

6000

6003{

6006

6009 plan->lefttree = NULL;

6010 plan->righttree = NULL;

6012

6013 return node;

6014}

6015

6018 List *joinclauses,

6019 List *otherclauses,

6020 List *nestParams,

6021 Plan *lefttree,

6022 Plan *righttree,

6024 bool inner_unique)

6025{

6028

6029 plan->targetlist = tlist;

6030 plan->qual = otherclauses;

6031 plan->lefttree = lefttree;

6032 plan->righttree = righttree;

6037

6038 return node;

6039}

6040

6043 List *joinclauses,

6044 List *otherclauses,

6045 List *hashclauses,

6046 List *hashoperators,

6047 List *hashcollations,

6048 List *hashkeys,

6049 Plan *lefttree,

6050 Plan *righttree,

6052 bool inner_unique)

6053{

6056

6057 plan->targetlist = tlist;

6058 plan->qual = otherclauses;

6059 plan->lefttree = lefttree;

6060 plan->righttree = righttree;

6068

6069 return node;

6070}

6071

6072static Hash *

6074 List *hashkeys,

6075 Oid skewTable,

6077 bool skewInherit)

6078{

6081

6084 plan->lefttree = lefttree;

6085 plan->righttree = NULL;

6086

6091

6092 return node;

6093}

6094

6097 List *joinclauses,

6098 List *otherclauses,

6099 List *mergeclauses,

6100 Oid *mergefamilies,

6101 Oid *mergecollations,

6102 bool *mergereversals,

6103 bool *mergenullsfirst,

6104 Plan *lefttree,

6105 Plan *righttree,

6107 bool inner_unique,

6108 bool skip_mark_restore)

6109{

6112

6113 plan->targetlist = tlist;

6114 plan->qual = otherclauses;

6115 plan->lefttree = lefttree;

6116 plan->righttree = righttree;

6119 node->mergeFamilies = mergefamilies;

6120 node->mergeCollations = mergecollations;

6121 node->mergeReversals = mergereversals;

6122 node->mergeNullsFirst = mergenullsfirst;

6126

6127 return node;

6128}

6129

6130

6131

6132

6133

6134

6135

6136static Sort *

6139 Oid *collations, bool *nullsFirst)

6140{

6143

6145

6150 plan->lefttree = lefttree;

6151 plan->righttree = NULL;

6152 node->numCols = numCols;

6153 node->sortColIdx = sortColIdx;

6154 node->sortOperators = sortOperators;

6155 node->collations = collations;

6156 node->nullsFirst = nullsFirst;

6157

6158 return node;

6159}

6160

6161

6162

6163

6164

6165

6166

6170 Oid *collations, bool *nullsFirst)

6171{

6174

6176

6180 plan->lefttree = lefttree;

6181 plan->righttree = NULL;

6184 node->sort.sortColIdx = sortColIdx;

6185 node->sort.sortOperators = sortOperators;

6186 node->sort.collations = collations;

6187 node->sort.nullsFirst = nullsFirst;

6188

6189 return node;

6190}

6191

6192

6193

6194

6195

6196

6197

6198

6199

6200

6201

6202

6203

6204

6205

6206

6207

6208

6209

6210

6211

6212

6213

6214

6215

6216

6217

6218

6219

6220

6221

6222

6223

6224

6225

6226

6227

6228

6229

6230

6231

6232

6233static Plan *

6237 bool adjust_tlist_in_place,

6238 int *p_numsortkeys,

6240 Oid **p_sortOperators,

6241 Oid **p_collations,

6242 bool **p_nullsFirst)

6243{

6246 int numsortkeys;

6248 Oid *sortOperators;

6249 Oid *collations;

6250 bool *nullsFirst;

6251

6252

6253

6254

6257 sortOperators = (Oid *) palloc(numsortkeys * sizeof(Oid));

6258 collations = (Oid *) palloc(numsortkeys * sizeof(Oid));

6259 nullsFirst = (bool *) palloc(numsortkeys * sizeof(bool));

6260

6261 numsortkeys = 0;

6262

6263 foreach(i, pathkeys)

6264 {

6270 Oid sortop;

6272

6274 {

6275

6276

6277

6278

6279

6280 if (ec->ec_sortref == 0)

6281 elog(ERROR, "volatile EquivalenceClass has no sortref");

6286 }

6287 else if (reqColIdx != NULL)

6288 {

6289

6290

6291

6292

6293

6294

6295

6296

6297

6299 if (tle)

6300 {

6302 if (em)

6303 {

6304

6306 }

6307 else

6308 tle = NULL;

6309 }

6310 }

6311 else

6312 {

6313

6314

6315

6316

6317

6318

6319

6320

6321

6322

6323

6324

6325

6326 foreach(j, tlist)

6327 {

6330 if (em)

6331 {

6332

6334 break;

6335 }

6336 tle = NULL;

6337 }

6338 }

6339

6340 if (!tle)

6341 {

6342

6343

6344

6346 if (!em)

6347 elog(ERROR, "could not find pathkey item to sort");

6349

6350

6351

6352

6353 if (!adjust_tlist_in_place &&

6355 {

6356

6360 }

6361

6362

6363 adjust_tlist_in_place = true;

6364

6365

6366

6367

6370 NULL,

6371 true);

6372 tlist = lappend(tlist, tle);

6373 lefttree->targetlist = tlist;

6374 }

6375

6376

6377

6378

6379

6381 pk_datatype,

6382 pk_datatype,

6384 if (OidIsValid(sortop))

6385 elog(ERROR, "missing operator %d(%u,%u) in opfamily %u",

6386 pathkey->pk_cmptype, pk_datatype, pk_datatype,

6388

6389

6390 sortColIdx[numsortkeys] = tle->resno;

6391 sortOperators[numsortkeys] = sortop;

6394 numsortkeys++;

6395 }

6396

6397

6398 *p_numsortkeys = numsortkeys;

6399 *p_sortColIdx = sortColIdx;

6400 *p_sortOperators = sortOperators;

6401 *p_collations = collations;

6402 *p_nullsFirst = nullsFirst;

6403

6404 return lefttree;

6405}

6406

6407

6408

6409

6410

6411

6412

6413

6414

6415static Sort *

6417{

6418 int numsortkeys;

6420 Oid *sortOperators;

6421 Oid *collations;

6422 bool *nullsFirst;

6423

6424

6426 relids,

6427 NULL,

6428 false,

6429 &numsortkeys,

6430 &sortColIdx,

6431 &sortOperators,

6432 &collations,

6433 &nullsFirst);

6434

6435

6436 return make_sort(lefttree, numsortkeys,

6437 sortColIdx, sortOperators,

6438 collations, nullsFirst);

6439}

6440

6441

6442

6443

6444

6445

6446

6447

6448

6449

6452 Relids relids, int nPresortedCols)

6453{

6454 int numsortkeys;

6456 Oid *sortOperators;

6457 Oid *collations;

6458 bool *nullsFirst;

6459

6460

6462 relids,

6463 NULL,

6464 false,

6465 &numsortkeys,

6466 &sortColIdx,

6467 &sortOperators,

6468 &collations,

6469 &nullsFirst);

6470

6471

6473 sortColIdx, sortOperators,

6474 collations, nullsFirst);

6475}

6476

6477

6478

6479

6480

6481

6482

6483

6486{

6489 int numsortkeys;

6491 Oid *sortOperators;

6492 Oid *collations;

6493 bool *nullsFirst;

6494

6495

6498 sortOperators = (Oid *) palloc(numsortkeys * sizeof(Oid));

6499 collations = (Oid *) palloc(numsortkeys * sizeof(Oid));

6500 nullsFirst = (bool *) palloc(numsortkeys * sizeof(bool));

6501

6502 numsortkeys = 0;

6503 foreach(l, sortcls)

6504 {

6507

6508 sortColIdx[numsortkeys] = tle->resno;

6509 sortOperators[numsortkeys] = sortcl->sortop;

6511 nullsFirst[numsortkeys] = sortcl->nulls_first;

6512 numsortkeys++;

6513 }

6514

6515 return make_sort(lefttree, numsortkeys,

6516 sortColIdx, sortOperators,

6517 collations, nullsFirst);

6518}

6519

6520

6521

6522

6523

6524

6525

6526

6527

6528

6529

6530

6531

6532

6533static Sort *

6536 Plan *lefttree)

6537{

6540 int numsortkeys;

6542 Oid *sortOperators;

6543 Oid *collations;

6544 bool *nullsFirst;

6545

6546

6549 sortOperators = (Oid *) palloc(numsortkeys * sizeof(Oid));

6550 collations = (Oid *) palloc(numsortkeys * sizeof(Oid));

6551 nullsFirst = (bool *) palloc(numsortkeys * sizeof(bool));

6552

6553 numsortkeys = 0;

6554 foreach(l, groupcls)

6555 {

6558

6559 if (!tle)

6560 elog(ERROR, "could not retrieve tle for sort-from-groupcols");

6561

6562 sortColIdx[numsortkeys] = tle->resno;

6563 sortOperators[numsortkeys] = grpcl->sortop;

6565 nullsFirst[numsortkeys] = grpcl->nulls_first;

6566 numsortkeys++;

6567 }

6568

6569 return make_sort(lefttree, numsortkeys,

6570 sortColIdx, sortOperators,

6571 collations, nullsFirst);

6572}

6573

6576{

6579

6582 plan->lefttree = lefttree;

6583 plan->righttree = NULL;

6584

6585 return node;

6586}

6587

6588

6589

6590

6591

6592

6593

6594

6595

6598{

6599 Plan *matplan;

6600 Path matpath;

6601 Cost initplan_cost;

6602 bool unsafe_initplans;

6603

6605

6606

6607

6608

6609

6610

6611

6614

6615

6617 &initplan_cost, &unsafe_initplans);

6619 subplan->total_cost -= initplan_cost;

6620

6621

6635

6636 return matplan;

6637}

6638

6641 List *param_exprs, bool singlerow, bool binary_mode,

6643{

6646

6649 plan->lefttree = lefttree;

6650 plan->righttree = NULL;

6651

6653 node->hashOperators = hashoperators;

6654 node->collations = collations;

6660

6661 return node;

6662}

6663

6667 int numGroupCols, AttrNumber *grpColIdx, Oid *grpOperators, Oid *grpCollations,

6668 List *groupingSets, List *chain, double dNumGroups,

6669 Size transitionSpace, Plan *lefttree)

6670{

6673 long numGroups;

6674

6675

6677

6680 node->numCols = numGroupCols;

6681 node->grpColIdx = grpColIdx;

6682 node->grpOperators = grpOperators;

6683 node->grpCollations = grpCollations;

6686 node->aggParams = NULL;

6688 node->chain = chain;

6689

6690 plan->qual = qual;

6691 plan->targetlist = tlist;

6692 plan->lefttree = lefttree;

6693 plan->righttree = NULL;

6694

6695 return node;

6696}

6697

6700 int partNumCols, AttrNumber *partColIdx, Oid *partOperators, Oid *partCollations,

6701 int ordNumCols, AttrNumber *ordColIdx, Oid *ordOperators, Oid *ordCollations,

6702 List *runCondition, List *qual, bool topWindow, Plan *lefttree)

6703{

6706

6707 node->winname = wc->name;

6710 node->partColIdx = partColIdx;

6711 node->partOperators = partOperators;

6712 node->partCollations = partCollations;

6714 node->ordColIdx = ordColIdx;

6715 node->ordOperators = ordOperators;

6716 node->ordCollations = ordCollations;

6721

6729

6730 plan->targetlist = tlist;

6731 plan->lefttree = lefttree;

6732 plan->righttree = NULL;

6733 plan->qual = qual;

6734

6735 return node;

6736}

6737

6741 int numGroupCols,

6743 Oid *grpOperators,

6744 Oid *grpCollations,

6745 Plan *lefttree)

6746{

6749

6750 node->numCols = numGroupCols;

6751 node->grpColIdx = grpColIdx;

6752 node->grpOperators = grpOperators;

6753 node->grpCollations = grpCollations;

6754

6755 plan->qual = qual;

6756 plan->targetlist = tlist;

6757 plan->lefttree = lefttree;

6758 plan->righttree = NULL;

6759

6760 return node;

6761}

6762

6763

6764

6765

6766

6767

6770{

6773 int numCols = list_length(distinctList);

6774 int keyno = 0;

6776 Oid *uniqOperators;

6777 Oid *uniqCollations;

6779

6782 plan->lefttree = lefttree;

6783 plan->righttree = NULL;

6784

6785

6786

6787

6788

6789 Assert(numCols > 0);

6791 uniqOperators = (Oid *) palloc(sizeof(Oid) * numCols);

6792 uniqCollations = (Oid *) palloc(sizeof(Oid) * numCols);

6793

6794 foreach(slitem, distinctList)

6795 {

6798

6799 uniqColIdx[keyno] = tle->resno;

6800 uniqOperators[keyno] = sortcl->eqop;

6803 keyno++;

6804 }

6805

6806 node->numCols = numCols;

6807 node->uniqColIdx = uniqColIdx;

6808 node->uniqOperators = uniqOperators;

6809 node->uniqCollations = uniqCollations;

6810

6811 return node;

6812}

6813

6814

6815

6816

6819{

6822 int keyno = 0;

6824 Oid *uniqOperators;

6825 Oid *uniqCollations;

6827

6830 plan->lefttree = lefttree;

6831 plan->righttree = NULL;

6832

6833

6834

6835

6836

6837

6840 uniqOperators = (Oid *) palloc(sizeof(Oid) * numCols);

6841 uniqCollations = (Oid *) palloc(sizeof(Oid) * numCols);

6842

6843 foreach(lc, pathkeys)

6844 {

6850 Oid eqop;

6852

6853

6854 if (keyno >= numCols)

6855 break;

6856

6858 {

6859

6860

6861

6862

6863

6864 if (ec->ec_sortref == 0)

6865 elog(ERROR, "volatile EquivalenceClass has no sortref");

6870 }

6871 else

6872 {

6873

6874

6875

6876

6877

6878 foreach(j, plan->targetlist)

6879 {

6882 if (em)

6883 {

6884

6886 break;

6887 }

6888 tle = NULL;

6889 }

6890 }

6891

6892 if (!tle)

6893 elog(ERROR, "could not find pathkey item to sort");

6894

6895

6896

6897

6898

6900 pk_datatype,

6901 pk_datatype,

6903 if (OidIsValid(eqop))

6904 elog(ERROR, "missing operator %d(%u,%u) in opfamily %u",

6905 COMPARE_EQ, pk_datatype, pk_datatype,

6907

6908 uniqColIdx[keyno] = tle->resno;

6909 uniqOperators[keyno] = eqop;

6911

6912 keyno++;

6913 }

6914

6915 node->numCols = numCols;

6916 node->uniqColIdx = uniqColIdx;

6917 node->uniqOperators = uniqOperators;

6918 node->uniqCollations = uniqCollations;

6919

6920 return node;

6921}

6922

6925 List *qpqual,

6926 int nworkers,

6927 int rescan_param,

6928 bool single_copy,

6929 Plan *subplan)

6930{

6933

6934 plan->targetlist = qptlist;

6935 plan->qual = qpqual;

6936 plan->lefttree = subplan;

6937 plan->righttree = NULL;

6943

6944 return node;

6945}

6946

6947

6948

6949

6950

6951

6954 List *tlist, Plan *lefttree, Plan *righttree,

6955 List *groupList, long numGroups)

6956{

6960 int keyno = 0;

6962 Oid *cmpOperators;

6963 Oid *cmpCollations;

6964 bool *cmpNullsFirst;

6966

6967 plan->targetlist = tlist;

6969 plan->lefttree = lefttree;

6970 plan->righttree = righttree;

6971

6972

6973

6974

6975

6977 cmpOperators = (Oid *) palloc(sizeof(Oid) * numCols);

6978 cmpCollations = (Oid *) palloc(sizeof(Oid) * numCols);

6979 cmpNullsFirst = (bool *) palloc(sizeof(bool) * numCols);

6980

6981 foreach(slitem, groupList)

6982 {

6985

6986 cmpColIdx[keyno] = tle->resno;

6988 cmpOperators[keyno] = sortcl->eqop;

6989 else

6990 cmpOperators[keyno] = sortcl->sortop;

6993 cmpNullsFirst[keyno] = sortcl->nulls_first;

6994 keyno++;

6995 }

6996

6997 node->cmd = cmd;

6999 node->numCols = numCols;

7000 node->cmpColIdx = cmpColIdx;

7001 node->cmpOperators = cmpOperators;

7002 node->cmpCollations = cmpCollations;

7003 node->cmpNullsFirst = cmpNullsFirst;

7005

7006 return node;

7007}

7008

7009

7010

7011

7012

7015{

7018

7021 plan->lefttree = lefttree;

7022 plan->righttree = NULL;

7023

7026

7027 return node;

7028}

7029

7030

7031

7032

7033

7037 Oid *uniqOperators, Oid *uniqCollations)

7038{

7041

7044 plan->lefttree = lefttree;

7045 plan->righttree = NULL;

7046

7051 node->uniqColIdx = uniqColIdx;

7052 node->uniqOperators = uniqOperators;

7053 node->uniqCollations = uniqCollations;

7054

7055 return node;

7056}

7057

7058

7059

7060

7061

7064 Node *resconstantqual,

7065 Plan *subplan)

7066{

7069

7070 plan->targetlist = tlist;

7072 plan->lefttree = subplan;

7073 plan->righttree = NULL;

7075

7076 return node;

7077}

7078

7079

7080

7081

7082

7085 Plan *subplan)

7086{

7089

7090 plan->targetlist = tlist;

7092 plan->lefttree = subplan;

7093 plan->righttree = NULL;

7094

7095 return node;

7096}

7097

7098

7099

7100

7101

7104 CmdType operation, bool canSetTag,

7105 Index nominalRelation, Index rootRelation,

7106 bool partColsUpdated,

7107 List *resultRelations,

7108 List *updateColnosLists,

7109 List *withCheckOptionLists, List *returningLists,

7111 List *mergeActionLists, List *mergeJoinConditions,

7112 int epqParam)

7113{

7115 bool returning_old_or_new = false;

7116 bool returning_old_or_new_valid = false;

7117 List *fdw_private_list;

7120 int i;

7121

7125 updateColnosLists == NIL));

7126 Assert(withCheckOptionLists == NIL ||

7130

7134

7136

7143 if (!onconflict)

7144 {

7152 }

7153 else

7154 {

7156

7157

7158

7159

7160

7161

7162

7167

7168

7169

7170

7171

7172

7173

7175

7178 }

7188

7189

7190

7191

7192

7193 fdw_private_list = NIL;

7194 direct_modify_plans = NULL;

7195 i = 0;

7196 foreach(lc, resultRelations)

7197 {

7200 List *fdw_private;

7201 bool direct_modify;

7202

7203

7204

7205

7206

7207

7208

7209

7210 if (rti < root->simple_rel_array_size &&

7211 root->simple_rel_array[rti] != NULL)

7212 {

7213 RelOptInfo *resultRel = root->simple_rel_array[rti];

7214

7215 fdwroutine = resultRel->fdwroutine;

7216 }

7217 else

7218 {

7220

7222 rte->relkind == RELKIND_FOREIGN_TABLE)

7223 {

7224

7226 {

7227

7230 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),

7231 errmsg("access to non-system foreign table is restricted")));

7232 }

7233

7235 }

7236 else

7237 fdwroutine = NULL;

7238 }

7239

7240

7241

7242

7243

7244

7245

7246

7247 if (operation == CMD_MERGE && fdwroutine != NULL)

7248 {

7250

7252 errcode(ERRCODE_FEATURE_NOT_SUPPORTED),

7253 errmsg("cannot execute MERGE on relation \"%s\"",

7256 }

7257

7258

7259

7260

7261

7262

7263

7264

7265

7266 direct_modify = false;

7267 if (fdwroutine != NULL &&

7272 withCheckOptionLists == NIL &&

7275 {

7276

7277 if (!returning_old_or_new_valid)

7278 {

7279 returning_old_or_new =

7281 root->parse->returningList);

7282 returning_old_or_new_valid = true;

7283 }

7284 if (!returning_old_or_new)

7286 }

7287 if (direct_modify)

7288 direct_modify_plans = bms_add_member(direct_modify_plans, i);

7289

7290 if (!direct_modify &&

7291 fdwroutine != NULL &&

7294 else

7295 fdw_private = NIL;

7296 fdw_private_list = lappend(fdw_private_list, fdw_private);

7297 i++;

7298 }

7301

7302 return node;

7303}

7304

7305

7306

7307

7308

7309bool

7311{

7312

7314 {

7315 case T_Hash:

7316 case T_Material:

7317 case T_Memoize:

7318 case T_Sort:

7319 case T_IncrementalSort:

7320 case T_Unique:

7321 case T_SetOp:

7322 case T_LockRows:

7323 case T_Limit:

7324 case T_ModifyTable:

7325 case T_MergeAppend:

7326 case T_RecursiveUnion:

7327 return false;

7328 case T_CustomScan:

7330 return true;

7331 return false;

7332 case T_Append:

7333

7334

7335

7336

7337

7338

7340 case T_ProjectSet:

7341

7342

7343

7344

7345

7346

7347

7348 return false;

7349 default:

7350 break;

7351 }

7352 return true;

7353}

7354

7355

7356

7357

7358

7359bool

7361{

7362

7364 {

7365 case T_Hash:

7366 case T_Material:

7367 case T_Memoize:

7368 case T_Sort:

7369 case T_Unique:

7370 case T_SetOp:

7371 case T_LockRows:

7372 case T_Limit:

7373 case T_ModifyTable:

7374 case T_Append:

7375 case T_MergeAppend:

7376 case T_RecursiveUnion:

7377 return false;

7378 case T_CustomScan:

7380 return true;

7381 return false;

7382 case T_ProjectSet:

7383

7384

7385

7386

7387

7388

7389

7390 return false;

7391 default:

7392 break;

7393 }

7394 return true;

7395}

Datum sort(PG_FUNCTION_ARGS)

#define InvalidAttrNumber

Bitmapset * bms_difference(const Bitmapset *a, const Bitmapset *b)

bool bms_is_subset(const Bitmapset *a, const Bitmapset *b)

void bms_free(Bitmapset *a)

bool bms_is_member(int x, const Bitmapset *a)

Bitmapset * bms_add_member(Bitmapset *a, int x)

Bitmapset * bms_union(const Bitmapset *a, const Bitmapset *b)

bool bms_nonempty_difference(const Bitmapset *a, const Bitmapset *b)

#define PG_USED_FOR_ASSERTS_ONLY

#define OidIsValid(objectId)

bool contain_mutable_functions(Node *clause)

Bitmapset * pull_paramids(Expr *expr)

void CommuteOpExpr(OpExpr *clause)

void cost_material(Path *path, int input_disabled_nodes, Cost input_startup_cost, Cost input_total_cost, double tuples, int width)

void cost_sort(Path *path, PlannerInfo *root, List *pathkeys, int input_disabled_nodes, Cost input_cost, double tuples, int width, Cost comparison_cost, int sort_mem, double limit_tuples)

void cost_qual_eval_node(QualCost *cost, Node *qual, PlannerInfo *root)

void cost_incremental_sort(Path *path, PlannerInfo *root, List *pathkeys, int presorted_keys, int input_disabled_nodes, Cost input_startup_cost, Cost input_total_cost, double input_tuples, int width, Cost comparison_cost, int sort_mem, double limit_tuples)

double clamp_row_est(double nrows)

long clamp_cardinality_to_long(Cardinality x)

bool enable_partition_pruning

bool enable_incremental_sort

static Unique * make_unique_from_sortclauses(Plan *lefttree, List *distinctList)

static Plan * create_join_plan(PlannerInfo *root, JoinPath *best_path)

static bool use_physical_tlist(PlannerInfo *root, Path *path, int flags)

static SeqScan * create_seqscan_plan(PlannerInfo *root, Path *best_path, List *tlist, List *scan_clauses)

static WorkTableScan * make_worktablescan(List *qptlist, List *qpqual, Index scanrelid, int wtParam)

static Plan * create_merge_append_plan(PlannerInfo *root, MergeAppendPath *best_path, int flags)

static List * order_qual_clauses(PlannerInfo *root, List *clauses)

static MergeJoin * make_mergejoin(List *tlist, List *joinclauses, List *otherclauses, List *mergeclauses, Oid *mergefamilies, Oid *mergecollations, bool *mergereversals, bool *mergenullsfirst, Plan *lefttree, Plan *righttree, JoinType jointype, bool inner_unique, bool skip_mark_restore)

static GatherMerge * create_gather_merge_plan(PlannerInfo *root, GatherMergePath *best_path)

static ValuesScan * create_valuesscan_plan(PlannerInfo *root, Path *best_path, List *tlist, List *scan_clauses)

static SetOp * make_setop(SetOpCmd cmd, SetOpStrategy strategy, List *tlist, Plan *lefttree, Plan *righttree, List *groupList, long numGroups)

static void copy_generic_path_info(Plan *dest, Path *src)

static WindowAgg * make_windowagg(List *tlist, WindowClause *wc, int partNumCols, AttrNumber *partColIdx, Oid *partOperators, Oid *partCollations, int ordNumCols, AttrNumber *ordColIdx, Oid *ordOperators, Oid *ordCollations, List *runCondition, List *qual, bool topWindow, Plan *lefttree)

static Memoize * make_memoize(Plan *lefttree, Oid *hashoperators, Oid *collations, List *param_exprs, bool singlerow, bool binary_mode, uint32 est_entries, Bitmapset *keyparamids)

Sort * make_sort_from_sortclauses(List *sortcls, Plan *lefttree)

static BitmapOr * make_bitmap_or(List *bitmapplans)

static HashJoin * create_hashjoin_plan(PlannerInfo *root, HashPath *best_path)

static SeqScan * make_seqscan(List *qptlist, List *qpqual, Index scanrelid)

static TableFuncScan * create_tablefuncscan_plan(PlannerInfo *root, Path *best_path, List *tlist, List *scan_clauses)

static CustomScan * create_customscan_plan(PlannerInfo *root, CustomPath *best_path, List *tlist, List *scan_clauses)

static Node * fix_indexqual_operand(Node *node, IndexOptInfo *index, int indexcol)

static void fix_indexqual_references(PlannerInfo *root, IndexPath *index_path, List **stripped_indexquals_p, List **fixed_indexquals_p)

static List * fix_indexorderby_references(PlannerInfo *root, IndexPath *index_path)

static Result * make_result(List *tlist, Node *resconstantqual, Plan *subplan)

static AttrNumber * remap_groupColIdx(PlannerInfo *root, List *groupClause)

static Plan * create_append_plan(PlannerInfo *root, AppendPath *best_path, int flags)

static void bitmap_subplan_mark_shared(Plan *plan)

static TidScan * make_tidscan(List *qptlist, List *qpqual, Index scanrelid, List *tidquals)

static MergeJoin * create_mergejoin_plan(PlannerInfo *root, MergePath *best_path)

static Plan * create_plan_recurse(PlannerInfo *root, Path *best_path, int flags)

static void label_sort_with_costsize(PlannerInfo *root, Sort *plan, double limit_tuples)

static ForeignScan * create_foreignscan_plan(PlannerInfo *root, ForeignPath *best_path, List *tlist, List *scan_clauses)

static BitmapHeapScan * create_bitmap_scan_plan(PlannerInfo *root, BitmapHeapPath *best_path, List *tlist, List *scan_clauses)

static IncrementalSort * make_incrementalsort(Plan *lefttree, int numCols, int nPresortedCols, AttrNumber *sortColIdx, Oid *sortOperators, Oid *collations, bool *nullsFirst)

static Result * create_group_result_plan(PlannerInfo *root, GroupResultPath *best_path)

static Limit * create_limit_plan(PlannerInfo *root, LimitPath *best_path, int flags)

static Agg * create_agg_plan(PlannerInfo *root, AggPath *best_path)

bool is_projection_capable_path(Path *path)

static CteScan * make_ctescan(List *qptlist, List *qpqual, Index scanrelid, int ctePlanId, int cteParam)

static TidScan * create_tidscan_plan(PlannerInfo *root, TidPath *best_path, List *tlist, List *scan_clauses)

static TidRangeScan * make_tidrangescan(List *qptlist, List *qpqual, Index scanrelid, List *tidrangequals)

static Plan * create_bitmap_subplan(PlannerInfo *root, Path *bitmapqual, List **qual, List **indexqual, List **indexECs)

static Node * fix_indexqual_clause(PlannerInfo *root, IndexOptInfo *index, int indexcol, Node *clause, List *indexcolnos)

static Unique * make_unique_from_pathkeys(Plan *lefttree, List *pathkeys, int numCols)

static WorkTableScan * create_worktablescan_plan(PlannerInfo *root, Path *best_path, List *tlist, List *scan_clauses)

static Plan * create_gating_plan(PlannerInfo *root, Path *path, Plan *plan, List *gating_quals)

static FunctionScan * create_functionscan_plan(PlannerInfo *root, Path *best_path, List *tlist, List *scan_clauses)

static Result * create_resultscan_plan(PlannerInfo *root, Path *best_path, List *tlist, List *scan_clauses)

static BitmapHeapScan * make_bitmap_heapscan(List *qptlist, List *qpqual, Plan *lefttree, List *bitmapqualorig, Index scanrelid)

static Node * replace_nestloop_params_mutator(Node *node, PlannerInfo *root)

static SetOp * create_setop_plan(PlannerInfo *root, SetOpPath *best_path, int flags)

bool is_projection_capable_plan(Plan *plan)

static CteScan * create_ctescan_plan(PlannerInfo *root, Path *best_path, List *tlist, List *scan_clauses)

static Sort * create_sort_plan(PlannerInfo *root, SortPath *best_path, int flags)

static Unique * create_upper_unique_plan(PlannerInfo *root, UpperUniquePath *best_path, int flags)

static ProjectSet * make_project_set(List *tlist, Plan *subplan)

static Sort * make_sort_from_pathkeys(Plan *lefttree, List *pathkeys, Relids relids)

static HashJoin * make_hashjoin(List *tlist, List *joinclauses, List *otherclauses, List *hashclauses, List *hashoperators, List *hashcollations, List *hashkeys, Plan *lefttree, Plan *righttree, JoinType jointype, bool inner_unique)

static Gather * make_gather(List *qptlist, List *qpqual, int nworkers, int rescan_param, bool single_copy, Plan *subplan)

static Gather * create_gather_plan(PlannerInfo *root, GatherPath *best_path)

static Sort * make_sort(Plan *lefttree, int numCols, AttrNumber *sortColIdx, Oid *sortOperators, Oid *collations, bool *nullsFirst)

Limit * make_limit(Plan *lefttree, Node *limitOffset, Node *limitCount, LimitOption limitOption, int uniqNumCols, AttrNumber *uniqColIdx, Oid *uniqOperators, Oid *uniqCollations)

static ProjectSet * create_project_set_plan(PlannerInfo *root, ProjectSetPath *best_path)

static void label_incrementalsort_with_costsize(PlannerInfo *root, IncrementalSort *plan, List *pathkeys, double limit_tuples)

ForeignScan * make_foreignscan(List *qptlist, List *qpqual, Index scanrelid, List *fdw_exprs, List *fdw_private, List *fdw_scan_tlist, List *fdw_recheck_quals, Plan *outer_plan)

static Group * create_group_plan(PlannerInfo *root, GroupPath *best_path)

static ModifyTable * create_modifytable_plan(PlannerInfo *root, ModifyTablePath *best_path)

static Result * create_minmaxagg_plan(PlannerInfo *root, MinMaxAggPath *best_path)

static LockRows * create_lockrows_plan(PlannerInfo *root, LockRowsPath *best_path, int flags)

static Material * create_material_plan(PlannerInfo *root, MaterialPath *best_path, int flags)

static List * get_gating_quals(PlannerInfo *root, List *quals)

static Plan * create_scan_plan(PlannerInfo *root, Path *best_path, int flags)

static Group * make_group(List *tlist, List *qual, int numGroupCols, AttrNumber *grpColIdx, Oid *grpOperators, Oid *grpCollations, Plan *lefttree)

static LockRows * make_lockrows(Plan *lefttree, List *rowMarks, int epqParam)

static IncrementalSort * create_incrementalsort_plan(PlannerInfo *root, IncrementalSortPath *best_path, int flags)

static NamedTuplestoreScan * create_namedtuplestorescan_plan(PlannerInfo *root, Path *best_path, List *tlist, List *scan_clauses)

static Plan * create_projection_plan(PlannerInfo *root, ProjectionPath *best_path, int flags)

static RecursiveUnion * make_recursive_union(List *tlist, Plan *lefttree, Plan *righttree, int wtParam, List *distinctList, long numGroups)

static IndexOnlyScan * make_indexonlyscan(List *qptlist, List *qpqual, Index scanrelid, Oid indexid, List *indexqual, List *recheckqual, List *indexorderby, List *indextlist, ScanDirection indexscandir)

static List * build_path_tlist(PlannerInfo *root, Path *path)

static IndexScan * make_indexscan(List *qptlist, List *qpqual, Index scanrelid, Oid indexid, List *indexqual, List *indexqualorig, List *indexorderby, List *indexorderbyorig, List *indexorderbyops, ScanDirection indexscandir)

static FunctionScan * make_functionscan(List *qptlist, List *qpqual, Index scanrelid, List *functions, bool funcordinality)

static TableFuncScan * make_tablefuncscan(List *qptlist, List *qpqual, Index scanrelid, TableFunc *tablefunc)

static SubqueryScan * create_subqueryscan_plan(PlannerInfo *root, SubqueryScanPath *best_path, List *tlist, List *scan_clauses)

Agg * make_agg(List *tlist, List *qual, AggStrategy aggstrategy, AggSplit aggsplit, int numGroupCols, AttrNumber *grpColIdx, Oid *grpOperators, Oid *grpCollations, List *groupingSets, List *chain, double dNumGroups, Size transitionSpace, Plan *lefttree)

static Plan * inject_projection_plan(Plan *subplan, List *tlist, bool parallel_safe)

static TidRangeScan * create_tidrangescan_plan(PlannerInfo *root, TidRangePath *best_path, List *tlist, List *scan_clauses)

static List * get_switched_clauses(List *clauses, Relids outerrelids)

static void copy_plan_costsize(Plan *dest, Plan *src)

static ValuesScan * make_valuesscan(List *qptlist, List *qpqual, Index scanrelid, List *values_lists)

Plan * materialize_finished_plan(Plan *subplan)

static SampleScan * make_samplescan(List *qptlist, List *qpqual, Index scanrelid, TableSampleClause *tsc)

static NestLoop * create_nestloop_plan(PlannerInfo *root, NestPath *best_path)

static Memoize * create_memoize_plan(PlannerInfo *root, MemoizePath *best_path, int flags)

static NamedTuplestoreScan * make_namedtuplestorescan(List *qptlist, List *qpqual, Index scanrelid, char *enrname)

static bool mark_async_capable_plan(Plan *plan, Path *path)

static Material * make_material(Plan *lefttree)

Plan * change_plan_targetlist(Plan *subplan, List *tlist, bool tlist_parallel_safe)

static NestLoop * make_nestloop(List *tlist, List *joinclauses, List *otherclauses, List *nestParams, Plan *lefttree, Plan *righttree, JoinType jointype, bool inner_unique)

static BitmapIndexScan * make_bitmap_indexscan(Index scanrelid, Oid indexid, List *indexqual, List *indexqualorig)

static SubqueryScan * make_subqueryscan(List *qptlist, List *qpqual, Index scanrelid, Plan *subplan)

static Hash * make_hash(Plan *lefttree, List *hashkeys, Oid skewTable, AttrNumber skewColumn, bool skewInherit)

static WindowAgg * create_windowagg_plan(PlannerInfo *root, WindowAggPath *best_path)

static Node * replace_nestloop_params(PlannerInfo *root, Node *expr)

static BitmapAnd * make_bitmap_and(List *bitmapplans)

static Plan * create_groupingsets_plan(PlannerInfo *root, GroupingSetsPath *best_path)

static RecursiveUnion * create_recursiveunion_plan(PlannerInfo *root, RecursiveUnionPath *best_path)

static Sort * make_sort_from_groupcols(List *groupcls, AttrNumber *grpColIdx, Plan *lefttree)

static Scan * create_indexscan_plan(PlannerInfo *root, IndexPath *best_path, List *tlist, List *scan_clauses, bool indexonly)

static ModifyTable * make_modifytable(PlannerInfo *root, Plan *subplan, CmdType operation, bool canSetTag, Index nominalRelation, Index rootRelation, bool partColsUpdated, List *resultRelations, List *updateColnosLists, List *withCheckOptionLists, List *returningLists, List *rowMarks, OnConflictExpr *onconflict, List *mergeActionLists, List *mergeJoinConditions, int epqParam)

static Plan * prepare_sort_from_pathkeys(Plan *lefttree, List *pathkeys, Relids relids, const AttrNumber *reqColIdx, bool adjust_tlist_in_place, int *p_numsortkeys, AttrNumber **p_sortColIdx, Oid **p_sortOperators, Oid **p_collations, bool **p_nullsFirst)

static Plan * create_unique_plan(PlannerInfo *root, UniquePath *best_path, int flags)

static IncrementalSort * make_incrementalsort_from_pathkeys(Plan *lefttree, List *pathkeys, Relids relids, int nPresortedCols)

static SampleScan * create_samplescan_plan(PlannerInfo *root, Path *best_path, List *tlist, List *scan_clauses)

Plan * create_plan(PlannerInfo *root, Path *best_path)

int errcode(int sqlerrcode)

int errmsg(const char *fmt,...)

#define ereport(elevel,...)

bool equal(const void *a, const void *b)

bool is_redundant_with_indexclauses(RestrictInfo *rinfo, List *indexclauses)

EquivalenceMember * find_ec_member_matching_expr(EquivalenceClass *ec, Expr *expr, Relids relids)

EquivalenceMember * find_computable_ec_member(PlannerInfo *root, EquivalenceClass *ec, List *exprs, Relids relids, bool require_parallel_safe)

bool is_redundant_derived_clause(RestrictInfo *rinfo, List *clauselist)

#define CUSTOMPATH_SUPPORT_PROJECTION

FdwRoutine * GetFdwRoutineByRelId(Oid relid)

Assert(PointerIsAligned(start, uint64))

if(TABLE==NULL||TABLE_index==NULL)

List * list_difference(const List *list1, const List *list2)

List * lappend(List *list, void *datum)

List * list_difference_ptr(const List *list1, const List *list2)

List * list_concat(List *list1, const List *list2)

List * list_concat_copy(const List *list1, const List *list2)

List * list_copy(const List *oldlist)

List * lappend_oid(List *list, Oid datum)

bool list_member_ptr(const List *list, const void *datum)

bool list_member(const List *list, const void *datum)

List * list_copy_head(const List *oldlist, int len)

List * list_concat_unique(List *list1, const List *list2)

char * get_rel_name(Oid relid)

bool get_compatible_hash_operators(Oid opno, Oid *lhs_opno, Oid *rhs_opno)

Oid get_opfamily_member_for_cmptype(Oid opfamily, Oid lefttype, Oid righttype, CompareType cmptype)

Oid get_equality_op_for_ordering_op(Oid opno, bool *reverse)

Oid get_ordering_op_for_equality_op(Oid opno, bool use_lhs_type)

Datum lca(PG_FUNCTION_ARGS)

Datum subpath(PG_FUNCTION_ARGS)

Expr * make_orclause(List *orclauses)

Expr * make_ands_explicit(List *andclauses)

Var * makeVar(int varno, AttrNumber varattno, Oid vartype, int32 vartypmod, Oid varcollid, Index varlevelsup)

Node * makeBoolConst(bool value, bool isnull)

TargetEntry * makeTargetEntry(Expr *expr, AttrNumber resno, char *resname, bool resjunk)

void * palloc0(Size size)

Oid exprType(const Node *expr)

Oid exprCollation(const Node *expr)

#define expression_tree_mutator(n, m, c)

static bool is_opclause(const void *clause)

#define IsA(nodeptr, _type_)

#define IS_OUTER_JOIN(jointype)

#define castNode(_type_, nodeptr)

List * identify_current_nestloop_params(PlannerInfo *root, Relids leftrelids)

void process_subquery_nestloop_params(PlannerInfo *root, List *subplan_params)

Param * replace_nestloop_param_placeholdervar(PlannerInfo *root, PlaceHolderVar *phv)

int assign_special_exec_param(PlannerInfo *root)

Param * replace_nestloop_param_var(PlannerInfo *root, Var *var)

Index assignSortGroupRef(TargetEntry *tle, List *tlist)

TargetEntry * get_tle_by_resno(List *tlist, AttrNumber resno)

int make_partition_pruneinfo(PlannerInfo *root, RelOptInfo *parentrel, List *subpaths, List *prunequal)

bool pathkeys_contained_in(List *keys1, List *keys2)

Path * reparameterize_path_by_child(PlannerInfo *root, Path *path, RelOptInfo *child_rel)

#define IS_DUMMY_APPEND(p)

#define planner_rt_fetch(rti, root)

#define IS_OTHER_REL(rel)

int errdetail_relkind_not_supported(char relkind)

#define lfirst_node(type, lc)

static int list_length(const List *l)

#define forboth(cell1, list1, cell2, list2)

#define for_each_from(cell, lst, N)

static ListCell * list_head(const List *l)

static ListCell * lnext(const List *l, const ListCell *c)

static int list_nth_int(const List *list, int n)

PlaceHolderInfo * find_placeholder_info(PlannerInfo *root, PlaceHolderVar *phv)

bool has_stored_generated_columns(PlannerInfo *root, Index rti)

bool has_row_triggers(PlannerInfo *root, Index rti, CmdType event)

List * build_physical_tlist(PlannerInfo *root, RelOptInfo *rel)

List * infer_arbiter_indexes(PlannerInfo *root)

int restrict_nonsystem_relation_kind

bool predicate_implied_by(List *predicate_list, List *clause_list, bool weak)

List * extract_update_targetlist_colnos(List *tlist)

#define IS_SPECIAL_VARNO(varno)

static const struct fns functions

static struct subre * parse(struct vars *v, int stopper, int type, struct state *init, struct state *final)

List * extract_actual_clauses(List *restrictinfo_list, bool pseudoconstant)

void extract_actual_join_clauses(List *restrictinfo_list, Relids joinrelids, List **joinquals, List **otherquals)

List * get_actual_clauses(List *restrictinfo_list)

bool trivial_subqueryscan(SubqueryScan *plan)

void check_stack_depth(void)

Selectivity bitmapselectivity

Selectivity bitmapselectivity

struct Plan *(* PlanCustomPath)(PlannerInfo *root, RelOptInfo *rel, struct CustomPath *best_path, List *tlist, List *clauses, List *custom_plans)

const struct CustomPathMethods * methods

Bitmapset * custom_relids

BeginDirectModify_function BeginDirectModify

PlanForeignModify_function PlanForeignModify

PlanDirectModify_function PlanDirectModify

IterateDirectModify_function IterateDirectModify

EndDirectModify_function EndDirectModify

IsForeignPathAsyncCapable_function IsForeignPathAsyncCapable

Bitmapset * fs_base_relids

Cardinality inner_rows_total

struct RestrictInfo * rinfo

ScanDirection indexorderdir

ScanDirection indexscandir

Selectivity indexselectivity

ScanDirection indexorderdir

List * withCheckOptionLists

List * mergeJoinConditions

OnConflictExpr * onconflict

List * mergeJoinConditions

Bitmapset * fdwDirectModifyPlans

List * withCheckOptionLists

OnConflictAction onConflictAction

struct TableSampleClause * tablesample

struct PathTarget * reltarget

struct TableSampleClause * tablesample

SubqueryScanStatus scanstatus

void SS_attach_initplans(PlannerInfo *root, Plan *plan)

void SS_compute_initplan_cost(List *init_plans, Cost *initplan_cost_p, bool *unsafe_initplans_p)

void SS_make_initplan_from_plan(PlannerInfo *root, PlannerInfo *subroot, Plan *plan, Param *prm)

#define FirstLowInvalidHeapAttributeNumber

#define RESTRICT_RELKIND_FOREIGN_TABLE

Oid * extract_grouping_ops(List *groupClause)

TargetEntry * tlist_member(Expr *node, List *targetlist)

bool tlist_same_exprs(List *tlist1, List *tlist2)

void apply_tlist_labeling(List *dest_tlist, List *src_tlist)

void apply_pathtarget_labeling_to_tlist(List *tlist, PathTarget *target)

AttrNumber * extract_grouping_cols(List *groupClause, List *tlist)

TargetEntry * get_sortgroupclause_tle(SortGroupClause *sgClause, List *targetList)

TargetEntry * get_sortgroupref_tle(Index sortref, List *targetList)

Oid * extract_grouping_collations(List *groupClause, List *tlist)

#define FirstNormalObjectId

void pull_varattnos(Node *node, Index varno, Bitmapset **varattnos)

bool contain_vars_returning_old_or_new(Node *node)