aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/selfuncs.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2010-01-01 21:53:49 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2010-01-01 21:53:49 +0000
commit29c4ad98293e3c5cb3fcdd413a3f4904efff8762 (patch)
tree4e4eeea2655e87eca4d3d0dd97f3e2b7d5f1e032 /src/backend/utils/adt/selfuncs.c
parent15faca259651c065bb20e746777f5fb9eb9d50a1 (diff)
downloadpostgresql-29c4ad98293e3c5cb3fcdd413a3f4904efff8762.tar.gz
postgresql-29c4ad98293e3c5cb3fcdd413a3f4904efff8762.zip
Support "x IS NOT NULL" clauses as indexscan conditions. This turns out
to be just a minor extension of the previous patch that made "x IS NULL" indexable, because we can treat the IS NOT NULL condition as if it were "x < NULL" or "x > NULL" (depending on the index's NULLS FIRST/LAST option), just like IS NULL is treated like "x = NULL". Aside from any possible usefulness in its own right, this is an important improvement for index-optimized MAX/MIN aggregates: it is now reliably possible to get a column's min or max value cheaply, even when there are a lot of nulls cluttering the interesting end of the index.
Diffstat (limited to 'src/backend/utils/adt/selfuncs.c')
-rw-r--r--src/backend/utils/adt/selfuncs.c28
1 files changed, 15 insertions, 13 deletions
diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c
index 8bc26cb6e97..56e3a085974 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.264 2009/12/29 20:11:45 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/selfuncs.c,v 1.265 2010/01/01 21:53:49 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -5614,7 +5614,7 @@ btcostestimate(PG_FUNCTION_ARGS)
int indexcol;
bool eqQualHere;
bool found_saop;
- bool found_null_op;
+ bool found_is_null_op;
double num_sa_scans;
ListCell *l;
@@ -5639,7 +5639,7 @@ btcostestimate(PG_FUNCTION_ARGS)
indexcol = 0;
eqQualHere = false;
found_saop = false;
- found_null_op = false;
+ found_is_null_op = false;
num_sa_scans = 1;
foreach(l, indexQuals)
{
@@ -5680,12 +5680,14 @@ btcostestimate(PG_FUNCTION_ARGS)
{
NullTest *nt = (NullTest *) clause;
- Assert(nt->nulltesttype == IS_NULL);
leftop = (Node *) nt->arg;
rightop = NULL;
clause_op = InvalidOid;
- found_null_op = true;
- is_null_op = true;
+ if (nt->nulltesttype == IS_NULL)
+ {
+ found_is_null_op = true;
+ is_null_op = true;
+ }
}
else
{
@@ -5725,12 +5727,7 @@ btcostestimate(PG_FUNCTION_ARGS)
}
}
/* check for equality operator */
- if (is_null_op)
- {
- /* IS NULL is like = for purposes of selectivity determination */
- eqQualHere = true;
- }
- else
+ if (OidIsValid(clause_op))
{
op_strategy = get_op_opfamily_strategy(clause_op,
index->opfamily[indexcol]);
@@ -5738,6 +5735,11 @@ btcostestimate(PG_FUNCTION_ARGS)
if (op_strategy == BTEqualStrategyNumber)
eqQualHere = true;
}
+ else if (is_null_op)
+ {
+ /* IS NULL is like = for purposes of selectivity determination */
+ eqQualHere = true;
+ }
/* count up number of SA scans induced by indexBoundQuals only */
if (IsA(clause, ScalarArrayOpExpr))
{
@@ -5760,7 +5762,7 @@ btcostestimate(PG_FUNCTION_ARGS)
indexcol == index->ncolumns - 1 &&
eqQualHere &&
!found_saop &&
- !found_null_op)
+ !found_is_null_op)
numIndexTuples = 1.0;
else
{