1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-02 09:02:37 +03:00

Make 'col IS NULL' clauses be indexable conditions.

Teodor Sigaev, with some kibitzing from Tom Lane.
This commit is contained in:
Tom Lane
2007-04-06 22:33:43 +00:00
parent 146c83c045
commit f02a82b6ad
19 changed files with 432 additions and 110 deletions

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/executor/nodeIndexscan.c,v 1.120 2007/01/05 22:19:28 momjian Exp $
* $PostgreSQL: pgsql/src/backend/executor/nodeIndexscan.c,v 1.121 2007/04/06 22:33:42 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -599,7 +599,7 @@ ExecInitIndexScan(IndexScan *node, EState *estate, int eflags)
* The index quals are passed to the index AM in the form of a ScanKey array.
* This routine sets up the ScanKeys, fills in all constant fields of the
* ScanKeys, and prepares information about the keys that have non-constant
* comparison values. We divide index qual expressions into four types:
* comparison values. We divide index qual expressions into five types:
*
* 1. Simple operator with constant comparison value ("indexkey op constant").
* For these, we just fill in a ScanKey containing the constant value.
@ -620,6 +620,8 @@ ExecInitIndexScan(IndexScan *node, EState *estate, int eflags)
* (Note that we treat all array-expressions as requiring runtime evaluation,
* even if they happen to be constants.)
*
* 5. NullTest ("indexkey IS NULL"). We just fill in the ScanKey properly.
*
* Input params are:
*
* planstate: executor state node we are working for
@ -956,6 +958,38 @@ ExecIndexBuildScanKeys(PlanState *planstate, Relation index,
opfuncid, /* reg proc to use */
(Datum) 0); /* constant */
}
else if (IsA(clause, NullTest))
{
/* indexkey IS NULL */
Assert(((NullTest *) clause)->nulltesttype == IS_NULL);
/*
* argument should be the index key Var, possibly relabeled
*/
leftop = ((NullTest *) clause)->arg;
if (leftop && IsA(leftop, RelabelType))
leftop = ((RelabelType *) leftop)->arg;
Assert(leftop != NULL);
if (!(IsA(leftop, Var) &&
var_is_rel((Var *) leftop)))
elog(ERROR, "NullTest indexqual has wrong key");
varattno = ((Var *) leftop)->varattno;
/*
* initialize the scan key's fields appropriately
*/
ScanKeyEntryInitialize(this_scan_key,
SK_ISNULL | SK_SEARCHNULL,
varattno, /* attribute number to scan */
strategy, /* op's strategy */
subtype, /* strategy subtype */
InvalidOid, /* no reg proc for this */
(Datum) 0); /* constant */
}
else
elog(ERROR, "unsupported indexqual type: %d",
(int) nodeTag(clause));