|
8 | 8 | *
|
9 | 9 | *
|
10 | 10 | * IDENTIFICATION
|
11 |
| - * $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.188 2005/02/02 21:49:07 tgl Exp $ |
| 11 | + * $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.189 2005/03/27 19:18:02 tgl Exp $ |
12 | 12 | *
|
13 | 13 | * HISTORY
|
14 | 14 | * AUTHORDATEMAJOR EVENT
|
|
21 | 21 |
|
22 | 22 | #include"catalog/pg_aggregate.h"
|
23 | 23 | #include"catalog/pg_language.h"
|
| 24 | +#include"catalog/pg_operator.h" |
24 | 25 | #include"catalog/pg_proc.h"
|
25 | 26 | #include"catalog/pg_type.h"
|
26 | 27 | #include"executor/executor.h"
|
@@ -74,6 +75,7 @@ static List *simplify_or_arguments(List *args,
|
74 | 75 | bool*haveNull,bool*forceTrue);
|
75 | 76 | staticList*simplify_and_arguments(List*args,
|
76 | 77 | bool*haveNull,bool*forceFalse);
|
| 78 | +staticExpr*simplify_boolean_equality(List*args); |
77 | 79 | staticExpr*simplify_function(Oidfuncid,Oidresult_type,List*args,
|
78 | 80 | boolallow_inline,
|
79 | 81 | eval_const_expressions_context*context);
|
@@ -1341,6 +1343,17 @@ eval_const_expressions_mutator(Node *node,
|
1341 | 1343 | if (simple)/* successfully simplified it */
|
1342 | 1344 | return (Node*)simple;
|
1343 | 1345 |
|
| 1346 | +/* |
| 1347 | + * If the operator is boolean equality, we know how to simplify |
| 1348 | + * cases involving one constant and one non-constant argument. |
| 1349 | + */ |
| 1350 | +if (expr->opno==BooleanEqualOperator) |
| 1351 | +{ |
| 1352 | +simple=simplify_boolean_equality(args); |
| 1353 | +if (simple)/* successfully simplified it */ |
| 1354 | +return (Node*)simple; |
| 1355 | +} |
| 1356 | + |
1344 | 1357 | /*
|
1345 | 1358 | * The expression cannot be simplified any further, so build and
|
1346 | 1359 | * return a replacement OpExpr node using the possibly-simplified
|
@@ -1966,6 +1979,49 @@ simplify_and_arguments(List *args, bool *haveNull, bool *forceFalse)
|
1966 | 1979 | returnnewargs;
|
1967 | 1980 | }
|
1968 | 1981 |
|
| 1982 | +/* |
| 1983 | + * Subroutine for eval_const_expressions: try to simplify boolean equality |
| 1984 | + * |
| 1985 | + * Input is the list of simplified arguments to the operator. |
| 1986 | + * Returns a simplified expression if successful, or NULL if cannot |
| 1987 | + * simplify the expression. |
| 1988 | + * |
| 1989 | + * The idea here is to reduce "x = true" to "x" and "x = false" to "NOT x". |
| 1990 | + * This is only marginally useful in itself, but doing it in constant folding |
| 1991 | + * ensures that we will recognize the two forms as being equivalent in, for |
| 1992 | + * example, partial index matching. |
| 1993 | + * |
| 1994 | + * We come here only if simplify_function has failed; therefore we cannot |
| 1995 | + * see two constant inputs, nor a constant-NULL input. |
| 1996 | + */ |
| 1997 | +staticExpr* |
| 1998 | +simplify_boolean_equality(List*args) |
| 1999 | +{ |
| 2000 | +Expr*leftop; |
| 2001 | +Expr*rightop; |
| 2002 | + |
| 2003 | +Assert(list_length(args)==2); |
| 2004 | +leftop=linitial(args); |
| 2005 | +rightop=lsecond(args); |
| 2006 | +if (leftop&&IsA(leftop,Const)) |
| 2007 | +{ |
| 2008 | +Assert(!((Const*)leftop)->constisnull); |
| 2009 | +if (DatumGetBool(((Const*)leftop)->constvalue)) |
| 2010 | +returnrightop;/* true = foo */ |
| 2011 | +else |
| 2012 | +returnmake_notclause(rightop);/* false = foo */ |
| 2013 | +} |
| 2014 | +if (rightop&&IsA(rightop,Const)) |
| 2015 | +{ |
| 2016 | +Assert(!((Const*)rightop)->constisnull); |
| 2017 | +if (DatumGetBool(((Const*)rightop)->constvalue)) |
| 2018 | +returnleftop;/* foo = true */ |
| 2019 | +else |
| 2020 | +returnmake_notclause(leftop);/* foo = false */ |
| 2021 | +} |
| 2022 | +returnNULL; |
| 2023 | +} |
| 2024 | + |
1969 | 2025 | /*
|
1970 | 2026 | * Subroutine for eval_const_expressions: try to simplify a function call
|
1971 | 2027 | * (which might originally have been an operator; we don't care)
|
|