Beispiel #1
0
        public virtual void DetermineOrder(Plan plan)
        {
            // Set up the order columns
            Order             = new Schema.Order(_requestedOrder.MetaData);
            Order.IsInherited = false;

            Schema.OrderColumn newColumn;
            Schema.OrderColumn column;
            for (int index = 0; index < _requestedOrder.Columns.Count; index++)
            {
                column                  = _requestedOrder.Columns[index];
                newColumn               = new Schema.OrderColumn(TableVar.Columns[column.Column], column.Ascending, column.IncludeNils);
                newColumn.Sort          = column.Sort;
                newColumn.IsDefaultSort = column.IsDefaultSort;
                Error.AssertWarn(newColumn.Sort != null, "Sort is null");
                if (newColumn.IsDefaultSort)
                {
                    plan.AttachDependency(newColumn.Sort);
                }
                else
                {
                    if (newColumn.Sort.HasDependencies())
                    {
                        plan.AttachDependencies(newColumn.Sort.Dependencies);
                    }
                }
                Order.Columns.Add(newColumn);
            }

            Compiler.EnsureOrderUnique(plan, TableVar, Order);
        }
Beispiel #2
0
        // A scan order can be any order which includes all the columns in closed conditions, in any order,
        // followed by all the columns in open conditions, in any order,
        // if there is a scan condition, it must be the last order column, open or closed
        protected Schema.Order FindScanOrder(Plan plan)
        {
            Schema.Order newOrder;

            foreach (Schema.Key key in SourceTableVar.Keys)
            {
                newOrder = Compiler.OrderFromKey(plan, key);
                if (IsValidScanOrder(plan, newOrder, _closedConditions, _openConditions, _scanCondition))
                {
                    return(newOrder);
                }
            }

            foreach (Schema.Order order in TableVar.Orders)
            {
                if (IsValidScanOrder(plan, order, _closedConditions, _openConditions, _scanCondition))
                {
                    return(order);
                }
            }

            newOrder = new Schema.Order();
            Schema.OrderColumn newOrderColumn;
            for (int index = 0; index < _closedConditions.Count; index++)
            {
                if (!Object.ReferenceEquals(_closedConditions[index], _scanCondition))
                {
                    newOrderColumn      = new Schema.OrderColumn(_closedConditions[index].Column, true);
                    newOrderColumn.Sort = Compiler.GetUniqueSort(plan, newOrderColumn.Column.DataType);
                    plan.AttachDependency(newOrderColumn.Sort);
                    newOrder.Columns.Add(newOrderColumn);
                }
            }

            for (int index = 0; index < _openConditions.Count; index++)
            {
                if (!Object.ReferenceEquals(_openConditions[index], _scanCondition))
                {
                    newOrderColumn      = new Schema.OrderColumn(_openConditions[index].Column, true);
                    newOrderColumn.Sort = Compiler.GetUniqueSort(plan, newOrderColumn.Column.DataType);
                    plan.AttachDependency(newOrderColumn.Sort);
                    newOrder.Columns.Add(newOrderColumn);
                }
            }

            if (_scanCondition != null)
            {
                newOrderColumn      = new Schema.OrderColumn(_scanCondition.Column, true);
                newOrderColumn.Sort = Compiler.GetUniqueSort(plan, newOrderColumn.Column.DataType);
                plan.AttachDependency(newOrderColumn.Sort);
                newOrder.Columns.Add(newOrderColumn);
            }

            return(newOrder);
        }
Beispiel #3
0
 public int EvaluateSort(Schema.OrderColumn orderColumn, object indexValue, object compareValue)
 {
                 #if USEICOMPARABLE
     IComparable indexComparable = AIndexValue as IComparable;
     if (indexComparable != null)
     {
         return(indexComparable.CompareTo(ACompareValue) * (AOrderColumn.Ascending ? 1 : -1));
     }
     else
     {
                 #endif
     // NOTE: Use currently executing program because the whole point is that this is inner loop sort code.
     // We don't want to have to use a new program, or
     Program program = _serverProcess.ExecutingProgram;
     //LProgram.Stack.PushWindow(0);
     //try
     //{
     program.Stack.Push(indexValue);
     program.Stack.Push(compareValue);
     try
     {
         return(((int)orderColumn.Sort.CompareNode.Execute(program)) * (orderColumn.Ascending ? 1 : -1));
     }
     finally
     {
         program.Stack.Pop();
         program.Stack.Pop();
     }
     //}
     //finally
     //{
     //	LProgram.Stack.PopWindow();
     //}
                 #if USEICOMPARABLE
 }
                 #endif
 }
