示例#1
0
        internal override SqlRowNumber VisitRowNumber(SqlRowNumber rowNumber)
        {
            if (rowNumber.OrderBy.Count > 0)
            {
                return(rowNumber);
            }

            SqlDuplicator             dup            = new SqlDuplicator(true);
            List <SqlOrderExpression> orderBy        = new List <SqlOrderExpression>();
            List <SqlOrderExpression> existingOrders = new List <SqlOrderExpression>();

            if (this.rowNumberOrders != null && this.rowNumberOrders.Count != 0)
            {
                existingOrders = new List <SqlOrderExpression>(this.rowNumberOrders);
            }
            else if (this.orders != null)
            {
                existingOrders = new List <SqlOrderExpression>(this.orders);
            }

            foreach (SqlOrderExpression expr in existingOrders)
            {
                if (!expr.Expression.IsConstantColumn)
                {
                    orderBy.Add(expr);
                    if (this.rowNumberOrders != null)
                    {
                        this.rowNumberOrders.Remove(expr);
                    }
                    if (this.orders != null)
                    {
                        this.orders.Remove(expr);
                    }
                }
            }

            rowNumber.OrderBy.Clear();

            if (orderBy.Count == 0)
            {
                List <SqlColumn> columns = SqlGatherColumnsProduced.GatherColumns(this.currentSelect.From);

                foreach (SqlColumn col in columns)
                {
                    if (col.Expression.SqlType.IsOrderable)
                    {
                        orderBy.Add(new SqlOrderExpression(SqlOrderType.Ascending, new SqlColumnRef(col)));
                    }
                }

                if (orderBy.Count == 0)
                {
                    // insert simple column
                    SqlColumn col =
                        new SqlColumn(
                            "rowNumberOrder",
                            sql.Value(typeof(int), this.typeProvider.From(typeof(int)), 1, false, rowNumber.SourceExpression)
                            );
                    this.PushDown(col);
                    orderBy.Add(new SqlOrderExpression(SqlOrderType.Ascending, new SqlColumnRef(col)));
                }
            }

            foreach (SqlOrderExpression sox in orderBy)
            {
                rowNumber.OrderBy.Add(new SqlOrderExpression(sox.OrderType, (SqlExpression)dup.Duplicate(sox.Expression)));
            }

            return(rowNumber);
        }
示例#2
0
        internal override SqlSelect VisitSelect(SqlSelect select)
        {
            bool saveTop = this.topSelect;
            bool savePK  = this.addPrimaryKeys;

            SqlSelect saveSelect = this.currentSelect;

            this.currentSelect = select;

            if (select.OrderingType == SqlOrderingType.Always)
            {
                this.addPrimaryKeys = true;
            }

            this.topSelect = false;

            // can't forward ordering information through a group-by
            if (select.GroupBy.Count > 0)
            {
                this.Visit(select.From);
                this.orders = null;
            }
            else
            {
                this.Visit(select.From);
            }

            if (select.OrderBy.Count > 0)
            {
                this.PrependOrderExpressions(select.OrderBy);
            }

            List <SqlOrderExpression> save = this.orders;

            this.orders          = null;
            this.rowNumberOrders = save;             // lest orders be null when we need info

            /* do all the lower level stuff */
            select.Where = this.VisitExpression(select.Where);
            for (int i = 0, n = select.GroupBy.Count; i < n; i++)
            {
                select.GroupBy[i] = this.VisitExpression(select.GroupBy[i]);
            }
            select.Having = this.VisitExpression(select.Having);
            for (int i = 0, n = select.OrderBy.Count; i < n; i++)
            {
                select.OrderBy[i].Expression = this.VisitExpression(select.OrderBy[i].Expression);
            }
            select.Top       = this.VisitExpression(select.Top);
            select.Selection = this.VisitExpression(select.Selection);
            select.Row       = (SqlRow)this.Visit(select.Row);

            this.topSelect      = saveTop;
            this.addPrimaryKeys = savePK;

            this.orders = save;

            // all ordering is blocked for this layer and above
            if (select.OrderingType == SqlOrderingType.Blocked)
            {
                this.orders = null;
            }

            // rebuild orderby expressions, provided this select doesn't contain a SqlRowNumber
            // otherwise, replace the orderby with a reference to that column
            select.OrderBy.Clear();
            var rowNumberChecker = new SqlRowNumberChecker();

            if (rowNumberChecker.HasRowNumber(select) && rowNumberChecker.RowNumberColumn != null)
            {
                select.Row.Columns.Remove(rowNumberChecker.RowNumberColumn);
                this.PushDown(rowNumberChecker.RowNumberColumn);
                this.Orders.Add(new SqlOrderExpression(SqlOrderType.Ascending, new SqlColumnRef(rowNumberChecker.RowNumberColumn)));
            }
            if ((this.topSelect || select.Top != null) && select.OrderingType != SqlOrderingType.Never && this.orders != null)
            {
                this.orders = new HashSet <SqlOrderExpression>(this.orders).ToList();
                SqlDuplicator dup = new SqlDuplicator(true);
                foreach (SqlOrderExpression sox in this.orders)
                {
                    select.OrderBy.Add(new SqlOrderExpression(sox.OrderType, (SqlExpression)dup.Duplicate(sox.Expression)));
                }
            }
            this.currentSelect = saveSelect;

            return(select);
        }