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

34

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

92{

103};

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

144{

153

154

159 int partidx);

165 int partidx,

166 bool is_borrowed_rel);

175 bool *isnull);

177 bool *isnull);

180 bool *isnull,

181 int maxfieldlen);

188 List *pruning_steps,

195 Bitmapset *initially_valid_subplans,

196 int n_total_subplans);

199 bool initial_prune,

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

219{

221

222

223

224

225

226

227

228

232

233

234

235

236

237

238

240 NULL, 0, NULL);

241

242 return proute;

243}

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

269{

282

283

285

286

287

288

289

292

293

294 dispatch = pd[0];

295 while (dispatch != NULL)

296 {

297 int partidx = -1;

298 bool is_leaf;

299

301

303 partdesc = dispatch->partdesc;

304

305

306

307

308

309

310

311

312

315

316

317

318

319

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

322 {

323 char *val_desc;

324

329 (errcode(ERRCODE_CHECK_VIOLATION),

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

332 val_desc ?

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

334 val_desc) : 0,

336 }

337

338 is_leaf = partdesc->is_leaf[partidx];

339 if (is_leaf)

340 {

341

342

343

344

346 {

347

350 }

351 else

352 {

353

354

355

356

357

359 partdesc->oids[partidx],

360 true, false);

361 if (rri)

362 {

363

365

366

367

368

369

371 rri, partidx, true);

372 }

373 else

374 {

375

377 dispatch,

378 rootResultRelInfo, partidx);

379 }

380 }

382

383

384 dispatch = NULL;

385 }

386 else

387 {

388

389

390

392 {

393

395

397

398

399

400

401

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

403 }

404 else

405 {

406

408

409

410

411

412

414 proute,

415 partdesc->oids[partidx],

416 dispatch, partidx,

420

422 dispatch = subdispatch;

423 }

424

425

426

427

428

430 {

433

434 myslot = dispatch->tupslot;

436

437 if (tempslot != NULL)

439 }

440 }

441

442

443

444

445

446

447

448

449

451 {

452

453

454

455

456

457

458

459

460

461

462

463

464 if (is_leaf)

465 {

467

468 if (map)

471 else

472 slot = rootslot;

473 }

474

476 }

477 }

478

479

480 if (myslot != NULL)

482

485

486 return rri;

487}

488

489

490

491

492

493

494

495

496

502 int partidx)

503{

511 AttrMap *part_attmap = NULL;

512 bool found_whole_row;

513

515

517

520 partrel,

521 0,

522 rootResultRelInfo,

524

525

526

527

528

529

531

532

533

534

535

536

537

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

539 leaf_part_rri->ri_IndexRelationDescs == NULL)

541 (node != NULL &&

543

544

545

546

547

548

549

550

552 {

553 List *wcoList;

556

557

558

559

560

561

571

572

573

574

575

576

577

578

579

580

582

583

584

585

586 part_attmap =

589 false);

590 wcoList = (List *)

592 firstVarno, 0,

593 part_attmap,

595 &found_whole_row);

596

597

598 foreach(ll, wcoList)

599 {

602 &mtstate->ps);

603

604 wcoExprs = lappend(wcoExprs, wcoExpr);

605 }

606

607 leaf_part_rri->ri_WithCheckOptions = wcoList;

608 leaf_part_rri->ri_WithCheckOptionExprs = wcoExprs;

609 }

610

611

612

613

614

615

616

617

619 {

622 List *returningList;

623

624

634

635

636

637

638

639

640

642

643

644

645

646 if (part_attmap == NULL)

647 part_attmap =

650 false);

651 returningList = (List *)

653 firstVarno, 0,

654 part_attmap,

656 &found_whole_row);

657

658

659 leaf_part_rri->ri_returningList = returningList;

660

661

662

663

664

665

666

671 leaf_part_rri->ri_projectReturning =

674 }

675

676

678 leaf_part_rri, partidx, false);

679

680

681

682

