PostgreSQL Source Code: src/backend/optimizer/plan/analyzejoins.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
24
36
37
38
39
40
41
42
43
44
45
46
47typedef struct
48{
52
54
55
60 int relid, int ojrelid);
63 int relid, int subst);
67 List *clause_list, List **extra_clauses);
74 List *restrictlist,
75 List **extra_clauses);
79
80
81
82
83
84
85
86
87
88
91{
93
94
95
96
97
98restart:
99 foreach(lc, root->join_info_list)
100 {
102 int innerrelid;
103 int nremoved;
104
105
107 continue;
108
109
110
111
112
113
115
117
118
119 nremoved = 0;
121 if (nremoved != 1)
122 elog(ERROR, "failed to find relation %d in joinlist", innerrelid);
123
124
125
126
127
128
130
131
132
133
134
135
136
137 goto restart;
138 }
139
140 return joinlist;
141}
142
143
144
145
146
147
148
149
150
151
152
153
154static bool
156{
157 int innerrelid;
163 int attroff;
164
165
166
167
168
170 return false;
171
173 return false;
174
175
176
177
178
179
180 if (innerrelid == root->parse->resultRelation)
181 return false;
182
184
185
186
187
188
189
191 return false;
192
193
196 joinrelids = bms_copy(inputrelids);
198
199
200
201
202
203
204
205
206
207
208
209
211 attroff >= 0;
212 attroff--)
213 {
214 if ((innerrel->attr_needed[attroff], inputrelids))
215 return false;
216 }
217
218
219
220
221
222
223
224
225
226
227 foreach(l, root->placeholder_list)
228 {
230
232 return false;
234 continue;
236 continue;
238 return false;
239
240
241
242
243
245 return false;
246
249 return false;
250 }
251
252
253
254
255
256
257
258
259 foreach(l, innerrel->joininfo)
260 {
262
263
264
265
266
267
268
269
270
272 continue;
273
274
275
276
277
278
279
281 continue;
282
283
284 if (!restrictinfo->can_join ||
285 restrictinfo->mergeopfamilies == NIL)
286 continue;
287
288
289
290
291
294 continue;
295
296
297 clause_list = lappend(clause_list, restrictinfo);
298 }
299
300
301
302
303
305 return true;
306
307
308
309
310
311 return false;
312}
313
314
315
316
317
318
319
320
321
322
323
324static void
328{
329 int relid = rel->relid;
332
333
334
335
338
339 if (sjinfo != NULL)
340 {
345 }
346
347
348
349
350
351
352
353
354
355 foreach(l, root->join_info_list)
356 {
358
359
360
361
362
363
364
369
374
375 if (sjinfo != NULL)
376 {
378
379
388
397 }
398 else
399 {
401
404 }
405 }
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426 foreach(l, root->placeholder_list)
427 {
429
431 if (sjinfo != NULL &&
435 {
436
437
438
439
440
442 l);
443 root->placeholder_array[phinfo->phid] = NULL;
444 }
445 else
446 {
448
450 if (sjinfo != NULL)
454
457 else
459
461
462
463
464
465
467
468
470 if (sjinfo != NULL)
474
477
479 }
480 }
481
482
483
484
485 foreach(l, root->eq_classes)
486 {
488
492 }
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508 for (rti = 1; rti < root->simple_rel_array_size; rti++)
509 {
511 int attroff;
512
513
514 if (otherrel == NULL)
515 continue;
516
517 Assert(otherrel->relid == rti);
518
520 attroff >= 0;
521 attroff--)
522 {
523 if (bms_is_member(0, otherrel->attr_needed[attroff]))
525 else
526 otherrel->attr_needed[attroff] = NULL;
527 }
528
529 if (subst > 0)
532 }
533}
534
535
536
537
538
539
540
541
542
543static void
546{
548 int ojrelid = sjinfo->ojrelid;
550 Relids join_plus_commute;
551 List *joininfos;
553
554
556 Assert(ojrelid != 0);
558
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577 join_plus_commute = bms_union(joinrelids,
581
582
583
584
585
586
588 foreach(l, joininfos)
589 {
591
593
595 {
596
597
598
599
600
601
602
604
605
606
607
608
609#ifdef USE_ASSERT_CHECKING
610 {
613
616 }
617#endif
618
620 }
621 }
622
623
624
625
626
627
628
629
630
631
632
633 root->simple_rel_array[relid] = NULL;
634
635
637
638
639
640
641
646}
647
648
649
650
651
652
653
654
655
656static void
658{
659
660
661
662
663
664
665
666 rinfo->clause_relids = bms_copy(rinfo->clause_relids);
667 rinfo->clause_relids = bms_del_member(rinfo->clause_relids, relid);
668 rinfo->clause_relids = bms_del_member(rinfo->clause_relids, ojrelid);
669
673
674
676 {
678
680 foreach(lc, ((BoolExpr *) rinfo->orclause)->args)
681 {
683
684
686 {
689
690 foreach(lc2, andargs)
691 {
693
695 }
696 }
697 else
698 {
700
702 }
703 }
704 }
705}
706
707
708
709
710
711
712
713
714
715
716
717static void
719 int relid, int subst)
720{
722
723
725 if (sjinfo != NULL)
728
729
730
731
732
733
735
736
737
738
739
740
742 {
744
748 {
751 if (sjinfo != NULL)
756 }
757 }
758
759
761 {
763
764 if (sjinfo == NULL)
767 else
769 }
770
771
772
773
774
775
777}
778
779
780
781
782
783
784
785
786
787
790{
793
794 foreach(jl, joinlist)
795 {
797
799 {
800 int varno = ((RangeTblRef *) jlnode)->rtindex;
801
802 if (varno == relid)
803 (*nremoved)++;
804 else
805 result = lappend(result, jlnode);
806 }
807 else if (IsA(jlnode, List))
808 {
809
810 List *sublist;
811
813 relid, nremoved);
814
815 if (sublist)
816 result = lappend(result, sublist);
817 }
818 else
819 {
820 elog(ERROR, "unrecognized joinlist node type: %d",
822 }
823 }
824
825 return result;
826}
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842void
844{
846
847
848
849
850 foreach(lc, root->join_info_list)
851 {
853 int innerrelid;
856 List *restrictlist;
857
858
859
860
861
863 continue;
864
866 continue;
867
869
870
871
872
873
874
876 continue;
877
878
880 Assert(sjinfo->ojrelid == 0);
881
882
883
884
885
886
887 restrictlist =
889 joinrelids,
891 innerrel,
892 NULL),
894
895
899 continue;
900
901
903 }
904}
905
906
907
908
909
910
911
912
913
914
915
916
917
918static bool
920{
921
923 return false;
925 {
926
927
928
929
930
931
932
934
936 {
938
939 if (ind->unique && ind->immediate && ind->indpred == NIL)
940 return true;
941 }
942 }
944 {
945 Query *subquery = root->simple_rte_array[rel->relid]->subquery;
946
947
949 return true;
950 }
951
952 return false;
953}
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978static bool
980 List **extra_clauses)
981{
982
983
984
985
986
988 return false;
990 {
991
992
993
994
995
997 extra_clauses))
998 return true;
999 }
1001 {
1003 Query *subquery = root->simple_rte_array[relid]->subquery;
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017 foreach(l, clause_list)
1018 {
1021 Var *var;
1022
1023
1024
1025
1026
1027
1028
1029
1030
1032
1033
1034 if (rinfo->outer_is_left)
1036 else
1038
1039
1040
1041
1042
1043
1046
1047
1048
1049
1050
1051 if (!var || (var, Var) ||
1053 continue;
1054
1057 }
1058
1060 return true;
1061 }
1062 return false;
1063}
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077bool
1079{
1080
1082 return false;
1083
1084
1088 query->hasAggs ||
1091 return true;
1092
1093 return false;
1094}
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115bool
1117{
1119 Oid opid;
1120
1122
1123
1124
1125
1126
1127
1128
1130 {
1132 {
1136
1140 break;
1141 }
1142 if (l == NULL)
1143 return true;
1144 }
1145
1146
1147
1148
1149
1150
1151
1152
1153 if (query->hasTargetSRFs)
1154 return false;
1155
1156
1157
1158
1159
1161 {
1163 {
1167
1171 break;
1172 }
1173 if (l == NULL)
1174 return true;
1175 }
1177 {
1178
1179
1180
1181
1183 return false;
1184
1185
1186
1187
1188
1189
1190
1193 return true;
1194 else
1195 return false;
1196 }
1197 else
1198 {
1199
1200
1201
1202
1203 if (query->hasAggs || query->havingQual)
1204 return true;
1205 }
1206
1207
1208
1209
1210
1212 {
1214
1216
1217 if (!topop->all)
1218 {
1220
1221
1222 lg = list_head(topop->groupClauses);
1224 {
1227
1228 if (tle->resjunk)
1229 continue;
1230
1231
1234 lg = lnext(topop->groupClauses, lg);
1235
1239 break;
1240 }
1241 if (l == NULL)
1242 return true;
1243 }
1244 }
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254 return false;
1255}
1256
1257
1258
1259
1260
1261
1262
1263
1264static Oid
1266{
1268 *lc2;
1269
1270 forboth(lc1, colnos, lc2, opids)
1271 {
1274 }
1276}
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304bool
1310 List *restrictlist,
1311 bool force_cache)
1312{
1314 jointype, restrictlist, force_cache, NULL);
1315}
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326bool
1332 List *restrictlist,
1333 bool force_cache,
1334 List **extra_clauses)
1335{
1340 bool self_join = (extra_clauses != NULL);
1341
1342
1343 if (restrictlist == NIL)
1344 return false;
1345
1346
1347
1348
1349
1351 return false;
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1366 {
1368
1372 {
1373 if (extra_clauses)
1375 return true;
1376 }
1377 }
1378
1379
1380
1381
1382
1384 {
1386
1387 if (bms_is_subset(outerrelids, unique_for_rels))
1388 return false;
1389 }
1390
1391
1393 jointype, restrictlist,
1394 self_join ? &outer_exprs : NULL))
1395 {
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1409 uniqueRelInfo->self_join = self_join;
1412 uniqueRelInfo);
1414
1415 if (extra_clauses)
1416 *extra_clauses = outer_exprs;
1417 return true;
1418 }
1419 else
1420 {
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438 if (force_cache || root->join_search_private)
1439 {
1445 }
1446
1447 return false;
1448 }
1449}
1450
1451
1452
1453
1454
1455
1456static bool
1462 List *restrictlist,
1463 List **extra_clauses)
1464{
1467
1468
1469
1470
1471
1472
1473
1474
1475 foreach(lc, restrictlist)
1476 {
1478
1479
1480
1481
1482
1485 continue;
1486
1487
1488 if (!restrictinfo->can_join ||
1489 restrictinfo->mergeopfamilies == NIL)
1490 continue;
1491
1492
1493
1494
1495
1498 continue;
1499
1500
1501 clause_list = lappend(clause_list, restrictinfo);
1502 }
1503
1504
1506}
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530static void
1532{
1535
1536
1537
1538
1539
1540
1542
1544 {
1545 bool is_redundant = false;
1546
1548 {
1549 new_members = lappend(new_members, em);
1550 continue;
1551 }
1552
1554 em->em_jdomain->jd_relids = adjust_relid_set(em->em_jdomain->jd_relids, from, to);
1555
1556
1559
1561 {
1562 if ((em->em_relids, other->em_relids))
1563 continue;
1564
1565 if (equal(em->em_expr, other->em_expr))
1566 {
1567 is_redundant = true;
1568 break;
1569 }
1570 }
1571
1572 if (!is_redundant)
1573 new_members = lappend(new_members, em);
1574 }
1575
1578
1580
1581
1583 {
1584 bool is_redundant = false;
1585
1586 if ((from, rinfo->required_relids))
1587 {
1588 new_sources = lappend(new_sources, rinfo);
1589 continue;
1590 }
1591
1594
1595
1596
1597
1598
1599
1601 {
1602 if ((rinfo->clause_relids, other->clause_relids))
1603 continue;
1604
1605 if (equal(rinfo->clause, other->clause))
1606 {
1607 is_redundant = true;
1608 break;
1609 }
1610 }
1611
1612 if (!is_redundant)
1613 new_sources = lappend(new_sources, rinfo);
1614 }
1615
1619}
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630static bool
1632{
1633 int saved_rinfo_serial = a->rinfo_serial;
1634 bool result;
1635
1636 a->rinfo_serial = b->rinfo_serial;
1638 a->rinfo_serial = saved_rinfo_serial;
1639
1640 return result;
1641}
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656static void
1658 List *rinfo_candidates,
1659 List **keep_rinfo_list,
1660 Index removed_relid)
1661{
1663 {
1664 bool is_redundant = false;
1665
1667
1669 {
1670 if ((src->clause_relids, rinfo->clause_relids))
1671
1672 continue;
1673
1674 if (src == rinfo ||
1675 (rinfo->parent_ec != NULL &&
1676 src->parent_ec == rinfo->parent_ec) ||
1678 {
1679 is_redundant = true;
1680 break;
1681 }
1682 }
1683 if (!is_redundant)
1685 }
1686}
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700static bool
1702{
1704 {
1705 return true;
1706 }
1708 {
1710 int relid = -1;
1711 bool is_req_equal =
1713 bool clause_relids_is_multiple =
1715
1716
1717
1718
1719
1720
1721
1724 {
1725 Relids new_clause_relids;
1726
1729
1733
1734
1735
1736
1737
1738
1739
1740 rinfo->num_base_rels -= bms_num_members(rinfo->clause_relids) -
1742
1743 rinfo->clause_relids = new_clause_relids;
1744 rinfo->left_relids =
1746 rinfo->right_relids =
1748 }
1749
1750 if (is_req_equal)
1752 else
1755
1760
1761 if (rinfo->mergeopfamilies &&
1763 clause_relids_is_multiple &&
1765 {
1766 Expr *leftOp;
1767 Expr *rightOp;
1768
1771
1772
1773
1774
1775
1776
1777
1778
1779 if (leftOp != NULL && equal(leftOp, rightOp))
1780 {
1782
1783 ntest->arg = leftOp;
1785 ntest->argisrow = false;
1788 rinfo->mergeopfamilies = NIL;
1789 rinfo->left_em = NULL;
1790 rinfo->right_em = NULL;
1791 }
1792 Assert(rinfo->orclause == NULL);
1793 }
1794 return true;
1795 }
1796
1797 return false;
1798}
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824static void
1827 List *restrictlist)
1828{
1829 List *joininfos;
1831 int i;
1832 List *jinfo_candidates = NIL;
1833 List *binfo_candidates = NIL;
1834
1837
1838
1839
1840
1841
1842
1843
1846 {
1850
1852 jinfo_candidates = lappend(jinfo_candidates, rinfo);
1853 else
1854 binfo_candidates = lappend(binfo_candidates, rinfo);
1855 }
1856
1857
1858
1859
1860
1861
1862
1864 restrictlist);
1866 {
1869
1871 jinfo_candidates = lappend(jinfo_candidates, rinfo);
1872 else
1873 binfo_candidates = lappend(binfo_candidates, rinfo);
1874 }
1875
1876
1877
1878
1883
1886
1887
1888
1889
1890
1891
1892
1893 i = -1;
1895 {
1897
1900 }
1901
1902
1903
1904
1905
1907 {
1909
1914 }
1915
1916 for (i = toKeep->min_attr; i <= toKeep->max_attr; i++)
1917 {
1918 int attno = i - toKeep->min_attr;
1919
1920 toRemove->attr_needed[attno] = adjust_relid_set(toRemove->attr_needed[attno],
1922 toKeep->attr_needed[attno] = bms_add_members(toKeep->attr_needed[attno],
1923 toRemove->attr_needed[attno]);
1924 }
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934 if (rmark)
1935 {
1936 if (kmark)
1937 {
1939
1941 }
1942 else
1943 {
1944
1946
1948 }
1949 }
1950
1951
1952
1953
1954
1957
1958
1960
1961
1967
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981 root->simple_rel_array[toRemove->relid] = NULL;
1982
1983
1984 pfree(toRemove);
1985
1986
1987
1988
1989
1994}
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005static void
2007 List **otherjoinquals, int from, int to)
2008{
2011
2013 {
2015 Node *leftexpr;
2016 Node *rightexpr;
2017
2018
2019 if (!rinfo->mergeopfamilies ||
2023 {
2024 ojoinquals = lappend(ojoinquals, rinfo);
2025 continue;
2026 }
2027
2028 expr = (OpExpr *) rinfo->clause;
2029
2031 {
2032 ojoinquals = lappend(ojoinquals, rinfo);
2033 continue;
2034 }
2035
2036 leftexpr = get_leftop(rinfo->clause);
2038
2043
2044
2045
2046
2047
2048
2053
2054 if (equal(leftexpr, rightexpr))
2055 sjoinquals = lappend(sjoinquals, rinfo);
2056 else
2057 ojoinquals = lappend(ojoinquals, rinfo);
2058 }
2059
2060 *selfjoinquals = sjoinquals;
2061 *otherjoinquals = ojoinquals;
2062}
2063
2064
2065
2066
2067
2068
2069
2070static bool
2073{
2075 {
2076 Expr *clause;
2077 Node *iclause;
2079 bool matched = false;
2080
2082
2083
2086
2090
2095
2096
2097
2098
2099
2101 {
2102 Node *oclause;
2104
2105 if (orinfo->mergeopfamilies == NIL)
2106
2107 continue;
2108
2110
2111 oclause = bms_is_empty(orinfo->left_relids) ?
2115
2116 if (equal(iclause, oclause) && equal(c1, c2))
2117 {
2118 matched = true;
2119 break;
2120 }
2121 }
2122
2123 if (!matched)
2124 return false;
2125 }
2126
2127 return true;
2128}
2129
2130
2131
2132
2133
2134
2135
2138{
2139 Relids result = NULL;
2140 int k;
2141 int r = -1;
2142
2144 {
2146
2147 k = r;
2148
2150 {
2151 Relids joinrelids = NULL;
2153 List *restrictlist;
2154 List *selfjoinquals;
2155 List *otherjoinquals;
2157 bool jinfo_check = true;
2161
2162
2163 Assert(root->simple_rte_array[k]->relid ==
2164 root->simple_rte_array[r]->relid);
2165
2166
2167
2168
2169
2170
2171 foreach(lc, root->join_info_list)
2172 {
2174
2179 {
2180 jinfo_check = false;
2181 break;
2182 }
2183 }
2184 if (!jinfo_check)
2185 continue;
2186
2187
2188
2189
2190
2191
2192
2193 foreach(lc, root->rowMarks)
2194 {
2196
2197 if (rowMark->rti == k)
2198 {
2199 Assert(imark == NULL);
2200 imark = rowMark;
2201 }
2202 else if (rowMark->rti == r)
2203 {
2204 Assert(omark == NULL);
2205 omark = rowMark;
2206 }
2207
2208 if (omark && imark)
2209 break;
2210 }
2212 continue;
2213
2214
2215
2216
2217
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2233 outer, NULL);
2234 if (restrictlist == NIL)
2235 continue;
2236
2237
2238
2239
2240
2241
2243 &otherjoinquals, inner->relid, outer->relid);
2244
2247
2248
2249
2250
2251
2252
2253
2255
2256
2257
2258
2259
2260
2261
2262
2266 &uclauses))
2267 continue;
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2281 continue;
2282
2283
2284
2285
2286
2288
2290
2291
2292 break;
2293 }
2294 }
2295
2296 return result;
2297}
2298
2299
2300
2301
2302
2305{
2307 Relids relids = NULL;
2309 int i;
2310 int j;
2311 int numRels;
2312
2313
2314 foreach(jl, joinlist)
2315 {
2317
2319 {
2320 int varno = ((RangeTblRef *) jlnode)->rtindex;
2322
2323
2324
2325
2326
2327
2328
2329
2330
2332 rte->relkind == RELKIND_RELATION &&
2334 varno != root->parse->resultRelation &&
2335 varno != root->parse->mergeTargetRelation)
2336 {
2339 }
2340 }
2341 else if (IsA(jlnode, List))
2342 {
2343
2345 toRemove);
2346 }
2347 else
2348 elog(ERROR, "unrecognized joinlist node type: %d",
2350 }
2351
2353
2354
2355 if (numRels < 2)
2356 return toRemove;
2357
2358
2359
2360
2361
2363 numRels);
2364 i = -1;
2365 j = 0;
2367 {
2369 candidates[j].reloid = root->simple_rte_array[i]->relid;
2370 j++;
2371 }
2372
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385 i = 0;
2386 for (j = 1; j < numRels + 1; j++)
2387 {
2388 if (j == numRels || candidates[j].reloid != candidates[i].reloid)
2389 {
2391 {
2392
2393 Relids group = NULL;
2395
2397 {
2399 i++;
2400 }
2402
2403
2404
2405
2406
2407
2408
2409 do
2410 {
2419 }
2420 else
2421 {
2422
2425 }
2426 }
2427 }
2428
2430
2431 return toRemove;
2432}
2433
2434
2435
2436
2437static int
2439{
2442
2445 else
2446 return 0;
2447}
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2486{
2487 Relids toRemove = NULL;
2488 int relid = -1;
2489
2492 return joinlist;
2493
2494
2495
2496
2497
2499
2500 if (unlikely(toRemove != NULL))
2501 {
2502
2504 {
2505 int nremoved = 0;
2506
2508 if (nremoved != 1)
2509 elog(ERROR, "failed to find relation %d in joinlist", relid);
2510 }
2511 }
2512
2513 return joinlist;
2514}
static int self_join_candidates_cmp(const void *a, const void *b)
static bool match_unique_clauses(PlannerInfo *root, RelOptInfo *outer, List *uclauses, Index relid)
static bool replace_relid_callback(Node *node, ChangeVarNodes_context *context)
static void split_selfjoin_quals(PlannerInfo *root, List *joinquals, List **selfjoinquals, List **otherjoinquals, int from, int to)
static void add_non_redundant_clauses(PlannerInfo *root, List *rinfo_candidates, List **keep_rinfo_list, Index removed_relid)
static void remove_rel_from_query(PlannerInfo *root, RelOptInfo *rel, int subst, SpecialJoinInfo *sjinfo, Relids joinrelids)
bool innerrel_is_unique(PlannerInfo *root, Relids joinrelids, Relids outerrelids, RelOptInfo *innerrel, JoinType jointype, List *restrictlist, bool force_cache)
static List * remove_rel_from_joinlist(List *joinlist, int relid, int *nremoved)
static void remove_leftjoinrel_from_query(PlannerInfo *root, int relid, SpecialJoinInfo *sjinfo)
bool query_is_distinct_for(Query *query, List *colnos, List *opids)
static Relids remove_self_joins_one_group(PlannerInfo *root, Relids relids)
List * remove_useless_joins(PlannerInfo *root, List *joinlist)
static Oid distinct_col_search(int colno, List *colnos, List *opids)
static bool is_innerrel_unique_for(PlannerInfo *root, Relids joinrelids, Relids outerrelids, RelOptInfo *innerrel, JoinType jointype, List *restrictlist, List **extra_clauses)
static bool rel_is_distinct_for(PlannerInfo *root, RelOptInfo *rel, List *clause_list, List **extra_clauses)
bool innerrel_is_unique_ext(PlannerInfo *root, Relids joinrelids, Relids outerrelids, RelOptInfo *innerrel, JoinType jointype, List *restrictlist, bool force_cache, List **extra_clauses)
static void remove_rel_from_eclass(EquivalenceClass *ec, SpecialJoinInfo *sjinfo, int relid, int subst)
List * remove_useless_self_joins(PlannerInfo *root, List *joinlist)
bool query_supports_distinctness(Query *query)
static void update_eclasses(EquivalenceClass *ec, int from, int to)
static bool restrict_infos_logically_equal(RestrictInfo *a, RestrictInfo *b)
static Relids remove_self_joins_recurse(PlannerInfo *root, List *joinlist, Relids toRemove)
static bool join_is_removable(PlannerInfo *root, SpecialJoinInfo *sjinfo)
void reduce_unique_semijoins(PlannerInfo *root)
bool enable_self_join_elimination
static void remove_rel_from_restrictinfo(RestrictInfo *rinfo, int relid, int ojrelid)
static bool rel_supports_distinctness(PlannerInfo *root, RelOptInfo *rel)
static void remove_self_join_rel(PlannerInfo *root, PlanRowMark *kmark, PlanRowMark *rmark, RelOptInfo *toKeep, RelOptInfo *toRemove, List *restrictlist)
Bitmapset * bms_difference(const Bitmapset *a, const Bitmapset *b)
Bitmapset * bms_make_singleton(int x)
bool bms_equal(const Bitmapset *a, const Bitmapset *b)
int bms_next_member(const Bitmapset *a, int prevbit)
Bitmapset * bms_del_members(Bitmapset *a, const Bitmapset *b)
Bitmapset * bms_del_member(Bitmapset *a, int x)
bool bms_is_subset(const Bitmapset *a, const Bitmapset *b)
int bms_singleton_member(const Bitmapset *a)
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_union(const Bitmapset *a, const Bitmapset *b)
BMS_Membership bms_membership(const Bitmapset *a)
bool bms_overlap(const Bitmapset *a, const Bitmapset *b)
bool bms_get_singleton_member(const Bitmapset *a, int *member)
Bitmapset * bms_copy(const Bitmapset *a)
#define OidIsValid(objectId)
bool equal(const void *a, const void *b)
void rebuild_eclass_attr_needed(PlannerInfo *root)
void ec_clear_derived_clauses(EquivalenceClass *ec)
List * generate_join_implied_equalities(PlannerInfo *root, Relids join_relids, Relids outer_relids, RelOptInfo *inner_rel, SpecialJoinInfo *sjinfo)
Assert(PointerIsAligned(start, uint64))
bool relation_has_unique_index_ext(PlannerInfo *root, RelOptInfo *rel, List *restrictlist, List *exprlist, List *oprlist, List **extra_clauses)
void rebuild_lateral_attr_needed(PlannerInfo *root)
void distribute_restrictinfo_to_rels(PlannerInfo *root, RestrictInfo *restrictinfo)
void rebuild_joinclause_attr_needed(PlannerInfo *root)
if(TABLE==NULL||TABLE_index==NULL)
void remove_join_clause_from_rels(PlannerInfo *root, RestrictInfo *restrictinfo, Relids join_relids)
List * list_delete_ptr(List *list, void *datum)
List * lappend(List *list, void *datum)
List * list_concat(List *list1, const List *list2)
List * list_delete_cell(List *list, ListCell *cell)
List * list_copy(const List *oldlist)
List * lappend_int(List *list, int datum)
List * lappend_oid(List *list, Oid datum)
void list_free(List *list)
bool list_member(const List *list, const void *datum)
bool equality_ops_are_compatible(Oid opno1, Oid opno2)
void pfree(void *pointer)
static bool is_andclause(const void *clause)
static bool is_orclause(const void *clause)
static Node * get_rightop(const void *clause)
static bool is_opclause(const void *clause)
static Node * get_leftop(const void *clause)
#define IsA(nodeptr, _type_)
#define IS_OUTER_JOIN(jointype)
#define castNode(_type_, nodeptr)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
#define RINFO_IS_PUSHED_DOWN(rinfo, joinrelids)
#define lfirst_node(type, lc)
static int list_length(const List *l)
#define forboth(cell1, list1, cell2, list2)
#define foreach_delete_current(lst, var_or_cell)
static void * list_nth(const List *list, int n)
#define foreach_node(type, var, lst)
static ListCell * list_head(const List *l)
static ListCell * lnext(const List *l, const ListCell *c)
void rebuild_placeholder_attr_needed(PlannerInfo *root)
#define qsort(a, b, c, d)
RelOptInfo * find_base_rel(PlannerInfo *root, int relid)
bool restriction_is_or_clause(RestrictInfo *restrictinfo)
static bool clause_sides_match_join(RestrictInfo *rinfo, Relids outerrelids, Relids innerrelids)
bool ChangeVarNodesWalkExpression(Node *node, ChangeVarNodes_context *context)
Relids adjust_relid_set(Relids relids, int oldrelid, int newrelid)
void ChangeVarNodesExtended(Node *node, int rt_index, int new_index, int sublevels_up, ChangeVarNodes_callback callback)
NullTestType nulltesttype
struct TableSampleClause * tablesample
struct PathTarget * reltarget
List * non_unique_for_rels
Bitmapset * eclass_indexes
Relids incompatible_relids
TargetEntry * get_sortgroupclause_tle(SortGroupClause *sgClause, List *targetList)
Relids pull_varnos(PlannerInfo *root, Node *node)