PostgreSQL Source Code: src/backend/optimizer/util/pathnode.c Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

16

17#include <math.h>

18

33

34typedef enum

35{

41

42

43

44

45

46

47#define STD_FUZZ_FACTOR 1.01

48

53 List *pathlist,

57

58

59

60

61

62

63

64

65

66

67

68int

70{

71

73 {

75 return -1;

76 else

77 return +1;

78 }

79

81 {

83 return -1;

85 return +1;

86

87

88

89

90

92 return -1;

94 return +1;

95 }

96 else

97 {

99 return -1;

101 return +1;

102

103

104

105

107 return -1;

109 return +1;

110 }

111 return 0;

112}

113

114

115

116

117

118

119

120

121

122

123int

125 double fraction)

126{

128 cost2;

129

130

132 {

134 return -1;

135 else

136 return +1;

137 }

138

139 if (fraction <= 0.0 || fraction >= 1.0)

145 if (cost1 < cost2)

146 return -1;

147 if (cost1 > cost2)

148 return +1;

149 return 0;

150}

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

183{

184#define CONSIDER_PATH_STARTUP_COST(p) \

185 ((p)->param_info == NULL ? (p)->parent->consider_startup : (p)->parent->consider_param_startup)

186

187

189 {

192 else

194 }

195

196

197

198

199

201 {

202

205 {

206

208 }

209

211 }

213 {

214

217 {

218

220 }

221

223 }

224

226 {

227

229 }

231 {

232

234 }

235

237

238#undef CONSIDER_PATH_STARTUP_COST

239}

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268void

270{

271 Path *cheapest_startup_path;

272 Path *cheapest_total_path;

273 Path *best_param_path;

274 List *parameterized_paths;

276

278

280 elog(ERROR, "could not devise a query plan for the given query");

281

282 cheapest_startup_path = cheapest_total_path = best_param_path = NULL;

283 parameterized_paths = NIL;

284

285 foreach(p, parent_rel->pathlist)

286 {

289

290 if (path->param_info)

291 {

292

293 parameterized_paths = lappend(parameterized_paths, path);

294

295

296

297

298

299 if (cheapest_total_path)

300 continue;

301

302

303

304

305

306

307 if (best_param_path == NULL)

308 best_param_path = path;

309 else

310 {

313 {

315

318 best_param_path = path;

319 break;

321

322 best_param_path = path;

323 break;

325

326 break;

328

329

330

331

332

333

334 break;

335 }

336 }

337 }

338 else

339 {

340

341 if (cheapest_total_path == NULL)

342 {

343 cheapest_startup_path = cheapest_total_path = path;

344 continue;

345 }

346

347

348

349

350

351

352

353

355 if (cmp > 0 ||

356 (cmp == 0 &&

359 cheapest_startup_path = path;

360

362 if (cmp > 0 ||

363 (cmp == 0 &&

366 cheapest_total_path = path;

367 }

368 }

369

370

371 if (cheapest_total_path)

372 parameterized_paths = lcons(cheapest_total_path, parameterized_paths);

373

374

375

376

377

378 if (cheapest_total_path == NULL)

379 cheapest_total_path = best_param_path;

380 Assert(cheapest_total_path != NULL);

381

386}

387

388

389

390

391

392

393

394

395

396

397

398

399

400

401

402

403

404

405

406

407

408

409

410

411

412

413

414

415

416

417

418

419

420

421

422

423

424

425

426

427

428

429

430

431

432

433

434

435

436

437

438

439

440

441

442

443

444

445

446

447

448

449

450

451

452

453

454

455

456

457

458

459

460void

462{

463 bool accept_new = true;

464 int insert_at = 0;

465 List *new_path_pathkeys;

467

468

469

470

471

473

474

475 new_path_pathkeys = new_path->param_info ? NIL : new_path->pathkeys;

476

477

478

479

480

481

482 foreach(p1, parent_rel->pathlist)

483 {

485 bool remove_old = false;

489

490

491

492

495

496

497

498

499

500

501

502

503

504

505

506

508 {

509

510 List *old_path_pathkeys;

511

512 old_path_pathkeys = old_path->param_info ? NIL : old_path->pathkeys;

514 old_path_pathkeys);

516 {

517 switch (costcmp)

518 {

523 {

526 new_path->rows <= old_path->rows &&

528 remove_old = true;

529 }

531 {

534 new_path->rows >= old_path->rows &&

536 accept_new = false;

537 }

538 else

539 {

541 {

542

543

544

545

546

547

548

549

550

551

552

553

554

555

556

559 remove_old = true;

562 accept_new = false;

563 else if (new_path->rows < old_path->rows)

564 remove_old = true;

565 else if (new_path->rows > old_path->rows)

566 accept_new = false;

568 old_path,

570 remove_old = true;

571 else

572 accept_new = false;

573

574 }

576 new_path->rows <= old_path->rows &&

578 remove_old = true;

580 new_path->rows >= old_path->rows &&

582 accept_new = false;

583

584 }

585 break;

588 {

593 new_path->rows <= old_path->rows &&

595 remove_old = true;

596 }

597 break;

600 {

605 new_path->rows >= old_path->rows &&

607 accept_new = false;

608 }

609 break;

611

612

613

614

615

616 break;

617 }

618 }

619 }

620

621

622

623

624 if (remove_old)

625 {

627 p1);

628

629

630

631

634 }

635 else

636 {

637

638

639

640

645 }

646

647

648

649

650

651

652 if (!accept_new)

653 break;

654 }

655

656 if (accept_new)

657 {

658

661 }

662 else

663 {

664

667 }

668}

669

670

671

672

673

674

675

676

677

678

679

680

681

682

683

684

685

686

687bool

689 Cost startup_cost, Cost total_cost,

690 List *pathkeys, Relids required_outer)

691{

692 List *new_path_pathkeys;

693 bool consider_startup;

695

696

697 new_path_pathkeys = required_outer ? NIL : pathkeys;

698

699

701

702 foreach(p1, parent_rel->pathlist)

703 {

706

707

708

709

710

711

712

714 {

715 if (disabled_nodes < old_path->disabled_nodes)

716 break;

717 }

718 else if (total_cost <= old_path->total_cost * STD_FUZZ_FACTOR)

719 break;

720

721

722

723

724

725

726

727

728

729

731 !consider_startup)

732 {

733

734 List *old_path_pathkeys;

735

736 old_path_pathkeys = old_path->param_info ? NIL : old_path->pathkeys;

738 old_path_pathkeys);

741 {

742

744 {

745

746 return false;

747 }

748 }

749 }

750 }

751

752 return true;

753}

754

755

756

757

758

759

760

761

762

763

764

765

766

767

768

769

770

771

772

773

774

775

776

777

778

779

780

781

782

783

784

785

786

787

788

789

790

791

792

793

794void

796{

797 bool accept_new = true;

798 int insert_at = 0;

800

801

803

804

806

807

809

810

811

812

813

815 {

817 bool remove_old = false;

819

820

822

823

825 {

827 {

829 accept_new = false;

830 else

831 remove_old = true;

832 }

835 {

836

838 accept_new = false;

839 }

842 {

843

845 remove_old = true;

846 }

848 {

849

850 remove_old = true;

851 }

853 {

854

855 accept_new = false;

856 }

858 {

859

860 remove_old = true;

861 }

862 else

863 {

864

865

866

867

868 accept_new = false;

869 }

870 }

871

872

873

874

875 if (remove_old)

876 {

880 }

881 else

882 {

883

886 }

887

888

889

890

891

892

893 if (!accept_new)

894 break;

895 }

896

897 if (accept_new)

898 {

899

902 }

903 else

904 {

905

907 }

908}

909

910

911

912

913

914

915

916

917

918

919

920bool

922 Cost total_cost, List *pathkeys)

923{

925

926

927

928

929

930

931

932

933

934

935

936

938 {

941

944 {

947 return false;

950 return true;

951 }

952 }

953

954

955

956

957

958

959

960

961

962

963

964

965 if (add\_path\_precheck(parent_rel, disabled_nodes, total_cost, total_cost,

966 pathkeys, NULL))

967 return false;

968

969 return true;

970}

971

972

973

974

975

976

977

978

979

980

981

984 Relids required_outer, int parallel_workers)

985{

987

988 pathnode->pathtype = T_SeqScan;

989 pathnode->parent = rel;

990 pathnode->pathtarget = rel->reltarget;

992 required_outer);

996 pathnode->pathkeys = NIL;

997

999

1000 return pathnode;

1001}

1002

1003

1004

1005

1006

1009{

1011

1012 pathnode->pathtype = T_SampleScan;

1013 pathnode->parent = rel;

1014 pathnode->pathtarget = rel->reltarget;

1016 required_outer);

1020 pathnode->pathkeys = NIL;

1021

1023

1024 return pathnode;

1025}

1026

1027

1028

1029

1030

1031

1032

1033

1034

1035

1036

1037

1038

1039

1040

1041

1042

1043

1044

1045

1046

1047

1051 List *indexclauses,

1052 List *indexorderbys,

1053 List *indexorderbycols,

1054 List *pathkeys,

1056 bool indexonly,

1057 Relids required_outer,

1058 double loop_count,

1059 bool partial_path)

1060{

1063

1064 pathnode->path.pathtype = indexonly ? T_IndexOnlyScan : T_IndexScan;

1065 pathnode->path.parent = rel;

1068 required_outer);

1073

1079

1080 cost_index(pathnode, root, loop_count, partial_path);

1081

1082 return pathnode;

1083}

1084

1085

1086

1087

1088

1089

1090

1091

1092

1093

1094

1095

1096

1100 Path *bitmapqual,

1101 Relids required_outer,

1102 double loop_count,

1103 int parallel_degree)

1104{

1106

1108 pathnode->path.parent = rel;

1111 required_outer);

1116

1118

1120 pathnode->path.param_info,

1121 bitmapqual, loop_count);

1122

1123 return pathnode;

1124}

1125

1126

1127

1128

1129

1133 List *bitmapquals)

1134{

1136 Relids required_outer = NULL;

1138

1140 pathnode->path.parent = rel;

1142

1143

1144

1145

1146

1147

1148 foreach(lc, bitmapquals)

1149 {

1151

1154 }

1156 required_outer);

1157

1158

1159

1160

1161

1162

1163

1167

1169

1171

1172

1174

1175 return pathnode;

1176}

1177

1178

1179

1180

1181

1185 List *bitmapquals)

1186{

1188 Relids required_outer = NULL;

1190

1192 pathnode->path.parent = rel;

1194

1195

1196

1197

1198

1199

1200 foreach(lc, bitmapquals)

1201 {

1203

1206 }

1208 required_outer);

1209

1210

1211

1212

1213

1214

1215

1219

1221

1223

1224

1226

1227 return pathnode;

1228}

1229

1230

1231

1232

1233

1236 Relids required_outer)

1237{

1239

1241 pathnode->path.parent = rel;

1244 required_outer);

1249

1250 pathnode->tidquals = tidquals;

1251

1253 pathnode->path.param_info);

1254

1255 return pathnode;

1256}

1257

1258

1259

1260

1261

1262

1265 List *tidrangequals, Relids required_outer)

1266{

1268

1270 pathnode->path.parent = rel;

1273 required_outer);

1278

1280

1282 pathnode->path.param_info);

1283

1284 return pathnode;

1285}

1286

1287

1288

1289

1290

1291

1292

1293

1294

1295

1296

1297

1298

1302 List *subpaths, List *partial_subpaths,

1303 List *pathkeys, Relids required_outer,

1304 int parallel_workers, bool parallel_aware,

1305 double rows)

1306{

1309

1310 Assert(!parallel_aware || parallel_workers > 0);

1311

1313 pathnode->path.parent = rel;

1315

1316

1317

1318

1319

1320

1321

1322

1323

1324

1325

1326

1329 rel,

1330 required_outer);

1331 else

1333 required_outer);

1334

1339

1340

1341

1342

1343

1344

1345

1346

1347

1348

1350 {

1351

1352

1353

1354

1355

1357

1360 }

1363

1364

1365

1366

1367

1370 else

1372

1373 foreach(l, pathnode->subpaths)

1374 {

1376

1379

1380

1382 }

1383

1385

1386

1387

1388

1389

1390

1391

1392

1393

1394

1395

1397 {

1399

1401 {

1405 }

1406 else

1408

1410 }

1411 else

1413

1414

1415 if (rows >= 0)

1417

1418 return pathnode;

1419}

1420

1421

1422

1423

1424

1425

1426

1427

1428

1429

1430static int

1432{

1435 int cmp;

1436

1438 if (cmp != 0)

1439 return -cmp;

1440 return bms_compare(path1->parent->relids, path2->parent->relids);

1441}

1442

1443

1444

1445

1446

1447

1448

1449

1450

1451

1452static int

1454{

1457 int cmp;

1458

1460 if (cmp != 0)

1461 return -cmp;

1462 return bms_compare(path1->parent->relids, path2->parent->relids);

1463}

1464

1465

1466

1467

1468

1469

1473 List *subpaths,

1474 List *pathkeys,

1475 Relids required_outer)

1476{

1478 int input_disabled_nodes;

1479 Cost input_startup_cost;

1480 Cost input_total_cost;

1482

1483

1484

1485

1486

1488

1490 pathnode->path.parent = rel;

1492 pathnode->path.param_info = NULL;

1497 pathnode->subpaths = subpaths;

1498

1499

1500

1501

1502

1505 else

1507

1508

1509

1510

1512 input_disabled_nodes = 0;

1513 input_startup_cost = 0;

1514 input_total_cost = 0;

1515 foreach(l, subpaths)

1516 {

1518

1519

1521

1525

1527 {

1528

1529 input_disabled_nodes += subpath->disabled_nodes;

1530 input_startup_cost += subpath->startup_cost;

1531 input_total_cost += subpath->total_cost;

1532 }

1533 else

1534 {

1535

1536 Path sort_path;

1537

1540 pathkeys,

1541 subpath->disabled_nodes,

1544 subpath->pathtarget->width,

1545 0.0,

1549 input_startup_cost += sort_path.startup_cost;

1550 input_total_cost += sort_path.total_cost;

1551 }

1552 }

1553

1554

1555

1556

1557

1558

1559

1561 ((Path *) linitial(subpaths))->parallel_aware ==

1563 {

1567 }

1568 else

1571 input_disabled_nodes,

1572 input_startup_cost, input_total_cost,

1574

1575 return pathnode;

1576}

1577

1578

1579

1580

1581

1582

1583

1584

1588{

1590

1592 pathnode->path.parent = rel;

1593 pathnode->path.pathtarget = target;

1594 pathnode->path.param_info = NULL;

1599 pathnode->quals = havingqual;

1600

1601

1602

1603

1604

1605

1610

1611

1612

1613

1614

1615 if (havingqual)

1616 {

1618

1620

1623 }

1624

1625 return pathnode;

1626}

1627

1628

1629

1630

1631

1632

1635{

1637

1639

1641 pathnode->path.parent = rel;

1643 pathnode->path.param_info = subpath->param_info;

1649

1651

1653 subpath->disabled_nodes,

1657 subpath->pathtarget->width);

1658

1659 return pathnode;

1660}

1661

1662

1663

1664

1665

1668 List *param_exprs, List *hash_operators,

1669 bool singlerow, bool binary_mode, double calls)

1670{

1672

1674

1676 pathnode->path.parent = rel;

1678 pathnode->path.param_info = subpath->param_info;

1684

1688 pathnode->singlerow = singlerow;

1691

1692

1693

1694

1695

1696

1697

1699

1700

1703

1704

1705

1706

1707

1711

1712 return pathnode;

1713}

1714

1715

1716

1717

1718

1719

1720

1721

1722

1723

1724

1725

