示例#1
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);
        }
示例#2
0
        private void ApplyInputOperations(LogicalElement logicalTree, List <QueryPlanNode> path)
        {
            if (logicalTree == null)
            {
                return;
            }

            PhysicalOperation curNode   = path.First(x => x.LogicalElement == logicalTree).PhysicalOperation;
            PhysicalOperation leftInput = null;

            if (logicalTree.LeftChild != null)
            {
                leftInput = path.First(x => x.LogicalElement == logicalTree.LeftChild).PhysicalOperation;
            }

            PhysicalOperation rightInput = null;

            if (logicalTree.RightChild != null)
            {
                rightInput = path.First(x => x.LogicalElement == logicalTree.RightChild).PhysicalOperation;
            }

            curNode?.SetInput(leftInput, rightInput);

            ApplyInputOperations(logicalTree.LeftChild, path);
            ApplyInputOperations(logicalTree.RightChild, path);
        }
 public HashSetJoinOperation(LogicalElement logicalElement, PhysicalOperation left, PhysicalOperation right, AttributeDefinition leftJoinColumn, AttributeDefinition rightJoinColumn)
     : base(logicalElement)
 {
     Left             = left;
     Right            = right;
     _leftJoinColumn  = leftJoinColumn;
     _rightJoinColumn = rightJoinColumn;
 }
 public void SetInput(PhysicalOperation left, PhysicalOperation right)
 {
     Left  = left;
     Right = right;
 }
 public TopOperation(LogicalElement logicalElement, PhysicalOperation inputOperation, int?amount)
     : base(logicalElement)
 {
     Left    = inputOperation;
     _amount = amount;
 }
 public UnionOperator(LogicalElement logicalElement, PhysicalOperation left, PhysicalOperation right)
     : base(logicalElement)
 {
     Left  = left;
     Right = right;
 }
示例#7
0
        private Dictionary <QueryPlanNode, int> GetOptions(LogicalElement element)
        {
            Dictionary <QueryPlanNode, int> options = new Dictionary <QueryPlanNode, int>();

            if (element is ProjectionElement p)
            {
                PhysicalOperation proj = new ProjectionOperation(element, null, p.Columns.Select(x => x.AttributeDefinition).ToList());
                options.Add(new QueryPlanNode(element, proj), proj.GetCost());
            }
            else if (element is SelectionElement selectionElement)
            {
                if (selectionElement.LeftChild is RelationElement relationElement)
                {
                    Table table = Program.RelationManager.GetTable(relationElement.Relation.Id);

                    PhysicalOperation tableScan = new TableScanOperation(element, table);
                    if (selectionElement.Condition != null)
                    {
                        PhysicalOperation f = new FilterOperation(element, tableScan, selectionElement.Condition);
                        options.Add(new QueryPlanNode(element, f), f.GetCost());
                    }
                    else
                    {
                        options.Add(new QueryPlanNode(element, tableScan), tableScan.GetCost());
                    }

                    Condition clonedCondition = selectionElement.Condition?.Clone();

                    if (TryExtractConstantConditionWithIndex(relationElement.Relation, clonedCondition, out LeafCondition constantCondition))
                    {
                        selectionElement.Condition = selectionElement.Condition.Simplify();

                        PhysicalOperation indexSeek = new IndexSeekOperation(element, table, table.GetIndex(table.TableDefinition.GetClusteredIndex().Column), constantCondition);

                        if (selectionElement.Condition != null)
                        {
                            PhysicalOperation f = new FilterOperation(element, indexSeek, clonedCondition);
                            options.Add(new QueryPlanNode(element, f), f.GetCost());
                        }
                        else
                        {
                            options.Add(new QueryPlanNode(element, indexSeek), indexSeek.GetCost());
                        }
                    }
                    else
                    {
                        if (table.TableDefinition.HasClusteredIndex())
                        {
                            PhysicalOperation indexSeek = new IndexSeekOperation(element, table, table.GetIndex(table.TableDefinition.GetClusteredIndex().Column), constantCondition);

                            if (selectionElement.Condition != null)
                            {
                                PhysicalOperation f = new FilterOperation(element, indexSeek, selectionElement.Condition);
                                options.Add(new QueryPlanNode(element, f), f.GetCost());
                            }
                            else
                            {
                                options.Add(new QueryPlanNode(element, indexSeek), indexSeek.GetCost());
                            }
                        }
                    }
                }
            }
            else if (element is RelationElement relElement)
            {
                Table table = Program.RelationManager.GetTable(relElement.Relation.Id);

                if (table.TableDefinition.HasClusteredIndex())
                {
                    PhysicalOperation indexSeek = new IndexScanOperation(element, table, table.GetIndex(table.TableDefinition.GetClusteredIndex().Column));
                    options.Add(new QueryPlanNode(element, indexSeek), indexSeek.GetCost());
                }

                PhysicalOperation tableScan = new TableScanOperation(element, table);
                options.Add(new QueryPlanNode(element, tableScan), tableScan.GetCost());
            }
            else if (element is CartesianProductElement cartesianProduct)
            {
                PhysicalOperation left  = null; //GetDefaultPhysicalOperation(element.LeftChild);
                PhysicalOperation right = null; //GetDefaultPhysicalOperation(element.RightChild);

                PhysicalOperation join = new NestedLoopJoinOperation(cartesianProduct, (ReadLogicalElement)element.LeftChild, (ReadLogicalElement)element.RightChild, cartesianProduct.LeftJoinColumn, cartesianProduct.RightJoinColumn);
                options.Add(new QueryPlanNode(cartesianProduct, join), join.GetCost());
            }
            else if (element is MemorySetElement memElem)
            {
                options.Add(new QueryPlanNode(memElem, new MemorySetOperation(memElem, memElem.Set)), 0);
            }
            else if (element is InsertElement insertElem)
            {
                Table table = Program.RelationManager.GetTable(insertElem.TableDefinition.Id);

                options.Add(new QueryPlanNode(insertElem, new InsertOperation(insertElem, table)), 0);
            }

            if (options.Count == 0)
            {
                throw new Exception();
            }

            return(options);
        }
示例#8
0
 public ProjectionOperation(LogicalElement logicalElement, PhysicalOperation inputOperation, List <AttributeDefinition> projectionColumns)
     : base(logicalElement)
 {
     Left = inputOperation;
     _projectionColumns = projectionColumns;
 }
示例#9
0
 public FilterOperation(LogicalElement logicalElement, PhysicalOperation inputOperation, Condition condition)
     : base(logicalElement)
 {
     Left      = inputOperation;
     Condition = condition;
 }