684 {

688 List *arbiterIndexes = NIL;

689

690

691

692

693

694

695

697 {

698 List *childIdxs;

699

701

702 foreach(lc, childIdxs)

703 {

705 List *ancestors;

707

710 {

712 arbiterIndexes = lappend_oid(arbiterIndexes, childIdx);

713 }

715 }

716 }

717

718

719

720

721

722

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

726 leaf_part_rri->ri_onConflictArbiterIndexes = arbiterIndexes;

727

728

729

730

732 {

735

737

740

741 leaf_part_rri->ri_onConflict = onconfl;

742

743

744

745

746

747

751

752

753

754

755

756

757

758 if (map == NULL)

759 {

760

761

762

763

764

765

766

767

774 }

775 else

776 {

777 List *onconflset;

778 List *onconflcols;

779

780

781

782

783

784

785

786

788 if (part_attmap == NULL)

789 part_attmap =

792 false);

793 onconflset = (List *)

796 part_attmap,

798 &found_whole_row);

799

800 onconflset = (List *)

802 firstVarno, 0,

803 part_attmap,

805 &found_whole_row);

806

807

808

810 leaf_part_rri);

811

812

816

817

820 true,

821 onconflcols,

822 partrelDesc,

823 econtext,

825 &mtstate->ps);

826

827

828

829

830

831

832

834 {

835 List *clause;

836

838 clause = (List *)

841 part_attmap,

843 &found_whole_row);

844

845 clause = (List *)

847 firstVarno, 0,

848 part_attmap,

850 &found_whole_row);

851

854 }

855 }

856 }

857 }

858

859

860

861

862

863

864

865

866

870 leaf_part_rri);

871

872

873

874

875

876

877

878

879

880

882 {

886 Node *joinCondition;

887

888 if (part_attmap == NULL)

889 part_attmap =

892 false);

893

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

896

897

898 joinCondition =

900 firstVarno, 0,

901 part_attmap,

903 &found_whole_row);

904

905 leaf_part_rri->ri_MergeJoinCondition =

907

908 foreach(lc, firstMergeActionList)

909 {

910

913

914

917

918

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

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

921 action_state);

922

923 switch (action->commandType)

924 {

926

927

928

929

930

931

934 leaf_part_rri->ri_newTupleSlot,

935 &mtstate->ps,

937 break;

939

940

941

942

943

944 if (part_attmap)

945 action->updateColnos =

947 part_attmap);

950 true,

951 action->updateColnos,

953 econtext,

954 leaf_part_rri->ri_newTupleSlot,

955 NULL);

956 break;

959

960 break;

961

962 default:

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

964 }

965

966

969 firstVarno, 0,

970 part_attmap,

972 &found_whole_row);

975 }

976 }

978

979 return leaf_part_rri;

980}

981

982

983

984

985

986

987

988static void

994 int partidx,

995 bool is_borrowed_rel)

996{

998 int rri_index;

999

1001

1002

1003

1004

1005

1006

1007

1008

1010 {

1012

1013

1014

1015

1016

1019 }

1020 else

1022

1023

1024

1025

1026

1030

1031

1032

1033

1034

1035

1036

1037

1043 else

1045

1047

1049

1050

1051

1052

1054

1056

1057

1059 {

1061 {

1067 }

1068 else

1069 {

1077 }

1078 }

1079

1080 proute->partitions[rri_index] = partRelInfo;

1082 dispatch->indexes[partidx] = rri_index;

1083

1085}

1086

1087

1088

1089

1090

1091

1092

1093

1094

1095

1101{

1105 int dispatchidx;

1107

1108

1109

1110

1111

1112

1113

1114

1115

1120

1122

1123

1124

1125

1126

1127

1130 else

1133

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

1140 if (parent_pd != NULL)

1141 {

1143

1144

1145

1146

1147

1148

1149

1150

1151

1152

1154 tupdesc,

1155 false);

1158 }

1159 else

1160 {

1161

1164 }

1165

1166

1167

1168

1169

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

1171

1172

1174

1175

1177 {

1179 {

1185 }

1186 else

1187 {

1195 }

1196 }

1198

1199

1200

1201

1202

1203

1204 if (parent_pd)

1205 {

1207

1210 }

1211 else

1213

1214

1215

1216

1217

1218 if (parent_pd)

1219 {

1221 parent_pd->indexes[partidx] = dispatchidx;

1222 }

1223

1225

1226 return pd;

1227}

1228

1229

1230

1231

1232

1233

1234

1235void

1238{

1239 int i;

1240

1241

1242

1243

1244

1245

1246

1247

1249 {

1251

1253

1256 }

1257

1259 {

1261

1262

1266 resultRelInfo);

1267

1268

1269

1270

1271

1273 continue;

1274

1277 }

1278}

1279

1280

1281

1282

1283

1284

1285

1286

1287

1288

1289