1729{

1731 Path sort_path;

1732 Path agg_path;

1734 int numCols;

1735

1736

1739

1742

1743

1746

1747

1749 return NULL;

1750

1751

1752

1753

1754

1755

1756

1757

1758

1759

1760

1762

1764

1766 pathnode->path.parent = rel;

1768 pathnode->path.param_info = subpath->param_info;

1773

1774

1775

1776

1777

1779

1781

1782

1783

1784

1785

1786

1789

1790

1791

1792

1793

1794

1795

1800 {

1807

1809

1811

1812 return pathnode;

1813 }

1814

1815

1816

1817

1818

1819

1820

1821

1822

1823

1825 {

1827

1829 {

1830 List *sub_tlist_colnos;

1831

1834

1835 if (sub_tlist_colnos &&

1837 sub_tlist_colnos,

1839 {

1846

1848

1850

1851 return pathnode;

1852 }

1853 }

1854 }

1855

1856

1860 NULL,

1861 NULL);

1863

1865 {

1866

1867

1868

1870 subpath->disabled_nodes,

1873 subpath->pathtarget->width,

1874 0.0,

1876 -1.0);

1877

1878

1879

1880

1881

1882

1883

1885 }

1886

1888 {

1889

1890

1891

1892

1893 int hashentrysize = subpath->pathtarget->width + 64;

1894

1896 {

1897

1898

1899

1900

1902 }

1903 else

1906 numCols, pathnode->path.rows,

1908 subpath->disabled_nodes,

1912 subpath->pathtarget->width);

1913 }

1914

1916 {

1921 else

1923 }

1928 else

1929 {

1930

1932 return NULL;

1933 }

1934

1936 {

1940 }

1941 else

1942 {

1946 }

1947

1949

1951

1952 return pathnode;

1953}

1954

1955

1956

1957

1958

1959

1960

1964 Relids required_outer, double *rows)

1965{

1967 int input_disabled_nodes = 0;

1968 Cost input_startup_cost = 0;

1969 Cost input_total_cost = 0;

1970

1973

1974

1975

1976

1977

1978

1979

1980

1982 elog(ERROR, "gather merge input not sufficiently sorted");

1983

1985 pathnode->path.parent = rel;

1987 required_outer);

1989

1993 pathnode->path.pathtarget = target ? target : rel->reltarget;

1994

1995 input_disabled_nodes += subpath->disabled_nodes;

1996 input_startup_cost += subpath->startup_cost;

1997 input_total_cost += subpath->total_cost;

1998

2000 input_disabled_nodes, input_startup_cost,

2001 input_total_cost, rows);

2002

2003 return pathnode;

2004}

2005

2006

2007

2008

2009

2010

2011

2012

2013

2014

2015

2016

2017static List *

2019{

2022

2023 foreach(l, tlist)

2024 {

2026

2027 if (!var || IsA(var, Var) ||

2028 var->varno != relid)

2029 return NIL;

2030

2032 }

2033 return result;

2034}

2035

2036

2037

2038

2039

2040

2041

2042

2046{

2048

2050

2052 pathnode->path.parent = rel;

2053 pathnode->path.pathtarget = target;

2055 required_outer);

2059 pathnode->path.pathkeys = NIL;

2060

2064

2066 {

2070 }

2071

2073

2074 return pathnode;

2075}

2076

2077

2078

2079

2080

2081

2082

2083

2084

2085

2086

2089 bool trivial_pathtarget,

2090 List *pathkeys, Relids required_outer)

2091{

2093

2095 pathnode->path.parent = rel;

2098 required_outer);

2105

2107 trivial_pathtarget);

2108

2109 return pathnode;

2110}

2111

2112

2113

2114

2115

2116

2119 List *pathkeys, Relids required_outer)

2120{

2122

2123 pathnode->pathtype = T_FunctionScan;

2124 pathnode->parent = rel;

2125 pathnode->pathtarget = rel->reltarget;

2127 required_outer);

2131 pathnode->pathkeys = pathkeys;

2132

2134

2135 return pathnode;

2136}

2137

2138

2139

2140

2141

2142

2145 Relids required_outer)

2146{

2148

2149 pathnode->pathtype = T_TableFuncScan;

2150 pathnode->parent = rel;

2151 pathnode->pathtarget = rel->reltarget;

2153 required_outer);

2157 pathnode->pathkeys = NIL;

2158

2160

2161 return pathnode;

2162}

2163

2164

2165

2166

2167

2168

2171 Relids required_outer)

2172{

2174

2175 pathnode->pathtype = T_ValuesScan;

2176 pathnode->parent = rel;

2177 pathnode->pathtarget = rel->reltarget;

2179 required_outer);

2183 pathnode->pathkeys = NIL;

2184

2186

2187 return pathnode;

2188}

2189

2190

2191

2192

2193

2194

2197 List *pathkeys, Relids required_outer)

2198{

2200

2201 pathnode->pathtype = T_CteScan;

2202 pathnode->parent = rel;

2203 pathnode->pathtarget = rel->reltarget;

2205 required_outer);

2209 pathnode->pathkeys = pathkeys;

2210

2212

2213 return pathnode;

2214}

2215

2216

2217

2218

2219

2220

2223 Relids required_outer)

2224{

2226

2227 pathnode->pathtype = T_NamedTuplestoreScan;

2228 pathnode->parent = rel;

2229 pathnode->pathtarget = rel->reltarget;

2231 required_outer);

2235 pathnode->pathkeys = NIL;

2236

2238

2239 return pathnode;

2240}

2241

2242

2243

2244

2245

2246

2249 Relids required_outer)

2250{

2252

2253 pathnode->pathtype = T_Result;

2254 pathnode->parent = rel;

2255 pathnode->pathtarget = rel->reltarget;

2257 required_outer);

2261 pathnode->pathkeys = NIL;

2262

2264

2265 return pathnode;

2266}

2267

2268

2269

2270

2271

2272

2275 Relids required_outer)

2276{

2278

2279 pathnode->pathtype = T_WorkTableScan;

2280 pathnode->parent = rel;

2281 pathnode->pathtarget = rel->reltarget;

2283 required_outer);

2287 pathnode->pathkeys = NIL;

2288

2289

2291

2292 return pathnode;

2293}

2294

2295

2296

2297

2298

2299

2300

2301

2302

2303

2304

2305

2309 double rows, int disabled_nodes,

2310 Cost startup_cost, Cost total_cost,

2311 List *pathkeys,

2312 Relids required_outer,

2313 Path *fdw_outerpath,

2314 List *fdw_restrictinfo,

2315 List *fdw_private)

2316{

2318

2319

2321

2323 pathnode->path.parent = rel;

2324 pathnode->path.pathtarget = target ? target : rel->reltarget;

2326 required_outer);

2335

2339

2340 return pathnode;

2341}

2342

2343

2344

2345

2346

2347

2348

2349

2350

2351

2352

2353

2357 double rows, int disabled_nodes,

2358 Cost startup_cost, Cost total_cost,

2359 List *pathkeys,

2360 Relids required_outer,

2361 Path *fdw_outerpath,

2362 List *fdw_restrictinfo,

2363 List *fdw_private)

2364{

2366

2367

2368

2369

2370

2371

2372

2373

2375 elog(ERROR, "parameterized foreign joins are not supported yet");

2376

2378 pathnode->path.parent = rel;

2379 pathnode->path.pathtarget = target ? target : rel->reltarget;

2380 pathnode->path.param_info = NULL;

2389

2393

2394 return pathnode;

2395}

2396

2397

2398

2399

2400

2401

2402

2403

2404

2405

2406

2407

2411 double rows, int disabled_nodes,

2412 Cost startup_cost, Cost total_cost,

2413 List *pathkeys,

2414 Path *fdw_outerpath,

2415 List *fdw_restrictinfo,

2416 List *fdw_private)

2417{

2419

2420

2421

2422

2423

2425

2427 pathnode->path.parent = rel;

2428 pathnode->path.pathtarget = target ? target : rel->reltarget;

2429 pathnode->path.param_info = NULL;

2438

2442

2443 return pathnode;

2444}

2445

2446

2447

2448

2449

2450

2451

2452

2453

2454

2457 Relids outer_paramrels,

2459 Relids inner_paramrels)

2460{

2461 Relids required_outer;

2462

2463

2465

2466 if (!inner_paramrels)

2467 return bms_copy(outer_paramrels);

2468

2469 required_outer = bms_union(outer_paramrels, inner_paramrels);

2470

2472 outerrelids);

2473 return required_outer;

2474}

2475

2476

2477

2478

2479

2480

2481

