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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

18

41

42

44{

48

50{

54

56{

60

62{

63 const char *ctename;

67

68

72 Node *testexpr, List *testexpr_paramids,

73 bool unknownEqFalse);

75 List **paramIds);

79 Node *testexpr,

80 List *subst_nodes);

96 Node **testexpr, List **paramIds);

102 int gather_param,

108

109

110

111

112

113

114

115

116

117

118

119static void

121 Oid *colcollation)

122{

123

124 if (plan->targetlist)

125 {

127

128 if (!tent->resjunk)

129 {

133 return;

134 }

135 }

136 *coltype = VOIDOID;

137 *coltypmod = -1;

139}

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

166 Node *testexpr, bool isTopQual)

167{

169 bool simple_exists = false;

170 double tuple_fraction;

173 Path *best_path;

175 List *plan_params;

176 Node *result;

178

179

180

181

182

183

184

185 subquery = copyObject(orig_subquery);

186

187

188

189

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

213 tuple_fraction = 1.0;

216 tuple_fraction = 0.5;

217 else

218 tuple_fraction = 0.0;

219

220

222

223

226 root, false, tuple_fraction, NULL);

227

228

229 plan_params = root->plan_params;

231

232

233

234

235

238

240

241

243 subroot, plan_params,

244 subLinkType, subLinkId,

245 testexpr, NIL, isTopQual);

246

247

248

249

250

251

252

253

254

255

256 if (simple_exists && IsA(result, SubPlan))

257 {

258 Node *newtestexpr;

259 List *paramIds;

260

261

262 subquery = copyObject(orig_subquery);

263

265 Assert(simple_exists);

266

268 &newtestexpr, &paramIds);

269 if (subquery)

270 {

271 char *plan_name;

272

273

276 root, false, 0.0, NULL);

277

278

279 plan_params = root->plan_params;

281

282

285

286

288 {

291

292

294

295

298 subroot, plan_params,

300 newtestexpr,

301 paramIds,

302 true));

303

306

307

310 result = (Node *) asplan;

311 root->hasAlternativeSubPlans = true;

312 }

313 }

314 }

315

316 return result;

317}

318

319

320

321

322

323

324

329 Node *testexpr, List *testexpr_paramids,

330 bool unknownEqFalse)

331{

332 Node *result;

335

336

337

338

339

340

354

355

356

357

358

359 foreach(lc, plan_params)

360 {

363

364

365

366

367

368

369

370

371

372

373

379

382 }

383

384

385

386

387

388

389

390

391

392

393

394

396 {

398

399 Assert(testexpr == NULL);

403 result = (Node *) prm;

404 }

406 {

409

410 Assert(!te->resjunk);

411 Assert(testexpr == NULL);

418 result = (Node *) prm;

419 }

421 {

423 Oid arraytype;

425

426 Assert(!te->resjunk);

427 Assert(testexpr == NULL);

430 elog(ERROR, "could not find array type for datatype %s",

433 arraytype,

438 result = (Node *) prm;

439 }

441 {

442

443 List *params;

444

445 Assert(testexpr != NULL);

447 plan->targetlist,

450 testexpr,

451 params);

454

455

456

457

458

459 }

461 {

462

463

464

465

466 List *params;

467

468 Assert(testexpr == NULL);

470 plan->targetlist,

472

473

474

475

476

477

483

484

486 {

489 }

490 else

491 {

493 result = (Node *) splan;

494 }

495 }

496 else

497 {

498

499

500

501

502 if (testexpr && testexpr_paramids == NIL)

503 {

504 List *params;

505

507 plan->targetlist,

510 testexpr,

511 params);

512 }

513 else

514 {

516 splan->paramIds = testexpr_paramids;

517 }

518

519

520

521

522

523

524

525

531

532

533

534

535

536

537

538

539

540

541

545

546 result = (Node *) splan;

548 }

549

550

551

552

554 root->glob->subpaths = lappend(root->glob->subpaths, path);

555 root->glob->subroots = lappend(root->glob->subroots, subroot);

557

560

561

562

563

564

565

566

567

571

572

574

575 return result;

576}

577

578

579

580

581

582

583

586{

587 List *result;

590

591 result = ids = NIL;

592 foreach(lc, tlist)

593 {

596

597 if (tent->resjunk)

598 continue;

599

604 result = lappend(result, param);

606 }

607

608 *paramIds = ids;

609 return result;

610}

611

612

613

614

615

616

619{

620 List *result;

622

623 result = NIL;

624 foreach(lc, tlist)

625 {

627 Var *var;

628

629 if (tent->resjunk)

630 continue;

631

633 result = lappend(result, var);

634 }

635

636 return result;

637}

638

639

640

641

642

643

644

645

648 Node *testexpr,

649 List *subst_nodes)

650{

652

656}

657

661{

662 if (node == NULL)

663 return NULL;

665 {

667

669 {

670 if (param->paramid <= 0 ||

672 elog(ERROR, "unexpected PARAM_SUBLINK ID: %d", param->paramid);

673

674

675

676

677

678

681 }

682 }

684 {

685

686

687

688

689

690

691

692

693

694

695

696

697

698

699

700

701

702

703 return node;

704 }

706}

707

708

709

710

711

712

713

714static bool

716{

717 Size hashtablesize;

718

719

720

721

722

723

725 plan->plan_width,

726 unknownEqFalse);

728 return false;

729

730 return true;

731}

732

733

734

735

736

737

738static bool

740{

741 Size hashtablesize;

742

743

744

745

746

747

749 path->pathtarget->width,

750 unknownEqFalse);

752 return false;

753

754 return true;

755}

756

757

758

759

760

761

762

763static bool

765{

766

767

768

769

770 if (testexpr && IsA(testexpr, OpExpr))

771 {

773 return true;

774 }

776 {

778

780 {

782

784 return false;

786 return false;

787 }

788 return true;

789 }

790

791 return false;

792}

793

794static bool

796{

797

798

799

800

801

802

803

804

806 return false;

807

808

809

810

811

812

813

814

815

816

817

818

820 return false;

822 return false;

824 return false;

825 return true;

826}

827

828

829

830

831

832

833

834static bool

836{

838

839

841 return false;

842 if (opid == ARRAY_EQ_OP ||

843 opid == RECORD_EQ_OP)

844 {

845

847

849 }

850 else

851 {

852

855

858 elog(ERROR, "cache lookup failed for operator %u", opid);

860 if (!optup->oprcanhash || func\_strict(optup->oprcode))

861 {

863 return false;

864 }

866 return true;

867 }

868}

869

870

871

872

873

874

875

876

877

878

879

880

881

882void

884{

886

888

889 foreach(lc, root->parse->cteList)

890 {

896 Path *best_path;

899 int paramid;

900

901

902

903

904 if (cte->cterefcount == 0 && cmdType == CMD_SELECT)

905 {

906

908 continue;

909 }

910

911

912

913

914

915

916

917

918

919

920

921

922

923

924

925

926

927

928

929

930

931

932

933

934

935

936

937

938

939

940

941

944 cte->cterefcount == 1)) &&

945 !cte->cterecursive &&

948 (cte->cterefcount <= 1 ||

951 {

953

955 continue;

956 }

957

958

959

960

961

963

964

966

967

968

969

970

973 root, cte->cterecursive, 0.0, NULL);

974

975

976

977

978

979

980 if (root->plan_params)

981 elog(ERROR, "unexpected outer reference in CTE query");

982

983

984

985

986

989

991

992

993

994

995

996

997

1007

1008

1009

1010

1011

1016

1017

1018

1019

1020

1021

1022

1023

1024

1025

1026

1027

1028

1029

1030

1031

1034

1035

1036

1037

1039 root->glob->subpaths = lappend(root->glob->subpaths, best_path);

1040 root->glob->subroots = lappend(root->glob->subroots, subroot);

1042

1044

1046

1047

1049 }

1050}

1051

1052

1053

1054

1055

1056

1057static bool

1059{

1061}

1062

1063static bool

1065{

1066 if (node == NULL)

1067 return false;

1069 {

1071

1074 return true;

1075

1077 }

1079}

1080

1081

1082

1083

1084static bool

1086{

1087 Index depth = 0;

1088

1089

1090

1091

1092

1094

1096}

1097

1098static bool

1100{

1101 if (node == NULL)

1102 return false;

1104 {

1106

1107

1108

1109

1110

1112 rte->self_reference &&

1114 return true;

1115 return false;

1116 }

1118 {

1119

1121 bool result;

1122

1123 (*depth)++;

1124

1127

1128 (*depth)--;

1129

1130 return result;

1131 }

1133}

1134

1135

1136

1137

1138static void

1140{

1142

1144

1147

1149}

1150

1151static bool

1153{

1154 if (node == NULL)

1155 return false;

1157 {

1159

1161

1162

1163

1164

1165

1166

1169

1171

1172 return false;

1173 }

1175 {

1177

1181 {

1182

1183

1184

1185

1186

1188

1191

1192

1193

1194

1195

1196

1197

1198

1199

1202 rte->security_barrier = false;

1203

1204

1207 rte->self_reference = false;

1208 rte->coltypes = NIL;

1209 rte->coltypmods = NIL;

1210 rte->colcollations = NIL;

1211 }

1212

1213 return false;

1214 }

1215

1217}

1218

1219

1220

1221

1222

1223

1224

1225

1226

1227

1230{

1232 Node *leftop;

1233 Node *rightop;

1234 Oid opno;

1236 Oid inputcollid;

1238

1239

1240

1241

1242

1246 values->limitCount != NULL ||

1247 values->limitOffset != NULL ||

1250 return NULL;

1251

1255 opno = ((OpExpr *) testexpr)->opno;

1256 inputcollid = ((OpExpr *) testexpr)->inputcollid;

1257

1258

1259

1260

1261

1265 return NULL;

1266

1268 {

1271

1272

1273

1274

1275

1277

1278

1279

1280

1281

1283

1284

1285

1286

1287

1289 return NULL;

1290

1292 }

1293

1294

1296 linitial_oid(rte->colcollations), inputcollid,

1297 exprs, false);

1298}

1299

1300

1301

1302

1303

1304

1305

1306

1307

1308

1309

1310

1311

1312

1313

1314

1315

1316

1317

1318

1319

1320

1321

1322

1323

1324

1325

1326

1327

1328

1329

1330

1331

1332

1333

1336 Relids available_rels)

1337{

1341 Relids upper_varnos;

1342 int rtindex;

1346 List *subquery_vars;

1347 Node *quals;

1349 Relids sub_ref_outer_relids;

1350 bool use_lateral;

1351

1353

1354

1355

1356

1357

1359 use_lateral = bms\_is\_empty(sub_ref_outer_relids);

1360

1361

1362

1363

1364

1365 if (bms\_is\_subset(sub_ref_outer_relids, available_rels))

1366 return NULL;

1367

1368

1369

1370

1371

1372

1375 return NULL;

1376

1377

1378

1379

1380 if (bms\_is\_subset(upper_varnos, available_rels))

1381 return NULL;

1382

1383

1384

1385

1387 return NULL;

1388

1389

1391

1392

1393

1394

1395

1396

1397

1398

1399

1401 subselect,

1402 NULL,

1403 use_lateral,

1404 false);

1405 rte = nsitem->p_rte;

1408

1409

1410

1411

1413 rtr->rtindex = rtindex;

1414

1415

1416

1417

1420 rtindex);

1421

1422

1423

1424

1426

1427

1428

1429

1433 result->larg = NULL;

1434 result->rarg = (Node *) rtr;

1435 result->usingClause = NIL;

1436 result->join_using_alias = NULL;

1437 result->quals = quals;

1438 result->alias = NULL;

1439 result->rtindex = 0;

1440

1441 return result;

1442}

1443

1444

1445

1446

1447

1448

1449

1450

1453 bool under_not, Relids available_rels)

1454{

1458 Node *whereClause;

1460 int rtoffset;

1461 int varno;

1462 Relids clause_varnos;

1463 Relids upper_varnos;

1464

1466

1467

1468

1469

1470

1471

1472

1473

1474

1476 return NULL;

1477

1478

1479

1480

1481

1483

1484

1485

1486

1487

1488

1489

1491 return NULL;

1492

1493

1494

1495

1496

1497

1500

1501

1502

1503

1504

1506 return NULL;

1507

1508

1509

1510

1511

1513 return NULL;

1514

1515

1516

1517

1519 return NULL;

1520

1521

1522

1523

1524

1525

1526

1527

1528

1529

1530

1531

1532

1533

1534

1535

1536

1537 MemSet(&subroot, 0, sizeof(subroot));

1538 subroot.type = T_PlannerInfo;

1539 subroot.glob = root->glob;

1540 subroot.parse = subselect;

1543

1544

1545

1546

1549

1550

1551

1552

1554

1555

1556

1557

1558

1559

1560

1561

1562

1563

1564

1565

1566

1567

1568

1569

1573

1574

1575

1576

1577

1578

1581

1582

1583

1584

1585

1586

1587

1589 upper_varnos = NULL;

1590 varno = -1;

1591 while ((varno = bms_next_member(clause_varnos, varno)) >= 0)

1592 {

1593 if (varno <= rtoffset)

1595 }

1598

1599

1600

1601

1602

1603 if (bms\_is\_subset(upper_varnos, available_rels))

1604 return NULL;

1605

1606

1607

1608

1609

1611 subselect->rtable, subselect->rteperminfos);

1612

1613

1614

1615

1619 result->larg = NULL;

1620

1623 else

1625 result->usingClause = NIL;

1626 result->join_using_alias = NULL;

1627 result->quals = whereClause;

1628 result->alias = NULL;

1629 result->rtindex = 0;

1630

1631 return result;

1632}

1633

1634

1635

1636

1637

1638

1639

1640

1641

1642

1643

1644

1645

1646

1647

1648

1649

1650static bool

1652{

1654

1655

1656

1657

1658

1659

1660

1661

1662

1665 query->hasAggs ||

1667 query->hasWindowFuncs ||

1668 query->hasTargetSRFs ||

1669 query->hasModifyingCTE ||

1673 return false;

1674

1675

1676

1677

1678

1679

1680

1681

1683 {

1684

1685

1686

1687

1688

1689

1690

1693

1694

1696

1698 return false;

1699

1700 limit = (Const *) node;

1702 if (!limit->constisnull && DatumGetInt64(limit->constvalue) <= 0)

1703 return false;

1704

1705

1707 }

1708

1709

1710

1711

1712

1713

1714

1715

1721 query->hasDistinctOn = false;

1722

1723

1724

1725

1726

1727 foreach(lc, query->rtable)

1728 {

1730

1731

1732

1733

1734

1735

1737 {

1738 Assert(query->hasGroupRTE);

1740 query->hasGroupRTE = false;

1741 break;

1742 }

1743 }

1744

1745 return true;

1746}

1747

1748

1749

1750

1751

1752

1753

1754

1755

1756

1757

1758

1759

1760

1761