1290

1291

1292

1293

1294

1295

1296static void

1301 bool *isnull)

1302{

1304 int i;

1305

1307 {

1308

1309 Assert(estate != NULL &&

1311

1312

1314 }

1315

1318 {

1321 bool isNull;

1322

1323 if (keycol != 0)

1324 {

1325

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

1327 }

1328 else

1329 {

1330

1331 if (partexpr_item == NULL)

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

1335 &isNull);

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

1337 }

1339 isnull[i] = isNull;

1340 }

1341

1342 if (partexpr_item != NULL)

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

1344}

1345

1346

1347

1348

1349

1350

1351#define PARTITION_CACHED_FIND_THRESHOLD 16

1352

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

1393static int

1395{

1396 int bound_offset = -1;

1397 int part_index = -1;

1401

1402

1403

1404

1405

1406

1407

1408

1409

1410

1411

1412

1413

1414

1415 switch (key->strategy)

1416 {

1418 {

1420

1421

1423 key->partsupfunc,

1424 key->partcollation,

1426

1427

1428

1429

1430

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

1432 }

1433

1435 if (isnull[0])

1436 {

1437

1439 {

1440

1441

1442

1443

1444

1445

1446

1447

1448

1449

1451 }

1452 }

1453 else

1454 {

1456

1458 {

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

1462

1463

1465 key->partcollation[0],

1466 lastDatum,

1468

1469 if (cmpval == 0)

1470 return boundinfo->indexes[last_datum_offset];

1471

1472

1473 }

1474

1476 key->partcollation,

1477 boundinfo,

1479 if (bound_offset >= 0 && equal)

1480 part_index = boundinfo->indexes[bound_offset];

1481 }

1482 break;

1483

1485 {

1486 bool equal = false,

1487 range_partkey_has_null = false;

1488 int i;

1489

1490

1491

1492

1493

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

1495 {

1496 if (isnull[i])

1497 {

1498 range_partkey_has_null = true;

1499 break;

1500 }

1501 }

1502

1503

1504 if (range_partkey_has_null)

1505 break;

1506

1508 {

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

1513

1514

1516 key->partcollation,

1517 lastDatums,

1518 kind,

1520 key->partnatts);

1521

1522

1523

1524

1525

1526 if (cmpval == 0)

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

1528

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

1530 {

1531

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

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

1535 key->partcollation,

1536 lastDatums,

1537 kind,

1539 key->partnatts);

1540

1541 if (cmpval > 0)

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

1543 }

1544

1545 }

1546

1548 key->partcollation,

1549 boundinfo,

1550 key->partnatts,

1553

1554

1555

1556

1557

1558

1559

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

1561 }

1562 break;

1563

1564 default:

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

1566 (int) key->strategy);

1567 }

1568

1569

1570

1571

1572

1573 if (part_index < 0)

1574 {

1575

1576

1577

1578

1579

1581 }

1582

1583

1584 Assert(bound_offset >= 0);

1585

1586

1587

1588

1589

1590

1591

1592

1593

1596 else

1597 {

1601 }

1602

1603 return part_index;

1604}

1605

1606

1607

1608

1609

1610

1611

1612

1613static char *

1616 bool *isnull,

1617 int maxfieldlen)

1618{

1622 int i;

1625

1627 return NULL;

1628

1629

1632 {

1633

1634

1635

1636

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

1638 {

1640

1641

1642

1643

1644

1645

1649 return NULL;

1650 }

1651 }

1652

1656

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

1658 {

1659 char *val;

1660 int vallen;

1661

1662 if (isnull[i])

1663 val = "null";

1664 else

1665 {

1666 Oid foutoid;

1667 bool typisvarlena;

1668

1670 &foutoid, &typisvarlena);

1672 }

1673

1674 if (i > 0)

1676

1677

1678 vallen = strlen(val);

1679 if (vallen <= maxfieldlen)

1681 else

1682 {

1686 }

1687 }

1688

1690

1691 return buf.data;

1692}

1693

1694

1695

1696

1697

1698

1699

1700

1701static List *

1703{

1705

1706 Assert(map != NULL);

1707

1709}

1710

1711

1712

1713

1714

1715

1716

1717

1718static List *

1720{

1723

1724 Assert(attrMap != NULL);

1725

1726 foreach(lc, colnos)

1727 {

1729

1730 if (parentattrno <= 0 ||

1731 parentattrno > attrMap->maplen ||

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

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

1734 parentattrno);

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

1737 }

1738

1739 return new_colnos;

1740}

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

