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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

24

36

37

38

39

40

41

42

43

44

45

46

47typedef struct

48{

52

54

55

60 int relid, int ojrelid);

63 int relid, int subst);

67 List *clause_list, List **extra_clauses);

74 List *restrictlist,

75 List **extra_clauses);

79

80

81

82

83

84

85

86

87

88

91{

93

94

95

96

97

98restart:

99 foreach(lc, root->join_info_list)

100 {

102 int innerrelid;

103 int nremoved;

104

105

107 continue;

108

109

110

111

112

113

115

117

118

119 nremoved = 0;

121 if (nremoved != 1)

122 elog(ERROR, "failed to find relation %d in joinlist", innerrelid);

123

124

125

126

127

128

130

131

132

133

134

135

136

137 goto restart;

138 }

139

140 return joinlist;

141}

142

143

144

145

146

147

148

149

150

151

152

153

154static bool

156{

157 int innerrelid;

163 int attroff;

164

165

166

167

168

170 return false;

171

173 return false;

174

175

176

177

178

179

180 if (innerrelid == root->parse->resultRelation)

181 return false;

182

184

185

186

187

188

189

191 return false;

192

193

196 joinrelids = bms_copy(inputrelids);

198

199

200

201

202

203

204

205

206

207

208

209

211 attroff >= 0;

212 attroff--)

213 {

214 if (bms\_is\_subset(innerrel->attr_needed[attroff], inputrelids))

215 return false;

216 }

217

218

219

220

221

222

223

224

225

226

227 foreach(l, root->placeholder_list)

228 {

230

232 return false;

234 continue;

236 continue;

238 return false;

239

240

241

242

243

245 return false;

246

249 return false;

250 }

251

252

253

254

255

256

257

258

259 foreach(l, innerrel->joininfo)

260 {

262

263

264

265

266

267

268

269

270

272 continue;

273

274

275

276

277

278

279

281 continue;

282

283

284 if (!restrictinfo->can_join ||

285 restrictinfo->mergeopfamilies == NIL)

286 continue;

287

288

289

290

291

294 continue;

295

296

297 clause_list = lappend(clause_list, restrictinfo);

298 }

299

300

301

302

303

305 return true;

306

307

308

309

310

311 return false;

312}

313

314

315

316

317

318

319

320

321

322

323

324static void

328{

329 int relid = rel->relid;

332

333

334

335

338

339 if (sjinfo != NULL)

340 {

345 }

346

347

348

349

350

351

352

353

354

355 foreach(l, root->join_info_list)

356 {

358

359

360

361

362

363

364

369

374

375 if (sjinfo != NULL)

376 {

378

379

388

397 }

398 else

399 {

401

404 }

405 }

406

407

408

409

410

411

412

413

414

415

416

417

418

419

420

421

422

423

424

425

426 foreach(l, root->placeholder_list)

427 {

429

431 if (sjinfo != NULL &&

435 {

436

437

438

439

440

442 l);

443 root->placeholder_array[phinfo->phid] = NULL;

444 }

445 else

446 {

448

450 if (sjinfo != NULL)

454

457 else

459

461

462

463

464

465

467

468

470 if (sjinfo != NULL)

474

477

479 }

480 }

481

482

483

484

485 foreach(l, root->eq_classes)

486 {

488

492 }

493

494

495

496

497

498

499

500

501

502

503

504

505

506

507

508 for (rti = 1; rti < root->simple_rel_array_size; rti++)

509 {

511 int attroff;

512

513

514 if (otherrel == NULL)

515 continue;

516

517 Assert(otherrel->relid == rti);

518

520 attroff >= 0;

521 attroff--)

522 {

523 if (bms_is_member(0, otherrel->attr_needed[attroff]))

525 else

526 otherrel->attr_needed[attroff] = NULL;

527 }

528

529 if (subst > 0)

532 }

533}

534

535

536

537

538

539

540

541

542

543static void

