private static AstPipeline TranslateSelectManyWithCollectionSelectorAndNonIdentityResultSelector( TranslationContext context, AstPipeline pipeline, AggregationExpression collectionSelectorTranslation, LambdaExpression resultSelectorLambda) { var sourceSerializer = pipeline.OutputSerializer; var collectionItemSerializer = ArraySerializerHelper.GetItemSerializer(collectionSelectorTranslation.Serializer); var resultSelectorSourceParameterExpression = resultSelectorLambda.Parameters[0]; var resultSelectorSourceAst = AstExpression.Var("ROOT", isCurrent: true); var resultSelectorSourceParameterSymbol = context.CreateSymbol(resultSelectorSourceParameterExpression, resultSelectorSourceAst, sourceSerializer, isCurrent: true); var resultSelectorCollectionItemParameterExpression = resultSelectorLambda.Parameters[1]; var resultSelectorCollectionItemParameterSymbol = context.CreateSymbol(resultSelectorCollectionItemParameterExpression, collectionItemSerializer); var resultSelectorContext = context.WithSymbols(resultSelectorSourceParameterSymbol, resultSelectorCollectionItemParameterSymbol); var resultSelectorTranslation = ExpressionToAggregationExpressionTranslator.Translate(resultSelectorContext, resultSelectorLambda.Body); var resultValueSerializer = resultSelectorTranslation.Serializer; var resultWrappedValueSerializer = WrappedValueSerializer.Create("_v", resultValueSerializer); var resultAst = AstExpression.Map( input: collectionSelectorTranslation.Ast, @as: resultSelectorCollectionItemParameterSymbol.Var, @in: resultSelectorTranslation.Ast); return(pipeline.AddStages( resultWrappedValueSerializer, AstStage.Project( AstProject.Set("_v", resultAst), AstProject.ExcludeId()), AstStage.Unwind("_v"))); }
public void DifferentAggregationModifier() { var dataInfo = new TestStreamedValueInfo(typeof(int)); var selectProjection = Expression.Constant(1); var selectProjectionWithCountAggregation = new AggregationExpression(typeof(int), selectProjection, AggregationModifier.Count); var sqlStatement1 = new SqlStatement( dataInfo, selectProjectionWithCountAggregation, new SqlTable[] { }, null, null, new Ordering[] { }, null, false, null, null); var sqlStatement2 = new SqlStatement( dataInfo, selectProjection, new SqlTable[] { }, null, null, new Ordering[] { }, null, false, null, null); Assert.That(sqlStatement1.Equals(sqlStatement2), Is.False); }
private BsonValue BuildAggregation(AggregationExpression node) { switch (node.AggregationType) { case AggregationType.AddToSet: return(new BsonDocument("$addToSet", BuildValue(node.Argument))); case AggregationType.Average: return(new BsonDocument("$avg", BuildValue(node.Argument))); case AggregationType.First: return(new BsonDocument("$first", BuildValue(node.Argument))); case AggregationType.Last: return(new BsonDocument("$last", BuildValue(node.Argument))); case AggregationType.Max: return(new BsonDocument("$max", BuildValue(node.Argument))); case AggregationType.Min: return(new BsonDocument("$min", BuildValue(node.Argument))); case AggregationType.Push: return(new BsonDocument("$push", BuildValue(node.Argument))); case AggregationType.Sum: return(new BsonDocument("$sum", BuildValue(node.Argument))); } // we should never ever get here. throw new MongoInternalException("Unrecognized aggregation type."); }
public void VisitAggregationExpression_Count() { var columnExpression = new SqlColumnDefinitionExpression(typeof(string), "c", "Name", false); var expression = new AggregationExpression(typeof(int), columnExpression, AggregationModifier.Count); SqlGeneratingExpressionVisitor.GenerateSql(expression, _commandBuilder, _stageMock); Assert.That(_commandBuilder.GetCommandText(), Is.EqualTo("COUNT(*)")); }
public void VisitAggregationExpression_Average() { var columnExpression = new NamedExpression(null, new SqlColumnDefinitionExpression(typeof(string), "c", "Name", false)); var expression = new AggregationExpression(typeof(double), columnExpression, AggregationModifier.Average); SqlGeneratingExpressionVisitor.GenerateSql(expression, _commandBuilder, _stageMock); Assert.That(_commandBuilder.GetCommandText(), Is.EqualTo("AVG([c].[Name])")); }
// public static methods public static (AstProjectStage, IBsonSerializer) CreateProjectStage(AggregationExpression expression) { if (expression.Ast.NodeType == AstNodeType.ComputedDocumentExpression) { return(CreateComputedDocumentProjectStage(expression)); } else { return(CreateWrappedValueProjectStage(expression)); } }
private bool TryBindAggregationExpression(MethodCallExpression node, out Expression aggregationNode) { AggregationType aggregationType; if (TryGetAggregationType(node.Method.Name, out aggregationType)) { var argument = GetAggregationArgument(node); aggregationNode = new AggregationExpression(node.Type, aggregationType, argument); return(true); } aggregationNode = null; return(false); }
public void CreateExpression_HasAggregationModifier() { var sqlStatementBuilder = new SqlStatementBuilder(SqlStatementModelObjectMother.CreateSqlStatement()); sqlStatementBuilder.SqlTables.Clear(); var selectProjection = new AggregationExpression(typeof(double), sqlStatementBuilder.SelectProjection, AggregationModifier.Max); sqlStatementBuilder.SelectProjection = selectProjection; var sqlStatement = sqlStatementBuilder.GetSqlStatement(); var result = sqlStatement.CreateExpression(); Assert.That(result, Is.SameAs(selectProjection)); }
private static AstPipeline TranslateSelectManyWithCollectionSelectorAndIdentityResultSelector( AstPipeline pipeline, AggregationExpression collectionSelectorTranslation) { var collectionItemSerializer = ArraySerializerHelper.GetItemSerializer(collectionSelectorTranslation.Serializer); var resultValueSerializer = collectionItemSerializer; var resultWrappedValueSerializer = WrappedValueSerializer.Create("_v", resultValueSerializer); return(pipeline.AddStages( resultWrappedValueSerializer, AstStage.Project( AstProject.Set("_v", collectionSelectorTranslation.Ast), AstProject.ExcludeId()), AstStage.Unwind("_v"))); }
public void BuildSelectPart_WithAggregation() { var aggregationExpression = new AggregationExpression(typeof(int), _entityExpression, AggregationModifier.Count); var sqlStatement = new SqlStatementBuilder { SelectProjection = aggregationExpression, DataInfo = new TestStreamedValueInfo(typeof(object)) }.GetSqlStatement(); _stageMock.Expect( mock => mock.GenerateTextForSelectExpression(_commandBuilder, aggregationExpression)) .WhenCalled(mi => ((SqlCommandBuilder)mi.Arguments[0]).Append("COUNT(*)")); _generator.BuildSelectPart(sqlStatement, _commandBuilder, false); Assert.That(_commandBuilder.GetCommandText(), Is.EqualTo("SELECT COUNT(*)")); _stageMock.VerifyAllExpectations(); }
public void BuildSelectPart_WithAggregation() { var aggregationExpression = new AggregationExpression(typeof(int), ExpressionHelper.CreateExpression(), AggregationModifier.Count); var sqlStatement = SqlStatementModelObjectMother.CreateMinimalSqlStatement(new SqlStatementBuilder { SelectProjection = aggregationExpression }); _stageMock.Expect( mock => mock.GenerateTextForSelectExpression(_commandBuilder, aggregationExpression)) .WhenCalled(mi => ((SqlCommandBuilder)mi.Arguments[0]).Append("COUNT(*)")); _generator.BuildSelectPart(sqlStatement, _commandBuilder, false); Assert.That(_commandBuilder.GetCommandText(), Is.EqualTo("SELECT COUNT(*)")); _stageMock.VerifyAllExpectations(); }
public void GetSqlStatement_CheckProperties() { var dataInfo = new TestStreamedValueInfo(typeof(Cook)); var topExpression = ExpressionHelper.CreateExpression(); var isDistinctQuery = BooleanObjectMother.GetRandomBoolean(); var selectProjection = new AggregationExpression(typeof(int), Expression.Constant(1), AggregationModifier.Min); var whereCondition = Expression.Constant(true); var sqlTable = new SqlTable(new ResolvedSimpleTableInfo(typeof(Cook), "CookTable", "c"), JoinSemantics.Inner); var ordering = new Ordering(Expression.Constant("order"), OrderingDirection.Desc); var rowNumberSelector = Expression.Constant("selector"); var currentRowNumberOffset = Expression.Constant(1); var groupExpression = Expression.Constant("group"); var setOperationCombinedStatement = SqlStatementModelObjectMother.CreateSetOperationCombinedStatement(); var statementBuilder = new SqlStatementBuilder { DataInfo = dataInfo, TopExpression = topExpression, IsDistinctQuery = isDistinctQuery, SelectProjection = selectProjection, SqlTables = { sqlTable }, WhereCondition = whereCondition, RowNumberSelector = rowNumberSelector, CurrentRowNumberOffset = currentRowNumberOffset, GroupByExpression = groupExpression, Orderings = { ordering }, SetOperationCombinedStatements = { setOperationCombinedStatement } }; var sqlStatement = statementBuilder.GetSqlStatement(); Assert.That(sqlStatement.DataInfo, Is.SameAs(dataInfo)); Assert.That(sqlStatement.TopExpression, Is.SameAs(topExpression)); Assert.That(sqlStatement.IsDistinctQuery, Is.EqualTo(isDistinctQuery)); Assert.That(sqlStatement.SelectProjection, Is.SameAs(selectProjection)); Assert.That(sqlStatement.SqlTables, Is.EqualTo(new[] { sqlTable })); Assert.That(sqlStatement.Orderings, Is.EqualTo(new[] { ordering })); Assert.That(sqlStatement.WhereCondition, Is.SameAs(whereCondition)); Assert.That(sqlStatement.RowNumberSelector, Is.SameAs(rowNumberSelector)); Assert.That(sqlStatement.CurrentRowNumberOffset, Is.SameAs(currentRowNumberOffset)); Assert.That(sqlStatement.GroupByExpression, Is.SameAs(groupExpression)); Assert.That(sqlStatement.SetOperationCombinedStatements, Is.EqualTo(new[] { setOperationCombinedStatement })); }
private static ValueResult RunAggregationExpression(AggregationExpression expr, RunContext ctx) { var dice = ctx.Variables.GetVariableValue <RollResult>(expr.Variable); var options = MergeOptions(expr.Options); var filteredDices = FilterDices( dice.Dices, options.Filter ?? new FilterOption { Type = FilterType.None }, options.Ranking ?? new RankingOption { Type = RankingType.None }, ctx.Variables); var result = ComputeResult(filteredDices, options.Aggregation); return(new ValueResult { Result = result, Name = expr.Name }); }
public virtual Expression VisitAggregationExpression(AggregationExpression expression) { ArgumentUtility.CheckNotNull("expression", expression); if (expression.AggregationModifier == AggregationModifier.Count) { _commandBuilder.Append("COUNT(*)"); return(expression); } if (expression.AggregationModifier == AggregationModifier.Average) { _commandBuilder.Append("AVG"); } else if (expression.AggregationModifier == AggregationModifier.Max) { _commandBuilder.Append("MAX"); } else if (expression.AggregationModifier == AggregationModifier.Min) { _commandBuilder.Append("MIN"); } else if (expression.AggregationModifier == AggregationModifier.Sum) { _commandBuilder.Append("SUM"); } else { var message = string.Format( "Cannot generate SQL for aggregation '{0}'. Expression: '{1}'", expression.AggregationModifier, FormattingExpressionTreeVisitor.Format(expression)); throw new NotSupportedException(message); } _commandBuilder.Append("("); VisitExpression(expression.Expression); _commandBuilder.Append(")"); return(expression); }
public void SetUp() { _dataInfo = new StreamedScalarValueInfo(typeof(int)); _resolvedElementExpressionReference = new SqlColumnDefinitionExpression(typeof(string), "q0", "element", false); _resolvedSelectProjection = new NamedExpression( null, new AggregationExpression(typeof(int), _resolvedElementExpressionReference, AggregationModifier.Min)); _associatedGroupingSelectExpression = new SqlGroupingSelectExpression( new NamedExpression("key", Expression.Constant("k")), new NamedExpression("element", Expression.Constant("e"))); _resolvedJoinedGroupingSubStatement = SqlStatementModelObjectMother.CreateSqlStatement(_associatedGroupingSelectExpression); _resolvedJoinedGroupingTable = new SqlTable( new ResolvedJoinedGroupingTableInfo( "q1", _resolvedJoinedGroupingSubStatement, _associatedGroupingSelectExpression, "q0"), JoinSemantics.Inner); _simplifiableResolvedSqlStatement = new SqlStatement( _dataInfo, _resolvedSelectProjection, new[] { _resolvedJoinedGroupingTable }, null, null, new Ordering[0], null, false, Expression.Constant(0), Expression.Constant(0)); _simplifiableUnresolvedProjection = new AggregationExpression( typeof(int), new SqlTableReferenceExpression(_resolvedJoinedGroupingTable), AggregationModifier.Count); _stageMock = MockRepository.GenerateStrictMock <IMappingResolutionStage> (); _context = new MappingResolutionContext(); _groupAggregateSimplifier = new GroupAggregateSimplifier(_stageMock, _context); }
public void SimplifyIfPossible_WithNonSimplifiableProjection_ReturnsOriginalStatement() { Assert.That(_associatedGroupingSelectExpression.AggregationExpressions.Count, Is.EqualTo(0)); var expression = new SqlSubStatementExpression(_simplifiableResolvedSqlStatement); _stageMock.Replay(); var nonSimplifiableProjection = new AggregationExpression( typeof(int), new SqlTableReferenceExpression(SqlStatementModelObjectMother.CreateSqlTable()), AggregationModifier.Count); var result = _groupAggregateSimplifier.SimplifyIfPossible(expression, nonSimplifiableProjection); _stageMock.VerifyAllExpectations(); var expected = new SqlSubStatementExpression(_simplifiableResolvedSqlStatement); SqlExpressionTreeComparer.CheckAreEqualTrees(expected, result); Assert.That(_associatedGroupingSelectExpression.AggregationExpressions.Count, Is.EqualTo(0)); }
private static bool TryTranslateInstanceToStringWithNoArguments(TranslationContext context, MethodCallExpression expression, out AggregationExpression translation) { var method = expression.Method; var arguments = expression.Arguments; translation = null; if (method.IsStatic || method.ReturnType != typeof(string) || method.Name != "ToString" || arguments.Count != 0) { return(false); } var objectExpression = expression.Object; var objectTranslation = ExpressionToAggregationExpressionTranslator.Translate(context, objectExpression); var ast = AstExpression.ToString(objectTranslation.Ast); translation = new AggregationExpression(expression, ast, new StringSerializer()); return(true); }
private static bool TryTranslateDateTimeToStringWithFormat(TranslationContext context, MethodCallExpression expression, out AggregationExpression translation) { var method = expression.Method; var arguments = expression.Arguments; if (method.DeclaringType != typeof(DateTime) || method.IsStatic || method.ReturnType != typeof(string) || method.Name != "ToString" || arguments.Count != 1 || arguments[0].Type != typeof(string)) { translation = null; return(false); } var dateTimeExpression = expression.Object; var dateTimeTranslation = ExpressionToAggregationExpressionTranslator.Translate(context, dateTimeExpression); var formatExpression = arguments[0]; var formatTranslation = ExpressionToAggregationExpressionTranslator.Translate(context, formatExpression); var ast = AstExpression.DateToString(dateTimeTranslation.Ast, formatTranslation.Ast); translation = new AggregationExpression(expression, ast, new StringSerializer()); return(true); }
public Expression VisitAggregation(AggregationExpression expression) { Expression newInnerExpression; if (expression.AggregationModifier == AggregationModifier.Count) { newInnerExpression = ApplyValueContext(expression.Expression); } else { newInnerExpression = ApplySingleValueContext(expression.Expression); } if (newInnerExpression != expression.Expression) { return(new AggregationExpression(expression.Type, newInnerExpression, expression.AggregationModifier)); } return(expression); }
public static AggregationExpression Translate(TranslationContext context, MethodCallExpression expression) { var method = expression.Method; var arguments = expression.Arguments; if (IsStandardDeviationMethod(method, out var stddevOperator)) { if (arguments.Count == 1 || arguments.Count == 2) { var sourceExpression = arguments[0]; var sourceTranslation = ExpressionToAggregationExpressionTranslator.TranslateEnumerable(context, sourceExpression); if (arguments.Count == 2) { var selectorLambda = (LambdaExpression)arguments[1]; var selectorParameter = selectorLambda.Parameters[0]; var selectorParameterSerializer = ArraySerializerHelper.GetItemSerializer(sourceTranslation.Serializer); var selectorParameterSymbol = context.CreateSymbol(selectorParameter, selectorParameterSerializer); var selectorContext = context.WithSymbol(selectorParameterSymbol); var selectorTranslation = ExpressionToAggregationExpressionTranslator.Translate(selectorContext, selectorLambda.Body); var selectorAst = AstExpression.Map( input: sourceTranslation.Ast, @as: selectorParameterSymbol.Var, @in: selectorTranslation.Ast); var selectorResultSerializer = BsonSerializer.LookupSerializer(selectorLambda.ReturnType); sourceTranslation = new AggregationExpression(selectorLambda, selectorAst, selectorResultSerializer); } var ast = AstExpression.StdDev(stddevOperator, sourceTranslation.Ast); var serializer = BsonSerializer.LookupSerializer(expression.Type); return(new AggregationExpression(expression, ast, serializer)); } } if (SetWindowFieldsMethodToAggregationExpressionTranslator.CanTranslate(expression)) { return(SetWindowFieldsMethodToAggregationExpressionTranslator.Translate(context, expression)); } throw new ExpressionNotSupportedException(expression); }
public static AggregationExpression Translate(TranslationContext context, MethodCallExpression expression) { var method = expression.Method; var arguments = expression.Arguments; if (method.IsOneOf(EnumerableMethod.Where, MongoEnumerableMethod.WhereWithLimit)) { var sourceExpression = arguments[0]; var sourceTranslation = ExpressionToAggregationExpressionTranslator.TranslateEnumerable(context, sourceExpression); var itemSerializer = ArraySerializerHelper.GetItemSerializer(sourceTranslation.Serializer); var predicateLambda = (LambdaExpression)arguments[1]; var predicateParameter = predicateLambda.Parameters[0]; var predicateSymbol = context.CreateSymbol(predicateParameter, itemSerializer); var predicateContext = context.WithSymbol(predicateSymbol); var predicateTranslation = ExpressionToAggregationExpressionTranslator.Translate(predicateContext, predicateLambda.Body); AggregationExpression limitTranslation = null; if (method.Is(MongoEnumerableMethod.WhereWithLimit)) { var limitExpression = arguments[2]; limitTranslation = ExpressionToAggregationExpressionTranslator.Translate(context, limitExpression); } var ast = AstExpression.Filter( sourceTranslation.Ast, predicateTranslation.Ast, predicateParameter.Name, limitTranslation?.Ast); var enumerableSerializer = IEnumerableSerializer.Create(itemSerializer); return(new AggregationExpression(expression, ast, enumerableSerializer)); } throw new ExpressionNotSupportedException(expression); }
public void SimplifyIfPossible_SimplifiableStatement_AddsAggregationAndReturnsReference() { Assert.That(_associatedGroupingSelectExpression.AggregationExpressions.Count, Is.EqualTo(0)); var expression = new SqlSubStatementExpression(_simplifiableResolvedSqlStatement); var preparedResolvedAggregate = new AggregationExpression( typeof(int), new NamedExpression("element", Expression.Constant("e")), AggregationModifier.Count); _stageMock .Expect(mock => mock.ResolveAggregationExpression(Arg <Expression> .Is.Anything, Arg.Is(_context))) .Return(preparedResolvedAggregate) .WhenCalled(mi => { var expectedReplacedAggregate = new AggregationExpression( typeof(int), ((NamedExpression)_associatedGroupingSelectExpression.ElementExpression).Expression, AggregationModifier.Count); SqlExpressionTreeComparer.CheckAreEqualTrees(expectedReplacedAggregate, (Expression)mi.Arguments[0]); }); _stageMock.Replay(); var result = _groupAggregateSimplifier.SimplifyIfPossible(expression, _simplifiableUnresolvedProjection); _stageMock.VerifyAllExpectations(); Assert.That(_associatedGroupingSelectExpression.AggregationExpressions.Count, Is.EqualTo(1)); Assert.That( ((NamedExpression)_associatedGroupingSelectExpression.AggregationExpressions[0]).Expression, Is.SameAs(preparedResolvedAggregate)); var expected = new SqlColumnDefinitionExpression(typeof(int), "q0", "a0", false); SqlExpressionTreeComparer.CheckAreEqualTrees(expected, result); }
public void SetUp() { _wrappedExpression = Expression.Constant(1); _aggregationEpression = new AggregationExpression(typeof(int), _wrappedExpression, AggregationModifier.Max); }
public static AggregationExpression Translate(TranslationContext context, MethodCallExpression expression) { var method = expression.Method; var arguments = expression.Arguments; if (CanTranslate(expression)) { Expression objectExpression; if (method.Is(EnumerableMethod.Contains)) { objectExpression = arguments[0]; arguments = new ReadOnlyCollection <Expression>(arguments.Skip(1).ToList()); if (objectExpression.Type != typeof(string)) { throw new ExpressionNotSupportedException(objectExpression, expression, because: "type implementing IEnumerable<char> is not string"); } } else { objectExpression = expression.Object; } var objectTranslation = ExpressionToAggregationExpressionTranslator.Translate(context, objectExpression); var valueExpression = arguments[0]; AggregationExpression valueTranslation; if (valueExpression.Type == typeof(char) && valueExpression is ConstantExpression constantValueExpression) { var c = (char)constantValueExpression.Value; var value = new string(c, 1); valueTranslation = new AggregationExpression(valueExpression, value, objectTranslation.Serializer); } else { valueTranslation = ExpressionToAggregationExpressionTranslator.Translate(context, valueExpression); if (valueTranslation.Serializer is IRepresentationConfigurable representationConfigurable && representationConfigurable.Representation != BsonType.String) { throw new ExpressionNotSupportedException(valueExpression, expression, because: "it is not serialized as a string"); } } bool ignoreCase = false; if (IsWithComparisonTypeMethod(method)) { var comparisonTypeExpression = arguments[1]; ignoreCase = GetIgnoreCaseFromComparisonType(comparisonTypeExpression); } if (IsWithIgnoreCaseAndCultureMethod(method)) { var ignoreCaseExpression = arguments[1]; var cultureExpression = arguments[2]; ignoreCase = GetIgnoreCaseFromIgnoreCaseAndCulture(ignoreCaseExpression, cultureExpression); } var stringAst = objectTranslation.Ast; var substringAst = valueTranslation.Ast; if (ignoreCase) { stringAst = AstExpression.ToLower(stringAst); substringAst = AstExpression.ToLower(substringAst); } var ast = CreateAst(method.Name, stringAst, substringAst); return(new AggregationExpression(expression, ast, new BooleanSerializer())); } throw new ExpressionNotSupportedException(expression);
public static AggregationExpression Translate(TranslationContext context, MethodCallExpression expression) { var method = expression.Method; var parameters = method.GetParameters(); var arguments = expression.Arguments.ToArray(); if (method.IsOneOf(__windowMethods)) { var partitionExpression = arguments[0]; var partitionTranslation = ExpressionToAggregationExpressionTranslator.TranslateEnumerable(context, partitionExpression); var partitionSerializer = (ISetWindowFieldsPartitionSerializer)partitionTranslation.Serializer; var inputSerializer = partitionSerializer.InputSerializer; AstWindow window = null; if (HasArgument <Expression>(parameters, "window", arguments, out var windowExpression)) { window = TranslateWindow(context, expression, windowExpression, inputSerializer); } if (method.IsOneOf(__nullaryMethods)) { var @operator = GetNullaryWindowOperator(method); var ast = AstExpression.NullaryWindowExpression(@operator, window); var serializer = BsonSerializer.LookupSerializer(method.ReturnType); // TODO: use correct serializer return(new AggregationExpression(expression, ast, serializer)); } AggregationExpression selectorTranslation = null; if (HasArgument <LambdaExpression>(parameters, "selector", arguments, out var selectorLambda)) { selectorTranslation = TranslateSelector(context, selectorLambda, inputSerializer); } if (method.IsOneOf(__unaryMethods)) { var @operator = GetUnaryWindowOperator(method); var ast = AstExpression.UnaryWindowExpression(@operator, selectorTranslation.Ast, window); var serializer = BsonSerializer.LookupSerializer(method.ReturnType); // TODO: use correct serializer return(new AggregationExpression(expression, ast, serializer)); } if (method.IsOneOf(__binaryMethods)) { var selector1Lambda = GetArgument <LambdaExpression>(parameters, "selector1", arguments); var selector2Lambda = GetArgument <LambdaExpression>(parameters, "selector2", arguments); var selector1Translation = TranslateSelector(context, selector1Lambda, inputSerializer); var selector2Translation = TranslateSelector(context, selector2Lambda, inputSerializer); var @operator = GetBinaryWindowOperator(method); var ast = AstExpression.BinaryWindowExpression(@operator, selector1Translation.Ast, selector2Translation.Ast, window); var serializer = BsonSerializer.LookupSerializer(method.ReturnType); // TODO: use correct serializer return(new AggregationExpression(expression, ast, serializer)); } if (method.IsOneOf(__derivativeOrIntegralMethods)) { WindowTimeUnit?unit = default; if (HasArgument <Expression>(parameters, "unit", arguments, out var unitExpression)) { unit = unitExpression.GetConstantValue <WindowTimeUnit>(expression); } var @operator = GetDerivativeOrIntegralWindowOperator(method); var ast = AstExpression.DerivativeOrIntegralWindowExpression(@operator, selectorTranslation.Ast, unit, window); var serializer = BsonSerializer.LookupSerializer(method.ReturnType); // TODO: use correct serializer return(new AggregationExpression(expression, ast, serializer)); } if (method.IsOneOf(__exponentialMovingAverageMethods)) { var weightingExpression = arguments[2]; var weighting = weightingExpression.GetConstantValue <ExponentialMovingAverageWeighting>(expression); var ast = AstExpression.ExponentialMovingAverageWindowExpression(selectorTranslation.Ast, weighting, window); var serializer = BsonSerializer.LookupSerializer(method.ReturnType); // TODO: use correct serializer return(new AggregationExpression(expression, ast, serializer)); } if (method.IsOneOf(__shiftMethods)) { var byExpression = arguments[2]; var by = byExpression.GetConstantValue <int>(expression); AstExpression defaultValue = null; if (method.Is(WindowMethod.ShiftWithDefaultValue)) { var defaultValueExpression = arguments[3]; var defaultValueTranslation = ExpressionToAggregationExpressionTranslator.Translate(context, defaultValueExpression); defaultValue = defaultValueTranslation.Ast; } var ast = AstExpression.ShiftWindowExpression(selectorTranslation.Ast, by, defaultValue); var serializer = BsonSerializer.LookupSerializer(method.ReturnType); // TODO: use correct serializer return(new AggregationExpression(expression, ast, serializer)); } } throw new ExpressionNotSupportedException(expression); }
// private static methods private static (AstProjectStage, IBsonSerializer) CreateComputedDocumentProjectStage(AggregationExpression expression) { var computedDocument = (AstComputedDocumentExpression)expression.Ast; var specifications = new List <AstProjectStageSpecification>(); var isIdProjected = false; foreach (var computedField in computedDocument.Fields) { var path = computedField.Path; var value = computedField.Value; if (value is AstConstantExpression astConstantExpression) { if (ValueNeedsToBeQuoted(astConstantExpression.Value)) { value = AstExpression.Literal(value); } } specifications.Add(AstProject.Set(path, value)); isIdProjected |= path == "_id"; } if (!isIdProjected) { specifications.Add(AstProject.ExcludeId()); } var projectStage = AstStage.Project(specifications); return(projectStage, expression.Serializer); bool ValueNeedsToBeQuoted(BsonValue constantValue) { switch (constantValue.BsonType) { case BsonType.Boolean: case BsonType.Decimal128: case BsonType.Double: case BsonType.Int32: case BsonType.Int64: return(true); default: return(false); } } }
private static (AstProjectStage, IBsonSerializer) CreateWrappedValueProjectStage(AggregationExpression expression) { var wrappedValueSerializer = WrappedValueSerializer.Create("_v", expression.Serializer); var projectStage = AstStage.Project( AstProject.Set("_v", expression.Ast), AstProject.ExcludeId()); return(projectStage, wrappedValueSerializer); }