PostgreSQL Source Code: src/backend/executor/execPartition.c Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

15

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

93{

104};

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

145{

154

155

160 int partidx);

166 int partidx,

167 bool is_borrowed_rel);

176 bool *isnull);

178 bool *isnull);

181 bool *isnull,

182 int maxfieldlen);

189 List *pruning_steps,

196 Bitmapset *initially_valid_subplans,

197 int n_total_subplans);

200 bool initial_prune,

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

220{

222

223

224

225

226

227

228

229

233

234

235

236

237

238

239

241 NULL, 0, NULL);

242

243 return proute;

244}

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

270{

283

284

286

287

288

289

290

293

294

295 dispatch = pd[0];

296 while (dispatch != NULL)

297 {

298 int partidx = -1;

299 bool is_leaf;

300

302

304 partdesc = dispatch->partdesc;

305

306

307

308

309

310

311

312

313

316

317

318

319

320

321 if (partdesc->nparts == 0 ||

323 {

324 char *val_desc;

325

330 (errcode(ERRCODE_CHECK_VIOLATION),

331 errmsg("no partition of relation \"%s\" found for row",

333 val_desc ?

334 errdetail("Partition key of the failing row contains %s.",

335 val_desc) : 0,

337 }

338

339 is_leaf = partdesc->is_leaf[partidx];

340 if (is_leaf)

341 {

342

343

344

345

347 {

348

351 }

352 else

353 {

354

355

356

357

358

360 partdesc->oids[partidx],

361 true, false);

362 if (rri)

363 {

364

366

367

368

369

370

372 rri, partidx, true);

373 }

374 else

375 {

376

378 dispatch,

379 rootResultRelInfo, partidx);

380 }

381 }

383

384

385 dispatch = NULL;

386 }

387 else

388 {

389

390

391

393 {

394

396

398

399

400

401

402

403 dispatch = pd[dispatch->indexes[partidx]];

404 }

405 else

406 {

407

409

410

411

412

413

415 proute,

416 partdesc->oids[partidx],

417 dispatch, partidx,

421

423 dispatch = subdispatch;

424 }

425

426

427

428

429

431 {

434

435 myslot = dispatch->tupslot;

437

438 if (tempslot != NULL)

440 }

441 }

442

443

444

445

446

447

448

449

450

452 {

453

454

455

456

457

458

459

460

461

462

463

464

465 if (is_leaf)

466 {

468

469 if (map)

472 else

473 slot = rootslot;

474 }

475

477 }

478 }

479

480

481 if (myslot != NULL)

483

486

487 return rri;

488}

489

490

491

492

493

494

495

496

497

503 int partidx)

504{

512 AttrMap *part_attmap = NULL;

513 bool found_whole_row;

514

516

518

521 partrel,

522 0,

523 rootResultRelInfo,

525

526

527

528

529

530

532

533

534

535

536

537

538

539 if (partrel->rd_rel->relhasindex &&

540 leaf_part_rri->ri_IndexRelationDescs == NULL)

542 (node != NULL &&

544

545

546

547

548

549

550

551

553 {

554 List *wcoList;

557

558

559

560

561

562

572

573

574

575

576

577

578

579

580

581

583

584

585

586

587 part_attmap =

590 false);

591 wcoList = (List *)

593 firstVarno, 0,

594 part_attmap,

596 &found_whole_row);

597

598

599 foreach(ll, wcoList)

600 {

603 &mtstate->ps);

604

605 wcoExprs = lappend(wcoExprs, wcoExpr);

606 }

607

608 leaf_part_rri->ri_WithCheckOptions = wcoList;

609 leaf_part_rri->ri_WithCheckOptionExprs = wcoExprs;

610 }

611

612

613

614

615

616

617

618

620 {

623 List *returningList;

624

625

635

636

637

638

639

640

641

643

644

645

646

647 if (part_attmap == NULL)

648 part_attmap =

651 false);

652 returningList = (List *)

654 firstVarno, 0,

655 part_attmap,

657 &found_whole_row);

658

659

660 leaf_part_rri->ri_returningList = returningList;

661

662

663

664

665

666

667

672 leaf_part_rri->ri_projectReturning =

675 }

676

677

679 leaf_part_rri, partidx, false);

680

681

682

683

685 {

689 List *arbiterIndexes = NIL;

690

691

692

693

694

695

696

698 {

699 List *childIdxs;

700

702

703 foreach(lc, childIdxs)

704 {

706 List *ancestors;

708

711 {

713 arbiterIndexes = lappend_oid(arbiterIndexes, childIdx);

714 }

716 }

717 }

718

719

720

721

722

723

726 elog(ERROR, "invalid arbiter index list");

727 leaf_part_rri->ri_onConflictArbiterIndexes = arbiterIndexes;

728

729

730

731

733 {

736

738

741

742 leaf_part_rri->ri_onConflict = onconfl;

743

744

745

746

747

748

752

753

754

755

756

757

758

759 if (map == NULL)

760 {

761

762

763

764

765

766

767

768

775 }

776 else

777 {

778 List *onconflset;

779 List *onconflcols;

780

781

782

783

784

785

786

787

789 if (part_attmap == NULL)

790 part_attmap =

793 false);

794 onconflset = (List *)

797 part_attmap,

799 &found_whole_row);

800

801 onconflset = (List *)

803 firstVarno, 0,

804 part_attmap,

806 &found_whole_row);

