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

Lines changed: 40 additions & 16 deletions
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

Lines changed: 2 additions & 1 deletion
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy