예제 #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);
        }
예제 #2
0
        protected bool IsValidScanOrder(Plan plan, Schema.Order order, Conditions closedConditions, Conditions openConditions, ColumnConditions scanCondition)
        {
            int columnIndex;

            for (int index = 0; index < closedConditions.Count; index++)
            {
                columnIndex = order.Columns.IndexOf(closedConditions[index].Column.Name, Compiler.GetUniqueSort(plan, closedConditions[index].Column.DataType));
                if ((columnIndex < 0) || (columnIndex >= closedConditions.Count))
                {
                    return(false);
                }
            }

            for (int index = 0; index < openConditions.Count; index++)
            {
                columnIndex = order.Columns.IndexOf(openConditions[index].Column.Name, Compiler.GetUniqueSort(plan, openConditions[index].Column.DataType));
                if ((columnIndex < closedConditions.Count) || (columnIndex >= closedConditions.Count + openConditions.Count))
                {
                    return(false);
                }
            }

            if (scanCondition != null)
            {
                columnIndex = order.Columns.IndexOf(scanCondition.Column.Name, Compiler.GetUniqueSort(plan, scanCondition.Column.DataType));
                if (columnIndex != (closedConditions.Count + openConditions.Count - 1))
                {
                    return(false);
                }
            }

            return(true);
        }
예제 #3
0
        ///<summary>Returns true if the given key has the same or fewer columns in the same order as the node order key, and once any column is null, the rest of the columns are also null.</summary>
        protected bool IsPartialKeyRow(IRow key)
        {
            bool isNull = false;

            Schema.Order order = Order;
            if (key.DataType.Columns.Count > order.Columns.Count)
            {
                return(false);
            }

            for (int index = 0; index < order.Columns.Count; index++)
            {
                if (key.DataType.Columns.Count > index)
                {
                    if (!Schema.Object.NamesEqual(key.DataType.Columns[index].Name, order.Columns[index].Column.Name))
                    {
                        return(false);
                    }
                    if (isNull && key.HasValue(index))
                    {
                        return(false);
                    }
                    if (!key.HasValue(index))
                    {
                        isNull = true;
                    }
                }
            }

            return(true);
        }
예제 #4
0
        ///	<summary>
        ///	Returns a row that is guaranteed to contain the same columns in the same order as the node order.
        /// If the given row does not satisfy this requirement, a row of the proper row type is created and the values from the given row are copied into it.
        /// </summary>
        protected IRow EnsureKeyRow(IRow key)
        {
            if (IsKeyRow(key))
            {
                return(key);
            }
            else
            {
                Schema.IRowType rowType = DataType.CreateRowType(String.Empty, false);
                Schema.Order    order   = Order;
                for (int index = 0; index < order.Columns.Count; index++)
                {
                    //int LColumnIndex = AKey.DataType.Columns.IndexOfName(LOrder.Columns[LIndex].Column.Name);
                    //if (LColumnIndex >= 0)
                    rowType.Columns.Add(order.Columns[index].Column.Column.Copy());
                    // BTR 4/25/2005 -> There is no difference between not having the column, and having the column, but not having a value.
                    // as such, I see no reason to throw this error, simply create the row and leave the column empty.
                    //else
                    //	throw new RuntimeException(RuntimeException.Codes.InvalidSearchArgument);
                }

                Row localKey = new Row(Manager, rowType);
                key.CopyTo(localKey);
                return(localKey);
            }
        }
예제 #5
0
        public NativeRowTree
        (
            Schema.Order key,
            Schema.RowType keyRowType,
            Schema.RowType dataRowType,
            int fanout,
            int capacity,
            bool isClustered
        ) : base(keyRowType, dataRowType)
        {
            _key = key;
                        #if DEBUG
            for (int index = 0; index < _key.Columns.Count; index++)
            {
                if (_key.Columns[index].Sort == null)
                {
                    Error.Fail("Sort is null");
                }
            }
                        #endif

            _fanout     = fanout < MinimumFanout ? MinimumFanout : fanout;
            _capacity   = capacity;
            IsClustered = isClustered;
            Root        = new NativeRowTreeDataNode(this);
            Head        = Root;
            Tail        = Root;
            Height      = 1;
        }