807

808

809

811 leaf_part_rri);

812

813

817

818

821 true,

822 onconflcols,

823 partrelDesc,

824 econtext,

826 &mtstate->ps);

827

828

829

830

831

832

833

835 {

836 List *clause;

837

839 clause = (List *)

842 part_attmap,

844 &found_whole_row);

845

846 clause = (List *)

848 firstVarno, 0,

849 part_attmap,

851 &found_whole_row);

852

855 }

856 }

857 }

858 }

859

860

861

862

863

864

865

866

867

871 leaf_part_rri);

872

873

874

875

876

877

878

879

880

881

883 {

887 Node *joinCondition;

888

889 if (part_attmap == NULL)

890 part_attmap =

893 false);

894

895 if (unlikely(!leaf_part_rri->ri_projectNewInfoValid))

897

898

899 joinCondition =

901 firstVarno, 0,

902 part_attmap,

904 &found_whole_row);

905

906 leaf_part_rri->ri_MergeJoinCondition =

908

909 foreach(lc, firstMergeActionList)

910 {

911

914

915

918

919

920 leaf_part_rri->ri_MergeActions[action->matchKind] =

921 lappend(leaf_part_rri->ri_MergeActions[action->matchKind],

922 action_state);

923

924 switch (action->commandType)

925 {

927

928

929

930

931

932

935 leaf_part_rri->ri_newTupleSlot,

936 &mtstate->ps,

938 break;

940

941

942

943

944

945 if (part_attmap)

946 action->updateColnos =

948 part_attmap);

951 true,

952 action->updateColnos,

954 econtext,

955 leaf_part_rri->ri_newTupleSlot,

956 NULL);

957 break;

960

961 break;

962

963 default:

964 elog(ERROR, "unknown action in MERGE WHEN clause");

965 }

966

967

970 firstVarno, 0,

971 part_attmap,

973 &found_whole_row);

976 }

977 }

979

980 return leaf_part_rri;

981}

982

983

984

985

986

987

988

989static void

995 int partidx,

996 bool is_borrowed_rel)

997{

999 int rri_index;

1000

1002

1003

1004

1005

1006

1007

1008

1009

1011 {

1013

1014

1015

1016

1017

1020 }

1021 else

1023

1024

1025

1026

1027

1031

1032

1033

1034

1035

1036

1037

1038

1044 else

1046

1048

1050

1051

1052

1053

1055

1057

1058

1060 {

1062 {

1068 }

1069 else

1070 {

1078 }

1079 }

1080

1081 proute->partitions[rri_index] = partRelInfo;

1083 dispatch->indexes[partidx] = rri_index;

1084

1086}

1087

1088

1089

1090

1091

1092

1093

1094

1095

1096

1102{

1106 int dispatchidx;

1108

1109

1110

1111

1112

1113

1114

1115

1116

1121

1123

1124

1125

1126

1127

1128

1131 else

1134

1136 partdesc->nparts * sizeof(int));

1141 if (parent_pd != NULL)

1142 {

1144

1145

1146

1147

1148

1149

1150

1151

1152

1153

1155 tupdesc,

1156 false);

1159 }

1160 else

1161 {

1162

1165 }

1166

1167

1168

1169

1170

1171 memset(pd->indexes, -1, sizeof(int) * partdesc->nparts);

1172

1173

1175

1176

1178 {

1180 {

1186 }

1187 else

1188 {

1196 }

1197 }

1199

1200

1201

1202

1203

1204

1205 if (parent_pd)

1206 {

1208

1211 }

1212 else

1214

1215

1216

1217

1218

1219 if (parent_pd)

1220 {

1222 parent_pd->indexes[partidx] = dispatchidx;

1223 }

1224

1226

1227 return pd;

1228}

1229

1230

1231

1232

1233

1234

1235

1236void

1239{

1240 int i;

1241

1242

1243

1244

1245

1246

1247

1248

1250 {

1252

1254

1257 }

1258

1260 {

1262

1263

1267 resultRelInfo);

1268

1269

1270

1271

1272

1274 continue;

1275

1278 }

1279}

1280

1281

1282

1283

1284

1285

1286

1287

1288

1289

1290

1291

1292

1293

1294

1295

1296

1297static void

1302 bool *isnull)

