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

37

38

39

40

41

42

43

44

45

46

47

48typedef struct

49{

53

55

56

61 int relid, int ojrelid);

64 int relid, int subst);

68 List *clause_list, List **extra_clauses);

75 List *restrictlist,

76 List **extra_clauses);

80

81

82

83

84

85

86

87

88

89

92{

94

95

96

97

98

99restart:

100 foreach(lc, root->join_info_list)

101 {

103 int innerrelid;

104 int nremoved;

105

106

108 continue;

109

110

111

112

113

114

116

118

119

120 nremoved = 0;

122 if (nremoved != 1)

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

124

125

126

127

128

129

131

132

133

134

135

136

137

138 goto restart;

139 }

140

141 return joinlist;

142}

143

144

145

146

147

148

149

150

151

152

153

154

155static bool

157{

158 int innerrelid;

164 int attroff;

165

166

167

168

169

171 return false;

172

174 return false;

175

176

177

178

179

180

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

182 return false;

183

185

186

187

188

189

190

192 return false;

193

194

197 joinrelids = bms_copy(inputrelids);

199

200

201

202

203

204

205

206

207

208

209

210

212 attroff >= 0;

213 attroff--)

214 {

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

216 return false;

217 }

218

219

220

221

222

223

224

225

226

227

228 foreach(l, root->placeholder_list)

229 {

231

233 return false;

235 continue;

237 continue;

239 return false;

240

241

242

243

244

246 return false;

247

250 return false;

251 }

252

253

254

255

256

257

258

259

260 foreach(l, innerrel->joininfo)

261 {

263

264

265

266

267

268

269

270

271

273 continue;

274

275

276

277

278

279

280

282 continue;

283

284

285 if (!restrictinfo->can_join ||

286 restrictinfo->mergeopfamilies == NIL)

287 continue;

288

289

290

291

292

295 continue;

296

297

298 clause_list = lappend(clause_list, restrictinfo);

299 }

300

301

302

303

304

306 return true;

307

308

309

310

311

312 return false;

313}

314

315

316

317

318

319

320

321

322

323

324

325static void

329{

330 int relid = rel->relid;

333

334

335

336

339

340 if (sjinfo != NULL)

341 {

346 }

347

348

349

350

351

352

353

354

355

356 foreach(l, root->join_info_list)

357 {

359

360

361

362

363

364

365

370

375

376 if (sjinfo != NULL)

377 {

379

380

389

398 }

399 else

400 {

402

405 }

406 }

407

408

409

410

411

412

413

414

415

416

417

418

419

420

421

422

423

424

425

426

427 foreach(l, root->placeholder_list)

428 {

430

432 if (sjinfo != NULL &&

436 {

437

438

439

440

441

443 l);

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

445 }

446 else

447 {

449

451 if (sjinfo != NULL)

455

458 else

460

462

463

464

465

466

468

469

471 if (sjinfo != NULL)

475

478

480 }

481 }

482

483

484

485

486 foreach(l, root->eq_classes)

487 {

489

493 }

494

495

496

497

498

499

500

501

502

503

504

505

506

507

508

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

510 {

512 int attroff;

513

514

515 if (otherrel == NULL)

516 continue;

517

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

519

521 attroff >= 0;

522 attroff--)

523 {

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

526 else

527 otherrel->attr_needed[attroff] = NULL;

528 }

529

530 if (subst > 0)

533 }

534}

535

536

537

538

539

540

541

542

543

544static void

547{

549 int ojrelid = sjinfo->ojrelid;

551 Relids join_plus_commute;

552 List *joininfos;

554

555

557 Assert(ojrelid != 0);

559

561

562

563

564

565

566

567

568

569

570

571

572

573

574

575

576

577

578 join_plus_commute = bms_union(joinrelids,

582

583

584

585

586

587

589 foreach(l, joininfos)

590 {

592

594

596 {

597

598

599

600

601

602

603

605

606

607

608

609

610#ifdef USE_ASSERT_CHECKING

611 {

614

617 }

618#endif

619

621 }

622 }

623

624

625

626

627

628

629

630

631

632

633

634 root->simple_rel_array[relid] = NULL;

635 root->simple_rte_array[relid] = NULL;

636

637

639

640

641

642

643

648}

649

650

651

652

653

654

655

656

657

658static void

660{

661

662

663

664

665

666

667

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

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

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

671

675

676

678 {

680

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

683 {

685

686

688 {

691

692 foreach(lc2, andargs)

693 {

695

697 }

698 }

699 else

700 {

702

704 }

705 }

706 }

707}

708

709

710

711

712

713

714

715

716

717

718

719static void

721 int relid, int subst)

