|
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
1436
1437
1438 if (force_cache ||
root->join_search_private)
1439 {
1445 }
1446
1447 return false;
1448 }
1449}
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 2071 of file analyzejoins.c.
2073{
2075 {
2079 bool matched = false;
2080
2082
2083
2086
2090
2095
2096
2097
2098
2099
2101 {
2104
2105 if (orinfo->mergeopfamilies ==
NIL)
2106
2107 continue;
2108
2110
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}
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 create_unique_path(), and rel_is_distinct_for().
Definition at line 843 of file analyzejoins.c.
844{
846
847
848
849
850 foreach(lc,
root->join_info_list)
851 {
853 int innerrelid;
857
858
859
860
861
863 continue;
864
866 continue;
867
869
870
871
872
873
874
876 continue;
877
878
881
882
883
884
885
886
887 restrictlist =
889 joinrelids,
891 innerrel,
892 NULL),
894
895
899 continue;
900
901
903 }
904}
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 979 of file analyzejoins.c.
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 {
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_ext(PlannerInfo *root, RelOptInfo *rel, List *restrictlist, List *exprlist, List *oprlist, 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_ext(), 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
635
637
638
639
640
641
646}
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 1825 of file analyzejoins.c.
1828{
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
1895 {
1897
1900 }
1901
1902
1903
1904
1905
1907 {
1909
1914 }
1915
1916 for (
i = toKeep->
min_attr; i <= toKeep->max_attr;
i++)
1917 {
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
1985
1986
1987
1988
1989
1994}
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 2137 of file analyzejoins.c.
2138{
2140 int k;
2141 int r = -1;
2142
2144 {
2146
2147 k = r;
2148
2150 {
2151 Relids joinrelids = NULL;
2154 List *selfjoinquals;
2155 List *otherjoinquals;
2157 bool jinfo_check = true;
2161
2162
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 {
2200 imark = rowMark;
2201 }
2202 else if (rowMark->
rti == r)
2203 {
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}
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 2304 of file analyzejoins.c.
2305{
2311 int numRels;
2312
2313
2314 foreach(jl, joinlist)
2315 {
2317
2319 {
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 }
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);
2367 {
2369 candidates[
j].
reloid =
root->simple_rte_array[
i]->relid;
2371 }
2372
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2386 for (
j = 1;
j < numRels + 1;
j++)
2387 {
2388 if (
j == numRels || candidates[
j].reloid != candidates[
i].reloid)
2389 {
2391 {
2392
2395
2397 {
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}
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 1701 of file analyzejoins.c.
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
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 {
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}
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 2006 of file analyzejoins.c.
2008{
2011
2013 {
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
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}
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 1531 of file analyzejoins.c.
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 (!
equal(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
1587 {
1588 new_sources =
lappend(new_sources, rinfo);
1589 continue;
1590 }
1591
1594
1595
1596
1597
1598
1599
1601 {
1602 if (!
equal(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}
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().