1303{

1305 int i;

1306

1308 {

1309

1310 Assert(estate != NULL &&

1312

1313

1315 }

1316

1319 {

1322 bool isNull;

1323

1324 if (keycol != 0)

1325 {

1326

1327 datum = slot_getattr(slot, keycol, &isNull);

1328 }

1329 else

1330 {

1331

1332 if (partexpr_item == NULL)

1333 elog(ERROR, "wrong number of partition key expressions");

1336 &isNull);

1337 partexpr_item = lnext(pd->keystate, partexpr_item);

1338 }

1340 isnull[i] = isNull;

1341 }

1342

1343 if (partexpr_item != NULL)

1344 elog(ERROR, "wrong number of partition key expressions");

1345}

1346

1347

1348

1349

1350

1351

1352#define PARTITION_CACHED_FIND_THRESHOLD 16

1353

1354

1355

1356

1357

1358

1359

1360

1361

1362

1363

1364

1365

1366

1367

1368

1369

1370

1371

1372

1373

1374

1375

1376

1377

1378

1379

1380

1381

1382

1383

1384

1385

1386

1387

1388

1389

1390

1391

1392

1393

1394static int

1396{

1397 int bound_offset = -1;

1398 int part_index = -1;

1402

1403

1404

1405

1406

1407

1408

1409

1410

1411

1412

1413

1414

1415

1416 switch (key->strategy)

1417 {

1419 {

1421

1422

1424 key->partsupfunc,

1425 key->partcollation,

1427

1428

1429

1430

1431

1432 return boundinfo->indexes[rowHash % boundinfo->nindexes];

1433 }

1434

1436 if (isnull[0])

1437 {

1438

1440 {

1441

1442

1443

1444

1445

1446

1447

1448

1449

1450

1452 }

1453 }

1454 else

1455 {

1457

1459 {

1461 Datum lastDatum = boundinfo->datums[last_datum_offset][0];

1463

1464

1466 key->partcollation[0],

1467 lastDatum,

1469

1470 if (cmpval == 0)

1471 return boundinfo->indexes[last_datum_offset];

1472

1473

1474 }

1475

1477 key->partcollation,

1478 boundinfo,

1480 if (bound_offset >= 0 && equal)

1481 part_index = boundinfo->indexes[bound_offset];

1482 }

1483 break;

1484

1486 {

1487 bool equal = false,

1488 range_partkey_has_null = false;

1489 int i;

1490

1491

1492

1493

1494

1495 for (i = 0; i < key->partnatts; i++)

1496 {

1497 if (isnull[i])

1498 {

1499 range_partkey_has_null = true;

1500 break;

1501 }

1502 }

1503

1504

1505 if (range_partkey_has_null)

1506 break;

1507

1509 {

1511 Datum *lastDatums = boundinfo->datums[last_datum_offset];

1514

1515

1517 key->partcollation,

1518 lastDatums,

1519 kind,

1521 key->partnatts);

1522

1523

1524

1525

1526

1527 if (cmpval == 0)

1528 return boundinfo->indexes[last_datum_offset + 1];

1529

1530 if (cmpval < 0 && last_datum_offset + 1 < boundinfo->ndatums)

1531 {

1532

1533 lastDatums = boundinfo->datums[last_datum_offset + 1];

1534 kind = boundinfo->kind[last_datum_offset + 1];

1536 key->partcollation,

1537 lastDatums,

1538 kind,

1540 key->partnatts);

1541

1542 if (cmpval > 0)

1543 return boundinfo->indexes[last_datum_offset + 1];

1544 }

1545

1546 }

1547

1549 key->partcollation,

1550 boundinfo,

1551 key->partnatts,

1554

1555

1556

1557

1558

1559

1560

1561 part_index = boundinfo->indexes[bound_offset + 1];

1562 }

1563 break;

1564

1565 default:

1566 elog(ERROR, "unexpected partition strategy: %d",

1567 (int) key->strategy);

1568 }

1569

1570

1571

1572

1573

1574 if (part_index < 0)

1575 {

1576

1577

1578

1579

1580

1582 }

1583

1584

1585 Assert(bound_offset >= 0);

1586

1587

1588

1589

1590

1591

1592

1593

1594

1597 else

1598 {

1602 }

1603

1604 return part_index;

1605}

1606

1607

1608

1609

1610

1611

1612

1613

1614static char *

1617 bool *isnull,

1618 int maxfieldlen)

1619{

1623 int i;

1626

1628 return NULL;

1629

1630

1633 {

1634

1635

1636

1637

1638 for (i = 0; i < partnatts; i++)

1639 {

1641

1642

1643

1644

1645

1646

1650 return NULL;

1651 }

1652 }

1653

1657

1658 for (i = 0; i < partnatts; i++)

1659 {

1660 char *val;

1661 int vallen;

1662

1663 if (isnull[i])

1664 val = "null";

1665 else

1666 {

1667 Oid foutoid;

1668 bool typisvarlena;

1669

1671 &foutoid, &typisvarlena);

1673 }

1674

1675 if (i > 0)

1677

1678

1679 vallen = strlen(val);

1680 if (vallen <= maxfieldlen)

1682 else

1683 {

1687 }

1688 }

