Beispiel #1
0
        public override void DetermineDataType(Plan plan)
        {
            base.DetermineDataType(plan);

            if (_sequenceColumn != null)
            {
                Schema.TableVarColumn column =
                    Compiler.CompileIncludeColumnExpression
                    (
                        plan,
                        _sequenceColumn,
                        Keywords.Sequence,
                        plan.DataTypes.SystemInteger,
                        Schema.TableVarColumnType.Sequence
                    );
                DataType.Columns.Add(column.Column);
                TableVar.Columns.Add(column);
                _sequenceColumnIndex = TableVar.Columns.Count - 1;

                Schema.Key sequenceKey = new Schema.Key();
                sequenceKey.IsInherited = true;
                sequenceKey.Columns.Add(column);
                TableVar.Keys.Add(sequenceKey);
            }
        }
Beispiel #2
0
        // Validate
        protected override bool InternalValidate(Program program, IRow oldRow, IRow newRow, BitArray valueFlags, string columnName, bool isDescending, bool isProposable)
        {
            if (columnName == String.Empty)
            {
                PushNewRow(program, newRow);
                try
                {
                    foreach (Schema.TableVarColumn column in TableVar.Columns)
                    {
                        if (column.Constraints.Count > 0)
                        {
                            InternalValidateColumnConstraints(newRow, column, program);
                        }
                    }
                }
                finally
                {
                    PopRow(program);
                }
            }
            else
            {
                Schema.TableVarColumn column = TableVar.Columns[TableVar.Columns.IndexOfName(columnName)];
                if ((column.Constraints.Count > 0) && newRow.HasValue(column.Name))
                {
                    InternalValidateColumnConstraints(newRow, column, program);
                }
            }

            return(base.InternalValidate(program, oldRow, newRow, valueFlags, columnName, isDescending, isProposable));
        }
Beispiel #3
0
 public int IndexOf(Schema.TableVarColumn column)
 {
     for (int index = 0; index < Count; index++)
     {
         if (this[index].Column == column)
         {
             return(index);
         }
     }
     return(-1);
 }
Beispiel #4
0
 protected Expression EmitOriginNilExpression(Schema.TableVarColumn column, bool isNil)
 {
     if (isNil)
     {
         return(new CallExpression("IsNil", new Expression[] { new IdentifierExpression(Schema.Object.Qualify(column.Name, Keywords.Origin)) }));
     }
     else
     {
         return(new UnaryExpression(Instructions.Not, EmitOriginNilExpression(column, true)));
     }
 }
Beispiel #5
0
 protected Expression EmitBrowseNilExpression(Schema.TableVarColumn column, bool isNil)
 {
     if (isNil)
     {
         return(new CallExpression("IsNil", new Expression[] { new IdentifierExpression(column.Name) }));
     }
     else
     {
         return(new UnaryExpression(Instructions.Not, EmitBrowseNilExpression(column, true)));
     }
 }
Beispiel #6
0
 protected void InternalValidateColumnConstraints(IRow row, Schema.TableVarColumn column, Program program)
 {
     program.Stack.Push(row[column.Name]);
     try
     {
         foreach (Schema.TableVarColumnConstraint constraint in column.Constraints)
         {
             constraint.Validate(program, Schema.Transition.Insert);
         }
     }
     finally
     {
         program.Stack.Pop();
     }
 }
Beispiel #7
0
 public ColumnConditions this[Schema.TableVarColumn column]
 {
     get
     {
         int index = IndexOf(column);
         if (index < 0)
         {
             ColumnConditions conditions = new ColumnConditions(column);
             Add(conditions);
             return(conditions);
         }
         else
         {
             return(this[index]);
         }
     }
 }
