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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

17

18#include <limits.h>

19#include <math.h>

20

37#ifdef OPTIMIZER_DEBUG

39#endif

66

67

72

73

75

76

78

79

81

82

84

85

86

87#define EXPRKIND_QUAL 0

88#define EXPRKIND_TARGET 1

89#define EXPRKIND_RTFUNC 2

90#define EXPRKIND_RTFUNC_LATERAL 3

91#define EXPRKIND_VALUES 4

92#define EXPRKIND_VALUES_LATERAL 5

93#define EXPRKIND_LIMIT 6

94#define EXPRKIND_APPINFO 7

95#define EXPRKIND_PHV 8

96#define EXPRKIND_TABLESAMPLE 9

97#define EXPRKIND_ARBITER_ELEM 10

98#define EXPRKIND_TABLEFUNC 11

99#define EXPRKIND_TABLEFUNC_LATERAL 12

100#define EXPRKIND_GROUPEXPR 13

101

102

103

104

116

117

118

119

120

121typedef struct

122{

125

127

128

129typedef struct

130{

134

136

137

144 int *tleref_to_colnum_map);

147 double tuple_fraction,

148 int64 *offset_est, int64 *count_est);

160 bool target_parallel_safe,

167 PathTarget *target, bool target_parallel_safe,

168 Node *havingQual);

190 List *activeWindows);

197 List *activeWindows);

214 bool target_parallel_safe,

215 double limit_tuples);

220 Node *havingQual);

228 List *activeWindows);

230 List *tlist);

252 List *pathkeys,

253 double limit_tuples);

271 List *targetList,

272 List *groupClause);

275 List *targetlist);

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

315planner(Query *parse, const char *query_string, int cursorOptions,

317{

319

321 result = (*planner_hook) (parse, query_string, cursorOptions,

322 boundParams, es);

323 else

325 boundParams, es);

326

328

329 return result;

330}

331

335{

338 double tuple_fraction;

345

346

347

348

349

350

351

353

354 glob->boundParams = boundParams;

357 glob->subroots = NIL;

375 glob->partition_directory = NULL;

376 glob->rel_notnullatts_hash = NULL;

377

378

379

380

381

382

383

384

385

386

387

388

389

390

391

392

393

394

395

396

397

398

402 parse->hasModifyingCTE &&

405 {

406

409 }

410 else

411 {

412

415 }

416

417

418

419

420

421

422

423

424

425

426

427

428

429

430

431

432

433

436

437

439 {

440

441

442

443

444

445

446

448

449

450

451

452

453

454 if (tuple_fraction >= 1.0)

455 tuple_fraction = 0.0;

456 else if (tuple_fraction <= 0.0)

457 tuple_fraction = 1e-10;

458 }

459 else

460 {

461

462 tuple_fraction = 0.0;

463 }

464

465

466

467

468

469

470

471

472

473

474

475

476

477

478

492 {

496 }

498 {

504 }

511

512

514 (*planner_setup_hook) (glob, parse, query_string, cursorOptions,

515 &tuple_fraction, es);

516

517

520

521

524

526

527

528

529

530

532 {

535 }

536

537

538

539

540

541

542

543

544

545

546

547

548

553 {

557

562 gather->num_workers = 1;

563 gather->single_copy = true;

565

566

569

570

571

572

573

574 gather->rescan_param = -1;

575

576

577

578

579

586 gather->plan.parallel_aware = false;

587 gather->plan.parallel_safe = false;

588

589

590

591

592

597

598

599 root->glob->parallelModeNeeded = true;

600

602 }

603

604

605

606

607

608

609

611 {

614 {

617

619 }

621 }

622

623

630

633 {

636

638 }

639

640

642

667

672

676 {

678

679

680

681

688

689

690

691

696 }

697

698

700 (*planner_shutdown_hook) (glob, parse, query_string, result);

701

702 if (glob->partition_directory != NULL)

704

705 return result;

706}

707

708

709

710

711

712

713

714

715

716

717

718

719

720

721

722

723

724

725

726

727

728

729

730

731

732

733

734

735

736

737

738

739

740

741

746{

754

755

758 root->glob = glob;

760 root->plan_name = plan_name;

766 root->cte_plan_ids = NIL;

767 root->multiexpr_params = NIL;

768 root->join_domains = NIL;

770 root->ec_merging_done = false;

771 root->last_rinfo_serial = 0;

772 root->all_result_relids =

774 root->leaf_result_relids = NULL;

775 root->append_rel_list = NIL;

776 root->row_identity_vars = NIL;

778 memset(root->upper_rels, 0, sizeof(root->upper_rels));

779 memset(root->upper_targets, 0, sizeof(root->upper_targets));

780 root->processed_groupClause = NIL;

781 root->processed_distinctClause = NIL;

782 root->processed_tlist = NIL;

783 root->update_colnos = NIL;

786 root->qual_security_level = 0;

787 root->hasPseudoConstantQuals = false;

788 root->hasAlternativeSubPlans = false;

789 root->placeholdersFrozen = false;

790 root->hasRecursion = hasRecursion;

791 root->assumeReplanning = false;

792 if (hasRecursion)

794 else

795 root->wt_param_id = -1;

796 root->non_recursive_path = NULL;

797

798

799

800

801

802

804

805

806

807

808

809 if (parse->cteList)

811

812

813

814

816

817

818

819

820

821

822

823

824

825

826

828

829

830

831

832

834

835

836

837

838

839

840

841 if (parse->hasSubLinks)

843

844

845

846

847

848

849

851

852

853

854

855

857

858

859

860

861

862

863

864 if (parse->setOperations)

866

867

868

869

870

871

872

873

874

875

876

877 root->hasJoinRTEs = false;

878 root->hasLateralRTEs = false;

879 root->group_rtindex = 0;

882 foreach(l, parse->rtable)

883 {

885

886 switch (rte->rtekind)

887 {

889 root->hasJoinRTEs = true;

892 break;

895 break;

899 break;

900 default:

901

902 break;

903 }

904

905 if (rte->lateral)

906 root->hasLateralRTEs = true;

907

908

909

910

911

912

913

914 if (rte->securityQuals)

915 root->qual_security_level = Max(root->qual_security_level,

917 }

918

919

920

921

922

923 if (parse->resultRelation)

924 {

926

927 if (rte->inh)

928 root->leaf_result_relids =

930 }

931

932

933

934

935

936

937

938

939

940

941

942

943

944

945

946 foreach(l, parse->rtable)

947 {

949

950 if (rte->perminfoindex != 0 &&

952 {

954 bool result;

955

958 if (!result)

961 }

962 }

963

964

965

966

967

969

970

971

972

973

974

975 root->hasHavingQual = (parse->havingQual != NULL);

976

977

978

979

980

981

982

986

988 foreach(l, parse->withCheckOptions)

989 {

991

996 }

998

1002

1004

1007

1008 foreach(l, parse->windowClause)

1009 {

1011

1012

1017 }

1018

1023

1024 if (parse->onConflict)

1025 {

1026 parse->onConflict->arbiterElems = (List *)

1028 (Node *) parse->onConflict->arbiterElems,

1030 parse->onConflict->arbiterWhere =

1032 parse->onConflict->arbiterWhere,

1034 parse->onConflict->onConflictSet = (List *)

1036 (Node *) parse->onConflict->onConflictSet,

1038 parse->onConflict->onConflictWhere =

1040 parse->onConflict->onConflictWhere,

1042

1043 }

1044

1045 foreach(l, parse->mergeActionList)

1046 {

1048

1049 action->targetList = (List *)

1051 (Node *) action->targetList,

1053 action->qual =

1055 (Node *) action->qual,

1057 }

1058

1059 parse->mergeJoinCondition =

1061

1062 root->append_rel_list = (List *)

1065

1066

1067 foreach(l, parse->rtable)

1068 {

1070 int kind;

1072

1074 {

1075 if (rte->tablesample)

1078 (Node *) rte->tablesample,

1080 }

1082 {

1083

1084

1085

1086

1087

1088

1089

1090 if (rte->lateral && root->hasJoinRTEs)

1093 (Node *) rte->subquery);

1094 }

1096 {

1097

1099 rte->functions = (List *)

1101 }

1103 {

1104

1108 }

1110 {

1111

1113 rte->values_lists = (List *)

1115 }

1117 {

1118

1119 rte->groupexprs = (List *)

1122 }

1123

1124

1125

1126

1127

1128

1129

1130 foreach(lcsq, rte->securityQuals)

1131 {

1135 }

1136 }

1137

1138

1139

1140

1141

1142

1143

1144

1145

1146

1147

1148

1149 if (root->hasJoinRTEs)

1150 {

1151 foreach(l, parse->rtable)

1152 {

1154

1155 rte->joinaliasvars = NIL;

1156 }

1157 }

1158

1159

1160

1161

1162

1163

1164

1165

1166

1167

1168 if (parse->hasGroupRTE)

1169 {

1172 parse->havingQual =

1174 }

1175

1176

1177 if (parse->hasTargetSRFs)

1179

1180

1181

1182

1183

1184

1185

1186 if (parse->groupingSets)

1187 {

1188 parse->groupingSets =

1190 }

1191

1192

1193

1194

1195

1196

1197

1198

1199

1200

1201

1202

1203

1204

1205

1206

1207

1208

1209

1210

1211

1212

1213

1214

1215

1216

1217

1218

1219

1220

1221

1222

1223

1224

1225

1226

1227

1228

1229

1230

1231

1232

1233

1235 foreach(l, (List *) parse->havingQual)

1236 {

1238

1242 (parse->groupClause && parse->groupingSets &&

1244 {

1245

1247 }

1248 else if (parse->groupClause &&

1249 (parse->groupingSets == NIL ||

1251 {

1252

1254

1255

1258

1259 parse->jointree->quals = (Node *)

1262 }

1263 else

1264 {

1265

1267

1268

1271

1272 parse->jointree->quals = (Node *)

1275

1277 }

1278 }

1280

1281

1282

1283

1284

1285

1288

1289

1290

1291

1292

1293

1294

1297

1298

1299

1300

1302

1303

1304

1305

1306

1308

1309

1310

1311

1312

1313

1314

1317

1318

1319

1320

1321

1322

1324

1325 return root;

1326}

1327

1328

1329

1330

1331

1332

1333

1334static Node *

1336{

1337

1338

1339

1340

1341

1342 if (expr == NULL)

1343 return NULL;

1344

1345

1346

1347

1348

1349

1350

1351

1352

1353

1354 if (root->hasJoinRTEs &&

1360

1361

1362

1363

1364

1365

1366

1367

1368

1369

1370

1371

1372

1373

1374

1375

1376

1377

1378

1379

1382

1383

1384

1385

1387 {

1389

1390#ifdef OPTIMIZER_DEBUG

1391 printf("After canonicalize_qual()\n");

1393#endif

1394 }

1395

1396

1397

1398

1399

1400

1402 {

1404 }

1405

1406

1407 if (root->parse->hasSubLinks)

1409

1410

1411

1412

1413

1414

1415

1416 if (root->query_level > 1)

1418

1419

1420

1421

1422

1423

1424

1427

1428 return expr;

1429}

1430

1431

1432

1433

1434

1435

1436static void

1438{

1439 if (jtnode == NULL)

1440 return;

1442 {

1443

1444 }

1446 {

1449

1452

1454 }

1456 {

1458

1461

1463 }

1464 else

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

1467}

1468

1469

1470

1471

1472

1473

1474

1475

1476

1477

1478

1479

1485

1486

1487

1488

1489

1490

1491

1492

1493

1494

1495

1496

1497

1498

1499

1500

1501

1502

1503

1504

1505

1506

1507

1508

1509

1510

1511

1512

1513static void

1516{

1518 int64 offset_est = 0;

1519 int64 count_est = 0;

1520 double limit_tuples = -1.0;

1530

1531

1532 if (parse->limitCount || parse->limitOffset)

1533 {

1535 &offset_est, &count_est);

1536

1537

1538

1539

1540

1541 if (count_est > 0 && offset_est >= 0)

1542 limit_tuples = (double) count_est + (double) offset_est;

1543 }

1544

1545

1546 root->tuple_fraction = tuple_fraction;

1547

1548 if (parse->setOperations)

1549 {

1550

1551

1552

1553

1554

1555

1557

1558

1559

1560

1561

1562

1563

1564

1566

1567

1568 root->processed_tlist =

1570 parse->targetList);

1571

1572

1574

1575

1578

1579

1582

1583

1584

1585

1586

1587 if (parse->rowMarks)

1590

1591

1592 errmsg("%s is not allowed with UNION/INTERSECT/EXCEPT",

1594 parse->rowMarks)->strength))));

1595

1596

1597

1598

1601 parse->sortClause,

1602 root->processed_tlist);

1603 }

1604 else

