Пример #1
0
 public virtual ExpressionNode VisitBetweenExpression(BetweenExpression expression)
 {
     expression.Expression = VisitExpression(expression.Expression);
     expression.LowerBound = VisitExpression(expression.LowerBound);
     expression.UpperBound = VisitExpression(expression.UpperBound);
     return(expression);
 }
Пример #2
0
 private static bool VisitBetweenExpression(BetweenExpression node1, BetweenExpression node2)
 {
     return(node2 != null &&
            Visit(node1.Expression, node2.Expression) &&
            Visit(node1.LowerBound, node2.LowerBound) &&
            Visit(node1.UpperBound, node2.UpperBound));
 }
Пример #3
0
        private static bool NeedParentheses(ExpressionNode childExpression, int parentPrecedence, bool isRightOperand)
        {
            // If childExpression is also an operator expression we may need parentheses.
            //
            // This depends on the precedence and associativity of the child operator.
            // Since we have unary, binary and ternary operators we extract theses pieces
            // of information using casts.

            int  childPrecedence;
            bool isRightAssociative;

            OperatorExpression expressionOperatorExpression = childExpression as OperatorExpression;

            if (expressionOperatorExpression != null)
            {
                // It is a binary or unary operator.

                childPrecedence    = expressionOperatorExpression.Op.Precedence;
                isRightAssociative = expressionOperatorExpression.Op.IsRightAssociative;
            }
            else
            {
                // Special handling for the only ternary operator.

                BetweenExpression expressionAsBetweenExpression = childExpression as BetweenExpression;

                if (expressionAsBetweenExpression != null)
                {
                    childPrecedence    = Operator.BETWEEN_PRECEDENCE;
                    isRightAssociative = false;
                }
                else
                {
                    return(false);
                }
            }

            // Analyze precedences.

            if (childPrecedence < parentPrecedence)
            {
                return(true);
            }

            if (childPrecedence == parentPrecedence)
            {
                if (isRightOperand && !isRightAssociative)
                {
                    return(true);
                }

                if (!isRightOperand && isRightAssociative)
                {
                    return(true);
                }
            }

            return(false);
        }
Пример #4
0
        public override ExpressionNode VisitBetweenExpression(BetweenExpression expression)
        {
            _xmlWriter.WriteStartElement("betweenExpression");
            WriteTypeAttribute(expression.ExpressionType);

            WriteAstNode("lowerBound", expression.LowerBound);
            WriteAstNode("upperBound", expression.UpperBound);

            _xmlWriter.WriteEndElement();

            return(expression);
        }
Пример #5
0
        public override ExpressionNode VisitBetweenExpression(BetweenExpression expression)
        {
            // First visit all expressions
            base.VisitBetweenExpression(expression);

            // Since a BETWEEN expression can be expressed using an AND expression and two
            // <= binary operator nodes we convert them to simplify the join and optimization engine.

            BinaryExpression lowerBound = new BinaryExpression(BinaryOperator.LessOrEqual, expression.LowerBound, expression.Expression);
            BinaryExpression upperBound = new BinaryExpression(BinaryOperator.LessOrEqual, expression.Expression, expression.UpperBound);
            BinaryExpression and        = new BinaryExpression(BinaryOperator.LogicalAnd, lowerBound, upperBound);

            // Make sure we also resolve the result.
            return(VisitExpression(and));
        }
Пример #6
0
        public override ExpressionNode VisitBetweenExpression(BetweenExpression expression)
        {
            Visit(expression.Expression);
            _writer.Write(" BETWEEN ");

            // Emit lower bound

            bool parenthesesNedded = expression.LowerBound is BinaryExpression;

            if (parenthesesNedded)
            {
                _writer.Write("(");
            }

            Visit(expression.LowerBound);

            if (parenthesesNedded)
            {
                _writer.Write(")");
            }

            // Emit and

            _writer.Write(" AND ");

            // Emit upper bound

            parenthesesNedded = expression.UpperBound is BinaryExpression;

            if (parenthesesNedded)
            {
                _writer.Write("(");
            }

            Visit(expression.UpperBound);

            if (parenthesesNedded)
            {
                _writer.Write(")");
            }

            return(expression);
        }
Пример #7
0
		private static bool VisitBetweenExpression(BetweenExpression node1, BetweenExpression node2)
		{
			return node2 != null &&
			       Visit(node1.Expression, node2.Expression) &&
			       Visit(node1.LowerBound, node2.LowerBound) &&
			       Visit(node1.UpperBound, node2.UpperBound);
		}
Пример #8
0
		public override ExpressionNode VisitBetweenExpression(BetweenExpression expression)
		{
			Visit(expression.Expression);
			_writer.Write(" BETWEEN ");

			// Emit lower bound

			bool parenthesesNedded = expression.LowerBound is BinaryExpression;

			if (parenthesesNedded)
				_writer.Write("(");

			Visit(expression.LowerBound);

			if (parenthesesNedded)
				_writer.Write(")");

			// Emit and

			_writer.Write(" AND ");

			// Emit upper bound

			parenthesesNedded = expression.UpperBound is BinaryExpression;

			if (parenthesesNedded)
				_writer.Write("(");

			Visit(expression.UpperBound);

			if (parenthesesNedded)
				_writer.Write(")");

			return expression;
		}
