protected override Expression VisitSubQueryExpression(SubQueryExpression expression)
        {
            ContainsAggregateMethods =
                new GroupByAggregateDetectionVisitor().Visit(expression.QueryModel.SelectClause.Selector);

            return expression;
        }
		private void FlattenSubQuery(SubQueryExpression subQueryExpression, QueryModel queryModel)
		{
			// Create a new client-side select for the outer
			// TODO - don't like calling GetGenericArguments here...
			var clientSideSelect = new ClientSideSelect(
				new NonAggregatingGroupBySelectRewriter()
					.Visit(queryModel.SelectClause.Selector, subQueryExpression.Type.GetGenericArguments()[0], queryModel.MainFromClause));

			// Replace the outer select clause...
			queryModel.SelectClause = subQueryExpression.QueryModel.SelectClause;

			// Replace the outer from clause...
			queryModel.MainFromClause = subQueryExpression.QueryModel.MainFromClause;

			foreach (var bodyClause in subQueryExpression.QueryModel.BodyClauses)
			{
				queryModel.BodyClauses.Add(bodyClause);
			}

			// Move the result operator up 
			if (queryModel.ResultOperators.Count != 0)
			{
				throw new NotImplementedException();
			}

			queryModel.ResultOperators.Add(new NonAggregatingGroupBy((GroupResultOperator)subQueryExpression.QueryModel.ResultOperators[0]));
			queryModel.ResultOperators.Add(clientSideSelect);
		}
		protected override Expression VisitSubQueryExpression(SubQueryExpression subQuery)
		{
			var hasBodyClauses = subQuery.QueryModel.BodyClauses.Count > 0;
			if(hasBodyClauses)
			{
				return base.VisitSubQueryExpression(subQuery);
			}
			var resultOperators = subQuery.QueryModel.ResultOperators;
			if (resultOperators.Count == 0 || HasJustAllFlattenableOperator(resultOperators))
			{
				var selectQuerySource = subQuery.QueryModel.SelectClause.Selector as QuerySourceReferenceExpression;

				if (selectQuerySource != null && selectQuerySource.ReferencedQuerySource == subQuery.QueryModel.MainFromClause)
				{
					foreach (var resultOperator in resultOperators)
					{
						_model.ResultOperators.Add(resultOperator);
					}

					return subQuery.QueryModel.MainFromClause.FromExpression;
				}
			}

			return base.VisitSubQueryExpression(subQuery);
		}
    public void Replaces_SubQueryExpressions ()
    {
      var expression = new SubQueryExpression (ExpressionHelper.CreateQueryModel<Cook> ());
      var result = CloningExpressionTreeVisitor.AdjustExpressionAfterCloning (expression, _querySourceMapping);

      Assert.That (((SubQueryExpression) result).QueryModel, Is.Not.SameAs (expression.QueryModel));
    }
    public void VisitSubQuery_ExpressionUnchanged ()
    {
      var expression = new SubQueryExpression (ExpressionHelper.CreateQueryModel<Cook> ());
      var result = ReferenceReplacingExpressionTreeVisitor.ReplaceClauseReferences (expression, _querySourceMapping, false);

      Assert.That (((SubQueryExpression) result).QueryModel, Is.SameAs (expression.QueryModel));
    }
		private static void FlattenSubQuery(SubQueryExpression subQueryExpression, QueryModel queryModel)
		{
			// Create a new client-side select for the outer
			var clientSideSelect = CreateClientSideSelect(subQueryExpression, queryModel);

			var subQueryModel = subQueryExpression.QueryModel;

			// Replace the outer select clause...
			queryModel.SelectClause = subQueryModel.SelectClause;

			// Replace the outer from clause...
			queryModel.MainFromClause = subQueryModel.MainFromClause;

			foreach (var bodyClause in subQueryModel.BodyClauses)
			{
				queryModel.BodyClauses.Add(bodyClause);
			}

			// Move the result operator up 
			if (queryModel.ResultOperators.Count != 0)
			{
				throw new NotImplementedException();
			}

			queryModel.ResultOperators.Add(new NonAggregatingGroupBy((GroupResultOperator) subQueryModel.ResultOperators[0]));
			queryModel.ResultOperators.Add(clientSideSelect);
		}
    protected internal override Expression VisitSubQuery (SubQueryExpression expression)
    {
      ArgumentUtility.CheckNotNull ("expression", expression);

      expression.QueryModel.TransformExpressions (ReplaceTransparentIdentifiers);
      return expression; // Note that we modifiy the (mutable) QueryModel, we return an unchanged expression
    }
 protected override void FlattenSubQuery(SubQueryExpression subQueryExpression, FromClauseBase fromClause, QueryModel queryModel,
     int destinationIndex)
 {
     var subQueryModel = subQueryExpression.QueryModel;
     MoveResultOperatorsToParent(queryModel, subQueryModel);
     base.FlattenSubQuery(subQueryExpression, fromClause, queryModel, destinationIndex);
 }
예제 #9
0
        private void FlattenSubQuery(SubQueryExpression subQueryExpression, FromClauseBase fromClause,
		                             QueryModel queryModel)
        {
            // Move the result operator up
            if (queryModel.ResultOperators.Count != 0)
            {
                throw new NotImplementedException();
            }

            var groupBy = (GroupResultOperator) subQueryExpression.QueryModel.ResultOperators[0];

            // Replace the outer select clause...
            queryModel.SelectClause.TransformExpressions(s => GroupBySelectClauseRewriter.ReWrite(s, groupBy, subQueryExpression.QueryModel));

            queryModel.SelectClause.TransformExpressions(
                s =>
                new SwapQuerySourceVisitor(queryModel.MainFromClause, subQueryExpression.QueryModel.MainFromClause).Swap
                    (s));

            MainFromClause innerMainFromClause = subQueryExpression.QueryModel.MainFromClause;
            CopyFromClauseData(innerMainFromClause, fromClause);

            foreach (var bodyClause in subQueryExpression.QueryModel.BodyClauses)
            {
                queryModel.BodyClauses.Add(bodyClause);
            }

            queryModel.ResultOperators.Add(groupBy);
        }
    protected override Expression VisitSubQueryExpression (SubQueryExpression expression)
    {
      ArgumentUtility.CheckNotNull ("expression", expression);

      var clonedQueryModel = expression.QueryModel.Clone (QuerySourceMapping);
      return new SubQueryExpression (clonedQueryModel);
    }
예제 #11
0
		protected override Expression VisitSubQueryExpression(SubQueryExpression expression)
		{
			var selector = expression.QueryModel.SelectClause.Selector;

			var value = Expression.Parameter(typeof (Tuple), "value");

			var rewriter = new SelectClauseRewriter(value, values, expressions, tuple + 1);

			var resultSelector = rewriter.VisitExpression(selector);

			var where = EnumerableHelper.GetMethod("Where",
												   new[] {typeof (IEnumerable<>), typeof (Func<,>)},
												   new[] {Tuple.Type});

			var select = EnumerableHelper.GetMethod("Select",
													new[] {typeof (IEnumerable<>), typeof (Func<,>)},
													new[] {Tuple.Type, selector.Type});

			var toList = EnumerableHelper.GetMethod("ToList",
													new[] {typeof (IEnumerable<>)},
													new[] {selector.Type});

			return Expression.Call(Expression.Call(toList,
												   Expression.Call(select,
																   Expression.Call(where, values, WherePredicate),
																   Expression.Lambda(resultSelector, value))),
								   "AsReadOnly", System.Type.EmptyTypes);
		}