1764 Node **testexpr, List **paramIds)

1765{

1766 Node *whereClause;

1768 List *leftargs,

1769 *rightargs,

1770 *opids,

1771 *opcollations,

1772 *newWhere,

1773 *tlist,

1774 *testlist,

1775 *paramids;

1777 *rc,

1778 *oc,

1779 *cc;

1781

1782

1783

1784

1785

1787

1788

1789

1790

1791

1792

1795

1796

1797

1798

1799

1800

1801

1802

1803

1805 return NULL;

1806

1807

1808

1809

1811 return NULL;

1812

1813

1814

1815

1816

1817

1818

1819

1820

1821

1822

1823

1824

1825

1826

1827

1828

1829

1830

1831 MemSet(&subroot, 0, sizeof(subroot));

1832 subroot.type = T_PlannerInfo;

1834 subroot.parse = subselect;

1838

1839

1840

1841

1842

1843

1844

1845

1846 leftargs = rightargs = opids = opcollations = newWhere = NIL;

1847 foreach(lc, (List *) whereClause)

1848 {

1850

1853 {

1856

1858 {

1859 leftargs = lappend(leftargs, leftarg);

1860 rightargs = lappend(rightargs, rightarg);

1862 opcollations = lappend_oid(opcollations, expr->inputcollid);

1863 continue;

1864 }

1866 {

1867

1868

1869

1870

1871

1872

1875 {

1876 leftargs = lappend(leftargs, rightarg);

1877 rightargs = lappend(rightargs, leftarg);

1879 opcollations = lappend_oid(opcollations, expr->inputcollid);

1880 continue;

1881 }

1882

1883 return NULL;

1884 }

1885 }

1886

1887 newWhere = lappend(newWhere, expr);

1888 }

1889

1890

1891

1892

1893 if (leftargs == NIL)

1894 return NULL;

1895

1896

1897

1898

1899

1900

1901

1902

1903

1904

1907 return NULL;

1908 if (root->parse->hasAggs &&

1911 return NULL;

1912

1913

1914

1915

1916

1917

1918

1920 return NULL;

1921

1922

1923

1924

1925

1927 return NULL;

1928

1929

1930

1931

1933

1934

1935

1936

1937 if (newWhere)

1939

1940

1941

1942

1943

1944

1945

1946 tlist = testlist = paramids = NIL;

1947 resno = 1;

1948 forfour(lc, leftargs, rc, rightargs, oc, opids, cc, opcollations)

1949 {

1955

1962 resno++,

1963 NULL,

1964 false));

1965 testlist = lappend(testlist,

1967 (Expr *) leftarg, (Expr *) param,

1970 }

1971

1972

1975 *paramIds = paramids;

1976

1977 return subselect;

1978}

1979

1980

1981

1982

1983

1984

1985

1986

1987

1988

1989

1990

1991

1992

1993

1994

1995

1996

1997

1998

1999

2000

2001

2002

2003

2004

2005

2008{

2009

2011}

2012

2013static Node *

2015{

2016 if (node == NULL)

2017 return NULL;

2019 {

2020 if (((Var *) node)->varlevelsup > 0)

2022 }

2024 {

2028 }

2030 {

2031 if (((Aggref *) node)->agglevelsup > 0)

2033 }

2035 {

2036 if (((GroupingFunc *) node)->agglevelsup > 0)

2038 }

2040 {

2044 }

2046 {

2050 }

2052}

2053

2054

2055

2056

2057

2058

2059

2060

2063{

2065

2069}

2070

2071static Node *

2073{

2075

2076 locContext.root = context->root;

2077

2078 if (node == NULL)

2079 return NULL;

2081 {

2083 Node *testexpr;

2084

2085

2086

2087

2088

2091

2092

2093

2094

2099 testexpr,

2101 }

2102

2103

2104

2105

2106

2107

2108

2109

2111 {

2113 return node;

2114 }

2116 {

2117 if (((Aggref *) node)->agglevelsup > 0)

2118 return node;

2119 }

2121 {

2122 if (((GroupingFunc *) node)->agglevelsup > 0)

2123 return node;

2124 }

2126 {

2128 return node;

2129 }

2130

2131

2132

2133

2134

2135

2139

2140

2141

2142

2143

2144

2145

2146

2147

2148

2149

2150

2151

2152

2153

2155 {

2158

2159

2161

2163 {

2164 Node *newarg;

2165

2169 else

2170 newargs = lappend(newargs, newarg);

2171 }

2173 }

2174

2176 {

2179

2180

2182

2184 {

2185 Node *newarg;

2186

2190 else

2191 newargs = lappend(newargs, newarg);

2192 }

2194 }

2195

2196

2197

2198

2199

2201

2204 &locContext);

2205}

2206

2207

2208

2209

2210

2211

2212

2213

2214

2215

2216

2217

2218

2219void

2221{

2225

2226

2227

2228

2229

2230 if (root->glob->paramExecTypes == NIL)

2231 return;

2232

2233

2234

2235

2236

2237

2238

2239 outer_params = NULL;

2240 for (proot = root->parent_root; proot != NULL; proot = proot->parent_root)

2241 {

2242

2243

2244

2246 {

2248

2250 }

2251

2253 {

2256

2257 foreach(l2, initsubplan->setParam)

2258 {

2260 }

2261 }

2262

2265 }

2266 root->outer_params = outer_params;

2267}