1605 {

1606

1622 List *activeWindows = NIL;

1625

1626

1628

1629

1630 if (parse->groupingSets)

1631 {

1633 }

1634 else if (parse->groupClause)

1635 {

1636

1638 }

1639

1640

1641

1642

1643

1644

1645

1646

1648

1649

1650

1651

1652

1653

1654

1655

1656 if (parse->hasAggs)

1657 {

1660 }

1661

1662

1663

1664

1665

1666

1667

1668 if (parse->hasWindowFuncs)

1669 {

1672 if (wflists->numWindowFuncs > 0)

1673 {

1674

1675

1676

1677

1678

1680

1681

1683

1684

1686 }

1687 else

1688 parse->hasWindowFuncs = false;

1689 }

1690

1691

1692

1693

1694

1695

1696

1697 if (parse->hasAggs)

1699

1700

1701

1702

1703

1704

1705

1706 if (parse->groupClause ||

1707 parse->groupingSets ||

1708 parse->distinctClause ||

1709 parse->hasAggs ||

1710 parse->hasWindowFuncs ||

1711 parse->hasTargetSRFs ||

1712 root->hasHavingQual)

1713 root->limit_tuples = -1.0;

1714 else

1715 root->limit_tuples = limit_tuples;

1716

1717

1718 qp_extra.activeWindows = activeWindows;

1719 qp_extra.gset_data = gset_data;

1720

1721

1722

1723

1724

1726

1727

1728

1729

1730

1731

1732

1733

1735

1736

1737

1738

1739

1740

1741

1742

1743

1744

1748

1749

1750

1751

1752

1753

1754 if (parse->sortClause)

1755 {

1761 }

1762 else

1763 {

1766 }

1767

1768

1769

1770

1771

1772

1773 if (activeWindows)

1774 {

1777 activeWindows);

1780 }

1781 else

1782 {

1785 }

1786

1787

1788

1789

1790

1791

1793 parse->hasAggs || root->hasHavingQual);

1795 {

1799 }

1800 else

1801 {

1804 }

1805

1806

1807

1808

1809

1810

1811

1812 if (parse->hasTargetSRFs)

1813 {

1814

1820

1826

1833

1839 }

1840 else

1841 {

1842

1848 }

1849

1850

1857

1858

1859

1860

1861

1862

1863

1864

1871

1872

1873

1874

1875

1876

1878 {

1883 gset_data);

1884

1885 if (parse->hasTargetSRFs)

1889 }

1890

1891

1892

1893

1894

1895 if (activeWindows)

1896 {

1903 activeWindows);

1904

1905 if (parse->hasTargetSRFs)

1909 }

1910

1911

1912

1913

1914

1915 if (parse->distinctClause)

1916 {

1920 }

1921 }

1922

1923

1924

1925

1926

1927

1928

1929

1930 if (parse->sortClause)

1931 {

1937 limit_tuples);

1938

1939 if (parse->hasTargetSRFs)

1943 }

1944

1945

1946

1947

1949

1950

1951

1952

1953

1954

1955

1956

1960 final_rel->consider_parallel = true;

1961

1962

1963

1964

1969

1970

1971

1972

1973

1975 {

1977

1978

1979

1980

1981

1982

1983

1984

1985 if (parse->rowMarks)

1986 {

1988 root->rowMarks,

1990 }

1991

1992

1993

1994

1996 {

1998 parse->limitOffset,

1999 parse->limitCount,

2000 parse->limitOption,

2001 offset_est, count_est);

2002 }

2003

2004

2005

2006

2008 {

2009 Index rootRelation;

2010 List *resultRelations = NIL;

2011 List *updateColnosLists = NIL;

2012 List *withCheckOptionLists = NIL;

2013 List *returningLists = NIL;

2014 List *mergeActionLists = NIL;

2015 List *mergeJoinConditions = NIL;

2016 List *rowMarks;

2017

2019 {

2020

2022 parse->resultRelation);

2023 int resultRelation = -1;

2024

2025

2026 rootRelation = parse->resultRelation;

2027

2028

2030 resultRelation)) >= 0)

2031 {

2033 resultRelation);

2034

2035

2036

2037

2038

2039

2041 continue;

2042

2043

2044 resultRelations = lappend_int(resultRelations,

2045 resultRelation);

2047 {

2048 List *update_colnos = root->update_colnos;

2049

2051 update_colnos =

2053 update_colnos,

2056 updateColnosLists = lappend(updateColnosLists,

2057 update_colnos);

2058 }

2059 if (parse->withCheckOptions)

2060 {

2062

2069 withCheckOptionLists = lappend(withCheckOptionLists,

2071 }

2072 if (parse->returningList)

2073 {

2074 List *returningList = parse->returningList;

2075

2077 returningList = (List *)

2079 (Node *) returningList,

2082 returningLists = lappend(returningLists,

2083 returningList);

2084 }

2085 if (parse->mergeActionList)

2086 {

2088 List *mergeActionList = NIL;

2089

2090

2091

2092

2093

2094 foreach(l, parse->mergeActionList)

2095 {

2098

2101 (Node *) action->qual,

2106 (Node *) action->targetList,

2112 action->updateColnos,

2115 mergeActionList = lappend(mergeActionList,

2117 }

2118

2119 mergeActionLists = lappend(mergeActionLists,

2120 mergeActionList);

2121 }

2123 {

2124 Node *mergeJoinCondition = parse->mergeJoinCondition;

2125

2127 mergeJoinCondition =

2129 mergeJoinCondition,

2132 mergeJoinConditions = lappend(mergeJoinConditions,

2133 mergeJoinCondition);

2134 }

2135 }

2136

2137 if (resultRelations == NIL)

2138 {

2139

2140

2141

2142

2143

2144

2145

2146

2147

2148

2149

2152 updateColnosLists = list_make1(root->update_colnos);

2153 if (parse->withCheckOptions)

2154 withCheckOptionLists = list_make1(parse->withCheckOptions);

2155 if (parse->returningList)

2157 if (parse->mergeActionList)

2160 mergeJoinConditions = list_make1(parse->mergeJoinCondition);

2161 }

2162 }

2163 else

2164 {

2165

2166 rootRelation = 0;

2169 updateColnosLists = list_make1(root->update_colnos);

2170 if (parse->withCheckOptions)

2171 withCheckOptionLists = list_make1(parse->withCheckOptions);

2172 if (parse->returningList)

2174 if (parse->mergeActionList)

2177 mergeJoinConditions = list_make1(parse->mergeJoinCondition);

2178 }

2179

2180

2181

2182

2183

2184

2185 if (parse->rowMarks)

2186 rowMarks = NIL;

2187 else

2188 rowMarks = root->rowMarks;

2189

2190 path = (Path *)

2192 path,

2193 parse->commandType,

2194 parse->canSetTag,

2195 parse->resultRelation,

2196 rootRelation,

2197 resultRelations,

2198 updateColnosLists,

2199 withCheckOptionLists,

2200 returningLists,

2201 rowMarks,

2202 parse->onConflict,

2203 mergeActionLists,

2204 mergeJoinConditions,

2206 }

2207

2208

2210 }

2211

2212

2213

2214

2215

2216 if (final_rel->consider_parallel && root->query_level > 1 &&

2218 {

2221 {

2223

2225 }

2226 }

2227

2232

2233

2234

2235

2236

2238 final_rel->fdwroutine->GetForeignUpperPaths)

2241 &extra);

2242

2243

2247

2248

2249}

2250

2251

2252

2253

2254

2255

2256

2257

2258

2259

2262{

2268

2269

2270

2271

2272

2273 root->processed_groupClause = parse->groupClause;

2274

2275

2276 gd->any_hashable = false;

2277 gd->unhashable_refs = NULL;

2278 gd->unsortable_refs = NULL;

2279 gd->unsortable_sets = NIL;

2280

2281 if (parse->groupClause)

2282 {

2284

2285 foreach(lc, parse->groupClause)

2286 {

2289

2292

2293 if (gc->hashable)

2295

2298 }

2299 }

2300

2301

2302 gd->tleref_to_colnum_map = (int *) palloc((maxref + 1) * sizeof(int));

2303

2304

2305

2306

2307

2308

2309

2311 {

2314

2315 foreach(lc, parse->groupingSets)

2316 {

2318

2320 {

2322

2324 gd->unsortable_sets = lappend(gd->unsortable_sets, gs);

2325

2326

2327

2328

2329

2330

2331

2332

2333

2337 errmsg("could not implement GROUP BY"),

2338 errdetail("Some of the datatypes only support hashing, while others only support sorting.")));

2339 }

2340 else

2342 }

2343

2346 else

2348 }

2349 else

2351

2353 {

2357

2358

2359

2360

2361

2362

2363

2364

2365

2366

2367

2370 ? parse->sortClause

2371 : NIL));

2372

2373

2374

2375

2377

2378

2379

2380

2381

2382

2383

2384

2385

2386

2387 if (gs->set)

2389 else

2391

2392

2393

2394

2395

2396

2397

2398 if (gs->set &&

2400 {

2401 rollup->hashable = true;

2402 gd->any_hashable = true;

2403 }

2404

2405

2406

2407

2408

2409

2410

2411

2414 gd->tleref_to_colnum_map);

2416

2418 }

2419

2420 if (gd->unsortable_sets)

2421 {

2422

2423

2424

2425

2426

2428 gd->unsortable_sets,

2429 gd->tleref_to_colnum_map);

2430 gd->any_hashable = true;

2431 }

2432

2433 return gd;

2434}

2435

2436

2437

2438

2439

2440static List *

2442 List *gsets,

2443 int *tleref_to_colnum_map)

2444{

2445 int ref = 0;

2448

2449 foreach(lc, groupClause)

2450 {

2452

2453 tleref_to_colnum_map[gc->tleSortGroupRef] = ref++;

2454 }

2455

2456 foreach(lc, gsets)

2457 {

2461

2462 foreach(lc2, gs->set)

2463 {

2465 }

2466

2467 result = lappend(result, set);

2468 }

2469

2470 return result;

2471}

2472

2473

2474

2475

2476

2477static void

2479{

2484 int i;

2485

2486 if (parse->rowMarks)

2487 {

2488

2489

2490

2491

2492

2493

2495 parse->rowMarks)->strength);

2496 }

2497 else

2498 {

2499

2500

2501

2502

2506 return;

2507 }

2508

2509

2510

2511

2512

2513

2515 if (parse->resultRelation)

2517

2518

2519

2520

2522 foreach(l, parse->rowMarks)

2523 {

2527

2528

2529

2530

2531

2532

2534

2535

2536

2537

2538

2539

2540

2542 continue;

2543

2545

2548 newrc->rowmarkId = ++(root->glob->lastRowMarkId);

2550 newrc->allMarkTypes = (1 << newrc->markType);

2553 newrc->isParent = false;

2554

2556 }

2557

2558

2559

2560

2561 i = 0;

2562 foreach(l, parse->rtable)

2563 {

2566

2567 i++;

2569 continue;

2570

2573 newrc->rowmarkId = ++(root->glob->lastRowMarkId);

2575 newrc->allMarkTypes = (1 << newrc->markType);

2578 newrc->isParent = false;

2579

2581 }

2582

2584}

2585

2586

2587

2588

2591{

2593 {

2594

2596 }

2598 {

2599

2601

2604

2606 }

2607 else

2608 {

2609

2610 switch (strength)

2611 {

2613

2614

2615

2616

2617

2619 break;

2622 break;

2625 break;

2628 break;

2631 break;

2632 }

2633 elog(ERROR, "unrecognized LockClauseStrength %d", (int) strength);

2635 }

2636}

2637

2638

2639

2640

2641

2642

2643

2644

2645

2646

2647

2648

2649

2650

2651

2652

2653

2654

2655static double

2657 int64 *offset_est, int64 *count_est)

2658{

2662

2663

2665

2666

2667

2668

2669

2670 if (parse->limitCount)

2671 {

2674 {

2676 {

2677

2678 *count_est = 0;

2679 }

2680 else

2681 {

2683 if (*count_est <= 0)

2684 *count_est = 1;

2685 }

2686 }

2687 else

2688 *count_est = -1;

2689 }

2690 else

2691 *count_est = 0;

2692

2693 if (parse->limitOffset)

2694 {

2697 {

2699 {

2700

2701 *offset_est = 0;

2702 }

2703 else

2704 {

2706 if (*offset_est < 0)

2707 *offset_est = 0;

2708 }

2709 }

2710 else

2711 *offset_est = -1;

2712 }

2713 else

2714 *offset_est = 0;

2715

2716 if (*count_est != 0)

2717 {

2718

2719

2720

2721

2722

2723 if (*count_est < 0 || *offset_est < 0)

2724 {

2725

2727 }

2728 else

2729 {

2730

2732 }

2733

2734

2735

2736

2737

2738

2739

2740

2741 if (tuple_fraction >= 1.0)

2742 {

2744 {

2745

2747 }

2748 else

2749 {

2750

2751 }

2752 }

2753 else if (tuple_fraction > 0.0)

2754 {

2756 {

2757

2759 }

2760 else

2761 {

2762

2764 }

2765 }

2766 else

2767 {

2768

2770 }

2771 }

2772 else if (*offset_est != 0 && tuple_fraction > 0.0)

2773 {

2774

2775

2776

2777

2778

2779

2780

2781

2782

2783 if (*offset_est < 0)

2785 else

2787

2788

2789

2790

2791

2792

2793

2794 if (tuple_fraction >= 1.0)

2795 {

2797 {

2798

2800 }

2801 else

2802 {

2803

2805 }

2806 }

2807 else

2808 {

2810 {

2811

2812 }

2813 else

2814 {

2815

2817 if (tuple_fraction >= 1.0)

2818 tuple_fraction = 0.0;

2819 }

2820 }

2821 }

2822

2823 return tuple_fraction;

2824}

2825

2826

2827

2828

2829

2830

2831

2832

2833

2834

2835

2836

2837

2838

2839

2840bool

2842{

2844

2845 node = parse->limitCount;

2846 if (node)

2847 {

2849 {

2850

2852 return true;

2853 }

2854 else

2855 return true;

2856 }

2857

2858 node = parse->limitOffset;

2859 if (node)

2860 {

2862 {

2863

2865 {

2867

2868 if (offset != 0)

2869 return true;

2870 }

2871 }

2872 else

2873 return true;

2874 }

2875

2876 return false;

2877}

2878

2879

2880

2881

2882

2883

2884

2885

2886

2887

2888

2889

2890

2891

2892

2893

2894

2895

2896

2897

2898

2899

2900

2901

2902

2903

2904

2905

2906static List *

2908{

2913

2914

2915 if (force)

2916 {

2917 foreach(sl, force)

2918 {

2921

2923 }

2924

2926 }

2927

2928

2929 if (parse->sortClause == NIL)

2931

2932

2933

2934

2935

2936

2937

2938 foreach(sl, parse->sortClause)

2939 {

2941

2942 foreach(gl, parse->groupClause)

2943 {

2945

2947 {

2949 break;

2950 }

2951 }

2953 break;

2954 }

2955

2956

2957

2960

2961

2962

2963

2964

2965

2966

2967 foreach(gl, parse->groupClause)

2968 {

2970

2972 continue;

2973 if (OidIsValid(gc->sortop))

2976 }

2977

2978

2981}

2982

2983

2984

2985

2986

2987

2988

2989

2990

2991

2992

2993

2994

2995

2996

2997

2998

2999

3000

3001

3002static List *

3004{

3007 int num_sets = 0;

3010 List **results;

3014 short **adjacency;

3017 int i;

3018 int j;

3022

3023

3024

3025

3026

3027

3029 {

3032 }

3033

3034

3035 if (lc1)

3037

3038

3039

3040

3041

3042

3043

3044

3045

3046

3047

3048

3049

3050

3051

3052

3053

3054

3055

3060

3062 j = 0;

3063 i = 1;

3064

3066 {

3071

3073 {

3075 }

3076

3077

3079 {

3080 int k;

3081

3082 for (k = j; k < i; ++k)

3083 {

3085 {

3087 break;

3088 }

3089 }

3090 }

3092 {

3094 j = i;

3095 }

3096

3098 {

3101 }

3102 else

3103 {

3104 int k;

3106

3109

3110

3111

3112 for (k = j - 1; k > 0; --k)

3113 {

3116 }

3117

3119 {

3121 adjacency[i] = palloc((n_adj + 1) * sizeof(short));

3123 }

3124 else

3125 adjacency[i] = NULL;

3126

3127 ++i;

3128 }

3129 }

3130

3132

3133

3134

3135

3137

3138

3139

3140

3141

3142

3143

3145

3147 {

3148 int u = state->pair_vu[i];

3149 int v = state->pair_uv[i];

3150

3151 if (u > 0 && u < i)

3153 else if (v > 0 && v < i)

3155 else

3157 }

3158

3159

3161

3163 {

3165

3167

3169 }

3170

3171

3173 results[1] = lcons(NIL, results[1]);

3174

3175

3177 result = lappend(result, results[i]);

3178

3179

3180

3181

3182

3183

3184

3189 if (adjacency[i])

3190 pfree(adjacency[i]);

3191 pfree(adjacency);

3197

3198 return result;

3199}

3200

3201

3202

3203

3204

3205

3206

3207

3208

3209

3210

3211

3212

3213

3214static List *

3216{

3220

3221 foreach(lc, groupingSets)

3222 {

3226

3229 {

3231 int ref = sc->tleSortGroupRef;

3232

3234 {

3237 }

3238 else

3239 {

3240

3242 break;

3243 }

3244 }

3245

3247

3249 result = lcons(gs, result);

3250 }

3251

3253

3254 return result;

3255}

3256

3257

3258

3259

3260

3261

3262static bool

3264{

3266

3267 foreach(lc, keys)

3268 {

3270

3271 if (pathkey->pk_eclass->ec_has_volatile)

3272 return true;

3273 }

3274

3275 return false;

3276}

3277

3278

3279

3280

3281

3282

3283

3284

3285

3286

3287

3288

3289

3290

3291

3292

3293

3294

3295

3296

3297

3298

3299

3300

3301

3302

3303

3304

3305

3306

3307static void

3309{

3315 int i;

3316

3317

3319

3321

3322

3324 return;

3325

3326

3327

3328

3329

3331 foreach(lc, root->agginfos)

3332 {

3335

3337 continue;

3338

3339

3341 continue;

3342

3343

3345 {

3348

3349

3350

3351

3352

3353

3354

3355

3356

3357

3358

3359

3360

3361

3362 foreach(lc2, aggref->args)

3363 {

3366

3369

3370

3372 continue;

3373

3374

3376 break;

3377 }

3378

3379

3381 continue;

3382 }

3383

3386 }

3387

3388

3389

3390

3391

3392

3393

3394

3395

3396

3397

3398

3399

3400

3401

3402

3406 {

3409

3410 i = -1;

3412 {

3416 List *pathkeys;

3417

3420 else

3422

3424 aggref->args);

3425

3426

3427

3428

3429

3431 {

3433 continue;

3434 }

3435

3436

3437

3438

3439

3441 {

3443

3444

3448

3449

3451 }

3452 else

3453 {

3454

3455

3456

3459 pathkeys);

3460

3461

3463 {

3465

3468

3470

3472

3474

3476 break;

3477

3479 break;

3480 }

3481 }

3482 }

3483

3484

3486

3487

3488

3489

3490

3492 {

3495 }

3496 }

3497

3498

3499

3500

3501

3502

3505

3506

3507

3508

3509

3510

3511

3512

3513

3514 i = -1;

3516 {

3518

3520 {

3522

3523 aggref->aggpresorted = true;

3524 }

3525 }

3526}

3527

3528

3529

3530

3531static void

3533{

3536 List *tlist = root->processed_tlist;

3537 List *activeWindows = qp_extra->activeWindows;

3538

3539

3540

3541

3542

3544 {

3545

3546

3547

3548

3549

3550

3551 List *rollups = qp_extra->gset_data->rollups;

3553

3555 {

3557

3558

3559

3560

3561

3562

3563

3564 root->group_pathkeys =

3566 &groupClause,

3567 tlist,

3568 false,

3569 parse->hasGroupRTE,

3571 false);

3574 }

3575 else

3576 {

3577 root->group_pathkeys = NIL;

3578 root->num_groupby_pathkeys = 0;

3579 }

3580 }

3581 else if (parse->groupClause || root->numOrderedAggs > 0)

3582 {

3583

3584

3585

3586

3587

3588

3589

3590

3592

3593

3594

3595

3596

3597 root->group_pathkeys =

3599 &root->processed_groupClause,

3600 tlist,

3601 true,

3602 false,

3604 true);

3606 {

3607

3608 root->group_pathkeys = NIL;

3609 root->num_groupby_pathkeys = 0;

3610 }

3611 else

3612 {

3614

3615 if (root->numOrderedAggs > 0)

3617 }

3618 }

3619 else

3620 {

3621 root->group_pathkeys = NIL;

3622 root->num_groupby_pathkeys = 0;

3623 }

3624

3625

3626 if (activeWindows != NIL)

3627 {

3629

3631 wc,

3632 tlist);

3633 }

3634 else

3635 root->window_pathkeys = NIL;

3636

3637

3638

3639

3640

3641

3642

3643 if (parse->distinctClause)

3644 {

3646

3647

3649 root->distinct_pathkeys =

3651 &root->processed_distinctClause,

3652 tlist,

3653 true,

3654 false,

3656 false);

3658 root->distinct_pathkeys = NIL;

3659 }

3660 else

3661 root->distinct_pathkeys = NIL;

3662

3663 root->sort_pathkeys =

3665 parse->sortClause,

3666 tlist);

3667

3668

3670 {

3671 List *groupClauses;

3673

3675

3676 root->setop_pathkeys =

3678 &groupClauses,

3679 tlist,

3680 false,

3681 false,

3683 false);

3685 root->setop_pathkeys = NIL;

3686 }

3687 else

3688 root->setop_pathkeys = NIL;

3689

3690

3691

3692

3693

3694

3695

3696

3697

3698

3699

3700

3701

3702

3703

3704

3705

3706

3707

3708

3709

3710 if (root->group_pathkeys)

3711 root->query_pathkeys = root->group_pathkeys;

3712 else if (root->window_pathkeys)

3713 root->query_pathkeys = root->window_pathkeys;

3716 root->query_pathkeys = root->distinct_pathkeys;

3717 else if (root->sort_pathkeys)

3718 root->query_pathkeys = root->sort_pathkeys;

3719 else if (root->setop_pathkeys != NIL)

3720 root->query_pathkeys = root->setop_pathkeys;

3721 else

3722 root->query_pathkeys = NIL;

3723}

3724

3725

3726

3727

3728

3729

3730

3731

3732

3733

3734

3735

3736static double

3741{

3744

3745 if (parse->groupClause)

3746 {

3748

3749 if (parse->groupingSets)

3750 {

3751

3753

3754 Assert(gd);

3755

3757

3758 foreach(lc, gd->rollups)

3759 {

3763

3766

3767 rollup->numGroups = 0.0;

3768

3770 {

3778

3779 gs->numGroups = numGroups;

3780 rollup->numGroups += numGroups;

3781 }

3782

3784 }

3785

3786 if (gd->hash_sets_idx)

3787 {

3789

3790 gd->dNumHashGroups = 0;

3791

3794

3796 {

3804

3805 gs->numGroups = numGroups;

3806 gd->dNumHashGroups += numGroups;

3807 }

3808

3810 }

3811 }

3812 else

3813 {

3814

3817

3820 }

3821 }

3822 else if (parse->groupingSets)

3823 {

3824

3826 }

3827 else if (parse->hasAggs || root->hasHavingQual)

3828 {

3829

3831 }

3832 else

3833 {

3834

3836 }

3837

3839}

3840

3841

3842

3843

3844

3845

3846

3847

3848

3849

3850

3851

3852

3853

3854

3855

3856

3857

3862 bool target_parallel_safe,

3864{

3869

3872

3873

3874

3875

3876

3878 target_parallel_safe, parse->havingQual);

3879

3880

3881

3882

3883

3886 else

3887 {

3888 int flags = 0;

3890

3891

3892

3893

3894

3895

3896

3897

3898

3899

3900

3901

3902 if ((gd && gd->rollups != NIL)

3905

3906

3907

3908

3909

3910

3911

3912

3913

3914

3915

3916

3917

3918

3919

3920

3921

3922

3923

3924

3925

3926 if ((parse->groupClause != NIL &&

3927 root->numOrderedAggs == 0 &&

3930

3931

3932

3933

3936

3937 extra.flags = flags;

3942

3943

3944

3945

3946

3947

3948

3951 else

3953

3957 }

3958

3960 return grouped_rel;

3961}

3962

3963

3964

3965

3966

3967

3968

3969

3970

3973 PathTarget *target, bool target_parallel_safe,

3974 Node *havingQual)

3975{

3977

3979 {

3983 }

3984 else

3985 {

3986

3987

3988

3989

3990

3992 }

3993

3994

3995 grouped_rel->reltarget = target;

3996

3997

3998

3999

4000

4001

4002 if (input_rel->consider_parallel && target_parallel_safe &&

4005

4006

4008

4009

4010

4011

4015 grouped_rel->fdwroutine = input_rel->fdwroutine;

4016

4017 return grouped_rel;

4018}

4019

4020

4021

4022

4023

4024

4025

4026

4027static bool

4029{

4031

4032 return (root->hasHavingQual || parse->groupingSets) &&

4034}

4035

4036

4037

4038

4039

4040

4041

4042

4043

4044

4045

4046

4047

4048static void

4051{

4053 int nrows;

4055

4057 if (nrows > 1)

4058 {

4059

4060

4061

4062

4063

4064

4065

4067

4068 while (--nrows >= 0)

4069 {

4070 path = (Path *)

4075 }

4076 path = (Path *)

4078 grouped_rel,

4082 0,

4083 false,

4084 -1);

4085 }

4086 else

4087 {

4088

4089 path = (Path *)

4093 }

4094

4095 add_path(grouped_rel, path);

4096}

4097

4098

4099

4100

4101

4102

4103

4104

4105

4106

4107

4108

4109

4110

4111static void

4118{

4121

4122

4123

4124

4125

4126

4127

4130 {

4131

4132

4133

4134

4135

4136

4137

4138

4139

4140

4141

4142

4143

4146 root->parse->groupClause))

4150 else

4152 }