1689

1691

1692 return buf.data;

1693}

1694

1695

1696

1697

1698

1699

1700

1701

1702static List *

1704{

1706

1707 Assert(map != NULL);

1708

1710}

1711

1712

1713

1714

1715

1716

1717

1718

1719static List *

1721{

1724

1725 Assert(attrMap != NULL);

1726

1727 foreach(lc, colnos)

1728 {

1730

1731 if (parentattrno <= 0 ||

1732 parentattrno > attrMap->maplen ||

1733 attrMap->attnums[parentattrno - 1] == 0)

1734 elog(ERROR, "unexpected attno %d in target column list",

1735 parentattrno);

1737 attrMap->attnums[parentattrno - 1]);

1738 }

1739

1740 return new_colnos;

1741}

1742

1743

1744

1745

1746

1747

1748

1749

1750

1751

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

1785

1786

1787

1788

1789

1790

1791

1792

1793

1794

1795

1796

1797

1798

1799

1800

1801

1802

1803

1804

1805

1806

1807

1808

1809

1810

1811

1812

1813

1814

1815

1816

1817

1818

1819

1820

1821void

1823{

1826 List *locked_relids = NIL;

1827

1829 {

1832 Bitmapset *validsubplans = NULL;

1833 Bitmapset *all_leafpart_rtis = NULL;

1834 Bitmapset *validsubplan_rtis = NULL;

1835

1836

1838 &all_leafpart_rtis);

1840 prunestate);

1841

1842

1843

1844

1845

1848 &validsubplan_rtis);

1849 else

1850 validsubplan_rtis = all_leafpart_rtis;

1851

1853 {

1854 int rtindex = -1;

1855

1857 rtindex)) >= 0)

1858 {

1860

1862 rte->rellockmode != NoLock);

1864 locked_relids = lappend_int(locked_relids, rtindex);

1865 }

1866 }

1868 validsubplan_rtis);

1870 validsubplans);

1871 }

1872

1873

1874

1875

1876

1877

1878

1879

1880

1881

1882

1883

1885 {

1886 foreach(lc, stmt->firstResultRels)

1887 {

1889

1891 {

1893

1896 locked_relids = lappend_int(locked_relids, firstResultRel);

1897 }

1898 }

1899 }

1900

1901

1902

1903

1904

1906 {

1907 foreach(lc, locked_relids)

1908 {

1910

1912 }

1913 }

1914}

1915

1916

1917

1918

1919

1920

1921

1922

1923

1924

1925

1926

1927

1928

1929

1930

1931

1932

1933

1934

1935

1938 int n_total_subplans,

1939 int part_prune_index,

1941 Bitmapset **initially_valid_subplans)

1942{

1946

1947

1949 part_prune_index);

1950

1951

1953 elog(ERROR, "wrong pruneinfo with relids=%s found at part_prune_index=%d contained in plan node with relids=%s",

1956

1957

1958

1959

1960

1961

1963 Assert(prunestate != NULL);

1964

1965

1969 part_prune_index);

1970 else

1971 {

1972

1973 Assert(n_total_subplans > 0);

1974 *initially_valid_subplans = bms_add_range(NULL, 0,

1975 n_total_subplans - 1);

1976 }

1977

1978

1979

1980

1981

1982

1983

1984

1985

1986

1987

1988

1989

1992 *initially_valid_subplans,

1993 n_total_subplans);

1994

1995 return prunestate;

1996}

1997

1998

1999

2000

2001

2002

2003

2004

2005

2006

2007

2008

2009

2010

2011

2012

2013

2014

2015

2016

2017

2018

2019

2020

2021

2022

2023

2024

2025

2026

2027

2028

2029

2033{

2035 int n_part_hierarchies;

2037 int i;

2038

2039

2040

2041

2042

2044

2045

2049

2051 Assert(n_part_hierarchies > 0);

2052

2053

2054

2055

2059

2060

2061 prunestate->econtext = econtext;

2063

2065 prunestate->do_initial_prune = false;

2066 prunestate->do_exec_prune = false;

2068

2069

2070

2071

2072

2073

2074

2077 "Partition Prune",

2079

2080 i = 0;

2082 {

2084 int npartrelpruneinfos = list_length(partrelpruneinfos);

2087 int j;

2088

2094

2095 j = 0;

2096 foreach(lc2, partrelpruneinfos)

2097 {

2103

2104

2105

2106

2107

2108

2109

2111

2112

2113 pprune->partrel = partrel;

2114

2117 partrel);

2118

2119

2120

2121

2122

2123

2124

2125

2126

2127

2128

2129

2130

2131

2132

2133

2134

2135

2136

2139

2141 memcmp(partdesc->oids, pinfo->relid_map,

2142 sizeof(int) * partdesc->nparts) == 0)

2143 {

2144 pprune->subpart_map = pinfo->subpart_map;

2146 memcpy(pprune->subplan_map, pinfo->subplan_map,

2147 sizeof(int) * pinfo->nparts);

2148 }

2149 else

2150 {

2151 int pd_idx = 0;

2152 int pp_idx;

2153

2154

2155

2156

2157

2158

2159

2160

2161

2162

2163

2164

2167

2168 for (pp_idx = 0; pp_idx < partdesc->nparts; pp_idx++)

2169 {

2170

2171 while (pd_idx < pinfo->nparts &&

2172 OidIsValid(pinfo->relid_map[pd_idx]))

2173 pd_idx++;

2174

2175 recheck:

2176 if (pd_idx < pinfo->nparts &&

2177 pinfo->relid_map[pd_idx] == partdesc->oids[pp_idx])

2178 {

2179

2181 pinfo->subplan_map[pd_idx];

2183 pinfo->subpart_map[pd_idx];

2185 pinfo->leafpart_rti_map[pd_idx];

2186 pd_idx++;

2187 continue;

2188 }

2189

2190

2191

2192

2193

2194

2195

2196

2197

2198

2199

2200

2201

2202

2203

2204

2205

2206

2207

2208

2209

2210 for (int pd_idx2 = pd_idx + 1; pd_idx2 < pinfo->nparts; pd_idx2++)

2211 {

2212 if (pd_idx2 >= pinfo->nparts)

2213 break;

2214 if (pinfo->relid_map[pd_idx2] == partdesc->oids[pp_idx])

2215 {

2216 pd_idx = pd_idx2;

2217 goto recheck;

2218 }

2219 }

2220

2224 }

2225 }

2226

2227

2229

2230

2231

2232

2233

2234

2235

2236

2237

2238

2242 {

2245 partdesc, partkey, NULL,

2246 econtext);

2247

2249 }

2253 {

2254

2256 }

2257

2258

2259

2260

2261

2264

2265

2266

2267

2268

2270 {

2271 int part_index = -1;

2272

2274 part_index)) >= 0)

2275 {

2277

2278 if (rtindex)

2279 *all_leafpart_rtis = bms_add_member(*all_leafpart_rtis,

2280 rtindex);

2281 }

2282 }

2283

2284 j++;

2285 }

2286 i++;

2287 }

2288

2289 return prunestate;

2290}

2291

2292

2293

2294

2295static void

2297 List *pruning_steps,

2302{

2303 int n_steps;

2304 int partnatts;

2306

2308

2315

2316

2319

2323

2324

2327 foreach(lc, pruning_steps)

2328 {

2331 int keyno;

2332

2333

2335 continue;

2336

2338

2339 for (keyno = 0; keyno < partnatts; keyno++)

2340 {

2342 continue;

2343

2344 if (lc2 != NULL)

2345 {

2347

2348

2350 {

2353 keyno);

2354

2355

2356

2357

2358

2359

2360

2361

2362 if (planstate == NULL)

2366 else

2369 }

2371 }

2372 }

2373 }

2374}

2375

2376

2377

2378

2379

2380

2381

2382

2383

2384

2385

2386

2387

2388

2389

2390

2391

2392

2393

2394

2395

2396

2397static void

2400 Bitmapset *initially_valid_subplans,

2401 int n_total_subplans)

2402{

2404 int *new_subplan_indexes = NULL;

2406 int i;

2407 int newidx;

2408 bool fix_subplan_map = false;

2409

2411 Assert(parent_plan != NULL);

2412 estate = parent_plan->state;

2413

2414

2415

2416

2417

2418 if (bms_num_members(initially_valid_subplans) < n_total_subplans)

2419 {

2420 fix_subplan_map = true;

2421

2422

2423

2424

2425

2426

2427 new_subplan_indexes = (int *) palloc0(sizeof(int) * n_total_subplans);

2428 newidx = 1;

2429 i = -1;

2431 {

2432 Assert(i < n_total_subplans);

2433 new_subplan_indexes[i] = newidx++;

2434 }

2435 }

2436

2437

2438

2439

2440

2442 {

2444 int j;

2445

2446

2447

2448

2449

2450

2451

2452

2454 {

2456 int nparts = pprune->nparts;

2457 int k;

2458

2459

2461 {

2464

2465

2466

2467

2468

2472

2475 partdesc, partkey, parent_plan,

2477 }

2478

2479 if (!fix_subplan_map)

2480 continue;

2481

2482

2485

2486 for (k = 0; k < nparts; k++)

2487 {

2489 int subidx;

2490

2491

2492

2493

2494

2495

2496

2497

2498

2499 if (oldidx >= 0)

2500 {

2501 Assert(oldidx < n_total_subplans);

2502 pprune->subplan_map[k] = new_subplan_indexes[oldidx] - 1;

2503

2504 if (new_subplan_indexes[oldidx] > 0)

2507 }

2508 else if ((subidx = pprune->subpart_map[k]) >= 0)

2509 {

2511

2513

2517 }

2518 }

2519 }

2520 }

2521

2522

2523

2524

2525

2526 if (fix_subplan_map)

2527 {

2528 new_other_subplans = NULL;

2529 i = -1;

2531 new_other_subplans = bms_add_member(new_other_subplans,

2532 new_subplan_indexes[i] - 1);

2533

2536

2537 pfree(new_subplan_indexes);

2538 }

2539}

2540

2541

2542

2543

2544

2545

2546

2547

2548

2549

2550

2551

2552

2553

2556 bool initial_prune,

2558{

2561 int i;

2562

2563

2564

2565

2566

2567

2569 Assert(validsubplan_rtis != NULL || !initial_prune);

2570

2571

2572

2573

2574

2576

2577

2578

2579

2580

2582 {

2585

2586

2587

2588

2589

2590

2593 &result, validsubplan_rtis);

2594

2595

2596

2597

2598

2599

2602 }

2603

2604

2606

2608

2609

2611 if (validsubplan_rtis)

2612 *validsubplan_rtis = bms_copy(*validsubplan_rtis);

2613

2615

2616 return result;

2617}

2618

2619

2620

2621

2622

2623

2624

2625

2626

2627static void

2630 bool initial_prune,

2633{

2635 int i;

2636

2637

2639

2640

2641

2642

2643

2644

2651 else

2653

2654

2655 i = -1;

2657 {

2659 {

2662

2663

2664

2665

2666

2668 *validsubplan_rtis = bms_add_member(*validsubplan_rtis,

2670 }

2671 else

2672 {

2674

2675 if (partidx >= 0)

2678 initial_prune, validsubplans,

2679 validsubplan_rtis);

2680 else

2681 {

2682

2683

2684

2685

2686

2687

2688

2689 }

2690 }

2691 }

2692}

AclResult pg_attribute_aclcheck(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mode)

AclResult pg_class_aclcheck(Oid table_oid, Oid roleid, AclMode mode)

AttrMap * build_attrmap_by_name(TupleDesc indesc, TupleDesc outdesc, bool missing_ok)

AttrMap * build_attrmap_by_name_if_req(TupleDesc indesc, TupleDesc outdesc, bool missing_ok)

#define InvalidAttrNumber

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

int bms_next_member(const Bitmapset *a, int prevbit)

Bitmapset * bms_add_range(Bitmapset *a, int lower, int upper)

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_copy(const Bitmapset *a)

static Datum values[MAXATTR]

#define FLEXIBLE_ARRAY_MEMBER

#define OidIsValid(objectId)

int errdetail(const char *fmt,...)

int errcode(int sqlerrcode)

int errmsg(const char *fmt,...)

#define ereport(elevel,...)

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

ExprState * ExecInitExpr(Expr *node, PlanState *parent)

ProjectionInfo * ExecBuildProjectionInfo(List *targetList, ExprContext *econtext, TupleTableSlot *slot, PlanState *parent, TupleDesc inputDesc)

ExprState * ExecInitQual(List *qual, PlanState *parent)

ExprState * ExecInitExprWithParams(Expr *node, ParamListInfo ext_params)

ProjectionInfo * ExecBuildUpdateProjection(List *targetList, bool evalTargetList, List *targetColnos, TupleDesc relDesc, ExprContext *econtext, TupleTableSlot *slot, PlanState *parent)

List * ExecPrepareExprList(List *nodes, EState *estate)

void ExecCloseIndices(ResultRelInfo *resultRelInfo)

void ExecOpenIndices(ResultRelInfo *resultRelInfo, bool speculative)

void CheckValidResultRel(ResultRelInfo *resultRelInfo, CmdType operation, List *mergeActions)

bool ExecPartitionCheck(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate, bool emitError)

void InitResultRelInfo(ResultRelInfo *resultRelInfo, Relation resultRelationDesc, Index resultRelationIndex, ResultRelInfo *partition_root_rri, int instrument_options)

static void InitExecPartitionPruneContexts(PartitionPruneState *prunestate, PlanState *parent_plan, Bitmapset *initially_valid_subplans, int n_total_subplans)

static PartitionDispatch ExecInitPartitionDispatchInfo(EState *estate, PartitionTupleRouting *proute, Oid partoid, PartitionDispatch parent_pd, int partidx, ResultRelInfo *rootResultRelInfo)

void ExecDoInitialPruning(EState *estate)

static ResultRelInfo * ExecInitPartitionInfo(ModifyTableState *mtstate, EState *estate, PartitionTupleRouting *proute, PartitionDispatch dispatch, ResultRelInfo *rootResultRelInfo, int partidx)

PartitionPruneState * ExecInitPartitionExecPruning(PlanState *planstate, int n_total_subplans, int part_prune_index, Bitmapset *relids, Bitmapset **initially_valid_subplans)

Bitmapset * ExecFindMatchingSubPlans(PartitionPruneState *prunestate, bool initial_prune, Bitmapset **validsubplan_rtis)

