Example #1
0
        private IGraphQueryStep BuildQueryPlanForPattern(PatternMatchElementExpression patternExpression, int start)
        {
            var prev = BuildQueryPlanForMatchNode(patternExpression.Path[start]);

            for (int i = start + 1; i < patternExpression.Path.Length; i += 2)
            {
                if (patternExpression.Path[i].Recursive == null)
                {
                    var next = i + 1 < patternExpression.Path.Length ?
                               BuildQueryPlanForMatchNode(patternExpression.Path[i + 1]) :
                               null;

                    prev = BuildQueryPlanForEdge(prev, next, patternExpression.Path[i]);
                }
                else
                {
                    return(BuildQueryPlanForRecursiveEdge(prev, i, patternExpression));
                }
            }

            return(prev);
        }
Example #2
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);
        }