示例#1
0
 public ProjectionExpression(SelectExpression source, Expression projector, LambdaExpression aggregator)
     : base(DbExpressionType.Projection, aggregator != null ? aggregator.Body.Type : typeof(IEnumerable<>).MakeGenericType(projector.Type))
 {
     this.select = source;
     this.projector = projector;
     this.aggregator = aggregator;
 }
示例#2
0
 protected override Expression VisitSelect(SelectExpression select)
 {
     IdentifiableAlias newAlias = new IdentifiableAlias();
     this.map[select.Alias] = newAlias;
     select = (SelectExpression)base.VisitSelect(select);
     return new SelectExpression(newAlias, select.Fields, select.From, select.Where, select.OrderBy, select.GroupBy, select.IsDistinct, select.Skip, select.Take, select.IsReverse);
 }
示例#3
0
 protected override Expression VisitSelect(SelectExpression select)
 {
     Expression saveCurrentFrom = this.currentFrom;
     this.currentFrom = this.VisitSource(select.From);
     try
     {
         Expression where = this.Visit(select.Where);
         ReadOnlyCollection<OrderExpression> orderBy = this.VisitOrderBy(select.OrderBy);
         ReadOnlyCollection<Expression> groupBy = this.VisitExpressionList(select.GroupBy);
         Expression skip = this.Visit(select.Skip);
         Expression take = this.Visit(select.Take);
         ReadOnlyCollection<FieldDeclaration> Fields = this.VisitFieldDeclarations(select.Fields);
         if (this.currentFrom != select.From
             || where != select.Where
             || orderBy != select.OrderBy
             || groupBy != select.GroupBy
             || take != select.Take
             || skip != select.Skip
             || Fields != select.Fields
             )
         {
             return new SelectExpression(select.Alias, Fields, this.currentFrom, where, orderBy, groupBy, select.IsDistinct, skip, take, select.IsReverse);
         }
         return select;
     }
     finally
     {
         this.currentFrom = saveCurrentFrom;
     }
 }
示例#4
0
 protected DeclarationCommand UpdateDeclaration(DeclarationCommand decl, IEnumerable<VariableDeclaration> variables, SelectExpression source)
 {
     if (variables != decl.Variables || source != decl.Source)
     {
         return new DeclarationCommand(variables, source);
     }
     return decl;
 }
示例#5
0
 protected override Expression VisitSelect(SelectExpression select)
 {
     // only consider aggregates in these locations
     this.Visit(select.Where);
     this.VisitOrderBy(select.OrderBy);
     this.VisitFieldDeclarations(select.Fields);
     return select;
 }
        public static SelectExpression AddRedundantSelect(this SelectExpression sel, QueryLanguage language, IdentifiableAlias newAlias)
        {
            var newFields =
                from d in sel.Fields
                let qt = (d.Expression is FieldExpression) ? ((FieldExpression)d.Expression).QueryType : language.TypeSystem.GetStorageType(d.Expression.Type)
                select new FieldDeclaration(d.Name, new FieldExpression(d.Expression.Type, qt, newAlias, d.Name), qt);

            var newFrom = new SelectExpression(newAlias, sel.Fields, sel.From, sel.Where, sel.OrderBy, sel.GroupBy, sel.IsDistinct, sel.Skip, sel.Take, sel.IsReverse);
            return new SelectExpression(sel.Alias, newFields, newFrom, null, null, null, false, null, null, false);
        }
