Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 31d1f23

Browse files
committed
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.
1 parent 400e2c9 commit 31d1f23

File tree

2 files changed

+42
-17
lines changed

2 files changed

+42
-17
lines changed

src/backend/optimizer/util/clauses.c

+40-16
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.277 2009/06/11 14:48:59 momjian Exp $
11+
* $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.278 2009/07/20 00:24:30 tgl Exp $
1212
*
1313
* HISTORY
1414
* AUTHOR DATE MAJOR EVENT
@@ -92,7 +92,7 @@ static List *simplify_or_arguments(List *args,
9292
static List *simplify_and_arguments(List *args,
9393
eval_const_expressions_context *context,
9494
bool *haveNull, bool *forceFalse);
95-
static Expr *simplify_boolean_equality(List *args);
95+
static Expr *simplify_boolean_equality(Oid opno, List *args);
9696
static Expr *simplify_function(Oid funcid,
9797
Oid result_type, int32 result_typmod, List **args,
9898
bool allow_inline,
@@ -2186,12 +2186,14 @@ eval_const_expressions_mutator(Node *node,
21862186
return (Node *) simple;
21872187

21882188
/*
2189-
* If the operator is boolean equality, we know how to simplify cases
2190-
* involving one constant and one non-constant argument.
2189+
* If the operator is boolean equality or inequality, we know how to
2190+
* simplify cases involving one constant and one non-constant
2191+
* argument.
21912192
*/
2192-
if (expr->opno == BooleanEqualOperator)
2193+
if (expr->opno == BooleanEqualOperator ||
2194+
expr->opno == BooleanNotEqualOperator)
21932195
{
2194-
simple = simplify_boolean_equality(args);
2196+
simple = simplify_boolean_equality(expr->opno, args);
21952197
if (simple) /* successfully simplified it */
21962198
return (Node *) simple;
21972199
}
@@ -3165,21 +3167,23 @@ simplify_and_arguments(List *args,
31653167

31663168
/*
31673169
* Subroutine for eval_const_expressions: try to simplify boolean equality
3170+
* or inequality condition
31683171
*
3169-
* Input is the list of simplified arguments to the operator.
3172+
* Inputs are the operator OID and the simplified arguments to the operator.
31703173
* Returns a simplified expression if successful, or NULL if cannot
31713174
* simplify the expression.
31723175
*
3173-
* The idea here is to reduce "x = true" to "x" and "x = false" to "NOT x".
3176+
* The idea here is to reduce "x = true" to "x" and "x = false" to "NOT x",
3177+
* or similarly "x <> true" to "NOT x" and "x <> false" to "x".
31743178
* This is only marginally useful in itself, but doing it in constant folding
3175-
* ensures that we will recognize the two forms as being equivalent in, for
3179+
* ensures that we will recognize these forms as being equivalent in, for
31763180
* example, partial index matching.
31773181
*
31783182
* We come here only if simplify_function has failed; therefore we cannot
31793183
* see two constant inputs, nor a constant-NULL input.
31803184
*/
31813185
static Expr *
3182-
simplify_boolean_equality(List *args)
3186+
simplify_boolean_equality(Oid opno, List *args)
31833187
{
31843188
Expr *leftop;
31853189
Expr *rightop;
@@ -3190,18 +3194,38 @@ simplify_boolean_equality(List *args)
31903194
if (leftop && IsA(leftop, Const))
31913195
{
31923196
Assert(!((Const *) leftop)->constisnull);
3193-
if (DatumGetBool(((Const *) leftop)->constvalue))
3194-
return rightop; /* true = foo */
3197+
if (opno == BooleanEqualOperator)
3198+
{
3199+
if (DatumGetBool(((Const *) leftop)->constvalue))
3200+
return rightop; /* true = foo */
3201+
else
3202+
return make_notclause(rightop); /* false = foo */
3203+
}
31953204
else
3196-
return make_notclause(rightop); /* false = foo */
3205+
{
3206+
if (DatumGetBool(((Const *) leftop)->constvalue))
3207+
return make_notclause(rightop); /* true <> foo */
3208+
else
3209+
return rightop; /* false <> foo */
3210+
}
31973211
}
31983212
if (rightop && IsA(rightop, Const))
31993213
{
32003214
Assert(!((Const *) rightop)->constisnull);
3201-
if (DatumGetBool(((Const *) rightop)->constvalue))
3202-
return leftop; /* foo = true */
3215+
if (opno == BooleanEqualOperator)
3216+
{
3217+
if (DatumGetBool(((Const *) rightop)->constvalue))
3218+
return leftop; /* foo = true */
3219+
else
3220+
return make_notclause(leftop); /* foo = false */
3221+
}
32033222
else
3204-
return make_notclause(leftop); /* foo = false */
3223+
{
3224+
if (DatumGetBool(((Const *) rightop)->constvalue))
3225+
return make_notclause(leftop); /* foo <> true */
3226+
else
3227+
return leftop; /* foo <> false */
3228+
}
32053229
}
32063230
return NULL;
32073231
}

src/include/catalog/pg_operator.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
99
* Portions Copyright (c) 1994, Regents of the University of California
1010
*
11-
* $PostgreSQL: pgsql/src/include/catalog/pg_operator.h,v 1.166 2009/06/11 14:49:09 momjian Exp $
11+
* $PostgreSQL: pgsql/src/include/catalog/pg_operator.h,v 1.167 2009/07/20 00:24:30 tgl Exp $
1212
*
1313
* NOTES
1414
* 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
9393
DATA(insert OID = 58 ( "<" PGNSP PGUID b f f 16 16 16 59 1695 boollt scalarltsel scalarltjoinsel ));
9494
DATA(insert OID = 59 ( ">" PGNSP PGUID b f f 16 16 16 58 1694 boolgt scalargtsel scalargtjoinsel ));
9595
DATA(insert OID = 85 ( "<>" PGNSP PGUID b f f 16 16 16 85 91 boolne neqsel neqjoinsel ));
96+
#define BooleanNotEqualOperator 85
9697
DATA(insert OID = 91 ( "=" PGNSP PGUID b t t 16 16 16 91 85 booleq eqsel eqjoinsel ));
9798
#define BooleanEqualOperator 91
9899
DATA(insert OID = 1694 ( "<=" PGNSP PGUID b f f 16 16 16 1695 59 boolle scalarltsel scalarltjoinsel ));

0 commit comments

Comments
 (0)