99 *
1010 *
1111 * IDENTIFICATION
12- * $PostgreSQL: pgsql/src/backend/optimizer/util/predtest.c,v 1.18 2008/01/01 19:45:50 momjian Exp $
12+ * $PostgreSQL: pgsql/src/backend/optimizer/util/predtest.c,v 1.19 2008/01/12 00:11:39 tgl Exp $
1313 *
1414 *-------------------------------------------------------------------------
1515 */
@@ -82,7 +82,6 @@ static Node *arrayexpr_next_fn(PredIterInfo info);
8282static void arrayexpr_cleanup_fn (PredIterInfo info );
8383static bool predicate_implied_by_simple_clause (Expr * predicate ,Node * clause );
8484static bool predicate_refuted_by_simple_clause (Expr * predicate ,Node * clause );
85- static bool is_null_contradicts (NullTest * ntest ,Node * clause );
8685static Node * extract_not_arg (Node * clause );
8786static bool list_member_strip (List * list ,Expr * datum );
8887static bool btree_predicate_proof (Expr * predicate ,Node * clause ,
@@ -129,6 +128,14 @@ predicate_implied_by(List *predicate_list, List *restrictinfo_list)
129128 * This is NOT the same as !(predicate_implied_by), though it is similar
130129 * in the technique and structure of the code.
131130 *
131+ * An important fine point is that truth of the clauses must imply that
132+ * the predicate returns FALSE, not that it does not return TRUE. This
133+ * is normally used to try to refute CHECK constraints, and the only
134+ * thing we can assume about a CHECK constraint is that it didn't return
135+ * FALSE --- a NULL result isn't a violation per the SQL spec. (Someday
136+ * perhaps this code should be extended to support both "strong" and
137+ * "weak" refutation, but for now we only need "strong".)
138+ *
132139 * The top-level List structure of each list corresponds to an AND list.
133140 * We assume that eval_const_expressions() has been applied and so there
134141 * are no un-flattened ANDs or ORs (e.g., no AND immediately within an AND,
@@ -408,10 +415,11 @@ predicate_implied_by_recurse(Node *clause, Node *predicate)
408415 *
409416 * In addition, if the predicate is a NOT-clause then we can use
410417 *A R=> NOT B if:A => B
411- * while if the restriction clause is a NOT-clause then we can use
412- *NOT A R=> B if:B => A
413418 * This works for several different SQL constructs that assert the non-truth
414419 * of their argument, ie NOT, IS FALSE, IS NOT TRUE, IS UNKNOWN.
420+ * Unfortunately we *cannot* use
421+ *NOT A R=> B if:B => A
422+ * because this type of reasoning fails to prove that B doesn't yield NULL.
415423 *
416424 * Other comments are as for predicate_implied_by_recurse().
417425 *----------
@@ -595,13 +603,21 @@ predicate_refuted_by_recurse(Node *clause, Node *predicate)
595603
596604case CLASS_ATOM :
597605
606+ #ifdef NOT_USED
598607/*
599608 * If A is a NOT-clause, A R=> B if B => A's arg
609+ *
610+ * Unfortunately not: this would only prove that B is not-TRUE,
611+ * not that it's not NULL either. Keep this code as a comment
612+ * because it would be useful if we ever had a need for the
613+ * weak form of refutation.
600614 */
601615not_arg = extract_not_arg (clause );
602616if (not_arg &&
603617predicate_implied_by_recurse (predicate ,not_arg ))
604618return true;
619+ #endif
620+
605621switch (pclass )
606622{
607623case CLASS_AND :
@@ -990,9 +1006,11 @@ predicate_implied_by_simple_clause(Expr *predicate, Node *clause)
9901006 * When the predicate is of the form "foo IS NULL", we can conclude that
9911007 * the predicate is refuted if the clause is a strict operator or function
9921008 * that has "foo" as an input (see notes for implication case), or if the
993- * clause is "foo IS NOT NULL". Conversely a clause "foo IS NULL" refutes
994- * predicates of those types. (The motivation for covering these cases is
995- * to support using IS NULL/IS NOT NULL as partition-defining constraints.)
1009+ * clause is "foo IS NOT NULL". A clause "foo IS NULL" refutes a predicate
1010+ * "foo IS NOT NULL", but unfortunately does not refute strict predicates,
1011+ * because we are looking for strong refutation. (The motivation for covering
1012+ * these cases is to support using IS NULL/IS NOT NULL as partition-defining
1013+ * constraints.)
9961014 *
9971015 * Finally, we may be able to deduce something using knowledge about btree
9981016 * operator families; this is encapsulated in btree_predicate_proof().
@@ -1010,17 +1028,47 @@ predicate_refuted_by_simple_clause(Expr *predicate, Node *clause)
10101028if (predicate && IsA (predicate ,NullTest )&&
10111029((NullTest * )predicate )-> nulltesttype == IS_NULL )
10121030{
1013- if (is_null_contradicts ((NullTest * )predicate ,clause ))
1031+ Expr * isnullarg = ((NullTest * )predicate )-> arg ;
1032+
1033+ /* row IS NULL does not act in the simple way we have in mind */
1034+ if (type_is_rowtype (exprType ((Node * )isnullarg )))
1035+ return false;
1036+
1037+ /* Any strict op/func on foo refutes foo IS NULL */
1038+ if (is_opclause (clause )&&
1039+ list_member_strip (((OpExpr * )clause )-> args ,isnullarg )&&
1040+ op_strict (((OpExpr * )clause )-> opno ))
1041+ return true;
1042+ if (is_funcclause (clause )&&
1043+ list_member_strip (((FuncExpr * )clause )-> args ,isnullarg )&&
1044+ func_strict (((FuncExpr * )clause )-> funcid ))
10141045return true;
1046+
1047+ /* foo IS NOT NULL refutes foo IS NULL */
1048+ if (clause && IsA (clause ,NullTest )&&
1049+ ((NullTest * )clause )-> nulltesttype == IS_NOT_NULL &&
1050+ equal (((NullTest * )clause )-> arg ,isnullarg ))
1051+ return true;
1052+
10151053return false;/* we can't succeed below... */
10161054}
10171055
10181056/* Try the clause-IS-NULL case */
10191057if (clause && IsA (clause ,NullTest )&&
10201058((NullTest * )clause )-> nulltesttype == IS_NULL )
10211059{
1022- if (is_null_contradicts ((NullTest * )clause , (Node * )predicate ))
1060+ Expr * isnullarg = ((NullTest * )clause )-> arg ;
1061+
1062+ /* row IS NULL does not act in the simple way we have in mind */
1063+ if (type_is_rowtype (exprType ((Node * )isnullarg )))
1064+ return false;
1065+
1066+ /* foo IS NULL refutes foo IS NOT NULL */
1067+ if (predicate && IsA (predicate ,NullTest )&&
1068+ ((NullTest * )predicate )-> nulltesttype == IS_NOT_NULL &&
1069+ equal (((NullTest * )predicate )-> arg ,isnullarg ))
10231070return true;
1071+
10241072return false;/* we can't succeed below... */
10251073}
10261074
@@ -1029,40 +1077,6 @@ predicate_refuted_by_simple_clause(Expr *predicate, Node *clause)
10291077}
10301078
10311079
1032- /*
1033- * Check whether a "foo IS NULL" test contradicts clause. (We say
1034- * "contradicts" rather than "refutes" because the refutation goes
1035- * both ways.)
1036- */
1037- static bool
1038- is_null_contradicts (NullTest * ntest ,Node * clause )
1039- {
1040- Expr * isnullarg = ntest -> arg ;
1041-
1042- /* row IS NULL does not act in the simple way we have in mind */
1043- if (type_is_rowtype (exprType ((Node * )isnullarg )))
1044- return false;
1045-
1046- /* foo IS NULL contradicts any strict op/func on foo */
1047- if (is_opclause (clause )&&
1048- list_member_strip (((OpExpr * )clause )-> args ,isnullarg )&&
1049- op_strict (((OpExpr * )clause )-> opno ))
1050- return true;
1051- if (is_funcclause (clause )&&
1052- list_member_strip (((FuncExpr * )clause )-> args ,isnullarg )&&
1053- func_strict (((FuncExpr * )clause )-> funcid ))
1054- return true;
1055-
1056- /* foo IS NULL contradicts foo IS NOT NULL */
1057- if (clause && IsA (clause ,NullTest )&&
1058- ((NullTest * )clause )-> nulltesttype == IS_NOT_NULL &&
1059- equal (((NullTest * )clause )-> arg ,isnullarg ))
1060- return true;
1061-
1062- return false;
1063- }
1064-
1065-
10661080/*
10671081 * If clause asserts the non-truth of a subclause, return that subclause;
10681082 * otherwise return NULL.