Reset API of clause_selectivity()
authorSimon Riggs <simon@2ndQuadrant.com>
Thu, 6 Apr 2017 23:10:51 +0000 (19:10 -0400)
committerSimon Riggs <simon@2ndQuadrant.com>
Thu, 6 Apr 2017 23:10:51 +0000 (19:10 -0400)
Discussion: https://postgr.es/m/CAKJS1f9yurJQW9pdnzL+rmOtsp2vOytkpXKGnMFJEO-qz5O5eA@mail.gmail.com

contrib/file_fdw/file_fdw.c
contrib/postgres_fdw/postgres_fdw.c
src/backend/optimizer/path/clausesel.c
src/backend/optimizer/path/costsize.c
src/backend/optimizer/util/orclauses.c
src/backend/statistics/dependencies.c
src/backend/utils/adt/selfuncs.c
src/include/optimizer/cost.h

index 7414c16128b4d4549ddd5517991554804b82f689..277639f6e9db8a5ee0da594aacb0fd74b5f95f3c 100644 (file)
@@ -1013,7 +1013,6 @@ estimate_size(PlannerInfo *root, RelOptInfo *baserel,
                               baserel->baserestrictinfo,
                               0,
                               JOIN_INNER,
-                              NULL,
                               NULL);
 
    nrows = clamp_row_est(nrows);
index a73d1a0bed972c290b28f2baaef95c05f0c23dd9..2851869932dd1c55c4879d44f8345f8aa37710e6 100644 (file)
@@ -591,7 +591,6 @@ postgresGetForeignRelSize(PlannerInfo *root,
                                                     fpinfo->local_conds,
                                                     baserel->relid,
                                                     JOIN_INNER,
-                                                    NULL,
                                                     NULL);
 
    cost_qual_eval(&fpinfo->local_conds_cost, fpinfo->local_conds, root);
@@ -2573,7 +2572,6 @@ estimate_path_cost_size(PlannerInfo *root,
                                           local_param_join_conds,
                                           foreignrel->relid,
                                           JOIN_INNER,
-                                          NULL,
                                           NULL);
        local_sel *= fpinfo->local_conds_sel;
 
@@ -4457,7 +4455,6 @@ postgresGetForeignJoinPaths(PlannerInfo *root,
                                                     fpinfo->local_conds,
                                                     0,
                                                     JOIN_INNER,
-                                                    NULL,
                                                     NULL);
    cost_qual_eval(&fpinfo->local_conds_cost, fpinfo->local_conds, root);
 
@@ -4468,7 +4465,7 @@ postgresGetForeignJoinPaths(PlannerInfo *root,
    if (!fpinfo->use_remote_estimate)
        fpinfo->joinclause_sel = clauselist_selectivity(root, fpinfo->joinclauses,
                                                        0, fpinfo->jointype,
-                                                       extra->sjinfo, NULL);
+                                                       extra->sjinfo);
 
    /* Estimate costs for bare join relation */
    estimate_path_cost_size(root, joinrel, NIL, NIL, &rows,
index 1ba578130e969ec9ac991d73fbe7b01663fcb1ca..614c1d127ca2da0d0d816558bc7c50525d5f0f51 100644 (file)
@@ -41,7 +41,8 @@ typedef struct RangeQueryClause
 
 static void addRangeClause(RangeQueryClause **rqlist, Node *clause,
               bool varonleft, bool isLTsel, Selectivity s2);
-
+static RelOptInfo *find_relation_from_clauses(PlannerInfo *root,
+                                             List *clauses);
 
 /****************************************************************************
  *     ROUTINES TO COMPUTE SELECTIVITIES
@@ -101,14 +102,14 @@ clauselist_selectivity(PlannerInfo *root,
                       List *clauses,
                       int varRelid,
                       JoinType jointype,
-                      SpecialJoinInfo *sjinfo,
-                      RelOptInfo *rel)
+                      SpecialJoinInfo *sjinfo)
 {
    Selectivity s1 = 1.0;
    RangeQueryClause *rqlist = NULL;
    ListCell   *l;
    Bitmapset  *estimatedclauses = NULL;
    int         listidx;
+   RelOptInfo *rel;
 
    /*
     * If there's exactly one clause, then extended statistics is futile at
@@ -117,7 +118,14 @@ clauselist_selectivity(PlannerInfo *root,
     */
    if (list_length(clauses) == 1)
        return clause_selectivity(root, (Node *) linitial(clauses),
-                                 varRelid, jointype, sjinfo, rel);
+                                 varRelid, jointype, sjinfo);
+
+   /*
+    * Determine if these clauses reference a single relation. If so we might
+    * like to try applying any extended statistics which exist on it.
+    * Called many time during joins, so must return NULL quickly if not.
+    */
+   rel = find_relation_from_clauses(root, clauses);
 
    /*
     * When a relation of RTE_RELATION is given as 'rel', we'll try to
@@ -164,7 +172,7 @@ clauselist_selectivity(PlannerInfo *root,
            continue;
 
        /* Always compute the selectivity using clause_selectivity */
-       s2 = clause_selectivity(root, clause, varRelid, jointype, sjinfo, rel);
+       s2 = clause_selectivity(root, clause, varRelid, jointype, sjinfo);
 
        /*
         * Check for being passed a RestrictInfo.
@@ -417,6 +425,39 @@ addRangeClause(RangeQueryClause **rqlist, Node *clause,
    *rqlist = rqelem;
 }
 
+/*
+ * find_relation_from_clauses
+ *     Process each clause in 'clauses' and determine if all clauses
+ *     reference only a single relation. If so return that relation,
+ *     otherwise return NULL.
+ */
+static RelOptInfo *
+find_relation_from_clauses(PlannerInfo *root, List *clauses)
+{
+   ListCell *l;
+   int relid;
+   int lastrelid = 0;
+
+   foreach(l, clauses)
+   {
+       RestrictInfo *rinfo = (RestrictInfo *) lfirst(l);
+
+       if (bms_get_singleton_member(rinfo->clause_relids, &relid))
+       {
+           if (lastrelid != 0 && relid != lastrelid)
+               return NULL;        /* relation not the same as last one */
+           lastrelid = relid;
+       }
+       else
+           return NULL;            /* multiple relations in clause */
+   }
+
+   if (lastrelid != 0)
+       return find_base_rel(root, lastrelid);
+
+   return NULL;            /* no clauses */
+}
+
 /*
  * bms_is_subset_singleton
  *
@@ -529,8 +570,7 @@ clause_selectivity(PlannerInfo *root,
                   Node *clause,
                   int varRelid,
                   JoinType jointype,
-                  SpecialJoinInfo *sjinfo,
-                  RelOptInfo *rel)
+                  SpecialJoinInfo *sjinfo)
 {
    Selectivity s1 = 0.5;       /* default for any unhandled clause type */
    RestrictInfo *rinfo = NULL;
@@ -650,8 +690,7 @@ clause_selectivity(PlannerInfo *root,
                                  (Node *) get_notclausearg((Expr *) clause),
                                      varRelid,
                                      jointype,
-                                     sjinfo,
-                                     rel);
+                                     sjinfo);
    }
    else if (and_clause(clause))
    {
@@ -660,8 +699,7 @@ clause_selectivity(PlannerInfo *root,
                                    ((BoolExpr *) clause)->args,
                                    varRelid,
                                    jointype,
-                                   sjinfo,
-                                   rel);
+                                   sjinfo);
    }
    else if (or_clause(clause))
    {
@@ -680,8 +718,7 @@ clause_selectivity(PlannerInfo *root,
                                                (Node *) lfirst(arg),
                                                varRelid,
                                                jointype,
-                                               sjinfo,
-                                               rel);
+                                               sjinfo);
 
            s1 = s1 + s2 - s1 * s2;
        }