Beispiel #4
0
        protected PlanNode EmitBrowseComparisonNode
        (
            Plan plan,
            Schema.Order order,
            bool forward,
            bool inclusive,
            int originIndex
        )
        {
            PlanNode node = null;

            Schema.OrderColumn originColumn = order.Columns[originIndex];
            if (originColumn.Ascending != forward)
            {
                if (inclusive && (originIndex == order.Columns.Count - 1))
                {
                    node = EmitBrowseColumnNode(plan, originColumn, Instructions.InclusiveLess);
                }
                else
                {
                    node = EmitBrowseColumnNode(plan, originColumn, Instructions.Less);
                }
            }
            else
            {
                if (inclusive && (originIndex == order.Columns.Count - 1))
                {
                    node = EmitBrowseColumnNode(plan, originColumn, Instructions.InclusiveGreater);
                }
                else
                {
                    node = EmitBrowseColumnNode(plan, originColumn, Instructions.Greater);
                }
            }
            return(node);
        }
Beispiel #5
0
        protected Expression EmitBrowseComparisonExpression
        (
            Schema.Order order,
            bool forward,
            bool inclusive,
            int originIndex
        )
        {
            Expression expression = null;

            Schema.OrderColumn originColumn = order.Columns[originIndex];
            if (originColumn.Ascending != forward)
            {
                if (inclusive && (originIndex == order.Columns.Count - 1))
                {
                    expression = EmitBrowseColumnExpression(originColumn, Instructions.InclusiveLess);
                }
                else
                {
                    expression = EmitBrowseColumnExpression(originColumn, Instructions.Less);
                }
            }
            else
            {
                if (inclusive && (originIndex == order.Columns.Count - 1))
                {
                    expression = EmitBrowseColumnExpression(originColumn, Instructions.InclusiveGreater);
                }
                else
                {
                    expression = EmitBrowseColumnExpression(originColumn, Instructions.Greater);
                }
            }

            return(expression);
        }
