protected virtual void MapAliases(SourceExpression sourceA, SourceExpression sourceB) { for (int i = 0, n = sourceA.KnownAliases.Length; i < n; i++) { aliasMap !.Add(sourceA.KnownAliases[i], sourceB.KnownAliases[i]); } }
protected internal override Expression VisitSelect(SelectExpression select) { // visit column projection first HashSet <string> columnsUsed = allColumnsUsed.GetOrCreate(select.Alias); // a veces no se usa ReadOnlyCollection <ColumnDeclaration> columns = select.Columns.Select(c => { if (select.IsDistinct ? IsConstant(c.Expression) : !columnsUsed.Contains(c.Name)) { return(null); } var ex = Visit(c.Expression); return(ex == c.Expression ? c : new ColumnDeclaration(c.Name, ex)); }).NotNull().ToReadOnly(); ReadOnlyCollection <OrderExpression> orderbys = Visit(select.OrderBy, VisitOrderBy); Expression where = this.Visit(select.Where); ReadOnlyCollection <Expression> groupBy = select.GroupBy.Select(e => IsConstant(e) ? null : Visit(e)).NotNull().ToReadOnly(); SourceExpression from = this.VisitSource(select.From); if (columns != select.Columns || orderbys != select.OrderBy || where != select.Where || from != select.From || groupBy != select.GroupBy) { return(new SelectExpression(select.Alias, select.IsDistinct, select.Top, columns, from, where, orderbys, groupBy, select.SelectOptions)); } return(select); }
protected internal override Expression VisitSelect(SelectExpression select) { var saveFrom = this.currentFrom; var saveInAggregate = this.inAggregate; this.inAggregate = false; SourceExpression from = this.VisitSource(select.From); this.currentFrom = from; Expression top = this.Visit(select.Top); Expression where = this.Visit(select.Where); ReadOnlyCollection <ColumnDeclaration> columns = Visit(select.Columns, VisitColumnDeclaration); ReadOnlyCollection <OrderExpression> orderBy = Visit(select.OrderBy, VisitOrderBy); ReadOnlyCollection <Expression> groupBy = Visit(select.GroupBy, Visit); from = this.currentFrom; this.inAggregate = saveInAggregate; this.currentFrom = saveFrom; if (top != select.Top || from != select.From || where != select.Where || columns != select.Columns || orderBy != select.OrderBy || groupBy != select.GroupBy) { return(new SelectExpression(select.Alias, select.IsDistinct, top, columns, from, where, orderBy, groupBy, select.SelectOptions)); } return(select); }
protected internal override SourceExpression VisitSource(SourceExpression source) { if (source is SourceWithAliasExpression) { if (source is TableExpression || source is SqlTableValuedFunctionExpression) { Visit(source); } else { sb.Append("("); Visit(source); sb.Append(")"); } sb.Append(" AS "); sb.Append(((SourceWithAliasExpression)source).Alias.ToString()); if (source is TableExpression ta && ta.WithHint != null) { sb.Append(" WITH(" + ta.WithHint + ")"); } } else { this.VisitJoin((JoinExpression)source); } return(source); }
static bool HasApplyJoin(SourceExpression source) { if (source is not JoinExpression join) { return(false); } return(join.JoinType == JoinType.CrossApply || join.JoinType == JoinType.OuterApply || HasApplyJoin(join.Left) || HasApplyJoin(join.Right)); }
protected internal override Expression VisitSelect(SelectExpression select) { Dictionary <ColumnExpression, ColumnExpression> askedColumns = CurrentScope.Keys.Where(k => select.KnownAliases.Contains(k.Alias)).ToDictionary(k => k, k => (ColumnExpression)null); Dictionary <ColumnExpression, ColumnExpression> externalAnswers = CurrentScope.Where(kvp => !select.KnownAliases.Contains(kvp.Key.Alias) && kvp.Value != null).ToDictionary(); var disposable = NewScope();//SCOPE START var scope = CurrentScope; scope.AddRange(askedColumns.Where(kvp => kvp.Key.Alias != select.Alias).ToDictionary()); scope.AddRange(externalAnswers); var col = GetColumnCollector(select.KnownAliases); col.Visit(select.Top); col.Visit(select.Where); foreach (var cd in select.Columns) { col.Visit(cd.Expression); } foreach (var oe in select.OrderBy) { col.Visit(oe.Expression); } foreach (var e in select.GroupBy) { col.Visit(e); } SourceExpression from = this.VisitSource(select.From); Expression top = this.Visit(select.Top); Expression where = this.Visit(select.Where); ReadOnlyCollection <OrderExpression> orderBy = Visit(select.OrderBy, VisitOrderBy); if (orderBy.HasItems()) { orderBy = RemoveDuplicates(orderBy); } ReadOnlyCollection <Expression> groupBy = Visit(select.GroupBy, Visit); ReadOnlyCollection <ColumnDeclaration> columns = Visit(select.Columns, VisitColumnDeclaration);; columns = AnswerAndExpand(columns, select.Alias, askedColumns); var externals = CurrentScope.Where(kvp => !select.KnownAliases.Contains(kvp.Key.Alias) && kvp.Value == null).ToDictionary(); disposable.Dispose(); ////SCOPE END CurrentScope.SetRange(externals); CurrentScope.SetRange(askedColumns); if (top != select.Top || from != select.From || where != select.Where || columns != select.Columns || orderBy != select.OrderBy || groupBy != select.GroupBy) { return(new SelectExpression(select.Alias, select.IsDistinct, top, columns, from, where, orderBy, groupBy, select.SelectOptions)); } return(select); }
static bool HasApplyJoin(SourceExpression source) { var join = source as JoinExpression; if (join == null) { return(false); } return(join.JoinType == JoinType.CrossApply || join.JoinType == JoinType.OuterApply || HasApplyJoin(join.Left) || HasApplyJoin(join.Right)); }
protected internal virtual Expression VisitJoin(JoinExpression join) { SourceExpression left = this.VisitSource(join.Left); SourceExpression right = this.VisitSource(join.Right); Expression condition = this.Visit(join.Condition); if (left != join.Left || right != join.Right || condition != join.Condition) { return(new JoinExpression(join.JoinType, left, right, condition)); } return(join); }
internal SelectExpression(Alias alias, bool distinct, Expression top, IEnumerable <ColumnDeclaration> columns, SourceExpression from, Expression where, IEnumerable <OrderExpression> orderBy, IEnumerable <Expression> groupBy, SelectOptions options) : base(DbExpressionType.Select, alias) { this.IsDistinct = distinct; this.SelectOptions = options; this.Top = top; this.Columns = columns.ToReadOnly(); this.From = from; this.Where = where; this.OrderBy = orderBy.ToReadOnly(); this.GroupBy = groupBy.ToReadOnly(); this.knownAliases = from == null ? new[] { alias } : from.KnownAliases.And(alias).ToArray(); }
internal JoinExpression(JoinType joinType, SourceExpression left, SourceExpression right, Expression condition) : base(DbExpressionType.Join) { if (condition == null && joinType != JoinType.CrossApply && joinType != JoinType.OuterApply && joinType != JoinType.CrossJoin) { throw new ArgumentNullException("condition"); } this.JoinType = joinType; this.Left = left ?? throw new ArgumentNullException("left"); this.Right = right ?? throw new ArgumentNullException("right"); this.Condition = condition; }
protected internal virtual Expression VisitSelect(SelectExpression select) { Expression top = this.Visit(select.Top); SourceExpression from = this.VisitSource(select.From !); Expression where = this.Visit(select.Where); ReadOnlyCollection <ColumnDeclaration> columns = Visit(select.Columns, VisitColumnDeclaration); ReadOnlyCollection <OrderExpression> orderBy = Visit(select.OrderBy, VisitOrderBy); ReadOnlyCollection <Expression> groupBy = Visit(select.GroupBy, Visit); if (top != select.Top || from != select.From || where != select.Where || columns != select.Columns || orderBy != select.OrderBy || groupBy != select.GroupBy) { return(new SelectExpression(select.Alias, select.IsDistinct, top, columns, from, where, orderBy, groupBy, select.SelectOptions)); } return(select); }
protected internal override Expression VisitJoin(JoinExpression join) { this.Visit(join.Condition); if (join.JoinType == JoinType.CrossApply || join.JoinType == JoinType.OuterApply) { this.VisitSource(join.Right); } SourceExpression left = this.VisitSource(join.Left); SourceExpression right = this.VisitSource(join.Right); Expression? condition = this.Visit(join.Condition); if (left != join.Left || right != join.Right || condition != join.Condition) { return(new JoinExpression(join.JoinType, left, right, condition)); } return(join); }
protected internal override Expression VisitScalar(ScalarExpression scalar) { if (connector.SupportsScalarSubquery && (!inAggregate || connector.SupportsScalarSubqueryInAggregates)) { return(base.VisitScalar(scalar)); } else { var select = scalar.Select; if (string.IsNullOrEmpty(select.Columns[0].Name)) { select = new SelectExpression(select.Alias, select.IsDistinct, select.Top, new[] { new ColumnDeclaration("scalar", select.Columns[0].Expression) }, select.From, select.Where, select.OrderBy, select.GroupBy, select.SelectOptions); } this.currentFrom = new JoinExpression(JoinType.OuterApply, this.currentFrom, select, null); return(new ColumnExpression(scalar.Type, scalar.Select.Alias, select.Columns[0].Name)); } }
protected internal override Expression VisitJoin(JoinExpression join) { SourceExpression left = this.VisitSource(join.Left); ReadOnlyCollection <OrderExpression> leftOrders = this.gatheredOrderings; this.gatheredOrderings = null; SourceExpression right = join.Right is TableExpression ? join.Right : this.VisitSource(join.Right); this.PrependOrderings(leftOrders); Expression condition = this.Visit(join.Condition); if (left != join.Left || right != join.Right || condition != join.Condition) { return(new JoinExpression(join.JoinType, left, right, condition)); } return(join); }
protected internal override Expression VisitJoin(JoinExpression join) { if (join.Condition != null) { this.Visit(join.Condition); } else { this.VisitSource(join.Right); } SourceExpression left = this.VisitSource(join.Left); SourceExpression right = this.VisitSource(join.Right); Expression condition = this.Visit(join.Condition); if (left != join.Left || right != join.Right || condition != join.Condition) { return(new JoinExpression(join.JoinType, left, right, condition)); } return(join); }
protected internal override Expression VisitJoin(JoinExpression join) { if (join.Condition != null) { GetColumnCollector(join.KnownAliases).Visit(join.Condition); } else if (join.JoinType == JoinType.CrossApply || join.JoinType == JoinType.OuterApply) { GetColumnCollector(join.Left.KnownAliases).Visit(join.Right); } SourceExpression left = this.VisitSource(join.Left); SourceExpression right = this.VisitSource(join.Right); Expression condition = this.Visit(join.Condition); if (left != join.Left || right != join.Right || condition != join.Condition) { return(new JoinExpression(join.JoinType, left, right, condition)); } return(join); }
public static IEnumerable <ColumnExpression> Keys(SourceExpression source) { if (source is SelectExpression) { return(KeysSelect((SelectExpression)source)); } if (source is TableExpression) { return(KeysTable((TableExpression)source)); } if (source is JoinExpression) { return(KeysJoin((JoinExpression)source)); } if (source is SetOperatorExpression) { return(KeysSet((SetOperatorExpression)source)); } throw new InvalidOperationException("Unexpected source"); }
protected internal override Expression VisitJoin(JoinExpression join) { if (join.JoinType == JoinType.SingleRowLeftOuterJoin) { var source = join.Right as SourceWithAliasExpression; var hs = allColumnsUsed.TryGetC(source.Alias); if (hs == null || hs.Count == 0) { return(Visit(join.Left)); } } if (join.JoinType == JoinType.OuterApply || join.JoinType == JoinType.LeftOuterJoin) { var sql = join.Right as SelectExpression; if (sql != null && sql.IsOneRow()) { var hs = allColumnsUsed.TryGetC(sql.Alias); if (hs == null || hs.Count == 0) { return(Visit(join.Left)); } } } // visit join in reverse order Expression condition = this.Visit(join.Condition); SourceExpression right = this.VisitSource(join.Right); SourceExpression left = this.VisitSource(join.Left); if (left != join.Left || right != join.Right || condition != join.Condition) { return(new JoinExpression(join.JoinType, left, right, condition)); } return(join); }
protected internal override Expression VisitSelect(SelectExpression select) { //if (select.SelectRoles == SelectRoles.Where && select.From is TableExpression table && table.SystemTime != null && !(table.SystemTime is SystemTime.HistoryTable)) //{ // var current = (SelectExpression)AliasReplacer.Replace(select, this.aliasGenerator); // var history = (SelectExpression)AliasReplacer.Replace(select, this.aliasGenerator); // var newAlias = aliasGenerator.NextSelectAlias(); // if (columnReplacements.ContainsKey(select.Alias)) // throw new InvalidOperationException("Requests to trivial select (only where) not expected"); // var requests = columnReplacements.TryGetC(table.Alias).EmptyIfNull().Select(ce => new ColumnDeclaration(ce.Key, )); // return new SetOperatorExpression(SetOperator.UnionAll, current, history, table.Alias); //} //else //{ this.Visit(select.Top); this.Visit(select.Where); Visit(select.Columns, VisitColumnDeclaration); Visit(select.OrderBy, VisitOrderBy); Visit(select.GroupBy, Visit); SourceExpression from = this.VisitSource(select.From !); Expression? top = this.Visit(select.Top); Expression? where = this.Visit(select.Where); ReadOnlyCollection <ColumnDeclaration> columns = Visit(select.Columns, VisitColumnDeclaration); ReadOnlyCollection <OrderExpression> orderBy = Visit(select.OrderBy, VisitOrderBy); ReadOnlyCollection <Expression> groupBy = Visit(select.GroupBy, Visit); if (top != select.Top || from != select.From || where != select.Where || columns != select.Columns || orderBy != select.OrderBy || groupBy != select.GroupBy) { return(new SelectExpression(select.Alias, select.IsDistinct, top, columns, from, where, orderBy, groupBy, select.SelectOptions)); } return(select); //} }
protected internal override Expression VisitJoin(JoinExpression join) { SourceExpression left = this.VisitSource(join.Left); SourceExpression right = this.VisitSource(join.Right); Expression? condition = this.Visit(join.Condition); if (join.JoinType == JoinType.CrossApply || join.JoinType == JoinType.OuterApply) { if (right is TableExpression) { return(new JoinExpression(join.JoinType == JoinType.OuterApply ? JoinType.LeftOuterJoin : JoinType.InnerJoin, left, right, Schema.Current.Settings.IsPostgres ? (Expression) new SqlConstantExpression(true) : Expression.Equal(new SqlConstantExpression(1), new SqlConstantExpression(1)))); } } if (left != join.Left || right != join.Right || condition != join.Condition) { return(new JoinExpression(join.JoinType, left, right, condition)); } return(join); }
protected internal virtual SourceExpression VisitSource(SourceExpression source) { return((SourceExpression)this.Visit(source)); }