@@ -774,8 +811,7 @@ clause_selectivity(PlannerInfo *root,
                                (Node *) ((RelabelType *) clause)->arg,
                                varRelid,
                                jointype,
-                               sjinfo,
-                               rel);
+                               sjinfo);
    }
    else if (IsA(clause, CoerceToDomain))
    {
@@ -784,8 +820,7 @@ clause_selectivity(PlannerInfo *root,
                                (Node *) ((CoerceToDomain *) clause)->arg,
                                varRelid,
                                jointype,
-                               sjinfo,
-                               rel);
+                               sjinfo);
    }
    else
    {
index bf0fb56ab0ecf66b50c210a7bf854c5761cb7b35..ed07e2f6559b8a9986eaf97ed516e4b894cd567f 100644 (file)
@@ -3750,8 +3750,7 @@ compute_semi_anti_join_factors(PlannerInfo *root,
                                    joinquals,
                                    0,
                                    jointype,
-                                   sjinfo,
-                                   NULL);
+                                   sjinfo);
 
    /*
     * Also get the normal inner-join selectivity of the join clauses.
@@ -3774,8 +3773,7 @@ compute_semi_anti_join_factors(PlannerInfo *root,
                                    joinquals,
                                    0,
                                    JOIN_INNER,
-                                   &norm_sjinfo,
-                                   NULL);
+                                   &norm_sjinfo);
 
    /* Avoid leaking a lot of ListCells */
    if (jointype == JOIN_ANTI)
@@ -3942,7 +3940,7 @@ approx_tuple_count(PlannerInfo *root, JoinPath *path, List *quals)
        Node       *qual = (Node *) lfirst(l);
 
        /* Note that clause_selectivity will be able to cache its result */
-       selec *= clause_selectivity(root, qual, 0, JOIN_INNER, &sjinfo, NULL);
+       selec *= clause_selectivity(root, qual, 0, JOIN_INNER, &sjinfo);
    }
 
    /* Apply it to the input relation sizes */
@@ -3978,8 +3976,7 @@ set_baserel_size_estimates(PlannerInfo *root, RelOptInfo *rel)
                               rel->baserestrictinfo,
                               0,
                               JOIN_INNER,
-                              NULL,
-                              rel);
+                              NULL);
 
    rel->rows = clamp_row_est(nrows);
 
@@ -4016,8 +4013,7 @@ get_parameterized_baserel_size(PlannerInfo *root, RelOptInfo *rel,
                               allclauses,
                               rel->relid,      /* do not use 0! */
                               JOIN_INNER,
-                              NULL,
-                              rel);
+                              NULL);
    nrows = clamp_row_est(nrows);
    /* For safety, make sure result is not more than the base estimate */
    if (nrows > rel->rows)
@@ -4183,14 +4179,12 @@ calc_joinrel_size_estimate(PlannerInfo *root,
                                        joinquals,
                                        0,
                                        jointype,
-                                       sjinfo,
-                                       NULL);
+                                       sjinfo);
        pselec = clauselist_selectivity(root,
                                        pushedquals,
                                        0,
                                        jointype,
-                                       sjinfo,
-                                       NULL);
+                                       sjinfo);
 
        /* Avoid leaking a lot of ListCells */
        list_free(joinquals);
@@ -4202,8 +4196,7 @@ calc_joinrel_size_estimate(PlannerInfo *root,
                                        restrictlist,
                                        0,
                                        jointype,
-                                       sjinfo,
-                                       NULL);
+                                       sjinfo);
        pselec = 0.0;           /* not used, keep compiler quiet */
    }
 
@@ -4498,7 +4491,7 @@ get_foreign_key_join_selectivity(PlannerInfo *root,
                Selectivity csel;
 
                csel = clause_selectivity(root, (Node *) rinfo,
-                                         0, jointype, sjinfo, NULL);
+                                         0, jointype, sjinfo);
                thisfksel = Min(thisfksel, csel);
            }
            fkselec *= thisfksel;
index 735697d2f36725a98ce1a040c75d80b03c8d6412..9cbcaedb75d02373fc091eaf1fdcd60b96bb4663 100644 (file)
@@ -280,7 +280,7 @@ consider_new_or_clause(PlannerInfo *root, RelOptInfo *rel,
     * saving work later.)
     */
    or_selec = clause_selectivity(root, (Node *) or_rinfo,
-                                 0, JOIN_INNER, NULL, rel);
+                                 0, JOIN_INNER, NULL);
 
    /*
     * The clause is only worth adding to the query if it rejects a useful
@@ -344,7 +344,7 @@ consider_new_or_clause(PlannerInfo *root, RelOptInfo *rel,
 
        /* Compute inner-join size */
        orig_selec = clause_selectivity(root, (Node *) join_or_rinfo,
-                                       0, JOIN_INNER, &sjinfo, NULL);
+                                       0, JOIN_INNER, &sjinfo);
 
        /* And hack cached selectivity so join size remains the same */
        join_or_rinfo->norm_selec = orig_selec / or_selec;
index 159ddb872333e4eccba041c8e906ae89fbe838db..1a90e4b7157ab5b2dca9820d8b67d5755e5ed806 100644 (file)
@@ -1050,8 +1050,8 @@ dependencies_clauselist_selectivity(PlannerInfo *root,
            {
                clause = (Node *) lfirst(l);
 
-               s2 = clause_selectivity(root, clause, varRelid, jointype, sjinfo,
-                                       NULL);  /* don't try to use ext stats */
+               s2 = clause_selectivity(root, clause, varRelid, jointype,
+                                       sjinfo);
 
                /* mark this one as done, so we don't touch it again. */
                *estimatedclauses = bms_add_member(*estimatedclauses, listidx);
index b6893e22bfafa97ee3c1cb243f33ee33a67f964d..51c50eff50524ea126f0d38ac82351673387b416 100644 (file)
@@ -1634,17 +1634,13 @@ booltestsel(PlannerInfo *root, BoolTestType booltesttype, Node *arg,
            case IS_NOT_FALSE:
                selec = (double) clause_selectivity(root, arg,
                                                    varRelid,
-                                                   jointype,
-                                                   sjinfo,
-                                                   NULL);
+                                                   jointype, sjinfo);
                break;
            case IS_FALSE:
            case IS_NOT_TRUE:
                selec = 1.0 - (double) clause_selectivity(root, arg,
                                                          varRelid,
-                                                         jointype,
-                                                         sjinfo,
-                                                         NULL);
+                                                         jointype, sjinfo);
                break;
            default:
                elog(ERROR, "unrecognized booltesttype: %d",
@@ -6441,8 +6437,7 @@ genericcostestimate(PlannerInfo *root,
    indexSelectivity = clauselist_selectivity(root, selectivityQuals,
                                              index->rel->relid,
                                              JOIN_INNER,
-                                             NULL,
-                                             index->rel);
+                                             NULL);
 
    /*
     * If caller didn't give us an estimate, estimate the number of index
@@ -6763,8 +6758,7 @@ btcostestimate(PlannerInfo *root, IndexPath *path, double loop_count,
        btreeSelectivity = clauselist_selectivity(root, selectivityQuals,
                                                  index->rel->relid,
                                                  JOIN_INNER,
-                                                 NULL,
-                                                 index->rel);
+                                                 NULL);
        numIndexTuples = btreeSelectivity * index->rel->tuples;
 
        /*
@@ -7523,8 +7517,7 @@ gincostestimate(PlannerInfo *root, IndexPath *path, double loop_count,
    *indexSelectivity = clauselist_selectivity(root, selectivityQuals,
                                               index->rel->relid,
                                               JOIN_INNER,
-                                              NULL,
-                                              index->rel);
+                                              NULL);
 
    /* fetch estimated page cost for tablespace containing index */
    get_tablespace_page_costs(index->reltablespace,
@@ -7854,8 +7847,7 @@ brincostestimate(PlannerInfo *root, IndexPath *path, double loop_count,
 
    qualSelectivity = clauselist_selectivity(root, indexQuals,
                                             baserel->relid,
-                                            JOIN_INNER, NULL,
-                                            baserel);
+                                            JOIN_INNER, NULL);
 
    /* work out the actual number of ranges in the index */
    indexRanges = Max(ceil((double) baserel->pages / statsData.pagesPerRange),
index 81a84b54942f5431ecee3cef65607425d15bbc02..6909359bcff529658048c111479dfc43a6164089 100644 (file)
@@ -203,14 +203,12 @@ extern Selectivity clauselist_selectivity(PlannerInfo *root,
                       List *clauses,
                       int varRelid,
                       JoinType jointype,
-                      SpecialJoinInfo *sjinfo,
-                      RelOptInfo *rel);
+                      SpecialJoinInfo *sjinfo);
 extern Selectivity clause_selectivity(PlannerInfo *root,
                   Node *clause,
                   int varRelid,
                   JoinType jointype,
-                  SpecialJoinInfo *sjinfo,
-                  RelOptInfo *rel);
+                  SpecialJoinInfo *sjinfo);
 extern void cost_gather_merge(GatherMergePath *path, PlannerInfo *root,
                              RelOptInfo *rel, ParamPathInfo *param_info,
                              Cost input_startup_cost, Cost input_total_cost,