示例#1
0
        /// <summary>
        /// Visits the select.
        /// </summary>
        /// <param name="select">The select.</param>
        /// <returns></returns>
        protected override Expression VisitSelect(SelectExpression select)
        {
            select = (SelectExpression)base.VisitSelect(select);

            if (select.Skip != null && select.Take != null && select.OrderBy.Count > 0)
            {
                var skip         = select.Skip;
                var take         = select.Take;
                var skipPlusTake = PartialEvaluator.Eval(Expression.Add(skip, take));

                select = select.SetTake(skipPlusTake).SetSkip(null);
                select = select.AddRedundantSelect(this.language, new TableAlias());
                select = select.SetTake(take);

                // propagate order-bys to new layer
                select = (SelectExpression)OrderByRewriter.Rewrite(this.language, select);
                var inverted = select.OrderBy.Select(ob => new OrderExpression(ob.OrderType == OrderType.Ascending ? OrderType.Descending : OrderType.Ascending, ob.Expression));
                select = select.SetOrderBy(inverted);

                select = select.AddRedundantSelect(this.language, new TableAlias());
                select = select.SetTake(Expression.Constant(0)); // temporary
                select = (SelectExpression)OrderByRewriter.Rewrite(this.language, select);
                var reverted = select.OrderBy.Select(ob => new OrderExpression(ob.OrderType == OrderType.Ascending ? OrderType.Descending : OrderType.Ascending, ob.Expression));
                select = select.SetOrderBy(reverted);
                select = select.SetTake(null);
            }

            return(select);
        }
示例#2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="select"></param>
        /// <returns></returns>
        protected override Expression VisitSelect(SelectExpression select)
        {
            switch (_dataType)
            {
            case Nequeo.Data.DataType.ConnectionContext.ConnectionDataType.OracleDataType:
            case Nequeo.Data.DataType.ConnectionContext.ConnectionDataType.SqlDataType:

                select = (SelectExpression)base.VisitSelect(select);
                if (select.Skip != null)
                {
                    SelectExpression newSelect    = select.SetSkip(null).SetTake(null);
                    bool             canAddColumn = !select.IsDistinct && (select.GroupBy == null || select.GroupBy.Count == 0);
                    if (!canAddColumn)
                    {
                        newSelect = newSelect.AddRedundantSelect(new TableAlias());
                    }
                    newSelect = newSelect.AddColumn(new ColumnDeclaration("ROW_NUM", new RowNumberExpression(select.OrderBy)));

                    // add layer for WHERE clause that references new rownum column
                    newSelect = newSelect.AddRedundantSelect(new TableAlias());
                    newSelect = newSelect.RemoveColumn(newSelect.Columns[newSelect.Columns.Count - 1]);

                    var newAlias           = ((SelectExpression)newSelect.From).Alias;
                    ColumnExpression rnCol = new ColumnExpression(typeof(int), newAlias, "ROW_NUM");
                    Expression where;
                    if (select.Take != null)
                    {
                        where = new BetweenExpression(rnCol, Expression.Add(select.Skip, Expression.Constant(1)), Expression.Add(select.Skip, select.Take));
                    }
                    else
                    {
                        where = Expression.GreaterThan(rnCol, select.Skip);
                    }
                    if (newSelect.Where != null)
                    {
                        where = Expression.And(newSelect.Where, where);
                    }
                    newSelect = newSelect.SetWhere(where);

                    select = newSelect;
                }
                return(select);

            default:
                select = (SelectExpression)base.VisitSelect(select);
                if (select.Skip != null)
                {
                    SelectExpression newSelect = select.SetSkip(select.Skip).SetTake(select.Take);
                    select = newSelect;
                }
                return(select);
            }
        }
        protected override Expression VisitSelect(SelectExpression select)
        {
            select = (SelectExpression)base.VisitSelect(select);
            if (select.Skip != null)
            {
                SelectExpression newSelect    = select.SetSkip(null).SetTake(null);
                bool             canAddColumn = !select.IsDistinct && (select.GroupBy == null || select.GroupBy.Count == 0);
                if (!canAddColumn)
                {
                    newSelect = newSelect.AddRedundantSelect(new TableAlias());
                }

                newSelect = newSelect.AddColumn(new ColumnDeclaration(COLUMN_NAME, new RowNumberExpression(select.OrderBy)));

                // add layer for WHERE clause that references new rownum column
                newSelect = newSelect.AddRedundantSelect(new TableAlias());
                newSelect = newSelect.RemoveColumn(newSelect.Columns.Single(c => c.Name == COLUMN_NAME));

                var newAlias           = ((SelectExpression)newSelect.From).Alias;
                ColumnExpression rnCol = new ColumnExpression(typeof(int), newAlias, COLUMN_NAME, null);
                Expression where;

                if (select.Take != null)
                {
                    where = new BetweenExpression(rnCol, Expression.Add(select.Skip, Expression.Constant(1)), Expression.Add(select.Skip, select.Take));
                }
                else
                {
                    where = rnCol.GreaterThan(select.Skip);
                }

                if (newSelect.Where != null)
                {
                    where = newSelect.Where.And(where);
                }

                newSelect = newSelect.SetWhere(where);

                select = newSelect;
            }

            return(select);
        }