546{

548 int ojrelid = sjinfo->ojrelid;

550 Relids join_plus_commute;

551 List *joininfos;

553

554

556 Assert(ojrelid != 0);

558

560

561

562

563

564

565

566

567

568

569

570

571

572

573

574

575

576

577 join_plus_commute = bms_union(joinrelids,

581

582

583

584

585

586

588 foreach(l, joininfos)

589 {

591

593

595 {

596

597

598

599

600

601

602

604

605

606

607

608

609#ifdef USE_ASSERT_CHECKING

610 {

613

616 }

617#endif

618

620 }

621 }

622

623

624

625

626

627

628

629

630

631

632

633 root->simple_rel_array[relid] = NULL;

634

635

637

638

639

640

641

646}

647

648

649

650

651

652

653

654

655

656static void

658{

659

660

661

662

663

664

665

666 rinfo->clause_relids = bms_copy(rinfo->clause_relids);

667 rinfo->clause_relids = bms_del_member(rinfo->clause_relids, relid);

668 rinfo->clause_relids = bms_del_member(rinfo->clause_relids, ojrelid);

669

673

674

676 {

678

680 foreach(lc, ((BoolExpr *) rinfo->orclause)->args)

681 {

683

684

686 {

689

690 foreach(lc2, andargs)

691 {

693

695 }

696 }

697 else

698 {

700

702 }

703 }

704 }

705}

706

707

708

709

710

711

712

713

714

715

716

717static void

719 int relid, int subst)

720{

722

723

725 if (sjinfo != NULL)

728

729

730

731

732

733

735

736

737

738

739

740

742 {

744

748 {

751 if (sjinfo != NULL)

756 }

757 }

758

759

761 {

763

764 if (sjinfo == NULL)

767 else

769 }

770

771

772

773

774

775

777}

778

779

780

781

782

783

784

785

786

787

790{

793

794 foreach(jl, joinlist)

795 {

797

799 {

800 int varno = ((RangeTblRef *) jlnode)->rtindex;

801

802 if (varno == relid)

803 (*nremoved)++;

804 else

805 result = lappend(result, jlnode);

806 }

807 else if (IsA(jlnode, List))

808 {

809

810 List *sublist;

811

813 relid, nremoved);

814

815 if (sublist)

816 result = lappend(result, sublist);

817 }

818 else

819 {

820 elog(ERROR, "unrecognized joinlist node type: %d",

822 }

823 }

824

825 return result;

826}

827

828

829

830

831

832

833

834

835

836

837

838

839

840

841

842void

844{

846

847

848

849

850 foreach(lc, root->join_info_list)

851 {

853 int innerrelid;

856 List *restrictlist;

857

858

859

860

861

863 continue;

864

866 continue;

867

869

870

871

872

873

874

876 continue;

877

878

880 Assert(sjinfo->ojrelid == 0);

881

882

883

884

885

886

887 restrictlist =

889 joinrelids,

891 innerrel,

892 NULL),

894

895

899 continue;

900

901

903 }

904}

905

906

907

908

909

910

911

912

913

914

915

916

917

918static bool

920{

921

923 return false;

925 {

926

927

928

929

930

931

932

934

936 {

938

939 if (ind->unique && ind->immediate && ind->indpred == NIL)

940 return true;

941 }

942 }

944 {

945 Query *subquery = root->simple_rte_array[rel->relid]->subquery;

946

947

949 return true;

950 }

951

952 return false;

953}

954

955

956

957

958

959

960

961

962

963

964

965

966

967

968

969

970

971

972

973

974

975

976

977

978static bool

980 List **extra_clauses)

981{

982

983

984

985

986

988 return false;

990 {

991

992

993

994

995

997 extra_clauses))

998 return true;

999 }

1001 {

1003 Query *subquery = root->simple_rte_array[relid]->subquery;

1007

1008

1009

1010

1011

1012

1013

1014

1015

1016

1017 foreach(l, clause_list)

1018 {

1021 Var *var;

1022

1023

1024

1025

1026

1027

1028

1029

1030

1032

1033

1034 if (rinfo->outer_is_left)

1036 else

1038

1039

1040

1041

1042

1043

1046

1047

1048

1049

1050

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

1053 continue;

1054

1057 }

1058

1060 return true;

1061 }

1062 return false;

1063}

1064

1065

1066

1067

1068

1069

1070

1071

1072

1073

1074

1075

1076

1077bool

1079{

1080

1082 return false;

1083

1084

1088 query->hasAggs ||

1091 return true;

1092

1093 return false;

1094}

1095

1096

1097

1098

1099

1100

1101

1102

1103

1104

1105

1106

1107

1108

1109

1110

1111

1112

1113

1114

1115bool

1117{

1119 Oid opid;

1120

1122

1123

1124

1125

1126

1127

1128

1130 {

1132 {

1136

1140 break;

1141 }

1142 if (l == NULL)

1143 return true;

1144 }

1145

1146

1147

1148

1149

1150

1151

1152

1153 if (query->hasTargetSRFs)

1154 return false;

1155

1156

1157

1158

1159

1161 {

1163 {

1167

1171 break;

1172 }

1173 if (l == NULL)

1174 return true;

1175 }

1177 {

1178

1179

1180

1181

1183 return false;

1184

1185

1186

1187

1188

1189

1190

1193 return true;

1194 else

1195 return false;

1196 }

1197 else

1198 {

1199

1200

1201

1202

1203 if (query->hasAggs || query->havingQual)

1204 return true;

1205 }

1206

1207

1208

1209

1210

1212 {

1214

1216

1217 if (!topop->all)

1218 {

1220

1221

1222 lg = list_head(topop->groupClauses);

1224 {

1227

1228 if (tle->resjunk)

1229 continue;

1230

1231

1234 lg = lnext(topop->groupClauses, lg);

1235

1239 break;

1240 }

1241 if (l == NULL)

1242 return true;

1243 }

1244 }

1245

1246

1247

1248

1249

1250

1251

1252

1253

1254 return false;

1255}

1256

1257

1258

1259

1260

1261

1262

1263

1264static Oid

1266{

1268 *lc2;

1269

1270 forboth(lc1, colnos, lc2, opids)

1271 {

1274 }

1276}

1277

1278

1279

1280

1281

1282

1283

1284

1285

1286

1287

1288

1289

1290

1291

1292

1293

1294

1295

1296

1297

1298

1299

1300

1301

1302

1303

1304bool

1310 List *restrictlist,

1311 bool force_cache)

1312{

1314 jointype, restrictlist, force_cache, NULL);

1315}

1316

1317

1318

1319

1320

1321

1322

1323

1324

1325

1326bool

1332 List *restrictlist,

1333 bool force_cache,

1334 List **extra_clauses)

1335{

1339 List *outer_exprs = NIL;

1340 bool self_join = (extra_clauses != NULL);

1341

1342

1343 if (restrictlist == NIL)

1344 return false;

1345

1346

1347

1348

1349

1351 return false;

1352

1353

1354

1355

1356

1357

1358

1359

1360

1361

1362

1363

1364

1366 {

1368

1372 {

1373 if (extra_clauses)

1375 return true;

1376 }

1377 }

1378

1379

1380

1381

1382

1384 {

1386

1387 if (bms_is_subset(outerrelids, unique_for_rels))

1388 return false;

1389 }

1390

1391

1393 jointype, restrictlist,

1394 self_join ? &outer_exprs : NULL))

1395 {

1396

1397

1398

1399

1400

1401

1402

1403

1404

1405

1409 uniqueRelInfo->self_join = self_join;

1412 uniqueRelInfo);

1414

1415 if (extra_clauses)

1416 *extra_clauses = outer_exprs;

1417 return true;

1418 }

1419 else

1420 {

1421

1422

1423

1424

1425

1426

1427

1428

1429

1430

1431

1432

1433

1434

1435

1436

1437

1438 if (force_cache || root->join_search_private)

1439 {

1445 }

1446

1447 return false;

1448 }

1449}

1450

1451

1452

1453

1454

1455

1456static bool

1462 List *restrictlist,

1463 List **extra_clauses)

1464{

1465 List *clause_list = NIL;

1467

1468

1469

1470

1471

1472

1473

1474

1475 foreach(lc, restrictlist)

1476 {

1478

1479

1480

1481

1482

1485 continue;

1486

1487

1488 if (!restrictinfo->can_join ||

1489 restrictinfo->mergeopfamilies == NIL)

1490 continue;

1491

1492

1493

1494

1495

1498 continue;

1499

1500

1501 clause_list = lappend(clause_list, restrictinfo);

1502 }

1503

1504

1506}

1507

1508

1509

1510

1511

1512

1513

1514

1515

1516

1517

1518

1519

1520

1521

1522

1523

1524

1525

1526

1527

1528

1529

1530static void

1532{

1533 List *new_members = NIL;

1534 List *new_sources = NIL;

1535

1536

1537

1538

1539

1540

1542

1544 {

1545 bool is_redundant = false;

1546

1548 {

1549 new_members = lappend(new_members, em);

1550 continue;

1551 }

1552

1554 em->em_jdomain->jd_relids = adjust_relid_set(em->em_jdomain->jd_relids, from, to);

1555

1556

1559

1561 {

1562 if (equal(em->em_relids, other->em_relids))

1563 continue;

1564

1565 if (equal(em->em_expr, other->em_expr))

1566 {

1567 is_redundant = true;

1568 break;

1569 }

1570 }

1571

1572 if (!is_redundant)

1573 new_members = lappend(new_members, em);

1574 }

1575

1578

1580

1581

1583 {

1584 bool is_redundant = false;

1585

1586 if (bms\_is\_member(from, rinfo->required_relids))

1587 {

1588 new_sources = lappend(new_sources, rinfo);

1589 continue;

1590 }

1591

1594

1595

1596

1597

1598

1599

1601 {

1602 if (equal(rinfo->clause_relids, other->clause_relids))

1603 continue;

1604

1605 if (equal(rinfo->clause, other->clause))

1606 {

1607 is_redundant = true;

1608 break;

1609 }

1610 }

1611

1612 if (!is_redundant)

1613 new_sources = lappend(new_sources, rinfo);

1614 }

1615

1619}

1620

1621

1622

1623

1624

1625

1626

1627

1628

1629

1630static bool

1632{

1633 int saved_rinfo_serial = a->rinfo_serial;

1634 bool result;

1635

1636 a->rinfo_serial = b->rinfo_serial;

1638 a->rinfo_serial = saved_rinfo_serial;

1639

1640 return result;

1641}

1642

1643

1644

1645

1646

1647

1648

1649

1650

1651

1652

1653

1654

1655

1656static void

1658 List *rinfo_candidates,

1659 List **keep_rinfo_list,

1660 Index removed_relid)

1661{

1663 {

1664 bool is_redundant = false;

1665

1667

1669 {

1670 if (bms\_equal(src->clause_relids, rinfo->clause_relids))

1671

1672 continue;

1673

1674 if (src == rinfo ||

1675 (rinfo->parent_ec != NULL &&

1676 src->parent_ec == rinfo->parent_ec) ||

1678 {

1679 is_redundant = true;

1680 break;

1681 }

1682 }

1683 if (!is_redundant)

1685 }

1686}

1687

1688

1689

1690

1691

1692

1693

1694

1695

1696

1697

1698

1699

1700static bool

1702{

1704 {

1705 return true;

1706 }

1708 {

1710 int relid = -1;

1711 bool is_req_equal =

1713 bool clause_relids_is_multiple =

1715

1716

1717

1718

1719

1720

1721

1724 {

1725 Relids new_clause_relids;

1726

1729

1733

1734

1735

1736

1737

1738

1739

1740 rinfo->num_base_rels -= bms_num_members(rinfo->clause_relids) -

1742

1743 rinfo->clause_relids = new_clause_relids;

1744 rinfo->left_relids =

1746 rinfo->right_relids =

1748 }

1749

1750 if (is_req_equal)

1752 else

1755

1760

1761 if (rinfo->mergeopfamilies &&

1763 clause_relids_is_multiple &&

1765 {

1766 Expr *leftOp;

1767 Expr *rightOp;

1768

1771

1772

1773

1774

1775

1776

1777

1778

1779 if (leftOp != NULL && equal(leftOp, rightOp))

1780 {

1782

1783 ntest->arg = leftOp;

1785 ntest->argisrow = false;

1788 rinfo->mergeopfamilies = NIL;

1789 rinfo->left_em = NULL;

1790 rinfo->right_em = NULL;

1791 }

1792 Assert(rinfo->orclause == NULL);

1793 }

1794 return true;

1795 }

1796

1797 return false;

1798}

1799

1800

1801

1802

1803

1804

1805

1806

1807

1808

1809

1810

1811

1812

1813

1814

1815

1816

1817

1818

1819

1820

1821

1822

1823

1824static void

1827 List *restrictlist)

1828{

1829 List *joininfos;

1831 int i;

1832 List *jinfo_candidates = NIL;

1833 List *binfo_candidates = NIL;

1834

1837

1838

1839

1840

1841

1842

1843

1846 {

1850

1852 jinfo_candidates = lappend(jinfo_candidates, rinfo);

1853 else

1854 binfo_candidates = lappend(binfo_candidates, rinfo);

1855 }

1856

1857

1858

1859

1860

1861

1862

1864 restrictlist);

1866 {

1869

1871 jinfo_candidates = lappend(jinfo_candidates, rinfo);

1872 else

1873 binfo_candidates = lappend(binfo_candidates, rinfo);

1874 }

1875

1876

1877

1878

1883

1886

1887

1888

1889

1890

1891

1892

1893 i = -1;

1895 {

1897

1900 }

1901

1902

1903

1904

1905

1907 {

1909

1914 }

1915

1916 for (i = toKeep->min_attr; i <= toKeep->max_attr; i++)

1917 {

1918 int attno = i - toKeep->min_attr;

1919

1920 toRemove->attr_needed[attno] = adjust_relid_set(toRemove->attr_needed[attno],

1922 toKeep->attr_needed[attno] = bms_add_members(toKeep->attr_needed[attno],

1923 toRemove->attr_needed[attno]);

1924 }

1925

1926

1927

1928

1929

1930

1931

1932

1933

1934 if (rmark)

1935 {

1936 if (kmark)

1937 {

1939

1941 }

1942 else

1943 {

1944

1946

1948 }

1949 }

1950

1951

1952

1953

1954

1957

1958

1960

1961

1967

1970

1971

1972

1973

1974

1975

1976

1977

1978

1979

1980

1981 root->simple_rel_array[toRemove->relid] = NULL;

1982

1983

1984 pfree(toRemove);

1985

1986

1987

1988

1989

1994}

1995

1996

1997

1998

1999

2000

2001

2002

2003

2004

2005static void

2007 List **otherjoinquals, int from, int to)

2008{

2011

2013 {

2015 Node *leftexpr;

2016 Node *rightexpr;

2017

2018

2019 if (!rinfo->mergeopfamilies ||

2023 {

2024 ojoinquals = lappend(ojoinquals, rinfo);

2025 continue;

2026 }

2027

2028 expr = (OpExpr *) rinfo->clause;

2029

2031 {

2032 ojoinquals = lappend(ojoinquals, rinfo);

2033 continue;

2034 }

2035

2036 leftexpr = get_leftop(rinfo->clause);

2038

2043

2044

2045

2046

2047

2048

2053

2054 if (equal(leftexpr, rightexpr))

2055 sjoinquals = lappend(sjoinquals, rinfo);

2056 else

2057 ojoinquals = lappend(ojoinquals, rinfo);

2058 }

2059

2060 *selfjoinquals = sjoinquals;

2061 *otherjoinquals = ojoinquals;

2062}

2063

2064

2065

2066

2067

2068

2069

2070static bool

2073{

2075 {

2076 Expr *clause;

2077 Node *iclause;

2079 bool matched = false;

2080

2082

2083

2086

2090

2095

2096

2097

2098

2099

2101 {

2102 Node *oclause;

2104

2105 if (orinfo->mergeopfamilies == NIL)

2106

2107 continue;

2108

2110

2111 oclause = bms_is_empty(orinfo->left_relids) ?

2115

2116 if (equal(iclause, oclause) && equal(c1, c2))

2117 {

2118 matched = true;

2119 break;

2120 }

2121 }

2122

2123 if (!matched)

2124 return false;

2125 }

2126

2127 return true;

2128}

2129

2130

2131

2132

2133

2134

2135

2138{

2139 Relids result = NULL;

2140 int k;

2141 int r = -1;

2142

2144 {

2146

2147 k = r;

2148

2150 {

2151 Relids joinrelids = NULL;

2153 List *restrictlist;

2154 List *selfjoinquals;

2155 List *otherjoinquals;

2157 bool jinfo_check = true;

2161

2162

2163 Assert(root->simple_rte_array[k]->relid ==

2164 root->simple_rte_array[r]->relid);

2165

2166

2167

2168

2169

2170

2171 foreach(lc, root->join_info_list)

2172 {

2174

2179 {

2180 jinfo_check = false;

2181 break;

2182 }

2183 }

2184 if (!jinfo_check)

2185 continue;

2186

2187

2188

2189

2190

2191

2192

2193 foreach(lc, root->rowMarks)

2194 {

2196

2197 if (rowMark->rti == k)

2198 {

2199 Assert(imark == NULL);

2200 imark = rowMark;

2201 }

2202 else if (rowMark->rti == r)

2203 {

2204 Assert(omark == NULL);

2205 omark = rowMark;

2206 }

2207

2208 if (omark && imark)

2209 break;

2210 }

2212 continue;

2213

2214

2215

2216

2217

2220

2221

2222

2223

2224

2225

2226

2227

2228

2229

2230

2233 outer, NULL);

2234 if (restrictlist == NIL)

2235 continue;

2236

2237

2238

2239

2240

2241

2243 &otherjoinquals, inner->relid, outer->relid);

2244

2247

2248

2249

2250

2251

2252

2253

2255

2256

2257

2258

2259

2260

2261

2262

2266 &uclauses))

2267 continue;

2268

2269

2270

2271

2272

2273

2274

2275

2276

2277

2278

2279

2281 continue;

2282

2283

2284

2285

2286

2288

2290

2291

2292 break;

2293 }

2294 }

2295

2296 return result;

2297}

2298

2299

2300

2301

2302

2305{

2307 Relids relids = NULL;

2309 int i;

2310 int j;

2311 int numRels;

2312

2313

2314 foreach(jl, joinlist)

2315 {

2317

2319 {

2320 int varno = ((RangeTblRef *) jlnode)->rtindex;

2322

2323

2324

2325

2326

2327

2328

2329

2330

2332 rte->relkind == RELKIND_RELATION &&

2334 varno != root->parse->resultRelation &&

2335 varno != root->parse->mergeTargetRelation)

2336 {

2339 }

2340 }

2341 else if (IsA(jlnode, List))

2342 {

2343

2345 toRemove);

2346 }

2347 else

2348 elog(ERROR, "unrecognized joinlist node type: %d",

2350 }

2351

2353

2354

2355 if (numRels < 2)

2356 return toRemove;

2357

2358

2359

2360

2361

2363 numRels);

2364 i = -1;

2365 j = 0;

2367 {

2368 candidates[j].relid = i;

2369 candidates[j].reloid = root->simple_rte_array[i]->relid;

2370 j++;

2371 }

2372

2375

2376

2377

2378

2379

2380

2381

2382

2383

2384

2385 i = 0;

2386 for (j = 1; j < numRels + 1; j++)

2387 {

2388 if (j == numRels || candidates[j].reloid != candidates[i].reloid)

2389 {

2390 if (j - i >= 2)

2391 {

2392

2393 Relids group = NULL;

2395

2396 while (i < j)

2397 {

2399 i++;

2400 }

2402

2403

2404

2405

2406

2407

2408

2409 do

2410 {

2419 }

2420 else

2421 {

2422

2424 i = j;

2425 }

2426 }

2427 }

2428

2430

2431 return toRemove;

2432}

2433

2434

2435

2436

2437static int

2439{

2442

2445 else

2446 return 0;

2447}

2448

2449

2450

2451

2452

2453

2454

2455

2456

2457

2458

2459

2460

2461

2462

2463

2464

2465

2466

2467

2468

2469

2470

2471

2472

2473

2474

2475

2476

2477

2478

2479

2480

2481

2482

2483

2486{

2487 Relids toRemove = NULL;

2488 int relid = -1;

2489

2492 return joinlist;

2493

2494

2495

2496

2497

2499

2500 if (unlikely(toRemove != NULL))

2501 {

2502

2504 {

2505 int nremoved = 0;

2506

2508 if (nremoved != 1)

2509 elog(ERROR, "failed to find relation %d in joinlist", relid);

2510 }

2511 }

2512

2513 return joinlist;

2514}

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

static bool match_unique_clauses(PlannerInfo *root, RelOptInfo *outer, List *uclauses, Index relid)

static bool replace_relid_callback(Node *node, ChangeVarNodes_context *context)

static void split_selfjoin_quals(PlannerInfo *root, List *joinquals, List **selfjoinquals, List **otherjoinquals, int from, int to)

static void add_non_redundant_clauses(PlannerInfo *root, List *rinfo_candidates, List **keep_rinfo_list, Index removed_relid)

static void remove_rel_from_query(PlannerInfo *root, RelOptInfo *rel, int subst, SpecialJoinInfo *sjinfo, Relids joinrelids)

bool innerrel_is_unique(PlannerInfo *root, Relids joinrelids, Relids outerrelids, RelOptInfo *innerrel, JoinType jointype, List *restrictlist, bool force_cache)

static List * remove_rel_from_joinlist(List *joinlist, int relid, int *nremoved)

static void remove_leftjoinrel_from_query(PlannerInfo *root, int relid, SpecialJoinInfo *sjinfo)

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

static Relids remove_self_joins_one_group(PlannerInfo *root, Relids relids)

List * remove_useless_joins(PlannerInfo *root, List *joinlist)

static Oid distinct_col_search(int colno, List *colnos, List *opids)

static bool is_innerrel_unique_for(PlannerInfo *root, Relids joinrelids, Relids outerrelids, RelOptInfo *innerrel, JoinType jointype, List *restrictlist, List **extra_clauses)

static bool rel_is_distinct_for(PlannerInfo *root, RelOptInfo *rel, List *clause_list, List **extra_clauses)

bool innerrel_is_unique_ext(PlannerInfo *root, Relids joinrelids, Relids outerrelids, RelOptInfo *innerrel, JoinType jointype, List *restrictlist, bool force_cache, List **extra_clauses)

static void remove_rel_from_eclass(EquivalenceClass *ec, SpecialJoinInfo *sjinfo, int relid, int subst)

List * remove_useless_self_joins(PlannerInfo *root, List *joinlist)

bool query_supports_distinctness(Query *query)

static void update_eclasses(EquivalenceClass *ec, int from, int to)

static bool restrict_infos_logically_equal(RestrictInfo *a, RestrictInfo *b)

static Relids remove_self_joins_recurse(PlannerInfo *root, List *joinlist, Relids toRemove)

static bool join_is_removable(PlannerInfo *root, SpecialJoinInfo *sjinfo)

void reduce_unique_semijoins(PlannerInfo *root)

bool enable_self_join_elimination

static void remove_rel_from_restrictinfo(RestrictInfo *rinfo, int relid, int ojrelid)

static bool rel_supports_distinctness(PlannerInfo *root, RelOptInfo *rel)

static void remove_self_join_rel(PlannerInfo *root, PlanRowMark *kmark, PlanRowMark *rmark, RelOptInfo *toKeep, RelOptInfo *toRemove, List *restrictlist)

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

Bitmapset * bms_make_singleton(int x)

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

int bms_next_member(const Bitmapset *a, int prevbit)

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

Bitmapset * bms_del_member(Bitmapset *a, int x)

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

int bms_singleton_member(const Bitmapset *a)

void bms_free(Bitmapset *a)

int bms_num_members(const Bitmapset *a)

bool bms_is_member(int x, const Bitmapset *a)

Bitmapset * bms_add_member(Bitmapset *a, int x)

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

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

BMS_Membership bms_membership(const Bitmapset *a)

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

bool bms_get_singleton_member(const Bitmapset *a, int *member)

Bitmapset * bms_copy(const Bitmapset *a)

#define OidIsValid(objectId)

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

void rebuild_eclass_attr_needed(PlannerInfo *root)

void ec_clear_derived_clauses(EquivalenceClass *ec)

List * generate_join_implied_equalities(PlannerInfo *root, Relids join_relids, Relids outer_relids, RelOptInfo *inner_rel, SpecialJoinInfo *sjinfo)

Assert(PointerIsAligned(start, uint64))

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

void rebuild_lateral_attr_needed(PlannerInfo *root)

void distribute_restrictinfo_to_rels(PlannerInfo *root, RestrictInfo *restrictinfo)

void rebuild_joinclause_attr_needed(PlannerInfo *root)

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

void remove_join_clause_from_rels(PlannerInfo *root, RestrictInfo *restrictinfo, Relids join_relids)

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

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)

void list_free(List *list)

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

bool equality_ops_are_compatible(Oid opno1, Oid opno2)

void pfree(void *pointer)

static bool is_andclause(const void *clause)

static bool is_orclause(const void *clause)

static Node * get_rightop(const void *clause)

static bool is_opclause(const void *clause)

static Node * get_leftop(const void *clause)

#define IsA(nodeptr, _type_)

#define IS_OUTER_JOIN(jointype)

#define castNode(_type_, nodeptr)

static MemoryContext MemoryContextSwitchTo(MemoryContext context)

#define RINFO_IS_PUSHED_DOWN(rinfo, joinrelids)

#define lfirst_node(type, lc)

static int list_length(const List *l)

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

#define foreach_delete_current(lst, var_or_cell)

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

#define foreach_node(type, var, lst)

static ListCell * list_head(const List *l)

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

void rebuild_placeholder_attr_needed(PlannerInfo *root)

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

RelOptInfo * find_base_rel(PlannerInfo *root, int relid)

bool restriction_is_or_clause(RestrictInfo *restrictinfo)

static bool clause_sides_match_join(RestrictInfo *rinfo, Relids outerrelids, Relids innerrelids)

bool ChangeVarNodesWalkExpression(Node *node, ChangeVarNodes_context *context)

Relids adjust_relid_set(Relids relids, int oldrelid, int newrelid)

void ChangeVarNodesExtended(Node *node, int rt_index, int new_index, int sublevels_up, ChangeVarNodes_callback callback)

NullTestType nulltesttype

struct TableSampleClause * tablesample

struct PathTarget * reltarget

List * non_unique_for_rels

Bitmapset * eclass_indexes

Relids incompatible_relids

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

Relids pull_varnos(PlannerInfo *root, Node *node)