summaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/selfuncs.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/adt/selfuncs.c')
-rw-r--r--src/backend/utils/adt/selfuncs.c31
1 files changed, 26 insertions, 5 deletions
diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c
index 493df17b6c2..85e66a3b1c4 100644
--- a/src/backend/utils/adt/selfuncs.c
+++ b/src/backend/utils/adt/selfuncs.c
@@ -15,7 +15,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.220 2007/01/20 20:45:40 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.221 2007/01/22 20:00:40 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -2112,8 +2112,8 @@ icnlikejoinsel(PG_FUNCTION_ARGS)
* we can estimate how much of the input will actually be read. This
* can have a considerable impact on the cost when using indexscans.
*
- * clause should be a clause already known to be mergejoinable. opfamily and
- * strategy specify the sort ordering being used.
+ * clause should be a clause already known to be mergejoinable. opfamily,
+ * strategy, and nulls_first specify the sort ordering being used.
*
* *leftscan is set to the fraction of the left-hand variable expected
* to be scanned (0 to 1), and similarly *rightscan for the right-hand
@@ -2121,7 +2121,7 @@ icnlikejoinsel(PG_FUNCTION_ARGS)
*/
void
mergejoinscansel(PlannerInfo *root, Node *clause,
- Oid opfamily, int strategy,
+ Oid opfamily, int strategy, bool nulls_first,
Selectivity *leftscan,
Selectivity *rightscan)
{
@@ -2214,18 +2214,39 @@ mergejoinscansel(PlannerInfo *root, Node *clause,
/*
* Now, the fraction of the left variable that will be scanned is the
* fraction that's <= the right-side maximum value. But only believe
- * non-default estimates, else stick with our 1.0.
+ * non-default estimates, else stick with our 1.0. Also, if the sort
+ * order is nulls-first, we're going to have to read over any nulls too.
*/
selec = scalarineqsel(root, leop, false, &leftvar,
rightmax, op_righttype);
if (selec != DEFAULT_INEQ_SEL)
+ {
+ if (nulls_first && HeapTupleIsValid(leftvar.statsTuple))
+ {
+ Form_pg_statistic stats;
+
+ stats = (Form_pg_statistic) GETSTRUCT(leftvar.statsTuple);
+ selec += stats->stanullfrac;
+ CLAMP_PROBABILITY(selec);
+ }
*leftscan = selec;
+ }
/* And similarly for the right variable. */
selec = scalarineqsel(root, revleop, false, &rightvar,
leftmax, op_lefttype);
if (selec != DEFAULT_INEQ_SEL)
+ {
+ if (nulls_first && HeapTupleIsValid(rightvar.statsTuple))
+ {
+ Form_pg_statistic stats;
+
+ stats = (Form_pg_statistic) GETSTRUCT(rightvar.statsTuple);
+ selec += stats->stanullfrac;
+ CLAMP_PROBABILITY(selec);
+ }
*rightscan = selec;
+ }
/*
* Only one of the two fractions can really be less than 1.0; believe the