Beispiel #1
0
        public override ExpressionNode VisitUnaryExpression(UnaryExpression expression)
        {
            // First visit arguments
            base.VisitUnaryExpression(expression);

            if (expression.Op == UnaryOperator.LogicalNot)
            {
                // Replace "NOT NOT expr" by "expr"

                UnaryExpression unOp = expression.Operand as UnaryExpression;
                if (unOp != null)
                {
                    if (unOp.Op == UnaryOperator.LogicalNot)
                    {
                        return(VisitExpression(unOp.Operand));
                    }
                }

                // Replace "NOT expr IS NULL" and "NOT expr IS NOT NULL" by
                //         "expr IS NOT NULL" and "expr IS NULL" resp.

                IsNullExpression isNull = expression.Operand as IsNullExpression;
                if (isNull != null)
                {
                    isNull.Negated = !isNull.Negated;
                    return(VisitExpression(isNull));
                }

                // Apply negation on EXISTS

                ExistsSubselect existsSubselect = expression.Operand as ExistsSubselect;
                if (existsSubselect != null)
                {
                    existsSubselect.Negated = !existsSubselect.Negated;
                    return(existsSubselect);
                }

                // Apply negation on ALL/ANY subquery

                AllAnySubselect allAnySubselect = expression.Operand as AllAnySubselect;
                if (allAnySubselect != null)
                {
                    allAnySubselect.Op   = AstUtil.NegateBinaryOp(allAnySubselect.Op);
                    allAnySubselect.Type = (allAnySubselect.Type == AllAnySubselect.AllAnyType.All) ? AllAnySubselect.AllAnyType.Any : AllAnySubselect.AllAnyType.All;
                    return(allAnySubselect);
                }

                // Apply De Morgan's law

                BinaryExpression binOp = expression.Operand as BinaryExpression;

                if (binOp != null)
                {
                    BinaryOperator negatedOp = AstUtil.NegateBinaryOp(binOp.Op);

                    if (negatedOp != null)
                    {
                        ExpressionNode newLeft;
                        ExpressionNode newRight;

                        if (binOp.Op == BinaryOperator.LogicalAnd || binOp.Op == BinaryOperator.LogicalOr)
                        {
                            newLeft  = new UnaryExpression(expression.Op, binOp.Left);
                            newRight = new UnaryExpression(expression.Op, binOp.Right);
                        }
                        else
                        {
                            newLeft  = binOp.Left;
                            newRight = binOp.Right;
                        }

                        binOp.Op    = negatedOp;
                        binOp.Left  = newLeft;
                        binOp.Right = newRight;
                        return(VisitExpression(binOp));
                    }
                }
            }

            return(expression);
        }