2484{

2489 Relids required_outer;

2490

2491

2492

2493

2494

2495

2496

2497

2498 if (inner_path->parent->top_parent_relids)

2499 innerrelids = inner_path->parent->top_parent_relids;

2500 else

2501 innerrelids = inner_path->parent->relids;

2502

2503 if (outer_path->parent->top_parent_relids)

2504 outerrelids = outer_path->parent->top_parent_relids;

2505 else

2506 outerrelids = outer_path->parent->relids;

2507

2508

2511

2512 required_outer = bms_union(outer_paramrels, inner_paramrels);

2513

2514 return required_outer;

2515}

2516

2517

2518

2519

2520

2521

2522

2523

2524

2525

2526

2527

2528

2529

2530

2531

2532

2533

2540 Path *outer_path,

2541 Path *inner_path,

2542 List *restrict_clauses,

2543 List *pathkeys,

2544 Relids required_outer)

2545{

2549

2550

2551

2552

2553

2554 if (outer_path->parent->top_parent_relids)

2555 outerrelids = outer_path->parent->top_parent_relids;

2556 else

2557 outerrelids = outer_path->parent->relids;

2558

2559

2560

2561

2562

2563

2564

2565

2566

2567 if (bms_overlap(inner_req_outer, outerrelids))

2568 {

2572

2573 foreach(lc, restrict_clauses)

2574 {

2576

2578 jclauses = lappend(jclauses, rinfo);

2579 }

2580 restrict_clauses = jclauses;

2581 }

2582

2583 pathnode->jpath.path.pathtype = T_NestLoop;

2584 pathnode->jpath.path.parent = joinrel;

2585 pathnode->jpath.path.pathtarget = joinrel->reltarget;

2586 pathnode->jpath.path.param_info =

2588 joinrel,

2589 outer_path,

2590 inner_path,

2592 required_outer,

2593 &restrict_clauses);

2594 pathnode->jpath.path.parallel_aware = false;

2597

2599 pathnode->jpath.path.pathkeys = pathkeys;

2605

2607

2608 return pathnode;

2609}

2610

2611

2612

2613

2614

2615

2616

2617

2618

2619

2620

2621

2622

2623

2624

2625

2626

2627

2628

2629

2630

2637 Path *outer_path,

2638 Path *inner_path,

2639 List *restrict_clauses,

2640 List *pathkeys,

2641 Relids required_outer,

2642 List *mergeclauses,

2643 List *outersortkeys,

2644 List *innersortkeys,

2645 int outer_presorted_keys)

2646{

2648

2649 pathnode->jpath.path.pathtype = T_MergeJoin;

2650 pathnode->jpath.path.parent = joinrel;

2651 pathnode->jpath.path.pathtarget = joinrel->reltarget;

2652 pathnode->jpath.path.param_info =

2654 joinrel,

2655 outer_path,

2656 inner_path,

2658 required_outer,

2659 &restrict_clauses);

2660 pathnode->jpath.path.parallel_aware = false;

2663

2665 pathnode->jpath.path.pathkeys = pathkeys;

2675

2676

2677

2679

2680 return pathnode;

2681}

2682

2683

2684

2685

2686

2687

2688

2689

2690

2691

2692

2693

2694

2695

2696

2697

2698

2705 Path *outer_path,

2706 Path *inner_path,

2707 bool parallel_hash,

2708 List *restrict_clauses,

2709 Relids required_outer,

2710 List *hashclauses)

2711{

2713

2714 pathnode->jpath.path.pathtype = T_HashJoin;

2715 pathnode->jpath.path.parent = joinrel;

2716 pathnode->jpath.path.pathtarget = joinrel->reltarget;

2717 pathnode->jpath.path.param_info =

2719 joinrel,

2720 outer_path,

2721 inner_path,

2723 required_outer,

2724 &restrict_clauses);

2725 pathnode->jpath.path.parallel_aware =

2729

2731

2732

2733

2734

2735

2736

2737

2738

2739

2740

2741

2742

2743 pathnode->jpath.path.pathkeys = NIL;

2750

2751

2753

2754 return pathnode;

2755}

2756

2757

2758

2759

2760

2761

2762

2763

2764

2770{

2773

2774

2775

2776

2777

2778

2779

2780

2782 {

2784

2788 }

2789

2791 pathnode->path.parent = rel;

2792 pathnode->path.pathtarget = target;

2793

2794 pathnode->path.param_info = NULL;

2797 subpath->parallel_safe &&

2800

2802

2804

2805

2806

2807

2808

2809

2810

2811

2812

2813

2814 oldtarget = subpath->pathtarget;

2817 {

2818

2819 pathnode->dummypp = true;

2820

2821

2822

2823

2831 }

2832 else

2833 {

2834

2835 pathnode->dummypp = false;

2836

2837

2838

2839

2840

2848 }

2849

2850 return pathnode;

2851}

2852

2853

2854

2855

2856

2857

2858

2859

2860

2861

2862

2863

2864

2865

2866

2867

2868

2869

2870

2871

2872

2873

2874

2880{

2882

2883

2884

2885

2886

2889

2890

2891

2892

2893

2894 oldcost = path->pathtarget->cost;

2895 path->pathtarget = target;

2896

2900

2901

2902

2903

2904

2905

2906

2909 {

2910

2911

2912

2913

2914

2915

2916

2917

2918

2919

2921 {

2923

2928 target);

2929 }

2930 else

2931 {

2933

2936 gmpath->subpath->parent,

2938 target);

2939 }

2940 }

2943 {

2944

2945

2946

2947

2948

2950 }

2951

2952 return path;

2953}

2954

2955

2956

2957

2958

2959

2960

2961

2962

2963

2969{

2971 double tlist_rows;

2973

2975 pathnode->path.parent = rel;

2976 pathnode->path.pathtarget = target;

2977

2978 pathnode->path.param_info = NULL;

2981 subpath->parallel_safe &&

2984

2986

2988

2989

2990

2991

2992

2993 tlist_rows = 1;

2994 foreach(lc, target->exprs)

2995 {

2997 double itemrows;

2998

3000 if (tlist_rows < itemrows)

3001 tlist_rows = itemrows;

3002 }

3003

3004

3005

3006

3007

3008

3009

3018

3019 return pathnode;

3020}

3021

3022

3023

3024

3025

3026

3027

3028

3029

3030

3031

3032

3033

3038 List *pathkeys,

3039 int presorted_keys,

3040 double limit_tuples)

3041{

3044

3045 pathnode->path.pathtype = T_IncrementalSort;

3046 pathnode->path.parent = rel;

3047

3048 pathnode->path.pathtarget = subpath->pathtarget;

3049

3050 pathnode->path.param_info = NULL;

3056

3058

3060 root, pathkeys, presorted_keys,

3061 subpath->disabled_nodes,

3065 subpath->pathtarget->width,

3066 0.0,

3068

3069 sort->nPresortedCols = presorted_keys;

3070

3071 return sort;

3072}

3073

3074

3075

3076

3077

3078

3079

3080

3081

3082

3083

3088 List *pathkeys,

3089 double limit_tuples)

3090{

3092

3094 pathnode->path.parent = rel;

3095

3096 pathnode->path.pathtarget = subpath->pathtarget;

3097

3098 pathnode->path.param_info = NULL;

3104

3106

3108 subpath->disabled_nodes,

3111 subpath->pathtarget->width,

3112 0.0,

3114

3115 return pathnode;

3116}

3117

3118

3119

3120

3121

3122

3123

3124

3125

3126

3127

3128

3133 List *groupClause,

3135 double numGroups)

3136{

3139

3141 pathnode->path.parent = rel;

3142 pathnode->path.pathtarget = target;

3143

3144 pathnode->path.param_info = NULL;

3149

3151

3153

3155 pathnode->qual = qual;

3156

3159 numGroups,

3160 qual,

3161 subpath->disabled_nodes,

3164

3165

3169

3170 return pathnode;

3171}

3172

3173

3174

3175

3176

3177

3178

3179

3180

3181

3182

3183

3184

3185

3186

3187

3188

3193 int numCols,

3194 double numGroups)

3195{

3197

3199 pathnode->path.parent = rel;

3200

3201 pathnode->path.pathtarget = subpath->pathtarget;

3202

3203 pathnode->path.param_info = NULL;

3208

3210

3212 pathnode->numkeys = numCols;

3213

3214

3215

3216

3217

3218

3223 pathnode->path.rows = numGroups;

3224

3225 return pathnode;

3226}

3227

3228

3229

3230

3231

3232

3233

3234

3235

3236

3237

3238

3239

3240

3241

3249 List *groupClause,

3252 double numGroups)

3253{

3255

3257 pathnode->path.parent = rel;

3258 pathnode->path.pathtarget = target;

3259

3260 pathnode->path.param_info = NULL;

3265

3267 {

3268

3269

3270

3271

3272

3273

3274

3275

3278 root->num_groupby_pathkeys);

3279 else

3281 }

3282 else

3283 pathnode->path.pathkeys = NIL;

3284

3286

3288 pathnode->aggsplit = aggsplit;

3289 pathnode->numGroups = numGroups;

3292 pathnode->qual = qual;

3293

3295 aggstrategy, aggcosts,

3297 qual,

3298 subpath->disabled_nodes,

3301

3302

3306

3307 return pathnode;

3308}

3309

3310

3311

3312

3313

3314

3315

3316

3317

3318

3319

3320

3321

3322

3323

3324

3329 List *having_qual,

3331 List *rollups,

3333{

3337 bool is_first = true;

3338 bool is_first_sort = true;

3339

3340

3342 pathnode->path.parent = rel;

3343 pathnode->path.pathtarget = target;

3344 pathnode->path.param_info = subpath->param_info;

3350

3351

3352

3353

3354

3359

3363

3364

3365

3366

3367

3368

3371 else

3373

3375 pathnode->rollups = rollups;

3376 pathnode->qual = having_qual;

3378

3382

3383 foreach(lc, rollups)

3384 {

3388

3389

3390

3391

3392

3393

3394

3395

3396

3397

3398

3399 if (is_first)

3400 {

3402 aggstrategy,

3403 agg_costs,

3404 numGroupCols,

3406 having_qual,

3407 subpath->disabled_nodes,

3411 subpath->pathtarget->width);

3412 is_first = false;

3414 is_first_sort = false;

3415 }

3416 else

3417 {

3418 Path sort_path;

3419 Path agg_path;

3420

3421 if (rollup->is_hashed || is_first_sort)

3422 {

3423

3424

3425

3426

3429 agg_costs,

3430 numGroupCols,

3432 having_qual,

3433 0, 0.0, 0.0,

3435 subpath->pathtarget->width);

3437 is_first_sort = false;

3438 }

3439 else

3440 {

3441

3443 0.0,

3445 subpath->pathtarget->width,

3446 0.0,

3448 -1.0);

3449

3450

3451

3454 agg_costs,

3455 numGroupCols,

3457 having_qual,

3461 sort_path.rows,

3462 subpath->pathtarget->width);

3463 }

3464

3468 }

3469 }

3470

3471

3475

3476 return pathnode;

3477}

3478

3479

3480

3481

3482

3483

3484

3485

3486

3487

3492 List *mmaggregates,

3493 List *quals)

3494{

3496 Cost initplan_cost;

3497 int initplan_disabled_nodes = 0;

3499

3500

3502 pathnode->path.parent = rel;

3503 pathnode->path.pathtarget = target;

3504

3505 pathnode->path.param_info = NULL;

3509

3512

3514 pathnode->quals = quals;

3515

3516

3517 initplan_cost = 0;

3518 foreach(lc, mmaggregates)

3519 {

3521

3523 initplan_cost += mminfo->pathcost;

3526 }

3527

3528

3533

3534

3535

3536

3537

3538 if (quals)

3539 {

3541

3545 }

3546

3547

3548

3549

3550

3551

3552

3557

3558 return pathnode;

3559}

3560

3561

3562

3563

3564

3565

3566

3567

3568

3569

3570

3571

3572

3573

3574

3575

3576

3577

3578

3584 List *windowFuncs,

3585 List *runCondition,

3588 bool topwindow)

3589{

3591

3592

3593 Assert(qual == NIL || topwindow);

3594

3596 pathnode->path.parent = rel;

3597 pathnode->path.pathtarget = target;

3598

3599 pathnode->path.param_info = NULL;

3604

3606

3608 pathnode->winclause = winclause;

3609 pathnode->qual = qual;

3611 pathnode->topwindow = topwindow;

3612

3613

3614

3615

3616

3617

3618

3620 windowFuncs,

3621 winclause,

3622 subpath->disabled_nodes,

3626

3627

3631

3632 return pathnode;

3633}

3634

3635

3636

3637

3638

3639

3640

3641

3642

3643

3644

3645

3646

3647

3648

3649

3650

3651

3655 Path *leftpath,

3656 Path *rightpath,

3659 List *groupList,

3660 double numGroups,

3661 double outputRows)

3662{

3664

3666 pathnode->path.parent = rel;

3668

3669 pathnode->path.param_info = NULL;

3675

3678

3679 pathnode->leftpath = leftpath;

3680 pathnode->rightpath = rightpath;

3681 pathnode->cmd = cmd;

3682 pathnode->strategy = strategy;

3683 pathnode->groupList = groupList;

3684 pathnode->numGroups = numGroups;

3685

3686

3687

3688

3689

3690

3694 {

3695

3696

3697

3698

3699

3705

3706

3707

3708

3709

3710

3712 }

3713 else

3714 {

3715 Size hashentrysize;

3716

3717

3718

3719

3720

3721

3726

3727

3728

3729

3730

3731

3733

3734

3735

3736

3737

3738

3741

3742

3743

3744

3745

3746 hashentrysize = MAXALIGN(leftpath->pathtarget->width) +

3750 }

3751 pathnode->path.rows = outputRows;

3752

3753 return pathnode;

3754}

3755

3756

3757

3758

3759

3760

3761

3762

3763

3764

3765

3766

3767

3768

3769

3773 Path *leftpath,

3774 Path *rightpath,

3776 List *distinctList,

3777 int wtParam,

3778 double numGroups)

3779{

3781

3783 pathnode->path.parent = rel;

3784 pathnode->path.pathtarget = target;

3785

3786 pathnode->path.param_info = NULL;

3790

3792

3794

3795 pathnode->leftpath = leftpath;

3796 pathnode->rightpath = rightpath;

3798 pathnode->wtParam = wtParam;

3799 pathnode->numGroups = numGroups;

3800

3802

3803 return pathnode;

3804}

3805

3806

3807

3808

3809

3810

3811

3812

3813

3814

3818{

3820

3822 pathnode->path.parent = rel;

3823

3824 pathnode->path.pathtarget = subpath->pathtarget;

3825

3826 pathnode->path.param_info = NULL;

3831

3832

3833

3834

3835

3837

3839 pathnode->rowMarks = rowMarks;

3840 pathnode->epqParam = epqParam;

3841

3842

3843

3844

3845

3846

3851

3852 return pathnode;

3853}

3854

3855

3856

3857

3858

3859

3860

3861

3862

3863

3864

3865

3866

3867

3868

3869

3870

3871

3872

3873

3874

3875

3876

3877

3878

3882 CmdType operation, bool canSetTag,

3883 Index nominalRelation, Index rootRelation,

3884 bool partColsUpdated,

3885 List *resultRelations,

3886 List *updateColnosLists,

3887 List *withCheckOptionLists, List *returningLists,

3889 List *mergeActionLists, List *mergeJoinConditions,

3890 int epqParam)

3891{

3893

3897 updateColnosLists == NIL));

3898 Assert(withCheckOptionLists == NIL ||

3902

3904 pathnode->path.parent = rel;

3905

3907

3908 pathnode->path.param_info = NULL;

3913

3914

3915

3916

3917

3918

3919

3920

3921

3922

3923

3927 if (returningLists != NIL)

3928 {

3930

3931

3932

3933

3934

3935

3936

3937 pathnode->path.pathtarget->width = subpath->pathtarget->width;

3938 }

3939 else

3940 {

3942 pathnode->path.pathtarget->width = 0;

3943 }

3944

3946 pathnode->operation = operation;

3947 pathnode->canSetTag = canSetTag;

3955 pathnode->rowMarks = rowMarks;

3957 pathnode->epqParam = epqParam;

3960

3961 return pathnode;

3962}

3963

3964

3965

3966

3967

3968

3969

3970

3971

3972

3973

3974

3975

3976

3977

3978

3979

3980

3984 Node *limitOffset, Node *limitCount,

3987{

3989

3991 pathnode->path.parent = rel;

3992

3993 pathnode->path.pathtarget = subpath->pathtarget;

3994

3995 pathnode->path.param_info = NULL;

4009

4010

4011

4012

4016 offset_est, count_est);

4017

4018 return pathnode;

4019}

4020

4021

4022

4023

4024

4025

4026

4027

4028

4029

4030

4031

4032

4033

4034

4035

4036

4037void

4039 Cost *startup_cost,

4040 Cost *total_cost,

4041 int64 offset_est,

4042 int64 count_est)

4043{

4044 double input_rows = *rows;

4045 Cost input_startup_cost = *startup_cost;

4046 Cost input_total_cost = *total_cost;

4047

4048 if (offset_est != 0)

4049 {

4050 double offset_rows;

4051

4052 if (offset_est > 0)

4053 offset_rows = (double) offset_est;

4054 else

4056 if (offset_rows > *rows)

4057 offset_rows = *rows;

4058 if (input_rows > 0)

4059 *startup_cost +=

4060 (input_total_cost - input_startup_cost)

4061 * offset_rows / input_rows;

4062 *rows -= offset_rows;

4063 if (*rows < 1)

4064 *rows = 1;

4065 }

4066

4067 if (count_est != 0)

4068 {

4069 double count_rows;

4070

4071 if (count_est > 0)

4072 count_rows = (double) count_est;

4073 else

4075 if (count_rows > *rows)

4076 count_rows = *rows;

4077 if (input_rows > 0)

4078 *total_cost = *startup_cost +

4079 (input_total_cost - input_startup_cost)

4080 * count_rows / input_rows;

4081 *rows = count_rows;

4082 if (*rows < 1)

4083 *rows = 1;

4084 }

4085}

4086

4087

4088

4089

4090

4091

4092

4093

4094

4095

4096

4097

4098

4099

4100

4101

4102

4103

4104

4107 Relids required_outer,

4108 double loop_count)

4109{

4111

4112

4114 return NULL;

4116 {

4117 case T_SeqScan:

4119 case T_SampleScan:

4121 case T_IndexScan:

4122 case T_IndexOnlyScan:

4123 {

4126

4127

4128

4129

4130

4131

4132

4133

4134 memcpy(newpath, ipath, sizeof(IndexPath));

4135 newpath->path.param_info =

4138 return (Path *) newpath;

4139 }

4140 case T_BitmapHeapScan:

4141 {

4143

4145 rel,

4147 required_outer,

4148 loop_count, 0);

4149 }

4150 case T_SubqueryScan:

4151 {

4154 bool trivial_pathtarget;

4155

4156

4157

4158

4159

4160

4161

4162

4163 trivial_pathtarget =

4165

4167 rel,

4169 trivial_pathtarget,

4171 required_outer);

4172 }

4173 case T_Result:

4174

4177 break;

4178 case T_Append:

4179 {

4182 List *partialpaths = NIL;

4183 int i;

4185

4186

4187 i = 0;

4188 foreach(lc, apath->subpaths)

4189 {

4191

4193 required_outer,

4194 loop_count);

4195 if (spath == NULL)

4196 return NULL;

4197

4198 if (i < apath->first_partial_path)

4199 childpaths = lappend(childpaths, spath);

4200 else

4201 partialpaths = lappend(partialpaths, spath);

4202 i++;

4203 }

4204 return (Path *)

4209 -1);

4210 }

4211 case T_Material:

4212 {

4215

4217 required_outer,

4218 loop_count);

4219 if (spath == NULL)

4220 return NULL;

4222 }

4223 case T_Memoize:

4224 {

4227

4229 required_outer,

4230 loop_count);

4231 if (spath == NULL)

4232 return NULL;

4234 spath,

4240 }

4241 default:

4242 break;

4243 }

4244 return NULL;

4245}

4246

4247

4248

4249

4250

4251

4252

4253

4254

4255

4256

4257

4258

4259

4260

4261

4262

4263

4264

4265

4266

4267

4268

4269

4270

4274{

4275 Path *new_path;

4278 Relids required_outer;

4279

4280#define ADJUST_CHILD_ATTRS(node) \

4281 ((node) = (void *) adjust_appendrel_attrs_multilevel(root, \

4282 (Node *) (node), \

4283 child_rel, \

4284 child_rel->top_parent))

4285

4286#define REPARAMETERIZE_CHILD_PATH(path) \

4287do { \

4288 (path) = reparameterize_path_by_child(root, (path), child_rel); \

4289 if ((path) == NULL) \

4290 return NULL; \

4291} while(0)

4292

4293#define REPARAMETERIZE_CHILD_PATH_LIST(pathlist) \

4294do { \

4295 if ((pathlist) != NIL) \

4296 { \

4297 (pathlist) = reparameterize_pathlist_by_child(root, (pathlist), \

4298 child_rel); \

4299 if ((pathlist) == NIL) \

4300 return NULL; \

4301 } \

4302} while(0)

4303

4304

4305

4306

4307

4308 if (!path->param_info ||

4310 return path;

4311

4312

4313

4314

4315

4316

4317

4318

4319

4320

4321

4322

4323

4325 {

4326 case T_Path:

4327 new_path = path;

4329 if (path->pathtype == T_SampleScan)

4330 {

4331 Index scan_relid = path->parent->relid;

4333

4334

4335 Assert(scan_relid > 0);

4339

4341 }

4342 break;

4343

4344 case T_IndexPath:

4345 {

4347

4350 new_path = (Path *) ipath;

4351 }

4352 break;

4353

4354 case T_BitmapHeapPath:

4355 {

4357

4360 new_path = (Path *) bhpath;

4361 }

4362 break;

4363

4364 case T_BitmapAndPath:

4365 {

4367

4369 new_path = (Path *) bapath;

4370 }

4371 break;

4372

4373 case T_BitmapOrPath:

4374 {

4376

4378 new_path = (Path *) bopath;

4379 }

4380 break;

4381

4382 case T_ForeignPath:

4383 {

4386

4392

4393

4394 rfpc_func =

4395 path->parent->fdwroutine->ReparameterizeForeignPathByChild;

4396 if (rfpc_func)

4398 child_rel);

4399 new_path = (Path *) fpath;

4400 }

4401 break;

4402

4403 case T_CustomPath:

4404 {

4406

4416 child_rel);

4417 new_path = (Path *) cpath;

4418 }

4419 break;

4420

4421 case T_NestPath:

4422 {

4425

4429 new_path = (Path *) npath;

4430 }

4431 break;

4432

4433 case T_MergePath:

4434 {

4437

4442 new_path = (Path *) mpath;

4443 }

4444 break;

4445

4446 case T_HashPath:

4447 {

4450

4455 new_path = (Path *) hpath;

4456 }

4457 break;

4458

4459 case T_AppendPath:

4460 {

4462

4464 new_path = (Path *) apath;

4465 }

4466 break;

4467

4468 case T_MaterialPath:

4469 {

4471

4473 new_path = (Path *) mpath;

4474 }

4475 break;

4476

4477 case T_MemoizePath:

4478 {

4480

4483 new_path = (Path *) mpath;

4484 }

4485 break;

4486

4487 case T_GatherPath:

4488 {

4490

4492 new_path = (Path *) gpath;

4493 }

4494 break;

4495

4496 default:

4497

4498 return NULL;

4499 }

4500

4501

4502

4503

4504

4505

4506 old_ppi = new_path->param_info;

4507 required_outer =

4509 child_rel,

4510 child_rel->top_parent);

4511

4512

4514

4515

4516

4517

4518

4519

4520 if (new_ppi == NULL)

4521 {

4524

4526

4534

4536 }

4538

4539 new_path->param_info = new_ppi;

4540

4541

4542

4543

4544

4545

