protected override Expression VisitProjection(ProjectionExpression proj) { using (Scope()) { var oldOuterMostSelect = outerMostSelect; outerMostSelect = proj.Select; var oldHasProjectionInProjector = hasProjectionInProjector; hasProjectionInProjector = false; Expression projector = this.Visit(proj.Projector); SelectExpression source = (SelectExpression)this.Visit(proj.Select); hasProjectionInProjector = oldHasProjectionInProjector; hasProjectionInProjector |= true; outerMostSelect = oldOuterMostSelect; if (source != proj.Select || projector != proj.Projector) return new ProjectionExpression(source, projector, proj.UniqueFunction, proj.Type); return proj; } }
protected 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 = select.Columns.NewIfChange(VisitColumnDeclaration); ReadOnlyCollection<OrderExpression> orderBy = select.OrderBy.NewIfChange(VisitOrderBy); ReadOnlyCollection<Expression> groupBy = select.GroupBy.NewIfChange(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 override Expression VisitSelect(SelectExpression select) { select = (SelectExpression)base.VisitSelect(select); if (lookup.Contains(select.Alias)) { List<ColumnDeclaration> aggColumns = new List<ColumnDeclaration>(select.Columns); foreach (AggregateSubqueryExpression ae in lookup[select.Alias]) { string name = "agg" + aggColumns.Count; var colType = DbTypeSystem.GetColumnType(ae.Type); ColumnDeclaration cd = new ColumnDeclaration(name, ae.AggregateInGroupSelect, colType); this.map.Add(ae, new ColumnExpression(ae.Type, colType, ae.GroupByAlias, name)); aggColumns.Add(cd); } return new SelectExpression( select.Alias, aggColumns, select.From, select.Where, select.OrderBy, select.GroupBy, select.IsDistinct, select.Skip, select.Take, select.IsReverse); } return select; }
protected override Expression VisitSelect(SelectExpression select) { TableAlias newAlias = new TableAlias(); this.map[select.Alias] = newAlias; select = (SelectExpression)base.VisitSelect(select); return new SelectExpression(newAlias, select.Columns, select.From, select.Where, select.OrderBy, select.GroupBy, select.IsDistinct, select.Skip, select.Take, select.IsReverse); }
protected override Expression VisitSelect(SelectExpression select) { Expression saveCurrentFrom = this.currentFrom; this.currentFrom = this.VisitSource(select.From); try { Expression where = this.Visit(select.Where); ReadOnlyCollection<OrderExpression> orderBy = this.VisitOrderBy(select.OrderBy); ReadOnlyCollection<Expression> groupBy = this.VisitExpressionList(select.GroupBy); Expression skip = this.Visit(select.Skip); Expression take = this.Visit(select.Take); ReadOnlyCollection<ColumnDeclaration> columns = this.VisitColumnDeclarations(select.Columns); if (this.currentFrom != select.From || where != select.Where || orderBy != select.OrderBy || groupBy != select.GroupBy || take != select.Take || skip != select.Skip || columns != select.Columns ) { return new SelectExpression(select.Alias, columns, this.currentFrom, where, orderBy, groupBy, select.IsDistinct, skip, take, select.IsReverse); } return select; } finally { this.currentFrom = saveCurrentFrom; } }
protected override Expression VisitSelect(SelectExpression select) { if (this.selectsToRemove.Contains(select)) return this.Visit(select.From); else return base.VisitSelect(select); }
protected override Expression VisitIn(InExpression expression) { if (!ShouldRewrite(expression)) { return base.VisitIn(expression); } Array array = expression.Values.OfType<ConstantExpression>().Select(item => item.Value).Distinct().ToArray(); var vfpDataXml = new ArrayXmlToCursor(array); var tableAlias = new TableAlias(); var columnType = _language.TypeSystem.GetColumnType(vfpDataXml.ItemType); var columnExpression = new ColumnExpression(vfpDataXml.ItemType, columnType, tableAlias, ArrayXmlToCursor.ColumnName); var columns = new List<ColumnDeclaration> { new ColumnDeclaration(string.Empty, columnExpression, columnType) }; var xml = Expression.Constant(vfpDataXml.Xml); var cursorName = Expression.Constant("curTemp_" + DateTime.Now.ToString("ddHHssmm")); var check = Expression.GreaterThan(new XmlToCursorExpression(xml, cursorName), Expression.Constant(0)); var from = Expression.Condition(check, cursorName, Expression.Constant(string.Empty)); var select = new SelectExpression(tableAlias, columns, from, null); return new InExpression(expression.Expression, select); }
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; }
public static Expression GetOuterJoinTest(SelectExpression select) { // if the column is used in the join condition (equality test) // if it is null in the database then the join test won't match (null != null) so the row won't appear // we can safely use this existing column as our test to determine if the outer join produced a row // find a column that is used in equality test var aliases = DeclaredAliasGatherer.Gather(select.From); var joinColumns = JoinColumnGatherer.Gather(aliases, select).ToList(); if (joinColumns.Count > 0) { // prefer one that is already in the projection list. foreach (var jc in joinColumns) { foreach (var col in select.Columns) { if (jc.Equals(col.Expression)) { return jc; } } } return joinColumns[0]; } // fall back to introducing a constant return Expression.Constant(1, typeof(int?)); }
protected override Expression VisitSelect(SelectExpression select) { if (first) { first = false; return base.VisitSelect(select); } return select; }
protected override Expression VisitSelect(SelectExpression select) { // only consider aggregates in these locations this.Visit(select.Where); this.VisitOrderBy(select.OrderBy); this.VisitColumnDeclarations(select.Columns); return select; }
protected DeclarationCommand UpdateDeclaration(DeclarationCommand decl, IEnumerable<VariableDeclaration> variables, SelectExpression source) { if (variables != decl.Variables || source != decl.Source) { return new DeclarationCommand(variables, source); } return decl; }
protected override Expression VisitSelect(SelectExpression select) { bool saveIsOuterMostSelect = this.isOuterMostSelect; try { this.isOuterMostSelect = false; select = (SelectExpression)base.VisitSelect(select); bool hasOrderBy = select.OrderBy != null && select.OrderBy.Count > 0; bool hasGroupBy = select.GroupBy != null && select.GroupBy.Count > 0; bool canHaveOrderBy = saveIsOuterMostSelect || select.Take != null || select.Skip != null; bool canReceiveOrderings = canHaveOrderBy && !hasGroupBy && !select.IsDistinct; if (hasOrderBy) { this.PrependOrderings(select.OrderBy); } IEnumerable<OrderExpression> orderings = null; if (canReceiveOrderings) { orderings = this.gatheredOrderings; } else if (canHaveOrderBy) { orderings = select.OrderBy; } bool canPassOnOrderings = !saveIsOuterMostSelect && !hasGroupBy && !select.IsDistinct; ReadOnlyCollection<ColumnDeclaration> columns = select.Columns; if (this.gatheredOrderings != null) { if (canPassOnOrderings) { var producedAliases = DeclaredAliasGatherer.Gather(select.From); // reproject order expressions using this select's alias so the outer select will have properly formed expressions BindResult project = this.RebindOrderings(this.gatheredOrderings, select.Alias, producedAliases, select.Columns); this.gatheredOrderings = null; this.PrependOrderings(project.Orderings); columns = project.Columns; } else { this.gatheredOrderings = null; } } if (orderings != select.OrderBy || columns != select.Columns) { select = new SelectExpression(select.Alias, columns, select.From, select.Where, orderings, select.GroupBy, select.IsDistinct, select.Skip, select.Take); } return select; } finally { this.isOuterMostSelect = saveIsOuterMostSelect; } }
public static SelectExpression AddRedundantSelect(this SelectExpression sel, QueryLanguage language, TableAlias newAlias) { var newColumns = from d in sel.Columns let qt = (d.Expression is ColumnExpression) ? ((ColumnExpression)d.Expression).QueryType : language.TypeSystem.GetColumnType(d.Expression.Type) select new ColumnDeclaration(d.Name, new ColumnExpression(d.Expression.Type, qt, newAlias, d.Name), qt); var newFrom = new SelectExpression(newAlias, sel.Columns, sel.From, sel.Where, sel.OrderBy, sel.GroupBy, sel.IsDistinct, sel.Skip, sel.Take, sel.IsReverse); return new SelectExpression(sel.Alias, newColumns, newFrom, null, null, null, false, null, null, false); }
internal static bool IsSimpleProjection(SelectExpression select) { foreach (ColumnDeclaration decl in select.Columns) { ColumnExpression col = decl.Expression as ColumnExpression; if (col == null || decl.Name != col.Name) { return false; } } return true; }
protected override Expression VisitProjection(ProjectionExpression proj) { SelectExpression save = this.currentSelect; this.currentSelect = proj.Source; try { if (!this.isTopLevel) { if (this.CanJoinOnClient(this.currentSelect)) { // make a query that combines all the constraints from the outer queries into a single select SelectExpression newOuterSelect = (SelectExpression)QueryDuplicator.Duplicate(save); // remap any references to the outer select to the new alias; SelectExpression newInnerSelect = (SelectExpression)ColumnMapper.Map(proj.Source, newOuterSelect.Alias, save.Alias); // add outer-join test ProjectionExpression newInnerProjection = new ProjectionExpression(newInnerSelect, proj.Projector).AddOuterJoinTest(); newInnerSelect = newInnerProjection.Source; Expression newProjector = newInnerProjection.Projector; TableAlias newAlias = new TableAlias(); var pc = ColumnProjector.ProjectColumns(this.language.CanBeColumn, newProjector, newOuterSelect.Columns, newAlias, newOuterSelect.Alias, newInnerSelect.Alias); JoinExpression join = new JoinExpression(JoinType.OuterApply, newOuterSelect, newInnerSelect, null); SelectExpression joinedSelect = new SelectExpression(newAlias, pc.Columns, join, null, null, null, proj.IsSingleton, null, null); // apply client-join treatment recursively this.currentSelect = joinedSelect; newProjector = this.Visit(pc.Projector); // compute keys (this only works if join condition was a single column comparison) List<Expression> outerKeys = new List<Expression>(); List<Expression> innerKeys = new List<Expression>(); if (this.GetEquiJoinKeyExpressions(newInnerSelect.Where, newOuterSelect.Alias, outerKeys, innerKeys)) { // outerKey needs to refer to the outer-scope's alias var outerKey = outerKeys.Select(k => ColumnMapper.Map(k, save.Alias, newOuterSelect.Alias)); // innerKey needs to refer to the new alias for the select with the new join var innerKey = innerKeys.Select(k => ColumnMapper.Map(k, joinedSelect.Alias, ((ColumnExpression)k).Alias)); ProjectionExpression newProjection = new ProjectionExpression(joinedSelect, newProjector, proj.Aggregator); return new ClientJoinExpression(newProjection, outerKey, innerKey); } } } else { this.isTopLevel = false; } return base.VisitProjection(proj); } finally { this.currentSelect = save; } }
protected override Expression VisitSelect(SelectExpression select) { var saveColumns = this.columns; this.columns = ReferencedColumnGatherer.Gather(select).ToLookup(c => c.Alias); var saveLastJoin = this.lastJoin; this.lastJoin = null; var result = base.VisitSelect(select); this.columns = saveColumns; this.lastJoin = saveLastJoin; return result; }
protected override Expression VisitClientJoin(ClientJoinExpression join) { // treat client joins as new top level var saveTop = isTopLevel; var saveSelect = currentSelect; isTopLevel = true; currentSelect = null; Expression result = base.VisitClientJoin(join); isTopLevel = saveTop; currentSelect = saveSelect; return result; }
private static SelectExpression AddInnerJoins(SelectExpression select, IEnumerable<InExpression> inExpressions) { foreach (var inExpression in inExpressions) { var joinExpression = new JoinExpression(JoinType.InnerJoin, select.From, inExpression.Select, Expression.MakeBinary(ExpressionType.Equal, inExpression.Expression, inExpression.Select.Columns[0].Expression)); select = select.SetFrom(joinExpression); } return select; }
protected override Expression VisitSelect(SelectExpression select) { select = (SelectExpression)base.VisitSelect(select); // first remove all purely redundant subqueries List<SelectExpression> redundant = RedundantSubqueryGatherer.Gather(select.From); if (redundant != null) { select = SubqueryRemover.Remove(select, redundant); } return select; }
protected override Expression VisitSelect(SelectExpression select) { Expression from = this.VisitSource(select.From); Expression where = this.Visit(select.Where); ReadOnlyCollection<OrderExpression> orderBy = this.VisitOrderBy(select.OrderBy); ReadOnlyCollection<Expression> groupBy = this.VisitExpressionList(select.GroupBy); Expression skip = this.Visit(select.Skip); Expression take = this.Visit(select.Take); ReadOnlyCollection<ColumnDeclaration> columns = this.VisitColumnDeclarations(select.Columns); SelectExpression output = new SelectExpression(select.Alias, columns, from, where, orderBy, groupBy, select.IsDistinct, skip, take); return output; }
protected override Expression VisitSelect(SelectExpression select) { select = (SelectExpression)base.VisitSelect(select); var inExpressions = InExpressionGatherer.Gather(select.Where); if (!inExpressions.Any()) { return select; } var newSelect = AddInnerJoins(select, inExpressions); return InExpressionRemover.Remove(newSelect, inExpressions); }
protected override Expression VisitSelect(SelectExpression select) { var saveWhere = this.currentWhere; try { this.currentWhere = select.Where; var result = (SelectExpression)base.VisitSelect(select); if (this.currentWhere != result.Where) { return result.SetWhere(this.currentWhere); } return result; } finally { this.currentWhere = saveWhere; } }
protected override 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 = select.Columns.NewIfChange(VisitColumnDeclaration); ReadOnlyCollection<OrderExpression> orderBy = select.OrderBy.NewIfChange(VisitOrderBy); ReadOnlyCollection<Expression> groupBy = select.GroupBy.NewIfChange(Visit); Alias newAlias = aliasMap.TryGetC(select.Alias) ?? select.Alias; if (top != select.Top || from != select.From || where != select.Where || columns != select.Columns || orderBy != select.OrderBy || groupBy != select.GroupBy || newAlias != select.Alias) return new SelectExpression(newAlias, select.IsDistinct, top, columns, from, where, orderBy, groupBy, select.SelectOptions); return select; }
protected internal override Expression VisitSelect(SelectExpression select) { select = (SelectExpression)base.VisitSelect(select); if (lookup.Contains(select.Alias)) { List<ColumnDeclaration> aggColumns = new List<ColumnDeclaration>(select.Columns); foreach (AggregateRequestsExpression ae in lookup[select.Alias]) { ColumnDeclaration cd = new ColumnDeclaration("agg" + aggColumns.Count, ae.Aggregate); this.map.Add(ae, cd.GetReference(ae.GroupByAlias)); aggColumns.Add(cd); } return new SelectExpression(select.Alias, select.IsDistinct, select.Top, aggColumns, select.From, select.Where, select.OrderBy, select.GroupBy, select.SelectOptions); } return select; }
internal static bool IsNameMapProjection(SelectExpression select) { if (select.From is TableExpression) return false; SelectExpression fromSelect = select.From as SelectExpression; if (fromSelect == null || select.Columns.Count != fromSelect.Columns.Count) return false; ReadOnlyCollection<ColumnDeclaration> fromColumns = fromSelect.Columns; // test that all columns in 'select' are refering to columns in the same position // in from. for (int i = 0, n = select.Columns.Count; i < n; i++) { ColumnExpression col = select.Columns[i].Expression as ColumnExpression; if (col == null || !(col.Name == fromColumns[i].Name)) return false; } return true; }
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()); } var colType = DbTypeSystem.GetColumnType(typeof(int)); newSelect = newSelect.AddColumn(new ColumnDeclaration(columnName, new RowNumberExpression(select.OrderBy), colType)); // add layer for WHERE clause that references new rownum column newSelect = newSelect.AddRedundantSelect(new TableAlias()); newSelect = newSelect.RemoveColumn(newSelect.Columns.Single(c => c.Name == columnName)); var newAlias = ((SelectExpression)newSelect.From).Alias; ColumnExpression rnCol = new ColumnExpression(typeof(int), colType, newAlias, columnName); 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; }
private bool TrivialWhere(DeleteExpression delete, SelectExpression select) { if (delete.Where == null || delete.Where.NodeType == ExpressionType.Equal) return false; var b = (BinaryExpression)delete.Where; var ce1 = b.Left as ColumnExpression; var ce2 = b.Right as ColumnExpression; if (ce1 == null || ce2 == null) return false; ce1 = ResolveColumn(ce1, select); ce2 = ResolveColumn(ce2, select); return ce1.Equals(ce2); }
/// <summary> /// Visits the select. /// </summary> /// <param name="select">The select.</param> /// <returns></returns> protected override Expression VisitSelect(SelectExpression select) { if (select.Skip != null) { if (select.OrderBy == null && select.OrderBy.Count == 0) { throw new NotSupportedException("Access cannot support the 'skip' operation without explicit ordering"); } else if (select.Take == null) { throw new NotSupportedException("Access cannot support the 'skip' operation without the 'take' operation"); } else { } } return base.VisitSelect(select); }
protected override Expression VisitSelect(SelectExpression select) { select = (SelectExpression) base.VisitSelect(select); // look for redundant column declarations List<ColumnDeclaration> cols = select.Columns.OrderBy(c => c.Name).ToList(); BitArray removed = new BitArray(select.Columns.Count); bool anyRemoved = false; for (int i = 0, n = cols.Count; i < n - 1; i++) { ColumnDeclaration ci = cols[i]; ColumnExpression cix = ci.Expression as ColumnExpression; QueryType qt = cix != null ? cix.QueryType : ci.QueryType; ColumnExpression cxi = new ColumnExpression(ci.Expression.Type, qt, select.Alias, ci.Name); for (int j = i + 1; j < n; j++) { if (!removed.Get(j)) { ColumnDeclaration cj = cols[j]; if (SameExpression(ci.Expression, cj.Expression)) { // any reference to 'j' should now just be a reference to 'i' ColumnExpression cxj = new ColumnExpression(cj.Expression.Type, qt, select.Alias, cj.Name); this.map.Add(cxj, cxi); removed.Set(j, true); anyRemoved = true; } } } } if (anyRemoved) { List<ColumnDeclaration> newDecls = new List<ColumnDeclaration>(); for (int i = 0, n = cols.Count; i < n; i++) { if (!removed.Get(i)) { newDecls.Add(cols[i]); } } select = select.SetColumns(newDecls); } return select; }
protected override Expression VisitSelect(SelectExpression selectExpression) { if (IsNonComposedSetOperation(selectExpression)) { // Naked set operation GenerateSetOperation((SetOperationBase)selectExpression.Tables[0]); return(selectExpression); } IDisposable subQueryIndent = null; if (selectExpression.Alias != null) { _relationalCommandBuilder.AppendLine("("); subQueryIndent = _relationalCommandBuilder.Indent(); } _relationalCommandBuilder.Append("SELECT "); if (selectExpression.IsDistinct) { _relationalCommandBuilder.Append("DISTINCT "); } GenerateTop(selectExpression); if (selectExpression.Projection.Any()) { GenerateList(selectExpression.Projection, e => Visit(e)); } else { _relationalCommandBuilder.Append("1"); } if (selectExpression.Tables.Any()) { _relationalCommandBuilder.AppendLine().Append("FROM "); GenerateList(selectExpression.Tables, e => Visit(e), sql => sql.AppendLine()); } if (selectExpression.Predicate != null) { _relationalCommandBuilder.AppendLine().Append("WHERE "); Visit(selectExpression.Predicate); } if (selectExpression.GroupBy.Count > 0) { _relationalCommandBuilder.AppendLine().Append("GROUP BY "); GenerateList(selectExpression.GroupBy, e => Visit(e)); } if (selectExpression.Having != null) { _relationalCommandBuilder.AppendLine().Append("HAVING "); Visit(selectExpression.Having); } GenerateOrderings(selectExpression); GenerateLimitOffset(selectExpression); if (selectExpression.Alias != null) { subQueryIndent.Dispose(); _relationalCommandBuilder.AppendLine() .Append(")" + AliasSeparator + _sqlGenerationHelper.DelimitIdentifier(selectExpression.Alias)); } return(selectExpression); }
protected override void GenerateTop([NotNull] SelectExpression selectExpression) { // No TOP in postgres }
public TestQuerySqlGenerator( QuerySqlGeneratorDependencies dependencies, SelectExpression selectExpression) : base(dependencies, selectExpression) { }
protected override Expression VisitSelect(SelectExpression selectExpression) { var changed = false; var parentSearchCondition = _isSearchCondition; var projections = new List <ProjectionExpression>(); _isSearchCondition = false; foreach (var item in selectExpression.Projection) { var updatedProjection = (ProjectionExpression)Visit(item); projections.Add(updatedProjection); changed |= updatedProjection != item; } var tables = new List <TableExpressionBase>(); foreach (var table in selectExpression.Tables) { var newTable = (TableExpressionBase)Visit(table); changed |= newTable != table; tables.Add(newTable); } _isSearchCondition = true; var predicate = (SqlExpression)Visit(selectExpression.Predicate); changed |= predicate != selectExpression.Predicate; var groupBy = new List <SqlExpression>(); _isSearchCondition = false; foreach (var groupingKey in selectExpression.GroupBy) { var newGroupingKey = (SqlExpression)Visit(groupingKey); changed |= newGroupingKey != groupingKey; groupBy.Add(newGroupingKey); } _isSearchCondition = true; var havingExpression = (SqlExpression)Visit(selectExpression.Having); changed |= havingExpression != selectExpression.Having; var orderings = new List <OrderingExpression>(); _isSearchCondition = false; foreach (var ordering in selectExpression.Orderings) { var orderingExpression = (SqlExpression)Visit(ordering.Expression); changed |= orderingExpression != ordering.Expression; orderings.Add(ordering.Update(orderingExpression)); } var offset = (SqlExpression)Visit(selectExpression.Offset); changed |= offset != selectExpression.Offset; var limit = (SqlExpression)Visit(selectExpression.Limit); changed |= limit != selectExpression.Limit; _isSearchCondition = parentSearchCondition; if (changed) { return(selectExpression.Update( projections, tables, predicate, groupBy, havingExpression, orderings, limit, offset, selectExpression.IsDistinct, selectExpression.Alias)); } return(selectExpression); }
public SelectExpressionCorrelationFindingExpressionVisitor(SelectExpression outerSelectExpression) { _outerSelectExpression = outerSelectExpression; }
internal static bool IsInitialProjection(SelectExpression select) { return(select.From is TableExpression); }
protected override Expression VisitSelect(SelectExpression select) { select = PreProcessSelect(select); if (select.From != null) { VisitSource(select.From); } if (select.Where != null) { try { //try this first, and if it fails, resort to javascript generation, which is slower on the server side. _queryObject.SetQueryDocument(new BsonDocumentFormatter().FormatDocument(select.Where)); } catch (InvalidQueryException) { throw; } catch (Exception) { _queryObject.SetWhereClause(new JavascriptFormatter().FormatJavascript(select.Where)); } } if (_queryAttributes.IsMapReduce) { _queryObject.IsMapReduce = true; _queryObject.MapFunction = new MapReduceMapFunctionBuilder().Build(select.Fields, select.GroupBy); _queryObject.ReduceFunction = new MapReduceReduceFunctionBuilder().Build(select.Fields); _queryObject.FinalizerFunction = new MapReduceFinalizerFunctionBuilder().Build(select.Fields); } else if (!_queryAttributes.IsCount && !select.Fields.HasSelectAllField()) { var fieldGatherer = new FieldGatherer(); foreach (var field in select.Fields) { var expandedFields = fieldGatherer.Gather(field.Expression); foreach (var expandedField in expandedFields) { _queryObject.Fields[expandedField.Name] = 1; } } // if the _id field isn't selected, then unselect it explicitly if (!_queryObject.Fields.Any(e => e.Name.StartsWith("_id"))) { _queryObject.Fields.Add("_id", 0); } } if (select.OrderBy != null) { foreach (var order in select.OrderBy) { var field = Visit(order.Expression) as FieldExpression; if (field == null) { throw new InvalidQueryException("Complex order by clauses are not supported."); } _queryObject.AddSort(field.Name, order.OrderType == OrderType.Ascending ? 1 : -1); } } if (select.Take != null) { _queryObject.NumberToLimit = EvaluateConstant <int>(select.Take); } if (select.Skip != null) { _queryObject.NumberToSkip = EvaluateConstant <int>(select.Skip); } return(select); }
/// <summary> /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> public SqliteQuerySqlGenerator( [NotNull] QuerySqlGeneratorDependencies dependencies, [NotNull] SelectExpression selectExpression) : base(dependencies, selectExpression) { }
public override JoinQueryResult Visit(SelectExpression exp) { JoinQueryResult ret = this.Visit(exp); return(ret); }
protected override Expression VisitSelect(SelectExpression select) { this.AddAliases(select.From); this.Write("SELECT "); if (select.IsDistinct) { this.Write("DISTINCT "); } this.WriteColumns(select.Columns); if (select.From != null) { this.WriteLine(Indentation.Same); this.Write("FROM "); this.VisitSource(select.From); } if (select.Where != null) { this.WriteLine(Indentation.Same); this.Write("WHERE "); this.VisitPredicate(select.Where); } if (select.GroupBy != null && select.GroupBy.Count > 0) { this.WriteLine(Indentation.Same); this.Write("GROUP BY "); for (int i = 0, n = select.GroupBy.Count; i < n; i++) { if (i > 0) { this.Write(", "); } this.VisitValue(select.GroupBy[i]); } } if (select.OrderBy != null && select.OrderBy.Count > 0) { this.WriteLine(Indentation.Same); this.Write("ORDER BY "); for (int i = 0, n = select.OrderBy.Count; i < n; i++) { OrderExpression exp = select.OrderBy[i]; if (i > 0) { this.Write(", "); } this.VisitValue(exp.Expression); if (exp.OrderType != OrderType.Ascending) { this.Write(" DESC"); } } } if (select.Take != null) { this.WriteLine(Indentation.Same); this.Write("LIMIT "); if (select.Skip == null) { this.Write("0"); } else { this.Write(select.Skip); } this.Write(", "); this.Visit(select.Take); } return(select); }
/// <summary> /// 有跳过的分页 /// </summary> /// <param name="select"></param> private void HasSkipPaging(SelectExpression select) { var externalAlias = this.GetNewAlias(); _sb.Append("SELECT "); var isFromTable = false; if (!select.ColumnsPrefix.IsNullOrWhiteSpace()) { _sb.AppendFormat("{0} ", select.ColumnsPrefix); } int index = 0; foreach (var column in select.Columns) { var tempColumn = column.DeepClone(); if (index++ > 0) { _sb.Append(", "); } tempColumn.TableAlias = externalAlias; this.VisitColumn(tempColumn); } _sb.Append(" FROM ("); _sb.Append("SELECT "); index = 0; if (select.From is TableExpression fromTable) { isFromTable = true; var except = fromTable.Columns.Where(it => select.Columns.Any(x => x.MemberInfo == it.MemberInfo) || select.OrderBy .Select(x => x.ColumnExpression).Any(x => x.MemberInfo == it.MemberInfo)).Distinct().ToList(); foreach (var column in except) { if (index++ > 0) { _sb.Append(", "); } column.TableAlias = select.Alias; this.VisitColumn(column); } } else if (select.From is SelectExpression subSelectExpression && subSelectExpression.From is TableExpression fromTable2) { var except = fromTable2.Columns.Where(it => subSelectExpression.Columns.Any(x => x.MemberInfo == it.MemberInfo) || subSelectExpression.OrderBy .Select(x => x.ColumnExpression).Any(x => x.MemberInfo == it.MemberInfo)).Distinct().ToList(); foreach (var column in except) { if (index++ > 0) { _sb.Append(", "); } column.TableAlias = select.Alias; this.VisitColumn(column); } }
public void Generates_ignores_missing_take_value() { var expression = new SelectExpression(typeof(PocoTestType)); Assert.Null(_generator.GenerateTableQuery(expression).TakeCount); }
public ExistsExpression Exists(SelectExpression subquery, bool negated) { return(new ExistsExpression(subquery, negated, _boolTypeMapping)); }
protected virtual void GenerateTop(SelectExpression selectExpression) { }
protected override void GenerateTop(SelectExpression expression) { // not supported in SQLite }
protected virtual void GenerateSetOperationOperand(SetOperationBase setOperation, SelectExpression operand) { // INTERSECT has higher precedence over UNION and EXCEPT, but otherwise evaluation is left-to-right. // To preserve meaning, add parentheses whenever a set operation is nested within a different set operation. if (IsNonComposedSetOperation(operand) && operand.Tables[0].GetType() != setOperation.GetType()) { _relationalCommandBuilder.AppendLine("("); using (_relationalCommandBuilder.Indent()) { Visit(operand); } _relationalCommandBuilder.AppendLine().Append(")"); } else { Visit(operand); } }
protected virtual void GenerateTop([NotNull] SelectExpression selectExpression) { Check.NotNull(selectExpression, nameof(selectExpression)); }
/// <summary> /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> public override IQuerySqlGenerator CreateDefault(SelectExpression selectExpression) => new JetQuerySqlGenerator( Dependencies, Check.NotNull(selectExpression, nameof(selectExpression)));
public override ISqlQueryGenerator CreateSqlQueryGenerator(SelectExpression selectExpression) => new SqliteQuerySqlGenerator(selectExpression);
protected override Expression VisitSelect(SelectExpression select) { bool wasTopLevel = _isTopLevel; _isTopLevel = false; select = (SelectExpression)base.VisitSelect(select); // next attempt to merge subqueries that would have been removed by the above // logic except for the existence of a where clause while (CanMergeWithFrom(select, wasTopLevel)) { SelectExpression fromSelect = GetLeftMostSelect(select.From); // remove the redundant subquery select = SubqueryRemover.Remove(select, fromSelect); // merge where expressions Expression where; Expression having; if (fromSelect.GroupBy != null && fromSelect.GroupBy.Count > 0) { where = fromSelect.Where; having = select.Where; if (fromSelect.Having != null) { having = having != null?Expression.AndAlso(fromSelect.Having, having) : fromSelect.Having; } } else { where = select.Where; if (fromSelect.Where != null) { where = where != null?Expression.AndAlso(fromSelect.Where, where) : fromSelect.Where; } having = null; } var orderBy = select.OrderBy != null && select.OrderBy.Count > 0 ? select.OrderBy : fromSelect.OrderBy; var groupBy = select.GroupBy != null && select.GroupBy.Count > 0 ? select.GroupBy : fromSelect.GroupBy; Expression offset = select.Offset; if (fromSelect.Offset != null) { offset = offset == null ? fromSelect.Offset : Expression.Add(fromSelect.Offset, offset); } Expression limit = select.Limit ?? fromSelect.Limit; if (fromSelect.Limit != null) { limit = limit == null ? fromSelect.Limit : Expression.Call(typeof(Math), nameof(Math.Min), null, fromSelect.Limit, limit); } bool isDistinct = select.IsDistinct | fromSelect.IsDistinct; if (where != select.Where || orderBy != select.OrderBy || groupBy != select.GroupBy || having != select.Having || isDistinct != select.IsDistinct || offset != select.Offset || limit != select.Limit) { select = new SelectExpression( select.Alias, select.Columns, select.From, where, groupBy, having, orderBy, offset, limit, isDistinct ); } } return(select); }
public override IQuerySqlGenerator CreateDefault( SelectExpression selectExpression) => new TestQuerySqlGenerator(Dependencies, selectExpression);
protected abstract void VisitSelect(SelectExpression expression);
protected override void GenerateTop(SelectExpression selectExpression) { }
public override IQueryState Accept(SelectExpression exp) { ResultElement result = this.CreateNewResult(exp.Selector); return(this.CreateQueryState(result)); }
protected override Expression VisitSelect(SelectExpression select) { // visit column projection first var columns = select.Columns; var wasRetained = _retainAllColumns; _retainAllColumns = false; List <ColumnDeclaration> alternate = null; for (int i = 0, n = select.Columns.Count; i < n; i++) { var decl = select.Columns[i]; if (wasRetained || select.IsDistinct || IsColumnUsed(select.Alias, decl.Name)) { var expr = Visit(decl.Expression); if (expr != decl.Expression) { decl = new ColumnDeclaration(decl.Name, expr); } } else { decl = null; // null means it gets omitted } if (decl != select.Columns[i] && alternate == null) { alternate = new List <ColumnDeclaration>(); for (int j = 0; j < i; j++) { alternate.Add(select.Columns[j]); } } if (decl != null && alternate != null) { alternate.Add(decl); } } if (alternate != null) { columns = alternate.AsReadOnly(); } var take = Visit(select.Take); var skip = Visit(select.Skip); var groupbys = VisitMemberAndExpressionList(select.GroupBy); var orderbys = VisitOrderBy(select.OrderBy); var where = Visit(select.Where); var having = Visit(select.Having); var from = Visit(select.From); ClearColumnsUsed(select.Alias); //构成新的查询表达式 select = select.Update(from, where, orderbys, groupbys, skip, take, select.Segment, select.IsDistinct, columns, having, select.IsReverse); _retainAllColumns = wasRetained; return(select); }
protected override void GenerateTop(SelectExpression selectExpression) { // Handled by GenerateLimitOffset }
protected override Expression VisitSelect(SelectExpression select) { _selects.Add(select); return(select); }
/// <summary> /// Visits the children of the select expression. /// </summary> /// <param name="selectExpression"> The expression to visit. </param> /// <returns> The modified expression, if it or any subexpression was modified; otherwise, returns the original expression. </returns> protected abstract Expression VisitSelect([NotNull] SelectExpression selectExpression);
public virtual Expression CreateMaterializer( [NotNull] IEntityType entityType, [NotNull] SelectExpression selectExpression, [NotNull] Func <IProperty, SelectExpression, int> projectionAdder, [CanBeNull] IQuerySource querySource) { Check.NotNull(entityType, nameof(entityType)); Check.NotNull(selectExpression, nameof(selectExpression)); Check.NotNull(projectionAdder, nameof(projectionAdder)); var valueBufferParameter = Expression.Parameter(typeof(ValueBuffer)); var concreteEntityTypes = entityType.GetConcreteTypesInHierarchy().ToArray(); var indexMap = new int[concreteEntityTypes[0].GetProperties().Count()]; var propertyIndex = 0; foreach (var property in concreteEntityTypes[0].GetProperties()) { indexMap[propertyIndex++] = projectionAdder(property, selectExpression); } var materializer = _entityMaterializerSource .CreateMaterializeExpression( concreteEntityTypes[0], valueBufferParameter, indexMap); if (concreteEntityTypes.Length == 1 && concreteEntityTypes[0].RootType() == concreteEntityTypes[0]) { return(Expression.Lambda <Func <ValueBuffer, object> >(materializer, valueBufferParameter)); } var discriminatorProperty = _relationalAnnotationProvider.For(concreteEntityTypes[0]).DiscriminatorProperty; var discriminatorColumn = selectExpression.Projection .OfType <AliasExpression>() .Single(c => c.TryGetColumnExpression()?.Property == discriminatorProperty); var firstDiscriminatorValue = Expression.Constant( _relationalAnnotationProvider.For(concreteEntityTypes[0]).DiscriminatorValue); var discriminatorPredicate = Expression.Equal(discriminatorColumn, firstDiscriminatorValue); if (concreteEntityTypes.Length == 1) { selectExpression.Predicate = new DiscriminatorPredicateExpression(discriminatorPredicate, querySource); return(Expression.Lambda <Func <ValueBuffer, object> >(materializer, valueBufferParameter)); } var discriminatorValueVariable = Expression.Variable(discriminatorProperty.ClrType); var returnLabelTarget = Expression.Label(typeof(object)); var blockExpressions = new Expression[] { Expression.Assign( discriminatorValueVariable, _entityMaterializerSource .CreateReadValueExpression( valueBufferParameter, discriminatorProperty.ClrType, discriminatorProperty.Index)), Expression.IfThenElse( Expression.Equal(discriminatorValueVariable, firstDiscriminatorValue), Expression.Return(returnLabelTarget, materializer), Expression.Throw( Expression.Call( _createUnableToDiscriminateException, Expression.Constant(concreteEntityTypes[0])))), Expression.Label( returnLabelTarget, Expression.Default(returnLabelTarget.Type)) }; foreach (var concreteEntityType in concreteEntityTypes.Skip(1)) { indexMap = new int[concreteEntityType.GetProperties().Count()]; propertyIndex = 0; foreach (var property in concreteEntityType.GetProperties()) { indexMap[propertyIndex++] = projectionAdder(property, selectExpression); } var discriminatorValue = Expression.Constant( _relationalAnnotationProvider.For(concreteEntityType).DiscriminatorValue); materializer = _entityMaterializerSource .CreateMaterializeExpression(concreteEntityType, valueBufferParameter, indexMap); blockExpressions[1] = Expression.IfThenElse( Expression.Equal(discriminatorValueVariable, discriminatorValue), Expression.Return(returnLabelTarget, materializer), blockExpressions[1]); discriminatorPredicate = Expression.OrElse( Expression.Equal(discriminatorColumn, discriminatorValue), discriminatorPredicate); } selectExpression.Predicate = new DiscriminatorPredicateExpression(discriminatorPredicate, querySource); return(Expression.Lambda <Func <ValueBuffer, object> >( Expression.Block(new[] { discriminatorValueVariable }, blockExpressions), valueBufferParameter)); }
public LowercaseQuerySqlGenerator(QuerySqlGeneratorDependencies dependencies, RelationalSqlGenerationHelperDependencies rSGenDep, SelectExpression selectExpression) : base( new QuerySqlGeneratorDependencies(dependencies.CommandBuilderFactory, new LowercaseSqlGenerationHelper(rSGenDep), dependencies.ParameterNameGeneratorFactory, dependencies.RelationalTypeMapper) , selectExpression) { }