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

Commit 284e473

Browse files
committed
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.
1 parent 80f6c35 commit 284e473

File tree

1 file changed

+10
-19
lines changed

1 file changed

+10
-19
lines changed

src/backend/optimizer/prep/prepqual.c

+10-19
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
*
2626
*
2727
* IDENTIFICATION
28-
* $PostgreSQL: pgsql/src/backend/optimizer/prep/prepqual.c,v 1.49 2005/03/28 00:58:23 tgl Exp $
28+
* $PostgreSQL: pgsql/src/backend/optimizer/prep/prepqual.c,v 1.50 2005/07/29 21:40:02 tgl Exp $
2929
*
3030
*-------------------------------------------------------------------------
3131
*/
@@ -167,9 +167,6 @@ pull_ors(List *orlist)
167167
static Expr *
168168
find_nots(Expr *qual)
169169
{
170-
if (qual == NULL)
171-
return NULL;
172-
173170
if (and_clause((Node *) qual))
174171
{
175172
List *t_list = NIL;
@@ -204,17 +201,13 @@ find_nots(Expr *qual)
204201
static Expr *
205202
push_nots(Expr *qual)
206203
{
207-
if (qual == NULL)
208-
return make_notclause(qual); /* XXX is this right? Or
209-
* possible? */
210-
211-
/*
212-
* Negate an operator clause if possible: (NOT (< A B)) => (>= A B)
213-
* Otherwise, retain the clause as it is (the NOT can't be pushed down
214-
* any farther).
215-
*/
216204
if (is_opclause(qual))
217205
{
206+
/*
207+
* Negate an operator clause if possible: (NOT (< A B)) => (>= A B)
208+
* Otherwise, retain the clause as it is (the NOT can't be pushed down
209+
* any farther).
210+
*/
218211
OpExpr *opexpr = (OpExpr *) qual;
219212
Oid negator = get_negator(opexpr->opno);
220213

@@ -256,15 +249,16 @@ push_nots(Expr *qual)
256249
{
257250
/*
258251
* Another NOT cancels this NOT, so eliminate the NOT and stop
259-
* negating this branch.
252+
* negating this branch. But search the subexpression for more
253+
* NOTs to simplify.
260254
*/
261-
return get_notclausearg(qual);
255+
return find_nots(get_notclausearg(qual));
262256
}
263257
else
264258
{
265259
/*
266260
* We don't know how to negate anything else, place a NOT at this
267-
* level.
261+
* level. No point in recursing deeper, either.
268262
*/
269263
return make_notclause(qual);
270264
}
@@ -303,9 +297,6 @@ push_nots(Expr *qual)
303297
static Expr *
304298
find_duplicate_ors(Expr *qual)
305299
{
306-
if (qual == NULL)
307-
return NULL;
308-
309300
if (or_clause((Node *) qual))
310301
{
311302
List *orlist = NIL;

0 commit comments

Comments
 (0)