Example #1
0
        public void NestedGroupbyTransformationsInExpandIsAllowed()
        {
            // Arrange & Act
            ExpandTermToken expandTerm = this.ParseExpandOptions("($apply=groupby((Customer/CountryRegion,Product/Name),aggregate(Amount with sum as Total)))");

            // Assert
            Assert.NotNull(expandTerm);
            Assert.NotNull(expandTerm.ApplyOptions);
            QueryToken token = Assert.Single(expandTerm.ApplyOptions);

            GroupByToken groupBy = Assert.IsType <GroupByToken>(token);

            Assert.Equal(2, groupBy.Properties.Count());

            QueryToken   queryToken = groupBy.Properties.ElementAt(0);
            EndPathToken pathToken  = queryToken.ShouldBeEndPathToken("CountryRegion");

            pathToken.NextToken.ShouldBeInnerPathToken("Customer");

            queryToken = groupBy.Properties.ElementAt(1);
            pathToken  = queryToken.ShouldBeEndPathToken("Name");
            pathToken.NextToken.ShouldBeInnerPathToken("Product");

            Assert.NotNull(groupBy.Child);
            AggregateToken           aggregate = Assert.IsType <AggregateToken>(groupBy.Child);
            AggregateExpressionToken aggregateExpressionToken = Assert.Single(aggregate.Expressions);

            Assert.Equal("Total", aggregateExpressionToken.Alias);
            Assert.Equal(AggregationMethod.Sum, aggregateExpressionToken.Method);
            aggregateExpressionToken.Expression.ShouldBeEndPathToken("Amount");
        }
        public void NestedGroupbyTransformationsIsAllowed()
        {
            var result = this.ParseExpandOptions("($apply=groupby((Customer/CountryRegion,Product/Name),aggregate(Amount with sum as Total)))");

            result.Should().NotBeNull();

            QueryToken token = result.ApplyOptions.Single();

            token.Should().BeOfType <GroupByToken>();
            GroupByToken groupBy = token as GroupByToken;

            groupBy.Properties.Should().HaveCount(2);
            QueryToken   queryToken = groupBy.Properties.ElementAt(0);
            EndPathToken pathToken  = queryToken.ShouldBeEndPathToken("CountryRegion");

            pathToken.NextToken.ShouldBeInnerPathToken("Customer");

            queryToken = groupBy.Properties.ElementAt(1);
            pathToken  = queryToken.ShouldBeEndPathToken("Name");
            pathToken.NextToken.ShouldBeInnerPathToken("Product");

            groupBy.Child.Should().NotBeNull();
            groupBy.Child.Should().BeOfType <AggregateToken>();
            AggregateToken           aggregate = groupBy.Child as AggregateToken;
            AggregateExpressionToken aggregateExpressionToken = aggregate.Expressions.Single();

            aggregateExpressionToken.Alias.Should().Equals("Total");
            aggregateExpressionToken.Method.Should().Equals(AggregationMethod.Sum);
            aggregateExpressionToken.Expression.ShouldBeEndPathToken("Amount");
        }
        public void ParseApplyWithNestedAggregation()
        {
            string apply = "groupby((UnitPrice), aggregate(Sales($count as Count)))";

            IEnumerable <QueryToken> actual = this.testSubject.ParseApply(apply);

            actual.Should().NotBeNull();
            actual.Should().HaveCount(1);

            List <QueryToken> transformations = actual.ToList();

            // verify groupby
            GroupByToken groupBy = transformations[0] as GroupByToken;

            groupBy.Should().NotBeNull();

            VerifyGroupByTokenProperties(new string[] { "UnitPrice" }, groupBy);

            groupBy.Properties.Should().HaveCount(1);
            groupBy.Child.Should().NotBeNull();

            AggregateToken groupByAggregate = groupBy.Child as AggregateToken;

            groupByAggregate.AggregateExpressions.Should().HaveCount(1);

            EntitySetAggregateToken entitySetAggregate = groupByAggregate.AggregateExpressions.First() as EntitySetAggregateToken;

            entitySetAggregate.Should().NotBeNull();

            entitySetAggregate.EntitySet.ShouldBeEndPathToken("Sales");
            VerifyAggregateExpressionToken("$count", AggregationMethodDefinition.VirtualPropertyCount, "Count", entitySetAggregate.Expressions.First() as AggregateExpressionToken);
        }
        public void ParseApplyWithMultipleGroupByPropertiesShouldReturnGroupByToken()
        {
            string apply = "groupby((UnitPrice, SharePrice, ReservedPrice))";

            IEnumerable <QueryToken> actual = this.testSubject.ParseApply(apply);

            actual.Should().NotBeNull();
            actual.Should().HaveCount(1);

            GroupByToken groupBy = actual.First() as GroupByToken;

            VerifyGroupByTokenProperties(new string[] { "UnitPrice", "SharePrice", "ReservedPrice" }, groupBy);
        }
Example #5
0
        private GroupByTransformationNode BindGroupByToken(GroupByToken token)
        {
            var properties = new List <GroupByPropertyNode>();

            foreach (var propertyToken in token.Properties)
            {
                var bindResult = this.bindMethod(propertyToken);
                var property   = bindResult as SingleValuePropertyAccessNode;

                if (property != null)
                {
                    RegisterProperty(properties, ReversePropertyPath(property));
                }
                else
                {
                    var openProperty = bindResult as SingleValueOpenPropertyAccessNode;
                    if (openProperty != null)
                    {
                        var type = GetTypeReferenceByPropertyName(openProperty.Name);
                        properties.Add(new GroupByPropertyNode(openProperty.Name, openProperty, type));
                    }
                    else
                    {
                        throw new ODataException(
                                  ODataErrorStrings.ApplyBinder_GroupByPropertyNotPropertyAccessValue(propertyToken.Identifier));
                    }
                }
            }

            TransformationNode aggregate = null;

            if (token.Child != null)
            {
                if (token.Child.Kind == QueryTokenKind.Aggregate)
                {
                    aggregate = BindAggregateToken((AggregateToken)token.Child);
                    aggregateStatementsCache   = ((AggregateTransformationNode)aggregate).Statements;
                    state.AggregatedProperties =
                        aggregateStatementsCache.Select(statement => statement.AsAlias).ToList();
                }
                else
                {
                    throw new ODataException(ODataErrorStrings.ApplyBinder_UnsupportedGroupByChild(token.Child.Kind));
                }
            }

            // TODO: Determine source
            return(new GroupByTransformationNode(properties, aggregate, null));
        }
Example #6
0
        public void ParseApplyWithSingleGroupByPropertyShouldReturnGroupByToken()
        {
            string apply = "groupby((UnitPrice))";

            IEnumerable <QueryToken> actual = this.testSubject.ParseApply(apply);

            Assert.NotNull(actual);
            Assert.Single(actual);

            GroupByToken groupBy = actual.First() as GroupByToken;

            Assert.NotNull(groupBy);

            VerifyGroupByTokenProperties(new string[] { "UnitPrice" }, groupBy);
        }
        public void ParseApplyWithNestedFunctionAggregation()
        {
            string apply = "groupby((UnitPrice), aggregate(Sales($count as Count,  cast(SalesPrice, Edm.Decimal)  with average as RetailPrice)))";

            IEnumerable <QueryToken> actual = this.testSubject.ParseApply(apply);

            actual.Should().NotBeNull();
            actual.Should().HaveCount(1);

            List <QueryToken> transformations = actual.ToList();

            // verify groupby
            GroupByToken groupBy = transformations[0] as GroupByToken;

            groupBy.Should().NotBeNull();

            VerifyGroupByTokenProperties(new string[] { "UnitPrice" }, groupBy);

            groupBy.Properties.Should().HaveCount(1);
            groupBy.Child.Should().NotBeNull();

            AggregateToken groupByAggregate = groupBy.Child as AggregateToken;

            groupByAggregate.AggregateExpressions.Should().HaveCount(1);

            EntitySetAggregateToken entitySetAggregate = groupByAggregate.AggregateExpressions.First() as EntitySetAggregateToken;

            entitySetAggregate.Should().NotBeNull();

            entitySetAggregate.EntitySet.ShouldBeEndPathToken("Sales");
            entitySetAggregate.Expressions.Should().HaveCount(2);
            VerifyAggregateExpressionToken("$count", AggregationMethodDefinition.VirtualPropertyCount, "Count", entitySetAggregate.Expressions.First() as AggregateExpressionToken);

            AggregateExpressionToken funcAggregate = entitySetAggregate.Expressions.Last() as AggregateExpressionToken;

            funcAggregate.Should().NotBeNull();
            funcAggregate.Alias.ShouldBeEquivalentTo("RetailPrice");
            funcAggregate.Method.Should().Equals(AggregationMethodDefinition.Average);

            FunctionCallToken funcToken = funcAggregate.Expression as FunctionCallToken;

            funcToken.Should().NotBeNull();
            funcToken.Name.ShouldBeEquivalentTo("cast");
        }