4153

4154

4155

4156

4157

4158

4160 {

4162

4163

4164

4165

4166

4167

4169

4172 grouped_rel,

4175 extra,

4177 }

4178

4179

4181

4182

4186 gd, patype, extra);

4187

4188

4190 {

4192

4195

4196 return;

4197 }

4198

4199

4202

4203

4206

4207

4210 extra);

4211

4212

4216 errmsg("could not implement GROUP BY"),

4217 errdetail("Some of the datatypes only support hashing, while others only support sorting.")));

4218

4219

4220

4221

4222

4223 if (grouped_rel->fdwroutine &&

4224 grouped_rel->fdwroutine->GetForeignUpperPaths)

4227 extra);

4228

4229

4233 extra);

4234}

4235

4236

4237

4238

4239

4240

4241

4242static void

4251{

4254

4255

4256

4257

4258

4259

4260

4261

4262

4263

4264

4265

4267 {

4278

4280

4281

4282

4283

4284

4285

4286

4287

4288

4289

4290

4291

4292

4293

4294

4295

4296

4297

4298

4299

4300

4303 {

4307 }

4308

4310 path,

4313

4314

4315

4316

4317

4318

4319 if (hashsize > hash_mem_limit && gd->rollups)

4320 return;

4321

4322

4323

4324

4325

4327

4329 {

4331

4332

4333

4334

4335

4336

4337

4338

4339

4340

4341

4342

4343 if (rollup->hashable)

4344 return;

4345

4347 }

4349 {

4353

4355 {

4356

4359 }

4360 else

4361 {

4363

4368 gd->tleref_to_colnum_map);

4369 rollup->numGroups = gs->numGroups;

4370 rollup->hashable = true;

4371 rollup->is_hashed = true;

4373 }

4374 }

4375

4376

4377

4378

4379

4381 return;

4382

4383

4384

4385

4386

4388

4390 {

4393 }

4395 {

4397

4402 rollup->hashable = false;

4403 rollup->is_hashed = false;

4406 }

4407

4410 grouped_rel,

4411 path,

4416 return;

4417 }

4418

4419

4420

4421

4422 if (gd->rollups == NIL)

4423 return;

4424

4425

4426

4427

4428

4429

4430

4431

4432

4434 {

4439

4440

4441

4442

4444 path,

4446 gd->dNumHashGroups);

4447

4449 {

4455 int i;

4456

4457

4458

4459

4460

4461

4462

4463

4464

4465

4466

4467

4468

4469

4470

4471

4472

4473

4474

4475

4476

4477

4478

4481

4482

4483

4484

4485

4486

4487

4488 i = 0;

4490 {

4492

4493 if (rollup->hashable)

4494 {

4496 path,

4499

4500

4501

4502

4503

4506 ++i;

4507 }

4508 }

4509

4510

4511

4512

4513

4514

4515

4516 if (i > 0)

4518

4520 {

4522

4523 i = 0;

4525 {

4527

4528 if (rollup->hashable)

4529 {

4532 rollup->gsets_data);

4533 else

4535 ++i;

4536 }

4537 else

4539 }

4540 }

4541 }

4542

4545

4547 {

4550

4552

4557 gd->tleref_to_colnum_map);

4558 rollup->numGroups = gs->numGroups;

4559 rollup->hashable = true;

4560 rollup->is_hashed = true;

4562 }

4563

4564 if (rollups)

4565 {

4568 grouped_rel,

4569 path,

4572 rollups,

4574 }

4575 }

4576

4577

4578

4579

4580 if (gd->unsortable_sets)

4583 grouped_rel,

4584 path,

4587 gd->rollups,

4589}

4590

4591

4592

4593

4594

4595

4596

4597

4598

4599

4600

4601

4602

4603

4611 List *activeWindows)

4612{

4615

4616

4618

4619

4620

4621

4622

4623

4626 window_rel->consider_parallel = true;

4627

4628

4629

4630

4635

4636

4637

4638

4639

4640

4642 {

4644 int presorted_keys;

4645

4646 if (path == input_rel->cheapest_total_path ||

4648 &presorted_keys) ||

4649 presorted_keys > 0)

4652 path,

4656 activeWindows);

4657 }

4658

4659

4660

4661

4662

4664 window_rel->fdwroutine->GetForeignUpperPaths)

4668

4669

4673

4674

4676

4678}

4679

4680

4681

4682

4683

4684

4685

4686

4687

4688

4689

4690

4691static void

4698 List *activeWindows)

4699{

4703

4704

4705

4706

4707

4708

4709

4710

4711

4712

4713

4714

4715

4716

4717

4718

4720

4721 foreach(l, activeWindows)

4722 {

4724 List *window_pathkeys;

4725 List *runcondition = NIL;

4726 int presorted_keys;

4728 bool topwindow;

4730

4732 wc,

4733 root->processed_tlist);

4734

4737 &presorted_keys);

4738

4739

4741 {

4742

4743

4744

4745

4748 path,

4749 window_pathkeys,

4750 -1.0);

4751 else

4752 {

4753

4754

4755

4756

4759 path,

4760 window_pathkeys,

4761 presorted_keys,

4762 -1.0);

4763 }

4764 }

4765

4766 if (lnext(activeWindows, l))

4767 {

4768

4769

4770

4771

4772

4773

4774

4775

4777

4780 {

4782

4785 }

4787 }

4788 else

4789 {

4790

4792 }

4793

4794

4796

4797

4798

4799

4800

4802 {

4805

4806 foreach(lc3, wfunc->runCondition)

4807 {

4810 Expr *opexpr;

4813

4814 if (wfuncrc->wfunc_left)

4815 {

4818 }

4819 else

4820 {

4823 }

4824

4827 false,

4832

4833 runcondition = lappend(runcondition, opexpr);

4834

4835 if (!topwindow)

4837 }

4838 }

4839

4840 path = (Path *)

4843 runcondition, wc,

4844 topwindow ? topqual : NIL, topwindow);

4845 }

4846

4848}

4849

4850

4851

4852

4853

4854

4855

4856

4857

4858

4859

4860

4864{

4866

4867

4869

4870

4871

4872

4873

4874

4875

4876

4878

4879

4880

4881

4886

4887

4889

4890

4892

4893

4897 errmsg("could not implement DISTINCT"),

4898 errdetail("Some of the datatypes only support hashing, while others only support sorting.")));

4899

4900

4901

4902

4903

4905 distinct_rel->fdwroutine->GetForeignUpperPaths)

4911

4912

4916

4917

4919

4921}

4922

4923

4924

4925

4926

4927

4928

4929

4930

4931static void

4935{

4942

4943

4945 return;

4946

4948

4949

4950 if (parse->hasDistinctOn)

4951 return;

4952

4957

4958

4959

4960

4965

4967

4969 parse->targetList);

4970

4971

4975

4976

4977

4978

4979

4980

4981

4982

4984 {

4985 foreach(lc, input_rel->partial_pathlist)

4986 {

4990

4993 root->distinct_pathkeys,

4996

4998 {

5004 -1.0);

5005

5007 continue;

5008

5009

5010

5011

5012

5013

5014 if (root->distinct_pathkeys == NIL)

5015 {

5016 Node *limitCount;

5017

5021 true);

5022

5023

5024

5025

5026

5027

5028

5029

5030

5031

5032

5033

5038 limitCount,

5040 0, 1));

5041 }

5042 else

5043 {

5049 }

5050 }

5051 }

5052 }

5053

5054

5055

5056

5057

5058

5059

5061 {

5069 root->processed_distinctClause,

5073 }

5074

5075

5076

5077

5078

5086

5087

5091

5093 {

5096

5097

5098

5099

5100

5101

5104 }

5105}

5106

5107

5108

5109

5110

5111

5112

5113

5117{

5122

5123

5124 if (parse->groupClause || parse->groupingSets || parse->hasAggs ||

5125 root->hasHavingQual)

5126 {

5127

5128

5129

5130

5131

5133 }

5134 else

5135 {

5136

5137

5138

5140

5142 parse->targetList);

5146 }

5147

5148

5149

5150

5152 {

5153

5154

5155

5156

5157

5158

5159

5160

5161

5162

5163

5164

5165

5166

5167

5168

5172

5173 if (parse->hasDistinctOn &&

5177 else

5179

5181 {

5185

5191

5193 {

5200

5202 continue;

5203

5204

5205

5206

5207

5208

5209

5210

5211

5212

5213

5214

5215

5216

5217 if (root->distinct_pathkeys == NIL)

5218 {

5219 Node *limitCount;

5220

5224 true);

5225

5226

5227

5228

5229

5230

5233 NULL, limitCount,

5235 }

5236 else

5237 {

5243 }

5244 }

5245 }

5246 }

5247

5248

5249

5250

5251

5252

5253

5254

5255

5256

5257

5258

5259

5261 allow_hash = true;

5263 allow_hash = false;

5264 else

5266

5268 {

5269

5277 root->processed_distinctClause,

5281 }

5282

5284}

5285

5286

5287

5288

5289

5290

5291

5292

5293

5294static List *

5297{

5300

5301

5304

5307

5308

5309

5310

5311

5312

5313

5314

5315

5316

5318 {

5319

5320

5321

5322

5324 break;

5325 if (root->parse->hasDistinctOn &&

5327 break;

5328

5330 }

5331

5332

5335

5336

5337

5338

5339

5343

5344

5347

5348

5349

5350

5351

5355

5358

5360}

5361

5362

5363

5364

5365

5366

5367

5368

5369

5370

5371

5372

5373

5374

5375

5376

5377

5378

5383 bool target_parallel_safe,

5384 double limit_tuples)

5385{

5389

5390

5392

5393

5394

5395

5396

5397

5398 if (input_rel->consider_parallel && target_parallel_safe)

5400

5401

5403

5404

5405

5406

5411

5413 {

5417 int presorted_keys;

5418

5420 input_path->pathkeys, &presorted_keys);

5421

5424 else

5425 {

5426

5427

5428

5429

5430

5431

5432

5435 continue;

5436

5437

5438

5439

5440

5441

5446 root->sort_pathkeys,

5447 limit_tuples);

5448 else

5452 root->sort_pathkeys,

5453 presorted_keys,

5454 limit_tuples);

5455 }

5456

5457

5458

5459

5460

5464

5466 }

5467

5468

5469

5470

5471

5472

5473

5474

5475

5476

5477

5478

5481 {

5483

5485

5486 foreach(lc, input_rel->partial_pathlist)

5487 {

5491 int presorted_keys;

5493

5496 &presorted_keys);

5497

5499 continue;

5500

5501

5502

5503

5504

5505

5506

5507

5510 continue;

5511

5512

5513

5514

5515

5516

5521 root->sort_pathkeys,

5522 limit_tuples);

5523 else

5527 root->sort_pathkeys,

5528 presorted_keys,

5529 limit_tuples);

5537

5538

5539

5540

5541

5545

5547 }

5548 }

5549

5550

5551

5552

5553

5555 ordered_rel->fdwroutine->GetForeignUpperPaths)

5559

5560

5564

5565

5566

5567

5568

5570

5572}

5573

5574

5575

5576

5577

5578

5579

5580

5581

5582

5583

5584

5585

5586

5587

5588

5589

5590

5591

5592

5593

5594

5595

5596

5597

5598

5599

5600

5601

5604{

5609 int i;

5611

5612

5613

5614

5615

5618

5619 i = 0;

5621 {

5624

5625 if (sgref && root->processed_groupClause &&

5627 root->processed_groupClause) != NULL)

5628 {

5629

5630

5631

5632

5633

5634

5635

5636 if (parse->hasGroupRTE && parse->groupingSets != NIL)

5637 {

5639 expr = (Expr *)

5643 }

5645 }

5646 else

5647 {

5648

5649

5650

5651

5653 }

5654

5655 i++;

5656 }

5657

5658

5659

5660

5661 if (parse->havingQual)

5663

5664

5665

5666

5667

5668

5669

5670

5671

5672

5673

5674

5675

5680 if (parse->hasGroupRTE && parse->groupingSets != NIL)

5681 {

5687 }

5689

5690

5693

5694

5696}

5697

5698

5699

5700

5701

5702

5703

5704

5705

5706

5707

5708

5709

5710

5711

5712

5713

5717 Node *havingQual)

5718{

5722 int i;

5724

5727

5728 i = 0;

5730 {

5733

5734 if (sgref && root->processed_groupClause &&

5736 root->processed_groupClause) != NULL)

5737 {

5738

5739

5740

5741

5743 }

5744 else

5745 {

5746

5747

5748

5749

5751 }

5752

5753 i++;

5754 }

