diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2007-04-06 22:33:43 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2007-04-06 22:33:43 +0000 |
commit | f02a82b6adad1af75499c4ac7221bbd94e3c4fbf (patch) | |
tree | d15b0a2a52d95e046bb3945f4487982943ed211e /src/backend/executor/nodeIndexscan.c | |
parent | 146c83c045625d6f0072dd96045ebbc54582be05 (diff) | |
download | postgresql-f02a82b6adad1af75499c4ac7221bbd94e3c4fbf.tar.gz postgresql-f02a82b6adad1af75499c4ac7221bbd94e3c4fbf.zip |
Make 'col IS NULL' clauses be indexable conditions.
Teodor Sigaev, with some kibitzing from Tom Lane.
Diffstat (limited to 'src/backend/executor/nodeIndexscan.c')
-rw-r--r-- | src/backend/executor/nodeIndexscan.c | 38 |
1 files changed, 36 insertions, 2 deletions
diff --git a/src/backend/executor/nodeIndexscan.c b/src/backend/executor/nodeIndexscan.c index 5f0a66f92bb..d9136de0035 100644 --- a/src/backend/executor/nodeIndexscan.c +++ b/src/backend/executor/nodeIndexscan.c @@ -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)); |