internal static HashSet <string> Gather(Expression source, TextWriter logger) { AliasesProduced produced = new AliasesProduced(logger); produced.Visit(source); return(produced.aliases); }
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; if (hasOrderBy) { this.PrependOrderings(select.OrderBy); } bool canHaveOrderBy = saveIsOuterMostSelect; bool canPassOnOrderings = !saveIsOuterMostSelect && (select.GroupBy == null || select.GroupBy.Count == 0); IEnumerable <OrderExpression> orderings = (canHaveOrderBy) ? this.gatheredOrderings : null; ReadOnlyCollection <ColumnDeclaration> columns = select.Columns; if (this.gatheredOrderings != null) { if (canPassOnOrderings) { HashSet <string> producedAliases = AliasesProduced.Gather(select.From, Logger); // 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 = project.Orderings; columns = project.Columns; } else { this.gatheredOrderings = null; } } if (orderings != select.OrderBy || columns != select.Columns) { select = new SelectExpression(select.Type, select.Alias, columns, select.From, select.Where, orderings, select.GroupBy); } return(select); } finally { this.isOuterMostSelect = saveIsOuterMostSelect; } }