예제 #12
0
        private static bool CheckShortCircuitSum(SubQueryExpression expression, MainQueryParts queryParts, Action<Expression> visitExpression)
        {
            var subquery = SubqueryGeneratorQueryModelVisitor.ParseSubquery(expression.QueryModel, queryParts, true);
            if (subquery.ShouldQueryInMemory)
            {
                throw new NotImplementedException("Unsupported subquery. Please provide more info about query.");
                //return false;
            }

            var sql = subquery.BuildSqlString(false);
            var cnt = queryParts.CurrentSelectIndex;

            var selector = expression.QueryModel.SelectClause.Selector as MemberExpression;
            if (selector == null)
                return false;

            var type = expression.QueryModel.ResultTypeOverride;
            if (type.IsNullable())
                type = type.GetGenericArguments()[0];

            queryParts.AddSelectPart(
                expression.QueryModel.MainFromClause,
                @"(SELECT SUM((""{1}"").""{3}"") FROM ({2}) ""{1}"") AS ""{0}""".With(
                    "_subquery_" + cnt,
                    expression.QueryModel.MainFromClause.ItemName,
                    sql,
                    selector.Member.Name),
                "_sum_" + cnt,
                expression.QueryModel.ResultTypeOverride,
                (_, dr) => dr.IsDBNull(cnt) ? 0 : Convert.ChangeType(dr.GetValue(cnt), type));
            return true;
        }
    protected internal override Expression VisitSubQuery (SubQueryExpression expression)
    {
      ArgumentUtility.CheckNotNull ("expression", expression);

      expression.QueryModel.TransformExpressions (ex => ReplaceClauseReferences (ex, _querySourceMapping, _throwOnUnmappedReferences));
      return expression;
    }
        protected override Expression VisitSubQuery(SubQueryExpression expression)
        {
            var clonedModel = expression.QueryModel.Clone();

            clonedModel.TransformExpressions(Visit);

            return new SubQueryExpression(clonedModel);
        }
예제 #15
0
 public void Initialization ()
 {
   var queryModel = ExpressionHelper.CreateQueryModel<Cook>();
   var expression = new SubQueryExpression (queryModel);
   Assert.That (expression.Type, Is.SameAs (typeof(IQueryable<Cook>)));
   Assert.That (expression.QueryModel, Is.SameAs (queryModel));
   Assert.That (expression.NodeType, Is.EqualTo (SubQueryExpression.ExpressionType));
 }
        protected override Expression VisitSubQueryExpression(SubQueryExpression subQueryExpression)
        {
            var queryModelVisitor = CreateQueryModelVisitor();

            queryModelVisitor.VisitQueryModel(subQueryExpression.QueryModel);

            var subExpression = queryModelVisitor.Expression;

            var resultItemType
                = queryModelVisitor.StreamedSequenceInfo?.ResultItemType
                  ?? subExpression.Type;

            if (queryModelVisitor.StreamedSequenceInfo == null)
            {
                return subExpression;
            }

            if (subExpression.Type != subQueryExpression.Type)
            {
                var subQueryExpressionTypeInfo = subQueryExpression.Type.GetTypeInfo();

                if (typeof(IQueryable).GetTypeInfo().IsAssignableFrom(subQueryExpressionTypeInfo))
                {
                    subExpression
                        = Expression.Call(
                            QueryModelVisitor.LinqOperatorProvider.ToQueryable
                                .MakeGenericMethod(resultItemType),
                            subExpression);
                }
                else if (subQueryExpressionTypeInfo.IsGenericType)
                {
                    var genericTypeDefinition = subQueryExpressionTypeInfo.GetGenericTypeDefinition();

                    if (genericTypeDefinition == typeof(IOrderedEnumerable<>))
                    {
                        subExpression
                            = Expression.Call(
                                QueryModelVisitor.LinqOperatorProvider.ToOrdered
                                    .MakeGenericMethod(resultItemType),
                                subExpression);
                    }
                    else if (genericTypeDefinition == typeof(IEnumerable<>))
                    {
                        subExpression
                            = Expression.Call(
                                QueryModelVisitor.LinqOperatorProvider.ToEnumerable
                                    .MakeGenericMethod(resultItemType),
                                subExpression);
                    }
                }
            }

            return subExpression;
        }
