|
|
|
|
@ -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); |
|
|
|
|
} |
|
|
|
|
|