722{

724

725

727 if (sjinfo != NULL)

730

731

732

733

734

735

737

738

739

740

741

742

744 {

746

750 {

753 if (sjinfo != NULL)

758 }

759 }

760

761

763 {

765

766 if (sjinfo == NULL)

769 else

771 }

772

773

774

775

776

777

779}

780

781

782

783

784

785

786

787

788

789

792{

795

796 foreach(jl, joinlist)

797 {

799

801 {

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

803

804 if (varno == relid)

805 (*nremoved)++;

806 else

807 result = lappend(result, jlnode);

808 }

809 else if (IsA(jlnode, List))

810 {

811

812 List *sublist;

813

815 relid, nremoved);

816

817 if (sublist)

818 result = lappend(result, sublist);

819 }

820 else

821 {

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

824 }

825 }

826

827 return result;

828}

829

830

831

832

833

834

835

836

837

838

839

840

841

842

843

844void

846{

848

849

850

851

852 foreach(lc, root->join_info_list)

853 {

855 int innerrelid;

858 List *restrictlist;

859

860

861

862

863

865 continue;

866

868 continue;

869

871

872

873

874

875

876

878 continue;

879

880

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

883

884

885

886

887

888

889 restrictlist =

891 joinrelids,

893 innerrel,

894 NULL),

896

897

901 continue;

902

903

905 }

906}

907

908

909

910

911

912

913

914

915

916

917

918

919

920static bool

922{

923

925 return false;

927 {

928

929

930

931

932

933

934

936

938 {

940

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

942 return true;

943 }

944 }

946 {

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

948

949

951 return true;

952 }

953

954 return false;

955}

956

957

958

959

960

961

962

963

964

965

966

967

968

969

970

971

972

973

974

975

976

977

978

979

980static bool

982 List **extra_clauses)

983{

984

985

986

987

988

990 return false;

992 {

993

994

995

996

997

999 return true;

1000 }

1002 {

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

1008

1009

1010

1011

1012

1013

1014

1015

1016

1017

1018 foreach(l, clause_list)

1019 {

1022 Var *var;

1023

1024

1025

1026

1027

1028

1029

1030

1031

1033

1034

1035 if (rinfo->outer_is_left)

1037 else

1039

1040

1041

1042

1043

1044

1047

1048

1049

1050

1051

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

1054 continue;

1055

1058 }

1059

1061 return true;

1062 }

1063 return false;

1064}

1065

1066

1067

1068

1069

1070

1071

1072

1073

1074

1075

1076

1077

1078bool

1080{

1081

1083 return false;

1084

1085

1089 query->hasAggs ||

1092 return true;

1093

1094 return false;

1095}

1096

1097

1098

1099

1100

1101

1102

1103

1104

1105

1106

1107

1108

1109

1110

1111

1112

1113

1114

1115

1116bool

1118{

1120 Oid opid;

1121

1123

1124

1125

1126

1127

1128

1129

1131 {

1133 {

1137

1141 break;

1142 }

1143 if (l == NULL)

1144 return true;

1145 }

1146

1147

1148

1149

1150

1151

1152

1153

1154 if (query->hasTargetSRFs)

1155 return false;

1156

1157

1158

1159

1160

1162 {

1164 {

1168

1172 break;

1173 }

1174 if (l == NULL)

1175 return true;

1176 }

1178 {

1179 List *gsets;

1180

1181

1182

1183

1184

1186 return false;

1187

1188

1189

1190

1191

1192

1193

1194

1196 return true;

1197

1199

1201 }

1202 else

1203 {

1204

1205

1206

1207

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

1209 return true;

1210 }

1211

1212

1213

1214

1215

1217 {

1219

1221

1222 if (!topop->all)

1223 {

1225

1226

1227 lg = list_head(topop->groupClauses);

1229 {

1232

1233 if (tle->resjunk)

1234 continue;

1235

1236

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

1240

1244 break;

1245 }

1246 if (l == NULL)

1247 return true;

1248 }

1249 }

1250

1251

1252

1253

1254

1255

1256

1257

1258

1259 return false;

1260}

1261

1262

1263

1264

1265

1266

1267

1268

1269static Oid

1271{

1273 *lc2;

1274

1275 forboth(lc1, colnos, lc2, opids)

1276 {

1279 }

1281}

