|
9 | 9 | * |
10 | 10 | * |
11 | 11 | * IDENTIFICATION |
12 | | - * $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.156 2004/01/0722:02:48 tgl Exp $ |
| 12 | + * $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.157 2004/03/0705:43:53 tgl Exp $ |
13 | 13 | * |
14 | 14 | *------------------------------------------------------------------------- |
15 | 15 | */ |
@@ -965,24 +965,38 @@ static const StrategyNumber |
965 | 965 | }; |
966 | 966 |
|
967 | 967 |
|
968 | | -/* |
| 968 | +/*---------- |
969 | 969 | * pred_test_simple_clause |
970 | 970 | * Does the "predicate inclusion test" for a "simple clause" predicate |
971 | 971 | * and a "simple clause" restriction. |
972 | 972 | * |
973 | | - * We have two strategies for determining whether one simple clause |
974 | | - * implies another.A simple and general way is to see if they are |
975 | | - * equal(); this works for any kind of expression. (Actually, there |
976 | | - * is an implied assumption that the functions in the expression are |
977 | | - * immutable, ie dependent only on their input arguments --- but this |
978 | | - * was checked for the predicate by CheckPredicate().) |
| 973 | + * We have three strategies for determining whether one simple clause |
| 974 | + * implies another: |
| 975 | + * |
| 976 | + * A simple and general way is to see if they are equal(); this works for any |
| 977 | + * kind of expression. (Actually, there is an implied assumption that the |
| 978 | + * functions in the expression are immutable, ie dependent only on their input |
| 979 | + * arguments --- but this was checked for the predicate by CheckPredicate().) |
979 | 980 | * |
980 | | - * Our other way works only for (binary boolean) operators that are |
981 | | - * in some btree operator class. We use the above operator implication |
982 | | - * table to be able to derive implications between nonidentical clauses. |
| 981 | + * When the predicate is of the form "foo IS NOT NULL", we can conclude that |
| 982 | + * the predicate is implied if the clause is a strict operator or function |
| 983 | + * that has "foo" as an input. In this case the clause must yield NULL when |
| 984 | + * "foo" is NULL, which we can take as equivalent to FALSE because we know |
| 985 | + * we are within an AND/OR subtree of a WHERE clause. (Again, "foo" is |
| 986 | + * already known immutable, so the clause will certainly always fail.) |
983 | 987 | * |
984 | | - * Eventually, rtree operators could also be handled by defining an |
985 | | - * appropriate "RT_implic_table" array. |
| 988 | + * Our other way works only for binary boolean opclauses of the form |
| 989 | + * "foo op constant", where "foo" is the same in both clauses. The operators |
| 990 | + * and constants can be different but the operators must be in the same btree |
| 991 | + * operator class. We use the above operator implication table to be able to |
| 992 | + * derive implications between nonidentical clauses. (Note: "foo" is known |
| 993 | + * immutable, and constants are surely immutable, and we assume that operators |
| 994 | + * that are in btree opclasses are immutable, so there's no need to do extra |
| 995 | + * mutability checks in this case either.) |
| 996 | + * |
| 997 | + * Eventually, rtree operators could also be handled by defining an |
| 998 | + * appropriate "RT_implic_table" array. |
| 999 | + *---------- |
986 | 1000 | */ |
987 | 1001 | staticbool |
988 | 1002 | pred_test_simple_clause(Expr*predicate,Node*clause) |
@@ -1020,6 +1034,23 @@ pred_test_simple_clause(Expr *predicate, Node *clause) |
1020 | 1034 | if (equal((Node*)predicate,clause)) |
1021 | 1035 | return true; |
1022 | 1036 |
|
| 1037 | +/* Next try the IS NOT NULL case */ |
| 1038 | +if (predicate&&IsA(predicate,NullTest)&& |
| 1039 | +((NullTest*)predicate)->nulltesttype==IS_NOT_NULL) |
| 1040 | +{ |
| 1041 | +Expr*nonnullarg= ((NullTest*)predicate)->arg; |
| 1042 | + |
| 1043 | +if (is_opclause(clause)&& |
| 1044 | +member(nonnullarg, ((OpExpr*)clause)->args)&& |
| 1045 | +op_strict(((OpExpr*)clause)->opno)) |
| 1046 | +return true; |
| 1047 | +if (is_funcclause(clause)&& |
| 1048 | +member(nonnullarg, ((FuncExpr*)clause)->args)&& |
| 1049 | +func_strict(((FuncExpr*)clause)->funcid)) |
| 1050 | +return true; |
| 1051 | +return false;/* we can't succeed below... */ |
| 1052 | +} |
| 1053 | + |
1023 | 1054 | /* |
1024 | 1055 | * Can't do anything more unless they are both binary opclauses with a |
1025 | 1056 | * Const on one side, and identical subexpressions on the other sides. |
|