예제 #17
0
    public void GetResolvedExpression_WithSubQueries ()
    {
      var parameterExpression = Expression.Parameter (typeof (int), "i");
      var subQueryExpression = new SubQueryExpression (ExpressionHelper.CreateQueryModel_Int ());
      subQueryExpression.QueryModel.SelectClause.Selector = parameterExpression;

      var result = (SubQueryExpression) _expressionResolver.GetResolvedExpression (subQueryExpression, parameterExpression, ClauseGenerationContext);

      var subQuerySelector = result.QueryModel.SelectClause.Selector;
      Assert.That (subQuerySelector, Is.InstanceOf (typeof (QuerySourceReferenceExpression)));
      Assert.That (((QuerySourceReferenceExpression) subQuerySelector).ReferencedQuerySource, Is.SameAs (SourceClause));
    }
    public void Replaces_SubQueryExpressions_WithCorrectCloneContext ()
    {
      var subQueryModel = ExpressionHelper.CreateQueryModel<Cook> ();
      var referencedClause = ExpressionHelper.CreateMainFromClause_Int ();
      subQueryModel.SelectClause.Selector = new QuerySourceReferenceExpression (referencedClause);
      var expression = new SubQueryExpression (subQueryModel);

      var newReferenceExpression = new QuerySourceReferenceExpression (ExpressionHelper.CreateMainFromClause_Int ());
      _querySourceMapping.AddMapping (referencedClause, newReferenceExpression);

      var result = CloningExpressionTreeVisitor.AdjustExpressionAfterCloning (expression, _querySourceMapping);
      var newSubQuerySelectClause = ((SubQueryExpression) result).QueryModel.SelectClause;
      Assert.That (newSubQuerySelectClause.Selector, Is.SameAs (newReferenceExpression));
    }
    public void ReplacesTreePart_InSubQueries ()
    {
      var replacedNode = ExpressionHelper.CreateQueryable<Cook> ().Expression;
      var replacementNode = Expression.Constant (null, typeof (Cook[]));

      var subQueryMainFromClause = new MainFromClause ("c", typeof (Cook), replacedNode);
      var subQuery = ExpressionHelper.CreateQueryModel (subQueryMainFromClause);

      var tree = new SubQueryExpression (subQuery);

      ReplacingExpressionVisitor.Replace (replacedNode, replacementNode, tree);

      Assert.That (subQueryMainFromClause.FromExpression, Is.SameAs (replacementNode));
    }
        private static ReqlExpr ResolveExtensionExpression( ReqlExpr reqlExpr, SubQueryExpression expression )
        {
            var subQueryVisitors = new List<ISubQueryVisitor>
            {
                new AnySubQueryVisitor(),
                new AllSubQueryVisitor(),
                new FirstAndLastSubQueryVisitor()
            };

            var subQueryVisitor = subQueryVisitors.FirstOrDefault( x => x.CanVisit( expression.QueryModel ) );

            if( subQueryVisitor == null )
                throw new NotSupportedException( "subqueries not allowed ." );

            return subQueryVisitor.Visit( reqlExpr, expression.QueryModel );
        }
        protected override Expression VisitSubQueryExpression(SubQueryExpression expression)
        {
            var operators = expression.QueryModel.ResultOperators;

            if (operators.Count == 1 && operators[0] is ContainsResultOperator)
            {
                var op = (ContainsResultOperator) operators[0];

                var field = expression.QueryModel.MainFromClause.FromExpression;
                var pattern = op.Item;

                return Expression.MakeBinary(ExpressionType.Equal, field, pattern);
            }
            
            return base.VisitSubQueryExpression(expression);
        }
        protected override Expression VisitSubQuery(SubQueryExpression expression)
        {
            var queryModelVisitor = CreateQueryModelVisitor();

            queryModelVisitor.VisitQueryModel(expression.QueryModel);

            var subExpression = queryModelVisitor.Expression;

            if (subExpression.Type != expression.Type)
            {
                var subQueryExpressionTypeInfo = expression.Type.GetTypeInfo();

                if (typeof(IQueryable).GetTypeInfo().IsAssignableFrom(expression.Type.GetTypeInfo()))
                {
                    subExpression
                        = Expression.Call(
                            QueryModelVisitor.LinqOperatorProvider.ToQueryable
                                .MakeGenericMethod(expression.Type.GetSequenceType()),
                            subExpression);
                }
                else if (subQueryExpressionTypeInfo.IsGenericType)
                {
                    var genericTypeDefinition = subQueryExpressionTypeInfo.GetGenericTypeDefinition();

                    if (genericTypeDefinition == typeof(IOrderedEnumerable<>))
                    {
                        subExpression
                            = Expression.Call(
                                QueryModelVisitor.LinqOperatorProvider.ToOrdered
                                    .MakeGenericMethod(expression.Type.GetSequenceType()),
                                subExpression);
                    }
                    else if (genericTypeDefinition == typeof(IEnumerable<>))
                    {
                        subExpression
                            = Expression.Call(
                                QueryModelVisitor.LinqOperatorProvider.ToEnumerable
                                    .MakeGenericMethod(expression.Type.GetSequenceType()),
                                subExpression);
                    }
                }
            }

            return subExpression;
        }
        protected override Expression VisitSubQueryExpression(SubQueryExpression subQueryExpression)
        {
            var queryModelVisitor = CreateQueryModelVisitor();

            queryModelVisitor.VisitQueryModel(subQueryExpression.QueryModel);

            var subExpression = queryModelVisitor.Expression;

            var streamedSequenceInfo
                = subQueryExpression.QueryModel.GetOutputDataInfo() as StreamedSequenceInfo;

            if (streamedSequenceInfo == null)
            {
                return subExpression;
            }

            var typeInfo = subQueryExpression.Type.GetTypeInfo();

            if (typeof(IQueryable).GetTypeInfo().IsAssignableFrom(typeInfo))
            {
                subExpression
                    = Expression.Call(
                        QueryModelVisitor.LinqOperatorProvider.AsQueryable
                            .MakeGenericMethod(streamedSequenceInfo.ResultItemType),
                        subExpression);
            }
            else if (typeInfo.IsGenericType
                     && typeInfo.GetGenericTypeDefinition() == typeof(IOrderedEnumerable<>))
            {
                var elementType
                    = subExpression.Type.TryGetElementType(typeof(IOrderedAsyncEnumerable<>));

                if (elementType != null)
                {
                    subExpression
                        = Expression.Call(
                            QueryModelVisitor.LinqOperatorProvider.AsQueryable
                                .MakeGenericMethod(streamedSequenceInfo.ResultItemType),
                            subExpression);
                }
            }

            return Expression.Convert(subExpression, subQueryExpression.Type);
        }
