internal LinkOptimizationScope(LinkOptimizationScope previous) { this.previous = previous; }
internal override SqlSelect VisitSelect(SqlSelect select) { LinkOptimizationScope saveScope = this.linkMap; SqlSelect saveSelect = this.currentSelect; bool saveInGroupBy = inGroupBy; inGroupBy = false; try { // don't preserve any link optimizations across a group or distinct boundary bool linkOptimize = true; if (this.binder.optimizeLinkExpansions && (select.GroupBy.Count > 0 || this.aggregateChecker.HasAggregates(select) || select.IsDistinct)) { linkOptimize = false; this.linkMap = new LinkOptimizationScope(this.linkMap); } select.From = this.VisitSource(select.From); this.currentSelect = select; select.Where = this.VisitExpression(select.Where); this.inGroupBy = true; for (int i = 0, n = select.GroupBy.Count; i < n; i++) { select.GroupBy[i] = this.VisitExpression(select.GroupBy[i]); } this.inGroupBy = false; 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.Row = (SqlRow)this.Visit(select.Row); select.Selection = this.VisitExpression(select.Selection); select.Selection = this.columnizer.ColumnizeSelection(select.Selection); if (linkOptimize) { select.Selection = ConvertLinks(select.Selection); } // optimize out where clause for WHERE TRUE if (select.Where != null && select.Where.NodeType == SqlNodeType.Value && (bool)((SqlValue)select.Where).Value) { select.Where = null; } } finally { this.currentSelect = saveSelect; this.linkMap = saveScope; this.inGroupBy = saveInGroupBy; } return select; }
internal override SqlExpression VisitSubSelect(SqlSubSelect ss) { // don't preserve any link optimizations across sub-queries LinkOptimizationScope saveScope = this.linkMap; SqlSelect saveSelect = this.currentSelect; try { this.linkMap = new LinkOptimizationScope(this.linkMap); this.currentSelect = null; return base.VisitSubSelect(ss); } finally { this.linkMap = saveScope; this.currentSelect = saveSelect; } }
internal Visitor(SqlBinder binder, Translator translator, SqlColumnizer columnizer, SqlFactory sqlFactory, MetaModel model, DataLoadOptions shape, bool canUseOuterApply) { this.binder = binder; this.translator = translator; this.columnizer = columnizer; this.sql = sqlFactory; this.typeProvider = sqlFactory.TypeProvider; this.expander = new SqlExpander(this.sql); this.aggregateChecker = new SqlAggregateChecker(); this.linkMap = new LinkOptimizationScope(null); this.outerAliasMap = new Dictionary<SqlAlias, SqlAlias>(); this.model = model; this.shape = shape; this.canUseOuterApply = canUseOuterApply; }