[CSHARP-2899] And/or concatenation is not respected in Aggregate and Match Created: 15/Jan/20  Updated: 27/Oct/23  Resolved: 29/Jan/20

Status: Closed
Project: C# Driver
Component/s: Linq
Affects Version/s: 2.10.0
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: Klaus Prünster Assignee: Dmitry Lukyanov (Inactive)
Resolution: Works as Designed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Visual Studio 2019.4.2



 Description   

I use match to compare if any of the req are equal to one User.AdUserTypeId

var req = new[] { 1 };
 
var x = _context.Users.Aggregate()
				.Match(c => (req.Length > 0 && req[0] == c.AdUserTypeId) ||
							(req.Length > 1 && req[1] == c.AdUserTypeId));
 
var users = x.ToList();

If the req length is > 1 everything works as expected.
If the req length is <= 1 (as shown in the example) the following exception is thrown:

Exception

System.IndexOutOfRangeException
HResult=0x80131508
Message=Index was outside the bounds of the array.
Source=System.Private.CoreLib
StackTrace:
at System.Array.InternalGetReference(Void* elemRef, Int32 rank, Int32* pIndices)
at System.Array.GetValue(Int32 index)
at MongoDB.Driver.Linq.Processors.PartialEvaluator.ReflectionEvaluator.VisitBinary(BinaryExpression node)
at System.Linq.Expressions.BinaryExpression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at System.Linq.Expressions.ExpressionVisitor.VisitUnary(UnaryExpression node)
at System.Linq.Expressions.UnaryExpression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at MongoDB.Driver.Linq.Processors.PartialEvaluator.ReflectionEvaluator.Evaluate(Expression node)
at MongoDB.Driver.Linq.Processors.PartialEvaluator.EvaluateSubtree(Expression subtree)
at MongoDB.Driver.Linq.Processors.PartialEvaluator.Visit(Expression node)
at System.Linq.Expressions.ExpressionVisitor.VisitBinary(BinaryExpression node)
at System.Linq.Expressions.BinaryExpression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at MongoDB.Driver.Linq.Processors.PartialEvaluator.Visit(Expression node)
at System.Linq.Expressions.ExpressionVisitor.VisitBinary(BinaryExpression node)
at System.Linq.Expressions.BinaryExpression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at MongoDB.Driver.Linq.Processors.PartialEvaluator.Visit(Expression node)
at System.Linq.Expressions.ExpressionVisitor.VisitBinary(BinaryExpression node)
at System.Linq.Expressions.BinaryExpression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at MongoDB.Driver.Linq.Processors.PartialEvaluator.Visit(Expression node)
at MongoDB.Driver.Linq.Processors.PartialEvaluator.Evaluate(Expression node)
at MongoDB.Driver.Linq.Translators.PredicateTranslator.Translate[TDocument](Expression`1 predicate, IBsonSerializer`1 parameterSerializer, IBsonSerializerRegistry serializerRegistry)
at MongoDB.Driver.ExpressionFilterDefinition`1.Render(IBsonSerializer`1 documentSerializer, IBsonSerializerRegistry serializerRegistry)
at MongoDB.Driver.PipelineStageDefinitionBuilder.<>c_DisplayClass27_0`1.<Match>b_0(IBsonSerializer`1 s, IBsonSerializerRegistry sr)
at MongoDB.Driver.DelegatedPipelineStageDefinition`2.Render(IBsonSerializer`1 inputSerializer, IBsonSerializerRegistry serializerRegistry)
at MongoDB.Driver.AppendedStagePipelineDefinition`3.Render(IBsonSerializer`1 inputSerializer, IBsonSerializerRegistry serializerRegistry)
at MongoDB.Driver.MongoCollectionImpl`1.Aggregate[TResult](IClientSessionHandle session, PipelineDefinition`2 pipeline, AggregateOptions options, CancellationToken cancellationToken)
at MongoDB.Driver.MongoCollectionImpl`1.<>c_DisplayClass19_0`1.<Aggregate>b_0(IClientSessionHandle session)
at MongoDB.Driver.MongoCollectionImpl`1.UsingImplicitSession[TResult](Func`2 func, CancellationToken cancellationToken)
at MongoDB.Driver.MongoCollectionImpl`1.Aggregate[TResult](PipelineDefinition`2 pipeline, AggregateOptions options, CancellationToken cancellationToken)
at MongoDB.Driver.CollectionAggregateFluent`2.ToCursor(CancellationToken cancellationToken)
at MongoDB.Driver.IAsyncCursorSourceExtensions.ToList[TDocument](IAsyncCursorSource`1 source, CancellationToken cancellationToken)
at QueryTester.QueryTest.QueryTest1() in C:\xxxxx\QueryTester\QueryTest.cs:line 53

In my opinion this should not happen because the first

req.Length > 0

prevents the second from being executed.



 Comments   
Comment by Klaus Prünster [ 30/Jan/20 ]

Ok, that's a pity. I found a work around:

var x = _context.Users.Aggregate().Match(Builders<User>.Filter.In(d => d.AdUserTypeId, filter.Select(c => (int?)c)))

Comment by Dmitry Lukyanov (Inactive) [ 29/Jan/20 ]

Hello Klaus Prünster,

our LINQ implementation doesn't support this type of query analysis. That's why the right branch of binary expression(req[1] == c.AdUserTypeId) doesn't know anything about the left branch(req.Length > 1) and then will be used in generating a mongo query that will fail because your local array doesn't have the second item.

Generated at Wed Feb 07 21:43:49 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.