internal static bool IsInitialProjection(SelectExpression select) { return(select.From is TableExpression); }
public DeclarationCommand(IEnumerable <VariableDeclaration> variables, SelectExpression source) : base(DbExpressionType.Declaration, typeof(void)) { this.Variables = variables.ToReadOnly(); this.Source = source; }
private static bool CanMergeWithFrom(SelectExpression select, bool isTopLevel) { SelectExpression fromSelect = GetLeftMostSelect(select.From); if (fromSelect == null) { return(false); } if (!IsColumnProjection(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); }
public InExpression(Expression expression, SelectExpression select) : base(DbExpressionType.In, typeof(bool), select) { this.Expression = expression; }
public ProjectionExpression(SelectExpression source, Expression projector) : this(source, projector, null) { }
public ExistsExpression(SelectExpression select) : base(DbExpressionType.Exists, typeof(bool), select) { }
public ScalarExpression(Type type, SelectExpression select) : base(DbExpressionType.Scalar, type, select) { }
protected SubqueryExpression(DbExpressionType eType, Type type, SelectExpression select) : base(eType, type) { System.Diagnostics.Debug.Assert(eType == DbExpressionType.Scalar || eType == DbExpressionType.Exists || eType == DbExpressionType.In); this.Select = select; }
protected override Expression VisitSelect(SelectExpression select) { // visit column projection first ReadOnlyCollection <ColumnDeclaration> columns = select.Columns; var wasRetained = this.retainAllColumns; this.retainAllColumns = false; List <ColumnDeclaration> alternate = null; for (int i = 0, n = select.Columns.Count; i < n; i++) { ColumnDeclaration decl = select.Columns[i]; if (wasRetained || select.IsDistinct || IsColumnUsed(select.Alias, decl.Name)) { Expression expr = this.Visit(decl.Expression); if (expr != decl.Expression) { decl = new ColumnDeclaration(decl.Name, expr, decl.QueryType); } } else { decl = null; // null means it gets omitted } if (decl != select.Columns[i] && alternate == null) { alternate = new List <ColumnDeclaration>(); for (int j = 0; j < i; j++) { alternate.Add(select.Columns[j]); } } if (decl != null && alternate != null) { alternate.Add(decl); } } if (alternate != null) { columns = alternate.AsReadOnly(); } Expression take = this.Visit(select.Take); Expression skip = this.Visit(select.Skip); ReadOnlyCollection <Expression> groupbys = this.VisitExpressionList(select.GroupBy); ReadOnlyCollection <OrderExpression> orderbys = this.VisitOrderBy(select.OrderBy); Expression where = this.Visit(select.Where); Expression from = this.Visit(select.From); ClearColumnsUsed(select.Alias); if (columns != select.Columns || take != select.Take || skip != select.Skip || orderbys != select.OrderBy || groupbys != select.GroupBy || where != select.Where || from != select.From) { select = new SelectExpression(select.Alias, columns, from, where, orderbys, groupbys, select.IsDistinct, skip, take, select.IsReverse); } this.retainAllColumns = wasRetained; return(select); }
protected override Expression VisitSelect(SelectExpression select) { bool saveIsOuterMostSelect = this.isOuterMostSelect; try { this.isOuterMostSelect = false; select = (SelectExpression)base.VisitSelect(select); bool hasOrderBy = select.OrderBy != null && select.OrderBy.Count > 0; bool hasGroupBy = select.GroupBy != null && select.GroupBy.Count > 0; bool canHaveOrderBy = saveIsOuterMostSelect || select.Take != null || select.Skip != null; bool canReceiveOrderings = canHaveOrderBy && !hasGroupBy && !select.IsDistinct && !AggregateChecker.HasAggregates(select); if (hasOrderBy) { this.PrependOrderings(select.OrderBy); } if (select.IsReverse) { this.ReverseOrderings(); } IEnumerable <OrderExpression> orderings = null; if (canReceiveOrderings) { orderings = this.gatheredOrderings; } else if (canHaveOrderBy) { orderings = select.OrderBy; } bool canPassOnOrderings = !saveIsOuterMostSelect && !hasGroupBy && !select.IsDistinct; ReadOnlyCollection <ColumnDeclaration> columns = select.Columns; if (this.gatheredOrderings != null) { if (canPassOnOrderings) { var producedAliases = DeclaredAliasGatherer.Gather(select.From); // reproject order expressions using this select's alias so the outer select will have properly formed expressions BindResult project = this.RebindOrderings(this.gatheredOrderings, select.Alias, producedAliases, select.Columns); this.gatheredOrderings = null; this.PrependOrderings(project.Orderings); columns = project.Columns; } else { this.gatheredOrderings = null; } } if (orderings != select.OrderBy || columns != select.Columns || select.IsReverse) { select = new SelectExpression(select.Alias, columns, select.From, select.Where, orderings, select.GroupBy, select.IsDistinct, select.Skip, select.Take, false); } return(select); } finally { this.isOuterMostSelect = saveIsOuterMostSelect; } }