示例#4
0
        protected override Expression VisitSelect(SelectExpression select)
        {
            // select * from table order by x skip s take t
            // =>
            // select * from (select top s * from (select top s + t from table order by x) order by -x) order by x

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

            if (select.Skip != null && select.Take != null && select.OrderBy.Count > 0)
            {
                var skip         = select.Skip;
                var take         = select.Take;
                var skipPlusTake = PartialEvaluator.Eval(Expression.Add(skip, take));

                select = select.SetTake(skipPlusTake).SetSkip(null);
                select = select.AddRedundantSelect(new TableAlias());
                select = select.SetTake(take);

                // propogate order-bys to new layer
                select = (SelectExpression) new OrderByRewriter().Visit(select);

                var inverted = select.OrderBy.Select(ob => new OrderExpression(
                                                         ob.OrderType == OrderType.Ascending ? OrderType.Descending : OrderType.Ascending,
                                                         ob.Expression
                                                         ));

                select = select.SetOrderBy(inverted);

                select = select.AddRedundantSelect(new TableAlias());
                select = select.SetTake(Expression.Constant(0)); // temporary
                select = (SelectExpression) new OrderByRewriter().Visit(select);

                var reverted = select.OrderBy.Select(ob => new OrderExpression(
                                                         ob.OrderType == OrderType.Ascending ? OrderType.Descending : OrderType.Ascending,
                                                         ob.Expression
                                                         ));

                select = select.SetOrderBy(reverted);
                select = select.SetTake(null);
            }

            return(select);
        }
		protected override Expression VisitSelect(SelectExpression select)
		{
			// select * from table order by x skip s take t 
			// =>
			// select * from (select top s * from (select top s + t from table order by x) order by -x) order by x

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

			if (select.Skip != null && select.Take != null && select.OrderBy.Count > 0)
			{
				var skip = select.Skip;
				var take = select.Take;
				var skipPlusTake = PartialEvaluator.Eval(Expression.Add(skip, take));

				select = select.SetTake(skipPlusTake).SetSkip(null);
				select = select.AddRedundantSelect(new TableAlias());
				select = select.SetTake(take);

				// propogate order-bys to new layer
				select = (SelectExpression)OrderByRewriter.Rewrite(select);
				var inverted =
					select.OrderBy.Select(
						ob =>
						new OrderExpression(
							ob.OrderType == OrderType.Ascending ? OrderType.Descending : OrderType.Ascending, ob.Expression));
				select = select.SetOrderBy(inverted);

				select = select.AddRedundantSelect(new TableAlias());
				select = select.SetTake(Expression.Constant(0)); // temporary
				select = (SelectExpression)OrderByRewriter.Rewrite(select);
				var reverted =
					select.OrderBy.Select(
						ob =>
						new OrderExpression(
							ob.OrderType == OrderType.Ascending ? OrderType.Descending : OrderType.Ascending, ob.Expression));
				select = select.SetOrderBy(reverted);
				select = select.SetTake(null);
			}

			return select;
		}
        protected override Expression VisitProjection(ProjectionExpression proj)
        {
            if (isTopLevel)
            {
                isTopLevel    = false;
                currentSelect = proj.Select;
                var projector = Visit(proj.Projector);

                if (projector != proj.Projector || currentSelect != proj.Select)
                {
                    return(new ProjectionExpression(currentSelect, projector, proj.Aggregator, proj.IsAsync));
                }

                return(proj);
            }

            if (proj.IsSingleton && CanJoinOnServer(currentSelect))
            {
                var newAlias = new TableAlias();
                currentSelect = currentSelect.AddRedundantSelect(newAlias);
                var source = (SelectExpression)ColumnMapper.Map(proj.Select, newAlias, currentSelect.Alias);
                var pex    = new ProjectionExpression(source, proj.Projector, proj.IsAsync).AddOuterJoinTest();
                var pc     = ColumnProjector.ProjectColumns(QueryUtility.CanBeColumnExpression, pex.Projector, currentSelect.Columns, currentSelect.Alias, newAlias, proj.Select.Alias);

                // **fix** 解决返回关联对象后使用Distinct的问题
                var join = CreateJoinExpression(currentSelect.From, pex.Select, out bool isDistinct);
                currentSelect = new SelectExpression(currentSelect.Alias, pc.Columns, join, null);
                if (isDistinct)
                {
                    var newPc = ColumnProjector.ProjectColumns(QueryUtility.CanBeColumnExpression, proj.Projector, null, currentSelect.Alias, proj.Select.Alias);
                    currentSelect = new SelectExpression(currentSelect.Alias, newPc.Columns, currentSelect, null, null, null, isDistinct, null, null, null, null, false);
                    return(Visit(newPc.Projector));
                }

                return(Visit(pc.Projector));
            }

            var saveTop    = isTopLevel;
            var saveSelect = currentSelect;

            isTopLevel    = true;
            currentSelect = null;

            var result = base.VisitProjection(proj);

            isTopLevel    = saveTop;
            currentSelect = saveSelect;

            return(result);
        }
示例#7
0
        protected override Expression VisitProjection(ProjectionExpression proj)
        {
            if (isTopLevel)
            {
                isTopLevel    = false;
                currentSelect = proj.Source;
                Expression projector = Visit(proj.Projector);
                if (projector != proj.Projector || currentSelect != proj.Source)
                {
                    return(new ProjectionExpression(currentSelect, projector, proj.Aggregator));
                }
                return(proj);
            }

            if (proj.IsSingleton && CanJoinOnServer(currentSelect))
            {
                TableAlias newAlias = new TableAlias();
                currentSelect = currentSelect.AddRedundantSelect(newAlias);

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

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

                var pc = ColumnProjector.ProjectColumns(language.CanBeColumn, pex.Projector, currentSelect.Columns,
                                                        currentSelect.Alias, newAlias, proj.Source.Alias);

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

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

            var saveTop    = isTopLevel;
            var saveSelect = currentSelect;

            isTopLevel    = true;
            currentSelect = null;
            Expression result = base.VisitProjection(proj);

            isTopLevel    = saveTop;
            currentSelect = saveSelect;
            return(result);
        }