public override async Task VisitRecursionQueryStepAsync(RecursionQueryStep rqs)
        {
            _writer.WriteStartObject();
            _writer.WritePropertyName("Type");
            _writer.WriteString("RecursionQueryStep");
            _writer.WriteComma();
            _writer.WritePropertyName("Left");
            await VisitAsync(rqs.Left);

            _writer.WriteComma();
            _writer.WritePropertyName("Steps");
            _writer.WriteStartArray();
            var first = true;

            foreach (var step in rqs.Steps)
            {
                if (first == false)
                {
                    _writer.WriteComma();
                }

                first = false;
                await VisitAsync(step.Right);
            }
            _writer.WriteEndArray();
            _writer.WriteComma();
            await VisitAsync(rqs.GetNextStep());

            WriteIntermidiateResults(rqs.IntermediateResults);
            _writer.WriteEndObject();
        }
示例#2
0
        public virtual async Task VisitRecursionQueryStepAsync(RecursionQueryStep rqs)
        {
            await VisitAsync(rqs.Left);

            foreach (var step in rqs.Steps)
            {
                await VisitAsync(step.Right);
            }

            await VisitAsync(rqs.GetNextStep());
        }
示例#3
0
        public virtual void VisitRecursionQueryStep(RecursionQueryStep rqs)
        {
            Visit(rqs.Left);

            foreach (var step in rqs.Steps)
            {
                Visit(step.Right);
            }

            Visit(rqs.GetNextStep());
        }
示例#4
0
        private IGraphQueryStep BuildQueryPlanForRecursiveEdge(IGraphQueryStep left, int index, PatternMatchElementExpression patternExpression)
        {
            var recursive = patternExpression.Path[index].Recursive.Value;
            var pattern   = recursive.Pattern;
            var steps     = new List <SingleEdgeMatcher>((pattern.Count + 1) / 2);

            for (int i = 0; i < pattern.Count; i += 2)
            {
                if (GraphQuery.WithEdgePredicates.TryGetValue(pattern[i].Alias, out var recursiveEdge) == false)
                {
                    throw new InvalidOperationException($"BuildQueryPlanForEdge was invoked for recursive alias='{pattern[i].Alias}' which suppose to be an edge but no corresponding WITH EDGE clause was found.");
                }

                steps.Add(new SingleEdgeMatcher
                {
                    IncludedEdges   = new Dictionary <string, Sparrow.Json.BlittableJsonReaderObject>(StringComparer.OrdinalIgnoreCase),
                    QueryParameters = _query.QueryParameters,
                    Edge            = recursiveEdge,
                    Results         = new List <Match>(),
                    Right           = i + 1 < pattern.Count ? BuildQueryPlanForMatchNode(pattern[i + 1]) : null,
                    EdgeAlias       = pattern[i].Alias
                });
            }

            var recursiveStep = new RecursionQueryStep(left, steps, recursive, recursive.GetOptions(_query.Metadata, _query.QueryParameters), _token)
            {
                CollectIntermediateResults = CollectIntermediateResults
            };

            if (index + 1 < patternExpression.Path.Length)
            {
                if (patternExpression.Path[index + 1].Recursive.HasValue)
                {
                    throw new InvalidQueryException("Two adjacent 'recursive' queries are not allowed", GraphQuery.QueryText);
                }

                if (patternExpression.Path[index + 1].IsEdge)
                {
                    var nextPlan = BuildQueryPlanForPattern(patternExpression, index + 2);
                    nextPlan = BuildQueryPlanForEdge(recursiveStep, nextPlan, patternExpression.Path[index + 1]);
                    recursiveStep.SetNext(nextPlan.GetSingleGraphStepExecution());
                }
                else
                {
                    var nextPlan = BuildQueryPlanForPattern(patternExpression, index + 1);
                    recursiveStep.SetNext(nextPlan.GetSingleGraphStepExecution());
                }
            }


            return(recursiveStep);
        }
示例#5
0
        public override IGraphQueryStep VisitRecursionQueryStep(RecursionQueryStep rqs)
        {
            _token.ThrowIfCancellationRequested();
            var  left     = Visit(rqs.Left);
            bool modified = ReferenceEquals(left, rqs.Left) == false;

            var steps = new List <SingleEdgeMatcher>();

            foreach (var step in rqs.Steps)
            {
                _isVisitingRight = true;
                var right = Visit(step.Right);
                _isVisitingRight = false;
                if (ReferenceEquals(right, step.Right) == false)
                {
                    modified = true;
                    steps.Add(new SingleEdgeMatcher(step, right, _documentsStorage.DocumentDatabase.IdentityPartsSeparator));
                }
                else
                {
                    steps.Add(step);
                }
            }
            var next = rqs.GetNextStep();

            Visit(next);

            if (modified == false)
            {
                return(rqs);
            }

            var result = new RecursionQueryStep(rqs, left, steps, _token);

            if (next != null)
            {
                next.SetPrev(result);
                result.SetNext(next);
                result.SetAliases(rqs.GetAllAliases());
            }

            return(result);
        }
示例#6
0
        public RecursionQueryStep(IGraphQueryStep left, RecursionQueryStep rqs, OperationCancelToken token)
        {
            _left      = left;
            _steps     = rqs._steps;
            _recursive = rqs._recursive;
            _options   = rqs._options;

            _stepAliases.Add(left.GetOutputAlias());

            foreach (var step in _steps)
            {
                if (step.Right == null)
                {
                    continue;
                }
                _stepAliases.Add(step.Right.GetOutputAlias());
            }

            _outputAlias = _stepAliases.Last();
            _token       = token;
        }
示例#7
0
        public virtual IGraphQueryStep VisitRecursionQueryStep(RecursionQueryStep rqs)
        {
            _token.ThrowIfCancellationRequested();
            var  left     = Visit(rqs.Left);
            bool modified = ReferenceEquals(left, rqs.Left) == false;

            var steps = new List <SingleEdgeMatcher>();

            foreach (var step in rqs.Steps)
            {
                var right = Visit(step.Right);
                if (ReferenceEquals(right, step.Right) == false)
                {
                    modified = true;
                    steps.Add(new SingleEdgeMatcher(step, right));
                }
                else
                {
                    steps.Add(step);
                }
            }

            var next = rqs.GetNextStep();

            if (next != null)
            {
                Visit(next);
            }

            if (modified)
            {
                return(new RecursionQueryStep(rqs, left, steps, _token));
            }

            return(rqs);
        }