示例#7
0
 protected override Expression VisitSelect(SelectExpression select)
 {
     if (this.selectsToRemove.Contains(select))
     {
         return this.Visit(select.From);
     }
     else
     {
         return base.VisitSelect(select);
     }
 }
 internal static bool IsSimpleProjection(SelectExpression select)
 {
     foreach (FieldDeclaration decl in select.Fields)
     {
         FieldExpression col = decl.Expression as FieldExpression;
         if (col == null || decl.Name != col.Name)
         {
             return false;
         }
     }
     return true;
 }
 protected override Expression VisitClientJoin(ClientJoinExpression join)
 {
     // treat client joins as new top level
     var saveTop = this.isTopLevel;
     var saveSelect = this.currentSelect;
     this.isTopLevel = true;
     this.currentSelect = null;
     Expression result = base.VisitClientJoin(join);
     this.isTopLevel = saveTop;
     this.currentSelect = saveSelect;
     return result;
 }
        protected override Expression VisitSelect(SelectExpression select)
        {
            select = (SelectExpression)base.VisitSelect(select);

            // first remove all purely redundant subqueries
            List<SelectExpression> redundant = RedundantSubqueryGatherer.Gather(select.From);
            if (redundant != null)
            {
                select = SubqueryRemover.Remove(select, redundant);
            }

            return select;
        }
 internal static bool IsNameMapProjection(SelectExpression select)
 {
     if (select.From is IdentifiableExpression) return false;
     SelectExpression fromSelect = select.From as SelectExpression;
     if (fromSelect == null || select.Fields.Count != fromSelect.Fields.Count)
         return false;
     ReadOnlyCollection<FieldDeclaration> fromFields = fromSelect.Fields;
     // test that all fields in 'select' are refering to fields in the same position
     // in from.
     for (int i = 0, n = select.Fields.Count; i < n; i++)
     {
         FieldExpression col = select.Fields[i].Expression as FieldExpression;
         if (col == null || !(col.Name == fromFields[i].Name))
             return false;
     }
     return true;
 }
示例#12
0
 protected override Expression VisitSelect(SelectExpression select)
 {
     select = (SelectExpression)base.VisitSelect(select);
     if (lookup.Contains(select.Alias))
     {
         List<FieldDeclaration> aggFields = new List<FieldDeclaration>(select.Fields);
         foreach (AggregateSubqueryExpression ae in lookup[select.Alias])
         {
             string name = "agg" + aggFields.Count;
             var colType = this.language.TypeSystem.GetStorageType(ae.Type);
             FieldDeclaration cd = new FieldDeclaration(name, ae.AggregateInGroupSelect, colType);
             this.map.Add(ae, new FieldExpression(ae.Type, colType, ae.GroupByAlias, name));
             aggFields.Add(cd);
         }
         return new SelectExpression(select.Alias, aggFields, select.From, select.Where, select.OrderBy, select.GroupBy, select.IsDistinct, select.Skip, select.Take, select.IsReverse);
     }
     return select;
 }
示例#13
0
 protected override Expression VisitSelect(SelectExpression select)
 {
     var saveWhere = this.currentWhere;
     try
     {
         this.currentWhere = select.Where;
         var result = (SelectExpression)base.VisitSelect(select);
         if (this.currentWhere != result.Where)
         {
             return result.SetWhere(this.currentWhere);
         }
         return result;
     }
     finally
     {
         this.currentWhere = saveWhere;
     }
 }
