PostgreSQL Source Code: src/backend/executor/execMain.c Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
39
65
66
67
72
73
75
76
83 bool sendTuples,
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122void
124{
125
126
127
128
129
130
131
132
134
136 (*ExecutorStart_hook) (queryDesc, eflags);
137 else
139}
140
141void
143{
146
147
148 Assert(queryDesc != NULL);
150
151
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
172
173
174
175
177 queryDesc->estate = estate;
178
180
181
182
183
184
186
188 {
189 int nParamExec;
190
194 }
195
196
199
200
201
202
204
205
206
207
209 {
211
212
213
214
215
219
220
221
222
223
224
225
228 break;
229
235 break;
236
237 default:
238 elog(ERROR, "unrecognized operation code: %d",
240 break;
241 }
242
243
244
245
251
252
253
254
255
258
259
260
261
263
265}
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297void
300{
302 (*ExecutorRun_hook) (queryDesc, direction, count);
303 else
305}
306
307void
310{
314 bool sendTuples;
316
317
318 Assert(queryDesc != NULL);
319
320 estate = queryDesc->estate;
321
322 Assert(estate != NULL);
324
325
327
328
329
330
332
333
336
337
338
339
340 operation = queryDesc->operation;
342
343
344
345
347
348 sendTuples = (operation == CMD_SELECT ||
350
351 if (sendTuples)
353
354
355
356
357
358
359
360
361
362
363
364
365
368 operation,
369 sendTuples,
370 count,
371 direction,
373
374
375
376
377
379
380
381
382
383 if (sendTuples)
385
388
390}
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406void
408{
410 (*ExecutorFinish_hook) (queryDesc);
411 else
413}
414
415void
417{
420
421
422 Assert(queryDesc != NULL);
423
424 estate = queryDesc->estate;
425
426 Assert(estate != NULL);
428
429
431
432
434
435
438
439
441
442
445
448
450
452}
453
454
455
456
457
458
459
460
461
462
463
464
465
466void
468{
470 (*ExecutorEnd_hook) (queryDesc);
471 else
473}
474
475void
477{
480
481
482 Assert(queryDesc != NULL);
483
484 estate = queryDesc->estate;
485
486 Assert(estate != NULL);
487
491
492
493
494
495
496
499
500
501
502
504
506
507
510
511
512
513
515
516
517
518
519
521
522
523 queryDesc->tupDesc = NULL;
524 queryDesc->estate = NULL;
527}
528
529
530
531
532
533
534
535
536void
538{
541
542
543 Assert(queryDesc != NULL);
544
545 estate = queryDesc->estate;
546
547 Assert(estate != NULL);
548
549
551
552
553
554
556
557
558
559
561
563}
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582bool
584 bool ereport_on_violation)
585{
587 bool result = true;
588
589#ifdef USE_ASSERT_CHECKING
591
592
593 foreach(l, rangeTable)
594 {
596
597 if (rte->perminfoindex != 0)
598 {
599
600
601
602
603
604
607 rte->relkind == RELKIND_VIEW));
608
610
612 indexset = bms_add_member(indexset, rte->perminfoindex);
613 }
614 }
615
616
618#endif
619
620 foreach(l, rteperminfos)
621 {
623
626 if (!result)
627 {
628 if (ereport_on_violation)
632 return false;
633 }
634 }
635
637 result = (*ExecutorCheckPerms_hook) (rangeTable, rteperminfos,
638 ereport_on_violation);
639 return result;
640}
641
642
643
644
645
646static bool
648{
652 Oid userid;
653 Oid relOid = perminfo->relid;
654
656 Assert(requiredPerms != 0);
657
658
659
660
661
662
663
664
665
668
669
670
671
672
673
675 remainingPerms = requiredPerms & ~relPerms;
676 if (remainingPerms != 0)
677 {
678 int col = -1;
679
680
681
682
683
685 return false;
686
687
688
689
690
691
692
693
695 {
696
697
698
699
700
702 {
705 return false;
706 }
707
709 {
710
712
714 {
715
718 return false;
719 }
720 else
721 {
724 return false;
725 }
726 }
727 }
728
729
730
731
732
735 userid,
738 return false;
739
742 userid,
745 return false;
746 }
747 return true;
748}
749
750
751
752
753
754
755static bool
758{
759 int col = -1;
760
761
762
763
764
765
767 {
770 return false;
771 }
772
774 {
775
777
779 {
780
781 elog(ERROR, "whole-row update is not implemented");
782 }
783 else
784 {
787 return false;
788 }
789 }
790 return true;
791}
792
793
794
795
796
797
798
799
800
801
802static void
804{
806
807
808
809
810
811 foreach(l, plannedstmt->permInfos)
812 {
814
816 continue;
817
819 continue;
820
822 }
823
826}
827
828
829
830
831
832
833
834
835
836static void
838{
842 List *rangeTable = plannedstmt->rtable;
847 int i;
848
849
850
851
853
854
855
856
859
862
863
864
865
866
867
868
869
870
871
873
874
875
876
878 {
881 foreach(l, plannedstmt->rowMarks)
882 {
884 Oid relid;
887
888
889
890
891
892
895 continue;
896
897
899
900
902 {
909 break;
911
912 relation = NULL;
913 break;
914 default:
916 relation = NULL;
917 break;
918 }
919
920
921 if (relation)
923
926 erm->relid = relid;
936
939
941 }
942 }
943
944
945
946
948
949
951
952
953
954
955
956
958 i = 1;
959 foreach(l, plannedstmt->subplans)
960 {
963 int sp_eflags;
964
965
966
967
968
969
970 sp_eflags = eflags
974
975 subplanstate = ExecInitNode(subplan, estate, sp_eflags);
976
978 subplanstate);
979
980 i++;
981 }
982
983
984
985
986
987
989
990
991
992
994
995
996
997
998
1000 {
1001 bool junk_filter_needed = false;
1003
1004 foreach(tlist, plan->targetlist)
1005 {
1007
1008 if (tle->resjunk)
1009 {
1010 junk_filter_needed = true;
1011 break;
1012 }
1013 }
1014
1015 if (junk_filter_needed)
1016 {
1019
1022 slot);
1024
1025
1026 tupType = j->jf_cleanTupType;
1027 }
1028 }
1029
1030 queryDesc->tupDesc = tupType;
1031 queryDesc->planstate = planstate;
1032}
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047void
1049 List *mergeActions)
1050{
1053
1054
1057
1058 switch (resultRel->rd_rel->relkind)
1059 {
1060 case RELKIND_RELATION:
1061 case RELKIND_PARTITIONED_TABLE:
1063 break;
1064 case RELKIND_SEQUENCE:
1066 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1067 errmsg("cannot change sequence \"%s\"",
1069 break;
1070 case RELKIND_TOASTVALUE:
1072 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1073 errmsg("cannot change TOAST relation \"%s\"",
1075 break;
1076 case RELKIND_VIEW:
1077
1078
1079
1080
1081
1082
1083
1086 NULL);
1087 break;
1088 case RELKIND_MATVIEW:
1091 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1092 errmsg("cannot change materialized view \"%s\"",
1094 break;
1095 case RELKIND_FOREIGN_TABLE:
1096
1098 switch (operation)
1099 {
1103 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1104 errmsg("cannot insert into foreign table \"%s\"",
1109 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1110 errmsg("foreign table \"%s\" does not allow inserts",
1112 break;
1116 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1117 errmsg("cannot update foreign table \"%s\"",
1122 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1123 errmsg("foreign table \"%s\" does not allow updates",
1125 break;
1129 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1130 errmsg("cannot delete from foreign table \"%s\"",
1135 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
1136 errmsg("foreign table \"%s\" does not allow deletes",
1138 break;
1139 default:
1140 elog(ERROR, "unrecognized CmdType: %d", (int) operation);
1141 break;
1142 }
1143 break;
1144 default:
1146 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1147 errmsg("cannot change relation \"%s\"",
1149 break;
1150 }
1151}
1152
1153
1154
1155
1156
1157
1158
1159static void
1161{
1163
1164 switch (rel->rd_rel->relkind)
1165 {
1166 case RELKIND_RELATION:
1167 case RELKIND_PARTITIONED_TABLE:
1168
1169 break;
1170 case RELKIND_SEQUENCE:
1171
1173 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1174 errmsg("cannot lock rows in sequence \"%s\"",
1176 break;
1177 case RELKIND_TOASTVALUE:
1178
1180 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1181 errmsg("cannot lock rows in TOAST relation \"%s\"",
1183 break;
1184 case RELKIND_VIEW:
1185
1187 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1188 errmsg("cannot lock rows in view \"%s\"",
1190 break;
1191 case RELKIND_MATVIEW:
1192
1195 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1196 errmsg("cannot lock rows in materialized view \"%s\"",
1198 break;
1199 case RELKIND_FOREIGN_TABLE:
1200
1204 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
1205 errmsg("cannot lock rows in foreign table \"%s\"",
1207 break;
1208 default:
1210 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1211 errmsg("cannot lock rows in relation \"%s\"",
1213 break;
1214 }
1215}
1216
1217
1218
1219
1220
1221
1222
1223
1224void
1226 Relation resultRelationDesc,
1227 Index resultRelationIndex,
1229 int instrument_options)
1230{
1232 resultRelInfo->type = T_ResultRelInfo;
1240
1243 {
1245
1250 if (instrument_options)
1252 }
1253 else
1254 {
1258 }
1259 if (resultRelationDesc->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
1261 else
1263
1264
1288
1289
1290
1291
1292
1293
1294
1296
1299
1304}
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1328{
1333
1334
1336 {
1339 return rInfo;
1340 }
1341
1342
1343
1344
1345
1347 {
1350 return rInfo;
1351 }
1352
1353
1355 {
1358 return rInfo;
1359 }
1360
1361
1362
1363
1364
1365
1366
1367
1369
1370
1371
1372
1376 rel,
1377 0,
1378 rootRelInfo,
1383
1384
1385
1386
1387
1388
1389 return rInfo;
1390}
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1403{
1406 Oid rootRelOid;
1407
1408 if (!partRel->rd_rel->relispartition)
1409 elog(ERROR, "cannot find ancestors of a non-partition result relation");
1410 Assert(rootRelInfo != NULL);
1413 {
1416 List *ancResultRels = NIL;
1417
1418 foreach(lc, oids)
1419 {
1423
1424
1425
1426
1427
1428
1429
1430 if (ancOid == rootRelOid)
1431 break;
1432
1433
1434
1435
1436
1439
1440
1443 ancResultRels = lappend(ancResultRels, rInfo);
1444 }
1445 ancResultRels = lappend(ancResultRels, rootRelInfo);
1447 }
1448
1449
1451
1453}
1454
1455
1456
1457
1458
1459
1460
1461static void
1463{
1465
1466
1467
1468
1470
1471
1472
1473
1474
1475
1477 {
1479
1480 for (;;)
1481 {
1483
1484
1486
1488
1490 break;
1491 }
1492 }
1493}
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507static void
1509{
1511
1512
1513
1514
1516
1517
1518
1519
1521 {
1523
1525 }
1526
1527
1528
1529
1530
1531
1532
1534
1535
1536
1537
1538
1541}
1542
1543
1544
1545
1546void
1548{
1550
1551
1552
1553
1554
1555
1556
1557
1559 {
1562
1565 {
1567
1568
1569
1570
1571
1573 continue;
1574
1576 }
1577 }
1578
1579
1581 {
1583
1584
1585
1586
1587
1588
1590
1591
1592
1593
1594
1596
1598 }
1599}
1600
1601
1602
1603
1604
1605
1606void
1608{
1609 int i;
1610
1612 {
1615 }
1616}
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627static void
1630 bool sendTuples,
1631 uint64 numberTuples,
1634{
1637 bool use_parallel_mode;
1639 uint64 current_tuple_count;
1640
1641
1642
1643
1644 current_tuple_count = 0;
1645
1646
1647
1648
1650
1651
1652
1653
1654
1655
1656
1657
1659 use_parallel_mode = false;
1660 else
1663
1665 if (use_parallel_mode)
1667
1668
1669
1670
1671 for (;;)
1672 {
1673
1675
1676
1677
1678
1680
1681
1682
1683
1684
1686 break;
1687
1688
1689
1690
1691
1692
1693
1694
1695
1698
1699
1700
1701
1702
1703 if (sendTuples)
1704 {
1705
1706
1707
1708
1709
1710 if (->receiveSlot(slot, dest))
1711 break;
1712 }
1713
1714
1715
1716
1717
1718
1721
1722
1723
1724
1725
1726
1727 current_tuple_count++;
1728 if (numberTuples && numberTuples == current_tuple_count)
1729 break;
1730 }
1731
1732
1733
1734
1735
1738
1739 if (use_parallel_mode)
1741}
1742
1743
1744
1745
1746
1747
1748
1749static const char *
1752{
1758
1759
1760
1761
1762
1763
1764 if (ncheck != rel->rd_rel->relchecks)
1765 elog(ERROR, "%d pg_constraint record(s) missing for relation \"%s\"",
1767
1768
1769
1770
1771
1772
1774 {
1777 for (int i = 0; i < ncheck; i++)
1778 {
1779 Expr *checkconstr;
1780
1781
1782 if (!check[i].ccenforced)
1783 continue;
1784
1789 }
1791 }
1792
1793
1794
1795
1796
1798
1799
1801
1802
1803 for (int i = 0; i < ncheck; i++)
1804 {
1806
1807
1808
1809
1810
1811
1812 if (checkconstr && (checkconstr, econtext))
1814 }
1815
1816
1817 return NULL;
1818}
1819
1820
1821
1822
1823
1824
1825
1826
1827bool
1829 EState *estate, bool emitError)
1830{
1833
1834
1835
1836
1837
1838
1839
1840
1842 {
1843
1844
1845
1846
1849
1852 }
1853
1854
1855
1856
1857
1859
1860
1862
1863
1864
1865
1866
1868
1869
1870 if ( && emitError)
1872
1874}
1875
1876
1877
1878
1879
1880void
1884{
1885 Oid root_relid;
1887 char *val_desc;
1889
1890
1891
1892
1893
1894
1895
1897 {
1901
1904
1906
1908
1909
1910
1911
1912
1913 if (map != NULL)
1918 }
1919 else
1920 {
1925 }
1926
1928 slot,
1929 tupdesc,
1930 modifiedCols,
1931 64);
1933 (errcode(ERRCODE_CHECK_VIOLATION),
1934 errmsg("new row for relation \"%s\" violates partition constraint",
1936 val_desc ? errdetail("Failing row contains %s.", val_desc) : 0,
1938}
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951void
1954{
1959 List *notnull_virtual_attrs = NIL;
1960
1961 Assert(constr);
1962
1963
1964
1965
1966
1967
1968
1970 {
1972 {
1974
1975 if (att->attnotnull && att->attgenerated == ATTRIBUTE_GENERATED_VIRTUAL)
1976 notnull_virtual_attrs = lappend_int(notnull_virtual_attrs, attnum);
1979 }
1980 }
1981
1982
1983
1984
1985 if (notnull_virtual_attrs)
1986 {
1988
1990 notnull_virtual_attrs);
1993 }
1994
1995
1996
1997
1998 if (rel->rd_rel->relchecks > 0)
1999 {
2000 const char *failed;
2001
2002 if ((failed = ExecRelCheck(resultRelInfo, slot, estate)) != NULL)
2003 {
2004 char *val_desc;
2006
2007
2008
2009
2010
2011
2012
2014 {
2018
2020
2022 tupdesc,
2023 false);
2024
2025
2026
2027
2028
2029 if (map != NULL)
2035 }
2036 else
2040 slot,
2041 tupdesc,
2042 modifiedCols,
2043 64);
2045 (errcode(ERRCODE_CHECK_VIOLATION),
2046 errmsg("new row for relation \"%s\" violates check constraint \"%s\"",
2048 val_desc ? errdetail("Failing row contains %s.", val_desc) : 0,
2050 }
2051 }
2052}
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2067 EState *estate, List *notnull_virtual_attrs)
2068{
2072
2073
2074
2075
2076
2077
2079 {
2083
2085 {
2088
2089
2093 nnulltest->argisrow = false;
2095
2098 }
2100 }
2101
2102
2103
2104
2105
2106
2108
2109
2111
2112
2114 {
2117
2118 Assert(exprstate != NULL);
2119 if ((exprstate, econtext))
2121 }
2122
2123
2125}
2126
2127
2128
2129
2130static void
2133{
2135 char *val_desc;
2141
2143
2144
2145
2146
2147
2148
2149
2151 {
2154
2156
2158 tupdesc,
2159 false);
2160
2161
2162
2163
2164
2165 if (map != NULL)
2171 }
2172 else
2175
2177 slot,
2178 tupdesc,
2179 modifiedCols,
2180 64);
2182 errcode(ERRCODE_NOT_NULL_VIOLATION),
2183 errmsg("null value in column \"%s\" of relation \"%s\" violates not-null constraint",
2186 val_desc ? errdetail("Failing row contains %s.", val_desc) : 0,
2188}
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199void
2202{
2207 *l2;
2208
2209
2210
2211
2212
2214
2215
2217
2218
2221 {
2224
2225
2226
2227
2228
2229 if (wco->kind != kind)
2230 continue;
2231
2232
2233
2234
2235
2236
2237
2238
2239 if ((wcoExpr, econtext))
2240 {
2241 char *val_desc;
2243
2244 switch (wco->kind)
2245 {
2246
2247
2248
2249
2250
2251
2252
2253
2254
2256
2258 {
2262
2264
2266 tupdesc,
2267 false);
2268
2269
2270
2271
2272
2273 if (map != NULL)
2276
2280 }
2281 else
2285 slot,
2286 tupdesc,
2287 modifiedCols,
2288 64);
2289
2291 (errcode(ERRCODE_WITH_CHECK_OPTION_VIOLATION),
2292 errmsg("new row violates check option for view \"%s\"",
2294 val_desc ? errdetail("Failing row contains %s.",
2295 val_desc) : 0));
2296 break;
2299 if (wco->polname != NULL)
2301 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2302 errmsg("new row violates row-level security policy \"%s\" for table \"%s\"",
2304 else
2306 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2307 errmsg("new row violates row-level security policy for table \"%s\"",
2309 break;
2312 if (wco->polname != NULL)
2314 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2315 errmsg("target row violates row-level security policy \"%s\" (USING expression) for table \"%s\"",
2317 else
2319 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2320 errmsg("target row violates row-level security policy (USING expression) for table \"%s\"",
2322 break;
2324 if (wco->polname != NULL)
2326 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2327 errmsg("new row violates row-level security policy \"%s\" (USING expression) for table \"%s\"",
2329 else
2331 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
2332 errmsg("new row violates row-level security policy (USING expression) for table \"%s\"",
2334 break;
2335 default:
2336 elog(ERROR, "unrecognized WCO kind: %u", wco->kind);
2337 break;
2338 }
2339 }
2340 }
2341}
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362char *
2367 int maxfieldlen)
2368{
2371 bool write_comma = false;
2372 bool write_comma_collist = false;
2373 int i;
2375 bool table_perm = false;
2376 bool any_perm = false;
2377
2378
2379
2380
2381
2382
2384 return NULL;
2385
2387
2389
2390
2391
2392
2393
2394
2395
2396
2399 {
2400
2403 }
2404 else
2405 table_perm = any_perm = true;
2406
2407
2409
2410 for (i = 0; i < tupdesc->natts; i++)
2411 {
2412 bool column_perm = false;
2413 char *val;
2414 int vallen;
2416
2417
2418 if (att->attisdropped)
2419 continue;
2420
2421 if (!table_perm)
2422 {
2423
2424
2425
2426
2427
2428
2432 modifiedCols) || aclresult == ACLCHECK_OK)
2433 {
2434 column_perm = any_perm = true;
2435
2436 if (write_comma_collist)
2438 else
2439 write_comma_collist = true;
2440
2442 }
2443 }
2444
2445 if (table_perm || column_perm)
2446 {
2447 if (att->attgenerated == ATTRIBUTE_GENERATED_VIRTUAL)
2448 val = "virtual";
2450 val = "null";
2451 else
2452 {
2453 Oid foutoid;
2454 bool typisvarlena;
2455
2457 &foutoid, &typisvarlena);
2459 }
2460
2461 if (write_comma)
2463 else
2464 write_comma = true;
2465
2466
2467 vallen = strlen(val);
2468 if (vallen <= maxfieldlen)
2470 else
2471 {
2475 }
2476 }
2477 }
2478
2479
2480 if (!any_perm)
2481 return NULL;
2482
2484
2485 if (!table_perm)
2486 {
2489
2490 return collist.data;
2491 }
2492
2493 return buf.data;
2494}
2495
2496
2497
2498
2499
2500
2503{
2506
2507
2508
2509
2510
2511
2515
2518
2520}
2521
2522
2523
2524
2525
2526
2529{
2530 if (rti > 0 && rti <= estate->es_range_table_size &&
2532 {
2534
2535 if (erm)
2536 return erm;
2537 }
2538 if (!missing_ok)
2539 elog(ERROR, "failed to find ExecRowMark for rangetable index %u", rti);
2540 return NULL;
2541}
2542
2543
2544
2545
2546
2547
2548
2549
2552{
2554 char resname[32];
2555
2557
2558
2560 {
2561
2564 resname);
2566 elog(ERROR, "could not find junk %s column", resname);
2567 }
2568 else
2569 {
2570
2571 snprintf(resname, sizeof(resname), "wholerow%u", erm->rowmarkId);
2573 resname);
2575 elog(ERROR, "could not find junk %s column", resname);
2576 }
2577
2578
2579 if (erm->rti != erm->prti)
2580 {
2581 snprintf(resname, sizeof(resname), "tableoid%u", erm->rowmarkId);
2583 resname);
2585 elog(ERROR, "could not find junk %s column", resname);
2586 }
2587
2588 return aerm;
2589}
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2623{
2626
2628
2629
2630
2631
2633
2634
2635
2636
2637
2639 if (testslot != inputslot)
2641
2642
2643
2644
2645
2646
2649
2650
2651
2652
2654
2655
2656
2657
2658
2659
2660
2661
2664
2665
2666
2667
2668
2669
2672
2673 return slot;
2674}
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689void
2691 Plan *subplan, List *auxrowmarks,
2692 int epqParam, List *resultRelations)
2693{
2695
2696
2698 epqstate->epqParam = epqParam;
2700
2701
2702
2703
2704
2705
2706
2707
2711
2712
2713 epqstate->plan = subplan;
2714 epqstate->arowMarks = auxrowmarks;
2715
2716
2723}
2724
2725
2726
2727
2728
2729
2730
2731void
2733{
2734
2736
2737 epqstate->plan = subplan;
2738
2739 epqstate->arowMarks = auxrowmarks;
2740}
2741
2742
2743
2744
2745
2746
2747
2751{
2753
2755 Assert(rti > 0 && rti <= epqstate->parentestate->es_range_table_size);
2757
2758 if (*slot == NULL)
2759 {
2761
2765 }
2766
2767 return *slot;
2768}
2769
2770
2771
2772
2773
2774
2775
2776bool
2778{
2782 bool isNull;
2783
2784 Assert(earm != NULL);
2786
2788
2790 elog(ERROR, "EvalPlanQual doesn't support locking rowmarks");
2791
2792
2793 if (erm->rti != erm->prti)
2794 {
2795 Oid tableoid;
2796
2799 &isNull);
2800
2801 if (isNull)
2802 return false;
2803
2805
2807 if (tableoid != erm->relid)
2808 {
2809
2810 return false;
2811 }
2812 }
2813
2815 {
2817
2818
2821 &isNull);
2822
2823 if (isNull)
2824 return false;
2825
2826
2827 if (erm->relation->rd_rel->relkind == RELKIND_FOREIGN_TABLE)
2828 {
2830 bool updated = false;
2831
2833
2836 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
2837 errmsg("cannot lock rows in foreign table \"%s\"",
2839
2841 erm,
2842 datum,
2843 slot,
2844 &updated);
2846 elog(ERROR, "failed to fetch tuple for EvalPlanQual recheck");
2847
2848
2849
2850
2851
2852
2853 return true;
2854 }
2855 else
2856 {
2857
2861 elog(ERROR, "failed to fetch tuple for EvalPlanQual recheck");
2862 return true;
2863 }
2864 }
2865 else
2866 {
2868
2869
2872 &isNull);
2873
2874 if (isNull)
2875 return false;
2876
2878 return true;
2879 }
2880}
2881
2882
2883
2884
2885
2886
2889{
2892
2896
2897 return slot;
2898}
2899
2900
2901
2902
2903void
2905{
2908
2909 if (recheckestate == NULL)
2910 {
2911
2913 }
2914 else
2915 {
2916
2917
2918
2921
2922
2923
2924
2925
2926
2928 rtsize * sizeof(bool));
2929
2930
2932 {
2933 int i;
2934
2935
2936
2937
2938
2939
2942
2944
2945 while (--i >= 0)
2946 {
2947
2952 }
2953 }
2954
2955
2956
2957
2958
2961 }
2962}
2963
2964
2965
2966
2967
2968
2969
2970static void
2972{
2978
2980
2982
2983
2985
2986
2987
2988
2989
2990
2991
3004
3005
3006
3007
3008
3010
3013
3014
3015
3016
3017
3018
3019
3020
3023 {
3024 int i;
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3046
3047
3051
3052 while (--i >= 0)
3053 {
3054
3059 }
3060 }
3061
3062
3063
3064
3065
3066
3068
3069
3070
3071
3072
3073
3074
3075
3076
3079 {
3082
3083 subplanstate = ExecInitNode(subplan, rcestate, 0);
3085 subplanstate);
3086 }
3087
3088
3089
3090
3091
3092
3096 {
3098
3100 }
3101
3102
3103
3104
3105
3108
3110 {
3112
3113 Assert(rtindex > 0 && rtindex <= rtsize);
3115 }
3116
3118 rtsize * sizeof(bool));
3119
3120
3121
3122
3123
3124
3126
3128}
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141void
3143{
3148
3150
3151
3152
3153
3154
3156 {
3161 }
3162
3163
3164 if (estate == NULL)
3165 return;
3166
3168
3170
3172 {
3174
3176 }
3177
3178
3180
3181
3183
3185
3187
3188
3195}
AclResult pg_attribute_aclcheck_all(Oid table_oid, Oid roleid, AclMode mode, AclMaskHow how)
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
AclResult pg_attribute_aclcheck(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mode)
AclMode pg_class_aclmask(Oid table_oid, Oid roleid, AclMode mask, AclMaskHow how)
AclResult pg_class_aclcheck(Oid table_oid, Oid roleid, AclMode mode)
AttrMap * build_attrmap_by_name_if_req(TupleDesc indesc, TupleDesc outdesc, bool missing_ok)
#define AttributeNumberIsValid(attributeNumber)
#define InvalidAttrNumber
void pgstat_report_query_id(uint64 query_id, bool force)
int bms_next_member(const Bitmapset *a, int prevbit)
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_union(const Bitmapset *a, const Bitmapset *b)
bool bms_overlap(const Bitmapset *a, const Bitmapset *b)
Bitmapset * bms_copy(const Bitmapset *a)
#define MemSet(start, val, len)
#define OidIsValid(objectId)
bool IsInplaceUpdateRelation(Relation relation)
int errdetail(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
void ExecReScan(PlanState *node)
ExprState * ExecPrepareExpr(Expr *node, EState *estate)
bool ExecCheck(ExprState *state, ExprContext *econtext)
ExprState * ExecPrepareCheck(List *qual, EState *estate)
void ExecCloseIndices(ResultRelInfo *resultRelInfo)
TupleTableSlot * ExecFilterJunk(JunkFilter *junkfilter, TupleTableSlot *slot)
AttrNumber ExecFindJunkAttributeInTlist(List *targetlist, const char *attrName)
JunkFilter * ExecInitJunkFilter(List *targetList, TupleTableSlot *slot)
static void EvalPlanQualStart(EPQState *epqstate, Plan *planTree)
static void ReportNotNullViolationError(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate, int attnum)
LockTupleMode ExecUpdateLockMode(EState *estate, ResultRelInfo *relinfo)
ExecRowMark * ExecFindRowMark(EState *estate, Index rti, bool missing_ok)
ExecAuxRowMark * ExecBuildAuxRowMark(ExecRowMark *erm, List *targetlist)
ExecutorEnd_hook_type ExecutorEnd_hook
ResultRelInfo * ExecGetTriggerResultRel(EState *estate, Oid relid, ResultRelInfo *rootRelInfo)
void CheckValidResultRel(ResultRelInfo *resultRelInfo, CmdType operation, List *mergeActions)
TupleTableSlot * EvalPlanQualSlot(EPQState *epqstate, Relation relation, Index rti)
void EvalPlanQualBegin(EPQState *epqstate)
ExecutorFinish_hook_type ExecutorFinish_hook
char * ExecBuildSlotValueDescription(Oid reloid, TupleTableSlot *slot, TupleDesc tupdesc, Bitmapset *modifiedCols, int maxfieldlen)
static bool ExecCheckOneRelPerms(RTEPermissionInfo *perminfo)
bool ExecPartitionCheck(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate, bool emitError)
static void ExecEndPlan(PlanState *planstate, EState *estate)
ExecutorStart_hook_type ExecutorStart_hook
void ExecutorEnd(QueryDesc *queryDesc)
void EvalPlanQualInit(EPQState *epqstate, EState *parentestate, Plan *subplan, List *auxrowmarks, int epqParam, List *resultRelations)
void ExecWithCheckOptions(WCOKind kind, ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate)
ExecutorCheckPerms_hook_type ExecutorCheckPerms_hook
void InitResultRelInfo(ResultRelInfo *resultRelInfo, Relation resultRelationDesc, Index resultRelationIndex, ResultRelInfo *partition_root_rri, int instrument_options)
void standard_ExecutorStart(QueryDesc *queryDesc, int eflags)
void ExecutorFinish(QueryDesc *queryDesc)
static void CheckValidRowMarkRel(Relation rel, RowMarkType markType)
void EvalPlanQualEnd(EPQState *epqstate)
static void ExecCheckXactReadOnly(PlannedStmt *plannedstmt)
void EvalPlanQualSetPlan(EPQState *epqstate, Plan *subplan, List *auxrowmarks)
void ExecutorRewind(QueryDesc *queryDesc)
void ExecutorStart(QueryDesc *queryDesc, int eflags)
AttrNumber ExecRelGenVirtualNotNull(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate, List *notnull_virtual_attrs)
TupleTableSlot * EvalPlanQual(EPQState *epqstate, Relation relation, Index rti, TupleTableSlot *inputslot)
bool EvalPlanQualFetchRowMark(EPQState *epqstate, Index rti, TupleTableSlot *slot)
static bool ExecCheckPermissionsModified(Oid relOid, Oid userid, Bitmapset *modifiedCols, AclMode requiredPerms)
ExecutorRun_hook_type ExecutorRun_hook
static void ExecPostprocessPlan(EState *estate)
static const char * ExecRelCheck(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate)
static void ExecutePlan(QueryDesc *queryDesc, CmdType operation, bool sendTuples, uint64 numberTuples, ScanDirection direction, DestReceiver *dest)
void ExecCloseResultRelations(EState *estate)
void standard_ExecutorRun(QueryDesc *queryDesc, ScanDirection direction, uint64 count)
void standard_ExecutorEnd(QueryDesc *queryDesc)
void ExecCloseRangeTableRelations(EState *estate)
void ExecPartitionCheckEmitError(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate)
void ExecConstraints(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate)
static void InitPlan(QueryDesc *queryDesc, int eflags)
bool ExecCheckPermissions(List *rangeTable, List *rteperminfos, bool ereport_on_violation)
void ExecutorRun(QueryDesc *queryDesc, ScanDirection direction, uint64 count)
List * ExecGetAncestorResultRels(EState *estate, ResultRelInfo *resultRelInfo)
TupleTableSlot * EvalPlanQualNext(EPQState *epqstate)
void standard_ExecutorFinish(QueryDesc *queryDesc)
void ExecDoInitialPruning(EState *estate)
void ExecEndNode(PlanState *node)
PlanState * ExecInitNode(Plan *node, EState *estate, int eflags)
void ExecShutdownNode(PlanState *node)
void CheckCmdReplicaIdentity(Relation rel, CmdType cmd)
void ExecResetTupleTable(List *tupleTable, bool shouldFree)
const TupleTableSlotOps TTSOpsVirtual
TupleTableSlot * ExecInitExtraTupleSlot(EState *estate, TupleDesc tupledesc, const TupleTableSlotOps *tts_ops)
void ExecStoreHeapTupleDatum(Datum data, TupleTableSlot *slot)
TupleTableSlot * MakeTupleTableSlot(TupleDesc tupleDesc, const TupleTableSlotOps *tts_ops)
TupleDesc ExecGetResultType(PlanState *planstate)
Relation ExecGetRangeTableRelation(EState *estate, Index rti, bool isResultRel)
Bitmapset * ExecGetInsertedCols(ResultRelInfo *relinfo, EState *estate)
void ExecInitRangeTable(EState *estate, List *rangeTable, List *permInfos, Bitmapset *unpruned_relids)
Bitmapset * ExecGetUpdatedCols(ResultRelInfo *relinfo, EState *estate)
void FreeExecutorState(EState *estate)
Bitmapset * ExecGetAllUpdatedCols(ResultRelInfo *relinfo, EState *estate)
EState * CreateExecutorState(void)
#define EXEC_FLAG_BACKWARD
#define ResetPerTupleExprContext(estate)
#define GetPerTupleExprContext(estate)
void(* ExecutorFinish_hook_type)(QueryDesc *queryDesc)
static RangeTblEntry * exec_rt_fetch(Index rti, EState *estate)
void(* ExecutorRun_hook_type)(QueryDesc *queryDesc, ScanDirection direction, uint64 count)
void(* ExecutorStart_hook_type)(QueryDesc *queryDesc, int eflags)
static bool ExecQual(ExprState *state, ExprContext *econtext)
bool(* ExecutorCheckPerms_hook_type)(List *rangeTable, List *rtePermInfos, bool ereport_on_violation)
void(* ExecutorEnd_hook_type)(QueryDesc *queryDesc)
static TupleTableSlot * ExecProcNode(PlanState *node)
#define EXEC_FLAG_SKIP_TRIGGERS
#define EXEC_FLAG_EXPLAIN_ONLY
static Datum ExecGetJunkAttribute(TupleTableSlot *slot, AttrNumber attno, bool *isNull)
#define palloc_array(type, count)
#define palloc0_array(type, count)
char * OidOutputFunctionCall(Oid functionId, Datum val)
FdwRoutine * GetFdwRoutineForRelation(Relation relation, bool makecopy)
Assert(PointerIsAligned(start, uint64))
Instrumentation * InstrAlloc(int n, int instrument_options, bool async_mode)
void InstrStartNode(Instrumentation *instr)
void InstrStopNode(Instrumentation *instr, double nTuples)
static void ItemPointerSetInvalid(ItemPointerData *pointer)
List * lappend(List *list, void *datum)
List * lappend_int(List *list, int datum)
@ LockTupleNoKeyExclusive
char * get_rel_name(Oid relid)
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
char get_rel_relkind(Oid relid)
Oid get_rel_namespace(Oid relid)
bool MatViewIncrementalMaintenanceIsEnabled(void)
int pg_mbcliplen(const char *mbstr, int len, int limit)
void * palloc0(Size size)
bool isTempNamespace(Oid namespaceId)
void ExecSetParamPlanMulti(const Bitmapset *params, ExprContext *econtext)
ObjectType get_relkind_objtype(char relkind)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
RTEPermissionInfo * getRTEPermissionInfo(List *rteperminfos, RangeTblEntry *rte)
@ WCO_RLS_MERGE_UPDATE_CHECK
@ WCO_RLS_MERGE_DELETE_CHECK
List * RelationGetPartitionQual(Relation rel)
List * get_partition_ancestors(Oid relid)
FormData_pg_attribute * Form_pg_attribute
#define lfirst_node(type, lc)
static int list_length(const List *l)
#define forboth(cell1, list1, cell2, list2)
#define foreach_current_index(var_or_cell)
#define foreach_int(var, lst)
void pgstat_update_parallel_workers_stats(PgStat_Counter workers_to_launch, PgStat_Counter workers_launched)
#define RowMarkRequiresRowShareLock(marktype)
@ ROW_MARK_NOKEYEXCLUSIVE
static Oid DatumGetObjectId(Datum X)
static Pointer DatumGetPointer(Datum X)
@ MERGE_WHEN_NOT_MATCHED_BY_TARGET
@ MERGE_WHEN_NOT_MATCHED_BY_SOURCE
void * stringToNode(const char *str)
#define RelationGetRelid(relation)
#define RelationGetDescr(relation)
#define RelationGetRelationName(relation)
int errtableconstraint(Relation rel, const char *conname)
int errtablecol(Relation rel, int attnum)
Bitmapset * RelationGetIndexAttrBitmap(Relation relation, IndexAttrBitmapKind attrKind)
int errtable(Relation rel)
bool view_has_instead_trigger(Relation view, CmdType event, List *mergeActionList)
Node * build_generation_expression(Relation rel, int attrno)
void error_view_not_updatable(Relation view, CmdType command, List *mergeActionList, const char *detail)
Node * expand_generated_columns_in_expr(Node *node, Relation rel, int rt_index)
int check_enable_rls(Oid relid, Oid checkAsUser, bool noError)
#define ScanDirectionIsNoMovement(direction)
void UnregisterSnapshot(Snapshot snapshot)
Snapshot RegisterSnapshot(Snapshot snapshot)
Snapshot GetActiveSnapshot(void)
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)
ExecAuxRowMark ** relsubs_rowmark
TupleTableSlot * origslot
TupleTableSlot ** relsubs_slot
PlanState * recheckplanstate
List * es_part_prune_infos
struct ExecRowMark ** es_rowmarks
int es_parallel_workers_to_launch
List * es_tuple_routing_result_relations
PlannedStmt * es_plannedstmt
QueryEnvironment * es_queryEnv
ResultRelInfo ** es_result_relations
ParamExecData * es_param_exec_vals
uint64 es_total_processed
Bitmapset * es_unpruned_relids
ParamListInfo es_param_list_info
MemoryContext es_query_cxt
ScanDirection es_direction
struct EPQState * es_epq_active
List * es_trig_target_relations
List * es_opened_result_relations
bool es_use_parallel_mode
int es_parallel_workers_launched
Index es_range_table_size
const char * es_sourceText
List * es_auxmodifytables
JunkFilter * es_junkFilter
Snapshot es_crosscheck_snapshot
LockClauseStrength strength
LockWaitPolicy waitPolicy
TupleTableSlot * ecxt_scantuple
ExecForeignInsert_function ExecForeignInsert
ExecForeignUpdate_function ExecForeignUpdate
RefetchForeignRow_function RefetchForeignRow
ExecForeignDelete_function ExecForeignDelete
IsForeignRelUpdatable_function IsForeignRelUpdatable
NullTestType nulltesttype
LockClauseStrength strength
LockWaitPolicy waitPolicy
Bitmapset * rewindPlanIDs
Bitmapset * unprunableRelids
PlannedStmt * plannedstmt
struct Instrumentation * totaltime
QueryEnvironment * queryEnv
Snapshot crosscheck_snapshot
TupleConversionMap * ri_RootToChildMap
ExprState ** ri_CheckConstraintExprs
TupleTableSlot * ri_PartitionTupleSlot
bool ri_projectNewInfoValid
OnConflictSetState * ri_onConflict
List * ri_onConflictArbiterIndexes
struct ResultRelInfo * ri_RootResultRelInfo
ExprState * ri_PartitionCheckExpr
Instrumentation * ri_TrigInstrument
ExprState * ri_MergeJoinCondition
RelationPtr ri_IndexRelationDescs
TupleTableSlot * ri_ReturningSlot
List * ri_WithCheckOptions
TupleTableSlot * ri_oldTupleSlot
bool ri_RootToChildMapValid
struct CopyMultiInsertBuffer * ri_CopyMultiInsertBuffer
TriggerDesc * ri_TrigDesc
TupleTableSlot * ri_AllNullSlot
ExprState ** ri_GenVirtualNotNullConstraintExprs
Bitmapset * ri_extraUpdatedCols
ExprState ** ri_GeneratedExprsI
TupleConversionMap * ri_ChildToRootMap
bool ri_ChildToRootMapValid
List * ri_MergeActions[NUM_MERGE_MATCH_KINDS]
List * ri_ancestorResultRels
TupleTableSlot * ri_newTupleSlot
List * ri_WithCheckOptionExprs
ProjectionInfo * ri_projectNew
ProjectionInfo * ri_projectReturning
ExprState ** ri_GeneratedExprsU
struct FdwRoutine * ri_FdwRoutine
ExprState ** ri_TrigWhenExprs
FmgrInfo * ri_TrigFunctions
bool ri_usesFdwDirectModify
IndexInfo ** ri_IndexRelationInfo
TupleTableSlot * ri_TrigNewSlot
TupleTableSlot * ri_TrigOldSlot
#define FirstLowInvalidHeapAttributeNumber
void table_close(Relation relation, LOCKMODE lockmode)
Relation table_open(Oid relationId, LOCKMODE lockmode)
TupleTableSlot * table_slot_create(Relation relation, List **reglist)
static bool table_tuple_fetch_row_version(Relation rel, ItemPointer tid, Snapshot snapshot, TupleTableSlot *slot)
TriggerDesc * CopyTriggerDesc(TriggerDesc *trigdesc)
void AfterTriggerEndQuery(EState *estate)
void AfterTriggerBeginQuery(void)
TupleTableSlot * execute_attr_map_slot(AttrMap *attrMap, TupleTableSlot *in_slot, TupleTableSlot *out_slot)
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
static void slot_getallattrs(TupleTableSlot *slot)
static TupleTableSlot * ExecCopySlot(TupleTableSlot *dstslot, TupleTableSlot *srcslot)
static void ExecMaterializeSlot(TupleTableSlot *slot)
static bool slot_attisnull(TupleTableSlot *slot, int attnum)
void PreventCommandIfReadOnly(const char *cmdname)
void PreventCommandIfParallelMode(const char *cmdname)
static const char * CreateCommandName(Node *parsetree)
void ExitParallelMode(void)
void EnterParallelMode(void)
bool IsInParallelMode(void)
CommandId GetCurrentCommandId(bool used)