From a66e2c88855a8c290149d03cfcd6c6a2a5dc53fe Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sat, 26 Nov 2005 18:07:40 +0000 Subject: [PATCH] Teach push_nots() how to negate a ScalarArrayOpExpr. In passing, save a palloc or two in the OpExpr case. --- src/backend/optimizer/prep/prepqual.c | 41 +++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/src/backend/optimizer/prep/prepqual.c b/src/backend/optimizer/prep/prepqual.c index 106d4d1681..520e35f4d1 100644 --- a/src/backend/optimizer/prep/prepqual.c +++ b/src/backend/optimizer/prep/prepqual.c @@ -25,7 +25,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/optimizer/prep/prepqual.c,v 1.52 2005/11/22 18:17:14 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/prep/prepqual.c,v 1.53 2005/11/26 18:07:40 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -212,11 +212,40 @@ push_nots(Expr *qual) Oid negator = get_negator(opexpr->opno); if (negator) - return make_opclause(negator, - opexpr->opresulttype, - opexpr->opretset, - (Expr *) get_leftop(qual), - (Expr *) get_rightop(qual)); + { + OpExpr *newopexpr = makeNode(OpExpr); + + newopexpr->opno = negator; + newopexpr->opfuncid = InvalidOid; + newopexpr->opresulttype = opexpr->opresulttype; + newopexpr->opretset = opexpr->opretset; + newopexpr->args = opexpr->args; + return (Expr *) newopexpr; + } + else + return make_notclause(qual); + } + else if (qual && IsA(qual, ScalarArrayOpExpr)) + { + /* + * Negate a ScalarArrayOpExpr if there is a negator for its operator; + * for example x = ANY (list) becomes x <> ALL (list). + * Otherwise, retain the clause as it is (the NOT can't be pushed down + * any farther). + */ + ScalarArrayOpExpr *saopexpr = (ScalarArrayOpExpr *) qual; + Oid negator = get_negator(saopexpr->opno); + + if (negator) + { + ScalarArrayOpExpr *newopexpr = makeNode(ScalarArrayOpExpr); + + newopexpr->opno = negator; + newopexpr->opfuncid = InvalidOid; + newopexpr->useOr = !saopexpr->useOr; + newopexpr->args = saopexpr->args; + return (Expr *) newopexpr; + } else return make_notclause(qual); }