|
9 | 9 | * |
10 | 10 | * |
11 | 11 | * IDENTIFICATION |
12 | | - * $PostgreSQL: pgsql/src/backend/optimizer/util/predtest.c,v 1.15 2007/05/12 19:22:35 tgl Exp $ |
| 12 | + * $PostgreSQL: pgsql/src/backend/optimizer/util/predtest.c,v 1.16 2007/07/24 17:22:07 tgl Exp $ |
13 | 13 | * |
14 | 14 | *------------------------------------------------------------------------- |
15 | 15 | */ |
@@ -84,6 +84,7 @@ static bool predicate_implied_by_simple_clause(Expr *predicate, Node *clause); |
84 | 84 | staticboolpredicate_refuted_by_simple_clause(Expr*predicate,Node*clause); |
85 | 85 | staticboolis_null_contradicts(NullTest*ntest,Node*clause); |
86 | 86 | staticNode*extract_not_arg(Node*clause); |
| 87 | +staticboollist_member_strip(List*list,Expr*datum); |
87 | 88 | staticboolbtree_predicate_proof(Expr*predicate,Node*clause, |
88 | 89 | boolrefute_it); |
89 | 90 |
|
@@ -961,11 +962,11 @@ predicate_implied_by_simple_clause(Expr *predicate, Node *clause) |
961 | 962 | if (!type_is_rowtype(exprType((Node*)nonnullarg))) |
962 | 963 | { |
963 | 964 | if (is_opclause(clause)&& |
964 | | -list_member(((OpExpr*)clause)->args,nonnullarg)&& |
| 965 | +list_member_strip(((OpExpr*)clause)->args,nonnullarg)&& |
965 | 966 | op_strict(((OpExpr*)clause)->opno)) |
966 | 967 | return true; |
967 | 968 | if (is_funcclause(clause)&& |
968 | | -list_member(((FuncExpr*)clause)->args,nonnullarg)&& |
| 969 | +list_member_strip(((FuncExpr*)clause)->args,nonnullarg)&& |
969 | 970 | func_strict(((FuncExpr*)clause)->funcid)) |
970 | 971 | return true; |
971 | 972 | } |
@@ -1044,11 +1045,11 @@ is_null_contradicts(NullTest *ntest, Node *clause) |
1044 | 1045 |
|
1045 | 1046 | /* foo IS NULL contradicts any strict op/func on foo */ |
1046 | 1047 | if (is_opclause(clause)&& |
1047 | | -list_member(((OpExpr*)clause)->args,isnullarg)&& |
| 1048 | +list_member_strip(((OpExpr*)clause)->args,isnullarg)&& |
1048 | 1049 | op_strict(((OpExpr*)clause)->opno)) |
1049 | 1050 | return true; |
1050 | 1051 | if (is_funcclause(clause)&& |
1051 | | -list_member(((FuncExpr*)clause)->args,isnullarg)&& |
| 1052 | +list_member_strip(((FuncExpr*)clause)->args,isnullarg)&& |
1052 | 1053 | func_strict(((FuncExpr*)clause)->funcid)) |
1053 | 1054 | return true; |
1054 | 1055 |
|
@@ -1091,6 +1092,36 @@ extract_not_arg(Node *clause) |
1091 | 1092 | } |
1092 | 1093 |
|
1093 | 1094 |
|
| 1095 | +/* |
| 1096 | + * Check whether an Expr is equal() to any member of a list, ignoring |
| 1097 | + * any top-level RelabelType nodes. This is legitimate for the purposes |
| 1098 | + * we use it for (matching IS [NOT] NULL arguments to arguments of strict |
| 1099 | + * functions) because RelabelType doesn't change null-ness. It's helpful |
| 1100 | + * for cases such as a varchar argument of a strict function on text. |
| 1101 | + */ |
| 1102 | +staticbool |
| 1103 | +list_member_strip(List*list,Expr*datum) |
| 1104 | +{ |
| 1105 | +ListCell*cell; |
| 1106 | + |
| 1107 | +if (datum&&IsA(datum,RelabelType)) |
| 1108 | +datum= ((RelabelType*)datum)->arg; |
| 1109 | + |
| 1110 | +foreach(cell,list) |
| 1111 | +{ |
| 1112 | +Expr*elem= (Expr*)lfirst(cell); |
| 1113 | + |
| 1114 | +if (elem&&IsA(elem,RelabelType)) |
| 1115 | +elem= ((RelabelType*)elem)->arg; |
| 1116 | + |
| 1117 | +if (equal(elem,datum)) |
| 1118 | +return true; |
| 1119 | +} |
| 1120 | + |
| 1121 | +return false; |
| 1122 | +} |
| 1123 | + |
| 1124 | + |
1094 | 1125 | /* |
1095 | 1126 | * Define an "operator implication table" for btree operators ("strategies"), |
1096 | 1127 | * and a similar table for refutation. |
|