Commit deee4e16 authored by Tom Lane's avatar Tom Lane

Make eqsel produce better results for boolean columns,

and make scalarltsel a little more forgiving at the boundaries of the
known range of a column value.
parent 9c80cceb
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.55 2000/02/15 20:49:21 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.56 2000/02/16 00:59:27 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -144,10 +144,13 @@ eqsel(Oid opid, ...@@ -144,10 +144,13 @@ eqsel(Oid opid,
selec = 1.0 - commonfrac - nullfrac; selec = 1.0 - commonfrac - nullfrac;
if (selec > commonfrac) if (selec > commonfrac)
selec = commonfrac; selec = commonfrac;
/* and in fact it's probably less, so apply a fudge /* and in fact it's probably less, so we should apply
* factor. * a fudge factor. The only case where we don't is
* for a boolean column, where indeed we have estimated
* the less-common value's frequency exactly!
*/ */
selec *= 0.5; if (typid != BOOLOID)
selec *= 0.5;
} }
} }
else else
...@@ -310,20 +313,20 @@ scalarltsel(Oid opid, ...@@ -310,20 +313,20 @@ scalarltsel(Oid opid,
/* If we trusted the stats fully, we could return a small or /* If we trusted the stats fully, we could return a small or
* large selec depending on which side of the single data point * large selec depending on which side of the single data point
* the constant is on. But it seems better to assume that the * the constant is on. But it seems better to assume that the
* stats are out of date and return a default... * stats are wrong and return a default...
*/ */
*result = DEFAULT_INEQ_SEL; *result = DEFAULT_INEQ_SEL;
} }
else if (val <= low || val >= high) else if (val < low || val > high)
{ {
/* If given value is outside the statistical range, return a /* If given value is outside the statistical range, return a
* small or large value; but not 0.0/1.0 since there is a chance * small or large value; but not 0.0/1.0 since there is a chance
* the stats are out of date. * the stats are out of date.
*/ */
if (flag & SEL_RIGHT) if (flag & SEL_RIGHT)
*result = (val <= low) ? 0.01 : 0.99; *result = (val < low) ? 0.001 : 0.999;
else else
*result = (val <= low) ? 0.99 : 0.01; *result = (val < low) ? 0.999 : 0.001;
} }
else else
{ {
......
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