public virtual Expression VisitExistsExpression(ExistsExpression existsExpression) { Check.NotNull(existsExpression, "existsExpression"); _sql.AppendLine("EXISTS ("); using (_sql.Indent()) { VisitExpression(existsExpression.Expression); } _sql.AppendLine() .AppendLine(")"); return(existsExpression); }
protected virtual Expression BindIntersect(Expression outerSource, Expression innerSource, bool negate) { ProjectionExpression outerProjection = this.VisitSequence(outerSource); ProjectionExpression innerProjection = this.VisitSequence(innerSource); Expression exists = new ExistsExpression(new SelectExpression(new TableAlias(), null, innerProjection.Select, innerProjection.Projector.Equal(outerProjection.Projector))); if (negate) { exists = Expression.Not(exists); } var alias = this.GetNextAlias(); ProjectedColumns pc = this.ProjectColumns(outerProjection.Projector, alias, outerProjection.Select.Alias); return(new ProjectionExpression(new SelectExpression(alias, pc.Columns, outerProjection.Select, exists), pc.Projector, outerProjection.Aggregator)); }
protected override Expression VisitExists(ExistsExpression exists) { // how did we get here? Translate exists into count query var colType = this.linguist.Language.TypeSystem.GetColumnType(typeof(int)); var newSelect = exists.Select.SetColumns( new[] { new ColumnDeclaration("value", new AggregateExpression(typeof(int), "Count", null, false), colType) }); var projection = new ProjectionExpression( newSelect, new ColumnExpression(typeof(int), colType, newSelect.Alias, "value"), Aggregator.GetAggregator(typeof(int), typeof(IEnumerable <int>))); var expression = projection.GreaterThan(Expression.Constant(0)); return(this.Visit(expression)); }
protected override Expression VisitExists(ExistsExpression existsExpression) { if (existsExpression.IsNegated) { _relationalCommandBuilder.Append("NOT "); } _relationalCommandBuilder.AppendLine("EXISTS ("); using (_relationalCommandBuilder.Indent()) { Visit(existsExpression.Subquery); } _relationalCommandBuilder.Append(")"); return(existsExpression); }
public override Expression VisitExists(ExistsExpression existsExpression) { // OpenEdge does not support WHEN EXISTS, only WHERE EXISTS // We need to SELECT 1 using WHERE EXISTS, then compare // the result to 1 to satisfy the conditional. // OpenEdge requires that SELECT statements always include a table, // so we SELECT from the _File metaschema table that always exists, // selecting a single row that we know will always exist; the metaschema // record for the _File metaschema table itself. Sql.AppendLine(@"(SELECT 1 FROM pub.""_File"" f WHERE f.""_File-Name"" = '_File' AND EXISTS ("); using (Sql.Indent()) { Visit(existsExpression.Subquery); } Sql.Append(")) = 1"); _existsConditional = true; return(existsExpression); }
protected override Expression VisitExists(ExistsExpression exists) { using (Scope()) return base.VisitExists(exists); }
protected abstract Expression VisitExists(ExistsExpression existsExpression);
// don't count aggregates in subqueries protected internal override Expression VisitExists(ExistsExpression exists) { return base.VisitExists(exists); }
protected override Expression VisitExists(ExistsExpression exists) { sb.Append("EXISTS("); Visit(exists.Select); sb.Append(")"); return exists; }
private Expression BindAnyAll(Expression source, MethodInfo method, LambdaExpression predicate, bool isRoot) { bool isAll = method.Name == "All"; ConstantExpression constSource = source as ConstantExpression; if (constSource != null && !IsQuery(constSource)) { Debug.Assert(!isRoot); Expression where = null; foreach (object value in (IEnumerable) constSource.Value) { Expression expr = Expression.Invoke(predicate, Expression.Constant(value, predicate.Parameters[0].Type)); if (where == null) { where = expr; } else if (isAll) { where = Expression.And(where, expr); } else { where = Expression.Or(where, expr); } } return Visit(where); } else { if (isAll) { predicate = Expression.Lambda(Expression.Not(predicate.Body), predicate.Parameters.ToArray()); } if (predicate != null) { source = Expression.Call(typeof (Queryable), "Where", method.GetGenericArguments(), source, predicate); } ProjectionExpression projection = VisitSequence(source); Expression result = new ExistsExpression(projection.Source); if (isAll) { result = Expression.Not(result); } if (isRoot) { return GetSingletonSequence(result, "SingleOrDefault"); } return result; } }
public virtual void PostVisit(ExistsExpression data) { }
protected virtual Expression VisitExists(ExistsExpression exists) { SelectExpression select = (SelectExpression)this.Visit(exists.Select); if (select != exists.Select) { return new ExistsExpression(select); } return exists; }
protected virtual Expression VisitExists(ExistsExpression exists) { var select = (SelectExpression)this.Visit(exists.Select); return this.UpdateExists(exists, select); }
/// <summary> /// Visits the children of the exists expression. /// </summary> /// <param name="existsExpression"> 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 VisitExists([NotNull] ExistsExpression existsExpression);
protected virtual bool CompareExists(ExistsExpression a, ExistsExpression b) { return(Compare(a.Select, b.Select)); }
protected ExistsExpression UpdateExists(ExistsExpression exists, SelectExpression select) { if (select != exists.Select) { return new ExistsExpression(select); } return exists; }
// don't count aggregates in subqueries protected internal override Expression VisitExists(ExistsExpression exists) { return(base.VisitExists(exists)); }
protected override Expression VisitExists(ExistsExpression existsExpression) { if (existsExpression.IsNegated) { Sql.Append("NOT "); } Sql.Append(" if (count() > 0, 1, 0) "); using (Sql.Indent()) { if (IsNonComposedSetOperation(existsExpression.Subquery)) { // Naked set operation GenerateSetOperation((SetOperationBase)existsExpression.Subquery.Tables[0]); return(existsExpression.Subquery); } IDisposable subQueryIndent = null; if (existsExpression.Subquery.Alias != null) { Sql.AppendLine("("); subQueryIndent = Sql.Indent(); } if (existsExpression.Subquery.IsDistinct) { Sql.Append("DISTINCT "); } GenerateTop(existsExpression.Subquery); if (existsExpression.Subquery.Tables.Any()) { Sql.AppendLine().Append("FROM "); GenerateList(existsExpression.Subquery.Tables, e => Visit(e), sql => sql.AppendLine()); } if (existsExpression.Subquery.Predicate != null) { Sql.AppendLine().Append("WHERE "); Visit(existsExpression.Subquery.Predicate); } if (existsExpression.Subquery.GroupBy.Count > 0) { Sql.AppendLine().Append("GROUP BY "); GenerateList(existsExpression.Subquery.GroupBy, e => Visit(e)); } if (existsExpression.Subquery.Having != null) { Sql.AppendLine().Append("HAVING "); Visit(existsExpression.Subquery.Having); } GenerateOrderings(existsExpression.Subquery); GenerateLimitOffset(existsExpression.Subquery); if (existsExpression.Subquery.Alias != null) { subQueryIndent.Dispose(); // TODO //Sql.AppendLine() // .Append(")" + AliasSeparator + Sql.DelimitIdentifier(existsExpression.Subquery.Alias)); } } return(existsExpression); }
public virtual IExpression Visit(ExistsExpression expression) { return(expression); }
protected virtual Expression BindIntersect(Expression outerSource, Expression innerSource, bool negate) { // SELECT * FROM outer WHERE EXISTS(SELECT * FROM inner WHERE inner = outer)) ProjectionExpression outerProjection = this.VisitSequence(outerSource); ProjectionExpression innerProjection = this.VisitSequence(innerSource); Expression exists = new ExistsExpression( new SelectExpression(new TableAlias(), null, innerProjection.Select, innerProjection.Projector.Equal(outerProjection.Projector)) ); if (negate) exists = Expression.Not(exists); var alias = this.GetNextAlias(); ProjectedColumns pc = this.ProjectColumns(outerProjection.Projector, alias, outerProjection.Select.Alias); return new ProjectionExpression( new SelectExpression(alias, pc.Columns, outerProjection.Select, exists), pc.Projector, outerProjection.Aggregator ); }
private Expression BindAnyAll(Expression source, MethodInfo method, LambdaExpression predicate, bool isRoot) { bool isAll = method.Name.Equals("All", StringComparison.InvariantCultureIgnoreCase); ConstantExpression constSource = source as ConstantExpression; if (constSource != null && !IsQuery(constSource)) { System.Diagnostics.Debug.Assert(!isRoot); Expression where = null; foreach (object value in (IEnumerable)constSource.Value) { Expression expr = Expression.Invoke(predicate, Expression.Constant(value, predicate.Parameters[0].Type)); if (where == null) { where = expr; } else if (isAll) { where = where.And(expr); } else { where = where.Or(expr); } } return(this.Visit(where)); } else { if (isAll) { predicate = Expression.Lambda(Expression.Not(predicate.Body), predicate.Parameters.ToArray()); } if (predicate != null) { source = Expression.Call(typeof(Enumerable), "Where", method.GetGenericArguments(), source, predicate); } ProjectionExpression projection = this.VisitSequence(source); Expression result = new ExistsExpression(projection.Select); if (isAll) { result = Expression.Not(result); } if (isRoot) { if (this.language.AllowSubqueryInSelectWithoutFrom) { return(GetSingletonSequence(result, "SingleOrDefault")); } else { // use count aggregate instead of exists //var colType = this.language.TypeSystem.GetColumnType(typeof(int)); var newSelect = projection.Select.SetColumns(new[] { new ColumnDeclaration("value", new AggregateExpression(typeof(int), "Count", null, false)) }); var colx = new ColumnExpression(typeof(int), newSelect.Alias, "value"); var exp = isAll ? colx.Equal(Expression.Constant(0)) : colx.GreaterThan(Expression.Constant(0)); return(new ProjectionExpression(newSelect, exp, Aggregator.GetAggregator(typeof(bool), typeof(IEnumerable <bool>)))); } } return(result); } }
private Expression BindAnyAll(Expression source, MethodInfo method, LambdaExpression predicate, bool isRoot) { bool isAll = method.Name == "All"; ConstantExpression constSource = source as ConstantExpression; if (constSource != null && !IsQuery(constSource)) { System.Diagnostics.Debug.Assert(!isRoot); Expression where = null; foreach (object value in (IEnumerable)constSource.Value) { Expression expr = Expression.Invoke(predicate, Expression.Constant(value, predicate.Parameters[0].Type)); if (where == null) { where = expr; } else if (isAll) { where = where.And(expr); } else { where = where.Or(expr); } } return this.Visit(where); } else { if (isAll) { predicate = Expression.Lambda(Expression.Not(predicate.Body), predicate.Parameters.ToArray()); } if (predicate != null) { source = Expression.Call(typeof(Enumerable), "Where", method.GetGenericArguments(), source, predicate); } ProjectionExpression projection = this.VisitSequence(source); Expression result = new ExistsExpression(projection.Select); if (isAll) { result = Expression.Not(result); } if (isRoot) { if (this.language.AllowSubqueryInSelectWithoutFrom) { return GetSingletonSequence(result, "SingleOrDefault"); } else { // use count aggregate instead of exists var colType = this.language.TypeSystem.GetColumnType(typeof(int)); var newSelect = projection.Select.SetColumns( new[] { new ColumnDeclaration("value", new AggregateExpression(typeof(int), "Count", null, false), colType) } ); var colx = new ColumnExpression(typeof(int), colType, newSelect.Alias, "value"); var exp = isAll ? colx.Equal(Expression.Constant(0)) : colx.GreaterThan(Expression.Constant(0)); return new ProjectionExpression( newSelect, exp, Aggregator.GetAggregator(typeof(bool), typeof(IEnumerable<bool>)) ); } } return result; } }
protected override Expression VisitExists(ExistsExpression x) { return(x?.Update(x.Subquery.VisitNode(this))); }
protected virtual bool CompareExists(ExistsExpression a, ExistsExpression b) { return this.Compare(a.Select, b.Select); }
protected override Expression VisitExists(ExistsExpression existsExpression) { Visit(existsExpression.Subquery); return(existsExpression); }
protected override Expression VisitExists(ExistsExpression exists) { this.Write("EXISTS("); this.WriteLine(Indentation.Inner); this.Visit(exists.Select); this.WriteLine(Indentation.Same); this.Write(")"); this.Indent(Indentation.Outer); return exists; }
private bool CompareExists(ExistsExpression a, ExistsExpression b) { return this.Compare(a.Select, b.Select); }
private IReadOnlyList <Func <QueryContext, TRelatedEntitiesLoader> > CreateRelatedEntitiesLoaders <TRelatedEntitiesLoader>( IQuerySource querySource, IEnumerable <INavigation> navigationPath) { var relatedEntitiesLoaders = new List <Func <QueryContext, TRelatedEntitiesLoader> >(); var selectExpression = _queryCompilationContext.FindSelectExpression(querySource); var compositePredicateExpressionVisitor = _compositePredicateExpressionVisitorFactory.Create(); var targetTableExpression = selectExpression.GetTableForQuerySource(querySource); var canProduceInnerJoin = true; var navigationCount = 0; foreach (var navigation in navigationPath) { var queryIndex = _queryIndexes[navigationCount]; navigationCount++; var targetEntityType = navigation.GetTargetType(); var targetTableName = _relationalAnnotationProvider.For(targetEntityType).TableName; var targetTableAlias = _queryCompilationContext .CreateUniqueTableAlias(targetTableName[0].ToString().ToLowerInvariant()); if (!navigation.IsCollection()) { var joinedTableExpression = new TableExpression( targetTableName, _relationalAnnotationProvider.For(targetEntityType).Schema, targetTableAlias, querySource); var valueBufferOffset = selectExpression.Projection.Count; canProduceInnerJoin = canProduceInnerJoin && navigation.ForeignKey.IsRequired && navigation.IsDependentToPrincipal(); var joinExpression = canProduceInnerJoin ? selectExpression.AddInnerJoin(joinedTableExpression) : selectExpression.AddLeftOuterJoin(joinedTableExpression); var oldPredicate = selectExpression.Predicate; var materializer = _materializerFactory .CreateMaterializer( targetEntityType, selectExpression, (p, se) => se.AddToProjection( new AliasExpression( new ColumnExpression( _relationalAnnotationProvider.For(p).ColumnName, p, joinedTableExpression))) - valueBufferOffset, querySource: null); if (selectExpression.Predicate != oldPredicate) { selectExpression.Predicate = compositePredicateExpressionVisitor .Visit(selectExpression.Predicate); var newJoinExpression = AdjustJoinExpression(selectExpression, joinExpression); selectExpression.Predicate = oldPredicate; selectExpression.RemoveTable(joinExpression); selectExpression.AddTable(newJoinExpression, createUniqueAlias: false); joinExpression = newJoinExpression; } joinExpression.Predicate = BuildJoinEqualityExpression( navigation, navigation.IsDependentToPrincipal() ? targetTableExpression : joinExpression, navigation.IsDependentToPrincipal() ? joinExpression : targetTableExpression, querySource); targetTableExpression = joinedTableExpression; relatedEntitiesLoaders.Add(qc => (TRelatedEntitiesLoader)_queryCompilationContext.QueryMethodProvider .CreateReferenceRelatedEntitiesLoaderMethod .Invoke( null, new object[] { valueBufferOffset, queryIndex, materializer.Compile() // TODO: Used cached materializer? })); } else { var principalTable = selectExpression.Tables.Count == 1 && selectExpression.Tables .OfType <SelectExpression>() .Any(s => s.Tables.Any(t => t.QuerySource == querySource)) // true when select is wrapped e.g. when RowNumber paging is enabled ? selectExpression.Tables[0] : selectExpression.Tables.Last(t => t.QuerySource == querySource); var canGenerateExists = (selectExpression.Predicate != null || selectExpression.Offset == null) && !IsOrderingOnNonPrincipalKeyProperties( selectExpression.OrderBy, navigation.ForeignKey.PrincipalKey.Properties); foreach (var property in navigation.ForeignKey.PrincipalKey.Properties) { selectExpression .AddToOrderBy( _relationalAnnotationProvider.For(property).ColumnName, property, principalTable, OrderingDirection.Asc); } var targetSelectExpression = _selectExpressionFactory.Create(_queryCompilationContext); targetTableExpression = new TableExpression( targetTableName, _relationalAnnotationProvider.For(targetEntityType).Schema, targetTableAlias, querySource); targetSelectExpression.AddTable(targetTableExpression, createUniqueAlias: false); var materializer = _materializerFactory .CreateMaterializer( targetEntityType, targetSelectExpression, (p, se) => se.AddToProjection( _relationalAnnotationProvider.For(p).ColumnName, p, querySource), querySource: null); if (canGenerateExists) { var subqueryExpression = selectExpression.Clone(); subqueryExpression.ClearProjection(); subqueryExpression.ClearOrderBy(); subqueryExpression.IsProjectStar = false; var subqueryTable = subqueryExpression.Tables.Count == 1 && subqueryExpression.Tables .OfType <SelectExpression>() .Any(s => s.Tables.Any(t => t.QuerySource == querySource)) // true when select is wrapped e.g. when RowNumber paging is enabled ? subqueryExpression.Tables[0] : subqueryExpression.Tables.Last(t => t.QuerySource == querySource); var existsPredicateExpression = new ExistsExpression(subqueryExpression); AddToPredicate(targetSelectExpression, existsPredicateExpression); AddToPredicate(subqueryExpression, BuildJoinEqualityExpression(navigation, targetTableExpression, subqueryTable, querySource)); subqueryExpression.Predicate = compositePredicateExpressionVisitor .Visit(subqueryExpression.Predicate); var pkPropertiesToFkPropertiesMap = navigation.ForeignKey.PrincipalKey.Properties .Zip(navigation.ForeignKey.Properties, (k, v) => new { PkProperty = k, FkProperty = v }) .ToDictionary(x => x.PkProperty, x => x.FkProperty); foreach (var ordering in selectExpression.OrderBy) { // ReSharper disable once PossibleNullReferenceException var principalKeyProperty = ((ordering.Expression as AliasExpression)?.Expression as ColumnExpression).Property; var referencedForeignKeyProperty = pkPropertiesToFkPropertiesMap[principalKeyProperty]; targetSelectExpression .AddToOrderBy( _relationalAnnotationProvider.For(referencedForeignKeyProperty).ColumnName, referencedForeignKeyProperty, targetTableExpression, ordering.OrderingDirection); } } else { var innerJoinSelectExpression = selectExpression.Clone( selectExpression.OrderBy .Select(o => o.Expression) .Last(o => o.IsAliasWithColumnExpression()) .TryGetColumnExpression().TableAlias); innerJoinSelectExpression.ClearProjection(); var innerJoinExpression = targetSelectExpression.AddInnerJoin(innerJoinSelectExpression); LiftOrderBy(innerJoinSelectExpression, targetSelectExpression, innerJoinExpression); innerJoinSelectExpression.IsDistinct = true; innerJoinExpression.Predicate = BuildJoinEqualityExpression( navigation, targetTableExpression, innerJoinExpression, querySource); } targetSelectExpression.Predicate = compositePredicateExpressionVisitor .Visit(targetSelectExpression.Predicate); selectExpression = targetSelectExpression; relatedEntitiesLoaders.Add(qc => (TRelatedEntitiesLoader)_queryCompilationContext.QueryMethodProvider .CreateCollectionRelatedEntitiesLoaderMethod .Invoke( null, new object[] { qc, _shaperCommandContextFactory.Create(() => _querySqlGeneratorFactory.CreateDefault(targetSelectExpression)), queryIndex, materializer.Compile() // TODO: Used cached materializer? })); } } return(relatedEntitiesLoaders); }
public virtual void Visit(ExistsExpression expression) { }