Пример #9
0
        private ExpressionNode ParseSubExpression(ExpressionNode left, int precedence)
        {
            if (left == null)
            {
                // No left operand, so we parse one and take care about leading unary operators

                if (_token.Info.UnaryOperator != null)
                {
                    UnaryOperator op = _token.Info.UnaryOperator;

                    NextToken();

                    ExpressionNode expr = ParseSubExpression(null, op.Precedence);
                    left = new UnaryExpression(op, expr);
                }
                else
                {
                    left = ParseSimpleExpression();
                }
            }

            while (_token.Id != TokenId.Eof)
            {
                // Special handling for NOT BETWEEN, NOT IN, NOT LIKE, NOT SIMILAR TO, and NOT SOUNDSLIKE.

                bool negated = false;

                if (_token.Id == TokenId.NOT)
                {
                    if (_lookahead.Id == TokenId.BETWEEN ||
                        _lookahead.Id == TokenId.IN ||
                        _lookahead.Id == TokenId.LIKE ||
                        _lookahead.Id == TokenId.SIMILAR ||
                        _lookahead.Id == TokenId.SOUNDSLIKE)
                    {
                        NextToken();
                        negated = true;
                    }
                }

                // Special handling for the only ternary operator BETWEEN

                if (_token.Id == TokenId.BETWEEN)
                {
                    NextToken();
                    ExpressionNode lowerBound = ParseSubExpression(null, Operator.BETWEEN_PRECEDENCE);
                    Match(TokenId.AND);
                    ExpressionNode upperBound = ParseSubExpression(null, Operator.BETWEEN_PRECEDENCE);

                    left = new BetweenExpression(left, lowerBound, upperBound);
                }
                else
                {
                    // If there is no binary operator we are finished

                    if (_token.Info.BinaryOperator == null)
                        break;

                    BinaryOperator binaryOp = _token.Info.BinaryOperator;

                    // Precedence is lower, parse it later

                    if (binaryOp.Precedence < precedence)
                        break;

                    // Precedence is equal, but operator ist not right associative, parse it later

                    if (binaryOp.Precedence == precedence && !binaryOp.IsRightAssociative)
                        break;

                    // Precedence is higher

                    NextToken();

                    // Special handling for SIMILAR TO

                    if (binaryOp == BinaryOperator.SimilarTo)
                        Match(TokenId.TO);

                    if (binaryOp == BinaryOperator.In)
                    {
                        // Special handling for IN

                        InExpression inExpression = new InExpression();
                        inExpression.Left = left;
                        inExpression.RightExpressions = ParseSimpleQueryExpressionList();
                        left = inExpression;
                    }
                    else if (_token.Id == TokenId.ANY || _token.Id == TokenId.SOME || _token.Id == TokenId.ALL)
                    {
                        // Special handling for ANY (SOME) and ALL

                        if (binaryOp != BinaryOperator.Equal &&
                            binaryOp != BinaryOperator.NotEqual &&
                            binaryOp != BinaryOperator.Less &&
                            binaryOp != BinaryOperator.LessOrEqual &&
                            binaryOp != BinaryOperator.Greater &&
                            binaryOp != BinaryOperator.GreaterOrEqual)
                        {
                            _errorReporter.InvalidOperatorForAllAny(_token.Range, binaryOp);
                        }

                        AllAnySubselect allAnySubselect = new AllAnySubselect();
                        allAnySubselect.Left = left;
                        allAnySubselect.Op = binaryOp;
                        allAnySubselect.Type = (_token.Id == TokenId.ALL) ? AllAnySubselect.AllAnyType.All : AllAnySubselect.AllAnyType.Any;
                        NextToken();
                        Match(TokenId.LeftParentheses);
                        allAnySubselect.Query = ParseQuery();
                        Match(TokenId.RightParentheses);
                        left = allAnySubselect;
                    }
                    else
                    {
                        left = new BinaryExpression(binaryOp, left, ParseSubExpression(null, binaryOp.Precedence));
                    }
                }

                // Special handling for negated expressions (see above)

                if (negated)
                    left = new UnaryExpression(UnaryOperator.LogicalNot, left);
            }

            return left;
        }
Пример #10
0
	    public override ExpressionNode VisitBetweenExpression(BetweenExpression expression)
		{
			// First visit all expressions
			base.VisitBetweenExpression(expression);

			// Since a BETWEEN expression can be expressed using an AND expression and two
			// <= binary operator nodes we convert them to simplify the join and optimization engine.

			BinaryExpression lowerBound = new BinaryExpression(BinaryOperator.LessOrEqual, expression.LowerBound, expression.Expression);
			BinaryExpression upperBound = new BinaryExpression(BinaryOperator.LessOrEqual, expression.Expression, expression.UpperBound);
			BinaryExpression and = new BinaryExpression(BinaryOperator.LogicalAnd, lowerBound, upperBound);

			// Make sure we also resolve the result.
			return VisitExpression(and);
		}
