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.
This commit is contained in:
parent
400e2c9344
commit
31d1f23302
@ -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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* 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)
|
|||||||
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 @@
|
|||||||
* 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
|
|||||||
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 ));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user