private static bool TryExtractNullaryLambdaBody(QueryTree queryTree, out Expression result) { if (queryTree.QueryNodeType == QueryNodeType.Lambda) { var lambda = (LambdaAbstraction)queryTree; if (lambda.Parameters.Count == 0) { result = lambda.Body.Body; return(true); } } result = null; return(false); }
private static bool TryExtractNullaryLambdaBody <T>(QueryTree queryTree, ExpressionType nodeType, out T result) where T : Expression { if (queryTree.QueryNodeType == QueryNodeType.Lambda) { var lambda = (LambdaAbstraction)queryTree; if (lambda.Parameters.Count == 0) { return(TryCast <T>(lambda.Body.Body, nodeType, out result)); } } result = null; return(false); }
private static bool TryCast <T>(QueryTree queryExpressionNode, OperatorType nodeType, out T converted) where T : QueryOperator { if (queryExpressionNode.QueryNodeType == QueryNodeType.Operator) { var op = (QueryOperator)queryExpressionNode; if (op.NodeType == nodeType) { converted = op as T; return(converted != null); } } converted = null; return(false); }
public QueryTree Optimize(QueryTree queryTree) { var history = new HashSet <QueryTree>(new QueryExpressionEqualityComparator()); var current = queryTree; var reduced = default(QueryTree); var i = 0; while (current != reduced) { if (!history.Add(current)) { if (_throwOnCycle) { throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Irreducible recursive query tree detected: '{0}'.", current)); } else { break; } } if (i == _maxIterations) { break; } reduced = current; current = _optimizer.Optimize(current); i++; } return(current); }
/// <summary> /// Coalesces let clauses and flattens the transparent identifiers in the original query. /// </summary> /// <param name="queryTree">The query to optimize.</param> /// <returns>The query with the let clauses coalesced and types flattened.</returns> public QueryTree Optimize(QueryTree queryTree) { var optimizer = new Impl(); return(optimizer.Visit(queryTree)); }
/// <summary> /// Creates a <see cref="WhereOperator" /> that represents a where operator. /// </summary> /// <param name="elementType">The <see cref="Type" /> of the elements in the resulting monad.</param> /// <param name="source">The monad whose elements to filter.</param> /// <param name="predicate">The function to test each source element for a condition.</param> /// <returns>A <see cref="WhereOperator" /> that has the given source.</returns> public abstract WhereOperator Where(Type elementType, MonadMember source, QueryTree predicate);
/// <summary> /// Makes a <see cref="SelectOperator" /> 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="inputElementType">Input element type for the resulting operator.</param> /// <param name="selector">Selector query expression.</param> /// <returns>Representation of the original query expression.</returns> protected virtual QueryOperator MakeSelect(SelectOperator node, Type elementType, Type inputElementType, MonadMember source, QueryTree selector) { return(node.QueryExpressionFactory.Select(elementType, inputElementType, source, selector)); }
/// <summary> /// Optimizes the given query expression tree by coalescing adjacent operators. /// </summary> /// <param name="queryTree">The query expression tree to optimize.</param> /// <returns>An optimized version of the input query tree.</returns> public QueryTree Optimize(QueryTree queryTree) => Visit(queryTree);
/// <summary> /// Creates a <see cref="FirstOperator" /> that represents a take operator. /// </summary> /// <param name="elementType">The <see cref="Type" /> of the elements in the resulting monad.</param> /// <param name="source">The monad to take elements from.</param> /// <param name="count">The number of elements to return.</param> /// <returns>A <see cref="FirstOperator" /> that has the given source.</returns> public TakeOperator Take(Type elementType, MonadMember source, QueryTree count) { return(new TakeOperator(elementType, source, count)); }
/// <summary> /// Creates a <see cref="SelectOperator" /> that represents a select operator. /// </summary> /// <param name="elementType">The <see cref="Type" /> of the elements in the resulting monad.</param> /// <param name="inputElementType">The <see cref="Type" /> of the elements in the source monad.</param> /// <param name="source">The monad to invoke a transform function on.</param> /// <param name="selector">A transform function to apply to each source element.</param> /// <returns>A <see cref="SelectOperator" /> that has the given source.</returns> public SelectOperator Select(Type elementType, Type inputElementType, MonadMember source, QueryTree selector) { return(new SelectOperator(elementType, inputElementType, source, selector)); }
/// <summary> /// Creates a <see cref="Optimizers.MonadAbstraction" /> that abstracts over a monad member such as a source or unknown operator. /// </summary> /// <param name="elementType">The <see cref="Type" /> of the elements in the resulting monad.</param> /// <param name="inner">The inner monad to abstract over.</param> /// <returns>A <see cref="Optimizers.MonadAbstraction" /> that has the given monadic type.</returns> public MonadAbstraction MonadAbstraction(Type elementType, QueryTree inner) { return(new MonadAbstraction(elementType, inner)); }
/// <summary> /// Creates a <see cref="FirstPredicateOperator" /> that represents a first operator with a predicate. /// </summary> /// <param name="elementType">The <see cref="Type" /> of the elements in the resulting monad.</param> /// <param name="source">The monad from which to get the first element satisfying a condition.</param> /// <param name="predicate">The function to test each source element for a condition.</param> /// <returns>A <see cref="FirstPredicateOperator" /> that has the given source.</returns> public FirstPredicateOperator First(Type elementType, MonadMember source, QueryTree predicate) { return(new FirstPredicateOperator(elementType, source, predicate)); }
/// <summary> /// Creates a <see cref="WhereOperator" /> that represents a where operator. /// </summary> /// <param name="elementType">The <see cref="Type" /> of the elements in the resulting monad.</param> /// <param name="source">The monad whose elements to filter.</param> /// <param name="predicate">The function to test each source element for a condition.</param> /// <returns>A <see cref="WhereOperator" /> that has the given source.</returns> public WhereOperator Where(Type elementType, MonadMember source, QueryTree predicate) { return(new WhereOperator(elementType, source, predicate)); }
/// <summary> /// Makes a <see cref="FirstPredicateOperator" /> 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="predicate">Predicate query expression.</param> /// <returns>Representation of the original query expression.</returns> protected virtual QueryOperator MakeFirstPredicate(FirstPredicateOperator node, Type elementType, MonadMember source, QueryTree predicate) { return(node.QueryExpressionFactory.First(elementType, source, predicate)); }
/// <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)); }
/// <summary> /// Creates a monad abstraction. /// </summary> /// <param name="elementType">The element type of the monad.</param> /// <param name="inner">The query tree this abstraction wraps.</param> internal MonadAbstraction(Type elementType, QueryTree inner) : base(elementType) { Inner = inner; }
public QueryTree Optimize(QueryTree queryTree) => _second.Optimize(_first.Optimize(queryTree));
/// <summary> /// Creates a <see cref="FirstPredicateOperator" /> that represents a first operator with a predicate. /// </summary> /// <param name="elementType">The <see cref="Type" /> of the elements in the resulting monad.</param> /// <param name="source">The monad from which to get the first element satisfying a condition.</param> /// <param name="predicate">The function to test each source element for a condition.</param> /// <returns>A <see cref="FirstPredicateOperator" /> that has the given source.</returns> public abstract FirstPredicateOperator First(Type elementType, MonadMember source, QueryTree predicate);
/// <summary> /// Creates a <see cref="SelectOperator" /> that represents a select operator. /// </summary> /// <param name="elementType">The <see cref="Type" /> of the elements in the resulting monad.</param> /// <param name="inputElementType">The <see cref="Type" /> of the elements in the source monad.</param> /// <param name="source">The monad to invoke a transform function on.</param> /// <param name="selector">A transform function to apply to each source element.</param> /// <returns>A <see cref="SelectOperator" /> that has the given source.</returns> public abstract SelectOperator Select(Type elementType, Type inputElementType, MonadMember source, QueryTree selector);
/// <summary> /// Creates a <see cref="FirstOperator" /> that represents a take operator. /// </summary> /// <param name="elementType">The <see cref="Type" /> of the elements in the resulting monad.</param> /// <param name="source">The monad to take elements from.</param> /// <param name="count">The number of elements to return.</param> /// <returns>A <see cref="FirstOperator" /> that has the given source.</returns> public abstract TakeOperator Take(Type elementType, MonadMember source, QueryTree count);
/// <summary> /// Visits the specified query expression and rewrites it to the target query expression type. /// </summary> /// <param name="expression">Query expression to visit.</param> /// <returns>Result of visiting the query expression.</returns> public virtual TQueryTree Visit(QueryTree expression) { if (expression == null) { return(default);
/// <summary> /// Makes a <see cref="MonadAbstraction" /> with the given children. /// </summary> /// <param name="node">Original query expression.</param> /// <param name="elementType">Element type for the resulting operator.</param> /// <param name="inner">Inner query expression.</param> /// <returns>Representation of the original query expression.</returns> protected virtual MonadMember MakeMonadAbstraction(MonadAbstraction node, Type elementType, QueryTree inner) { return(DefaultQueryExpressionFactory.Instance.MonadAbstraction(elementType, inner)); }