|
| static bool | join_is_removable (PlannerInfo *root, SpecialJoinInfo *sjinfo) |
| |
| static void | remove_leftjoinrel_from_query (PlannerInfo *root, int relid, SpecialJoinInfo *sjinfo) |
| |
| static void | remove_rel_from_restrictinfo (RestrictInfo *rinfo, int relid, int ojrelid) |
| |
| static void | remove_rel_from_eclass (EquivalenceClass *ec, SpecialJoinInfo *sjinfo, int relid, int subst) |
| |
| static List * | remove_rel_from_joinlist (List *joinlist, int relid, int *nremoved) |
| |
| static bool | rel_supports_distinctness (PlannerInfo *root, RelOptInfo *rel) |
| |
| static bool | rel_is_distinct_for (PlannerInfo *root, RelOptInfo *rel, List *clause_list, List **extra_clauses) |
| |
| 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 int | self_join_candidates_cmp (const void *a, const void *b) |
| |
| static bool | replace_relid_callback (Node *node, ChangeVarNodes_context *context) |
| |
| List * | remove_useless_joins (PlannerInfo *root, List *joinlist) |
| |
| static void | remove_rel_from_query (PlannerInfo *root, RelOptInfo *rel, int subst, SpecialJoinInfo *sjinfo, Relids joinrelids) |
| |
| void | reduce_unique_semijoins (PlannerInfo *root) |
| |
| bool | query_supports_distinctness (Query *query) |
| |
| bool | query_is_distinct_for (Query *query, List *colnos, List *opids) |
| |
| bool | innerrel_is_unique (PlannerInfo *root, Relids joinrelids, Relids outerrelids, RelOptInfo *innerrel, JoinType jointype, List *restrictlist, bool force_cache) |
| |
| 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 | update_eclasses (EquivalenceClass *ec, int from, int to) |
| |
| static bool | restrict_infos_logically_equal (RestrictInfo *a, RestrictInfo *b) |
| |
| static void | add_non_redundant_clauses (PlannerInfo *root, List *rinfo_candidates, List **keep_rinfo_list, Index removed_relid) |
| |
| static void | remove_self_join_rel (PlannerInfo *root, PlanRowMark *kmark, PlanRowMark *rmark, RelOptInfo *toKeep, RelOptInfo *toRemove, List *restrictlist) |
| |
| static void | split_selfjoin_quals (PlannerInfo *root, List *joinquals, List **selfjoinquals, List **otherjoinquals, int from, int to) |
| |
| static bool | match_unique_clauses (PlannerInfo *root, RelOptInfo *outer, List *uclauses, Index relid) |
| |
| static Relids | remove_self_joins_one_group (PlannerInfo *root, Relids relids) |
| |
| static Relids | remove_self_joins_recurse (PlannerInfo *root, List *joinlist, Relids toRemove) |
| |
| List * | remove_useless_self_joins (PlannerInfo *root, List *joinlist) |
| |
Definition at line 1332 of file analyzejoins.c.
1340{
1345 bool self_join = (extra_clauses != NULL);
1346
1347
1348 if (restrictlist ==
NIL)
1349 return false;
1350
1351
1352
1353
1354
1356 return false;
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1371 {
1373
1377 {
1378 if (extra_clauses)
1380 return true;
1381 }
1382 }
1383
1384
1385
1386
1387
1389 {
1391
1393 return false;
1394 }
1395
1396
1398 jointype, restrictlist,
1399 self_join ? &outer_exprs : NULL))
1400 {
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1417 uniqueRelInfo);
1419
1420 if (extra_clauses)
1421 *extra_clauses = outer_exprs;
1422 return true;
1423 }
1424 else
1425 {
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440 if (force_cache ||
root->assumeReplanning)
1441 {
1447 }
1448
1449 return false;
1450 }
1451}
static bool is_innerrel_unique_for(PlannerInfo *root, Relids joinrelids, Relids outerrelids, RelOptInfo *innerrel, JoinType jointype, List *restrictlist, List **extra_clauses)
static bool rel_supports_distinctness(PlannerInfo *root, RelOptInfo *rel)
bool bms_is_subset(const Bitmapset *a, const Bitmapset *b)
Bitmapset * bms_copy(const Bitmapset *a)
List * lappend(List *list, void *datum)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
List * non_unique_for_rels
References bms_copy(), bms_equal(), bms_is_subset(), UniqueRelInfo::extra_clauses, is_innerrel_unique_for(), lappend(), lfirst, makeNode, MemoryContextSwitchTo(), NIL, RelOptInfo::non_unique_for_rels, UniqueRelInfo::outerrelids, rel_supports_distinctness(), root, UniqueRelInfo::self_join, and RelOptInfo::unique_for_rels.
Referenced by innerrel_is_unique(), and remove_self_joins_one_group().
Definition at line 156 of file analyzejoins.c.
157{
158 int innerrelid;
164 int attroff;
165
166
167
168
169
171 return false;
172
174 return false;
175
176
177
178
179
180
181 if (innerrelid ==
root->parse->resultRelation)
182 return false;
183
185
186
187
188
189
190
192 return false;
193
194
199
200
201
202
203
204
205
206
207
208
209
210
212 attroff >= 0;
213 attroff--)
214 {
215 if (!
bms_is_subset(innerrel->attr_needed[attroff], inputrelids))
216 return false;
217 }
218
219
220
221
222
223
224
225
226
227
228 foreach(l,
root->placeholder_list)
229 {
231
233 return false;
235 continue;
237 continue;
239 return false;
240
241
242
243
244
246 return false;
247
250 return false;
251 }
252
253
254
255
256
257
258
259
261 {
263
264
265
266
267
268
269
270
271
273 continue;
274
275
276
277
278
279
280
282 continue;
283
284
285 if (!restrictinfo->can_join ||
286 restrictinfo->mergeopfamilies ==
NIL)
287 continue;
288
289
290
291
292
295 continue;
296
297
298 clause_list =
lappend(clause_list, restrictinfo);
299 }
300
301
302
303
304
306 return true;
307
308
309
310
311
312 return false;
313}
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)
bool bms_get_singleton_member(const Bitmapset *a, int *member)
RelOptInfo * find_base_rel(PlannerInfo *root, int relid)
Relids pull_varnos(PlannerInfo *root, Node *node)
References Assert(), bms_add_member(), bms_copy(), bms_get_singleton_member(), bms_is_member(), bms_is_subset(), bms_overlap(), bms_union(), clause_sides_match_join(), find_base_rel(), RestrictInfo::is_clone, JOIN_LEFT, RelOptInfo::joininfo, SpecialJoinInfo::jointype, lappend(), lfirst, RelOptInfo::max_attr, RelOptInfo::min_attr, SpecialJoinInfo::min_lefthand, SpecialJoinInfo::min_righthand, NIL, SpecialJoinInfo::ojrelid, PlaceHolderInfo::ph_eval_at, PlaceHolderInfo::ph_lateral, PlaceHolderInfo::ph_needed, PlaceHolderInfo::ph_var, pull_varnos(), rel_is_distinct_for(), rel_supports_distinctness(), RelOptInfo::relids, RINFO_IS_PUSHED_DOWN, and root.
Referenced by remove_useless_joins().
Definition at line 2075 of file analyzejoins.c.
2077{
2079 {
2083 bool matched = false;
2084
2086
2087
2090
2094
2099
2100
2101
2102
2103
2105 {
2108
2109 if (orinfo->mergeopfamilies ==
NIL)
2110
2111 continue;
2112
2114
2119
2120 if (
equal(iclause, oclause) &&
equal(c1, c2))
2121 {
2122 matched = true;
2123 break;
2124 }
2125 }
2126
2127 if (!matched)
2128 return false;
2129 }
2130
2131 return true;
2132}
static bool replace_relid_callback(Node *node, ChangeVarNodes_context *context)
bool equal(const void *a, const void *b)
static Node * get_rightop(const void *clause)
static bool is_opclause(const void *clause)
static Node * get_leftop(const void *clause)
void ChangeVarNodesExtended(Node *node, int rt_index, int new_index, int sublevels_up, ChangeVarNodes_callback callback)
References Assert(), RelOptInfo::baserestrictinfo, bms_is_empty, ChangeVarNodesExtended(), copyObject, equal(), foreach_node, get_leftop(), get_rightop(), is_opclause(), NIL, RelOptInfo::relid, and replace_relid_callback().
Referenced by remove_self_joins_one_group().
| bool query_is_distinct_for |
( |
Query * |
query, |
|
|
List * |
colnos, |
|
|
List * |
opids |
|
) |
| |
Definition at line 1117 of file analyzejoins.c.
1118{
1121
1123
1124
1125
1126
1127
1128
1129
1131 {
1133 {
1137
1141 break;
1142 }
1143 if (l == NULL)
1144 return true;
1145 }
1146
1147
1148
1149
1150
1151
1152
1153
1154 if (query->hasTargetSRFs)
1155 return false;
1156
1157
1158
1159
1160
1162 {
1164 {
1168
1172 break;
1173 }
1174 if (l == NULL)
1175 return true;
1176 }
1178 {
1180
1181
1182
1183
1184
1186 return false;
1187
1188
1189
1190
1191
1192
1193
1194
1196 return true;
1197
1199
1201 }
1202 else
1203 {
1204
1205
1206
1207
1209 return true;
1210 }
1211
1212
1213
1214
1215
1217 {
1219
1221
1223 {
1225
1226
1229 {
1232
1233 if (tle->resjunk)
1234 continue;
1235
1236
1239 lg =
lnext(topop->groupClauses, lg);
1240
1244 break;
1245 }
1246 if (l == NULL)
1247 return true;
1248 }
1249 }
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259 return false;
1260}
static Oid distinct_col_search(int colno, List *colnos, List *opids)
#define OidIsValid(objectId)
bool equality_ops_are_compatible(Oid opno1, Oid opno2)
#define castNode(_type_, nodeptr)
List * expand_grouping_sets(List *groupingSets, bool groupDistinct, int limit)
static int list_length(const List *l)
static ListCell * list_head(const List *l)
static ListCell * lnext(const List *l, const ListCell *c)
TargetEntry * get_sortgroupclause_tle(SortGroupClause *sgClause, List *targetList)
References SetOperationStmt::all, Assert(), castNode, distinct_col_search(), Query::distinctClause, SortGroupClause::eqop, equality_ops_are_compatible(), expand_grouping_sets(), get_sortgroupclause_tle(), Query::groupClause, Query::groupDistinct, Query::groupingSets, Query::havingQual, lfirst, list_head(), list_length(), lnext(), OidIsValid, SetOperationStmt::op, TargetEntry::resno, SETOP_NONE, Query::setOperations, and Query::targetList.
Referenced by rel_is_distinct_for().
Definition at line 845 of file analyzejoins.c.
846{
848
849
850
851
852 foreach(lc,
root->join_info_list)
853 {
855 int innerrelid;
859
860
861
862
863
865 continue;
866
868 continue;
869
871
872
873
874
875
876
878 continue;
879
880
883
884
885
886
887
888
889 restrictlist =
891 joinrelids,
893 innerrel,
894 NULL),
896
897
901 continue;
902
903
905 }
906}
bool innerrel_is_unique(PlannerInfo *root, Relids joinrelids, Relids outerrelids, RelOptInfo *innerrel, JoinType jointype, List *restrictlist, bool force_cache)
List * generate_join_implied_equalities(PlannerInfo *root, Relids join_relids, Relids outer_relids, RelOptInfo *inner_rel, SpecialJoinInfo *sjinfo)
List * list_concat(List *list1, const List *list2)
#define foreach_delete_current(lst, var_or_cell)
References Assert(), bms_get_singleton_member(), bms_union(), find_base_rel(), foreach_delete_current, generate_join_implied_equalities(), innerrel_is_unique(), JOIN_SEMI, RelOptInfo::joininfo, SpecialJoinInfo::jointype, lfirst, list_concat(), SpecialJoinInfo::min_lefthand, SpecialJoinInfo::min_righthand, SpecialJoinInfo::ojrelid, rel_supports_distinctness(), and root.
Referenced by query_planner().
Definition at line 981 of file analyzejoins.c.
983{
984
985
986
987
988
990 return false;
992 {
993
994
995
996
997
999 return true;
1000 }
1002 {
1004 Query *subquery =
root->simple_rte_array[relid]->subquery;
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018 foreach(l, clause_list)
1019 {
1023
1024
1025
1026
1027
1028
1029
1030
1031
1033
1034
1035 if (rinfo->outer_is_left)
1037 else
1039
1040
1041
1042
1043
1044
1047
1048
1049
1050
1051
1052 if (!var || !
IsA(var,
Var) ||
1054 continue;
1055
1058 }
1059
1061 return true;
1062 }
1063 return false;
1064}
bool query_is_distinct_for(Query *query, List *colnos, List *opids)
bool relation_has_unique_index_for(PlannerInfo *root, RelOptInfo *rel, List *restrictlist, List **extra_clauses)
List * lappend_int(List *list, int datum)
List * lappend_oid(List *list, Oid datum)
#define IsA(nodeptr, _type_)
#define lfirst_node(type, lc)
References castNode, RestrictInfo::clause, get_leftop(), get_rightop(), IsA, lappend_int(), lappend_oid(), lfirst_node, NIL, query_is_distinct_for(), relation_has_unique_index_for(), RelOptInfo::relid, RELOPT_BASEREL, RelOptInfo::reloptkind, root, RTE_RELATION, RTE_SUBQUERY, RelOptInfo::rtekind, Var::varattno, Var::varlevelsup, and Var::varno.
Referenced by is_innerrel_unique_for(), and join_is_removable().
Definition at line 545 of file analyzejoins.c.
547{
554
555
559
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578 join_plus_commute =
bms_union(joinrelids,
582
583
584
585
586
587
589 foreach(l, joininfos)
590 {
592
594
596 {
597
598
599
600
601
602
603
605
606
607
608
609
610#ifdef USE_ASSERT_CHECKING
611 {
614
617 }
618#endif
619
621 }
622 }
623
624
625
626
627
628
629
630
631
632
633
634 root->simple_rel_array[relid] = NULL;
635 root->simple_rte_array[relid] = NULL;
636
637
639
640
641
642
643
648}
static void remove_rel_from_query(PlannerInfo *root, RelOptInfo *rel, int subst, SpecialJoinInfo *sjinfo, Relids joinrelids)
static void remove_rel_from_restrictinfo(RestrictInfo *rinfo, int relid, int ojrelid)
Bitmapset * bms_add_members(Bitmapset *a, const Bitmapset *b)
void rebuild_eclass_attr_needed(PlannerInfo *root)
void rebuild_lateral_attr_needed(PlannerInfo *root)
void rebuild_joinclause_attr_needed(PlannerInfo *root)
void remove_join_clause_from_rels(PlannerInfo *root, RestrictInfo *restrictinfo, Relids join_relids)
List * list_copy(const List *oldlist)
void pfree(void *pointer)
void rebuild_placeholder_attr_needed(PlannerInfo *root)
References Assert(), bms_add_member(), bms_add_members(), bms_is_member(), bms_union(), RestrictInfo::clause, SpecialJoinInfo::commute_above_r, SpecialJoinInfo::commute_below_l, distribute_restrictinfo_to_rels(), find_base_rel(), RelOptInfo::joininfo, lfirst, list_copy(), SpecialJoinInfo::min_lefthand, SpecialJoinInfo::min_righthand, SpecialJoinInfo::ojrelid, pfree(), pull_varnos(), rebuild_eclass_attr_needed(), rebuild_joinclause_attr_needed(), rebuild_lateral_attr_needed(), rebuild_placeholder_attr_needed(), remove_join_clause_from_rels(), remove_rel_from_query(), remove_rel_from_restrictinfo(), RestrictInfo::required_relids, RINFO_IS_PUSHED_DOWN, and root.
Referenced by remove_useless_joins().
Definition at line 326 of file analyzejoins.c.
329{
330 int relid = rel->
relid;
333
334
335
336
339
340 if (sjinfo != NULL)
341 {
346 }
347
348
349
350
351
352
353
354
355
356 foreach(l,
root->join_info_list)
357 {
359
360
361
362
363
364
365
370
375
376 if (sjinfo != NULL)
377 {
379
380
389
398 }
399 else
400 {
402
405 }
406 }
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427 foreach(l,
root->placeholder_list)
428 {
430
432 if (sjinfo != NULL &&
436 {
437
438
439
440
441
443 l);
444 root->placeholder_array[phinfo->
phid] = NULL;
445 }
446 else
447 {
449
451 if (sjinfo != NULL)
455
458 else
460
462
463
464
465
466
468
469
471 if (sjinfo != NULL)
475
478
480 }
481 }
482
483
484
485
486 foreach(l,
root->eq_classes)
487 {
489
493 }
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509 for (rti = 1; rti <
root->simple_rel_array_size; rti++)
510 {
512 int attroff;
513
514
515 if (otherrel == NULL)
516 continue;
517
519
521 attroff >= 0;
522 attroff--)
523 {
526 else
527 otherrel->attr_needed[attroff] = NULL;
528 }
529
530 if (subst > 0)
533 }
534}
static void remove_rel_from_eclass(EquivalenceClass *ec, SpecialJoinInfo *sjinfo, int relid, int subst)
Bitmapset * bms_difference(const Bitmapset *a, const Bitmapset *b)
Bitmapset * bms_make_singleton(int x)
Bitmapset * bms_del_member(Bitmapset *a, int x)
References adjust_relid_set(), Assert(), bms_copy(), bms_del_member(), bms_difference(), bms_is_empty, bms_is_member(), bms_is_subset(), bms_make_singleton(), ChangeVarNodesExtended(), SpecialJoinInfo::commute_above_l, SpecialJoinInfo::commute_above_r, SpecialJoinInfo::commute_below_l, SpecialJoinInfo::commute_below_r, EquivalenceClass::ec_relids, foreach_delete_current, RelOptInfo::lateral_vars, lfirst, RelOptInfo::max_attr, RelOptInfo::min_attr, SpecialJoinInfo::min_lefthand, SpecialJoinInfo::min_righthand, SpecialJoinInfo::ojrelid, PlaceHolderInfo::ph_eval_at, PlaceHolderInfo::ph_lateral, PlaceHolderInfo::ph_needed, PlaceHolderInfo::ph_var, PlaceHolderInfo::phid, PlaceHolderVar::phnullingrels, RelOptInfo::relid, remove_rel_from_eclass(), replace_relid_callback(), root, SpecialJoinInfo::semi_rhs_exprs, SpecialJoinInfo::syn_lefthand, and SpecialJoinInfo::syn_righthand.
Referenced by remove_leftjoinrel_from_query(), and remove_self_join_rel().
Definition at line 1827 of file analyzejoins.c.
1830{
1836
1839
1840
1841
1842
1843
1844
1845
1848 {
1852
1854 jinfo_candidates =
lappend(jinfo_candidates, rinfo);
1855 else
1856 binfo_candidates =
lappend(binfo_candidates, rinfo);
1857 }
1858
1859
1860
1861
1862
1863
1864
1866 restrictlist);
1868 {
1871
1873 jinfo_candidates =
lappend(jinfo_candidates, rinfo);
1874 else
1875 binfo_candidates =
lappend(binfo_candidates, rinfo);
1876 }
1877
1878
1879
1880
1885
1888
1889
1890
1891
1892
1893
1894
1897 {
1899
1902 }
1903
1904
1905
1906
1907
1909 {
1911
1916 }
1917
1918 for (
i = toKeep->
min_attr; i <= toKeep->max_attr;
i++)
1919 {
1921
1922 toRemove->attr_needed[attno] =
adjust_relid_set(toRemove->attr_needed[attno],
1924 toKeep->attr_needed[attno] =
bms_add_members(toKeep->attr_needed[attno],
1925 toRemove->attr_needed[attno]);
1926 }
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936 if (rmark)
1937 {
1938 if (kmark)
1939 {
1941
1943 }
1944 else
1945 {
1946
1948
1950 }
1951 }
1952
1953
1954
1955
1956
1959
1960
1962
1963
1969
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983 root->simple_rel_array[toRemove->
relid] = NULL;
1984 root->simple_rte_array[toRemove->
relid] = NULL;
1985
1986
1988
1989
1990
1991
1992
1993
1998}
static void add_non_redundant_clauses(PlannerInfo *root, List *rinfo_candidates, List **keep_rinfo_list, Index removed_relid)
static void update_eclasses(EquivalenceClass *ec, int from, int to)
int bms_next_member(const Bitmapset *a, int prevbit)
BMS_Membership bms_membership(const Bitmapset *a)
List * list_delete_ptr(List *list, void *datum)
void list_free(List *list)
bool list_member(const List *list, const void *datum)
static void * list_nth(const List *list, int n)
struct PathTarget * reltarget
Bitmapset * eclass_indexes
References add_non_redundant_clauses(), adjust_relid_set(), Assert(), RelOptInfo::baserestrictinfo, bms_add_member(), bms_add_members(), bms_membership(), BMS_MULTIPLE, bms_next_member(), ChangeVarNodesExtended(), RelOptInfo::eclass_indexes, PathTarget::exprs, foreach_node, i, RelOptInfo::joininfo, lappend(), lfirst, list_concat(), list_copy(), list_delete_ptr(), list_free(), list_member(), list_nth(), PlanRowMark::markType, RelOptInfo::min_attr, NIL, pfree(), PlanRowMark::prti, rebuild_eclass_attr_needed(), rebuild_joinclause_attr_needed(), rebuild_lateral_attr_needed(), rebuild_placeholder_attr_needed(), RelOptInfo::relid, RelOptInfo::reltarget, remove_join_clause_from_rels(), remove_rel_from_query(), replace_relid_callback(), root, PlanRowMark::rti, and update_eclasses().
Referenced by remove_self_joins_one_group().
Definition at line 2141 of file analyzejoins.c.
2142{
2144 int k;
2145 int r = -1;
2146
2148 {
2150
2151 k = r;
2152
2154 {
2155 Relids joinrelids = NULL;
2158 List *selfjoinquals;
2159 List *otherjoinquals;
2161 bool jinfo_check = true;
2165
2166
2168 root->simple_rte_array[r]->relid);
2169
2170
2171
2172
2173
2174
2175 foreach(lc,
root->join_info_list)
2176 {
2178
2183 {
2184 jinfo_check = false;
2185 break;
2186 }
2187 }
2188 if (!jinfo_check)
2189 continue;
2190
2191
2192
2193
2194
2195
2196
2197 foreach(lc,
root->rowMarks)
2198 {
2200
2201 if (rowMark->
rti == r)
2202 {
2204 rmark = rowMark;
2205 }
2206 else if (rowMark->
rti == k)
2207 {
2209 kmark = rowMark;
2210 }
2211
2212 if (kmark && rmark)
2213 break;
2214 }
2216 continue;
2217
2218
2219
2220
2221
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2237 krel, NULL);
2238 if (restrictlist ==
NIL)
2239 continue;
2240
2241
2242
2243
2244
2245
2248
2251
2252
2253
2254
2255
2256
2257
2259
2260
2261
2262
2263
2264
2265
2266
2270 &uclauses))
2271 continue;
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2285 continue;
2286
2287
2288
2289
2290
2292
2294
2295
2296 break;
2297 }
2298 }
2299
2300 return result;
2301}
static bool match_unique_clauses(PlannerInfo *root, RelOptInfo *outer, List *uclauses, Index relid)
static void split_selfjoin_quals(PlannerInfo *root, List *joinquals, List **selfjoinquals, List **otherjoinquals, int from, int to)
static void remove_self_join_rel(PlannerInfo *root, PlanRowMark *kmark, PlanRowMark *rmark, RelOptInfo *toKeep, RelOptInfo *toRemove, List *restrictlist)
References Assert(), RelOptInfo::baserestrictinfo, bms_add_member(), bms_is_member(), bms_next_member(), generate_join_implied_equalities(), innerrel_is_unique_ext(), JOIN_INNER, lfirst, list_concat(), list_length(), PlanRowMark::markType, match_unique_clauses(), NIL, RelOptInfo::relid, RelOptInfo::relids, remove_self_join_rel(), root, PlanRowMark::rti, split_selfjoin_quals(), SpecialJoinInfo::syn_lefthand, and SpecialJoinInfo::syn_righthand.
Referenced by remove_self_joins_recurse().
Definition at line 2308 of file analyzejoins.c.
2309{
2315 int numRels;
2316
2317
2318 foreach(jl, joinlist)
2319 {
2321
2323 {
2326
2327
2328
2329
2330
2331
2332
2333
2334
2336 rte->relkind == RELKIND_RELATION &&
2338 varno !=
root->parse->resultRelation &&
2339 varno !=
root->parse->mergeTargetRelation)
2340 {
2343 }
2344 }
2346 {
2347
2349 toRemove);
2350 }
2351 else
2352 elog(
ERROR,
"unrecognized joinlist node type: %d",
2354 }
2355
2357
2358
2359 if (numRels < 2)
2360 return toRemove;
2361
2362
2363
2364
2365
2370 {
2372 candidates[
j].
reloid =
root->simple_rte_array[
i]->relid;
2374 }
2375
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2389 for (
j = 1;
j < numRels + 1;
j++)
2390 {
2391 if (
j == numRels || candidates[
j].reloid != candidates[
i].reloid)
2392 {
2394 {
2395
2398
2400 {
2403 }
2405
2406
2407
2408
2409
2410
2411
2412 do
2413 {
2422 }
2423 else
2424 {
2425
2428 }
2429 }
2430 }
2431
2433
2434 return toRemove;
2435}
static int self_join_candidates_cmp(const void *a, const void *b)
static Relids remove_self_joins_one_group(PlannerInfo *root, Relids relids)
static Relids remove_self_joins_recurse(PlannerInfo *root, List *joinlist, Relids toRemove)
Bitmapset * bms_del_members(Bitmapset *a, const Bitmapset *b)
void bms_free(Bitmapset *a)
int bms_num_members(const Bitmapset *a)
#define palloc_array(type, count)
#define qsort(a, b, c, d)
struct TableSampleClause * tablesample
References Assert(), bms_add_member(), bms_add_members(), bms_del_member(), bms_del_members(), bms_free(), bms_is_empty, bms_is_member(), bms_membership(), BMS_MULTIPLE, bms_next_member(), bms_num_members(), bms_overlap(), elog, ERROR, i, IsA, j, lfirst, nodeTag, palloc_array, qsort, SelfJoinCandidate::relid, SelfJoinCandidate::reloid, remove_self_joins_one_group(), remove_self_joins_recurse(), root, RTE_RELATION, RangeTblEntry::rtekind, self_join_candidates_cmp(), and RangeTblEntry::tablesample.
Referenced by remove_self_joins_recurse(), and remove_useless_self_joins().
Definition at line 1703 of file analyzejoins.c.
1704{
1706 {
1707 return true;
1708 }
1710 {
1712 int relid = -1;
1713 bool is_req_equal =
1715 bool clause_relids_is_multiple =
1717
1718
1719
1720
1721
1722
1723
1726 {
1727 Relids new_clause_relids;
1728
1731
1735
1736
1737
1738
1739
1740
1741
1744
1745 rinfo->clause_relids = new_clause_relids;
1746 rinfo->left_relids =
1748 rinfo->right_relids =
1750 }
1751
1752 if (is_req_equal)
1754 else
1757
1762
1763 if (rinfo->mergeopfamilies &&
1765 clause_relids_is_multiple &&
1767 {
1770
1773
1774
1775
1776
1777
1778
1779
1780
1781 if (leftOp != NULL &&
equal(leftOp, rightOp))
1782 {
1784
1785 ntest->
arg = leftOp;
1787 ntest->argisrow = false;
1790 rinfo->mergeopfamilies =
NIL;
1791 rinfo->left_em = NULL;
1792 rinfo->right_em = NULL;
1793 }
1794 Assert(rinfo->orclause == NULL);
1795 }
1796 return true;
1797 }
1798
1799 return false;
1800}
bool ChangeVarNodesWalkExpression(Node *node, ChangeVarNodes_context *context)
NullTestType nulltesttype
Relids incompatible_relids
References adjust_relid_set(), NullTest::arg, Assert(), bms_get_singleton_member(), bms_is_member(), bms_membership(), BMS_MULTIPLE, bms_num_members(), ChangeVarNodesWalkExpression(), RestrictInfo::clause, equal(), get_leftop(), get_rightop(), RestrictInfo::incompatible_relids, IS_NOT_NULL, IsA, NullTest::location, makeNode, ChangeVarNodes_context::new_index, NIL, NullTest::nulltesttype, RestrictInfo::outer_relids, RestrictInfo::required_relids, and ChangeVarNodes_context::rt_index.
Referenced by match_unique_clauses(), remove_rel_from_eclass(), remove_rel_from_query(), remove_self_join_rel(), split_selfjoin_quals(), and update_eclasses().
| static void split_selfjoin_quals |
( |
PlannerInfo * |
root, |
|
|
List * |
joinquals, |
|
|
List ** |
selfjoinquals, |
|
|
List ** |
otherjoinquals, |
|
|
int |
from, |
|
|
int |
to |
|
) |
| |
|
static |
Definition at line 2010 of file analyzejoins.c.
2012{
2015
2017 {
2021
2022
2023 if (!rinfo->mergeopfamilies ||
2027 {
2028 ojoinquals =
lappend(ojoinquals, rinfo);
2029 continue;
2030 }
2031
2032 expr = (
OpExpr *) rinfo->clause;
2033
2035 {
2036 ojoinquals =
lappend(ojoinquals, rinfo);
2037 continue;
2038 }
2039
2042
2047
2048
2049
2050
2051
2052
2057
2058 if (
equal(leftexpr, rightexpr))
2059 sjoinquals =
lappend(sjoinquals, rinfo);
2060 else
2061 ojoinquals =
lappend(ojoinquals, rinfo);
2062 }
2063
2064 *selfjoinquals = sjoinquals;
2065 *otherjoinquals = ojoinquals;
2066}
if(TABLE==NULL||TABLE_index==NULL)
References arg, OpExpr::args, bms_membership(), bms_num_members(), BMS_SINGLETON, bms_singleton_member(), ChangeVarNodesExtended(), copyObject, equal(), foreach_node, get_leftop(), get_rightop(), if(), IsA, lappend(), list_length(), NIL, and replace_relid_callback().
Referenced by remove_self_joins_one_group().
Definition at line 1533 of file analyzejoins.c.
1534{
1537
1538
1539
1540
1541
1542
1544
1546 {
1547 bool is_redundant = false;
1548
1550 {
1551 new_members =
lappend(new_members, em);
1552 continue;
1553 }
1554
1556 em->em_jdomain->jd_relids =
adjust_relid_set(em->em_jdomain->jd_relids, from, to);
1557
1558
1561
1563 {
1564 if (!
equal(em->em_relids, other->em_relids))
1565 continue;
1566
1567 if (
equal(em->em_expr, other->em_expr))
1568 {
1569 is_redundant = true;
1570 break;
1571 }
1572 }
1573
1574 if (!is_redundant)
1575 new_members =
lappend(new_members, em);
1576 }
1577
1580
1582
1583
1585 {
1586 bool is_redundant = false;
1587
1589 {
1590 new_sources =
lappend(new_sources, rinfo);
1591 continue;
1592 }
1593
1596
1597
1598
1599
1600
1601
1603 {
1604 if (!
equal(rinfo->clause_relids, other->clause_relids))
1605 continue;
1606
1607 if (
equal(rinfo->clause, other->clause))
1608 {
1609 is_redundant = true;
1610 break;
1611 }
1612 }
1613
1614 if (!is_redundant)
1615 new_sources =
lappend(new_sources, rinfo);
1616 }
1617
1621}
References adjust_relid_set(), Assert(), bms_is_member(), ChangeVarNodesExtended(), EquivalenceClass::ec_childmembers, ec_clear_derived_clauses(), EquivalenceClass::ec_members, EquivalenceClass::ec_relids, EquivalenceClass::ec_sources, equal(), foreach_node, lappend(), list_free(), NIL, and replace_relid_callback().
Referenced by remove_self_join_rel().