/// <summary> /// Visits a <see cref="TakeOperator" /> node. /// </summary> /// <param name="op">Node to visit.</param> /// <returns>Result of visiting the node.</returns> protected internal override QueryOperator VisitTake(TakeOperator op) { var src = VisitAndConvert <MonadMember>(op.Source); var count = Visit(op.Count); if (src != op.Source || count != op.Count) { return(MakeTake(op, src, count)); } return(op); }
/// <summary> /// Visits a <see cref="TakeOperator" /> operator and coalesces it with any possible child operators. /// </summary> /// <param name="op">The operator to visit.</param> /// <returns>The coalesced operator.</returns> protected internal override QueryOperator VisitTake(TakeOperator op) { var source = VisitAndConvert <MonadMember>(op.Source); var count = Visit(op.Count); // Take coalescing var srcOperator = source.QueryNodeType == QueryNodeType.Operator ? (QueryOperator)source : null; var srcTake = srcOperator != null && srcOperator.NodeType == OperatorType.Take ? (TakeOperator)srcOperator : null; if (srcTake != null) { if (TryExtractNullaryLambdaBody(count, out Expression count1) && count1.NodeType == ExpressionType.Constant && TryExtractNullaryLambdaBody(srcTake.Count, out Expression count2) && count2.NodeType == ExpressionType.Constant) { var c1 = (int)((ConstantExpression)count1).Value; var c2 = (int)((ConstantExpression)count2).Value; return(op.QueryExpressionFactory.Take( op.ElementType, srcTake.Source, DefaultQueryExpressionFactory.Instance.LambdaAbstraction( Expression.Lambda( Expression.Constant( Math.Min(c1, c2) ) ), Array.Empty <QueryTree>() ) )); } var p1 = Expression.Parameter(typeof(int)); var p2 = Expression.Parameter(typeof(int)); return(op.QueryExpressionFactory.Take( op.ElementType, srcTake.Source, DefaultQueryExpressionFactory.Instance.LambdaAbstraction( Expression.Lambda( Expression.Call(s_Min, p1, p2), p1, p2 ), new[] { srcTake.Count, count } ) )); } return(op.Update(source, count)); }
/// <summary> /// Makes a <see cref="TakeOperator" /> with the given children. /// </summary> /// <param name="node">Original query expression.</param> /// <param name="source">Source query expression.</param> /// <param name="count">Count query expression.</param> /// <returns>Representation of the original query expression.</returns> protected sealed override QueryOperator MakeTake(TakeOperator node, MonadMember source, QueryTree count) { return(node.QueryExpressionFactory.Take(node.ElementType, source, count)); }
/// <summary> /// Creates a textual representation of the TakeOperator with the given children. /// </summary> /// <param name="node">Original query expression.</param> /// <param name="source">Source query expression.</param> /// <param name="count">Count query expression.</param> /// <returns>Representation of the original query expression.</returns> protected override string MakeTake(TakeOperator node, string source, string count) { return(string.Format(CultureInfo.InvariantCulture, "@Take({0}, {1})", source, count)); }
/// <summary> /// Makes a <see cref="TakeOperator" /> with the given children. /// </summary> /// <param name="node">Original query expression.</param> /// <param name="source">Source query expression.</param> /// <param name="elementType">Element type for the resulting operator.</param> /// <param name="count">Count query expression.</param> /// <returns>Representation of the original query expression.</returns> protected virtual QueryOperator MakeTake(TakeOperator node, Type elementType, MonadMember source, QueryTree count) { return(node.QueryExpressionFactory.Take(elementType, source, count)); }