Exemple #1
0
        private List <QueryPlanNode> GetLeastCostPath(QueryPlanNode root)
        {
            QueryPlanNode        cur    = root;
            List <QueryPlanNode> result = new List <QueryPlanNode>();

            result.Add(cur);

            while (cur != null)
            {
                QueryPlanNodeEdge cheapestEdge = cur.Edges.OrderBy(x => x.Cost).FirstOrDefault();
                if (cheapestEdge != null)
                {
                    cur = cheapestEdge.To;

                    if (cur != null)
                    {
                        result.Add(cur);
                    }
                }
                else
                {
                    cur = null;
                }
            }

            return(result);
        }
Exemple #2
0
        //private PhysicalOperation FindIndexes(SelectionElement selectionElement)
        //{
        //    List<LeafCondition> leafs = GetLeafConditions(selectionElement.Condition);

        //    foreach(LeafCondition leaf in leafs)
        //    {
        //        if (leaf.Column.Relation is TableDefinition tableDefinition)
        //        {
        //            Index index = tableDefinition.Indexes.FirstOrDefault(x => string.Equals(x.Column, leaf.Column.Name, StringComparison.OrdinalIgnoreCase));

        //            if (index != null)
        //            {
        //                ;
        //            }
        //        }
        //    }

        //    if (leafs.Count == 0)
        //    {
        //        // index seek / table scan
        //        return GetFullTableScanOperation(selectionElement..)
        //    }
        //}

        public PhysicalOperation GetPhysicalPlan(LogicalElement logicalTree)
        {
            List <LogicalElement> postorderLogicalTree = AppendPostOrder(new List <LogicalElement>(), logicalTree);

            QueryPlanNode root = new QueryPlanNode(null, null);

            List <QueryPlanNode> lastOptions = new List <QueryPlanNode> {
                root
            };

            for (int i = 0; i < postorderLogicalTree.Count; i++)
            {
                LogicalElement element = postorderLogicalTree[i];

                Dictionary <QueryPlanNode, int> options = GetOptions(element);
                ConnectEndNodesToNodes(lastOptions, options);

                lastOptions = options.Select(x => x.Key).ToList();
            }

            List <QueryPlanNode> leastCostPath = GetLeastCostPath(root);

            PhysicalOperation physicalOperation = CreateFromPath(logicalTree, leastCostPath);

            return(physicalOperation);
        }
        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);
                    }
Exemple #4
0
        public QueryPlanNode Provide(JObject jObject)
        {
            QueryTreeDataInternal queryTree = new QueryTreeDataInternal();

            ProcessRtes(queryTree, jObject);
            QueryPlanNode result = null;
            var           plan   = jObject.SelectToken("..planTree");

            if (plan != null)
            {
                result = LoadPlanNode(null, plan, queryTree);
            }
            return(result ?? new QueryPlanNode());
        }
        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);
        }
 private void PublishIndexStatistics(QueryPlanNode plan)
 {
     switch (plan.ScanOperation)
     {
     case AnyIndexScanOperation indexScan:
         statementDataAccumulator.PublishNormalizedStatementIndexStatistics(new LogEntryStatementIndexStatisticsData()
         {
             DatabaseID    = context.DatabaseID,
             ExecutionDate = context.Entry.Timestamp,
             IndexID       = indexScan.IndexId,
             NormalizedStatementFingerprint = context.StatementData.NormalizedStatementFingerprint,
             TotalCost = plan.TotalCost
         });
         break;
     }
     foreach (var item in plan.Plans)
     {
         PublishIndexStatistics(item);
     }
 }
        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);
        }
Exemple #8
0
 private QueryPlanNode LoadPlanNode(QueryPlanNode parent, JToken jObject, QueryTreeDataInternal queryTree)
 {
     if (jObject.ToString() != "<>")
     {
         var           planNode      = jObject.First.First;
         var           operationName = ((JProperty)jObject.First).Name.ToUpper();
         QueryPlanNode node          = new QueryPlanNode();
         node.StartupCost = planNode.SelectToken("startup_cost").Value <decimal>();
         node.TotalCost   = planNode.SelectToken("total_cost").Value <decimal>();
         if (operationName.Contains("INDEX") && planNode.SelectToken("indexid") != null)
         {
             node.ScanOperation = new AnyIndexScanOperation()
             {
                 IndexId = planNode.SelectToken("indexid").Value <uint>()
             };
         }
         else if (operationName == "SEQSCAN" && planNode.SelectToken("scanrelid") != null)
         {
             var index = planNode.SelectToken("scanrelid").Value <int>();
             var rte   = queryTree.Rtes[index - 1];
             if (rte.RelKind == RelKind.Relation)
             {
                 node.ScanOperation = new RelationSequenceScanOperation()
                 {
                     RelationId = rte.RelId.Value
                 };
             }
         }
         var left = planNode.SelectToken("lefttree");
         LoadPlanNode(node, left, queryTree);
         var right = planNode.SelectToken("righttree");
         LoadPlanNode(node, right, queryTree);
         if (parent != null)
         {
             parent.Plans.Add(node);
         }
         return(node);
     }
     return(null);
 }
 private static void CompareExecNodeSpec(int streamNum, QueryPlanNode expected, QueryPlanNode actual, IDictionary <TableLookupIndexReqKey, TableLookupIndexReqKey> indexNameMapping)
 {
     if (actual is QueryPlanNodeNoOp && expected == null)
     {
     }
     else if (actual is TableLookupNode && expected is TableLookupNode)
     {
         CompareTableLookup(streamNum, (TableLookupNode)expected, (TableLookupNode)actual, indexNameMapping);
     }
     else if (actual is TableOuterLookupNode && expected is TableOuterLookupNode)
     {
         CompareTableLookupOuter(streamNum, (TableOuterLookupNode)expected, (TableOuterLookupNode)actual, indexNameMapping);
     }
     else if (actual is LookupInstructionQueryPlanNode && expected is LookupInstructionQueryPlanNode)
     {
         CompareInstruction(streamNum, (LookupInstructionQueryPlanNode)expected, (LookupInstructionQueryPlanNode)actual, indexNameMapping);
     }
     else
     {
         Assert.Fail("Failed to compare plan node for stream " + streamNum + ", unhandled plan " + actual.GetType().Name);
     }
 }
Exemple #10
0
 private void ConnectEndNodesToNodes(QueryPlanNode node, Dictionary <QueryPlanNode, int> endNodes)
 {
     if (node.Edges.Count == 0)
     {
         foreach (KeyValuePair <QueryPlanNode, int> endNode in endNodes)
         {
             node.Edges.Add(new QueryPlanNodeEdge
             {
                 From = node,
                 To   = endNode.Key,
                 Cost = endNode.Value
             });
         }
     }
     else
     {
         foreach (QueryPlanNode node1 in node.Edges.Select(x => x.To))
         {
             ConnectEndNodesToNodes(node1, endNodes);
         }
     }
 }
        private QueryPlanNode LoadPlanNode(QueryPlanNode parent, JToken jObject, ISet <string> allIndices)
        {
            QueryPlanNode node     = new QueryPlanNode();
            var           nodeType = jObject.SelectToken("['Node Type']").Value <string>().ToUpper();

            if (nodeType.Contains("INDEX") && jObject.SelectToken("['Index Name']") != null)
            {
                var indexName = jObject.SelectToken("['Index Name']").Value <string>();
                node.ScanOperation = new AnyIndexScanOperation();
                allIndices.Add(indexName);
            }
            node.StartupCost = jObject.SelectToken("['Startup Cost']").Value <decimal>();
            node.TotalCost   = jObject.SelectToken("['Total Cost']").Value <decimal>();
            var plans = jObject.SelectToken("Plans");

            if (plans != null)
            {
                foreach (var plan in plans.Children())
                {
                    node.Plans.Add(LoadPlanNode(node, plan, allIndices));
                }
            }
            return(node);
        }
Exemple #12
0
 public OperationNode(QueryPlanNode operation)
     : base(ExecutionStrategy.Serial)
 {
     Operation = operation;
     AddNode(operation);
 }
 public EmptyExplainResult()
 {
     PlanJson = "";
     Plan     = new QueryPlanNode();
 }
 public StreamPlanNode(int id, QueryPlanNode root)
 {
     Id   = id;
     Root = root;
 }