예제 #24
0
        private IWhereFragment GetWhereFragment(DocumentMapping mapping, SubQueryExpression expression)
        {
            var queryType = expression.QueryModel.MainFromClause.ItemType;
            if (TypeMappings.HasTypeMapping(queryType))
            {
                var contains = expression.QueryModel.ResultOperators.OfType<ContainsResultOperator>().FirstOrDefault();
                if (contains != null)
                {
                    return ContainmentWhereFragment.SimpleArrayContains(_serializer, expression.QueryModel, contains);
                }
            }

            if (expression.QueryModel.ResultOperators.Any(x => x is AnyResultOperator))
            {
                return new CollectionAnyContainmentWhereFragment(_serializer, expression);
            }

            throw new NotImplementedException();
        }
		protected override Expression VisitSubQueryExpression(SubQueryExpression expression)
		{
			// If the sub query's main (and only) from clause is one of our aggregating group bys, then swap it
			GroupJoinClause groupJoin = LocateGroupJoinQuerySource(expression.QueryModel);

			if (groupJoin != null)
			{
				Expression innerSelector = new SwapQuerySourceVisitor(groupJoin.JoinClause, expression.QueryModel.MainFromClause).
					Swap(groupJoin.JoinClause.InnerKeySelector);

				expression.QueryModel.MainFromClause.FromExpression = groupJoin.JoinClause.InnerSequence;


				// TODO - this only works if the key selectors are not composite.  Needs improvement...
				expression.QueryModel.BodyClauses.Add(new WhereClause(Expression.Equal(innerSelector, groupJoin.JoinClause.OuterKeySelector)));
			}

			return expression;
		}
		private static void FlattenSubQuery(SubQueryExpression subQueryExpression, FromClauseBase fromClause, QueryModel queryModel, int destinationIndex)
		{
			if (!CheckFlattenable(subQueryExpression.QueryModel))
				return;

			var mainFromClause = subQueryExpression.QueryModel.MainFromClause;
			CopyFromClauseData(mainFromClause, fromClause);

			var innerSelectorMapping = new QuerySourceMapping();
			innerSelectorMapping.AddMapping(fromClause, subQueryExpression.QueryModel.SelectClause.Selector);
			queryModel.TransformExpressions((ex => ReferenceReplacingExpressionTreeVisitor.ReplaceClauseReferences(ex, innerSelectorMapping, false)));

			InsertBodyClauses(subQueryExpression.QueryModel.BodyClauses, queryModel, destinationIndex);
			CopyResultOperators(subQueryExpression.QueryModel.ResultOperators, queryModel);

			var innerBodyClauseMapping = new QuerySourceMapping();
			innerBodyClauseMapping.AddMapping(mainFromClause, new QuerySourceReferenceExpression(fromClause));
			queryModel.TransformExpressions((ex => ReferenceReplacingExpressionTreeVisitor.ReplaceClauseReferences(ex, innerBodyClauseMapping, false)));
		}
		private static void FlattenSubQuery(SubQueryExpression subQueryExpression, QueryModel queryModel)
		{
			// Move the result operator up 
			if (queryModel.ResultOperators.Count != 0)
			{
				throw new NotImplementedException();
			}

			var groupBy = (GroupResultOperator) subQueryExpression.QueryModel.ResultOperators[0];

			queryModel.ResultOperators.Add(groupBy);

			for (int i = 0; i < queryModel.BodyClauses.Count; i++)
			{
				var clause = queryModel.BodyClauses[i];
				clause.TransformExpressions(s => GroupBySelectClauseRewriter.ReWrite(s, groupBy, subQueryExpression.QueryModel));

				//all outer where clauses actually are having clauses
				var whereClause = clause as WhereClause;
				if (whereClause != null)
				{
					queryModel.BodyClauses.RemoveAt(i);
					queryModel.BodyClauses.Insert(i, new NhHavingClause(whereClause.Predicate));
				}
			}

			foreach (var bodyClause in subQueryExpression.QueryModel.BodyClauses)
			{
				queryModel.BodyClauses.Add(bodyClause);
			}

			// Replace the outer select clause...
			queryModel.SelectClause.TransformExpressions(s => 
				GroupBySelectClauseRewriter.ReWrite(s, groupBy, subQueryExpression.QueryModel));

			// Point all query source references to the outer from clause
			queryModel.TransformExpressions(s =>
				new SwapQuerySourceVisitor(queryModel.MainFromClause, subQueryExpression.QueryModel.MainFromClause).Swap(s));

			// Replace the outer query source
			queryModel.MainFromClause = subQueryExpression.QueryModel.MainFromClause;
		}