1818void

1820{

1822

1824 {

1827 Bitmapset *validsubplans = NULL;

1828 Bitmapset *all_leafpart_rtis = NULL;

1829 Bitmapset *validsubplan_rtis = NULL;

1830

1831

1833 &all_leafpart_rtis);

1835 prunestate);

1836

1837

1838

1839

1840

1843 &validsubplan_rtis);

1844 else

1845 validsubplan_rtis = all_leafpart_rtis;

1846

1848 validsubplan_rtis);

1850 validsubplans);

1851 }

1852}

1853

1854

1855

1856

1857

1858

1859

1860

1861

1862

1863

1864

1865

1866

1867

1868

1869

1870

1871

1872

1873

1876 int n_total_subplans,

1877 int part_prune_index,

1879 Bitmapset **initially_valid_subplans)

1880{

1884

1885

1887 part_prune_index);

1888

1889

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

1894

1895

1896

1897

1898

1899

1901 Assert(prunestate != NULL);

1902

1903

1907 part_prune_index);

1908 else

1909 {

1910

1911 Assert(n_total_subplans > 0);

1912 *initially_valid_subplans = bms_add_range(NULL, 0,

1913 n_total_subplans - 1);

1914 }

1915

1916

1917

1918

1919

1920

1921

1922

1923

1924

1925

1926

1927

1930 *initially_valid_subplans,

1931 n_total_subplans);

1932

1933 return prunestate;

1934}

1935

1936

1937

1938

1939

1940

1941

1942

1943

1944

1945

1946

1947

1948

1949

1950

1951

1952

1953

1954

1955

1956

1957

1958

1959

1960

1961

1962

1963

1964

1965

1966

1967

1971{

1973 int n_part_hierarchies;

1975 int i;

1976

1977

1978

1979

1980

1982

1983

1987

1989 Assert(n_part_hierarchies > 0);

1990

1991

1992

1993

1997

1998

1999 prunestate->econtext = econtext;

2001

2003 prunestate->do_initial_prune = false;

2004 prunestate->do_exec_prune = false;

2006

2007

2008

2009

2010

2011

2012

2015 "Partition Prune",

2017

2018 i = 0;

2020 {

2022 int npartrelpruneinfos = list_length(partrelpruneinfos);

2025 int j;

2026

2032

2033 j = 0;

2034 foreach(lc2, partrelpruneinfos)

2035 {

2041

2042

2043

2044

2045

2046

2047

2049

2050

2051 pprune->partrel = partrel;

2052

2055 partrel);

2056

2057

2058

2059

2060

2061

2062

2063

2064

2065

2066

2067

2068

2069

2070

2071

2072

2073

2074

2077

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

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

2081 {

2082 pprune->subpart_map = pinfo->subpart_map;

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

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

2086 }

2087 else

2088 {

2089 int pd_idx = 0;

2090 int pp_idx;

2091

2092

2093

2094

2095

2096

2097

2098

2099

2100

2101

2102

2105

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

2107 {

2108

2109 while (pd_idx < pinfo->nparts &&

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

2111 pd_idx++;

2112

2113 recheck:

2114 if (pd_idx < pinfo->nparts &&

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

2116 {

2117

2119 pinfo->subplan_map[pd_idx];

2121 pinfo->subpart_map[pd_idx];

2123 pinfo->leafpart_rti_map[pd_idx];

2124 pd_idx++;

2125 continue;

2126 }

2127

2128

2129

2130

2131

2132

2133

2134

2135

2136

2137

2138

2139

2140

2141

2142

2143

2144

2145

2146

2147

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

2149 {

2150 if (pd_idx2 >= pinfo->nparts)

2151 break;

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

2153 {

2154 pd_idx = pd_idx2;

2155 goto recheck;

2156 }

2157 }

2158

2162 }

2163 }

2164

2165

2167

2168

2169

2170

2171

2172

2173

2174

2175

2176

2180 {

2183 partdesc, partkey, NULL,

2184 econtext);

2185

2187 }

2191 {

2192

2194 }

2195

2196

2197

2198

2199

2202

2203

2204

2205

2206

2208 {

2209 int part_index = -1;

2210

2212 part_index)) >= 0)

2213 {

2215

2216 if (rtindex)

2217 *all_leafpart_rtis = bms_add_member(*all_leafpart_rtis,

2218 rtindex);

2219 }

2220 }