static void ExecInitRoutingInfo(ModifyTableState *mtstate, EState *estate, PartitionTupleRouting *proute, PartitionDispatch dispatch, ResultRelInfo *partRelInfo, int partidx, bool is_borrowed_rel)

static char * ExecBuildSlotPartitionKeyDescription(Relation rel, Datum *values, bool *isnull, int maxfieldlen)

static void FormPartitionKeyDatum(PartitionDispatch pd, TupleTableSlot *slot, EState *estate, Datum *values, bool *isnull)

#define PARTITION_CACHED_FIND_THRESHOLD

PartitionTupleRouting * ExecSetupPartitionTupleRouting(EState *estate, Relation rel)

static List * adjust_partition_colnos(List *colnos, ResultRelInfo *leaf_part_rri)

static List * adjust_partition_colnos_using_map(List *colnos, AttrMap *attrMap)

ResultRelInfo * ExecFindPartition(ModifyTableState *mtstate, ResultRelInfo *rootResultRelInfo, PartitionTupleRouting *proute, TupleTableSlot *slot, EState *estate)

static void InitPartitionPruneContext(PartitionPruneContext *context, List *pruning_steps, PartitionDesc partdesc, PartitionKey partkey, PlanState *planstate, ExprContext *econtext)

struct PartitionDispatchData PartitionDispatchData

static int get_partition_for_tuple(PartitionDispatch pd, Datum *values, bool *isnull)

static void find_matching_subplans_recurse(PartitionPruningData *prunedata, PartitionedRelPruningData *pprune, bool initial_prune, Bitmapset **validsubplans, Bitmapset **validsubplan_rtis)

static PartitionPruneState * CreatePartitionPruneState(EState *estate, PartitionPruneInfo *pruneinfo, Bitmapset **all_leafpart_rtis)

void ExecCleanupTupleRouting(ModifyTableState *mtstate, PartitionTupleRouting *proute)

struct PartitionDispatchData * PartitionDispatch

struct PartitionedRelPruningData PartitionedRelPruningData

TupleTableSlot * MakeSingleTupleTableSlot(TupleDesc tupdesc, const TupleTableSlotOps *tts_ops)

const TupleTableSlotOps TTSOpsVirtual

void ExecDropSingleTupleTableSlot(TupleTableSlot *slot)

Relation ExecGetRangeTableRelation(EState *estate, Index rti, bool isResultRel)

TupleConversionMap * ExecGetRootToChildMap(ResultRelInfo *resultRelInfo, EState *estate)

ExprContext * CreateExprContext(EState *estate)

TupleConversionMap * ExecGetChildToRootMap(ResultRelInfo *resultRelInfo)

#define GetPerTupleExprContext(estate)

static bool ExecShouldLockRelations(EState *estate)

#define EXEC_FLAG_EXPLAIN_GENERIC

static RangeTblEntry * exec_rt_fetch(Index rti, EState *estate)

#define ResetExprContext(econtext)

#define GetPerTupleMemoryContext(estate)

static bool ExecPlanStillValid(EState *estate)

static Datum ExecEvalExprSwitchContext(ExprState *state, ExprContext *econtext, bool *isNull)

Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)

char * OidOutputFunctionCall(Oid functionId, Datum val)

Assert(PointerIsAligned(start, uint64))

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

List * lappend_int(List *list, int datum)

List * lappend_oid(List *list, Oid datum)

void list_free(List *list)

bool list_member_oid(const List *list, Oid datum)

void UnlockRelationOid(Oid relid, LOCKMODE lockmode)

void LockRelationOid(Oid relid, LOCKMODE lockmode)

void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)

int pg_mbcliplen(const char *mbstr, int len, int limit)

void MemoryContextReset(MemoryContext context)

void * repalloc(void *pointer, Size size)

void pfree(void *pointer)

void * palloc0(Size size)

MemoryContext CurrentMemoryContext

#define AllocSetContextCreate

#define ALLOCSET_DEFAULT_SIZES

#define CHECK_FOR_INTERRUPTS()

ResultRelInfo * ExecLookupResultRelByOid(ModifyTableState *node, Oid resultoid, bool missing_ok, bool update_cache)

void ExecInitMergeTupleSlots(ModifyTableState *mtstate, ResultRelInfo *resultRelInfo)

#define IsA(nodeptr, _type_)

#define castNode(_type_, nodeptr)

char * bmsToString(const Bitmapset *bms)

static MemoryContext MemoryContextSwitchTo(MemoryContext context)

@ PARTITION_STRATEGY_HASH

@ PARTITION_STRATEGY_LIST

@ PARTITION_STRATEGY_RANGE

int32 partition_rbound_datum_cmp(FmgrInfo *partsupfunc, Oid *partcollation, Datum *rb_datums, PartitionRangeDatumKind *rb_kind, Datum *tuple_datums, int n_tuple_datums)

uint64 compute_partition_hash_value(int partnatts, FmgrInfo *partsupfunc, const Oid *partcollation, const Datum *values, const bool *isnull)

