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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

16

17#include <limits.h>

18

36

37

39{

43

47 List *pushed_down_joins,

48 bool can_null);

60 Relids both_input_relids,

61 List *new_restrictlist);

63 List *joininfo_list,

64 List *new_joininfo);

72 List *restrictlist);

77 bool strict_op);

84 int nappinfos,

86

87

88

89

90

91

92

93void

95{

96 int size;

99

100

102 root->simple_rel_array_size = size;

103

104

105

106

107

110

111

114 rti = 1;

115 foreach(lc, root->parse->rtable)

116 {

118

119 root->simple_rte_array[rti++] = rte;

120 }

121

122

123 if (root->append_rel_list == NIL)

124 {

125 root->append_rel_array = NULL;

126 return;

127 }

128

131

132

133

134

135

136

137

138 foreach(lc, root->append_rel_list)

139 {

142

143

144 Assert(child_relid < size);

145

146 if (root->append_rel_array[child_relid])

147 elog(ERROR, "child relation already exists");

148

149 root->append_rel_array[child_relid] = appinfo;

150 }

151}

152

153

154

155

156

157

158

159

160

161

162void

164{

165 int new_size;

166

168

169 new_size = root->simple_rel_array_size + add_size;

170

171 root->simple_rel_array =

173

174 root->simple_rte_array =

176

177 if (root->append_rel_array)

178 root->append_rel_array =

180 else

181 root->append_rel_array =

183

184 root->simple_rel_array_size = new_size;

185}

186

187

188

189

190

193{

196

197

198 Assert(relid > 0 && relid < root->simple_rel_array_size);

199 if (root->simple_rel_array[relid] != NULL)

200 elog(ERROR, "rel %d already exists", relid);

201

202

203 rte = root->simple_rte_array[relid];

205

209 rel->rows = 0;

210

222 rel->relid = relid;

224

239 {

240 Assert(parent == NULL ||

243

244

245

246

247

248

249

250

251

252

256 {

258

261 }

262 else

264 }

265 else

268 rel->fdwroutine = NULL;

269 rel->fdw_private = NULL;

279 rel->part_scheme = NULL;

281 rel->boundinfo = NULL;

284 rel->part_rels = NULL;

287 rel->partexprs = NULL;

288 rel->nullable_partexprs = NULL;

289

290

291

292

293 if (parent)

294 {

295

296 rel->parent = parent;

297 rel->top_parent = parent->top_parent ? parent->top_parent : parent;

299

300

301

302

303

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

323 }

324 else

325 {

326 rel->parent = NULL;

327 rel->top_parent = NULL;

333 }

334

335

337 {

339

341 break;

348

349

350

351

352

353

354

357 rel->attr_needed = (Relids *)

359 rel->attr_widths = (int32 *)

361 break;

363

366 rel->attr_needed = NULL;

367 rel->attr_widths = NULL;

368 break;

369 default:

370 elog(ERROR, "unrecognized RTE kind: %d",

372 break;

373 }

374

375

376

377

378

379

380 root->simple_rel_array[relid] = rel;

381

382

383

384

385

386

387

388

389

390

391 if (parent)

392 {

394

395 Assert(appinfo != NULL);

397 {

398

399

400

401

403 }

404 }

405

406 return rel;

407}

408

409

410

411

412

415{

417

418

420 {

421 rel = root->simple_rel_array[relid];

422 if (rel)

423 return rel;

424 }

425

426 elog(ERROR, "no relation entry for relid %d", relid);

427

428 return NULL;

429}

430

431

432

433

434

437{

438

440 return root->simple_rel_array[relid];

441 return NULL;

442}

443

444

445

446

447

448

449

450

451

452

455{

456

458 {

461

462 rel = root->simple_rel_array[relid];

463 if (rel)

464 return rel;

465

466

467

468

469

470

471 rte = root->simple_rte_array[relid];

473 return NULL;

474 }

475

476 elog(ERROR, "no relation entry for relid %d", relid);

477

478 return NULL;

479}

480

481

482

483

484

485static void

487{

488 HTAB *hashtab;

491

492

498 hashtab = hash_create("JoinRelHashTable",

499 256L,

500 &hash_ctl,

502

503

504 foreach(l, root->join_rel_list)

505 {

508 bool found;

509

513 &found);

516 }

517

518 root->join_rel_hash = hashtab;

519}

520

521

522

523

524

525

528{

529

530

531

532

535

536

537

538

539

540

541

542

543

544 if (root->join_rel_hash)

545 {

546 Relids hashkey = relids;

548

550 &hashkey,

552 NULL);

553 if (hentry)

555 }

556 else

557 {

559

560 foreach(l, root->join_rel_list)

561 {

563

565 return rel;

566 }

567 }

568

569 return NULL;

570}

571

572

573

574

575

576

577

578

579

580

581

582

583

584

585

586

587

588static void

591{

594 {

596 {

600 joinrel->fdwroutine = outer_rel->fdwroutine;

601 }

604 {

608 joinrel->fdwroutine = outer_rel->fdwroutine;

609 }

612 {

616 joinrel->fdwroutine = outer_rel->fdwroutine;

617 }

618 }

619}

620

621

622

623

624

625

626static void

628{

629

630 root->join_rel_list = lappend(root->join_rel_list, joinrel);

631

632

633 if (root->join_rel_hash)

634 {

636 bool found;

637

641 &found);

644 }

645}

646

647

648

649

650

651

652

653

654

655

656

657

658

659

660

661

662

663

670 List *pushed_down_joins,

671 List **restrictlist_ptr)

672{

674 List *restrictlist;

675

676

678

679

680

681

683

684 if (joinrel)

685 {

686

687

688

689

690 if (restrictlist_ptr)

692 joinrel,

693 outer_rel,

694 inner_rel,

695 sjinfo);

696 return joinrel;

697 }

698

699

700

701

705 joinrel->rows = 0;

706

718

723 outer_rel, inner_rel);

724 joinrel->relid = 0;

728 joinrel->attr_needed = NULL;

729 joinrel->attr_widths = NULL;

736 joinrel->pages = 0;

747 joinrel->fdwroutine = NULL;

748 joinrel->fdw_private = NULL;

758 joinrel->parent = NULL;

759 joinrel->top_parent = NULL;

761 joinrel->part_scheme = NULL;

762 joinrel->nparts = -1;

763 joinrel->boundinfo = NULL;

766 joinrel->part_rels = NULL;

769 joinrel->partexprs = NULL;

770 joinrel->nullable_partexprs = NULL;

771

772

774

775

776

777

778

779

780

781

782

783

789

790

791

792

793

794

795

796

799

800

801

802

803

804

806 outer_rel, inner_rel,

807 sjinfo);

808 if (restrictlist_ptr)

809 *restrictlist_ptr = restrictlist;

811

812

813

814

815

817

818

820 restrictlist);

821

822

823

824

826 sjinfo, restrictlist);

827

828

829

830

831

832

833

834

835

836

837

838

839

840

841

846

847

849

850

851

852

853

854

855

856 if (root->join_rel_level)

857 {

860 root->join_rel_level[root->join_cur_level] =

861 lappend(root->join_rel_level[root->join_cur_level], joinrel);

862 }

863

864 return joinrel;

865}

866

867

868

869

870

871

872

873

874

875

876

877

878

879

880

886{

888

889

891

892

894

897 nappinfos, appinfos);

898 joinrel->rows = 0;

899

913 joinrel->relid = 0;

917 joinrel->attr_needed = NULL;

918 joinrel->attr_widths = NULL;

924 joinrel->pages = 0;

934 joinrel->fdwroutine = NULL;

935 joinrel->fdw_private = NULL;

942 joinrel->parent = parent_joinrel;

943 joinrel->top_parent = parent_joinrel->top_parent ? parent_joinrel->top_parent : parent_joinrel;

945 joinrel->part_scheme = NULL;

946 joinrel->nparts = -1;

947 joinrel->boundinfo = NULL;

950 joinrel->part_rels = NULL;

953 joinrel->partexprs = NULL;

954 joinrel->nullable_partexprs = NULL;

955

956

958

959

961 nappinfos, appinfos);

962

963

966 nappinfos,

967 appinfos);

968

969

970

971

972

975

976

977

978

979

981

982

984 restrictlist);

985

986

988

989

991 sjinfo, restrictlist);

992

993

995

996

998

999

1000

1001

1002

1003

1004

1007 nappinfos, appinfos,

1008 parent_joinrel, joinrel);

1009

1010 return joinrel;

1011}

1012

1013

1014

1015

1016

1017

1018

1019

1020

1026{

1028

1029

1030

1031

1032

1033

1034

1035

1036

1037

1038

1039

1040

1041

1044 return result;

1045}

1046

1047

1048

1049

1050

1051

1052

1053

1054

1055

1056

1057

1058

1059

1060

1061

1062

1063

1064

1065

1066

1067

1068

1069

1070

1071

1072

1073

1074

1075

1076

1077

1078

1079

1080

1081

1082

1083

1084

1085

1086

1087

1088

1089

1090

1091

1092

1093

1094

1095

1096

1097

1098

1099static void

1103 List *pushed_down_joins,

1104 bool can_null)

1105{

1110

1112 {

1114

1115

1116

1117

1119 {

1122

1123

1125 {

1126

1127

1128

1129

1130

1131 if (can_null)

1132 {

1134

1135 if (sjinfo->ojrelid != 0 &&

1142 foreach(lc, pushed_down_joins)

1143 {

1145

1150 }

1154 relids));

1155 }

1156

1158 phv);

1159

1160 tuple_width += phinfo->ph_width;

1161 }

1162 continue;

1163 }

1164

1165

1166

1167

1168

1169

1171 elog(ERROR, "unexpected node type in rel targetlist: %d",

1173

1175 {

1176

1179

1180

1182 }

1183 else

1184 {

1186 int ndx;

1187

1188

1190

1191

1194 continue;

1195

1196

1197 tuple_width += baserel->attr_widths[ndx];

1198 }

1199

1200

1201

1202

1203

1204

1205

1207 {

1209

1210 if (sjinfo->ojrelid != 0 &&

1215 var->varnullingrels = bms_add_member(var->varnullingrels,

1217 foreach(lc, pushed_down_joins)

1218 {

1220

1223 var->varnullingrels = bms_add_member(var->varnullingrels,

1225 }

1226 var->varnullingrels =

1227 bms_join(var->varnullingrels,

1229 relids));

1230 }

1231

1233 var);

1234

1235

1236 }

1237

1239}

1240

1241

1242

1243

1244

1245

1246

1247

1248

1249

1250

1251

1252

1253

1254

1255

1256

1257

1258

1259

1260

1261

1262

1263

1264

1265

1266

1267

1268

1269

1270

1271

1272

1273

1274

1275

1276

1277

1278

1279

1280

1281

1282

1283

1284static List *

1290{

1291 List *result;

1292 Relids both_input_relids;

1293

1295

1296

1297

1298

1299

1300

1302 both_input_relids, NIL);

1304 both_input_relids, result);

1305

1306

1307

1308

1309

1310

1315 inner_rel,

1316 sjinfo));

1317

1318 return result;

1319}

1320

1321static void

1325{

1326 List *result;

1327

1328

1329

1330

1331

1332

1335

1337}

1338

1339static List *

1343 Relids both_input_relids,

1344 List *new_restrictlist)

1345{

1347

1348 foreach(l, input_rel->joininfo)

1349 {

1351

1353 {

1354

1355

1356

1357

1358

1359

1360

1361

1362

1364 {

1367 continue;

1369 continue;

1370 }

1371 else

1372 {

1373

1374

1375

1376

1377

1378

1379

1382 both_input_relids));

1383 }

1384

1385

1386

1387

1388

1389

1390

1392 }

1393 else

1394 {

1395

1396

1397

1398

1399 }

1400 }

1401

1402 return new_restrictlist;

1403}

1404

1405static List *

1407 List *joininfo_list,

1408 List *new_joininfo)

1409{

1411

1412

1414

1415 foreach(l, joininfo_list)

1416 {

1418

1420 {

1421

1422

1423

1424

1425

1426 }

1427 else

1428 {

1429

1430

1431

1432

1433

1434

1435

1437 }

1438 }

1439

1440 return new_joininfo;

1441}

1442

1443

1444

1445

1446

1447

1448

1449

1450

1451

1452

1453

1454

1455

1456

1459{

1462

1463

1464

1465

1466

1467

1468

1469

1470

1471 foreach(lc, root->upper_rels[kind])

1472 {

1474

1476 return upperrel;

1477 }

1478

1482

1483

1486 upperrel->consider_parallel = false;

1493

1494 root->upper_rels[kind] = lappend(root->upper_rels[kind], upperrel);

1495

1496 return upperrel;

1497}

1498

1499

1500

1501

1502

1503

1504

1505

1506

1507

1510{

1511 Relids result = NULL;

1512

1515

1516 do

1517 {

1520

1522

1523

1526

1528

1529 return result;

1530}

1531

1532

1533

1534

1535

1536

1537

1538

1539

1540

1541

1542

1543

1546 Relids required_outer)

1547{

1550 List *pclauses;

1551 List *eqclauses;

1553 double rows;

1555

1556

1558

1559

1561 return NULL;

1562

1564

1565

1567 return ppi;

1568

1569

1570

1571

1572

1573 joinrelids = bms_union(baserel->relids, required_outer);

1574 pclauses = NIL;

1575 foreach(lc, baserel->joininfo)

1576 {

1578

1581 joinrelids))

1582 pclauses = lappend(pclauses, rinfo);

1583 }

1584

1585

1586

1587

1588

1589

1591 joinrelids,

1592 required_outer,

1593 baserel,

1594 NULL);

1595#ifdef USE_ASSERT_CHECKING

1596 foreach(lc, eqclauses)

1597 {

1599

1602 joinrelids));

1603 }

1604#endif

1605 pclauses = list_concat(pclauses, eqclauses);

1606

1607

1608 pserials = NULL;

1609 foreach(lc, pclauses)

1610 {

1612

1614 }

1615

1616

1618

1619

1626

1627 return ppi;

1628}

1629

1630

1631

1632

1633

1634

1635

1636

1637

1638

1639

1640

1641

1642

1643

1644

1645

1646

1647

1648

1649

1650

1651

1652

1653

1654

1655

1656

1657

1660 Path *outer_path,

1661 Path *inner_path,

1663 Relids required_outer,

1664 List **restrict_clauses)

1665{

1667 Relids join_and_req;

1668 Relids outer_and_req;

1669 Relids inner_and_req;

1670 List *pclauses;

1671 List *eclauses;

1672 List *dropped_ecs;

1673 double rows;

1675

1676

1678

1679

1681 return NULL;

1682

1684

1685

1686

1687

1688

1689

1690

1691

1692

1693

1694 join_and_req = bms_union(joinrel->relids, required_outer);

1695 if (outer_path->param_info)

1696 outer_and_req = bms_union(outer_path->parent->relids,

1698 else

1699 outer_and_req = NULL;

1700 if (inner_path->param_info)

1701 inner_and_req = bms_union(inner_path->parent->relids,

1703 else

1704 inner_and_req = NULL;

1705

1706 pclauses = NIL;

1707 foreach(lc, joinrel->joininfo)

1708 {

1710

1713 join_and_req) &&

1715 outer_path->parent->relids,

1716 outer_and_req) &&

1718 inner_path->parent->relids,

1719 inner_and_req))

1720 pclauses = lappend(pclauses, rinfo);

1721 }

1722

1723

1725 join_and_req,

1726 required_outer,

1727 joinrel,

1728 NULL);

1729

1730 dropped_ecs = NIL;

1731 foreach(lc, eclauses)

1732 {

1734

1737 join_and_req));

1739 outer_path->parent->relids,

1740 outer_and_req))

1741 continue;

1743 inner_path->parent->relids,

1744 inner_and_req))

1745 {

1746

1747 Assert(rinfo->left_ec == rinfo->right_ec);

1748 dropped_ecs = lappend(dropped_ecs, rinfo->left_ec);

1749 continue;

1750 }

1751 pclauses = lappend(pclauses, rinfo);

1752 }

1753

1754

1755

1756

1757

1758

1759

1760

1761

1762

1763

1764

1765

1766

1767

1768

1769

1770

1771

1772

1773

1774

1775

1776

1777

1778

1779

1780

1781

1782

1783

1784 if (dropped_ecs)

1785 {

1786 Relids real_outer_and_req;

1787

1788 real_outer_and_req = bms_union(outer_path->parent->relids,

1789 required_outer);

1790 eclauses =

1792 dropped_ecs,

1793 real_outer_and_req,

1794 required_outer,

1795 outer_path->parent);

1796 foreach(lc, eclauses)

1797 {

1799

1801 outer_path->parent->relids,

1802 real_outer_and_req));

1804 outer_path->parent->relids,

1805 outer_and_req))

1806 pclauses = lappend(pclauses, rinfo);

1807 }

1808 }

1809

1810

1811

1812

1813

1814

1815 *restrict_clauses = list_concat(pclauses, *restrict_clauses);

1816

1817

1819 return ppi;

1820

1821

1823 outer_path,

1824 inner_path,

1825 sjinfo,

1826 *restrict_clauses);

1827

1828

1829

1830

1831

1832

1833

1834

1841

1842 return ppi;

1843}

1844

1845

1846

1847

1848

1849

1850

1851

1852

1853

1854

1857{

1859

1860

1862

1863

1865 return NULL;

1866

1868

1869

1871 return ppi;

1872

1873

1880

1881 return ppi;

1882}

1883

1884

1885

1886

1887

1890{

1892

1893 foreach(lc, rel->ppilist)

1894 {

1896

1898 return ppi;

1899 }

1900

1901 return NULL;

1902}

1903

1904

1905

1906

1907

1908

1911{

1912 if (path->param_info == NULL)

1913 return NULL;

1914

1915

1916

1917

1918

1920

1924 {

1925

1926

1927

1928

1929

1930

1931

1932

1936

1937 pserials = NULL;

1943 {

1945

1947 }

1948 return pserials;

1949 }

1951 {

1952

1953

1954

1955

1959

1960 pserials = NULL;

1961 foreach(lc, apath->subpaths)

1962 {

1965

1968 pserials = bms_copy(subserials);

1969 else

1971 }

1972 return pserials;

1973 }

1974 else

1975 {

1976

1977

1978

1979

1980 return path->param_info->ppi_serials;

1981 }

1982}

1983

1984

1985

1986

1987

1988

1989

1990static void

1994 List *restrictlist)

1995{

1997

1998

2000 {

2002 return;

2003 }

2004

2005

2006

2007

2008

2009

2010

2011

2012

2013

2014

2015

2016 if (outer_rel->part_scheme == NULL || inner_rel->part_scheme == NULL ||

2019 outer_rel->part_scheme != inner_rel->part_scheme ||

2021 sjinfo->jointype, restrictlist))

2022 {

2024 return;

2025 }

2026

2027 part_scheme = outer_rel->part_scheme;

2028

2029

2030

2031

2032

2033 Assert(!joinrel->part_scheme && !joinrel->partexprs &&

2034 !joinrel->nullable_partexprs && !joinrel->part_rels &&

2035 !joinrel->boundinfo);

2036

2037

2038

2039

2040

2041

2042

2043

2044 joinrel->part_scheme = part_scheme;

2047

2048

2049

2050

2054}

2055

2056

2057

2058

2059

2060

2061

2062

2063static bool

2067{

2070 int num_equal_pks;

2072

2073

2074

2075

2076

2077 Assert(rel1->part_scheme == rel2->part_scheme);

2078 Assert(part_scheme);

2079

2080

2081 memset(pk_known_equal, 0, sizeof(pk_known_equal));

2082

2083 num_equal_pks = 0;

2084

2085

2086 foreach(lc, restrictlist)

2087 {

2090 Expr *expr1;

2091 Expr *expr2;

2092 bool strict_op;

2093 int ipk1;

2094 int ipk2;

2095

2096

2099 continue;

2100

2101

2102 if (!rinfo->can_join)

2103 continue;

2104

2105

2106 if (!rinfo->mergeopfamilies && OidIsValid(rinfo->hashjoinoperator))

2107 continue;

2108

2109

2111

2112

2115 {

2118 }

2121 {

2124 }

2125 else

2126 continue;

2127

2128

2129

2130

2131

2133

2134

2135

2136

2137

2138

2139

2140 if (strict_op)

2141 {

2144 root->outer_join_rels,

2145 NULL);

2148 root->outer_join_rels,

2149 NULL);

2150 }

2151

2152

2153

2154

2155

2157 if (ipk1 < 0)

2158 continue;

2160 if (ipk2 < 0)

2161 continue;

2162

2163

2164

2165

2166

2167 if (ipk1 != ipk2)

2168 continue;

2169

2170

2171 if (pk_known_equal[ipk1])

2172 continue;

2173

2174

2175 if (rel1->part_scheme->partcollation[ipk1] != opexpr->inputcollid)

2176 return false;

2177

2178

2179

2180

2181

2183 {

2184 if (OidIsValid(rinfo->hashjoinoperator) ||

2187 continue;

2188 }

2191 continue;

2192

2193

2194 pk_known_equal[ipk1] = true;

2195

2196

2197 if (++num_equal_pks == part_scheme->partnatts)

2198 return true;

2199 }

2200

2201

2202

2203

2204

2205

2206

2207

