/// <exception cref="NotSupportedException">N1Ql Bucket Subqueries Require A UseKeys Call</exception> public override void VisitMainFromClause(MainFromClause fromClause, QueryModel queryModel) { var bucketConstantExpression = fromClause.FromExpression as ConstantExpression; if ((bucketConstantExpression != null) && typeof(IBucketQueryable).IsAssignableFrom(bucketConstantExpression.Type)) { if (_isSubQuery && !queryModel.BodyClauses.Any(p => p is UseKeysClause)) { throw new NotSupportedException("N1Ql Bucket Subqueries Require A UseKeys Call"); } _queryPartsAggregator.AddFromPart(new N1QlFromQueryPart() { Source = N1QlHelpers.EscapeIdentifier(((IBucketQueryable) bucketConstantExpression.Value).BucketName), ItemName = GetExtentName(fromClause) }); } else if (fromClause.FromExpression.NodeType == ExpressionType.MemberAccess) { if (!_isSubQuery) { throw new NotSupportedException("Member Access In The Main From Clause Is Only Supported In Subqueries"); } _queryPartsAggregator.AddFromPart(new N1QlFromQueryPart() { Source = GetN1QlExpression((MemberExpression) fromClause.FromExpression), ItemName = GetExtentName(fromClause) }); // This is an Array type subquery, since we're querying against a member not a bucket _queryPartsAggregator.QueryType = N1QlQueryType.Array; } else if (fromClause.FromExpression.NodeType == SubQueryExpression.ExpressionType) { var subQuery = (SubQueryExpression) fromClause.FromExpression; if (!subQuery.QueryModel.ResultOperators.Any(p => p is GroupResultOperator)) { throw new NotSupportedException("Subqueries In The Main From Clause Are Only Supported For Grouping"); } _groupingStatus = GroupingStatus.InGroupSubquery; _queryGenerationContext.GroupingQuerySource = new QuerySourceReferenceExpression(fromClause); VisitQueryModel(subQuery.QueryModel); _groupingStatus = GroupingStatus.AfterGroupSubquery; } else if (fromClause.FromExpression.NodeType == QuerySourceReferenceExpression.ExpressionType) { if (!fromClause.FromExpression.Equals(_queryGenerationContext.GroupingQuerySource)) { throw new NotSupportedException("From Clauses May Not Reference Any Query Source Other Than The Grouping Subquery"); } // We're performing an aggregate against a group _queryPartsAggregator.QueryType = N1QlQueryType.Aggregate; // Ensure that we use the same extent name as the grouping _queryGenerationContext.ExtentNameProvider.LinkExtents(_queryGenerationContext.GroupingQuerySource.ReferencedQuerySource, fromClause); } base.VisitMainFromClause(fromClause, queryModel); }
/// <exception cref="NotSupportedException">N1Ql Bucket Subqueries Require A UseKeys Call</exception> public override void VisitMainFromClause(MainFromClause fromClause, QueryModel queryModel) { var bucketConstantExpression = fromClause.FromExpression as ConstantExpression; if ((bucketConstantExpression != null) && typeof(IBucketQueryable).IsAssignableFrom(bucketConstantExpression.Type)) { if (_isSubQuery && !queryModel.BodyClauses.Any(p => p is UseKeysClause)) { throw new NotSupportedException("N1Ql Bucket Subqueries Require A UseKeys Call"); } _queryPartsAggregator.AddFromPart(new N1QlFromQueryPart() { Source = N1QlHelpers.EscapeIdentifier(((IBucketQueryable)bucketConstantExpression.Value).BucketName), ItemName = GetExtentName(fromClause) }); } else if (fromClause.FromExpression.NodeType == ExpressionType.MemberAccess) { if (!_isSubQuery) { throw new NotSupportedException("Member Access In The Main From Clause Is Only Supported In Subqueries"); } _queryPartsAggregator.AddFromPart(new N1QlFromQueryPart() { Source = GetN1QlExpression((MemberExpression)fromClause.FromExpression), ItemName = GetExtentName(fromClause) }); // This is an Array type subquery, since we're querying against a member not a bucket _queryPartsAggregator.QueryType = N1QlQueryType.Array; } else if (fromClause.FromExpression.NodeType == SubQueryExpression.ExpressionType) { var subQuery = (SubQueryExpression)fromClause.FromExpression; if (!subQuery.QueryModel.ResultOperators.Any(p => p is GroupResultOperator)) { throw new NotSupportedException("Subqueries In The Main From Clause Are Only Supported For Grouping"); } _groupingStatus = GroupingStatus.InGroupSubquery; _queryGenerationContext.GroupingQuerySource = new QuerySourceReferenceExpression(fromClause); VisitQueryModel(subQuery.QueryModel); _groupingStatus = GroupingStatus.AfterGroupSubquery; } else if (fromClause.FromExpression.NodeType == QuerySourceReferenceExpression.ExpressionType) { if (!fromClause.FromExpression.Equals(_queryGenerationContext.GroupingQuerySource)) { throw new NotSupportedException("From Clauses May Not Reference Any Query Source Other Than The Grouping Subquery"); } // We're performing an aggregate against a group _queryPartsAggregator.QueryType = N1QlQueryType.Aggregate; // Ensure that we use the same extent name as the grouping _queryGenerationContext.ExtentNameProvider.LinkExtents(_queryGenerationContext.GroupingQuerySource.ReferencedQuerySource, fromClause); } base.VisitMainFromClause(fromClause, queryModel); }