int partition_range_datum_bsearch(FmgrInfo *partsupfunc, Oid *partcollation, PartitionBoundInfo boundinfo, int nvalues, Datum *values, bool *is_equal)

int partition_list_bsearch(FmgrInfo *partsupfunc, Oid *partcollation, PartitionBoundInfo boundinfo, Datum value, bool *is_equal)

#define partition_bound_accepts_nulls(bi)

PartitionKey RelationGetPartitionKey(Relation rel)

static int16 get_partition_col_attnum(PartitionKey key, int col)

static int get_partition_natts(PartitionKey key)

static Oid get_partition_col_typid(PartitionKey key, int col)

PartitionDirectory CreatePartitionDirectory(MemoryContext mcxt, bool omit_detached)

PartitionDesc PartitionDirectoryLookup(PartitionDirectory pdir, Relation rel)

List * get_partition_ancestors(Oid relid)

Bitmapset * get_matching_partitions(PartitionPruneContext *context, List *pruning_steps)

#define PruneCxtStateIdx(partnatts, step_id, keyno)

#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_nth_node(type, list, n)

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

static int32 DatumGetInt32(Datum X)

#define RelationGetForm(relation)

#define RelationGetRelid(relation)

#define RelationGetDescr(relation)

#define RelationGetRelationName(relation)

List * RelationGetIndexList(Relation relation)

int errtable(Relation rel)

Node * map_variable_attnos(Node *node, int target_varno, int sublevels_up, const AttrMap *attno_map, Oid to_rowtype, bool *found_whole_row)

int check_enable_rls(Oid relid, Oid checkAsUser, bool noError)

char * pg_get_partkeydef_columns(Oid relid, bool pretty)

void check_stack_depth(void)

void appendStringInfo(StringInfo str, const char *fmt,...)

void appendBinaryStringInfo(StringInfo str, const void *data, int datalen)

void appendStringInfoString(StringInfo str, const char *s)

void appendStringInfoChar(StringInfo str, char ch)

void initStringInfo(StringInfo str)

List * es_part_prune_infos

List * es_tuple_routing_result_relations

PlannedStmt * es_plannedstmt

Bitmapset * es_unpruned_relids

List * es_part_prune_states

MemoryContext es_query_cxt

PartitionDirectory es_partition_directory

List * es_part_prune_results

ParamListInfo ecxt_param_list_info

TupleTableSlot * ecxt_scantuple

struct EState * ecxt_estate

EndForeignInsert_function EndForeignInsert

BeginForeignInsert_function BeginForeignInsert

ExecForeignBatchInsert_function ExecForeignBatchInsert

GetForeignModifyBatchSize_function GetForeignModifyBatchSize

ProjectionInfo * mas_proj

ResultRelInfo * resultRelInfo

ResultRelInfo * rootResultRelInfo

List * mergeJoinConditions

List * withCheckOptionLists

OnConflictAction onConflictAction

TupleTableSlot * oc_ProjSlot

TupleTableSlot * oc_Existing

ExprState * oc_WhereClause

ProjectionInfo * oc_ProjInfo

PartitionRangeDatumKind ** kind

int last_found_datum_index

PartitionBoundInfo boundinfo

int last_found_part_index

int indexes[FLEXIBLE_ARRAY_MEMBER]

PartitionStrategy strategy

ExprContext * exprcontext

PartitionBoundInfo boundinfo

Bitmapset * other_subplans

PartitionPruningData * partprunedata[FLEXIBLE_ARRAY_MEMBER]

Bitmapset * other_subplans

MemoryContext prune_context

PartitionedRelPruningData partrelprunedata[FLEXIBLE_ARRAY_MEMBER]

PartitionDispatch * partition_dispatch_info

ResultRelInfo ** partitions

ResultRelInfo ** nonleaf_partitions

Bitmapset * present_parts

List * initial_pruning_steps

List * exec_pruning_steps

List * exec_pruning_steps

PartitionPruneContext exec_context

PartitionPruneContext initial_context

Bitmapset * present_parts

List * initial_pruning_steps

ExprContext * ps_ExprContext

TupleTableSlot * ps_ResultTupleSlot

TupleTableSlot * ri_PartitionTupleSlot

OnConflictSetState * ri_onConflict

List * ri_onConflictArbiterIndexes

struct CopyMultiInsertBuffer * ri_CopyMultiInsertBuffer

struct FdwRoutine * ri_FdwRoutine

void table_close(Relation relation, LOCKMODE lockmode)

Relation table_open(Oid relationId, LOCKMODE lockmode)

TupleTableSlot * table_slot_create(Relation relation, List **reglist)

TupleTableSlot * execute_attr_map_slot(AttrMap *attrMap, TupleTableSlot *in_slot, TupleTableSlot *out_slot)

static Datum slot_getattr(TupleTableSlot *slot, int attnum, bool *isnull)

static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)

#define IsolationUsesXactSnapshot()