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);
            }
Exemple #4
0
            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);
Exemple #7
0
 /// <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));
 }
Exemple #14
0
 /// <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));
 }
Exemple #15
0
 /// <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));
 }
Exemple #16
0
 /// <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;
 }
Exemple #17
0
 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);
Exemple #21
0
 /// <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);
Exemple #22
0
 /// <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));
 }