5755

5756

5757

5758

5759 if (havingQual)

5761

5762

5763

5764

5765

5766

5767

5768

5773

5775

5776

5777

5778

5779

5780

5782 {

5784

5786 {

5788

5789

5790

5791

5792

5795

5796

5798

5800 }

5801 }

5802

5803

5806

5807

5809}

5810

5811

5812

5813

5814

5815

5816

5817void

5819{

5820

5822

5824

5825

5826 agg->aggsplit = aggsplit;

5827

5828

5829

5830

5831

5832

5834 {

5837 else

5838 agg->aggtype = agg->aggtranstype;

5839 }

5840}

5841

5842

5843

5844

5845

5846

5847

5848

5849

5850

5851

5852static List *

5854{

5857

5859 {

5862

5863

5865 continue;

5866

5870 if (orig_tle->resjunk)

5871 elog(ERROR, "resjunk output columns are not implemented");

5874 }

5876 elog(ERROR, "resjunk output columns are not implemented");

5878}

5879

5880

5881

5882

5883

5884

5885

5886

5887

5888

5889static void

5891{

5892 List *windowClause = root->parse->windowClause;

5894

5895 foreach(lc, windowClause)

5896 {

5900

5902

5903

5905 continue;

5906

5908 {

5913

5915

5916

5918 break;

5919

5921 req.window_clause = wc;

5922 req.window_func = wfunc;

5924

5925

5929

5930

5931

5932

5933

5934 if (res == NULL)

5935 break;

5936

5937

5938

5939

5940

5943

5944

5945

5946

5947

5948

5950 break;

5951 }

5952

5953

5955 {

5957

5958

5960

5961

5962

5963

5964

5965

5966

5968 continue;

5969

5970

5971

5972

5973

5974 foreach(lc3, windowClause)

5975 {

5977

5978

5980 continue;

5981

5982

5983

5984

5985

5991 {

5993

5994

5995

5996

5997

5998

5999

6001 {

6003

6005 }

6006

6007

6011

6012

6013

6014

6015

6016

6017 break;

6018 }

6019 }

6020 }

6021 }

6022}

6023

6024

6025

6026

6027

6028

6029static List *

6031{

6032 List *windowClause = root->parse->windowClause;

6038

6039

6040 foreach(lc, windowClause)

6041 {

6043

6044

6047 continue;

6048

6050

6051

6052

6053

6054

6055

6056

6057

6058

6059

6060

6061

6062

6063

6068 }

6069

6070

6071

6072

6073

6074

6075

6076

6077

6078

6079

6080

6081

6082

6083

6084

6085

6086

6087

6088

6089

6091

6092

6095

6097

6098 return result;

6099}

6100

6101

6102

6103

6104

6105

6106

6107

6108

6109

6110

6111

6112static void

6114{

6116 char newname[16];

6118

6119 foreach(lc, activeWindows)

6120 {

6122

6123

6124 if (wc->name)

6125 continue;

6126

6127

6128 for (;;)

6129 {

6131

6132 snprintf(newname, sizeof(newname), "w%d", next_n++);

6133 foreach(lc2, activeWindows)

6134 {

6136

6137 if (wc2->name && strcmp(wc2->name, newname) == 0)

6138 break;

6139 }

6141 break;

6142 }

6143 wc->name = pstrdup(newname);

6144 }

6145}

6146

6147

6148

6149

6150

6151

6152

6153

6154

6155

6156

6157

6158

6159

6160

6161

6162

6163static int

6165{

6170

6172 {

6175

6176 if (sca->tleSortGroupRef > scb->tleSortGroupRef)

6177 return -1;

6178 else if (sca->tleSortGroupRef < scb->tleSortGroupRef)

6179 return 1;

6180 else if (sca->sortop > scb->sortop)

6181 return -1;

6182 else if (sca->sortop < scb->sortop)

6183 return 1;

6184 else if (sca->nulls_first && scb->nulls_first)

6185 return -1;

6186 else if (sca->nulls_first && scb->nulls_first)

6187 return 1;

6188

6189 }

6190

6192 return -1;

6194 return 1;

6195

6196 return 0;

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

6235 List *activeWindows)

6236{

6241 int i;

6243

6244 Assert(root->parse->hasWindowFuncs);

6245

6246

6247

6248

6249

6251 foreach(lc, activeWindows)

6252 {

6255

6257 {

6259

6261 }

6263 {

6265

6267 }

6268 }

6269

6270

6271 foreach(lc, root->processed_groupClause)

6272 {

6274

6276 }

6277

6278

6279

6280

6281

6284

6285 i = 0;

6287 {

6290

6291

6292

6293

6294

6295

6297 {

6298

6299

6300

6301

6303 }

6304 else

6305 {

6306

6307

6308

6309

6311 }

6312

6313 i++;

6314 }

6315

6316

6317

6318

6319

6320

6321

6322

6323

6324

6325

6331

6332

6335

6336

6338}

6339

6340

6341

6342

6343

6344

6345

6346

6347

6348

6349

6350

6351

6352static List *

6354 List *tlist)

6355{

6356 List *window_pathkeys = NIL;

6357

6358

6362 errmsg("could not implement window PARTITION BY"),

6363 errdetail("Window partitioning columns must be of sortable datatypes.")));

6367 errmsg("could not implement window ORDER BY"),

6368 errdetail("Window ordering columns must be of sortable datatypes.")));

6369

6370

6371

6372

6373

6375 {

6377

6380 tlist,

6381 true,

6382 false,

6384 false);

6385

6387 }

6388

6389

6390

6391

6392

6393

6394

6395

6397 {

6399

6402 tlist);

6403

6404

6405 if (window_pathkeys != NIL)

6407 else

6409 }

6410

6411 return window_pathkeys;

6412}

6413

6414

6415

6416

6417

6418

6419

6420

6421

6422

6423

6424

6425

6426

6427

6428

6429

6430

6431

6432

6433

6434

6435

6436

6437

6438

6439

6440

6441

6442

6443

6444

6445

6446

6447

6448

6449

6450

6451

6452

6453

6454

6455

6456

6457

6458

6459

6460

6461

6462

6463

6464

6465

6466

6467

6468

6469

6470

6471

6472

6473

6474

6475

6476

6477

6478

6479

6484{

6487 int ncols;

6497 int i;

6499

6500

6502

6504

6505

6510

6511 i = 0;

6513 {

6515

6516

6517

6518

6519

6520

6521

6522

6523

6525 {

6526

6527

6528

6529

6530 if (parse->hasTargetSRFs &&

6532 {

6533

6536 }

6538 {

6539

6542 }

6543 else

6544 {

6545

6546

6547

6548

6549

6551

6553

6554

6555

6556

6557

6558

6560 {

6563 }

6564 }

6565 }

6566 else

6567 {

6568

6570 parse->hasTargetSRFs &&

6573 }

6574

6575 i++;

6576 }

6577

6578

6579

6580

6582

6583

6584

6585

6588 (parse->limitCount || root->tuple_fraction > 0))))

6590

6591

6592

6593

6594

6595

6596

6598

6599

6600

6601

6602

6603

6606

6607 i = 0;

6609 {

6611

6614 else

6617

6618 i++;

6619 }

6620

6621

6622

6623

6624

6625

6626

6627

6633

6634

6637

6638

6640}

6641

6642

6643

6644

6645

6646

6647

6648

6649

6650

6651

6652

6653

6654

6655

6658{

6661

6662

6663 if (tuple_fraction <= 0.0)

6665

6666

6667 if (tuple_fraction >= 1.0 && best_path->rows > 0)

6668 tuple_fraction /= best_path->rows;

6669

6671 {

6673

6674 if (path->param_info)

6675 continue;

6676

6679 continue;

6680

6682 }

6683

6685}

6686

6687

6688

6689

6690

6691

6692

6693

6694

6695

6696

6697

6698

6699

6700

6701

6702static void

6705{

6707

6710

6711

6713 return;

6714

6715

6716

6717

6718

6719

6720

6721

6722

6723

6724

6726 {

6731

6734 {

6737

6738

6741 rel,

6744 else

6746 rel,

6749 }

6755 }

6756

6757

6759 {

6764

6767 {

6770

6771

6774 rel,

6777 else

6778 {

6779

6781 rel,

6784 }

6785 }

6787 }

6788}

6789

6790

6791

6792

6793

6794

6795

6796

6797

6798

6799

6800

6801

6802

6803

6804

6805

6806

6807

6808

6809

6810

6811

6812

6813

6814

6815

6816

6817

6820{

6821 Node *result;

6822

6823

6824

6825

6826

6828

6829

6831

6832 return (Expr *) result;

6833}

6834

6835

6836

6837

6838

6839

6840

6841

6842

6843

6844

6847 List **relationOids,

6848 List **invalItems)

6849{

6850 Node *result;

6853

6854

6855 MemSet(&glob, 0, sizeof(glob));

6859

6862 root.glob = &glob;

6863

6864

6865

6866

6867

6868

6870

6871

6873

6874

6875

6876

6877

6879

6882

6883 return (Expr *) result;

6884}

6885

6886

6887

6888

6889

6890

6891

6892

6893

6894

6895

6896

6897

6898bool

6900{

6913

6914

6916 return true;

6917

6918

6921

6923

6925 root->parse = query;

6926 root->glob = glob;

6927 root->query_level = 1;

6929 root->wt_param_id = -1;

6931

6932

6935 rte->relid = tableOid;

6938 rte->lateral = false;

6939 rte->inh = false;

6940 rte->inFromCl = true;

6943

6944

6946

6947

6949

6950

6951 indexInfo = NULL;

6953 {

6955 if (indexInfo->indexoid == indexOid)

6956 break;

6957 }

6958

6959

6960

6961

6962

6963

6964

6965

6966 if (lc == NULL)

6967 return true;

6968

6969

6970

6971

6972

6975

6976 root->total_table_pages = rel->pages;

6977

6978

6979

6980

6981

6982

6983

6986

6987

6993

6994

6998 NULL, 1.0, false);

6999

7001}

7002

7003

7004

7005

7006

7007

7008

7009

7010

7011

7012

7013

7014

7015

7016

7017

7018

7019

7020int

7022{

7030 int parallel_workers;

7032 double reltuples;

7033 double allvisfrac;

7034

7035

7036

7037

7038

7040 return 0;

7041

7042

7045

7047

7049 root->parse = query;

7050 root->glob = glob;

7051 root->query_level = 1;

7053 root->wt_param_id = -1;

7055

7056

7057

7058

7059

7060

7061

7062

7063

7066 rte->relid = tableOid;

7069 rte->lateral = false;

7070 rte->inh = true;

7071 rte->inFromCl = true;

7074

7075

7077

7078

7080

7081

7084

7085

7086

7087

7088

7089

7090

7091

7095 {

7096 parallel_workers = 0;

7097 goto done;

7098 }

7099

7100

7101

7102

7103

7104

7105

7106

7108 {

7111 goto done;

7112 }

7113

7114

7115

7116

7117

7119

7120

7121

7122

7123

7126

7127

7128

7129

7130

7131

7132

7133

7134

7135

7136

7137 while (parallel_workers > 0 &&

7139 parallel_workers--;

7140

7141done:

7144

7145 return parallel_workers;

7146}

7147

7148

7149

7150

7151

7152

7153static void

7160{

7171

7172

7173

7174

7179

7181 {

7184

7185

7186

7187

7193 }

7194

7196 {

7197

7198

7199

7200

7201

7203 {

7208

7209

7211

7213

7215 {

7217

7218

7220

7222 grouped_rel,

7223 path,

7226 -1.0);

7227 if (path == NULL)

7228 continue;

7229

7230

7231 if (parse->groupingSets)

7232 {

7236 }

7237 else if (parse->hasAggs)

7238 {

7239

7240

7241

7242

7245 grouped_rel,

7246 path,

7251 havingQual,

7254 }

7255 else if (parse->groupClause)

7256 {

7257

7258

7259

7260

7263 grouped_rel,

7264 path,

7266 havingQual,

7268 }

7269 else

7270 {

7271

7273 }

7274 }

7275 }

7276

7277

7278

7279

7280

7282 {

7284 {

7289

7290

7292

7294

7295

7297 {

7299

7300

7302

7304 grouped_rel,

7305 path,

7308 -1.0);

7309

7310 if (path == NULL)

7311 continue;

7312

7313 if (parse->hasAggs)

7316 grouped_rel,

7317 path,

7322 havingQual,

7323 agg_final_costs,

7325 else

7328 grouped_rel,

7329 path,

7331 havingQual,

7333

7334 }

7335 }

7336 }

7337 }

7338

7340 {

7341 if (parse->groupingSets)

7342 {

7343

7344

7345

7349 }

7350 else

7351 {

7352

7353

7354

7355

7362 root->processed_groupClause,

7363 havingQual,

7366 }

7367

7368

7369

7370

7371

7373 {

7376 grouped_rel,

7381 root->processed_groupClause,

7382 havingQual,

7383 agg_final_costs,

7385 }

7386 }