示例#14
0
        protected override Expression VisitSelect(SelectExpression select)
        {
            select = (SelectExpression)base.VisitSelect(select);

            // look for redundant field declarations
            List<FieldDeclaration> cols = select.Fields.OrderBy(c => c.Name).ToList();
            BitArray removed = new BitArray(select.Fields.Count);
            bool anyRemoved = false;
            for (int i = 0, n = cols.Count; i < n - 1; i++)
            {
                FieldDeclaration ci = cols[i];
                FieldExpression cix = ci.Expression as FieldExpression;
                StorageType qt = cix != null ? cix.QueryType : ci.QueryType;
                FieldExpression cxi = new FieldExpression(ci.Expression.Type, qt, select.Alias, ci.Name);
                for (int j = i + 1; j < n; j++)
                {
                    if (!removed.Get(j))
                    {
                        FieldDeclaration cj = cols[j];
                        if (SameExpression(ci.Expression, cj.Expression))
                        {
                            // any reference to 'j' should now just be a reference to 'i'
                            FieldExpression cxj = new FieldExpression(cj.Expression.Type, qt, select.Alias, cj.Name);
                            this.map.Add(cxj, cxi);
                            removed.Set(j, true);
                            anyRemoved = true;
                        }
                    }
                }
            }
            if (anyRemoved)
            {
                List<FieldDeclaration> newDecls = new List<FieldDeclaration>();
                for (int i = 0, n = cols.Count; i < n; i++)
                {
                    if (!removed.Get(i))
                    {
                        newDecls.Add(cols[i]);
                    }
                }
                select = select.SetFields(newDecls);
            }
            return select;
        }
        protected override Expression VisitProjection(ProjectionExpression proj)
        {
            if (isTopLevel)
            {
                isTopLevel = false;
                this.currentSelect = proj.Select;
                Expression projector = this.Visit(proj.Projector);
                if (projector != proj.Projector || this.currentSelect != proj.Select)
                {
                    return new ProjectionExpression(this.currentSelect, projector, proj.Aggregator);
                }
                return proj;
            }

            if (proj.IsSingleton && this.CanJoinOnServer(this.currentSelect))
            {
                IdentifiableAlias newAlias = new IdentifiableAlias();
                this.currentSelect = this.currentSelect.AddRedundantSelect(this.language, newAlias);

                // remap any references to the outer select to the new alias;
                SelectExpression source = (SelectExpression)FieldMapper.Map(proj.Select, newAlias, this.currentSelect.Alias);

                // add outer-join test
                ProjectionExpression pex = this.language.AddOuterJoinTest(new ProjectionExpression(source, proj.Projector));

                var pc = FieldProjector.ProjectFields(this.language, pex.Projector, this.currentSelect.Fields, this.currentSelect.Alias, newAlias, proj.Select.Alias);

                JoinExpression join = new JoinExpression(JoinType.OuterApply, this.currentSelect.From, pex.Select, null);

                this.currentSelect = new SelectExpression(this.currentSelect.Alias, pc.Fields, join, null);
                return this.Visit(pc.Projector);
            }

            var saveTop = this.isTopLevel;
            var saveSelect = this.currentSelect;
            this.isTopLevel = true;
            this.currentSelect = null;
            Expression result = base.VisitProjection(proj);
            this.isTopLevel = saveTop;
            this.currentSelect = saveSelect;
            return result;
        }
        protected override Expression VisitSelect(SelectExpression select)
        {
            var from = this.VisitSource(select.From);
            var where = this.Visit(select.Where);
            var orderBy = this.VisitOrderBy(select.OrderBy);
            var groupBy = this.VisitExpressionList(select.GroupBy);
            var skip = this.Visit(select.Skip);
            var take = this.Visit(select.Take);
            var fields = this.VisitFieldDeclarations(select.Fields);
            select = this.UpdateSelect(select, from, where, orderBy, groupBy, skip, take, select.IsDistinct, select.IsReverse, fields);

            // first remove all purely redundant subqueries
            List<SelectExpression> redundant = ORedundantSubqueryGatherer.Gather(select.From);
            if (redundant != null)
            {
                select = OSubqueryRemover.Remove(select, redundant);
            }

            return select;
        }
示例#17
0
        protected override Expression VisitSelect(SelectExpression select)
        {
            if (!_visited)
            {
                _visited = true;
                if (select.Take == null)
                {
                    Expression take = Visit(Expression.Constant(Policy.Limit));
                    select = new SelectExpression(
                        select.Alias,
                        select.Fields,
                        select.From,
                        select.Where,
                        select.OrderBy,
                        select.GroupBy,
                        select.IsDistinct,
                        select.Skip,
                        take,
                        select.IsReverse);
                }
            }

            return select;
        }
示例#18
0
 protected InExpression UpdateIn(InExpression @in, Expression expression, SelectExpression select, IEnumerable<Expression> values)
 {
     if (expression != @in.Expression || select != @in.Select || values != @in.Values)
     {
         if (select != null)
         {
             return new InExpression(expression, select);
         }
         else
         {
             return new InExpression(expression, values);
         }
     }
     return @in;
 }
示例#19
0
 protected ExistsExpression UpdateExists(ExistsExpression exists, SelectExpression select)
 {
     if (select != exists.Select)
     {
         return new ExistsExpression(select);
     }
     return exists;
 }
示例#20
0
 protected ProjectionExpression UpdateProjection(ProjectionExpression proj, SelectExpression select, Expression projector, LambdaExpression aggregator)
 {
     if (select != proj.Select || projector != proj.Projector || aggregator != proj.Aggregator)
     {
         return new ProjectionExpression(select, projector, aggregator);
     }
     return proj;
 }
示例#21
0
 protected SelectExpression UpdateSelect(
     SelectExpression select,
     Expression from, Expression where,
     IEnumerable<OrderExpression> orderBy, IEnumerable<Expression> groupBy,
     Expression skip, Expression take,
     bool isDistinct, bool isReverse,
     IEnumerable<FieldDeclaration> fields
     )
 {
     if (from != select.From
         || where != select.Where
         || orderBy != select.OrderBy
         || groupBy != select.GroupBy
         || take != select.Take
         || skip != select.Skip
         || isDistinct != select.IsDistinct
         || fields != select.Fields
         || isReverse != select.IsReverse
         )
     {
         return new SelectExpression(select.Alias, fields, from, where, orderBy, groupBy, isDistinct, skip, take, isReverse);
     }
     return select;
 }
 internal static bool IsInitialProjection(SelectExpression select)
 {
     return select.From is IdentifiableExpression;
 }
示例#23
0
 protected ScalarExpression UpdateScalar(ScalarExpression scalar, SelectExpression select)
 {
     if (select != scalar.Select)
     {
         return new ScalarExpression(scalar.Type, select);
     }
     return scalar;
 }
 private static bool IsRedudantSubquery(SelectExpression select)
 {
     return (IsSimpleProjection(select) || IsNameMapProjection(select))
         && !select.IsDistinct
         && !select.IsReverse
         && select.Take == null
         && select.Skip == null
         && select.Where == null
         && (select.OrderBy == null || select.OrderBy.Count == 0)
         && (select.GroupBy == null || select.GroupBy.Count == 0);
 }
示例#25
0
 protected virtual Expression VisitSelect(SelectExpression select)
 {
     var from = this.VisitSource(select.From);
     var where = this.Visit(select.Where);
     var orderBy = this.VisitOrderBy(select.OrderBy);
     var groupBy = this.VisitExpressionList(select.GroupBy);
     var skip = this.Visit(select.Skip);
     var take = this.Visit(select.Take);
     var fields = this.VisitFieldDeclarations(select.Fields);
     return this.UpdateSelect(select, from, where, orderBy, groupBy, skip, take, select.IsDistinct, select.IsReverse, fields);
 }
            protected override Expression VisitSelect(SelectExpression select)
            {
                bool wasTopLevel = isTopLevel;
                isTopLevel = false;

                select = (SelectExpression)base.VisitSelect(select);

                // next attempt to merge subqueries that would have been removed by the above
                // logic except for the existence of a where clause
                while (CanMergeWithFrom(select, wasTopLevel))
                {
                    SelectExpression fromSelect = GetLeftMostSelect(select.From);

                    // remove the redundant subquery
                    select = SubqueryRemover.Remove(select, fromSelect);

                    // merge where expressions
                    Expression where = select.Where;
                    if (fromSelect.Where != null)
                    {
                        if (where != null)
                        {
                            where = fromSelect.Where.And(where);
                        }
                        else
                        {
                            where = fromSelect.Where;
                        }
                    }
                    var orderBy = select.OrderBy != null && select.OrderBy.Count > 0 ? select.OrderBy : fromSelect.OrderBy;
                    var groupBy = select.GroupBy != null && select.GroupBy.Count > 0 ? select.GroupBy : fromSelect.GroupBy;
                    Expression skip = select.Skip != null ? select.Skip : fromSelect.Skip;
                    Expression take = select.Take != null ? select.Take : fromSelect.Take;
                    bool isDistinct = select.IsDistinct | fromSelect.IsDistinct;

                    if (where != select.Where
                        || orderBy != select.OrderBy
                        || groupBy != select.GroupBy
                        || isDistinct != select.IsDistinct
                        || skip != select.Skip
                        || take != select.Take)
                    {
                        select = new SelectExpression(select.Alias, select.Fields, select.From, where, orderBy, groupBy, isDistinct, skip, take, select.IsReverse);
                    }
                }

                return select;
            }