2208 for (int ipk = 0; ipk < part_scheme->partnatts; ipk++)

2209 {

2210 Oid btree_opfamily;

2211

2212

2213 if (pk_known_equal[ipk])

2214 continue;

2215

2216

2217

2218

2219

2220

2221

2222

2224 {

2225 Oid eq_op;

2226 List *eq_opfamilies;

2227

2233 break;

2235 if (eq_opfamilies == NIL)

2236 break;

2237 btree_opfamily = linitial_oid(eq_opfamilies);

2238 }

2239 else

2240 btree_opfamily = part_scheme->partopfamily[ipk];

2241

2242

2243

2244

2245

2246

2247 foreach(lc, rel1->partexprs[ipk])

2248 {

2251 Oid partcoll1 = rel1->part_scheme->partcollation[ipk];

2253

2254 foreach(lc2, rel2->partexprs[ipk])

2255 {

2257

2259 {

2260

2261

2262

2263

2264

2265

2266

2267

2268

2269 if (partcoll1 == exprcoll1)

2270 {

2272 rel2->part_scheme->partcollation[ipk];

2275

2276 Assert(partcoll2 == exprcoll2);

2277 pk_known_equal[ipk] = true;

2278 break;

2279 }

2280 }

2281 }

2282 if (pk_known_equal[ipk])

2283 break;

2284 }

2285

2286 if (pk_known_equal[ipk])

2287 {

2288

2289 if (++num_equal_pks == part_scheme->partnatts)

2290 return true;

2291 }

2292 else

2293 break;

2294 }

2295

2296 return false;

2297}

2298

2299

2300

2301

2302

2303

2304

2305

2306

2307

2308

2309

2310static int

2312{

2313 int cnt;

2314

2315

2316 Assert(rel->part_scheme);

2317 Assert(rel->partexprs);

2318 Assert(rel->nullable_partexprs);

2319

2320

2323

2324 for (cnt = 0; cnt < rel->part_scheme->partnatts; cnt++)

2325 {

2327

2328

2329 foreach(lc, rel->partexprs[cnt])

2330 {

2332 return cnt;

2333 }

2334

2335 if (!strict_op)

2336 continue;

2337

2338

2339

2340

2341

2342

2343

2344

2345 foreach(lc, rel->nullable_partexprs[cnt])

2346 {

2348 return cnt;

2349 }

2350 }

2351

2352 return -1;

2353}

2354

2355

2356

2357

2358

2359static void

2363{

2365 int partnatts = part_scheme->partnatts;

2366

2367 joinrel->partexprs = (List **) palloc0(sizeof(List *) * partnatts);

2368 joinrel->nullable_partexprs =

2370

2371

2372

2373

2374

2375

2376

2377 for (int cnt = 0; cnt < partnatts; cnt++)

2378 {

2379

2380 const List *outer_expr = outer_rel->partexprs[cnt];

2381 const List *outer_null_expr = outer_rel->nullable_partexprs[cnt];

2382 const List *inner_expr = inner_rel->partexprs[cnt];

2383 const List *inner_null_expr = inner_rel->nullable_partexprs[cnt];

2385 List *nullable_partexpr = NIL;

2387

2388 switch (jointype)

2389 {

2390

2391

2392

2393

2394

2395

2396

2397

2398

2402 inner_null_expr);

2403 break;

2404

2405

2406

2407

2408

2409

2410

2411

2414 partexpr = list_copy(outer_expr);

2415 nullable_partexpr = list_copy(outer_null_expr);

2416 break;

2417

2418

2419

2420

2421

2422

2423

2424

2426 partexpr = list_copy(outer_expr);

2428 outer_null_expr);

2429 nullable_partexpr = list_concat(nullable_partexpr,

2430 inner_null_expr);

2431 break;

2432

2433

2434

2435

2436

2437

2438

2441 inner_expr);

2442 nullable_partexpr = list_concat(nullable_partexpr,

2443 outer_null_expr);

2444 nullable_partexpr = list_concat(nullable_partexpr,

2445 inner_null_expr);

2446

2447

2448

2449

2450

2451

2452

2453

2454

2455

2456

2457

2458

2459

2460

2461

2462

2463

2464

2465

2466

2467

2468

2469

2470

2472 {

2475

2477 {

2480

2481 c->coalescetype = exprType(larg);

2484 c->location = -1;

2485 nullable_partexpr = lappend(nullable_partexpr, c);

2486 }

2487 }