Example #8
0
        public void ParseApplyWithNestedAggregationAndFunction()
        {
            string apply = "groupby((UnitPrice), aggregate(Sales($count as Count),  cast(SalesPrice, Edm.Decimal)  with average as RetailPrice))";

            IEnumerable <QueryToken> actual = this.testSubject.ParseApply(apply);

            Assert.NotNull(actual);
            Assert.Single(actual);

            List <QueryToken> transformations = actual.ToList();

            // verify groupby
            GroupByToken groupBy = transformations[0] as GroupByToken;

            Assert.NotNull(groupBy);

            VerifyGroupByTokenProperties(new string[] { "UnitPrice" }, groupBy);

            Assert.Single(groupBy.Properties);
            Assert.NotNull(groupBy.Child);

            AggregateToken groupByAggregate = groupBy.Child as AggregateToken;

            Assert.Equal(2, groupByAggregate.AggregateExpressions.Count());

            EntitySetAggregateToken entitySetAggregate = groupByAggregate.AggregateExpressions.First() as EntitySetAggregateToken;

            Assert.NotNull(entitySetAggregate);

            entitySetAggregate.EntitySet.ShouldBeEndPathToken("Sales");
            VerifyAggregateExpressionToken("$count", AggregationMethodDefinition.VirtualPropertyCount, "Count", entitySetAggregate.Expressions.First() as AggregateExpressionToken);

            AggregateExpressionToken funcAggregate = groupByAggregate.AggregateExpressions.Last() as AggregateExpressionToken;

            Assert.NotNull(funcAggregate);
            Assert.Equal("RetailPrice", funcAggregate.Alias);
            Assert.Equal(AggregationMethod.Average, funcAggregate.Method);

            FunctionCallToken funcToken = funcAggregate.Expression as FunctionCallToken;

            Assert.NotNull(funcToken);
            Assert.Equal("cast", funcToken.Name);
        }
        public void ParseApplyWithMultipleTransformationShouldReturnTransformations()
        {
            string apply = "groupby((UnitPrice), aggregate(SalesPrice with average as RetailPrice))/filter(UnitPrice eq 5)/aggregate(CustomerId with sum as Total, SharePrice with countdistinct as SharePriceDistinctCount)";

            IEnumerable <QueryToken> actual = this.testSubject.ParseApply(apply);

            actual.Should().NotBeNull();
            actual.Should().HaveCount(3);

            List <QueryToken> transformations = actual.ToList();

            // verify groupby
            GroupByToken groupBy = transformations[0] as GroupByToken;

            groupBy.Should().NotBeNull();

            VerifyGroupByTokenProperties(new string[] { "UnitPrice" }, groupBy);


            groupBy.Properties.Should().HaveCount(1);
            groupBy.Child.Should().NotBeNull();

            AggregateToken groupByAggregate = groupBy.Child as AggregateToken;

            groupByAggregate.AggregateExpressions.Should().HaveCount(1);
            VerifyAggregateExpressionToken("SalesPrice", AggregationMethodDefinition.Average, "RetailPrice", groupByAggregate.AggregateExpressions.First() as AggregateExpressionToken);

            // verify filter
            BinaryOperatorToken filter = transformations[1] as BinaryOperatorToken;

            VerifyBinaryOperatorToken <int>("UnitPrice", BinaryOperatorKind.Equal, 5, filter);

            // verify aggregate
            AggregateToken aggregate = transformations[2] as AggregateToken;

            aggregate.Should().NotBeNull();
            aggregate.AggregateExpressions.Should().HaveCount(2);

            List <AggregateTokenBase> aggregateExpressions = aggregate.AggregateExpressions.ToList();

            VerifyAggregateExpressionToken("CustomerId", AggregationMethodDefinition.Sum, "Total", aggregateExpressions[0] as AggregateExpressionToken);
            VerifyAggregateExpressionToken("SharePrice", AggregationMethodDefinition.CountDistinct, "SharePriceDistinctCount", aggregateExpressions[1] as AggregateExpressionToken);
        }
        public void ParseApplyWithGroupByAndAggregateShouldReturnGroupByToken()
        {
            string apply = "groupby((UnitPrice), aggregate(SalesPrice with average as RetailPrice))";

            IEnumerable <QueryToken> actual = this.testSubject.ParseApply(apply);

            actual.Should().NotBeNull();
            actual.Should().HaveCount(1);

            GroupByToken groupBy = actual.First() as GroupByToken;

            VerifyGroupByTokenProperties(new string[] { "UnitPrice" }, groupBy);

            groupBy.Child.Should().NotBeNull();

            AggregateToken aggregate = groupBy.Child as AggregateToken;

            aggregate.AggregateExpressions.Should().HaveCount(1);

            VerifyAggregateExpressionToken("SalesPrice", AggregationMethodDefinition.Average, "RetailPrice", aggregate.AggregateExpressions.First() as AggregateExpressionToken);
        }
