From 4b97f18c43aafe681148019ce3a2c94cd4996ca3 Mon Sep 17 00:00:00 2001 From: Alex <57764940+axnetg@users.noreply.github.com> Date: Tue, 28 Nov 2023 23:01:04 +0100 Subject: [PATCH] fix: culture invariant decimals for aggregation queries --- .../AggregationPredicates/QueryPredicate.cs | 36 +++++++++---------- .../RediSearchTests/AggregationSetTests.cs | 30 ++++++++++++++++ 2 files changed, 48 insertions(+), 18 deletions(-) diff --git a/src/Redis.OM/Aggregation/AggregationPredicates/QueryPredicate.cs b/src/Redis.OM/Aggregation/AggregationPredicates/QueryPredicate.cs index 5a6a27ef..56861ad9 100644 --- a/src/Redis.OM/Aggregation/AggregationPredicates/QueryPredicate.cs +++ b/src/Redis.OM/Aggregation/AggregationPredicates/QueryPredicate.cs @@ -57,32 +57,32 @@ protected override void ValidateAndPushOperand(Expression expression, Stack(); @@ -190,13 +190,13 @@ private static string BuildEqualityPredicate(MemberInfo member, ConstantExpressi switch (searchFieldType) { case SearchFieldType.TAG: - sb.Append($"{{{ExpressionParserUtilities.EscapeTagField(expression.Value.ToString())}}}"); + sb.Append($"{{{ExpressionParserUtilities.EscapeTagField(queryValue)}}}"); break; case SearchFieldType.TEXT: - sb.Append(expression.Value); + sb.Append(queryValue); break; case SearchFieldType.NUMERIC: - sb.Append($"[{expression.Value} {expression.Value}]"); + sb.Append($"[{queryValue} {queryValue}]"); break; default: throw new InvalidOperationException("Could not translate query equality searches only supported for Tag, text, and numeric fields"); @@ -205,17 +205,17 @@ private static string BuildEqualityPredicate(MemberInfo member, ConstantExpressi return sb.ToString(); } - private string BuildQueryPredicate(ExpressionType expType, MemberExpression member, ConstantExpression constExpression) + private string BuildQueryPredicate(ExpressionType expType, MemberExpression member, string queryValue) { var memberStr = ExpressionParserUtilities.GetOperandString(member); var queryPredicate = expType switch { - ExpressionType.GreaterThan => $"{memberStr}:[({constExpression.Value} inf]", - ExpressionType.LessThan => $"{memberStr}:[-inf ({constExpression.Value}]", - ExpressionType.GreaterThanOrEqual => $"{memberStr}:[{constExpression.Value} inf]", - ExpressionType.LessThanOrEqual => $"{memberStr}:[-inf {constExpression.Value}]", - ExpressionType.Equal => BuildEqualityPredicate(member.Member, constExpression, memberStr), - ExpressionType.NotEqual => BuildEqualityPredicate(member.Member, constExpression, memberStr, true), + ExpressionType.GreaterThan => $"{memberStr}:[({queryValue} inf]", + ExpressionType.LessThan => $"{memberStr}:[-inf ({queryValue}]", + ExpressionType.GreaterThanOrEqual => $"{memberStr}:[{queryValue} inf]", + ExpressionType.LessThanOrEqual => $"{memberStr}:[-inf {queryValue}]", + ExpressionType.Equal => BuildEqualityPredicate(member.Member, queryValue, memberStr), + ExpressionType.NotEqual => BuildEqualityPredicate(member.Member, queryValue, memberStr, true), _ => string.Empty }; return queryPredicate; diff --git a/test/Redis.OM.Unit.Tests/RediSearchTests/AggregationSetTests.cs b/test/Redis.OM.Unit.Tests/RediSearchTests/AggregationSetTests.cs index 55e25b25..4ea88753 100644 --- a/test/Redis.OM.Unit.Tests/RediSearchTests/AggregationSetTests.cs +++ b/test/Redis.OM.Unit.Tests/RediSearchTests/AggregationSetTests.cs @@ -587,5 +587,35 @@ public void DateTimeQuery() _ = collection.Where(query).ToList(); _substitute.Received().Execute("FT.AGGREGATE", "objectwithdatetime-idx", $"@TimestampOffset:[({dtMs} inf]", "WITHCURSOR", "COUNT", "10000"); } + + [Fact] + public void TestDecimalQuery() + { + var collection = new RedisAggregationSet(_substitute, true, chunkSize: 10000); + _substitute.Execute("FT.AGGREGATE", Arg.Any()).Returns(MockedResult); + _substitute.Execute("FT.CURSOR", Arg.Any()).Returns(MockedResultCursorEnd); + + var y = 30.55M; + Expression, bool>> query = a => a.RecordShell!.Salary > y; + _ = collection.Where(query).ToList(); + _substitute.Received().Execute("FT.AGGREGATE", "person-idx", "@Salary:[(30.55 inf]", "WITHCURSOR", "COUNT", "10000"); + + query = a => a.RecordShell!.Salary > 85.99M; + _ = collection.Where(query).ToList(); + _substitute.Received().Execute("FT.AGGREGATE", "person-idx", "@Salary:[(85.99 inf]", "WITHCURSOR", "COUNT", "10000"); + + query = a => a.RecordShell!.Salary == 70.5M; + _ = collection.Where(query).ToList(); + _substitute.Received().Execute("FT.AGGREGATE", "person-idx", "@Salary:[70.5 70.5]", "WITHCURSOR", "COUNT", "10000"); + } + + [Theory] + [InlineData("en-DE")] + [InlineData("it-IT")] + [InlineData("es-ES")] + public void TestDecimalQueryTestingInvariantCultureCompliance(string lcid) + { + Helper.RunTestUnderDifferentCulture(lcid, _ => TestDecimalQuery()); + } } }