Commit cbf50318 authored by Tom Lane's avatar Tom Lane

Tweak recognition of range-clause pairs so that 'var > $1 AND var < $2'

(ie, parameters instead of consts) will be treated as a range query.
We do not know the actual selectivities involved, but it seems like
a good idea to use a smaller estimate than we would use for two unrelated
inequalities.
parent 6a68f426
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/clausesel.c,v 1.36 2000/05/30 00:49:46 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/optimizer/path/clausesel.c,v 1.37 2000/05/31 15:38:53 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -95,7 +95,7 @@ restrictlist_selectivity(Query *root, ...@@ -95,7 +95,7 @@ restrictlist_selectivity(Query *root,
* directly as a 0..1 value but we need to convert losel to 1-losel before * directly as a 0..1 value but we need to convert losel to 1-losel before
* interpreting it as a value. Then the available range is 1-losel to hisel.) * interpreting it as a value. Then the available range is 1-losel to hisel.)
* If the calculation yields zero or negative, however, we chicken out and * If the calculation yields zero or negative, however, we chicken out and
* use the default interpretation; that probably means that one or both * use a default estimate; that probably means that one or both
* selectivities is a default estimate rather than an actual range value. * selectivities is a default estimate rather than an actual range value.
* Of course this is all very dependent on the behavior of * Of course this is all very dependent on the behavior of
* scalarltsel/scalargtsel; perhaps some day we can generalize the approach. * scalarltsel/scalargtsel; perhaps some day we can generalize the approach.
...@@ -120,10 +120,12 @@ clauselist_selectivity(Query *root, ...@@ -120,10 +120,12 @@ clauselist_selectivity(Query *root,
Selectivity s2; Selectivity s2;
/* /*
* See if it looks like a restriction clause with a constant. (If * See if it looks like a restriction clause with a Const or Param
* it's not a constant we can't really trust the selectivity!) NB: * on one side. (Anything more complicated than that might not
* for consistency of results, this fragment of code had better * behave in the simple way we are expecting.)
* match what clause_selectivity() would do. *
* NB: for consistency of results, this fragment of code had better
* match what clause_selectivity() would do in the cases it handles.
*/ */
if (varRelid != 0 || NumRelids(clause) == 1) if (varRelid != 0 || NumRelids(clause) == 1)
{ {
...@@ -134,41 +136,48 @@ clauselist_selectivity(Query *root, ...@@ -134,41 +136,48 @@ clauselist_selectivity(Query *root,
get_relattval(clause, varRelid, get_relattval(clause, varRelid,
&relidx, &attno, &constval, &flag); &relidx, &attno, &constval, &flag);
if (relidx != 0 && (flag & SEL_CONSTANT)) if (relidx != 0)
{ {
/* if get_relattval succeeded, it must be an opclause */ /* if get_relattval succeeded, it must be an opclause */
Oid opno = ((Oper *) ((Expr *) clause)->oper)->opno; Var *other;
RegProcedure oprrest = get_oprrest(opno);
if (!oprrest) other = (flag & SEL_RIGHT) ? get_rightop((Expr *) clause) :
s2 = (Selectivity) 0.5; get_leftop((Expr *) clause);
else if (IsA(other, Const) || IsA(other, Param))
s2 = restriction_selectivity(oprrest, opno,
getrelid(relidx,
root->rtable),
attno,
constval, flag);
/*
* If we reach here, we have computed the same result that
* clause_selectivity would, so we can just use s2 if it's
* the wrong oprrest. But if it's the right oprrest, add
* the clause to rqlist for later processing.
*/
switch (oprrest)
{ {
case F_SCALARLTSEL: Oid opno = ((Oper *) ((Expr *) clause)->oper)->opno;
addRangeClause(&rqlist, clause, flag, true, s2); RegProcedure oprrest = get_oprrest(opno);
break;
case F_SCALARGTSEL: if (!oprrest)
addRangeClause(&rqlist, clause, flag, false, s2); s2 = (Selectivity) 0.5;
break; else
default: s2 = restriction_selectivity(oprrest, opno,
/* Just merge the selectivity in generically */ getrelid(relidx,
s1 = s1 * s2; root->rtable),
break; attno,
constval, flag);
/*
* If we reach here, we have computed the same result that
* clause_selectivity would, so we can just use s2 if it's
* the wrong oprrest. But if it's the right oprrest, add
* the clause to rqlist for later processing.
*/
switch (oprrest)
{
case F_SCALARLTSEL:
addRangeClause(&rqlist, clause, flag, true, s2);
break;
case F_SCALARGTSEL:
addRangeClause(&rqlist, clause, flag, false, s2);
break;
default:
/* Just merge the selectivity in generically */
s1 = s1 * s2;
break;
}
continue; /* drop to loop bottom */
} }
continue; /* drop to loop bottom */
} }
} }
/* Not the right form, so treat it generically. */ /* Not the right form, so treat it generically. */
...@@ -374,7 +383,7 @@ clause_selectivity(Query *root, ...@@ -374,7 +383,7 @@ clause_selectivity(Query *root,
BooleanEqualOperator, BooleanEqualOperator,
getrelid(varno, root->rtable), getrelid(varno, root->rtable),
((Var *) clause)->varattno, ((Var *) clause)->varattno,
Int8GetDatum(true), BoolGetDatum(true),
SEL_CONSTANT | SEL_RIGHT); SEL_CONSTANT | SEL_RIGHT);
/* an outer-relation bool var is taken as always true... */ /* an outer-relation bool var is taken as always true... */
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment