Mixed whole-entity + computed-arithmetic projection returns silently wrong values

XMLWordPrintableJSON

    • Type: Bug
    • Resolution: Fixed
    • Priority: Minor - P4
    • 10.0.3, 9.1.3, 8.4.3
    • Affects Version/s: None
    • Component/s: None
    • None
    • Dotnet Drivers
    • Not Needed
    • None
    • None
    • None
    • None
    • None
    • None

      Summary

      A projection that mixes a whole entity reference with a computed-arithmetic leaf, e.g.:

      Unable to find source-code formatter for language: csharp. Available languages are: actionscript, ada, applescript, bash, c, c#, c++, cpp, css, erlang, go, groovy, haskell, html, java, javascript, js, json, lua, none, nyan, objc, perl, php, python, r, rainbow, ruby, scala, sh, sql, swift, visualbasic, xml, yaml
      db.Customers.Select(c => new { c, Total = c.Age * c.Score })
      

      returns silently wrong values under the default Native query mode: the whole-entity fields materialize correctly, but the computed Total comes out as Score * Score (the second operand squared) instead of Age * Score. No exception is thrown.

      Root cause

      This shape falls back to the mixed projection shaper (MongoMixedProjectionBindingRemovingExpressionVisitor, engaged because the projection contains an entity reference). That visitor's TryResolveFieldAccess only understands MemberExpression / MethodCallExpression leaves; it has no handling for a BinaryExpression-mapped (arithmetic) leaf. The projection-binding visitor's default walk decomposes c.Age * c.Score into two separate MemberExpression visits that write the same ProjectionMember dictionary slot, so the second operand overwrites the first, yielding Score * Score.

      Pre-existing — NOT introduced by the native-arithmetic-computed-projection slice

      This bug pre-dates the "native arithmetic computed projections" work (commit ad72ae2 on the NativeQueryOngoing line). That slice made pure-scalar arithmetic projections native, and its MongoProjectionBindingExpressionVisitor arithmetic case is deliberately gated on Route == NativeRoute.Projection, so a mixed projection (which is Route == Fallback) never reaches it — the slice neither fixes nor worsens this shape.

      Repro / documenting test

      NativeComputedProjectionTests.Mixed_whole_entity_and_computed_leaf_is_a_known_preexisting_limitation pins the current wrong behavior (asserts Total == Score*Score, with an XML-doc comment marking it a known pre-existing limitation).

      Suggested fix

      Teach the mixed projection shaper (MongoMixedProjectionBindingRemovingExpressionVisitor / the shared TryResolveFieldAccess path) to handle a computed BinaryExpression-mapped projection leaf — i.e. evaluate the arithmetic client-side over the materialized document rather than reading a non-existent field / clobbering a single slot. Update the documenting test to assert the correct value once fixed.

            Assignee:
            Arthur Vickers
            Reporter:
            Arthur Vickers
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: