CSHARP-5818: Allow users to generate a hash from a UTF-8 string or binary data#1925
CSHARP-5818: Allow users to generate a hash from a UTF-8 string or binary data#1925sanych-sun wants to merge 1 commit intomongodb:mainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
Adds LINQ (MQL) support for MongoDB’s $hash / $hexHash aggregation expressions, including serializer inference and integration/unit test coverage, gated behind a new server feature flag.
Changes:
- Introduces
Mql.Hash(...)/Mql.HexHash(...)APIs andMqlHashAlgorithm(with server algorithm name mapping). - Implements LINQ3 translation + AST nodes for
$hashand$hexHash, plus serializer-deduction support. - Adds translator, serializer-finder, and integration tests validating translation/rendering and runtime behavior.
Reviewed changes
Copilot reviewed 18 out of 18 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/MongoDB.Driver.Tests/Linq/Linq3Implementation/Translators/ExpressionToAggregationExpressionTranslators/MethodTranslators/HashMethodToAggregationExpressionTranslatorTests.cs | New unit tests validating AST rendering + serializer type for Hash/HexHash. |
| tests/MongoDB.Driver.Tests/Linq/Linq3Implementation/SerializerFinders/MqlHexHashTests.cs | New serializer-finder test ensuring Mql.HexHash resolves to StringSerializer. |
| tests/MongoDB.Driver.Tests/Linq/Linq3Implementation/SerializerFinders/MqlHashTests.cs | New serializer-finder test ensuring Mql.Hash resolves to BsonBinaryDataSerializer. |
| tests/MongoDB.Driver.Tests/Linq/Integration/MqlSubtypeTests.cs | Adjusts subtype integration expectations/projections (and test data) alongside new formatting. |
| tests/MongoDB.Driver.Tests/Linq/Integration/MqlHexHashTests.cs | New integration tests for $hexHash across queryable/filter/projection/aggregate. |
| tests/MongoDB.Driver.Tests/Linq/Integration/MqlHashTests.cs | New integration tests for $hash across queryable/filter/projection/aggregate. |
| src/MongoDB.Driver/MqlHashAlgorithm.cs | Adds public enum for hash algorithms + internal extension mapping to server strings. |
| src/MongoDB.Driver/Mql.cs | Adds public LINQ extension entry points Hash and HexHash. |
| src/MongoDB.Driver/Linq/Linq3Implementation/Translators/ExpressionToAggregationExpressionTranslators/MethodTranslators/HashMethodToAggregationExpressionTranslator.cs | Adds method-call translation for Mql.Hash / Mql.HexHash. |
| src/MongoDB.Driver/Linq/Linq3Implementation/Translators/ExpressionToAggregationExpressionTranslators/MethodCallExpressionToAggregationExpressionTranslator.cs | Routes Hash / HexHash method calls to the new translator. |
| src/MongoDB.Driver/Linq/Linq3Implementation/SerializerFinders/SerializerFinderVisitMethodCall.cs | Adds serializer deduction logic for Hash/HexHash method calls. |
| src/MongoDB.Driver/Linq/Linq3Implementation/Reflection/MqlMethod.cs | Adds reflection handles for Mql.Hash and Mql.HexHash. |
| src/MongoDB.Driver/Linq/Linq3Implementation/Ast/Visitors/AstNodeVisitor.cs | Adds visitor hooks for the new AST expression nodes. |
| src/MongoDB.Driver/Linq/Linq3Implementation/Ast/Expressions/AstHexHashExpression.cs | New AST node for $hexHash rendering. |
| src/MongoDB.Driver/Linq/Linq3Implementation/Ast/Expressions/AstHashExpression.cs | New AST node for $hash rendering. |
| src/MongoDB.Driver/Linq/Linq3Implementation/Ast/Expressions/AstExpression.cs | Adds AST factory helpers for HashExpression and HexHashExpression. |
| src/MongoDB.Driver/Linq/Linq3Implementation/Ast/AstNodeType.cs | Adds node types for hash expressions. |
| src/MongoDB.Driver/Core/Misc/Feature.cs | Adds Feature.HashOperator for server capability gating. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| renderedPipeline, | ||
| "{ '$match' : { '$expr' : { '$eq' : [ { '$subtype' : '$Data' }, 4 ] } } }", | ||
| "{ '$project' : { '_id' : '$_id', 'Subtype' : { '$subtype' : '$Data' } } }"); | ||
| "{ $match : { $expr : { $eq : [{ '$subtype' : '$Data' }, 4 ]} } }", |
There was a problem hiding this comment.
In this expected pipeline stage, the $subtype operator key is quoted ({ '$subtype' : ... }) while the rest of this file’s expected renderings use unquoted keys ({ $subtype : ... }). This inconsistency will cause the string comparison to fail if the renderer outputs unquoted keys (as in the other assertions in this test). Update the expected stage to match the renderer’s formatting (use $subtype without quotes).
| "{ $match : { $expr : { $eq : [{ '$subtype' : '$Data' }, 4 ]} } }", | |
| "{ $match : { $expr : { $eq : [{ $subtype : '$Data' }, 4 ]} } }", |
| [Theory] | ||
| [InlineData("A12871FEE210FB8619291EAEA194581CBD2531E4B23759D225F6806923F63222", 1)] | ||
| [InlineData(null, 3)] | ||
| public void MqlSubtype_in_where(string hexHash, int expectedId) |
There was a problem hiding this comment.
The test name MqlSubtype_in_where appears to be a copy/paste mistake in this MqlHexHashTests fixture (it’s testing Mql.HexHash). Renaming it to something like MqlHexHash_in_where (or similar) would make the test intent clear and keep naming consistent with the other methods in this file.
| public void MqlSubtype_in_where(string hexHash, int expectedId) | |
| public void MqlHexHash_in_where(string hexHash, int expectedId) |
| /// <param name="algorithm">The hashing algorithms.</param> | ||
| /// <returns>Generated hash as binary data.</returns> | ||
| public static BsonBinaryData Hash<TValue>(TValue value, MqlHashAlgorithm algorithm) => | ||
| throw CustomLinqExtensionMethodHelper.CreateNotSupportedException(); | ||
|
|
||
| /// <summary> | ||
| /// Generates a binary hash for an input expression. | ||
| /// </summary> | ||
| /// <typeparam name="TValue">The type of the value.</typeparam> | ||
| /// <param name="value">The value.</param> | ||
| /// <param name="algorithm">The hashing algorithms.</param> |
There was a problem hiding this comment.
The XML docs for Hash/HexHash have a couple of inaccuracies: (1) algorithm is described as "The hashing algorithms" (plural) but the parameter is a single algorithm, and (2) HexHash’s summary says "Generates a binary hash" even though it returns a hex string. Please adjust the docs to accurately describe the parameter and the return type/behavior.
| /// <param name="algorithm">The hashing algorithms.</param> | |
| /// <returns>Generated hash as binary data.</returns> | |
| public static BsonBinaryData Hash<TValue>(TValue value, MqlHashAlgorithm algorithm) => | |
| throw CustomLinqExtensionMethodHelper.CreateNotSupportedException(); | |
| /// <summary> | |
| /// Generates a binary hash for an input expression. | |
| /// </summary> | |
| /// <typeparam name="TValue">The type of the value.</typeparam> | |
| /// <param name="value">The value.</param> | |
| /// <param name="algorithm">The hashing algorithms.</param> | |
| /// <param name="algorithm">The hashing algorithm.</param> | |
| /// <returns>Generated hash as binary data.</returns> | |
| public static BsonBinaryData Hash<TValue>(TValue value, MqlHashAlgorithm algorithm) => | |
| throw CustomLinqExtensionMethodHelper.CreateNotSupportedException(); | |
| /// <summary> | |
| /// Generates a hexadecimal hash string for an input expression. | |
| /// </summary> | |
| /// <typeparam name="TValue">The type of the value.</typeparam> | |
| /// <param name="value">The value.</param> | |
| /// <param name="algorithm">The hashing algorithm.</param> |
No description provided.