7387

7388

7389

7390

7391

7392

7393

7396}

7397

7398

7399

7400

7401

7402

7403

7404

7405

7406

7407

7408

7409

7410

7411

7412

7413

7421{

7428 Path *cheapest_total_path = NULL;

7434

7435

7436

7437

7438

7443

7444

7445

7446

7447

7448

7449

7450

7453 cheapest_total_path = input_rel->cheapest_total_path;

7454

7455

7456

7457

7458

7459

7462

7463

7464

7465

7466

7467

7468

7469 if (cheapest_total_path == NULL &&

7473 return NULL;

7474

7475

7476

7477

7478

7481 grouped_rel->relids);

7490

7491

7492

7493

7494

7495

7496

7500

7502 {

7503

7504

7505

7506

7509 if (parse->hasAggs)

7510 {

7511

7513 agg_partial_costs);

7514

7515

7517 agg_final_costs);

7518 }

7519

7521 }

7522

7523

7524 if (cheapest_total_path != NULL)

7527 cheapest_total_path->rows,

7536

7537 if (can_sort && cheapest_total_path != NULL)

7538 {

7539

7541

7542

7543

7544

7545

7547 {

7552

7553

7555

7557

7558

7560 {

7562

7563

7565

7568 path,

7569 cheapest_total_path,

7571 -1.0);

7572

7573 if (path == NULL)

7574 continue;

7575

7576 if (parse->hasAggs)

7580 path,

7586 agg_partial_costs,

7588 else

7592 path,

7596 }

7597 }

7598 }

7599

7601 {

7602

7603 foreach(lc, input_rel->partial_pathlist)

7604 {

7609

7610

7612

7614

7615

7617 {

7619

7620

7621

7623

7626 path,

7629 -1.0);

7630

7631 if (path == NULL)

7632 continue;

7633

7634 if (parse->hasAggs)

7638 path,

7644 agg_partial_costs,

7646 else

7650 path,

7654 }

7655 }

7656 }

7657

7658

7659

7660

7661 if (can_hash && cheapest_total_path != NULL)

7662 {

7663

7665

7669 cheapest_total_path,

7673 root->processed_groupClause,

7675 agg_partial_costs,

7677 }

7678

7679

7680

7681

7683 {

7691 root->processed_groupClause,

7693 agg_partial_costs,

7695 }

7696

7697

7698

7699

7700

7702 {

7703

7705 {

7707

7708

7710

7713 path,

7715

7717 }

7718

7719

7720

7721

7722

7724 {

7726 {

7728

7729

7731

7734 path,

7736

7738 }

7739 }

7740 }

7741

7742

7743

7744

7745

7748 {

7750

7754 extra);

7755 }

7756

7758}

7759

7760

7761

7762

7763

7764

7765

7766static Path *

7769{

7771 int presorted_keys;

7772

7775 &presorted_keys);

7776

7778 {

7779

7780

7781

7782

7783

7784

7787 return NULL;

7788

7789

7790

7791

7792

7793

7796 rel,

7797 path,

7798 pathkeys,

7799 limit_tuples);

7800 else

7802 rel,

7803 path,

7804 pathkeys,

7805 presorted_keys,

7806 limit_tuples);

7807 }

7808

7809 return path;

7810}

7811

7812

7813

7814

7815

7816

7817

7818

7819

7820

7821

7822

7823

7824

7825static void

7827{

7831

7832

7833

7834

7835

7838 root->num_groupby_pathkeys);

7839 else

7841

7842

7844

7846

7847

7849 {

7852 int presorted_keys;

7854

7857 &presorted_keys);

7858

7860 continue;

7861

7862

7863

7864

7865

7866

7867

7870 continue;

7871

7872

7873

7874

7875

7876

7880 -1.0);

7881 else

7883 rel,

7884 path,

7886 presorted_keys,

7887 -1.0);

7889 path = (Path *)

7891 rel,

7892 path,

7897

7899 }

7900}

7901

7902

7903

7904

7905

7906

7907

7908static bool

7910{

7912

7913 if (parse->hasAggs && parse->groupClause == NIL)

7914 {

7915

7916

7917

7918

7919 return false;

7920 }

7921 else if (parse->groupingSets)

7922 {

7923

7924 return false;

7925 }

7926 else if (root->hasNonPartialAggs || root->hasNonSerialAggs)

7927 {

7928

7929 return false;

7930 }

7931

7932

7933 return true;

7934}

7935

7936

7937

7938

7939

7940

7941

7942

7943

7944

7945

7946

7947

7948

7949

7950static void

7957{

7961

7962

7964

7965

7966

7967

7968

7969

7970

7971

7972

7973

7974

7975

7976

7977

7978

7979

7980

7981

7982

7983

7984

7985

7986

7987

7988

7989

7992

7993

7994

7995

7996

7998 {

7999

8000

8001

8002

8003

8004

8005

8006

8007

8009

8010

8013 }

8014

8015

8018

8019

8021

8022

8023

8024

8025

8026

8027

8028

8029

8030

8032 {

8034

8035

8037

8039 subpath->pathtarget->sortgrouprefs =

8041 else

8042 {

8044

8048 }

8049 }

8050

8051

8053 {

8055

8056

8058

8060 subpath->pathtarget->sortgrouprefs =

8062 else

8063 {

8065

8069 }

8070 }

8071

8072

8073

8074

8075

8076

8077

8078 if (root->parse->hasTargetSRFs)

8082

8083

8084

8085

8086

8087

8088

8089

8090

8091

8092

8093

8095

8096

8097

8098

8099

8100

8101

8102

8104 {

8106 int i;

8107

8108

8109 i = -1;

8111 {

8114 int nappinfos;

8116

8118

8119

8121 continue;

8122

8123

8125 &nappinfos);

8127 {

8129

8134 nappinfos, appinfos);

8136 target);

8137 }

8138 pfree(appinfos);

8139

8140

8146

8147

8150 }

8151

8152

8154 }

8155

8156

8157

8158

8159

8160

8161

8162

8165

8166

8167

8168

8169

8170

8172}

8173

8174

8175

8176

8177

8178

8179

8180

8181

8182

8183

8184

8185

8186

8187

8188

8189

8190

8191static void

8200{

8205 int i;

8206

8210

8211

8212 i = -1;

8214 {

8218 int nappinfos;

8222

8224

8225

8227 continue;

8228

8230

8231

8232

8233

8234

8236

8238 &nappinfos);

8239

8243 nappinfos, appinfos);

8244

8245

8249 nappinfos, appinfos);

8253 nappinfos, appinfos);

8254

8255

8256

8257

8258

8259

8261

8262

8263

8264

8265

8270

8271

8276

8278 {

8282 }

8283 else

8285

8287 {

8291 }

8292

8293 pfree(appinfos);

8294 }

8295

8296

8297

8298

8299

8300

8301

8302

8303

8304

8306 {

8308

8311 }

8312

8313

8315 {

8317

8319 }

8320}

8321

8322

8323

8324

8325

8326

8327

8328static bool

8330 List *targetList,

8331 List *groupClause)

8332{

8334 int cnt = 0;

8335 int partnatts;

8336

8337

8339

8340

8342 return false;

8343

8344 partnatts = input_rel->part_scheme->partnatts;

8345

8346 for (cnt = 0; cnt < partnatts; cnt++)

8347 {

8350 bool found = false;

8351

8352 foreach(lc, partexprs)

8353 {

8357

8358 foreach(lg, groupexprs)

8359 {

8362

8363

8364

8365

8366

8367

8370

8372 {

8373

8374

8375

8376

8379 return false;

8380

8381 found = true;

8382 break;

8383 }

8384 }

8385

8386 if (found)

8387 break;

8388 }

8389

8390

8391

8392

8393

8394 if (!found)

8395 return false;

8396 }

8397

8398 return true;

8399}

8400

8401

8402

8403

8404

8405

8406

8407

8408

8409

8410

8411

8412

8413

8414

8415static List *

8417{

8422

8425 foreach(lt, targetlist)

8426 {

8429 Oid coltype;

8430

8431

8432 if (tle->resjunk)

8433 continue;

8434

8435

8436

8437

8438

8443

8444

8446 return NIL;

8447

8450

8451

8453 }

8454

8457

8459}

8460

8461

8462

8463

8464

8465

8466

8467

8468

8469

8470

8473{

8476 List *groupClause = NIL;

8478

8479

8482

8483

8486

8487

8489 return NULL;

8490

8491

8492

8493

8494

8495

8496

8498 return NULL;

8499

8500

8501

8502

8503

8504

8505

8506

8507

8508

8509

8511

8514

8515

8516

8517

8524

8525

8526

8527

8528

8529

8530

8531

8532

8533

8535 {

8538

8540

8542

8543

8547 rel,

8548 rel->top_parent);

8549

8551

8554 }

8555 else

8556 {

8562

8563

8564

8565

8566

8567

8568

8569

8570

8571

8572

8573

8574

8575

8576

8579

8581 {

8584 Oid sortop;

8587

8589 if (tle)

8590 {

8594 false);

8598 }

8599

8600

8601

8602

8603

8604

8605

8608 {

8609 Oid eqop;

8611

8612

8613

8614

8615

8616

8617

8619 if (OidIsValid(eqop))

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

8621 sortop);

8622

8625 sortcl->eqop = eqop;

8626 sortcl->sortop = sortop;

8627 sortcl->reverse_sort = false;

8628 sortcl->nulls_first = false;

8629 sortcl->hashable = false;

8631

8632

8633

8634

8635

8636

8640 {

8641

8644

8646 {

8649 }

8650

8651 continue;

8652 }

8653 }

8654 else if (sjinfo->semi_can_btree)

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

8657

8659 {

8660

8663

8664

8665

8666

8667

8668

8669

8670

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

8674

8678 groupcl->sortop = sortop;

8679 groupcl->reverse_sort = false;

8680 groupcl->nulls_first = false;

8681 groupcl->hashable = true;

8683 }

8684 }

8685

8686

8687

8688

8689

8692

8693

8694

8695

8696

8697

8698

8700 {

8702 return NULL;

8703 }

8704

8705

8707 }

8708

8709

8711 sjinfo, unique_rel);

8712

8713

8715 sjinfo, unique_rel);

8716

8717

8719

8720

8721

8722

8723

8725

8726

8730

8732

8733 return unique_rel;

8734}

8735

8736

8737

8738

8739

8740static void

8744{

8746

8747

8753

8754

8756 {

8758

8759

8760

8761

8762

8763

8764

8765

8766

8768 {

8772 int presorted_keys;

8773

8774

8775

8776

8777

8780 continue;

8781

8784 &presorted_keys);

8785

8786

8787

8788

8789

8790

8793 continue;

8794

8795

8796

8797

8799 unique_rel,

8802

8804 {

8805

8806

8807

8808

8809

8812 unique_rel,

8813 path,

8815 -1.0);

8816 else

8818 unique_rel,

8819 path,

8821 presorted_keys,

8822 -1.0);

8823 }

8824

8827 unique_rel->rows);

8828

8830 }

8831 }

8832

8833

8835 {

8837

8838

8839

8840

8842 unique_rel,

8845

8847 unique_rel,

8848 path,

8852 groupClause,

8855 unique_rel->rows);

8856

8858 }

8859}

8860

8861

8862

8863

8864

8865static void

8869{

8872

8873

8875 return;

8876

8877

8878

8879

8880

8882 return;

8883

8885

8888

8889

8890

8891

8898

8899

8906

8907

8909 {

8911

8912

8913

8914

8915

8916

8917 foreach(lc, input_rel->partial_pathlist)

8918 {

8922 int presorted_keys;

8923

8926 &presorted_keys);

8927

8928

8929

8930

8931

8932

8935 continue;

8936

8937

8938

8939

8944

8946 {

8947

8948

8949

8950

8951

8955 path,

8957 -1.0);

8958 else

8961 path,

8963 presorted_keys,

8964 -1.0);

8965 }

8966

8970

8972 }

8973 }

8974

8975

8977 {

8979

8980

8981

8982

8987

8990 path,

8994 groupClause,

8998

9000 }

9001

9003 {

9006

9007

9008

9009

9010

9011

9014 sjinfo, unique_rel);

9015 }

9016}

9017

9018

9019

9020

9021

9022

9023char *

9025{

9026 unsigned n;

9027

9028

9029

9030

9031

9032

9034 {

9035 bool found = false;

9036

9038 {

9040 {

9041 found = true;

9042 break;

9043 }

9044 }

9045

9046 if (!found)

9047 {

9048

9050

9053 }

9054 }

9055

9056

9057

9058

9059

9060

9061 for (n = 1; true; ++n)

9062 {

9064 bool found = false;

9065

9067 {

9069 {

9070 found = true;

9071 break;

9072 }

9073 }

9074

9075 if (!found)

9076 {

9079 }

9080

9082 }

9083}

void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)

int compute_parallel_worker(RelOptInfo *rel, double heap_pages, double index_pages, int max_workers)