Beispiel #8
0
        protected override void InternalOpen()
        {
            _sourceTables = new Stack(Program.Stack.MaxStackDepth, Program.Stack.MaxCallDepth);
            _sourceTables.PushWindow(0);
            _parentRows = new Stack(Program.Stack.MaxStackDepth, Program.Stack.MaxCallDepth);
            _parentRows.PushWindow(0);
            PushSourceTable(null);
            _sourceRow = new Row(Manager, ((TableNode)Node.Nodes[0]).DataType.RowType);
            _tableType = new Schema.TableType();
            _tableVar  = new Schema.BaseTableVar(_tableType, Program.TempDevice);
            Schema.TableVarColumn newColumn;
            foreach (Schema.TableVarColumn column in Node.TableVar.Columns)
            {
                newColumn = (Schema.TableVarColumn)column.Copy();
                _tableType.Columns.Add(newColumn.Column);
                _tableVar.Columns.Add(newColumn);
            }

            if (Node.SequenceColumnIndex < 0)
            {
                newColumn = new Schema.TableVarColumn(new Schema.Column(Keywords.Sequence, Program.DataTypes.SystemInteger), Schema.TableVarColumnType.Stored);
                _tableType.Columns.Add(newColumn.Column);
                _tableVar.Columns.Add(newColumn);
                _sequenceColumnIndex = _tableVar.Columns.Count - 1;
            }
            else
            {
                _sequenceColumnIndex = Node.SequenceColumnIndex;
            }

            _targetRow = new Row(Manager, _tableType.RowType);
            Schema.Key key = new Schema.Key();
            key.Columns.Add(_tableVar.Columns[_sequenceColumnIndex]);
            _tableVar.Keys.Add(key);
            _buffer = new NativeTable(Manager, _tableVar);
            _scan   = new Scan(Manager, _buffer, _buffer.ClusteredIndex, ScanDirection.Forward, null, null);
            _scan.Open();
            _sequence = 0;
            _empty    = false;
            InternalNext();
            _empty = _scan.EOF();
            _scan.First();
        }
Beispiel #9
0
 protected PlanNode EmitOriginNilNode(Plan plan, Schema.TableVarColumn column, bool isNil)
 {
     if (isNil)
     {
         return
             (Compiler.EmitCallNode
              (
                  plan,
                  "IsNil",
                  new PlanNode[] { Compiler.EmitIdentifierNode(plan, Schema.Object.Qualify(column.Name, Keywords.Origin)) }
              ));
     }
     else
     {
         return
             (Compiler.EmitUnaryNode
              (
                  plan,
                  Instructions.Not,
                  EmitOriginNilNode(plan, column, true)
              ));
     }
 }
Beispiel #10
0
 protected PlanNode EmitBrowseNilNode(Plan plan, Schema.TableVarColumn column, bool isNil)
 {
     if (isNil)
     {
         return
             (Compiler.EmitCallNode
              (
                  plan,
                  "IsNil",
                  new PlanNode[] { Compiler.EmitIdentifierNode(plan, column.Name) }
              ));
     }
     else
     {
         return
             (Compiler.EmitUnaryNode
              (
                  plan,
                  Instructions.Not,
                  EmitBrowseNilNode(plan, column, true)
              ));
     }
 }
Beispiel #11
0
        private bool ConvertSargableArguments(Plan plan)
        {
            // For each comparison,
            // if the column referencing branch contains conversions, attempt to push the conversion to the context literal branch
            // if successful, the comparison is still sargable, and a conversion is placed on the argument node for the condition
            // otherwise, the comparison is not sargable, and a warning should be produced indicating the failure
            // note that the original argument node is still participating in the condition expression
            // this is acceptable because for sargable restrictions, the condition expression is only used
            // for statement emission and device compilation, not for execution of the actual restriction.
            bool canConvert = true;

            for (int columnIndex = 0; columnIndex < _conditions.Count; columnIndex++)
            {
                Schema.TableVarColumn column = _conditions[columnIndex].Column;
                for (int conditionIndex = 0; conditionIndex < _conditions[columnIndex].Count; conditionIndex++)
                {
                    ColumnCondition condition = _conditions[columnIndex][conditionIndex];
                    if (!condition.ColumnReference.DataType.Equals(column.DataType))
                    {
                        // Find a conversion path to convert the type of the argument to the type of the column
                        ConversionContext conversionContext = Compiler.FindConversionPath(plan, condition.Argument.DataType, column.DataType);
                        if (conversionContext.CanConvert)
                        {
                            condition.Argument = Compiler.ConvertNode(plan, condition.Argument, conversionContext);
                        }
                        else
                        {
                            plan.Messages.Add(new CompilerException(CompilerException.Codes.CouldNotConvertSargableArgument, CompilerErrorLevel.Warning, plan.CurrentStatement(), column.Name, conversionContext.SourceType.Name, conversionContext.TargetType.Name));
                            canConvert = false;
                        }
                    }
                }
            }

            return(canConvert);
        }
Beispiel #12
0
 public ColumnConditions(Schema.TableVarColumn column) : base()
 {
     Column = column;
 }
Beispiel #13
0
 public bool Contains(Schema.TableVarColumn column)
 {
     return(IndexOf(column) >= 0);
 }
Beispiel #14
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
                        )
                    );
                }
            }
        }