2488 break;

2489

2490 default:

2491 elog(ERROR, "unrecognized join type: %d", (int) jointype);

2492 }

2493

2494 joinrel->partexprs[cnt] = partexpr;

2495 joinrel->nullable_partexprs[cnt] = nullable_partexpr;

2496 }

2497}

2498

2499

2500

2501

2502

2503static void

2507 int nappinfos,

2509{

2510

2514 nappinfos, appinfos);

2515

2516

2520}

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

Relids adjust_child_relids(Relids relids, int nappinfos, AppendRelInfo **appinfos)

Bitmapset * bms_make_singleton(int x)

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

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

uint32 bitmap_hash(const void *key, Size keysize)

bool bms_equal(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)

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)

int bitmap_match(const void *key1, const void *key2, Size keysize)

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

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

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

Bitmapset * bms_copy(const Bitmapset *a)

#define PG_USED_FOR_ASSERTS_ONLY

#define OidIsValid(objectId)

bool is_parallel_safe(PlannerInfo *root, Node *node)

double get_parameterized_baserel_size(PlannerInfo *root, RelOptInfo *rel, List *param_clauses)

double get_parameterized_joinrel_size(PlannerInfo *root, RelOptInfo *rel, Path *outer_path, Path *inner_path, SpecialJoinInfo *sjinfo, List *restrict_clauses)

void set_joinrel_size_estimates(PlannerInfo *root, RelOptInfo *rel, RelOptInfo *outer_rel, RelOptInfo *inner_rel, SpecialJoinInfo *sjinfo, List *restrictlist)

bool enable_partitionwise_join

int32 clamp_width_est(int64 tuple_width)

void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)

HTAB * hash_create(const char *tabname, long nelem, const HASHCTL *info, int flags)

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

bool exprs_known_equal(PlannerInfo *root, Node *item1, Node *item2, Oid opfamily)

List * generate_join_implied_equalities_for_ecs(PlannerInfo *root, List *eclasses, Relids join_relids, Relids outer_relids, RelOptInfo *inner_rel)

void add_child_join_rel_equivalences(PlannerInfo *root, int nappinfos, AppendRelInfo **appinfos, RelOptInfo *parent_joinrel, RelOptInfo *child_joinrel)

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

bool has_relevant_eclass_joinclause(PlannerInfo *root, RelOptInfo *rel1)

#define palloc0_array(type, count)

Assert(PointerIsAligned(start, uint64))

bool apply_child_basequals(PlannerInfo *root, RelOptInfo *parentrel, RelOptInfo *childrel, RangeTblEntry *childRTE, AppendRelInfo *appinfo)

void mark_dummy_rel(RelOptInfo *rel)

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

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

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

List * list_copy(const List *oldlist)

bool list_member_oid(const List *list, Oid datum)

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

Oid get_opfamily_member(Oid opfamily, Oid lefttype, Oid righttype, int16 strategy)

List * get_mergejoin_opfamilies(Oid opno)

bool op_in_opfamily(Oid opno, Oid opfamily)

Datum subpath(PG_FUNCTION_ARGS)

void * palloc0(Size size)

MemoryContext CurrentMemoryContext

Oid exprType(const Node *expr)

Oid exprCollation(const Node *expr)

#define IsA(nodeptr, _type_)

#define IS_OUTER_JOIN(jointype)

#define castNode(_type_, nodeptr)

#define repalloc0_array(pointer, type, oldcount, count)

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

@ PARTITION_STRATEGY_HASH

bool has_useful_pathkeys(PlannerInfo *root, RelOptInfo *rel)

#define RINFO_IS_PUSHED_DOWN(rinfo, joinrelids)

#define IS_PARTITIONED_REL(rel)

#define PATH_REQ_OUTER(path)

@ RELOPT_OTHER_MEMBER_REL

#define IS_OTHER_REL(rel)

#define PARTITION_MAX_KEYS

#define lfirst_node(type, lc)

static int list_length(const List *l)

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

static ListCell * list_head(const List *l)

#define list_make2(x1, x2)

PlaceHolderInfo * find_placeholder_info(PlannerInfo *root, PlaceHolderVar *phv)

void add_placeholders_to_joinrel(PlannerInfo *root, RelOptInfo *joinrel, RelOptInfo *outer_rel, RelOptInfo *inner_rel, SpecialJoinInfo *sjinfo)

void get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, RelOptInfo *rel)

