33
33
#include "utils/lsyscache.h"
34
34
35
35
/*
36
- * The struct containing self-join candidate. Used to find duplicate reloids.
36
+ * Utility structure. It is needed to perform a sorting procedure and simplify
37
+ * the search of SJE-candidate baserels referencing the same database relation.
38
+ * Having collected all baserels from the query jointree, the planner sorts them
39
+ * according to the reloid value, groups them with the next pass and attempts to
40
+ * remove self-joins.
41
+ * Preliminary sorting prevents quadratic behaviour that can be harmful in the
42
+ * case of numerous joins.
37
43
*/
38
44
typedef struct
39
45
{
@@ -1584,6 +1590,9 @@ replace_varno(Node *node, int from, int to)
1584
1590
* We must make a copy of the original Bitmapset before making any
1585
1591
* modifications, because the same pointer to it might be shared among
1586
1592
* different places.
1593
+ * Also, this function can be used in 'delete only' mode (newId < 0).
1594
+ * It allows us to utilise the same code in the remove_useless_joins and the
1595
+ * remove_self_joins features.
1587
1596
*/
1588
1597
static Bitmapset *
1589
1598
replace_relid (Relids relids , int oldId , int newId )
@@ -2463,7 +2472,7 @@ self_join_candidates_cmp(const void *a, const void *b)
2463
2472
* of the removed relation become either restriction or join clauses, based on
2464
2473
* whether they reference any relations not participating in the removed join.
2465
2474
*
2466
- * 'targetlist ' is the top-level targetlist of the query. If it has any
2475
+ * 'joinlist ' is the top-level joinlist of the query. If it has any
2467
2476
* references to the removed relations, we update them to point to the
2468
2477
* remaining ones.
2469
2478
*/
@@ -2485,11 +2494,15 @@ remove_useless_self_joins(PlannerInfo *root, List *joinlist)
2485
2494
2486
2495
if (unlikely (toRemove != NULL ))
2487
2496
{
2488
- int nremoved = 0 ;
2489
-
2490
2497
/* At the end, remove orphaned relation links */
2491
2498
while ((relid = bms_next_member (toRemove , relid )) >= 0 )
2499
+ {
2500
+ int nremoved = 0 ;
2501
+
2492
2502
joinlist = remove_rel_from_joinlist (joinlist , relid , & nremoved );
2503
+ if (nremoved != 1 )
2504
+ elog (ERROR , "SJE failed to find relation %d in joinlist" , relid );
2505
+ }
2493
2506
}
2494
2507
2495
2508
return joinlist ;
0 commit comments