Пример #11
0
		public virtual ExpressionNode VisitBetweenExpression(BetweenExpression expression)
		{
			expression.Expression = VisitExpression(expression.Expression);
			expression.LowerBound = VisitExpression(expression.LowerBound);
			expression.UpperBound = VisitExpression(expression.UpperBound);
			return expression;
		}
Пример #12
0
        private ExpressionNode ParseSubExpression(ExpressionNode left, int precedence)
        {
            if (left == null)
            {
                // No left operand, so we parse one and take care about leading unary operators

                if (_token.Info.UnaryOperator != null)
                {
                    UnaryOperator op = _token.Info.UnaryOperator;

                    NextToken();

                    ExpressionNode expr = ParseSubExpression(null, op.Precedence);
                    left = new UnaryExpression(op, expr);
                }
                else
                {
                    left = ParseSimpleExpression();
                }
            }

            while (_token.Id != TokenId.Eof)
            {
                // Special handling for NOT BETWEEN, NOT IN, NOT LIKE, NOT SIMILAR TO, and NOT SOUNDSLIKE.

                bool negated = false;

                if (_token.Id == TokenId.NOT)
                {
                    if (_lookahead.Id == TokenId.BETWEEN ||
                        _lookahead.Id == TokenId.IN ||
                        _lookahead.Id == TokenId.LIKE ||
                        _lookahead.Id == TokenId.SIMILAR ||
                        _lookahead.Id == TokenId.SOUNDSLIKE)
                    {
                        NextToken();
                        negated = true;
                    }
                }

                // Special handling for the only ternary operator BETWEEN

                if (_token.Id == TokenId.BETWEEN)
                {
                    NextToken();
                    ExpressionNode lowerBound = ParseSubExpression(null, Operator.BETWEEN_PRECEDENCE);
                    Match(TokenId.AND);
                    ExpressionNode upperBound = ParseSubExpression(null, Operator.BETWEEN_PRECEDENCE);

                    left = new BetweenExpression(left, lowerBound, upperBound);
                }
                else
                {
                    // If there is no binary operator we are finished

                    if (_token.Info.BinaryOperator == null)
                    {
                        break;
                    }

                    BinaryOperator binaryOp = _token.Info.BinaryOperator;

                    // Precedence is lower, parse it later

                    if (binaryOp.Precedence < precedence)
                    {
                        break;
                    }

                    // Precedence is equal, but operator ist not right associative, parse it later

                    if (binaryOp.Precedence == precedence && !binaryOp.IsRightAssociative)
                    {
                        break;
                    }

                    // Precedence is higher

                    NextToken();

                    // Special handling for SIMILAR TO

                    if (binaryOp == BinaryOperator.SimilarTo)
                    {
                        Match(TokenId.TO);
                    }

                    if (binaryOp == BinaryOperator.In)
                    {
                        // Special handling for IN

                        InExpression inExpression = new InExpression();
                        inExpression.Left             = left;
                        inExpression.RightExpressions = ParseSimpleQueryExpressionList();
                        left = inExpression;
                    }
                    else if (_token.Id == TokenId.ANY || _token.Id == TokenId.SOME || _token.Id == TokenId.ALL)
                    {
                        // Special handling for ANY (SOME) and ALL

                        if (binaryOp != BinaryOperator.Equal &&
                            binaryOp != BinaryOperator.NotEqual &&
                            binaryOp != BinaryOperator.Less &&
                            binaryOp != BinaryOperator.LessOrEqual &&
                            binaryOp != BinaryOperator.Greater &&
                            binaryOp != BinaryOperator.GreaterOrEqual)
                        {
                            _errorReporter.InvalidOperatorForAllAny(_token.Range, binaryOp);
                        }

                        AllAnySubselect allAnySubselect = new AllAnySubselect();
                        allAnySubselect.Left = left;
                        allAnySubselect.Op   = binaryOp;
                        allAnySubselect.Type = (_token.Id == TokenId.ALL) ? AllAnySubselect.AllAnyType.All : AllAnySubselect.AllAnyType.Any;
                        NextToken();
                        Match(TokenId.LeftParentheses);
                        allAnySubselect.Query = ParseQuery();
                        Match(TokenId.RightParentheses);
                        left = allAnySubselect;
                    }
                    else
                    {
                        left = new BinaryExpression(binaryOp, left, ParseSubExpression(null, binaryOp.Precedence));
                    }
                }

                // Special handling for negated expressions (see above)

                if (negated)
                {
                    left = new UnaryExpression(UnaryOperator.LogicalNot, left);
                }
            }

            return(left);
        }
Пример #13
0
		public override ExpressionNode VisitBetweenExpression(BetweenExpression expression)
		{
			_xmlWriter.WriteStartElement("betweenExpression");
			WriteTypeAttribute(expression.ExpressionType);

			WriteAstNode("lowerBound", expression.LowerBound);
			WriteAstNode("upperBound", expression.UpperBound);

			_xmlWriter.WriteEndElement();

			return expression;
		}