/// <summary>
        /// Helper method to create a stream feed iterator.
        /// It decides if it is a query or read feed and create
        /// the correct instance.
        /// </summary>
        public override FeedIteratorInternal GetItemQueryStreamIteratorInternal(
            SqlQuerySpec sqlQuerySpec,
            bool isContinuationExcpected,
            string continuationToken,
            FeedRangeInternal feedRange,
            QueryRequestOptions requestOptions)
        {
            requestOptions ??= new QueryRequestOptions();

            if (requestOptions.IsEffectivePartitionKeyRouting)
            {
                if (feedRange != null)
                {
                    throw new ArgumentException(nameof(feedRange), ClientResources.FeedToken_EffectivePartitionKeyRouting);
                }

                requestOptions.PartitionKey = null;
            }

            if (sqlQuerySpec == null)
            {
                NetworkAttachedDocumentContainer networkAttachedDocumentContainer = new NetworkAttachedDocumentContainer(
                    this,
                    this.queryClient,
                    requestOptions);

                DocumentContainer documentContainer = new DocumentContainer(networkAttachedDocumentContainer);

                ReadFeedPaginationOptions.PaginationDirection?direction = null;
                if ((requestOptions.Properties != null) && requestOptions.Properties.TryGetValue(HttpConstants.HttpHeaders.EnumerationDirection, out object enumerationDirection))
                {
                    direction = (byte)enumerationDirection == (byte)RntbdConstants.RntdbEnumerationDirection.Reverse ? ReadFeedPaginationOptions.PaginationDirection.Reverse : ReadFeedPaginationOptions.PaginationDirection.Forward;
                }

                ReadFeedPaginationOptions readFeedPaginationOptions = new ReadFeedPaginationOptions(
                    direction,
                    pageSizeHint: requestOptions.MaxItemCount ?? int.MaxValue);

                return(new ReadFeedIteratorCore(
                           documentContainer,
                           continuationToken,
                           readFeedPaginationOptions,
                           requestOptions,
                           cancellationToken: default));
            }

            return(QueryIterator.Create(
                       containerCore: this,
                       client: this.queryClient,
                       clientContext: this.ClientContext,
                       sqlQuerySpec: sqlQuerySpec,
                       continuationToken: continuationToken,
                       feedRangeInternal: feedRange,
                       queryRequestOptions: requestOptions,
                       resourceLink: this.LinkUri,
                       isContinuationExpected: isContinuationExcpected,
                       allowNonValueAggregateQuery: true,
                       forcePassthrough: false,
                       partitionedQueryExecutionInfo: null));
        }
        /// <summary>
        /// Helper method to create a stream feed iterator.
        /// It decides if it is a query or read feed and create
        /// the correct instance.
        /// </summary>
        internal FeedIterator GetItemQueryStreamIteratorInternal(
            SqlQuerySpec sqlQuerySpec,
            bool isContinuationExcpected,
            string continuationToken,
            QueryRequestOptions requestOptions)
        {
            requestOptions = requestOptions ?? new QueryRequestOptions();

            if (requestOptions.IsEffectivePartitionKeyRouting)
            {
                requestOptions.PartitionKey = null;
            }

            if (sqlQuerySpec == null)
            {
                return(new FeedIteratorCore(
                           this.ClientContext,
                           this.LinkUri,
                           resourceType: ResourceType.Document,
                           queryDefinition: null,
                           continuationToken: continuationToken,
                           options: requestOptions));
            }

            return(QueryIterator.Create(
                       client: this.queryClient,
                       sqlQuerySpec: sqlQuerySpec,
                       continuationToken: continuationToken,
                       queryRequestOptions: requestOptions,
                       resourceLink: this.LinkUri,
                       isContinuationExpected: isContinuationExcpected,
                       allowNonValueAggregateQuery: true,
                       partitionedQueryExecutionInfo: null));
        }
        public override FeedIteratorInternal GetReadFeedIterator(
            QueryDefinition queryDefinition,
            QueryRequestOptions queryRequestOptions,
            string resourceLink,
            ResourceType resourceType,
            string continuationToken,
            int pageSize)
        {
            queryRequestOptions ??= new QueryRequestOptions();

            NetworkAttachedDocumentContainer networkAttachedDocumentContainer = new NetworkAttachedDocumentContainer(
                this,
                this.queryClient,
                queryRequestOptions,
                resourceLink: resourceLink,
                resourceType: resourceType);

            DocumentContainer documentContainer = new DocumentContainer(networkAttachedDocumentContainer);

            FeedIteratorInternal feedIterator;

            if (queryDefinition != null)
            {
                feedIterator = QueryIterator.Create(
                    containerCore: this,
                    client: this.queryClient,
                    clientContext: this.ClientContext,
                    sqlQuerySpec: queryDefinition.ToSqlQuerySpec(),
                    continuationToken: continuationToken,
                    feedRangeInternal: FeedRangeEpk.FullRange,
                    queryRequestOptions: queryRequestOptions,
                    resourceLink: resourceLink,
                    isContinuationExpected: false,
                    allowNonValueAggregateQuery: true,
                    forcePassthrough: false,
                    partitionedQueryExecutionInfo: null);
            }
            else
            {
                ReadFeedPaginationOptions.PaginationDirection?direction = null;
                if ((queryRequestOptions.Properties != null) && queryRequestOptions.Properties.TryGetValue(HttpConstants.HttpHeaders.EnumerationDirection, out object enumerationDirection))
                {
                    direction = (byte)enumerationDirection == (byte)RntbdConstants.RntdbEnumerationDirection.Reverse ? ReadFeedPaginationOptions.PaginationDirection.Reverse : ReadFeedPaginationOptions.PaginationDirection.Forward;
                }

                ReadFeedPaginationOptions readFeedPaginationOptions = new ReadFeedPaginationOptions(
                    direction,
                    pageSizeHint: queryRequestOptions.MaxItemCount ?? int.MaxValue);

                feedIterator = new ReadFeedIteratorCore(
                    documentContainer: documentContainer,
                    queryRequestOptions: queryRequestOptions,
                    continuationToken: continuationToken,
                    readFeedPaginationOptions: readFeedPaginationOptions,
                    cancellationToken: default);
Example #4
0
        public override Node VisitQueryIterator(QueryIterator xiterator)
        {
            xiterator.Expression = this.VisitExpression(xiterator.Expression);
            Composer c    = this.GetComposer(xiterator.Expression);
            Composer save = this.contextComposer;

            this.contextComposer = c;
            this.VisitExpressionList(xiterator.HintList);
            this.contextComposer = save;
            return((Expression)this.Compose(xiterator, c));
        }
Example #5
0
        /// <summary>
        /// Helper method to create a stream feed iterator.
        /// It decides if it is a query or read feed and create
        /// the correct instance.
        /// </summary>
        public override FeedIteratorInternal GetItemQueryStreamIteratorInternal(
            SqlQuerySpec sqlQuerySpec,
            bool isContinuationExcpected,
            string continuationToken,
            FeedRangeInternal feedRange,
            QueryRequestOptions requestOptions)
        {
            requestOptions = requestOptions ?? new QueryRequestOptions();

            if (requestOptions.IsEffectivePartitionKeyRouting)
            {
                if (feedRange != null)
                {
                    throw new ArgumentException(nameof(feedRange), ClientResources.FeedToken_EffectivePartitionKeyRouting);
                }

                requestOptions.PartitionKey = null;
            }

            if (sqlQuerySpec == null)
            {
                return(FeedRangeIteratorCore.Create(
                           containerCore: this,
                           continuation: continuationToken,
                           feedRangeInternal: feedRange,
                           options: requestOptions));
            }

            return(QueryIterator.Create(
                       containerCore: this,
                       client: this.queryClient,
                       clientContext: this.ClientContext,
                       sqlQuerySpec: sqlQuerySpec,
                       continuationToken: continuationToken,
                       feedRangeInternal: feedRange,
                       queryRequestOptions: requestOptions,
                       resourceLink: this.LinkUri,
                       isContinuationExpected: isContinuationExcpected,
                       allowNonValueAggregateQuery: true,
                       forcePassthrough: false,
                       partitionedQueryExecutionInfo: null));
        }
Example #6
0
        /// <summary>
        /// Helper method to create a stream feed iterator.
        /// It decides if it is a query or read feed and create
        /// the correct instance.
        /// </summary>
        internal FeedIteratorInternal GetItemQueryStreamIteratorInternal(
            SqlQuerySpec sqlQuerySpec,
            bool isContinuationExcpected,
            string continuationToken,
            FeedTokenInternal feedToken,
            QueryRequestOptions requestOptions)
        {
            requestOptions = requestOptions ?? new QueryRequestOptions();

            if (requestOptions.IsEffectivePartitionKeyRouting)
            {
                if (feedToken != null)
                {
                    throw new ArgumentException(nameof(feedToken), ClientResources.FeedToken_EffectivePartitionKeyRouting);
                }

                requestOptions.PartitionKey = null;
            }

            if (sqlQuerySpec == null)
            {
                return(FeedIteratorCore.CreateForPartitionedResource(
                           this,
                           this.LinkUri,
                           resourceType: ResourceType.Document,
                           queryDefinition: null,
                           continuationToken: continuationToken,
                           feedTokenInternal: feedToken,
                           options: requestOptions));
            }

            return(QueryIterator.Create(
                       client: this.queryClient,
                       sqlQuerySpec: sqlQuerySpec,
                       continuationToken: continuationToken,
                       queryRequestOptions: requestOptions,
                       resourceLink: this.LinkUri,
                       isContinuationExpected: isContinuationExcpected,
                       allowNonValueAggregateQuery: true,
                       partitionedQueryExecutionInfo: null));
        }
Example #7
0
 public override Node VisitQueryIterator(QueryIterator qi) {
   if (qi == null) return null;
   Class cc = this.currentMethod.Scope.ClosureClass;
   qi.Expression = this.VisitExpression(qi.Expression);
   if (qi.Expression == null || qi.Expression.Type == null) return null;
   Cardinality card = this.typeSystem.GetCardinality(qi.Expression, this.TypeViewer);
   if (card != Cardinality.OneOrMore && card != Cardinality.ZeroOrMore) {
     this.HandleError(qi.Expression, Error.QueryNotStream);
     return null;
   }
   qi.HintList = this.VisitExpressionList(qi.HintList);
   if (qi.Type == null) return null;
   return qi;
 }
Example #8
0
 public override Node VisitQueryIterator(QueryIterator xiterator){
   if (xiterator == null) return null;
   this.VisitResolvedTypeReference(xiterator.Type, xiterator.TypeExpression);
   return base.VisitQueryIterator(xiterator);
 }
        /// <summary>
        /// Used in the compute gateway to support legacy gateway interface.
        /// </summary>
        public override async Task <TryExecuteQueryResult> TryExecuteQueryAsync(
            QueryFeatures supportedQueryFeatures,
            QueryDefinition queryDefinition,
            string continuationToken,
            FeedRangeInternal feedRangeInternal,
            QueryRequestOptions requestOptions,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            if (queryDefinition == null)
            {
                throw new ArgumentNullException(nameof(queryDefinition));
            }

            if (requestOptions == null)
            {
                throw new ArgumentNullException(nameof(requestOptions));
            }

            if (feedRangeInternal != null)
            {
                // The user has scoped down to a physical partition or logical partition.
                // In either case let the query execute as a passthrough.
                QueryIterator passthroughQueryIterator = QueryIterator.Create(
                    client: this.queryClient,
                    clientContext: this.ClientContext,
                    sqlQuerySpec: queryDefinition.ToSqlQuerySpec(),
                    continuationToken: continuationToken,
                    feedRangeInternal: feedRangeInternal,
                    queryRequestOptions: requestOptions,
                    resourceLink: this.LinkUri,
                    isContinuationExpected: false,
                    allowNonValueAggregateQuery: true,
                    forcePassthrough: true, // Forcing a passthrough, since we don't want to get the query plan nor try to rewrite it.
                    partitionedQueryExecutionInfo: null);

                return(new QueryPlanIsSupportedResult(passthroughQueryIterator));
            }

            cancellationToken.ThrowIfCancellationRequested();

            Documents.PartitionKeyDefinition partitionKeyDefinition;
            if (requestOptions.Properties != null &&
                requestOptions.Properties.TryGetValue("x-ms-query-partitionkey-definition", out object partitionKeyDefinitionObject))
            {
                if (partitionKeyDefinitionObject is Documents.PartitionKeyDefinition definition)
                {
                    partitionKeyDefinition = definition;
                }
                else
                {
                    throw new ArgumentException(
                              "partitionkeydefinition has invalid type",
                              nameof(partitionKeyDefinitionObject));
                }
            }
            else
            {
                ContainerQueryProperties containerQueryProperties = await this.queryClient.GetCachedContainerQueryPropertiesAsync(
                    this.LinkUri,
                    requestOptions.PartitionKey,
                    cancellationToken);

                partitionKeyDefinition = containerQueryProperties.PartitionKeyDefinition;
            }

            QueryPlanHandler queryPlanHandler = new QueryPlanHandler(this.queryClient);

            TryCatch <(PartitionedQueryExecutionInfo queryPlan, bool supported)> tryGetQueryInfoAndIfSupported = await queryPlanHandler.TryGetQueryInfoAndIfSupportedAsync(
                supportedQueryFeatures,
                queryDefinition.ToSqlQuerySpec(),
                partitionKeyDefinition,
                requestOptions.PartitionKey.HasValue,
                cancellationToken);

            if (tryGetQueryInfoAndIfSupported.Failed)
            {
                return(new FailedToGetQueryPlanResult(tryGetQueryInfoAndIfSupported.Exception));
            }

            (PartitionedQueryExecutionInfo queryPlan, bool supported) = tryGetQueryInfoAndIfSupported.Result;
            TryExecuteQueryResult tryExecuteQueryResult;

            if (supported)
            {
                QueryIterator queryIterator = QueryIterator.Create(
                    client: this.queryClient,
                    clientContext: this.ClientContext,
                    sqlQuerySpec: queryDefinition.ToSqlQuerySpec(),
                    continuationToken: continuationToken,
                    feedRangeInternal: feedRangeInternal,
                    queryRequestOptions: requestOptions,
                    resourceLink: this.LinkUri,
                    isContinuationExpected: false,
                    allowNonValueAggregateQuery: true,
                    forcePassthrough: false,
                    partitionedQueryExecutionInfo: queryPlan);

                tryExecuteQueryResult = new QueryPlanIsSupportedResult(queryIterator);
            }
            else
            {
                tryExecuteQueryResult = new QueryPlanNotSupportedResult(queryPlan);
            }

            return(tryExecuteQueryResult);
        }
        /// <summary>
        /// Used in the compute gateway to support legacy gateway interface.
        /// </summary>
        internal async Task <((Exception, PartitionedQueryExecutionInfo), (bool, QueryIterator))> TryExecuteQueryAsync(
            QueryFeatures supportedQueryFeatures,
            QueryDefinition queryDefinition,
            string continuationToken,
            QueryRequestOptions requestOptions,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            if (queryDefinition == null)
            {
                throw new ArgumentNullException(nameof(queryDefinition));
            }

            if (requestOptions == null)
            {
                throw new ArgumentNullException(nameof(requestOptions));
            }

            cancellationToken.ThrowIfCancellationRequested();

            Documents.PartitionKeyDefinition partitionKeyDefinition;
            if (requestOptions.Properties != null &&
                requestOptions.Properties.TryGetValue("x-ms-query-partitionkey-definition", out object partitionKeyDefinitionObject))
            {
                if (partitionKeyDefinitionObject is Documents.PartitionKeyDefinition definition)
                {
                    partitionKeyDefinition = definition;
                }
                else
                {
                    throw new ArgumentException(
                              "partitionkeydefinition has invalid type",
                              nameof(partitionKeyDefinitionObject));
                }
            }
            else
            {
                ContainerQueryProperties containerQueryProperties = await this.queryClient.GetCachedContainerQueryPropertiesAsync(
                    this.LinkUri,
                    requestOptions.PartitionKey,
                    cancellationToken);

                partitionKeyDefinition = containerQueryProperties.PartitionKeyDefinition;
            }

            QueryPlanHandler queryPlanHandler = new QueryPlanHandler(this.queryClient);

            ((Exception exception, PartitionedQueryExecutionInfo partitionedQueryExecutionInfo), bool supported) = await queryPlanHandler.TryGetQueryInfoAndIfSupportedAsync(
                supportedQueryFeatures,
                queryDefinition.ToSqlQuerySpec(),
                partitionKeyDefinition,
                requestOptions.PartitionKey.HasValue,
                cancellationToken);

            if (exception != null)
            {
                return((exception, null), (false, null));
            }

            QueryIterator queryIterator;

            if (supported)
            {
                queryIterator = QueryIterator.Create(
                    client: this.queryClient,
                    clientContext: this.ClientContext,
                    sqlQuerySpec: queryDefinition.ToSqlQuerySpec(),
                    continuationToken: continuationToken,
                    queryRequestOptions: requestOptions,
                    resourceLink: this.LinkUri,
                    isContinuationExpected: false,
                    allowNonValueAggregateQuery: true,
                    partitionedQueryExecutionInfo: partitionedQueryExecutionInfo);
            }
            else
            {
                queryIterator = null;
            }

            return((null, partitionedQueryExecutionInfo), (supported, queryIterator));
        }
Example #11
0
 public override Node VisitQueryIterator(QueryIterator xiterator){
   if (xiterator == null) return xiterator;
   return base.VisitQueryIterator((QueryIterator)xiterator.Clone());
 }
Example #12
0
 public virtual Node VisitQueryIterator(QueryIterator xiterator1, QueryIterator xiterator2){
   if (xiterator1 == null) return null;
   if (xiterator2 == null){
     xiterator1.Expression = this.VisitExpression(xiterator1.Expression, null);
     xiterator1.HintList = this.VisitExpressionList(xiterator1.HintList, null);
   }else{
     xiterator1.Expression = this.VisitExpression(xiterator1.Expression, xiterator2.Expression);
     xiterator1.HintList = this.VisitExpressionList(xiterator1.HintList, xiterator2.HintList);
   }
   return xiterator1;      
 }
Example #13
0
 public override Node VisitQueryIterator(QueryIterator qi) {
   // creates an iterator that encapsulates the original items as named members
   Block body = null;
   Node closure = this.StartQueryClosure(qi.ElementType, "iterator", out body);
   Expression target = null;
   Block inner = null;
   body.Statements.Add(this.BuildClosureForEach(qi.Expression, ref target, out inner, body.Scope));
   Local loc = new Local(qi.ElementType);
   Field f = this.GetTypeView(qi.ElementType).GetMembersNamed(qi.Name)[0] as Field;
   MemberBinding mb = new MemberBinding(loc, f); mb.Type = f.Type;
   inner.Statements.Add(new AssignmentStatement(mb, target));
   inner.Statements.Add(new Yield(loc));
   return this.EndQueryClosure(closure, qi.Type);
 }
Example #14
0
 public override Node VisitQueryIterator(QueryIterator xiterator){
   base.VisitQueryIterator(xiterator);
   if (xiterator.ElementType != null){
     xiterator.ElementType = this.VisitTypeReference(xiterator.ElementType);
   }
   // add to query scope
   if (this.scope is QueryScope){
     Field f = new Field();
     f.DeclaringType = this.scope;
     f.Flags = FieldFlags.CompilerControlled|FieldFlags.InitOnly;
     f.Name = xiterator.Name;
     f.Type = null;
     this.scope.Members.Add(f);
   }
   return xiterator; 
 }
Example #15
0
 public override Node VisitQueryIterator(QueryIterator xiterator) {
   xiterator.Expression = this.VisitExpression(xiterator.Expression);
   Composer c = this.GetComposer(xiterator.Expression);
   Composer save = this.contextComposer;
   this.contextComposer = c;
   this.VisitExpressionList(xiterator.HintList);
   this.contextComposer = save;
   return (Expression) this.Compose(xiterator, c);
 }    
Example #16
0
 public virtual Node VisitQueryIterator(QueryIterator xiterator){
   if (xiterator == null) return xiterator;
   xiterator.Expression = this.VisitExpression(xiterator.Expression);
   xiterator.HintList = this.VisitExpressionList(xiterator.HintList);
   return xiterator;      
 }
    public virtual Differences VisitQueryIterator(QueryIterator iterator1, QueryIterator iterator2){
      Differences differences = new Differences(iterator1, iterator2);
      if (iterator1 == null || iterator2 == null){
        if (iterator1 != iterator2) differences.NumberOfDifferences++; else differences.NumberOfSimilarities++;
        return differences;
      }
      QueryIterator changes = (QueryIterator)iterator2.Clone();
      QueryIterator deletions = (QueryIterator)iterator2.Clone();
      QueryIterator insertions = (QueryIterator)iterator2.Clone();

      //      iterator1.ElementType;
      //      iterator1.Expression;
      //      iterator1.HintList;
      //      iterator1.Name;

      if (differences.NumberOfDifferences == 0){
        differences.Changes = null;
        differences.Deletions = null;
        differences.Insertions = null;
      }else{
        differences.Changes = changes;
        differences.Deletions = deletions;
        differences.Insertions = insertions;
      }
      return differences;
    }
Example #18
0
 public virtual void VisitQueryIterator(QueryIterator xiterator){
   if (xiterator == null) return;
   this.VisitExpression(xiterator.Expression);
   this.VisitExpressionList(xiterator.HintList);
 }
Example #19
0
 public virtual Node VisitQueryIterator(QueryIterator xiterator, QueryIterator changes, QueryIterator deletions, QueryIterator insertions){
   this.UpdateSourceContext(xiterator, changes);
   if (xiterator == null) return changes;
   if (changes != null){
     if (deletions == null || insertions == null)
       Debug.Assert(false);
     else{
     }
   }else if (deletions != null)
     return null;
   return xiterator;      
 }
Example #20
0
 public override Node VisitQueryIterator(QueryIterator xiterator){
   if (xiterator == null) return null;
   xiterator.Expression = this.VisitExpression(xiterator.Expression);
   if (xiterator.Expression != null && xiterator.Expression.Type != null){
     if (xiterator.ElementType == null){
       xiterator.ElementType = this.typeSystem.GetStreamElementType(xiterator.Expression, this.TypeViewer);
     }
     if (xiterator.Name == null) xiterator.Name = Identifier.For("Item0");
     xiterator.ElementType = TupleType.For(new FieldList(this.NewField(xiterator.Name, xiterator.ElementType, Anonymity.Full)), this.currentType);
     xiterator.Type = this.GetResultType(xiterator.Expression, xiterator.ElementType, Cardinality.One);
     xiterator.HintList = this.VisitExpressionList(xiterator.HintList);        
   }
   return xiterator;      
 }    
Example #21
0
 public QueryPlanIsSupportedResult(QueryIterator queryIterator)
 {
     this.QueryIterator = queryIterator ?? throw new ArgumentNullException(nameof(queryIterator));
 }
 public EventingVisitor(Action<QueryIterator> visitQueryIterator) { VisitedQueryIterator += visitQueryIterator; } public event Action<QueryIterator> VisitedQueryIterator; public override Node VisitQueryIterator(QueryIterator xiterator) { if (VisitedQueryIterator != null) VisitedQueryIterator(xiterator); return base.VisitQueryIterator(xiterator); }