4546 if (bms_overlap(path->parent->lateral_relids,

4548 {

4549 new_path->pathtarget = copy_pathtarget(new_path->pathtarget);

4551 }

4552

4553 return new_path;

4554}

4555

4556

4557

4558

4559

4560

4561

4562

4563

4564

4565

4566

4567bool

4569{

4570#define REJECT_IF_PATH_NOT_REPARAMETERIZABLE(path) \

4571do { \

4572 if (!path_is_reparameterizable_by_child(path, child_rel)) \

4573 return false; \

4574} while(0)

4575

4576#define REJECT_IF_PATH_LIST_NOT_REPARAMETERIZABLE(pathlist) \

4577do { \

4578 if (!pathlist_is_reparameterizable_by_child(pathlist, child_rel)) \

4579 return false; \

4580} while(0)

4581

4582

4583

4584

4585

4586 if (!path->param_info ||

4588 return true;

4589

4590

4591

4592

4593

4595 {

4596 case T_Path:

4597 case T_IndexPath:

4598 break;

4599

4600 case T_BitmapHeapPath:

4601 {

4603

4605 }

4606 break;

4607

4608 case T_BitmapAndPath:

4609 {

4611

4613 }

4614 break;

4615

4616 case T_BitmapOrPath:

4617 {

4619

4621 }

4622 break;

4623

4624 case T_ForeignPath:

4625 {

4627

4630 }

4631 break;

4632

4633 case T_CustomPath:

4634 {

4636

4638 }

4639 break;

4640

4641 case T_NestPath:

4642 case T_MergePath:

4643 case T_HashPath:

4644 {

4646

4649 }

4650 break;

4651

4652 case T_AppendPath:

4653 {

4655

4657 }

4658 break;

4659

4660 case T_MaterialPath:

4661 {

4663

4665 }

4666 break;

4667

4668 case T_MemoizePath:

4669 {

4671

4673 }

4674 break;

4675

4676 case T_GatherPath:

4677 {

4679

4681 }

4682 break;

4683

4684 default:

4685

4686 return false;

4687 }

4688

4689 return true;

4690}

4691

4692

4693

4694

4695

4696

4697

4698static List *

4700 List *pathlist,

4702{

4705

4706 foreach(lc, pathlist)

4707 {

4709 child_rel);

4710

4711 if (path == NULL)

4712 {

4714 return NIL;

4715 }

4716

4717 result = lappend(result, path);

4718 }

4719

4720 return result;

4721}

4722

4723

4724

4725

4726

4727static bool

4729{

4731

4732 foreach(lc, pathlist)

4733 {

4735

4737 return false;

4738 }

4739

4740 return true;

4741}

Datum sort(PG_FUNCTION_ARGS)

bool query_is_distinct_for(Query *query, List *colnos, List *opids)

bool query_supports_distinctness(Query *query)

Relids adjust_child_relids_multilevel(PlannerInfo *root, Relids relids, RelOptInfo *childrel, RelOptInfo *parentrel)

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

BMS_Comparison bms_subset_compare(const Bitmapset *a, const Bitmapset *b)

Bitmapset * bms_del_members(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_members(Bitmapset *a, const Bitmapset *b)

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

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

int bms_compare(const Bitmapset *a, const Bitmapset *b)

Bitmapset * bms_copy(const Bitmapset *a)

#define PG_USED_FOR_ASSERTS_ONLY

bool is_parallel_safe(PlannerInfo *root, Node *node)

double expression_returns_set_rows(PlannerInfo *root, Node *clause)

void final_cost_hashjoin(PlannerInfo *root, HashPath *path, JoinCostWorkspace *workspace, JoinPathExtraData *extra)

void final_cost_mergejoin(PlannerInfo *root, MergePath *path, JoinCostWorkspace *workspace, JoinPathExtraData *extra)

void cost_windowagg(Path *path, PlannerInfo *root, List *windowFuncs, WindowClause *winclause, int input_disabled_nodes, Cost input_startup_cost, Cost input_total_cost, double input_tuples)

void cost_functionscan(Path *path, PlannerInfo *root, RelOptInfo *baserel, ParamPathInfo *param_info)

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

void cost_bitmap_heap_scan(Path *path, PlannerInfo *root, RelOptInfo *baserel, ParamPathInfo *param_info, Path *bitmapqual, double loop_count)

void cost_tidrangescan(Path *path, PlannerInfo *root, RelOptInfo *baserel, List *tidrangequals, ParamPathInfo *param_info)

void cost_agg(Path *path, PlannerInfo *root, AggStrategy aggstrategy, const AggClauseCosts *aggcosts, int numGroupCols, double numGroups, List *quals, int disabled_nodes, Cost input_startup_cost, Cost input_total_cost, double input_tuples, double input_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 final_cost_nestloop(PlannerInfo *root, NestPath *path, JoinCostWorkspace *workspace, JoinPathExtraData *extra)

void cost_gather_merge(GatherMergePath *path, PlannerInfo *root, RelOptInfo *rel, ParamPathInfo *param_info, int input_disabled_nodes, Cost input_startup_cost, Cost input_total_cost, double *rows)

void cost_recursive_union(Path *runion, Path *nrterm, Path *rterm)

void cost_tablefuncscan(Path *path, PlannerInfo *root, RelOptInfo *baserel, ParamPathInfo *param_info)

void cost_samplescan(Path *path, PlannerInfo *root, RelOptInfo *baserel, ParamPathInfo *param_info)

void cost_gather(GatherPath *path, PlannerInfo *root, RelOptInfo *rel, ParamPathInfo *param_info, double *rows)

void cost_namedtuplestorescan(Path *path, PlannerInfo *root, RelOptInfo *baserel, ParamPathInfo *param_info)

void cost_seqscan(Path *path, PlannerInfo *root, RelOptInfo *baserel, ParamPathInfo *param_info)

void cost_valuesscan(Path *path, PlannerInfo *root, RelOptInfo *baserel, ParamPathInfo *param_info)

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)

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

void cost_group(Path *path, PlannerInfo *root, int numGroupCols, double numGroups, List *quals, int input_disabled_nodes, Cost input_startup_cost, Cost input_total_cost, double input_tuples)

void cost_resultscan(Path *path, PlannerInfo *root, RelOptInfo *baserel, ParamPathInfo *param_info)

void cost_bitmap_and_node(BitmapAndPath *path, PlannerInfo *root)

void cost_tidscan(Path *path, PlannerInfo *root, RelOptInfo *baserel, List *tidquals, ParamPathInfo *param_info)

void cost_merge_append(Path *path, PlannerInfo *root, List *pathkeys, int n_streams, int input_disabled_nodes, Cost input_startup_cost, Cost input_total_cost, double tuples)

double clamp_row_est(double nrows)

void cost_subqueryscan(SubqueryScanPath *path, PlannerInfo *root, RelOptInfo *baserel, ParamPathInfo *param_info, bool trivial_pathtarget)

void cost_append(AppendPath *apath)

void cost_ctescan(Path *path, PlannerInfo *root, RelOptInfo *baserel, ParamPathInfo *param_info)

void cost_bitmap_or_node(BitmapOrPath *path, PlannerInfo *root)

void cost_index(IndexPath *path, PlannerInfo *root, double loop_count, bool partial_path)

bool is_projection_capable_path(Path *path)

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

List *(* ReparameterizeForeignPathByChild_function)(PlannerInfo *root, List *fdw_private, RelOptInfo *child_rel)

Assert(PointerIsAligned(start, uint64))

#define SizeofMinimalTupleHeader

bool relation_has_unique_index_for(PlannerInfo *root, RelOptInfo *rel, List *restrictlist, List *exprlist, List *oprlist)

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

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

void list_sort(List *list, list_sort_comparator cmp)

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

List * lappend_int(List *list, int datum)

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

void list_free(List *list)

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

List * list_insert_nth(List *list, int pos, void *datum)

Datum subpath(PG_FUNCTION_ARGS)

void pfree(void *pointer)

MemoryContext GetMemoryChunkContext(void *pointer)

#define CHECK_FOR_INTERRUPTS()

size_t get_hash_memory_limit(void)

#define IsA(nodeptr, _type_)

static MemoryContext MemoryContextSwitchTo(MemoryContext context)

bool pathkeys_contained_in(List *keys1, List *keys2)

PathKeysComparison compare_pathkeys(List *keys1, List *keys2)

#define REPARAMETERIZE_CHILD_PATH_LIST(pathlist)

static int append_startup_cost_compare(const ListCell *a, const ListCell *b)

TidRangePath * create_tidrangescan_path(PlannerInfo *root, RelOptInfo *rel, List *tidrangequals, Relids required_outer)

#define REPARAMETERIZE_CHILD_PATH(path)

Relids calc_non_nestloop_required_outer(Path *outer_path, Path *inner_path)

static PathCostComparison compare_path_costs_fuzzily(Path *path1, Path *path2, double fuzz_factor)

ForeignPath * create_foreign_upper_path(PlannerInfo *root, RelOptInfo *rel, PathTarget *target, double rows, int disabled_nodes, Cost startup_cost, Cost total_cost, List *pathkeys, Path *fdw_outerpath, List *fdw_restrictinfo, List *fdw_private)

BitmapAndPath * create_bitmap_and_path(PlannerInfo *root, RelOptInfo *rel, List *bitmapquals)

Path * create_functionscan_path(PlannerInfo *root, RelOptInfo *rel, List *pathkeys, Relids required_outer)

bool path_is_reparameterizable_by_child(Path *path, RelOptInfo *child_rel)

Path * create_valuesscan_path(PlannerInfo *root, RelOptInfo *rel, Relids required_outer)

MinMaxAggPath * create_minmaxagg_path(PlannerInfo *root, RelOptInfo *rel, PathTarget *target, List *mmaggregates, List *quals)

Path * create_worktablescan_path(PlannerInfo *root, RelOptInfo *rel, Relids required_outer)

static bool pathlist_is_reparameterizable_by_child(List *pathlist, RelOptInfo *child_rel)

SetOpPath * create_setop_path(PlannerInfo *root, RelOptInfo *rel, Path *leftpath, Path *rightpath, SetOpCmd cmd, SetOpStrategy strategy, List *groupList, double numGroups, double outputRows)

Relids calc_nestloop_required_outer(Relids outerrelids, Relids outer_paramrels, Relids innerrelids, Relids inner_paramrels)

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)

MemoizePath * create_memoize_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, List *param_exprs, List *hash_operators, bool singlerow, bool binary_mode, double calls)

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)

