Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug affecting $apply/aggregate when using average aggregation method against floats and nullable floats #1809

Closed
gathogojr opened this issue Jun 16, 2020 · 0 comments · Fixed by #1811
Assignees
Labels
Milestone

Comments

@gathogojr
Copy link
Contributor

It appears there might an ODL bug affecting $apply/aggregate expression specifically when using average aggregation method against floats and nullable floats

Assemblies affected

  • Microsoft.OData.Core 7.6.4
  • Microsoft.AspNetCore.OData 7.4.1

Reproduce steps

  1. Create an OData Web API project
  2. Create a CLR type with float and nullable float properties
    public class Number
    {
        public int Id { get; set; }
        public float SingleProp { get; set; }
        public float? NullableSingleProp { get; set; }
    }
  3. Create a controller with a Get action
    public class NumbersController : ODataController
    {
        // ...
        [EnableQuery]
        public IQueryable<Number> Get()
        {
            return _db.Numbers;
        }
        // ...
    }
  4. Bootstrap the service
    // ...
    ODataModelBuilder modelBuilder = new ODataConventionModelBuilder();
    modelBuilder.EntitySet<Number>("Numbers");
    
    app.UseMvc(routeBuilder =>
    {
        routeBuilder.Select().Filter().Expand().Count().OrderBy().SkipToken().MaxTop(null);
        routeBuilder.MapODataServiceRoute("odata", "odata", modelBuilder.GetEdmModel());
    });
    // ...
  5. Try to query for averages for the float and nullable float properties using $apply/aggregate expression
    a. http://ServiceRoot/Numbers?$apply=aggregate(SingleProp with average as AverageSingleProp)
    b. http://ServiceRoot/Numbers?$apply=aggregate(NullableSingleProp with average as AverageNullableSingleProp)

Expected result

The averages values for both properties should be returned in the respective cases

Actual result

An exception it thrown

{
"error": {
"code": "",
"message": "The query specified in the URI is not valid. $apply/aggregate expression 'Microsoft.OData.UriParser.SingleValuePropertyAccessNode' operation does not support value type 'Single'.",
"details": [],
"innererror": {
"message": "$apply/aggregate expression 'Microsoft.OData.UriParser.SingleValuePropertyAccessNode' operation does not support value type 'Single'.",
"type": "Microsoft.OData.ODataException",
"stacktrace": " at Microsoft.OData.UriParser.Aggregation.ApplyBinder.CreateAggregateExpressionTypeReference(SingleValueNode expression, AggregationMethodDefinition method)\r\n at Microsoft.OData.UriParser.Aggregation.ApplyBinder.BindAggregateExpressionToken(AggregateTokenBase aggregateToken)\r\n at Microsoft.OData.UriParser.Aggregation.ApplyBinder.BindAggregateToken(AggregateToken token)\r\n at Microsoft.OData.UriParser.Aggregation.ApplyBinder.BindApply(IEnumerable1 tokens)\r\n at Microsoft.OData.UriParser.ODataQueryOptionParser.ParseApplyImplementation(String apply, ODataUriParserConfiguration configuration, ODataPathInfo odataPathInfo)\r\n at Microsoft.OData.UriParser.ODataQueryOptionParser.ParseApply()\r\n at Microsoft.AspNet.OData.Query.ApplyQueryOption.get_ApplyClause() in C:\\Users\\jogathog\\Projects\\WebApi\\src\\Microsoft.AspNet.OData.Shared\\Query\\ApplyQueryOption.cs:line 78\r\n at Microsoft.AspNet.OData.Query.Validators.ODataQueryValidator.Validate(ODataQueryOptions options, ODataValidationSettings validationSettings) in C:\\Users\\jogathog\\Projects\\WebApi\\src\\Microsoft.AspNet.OData.Shared\\Query\\Validators\\ODataQueryValidator.cs:line 35\r\n at Microsoft.AspNet.OData.Query.ODataQueryOptions.Validate(ODataValidationSettings validationSettings) in C:\\Users\\jogathog\\Projects\\WebApi\\src\\Microsoft.AspNet.OData.Shared\\Query\\ODataQueryOptions.cs:line 586\r\n at Microsoft.AspNet.OData.EnableQueryAttribute.ValidateQuery(HttpRequest request, ODataQueryOptions queryOptions) in C:\\Users\\jogathog\\Projects\\WebApi\\src\\Microsoft.AspNetCore.OData\\EnableQueryAttribute.cs:line 222\r\n at Microsoft.AspNet.OData.EnableQueryAttribute.CreateAndValidateQueryOptions(HttpRequest request, ODataQueryContext queryContext) in C:\\Users\\jogathog\\Projects\\WebApi\\src\\Microsoft.AspNetCore.OData\\EnableQueryAttribute.cs:line 129\r\n at Microsoft.AspNet.OData.EnableQueryAttribute.<>c__DisplayClass1_0.<OnActionExecuted>b__1(ODataQueryContext queryContext) in C:\\Users\\jogathog\\Projects\\WebApi\\src\\Microsoft.AspNetCore.OData\\EnableQueryAttribute.cs:line 107\r\n at Microsoft.AspNet.OData.EnableQueryAttribute.ExecuteQuery(Object responseValue, IQueryable singleResultCollection, IWebApiActionDescriptor actionDescriptor, Func2 modelFunction, IWebApiRequestMessage request, Func2 createQueryOptionFunction) in C:\\Users\\jogathog\\Projects\\WebApi\\src\\Microsoft.AspNet.OData.Shared\\EnableQueryAttribute.cs:line 596\r\n at Microsoft.AspNet.OData.EnableQueryAttribute.OnActionExecuted(Object responseValue, IQueryable singleResultCollection, IWebApiActionDescriptor actionDescriptor, IWebApiRequestMessage request, Func2 modelFunction, Func2 createQueryOptionFunction, Action1 createResponseAction, Action`3 createErrorAction) in C:\Users\jogathog\Projects\WebApi\src\Microsoft.AspNet.OData.Shared\EnableQueryAttribute.cs:line 415"
}
}
}

Additional detail

This is almost certainly a bug since $apply/aggregate works for sum, min and max aggregation method

  • http://ServiceRoot/Numbers?$apply=aggregate(SingleProp with sum as SumSingleProp)

  • http://ServiceRoot/Numbers?$apply=aggregate(NullableSingleProp with sum as SumNullableSingleProp)

  • http://ServiceRoot/Numbers?$apply=aggregate(SingleProp with min as MinSingleProp)

  • http://ServiceRoot/Numbers?$apply=aggregate(NullableSingleProp with min as MinNullableSingleProp)

  • http://ServiceRoot/Numbers?$apply=aggregate(SingleProp with max as MaxSingleProp)

  • http://ServiceRoot/Numbers?$apply=aggregate(NullableSingleProp with max as MaxNullableSingleProp)

@xuzhg xuzhg added the bug label Jun 16, 2020
@gathogojr gathogojr added this to To do in OData project via automation Jun 17, 2020
@gathogojr gathogojr added this to the 7.7.0 milestone Jun 17, 2020
@gathogojr gathogojr linked a pull request Jun 17, 2020 that will close this issue
2 tasks
OData project automation moved this from To do to Done Jun 19, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
OData project
  
Done
Development

Successfully merging a pull request may close this issue.

2 participants