[CSHARP-4681] InvalidCastException when rendering projections Created: 20/Jun/23  Updated: 29/Nov/23  Resolved: 03/Aug/23

Status: Closed
Project: C# Driver
Component/s: None
Affects Version/s: 2.19.2
Fix Version/s: 2.21.0

Type: Improvement Priority: Unknown
Reporter: Aristarkh Zagorodnikov Assignee: Oleksandr Poliakov
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Related
related to CSHARP-4860 2.19.1 -> 2.19.2 FindExpressionProjec... Closed
Backwards Compatibility: Fully Compatible
Documentation Changes: Not Needed
Documentation Changes Summary:

1. What would you like to communicate to the user about this feature?
2. Would you like the user to see examples of the syntax and/or executable code and its output?
3. Which versions of the driver/connector does this apply to?


 Description   

Hi!

After upgrading from 2.19.1 to 2.19.2, when rendering projection definitions (for debug logging) we sometimes encounter the following exception:

System.InvalidCastException: Unable to cast object of type 'MongoDB.Bson.BsonString' to type 'MongoDB.Bson.BsonDocument'.
BsonDocument MongoDB.Driver.Linq.Linq2Implementation.Translators.AggregateProjectTranslator.TranslateProject(Expression expression, ExpressionTranslationOptions translationOptions)
RenderedProjectionDefinition<TResult> MongoDB.Driver.Linq.Linq2Implementation.Translators.AggregateProjectTranslator.Translate<TDocument, TResult>(Expression<Func<TDocument, TResult>> projector, IBsonSerializer<TDocument> parameterSerializer, IBsonSerializerRegistry serializerRegistry, ExpressionTranslationOptions translationOptions)
RenderedProjectionDefinition<TOutput> MongoDB.Driver.ExpressionProjectionDefinition<TInput, TOutput>.Render(IBsonSerializer<TInput> inputSerializer, IBsonSerializerRegistry serializerRegistry, LinqProvider linqProvider)

The projection itself is a single field selector: Project(d => d.Id).



 Comments   
Comment by Aristarkh Zagorodnikov [ 09/Aug/23 ]

I described the V3 issue I mentioned above in CSHARP-4749.

Comment by Aristarkh Zagorodnikov [ 03/Aug/23 ]

Oleksandr, thank you very much for taking a look at the issue and fixing it. We were using FluentFind API:

            return _collection.Find(Builders.Filter.In(p => p.Group, groups)
                & Builders.Filter.AnyNe(p => p.ViewedBy, profileId)
                & offset.And(v => Builders.Filter.Gt(p => p.OrderId, v))
                    .Unwrap(Builders.Filter.Empty))
                .Sort(Builders.Sort.Ascending(p => p.OrderId))
                .Limit(limit)
                .Project(p => p.OrderId)
                .ToList();

I'll create ticket for V3 issues next week.

Comment by Oleksandr Poliakov [ 03/Aug/23 ]

Hello onyxmaster ,

Sorry for the delay in ticket updates. We have investigated the issue and found a way to reproduce the problem, by using FluentFind API. We use the following code snippet to reproduce the issue:

var fluentFind = collection.Find(...).Project(a => a.Id);
fluentFind.Options.Projection.Render(...) // exception were here

The fix to address the problem was already merged into the master branch and will be included in the next release.
Could you please confirm if you encountered the problem while using FluentFind API too? Or please provide more detailed steps to reproduce.

Also we would much appreciate if you create a separate tickets for V3 related issues mentioned, so we can investigate them and provide fixes for you.

Thanks

Comment by Githook User [ 02/Aug/23 ]

Author:

{'name': 'Oleksandr Poliakov', 'email': '31327136+sanych-sun@users.noreply.github.com', 'username': 'sanych-sun'}

Message: CSHARP-4681: InvalidCastException when rendering projections (#1146)
Branch: master
https://github.com/mongodb/mongo-csharp-driver/commit/ff22548b7d3c4902f13124e55b3944f66fd3d46b

Comment by Aristarkh Zagorodnikov [ 04/Jul/23 ]

Also, please advise if I need to create another issue on V3 conversion "peculiarities".

Comment by Aristarkh Zagorodnikov [ 04/Jul/23 ]

It looks like it was updated by the https://github.com/mongodb/mongo-csharp-driver/commit/2cf3d6ca7838cf8fe6b5a5afc88604ac955b6e5e#diff-b35e54f5b66fd9653586a526e2e422e495c7b6e0e6a42620ff75648bc09c2923L62 which happened right before 2.20.0, resolving https://jira.mongodb.org/browse/CSHARP-4656

 

Comment by Aristarkh Zagorodnikov [ 04/Jul/23 ]

The difference betweeb 2.19.1 and 2.20.0 is that older driver creates FindExpressionProjectionDefinition, and newer one creates ExpressionProjectionDefinition, which have different translation rules.

Comment by Aristarkh Zagorodnikov [ 04/Jul/23 ]

To add to the context of the original issue, we do not encounter the issue with InvalidCastException in 2.19.1, but encounter it with 2.20.0, so I'm not sure if the analysis about reproducability in 2.19.x is correct. The code that breaks is called several tens of thousands time per day so the regression manifests itself in 2.20.0, 2.19.1 is fine wrt that code.

Comment by Aristarkh Zagorodnikov [ 04/Jul/23 ]

To be more specific it fails to work for Nullable<T>: Builders<SomeRecord>.Filter.Gt(record => record.Id, id), where record.Id is a user-defined type T and id is a Nullable<T>.

Also it doesn't work when the expression is a user-defined type T that has conversion to a primitive type, for example int, and the value is that primitive type.

So, well, V3 provider breaks a lot of our code right now (several hundreds of locations) and using it is impossible for us.

Comment by Aristarkh Zagorodnikov [ 04/Jul/23 ]

Unfortunately the V3 provider still doesn't work for cases where V2 worked OK:
MongoDB.Driver.Linq.ExpressionNotSupportedException: Expression not supported: Convert(...)

Comment by Aristarkh Zagorodnikov [ 22/Jun/23 ]

Thanks for the suggestion, but we encountered problems when moving to v3 provider with type casting support, which made us revert to v2. I'll check out if they are resolved in the newest driver.

Comment by Boris Dogadov [ 21/Jun/23 ]

Hi onyxmaster 

I have reproduced this issue in all 2.19 versions, but only in LINQ2.
This expression works in the new LINQ3 provider, which is the default LINQ provider since 2.19.
Our recommendation is to upgrade to LINQ3 as it contains many fixes and new features, while LINQ2 gets only critical security updates.

Comment by PM Bot [ 20/Jun/23 ]

Hi onyxmaster, thank you for reporting this issue! The team will look into it and get back to you soon.

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