示例#1
0
        public virtual Expression VisitExistsExpression(ExistsExpression existsExpression)
        {
            Check.NotNull(existsExpression, "existsExpression");

            _sql.AppendLine("EXISTS (");

            using (_sql.Indent())
            {
                VisitExpression(existsExpression.Expression);
            }

            _sql.AppendLine()
            .AppendLine(")");

            return(existsExpression);
        }
示例#2
0
        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));
        }
示例#3
0
        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);
        }
示例#5
0
        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);
        }
示例#6
0
 protected override Expression VisitExists(ExistsExpression exists)
 {
     using (Scope())
         return base.VisitExists(exists);
 }
示例#7
0
 protected abstract Expression VisitExists(ExistsExpression existsExpression);
 // don't count aggregates in subqueries
 protected internal override Expression VisitExists(ExistsExpression exists)
 {
     return base.VisitExists(exists);
 }
示例#9
0
 protected override Expression VisitExists(ExistsExpression exists)
 {
     sb.Append("EXISTS(");
     Visit(exists.Select);
     sb.Append(")");
     return exists;
 }
示例#10
0
 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;
     }
 }
示例#11
0
 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;
 }
示例#13
0
 protected virtual Expression VisitExists(ExistsExpression exists)
 {
     var select = (SelectExpression)this.Visit(exists.Select);
     return this.UpdateExists(exists, select);
 }
示例#14
0
 /// <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);
示例#15
0
 protected virtual bool CompareExists(ExistsExpression a, ExistsExpression b)
 {
     return(Compare(a.Select, b.Select));
 }
示例#16
0
 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));
 }
示例#18
0
        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
                );
        }
示例#21
0
        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);
 }
示例#25
0
 protected override Expression VisitExists(ExistsExpression existsExpression)
 {
     Visit(existsExpression.Subquery);
     return(existsExpression);
 }
示例#26
0
 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);
		}
示例#28
0
        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)
 {
 }