1282

1283

1284

1285

1286

1287

1288

1289

1290

1291

1292

1293

1294

1295

1296

1297

1298

1299

1300

1301

1302

1303

1304

1305

1306

1307

1308

1309bool

1315 List *restrictlist,

1316 bool force_cache)

1317{

1319 jointype, restrictlist, force_cache, NULL);

1320}

1321

1322

1323

1324

1325

1326

1327

1328

1329

1330

1331bool

1337 List *restrictlist,

1338 bool force_cache,

1339 List **extra_clauses)

1340{

1344 List *outer_exprs = NIL;

1345 bool self_join = (extra_clauses != NULL);

1346

1347

1348 if (restrictlist == NIL)

1349 return false;

1350

1351

1352

1353

1354

1356 return false;

1357

1358

1359

1360

1361

1362

1363

1364

1365

1366

1367

1368

1369

1371 {

1373

1377 {

1378 if (extra_clauses)

1380 return true;

1381 }

1382 }

1383

1384

1385

1386

1387

1389 {

1391

1392 if (bms_is_subset(outerrelids, unique_for_rels))

1393 return false;

1394 }

1395

1396

1398 jointype, restrictlist,

1399 self_join ? &outer_exprs : NULL))

1400 {

1401

1402

1403

1404

1405

1406

1407

1408

1409

1410

1414 uniqueRelInfo->self_join = self_join;

1417 uniqueRelInfo);

1419

1420 if (extra_clauses)

1421 *extra_clauses = outer_exprs;

1422 return true;

1423 }

1424 else

1425 {

1426

1427

1428

1429

1430

1431

1432

1433

1434

1435

1436

1437

1438

1439

1440 if (force_cache || root->assumeReplanning)

1441 {

1447 }

1448

1449 return false;

1450 }

1451}

1452

1453

1454

1455

1456

1457

1458static bool

1464 List *restrictlist,

1465 List **extra_clauses)

1466{

1467 List *clause_list = NIL;

1469

1470

1471

1472

1473

1474

1475

1476

1477 foreach(lc, restrictlist)

1478 {

1480

1481

1482

1483

1484

1487 continue;

1488

1489

1490 if (!restrictinfo->can_join ||

1491 restrictinfo->mergeopfamilies == NIL)

1492 continue;

1493

1494

1495

1496

1497

1500 continue;

1501

1502

1503 clause_list = lappend(clause_list, restrictinfo);

1504 }

1505

1506

1508}

1509

1510

1511

1512

1513

1514

1515

1516

1517

1518

1519

1520

1521

1522

1523

1524

1525

1526

1527

1528

1529

1530

1531

1532static void

1534{

1535 List *new_members = NIL;

1536 List *new_sources = NIL;

1537

1538

1539

1540

1541

1542

1544

1546 {

1547 bool is_redundant = false;

1548

1550 {

1551 new_members = lappend(new_members, em);

1552 continue;

1553 }

1554

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

1557

1558

1561

1563 {

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

1565 continue;

1566

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

1568 {

1569 is_redundant = true;

1570 break;

1571 }

1572 }

1573

1574 if (!is_redundant)

1575 new_members = lappend(new_members, em);

1576 }

1577

1580

1582

1583

1585 {

1586 bool is_redundant = false;

1587

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

1589 {

1590 new_sources = lappend(new_sources, rinfo);

1591 continue;

1592 }

1593

1596

1597

1598

1599

1600

1601

1603 {

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

1605 continue;

1606

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

1608 {

1609 is_redundant = true;

1610 break;

1611 }

1612 }

1613

1614 if (!is_redundant)

1615 new_sources = lappend(new_sources, rinfo);

1616 }

1617

1621}

1622

1623

1624

1625

1626

1627

1628

1629

1630

1631

1632static bool

1634{

1635 int saved_rinfo_serial = a->rinfo_serial;

1636 bool result;

1637

1638 a->rinfo_serial = b->rinfo_serial;

1640 a->rinfo_serial = saved_rinfo_serial;

1641

1642 return result;

1643}

1644

1645

1646

1647

1648

1649

1650

1651

1652

1653

1654

1655

1656

1657

1658static void

1660 List *rinfo_candidates,

1661 List **keep_rinfo_list,

1662 Index removed_relid)