示例#27
0
 public ScalarExpression(Type type, SelectExpression select)
     : base(DbExpressionType.Scalar, type, select)
 {
 }
 private static bool CanMergeWithFrom(SelectExpression select, bool isTopLevel)
 {
     SelectExpression fromSelect = GetLeftMostSelect(select.From);
     if (fromSelect == null)
         return false;
     if (!IsFieldProjection(fromSelect))
         return false;
     bool selHasNameMapProjection = IsNameMapProjection(select);
     bool selHasOrderBy = select.OrderBy != null && select.OrderBy.Count > 0;
     bool selHasGroupBy = select.GroupBy != null && select.GroupBy.Count > 0;
     bool selHasAggregates = AggregateChecker.HasAggregates(select);
     bool selHasJoin = select.From is JoinExpression;
     bool frmHasOrderBy = fromSelect.OrderBy != null && fromSelect.OrderBy.Count > 0;
     bool frmHasGroupBy = fromSelect.GroupBy != null && fromSelect.GroupBy.Count > 0;
     bool frmHasAggregates = AggregateChecker.HasAggregates(fromSelect);
     // both cannot have orderby
     if (selHasOrderBy && frmHasOrderBy)
         return false;
     // both cannot have groupby
     if (selHasGroupBy && frmHasGroupBy)
         return false;
     // these are distinct operations
     if (select.IsReverse || fromSelect.IsReverse)
         return false;
     // cannot move forward order-by if outer has group-by
     if (frmHasOrderBy && (selHasGroupBy || selHasAggregates || select.IsDistinct))
         return false;
     // cannot move forward group-by if outer has where clause
     if (frmHasGroupBy /*&& (select.Where != null)*/) // need to assert projection is the same in order to move group-by forward
         return false;
     // cannot move forward a take if outer has take or skip or distinct
     if (fromSelect.Take != null && (select.Take != null || select.Skip != null || select.IsDistinct || selHasAggregates || selHasGroupBy || selHasJoin))
         return false;
     // cannot move forward a skip if outer has skip or distinct
     if (fromSelect.Skip != null && (select.Skip != null || select.IsDistinct || selHasAggregates || selHasGroupBy || selHasJoin))
         return false;
     // cannot move forward a distinct if outer has take, skip, groupby or a different projection
     if (fromSelect.IsDistinct && (select.Take != null || select.Skip != null || !selHasNameMapProjection || selHasGroupBy || selHasAggregates || (selHasOrderBy && !isTopLevel) || selHasJoin))
         return false;
     if (frmHasAggregates && (select.Take != null || select.Skip != null || select.IsDistinct || selHasAggregates || selHasGroupBy || selHasJoin))
         return false;
     return true;
 }
示例#29
0
 public ExistsExpression(SelectExpression select)
     : base(DbExpressionType.Exists, typeof(bool), select)
 {
 }
 private static bool IsFieldProjection(SelectExpression select)
 {
     for (int i = 0, n = select.Fields.Count; i < n; i++)
     {
         var cd = select.Fields[i];
         if (cd.Expression.NodeType != (ExpressionType)DbExpressionType.Field &&
             cd.Expression.NodeType != ExpressionType.Constant)
             return false;
     }
     return true;
 }