Commit 31d1f233 authored by Tom Lane's avatar Tom Lane

Teach simplify_boolean_equality to simplify the forms foo <> true and

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.
parent 400e2c93
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * HISTORY
* AUTHOR DATE MAJOR EVENT * AUTHOR DATE MAJOR EVENT
...@@ -92,7 +92,7 @@ static List *simplify_or_arguments(List *args, ...@@ -92,7 +92,7 @@ static List *simplify_or_arguments(List *args,
static List *simplify_and_arguments(List *args, static List *simplify_and_arguments(List *args,
eval_const_expressions_context *context, eval_const_expressions_context *context,
bool *haveNull, bool *forceFalse); 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, static Expr *simplify_function(Oid funcid,
Oid result_type, int32 result_typmod, List **args, Oid result_type, int32 result_typmod, List **args,
bool allow_inline, bool allow_inline,
...@@ -2186,12 +2186,14 @@ eval_const_expressions_mutator(Node *node, ...@@ -2186,12 +2186,14 @@ eval_const_expressions_mutator(Node *node,
return (Node *) simple; return (Node *) simple;
/* /*
* If the operator is boolean equality, we know how to simplify cases * If the operator is boolean equality or inequality, we know how to
* involving one constant and one non-constant argument. * 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 */ if (simple) /* successfully simplified it */
return (Node *) simple; return (Node *) simple;
} }
...@@ -3165,21 +3167,23 @@ simplify_and_arguments(List *args, ...@@ -3165,21 +3167,23 @@ simplify_and_arguments(List *args,
/* /*
* Subroutine for eval_const_expressions: try to simplify boolean equality * 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 * Returns a simplified expression if successful, or NULL if cannot
* simplify the expression. * 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 * 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. * example, partial index matching.
* *
* We come here only if simplify_function has failed; therefore we cannot * We come here only if simplify_function has failed; therefore we cannot
* see two constant inputs, nor a constant-NULL input. * see two constant inputs, nor a constant-NULL input.
*/ */
static Expr * static Expr *
simplify_boolean_equality(List *args) simplify_boolean_equality(Oid opno, List *args)
{ {
Expr *leftop; Expr *leftop;
Expr *rightop; Expr *rightop;
...@@ -3190,18 +3194,38 @@ simplify_boolean_equality(List *args) ...@@ -3190,18 +3194,38 @@ simplify_boolean_equality(List *args)
if (leftop && IsA(leftop, Const)) if (leftop && IsA(leftop, Const))
{ {
Assert(!((Const *) leftop)->constisnull); Assert(!((Const *) leftop)->constisnull);
if (DatumGetBool(((Const *) leftop)->constvalue)) if (opno == BooleanEqualOperator)
return rightop; /* true = foo */ {
if (DatumGetBool(((Const *) leftop)->constvalue))
return rightop; /* true = foo */
else
return make_notclause(rightop); /* false = foo */
}
else 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)) if (rightop && IsA(rightop, Const))
{ {
Assert(!((Const *) rightop)->constisnull); Assert(!((Const *) rightop)->constisnull);
if (DatumGetBool(((Const *) rightop)->constvalue)) if (opno == BooleanEqualOperator)
return leftop; /* foo = true */ {
if (DatumGetBool(((Const *) rightop)->constvalue))
return leftop; /* foo = true */
else
return make_notclause(leftop); /* foo = false */
}
else 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; return NULL;
} }
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 * NOTES
* the genbki.sh script reads this file and generates .bki * 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 ...@@ -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 = 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 = 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 )); 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 )); DATA(insert OID = 91 ( "=" PGNSP PGUID b t t 16 16 16 91 85 booleq eqsel eqjoinsel ));
#define BooleanEqualOperator 91 #define BooleanEqualOperator 91
DATA(insert OID = 1694 ( "<=" PGNSP PGUID b f f 16 16 16 1695 59 boolle scalarltsel scalarltjoinsel )); DATA(insert OID = 1694 ( "<=" PGNSP PGUID b f f 16 16 16 1695 59 boolle scalarltsel scalarltjoinsel ));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment