public void RightShouldBeSetCorrectly()
 {
     ConstantNode left = new ConstantNode(1);
     ConstantNode right = new ConstantNode(2);
     BinaryOperatorNode operatorNode = new BinaryOperatorNode(BinaryOperatorKind.Add, left, right);
     operatorNode.Right.Should().Be(right);
 }
 public void KindIsBinaryOperatorNode()
 {
     ConstantNode left = new ConstantNode(1);
     ConstantNode right = new ConstantNode(2);
     BinaryOperatorNode operatorNode = new BinaryOperatorNode(BinaryOperatorKind.Add, left, right);
     operatorNode.InternalKind.Should().Be(InternalQueryNodeKind.BinaryOperator);
 }
        public void ToODataString_EscapesThe_Uri()
        {

            //updatedat gt datetimeoffset'2014-04-04T07:00:00.0000000+00:00'
            var datetime1 = new ConstantNode(new DateTimeOffset(2014, 4, 4, 7, 0, 0, TimeSpan.FromHours(0)));
            var updatedAt = new MemberAccessNode(null, "updatedat");
            var gt1 = new BinaryOperatorNode(BinaryOperatorKind.GreaterThan, updatedAt, datetime1);

            // updatedat gt datetime'2014-04-04T07:0:0.000Z'
            var datetime2 = new ConstantNode(new DateTime(2014, 4, 4, 7, 0, 0, DateTimeKind.Utc));
            var someDate = new MemberAccessNode(null, "someDate");
            var gt2 = new BinaryOperatorNode(BinaryOperatorKind.GreaterThan, someDate, datetime2);

            // startswith(text,'this&''%%=,?#')
            var text = new MemberAccessNode(null, "text");
            var value = new ConstantNode("this&'%%=,?#");
            var startswith = new FunctionCallNode("startswith", new QueryNode[] { text, value });

            //updatedat gt datetimeoffset'2014-04-04T07:00:00.0000000+00:00' and startswith(text,'this&''%%=,?#')
            var and2 = new BinaryOperatorNode(BinaryOperatorKind.And, gt2, startswith);

            var and1 = new BinaryOperatorNode(BinaryOperatorKind.And, gt1, and2);

            var desc = new MobileServiceTableQueryDescription("someTable") { Filter = and1 };
            Assert.AreEqual(desc.ToODataString(), EscapedODataString);
        }
 public void TypeReferenceIsSetCorrectlyFromOperands()
 {
     ConstantNode left = new ConstantNode(1);
     ConstantNode right = new ConstantNode(2);
     BinaryOperatorNode operatorNode = new BinaryOperatorNode(BinaryOperatorKind.Add, left, right);
     operatorNode.TypeReference.FullName().Should().Be("Edm.Int32");
 }
 public void FilterOptionSetCorrectly()
 {
     BinaryOperatorNode filterExpression = new BinaryOperatorNode(BinaryOperatorKind.Equal, new ConstantNode(1), new ConstantNode(1));
     FilterClause filterClause = new FilterClause(filterExpression, new EntityRangeVariable(ExpressionConstants.It, HardCodedTestModel.GetPersonTypeReference(), HardCodedTestModel.GetPeopleSet()));
     ExpandedNavigationSelectItem expansion = new ExpandedNavigationSelectItem(new ODataExpandPath(new NavigationPropertySegment(ModelBuildingHelpers.BuildValidNavigationProperty(), null)), HardCodedTestModel.GetPeopleSet(), null, filterClause, null, null, null, null, null, null);
     expansion.FilterOption.Expression.ShouldBeBinaryOperatorNode(BinaryOperatorKind.Equal);
     expansion.FilterOption.Expression.As<BinaryOperatorNode>().Left.ShouldBeConstantQueryNode(1);
     expansion.FilterOption.Expression.As<BinaryOperatorNode>().Right.ShouldBeConstantQueryNode(1);
 }
 private QueryNode ParseLogicalOr()
 {
     QueryNode left = this.ParseLogicalAnd();
     while (this.lexer.Token.Kind == QueryTokenKind.Or)
     {
         this.lexer.NextToken();
         QueryNode right = this.ParseLogicalAnd();
         left = new BinaryOperatorNode(BinaryOperatorKind.Or, left, right);
     }
     return left;
 }
        //$filter=EnterpriseName%20eq%20%27DIEGO_520%27
        public BinaryOperatorResolver(BinaryOperatorNode binaryOperator)
        {
            if (binaryOperator != null)
            {
                var property = binaryOperator.Left as SingleValuePropertyAccessNode ?? binaryOperator.Right as SingleValuePropertyAccessNode;
                var constant = binaryOperator.Left as ConstantNode ?? binaryOperator.Right as ConstantNode;

                if (property != null && property.Property != null && constant != null && constant.Value != null)
                {
                    Property = property.Property.Name;
                    Operator = binaryOperator.OperatorKind;
                    Value = constant.LiteralText;
                }
            }
        }
        public BinaryExpressionNode(ExpressionNode left, ExpressionNode right, BinaryOperatorNode operatorNode)
        {
            if (left == null)
                ThrowHelper.ThrowArgumentNullException(() => left);
            if (right == null)
                ThrowHelper.ThrowArgumentNullException(() => right);
            if (operatorNode == null)
                ThrowHelper.ThrowArgumentNullException(() => operatorNode);

            Left = left;
            Right = right;
            Operator = operatorNode;

            AddChildren(Left, Right, Operator);
        }
Exemple #9
0
 private BinaryOperatorNode Process(BinaryOperatorNode node)
 {
     Process(node.Left);
     Process(node.Right);
     return(node);
 }
        private QueryNode ParseAdditive()
        {
            QueryNode left = this.ParseMultiplicative();

            while (this.lexer.Token.Kind == QueryTokenKind.Add || this.lexer.Token.Kind == QueryTokenKind.Sub)
            {
                QueryTokenKind opKind = this.lexer.Token.Kind;
                this.lexer.NextToken();
                QueryNode right = this.ParseMultiplicative();
                switch (opKind)
                {
                    case QueryTokenKind.Add:
                        left = new BinaryOperatorNode(BinaryOperatorKind.And, left, right);
                        break;
                    case QueryTokenKind.Sub:
                        left = new BinaryOperatorNode(BinaryOperatorKind.Subtract, left, right);
                        break;
                }
            }
            return left;
        }
        private static AllowedLogicalOperators ToLogicalOperator(BinaryOperatorNode binaryNode)
        {
            AllowedLogicalOperators result = AllowedLogicalOperators.None;

            switch (binaryNode.OperatorKind)
            {
                case BinaryOperatorKind.Equal:
                    result = AllowedLogicalOperators.Equal;
                    break;

                case BinaryOperatorKind.NotEqual:
                    result = AllowedLogicalOperators.NotEqual;
                    break;

                case BinaryOperatorKind.And:
                    result = AllowedLogicalOperators.And;
                    break;

                case BinaryOperatorKind.GreaterThan:
                    result = AllowedLogicalOperators.GreaterThan;
                    break;

                case BinaryOperatorKind.GreaterThanOrEqual:
                    result = AllowedLogicalOperators.GreaterThanOrEqual;
                    break;

                case BinaryOperatorKind.LessThan:
                    result = AllowedLogicalOperators.LessThan;
                    break;

                case BinaryOperatorKind.LessThanOrEqual:
                    result = AllowedLogicalOperators.LessThanOrEqual;
                    break;

                case BinaryOperatorKind.Or:
                    result = AllowedLogicalOperators.Or;
                    break;

                default:
                    // should never be here
                    Contract.Assert(false, "ToLogicalOperator should never be here.");
                    break;
            }

            return result;
        }
Exemple #12
0
        public override FilterNode <ClrValue> Visit(BinaryOperatorNode nodeIn)
        {
            if (nodeIn.OperatorKind == BinaryOperatorKind.And)
            {
                return(ClrFilter.And(nodeIn.Left.Accept(this), nodeIn.Right.Accept(this)));
            }

            if (nodeIn.OperatorKind == BinaryOperatorKind.Or)
            {
                return(ClrFilter.Or(nodeIn.Left.Accept(this), nodeIn.Right.Accept(this)));
            }

            if (nodeIn.Left is SingleValueFunctionCallNode functionNode)
            {
                if (string.Equals(functionNode.Name, "geo.distance", StringComparison.OrdinalIgnoreCase) && nodeIn.OperatorKind == BinaryOperatorKind.LessThan)
                {
                    var valueDistance = (double)ConstantWithTypeVisitor.Visit(nodeIn.Right).Value !;

                    if (functionNode.Parameters.ElementAt(1) is not ConstantNode constantNode)
                    {
                        throw new NotSupportedException();
                    }

                    if (constantNode.Value is not GeographyPoint geographyPoint)
                    {
                        throw new NotSupportedException();
                    }

                    var property = PropertyPathVisitor.Visit(functionNode.Parameters.ElementAt(0));

                    return(ClrFilter.Lt(property, new FilterSphere(geographyPoint.Longitude, geographyPoint.Latitude, valueDistance)));
                }
                else
                {
                    var regexFilter = Visit(functionNode);

                    var value = ConstantWithTypeVisitor.Visit(nodeIn.Right);

                    if (value.ValueType == ClrValueType.Boolean && value.Value is bool booleanRight)
                    {
                        if ((nodeIn.OperatorKind == BinaryOperatorKind.Equal && !booleanRight) ||
                            (nodeIn.OperatorKind == BinaryOperatorKind.NotEqual && booleanRight))
                        {
                            regexFilter = ClrFilter.Not(regexFilter);
                        }

                        return(regexFilter);
                    }
                }
            }
            else
            {
                if (nodeIn.OperatorKind == BinaryOperatorKind.NotEqual)
                {
                    var value = ConstantWithTypeVisitor.Visit(nodeIn.Right);

                    return(ClrFilter.Ne(PropertyPathVisitor.Visit(nodeIn.Left), value));
                }

                if (nodeIn.OperatorKind == BinaryOperatorKind.Equal)
                {
                    var value = ConstantWithTypeVisitor.Visit(nodeIn.Right);

                    return(ClrFilter.Eq(PropertyPathVisitor.Visit(nodeIn.Left), value));
                }

                if (nodeIn.OperatorKind == BinaryOperatorKind.LessThan)
                {
                    var value = ConstantWithTypeVisitor.Visit(nodeIn.Right);

                    return(ClrFilter.Lt(PropertyPathVisitor.Visit(nodeIn.Left), value));
                }

                if (nodeIn.OperatorKind == BinaryOperatorKind.LessThanOrEqual)
                {
                    var value = ConstantWithTypeVisitor.Visit(nodeIn.Right);

                    return(ClrFilter.Le(PropertyPathVisitor.Visit(nodeIn.Left), value));
                }

                if (nodeIn.OperatorKind == BinaryOperatorKind.GreaterThan)
                {
                    var value = ConstantWithTypeVisitor.Visit(nodeIn.Right);

                    return(ClrFilter.Gt(PropertyPathVisitor.Visit(nodeIn.Left), value));
                }

                if (nodeIn.OperatorKind == BinaryOperatorKind.GreaterThanOrEqual)
                {
                    var value = ConstantWithTypeVisitor.Visit(nodeIn.Right);

                    return(ClrFilter.Ge(PropertyPathVisitor.Visit(nodeIn.Left), value));
                }
            }

            throw new NotSupportedException();
        }
 /// <summary>
 /// Compares binary operator query nodes.
 /// </summary>
 /// <param name="left">Left side of comparison</param>
 /// <param name="right">Right side of comparison</param>
 /// <returns>True if equal, otherwise false</returns>
 private bool Compare(BinaryOperatorNode left, BinaryOperatorNode right)
 {
     if (left.OperatorKind != right.OperatorKind) return false;
     if (left.TypeReference != right.TypeReference) return false;
     if (!this.Compare(left.Left, right.Left)) return false;
     return this.Compare(left.Right, right.Right);
 }
        private static void BuildNavigationWithAny()
        {
            // Request URI
            var requestUri = new Uri("Students?$filter=StudentId gt 100", UriKind.Relative);
            var requestODataUri = new ODataUriParser(SchoolModel.Model, requestUri).ParseUri();
            var requestFilterExpression = requestODataUri.Filter.Expression;

            // URI that contains additional condition
            var conditionUri = new Uri("Students?$filter=Courses/any(c:c/Teacher/Education/Degrees/any(d:d/Category eq 'English Literature'))", UriKind.Relative);
            var conditionODataUri = new ODataUriParser(SchoolModel.Model, conditionUri).ParseUri();
            var conditionExpression = conditionODataUri.Filter.Expression;

            // New $filter expression
            var newFilterExpression = new BinaryOperatorNode(BinaryOperatorKind.And, requestFilterExpression, conditionExpression);
            requestODataUri.Filter = new FilterClause(newFilterExpression, requestODataUri.Filter.RangeVariable);
            var builder = new ODataUriBuilder(ODataUrlConventions.Default, requestODataUri);
            Console.WriteLine(builder.BuildUri());

            // http://host/Students?$filter=StudentId%20gt%20100%20and%20Courses%2Fany%28c%3Ac%2FTeacher%2FEducation%2FDegrees%2Fany%28d%3Ad%2FCategory%20eq%20%27English%20Literature%27%29%29
            // http://host/Students?$filter=StudentId gt 100 and Courses/any(c:c/Teacher/Education/Degrees/any(d:d/Category eq 'English Literature'))
        }
        public override Expression Visit(BinaryOperatorNode nodeIn)
        {
            Expression left  = TranslateNode(nodeIn.Left);
            Expression right = TranslateNode(nodeIn.Right);

            if (left.Type != right.Type)
            {
                Type leftType  = left.Type;
                Type rightType = right.Type;

                if (OeExpressionHelper.IsNullable(left) && !OeExpressionHelper.IsNull(left))
                {
                    if (OeExpressionHelper.IsNull(right))
                    {
                        ConstantExpression newConstant = Expression.Constant(null, leftType);
                        ReplaceConstant((ConstantExpression)right, newConstant);
                        right = newConstant;
                    }
                    else
                    {
                        leftType = Nullable.GetUnderlyingType(left.Type);
                    }
                }
                else if (OeExpressionHelper.IsNullable(right) && !OeExpressionHelper.IsNull(right))
                {
                    if (OeExpressionHelper.IsNull(left))
                    {
                        ConstantExpression newConstant = Expression.Constant(null, rightType);
                        ReplaceConstant((ConstantExpression)left, newConstant);
                        left = newConstant;
                    }
                    else
                    {
                        rightType = Nullable.GetUnderlyingType(right.Type);
                    }
                }

                if (right.Type != left.Type)
                {
                    if (left is ConstantExpression)
                    {
                        ConstantExpression oldConstant = left as ConstantExpression;
                        ConstantExpression newConstant = OeExpressionHelper.ConstantChangeType(oldConstant, rightType);
                        if (oldConstant != newConstant)
                        {
                            ReplaceConstant(oldConstant, newConstant);
                        }
                        left = Expression.Convert(newConstant, right.Type);
                    }
                    else if (right is ConstantExpression)
                    {
                        ConstantExpression oldConstant = right as ConstantExpression;
                        ConstantExpression newConstant = OeExpressionHelper.ConstantChangeType(oldConstant, leftType);
                        if (oldConstant != newConstant)
                        {
                            ReplaceConstant(oldConstant, newConstant);
                        }
                        right = Expression.Convert(newConstant, left.Type);
                    }
                    else
                    {
                        Type precedenceType = OeExpressionHelper.GetTypeConversion(left.Type, right.Type);
                        if (left.Type != precedenceType)
                        {
                            left = Expression.Convert(left, precedenceType);
                        }
                        if (right.Type != precedenceType)
                        {
                            right = Expression.Convert(right, precedenceType);
                        }
                    }
                }
            }
            ExpressionType binaryType = OeExpressionHelper.ToExpressionType(nodeIn.OperatorKind);

            if (left.Type == typeof(String) && !(binaryType == ExpressionType.Equal || binaryType == ExpressionType.NotEqual))
            {
                Func <String, String, int> compareToFunc = String.Compare;
                MethodCallExpression       compareToCall = Expression.Call(null, compareToFunc.GetMethodInfo(), left, right);
                return(Expression.MakeBinary(binaryType, compareToCall, OeConstantToVariableVisitor.ZeroStringCompareConstantExpression));
            }

            return(Expression.MakeBinary(binaryType, left, right));
        }
Exemple #16
0
 /// <summary>
 /// Binds the specified <see cref="BinaryOperatorNode"/>.
 /// </summary>
 /// <param name="binaryOperatorNode">The <see cref="BinaryOperatorNode"/> to bind.</param>
 protected abstract void Bind(BinaryOperatorNode binaryOperatorNode);
Exemple #17
0
        private double Evaluate(BaseNode node)
        {
            double result = 0;

            if (node == null)
            {
                return(0);
            }

            // as a constant node
            ConstantNumbericalNode constantNode = node as ConstantNumbericalNode;

            if (constantNode != null)
            {
                result = constantNode.Value;
                return(result);
            }

            // as a variable
            VariableNode variableNode = node as VariableNode;

            if (variableNode != null)
            {
                // if the variable node name is in the dictionary
                if (this.keyValuePairs.ContainsKey(variableNode.Name))
                {
                    result = this.keyValuePairs[variableNode.Name];
                    return(result);
                }

                // otherwise return 0
                return(0);
            }

            // an operator node
            BinaryOperatorNode operatorNode = node as BinaryOperatorNode;

            if (operatorNode != null)
            {
                // choose operator
                switch (operatorNode.BinaryOperator)
                {
                case '+':
                    result = this.Evaluate(operatorNode.Left) + this.Evaluate(operatorNode.Right);
                    break;

                case '-':
                    result = this.Evaluate(operatorNode.Left) - this.Evaluate(operatorNode.Right);
                    break;

                case '*':
                    result = this.Evaluate(operatorNode.Left) * this.Evaluate(operatorNode.Right);
                    break;

                case '/':
                    result = this.Evaluate(operatorNode.Left) / this.Evaluate(operatorNode.Right);
                    break;
                }

                return(result);
            }

            return(0);
        }
Exemple #18
0
 public void Visit(BinaryOperatorNode op)
 {
     throw new NotSupportedException();
 }
        public override FilterNode <ClrValue> Visit(BinaryOperatorNode nodeIn)
        {
            if (nodeIn.OperatorKind == BinaryOperatorKind.And)
            {
                return(ClrFilter.And(nodeIn.Left.Accept(this), nodeIn.Right.Accept(this)));
            }

            if (nodeIn.OperatorKind == BinaryOperatorKind.Or)
            {
                return(ClrFilter.Or(nodeIn.Left.Accept(this), nodeIn.Right.Accept(this)));
            }

            if (nodeIn.Left is SingleValueFunctionCallNode functionNode)
            {
                var regexFilter = Visit(functionNode);

                var value = ConstantWithTypeVisitor.Visit(nodeIn.Right);

                if (value.ValueType == ClrValueType.Boolean && value.Value is bool booleanRight)
                {
                    if ((nodeIn.OperatorKind == BinaryOperatorKind.Equal && !booleanRight) ||
                        (nodeIn.OperatorKind == BinaryOperatorKind.NotEqual && booleanRight))
                    {
                        regexFilter = ClrFilter.Not(regexFilter);
                    }

                    return(regexFilter);
                }
            }
            else
            {
                if (nodeIn.OperatorKind == BinaryOperatorKind.NotEqual)
                {
                    var value = ConstantWithTypeVisitor.Visit(nodeIn.Right);

                    return(ClrFilter.Ne(PropertyPathVisitor.Visit(nodeIn.Left), value));
                }

                if (nodeIn.OperatorKind == BinaryOperatorKind.Equal)
                {
                    var value = ConstantWithTypeVisitor.Visit(nodeIn.Right);

                    return(ClrFilter.Eq(PropertyPathVisitor.Visit(nodeIn.Left), value));
                }

                if (nodeIn.OperatorKind == BinaryOperatorKind.LessThan)
                {
                    var value = ConstantWithTypeVisitor.Visit(nodeIn.Right);

                    return(ClrFilter.Lt(PropertyPathVisitor.Visit(nodeIn.Left), value));
                }

                if (nodeIn.OperatorKind == BinaryOperatorKind.LessThanOrEqual)
                {
                    var value = ConstantWithTypeVisitor.Visit(nodeIn.Right);

                    return(ClrFilter.Le(PropertyPathVisitor.Visit(nodeIn.Left), value));
                }

                if (nodeIn.OperatorKind == BinaryOperatorKind.GreaterThan)
                {
                    var value = ConstantWithTypeVisitor.Visit(nodeIn.Right);

                    return(ClrFilter.Gt(PropertyPathVisitor.Visit(nodeIn.Left), value));
                }

                if (nodeIn.OperatorKind == BinaryOperatorKind.GreaterThanOrEqual)
                {
                    var value = ConstantWithTypeVisitor.Visit(nodeIn.Right);

                    return(ClrFilter.Ge(PropertyPathVisitor.Visit(nodeIn.Left), value));
                }
            }

            throw new NotSupportedException();
        }
        /// <summary>
        /// Writes binary operator node to string
        /// </summary>
        /// <param name="node">Node to write to string</param>
        /// <returns>String representation of node.</returns>
        private static string ToString(BinaryOperatorNode node)
        {
            if (node != null)
            {
                return tabHelper.Indent(() => ToString(node.Left)) +
                    tabHelper.Prefix + node.OperatorKind +
                    tabHelper.Indent(() => (ToString(node.Right)));
            }

            return String.Empty;
        }
Exemple #21
0
        public override Expression Visit(BinaryOperatorNode nodeIn)
        {
            Expression left  = TranslateNode(nodeIn.Left);
            Expression right = TranslateNode(nodeIn.Right);

            if (left.Type != right.Type)
            {
                Type leftType  = left.Type;
                Type rightType = right.Type;

                Type?leftUnderlyingType = Nullable.GetUnderlyingType(left.Type);
                if (leftUnderlyingType != null && !OeExpressionHelper.IsNull(left))
                {
                    if (OeExpressionHelper.IsNull(right))
                    {
                        right = OeConstantToVariableVisitor.NullConstantExpression;
                    }
                    else
                    {
                        leftType = leftUnderlyingType;
                    }
                }
                else
                {
                    Type?rightUnderlyingType = Nullable.GetUnderlyingType(right.Type);
                    if (rightUnderlyingType != null && !OeExpressionHelper.IsNull(right))
                    {
                        if (OeExpressionHelper.IsNull(left))
                        {
                            left = OeConstantToVariableVisitor.NullConstantExpression;
                        }
                        else
                        {
                            rightType = rightUnderlyingType;
                        }
                    }
                }

                if (right.Type != left.Type)
                {
                    if (left is ConstantExpression leftOldConstant)
                    {
                        ConstantExpression newConstant = OeExpressionHelper.ConstantChangeType(leftOldConstant, rightType);
                        if (leftOldConstant != newConstant)
                        {
                            ReplaceConstant(leftOldConstant, newConstant);
                        }

                        if (newConstant.Value != null)
                        {
                            left = Expression.Convert(newConstant, right.Type);
                        }
                    }
                    else if (right is ConstantExpression rightOldConstant)
                    {
                        ConstantExpression newConstant = OeExpressionHelper.ConstantChangeType(rightOldConstant, leftType);
                        if (rightOldConstant != newConstant)
                        {
                            ReplaceConstant(rightOldConstant, newConstant);
                        }

                        if (newConstant.Value != null)
                        {
                            right = Expression.Convert(newConstant, left.Type);
                        }
                    }
                    else
                    {
                        Type precedenceType = OeExpressionHelper.GetTypeConversion(left.Type, right.Type);
                        if (left.Type != precedenceType)
                        {
                            left = Expression.Convert(left, precedenceType);
                        }
                        if (right.Type != precedenceType)
                        {
                            right = Expression.Convert(right, precedenceType);
                        }
                    }
                }
            }
            ExpressionType binaryType = OeExpressionHelper.ToExpressionType(nodeIn.OperatorKind);

            if (!(binaryType == ExpressionType.Equal || binaryType == ExpressionType.NotEqual))
            {
                if (left.Type == typeof(String))
                {
                    Func <String, String, int> compareToFunc = String.Compare;
                    MethodCallExpression       compareToCall = Expression.Call(null, compareToFunc.GetMethodInfo(), left, right);
                    return(Expression.MakeBinary(binaryType, compareToCall, OeConstantToVariableVisitor.ZeroStringCompareConstantExpression));
                }

                Type?underlyingType;
                if (left.Type.IsEnum)
                {
                    Type enumUnderlyingType = Enum.GetUnderlyingType(left.Type);
                    left  = ConvertEnumExpression(left, enumUnderlyingType);
                    right = ConvertEnumExpression(right, enumUnderlyingType);
                }
                else if ((underlyingType = Nullable.GetUnderlyingType(left.Type)) != null && underlyingType.IsEnum)
                {
                    Type enumUnderlyingType     = Enum.GetUnderlyingType(underlyingType);
                    Type nullableUnderlyingType = typeof(Nullable <>).MakeGenericType(enumUnderlyingType);
                    left  = ConvertEnumExpression(left, nullableUnderlyingType);
                    right = ConvertEnumExpression(right, nullableUnderlyingType);
                }
            }

            return(Expression.MakeBinary(binaryType, left, right));
 private string BindBinaryOperatorNode(BinaryOperatorNode binaryOperatorNode)
 {
     var left = Bind(binaryOperatorNode.Left);
     var right = Bind(binaryOperatorNode.Right);
     return "(" + left + " " + ToString(binaryOperatorNode.OperatorKind) + " " + right + ")";
 }
        private void UpdateDeltaToken()
        {
            this.deltaToken = this.maxUpdatedAt;

            if (this.ordered)
            {
                this.Query.Ordering.Clear();
                this.Query.Ordering.Add(orderByUpdatedAtNode);
            }
            // .NET runtime system properties are of datetimeoffset type so we'll use the datetimeoffset odata token
            QueryNode tokenNode = new ConstantNode(deltaToken);
            QueryNode greaterThanDeltaNode = new BinaryOperatorNode(BinaryOperatorKind.GreaterThanOrEqual, updatedAtNode, tokenNode);
            if (this.originalFilter == null)
            {
                this.Query.Filter = greaterThanDeltaNode;
            }
            else
            {
                var originalFilterAndGreaterThanDeltaNode = new BinaryOperatorNode(BinaryOperatorKind.And, this.originalFilter, greaterThanDeltaNode);
                this.Query.Filter = originalFilterAndGreaterThanDeltaNode;
            }
        }
Exemple #24
0
 public virtual BinaryOperatorNode Visit(BinaryOperatorNode bin)
 {
     return(bin);
 }
        /// <summary>
        /// override this method to restrict the binary operators inside the filter query. That includes all the logical operators except 'not' and all math operators.
        /// </summary>
        /// <remarks>
        /// This method is intended to be called from method overrides in subclasses. This method also supports unit-testing scenarios and is not intended to be called from user code.
        /// Call the Validate method to validate a <see cref="FilterQueryOption"/> instance.
        /// </remarks>
        /// <param name="binaryOperatorNode"></param>
        /// <param name="settings"></param>
        public virtual void ValidateBinaryOperatorNode(BinaryOperatorNode binaryOperatorNode, ODataValidationSettings settings)
        {
            if (binaryOperatorNode == null)
            {
                throw Error.ArgumentNull("binaryOperatorNode");
            }

            if (settings == null)
            {
                throw Error.ArgumentNull("settings");
            }

            // base case goes
            switch (binaryOperatorNode.OperatorKind)
            {
                case BinaryOperatorKind.Equal:
                case BinaryOperatorKind.NotEqual:
                case BinaryOperatorKind.And:
                case BinaryOperatorKind.GreaterThan:
                case BinaryOperatorKind.GreaterThanOrEqual:
                case BinaryOperatorKind.LessThan:
                case BinaryOperatorKind.LessThanOrEqual:
                case BinaryOperatorKind.Or:
                    // binary logical operators
                    ValidateLogicalOperator(binaryOperatorNode, settings);
                    break;
                default:
                    // math operators
                    ValidateArithmeticOperator(binaryOperatorNode, settings);
                    break;
            }
        }
Exemple #26
0
 public override void Init(AstContext context, ParseTreeNode parseNode)
 {
     Left = parseNode.ChildNodes[0].AstNode as Node;
     BinaryOperator = (parseNode.ChildNodes[1].AstNode as BinaryOperatorNode);
     Right = parseNode.ChildNodes[2].AstNode as Node;
 }
Exemple #27
0
        private string ResolveLamdaNode(LambdaNode node)
        {
            BinaryOperatorNode expression         = node.Body as BinaryOperatorNode;
            string             alias              = "";
            string             propertyName       = "";
            string             parentPropertyName = "";
            string             rootPropertyName   = "";

            //Property at root
            if (expression.Left is NonentityRangeVariableReferenceNode)
            {
                var leftNode = expression.Left as NonentityRangeVariableReferenceNode;
                alias = leftNode.Name;

                if (node.Source is CollectionPropertyAccessNode)
                {
                    propertyName = (node.Source as CollectionPropertyAccessNode).Property.Name;
                }
            }
            else if (expression.Left is SingleValuePropertyAccessNode)
            {
                var leftNode = expression.Left as SingleValuePropertyAccessNode;
                if (leftNode.Source is NonentityRangeVariableReferenceNode)
                {
                    alias = (leftNode.Source as NonentityRangeVariableReferenceNode).Name;
                }
                else if (leftNode.Source is EntityRangeVariableReferenceNode)
                {
                    alias = (leftNode.Source as EntityRangeVariableReferenceNode).Name;
                }
                propertyName = leftNode.Property.Name;

                if (node.Source is CollectionPropertyAccessNode)
                {
                    parentPropertyName = (node.Source as CollectionPropertyAccessNode).Property.Name;
                    var sourceNode = node.Source as CollectionPropertyAccessNode;
                    if (sourceNode.Source is SingleValuePropertyAccessNode)
                    {
                        var rootNode = sourceNode.Source as SingleValuePropertyAccessNode;
                        rootPropertyName = rootNode.Property.Name;
                    }
                }
                else if (node.Source is CollectionNavigationNode)
                {
                    var sourceNode = node.Source as CollectionNavigationNode;
                    parentPropertyName = sourceNode.NavigationProperty.Name;
                    if (sourceNode.Source is SingleNavigationNode)
                    {
                        var rootNode = sourceNode.Source as SingleNavigationNode;
                        rootPropertyName = rootNode.NavigationProperty.Name;
                    }
                }
            }

            var rightExpression = (expression.Right as ConstantNode).LiteralText;

            var mappedPropertyName = _fieldMapper.Map(propertyName, parentPropertyName, rootPropertyName);
            var lamdaProperty      = node.Kind == QueryNodeKind.Any ? "any" : "all";
            var expressionFormat   = $"{mappedPropertyName}/{lamdaProperty}({alias}: {alias} eq {rightExpression})";

            return(expressionFormat);
        }
 public override void ValidateBinaryOperatorNode(BinaryOperatorNode binaryOperatorNode, ODataValidationSettings settings)
 {
     IncrementCount("ValidateBinaryOperatorQueryNode");
     base.ValidateBinaryOperatorNode(binaryOperatorNode, settings);
 }
 /// <summary>
 /// Visit a <see cref="BinaryOperatorNode"/>
 /// </summary>
 public abstract T Visit(BinaryOperatorNode node);
Exemple #30
0
 private string BindBinaryOperatorNode(BinaryOperatorNode binaryOperatorNode)
 {
     var left = Bind(binaryOperatorNode.Left);
     var right = Bind(binaryOperatorNode.Right);
     if (binaryOperatorNode.OperatorKind == BinaryOperatorKind.Equal
         && right == "null")
         return "(" + left + " is null)";
     if (binaryOperatorNode.OperatorKind == BinaryOperatorKind.NotEqual
         && right == "null")
         return "(" + left + " is not null)";
     return "(" + left + " " + ToString(binaryOperatorNode.OperatorKind) + " " + right + ")";
 }
Exemple #31
0
        private static void BuildFilterWithNestedAny()
        {
            var personTypeRef = new EdmEntityTypeReference(TripPinModel.Person, false);
            var tripTypeRef = new EdmEntityTypeReference(TripPinModel.Trip, false);

            var friendsProp = (IEdmNavigationProperty)TripPinModel.Person.FindProperty("Friends");
            var tripsProp = (IEdmNavigationProperty)TripPinModel.Person.FindProperty("Trips");
            var budgetProp = TripPinModel.Trip.FindProperty("Budget");

            var topIt = new EntityRangeVariable("$it", personTypeRef, TripPinModel.PeopleSet);
            var topItRef = new EntityRangeVariableReferenceNode("$it", topIt);

            var friendsNavNode0 = new CollectionNavigationNode(friendsProp, topItRef);
            var e0 = new EntityRangeVariable("e0", personTypeRef, friendsNavNode0);
            var e0Ref = new EntityRangeVariableReferenceNode("e0", e0);

            var friendsNavNode1 = new CollectionNavigationNode(friendsProp, e0Ref);
            var e1 = new EntityRangeVariable("e1", personTypeRef, friendsNavNode1);
            var e1Ref = new EntityRangeVariableReferenceNode("e1", e1);

            var tripNavNode = new CollectionNavigationNode(tripsProp, e1Ref);
            var e2 = new EntityRangeVariable("e2", tripTypeRef, friendsNavNode1);
            var e2Ref = new EntityRangeVariableReferenceNode("e2", e2);

            var bugetNode = new SingleValuePropertyAccessNode(e2Ref, budgetProp);

            var gt = new BinaryOperatorNode(
                BinaryOperatorKind.GreaterThan,
                bugetNode,
                new ConstantNode(1200, "1200"));

            var any2 = new AnyNode(new Collection<RangeVariable> { e2 }, e2) { Body = gt, Source = tripNavNode };
            var any1 = new AnyNode(new Collection<RangeVariable> { e1 }, e1) { Body = any2, Source = friendsNavNode1 };
            var any0 = new AnyNode(new Collection<RangeVariable> { e0 }, e0) { Body = any1, Source = friendsNavNode0 };


            var odataUri = new ODataUri
            {
                Path = new ODataPath(new EntitySetSegment(TripPinModel.PeopleSet)),
                ServiceRoot = TripPinRoot,
                Filter = new FilterClause(any0, topIt)
            };
            var builder = new ODataUriBuilder(ODataUrlConventions.Default, odataUri);
            Console.WriteLine(builder.BuildUri());
            // http://services.odata.org/V4/TripPinService/People?$filter=Friends%2Fany(e0:e0%2FFriends%2Fany(e1:e1%2FTrips%2Fany(e2:e2%2FBudget gt 1200)))
        }
 public override void ValidateLogicalOperator(BinaryOperatorNode binaryNode, ODataValidationSettings settings)
 {
     IncrementCount("ValidateLogicalOperator");
     base.ValidateLogicalOperator(binaryNode, settings);
 }
        public static IEnumerable<FilterTestCase> UnaryOperatorTestCases()
        {
            // Single unary operator
            UnaryOperatorNode left = new UnaryOperatorNode(UnaryOperatorKind.Negate, new ConstantNode(1));
            yield return new FilterTestCase()
            {
                Filter = UnaryOperatorKind.Negate.ToOperatorName() + "(1) le 5",
                ExpectedFilterCondition = new BinaryOperatorNode(BinaryOperatorKind.LessThanOrEqual, left, new ConstantNode(5))
            };

            yield return new FilterTestCase()
            {
                Filter = UnaryOperatorKind.Not.ToOperatorName() + " true",
                ExpectedFilterCondition = new UnaryOperatorNode(UnaryOperatorKind.Not, new ConstantNode(true))
            };

            // Two unary operators
            UnaryOperatorNode inner = new UnaryOperatorNode(UnaryOperatorKind.Negate, new ConstantNode(1));
            UnaryOperatorNode outer = new UnaryOperatorNode(UnaryOperatorKind.Negate, inner);
            yield return new FilterTestCase()
            {
                Filter = UnaryOperatorKind.Negate.ToOperatorName() + "(" + UnaryOperatorKind.Negate.ToOperatorName() + "(1)) le 5",
                ExpectedFilterCondition = new BinaryOperatorNode(BinaryOperatorKind.LessThanOrEqual, outer, new ConstantNode(5))
            };

            UnaryOperatorNode inner2 = new UnaryOperatorNode(UnaryOperatorKind.Not, new ConstantNode(true));
            yield return new FilterTestCase()
            {
                Filter = UnaryOperatorKind.Not.ToOperatorName() + " " + UnaryOperatorKind.Not.ToOperatorName() + " true",
                ExpectedFilterCondition = new UnaryOperatorNode(UnaryOperatorKind.Not, inner2)
            };

            // Unary and binary operator.
            UnaryOperatorNode inner3 = new UnaryOperatorNode(UnaryOperatorKind.Not, new ConstantNode(true));
            yield return new FilterTestCase()
            {
                Filter = UnaryOperatorKind.Not.ToOperatorName() + " true " + BinaryOperatorKind.Equal.ToOperatorName() + " false",
                ExpectedFilterCondition = new BinaryOperatorNode(BinaryOperatorKind.Equal, inner3, new ConstantNode(false))
            };

            // With parenthesis
            BinaryOperatorNode innerBinary = new BinaryOperatorNode(BinaryOperatorKind.Add, new ConstantNode(2), new ConstantNode(3));
            UnaryOperatorNode outer2 = new UnaryOperatorNode(UnaryOperatorKind.Negate, innerBinary);
            yield return new FilterTestCase()
            {
                Filter = UnaryOperatorKind.Negate.ToOperatorName() + " (2 " + BinaryOperatorKind.Add.ToOperatorName() + " 3) le 5",
                ExpectedFilterCondition = new BinaryOperatorNode(BinaryOperatorKind.LessThanOrEqual, outer2, new ConstantNode(5))
            };

            BinaryOperatorNode innerBinary2 = new BinaryOperatorNode(BinaryOperatorKind.Equal, new ConstantNode(true), new ConstantNode(false));
            yield return new FilterTestCase()
            {
                Filter = UnaryOperatorKind.Not.ToOperatorName() + " (true " + BinaryOperatorKind.Equal.ToOperatorName() + " false)",
                ExpectedFilterCondition = new UnaryOperatorNode(UnaryOperatorKind.Not, innerBinary2)
            };
        }
        /// <summary>
        /// Override this method for the Arithmetic operators, including add, sub, mul, div, mod.
        /// </summary>
        /// <remarks>
        /// This method is intended to be called from method overrides in subclasses. This method also supports unit-testing scenarios and is not intended to be called from user code.
        /// Call the Validate method to validate a <see cref="FilterQueryOption"/> instance.
        /// </remarks>
        /// <param name="binaryNode"></param>
        /// <param name="settings"></param>
        public virtual void ValidateArithmeticOperator(BinaryOperatorNode binaryNode, ODataValidationSettings settings)
        {
            if (binaryNode == null)
            {
                throw Error.ArgumentNull("binaryNode");
            }

            if (settings == null)
            {
                throw Error.ArgumentNull("settings");
            }

            AllowedArithmeticOperators arithmeticOperator = ToArithmeticOperator(binaryNode);

            if ((settings.AllowedArithmeticOperators & arithmeticOperator) != arithmeticOperator)
            {
                // this means the given logical operator is not allowed
                throw new ODataException(Error.Format(SRResources.NotAllowedArithmeticOperator, arithmeticOperator, "AllowedArithmeticOperators"));
            }

            // recursion case goes here
            ValidateQueryNode(binaryNode.Left, settings);
            ValidateQueryNode(binaryNode.Right, settings);
        }
        static IEnumerable<FilterTestCase> BinaryOperatorTestCases()
        {
            #region Single operator
            foreach (var operatorKind in QueryTestUtils.BinaryOperatorGroups.Where(og => og.IsRelational).SelectMany(og => og.OperatorKinds))
            {
                yield return new FilterTestCase()
                {
                    Filter = "false " + operatorKind.ToOperatorName() + " true",
                    ExpectedFilterCondition = new BinaryOperatorNode(operatorKind, new ConstantNode(false), new ConstantNode(true))
                };
            }

            foreach (var operatorKind in QueryTestUtils.BinaryOperatorGroups.Where(og => !og.IsRelational).SelectMany(og => og.OperatorKinds))
            {
                BinaryOperatorNode left = new BinaryOperatorNode(operatorKind, new ConstantNode(1), new ConstantNode(2));
                yield return new FilterTestCase()
                {
                    Filter = "1 " + operatorKind.ToOperatorName() + " 2 le 5",
                    ExpectedFilterCondition = new BinaryOperatorNode(BinaryOperatorKind.LessThanOrEqual, left, new ConstantNode(5))
                };
            }
            #endregion Single operator

            #region Two operators from the same group
            foreach (var operatorGroup in QueryTestUtils.BinaryOperatorGroups.Where(od => od.IsRelational))
            {
                IEnumerable<BinaryOperatorKind[]> operatorPairs = new[] {
                    new BinaryOperatorKind[] { operatorGroup.OperatorKinds[0], operatorGroup.OperatorKinds[0] }
                };
                if (operatorGroup.OperatorKinds.Length > 1)
                {
                    operatorPairs = operatorPairs.Concat(operatorGroup.OperatorKinds.Variations(2));
                }

                foreach (var operatorPair in operatorPairs)
                {
                    BinaryOperatorNode left = new BinaryOperatorNode(operatorPair[0], new ConstantNode(true), new ConstantNode(false));
                    yield return new FilterTestCase()
                    {
                        Filter = "true " + operatorPair[0].ToOperatorName() + " false " + operatorPair[1].ToOperatorName() + " true",
                        ExpectedFilterCondition = new BinaryOperatorNode(operatorPair[1], left, new ConstantNode(true))
                    };

                    BinaryOperatorNode right = new BinaryOperatorNode(operatorPair[1], new ConstantNode(false), new ConstantNode(true));
                    yield return new FilterTestCase()
                    {
                        Filter = "true " + operatorPair[0].ToOperatorName() + " (false " + operatorPair[1].ToOperatorName() + " true)",
                        ExpectedFilterCondition = new BinaryOperatorNode(operatorPair[0], new ConstantNode(true), right)
                    };
                }
            }

            foreach (var operatorGroup in QueryTestUtils.BinaryOperatorGroups.Where(od => !od.IsRelational))
            {
                IEnumerable<BinaryOperatorKind[]> operatorPairs = new[] {
                    new BinaryOperatorKind[] { operatorGroup.OperatorKinds[0], operatorGroup.OperatorKinds[0] }
                };
                if (operatorGroup.OperatorKinds.Length > 1)
                {
                    operatorPairs = operatorPairs.Concat(operatorGroup.OperatorKinds.Variations(2));
                }

                foreach (var operatorPair in operatorPairs)
                {
                    BinaryOperatorNode innerLeft1 = new BinaryOperatorNode(operatorPair[0], new ConstantNode(1), new ConstantNode(2));
                    BinaryOperatorNode outerLeft1 = new BinaryOperatorNode(operatorPair[1], innerLeft1, new ConstantNode(3));
                    yield return new FilterTestCase()
                    {
                        Filter = "1 " + operatorPair[0].ToOperatorName() + " 2 " + operatorPair[1].ToOperatorName() + " 3 le 5",
                        ExpectedFilterCondition = new BinaryOperatorNode(BinaryOperatorKind.LessThanOrEqual, outerLeft1, new ConstantNode(5))
                    };


                    BinaryOperatorNode innerRight2 = new BinaryOperatorNode(operatorPair[1], new ConstantNode(2), new ConstantNode(3));
                    BinaryOperatorNode outerLeft2 = new BinaryOperatorNode(operatorPair[0], new ConstantNode(1), innerRight2);
                    yield return new FilterTestCase()
                    {
                        Filter = "1 " + operatorPair[0].ToOperatorName() + " (2 " + operatorPair[1].ToOperatorName() + " 3) le 5",
                        ExpectedFilterCondition = new BinaryOperatorNode(BinaryOperatorKind.LessThanOrEqual, outerLeft2, new ConstantNode(5))
                    };
                }
            }
            #endregion Two operators from the same group

            #region Two operators from different groups
            foreach (var operatorGroupHigher in QueryTestUtils.BinaryOperatorGroups.Where(og => og.IsRelational))
            {
                foreach (var operatorGroupLower in QueryTestUtils.BinaryOperatorGroups.Where(og => og.IsRelational && og.Priority > operatorGroupHigher.Priority))
                {
                    foreach (var operatorKindHigher in operatorGroupHigher.OperatorKinds)
                    {
                        foreach (var operatorKindLower in operatorGroupLower.OperatorKinds)
                        {
                            BinaryOperatorNode left = new BinaryOperatorNode(operatorKindLower, new ConstantNode(true), new ConstantNode(false));
                            // Lower and higher
                            yield return new FilterTestCase()
                            {
                                Filter = "true " + operatorKindLower.ToOperatorName() + " false " + operatorKindHigher.ToOperatorName() + " true",
                                ExpectedFilterCondition = new BinaryOperatorNode(operatorKindHigher, left, new ConstantNode(true))
                            };

                            // Lower and higher with parentheses
                            BinaryOperatorNode right = new BinaryOperatorNode(operatorKindHigher, new ConstantNode(false), new ConstantNode(true));
                            yield return new FilterTestCase()
                            {
                                Filter = "true " + operatorKindLower.ToOperatorName() + " (false " + operatorKindHigher.ToOperatorName() + " true)",
                                ExpectedFilterCondition = new BinaryOperatorNode(operatorKindLower, new ConstantNode(true), right)

                            };

                            BinaryOperatorNode right2 = new BinaryOperatorNode(operatorKindLower, new ConstantNode(false), new ConstantNode(true));

                            // Higher and lower
                            yield return new FilterTestCase()
                            {
                                Filter = "true " + operatorKindHigher.ToOperatorName() + " false " + operatorKindLower.ToOperatorName() + " true",
                                ExpectedFilterCondition = new BinaryOperatorNode(operatorKindHigher, new ConstantNode(true), right2)
                            };
                        }
                    }
                }
            }

            foreach (var operatorGroupHigher in QueryTestUtils.BinaryOperatorGroups.Where(og => !og.IsRelational))
            {
                foreach (var operatorGroupLower in QueryTestUtils.BinaryOperatorGroups.Where(og => !og.IsRelational && og.Priority > operatorGroupHigher.Priority))
                {
                    foreach (var operatorKindHigher in operatorGroupHigher.OperatorKinds)
                    {
                        foreach (var operatorKindLower in operatorGroupLower.OperatorKinds)
                        {
                            // Lower and higher
                            BinaryOperatorNode innerLeft = new BinaryOperatorNode(operatorKindLower, new ConstantNode(1), new ConstantNode(2));
                            BinaryOperatorNode outerLeft = new BinaryOperatorNode(operatorKindHigher, innerLeft, new ConstantNode(3));
                            yield return new FilterTestCase()
                            {
                                Filter = "1 " + operatorKindLower.ToOperatorName() + " 2 " + operatorKindHigher.ToOperatorName() + " 3 le 5",
                                ExpectedFilterCondition = new BinaryOperatorNode(BinaryOperatorKind.LessThanOrEqual, outerLeft, new ConstantNode(5))
                            };

                            // Lower and higher with parentheses
                            BinaryOperatorNode innerRight = new BinaryOperatorNode(operatorKindHigher, new ConstantNode(2), new ConstantNode(3));
                            BinaryOperatorNode outerLeft2 = new BinaryOperatorNode(operatorKindLower, new ConstantNode(1), innerRight);
                            yield return new FilterTestCase()
                            {
                                Filter = "1 " + operatorKindLower.ToOperatorName() + " (2 " + operatorKindHigher.ToOperatorName() + " 3) le 5",
                                ExpectedFilterCondition = new BinaryOperatorNode(BinaryOperatorKind.LessThanOrEqual, outerLeft2, new ConstantNode(5))
                            };

                            // Higher and lower
                            BinaryOperatorNode innerRight2 = new BinaryOperatorNode(operatorKindLower, new ConstantNode(2), new ConstantNode(3));
                            BinaryOperatorNode outerLeft3 = new BinaryOperatorNode(operatorKindHigher, new ConstantNode(1), innerRight2);

                            yield return new FilterTestCase()
                            {
                                Filter = "1 " + operatorKindHigher.ToOperatorName() + " 2 " + operatorKindLower.ToOperatorName() + " 3 le 5",
                                ExpectedFilterCondition = new BinaryOperatorNode(BinaryOperatorKind.LessThanOrEqual, outerLeft3, new ConstantNode(5))
                            };
                        }
                    }
                }
            }
            #endregion Two operators from different groups
        }
        private static AllowedArithmeticOperators ToArithmeticOperator(BinaryOperatorNode binaryNode)
        {
            AllowedArithmeticOperators result = AllowedArithmeticOperators.None;

            switch (binaryNode.OperatorKind)
            {
                case BinaryOperatorKind.Add:
                    result = AllowedArithmeticOperators.Add;
                    break;

                case BinaryOperatorKind.Divide:
                    result = AllowedArithmeticOperators.Divide;
                    break;

                case BinaryOperatorKind.Modulo:
                    result = AllowedArithmeticOperators.Modulo;
                    break;

                case BinaryOperatorKind.Multiply:
                    result = AllowedArithmeticOperators.Multiply;
                    break;

                case BinaryOperatorKind.Subtract:
                    result = AllowedArithmeticOperators.Subtract;
                    break;

                default:
                    // should never be here
                    Contract.Assert(false, "ToArithmeticOperator should never be here.");
                    break;
            }

            return result;
        }
Exemple #37
0
 private static void VerifyBinaryOperatorQueryNodesAreEqual(BinaryOperatorNode expected, BinaryOperatorNode actual, AssertionHandler assert)
 {
     assert.AreEqual(expected.OperatorKind, actual.OperatorKind, "Operator kinds differ.");
     VerifyQueryNodesAreEqual(expected.Left, actual.Left, assert);
     VerifyQueryNodesAreEqual(expected.Right, actual.Right, assert);
 }
        private QueryNode ParseMultiplicative()
        {
            QueryNode left = this.ParseUnary();

            while (this.lexer.Token.Kind == QueryTokenKind.Multiply ||
                   this.lexer.Token.Kind == QueryTokenKind.Divide ||
                   this.lexer.Token.Kind == QueryTokenKind.Modulo)
            {
                QueryTokenKind opKind = this.lexer.Token.Kind;
                this.lexer.NextToken();
                var right = this.ParseUnary();
                switch (opKind)
                {
                    case QueryTokenKind.Multiply:
                        left = new BinaryOperatorNode(BinaryOperatorKind.Multiply, left, right);
                        break;
                    case QueryTokenKind.Divide:
                        left = new BinaryOperatorNode(BinaryOperatorKind.Divide, left, right);
                        break;
                    case QueryTokenKind.Modulo:
                        left = new BinaryOperatorNode(BinaryOperatorKind.Modulo, left, right);
                        break;
                }
            }
            return left;
        }
        /// <summary>
        /// Process binary comparison operators.
        /// </summary>
        /// <param name="expression">
        /// The expression to visit.
        /// </param>
        /// <returns>
        /// The visited expression.
        /// </returns>
        private Expression VisitBinary(BinaryExpression expression)
        {
            if (expression != null)
            {
                // special case for enums, because we send them as strings
                UnaryExpression enumExpression = null;
                ConstantExpression constantExpression = null;
                BinaryExpression stringCompareExpression = null;
                if (this.CheckEnumExpression(expression, out enumExpression, out constantExpression))
                {
                    this.Visit(this.RewriteEnumExpression(enumExpression, (ConstantExpression)expression.Right, expression.NodeType));            
                }
                // special case concat as it's OData function isn't infix
                else if (expression.NodeType == ExpressionType.Add &&
                    expression.Left.Type == typeof(string) &&
                    expression.Right.Type == typeof(string))
                {
                    //rewrite addition into a call to concat, instead of duplicating generation code.
                    this.Visit(this.RewriteStringAddition(expression));
                }
                // special case for string comparisons emitted by the VB compiler
                else if (this.CheckVBStringCompareExpression(expression, out stringCompareExpression))
                {
                    this.Visit(stringCompareExpression);
                }
                else
                {
                    BinaryOperatorKind operatorKind;
                    switch (expression.NodeType)
                    {
                        case ExpressionType.AndAlso:
                        case ExpressionType.And:
                            operatorKind = BinaryOperatorKind.And;
                            break;
                        case ExpressionType.Or:
                        case ExpressionType.OrElse:
                            operatorKind = BinaryOperatorKind.Or;
                            break;
                        case ExpressionType.Equal:
                            operatorKind = BinaryOperatorKind.Equal;
                            break;
                        case ExpressionType.NotEqual:
                            operatorKind = BinaryOperatorKind.NotEqual;
                            break;
                        case ExpressionType.LessThan:
                            operatorKind = BinaryOperatorKind.LessThan;
                            break;
                        case ExpressionType.LessThanOrEqual:
                            operatorKind = BinaryOperatorKind.LessThanOrEqual;
                            break;
                        case ExpressionType.GreaterThan:
                            operatorKind = BinaryOperatorKind.GreaterThan;
                            break;
                        case ExpressionType.GreaterThanOrEqual:
                            operatorKind = BinaryOperatorKind.GreaterThanOrEqual;
                            break;
                        case ExpressionType.Add:
                            operatorKind = BinaryOperatorKind.Add;
                            break;
                        case ExpressionType.Subtract:
                            operatorKind = BinaryOperatorKind.Subtract;
                            break;
                        case ExpressionType.Multiply:
                            operatorKind = BinaryOperatorKind.Multiply;
                            break;
                        case ExpressionType.Divide:
                            operatorKind = BinaryOperatorKind.Divide;
                            break;
                        case ExpressionType.Modulo:
                            operatorKind = BinaryOperatorKind.Modulo;
                            break;
                        default:
                            throw new NotSupportedException(
                                string.Format(
                                    CultureInfo.InvariantCulture,
                                    "The operator '{0}' is not supported in the 'Where' Mobile Services query expression '{1}'.",
                                    expression.NodeType,
                                    expression.ToString()));
                    }                    

                    var node = new BinaryOperatorNode(operatorKind, null, null);
                    this.filterExpression.Push(node);

                    this.Visit(expression.Left);
                    this.Visit(expression.Right);

                    this.SetChildren(node);
                }
            }

            return expression;
        }
        private QueryNode ParseComparison()
        {
            QueryNode left = this.ParseAdditive();

            while (this.lexer.Token.Kind == QueryTokenKind.Equal ||
                   this.lexer.Token.Kind == QueryTokenKind.NotEqual ||
                   this.lexer.Token.Kind == QueryTokenKind.GreaterThan ||
                   this.lexer.Token.Kind == QueryTokenKind.GreaterThanEqual ||
                   this.lexer.Token.Kind == QueryTokenKind.LessThan ||
                   this.lexer.Token.Kind == QueryTokenKind.LessThanEqual)
            {

                QueryTokenKind opKind = this.lexer.Token.Kind;
                this.lexer.NextToken();
                QueryNode right = this.ParseAdditive();

                switch (opKind)
                {
                    case QueryTokenKind.Equal:
                        left = new BinaryOperatorNode(BinaryOperatorKind.Equal, left, right);
                        break;
                    case QueryTokenKind.NotEqual:
                        left = new BinaryOperatorNode(BinaryOperatorKind.NotEqual, left, right);
                        break;
                    case QueryTokenKind.GreaterThan:
                        left = new BinaryOperatorNode(BinaryOperatorKind.GreaterThan, left, right);
                        break;
                    case QueryTokenKind.GreaterThanEqual:
                        left = new BinaryOperatorNode(BinaryOperatorKind.GreaterThanOrEqual, left, right);
                        break;
                    case QueryTokenKind.LessThan:
                        left = new BinaryOperatorNode(BinaryOperatorKind.LessThan, left, right);
                        break;
                    case QueryTokenKind.LessThanEqual:
                        left = new BinaryOperatorNode(BinaryOperatorKind.LessThanOrEqual, left, right);
                        break;
                }
            }
            return left;
        }
Exemple #41
0
            private static Uri BuildNavigationNextPageLink(ODataResource entry, ExpandedNavigationSelectItem expandedNavigationSelectItem)
            {
                var segment = (NavigationPropertySegment)expandedNavigationSelectItem.PathToNavigationProperty.LastSegment;
                ResourceRangeVariableReferenceNode refNode            = OeGetParser.CreateRangeVariableReferenceNode((IEdmEntitySet)segment.NavigationSource);
                IEdmNavigationProperty             navigationProperty = segment.NavigationProperty;

                var keys = new List <KeyValuePair <IEdmStructuralProperty, Object> >();

                if (navigationProperty.IsPrincipal())
                {
                    IEnumerator <IEdmStructuralProperty> dependentProperties = navigationProperty.Partner.DependentProperties().GetEnumerator();
                    foreach (IEdmStructuralProperty key in navigationProperty.Partner.PrincipalProperties())
                    {
                        foreach (ODataProperty property in entry.Properties)
                        {
                            if (property.Name == key.Name)
                            {
                                dependentProperties.MoveNext();
                                keys.Add(new KeyValuePair <IEdmStructuralProperty, Object>(dependentProperties.Current, property.Value));
                                break;
                            }
                        }
                    }
                }
                else
                {
                    IEnumerator <IEdmStructuralProperty> principalProperties = navigationProperty.PrincipalProperties().GetEnumerator();
                    foreach (IEdmStructuralProperty key in navigationProperty.DependentProperties())
                    {
                        foreach (ODataProperty property in entry.Properties)
                        {
                            if (property.Name == key.Name)
                            {
                                principalProperties.MoveNext();
                                keys.Add(new KeyValuePair <IEdmStructuralProperty, Object>(principalProperties.Current, property.Value));
                                break;
                            }
                        }
                    }
                }

                BinaryOperatorNode filterExpression = OeGetParser.CreateFilterExpression(refNode, keys);

                if (expandedNavigationSelectItem.FilterOption != null)
                {
                    filterExpression = new BinaryOperatorNode(BinaryOperatorKind.And, filterExpression, expandedNavigationSelectItem.FilterOption.Expression);
                }

                var segments = new ODataPathSegment[] { new EntitySetSegment((IEdmEntitySet)refNode.NavigationSource) };

                var odataUri = new ODataUri()
                {
                    Path            = new ODataPath(segments),
                    Filter          = new FilterClause(filterExpression, refNode.RangeVariable),
                    OrderBy         = expandedNavigationSelectItem.OrderByOption,
                    SelectAndExpand = expandedNavigationSelectItem.SelectAndExpand,
                    Top             = expandedNavigationSelectItem.TopOption,
                    Skip            = expandedNavigationSelectItem.SkipOption,
                    QueryCount      = expandedNavigationSelectItem.CountOption
                };

                return(odataUri.BuildUri(ODataUrlKeyDelimiter.Parentheses));
            }