|
| 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 1327 of file analyzejoins.c.
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
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
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 if (force_cache ||
root->assumeReplanning)
1436 {
1442 }
1443
1444 return false;
1445 }
1446}
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 155 of file analyzejoins.c.
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
198
199
200
201
202
203
204
205
206
207
208
209
211 attroff >= 0;
212 attroff--)
213 {
214 if (!
bms_is_subset(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
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}
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 2070 of file analyzejoins.c.
2072{
2074 {
2078 bool matched = false;
2079
2081
2082
2085
2089
2094
2095
2096
2097
2098
2100 {
2103
2104 if (orinfo->mergeopfamilies ==
NIL)
2105
2106 continue;
2107
2109
2114
2115 if (
equal(iclause, oclause) &&
equal(c1, c2))
2116 {
2117 matched = true;
2118 break;
2119 }
2120 }
2121
2122 if (!matched)
2123 return false;
2124 }
2125
2126 return true;
2127}
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 1116 of file analyzejoins.c.
1117{
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
1204 return true;
1205 }
1206
1207
1208
1209
1210
1212 {
1214
1216
1218 {
1220
1221
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}
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)
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(), get_sortgroupclause_tle(), Query::groupClause, GROUPING_SET_EMPTY, Query::groupingSets, Query::havingQual, lfirst, linitial, 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 844 of file analyzejoins.c.
845{
847
848
849
850
851 foreach(lc,
root->join_info_list)
852 {
854 int innerrelid;
858
859
860
861
862
864 continue;
865
867 continue;
868
870
871
872
873
874
875
877 continue;
878
879
882
883
884
885
886
887
888 restrictlist =
890 joinrelids,
892 innerrel,
893 NULL),
895
896
900 continue;
901
902
904 }
905}
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 980 of file analyzejoins.c.
982{
983
984
985
986
987
989 return false;
991 {
992
993
994
995
996
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 {
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 || !
IsA(var,
Var) ||
1053 continue;
1054
1057 }
1058
1060 return true;
1061 }
1062 return false;
1063}
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 544 of file analyzejoins.c.
546{
553
554
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 root->simple_rte_array[relid] = NULL;
635
636
638
639
640
641
642
647}
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 325 of file analyzejoins.c.
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
518
520 attroff >= 0;
521 attroff--)
522 {
525 else
526 otherrel->attr_needed[attroff] = NULL;
527 }
528
529 if (subst > 0)
532 }
533}
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 1822 of file analyzejoins.c.
1825{
1831
1834
1835
1836
1837
1838
1839
1840
1843 {
1847
1849 jinfo_candidates =
lappend(jinfo_candidates, rinfo);
1850 else
1851 binfo_candidates =
lappend(binfo_candidates, rinfo);
1852 }
1853
1854
1855
1856
1857
1858
1859
1861 restrictlist);
1863 {
1866
1868 jinfo_candidates =
lappend(jinfo_candidates, rinfo);
1869 else
1870 binfo_candidates =
lappend(binfo_candidates, rinfo);
1871 }
1872
1873
1874
1875
1880
1883
1884
1885
1886
1887
1888
1889
1892 {
1894
1897 }
1898
1899
1900
1901
1902
1904 {
1906
1911 }
1912
1913 for (
i = toKeep->
min_attr; i <= toKeep->max_attr;
i++)
1914 {
1916
1917 toRemove->attr_needed[attno] =
adjust_relid_set(toRemove->attr_needed[attno],
1919 toKeep->attr_needed[attno] =
bms_add_members(toKeep->attr_needed[attno],
1920 toRemove->attr_needed[attno]);
1921 }
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931 if (rmark)
1932 {
1933 if (kmark)
1934 {
1936
1938 }
1939 else
1940 {
1941
1943
1945 }
1946 }
1947
1948
1949
1950
1951
1954
1955
1957
1958
1964
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978 root->simple_rel_array[toRemove->
relid] = NULL;
1979 root->simple_rte_array[toRemove->
relid] = NULL;
1980
1981
1983
1984
1985
1986
1987
1988
1993}
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 2136 of file analyzejoins.c.
2137{
2139 int k;
2140 int r = -1;
2141
2143 {
2145
2146 k = r;
2147
2149 {
2150 Relids joinrelids = NULL;
2153 List *selfjoinquals;
2154 List *otherjoinquals;
2156 bool jinfo_check = true;
2160
2161
2163 root->simple_rte_array[r]->relid);
2164
2165
2166
2167
2168
2169
2170 foreach(lc,
root->join_info_list)
2171 {
2173
2178 {
2179 jinfo_check = false;
2180 break;
2181 }
2182 }
2183 if (!jinfo_check)
2184 continue;
2185
2186
2187
2188
2189
2190
2191
2192 foreach(lc,
root->rowMarks)
2193 {
2195
2196 if (rowMark->
rti == r)
2197 {
2199 rmark = rowMark;
2200 }
2201 else if (rowMark->
rti == k)
2202 {
2204 kmark = rowMark;
2205 }
2206
2207 if (kmark && rmark)
2208 break;
2209 }
2211 continue;
2212
2213
2214
2215
2216
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2232 krel, NULL);
2233 if (restrictlist ==
NIL)
2234 continue;
2235
2236
2237
2238
2239
2240
2243
2246
2247
2248
2249
2250
2251
2252
2254
2255
2256
2257
2258
2259
2260
2261
2265 &uclauses))
2266 continue;
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2280 continue;
2281
2282
2283
2284
2285
2287
2289
2290
2291 break;
2292 }
2293 }
2294
2295 return result;
2296}
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 2303 of file analyzejoins.c.
2304{
2310 int numRels;
2311
2312
2313 foreach(jl, joinlist)
2314 {
2316
2318 {
2321
2322
2323
2324
2325
2326
2327
2328
2329
2331 rte->relkind == RELKIND_RELATION &&
2333 varno !=
root->parse->resultRelation &&
2334 varno !=
root->parse->mergeTargetRelation)
2335 {
2338 }
2339 }
2341 {
2342
2344 toRemove);
2345 }
2346 else
2347 elog(
ERROR,
"unrecognized joinlist node type: %d",
2349 }
2350
2352
2353
2354 if (numRels < 2)
2355 return toRemove;
2356
2357
2358
2359
2360
2362 numRels);
2366 {
2368 candidates[
j].
reloid =
root->simple_rte_array[
i]->relid;
2370 }
2371
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2385 for (
j = 1;
j < numRels + 1;
j++)
2386 {
2387 if (
j == numRels || candidates[
j].reloid != candidates[
i].reloid)
2388 {
2390 {
2391
2394
2396 {
2399 }
2401
2402
2403
2404
2405
2406
2407
2408 do
2409 {
2418 }
2419 else
2420 {
2421
2424 }
2425 }
2426 }
2427
2429
2430 return toRemove;
2431}
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 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(), 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 1698 of file analyzejoins.c.
1699{
1701 {
1702 return true;
1703 }
1705 {
1707 int relid = -1;
1708 bool is_req_equal =
1710 bool clause_relids_is_multiple =
1712
1713
1714
1715
1716
1717
1718
1721 {
1722 Relids new_clause_relids;
1723
1726
1730
1731
1732
1733
1734
1735
1736
1739
1740 rinfo->clause_relids = new_clause_relids;
1741 rinfo->left_relids =
1743 rinfo->right_relids =
1745 }
1746
1747 if (is_req_equal)
1749 else
1752
1757
1758 if (rinfo->mergeopfamilies &&
1760 clause_relids_is_multiple &&
1762 {
1765
1768
1769
1770
1771
1772
1773
1774
1775
1776 if (leftOp != NULL &&
equal(leftOp, rightOp))
1777 {
1779
1780 ntest->
arg = leftOp;
1782 ntest->argisrow = false;
1785 rinfo->mergeopfamilies =
NIL;
1786 rinfo->left_em = NULL;
1787 rinfo->right_em = NULL;
1788 }
1789 Assert(rinfo->orclause == NULL);
1790 }
1791 return true;
1792 }
1793
1794 return false;
1795}
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 2005 of file analyzejoins.c.
2007{
2010
2012 {
2016
2017
2018 if (!rinfo->mergeopfamilies ||
2022 {
2023 ojoinquals =
lappend(ojoinquals, rinfo);
2024 continue;
2025 }
2026
2027 expr = (
OpExpr *) rinfo->clause;
2028
2030 {
2031 ojoinquals =
lappend(ojoinquals, rinfo);
2032 continue;
2033 }
2034
2037
2042
2043
2044
2045
2046
2047
2052
2053 if (
equal(leftexpr, rightexpr))
2054 sjoinquals =
lappend(sjoinquals, rinfo);
2055 else
2056 ojoinquals =
lappend(ojoinquals, rinfo);
2057 }
2058
2059 *selfjoinquals = sjoinquals;
2060 *otherjoinquals = ojoinquals;
2061}
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 1528 of file analyzejoins.c.
1529{
1532
1533
1534
1535
1536
1537
1539
1541 {
1542 bool is_redundant = false;
1543
1545 {
1546 new_members =
lappend(new_members, em);
1547 continue;
1548 }
1549
1551 em->em_jdomain->jd_relids =
adjust_relid_set(em->em_jdomain->jd_relids, from, to);
1552
1553
1556
1558 {
1559 if (!
equal(em->em_relids, other->em_relids))
1560 continue;
1561
1562 if (
equal(em->em_expr, other->em_expr))
1563 {
1564 is_redundant = true;
1565 break;
1566 }
1567 }
1568
1569 if (!is_redundant)
1570 new_members =
lappend(new_members, em);
1571 }
1572
1575
1577
1578
1580 {
1581 bool is_redundant = false;
1582
1584 {
1585 new_sources =
lappend(new_sources, rinfo);
1586 continue;
1587 }
1588
1591
1592
1593
1594
1595
1596
1598 {
1599 if (!
equal(rinfo->clause_relids, other->clause_relids))
1600 continue;
1601
1602 if (
equal(rinfo->clause, other->clause))
1603 {
1604 is_redundant = true;
1605 break;
1606 }
1607 }
1608
1609 if (!is_redundant)
1610 new_sources =
lappend(new_sources, rinfo);
1611 }
1612
1616}
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().