void generate_useful_gather_paths(PlannerInfo *root, RelOptInfo *rel, bool override_rows)

void add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel, List *live_childrels)

AppendRelInfo ** find_appinfos_by_relids(PlannerInfo *root, Relids relids, int *nappinfos)

Node * adjust_appendrel_attrs(PlannerInfo *root, Node *node, int nappinfos, AppendRelInfo **appinfos)

List * adjust_inherited_attnums_multilevel(PlannerInfo *root, List *attnums, Index child_relid, Index top_parent_relid)

Node * adjust_appendrel_attrs_multilevel(PlannerInfo *root, Node *node, RelOptInfo *childrel, RelOptInfo *parentrel)

void pprint(const void *obj)

void pgstat_report_plan_id(int64 plan_id, bool force)

BipartiteMatchState * BipartiteMatch(int u_size, int v_size, short **adjacency)

void BipartiteMatchFree(BipartiteMatchState *state)

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

Bitmapset * bms_make_singleton(int x)

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

int bms_next_member(const Bitmapset *a, int prevbit)

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

Bitmapset * bms_del_member(Bitmapset *a, int x)

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

void bms_free(Bitmapset *a)

int bms_num_members(const Bitmapset *a)

bool bms_is_member(int x, const Bitmapset *a)

Bitmapset * bms_add_member(Bitmapset *a, int x)

BMS_Membership bms_membership(const Bitmapset *a)

bool bms_overlap_list(const Bitmapset *a, const List *b)

#define Assert(condition)

#define MemSet(start, val, len)

#define OidIsValid(objectId)

bool contain_agg_clause(Node *clause)

Node * estimate_expression_value(PlannerInfo *root, Node *node)

WindowFuncLists * find_window_functions(Node *clause, Index maxWinRef)

Node * eval_const_expressions(PlannerInfo *root, Node *node)

void convert_saop_to_hashed_saop(Node *node)

char max_parallel_hazard(Query *parse)

bool is_parallel_safe(PlannerInfo *root, Node *node)

bool contain_subplans(Node *clause)

bool contain_volatile_functions(Node *clause)

bool enable_partitionwise_aggregate

int max_parallel_workers_per_gather

double parallel_setup_cost

double parallel_tuple_cost

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)

bool enable_indexonlyscan

double compute_gather_rows(Path *path)

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

PathTarget * set_pathtarget_cost_width(PlannerInfo *root, PathTarget *target)

void cost_qual_eval(QualCost *cost, List *quals, PlannerInfo *root)

bool enable_presorted_aggregate

bool enable_partitionwise_join

int32 clamp_width_est(int64 tuple_width)

bool enable_incremental_sort

Plan * materialize_finished_plan(Plan *subplan)

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

int errcode(int sqlerrcode)

int errdetail(const char *fmt,...) pg_attribute_printf(1

#define ereport(elevel,...)

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

bool ExecSupportsBackwardScan(Plan *node)

bool ExecCheckOneRelPerms(RTEPermissionInfo *perminfo)

#define palloc_array(type, count)

#define palloc0_object(type)

#define OidFunctionCall1(functionId, arg1)

FdwRoutine * GetFdwRoutineByRelId(Oid relid)

int max_parallel_maintenance_workers

#define IsParallelWorker()

void index_close(Relation relation, LOCKMODE lockmode)

Relation index_open(Oid relationId, LOCKMODE lockmode)

double jit_optimize_above_cost

double jit_inline_above_cost

Bitmapset * DiscreteKnapsack(int max_weight, int num_items, int *item_weights, double *item_values)

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

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

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

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

List * list_copy(const List *oldlist)

List * lappend_int(List *list, int datum)

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

List * list_delete_int(List *list, int datum)

List * list_delete_last(List *list)

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

void list_free(List *list)

bool list_member_int(const List *list, int 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)

RegProcedure get_func_support(Oid funcid)

Oid get_equality_op_for_ordering_op(Oid opno, bool *reverse)

Oid get_ordering_op_for_equality_op(Oid opno, bool use_lhs_type)

int32 get_typavgwidth(Oid typid, int32 typmod)

Datum subpath(PG_FUNCTION_ARGS)

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

Expr * make_opclause(Oid opno, Oid opresulttype, bool opretset, Expr *leftop, Expr *rightop, Oid opcollid, Oid inputcollid)

Const * makeConst(Oid consttype, int32 consttypmod, Oid constcollid, int constlen, Datum constvalue, bool constisnull, bool constbyval)

List * make_ands_implicit(Expr *clause)

char * pstrdup(const char *in)

void pfree(void *pointer)

void * palloc0(Size size)

MemoryContext CurrentMemoryContext

MemoryContext GetMemoryChunkContext(void *pointer)

Oid exprType(const Node *expr)

Oid exprCollation(const Node *expr)

bool expression_returns_set(Node *clause)

void fix_opfuncids(Node *node)

size_t get_hash_memory_limit(void)

#define DO_AGGSPLIT_SKIPFINAL(as)

#define IsA(nodeptr, _type_)

#define IS_OUTER_JOIN(jointype)

#define DO_AGGSPLIT_SERIALIZE(as)

@ AGGSPLIT_FINAL_DESERIAL

@ AGGSPLIT_INITIAL_SERIAL

#define castNode(_type_, nodeptr)

#define PVC_RECURSE_AGGREGATES

#define PVC_RECURSE_WINDOWFUNCS

#define PVC_INCLUDE_WINDOWFUNCS

#define PVC_INCLUDE_PLACEHOLDERS

#define PVC_INCLUDE_AGGREGATES

static MemoryContext MemoryContextSwitchTo(MemoryContext context)

int assign_special_exec_param(PlannerInfo *root)

List * expand_grouping_sets(List *groupingSets, bool groupDistinct, int limit)

Index assignSortGroupRef(TargetEntry *tle, List *tlist)

RTEPermissionInfo * getRTEPermissionInfo(List *rteperminfos, RangeTblEntry *rte)

RTEPermissionInfo * addRTEPermissionInfo(List **rteperminfos, RangeTblEntry *rte)

#define CURSOR_OPT_SCROLL

#define CURSOR_OPT_FAST_PLAN

#define CURSOR_OPT_PARALLEL_OK

void CheckSelectLocking(Query *qry, LockClauseStrength strength)

const char * LCS_asString(LockClauseStrength strength)

#define rt_fetch(rangetable_index, rangetable)

void DestroyPartitionDirectory(PartitionDirectory pdir)

List * append_pathkeys(List *target, List *source)

bool pathkeys_count_contained_in(List *keys1, List *keys2, int *n_common)

List * make_pathkeys_for_sortclauses(PlannerInfo *root, List *sortclauses, List *tlist)

List * make_pathkeys_for_sortclauses_extended(PlannerInfo *root, List **sortclauses, List *tlist, bool remove_redundant, bool remove_group_rtindex, bool *sortable, bool set_ec_sortref)

bool pathkeys_contained_in(List *keys1, List *keys2)

PathKeysComparison compare_pathkeys(List *keys1, List *keys2)

List * get_useful_group_keys_orderings(PlannerInfo *root, Path *path)

ModifyTablePath * create_modifytable_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, CmdType operation, bool canSetTag, Index nominalRelation, Index rootRelation, List *resultRelations, List *updateColnosLists, List *withCheckOptionLists, List *returningLists, List *rowMarks, OnConflictExpr *onconflict, List *mergeActionLists, List *mergeJoinConditions, int epqParam)

IndexPath * create_index_path(PlannerInfo *root, IndexOptInfo *index, List *indexclauses, List *indexorderbys, List *indexorderbycols, List *pathkeys, ScanDirection indexscandir, bool indexonly, Relids required_outer, double loop_count, bool partial_path)

ProjectSetPath * create_set_projection_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, PathTarget *target)

ProjectionPath * create_projection_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, PathTarget *target)

WindowAggPath * create_windowagg_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, PathTarget *target, List *windowFuncs, List *runCondition, WindowClause *winclause, List *qual, bool topwindow)

LockRowsPath * create_lockrows_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, List *rowMarks, int epqParam)

Path * apply_projection_to_path(PlannerInfo *root, RelOptInfo *rel, Path *path, PathTarget *target)

Path * create_seqscan_path(PlannerInfo *root, RelOptInfo *rel, Relids required_outer, int parallel_workers)

GatherMergePath * create_gather_merge_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, PathTarget *target, List *pathkeys, Relids required_outer, double *rows)

void set_cheapest(RelOptInfo *parent_rel)

void add_partial_path(RelOptInfo *parent_rel, Path *new_path)

LimitPath * create_limit_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, Node *limitOffset, Node *limitCount, LimitOption limitOption, int64 offset_est, int64 count_est)

int compare_fractional_path_costs(Path *path1, Path *path2, double fraction)

IncrementalSortPath * create_incremental_sort_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, List *pathkeys, int presorted_keys, double limit_tuples)

GroupingSetsPath * create_groupingsets_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, List *having_qual, AggStrategy aggstrategy, List *rollups, const AggClauseCosts *agg_costs)

SortPath * create_sort_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, List *pathkeys, double limit_tuples)

GroupPath * create_group_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, List *groupClause, List *qual, double numGroups)

void add_path(RelOptInfo *parent_rel, Path *new_path)

AppendPath * create_append_path(PlannerInfo *root, RelOptInfo *rel, AppendPathInput input, List *pathkeys, Relids required_outer, int parallel_workers, bool parallel_aware, double rows)

UniquePath * create_unique_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, int numCols, double numGroups)

AggPath * create_agg_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, PathTarget *target, AggStrategy aggstrategy, AggSplit aggsplit, List *groupClause, List *qual, const AggClauseCosts *aggcosts, double numGroups)

GroupResultPath * create_group_result_path(PlannerInfo *root, RelOptInfo *rel, PathTarget *target, List *havingqual)

#define PGS_NESTLOOP_MEMOIZE

PartitionwiseAggregateType

@ PARTITIONWISE_AGGREGATE_PARTIAL

@ PARTITIONWISE_AGGREGATE_FULL

@ PARTITIONWISE_AGGREGATE_NONE

#define IS_SIMPLE_REL(rel)

#define PGS_CONSIDER_INDEXONLY

#define PGS_NESTLOOP_MATERIALIZE

#define PGS_MERGEJOIN_PLAIN

#define GROUPING_CAN_USE_HASH

#define PGS_MERGEJOIN_MATERIALIZE

#define get_pathtarget_sortgroupref(target, colno)

#define IS_PARTITIONED_REL(rel)

#define PGS_CONSIDER_NONPARTIAL

#define GROUPING_CAN_USE_SORT

#define GROUPING_CAN_PARTIAL_AGG

#define PGS_CONSIDER_PARTITIONWISE

@ UPPERREL_PARTIAL_GROUP_AGG

@ UPPERREL_PARTIAL_DISTINCT

#define IS_OTHER_REL(rel)

#define PGS_INDEXONLYSCAN

#define PGS_NESTLOOP_PLAIN

#define lfirst_node(type, lc)

static int list_length(const List *l)

#define linitial_node(type, l)

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

#define foreach_current_index(var_or_cell)

#define foreach_ptr(type, var, lst)

#define for_each_cell(cell, lst, initcell)

#define for_each_from(cell, lst, N)

static void * list_nth(const List *list, int n)

#define foreach_node(type, var, lst)

static ListCell * list_head(const List *l)

#define list_nth_node(type, list, n)

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

#define list_make1_int(x1)

static int list_cell_number(const List *l, const ListCell *c)

#define llast_node(type, l)

void preprocess_minmax_aggregates(PlannerInfo *root)

void estimate_rel_size(Relation rel, int32 *attr_widths, BlockNumber *pages, double *tuples, double *allvisfrac)

int32 get_relation_data_width(Oid relid, int32 *attr_widths)

RelOptInfo * query_planner(PlannerInfo *root, query_pathkeys_callback qp_callback, void *qp_extra)

#define DEFAULT_CURSOR_TUPLE_FRACTION

#define EXPRKIND_TABLEFUNC_LATERAL

static RelOptInfo * create_final_distinct_paths(PlannerInfo *root, RelOptInfo *input_rel, RelOptInfo *distinct_rel)

static List * postprocess_setop_tlist(List *new_tlist, List *orig_tlist)

static PathTarget * make_partial_grouping_target(PlannerInfo *root, PathTarget *grouping_target, Node *havingQual)

Expr * expression_planner_with_deps(Expr *expr, List **relationOids, List **invalItems)

static void gather_grouping_paths(PlannerInfo *root, RelOptInfo *rel)

static void preprocess_rowmarks(PlannerInfo *root)

#define EXPRKIND_TABLESAMPLE

static void add_paths_to_grouping_rel(PlannerInfo *root, RelOptInfo *input_rel, RelOptInfo *grouped_rel, RelOptInfo *partially_grouped_rel, const AggClauseCosts *agg_costs, grouping_sets_data *gd, GroupPathExtraData *extra)

PlannedStmt * planner(Query *parse, const char *query_string, int cursorOptions, ParamListInfo boundParams, ExplainState *es)

static void create_degenerate_grouping_paths(PlannerInfo *root, RelOptInfo *input_rel, RelOptInfo *grouped_rel)

char * choose_plan_name(PlannerGlobal *glob, const char *name, bool always_number)

#define EXPRKIND_GROUPEXPR

planner_hook_type planner_hook

double cursor_tuple_fraction

static bool is_degenerate_grouping(PlannerInfo *root)

planner_shutdown_hook_type planner_shutdown_hook

bool plan_cluster_use_sort(Oid tableOid, Oid indexOid)

static void preprocess_qual_conditions(PlannerInfo *root, Node *jtnode)

int plan_create_index_workers(Oid tableOid, Oid indexOid)

#define EXPRKIND_RTFUNC_LATERAL

#define EXPRKIND_VALUES_LATERAL

static void create_ordinary_grouping_paths(PlannerInfo *root, RelOptInfo *input_rel, RelOptInfo *grouped_rel, const AggClauseCosts *agg_costs, grouping_sets_data *gd, GroupPathExtraData *extra, RelOptInfo **partially_grouped_rel_p)

RelOptInfo * create_unique_paths(PlannerInfo *root, RelOptInfo *rel, SpecialJoinInfo *sjinfo)

PlannerInfo * subquery_planner(PlannerGlobal *glob, Query *parse, char *plan_name, PlannerInfo *parent_root, bool hasRecursion, double tuple_fraction, SetOperationStmt *setops)

static bool can_partial_agg(PlannerInfo *root)

static double preprocess_limit(PlannerInfo *root, double tuple_fraction, int64 *offset_est, int64 *count_est)

Path * get_cheapest_fractional_path(RelOptInfo *rel, double tuple_fraction)

Expr * preprocess_phv_expression(PlannerInfo *root, Expr *expr)

static List * get_useful_pathkeys_for_distinct(PlannerInfo *root, List *needed_pathkeys, List *path_pathkeys)

planner_setup_hook_type planner_setup_hook

bool parallel_leader_participation

static PathTarget * make_window_input_target(PlannerInfo *root, PathTarget *final_target, List *activeWindows)

static void apply_scanjoin_target_to_paths(PlannerInfo *root, RelOptInfo *rel, List *scanjoin_targets, List *scanjoin_targets_contain_srfs, bool scanjoin_target_parallel_safe, bool tlist_same_exprs)

static RelOptInfo * create_distinct_paths(PlannerInfo *root, RelOptInfo *input_rel, PathTarget *target)

static void optimize_window_clauses(PlannerInfo *root, WindowFuncLists *wflists)

RowMarkType select_rowmark_type(RangeTblEntry *rte, LockClauseStrength strength)

static void adjust_paths_for_srfs(PlannerInfo *root, RelOptInfo *rel, List *targets, List *targets_contain_srfs)

static void create_partial_distinct_paths(PlannerInfo *root, RelOptInfo *input_rel, RelOptInfo *final_distinct_rel, PathTarget *target)

static List * preprocess_groupclause(PlannerInfo *root, List *force)

static Node * preprocess_expression(PlannerInfo *root, Node *expr, int kind)

static Path * make_ordered_path(PlannerInfo *root, RelOptInfo *rel, Path *path, Path *cheapest_path, List *pathkeys, double limit_tuples)

static bool has_volatile_pathkey(List *keys)

static RelOptInfo * create_partial_grouping_paths(PlannerInfo *root, RelOptInfo *grouped_rel, RelOptInfo *input_rel, grouping_sets_data *gd, GroupPathExtraData *extra, bool force_rel_creation)

static void name_active_windows(List *activeWindows)

static void create_final_unique_paths(PlannerInfo *root, RelOptInfo *input_rel, List *sortPathkeys, List *groupClause, SpecialJoinInfo *sjinfo, RelOptInfo *unique_rel)

static PathTarget * make_sort_input_target(PlannerInfo *root, PathTarget *final_target, bool *have_postponed_srfs)

static void create_one_window_path(PlannerInfo *root, RelOptInfo *window_rel, Path *path, PathTarget *input_target, PathTarget *output_target, WindowFuncLists *wflists, List *activeWindows)

bool enable_distinct_reordering

void mark_partial_aggref(Aggref *agg, AggSplit aggsplit)

static grouping_sets_data * preprocess_grouping_sets(PlannerInfo *root)

static List * remap_to_groupclause_idx(List *groupClause, List *gsets, int *tleref_to_colnum_map)

static void adjust_group_pathkeys_for_groupagg(PlannerInfo *root)

static PathTarget * make_group_input_target(PlannerInfo *root, PathTarget *final_target)

static List * reorder_grouping_sets(List *groupingSets, List *sortclause)

static int common_prefix_cmp(const void *a, const void *b)

static void grouping_planner(PlannerInfo *root, double tuple_fraction, SetOperationStmt *setops)

static RelOptInfo * make_grouping_rel(PlannerInfo *root, RelOptInfo *input_rel, PathTarget *target, bool target_parallel_safe, Node *havingQual)

static List * generate_setop_child_grouplist(SetOperationStmt *op, List *targetlist)

PlannedStmt * standard_planner(Query *parse, const char *query_string, int cursorOptions, ParamListInfo boundParams, ExplainState *es)

static List * select_active_windows(PlannerInfo *root, WindowFuncLists *wflists)

Expr * expression_planner(Expr *expr)

static void create_partial_unique_paths(PlannerInfo *root, RelOptInfo *input_rel, List *sortPathkeys, List *groupClause, SpecialJoinInfo *sjinfo, RelOptInfo *unique_rel)

bool limit_needed(Query *parse)

create_upper_paths_hook_type create_upper_paths_hook

#define EXPRKIND_TABLEFUNC

static void consider_groupingsets_paths(PlannerInfo *root, RelOptInfo *grouped_rel, Path *path, bool is_sorted, bool can_hash, grouping_sets_data *gd, const AggClauseCosts *agg_costs, double dNumGroups)

static List * make_pathkeys_for_window(PlannerInfo *root, WindowClause *wc, List *tlist)

static RelOptInfo * create_ordered_paths(PlannerInfo *root, RelOptInfo *input_rel, PathTarget *target, bool target_parallel_safe, double limit_tuples)

static double get_number_of_groups(PlannerInfo *root, double path_rows, grouping_sets_data *gd, List *target_list)

static List * extract_rollup_sets(List *groupingSets)

static RelOptInfo * create_grouping_paths(PlannerInfo *root, RelOptInfo *input_rel, PathTarget *target, bool target_parallel_safe, grouping_sets_data *gd)

static void create_partitionwise_grouping_paths(PlannerInfo *root, RelOptInfo *input_rel, RelOptInfo *grouped_rel, RelOptInfo *partially_grouped_rel, const AggClauseCosts *agg_costs, grouping_sets_data *gd, PartitionwiseAggregateType patype, GroupPathExtraData *extra)

#define EXPRKIND_ARBITER_ELEM

static bool group_by_has_partkey(RelOptInfo *input_rel, List *targetList, List *groupClause)

static void standard_qp_callback(PlannerInfo *root, void *extra)

static RelOptInfo * create_window_paths(PlannerInfo *root, RelOptInfo *input_rel, PathTarget *input_target, PathTarget *output_target, bool output_target_parallel_safe, WindowFuncLists *wflists, List *activeWindows)

PlannedStmt *(* planner_hook_type)(Query *parse, const char *query_string, int cursorOptions, ParamListInfo boundParams, ExplainState *es)

void(* planner_setup_hook_type)(PlannerGlobal *glob, Query *parse, const char *query_string, int cursorOptions, double *tuple_fraction, ExplainState *es)

void(* create_upper_paths_hook_type)(PlannerInfo *root, UpperRelationKind stage, RelOptInfo *input_rel, RelOptInfo *output_rel, void *extra)

void(* planner_shutdown_hook_type)(PlannerGlobal *glob, Query *parse, const char *query_string, PlannedStmt *pstmt)

@ ROW_MARK_NOKEYEXCLUSIVE

#define qsort(a, b, c, d)

static Datum Int64GetDatum(int64 X)

static int64 DatumGetInt64(Datum X)

static Datum PointerGetDatum(const void *X)

static Pointer DatumGetPointer(Datum X)

void get_agg_clause_costs(PlannerInfo *root, AggSplit aggsplit, AggClauseCosts *costs)

void preprocess_aggrefs(PlannerInfo *root, Node *clause)

void preprocess_function_rtes(PlannerInfo *root)

void flatten_simple_union_all(PlannerInfo *root)

void transform_MERGE_to_join(Query *parse)

void remove_useless_result_rtes(PlannerInfo *root)

void pull_up_sublinks(PlannerInfo *root)

void replace_empty_jointree(Query *parse)

void pull_up_subqueries(PlannerInfo *root)

Relids get_relids_in_jointree(Node *jtnode, bool include_outer_joins, bool include_inner_joins)

Query * preprocess_relation_rtes(PlannerInfo *root)

void reduce_outer_joins(PlannerInfo *root)

Expr * canonicalize_qual(Expr *qual, bool is_check)

void preprocess_targetlist(PlannerInfo *root)

RelOptInfo * plan_set_operations(PlannerInfo *root)

char * psprintf(const char *fmt,...)

List * RelationGetIndexPredicate(Relation relation)

List * RelationGetIndexExpressions(Relation relation)

RelOptInfo * find_base_rel(PlannerInfo *root, int relid)

void setup_simple_rel_arrays(PlannerInfo *root)

RelOptInfo * fetch_upper_rel(PlannerInfo *root, UpperRelationKind kind, Relids relids)

RelOptInfo * build_simple_rel(PlannerInfo *root, int relid, RelOptInfo *parent)

Node * remove_nulling_relids(Node *node, const Bitmapset *removable_relids, const Bitmapset *except_relids)

double estimate_num_groups(PlannerInfo *root, List *groupExprs, double input_rows, List **pgset, EstimationInfo *estinfo)

double estimate_hashagg_tablesize(PlannerInfo *root, Path *path, const AggClauseCosts *agg_costs, double dNumGroups)

Plan * set_plan_references(PlannerInfo *root, Plan *plan)

bool extract_query_dependencies_walker(Node *node, PlannerInfo *context)

void check_stack_depth(void)

GetForeignRowMarkType_function GetForeignRowMarkType

GetForeignUpperPaths_function GetForeignUpperPaths

Bitmapset * rewindPlanIDs

PlannedStmtOrigin planOrigin

Bitmapset * unprunableRelids

Bitmapset * prunableRelids

Bitmapset * rewindPlanIDs

struct PathTarget * reltarget

List * cheapest_parameterized_paths

struct Path * cheapest_startup_path

struct Path * cheapest_total_path

List * unique_groupclause

struct RelOptInfo * unique_rel

LockClauseStrength strength

LockWaitPolicy waitPolicy

int * tleref_to_colnum_map

Bitmapset * unhashable_refs

Bitmapset * unsortable_refs

grouping_sets_data * gset_data

Node * SS_process_sublinks(PlannerInfo *root, Node *expr, bool isQual)

void SS_process_ctes(PlannerInfo *root)

void SS_identify_outer_params(PlannerInfo *root)

Node * SS_replace_correlation_vars(PlannerInfo *root, Node *expr)

void SS_finalize_plan(PlannerInfo *root, Plan *plan)

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

void SS_charge_for_initplans(PlannerInfo *root, RelOptInfo *final_rel)

void table_close(Relation relation, LOCKMODE lockmode)

Relation table_open(Oid relationId, LOCKMODE lockmode)

void split_pathtarget_at_srfs_grouping(PlannerInfo *root, PathTarget *target, PathTarget *input_target, List **targets, List **targets_contain_srfs)

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

bool tlist_same_exprs(List *tlist1, List *tlist2)

SortGroupClause * get_sortgroupref_clause_noerr(Index sortref, List *clauses)

SortGroupClause * get_sortgroupref_clause(Index sortref, List *clauses)

bool grouping_is_sortable(List *groupClause)

List * make_tlist_from_pathtarget(PathTarget *target)

PathTarget * copy_pathtarget(PathTarget *src)

void add_new_columns_to_pathtarget(PathTarget *target, List *exprs)

PathTarget * create_empty_pathtarget(void)

List * get_sortgrouplist_exprs(List *sgClauses, List *targetList)

void split_pathtarget_at_srfs(PlannerInfo *root, PathTarget *target, PathTarget *input_target, List **targets, List **targets_contain_srfs)

bool grouping_is_hashable(List *groupClause)

void add_column_to_pathtarget(PathTarget *target, Expr *expr, Index sortgroupref)

#define create_pathtarget(root, tlist)

Node * flatten_group_exprs(PlannerInfo *root, Query *query, Node *node)

Relids pull_varnos(PlannerInfo *root, Node *node)

List * pull_var_clause(Node *node, int flags)

Node * flatten_join_alias_vars(PlannerInfo *root, Query *query, Node *node)