Teach push_nots() how to negate a ScalarArrayOpExpr. In passing, save
authorTom Lane
Sat, 26 Nov 2005 18:07:40 +0000 (18:07 +0000)
committerTom Lane
Sat, 26 Nov 2005 18:07:40 +0000 (18:07 +0000)
a palloc or two in the OpExpr case.

src/backend/optimizer/prep/prepqual.c

index 106d4d16813776a8386921c65170305fe8b3e89d..520e35f4d1b154f320a486f30efd05835ff425f4 100644 (file)
@@ -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);
    }