2268

2269

2270

2271

2272

2273

2274

2275

2276

2277

2278

2279

2280

2281

2282

2283void

2285{

2286 Cost initplan_cost;

2287 bool unsafe_initplans;

2289

2290

2291 if (root->init_plans == NIL)

2292 return;

2293

2294

2295

2296

2297

2299 &initplan_cost, &unsafe_initplans);

2300

2301

2302

2303

2304 foreach(lc, final_rel->pathlist)

2305 {

2307

2310 if (unsafe_initplans)

2312 }

2313

2314

2315

2316

2317

2318 if (unsafe_initplans)

2319 {

2322 }

2323 else

2324 {

2326 {

2328

2331 }

2332 }

2333

2334

2335}

2336

2337

2338

2339

2340

2341

2342

2343

2344

2345

2346

2347void

2349 Cost *initplan_cost_p,

2350 bool *unsafe_initplans_p)

2351{

2352 Cost initplan_cost;

2353 bool unsafe_initplans;

2355

2356

2357

2358

2359

2360

2361 initplan_cost = 0;

2362 unsafe_initplans = false;

2363 foreach(lc, init_plans)

2364 {

2366

2369 unsafe_initplans = true;

2370 }

2371 *initplan_cost_p = initplan_cost;

2372 *unsafe_initplans_p = unsafe_initplans;

2373}

2374

2375

2376

2377

2378

2379

2380

2381

2382

2383

2384

2385

2386

2387

2388void

2390{

2391 plan->initPlan = root->init_plans;

2392}

2393

2394

2395

2396

2397

2398

2399

2400

2401

2402

2403void

2405{

2406

2408}

2409

2410

2411

2412

2413

2414

2415

2416

2417

2418

2419

2420

2421

2422

2423

2424

2425

2426

2427

2428

2429

2430

2431

2432

2433

2434

2435

2436

2437

2438

2439

2440

2443 int gather_param,

2446{

2448 int locally_added_param;

2454

2455 if (plan == NULL)

2456 return NULL;

2457

2459 context.paramids = NULL;

2460 locally_added_param = -1;

2461 nestloop_params = NULL;

2462

2463

2464

2465

2466

2467

2468 initExtParam = initSetParam = NULL;

2469 foreach(l, plan->initPlan)

2470 {

2474

2476 foreach(l2, initsubplan->setParam)

2477 {

2479 }

2480 }

2481

2482

2483 if (initSetParam)

2484 valid_params = bms_union(valid_params, initSetParam);

2485

2486

2487

2488

2489

2490

2491

2492

2493

2496

2497

2498

2499

2500

2501 if (plan->parallel_aware)

2502 {

2503 if (gather_param < 0)

2504 elog(ERROR, "parallel-aware plan node is not below a Gather");

2507 }

2508

2509

2511 {

2512 case T_Result:

2514 &context);

2515 break;

2516

2517 case T_SeqScan:

2519 break;

2520

2521 case T_SampleScan:

2523 &context);

2525 break;

2526

2527 case T_IndexScan:

2529 &context);

2531 &context);

2532

2533

2534

2535

2536

2537

2539 break;

2540

2541 case T_IndexOnlyScan:

2543 &context);

2545 &context);

2547 &context);

2548

2549

2550

2551

2553 break;

2554

2555 case T_BitmapIndexScan:

2557 &context);

2558

2559

2560

2561

2562

2563 break;

2564

2565 case T_BitmapHeapScan:

2567 &context);

2569 break;

2570

2571 case T_TidScan:

2573 &context);

2575 break;

2576

2577 case T_TidRangeScan:

2579 &context);

2581 break;

2582

2583 case T_SubqueryScan:

2584 {

2588

2589

2592 if (gather_param >= 0)

2594 gather_param);

2596 subquery_params, NULL);

2597

2598

2601

2603 scan_params);

2604 }

2605 break;

2606

2607 case T_FunctionScan:

2608 {

2611

2612

2613

2614

2615

2616

2617

2619 {

2622

2623 funccontext = context;

2624 funccontext.paramids = NULL;

2625

2627

2628

2629 rtfunc->funcparams = funccontext.paramids;

2630

2631

2634 }

2635

2637 scan_params);

2638 }

2639 break;

2640

2641 case T_TableFuncScan:

2643 &context);

2645 break;

2646

2647 case T_ValuesScan:

2649 &context);

2651 break;

2652

2653 case T_CteScan:

2654 {

2655

2656

2657

2658

2659

2660

2661

2662

2663

2664

2665

2666 int plan_id = ((CteScan *) plan)->ctePlanId;

2667 Plan *cteplan;

2668

2669

2670 if (plan_id < 1 || plan_id > list_length(root->glob->subplans))

2671 elog(ERROR, "could not find plan for CteScan referencing plan ID %d",

2672 plan_id);

2673 cteplan = (Plan *) list_nth(root->glob->subplans, plan_id - 1);

2676

2677#ifdef NOT_USED

2678

2682#endif

2683

2685 scan_params);

2686 }

2687 break;

2688

2689 case T_WorkTableScan:

2694 break;

2695

2696 case T_NamedTuplestoreScan:

2698 break;

2699

2700 case T_ForeignScan:

2701 {

2703

2705 &context);

2707 &context);

2708

2709

2711 scan_params);

2712 }

2713 break;

2714

2715 case T_CustomScan:

2716 {

2719

2721 &context);

2722

2725

2726

2728 {

2733 gather_param,

2734 valid_params,

2735 scan_params));

2736 }

2737 }

2738 break;

2739

2740 case T_ModifyTable:

2741 {

2743

2744

2745 locally_added_param = mtplan->epqParam;

2747 locally_added_param);

2749 locally_added_param);

2751 &context);

2753 &context);

2755 &context);

2756

2757 }

2758 break;

2759

2760 case T_Append:

2761 {

2762 foreach(l, ((Append *) plan)->appendplans)

2763 {

2768 gather_param,

2769 valid_params,

2770 scan_params));

2771 }

2772 }

2773 break;

2774

2775 case T_MergeAppend:

2776 {

2778 {

2783 gather_param,

2784 valid_params,

2785 scan_params));

2786 }

2787 }

2788 break;

2789

2790 case T_BitmapAnd:

2791 {

2793 {

2798 gather_param,

2799 valid_params,

2800 scan_params));

2801 }

2802 }

2803 break;

2804

2805 case T_BitmapOr:

2806 {

2807 foreach(l, ((BitmapOr *) plan)->bitmapplans)

2808 {

2813 gather_param,

2814 valid_params,

2815 scan_params));

2816 }

2817 }

2818 break;

2819

2820 case T_NestLoop:

2821 {

2823 &context);

2824

2826 {

2828

2831 }

2832 }

2833 break;

2834

2835 case T_MergeJoin:

2837 &context);

2839 &context);

2840 break;

2841

2842 case T_HashJoin:

2844 &context);

2846 &context);

2847 break;

2848

2849 case T_Hash:

2851 &context);

2852 break;

2853

2854 case T_Limit:

2856 &context);

2858 &context);

2859 break;

2860

2861 case T_RecursiveUnion:

2862

2865 locally_added_param);

2866

2867 break;

2868

2869 case T_LockRows:

2870

2871 locally_added_param = ((LockRows *) plan)->epqParam;

2873 locally_added_param);

2875 locally_added_param);

2876 break;

2877

2878 case T_Agg:

2879 {

2881

2882

2883

2884

2885

2887 {

2889

2893 &aggcontext);

2895 &aggcontext);

2897 }

2898 }

2899 break;

2900

2901 case T_WindowAgg:

2903 &context);

2905 &context);

2906 break;

2907

2908 case T_Gather:

2909

2910 locally_added_param = ((Gather *) plan)->rescan_param;

2911 if (locally_added_param >= 0)

2912 {

2914 locally_added_param);

2915

2916

2917

2918

2919

2920

2921 Assert(gather_param < 0);

2922

2923 gather_param = locally_added_param;

2924 }

2925

2926 break;

2927

2928 case T_GatherMerge:

2929

2930 locally_added_param = ((GatherMerge *) plan)->rescan_param;

2931 if (locally_added_param >= 0)

2932 {

2934 locally_added_param);

2935

2936

2937

2938

2939

2940

2941 Assert(gather_param < 0);

2942

2943 gather_param = locally_added_param;

2944 }

2945

2946 break;

2947

2948 case T_Memoize:

2950 &context);

2951 break;

2952

2953 case T_ProjectSet:

2954 case T_Material:

2955 case T_Sort:

2956 case T_IncrementalSort:

2957 case T_Unique:

2958 case T_SetOp:

2959 case T_Group:

2960

2961 break;

2962

2963 default:

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

2966 }

2967

2968

2970 plan->lefttree,

2971 gather_param,

2972 valid_params,

2973 scan_params);

2975

2976 if (nestloop_params)

2977 {

2978

2980 plan->righttree,

2981 gather_param,

2982 bms_union(nestloop_params, valid_params),

2983 scan_params);

2984

2985 child_params = bms_difference(child_params, nestloop_params);

2987 }

2988 else

2989 {

2990

2992 plan->righttree,

2993 gather_param,

2994 valid_params,

2995 scan_params);

2996 }

2998

2999

3000

3001

3002

3003

3004

3005 if (locally_added_param >= 0)

3006 {

3008 locally_added_param);

3009 }

3010

3011

3012

3014 elog(ERROR, "plan should not reference subplan's variable");

3015

3016

3017

3018

3019

3020

3021

3022

3023

3024

3027

3029

3031

3032 return plan->allParam;

3033}

3034

3035

3036

3037

3038

3039static bool