1663{

1665 {

1666 bool is_redundant = false;

1667

1669

1671 {

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

1673

1674 continue;

1675

1676 if (src == rinfo ||

1677 (rinfo->parent_ec != NULL &&

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

1680 {

1681 is_redundant = true;

1682 break;

1683 }

1684 }

1685 if (!is_redundant)

1687 }

1688}

1689

1690

1691

1692

1693

1694

1695

1696

1697

1698

1699

1700

1701

1702static bool

1704{

1706 {

1707 return true;

1708 }

1710 {

1712 int relid = -1;

1713 bool is_req_equal =

1715 bool clause_relids_is_multiple =

1717

1718

1719

1720

1721

1722

1723

1726 {

1727 Relids new_clause_relids;

1728

1731

1735

1736

1737

1738

1739

1740

1741

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

1744

1745 rinfo->clause_relids = new_clause_relids;

1746 rinfo->left_relids =

1748 rinfo->right_relids =

1750 }

1751

1752 if (is_req_equal)

1754 else

1757

1762

1763 if (rinfo->mergeopfamilies &&

1765 clause_relids_is_multiple &&

1767 {

1768 Expr *leftOp;

1769 Expr *rightOp;

1770

1773

1774

1775

1776

1777

1778

1779

1780

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

1782 {

1784

1785 ntest->arg = leftOp;

1787 ntest->argisrow = false;

1790 rinfo->mergeopfamilies = NIL;

1791 rinfo->left_em = NULL;

1792 rinfo->right_em = NULL;

1793 }

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

1795 }

1796 return true;

1797 }

1798

1799 return false;

1800}

1801

1802

1803

1804

1805

1806

1807

1808

1809

1810

1811

1812

1813

1814

1815

1816

1817

1818

1819

1820

1821

1822

1823

1824

1825

1826static void

1829 List *restrictlist)

1830{

1831 List *joininfos;

1833 int i;

1834 List *jinfo_candidates = NIL;

1835 List *binfo_candidates = NIL;

1836

1839

1840

1841

1842

1843

1844

1845

1848 {

1852

1854 jinfo_candidates = lappend(jinfo_candidates, rinfo);

1855 else

1856 binfo_candidates = lappend(binfo_candidates, rinfo);

1857 }

1858

1859

1860

1861

1862

1863

1864

1866 restrictlist);

1868 {

1871

1873 jinfo_candidates = lappend(jinfo_candidates, rinfo);

1874 else

1875 binfo_candidates = lappend(binfo_candidates, rinfo);

1876 }

1877

1878

1879

1880

1885

1888

1889

1890

1891

1892

1893

1894

1895 i = -1;

1897 {

1899

1902 }

1903

1904

1905

1906

1907

1909 {

1911

1916 }

1917

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

1919 {

1920 int attno = i - toKeep->min_attr;

1921

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

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

1925 toRemove->attr_needed[attno]);

1926 }

1927

1928

1929

1930

1931

1932

1933

1934

1935

1936 if (rmark)

1937 {

1938 if (kmark)

1939 {

1941

1943 }

1944 else

1945 {

1946

1948

1950 }

1951 }

1952

1953

1954

1955

1956

1959

1960

1962

1963

1969

1972

1973

1974

1975

1976

1977

1978

1979

1980

1981

1982

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

1984 root->simple_rte_array[toRemove->relid] = NULL;

1985

1986

1987 pfree(toRemove);

1988

1989

1990

1991

1992

1993

1998}

1999

2000

2001

2002

2003

2004

2005

2006

2007

2008

2009static void

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