static void build_joinrel_partition_info(PlannerInfo *root, RelOptInfo *joinrel, RelOptInfo *outer_rel, RelOptInfo *inner_rel, SpecialJoinInfo *sjinfo, List *restrictlist)

RelOptInfo * find_base_rel(PlannerInfo *root, int relid)

void setup_simple_rel_arrays(PlannerInfo *root)

static void set_joinrel_partition_key_exprs(RelOptInfo *joinrel, RelOptInfo *outer_rel, RelOptInfo *inner_rel, JoinType jointype)

ParamPathInfo * get_appendrel_parampathinfo(RelOptInfo *appendrel, Relids required_outer)

static void build_joinrel_tlist(PlannerInfo *root, RelOptInfo *joinrel, RelOptInfo *input_rel, SpecialJoinInfo *sjinfo, List *pushed_down_joins, bool can_null)

RelOptInfo * build_child_join_rel(PlannerInfo *root, RelOptInfo *outer_rel, RelOptInfo *inner_rel, RelOptInfo *parent_joinrel, List *restrictlist, SpecialJoinInfo *sjinfo, int nappinfos, AppendRelInfo **appinfos)

static bool have_partkey_equi_join(PlannerInfo *root, RelOptInfo *joinrel, RelOptInfo *rel1, RelOptInfo *rel2, JoinType jointype, List *restrictlist)

RelOptInfo * find_base_rel_noerr(PlannerInfo *root, int relid)

Relids min_join_parameterization(PlannerInfo *root, Relids joinrelids, RelOptInfo *outer_rel, RelOptInfo *inner_rel)

RelOptInfo * find_join_rel(PlannerInfo *root, Relids relids)

static void build_join_rel_hash(PlannerInfo *root)

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

Relids find_childrel_parents(PlannerInfo *root, RelOptInfo *rel)

void expand_planner_arrays(PlannerInfo *root, int add_size)

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

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

RelOptInfo * build_join_rel(PlannerInfo *root, Relids joinrelids, RelOptInfo *outer_rel, RelOptInfo *inner_rel, SpecialJoinInfo *sjinfo, List *pushed_down_joins, List **restrictlist_ptr)

static void build_child_join_reltarget(PlannerInfo *root, RelOptInfo *parentrel, RelOptInfo *childrel, int nappinfos, AppendRelInfo **appinfos)

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

static List * build_joinrel_restrictlist(PlannerInfo *root, RelOptInfo *joinrel, RelOptInfo *outer_rel, RelOptInfo *inner_rel, SpecialJoinInfo *sjinfo)

static int match_expr_to_partition_keys(Expr *expr, RelOptInfo *rel, bool strict_op)

ParamPathInfo * find_param_path_info(RelOptInfo *rel, Relids required_outer)

static void set_foreign_rel_properties(RelOptInfo *joinrel, RelOptInfo *outer_rel, RelOptInfo *inner_rel)

struct JoinHashEntry JoinHashEntry

static void build_joinrel_joinlist(RelOptInfo *joinrel, RelOptInfo *outer_rel, RelOptInfo *inner_rel)

Bitmapset * get_param_path_clause_serials(Path *path)

static void add_join_rel(PlannerInfo *root, RelOptInfo *joinrel)

RelOptInfo * find_base_rel_ignore_join(PlannerInfo *root, int relid)

static List * subbuild_joinrel_joinlist(RelOptInfo *joinrel, List *joininfo_list, List *new_joininfo)

static List * subbuild_joinrel_restrictlist(PlannerInfo *root, RelOptInfo *joinrel, RelOptInfo *input_rel, Relids both_input_relids, List *new_restrictlist)

bool join_clause_is_movable_into(RestrictInfo *rinfo, Relids currentrelids, Relids current_and_outer)

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

Size add_size(Size s1, Size s2)

#define HTEqualStrategyNumber

bool consider_param_startup

Bitmapset * notnullattnums

struct PathTarget * reltarget

List * cheapest_parameterized_paths

struct Path * cheapest_unique_path

Relids lateral_referencers

struct Path * cheapest_startup_path

QualCost baserestrictcost

struct Path * cheapest_total_path

List * non_unique_for_rels

Bitmapset * eclass_indexes

Relids direct_lateral_relids

bool consider_partitionwise_join

Index baserestrict_min_security

Relids incompatible_relids

PathTarget * create_empty_pathtarget(void)