public static IEnumerable <QueryPlanNode> BuildDeferred(QueryPlanContext context) { var processed = new HashSet <int>(); while (context.Deferred.TryPop(out IFragment? fragment) && processed.Add(fragment.Id)) { yield return(Build(context, fragment.SelectionSet)); } }
public static QueryPlanNode Build(QueryPlanContext context, ISelectionSet selectionSet) { foreach (ISelection selection in selectionSet.Selections) { Visit(selection, context); } CollectFragments(selectionSet, context); return(Optimize(context.Root !)); }
private static void Visit(ISelection selection, QueryPlanContext context) { if (selection.IsStreamable && selection.SelectionSet is not null) { QueryPlanContext streamContext = context.Branch(); VisitChildren(selection, streamContext); if (streamContext.Root is not null && !context.Streams.ContainsKey(selection.Id)) { context.Streams.Add(selection.Id, new(selection.Id, streamContext.Root)); } if (streamContext.Streams.Count > 0) { foreach (StreamPlanNode streamPlan in streamContext.Streams.Values) { if (!context.Streams.ContainsKey(selection.Id)) { context.Streams.Add(selection.Id, streamPlan); } } } } if (context.NodePath.Count == 0) { context.Root = new ResolverNode(selection); context.NodePath.Push(context.Root); } else { QueryPlanNode parent = context.NodePath.Peek(); if (selection.Strategy == SelectionExecutionStrategy.Serial) { if (parent is ResolverNode { Strategy : ExecutionStrategy.Serial } p) { p.Selections.Add(selection); } else if (context.SelectionPath.Count > 0 && context.NodePath.TryPeek(2, out QueryPlanNode? grandParent) && grandParent is ResolverNode { Strategy: ExecutionStrategy.Serial } gp&& gp.Selections.Contains(context.SelectionPath.PeekOrDefault() !)) { gp.Selections.Add(selection); }
public static QueryPlan Build(IPreparedOperation operation) { if (operation is null) { throw new ArgumentNullException(nameof(operation)); } var context = new QueryPlanContext(operation); OperationNode operationNode = Prepare(context); QueryPlan[] deferredPlans = operationNode.Deferred.Count > 0 ? new QueryPlan[operationNode.Deferred.Count] : Array.Empty <QueryPlan>(); Dictionary <int, QueryPlan>?streamPlans = context.Streams.Count > 0 ? new Dictionary <int, QueryPlan>() : null; if (operationNode.Deferred.Count > 0) { for (var i = 0; i < operationNode.Deferred.Count; i++) { deferredPlans[i] = new QueryPlan( operationNode.Deferred[i].CreateStep(), deferredPlans, streamPlans); } } if (context.Streams.Count > 0) { foreach (StreamPlanNode streamPlanNode in context.Streams.Values) { var streamPlan = new QueryPlan( streamPlanNode.Root.CreateStep(), deferredPlans, streamPlans); streamPlans !.Add(streamPlanNode.Id, streamPlan); } } return(new QueryPlan(operationNode.CreateStep(), deferredPlans, streamPlans)); }
public static OperationNode Build(QueryPlanContext context) { var root = new SequenceNode { CancelOnError = true }; context.Root = root; context.NodePath.Push(root); foreach (ISelection mutation in context.Operation.GetRootSelectionSet().Selections) { context.SelectionPath.Push(mutation); var mutationStep = new ResolverNode( mutation, context.SelectionPath.PeekOrDefault(), GetStrategyFromSelection(mutation)); root.AddNode(mutationStep); QueryStrategy.VisitChildren(mutation, context); } context.NodePath.Pop(); QueryPlanNode optimized = QueryStrategy.Optimize(context.Root); var operationNode = new OperationNode(optimized); if (context.Deferred.Count > 0) { foreach (QueryPlanNode?deferred in QueryStrategy.BuildDeferred(context)) { operationNode.Deferred.Add(deferred); } } if (context.Streams.Count > 0) { operationNode.Streams.AddRange(context.Streams.Values); } return(operationNode); }
public static OperationNode Build(QueryPlanContext context) { QueryPlanNode root = Build(context, context.Operation.GetRootSelectionSet()); var operationNode = new OperationNode(root); if (context.Deferred.Count > 0) { foreach (QueryPlanNode?deferred in BuildDeferred(context)) { operationNode.Deferred.Add(deferred); } } if (context.Streams.Count > 0) { operationNode.Streams.AddRange(context.Streams.Values); } return(operationNode); }
private static OperationNode Prepare(QueryPlanContext context) { return(context.Operation.Definition.Operation is OperationType.Mutation ? MutationStrategy.Build(context) : QueryStrategy.Build(context)); }