3041{

3042 if (node == NULL)

3043 return false;

3045 {

3047 {

3048 int paramid = ((Param *) node)->paramid;

3049

3051 }

3052 return false;

3053 }

3055 {

3056

3057

3058

3059

3060

3061

3062

3063

3065 Param *aggparam;

3066

3068 if (aggparam != NULL)

3071

3072 }

3074 {

3079

3080

3082

3083

3084

3085

3086

3087

3088

3089

3090

3091 foreach(lc, subplan->paramIds)

3092 {

3095 }

3096

3097

3099

3100

3101

3102

3103

3104

3106 foreach(lc, subplan->parParam)

3107 {

3109 }

3111

3112 return false;

3113 }

3115}

3116

3117

3118

3119

3120

3121

3122static bool

3124{

3125 if (node == NULL)

3126 return false;

3128 {

3130

3131

3134 return false;

3135 }

3137}

3138

3139

3140

3141

3142

3143

3144

3145

3146

3147

3150 Oid resulttype, int32 resulttypmod,

3151 Oid resultcollation)

3152{

3154 resulttypmod, resultcollation);

3155}

3156

3157

3158

3159

3160

3161

3162

3163

3164void

3168{

3170

3171

3172

3173

3174

3175

3176

3177

3179 root->glob->subpaths = lappend(root->glob->subpaths, NULL);

3180 root->glob->subroots = lappend(root->glob->subroots, subroot);

3181

3182

3183

3184

3185

3186

3196

3198

3199

3200

3201

3202

3203

3204

3206}

3207

3208

3209

3210

3211static const char *

3213{

3214 switch (subLinkType)

3215 {

3217 return "exists";

3219 return "all";

3221 return "any";

3223 return "rowcompare";

3225 return "expr";

3227 return "multiexpr";

3229 return "array";

3231 return "cte";

3232 }

3234 return "???";

3235}

Bitmapset * bms_difference(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)

Bitmapset * bms_add_member(Bitmapset *a, int x)

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

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

Bitmapset * bms_join(Bitmapset *a, Bitmapset *b)

Bitmapset * bms_copy(const Bitmapset *a)

static Datum values[MAXATTR]

#define MemSet(start, val, len)

#define OidIsValid(objectId)

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

bool contain_subplans(Node *clause)

ScalarArrayOpExpr * make_SAOP_expr(Oid oper, Node *leftexpr, Oid coltype, Oid arraycollid, Oid inputcollid, List *exprs, bool haveNonConst)

bool contain_volatile_functions(Node *clause)

bool contain_exec_param(Node *clause, List *param_ids)

void cost_subplan(PlannerInfo *root, SubPlan *subplan, Plan *plan)

Plan * materialize_finished_plan(Plan *subplan)

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

bool ExecMaterializesOutput(NodeTag plantype)

char * format_type_be(Oid type_oid)

Assert(PointerIsAligned(start, uint64))

#define HeapTupleIsValid(tuple)

static void * GETSTRUCT(const HeapTupleData *tuple)

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

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

List * list_delete_cell(List *list, ListCell *cell)

List * list_copy(const List *oldlist)

List * lappend_int(List *list, int datum)

List * lappend_oid(List *list, Oid datum)

bool op_hashjoinable(Oid opno, Oid inputtype)

bool func_strict(Oid funcid)

Oid get_promoted_array_type(Oid typid)

Oid get_commutator(Oid opno)

Expr * make_orclause(List *orclauses)

Expr * make_ands_explicit(List *andclauses)

Var * makeVarFromTargetEntry(int varno, TargetEntry *tle)

Const * makeNullConst(Oid consttype, int32 consttypmod, Oid constcollid)

Expr * make_andclause(List *andclauses)

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)

List * make_ands_implicit(Expr *clause)

Oid exprType(const Node *expr)

int32 exprTypmod(const Node *expr)

Oid exprCollation(const Node *expr)

#define expression_tree_mutator(n, m, c)

static bool is_andclause(const void *clause)

static bool is_orclause(const void *clause)

#define query_tree_walker(q, w, c, f)

#define QTW_EXAMINE_RTES_AFTER

#define expression_tree_walker(n, w, c)

#define QTW_EXAMINE_RTES_BEFORE

size_t get_hash_memory_limit(void)

Size EstimateSubplanHashTableSpace(double nentries, Size tupleWidth, bool unknownEqFalse)

#define IsA(nodeptr, _type_)

#define castNode(_type_, nodeptr)

Param * replace_outer_merge_support(PlannerInfo *root, MergeSupportFunc *msf)

Param * generate_new_exec_param(PlannerInfo *root, Oid paramtype, int32 paramtypmod, Oid paramcollation)

Param * replace_outer_agg(PlannerInfo *root, Aggref *agg)

Param * replace_outer_returning(PlannerInfo *root, ReturningExpr *rexpr)

Param * replace_outer_grouping(PlannerInfo *root, GroupingFunc *grp)

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

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

int assign_special_exec_param(PlannerInfo *root)

ParseState * make_parsestate(ParseState *parentParseState)

ParseNamespaceItem * addRangeTableEntryForSubquery(ParseState *pstate, Query *subquery, Alias *alias, bool lateral, bool inFromCl)

#define planner_subplan_get_plan(root, subplan)

