Commit 284e4739 authored by Tom Lane's avatar Tom Lane

Fix an oversight I introduced on 2003-12-28: find_nots/push_nots should

continue to recurse after eliminating a NOT-below-a-NOT, since the
contained subexpression will now be part of the top-level AND/OR structure
and so deserves to be simplified.  The real-world impact of this is
probably minimal, since it'd require at least three levels of NOT to make
a difference, but it's still a bug.
Also remove some redundant tests for NULL subexpressions.
parent 80f6c358
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/optimizer/prep/prepqual.c,v 1.49 2005/03/28 00:58:23 tgl Exp $ * $PostgreSQL: pgsql/src/backend/optimizer/prep/prepqual.c,v 1.50 2005/07/29 21:40:02 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -167,9 +167,6 @@ pull_ors(List *orlist) ...@@ -167,9 +167,6 @@ pull_ors(List *orlist)
static Expr * static Expr *
find_nots(Expr *qual) find_nots(Expr *qual)
{ {
if (qual == NULL)
return NULL;
if (and_clause((Node *) qual)) if (and_clause((Node *) qual))
{ {
List *t_list = NIL; List *t_list = NIL;
...@@ -204,17 +201,13 @@ find_nots(Expr *qual) ...@@ -204,17 +201,13 @@ find_nots(Expr *qual)
static Expr * static Expr *
push_nots(Expr *qual) push_nots(Expr *qual)
{ {
if (qual == NULL)
return make_notclause(qual); /* XXX is this right? Or
* possible? */
/*
* Negate an operator clause if possible: (NOT (< A B)) => (>= A B)
* Otherwise, retain the clause as it is (the NOT can't be pushed down
* any farther).
*/
if (is_opclause(qual)) if (is_opclause(qual))
{ {
/*
* Negate an operator clause if possible: (NOT (< A B)) => (>= A B)
* Otherwise, retain the clause as it is (the NOT can't be pushed down
* any farther).
*/
OpExpr *opexpr = (OpExpr *) qual; OpExpr *opexpr = (OpExpr *) qual;
Oid negator = get_negator(opexpr->opno); Oid negator = get_negator(opexpr->opno);
...@@ -256,15 +249,16 @@ push_nots(Expr *qual) ...@@ -256,15 +249,16 @@ push_nots(Expr *qual)
{ {
/* /*
* Another NOT cancels this NOT, so eliminate the NOT and stop * Another NOT cancels this NOT, so eliminate the NOT and stop
* negating this branch. * negating this branch. But search the subexpression for more
* NOTs to simplify.
*/ */
return get_notclausearg(qual); return find_nots(get_notclausearg(qual));
} }
else else
{ {
/* /*
* We don't know how to negate anything else, place a NOT at this * We don't know how to negate anything else, place a NOT at this
* level. * level. No point in recursing deeper, either.
*/ */
return make_notclause(qual); return make_notclause(qual);
} }
...@@ -303,9 +297,6 @@ push_nots(Expr *qual) ...@@ -303,9 +297,6 @@ push_nots(Expr *qual)
static Expr * static Expr *
find_duplicate_ors(Expr *qual) find_duplicate_ors(Expr *qual)
{ {
if (qual == NULL)
return NULL;
if (or_clause((Node *) qual)) if (or_clause((Node *) qual))
{ {
List *orlist = NIL; List *orlist = NIL;
......
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