2012{

2015

2017 {

2019 Node *leftexpr;

2020 Node *rightexpr;

2021

2022

2023 if (!rinfo->mergeopfamilies ||

2027 {

2028 ojoinquals = lappend(ojoinquals, rinfo);

2029 continue;

2030 }

2031

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

2033

2035 {

2036 ojoinquals = lappend(ojoinquals, rinfo);

2037 continue;

2038 }

2039

2040 leftexpr = get_leftop(rinfo->clause);

2042

2047

2048

2049

2050

2051

2052

2057

2058 if (equal(leftexpr, rightexpr))

2059 sjoinquals = lappend(sjoinquals, rinfo);

2060 else

2061 ojoinquals = lappend(ojoinquals, rinfo);

2062 }

2063

2064 *selfjoinquals = sjoinquals;

2065 *otherjoinquals = ojoinquals;

2066}

2067

2068

2069

2070

2071

2072

2073

2074static bool

2077{

2079 {

2080 Expr *clause;

2081 Node *iclause;

2083 bool matched = false;

2084

2086

2087

2090

2094

2099

2100

2101

2102

2103

2105 {

2106 Node *oclause;

2108

2109 if (orinfo->mergeopfamilies == NIL)

2110

2111 continue;

2112

2114

2115 oclause = bms_is_empty(orinfo->left_relids) ?

2119

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

2121 {

2122 matched = true;

2123 break;

2124 }

2125 }

2126

2127 if (!matched)

2128 return false;

2129 }

2130

2131 return true;

2132}

2133

2134

2135

2136

2137

2138

2139

2142{

2143 Relids result = NULL;

2144 int k;

2145 int r = -1;

2146

2148 {

2150

2151 k = r;

2152

2154 {

2155 Relids joinrelids = NULL;

2157 List *restrictlist;

2158 List *selfjoinquals;

2159 List *otherjoinquals;

2161 bool jinfo_check = true;

2165

2166

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

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

2169

2170

2171

2172

2173

2174

2175 foreach(lc, root->join_info_list)

2176 {

2178

2183 {

2184 jinfo_check = false;

2185 break;

2186 }

2187 }

2188 if (!jinfo_check)

2189 continue;

2190

2191

2192

2193

2194

2195

2196

2197 foreach(lc, root->rowMarks)

2198 {

2200

2201 if (rowMark->rti == r)

2202 {

2203 Assert(rmark == NULL);

2204 rmark = rowMark;

2205 }

2206 else if (rowMark->rti == k)

2207 {

2208 Assert(kmark == NULL);

2209 kmark = rowMark;

2210 }

2211

2212 if (kmark && rmark)

2213 break;

2214 }

2216 continue;

2217

2218

2219

2220

2221

2224

2225

2226

2227

2228

2229

2230

2231

2232

2233

2234

2237 krel, NULL);

2238 if (restrictlist == NIL)

2239 continue;

2240

2241

2242

2243

2244

2245

2247 &otherjoinquals, rrel->relid, krel->relid);

2248

2251

2252

2253

2254

2255

2256

2257

2259

2260

2261

2262

2263

2264

2265

2266

2270 &uclauses))

2271 continue;

2272

2273

2274

2275

2276

2277

2278

2279

2280

2281

2282

2283

2285 continue;

2286

2287

2288

2289

2290

2292

2294

2295

2296 break;

2297 }

2298 }

2299

2300 return result;

2301}

2302

2303

2304

2305

2306

2309{

2311 Relids relids = NULL;

2313 int i;

2314 int j;

2315 int numRels;

2316

2317

2318 foreach(jl, joinlist)

2319 {

2321

2323 {

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

2326

2327

2328

2329

2330

2331

2332

2333

2334

2336 rte->relkind == RELKIND_RELATION &&

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

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

2340 {

2343 }

2344 }

2345 else if (IsA(jlnode, List))

2346 {

2347

2349 toRemove);

2350 }

2351 else

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

2354 }

2355

2357

2358

2359 if (numRels < 2)

2360 return toRemove;

2361

2362

2363

2364

2365

2367 i = -1;

2368 j = 0;

2370 {

2371 candidates[j].relid = i;

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

2373 j++;

2374 }

2375

2378

2379

2380

2381

2382

2383

2384

2385

2386

2387

2388 i = 0;

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

2390 {

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

2392 {

2393 if (j - i >= 2)

2394 {

2395

2396 Relids group = NULL;

2398

2399 while (i < j)

2400 {

2402 i++;

2403 }

2405

2406

2407

2408

2409

2410

2411

2412 do

2413 {

2422 }

2423 else

2424 {

2425

2427 i = j;

2428 }

2429 }

2430 }

2431

2433

2434 return toRemove;

2435}

2436

2437

2438

2439

2440static int

2442{

2445

2448 else

2449 return 0;

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

2484

2485

2486

2489{

2490 Relids toRemove = NULL;

2491 int relid = -1;

2492

2495 return joinlist;

2496

2497

2498

2499

2500

2502

2503 if (unlikely(toRemove != NULL))

2504 {

2505

2507 {

2508 int nremoved = 0;

2509

2511 if (nremoved != 1)

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

2513 }

2514 }

2515

2516 return joinlist;

2517}

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)

#define palloc_array(type, count)

Assert(PointerIsAligned(start, uint64))

bool relation_has_unique_index_for(PlannerInfo *root, RelOptInfo *rel, List *restrictlist, 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)

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

#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)