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