Beispiel #6
0
        // TODO: Compile row types for each index, saving column indexes to prevent the need for lookup during insert, update, and delete.
        private void Create(IValueManager manager)
        {
            TableType = TableVar.DataType;
            RowType   = TableType.RowType;

            Schema.RowType keyRowType;
            Schema.RowType dataRowType;

            // Create the indexes required to store data as described by the given table variable
            // Determine Fanout, Capacity, Clustering Key
            Schema.Order clusteringKey = manager.FindClusteringOrder(TableVar);
            keyRowType  = new Schema.RowType(clusteringKey.Columns);
            dataRowType = new Schema.RowType();
            foreach (Schema.Column column in TableVar.DataType.Columns)
            {
                if (!clusteringKey.Columns.Contains(column.Name))
                {
                    dataRowType.Columns.Add(new Schema.Column(column.Name, column.DataType));
                }
            }

            // Add an internal identifier for uniqueness of keys in nonunique indexes
                        #if USEINTERNALID
            _internalIDColumn = new Schema.TableVarColumn(new Schema.Column(InternalIDColumnName, manager.DataTypes.SystemGuid), Schema.TableVarColumnType.InternalID);
            dataRowType.Columns.Add(_internalIDColumn.Column);
                        #endif

            // Create the Clustered index
            ClusteredIndex =
                new NativeRowTree
                (
                    clusteringKey,
                    keyRowType,
                    dataRowType,
                    _fanout,
                    _capacity,
                    true
                );

            // DataLength and DataColumns for all non clustered indexes is the key length and columns of the clustered key
            dataRowType = keyRowType;

            // Create non clustered indexes for each key and order (unique sets)
            Schema.Order key;
            foreach (Schema.Key nonClusteredKey in TableVar.Keys)
            {
                if (!nonClusteredKey.IsSparse && nonClusteredKey.Enforced)
                {
                    if (!manager.OrderIncludesKey(ClusteredIndex.Key, nonClusteredKey))
                    {
                        key = manager.OrderFromKey(nonClusteredKey);
                        if (!NonClusteredIndexes.Contains(key))
                        {
                            keyRowType = new Schema.RowType(key.Columns);

                            NonClusteredIndexes.Add
                            (
                                new NativeRowTree
                                (
                                    key,
                                    keyRowType,
                                    dataRowType,
                                    _fanout,
                                    _capacity,
                                    false
                                )
                            );
                        }
                    }
                }
                else
                {
                    // This is a potentially non-unique index, so add a GUID to ensure uniqueness of the key in the BTree
                    key = manager.OrderFromKey(nonClusteredKey);
                                        #if USEINTERNALID
                    Schema.OrderColumn uniqueColumn = new Schema.OrderColumn(_internalIDColumn, key.IsAscending);
                    uniqueColumn.Sort = manager.GetUniqueSort(uniqueColumn.Column.DataType);
                    key.Columns.Add(uniqueColumn);
                                        #endif

                    if (!NonClusteredIndexes.Contains(key))
                    {
                        keyRowType = new Schema.RowType(key.Columns);

                        NonClusteredIndexes.Add
                        (
                            new NativeRowTree
                            (
                                key,
                                keyRowType,
                                dataRowType,
                                _fanout,
                                _capacity,
                                false
                            )
                        );
                    }
                }
            }

            foreach (Schema.Order order in TableVar.Orders)
            {
                // This is a potentially non-unique index, so add a GUID to ensure uniqueness of the key in the BTree
                key = new Schema.Order(order);
                                #if USEINTERNALID
                if (!manager.OrderIncludesOrder(key, clusteringKey))
                {
                    Schema.OrderColumn uniqueColumn = new Schema.OrderColumn(_internalIDColumn, order.IsAscending);
                    uniqueColumn.Sort = manager.GetUniqueSort(uniqueColumn.Column.DataType);
                    key.Columns.Add(uniqueColumn);
                }
                                #endif

                if (!NonClusteredIndexes.Contains(key))
                {
                    keyRowType = new Schema.RowType(key.Columns);

                    NonClusteredIndexes.Add
                    (
                        new NativeRowTree
                        (
                            key,
                            keyRowType,
                            dataRowType,
                            _fanout,
                            _capacity,
                            false
                        )
                    );
                }
            }
        }
Beispiel #7
0
        protected PlanNode EmitBrowseColumnNode(Plan plan, Schema.OrderColumn column, string instruction)
        {
            PlanNode node =
                Compiler.EmitBinaryNode
                (
                    plan,
                    Compiler.EmitIdentifierNode(plan, column.Column.Name),
                    instruction,
                    Compiler.EmitIdentifierNode(plan, Schema.Object.Qualify(column.Column.Name, Keywords.Origin))
                );

            if (column.Column.IsNilable && column.IncludeNils)
            {
                switch (instruction)
                {
                case Instructions.Equal:
                    node =
                        Compiler.EmitBinaryNode
                        (
                            plan,
                            Compiler.EmitBinaryNode
                            (
                                plan,
                                EmitBrowseNilNode(plan, column.Column, true),
                                Instructions.And,
                                EmitOriginNilNode(plan, column.Column, true)
                            ),
                            Instructions.Or,
                            node
                        );
                    break;

                case Instructions.InclusiveGreater:
                    node =
                        Compiler.EmitBinaryNode
                        (
                            plan,
                            EmitOriginNilNode(plan, column.Column, true),
                            Instructions.Or,
                            node
                        );
                    break;

                case Instructions.Greater:
                    node =
                        Compiler.EmitBinaryNode
                        (
                            plan,
                            Compiler.EmitBinaryNode
                            (
                                plan,
                                EmitOriginNilNode(plan, column.Column, true),
                                Instructions.And,
                                EmitBrowseNilNode(plan, column.Column, false)
                            ),
                            Instructions.Or,
                            node
                        );
                    break;

                case Instructions.InclusiveLess:
                    node =
                        Compiler.EmitBinaryNode
                        (
                            plan,
                            EmitBrowseNilNode(plan, column.Column, true),
                            Instructions.Or,
                            node
                        );
                    break;

                case Instructions.Less:
                    node =
                        Compiler.EmitBinaryNode
                        (
                            plan,
                            Compiler.EmitBinaryNode
                            (
                                plan,
                                EmitBrowseNilNode(plan, column.Column, true),
                                Instructions.And,
                                EmitOriginNilNode(plan, column.Column, false)
                            ),
                            Instructions.Or,
                            node
                        );
                    break;
                }
            }

            return(node);
        }
