1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-08 11:42:09 +03:00

Reset API of clause_selectivity()

Discussion: https://postgr.es/m/CAKJS1f9yurJQW9pdnzL+rmOtsp2vOytkpXKGnMFJEO-qz5O5eA@mail.gmail.com
This commit is contained in:
Simon Riggs
2017-04-06 19:10:51 -04:00
parent 255efa241f
commit ac2b095088
8 changed files with 74 additions and 60 deletions

View 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
{

View 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;

View 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;