#define lfirst_node(type, lc)

static int list_length(const List *l)

#define linitial_node(type, l)

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

static ListCell * list_nth_cell(const List *list, int n)

#define forfour(cell1, list1, cell2, list2, cell3, list3, cell4, list4)

#define list_make1_int(x1)

#define list_make2(x1, x2)

FormData_pg_operator * Form_pg_operator

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

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

Path * get_cheapest_fractional_path(RelOptInfo *rel, double tuple_fraction)

static int64 DatumGetInt64(Datum X)

static Datum ObjectIdGetDatum(Oid X)

void replace_empty_jointree(Query *parse)

Query * preprocess_relation_rtes(PlannerInfo *root)

Expr * canonicalize_qual(Expr *qual, bool is_check)

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

RelOptInfo * find_base_rel(PlannerInfo *root, int relid)

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

void OffsetVarNodes(Node *node, int offset, int sublevels_up)

void CombineRangeTables(List **dst_rtable, List **dst_perminfos, List *src_rtable, List *src_perminfos)

bool contain_aggs_of_level(Node *node, int levelsup)

void IncrementVarSublevelsUp(Node *node, int delta_sublevels_up, int min_sublevels_up)

Param * find_minmax_agg_replacement_param(PlannerInfo *root, Aggref *aggref)

CTEMaterialize ctematerialized

struct Path * cheapest_total_path

JoinExpr * convert_ANY_sublink_to_join(PlannerInfo *root, SubLink *sublink, Relids available_rels)

static bool contain_dml_walker(Node *node, void *context)

static bool subpath_is_hashable(Path *path, bool unknownEqFalse)

static bool subplan_is_hashable(Plan *plan, bool unknownEqFalse)

static bool testexpr_is_hashable(Node *testexpr, List *param_ids)

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

void SS_process_ctes(PlannerInfo *root)

static const char * sublinktype_to_string(SubLinkType subLinkType)

void SS_identify_outer_params(PlannerInfo *root)

static bool finalize_agg_primnode(Node *node, finalize_primnode_context *context)

static bool contain_outer_selfref(Node *node)

static List * generate_subquery_vars(PlannerInfo *root, List *tlist, Index varno)

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

static bool contain_dml(Node *node)

void SS_finalize_plan(PlannerInfo *root, Plan *plan)

static Query * convert_EXISTS_to_ANY(PlannerInfo *root, Query *subselect, Node **testexpr, List **paramIds)

static Node * process_sublinks_mutator(Node *node, process_sublinks_context *context)

struct process_sublinks_context process_sublinks_context

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

static bool test_opexpr_is_hashable(OpExpr *testexpr, List *param_ids)

static List * generate_subquery_params(PlannerInfo *root, List *tlist, List **paramIds)

static Node * convert_testexpr(PlannerInfo *root, Node *testexpr, List *subst_nodes)

static Node * make_subplan(PlannerInfo *root, Query *orig_subquery, SubLinkType subLinkType, int subLinkId, Node *testexpr, bool isTopQual)

static bool contain_outer_selfref_walker(Node *node, Index *depth)

struct convert_testexpr_context convert_testexpr_context

static bool hash_ok_operator(OpExpr *expr)

ScalarArrayOpExpr * convert_VALUES_to_ANY(PlannerInfo *root, Node *testexpr, Query *values)

static void inline_cte(PlannerInfo *root, CommonTableExpr *cte)

static bool simplify_EXISTS_query(PlannerInfo *root, Query *query)

struct finalize_primnode_context finalize_primnode_context

static bool finalize_primnode(Node *node, finalize_primnode_context *context)

static void get_first_col_type(Plan *plan, Oid *coltype, int32 *coltypmod, Oid *colcollation)

static bool inline_cte_walker(Node *node, inline_cte_walker_context *context)

void SS_attach_initplans(PlannerInfo *root, Plan *plan)

JoinExpr * convert_EXISTS_sublink_to_join(PlannerInfo *root, SubLink *sublink, bool under_not, Relids available_rels)

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)

static Node * convert_testexpr_mutator(Node *node, convert_testexpr_context *context)

Param * SS_make_initplan_output_param(PlannerInfo *root, Oid resulttype, int32 resulttypmod, Oid resultcollation)

struct inline_cte_walker_context inline_cte_walker_context

static Node * build_subplan(PlannerInfo *root, Plan *plan, Path *path, PlannerInfo *subroot, List *plan_params, SubLinkType subLinkType, int subLinkId, Node *testexpr, List *testexpr_paramids, bool unknownEqFalse)

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

static Bitmapset * finalize_plan(PlannerInfo *root, Plan *plan, int gather_param, Bitmapset *valid_params, Bitmapset *scan_params)

void ReleaseSysCache(HeapTuple tuple)

HeapTuple SearchSysCache1(int cacheId, Datum key1)

bool contain_vars_of_level(Node *node, int levelsup)

bool contain_var_clause(Node *node)

Relids pull_varnos_of_level(PlannerInfo *root, Node *node, int levelsup)

Relids pull_varnos(PlannerInfo *root, Node *node)