public virtual ExpressionNode VisitBetweenExpression(BetweenExpression expression) { expression.Expression = VisitExpression(expression.Expression); expression.LowerBound = VisitExpression(expression.LowerBound); expression.UpperBound = VisitExpression(expression.UpperBound); return(expression); }
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)); }
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); }
public override ExpressionNode VisitBetweenExpression(BetweenExpression expression) { _xmlWriter.WriteStartElement("betweenExpression"); WriteTypeAttribute(expression.ExpressionType); WriteAstNode("lowerBound", expression.LowerBound); WriteAstNode("upperBound", expression.UpperBound); _xmlWriter.WriteEndElement(); return(expression); }
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)); }
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); }
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); }
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; }
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; }
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); }
public virtual ExpressionNode VisitBetweenExpression(BetweenExpression expression) { expression.Expression = VisitExpression(expression.Expression); expression.LowerBound = VisitExpression(expression.LowerBound); expression.UpperBound = VisitExpression(expression.UpperBound); return expression; }
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); }
public override ExpressionNode VisitBetweenExpression(BetweenExpression expression) { _xmlWriter.WriteStartElement("betweenExpression"); WriteTypeAttribute(expression.ExpressionType); WriteAstNode("lowerBound", expression.LowerBound); WriteAstNode("upperBound", expression.UpperBound); _xmlWriter.WriteEndElement(); return expression; }