2221

2222 j++;

2223 }

2224 i++;

2225 }

2226

2227 return prunestate;

2228}

2229

2230

2231

2232

2233static void

2235 List *pruning_steps,

2240{

2241 int n_steps;

2242 int partnatts;

2244

2246

2253

2254

2257

2261

2262

2265 foreach(lc, pruning_steps)

2266 {

2269 int keyno;

2270

2271

2273 continue;

2274

2276

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

2278 {

2280 continue;

2281

2282 if (lc2 != NULL)

2283 {

2285

2286

2288 {

2291 keyno);

2292

2293

2294

2295

2296

2297

2298

2299

2300 if (planstate == NULL)

2304 else

2307 }

2309 }

2310 }

2311 }

2312}

2313

2314

2315

2316

2317

2318

2319

2320

2321

2322

2323

2324

2325

2326

2327

2328

2329

2330

2331

2332

2333

2334

2335static void

2338 Bitmapset *initially_valid_subplans,

2339 int n_total_subplans)

2340{

2342 int *new_subplan_indexes = NULL;

2344 int i;

2345 int newidx;

2346 bool fix_subplan_map = false;

2347

2349 Assert(parent_plan != NULL);

2350 estate = parent_plan->state;

2351

2352

2353

2354

2355

2356 if (bms_num_members(initially_valid_subplans) < n_total_subplans)

2357 {

2358 fix_subplan_map = true;

2359

2360

2361

2362

2363

2364

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

2366 newidx = 1;

2367 i = -1;

2369 {

2370 Assert(i < n_total_subplans);

2371 new_subplan_indexes[i] = newidx++;

2372 }

2373 }

2374

2375

2376

2377

2378

2380 {

2382 int j;

2383

2384

2385

2386

2387

2388

2389

2390

2392 {

2394 int nparts = pprune->nparts;

2395 int k;

2396

2397

2399 {

2402

2403

2404

2405

2406

2410

2413 partdesc, partkey, parent_plan,

2415 }

2416

2417 if (!fix_subplan_map)

2418 continue;

2419

2420

2423

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

2425 {

2427 int subidx;

2428

2429

2430

2431

2432

2433

2434

2435

2436

2437 if (oldidx >= 0)

2438 {

2439 Assert(oldidx < n_total_subplans);

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

2441

2442 if (new_subplan_indexes[oldidx] > 0)

2445 }

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

2447 {

2449

2451

2455 }

2456 }

2457 }

2458 }

2459

2460

2461

2462

2463

2464 if (fix_subplan_map)

2465 {

2466 new_other_subplans = NULL;

2467 i = -1;

2469 new_other_subplans = bms_add_member(new_other_subplans,

2470 new_subplan_indexes[i] - 1);

2471

2474

2475 pfree(new_subplan_indexes);

2476 }

2477}

2478

2479

2480

2481

2482

2483

2484

2485

2486

2487

2488

2489

2490

2491

2494 bool initial_prune,

2496{

2499 int i;

2500

2501

2502

2503

2504

2505

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

2508

2509

2510

2511

2512

2514

2515

2516

2517

2518

2520 {

2523

2524

2525

2526

2527

2528

2531 &result, validsubplan_rtis);

2532

2533

2534

2535

2536

2537

2540 }

2541

2542

2544

2546

2547

2549 if (validsubplan_rtis)

2550 *validsubplan_rtis = bms_copy(*validsubplan_rtis);

2551

2553

2554 return result;

2555}

2556

2557

2558

2559

2560

2561

2562

2563

2564

2565static void

2568 bool initial_prune,

2571{

2573 int i;

2574

2575

2577

2578

2579

2580

2581

2582

2589 else

2591

2592

2593 i = -1;

2595 {

2597 {

2600

2601

2602

2603

2604

2606 *validsubplan_rtis = bms_add_member(*validsubplan_rtis,

2608 }

2609 else

2610 {

2612

2613 if (partidx >= 0)

2616 initial_prune, validsubplans,

2617 validsubplan_rtis);

2618 else

2619 {

2620

2621

2622

2623

2624

2625

2626

2627 }

2628 }

2629 }

2630}

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)

#define EXEC_FLAG_EXPLAIN_GENERIC

#define ResetExprContext(econtext)

#define GetPerTupleMemoryContext(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 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

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