]> granicus.if.org Git - postgresql/commitdiff
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,