diff options
Diffstat (limited to 'src/backend/optimizer')
-rw-r--r-- | src/backend/optimizer/path/indxpath.c | 26 | ||||
-rw-r--r-- | src/backend/optimizer/plan/createplan.c | 46 | ||||
-rw-r--r-- | src/backend/optimizer/util/plancat.c | 3 |
3 files changed, 60 insertions, 15 deletions
diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c index 7197658ae9b..176f2a66387 100644 --- a/src/backend/optimizer/path/indxpath.c +++ b/src/backend/optimizer/path/indxpath.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.218 2007/03/21 22:18:12 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.219 2007/04/06 22:33:42 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1050,6 +1050,7 @@ match_clause_to_indexcol(IndexOptInfo *index, * Clause must be a binary opclause, or possibly a ScalarArrayOpExpr * (which is always binary, by definition). Or it could be a * RowCompareExpr, which we pass off to match_rowcompare_to_indexcol(). + * Or, if the index supports it, we can handle IS NULL clauses. */ if (is_opclause(clause)) { @@ -1083,6 +1084,15 @@ match_clause_to_indexcol(IndexOptInfo *index, (RowCompareExpr *) clause, outer_relids); } + else if (index->amsearchnulls && IsA(clause, NullTest)) + { + NullTest *nt = (NullTest *) clause; + + if (nt->nulltesttype == IS_NULL && + match_index_to_operand((Node *) nt->arg, indexcol, index)) + return true; + return false; + } else return false; @@ -2102,8 +2112,8 @@ expand_indexqual_conditions(IndexOptInfo *index, List *clausegroups) } /* - * Else it must be an opclause (usual case), ScalarArrayOp, or - * RowCompare + * Else it must be an opclause (usual case), ScalarArrayOp, + * RowCompare, or NullTest */ if (is_opclause(clause)) { @@ -2123,6 +2133,16 @@ expand_indexqual_conditions(IndexOptInfo *index, List *clausegroups) index, indexcol)); } + else if (IsA(clause, NullTest)) + { + Assert(index->amsearchnulls); + resultquals = lappend(resultquals, + make_restrictinfo(clause, + true, + false, + false, + NULL)); + } else elog(ERROR, "unsupported indexqual type: %d", (int) nodeTag(clause)); diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c index 6c4bde14213..9b9645faf28 100644 --- a/src/backend/optimizer/plan/createplan.c +++ b/src/backend/optimizer/plan/createplan.c @@ -10,7 +10,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.227 2007/02/25 17:44:01 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.228 2007/04/06 22:33:42 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -18,6 +18,7 @@ #include <limits.h> +#include "access/skey.h" #include "nodes/makefuncs.h" #include "optimizer/clauses.h" #include "optimizer/cost.h" @@ -1821,6 +1822,7 @@ fix_indexqual_references(List *indexquals, IndexPath *index_path, Oid stratlefttype; Oid stratrighttype; bool recheck; + bool is_null_op = false; Assert(IsA(rinfo, RestrictInfo)); @@ -1907,6 +1909,17 @@ fix_indexqual_references(List *indexquals, IndexPath *index_path, &opfamily); clause_op = saop->opno; } + else if (IsA(clause, NullTest)) + { + NullTest *nt = (NullTest *) clause; + + Assert(nt->nulltesttype == IS_NULL); + nt->arg = (Expr *) fix_indexqual_operand((Node *) nt->arg, + index, + &opfamily); + is_null_op = true; + clause_op = InvalidOid; /* keep compiler quiet */ + } else { elog(ERROR, "unsupported indexqual type: %d", @@ -1916,16 +1929,27 @@ fix_indexqual_references(List *indexquals, IndexPath *index_path, *fixed_indexquals = lappend(*fixed_indexquals, clause); - /* - * Look up the (possibly commuted) operator in the operator family to - * get its strategy number and the recheck indicator. This also - * double-checks that we found an operator matching the index. - */ - get_op_opfamily_properties(clause_op, opfamily, - &stratno, - &stratlefttype, - &stratrighttype, - &recheck); + if (is_null_op) + { + /* IS NULL doesn't have a clause_op */ + stratno = InvalidStrategy; + stratrighttype = InvalidOid; + /* We assume it's non-lossy ... might need more work someday */ + recheck = false; + } + else + { + /* + * Look up the (possibly commuted) operator in the operator family + * to get its strategy number and the recheck indicator. This also + * double-checks that we found an operator matching the index. + */ + get_op_opfamily_properties(clause_op, opfamily, + &stratno, + &stratlefttype, + &stratrighttype, + &recheck); + } *indexstrategy = lappend_int(*indexstrategy, stratno); *indexsubtype = lappend_oid(*indexsubtype, stratrighttype); diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index e52943a675e..33b081ffffd 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/optimizer/util/plancat.c,v 1.132 2007/01/20 23:13:01 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/util/plancat.c,v 1.133 2007/04/06 22:33:42 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -187,6 +187,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, info->relam = indexRelation->rd_rel->relam; info->amcostestimate = indexRelation->rd_am->amcostestimate; info->amoptionalkey = indexRelation->rd_am->amoptionalkey; + info->amsearchnulls = indexRelation->rd_am->amsearchnulls; /* * Fetch the ordering operators associated with the index, if any. |