Beispiel #8
0
        /*
         *      for each column in the order descending
         *              if the current order column is also in the origin
         *                      [or]
         *                      for each column in the origin less than the current order column
         *                              [and]
         *                              current origin column = current origin value
         *
         *                      [and]
         *                      if the current order column is ascending xor the requested set is forward
         *                              if requested set is inclusive and current order column is the last origin column
         *                                      current order column <= current origin value
         *                              else
         *                                      current order column < current origin value
         *                      else
         *                              if requested set is inclusive and the current order column is the last origin column
         *                                      current order column >= current origin value
         *                              else
         *                                      current order column > current origin value
         *
         *                      for each column in the order greater than the current order column
         *                              if the current order column does not include nulls
         *                                      and current order column is not null
         *              else
         *                      if the current order column does not include nulls
         *                              [and] current order column is not null
         */

        protected Expression EmitBrowseColumnExpression(Schema.OrderColumn column, string instruction)
        {
            Expression expression =
                new BinaryExpression
                (
                    new IdentifierExpression(column.Column.Name),
                    instruction,
                    new IdentifierExpression(Schema.Object.Qualify(column.Column.Name, Keywords.Origin))
                );

            if (column.Column.IsNilable && column.IncludeNils)
            {
                switch (instruction)
                {
                case Instructions.Equal:
                    expression =
                        new BinaryExpression
                        (
                            new BinaryExpression
                            (
                                EmitBrowseNilExpression(column.Column, true),
                                Instructions.And,
                                EmitOriginNilExpression(column.Column, true)
                            ),
                            Instructions.Or,
                            expression
                        );
                    break;

                case Instructions.InclusiveGreater:
                    expression =
                        new BinaryExpression
                        (
                            EmitOriginNilExpression(column.Column, true),
                            Instructions.Or,
                            expression
                        );
                    break;

                case Instructions.Greater:
                    expression =
                        new BinaryExpression
                        (
                            new BinaryExpression
                            (
                                EmitOriginNilExpression(column.Column, true),
                                Instructions.And,
                                EmitBrowseNilExpression(column.Column, false)
                            ),
                            Instructions.Or,
                            expression
                        );
                    break;

                case Instructions.InclusiveLess:
                    expression =
                        new BinaryExpression
                        (
                            EmitBrowseNilExpression(column.Column, true),
                            Instructions.Or,
                            expression
                        );
                    break;

                case Instructions.Less:
                    expression =
                        new BinaryExpression
                        (
                            new BinaryExpression
                            (
                                EmitBrowseNilExpression(column.Column, true),
                                Instructions.And,
                                EmitOriginNilExpression(column.Column, false)
                            ),
                            Instructions.Or,
                            expression
                        );
                    break;
                }
            }

            return(expression);
        }
Beispiel #9
0
        protected override DevicePlanNode InternalPrepare(Schema.DevicePlan plan, PlanNode planNode)
        {
            if (planNode is BaseTableVarNode)
            {
                BaseTableVarNode node = (BaseTableVarNode)planNode;
                PrepareTableNode(plan, node);
                node.Order = Compiler.OrderFromKey(plan.Plan, Compiler.FindClusteringKey(plan.Plan, node.TableVar));
                return(new DevicePlanNode(node));
            }
            else if ((planNode is OrderNode) && (planNode.Nodes[0] is BaseTableVarNode) && (plan.Plan.CursorContext.CursorType != CursorType.Static))
            {
                OrderNode        node         = (OrderNode)planNode;
                BaseTableVarNode tableVarNode = (BaseTableVarNode)planNode.Nodes[0];
                Schema.Order     tableOrder;

                bool isSupported = false;
                foreach (Schema.Key key in tableVarNode.TableVar.Keys)
                {
                    tableOrder = Compiler.OrderFromKey(plan.Plan, key);
                    if (node.RequestedOrder.Equivalent(tableOrder))
                    {
                        node.PhysicalOrder = tableOrder;
                        node.ScanDirection = ScanDirection.Forward;
                        isSupported        = true;
                        break;
                    }
                    else if (node.RequestedOrder.Equivalent(new Schema.Order(tableOrder, true)))
                    {
                        node.PhysicalOrder = tableOrder;
                        node.ScanDirection = ScanDirection.Backward;
                        isSupported        = true;
                        break;
                    }
                }

                if (!isSupported)
                {
                    foreach (Schema.Order order in tableVarNode.TableVar.Orders)
                    {
                        if (node.RequestedOrder.Equivalent(order))
                        {
                            node.PhysicalOrder = order;
                            node.ScanDirection = ScanDirection.Forward;
                            isSupported        = true;
                            break;
                        }
                        else if (node.RequestedOrder.Equivalent(new Schema.Order(order, true)))
                        {
                            node.PhysicalOrder = order;
                            node.ScanDirection = ScanDirection.Backward;
                            isSupported        = true;
                            break;
                        }
                    }
                }

                if (isSupported)
                {
                    node.Order = new Schema.Order();
                    node.Order.MergeMetaData(node.RequestedOrder.MetaData);
                    node.Order.IsInherited = false;
                    Schema.OrderColumn orderColumn;
                    Schema.OrderColumn newOrderColumn;
                    for (int index = 0; index < node.PhysicalOrder.Columns.Count; index++)
                    {
                        orderColumn    = node.PhysicalOrder.Columns[index];
                        newOrderColumn =
                            new Schema.OrderColumn
                            (
                                node.TableVar.Columns[orderColumn.Column],
                                node.ScanDirection == ScanDirection.Forward ?
                                orderColumn.Ascending :
                                !orderColumn.Ascending
                            );
                        newOrderColumn.Sort          = orderColumn.Sort;
                        newOrderColumn.IsDefaultSort = orderColumn.IsDefaultSort;
                        Error.AssertWarn(newOrderColumn.Sort != null, "Sort is null");
                        node.Order.Columns.Add(newOrderColumn);
                    }
                    if (!node.TableVar.Orders.Contains(node.Order))
                    {
                        node.TableVar.Orders.Add(node.Order);
                    }

                    PrepareTableNode(plan, node);
                    PrepareTableNode(plan, tableVarNode);

                    return(new DevicePlanNode(node));
                }
            }
            else if (planNode is CreateTableVarBaseNode)
            {
                plan.Plan.CheckRight(GetRight(Schema.RightNames.CreateStore));
                return(new DevicePlanNode(planNode));
            }
            else if (planNode is AlterTableNode)
            {
                plan.Plan.CheckRight(GetRight(Schema.RightNames.AlterStore));
                AlterTableNode alterTableNode = (AlterTableNode)planNode;
                if (alterTableNode.AlterTableStatement.CreateColumns.Count > 0)
                {
                    throw new RuntimeException(RuntimeException.Codes.UnimplementedCreateCommand, "Columns in a memory device");
                }
                if (alterTableNode.AlterTableStatement.DropColumns.Count > 0)
                {
                    throw new RuntimeException(RuntimeException.Codes.UnimplementedDropCommand, "Columns in a memory device");
                }
                return(new DevicePlanNode(planNode));
            }
            else if (planNode is DropTableNode)
            {
                plan.Plan.CheckRight(GetRight(Schema.RightNames.DropStore));
                return(new DevicePlanNode(planNode));
            }
            plan.IsSupported = false;
            return(null);
        }