]> granicus.if.org Git - postgresql/commitdiff
Teach simplify_boolean_equality to simplify the forms foo <> true and
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 20 Jul 2009 00:24:30 +0000 (00:24 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 20 Jul 2009 00:24:30 +0000 (00:24 +0000)
foo <> false, along with its previous duties of simplifying foo = true
and foo = false.  (All of these are equivalent to just foo or NOT foo
as the case may be.)  It's not clear how often this is really useful;
but it costs almost nothing to do, and it seems some people think we
should be smart about such cases.  Per recent bug report.

src/backend/optimizer/util/clauses.c
src/include/catalog/pg_operator.h

index 75c5d0c94d095c0d34c1d7df697031f8010014e8..f2038c73af14282d0f52ae3c2d599d07a542f6ec 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.277 2009/06/11 14:48:59 momjian Exp $
+ *       $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.278 2009/07/20 00:24:30 tgl Exp $
  *
  * HISTORY
  *       AUTHOR                        DATE                    MAJOR EVENT
@@ -92,7 +92,7 @@ static List *simplify_or_arguments(List *args,
 static List *simplify_and_arguments(List *args,
                                           eval_const_expressions_context *context,
                                           bool *haveNull, bool *forceFalse);
-static Expr *simplify_boolean_equality(List *args);
+static Expr *simplify_boolean_equality(Oid opno, List *args);
 static Expr *simplify_function(Oid funcid,
                                  Oid result_type, int32 result_typmod, List **args,
                                  bool allow_inline,
@@ -2186,12 +2186,14 @@ eval_const_expressions_mutator(Node *node,
                        return (Node *) simple;
 
                /*
-                * If the operator is boolean equality, we know how to simplify cases
-                * involving one constant and one non-constant argument.
+                * If the operator is boolean equality or inequality, we know how to
+                * simplify cases involving one constant and one non-constant
+                * argument.
                 */
-               if (expr->opno == BooleanEqualOperator)
+               if (expr->opno == BooleanEqualOperator ||
+                       expr->opno == BooleanNotEqualOperator)
                {
-                       simple = simplify_boolean_equality(args);
+                       simple = simplify_boolean_equality(expr->opno, args);
                        if (simple)                     /* successfully simplified it */
                                return (Node *) simple;
                }
@@ -3165,21 +3167,23 @@ simplify_and_arguments(List *args,
 
 /*
  * Subroutine for eval_const_expressions: try to simplify boolean equality
+ * or inequality condition
  *
- * Input is the list of simplified arguments to the operator.
+ * Inputs are the operator OID and the simplified arguments to the operator.
  * Returns a simplified expression if successful, or NULL if cannot
  * simplify the expression.
  *
- * The idea here is to reduce "x = true" to "x" and "x = false" to "NOT x".
+ * The idea here is to reduce "x = true" to "x" and "x = false" to "NOT x",
+ * or similarly "x <> true" to "NOT x" and "x <> false" to "x".
  * This is only marginally useful in itself, but doing it in constant folding
- * ensures that we will recognize the two forms as being equivalent in, for
+ * ensures that we will recognize these forms as being equivalent in, for
  * example, partial index matching.
  *
  * We come here only if simplify_function has failed; therefore we cannot
  * see two constant inputs, nor a constant-NULL input.
  */
 static Expr *
-simplify_boolean_equality(List *args)
+simplify_boolean_equality(Oid opno, List *args)
 {
        Expr       *leftop;
        Expr       *rightop;
@@ -3190,18 +3194,38 @@ simplify_boolean_equality(List *args)
        if (leftop && IsA(leftop, Const))
        {
                Assert(!((Const *) leftop)->constisnull);
-               if (DatumGetBool(((Const *) leftop)->constvalue))
-                       return rightop;         /* true = foo */
+               if (opno == BooleanEqualOperator)
+               {
+                       if (DatumGetBool(((Const *) leftop)->constvalue))
+                               return rightop;         /* true = foo */
+                       else
+                               return make_notclause(rightop);         /* false = foo */
+               }
                else
-                       return make_notclause(rightop);         /* false = foo */
+               {
+                       if (DatumGetBool(((Const *) leftop)->constvalue))
+                               return make_notclause(rightop);         /* true <> foo */
+                       else
+                               return rightop;         /* false <> foo */
+               }
        }
        if (rightop && IsA(rightop, Const))
        {
                Assert(!((Const *) rightop)->constisnull);
-               if (DatumGetBool(((Const *) rightop)->constvalue))
-                       return leftop;          /* foo = true */
+               if (opno == BooleanEqualOperator)
+               {
+                       if (DatumGetBool(((Const *) rightop)->constvalue))
+                               return leftop;          /* foo = true */
+                       else
+                               return make_notclause(leftop);          /* foo = false */
+               }
                else
-                       return make_notclause(leftop);          /* foo = false */
+               {
+                       if (DatumGetBool(((Const *) rightop)->constvalue))
+                               return make_notclause(leftop);          /* foo <> true */
+                       else
+                               return leftop;          /* foo <> false */
+               }
        }
        return NULL;
 }
index 8cea420cd694f3808ecc39f45dbea569e81c4dc9..e4aef392dea56e963e57f2264d832e06d035c9a8 100644 (file)
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/catalog/pg_operator.h,v 1.166 2009/06/11 14:49:09 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/catalog/pg_operator.h,v 1.167 2009/07/20 00:24:30 tgl Exp $
  *
  * NOTES
  *       the genbki.sh script reads this file and generates .bki
@@ -93,6 +93,7 @@ DATA(insert OID =  82 ( ">="     PGNSP PGUID b f f    23      20      16 420  37 int48ge scalar
 DATA(insert OID =  58 ( "<"               PGNSP PGUID b f f    16      16      16      59      1695 boollt scalarltsel scalarltjoinsel ));
 DATA(insert OID =  59 ( ">"               PGNSP PGUID b f f    16      16      16      58      1694 boolgt scalargtsel scalargtjoinsel ));
 DATA(insert OID =  85 ( "<>"      PGNSP PGUID b f f    16      16      16      85      91 boolne neqsel neqjoinsel ));
+#define BooleanNotEqualOperator   85
 DATA(insert OID =  91 ( "="               PGNSP PGUID b t t    16      16      16      91      85 booleq eqsel eqjoinsel ));
 #define BooleanEqualOperator   91
 DATA(insert OID = 1694 (  "<="    PGNSP PGUID b f f    16      16      16 1695 59 boolle scalarltsel scalarltjoinsel ));