예제 #6
0
 public TableScan(IValueManager manager, NativeTable table, Schema.Order key, ScanDirection direction, Row firstKey, Row lastKey) : base(manager, table.TableType)
 {
     _nativeTable = table;
     _key         = key;
     _direction   = direction;
     _firstKey    = firstKey;
     _lastKey     = lastKey;
 }
예제 #7
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);
        }
예제 #8
0
 public int IndexOf(Schema.Order key)
 {
     for (int index = 0; index < Count; index++)
     {
         if (key.Equivalent(this[index].Key))
         {
             return(index);
         }
     }
     return(-1);
 }
예제 #9
0
 protected Expression EmitBrowseVariantExpression(Schema.Order originOrder, Schema.IRowType origin, int originIndex, bool forward, bool inclusive)
 {
     return
         (new OrderExpression
          (
              new RestrictExpression
              (
                  _sourceExpression,
                  EmitBrowseConditionExpression(originIndex < 0 ? Order : originOrder, originIndex < 0 ? null : origin, forward, inclusive)
              ),
              (from c in (new Schema.Order(Order, !forward)).Columns select(OrderColumnDefinition) c.EmitStatement(EmitMode.ForCopy)).ToArray()
          ));
 }
예제 #10
0
        protected PlanNode EmitBrowseConditionNode
        (
            Plan plan,
            Schema.Order order,
            Schema.IRowType origin,
            bool forward,
            bool inclusive
        )
        {
            PlanNode node = null;

            for (int orderIndex = order.Columns.Count - 1; orderIndex >= 0; orderIndex--)
            {
                if ((origin != null) && (orderIndex < origin.Columns.Count))
                {
                    node =
                        Compiler.AppendNode
                        (
                            plan,
                            node,
                            Instructions.Or,
                            EmitBrowseOriginNode(plan, order, forward, inclusive, orderIndex)
                        );
                }
                else
                                        #if USEINCLUDENILSWITHBROWSE
                if (order.Columns[orderIndex].Column.IsNilable && !order.Columns[orderIndex].IncludeNils)
                                        #endif
                {
                    node =
                        Compiler.AppendNode
                        (
                            plan,
                            node,
                            Instructions.And,
                            EmitBrowseNilNode(plan, order.Columns[orderIndex].Column, false)
                        );
                }
            }

            if (node == null)
            {
                node = new ValueNode(plan.DataTypes.SystemBoolean, inclusive);
            }

            return(node);
        }
예제 #11
0
        protected PlanNode EmitBrowseVariantNode(Plan plan, int originIndex, bool forward, bool inclusive)
        {
            Schema.Order originOrder = new Schema.Order();
            for (int index = 0; index <= originIndex; index++)
            {
                originOrder.Columns.Add(new Schema.OrderColumn(Order.Columns[index].Column, Order.Columns[index].Ascending, Order.Columns[index].IncludeNils));
            }
            Schema.IRowType origin = new Schema.RowType(originOrder.Columns, Keywords.Origin);
            //plan.PushCursorContext(new CursorContext(CursorType, CursorCapabilities & ~(CursorCapability.BackwardsNavigable | CursorCapability.Bookmarkable | CursorCapability.Searchable | CursorCapability.Countable), CursorIsolation));
            //try
            //{
            plan.EnterRowContext();
            try
            {
                plan.Symbols.Push(new Symbol(String.Empty, origin));
                try
                {
                    var cursorExpression = EmitBrowseVariantExpression(originOrder, origin, originIndex, forward, inclusive);
                    var cursorDefinition =
                        new CursorDefinition
                        (
                            cursorExpression,
                            CursorCapabilities & ~(CursorCapability.BackwardsNavigable | CursorCapability.Bookmarkable | CursorCapability.Searchable | CursorCapability.Countable),
                            CursorIsolation,
                            CursorType
                        );
                    var resultNode = Compiler.Compile(plan, cursorDefinition, true);

                    return(resultNode.ExtractNode <TableNode>());
                }
                finally
                {
                    plan.Symbols.Pop();
                }
            }
            finally
            {
                plan.ExitRowContext();
            }
            //}
            //finally
            //{
            //	plan.PopCursorContext();
            //}
        }
예제 #12
0
        ///<summary>Returns true if the given key has the same number of columns in the same order as the node order key.</summary>
        protected bool IsKeyRow(IRow key)
        {
            Schema.Order order = Order;
            if (key.DataType.Columns.Count != order.Columns.Count)
            {
                return(false);
            }

            for (int index = 0; index < order.Columns.Count; index++)
            {
                if ((key.DataType.Columns.Count <= index) || !Schema.Object.NamesEqual(key.DataType.Columns[index].Name, order.Columns[index].Column.Name))
                {
                    return(false);
                }
            }

            return(true);
        }
예제 #13
0
        protected Expression EmitBrowseConditionExpression
        (
            Schema.Order order,
            Schema.IRowType origin,
            bool forward,
            bool inclusive
        )
        {
            Expression expression = null;

            for (int orderIndex = order.Columns.Count - 1; orderIndex >= 0; orderIndex--)
            {
                if ((origin != null) && (orderIndex < origin.Columns.Count))
                {
                    expression =
                        AppendExpression
                        (
                            expression,
                            Instructions.Or,
                            EmitBrowseOriginExpression(order, forward, inclusive, orderIndex)
                        );
                }
                else
                                        #if USEINCLUDENILSWITHBROWSE
                if (order.Columns[orderIndex].Column.IsNilable && !order.Columns[orderIndex].IncludeNils)
                                        #endif
                {
                    expression =
                        AppendExpression
                        (
                            expression,
                            Instructions.And,
                            EmitBrowseNilExpression(order.Columns[orderIndex].Column, false)
                        );
                }
            }

            if (expression == null)
            {
                expression = new ValueExpression(inclusive, TokenType.Boolean);
            }

            return(expression);
        }
예제 #14
0
        protected PlanNode EmitBrowseOriginNode
        (
            Plan plan,
            Schema.Order order,
            bool forward,
            bool inclusive,
            int originIndex
        )
        {
            PlanNode node = null;

            for (int index = 0; index < originIndex; index++)
            {
                PlanNode equalNode = EmitBrowseColumnNode(plan, order.Columns[index], Instructions.Equal);

                node = Compiler.AppendNode(plan, node, Instructions.And, equalNode);
            }

            node =
                Compiler.AppendNode
                (
                    plan,
                    node,
                    Instructions.And,
                    EmitBrowseComparisonNode(plan, order, forward, inclusive, originIndex)
                );

            for (int index = originIndex + 1; index < order.Columns.Count; index++)
            {
                if (order.Columns[index].Column.IsNilable && !order.Columns[index].IncludeNils)
                {
                    node =
                        Compiler.AppendNode
                        (
                            plan,
                            node,
                            Instructions.And,
                            EmitBrowseNilNode(plan, order.Columns[index].Column, false)
                        );
                }
            }
            return(node);
        }
예제 #15
0
        private void DetermineRestrictionAlgorithm(Plan plan)
        {
            // determine restriction algorithm
            _restrictionAlgorithm = typeof(FilterTable);

            // If the node is not supported because of chunking, or because the scalar condition on the restrict was not supported,
            // a filter must be used because a seek or scan would not be supported either
            // Note that the call to HasDeviceOperator is preventing a duplicate resolution in the case that the operator is not mapped.
            if (((_device == null) || (_device.ResolveDeviceOperator(plan, Operator) == null)) && (_isSeekable || _isScanable))
            {
                // if IsSargable returns true, a column conditions list has been built where
                // the conditions for each column are separated and the comparison instructions are known
                if (_isSeekable)
                {
                    // The condition contains only equal comparisons against all the columns of some key
                    Schema.Order seekOrder = FindSeekOrder(plan);
                    Nodes[0] = Compiler.EnsureSearchableNode(plan, SourceNode, seekOrder);
                    Order    = CopyOrder(SourceNode.Order);
                    _restrictionAlgorithm = typeof(SeekTable);
                    _firstKeyNodes        = new Condition[Order.Columns.Count];
                    for (int index = 0; index < _firstKeyNodes.Length; index++)
                    {
                        _firstKeyNodes[index] = new Condition(_conditions[Order.Columns[index].Column][0].Argument, false);
                    }
                }
                else if (_isScanable)
                {
                    // The condition contains range comparisons against the columns of some order
                    Schema.Order scanOrder = FindScanOrder(plan);
                    Nodes[0] = Compiler.EnsureSearchableNode(plan, SourceNode, scanOrder);
                    Order    = CopyOrder(SourceNode.Order);
                    _restrictionAlgorithm = typeof(ScanTable);
                }
            }
            else
            {
                if ((Order == null) && (SourceNode.Order != null))
                {
                    Order = CopyOrder(SourceNode.Order);
                }
            }
        }
예제 #16
0
        protected Expression EmitBrowseOriginExpression
        (
            Schema.Order order,
            bool forward,
            bool inclusive,
            int originIndex
        )
        {
            Expression expression = null;

            for (int index = 0; index < originIndex; index++)
            {
                Expression equalExpression = EmitBrowseColumnExpression(order.Columns[index], Instructions.Equal);

                expression = AppendExpression(expression, Instructions.And, equalExpression);
            }

            expression =
                AppendExpression
                (
                    expression,
                    Instructions.And,
                    EmitBrowseComparisonExpression(order, forward, inclusive, originIndex)
                );

            for (int index = originIndex + 1; index < order.Columns.Count; index++)
            {
                if (order.Columns[index].Column.IsNilable && !order.Columns[index].IncludeNils)
                {
                    expression =
                        AppendExpression
                        (
                            expression,
                            Instructions.And,
                            EmitBrowseNilExpression(order.Columns[index].Column, false)
                        );
                }
            }

            return(expression);
        }
예제 #17
0
        /// <summary>
        /// Returns a row that is guaranteed to contain the same or fewer columns in the same order as the node order,
        ///	and once a column is null, the rest of the columns are null as well.  If the given row does not satisfy this
        /// requirement, a row of the proper row type is created and the values from the given row are copied into it.
        /// If no such row can be created, null is returned.
        /// </summary>
        protected IRow EnsurePartialKeyRow(IRow key)
        {
            if (IsPartialKeyRow(key))
            {
                return(key);
            }
            else
            {
                bool            isNull  = false;
                Schema.IRowType rowType = DataType.CreateRowType(String.Empty, false);
                Schema.Order    order   = Order;
                for (int index = 0; index < order.Columns.Count; index++)
                {
                    int columnIndex = key.DataType.Columns.IndexOfName(order.Columns[index].Column.Name);
                    if (columnIndex >= 0)
                    {
                        rowType.Columns.Add(order.Columns[index].Column.Column.Copy());
                        if (isNull && key.HasValue(columnIndex))
                        {
                            return(null);
                        }

                        if (!key.HasValue(index))
                        {
                            isNull = true;
                        }
                    }
                    else
                    {
                        break;
                    }
                }

                Row localKey = new Row(Manager, rowType);
                key.CopyTo(localKey);
                return(localKey);
            }
        }
예제 #18
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);
        }
예제 #19
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);
        }
예제 #20
0
 public bool OrderIncludesOrder(Schema.Order includingOrder, Schema.Order includedOrder)
 {
     return(Compiler.OrderIncludesOrder(_plan, includingOrder, includedOrder));
 }
예제 #21
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
                        )
                    );
                }
            }
        }
예제 #22
0
 public bool Contains(Schema.Order key)
 {
     return(IndexOf(key) >= 0);
 }
예제 #23
0
 public bool OrderIncludesKey(Schema.Order includingOrder, Schema.Key includedKey)
 {
     return(Compiler.OrderIncludesKey(_plan, includingOrder, includedKey));
 }
예제 #24
0
 public NativeRowTree this[Schema.Order key] {
     get { return(this[IndexOf(key)]); }
 }
예제 #25
0
        public override void DetermineDataType(Plan plan)
        {
            DetermineModifiers(plan);
            _dataType       = new Schema.TableType();
            _tableVar       = new Schema.ResultTableVar(this);
            _tableVar.Owner = plan.User;
            _tableVar.InheritMetaData(SourceTableVar.MetaData);
            _tableVar.MergeMetaData(MetaData);
            AlterNode.AlterMetaData(_tableVar, AlterMetaData, true);
            CopyTableVarColumns(SourceTableVar.Columns);
            int sourceColumnIndex;

            Schema.TableVarColumn sourceColumn;
            Schema.TableVarColumn newColumn;
            _isRestrict = false;
            PlanNode restrictNode = null;
            PlanNode constraintNode;

            foreach (AdornColumnExpression expression in _expressions)
            {
                sourceColumnIndex = TableVar.Columns.IndexOf(expression.ColumnName);
                sourceColumn      = TableVar.Columns[expression.ColumnName];
                newColumn         = CopyTableVarColumn(sourceColumn);
                if (expression.ChangeNilable)
                {
                    newColumn.IsNilable = expression.IsNilable;
                }
                newColumn.MergeMetaData(expression.MetaData);
                AlterNode.AlterMetaData(newColumn, expression.AlterMetaData, true);
                newColumn.ReadOnly = Convert.ToBoolean(MetaData.GetTag(newColumn.MetaData, "Frontend.ReadOnly", newColumn.ReadOnly.ToString()));

                foreach (ConstraintDefinition constraint in expression.Constraints)
                {
                    _isRestrict = true;
                    Schema.TableVarColumnConstraint newConstraint = Compiler.CompileTableVarColumnConstraint(plan, TableVar, newColumn, constraint);

                    //Schema.TableVarColumnConstraint newConstraint = new Schema.TableVarColumnConstraint(Schema.Object.GetObjectID(constraint.MetaData), constraint.ConstraintName);
                    //newConstraint.ConstraintType = Schema.ConstraintType.Column;
                    //newConstraint.MergeMetaData(constraint.MetaData);
                    plan.PushCreationObject(newConstraint);
                    try
                    {
                        plan.Symbols.Push(new Symbol(Keywords.Value, newColumn.DataType));
                        try
                        {
                            //PlanNode node = Compiler.CompileBooleanExpression(plan, constraint.Expression);
                            //newConstraint.Node = node;
                            //newConstraint.IsRemotable = true;
                            //if (newConstraint.HasDependencies())
                            //	for (int index = 0; index < newConstraint.Dependencies.Count; index++)
                            //	{
                            //		Schema.Object objectValue = newConstraint.Dependencies.Objects[index];
                            //		if (objectValue != null)
                            //		{
                            //			if (!objectValue.IsRemotable)
                            //			{
                            //				newConstraint.IsRemotable = false;
                            //				break;
                            //			}
                            //		}
                            //		else
                            //		{
                            //			Error.Fail("Missing object dependency in AdornNode.");
                            //			//Schema.ObjectHeader LHeader = APlan.CatalogDeviceSession.SelectObjectHeader(LNewConstraint.Dependencies.IDs[LIndex]);
                            //			//if (!LHeader.IsRemotable)
                            //			//{
                            //			//    LNewConstraint.IsRemotable = false;
                            //			//    break;
                            //			//}
                            //		}
                            //	}

                            newColumn.Constraints.Add(newConstraint);

                            constraintNode = Compiler.CompileBooleanExpression(plan, constraint.Expression);
                            constraintNode = ReplaceColumnReferences(plan, constraintNode, sourceColumn.Name, sourceColumnIndex);
                            if (restrictNode == null)
                            {
                                restrictNode = constraintNode;
                            }
                            else
                            {
                                restrictNode = Compiler.EmitBinaryNode(plan, restrictNode, Instructions.And, constraintNode);
                            }
                        }
                        finally
                        {
                            plan.Symbols.Pop();
                        }
                    }
                    finally
                    {
                        plan.PopCreationObject();
                    }

                    if (newConstraint.HasDependencies())
                    {
                        plan.AttachDependencies(newConstraint.Dependencies);
                    }
                }

                // TODO: verify that the default satisfies the constraints
                if (expression.Default != null)
                {
                    newColumn.Default = Compiler.CompileTableVarColumnDefault(plan, _tableVar, newColumn, expression.Default);
                    if (newColumn.Default.HasDependencies())
                    {
                        plan.AttachDependencies(newColumn.Default.Dependencies);
                    }
                }

                if (expression.MetaData != null)
                {
                    Tag tag;
                    tag = expression.MetaData.Tags.GetTag("DAE.IsDefaultRemotable");
                    if (tag != Tag.None)
                    {
                        newColumn.IsDefaultRemotable = newColumn.IsDefaultRemotable && Convert.ToBoolean(tag.Value);
                    }

                    tag = expression.MetaData.Tags.GetTag("DAE.IsChangeRemotable");
                    if (tag != Tag.None)
                    {
                        newColumn.IsChangeRemotable = newColumn.IsChangeRemotable && Convert.ToBoolean(tag.Value);
                    }

                    tag = expression.MetaData.Tags.GetTag("DAE.IsValidateRemotable");
                    if (tag != Tag.None)
                    {
                        newColumn.IsValidateRemotable = newColumn.IsValidateRemotable && Convert.ToBoolean(tag.Value);
                    }
                }

                DataType.Columns[sourceColumnIndex] = newColumn.Column;
                TableVar.Columns[sourceColumnIndex] = newColumn;
            }

            // Keys
            CopyKeys(SourceTableVar.Keys);
            foreach (DropKeyDefinition keyDefinition in _dropKeys)
            {
                Schema.Key oldKey = Compiler.FindKey(plan, TableVar, keyDefinition);

                TableVar.Keys.SafeRemove(oldKey);
                TableVar.Constraints.SafeRemove(oldKey.Constraint);
                TableVar.InsertConstraints.SafeRemove(oldKey.Constraint);
                TableVar.UpdateConstraints.SafeRemove(oldKey.Constraint);
            }

            foreach (AlterKeyDefinition keyDefinition in _alterKeys)
            {
                Schema.Key oldKey = Compiler.FindKey(plan, TableVar, keyDefinition);
                AlterNode.AlterMetaData(oldKey, keyDefinition.AlterMetaData);
            }

            Compiler.CompileTableVarKeys(plan, _tableVar, _keys, false);

            // Orders
            CopyOrders(SourceTableVar.Orders);

            foreach (DropOrderDefinition orderDefinition in _dropOrders)
            {
                Schema.Order oldOrder = Compiler.FindOrder(plan, TableVar, orderDefinition);

                TableVar.Orders.SafeRemove(oldOrder);
            }

            foreach (AlterOrderDefinition orderDefinition in _alterOrders)
            {
                AlterNode.AlterMetaData(Compiler.FindOrder(plan, TableVar, orderDefinition), orderDefinition.AlterMetaData);
            }

            Compiler.CompileTableVarOrders(plan, _tableVar, _orders);

            if (SourceNode.Order != null)
            {
                Order = CopyOrder(SourceNode.Order);
            }

            // Constraints
            Compiler.CompileTableVarConstraints(plan, _tableVar, _constraints);

            if (_tableVar.HasConstraints())
            {
                foreach (Schema.TableVarConstraint constraint in _tableVar.Constraints)
                {
                    if (restrictNode == null)
                    {
                        if (constraint is Schema.RowConstraint)
                        {
                            restrictNode = ((Schema.RowConstraint)constraint).Node;
                            _isRestrict  = true;
                        }
                    }
                    else
                    {
                        if (constraint is Schema.RowConstraint)
                        {
                            restrictNode = Compiler.EmitBinaryNode(plan, restrictNode, Instructions.And, ((Schema.RowConstraint)constraint).Node);
                            _isRestrict  = true;
                        }
                    }

                    if (constraint.HasDependencies())
                    {
                        plan.AttachDependencies(constraint.Dependencies);
                    }
                }
            }

            if (_isRestrict)
            {
                Nodes[0] = Compiler.EmitRestrictNode(plan, Nodes[0], restrictNode);
            }

            DetermineRemotable(plan);

            if (MetaData != null)
            {
                Tag tag;
                Schema.ResultTableVar tableVar = (Schema.ResultTableVar)TableVar;
                tag = MetaData.Tags.GetTag("DAE.IsDefaultRemotable");
                if (tag != Tag.None)
                {
                    tableVar.InferredIsDefaultRemotable = tableVar.InferredIsDefaultRemotable && Convert.ToBoolean(tag.Value);
                }

                tag = MetaData.Tags.GetTag("DAE.IsChangeRemotable");
                if (tag != Tag.None)
                {
                    tableVar.InferredIsChangeRemotable = tableVar.InferredIsChangeRemotable && Convert.ToBoolean(tag.Value);
                }

                tag = MetaData.Tags.GetTag("DAE.IsValidateRemotable");
                if (tag != Tag.None)
                {
                    tableVar.InferredIsValidateRemotable = tableVar.InferredIsValidateRemotable && Convert.ToBoolean(tag.Value);
                }
            }

            if (Order == null)
            {
                string orderName = MetaData.GetTag(MetaData, "DAE.DefaultOrder", String.Empty);
                if (orderName != String.Empty)
                {
                    Order =
                        Compiler.CompileOrderDefinition
                        (
                            plan,
                            TableVar,
                            new Parser().ParseOrderDefinition
                            (
                                MetaData.GetTag
                                (
                                    MetaData,
                                    "DAE.DefaultOrder",
                                    String.Empty
                                )
                            ),
                            false
                        );
                }
            }

            if ((Order != null) && !TableVar.Orders.Contains(Order))
            {
                TableVar.Orders.Add(Order);
            }

                        #if UseReferenceDerivation
                        #if UseElaborable
            if (plan.CursorContext.CursorCapabilities.HasFlag(CursorCapability.Elaborable))
                        #endif
            CopyReferences(plan, SourceTableVar);
                        #endif

            foreach (ReferenceDefinition referenceDefinition in _references)
            {
                // Create a reference on the table var
                Schema.Reference reference = new Schema.Reference(Schema.Object.GetObjectID(referenceDefinition.MetaData), referenceDefinition.ReferenceName, referenceDefinition.MetaData);
                reference.Enforced    = false;
                reference.SourceTable = TableVar;

                foreach (ReferenceColumnDefinition column in referenceDefinition.Columns)
                {
                    reference.SourceKey.Columns.Add(reference.SourceTable.Columns[column.ColumnName]);
                }
                foreach (Schema.Key key in reference.SourceTable.Keys)
                {
                    if (reference.SourceKey.Columns.IsSupersetOf(key.Columns))
                    {
                        reference.SourceKey.IsUnique = true;
                        break;
                    }
                }

                Schema.Object schemaObject = Compiler.ResolveCatalogIdentifier(plan, referenceDefinition.ReferencesDefinition.TableVarName, true);
                if (!(schemaObject is Schema.TableVar))
                {
                    throw new CompilerException(CompilerException.Codes.InvalidReferenceObject, referenceDefinition, referenceDefinition.ReferenceName, referenceDefinition.ReferencesDefinition.TableVarName);
                }
                if (schemaObject.IsATObject)
                {
                    referenceDefinition.ReferencesDefinition.TableVarName = Schema.Object.EnsureRooted(((Schema.TableVar)schemaObject).SourceTableName);
                }
                else
                {
                    referenceDefinition.ReferencesDefinition.TableVarName = Schema.Object.EnsureRooted(schemaObject.Name);                     // Set the TableVarName in the references expression to the resolved identifier so that subsequent compiles do not depend on current library context (This really only matters in remote contexts, but there it is imperative, or this could be an ambiguous identifier)
                }
                plan.AttachDependency(schemaObject);
                reference.TargetTable = (Schema.TableVar)schemaObject;
                reference.AddDependency(schemaObject);

                foreach (ReferenceColumnDefinition column in referenceDefinition.ReferencesDefinition.Columns)
                {
                    reference.TargetKey.Columns.Add(reference.TargetTable.Columns[column.ColumnName]);
                }
                foreach (Schema.Key key in reference.TargetTable.Keys)
                {
                    if (reference.TargetKey.Columns.IsSupersetOf(key.Columns))
                    {
                        reference.TargetKey.IsUnique = true;
                        break;
                    }
                }

                if (!reference.TargetKey.IsUnique)
                {
                    throw new CompilerException(CompilerException.Codes.ReferenceMustTargetKey, referenceDefinition, referenceDefinition.ReferenceName, referenceDefinition.ReferencesDefinition.TableVarName);
                }

                if (reference.SourceKey.Columns.Count != reference.TargetKey.Columns.Count)
                {
                    throw new CompilerException(CompilerException.Codes.InvalidReferenceColumnCount, referenceDefinition, referenceDefinition.ReferenceName);
                }

                TableVar.References.Add(reference);
            }

            if (!plan.IsEngine)
            {
                foreach (AlterReferenceDefinition alterReference in _alterReferences)
                {
                    int referenceIndex = TableVar.References.IndexOf(alterReference.ReferenceName);
                    if (referenceIndex < 0)
                    {
                        referenceIndex = TableVar.References.IndexOfOriginatingReference(alterReference.ReferenceName);
                    }

                    if
                    (
                        (referenceIndex >= 0) ||
                        (
                            (plan.ApplicationTransactionID == Guid.Empty) &&
                            (!plan.InLoadingContext()) &&
                            !plan.InATCreationContext                             // We will be in an A/T creation context if we are reinfering view references for an A/T view
                        )
                    )
                    {
                        Schema.ReferenceBase referenceToAlter;
                        if (referenceIndex < 0)
                        {
                            referenceToAlter = TableVar.References[alterReference.ReferenceName];                             // This is just to throw the object not found error
                        }
                        else
                        {
                            referenceToAlter = TableVar.References[referenceIndex];
                        }
                        AlterNode.AlterMetaData(referenceToAlter, alterReference.AlterMetaData);
                        Schema.Object originatingReference = Compiler.ResolveCatalogIdentifier(plan, referenceToAlter.OriginatingReferenceName(), false);
                        if (originatingReference != null)
                        {
                            plan.AttachDependency(originatingReference);
                        }
                    }
                }
            }

            foreach (DropReferenceDefinition dropReference in _dropReferences)
            {
                //if (TableVar.HasDerivedReferences())
                //{
                //	int referenceIndex = TableVar.DerivedReferences.IndexOf(dropReference.ReferenceName);
                //	if (referenceIndex >= 0)
                //		TableVar.DerivedReferences.RemoveAt(referenceIndex);

                //	referenceIndex = TableVar.DerivedReferences.IndexOfOriginatingReference(dropReference.ReferenceName);
                //	if (referenceIndex >= 0)
                //		TableVar.DerivedReferences.RemoveAt(referenceIndex);
                //}

                //if (TableVar.HasSourceReferences())
                //{
                //	int referenceIndex = TableVar.SourceReferences.IndexOf(dropReference.ReferenceName);
                //	if (referenceIndex >= 0)
                //		TableVar.SourceReferences.RemoveAt(referenceIndex);

                //	referenceIndex = TableVar.SourceReferences.IndexOfOriginatingReference(dropReference.ReferenceName);
                //	if (referenceIndex >= 0)
                //		TableVar.SourceReferences.RemoveAt(referenceIndex);
                //}

                //if (TableVar.HasTargetReferences())
                //{
                //	int referenceIndex = TableVar.TargetReferences.IndexOf(dropReference.ReferenceName);
                //	if (referenceIndex >= 0)
                //		TableVar.TargetReferences.RemoveAt(referenceIndex);

                //	referenceIndex = TableVar.TargetReferences.IndexOfOriginatingReference(dropReference.ReferenceName);
                //	if (referenceIndex >= 0)
                //		TableVar.TargetReferences.RemoveAt(referenceIndex);
                //}

                if (TableVar.HasReferences())
                {
                    int referenceIndex = TableVar.References.IndexOf(dropReference.ReferenceName);
                    if (referenceIndex >= 0)
                    {
                        TableVar.References.RemoveAt(referenceIndex);
                    }

                    referenceIndex = TableVar.References.IndexOfOriginatingReference(dropReference.ReferenceName);
                    if (referenceIndex >= 0)
                    {
                        TableVar.References.RemoveAt(referenceIndex);
                    }
                }
            }
        }