returns the set of all aliases produced by a query source
Inheritance: DbExpressionVisitor
Example #1
0
        protected override Expression VisitSelect(SelectExpression select)
        {
            bool saveIsOuterMostSelect = this.isOuterMostSelect;

            try
            {
                this.isOuterMostSelect = false;

                var saveSuppressOrderBy = this.suppressOrderby;
                this.suppressOrderby = false;

                var saveGatheredOrderings = this.gatheredOrderings;
                if (saveSuppressOrderBy)
                {
                    this.gatheredOrderings = null;
                    this.isOuterMostSelect = true;
                }

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

                this.suppressOrderby = saveSuppressOrderBy;
                if (saveSuppressOrderBy)
                {
                    this.gatheredOrderings = saveGatheredOrderings;
                }

                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) && !suppressOrderby;

                if (hasOrderBy)
                {
                    this.PrependOrderings(select.OrderBy);
                }

                if (select.IsReverse)
                {
                    if (this.gatheredOrderings == null || gatheredOrderings.Count == 0)
                    {
                        throw new NotSupportedException(string.Format(Res.OperationNotSupported, "", "Reverse", "if no 'OrderBy' expression."));
                    }

                    for (int i = 0, n = this.gatheredOrderings.Count; i < n; i++)
                    {
                        var ord = this.gatheredOrderings[i];
                        this.gatheredOrderings[i] =
                            new OrderExpression(
                                ord.OrderType == OrderType.Ascending ? OrderType.Descending : OrderType.Ascending,
                                ord.Expression
                                );
                    }
                }

                IEnumerable <OrderExpression> orderings = null;
                if (canReceiveOrderings)
                {
                    orderings = this.gatheredOrderings;
                }
                else if (canHaveOrderBy)
                {
                    orderings = select.OrderBy;
                }

                bool canPassOnOrderings = !saveIsOuterMostSelect && !hasGroupBy && !select.IsDistinct && !suppressOrderby;
                ReadOnlyCollection <ColumnDeclaration> columns = select.Columns;
                if (this.gatheredOrderings != null)
                {
                    if (canPassOnOrderings)
                    {
                        var producedAliases = TableAliasGatherer.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;
            }
        }
Example #2
0
 public static HashSet<TableAlias> Gather(Expression source)
 {
     var gatherer = new TableAliasGatherer();
     gatherer.Visit(source);
     return gatherer.aliases;
 }