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,9 +136,15 @@ clauselist_selectivity(Query *root, ...@@ -134,9 +136,15 @@ 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 */
Var *other;
other = (flag & SEL_RIGHT) ? get_rightop((Expr *) clause) :
get_leftop((Expr *) clause);
if (IsA(other, Const) || IsA(other, Param))
{
Oid opno = ((Oper *) ((Expr *) clause)->oper)->opno; Oid opno = ((Oper *) ((Expr *) clause)->oper)->opno;
RegProcedure oprrest = get_oprrest(opno); RegProcedure oprrest = get_oprrest(opno);
...@@ -171,6 +179,7 @@ clauselist_selectivity(Query *root, ...@@ -171,6 +179,7 @@ clauselist_selectivity(Query *root,
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. */
s2 = clause_selectivity(root, clause, varRelid); s2 = clause_selectivity(root, clause, varRelid);
s1 = s1 * s2; s1 = s1 * s2;
...@@ -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