]> granicus.if.org Git - postgresql/commitdiff
Tweak a couple of planner APIs to save recalculating join relids.
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 20 Apr 2018 20:00:47 +0000 (16:00 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 20 Apr 2018 20:00:47 +0000 (16:00 -0400)
Discussion: https://postgr.es/m/f8128b11-c5bf-3539-48cd-234178b2314d@proxel.se

src/backend/optimizer/path/costsize.c
src/backend/optimizer/path/joinpath.c
src/backend/optimizer/plan/analyzejoins.c
src/include/optimizer/cost.h
src/include/optimizer/planmain.h

index 10d41141f2b941e29a22d48f8752025e6431335b..957f751bd4889248d58012cc43c2990259026467 100644 (file)
@@ -4023,6 +4023,7 @@ get_restriction_qual_cost(PlannerInfo *root, RelOptInfo *baserel,
  * them to all the join cost estimation functions.
  *
  * Input parameters:
+ *     joinrel: join relation under consideration
  *     outerrel: outer relation under consideration
  *     innerrel: inner relation under consideration
  *     jointype: if not JOIN_SEMI or JOIN_ANTI, we assume it's inner_unique
@@ -4033,6 +4034,7 @@ get_restriction_qual_cost(PlannerInfo *root, RelOptInfo *baserel,
  */
 void
 compute_semi_anti_join_factors(PlannerInfo *root,
+                                                          RelOptInfo *joinrel,
                                                           RelOptInfo *outerrel,
                                                           RelOptInfo *innerrel,
                                                           JoinType jointype,
@@ -4056,14 +4058,12 @@ compute_semi_anti_join_factors(PlannerInfo *root,
         */
        if (IS_OUTER_JOIN(jointype))
        {
-               Relids          joinrelids = bms_union(outerrel->relids, innerrel->relids);
-
                joinquals = NIL;
                foreach(l, restrictlist)
                {
                        RestrictInfo *rinfo = lfirst_node(RestrictInfo, l);
 
-                       if (!RINFO_IS_PUSHED_DOWN(rinfo, joinrelids))
+                       if (!RINFO_IS_PUSHED_DOWN(rinfo, joinrel->relids))
                                joinquals = lappend(joinquals, rinfo);
                }
        }
index f47dd8185b532a8fac8cca06aba161df77d93e31..450edfae4649f68d86249bb779896649bd00e72c 100644 (file)
@@ -171,6 +171,7 @@ add_paths_to_joinrel(PlannerInfo *root,
                        break;
                case JOIN_UNIQUE_OUTER:
                        extra.inner_unique = innerrel_is_unique(root,
+                                                                                                       joinrel->relids,
                                                                                                        outerrel->relids,
                                                                                                        innerrel,
                                                                                                        JOIN_INNER,
@@ -179,6 +180,7 @@ add_paths_to_joinrel(PlannerInfo *root,
                        break;
                default:
                        extra.inner_unique = innerrel_is_unique(root,
+                                                                                                       joinrel->relids,
                                                                                                        outerrel->relids,
                                                                                                        innerrel,
                                                                                                        jointype,
@@ -207,7 +209,7 @@ add_paths_to_joinrel(PlannerInfo *root,
         * for cost estimation.  These will be the same for all paths.
         */
        if (jointype == JOIN_SEMI || jointype == JOIN_ANTI || extra.inner_unique)
-               compute_semi_anti_join_factors(root, outerrel, innerrel,
+               compute_semi_anti_join_factors(root, joinrel, outerrel, innerrel,
                                                                           jointype, sjinfo, restrictlist,
                                                                           &extra.semifactors);
 
index c5c43626096674aa013a185fc8f213932e6c7a8f..0e73f9cf4c7267f9f9e84be66810afa97c358b42 100644 (file)
@@ -42,6 +42,7 @@ static bool rel_is_distinct_for(PlannerInfo *root, RelOptInfo *rel,
                                        List *clause_list);
 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,
@@ -565,7 +566,8 @@ reduce_unique_semijoins(PlannerInfo *root)
                                                innerrel->joininfo);
 
                /* Test whether the innerrel is unique for those clauses. */
-               if (!innerrel_is_unique(root, sjinfo->min_lefthand, innerrel,
+               if (!innerrel_is_unique(root,
+                                                               joinrelids, sjinfo->min_lefthand, innerrel,
                                                                JOIN_SEMI, restrictlist, true))
                        continue;
 
@@ -947,7 +949,8 @@ distinct_col_search(int colno, List *colnos, List *opids)
  *
  * We need an actual RelOptInfo for the innerrel, but it's sufficient to
  * identify the outerrel by its Relids.  This asymmetry supports use of this
- * function before joinrels have been built.
+ * function before joinrels have been built.  (The caller is expected to
+ * also supply the joinrelids, just to save recalculating that.)
  *
  * The proof must be made based only on clauses that will be "joinquals"
  * rather than "otherquals" at execution.  For an inner join there's no
@@ -966,6 +969,7 @@ distinct_col_search(int colno, List *colnos, List *opids)
  */
 bool
 innerrel_is_unique(PlannerInfo *root,
+                                  Relids joinrelids,
                                   Relids outerrelids,
                                   RelOptInfo *innerrel,
                                   JoinType jointype,
@@ -1014,7 +1018,7 @@ innerrel_is_unique(PlannerInfo *root,
        }
 
        /* No cached information, so try to make the proof. */
-       if (is_innerrel_unique_for(root, outerrelids, innerrel,
+       if (is_innerrel_unique_for(root, joinrelids, outerrelids, innerrel,
                                                           jointype, restrictlist))
        {
                /*
@@ -1073,12 +1077,12 @@ innerrel_is_unique(PlannerInfo *root,
  */
 static bool
 is_innerrel_unique_for(PlannerInfo *root,
+                                          Relids joinrelids,
                                           Relids outerrelids,
                                           RelOptInfo *innerrel,
                                           JoinType jointype,
                                           List *restrictlist)
 {
-       Relids          joinrelids = bms_union(outerrelids, innerrel->relids);
        List       *clause_list = NIL;
        ListCell   *lc;
 
index d3269eae71c6c264f2fedf929de37554ece9c3ea..6e6d0d3c7960d847742267663cf9434e7dae33ba 100644 (file)
@@ -166,6 +166,7 @@ extern void cost_subplan(PlannerInfo *root, SubPlan *subplan, Plan *plan);
 extern void cost_qual_eval(QualCost *cost, List *quals, PlannerInfo *root);
 extern void cost_qual_eval_node(QualCost *cost, Node *qual, PlannerInfo *root);
 extern void compute_semi_anti_join_factors(PlannerInfo *root,
+                                                          RelOptInfo *joinrel,
                                                           RelOptInfo *outerrel,
                                                           RelOptInfo *innerrel,
                                                           JoinType jointype,
index 7132c88242bc9e43866075d4d807f527cedb6c7d..c8ab0280d2209cc45dd6042ed173b2bfd6f2cba5 100644 (file)
@@ -108,7 +108,7 @@ extern void reduce_unique_semijoins(PlannerInfo *root);
 extern bool query_supports_distinctness(Query *query);
 extern bool query_is_distinct_for(Query *query, List *colnos, List *opids);
 extern bool innerrel_is_unique(PlannerInfo *root,
-                                  Relids outerrelids, RelOptInfo *innerrel,
+                                  Relids joinrelids, Relids outerrelids, RelOptInfo *innerrel,
                                   JoinType jointype, List *restrictlist, bool force_cache);
 
 /*