#define REJECT_IF_PATH_LIST_NOT_REPARAMETERIZABLE(pathlist)

static List * reparameterize_pathlist_by_child(PlannerInfo *root, List *pathlist, RelOptInfo *child_rel)

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

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

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)

HashPath * create_hashjoin_path(PlannerInfo *root, RelOptInfo *joinrel, JoinType jointype, JoinCostWorkspace *workspace, JoinPathExtraData *extra, Path *outer_path, Path *inner_path, bool parallel_hash, List *restrict_clauses, Relids required_outer, List *hashclauses)

UniquePath * create_unique_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, SpecialJoinInfo *sjinfo)

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)

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

Path * create_namedtuplestorescan_path(PlannerInfo *root, RelOptInfo *rel, Relids required_outer)

SubqueryScanPath * create_subqueryscan_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, bool trivial_pathtarget, List *pathkeys, Relids required_outer)

#define ADJUST_CHILD_ATTRS(node)

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)

BitmapOrPath * create_bitmap_or_path(PlannerInfo *root, RelOptInfo *rel, List *bitmapquals)

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

BitmapHeapPath * create_bitmap_heap_path(PlannerInfo *root, RelOptInfo *rel, Path *bitmapqual, Relids required_outer, double loop_count, int parallel_degree)

Path * create_tablefuncscan_path(PlannerInfo *root, RelOptInfo *rel, Relids required_outer)

#define REJECT_IF_PATH_NOT_REPARAMETERIZABLE(path)

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)

ForeignPath * create_foreignscan_path(PlannerInfo *root, RelOptInfo *rel, PathTarget *target, double rows, int disabled_nodes, Cost startup_cost, Cost total_cost, List *pathkeys, Relids required_outer, Path *fdw_outerpath, List *fdw_restrictinfo, List *fdw_private)

TidPath * create_tidscan_path(PlannerInfo *root, RelOptInfo *rel, List *tidquals, Relids required_outer)

#define CONSIDER_PATH_STARTUP_COST(p)

GatherPath * create_gather_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, PathTarget *target, Relids required_outer, double *rows)

Path * create_samplescan_path(PlannerInfo *root, RelOptInfo *rel, Relids required_outer)

MaterialPath * create_material_path(RelOptInfo *rel, Path *subpath)

ForeignPath * create_foreign_join_path(PlannerInfo *root, RelOptInfo *rel, PathTarget *target, double rows, int disabled_nodes, Cost startup_cost, Cost total_cost, List *pathkeys, Relids required_outer, Path *fdw_outerpath, List *fdw_restrictinfo, List *fdw_private)

void add_path(RelOptInfo *parent_rel, Path *new_path)

int compare_path_costs(Path *path1, Path *path2, CostSelector criterion)

bool add_path_precheck(RelOptInfo *parent_rel, int disabled_nodes, Cost startup_cost, Cost total_cost, List *pathkeys, Relids required_outer)

static int append_total_cost_compare(const ListCell *a, const ListCell *b)

Path * create_resultscan_path(PlannerInfo *root, RelOptInfo *rel, Relids required_outer)

UpperUniquePath * create_upper_unique_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, int numCols, double numGroups)

void adjust_limit_rows_costs(double *rows, Cost *startup_cost, Cost *total_cost, int64 offset_est, int64 count_est)

Path * create_ctescan_path(PlannerInfo *root, RelOptInfo *rel, List *pathkeys, Relids required_outer)

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)

bool add_partial_path_precheck(RelOptInfo *parent_rel, int disabled_nodes, Cost total_cost, List *pathkeys)

ModifyTablePath * create_modifytable_path(PlannerInfo *root, RelOptInfo *rel, Path *subpath, 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)

MergePath * create_mergejoin_path(PlannerInfo *root, RelOptInfo *joinrel, JoinType jointype, JoinCostWorkspace *workspace, JoinPathExtraData *extra, Path *outer_path, Path *inner_path, List *restrict_clauses, List *pathkeys, Relids required_outer, List *mergeclauses, List *outersortkeys, List *innersortkeys, int outer_presorted_keys)

static List * translate_sub_tlist(List *tlist, int relid)

RecursiveUnionPath * create_recursiveunion_path(PlannerInfo *root, RelOptInfo *rel, Path *leftpath, Path *rightpath, PathTarget *target, List *distinctList, int wtParam, double numGroups)

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

MergeAppendPath * create_merge_append_path(PlannerInfo *root, RelOptInfo *rel, List *subpaths, List *pathkeys, Relids required_outer)

Path * reparameterize_path(PlannerInfo *root, Path *path, Relids required_outer, double loop_count)

NestPath * create_nestloop_path(PlannerInfo *root, RelOptInfo *joinrel, JoinType jointype, JoinCostWorkspace *workspace, JoinPathExtraData *extra, Path *outer_path, Path *inner_path, List *restrict_clauses, List *pathkeys, Relids required_outer)

#define IS_SIMPLE_REL(rel)

#define PATH_REQ_OUTER(path)

#define planner_rt_fetch(rti, root)

static int list_length(const List *l)

#define foreach_current_index(var_or_cell)

#define foreach_delete_current(lst, var_or_cell)

static int cmp(const chr *x, const chr *y, size_t len)

ParamPathInfo * get_appendrel_parampathinfo(RelOptInfo *appendrel, Relids required_outer)

ParamPathInfo * get_joinrel_parampathinfo(PlannerInfo *root, RelOptInfo *joinrel, Path *outer_path, Path *inner_path, SpecialJoinInfo *sjinfo, Relids required_outer, List **restrict_clauses)

ParamPathInfo * get_baserel_parampathinfo(PlannerInfo *root, RelOptInfo *baserel, Relids required_outer)

ParamPathInfo * find_param_path_info(RelOptInfo *rel, Relids required_outer)

Bitmapset * get_param_path_clause_serials(Path *path)

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

struct List *(* ReparameterizeCustomPathByChild)(PlannerInfo *root, List *custom_private, RelOptInfo *child_rel)

const struct CustomPathMethods * methods

List * custom_restrictinfo

ScanDirection indexscandir

List * withCheckOptionLists

List * mergeJoinConditions

OnConflictExpr * onconflict

struct TableSampleClause * tablesample

bool consider_param_startup

struct PathTarget * reltarget

List * cheapest_parameterized_paths

struct Path * cheapest_unique_path

struct Path * cheapest_startup_path

struct Path * cheapest_total_path

PathTarget * copy_pathtarget(PathTarget *src)