/// <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); }
/// <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); }
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); }
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); }