Example #11
0
        private GroupByTransformationNode BindGroupByToken(GroupByToken token)
        {
            var properties = new List<GroupByPropertyNode>();

            foreach (var propertyToken in token.Properties)
            {
                var bindResult = this.bindMethod(propertyToken);
                var property = bindResult as SingleValuePropertyAccessNode;

                if (property != null)
                {
                    RegisterProperty(properties, ReversePropertyPath(property));
                }
                else
                {
                    var openProperty = bindResult as SingleValueOpenPropertyAccessNode;
                    if (openProperty != null)
                    {
                        var type = GetTypeReferenceByPropertyName(openProperty.Name);
                        properties.Add(new GroupByPropertyNode(openProperty.Name, openProperty, type));
                    }
                    else
                    {
                        throw new ODataException(
                            ODataErrorStrings.ApplyBinder_GroupByPropertyNotPropertyAccessValue(propertyToken.Identifier));
                    }
                }
            }

            TransformationNode aggregate = null;
            if (token.Child != null)
            {
                if (token.Child.Kind == QueryTokenKind.Aggregate)
                {
                    aggregate = BindAggregateToken((AggregateToken)token.Child);
                    aggregateStatementsCache = ((AggregateTransformationNode)aggregate).Statements;
                    state.AggregatedProperties =
                        aggregateStatementsCache.Select(statement => statement.AsAlias).ToList();
                }
                else
                {
                    throw new ODataException(ODataErrorStrings.ApplyBinder_UnsupportedGroupByChild(token.Child.Kind));
                }
            }

            // TODO: Determine source
            return new GroupByTransformationNode(properties, aggregate, null);
        }
 public Expression Visit(GroupByToken tokenIn)
 {
     throw new NotImplementedException();
 }
Example #13
0
 /// <summary>
 /// Visits a GroupByToken
 /// </summary>
 /// <param name="tokenIn">The GroupByToken to visit</param>
 /// <returns>A T bound to this GroupByToken</returns>
 public virtual T Visit(GroupByToken tokenIn)
 {
     throw new NotImplementedException();
 }
        private static void VerifyGroupByTokenProperties(IEnumerable <string> expectedEndPathIdentifiers, GroupByToken actual)
        {
            actual.Should().NotBeNull();

            if (expectedEndPathIdentifiers == null || !expectedEndPathIdentifiers.Any())
            {
                actual.Properties.Should().HaveCount(0);
            }
            else
            {
                actual.Properties.Should().HaveCount(expectedEndPathIdentifiers.Count());

                List <string> expectedIdentifierList = expectedEndPathIdentifiers.ToList();
                int           i = 0;
                foreach (EndPathToken actualProperty in actual.Properties)
                {
                    actualProperty.Should().NotBeNull();

                    EndPathToken endPathToken = actualProperty as EndPathToken;
                    endPathToken.Should().NotBeNull();
                    endPathToken.Identifier.Should().Be(expectedIdentifierList[i]);
                    i++;
                }
            }
        }
Example #15
0
        public void AggregateSetCorrectly()
        {
            var token = new GroupByToken(properties, aggregate);

            ((object)token.Child).Should().Be(aggregate);
        }
Example #16
0
        public void KindIsSetCorrectly()
        {
            var token = new GroupByToken(properties, null);

            token.Kind.Should().Be(QueryTokenKind.AggregateGroupBy);
        }
Example #17
0
        public void KindIsSetCorrectly()
        {
            var token = new GroupByToken(properties, null);

            Assert.Equal(QueryTokenKind.AggregateGroupBy, token.Kind);
        }
Example #18
0
        public void PropertiesSetCorrectly()
        {
            var token = new GroupByToken(properties, null);

            ((object)token.Properties).Should().Be(properties);
        }
Example #19
0
        public void AggregateSetCorrectly()
        {
            var token = new GroupByToken(properties, aggregate);

            Assert.Same(aggregate, ((object)token.Child));
        }
Example #20
0
        private static void VerifyGroupByTokenProperties(IEnumerable <string> expectedEndPathIdentifiers, GroupByToken actual)
        {
            Assert.NotNull(actual);

            if (expectedEndPathIdentifiers == null || !expectedEndPathIdentifiers.Any())
            {
                Assert.Empty(actual.Properties);
            }
            else
            {
                Assert.Equal(actual.Properties.Count(), expectedEndPathIdentifiers.Count());

                List <string> expectedIdentifierList = expectedEndPathIdentifiers.ToList();
                int           i = 0;
                foreach (EndPathToken actualProperty in actual.Properties)
                {
                    Assert.NotNull(actualProperty);

                    EndPathToken endPathToken = actualProperty as EndPathToken;
                    Assert.NotNull(endPathToken);
                    Assert.Equal(endPathToken.Identifier, expectedIdentifierList[i]);
                    i++;
                }
            }
        }
Example #21
0
 public void PropertiesSetCorrectly()
 {
     var token = new GroupByToken(properties, null);
     ((object)token.Properties).Should().Be(properties);
 }
Example #22
0
 public void AggregateSetCorrectly()
 {
     var token = new GroupByToken(properties, aggregate);
     ((object)token.Child).Should().Be(aggregate);
 }
Example #23
0
        public void KindIsSetCorrectly()
        {
            var token = new GroupByToken(properties, null);

            token.Kind.Should().Be(QueryTokenKind.AggregateGroupBy);
        }
Example #24
0
        public void PropertiesSetCorrectly()
        {
            var token = new GroupByToken(properties, null);

            Assert.Same(properties, ((object)token.Properties));
        }
 public bool Visit(GroupByToken tokenIn)
 {
     throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "QueryToken of type '{0}' is not supported.", tokenIn.Kind));
 }