예제 #28
0
		private static void FlattenSubQuery(SubQueryExpression subQueryExpression, QueryModel queryModel)
		{
			// we can not flattern subquery if outer query has body clauses.
			var subQueryModel = subQueryExpression.QueryModel;
			var subQueryMainFromClause = subQueryModel.MainFromClause;
			if (queryModel.BodyClauses.Count == 0)
			{
				foreach (var resultOperator in subQueryModel.ResultOperators)
					queryModel.ResultOperators.Add(resultOperator);

				foreach (var bodyClause in subQueryModel.BodyClauses)
					queryModel.BodyClauses.Add(bodyClause);
			}
			else
			{
				var cro = new ContainsResultOperator(new QuerySourceReferenceExpression(subQueryMainFromClause));

				var newSubQueryModel = subQueryModel.Clone();
				newSubQueryModel.ResultOperators.Add(cro);
				newSubQueryModel.ResultTypeOverride = typeof (bool);

				var where = new WhereClause(new SubQueryExpression(newSubQueryModel));
				queryModel.BodyClauses.Add(where);

				if (!queryModel.BodyClauses.OfType<OrderByClause>().Any())
				{
					var orderByClauses = subQueryModel.BodyClauses.OfType<OrderByClause>();
					foreach (var orderByClause in orderByClauses)
						queryModel.BodyClauses.Add(orderByClause);
				}
			}

			var visitor1 = new PagingRewriterSelectClauseVisitor();
			queryModel.SelectClause.TransformExpressions(visitor1.Swap);

			// Point all query source references to the outer from clause
			var visitor2 = new SwapQuerySourceVisitor(queryModel.MainFromClause, subQueryMainFromClause);
			queryModel.TransformExpressions(visitor2.Swap);

			// Replace the outer query source
			queryModel.MainFromClause = subQueryMainFromClause;
		}
        protected override Expression VisitSubQueryExpression(SubQueryExpression expression)
        {
            var operators = expression.QueryModel.ResultOperators;

            if (operators.Count == 1 && operators[0] is ContainsResultOperator)
            {
                var op = (ContainsResultOperator) operators[0];

                var field = expression.QueryModel.MainFromClause.FromExpression;
                var pattern = op.Item;
                if (pattern.Type.IsPrimitive)
                {
                    pattern = Expression.Constant(((ConstantExpression)pattern).Value, typeof(object));
                }

                return Expression.MakeBinary(ExpressionType.Equal, field, pattern);
            }

            return base.VisitSubQueryExpression(expression);
        }
예제 #30
0
        private static bool CheckShortCircuitCount(SubQueryExpression expression, MainQueryParts queryParts, Action<Expression> visitExpression)
        {
            var subquery = SubqueryGeneratorQueryModelVisitor.ParseSubquery(expression.QueryModel, queryParts, true);
            if (subquery.ShouldQueryInMemory)
            {
                throw new NotImplementedException("Unsupported subquery. Please provide more info about query.");
                //return false;
            }

            var cnt = queryParts.CurrentSelectIndex;

            var mq = subquery.MainFrom.FromExpression as QuerySourceReferenceExpression;
            if (mq != null && subquery.Joins.Count == 0 && subquery.AdditionalJoins.Count == 0 && subquery.Conditions.Count == 0)
            {
                if (mq.ReferencedQuerySource.ItemType.IsGrouping())
                {
                    queryParts.AddSelectPart(
                        expression.QueryModel.MainFromClause,
                        "ARRAY_UPPER(\"{0}\".\"Values\", 1) AS \"_count_helper_{1}\"".With(mq.ReferencedQuerySource.ItemName, cnt),
                        "_count_helper_" + cnt,
                        expression.QueryModel.ResultTypeOverride,
                        (_, dr) => dr.IsDBNull(cnt) ? 0 : Convert.ChangeType(dr.GetValue(cnt), expression.QueryModel.ResultTypeOverride));
                    return true;
                }
            }

            var sql = subquery.BuildSqlString(false);

            queryParts.AddSelectPart(
                expression.QueryModel.MainFromClause,
                @"(SELECT COUNT(""{1}"") FROM ({2}) ""{1}"") AS ""{0}"" ".With(
                    "_subquery_" + cnt,
                    expression.QueryModel.MainFromClause.ItemName,
                    sql),
                "_count_" + cnt,
                expression.QueryModel.ResultTypeOverride,
                (_, dr) => dr.IsDBNull(cnt) ? 0 : Convert.ChangeType(dr.GetValue(cnt), expression.QueryModel.ResultTypeOverride));
            return true;
        }
예제 #31
0
 /// <summary>
 /// We are going after a query model - bounce this back up a level.
 /// </summary>
 /// <param name="expression"></param>
 /// <returns></returns>
 protected override System.Linq.Expressions.Expression VisitSubQuery(Remotion.Linq.Clauses.Expressions.SubQueryExpression expression)
 {
     _qmVisitor.VisitQueryModel(expression.QueryModel);
     return(expression);
 }