Пример #1
0
        private void AddColumnsForType(Schema.TableVar tableVar, Schema.ScalarType d4Type)
        {
            // Add columns for the base type, if any
            foreach (var parentType in d4Type.ParentTypes)
            {
                AddColumnsForType(tableVar, parentType);
            }

            // Add columns for the default representation
            var representation = Compiler.FindDefaultRepresentation(d4Type);

            if (representation != null)
            {
                // And columns for each property of the default representation
                foreach (var property in representation.Properties)
                {
                    var column         = new Schema.Column(property.Name, property.DataType);
                    var tableVarColumn = new Schema.TableVarColumn(column);
                    tableVar.DataType.Columns.Add(column);
                    tableVar.Columns.Add(tableVarColumn);
                }
            }

            tableVar.AddDependency(d4Type);
        }
Пример #2
0
        protected bool InternalInternalChange(IRow row, string columnName, Program program, bool isDefault)
        {
            bool changed = false;

            PushRow(program, row);
            try
            {
                // Evaluate the Redefined columns
                // TODO: This change code should only run if the column changing can be determined to affect the extended columns...
                int columnIndex;
                for (int index = 0; index < _redefineColumnOffsets.Length; index++)
                {
                    Schema.TableVarColumn column = TableVar.Columns[_redefineColumnOffsets[index]];
                    if ((isDefault || column.IsComputed) && (!program.ServerProcess.ServerSession.Server.IsEngine || column.IsChangeRemotable))
                    {
                        columnIndex = row.DataType.Columns.IndexOfName(column.Name);
                        if (columnIndex >= 0)
                        {
                            if (!isDefault || !row.HasValue(columnIndex))
                            {
                                row[columnIndex] = Nodes[index + 1].Execute(program);
                                changed          = true;
                            }
                        }
                    }
                }
                return(changed);
            }
            finally
            {
                PopRow(program);
            }
        }
Пример #3
0
        public override void DetermineRemotable(Plan plan)
        {
            Schema.ResultTableVar tableVar = (Schema.ResultTableVar)TableVar;
            tableVar.InferredIsDefaultRemotable  = !PropagateDefault || SourceTableVar.IsDefaultRemotable;
            tableVar.InferredIsChangeRemotable   = !PropagateChange || SourceTableVar.IsChangeRemotable;
            tableVar.InferredIsValidateRemotable = !PropagateValidate || SourceTableVar.IsValidateRemotable;
            tableVar.DetermineRemotable(plan.CatalogDeviceSession);

            tableVar.ShouldChange   = PropagateChange && (tableVar.ShouldChange || SourceTableVar.ShouldChange);
            tableVar.ShouldDefault  = PropagateDefault && (tableVar.ShouldDefault || SourceTableVar.ShouldDefault);
            tableVar.ShouldValidate = PropagateValidate && (tableVar.ShouldValidate || SourceTableVar.ShouldValidate);

            for (int index = 0; index < tableVar.Columns.Count; index++)
            {
                Schema.TableVarColumn column       = tableVar.Columns[index];
                Schema.TableVarColumn sourceColumn = SourceTableVar.Columns[index];

                column.ShouldChange   = PropagateChange && (column.ShouldChange || sourceColumn.ShouldChange);
                tableVar.ShouldChange = tableVar.ShouldChange || column.ShouldChange;

                column.ShouldDefault   = PropagateDefault && (column.ShouldDefault || sourceColumn.ShouldDefault);
                tableVar.ShouldDefault = tableVar.ShouldDefault || column.ShouldDefault;

                column.ShouldValidate   = PropagateValidate && (column.ShouldValidate || sourceColumn.ShouldValidate);
                tableVar.ShouldValidate = tableVar.ShouldValidate || column.ShouldValidate;
            }
        }
Пример #4
0
        protected Schema.TableVarColumn GetOrderColumn()
        {
            if (_orderColumn == null)
            {
                //if order is present use it for ordering, if not, attempt to use key. If no key, use the first column.
                _orderColumn =
                    Node.Order != null && Node.Order.Columns.Count > 0
                                                ? Node.TableVar.Columns[Node.TableVar.Columns.IndexOfName(Node.Order.Columns[0].Column.Name)]
                                                :
                    (Key != null && Key.Columns.Count > 0)
                                                                ? Key.Columns[0].Column
                                                                : Node.TableVar.Columns[0];
            }

            return(_orderColumn);
        }
Пример #5
0
        public override Statement EmitStatement(EmitMode mode)
        {
            ExplodeExpression expression = new ExplodeExpression();

            expression.Expression = (Expression)Nodes[0].EmitStatement(mode);
            PlanNode  rootNode  = Nodes[1];
            OrderNode orderNode = rootNode as OrderNode;

            if (orderNode != null)
            {
                expression.HasOrderByClause = true;
                for (int index = 0; index < orderNode.RequestedOrder.Columns.Count; index++)
                {
                    expression.OrderColumns.Add(orderNode.RequestedOrder.Columns[index].EmitStatement(mode));
                }
                rootNode = rootNode.Nodes[0];
            }

            expression.RootExpression = ((RestrictExpression)rootNode.EmitStatement(mode)).Condition;

            PlanNode byNode = Nodes[2];

            if (byNode is OrderNode)
            {
                byNode = byNode.Nodes[0];
            }

            expression.ByExpression = ((RestrictExpression)byNode.EmitStatement(mode)).Condition;

            if (_levelColumnIndex >= 0)
            {
                Schema.TableVarColumn levelColumn = TableVar.Columns[_levelColumnIndex];
                expression.LevelColumn = new IncludeColumnExpression(levelColumn.Name, levelColumn.MetaData == null ? null : levelColumn.MetaData.Copy());
            }

            if (_sequenceColumnIndex >= 0)
            {
                Schema.TableVarColumn sequenceColumn = TableVar.Columns[_sequenceColumnIndex];
                expression.SequenceColumn = new IncludeColumnExpression(sequenceColumn.Name, sequenceColumn.MetaData == null ? null : sequenceColumn.MetaData.Copy());
            }
            expression.Modifiers = Modifiers;
            return(expression);
        }
Пример #6
0
        public override void DetermineRemotable(Plan plan)
        {
            base.DetermineRemotable(plan);

            _tableVar.ShouldChange   = PropagateChangeLeft && (_tableVar.ShouldChange || LeftTableVar.ShouldChange);
            _tableVar.ShouldDefault  = PropagateDefaultLeft && (_tableVar.ShouldDefault || LeftTableVar.ShouldDefault);
            _tableVar.ShouldValidate = PropagateValidateLeft && (_tableVar.ShouldValidate || LeftTableVar.ShouldValidate);

            foreach (Schema.TableVarColumn column in _tableVar.Columns)
            {
                Schema.TableVarColumn sourceColumn = LeftTableVar.Columns[LeftTableVar.Columns.IndexOfName(column.Name)];

                column.ShouldChange    = PropagateChangeLeft && (column.ShouldChange || sourceColumn.ShouldChange);
                _tableVar.ShouldChange = _tableVar.ShouldChange || column.ShouldChange;

                column.ShouldDefault    = PropagateDefaultLeft && (column.ShouldDefault || sourceColumn.ShouldDefault);
                _tableVar.ShouldDefault = _tableVar.ShouldDefault || column.ShouldDefault;

                column.ShouldValidate    = PropagateValidateLeft && (column.ShouldValidate || sourceColumn.ShouldValidate);
                _tableVar.ShouldValidate = _tableVar.ShouldValidate || column.ShouldValidate;
            }
        }
Пример #7
0
        private bool IsSearchParamColumn(Schema.TableVarColumn column)
        {
            if (column.Name == "Id")
            {
                // The Id is always supported for all resources, and corresponds to a simple GET/{id}
                return(true);
            }

            switch (ResourceType)
            {
            // TODO: Have to figure this out...
            case "Appointment":
                switch (column.Name)
                {
                case "Patient": return(true);

                case "Practitioner": return(true);

                default: return(false);
                }

            default: return(false);
            }
        }
Пример #8
0
 private bool IsSearchParamColumn(Schema.TableVarColumn column)
 {
     return(_searchParams != null && _searchParams.GetType().GetMember(PHINVADSDevice.GetSearchParamIndicatorName(_resourceType, column.Name)) != null);
 }
Пример #9
0
        // Update
        protected override void InternalExecuteUpdate(Program program, IRow oldRow, IRow newRow, BitArray valueFlags, bool checkConcurrency, bool uncheckedValue)
        {
            base.InternalExecuteUpdate(program, oldRow, newRow, valueFlags, checkConcurrency, uncheckedValue);

            if (PropagateUpdate)
            {
                int columnIndex;
                for (int index = 1; index < Nodes.Count; index++)
                {
                    Schema.TableVarColumn column = TableVar.Columns[_extendColumnOffset + index - 1];
                    if (column.ColumnType == Schema.TableVarColumnType.Stored)
                    {
                        columnIndex = newRow.DataType.Columns.IndexOfName(column.Column.Name);
                        if (columnIndex >= 0)
                        {
                            TableNode tableNode = Nodes[index] as TableNode;
                            if (tableNode == null)
                            {
                                ExtractRowNode extractRowNode = Nodes[index] as ExtractRowNode;
                                if (extractRowNode != null)
                                {
                                    tableNode = (TableNode)extractRowNode.Nodes[0];
                                }
                            }

                            if (tableNode == null)
                            {
                                throw new RuntimeException(RuntimeException.Codes.InternalError, "Could not determine update path for extend column.");
                            }

                            bool referencesUpdatedColumn = ReferencesUpdatedColumn(tableNode, valueFlags);

                            // If the value is a row
                            // If the newValue is nil
                            // If the oldValue is not nil
                            // delete the table node
                            // else
                            // If the oldValue is nil
                            // insert the row
                            // else
                            // update the row

                            // If the value is a table
                            // If the newValue is nil
                            // If the oldValue is not nil
                            // delete all rows
                            // else
                            // If the oldValue is nil
                            // insert all rows
                            // else
                            // foreach row in oldvalue
                            // if there is a corresponding row in new value by the clustering key
                            // update the row
                            // else
                            // delete the row
                            // for each row in newvalue
                            // if there is no corresponding row in old value by the clustering key
                            // insert the row

                            if (column.DataType is Schema.IRowType)
                            {
                                IRow oldValue = (IRow)oldRow.GetValue(columnIndex);
                                IRow newValue = (IRow)newRow.GetValue(columnIndex);
                                if (newValue.IsNil)
                                {
                                    if (!oldValue.IsNil)
                                    {
                                        PushRow(program, oldRow);
                                        try
                                        {
                                            tableNode.Delete(program, oldValue, checkConcurrency, uncheckedValue);
                                        }
                                        finally
                                        {
                                            PopRow(program);
                                        }
                                    }
                                }
                                else
                                {
                                    if (oldValue.IsNil)
                                    {
                                        PushRow(program, newRow);
                                        try
                                        {
                                            tableNode.Insert(program, null, newValue, null, uncheckedValue);
                                        }
                                        finally
                                        {
                                            PopRow(program);
                                        }
                                    }
                                    else
                                    {
                                        if (referencesUpdatedColumn)
                                        {
                                            PushRow(program, oldRow);
                                            try
                                            {
                                                tableNode.Delete(program, oldValue, checkConcurrency, uncheckedValue);
                                            }
                                            finally
                                            {
                                                PopRow(program);
                                            }

                                            PushRow(program, newRow);
                                            try
                                            {
                                                tableNode.Insert(program, null, newValue, null, uncheckedValue);
                                            }
                                            finally
                                            {
                                                PopRow(program);
                                            }
                                        }
                                        else
                                        {
                                            PushRow(program, newRow);
                                            try
                                            {
                                                tableNode.Update(program, oldValue, newValue, null, checkConcurrency, uncheckedValue);
                                            }
                                            finally
                                            {
                                                PopRow(program);
                                            }
                                        }
                                    }
                                }
                            }
                            else
                            {
                                TableValue oldValue = (TableValue)oldRow.GetValue(columnIndex);
                                TableValue newValue = (TableValue)newRow.GetValue(columnIndex);

                                if (newValue.IsNil)
                                {
                                    if (!oldValue.IsNil)
                                    {
                                        PushRow(program, oldRow);
                                        try
                                        {
                                            using (ITable oldValueCursor = oldValue.OpenCursor())
                                            {
                                                while (oldValueCursor.Next())
                                                {
                                                    using (IRow oldValueCursorRow = oldValueCursor.Select())
                                                    {
                                                        tableNode.Delete(program, oldValueCursorRow, checkConcurrency, uncheckedValue);
                                                    }
                                                }
                                            }
                                        }
                                        finally
                                        {
                                            PopRow(program);
                                        }
                                    }
                                }
                                else
                                {
                                    if (referencesUpdatedColumn)
                                    {
                                        PushRow(program, oldRow);
                                        try
                                        {
                                            using (ITable oldValueCursor = oldValue.OpenCursor())
                                            {
                                                while (oldValueCursor.Next())
                                                {
                                                    using (IRow oldValueCursorRow = oldValueCursor.Select())
                                                    {
                                                        tableNode.Delete(program, oldValueCursorRow, checkConcurrency, uncheckedValue);
                                                    }
                                                }
                                            }
                                        }
                                        finally
                                        {
                                            PopRow(program);
                                        }

                                        PushRow(program, newRow);
                                        try
                                        {
                                            using (ITable newValueCursor = newValue.OpenCursor())
                                            {
                                                while (newValueCursor.Next())
                                                {
                                                    using (IRow newValueCursorRow = newValueCursor.Select())
                                                    {
                                                        tableNode.Insert(program, null, newValueCursorRow, null, uncheckedValue);
                                                    }
                                                }
                                            }
                                        }
                                        finally
                                        {
                                            PopRow(program);
                                        }
                                    }
                                    else
                                    {
                                        PushRow(program, newRow);
                                        try
                                        {
                                            if (oldValue.IsNil)
                                            {
                                                using (ITable newValueCursor = newValue.OpenCursor())
                                                {
                                                    while (newValueCursor.Next())
                                                    {
                                                        using (IRow newValueCursorRow = newValueCursor.Select())
                                                        {
                                                            tableNode.Insert(program, null, newValueCursorRow, null, uncheckedValue);
                                                        }
                                                    }
                                                }
                                            }
                                            else
                                            {
                                                using (ITable oldValueCursor = oldValue.OpenCursor())
                                                {
                                                    using (ITable newValueCursor = newValue.OpenCursor())
                                                    {
                                                        while (oldValueCursor.Next())
                                                        {
                                                            using (IRow oldValueCursorRow = oldValueCursor.Select())
                                                            {
                                                                if (newValueCursor.FindKey(oldValueCursorRow))
                                                                {
                                                                    using (IRow newValueCursorRow = newValueCursor.Select())
                                                                    {
                                                                        tableNode.Update(program, oldValueCursorRow, newValueCursorRow, null, checkConcurrency, uncheckedValue);
                                                                    }
                                                                }
                                                                else
                                                                {
                                                                    tableNode.Delete(program, oldValueCursorRow, checkConcurrency, uncheckedValue);
                                                                }
                                                            }
                                                        }

                                                        newValueCursor.Reset();

                                                        while (newValueCursor.Next())
                                                        {
                                                            using (IRow newValueCursorRow = newValueCursor.Select())
                                                            {
                                                                if (!oldValueCursor.FindKey(newValueCursorRow))
                                                                {
                                                                    tableNode.Insert(program, null, newValueCursorRow, null, uncheckedValue);
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                        finally
                                        {
                                            PopRow(program);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Пример #10
0
        // Delete
        protected override void InternalExecuteDelete(Program program, IRow row, bool checkConcurrency, bool uncheckedValue)
        {
            base.InternalExecuteDelete(program, row, checkConcurrency, uncheckedValue);

            if (PropagateDelete)
            {
                PushRow(program, row);
                try
                {
                    int columnIndex;
                    for (int index = 1; index < Nodes.Count; index++)
                    {
                        Schema.TableVarColumn column = TableVar.Columns[_extendColumnOffset + index - 1];
                        if (column.ColumnType == Schema.TableVarColumnType.Stored)
                        {
                            columnIndex = row.DataType.Columns.IndexOfName(column.Column.Name);
                            if (columnIndex >= 0)
                            {
                                TableNode tableNode = Nodes[index] as TableNode;
                                if (tableNode == null)
                                {
                                    ExtractRowNode extractRowNode = Nodes[index] as ExtractRowNode;
                                    if (extractRowNode != null)
                                    {
                                        tableNode = (TableNode)extractRowNode.Nodes[0];
                                    }
                                }

                                if (tableNode == null)
                                {
                                    throw new RuntimeException(RuntimeException.Codes.InternalError, "Could not determine update path for extend column.");
                                }

                                IDataValue oldValue = row.GetValue(columnIndex);
                                if (!oldValue.IsNil)
                                {
                                    IRow oldRowValue = oldValue as IRow;
                                    if (oldRowValue != null)
                                    {
                                        tableNode.Delete(program, oldRowValue, checkConcurrency, uncheckedValue);
                                    }
                                    else
                                    {
                                        TableValue oldTableValue = (TableValue)oldValue;
                                        using (ITable oldTableCursor = oldTableValue.OpenCursor())
                                        {
                                            while (oldTableCursor.Next())
                                            {
                                                using (IRow oldTableCursorRow = oldTableCursor.Select())
                                                {
                                                    tableNode.Delete(program, oldTableCursorRow, checkConcurrency, uncheckedValue);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                finally
                {
                    PopRow(program);
                }
            }
        }
Пример #11
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);
            CopyTableVarColumns(SourceTableVar.Columns);
            _extendColumnOffset = TableVar.Columns.Count;

            // This structure will track key columns as a set of sets, and any extended columns that are equivalent to them
            Dictionary <string, Schema.Key> keyColumns = new Dictionary <string, Schema.Key>();

            foreach (Schema.TableVarColumn tableVarColumn in TableVar.Columns)
            {
                if (SourceTableVar.Keys.IsKeyColumnName(tableVarColumn.Name) && !keyColumns.ContainsKey(tableVarColumn.Name))
                {
                    keyColumns.Add(tableVarColumn.Name, new Schema.Key(new Schema.TableVarColumn[] { tableVarColumn }));
                }
            }

            ApplicationTransaction transaction = null;

            if (plan.ApplicationTransactionID != Guid.Empty)
            {
                transaction = plan.GetApplicationTransaction();
            }
            try
            {
                if (transaction != null)
                {
                    transaction.PushLookup();
                }
                try
                {
                    plan.PushCursorContext(new CursorContext(CursorType.Dynamic, CursorCapability.Navigable, CursorIsolation.None));
                    try
                    {
                        plan.EnterRowContext();
                        try
                        {
                            plan.Symbols.Push(new Symbol(String.Empty, SourceTableType.RowType));
                            try
                            {
                                // Add a column for each expression
                                PlanNode planNode;
                                Schema.TableVarColumn newColumn;
                                foreach (NamedColumnExpression column in _expressions)
                                {
                                    newColumn = new Schema.TableVarColumn(new Schema.Column(column.ColumnAlias, plan.DataTypes.SystemScalar));
                                    plan.PushCreationObject(newColumn);
                                    try
                                    {
                                        planNode = Compiler.CompileExpression(plan, column.Expression);
                                    }
                                    finally
                                    {
                                        plan.PopCreationObject();
                                    }

                                    bool isChangeRemotable = true;
                                    if (newColumn.HasDependencies())
                                    {
                                        for (int index = 0; index < newColumn.Dependencies.Count; index++)
                                        {
                                            Schema.Object objectValue = newColumn.Dependencies.ResolveObject(plan.CatalogDeviceSession, index);
                                            isChangeRemotable = isChangeRemotable && objectValue.IsRemotable;
                                            plan.AttachDependency(objectValue);
                                        }
                                    }

                                    bool isUpdatable = planNode is TableNode || planNode is ExtractRowNode;

                                    newColumn =
                                        new Schema.TableVarColumn
                                        (
                                            new Schema.Column(column.ColumnAlias, planNode.DataType),
                                            column.MetaData,
                                            isUpdatable ? Schema.TableVarColumnType.Stored : Schema.TableVarColumnType.Virtual
                                        );

                                    newColumn.IsNilable          = planNode.IsNilable;
                                    newColumn.IsChangeRemotable  = isChangeRemotable;
                                    newColumn.IsDefaultRemotable = isChangeRemotable;

                                    DataType.Columns.Add(newColumn.Column);
                                    TableVar.Columns.Add(newColumn);

                                    string columnName = String.Empty;
                                    if (IsColumnReferencing(planNode, ref columnName))
                                    {
                                        // TODO: In theory we could allow updatability through an IsColumnReferencing add column as well
                                        Schema.TableVarColumn referencedColumn = TableVar.Columns[columnName];
                                        if (SourceTableVar.Keys.IsKeyColumnName(referencedColumn.Name))
                                        {
                                            Schema.Key key;
                                            if (keyColumns.TryGetValue(referencedColumn.Name, out key))
                                            {
                                                key.Columns.Add(newColumn);
                                            }
                                            else
                                            {
                                                keyColumns.Add(referencedColumn.Name, new Schema.Key(new Schema.TableVarColumn[] { newColumn }));
                                            }
                                        }
                                    }

                                    Nodes.Add(planNode);
                                }

                                DetermineRemotable(plan);
                            }
                            finally
                            {
                                plan.Symbols.Pop();
                            }
                        }
                        finally
                        {
                            plan.ExitRowContext();
                        }
                    }
                    finally
                    {
                        plan.PopCursorContext();
                    }
                }
                finally
                {
                    if (transaction != null)
                    {
                        transaction.PopLookup();
                    }
                }
            }
            finally
            {
                if (transaction != null)
                {
                    Monitor.Exit(transaction);
                }
            }

            foreach (Schema.Key key in SourceTableVar.Keys)
            {
                // Seed the result key set with the empty set
                Schema.Keys resultKeys = new Schema.Keys();
                resultKeys.Add(new Schema.Key());

                foreach (Schema.TableVarColumn column in key.Columns)
                {
                    resultKeys = KeyProduct(resultKeys, keyColumns[column.Name]);
                }

                foreach (Schema.Key resultKey in resultKeys)
                {
                    resultKey.IsSparse    = key.IsSparse;
                    resultKey.IsInherited = true;
                    resultKey.MergeMetaData(key.MetaData);
                    TableVar.Keys.Add(resultKey);
                }
            }

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

                        #if UseReferenceDerivation
                        #if UseElaborable
            if (plan.CursorContext.CursorCapabilities.HasFlag(CursorCapability.Elaborable))
                        #endif
            CopyReferences(plan, SourceTableVar);
                        #endif
        }
Пример #12
0
        // Insert
        protected override void InternalExecuteInsert(Program program, IRow oldRow, IRow newRow, BitArray valueFlags, bool uncheckedValue)
        {
            base.InternalExecuteInsert(program, oldRow, newRow, valueFlags, uncheckedValue);

            if (PropagateInsert != PropagateAction.False)
            {
                PushRow(program, newRow);
                try
                {
                    int columnIndex;
                    for (int index = 1; index < Nodes.Count; index++)
                    {
                        Schema.TableVarColumn column = TableVar.Columns[_extendColumnOffset + index - 1];
                        if (column.ColumnType == Schema.TableVarColumnType.Stored)
                        {
                            columnIndex = newRow.DataType.Columns.IndexOfName(column.Column.Name);
                            if (columnIndex >= 0)
                            {
                                TableNode tableNode = Nodes[index] as TableNode;
                                if (tableNode == null)
                                {
                                    ExtractRowNode extractRowNode = Nodes[index] as ExtractRowNode;
                                    if (extractRowNode != null)
                                    {
                                        tableNode = (TableNode)extractRowNode.Nodes[0];
                                    }
                                }

                                if (tableNode == null)
                                {
                                    throw new RuntimeException(RuntimeException.Codes.InternalError, "Could not determine update path for extend column.");
                                }

                                IDataValue newValue = newRow.GetValue(columnIndex);
                                if (!newValue.IsNil)
                                {
                                    IRow newRowValue = newValue as IRow;
                                    if (newRowValue != null)
                                    {
                                        PerformInsert(program, tableNode, null, newRowValue, null, uncheckedValue);
                                    }
                                    else
                                    {
                                        TableValue newTableValue = (TableValue)newValue;
                                        using (ITable newTableCursor = newTableValue.OpenCursor())
                                        {
                                            while (newTableCursor.Next())
                                            {
                                                using (IRow newTableCursorRow = newTableCursor.Select())
                                                {
                                                    PerformInsert(program, tableNode, null, newTableCursorRow, null, uncheckedValue);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                finally
                {
                    PopRow(program);
                }
            }
        }
Пример #13
0
        // TODO: Compile row types for each index, saving column indexes to prevent the need for lookup during insert, update, and delete.
        private void InternalInitialize(ServerProcess AProcess)
        {
            Schema.RowType LKeyRowType;
            Schema.RowType LDataRowType;

            // Create the indexes required to store data as described by the given table type
            // Determine Fanout, Capacity, Clustering Key, KeyLength, DataLength
            FClusteringKey = TableVar.FindClusteringOrder(AProcess.Plan);
            //Schema.Key LClusteringKey = TableVar.FindClusteringKey();
            //FClusteringKey = new Schema.Order(LClusteringKey, AProcess.Plan);
            LKeyRowType  = new Schema.RowType(FClusteringKey.Columns);
            LDataRowType = new Schema.RowType();
            foreach (Schema.Column LColumn in TableVar.DataType.Columns)
            {
                if (!FClusteringKey.Columns.Contains(LColumn.Name))
                {
                    LDataRowType.Columns.Add(new Schema.Column(LColumn.Name, LColumn.DataType));
                }
            }

            // Add an internal identifier for uniqueness of keys in nonunique indexes
                        #if USEINTERNALID
            FInternalIDColumn = new Schema.TableVarColumn(new Schema.Column(CInternalIDColumnName, AProcess.Plan.Catalog.DataTypes.SystemGuid), Schema.TableVarColumnType.InternalID);
            LDataRowType.Columns.Add(FInternalIDColumn.Column);
                        #endif

            // Create the Clustered index
            FClusteredIndex =
                new TableBufferIndex
                (
                    AProcess,
                    FClusteringKey,
                    LKeyRowType,
                    LDataRowType,
                    true,
                    FFanout,
                    FCapacity
                );
            Indexes.Add(FClusteredIndex);

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

            // Create non clustered indexes for each key and order (unique sets)
            Schema.Order LKey;
            foreach (Schema.Key LNonClusteredKey in TableVar.Keys)
            {
                if (!FClusteringKey.Includes(LNonClusteredKey))
                {
                    LKey = new Schema.Order(LNonClusteredKey, AProcess.Plan);
                    if (!Indexes.Contains(LKey))
                    {
                        LKeyRowType = new Schema.RowType(LKey.Columns);

                        Indexes.Add
                        (
                            new TableBufferIndex
                            (
                                AProcess,
                                LKey,
                                LKeyRowType,
                                LDataRowType,
                                false,
                                FFanout,
                                FCapacity
                            )
                        );
                    }
                }
            }

            foreach (Schema.Order LOrder in TableVar.Orders)
            {
                // This is a potentially non-unique index, so add a GUID to ensure uniqueness of the key in the BTree
                LKey = new Schema.Order(LOrder);
                                #if USEINTERNALID
                if (!LKey.Includes(LClusteringKey))
                {
                    Schema.OrderColumn LUniqueColumn = new Schema.OrderColumn(FInternalIDColumn, true);
                    LUniqueColumn.Sort = ((Schema.ScalarType)LUniqueColumn.Column.DataType).GetUniqueSort(AProcess.Plan);
                    LKey.Columns.Add(LUniqueColumn);
                }
                                #endif

                if (!Indexes.Contains(LKey))
                {
                    LKeyRowType = new Schema.RowType(LKey.Columns);

                    Indexes.Add
                    (
                        new TableBufferIndex
                        (
                            AProcess,
                            LKey,
                            LKeyRowType,
                            LDataRowType,
                            false,
                            FFanout,
                            FCapacity
                        )
                    );
                }
            }
        }
Пример #14
0
        // AggregateNode
        //		Nodes[0] = Project over {by Columns}
        //			Nodes[0] = ASourceNode
        //		Nodes[1..AggregateExpression.Count] = PlanNode - class determined by lookup from the server catalog
        //			Nodes[0] = Project over {aggregate columns for this expression}
        //				Nodes[0] = Restrict
        //					Nodes[0] = ASourceNode
        //					Nodes[1] = Condition over the first key in the project of the aggregate source (AggregateNode.Nodes[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);

            _sourceNode = SourceNode;

            // TODO: Aggregation source is required to be deterministic because it is long handed, we should do something that allows non-deterministic sources for aggregation
            if (!_sourceNode.IsRepeatable)
            {
                throw new CompilerException(CompilerException.Codes.InvalidAggregationSource, plan.CurrentStatement());
            }

            if (_columns.Count > 0)
            {
                ProjectNode projectNode = (ProjectNode)Compiler.EmitProjectNode(plan, SourceNode, _columns, true);
                Nodes[0] = projectNode;
            }
            else
            {
                Schema.TableType  tableType = new Schema.TableType();
                TableSelectorNode node      = new TableSelectorNode(tableType);
                node.TableVar.Keys.Add(new Schema.Key());
                node.Nodes.Add(new RowSelectorNode(new Schema.RowType()));
                node.DetermineCharacteristics(plan);
                Nodes[0] = node;
            }

            CopyTableVarColumns(SourceTableVar.Columns);
            CopyKeys(SourceTableVar.Keys);
            CopyOrders(SourceTableVar.Orders);
            if (SourceNode.Order != null)
            {
                Order = CopyOrder(SourceNode.Order);
            }

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

            _aggregateColumnOffset = TableVar.Columns.Count;

            Schema.Key compareKey = Compiler.FindClusteringKey(plan, TableVar);

            // Add the computed columns
            plan.EnterRowContext();
            try
            {
                plan.Symbols.Push(new Symbol(String.Empty, DataType.CreateRowType(Keywords.Source)));
                try
                {
                    Schema.RowType        rowType       = new Schema.RowType(compareKey.Columns);
                    Schema.RowType        sourceRowType = new Schema.RowType(compareKey.Columns, Keywords.Source);
                    Schema.TableVarColumn newColumn;
                    foreach (AggregateColumnExpression expression in _computeColumns)
                    {
                        PlanNode sourceNode  = null;
                        string[] columnNames = new string[expression.Columns.Count];
                        for (int index = 0; index < expression.Columns.Count; index++)
                        {
                            columnNames[index] = expression.Columns[index].ColumnName;
                        }

                        if (expression.Distinct)
                        {
                            sourceNode = Compiler.EmitProjectNode(plan, _sourceNode, columnNames, true);
                        }
                        else
                        {
                            sourceNode = _sourceNode;
                        }

                        for (int index = 0; index < columnNames.Length; index++)
                        {
                            if (((TableNode)sourceNode).TableVar.Columns.IndexOf(columnNames[index]) < 0)
                            {
                                throw new Schema.SchemaException(Schema.SchemaException.Codes.ObjectNotFound, columnNames[index]);
                            }
                        }

                        OperatorBindingContext context = new OperatorBindingContext(expression, expression.AggregateOperator, plan.NameResolutionPath, Compiler.AggregateSignatureFromArguments(sourceNode, columnNames, true), false);
                        PlanNode aggregateNode         = Compiler.EmitAggregateCallNode(plan, context, sourceNode, columnNames, expression.HasByClause ? expression.OrderColumns : null);
                        Compiler.CheckOperatorResolution(plan, context);
                        sourceNode = aggregateNode.Nodes[0];                                                                      // Make sure to preserve any conversion and casting done by the operator resolution

                        int stackDisplacement = ((AggregateCallNode)aggregateNode).Operator.Initialization.StackDisplacement + 1; // add 1 to account for the result variable
                        stackDisplacement += columnNames.Length;
                        for (int index = 0; index < stackDisplacement; index++)
                        {
                            plan.Symbols.Push(new Symbol(String.Empty, plan.DataTypes.SystemScalar));
                        }
                        try
                        {
                            // Walk sourceNode (assuming an n-length list of unary table operators) until _sourceNode is found
                            // Insert a restriction between it and a recompile of _sourceNode (to account for possible context changes)

                            if (sourceNode == _sourceNode)
                            {
                                sourceNode = Compiler.EmitRestrictNode(plan, Compiler.CompileExpression(plan, (Expression)_sourceNode.EmitStatement(EmitMode.ForCopy)), Compiler.BuildRowEqualExpression(plan, sourceRowType.Columns, rowType.Columns));
                            }
                            else
                            {
                                PlanNode currentNode = sourceNode;
                                while (currentNode != null)
                                {
                                    if (currentNode.NodeCount >= 1)
                                    {
                                        if (currentNode.Nodes[0] == _sourceNode)
                                        {
                                            currentNode.Nodes[0] = Compiler.EmitRestrictNode(plan, Compiler.CompileExpression(plan, (Expression)_sourceNode.EmitStatement(EmitMode.ForCopy)), Compiler.BuildRowEqualExpression(plan, sourceRowType.Columns, rowType.Columns));
                                            break;
                                        }
                                        currentNode = currentNode.Nodes[0];
                                    }
                                    else
                                    {
                                        Error.Fail("Internal Error: Original source node not found in aggregate invocation argument.");
                                    }
                                }
                            }

                            if (expression.HasByClause)
                            {
                                sourceNode = Compiler.EmitOrderNode(plan, (TableNode)sourceNode, Compiler.CompileOrderColumnDefinitions(plan, ((TableNode)sourceNode).TableVar, expression.OrderColumns, null, false), false);
                            }
                            aggregateNode.Nodes[0] = sourceNode;
                        }
                        finally
                        {
                            for (int index = 0; index < stackDisplacement; index++)
                            {
                                plan.Symbols.Pop();
                            }
                        }

                        newColumn =
                            new Schema.TableVarColumn
                            (
                                new Schema.Column
                                (
                                    expression.ColumnAlias,
                                    aggregateNode.DataType
                                ),
                                expression.MetaData,
                                Schema.TableVarColumnType.Virtual
                            );

                        DataType.Columns.Add(newColumn.Column);
                        TableVar.Columns.Add(newColumn);
                        newColumn.IsNilable = aggregateNode.IsNilable;
                        Nodes.Add(aggregateNode);
                    }

                    DetermineRemotable(plan);
                }
                finally
                {
                    plan.Symbols.Pop();
                }
            }
            finally
            {
                plan.ExitRowContext();
            }
        }
Пример #15
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);
            CopyTableVarColumns(SourceTableVar.Columns);

            if (_levelColumn != null)
            {
                Schema.TableVarColumn levelColumn =
                    Compiler.CompileIncludeColumnExpression
                    (
                        plan,
                        _levelColumn,
                        Keywords.Level,
                        plan.DataTypes.SystemInteger,
                        Schema.TableVarColumnType.Level
                    );
                DataType.Columns.Add(levelColumn.Column);
                TableVar.Columns.Add(levelColumn);
                _levelColumnIndex = TableVar.Columns.Count - 1;
            }

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

            DetermineRemotable(plan);

            //CopyKeys(SourceTableVar.Keys);
            if (_sequenceColumnIndex >= 0)
            {
                Schema.Key sequenceKey = new Schema.Key();
                sequenceKey.IsInherited = true;
                sequenceKey.Columns.Add(TableVar.Columns[_sequenceColumnIndex]);
                TableVar.Keys.Add(sequenceKey);
            }
            CopyOrders(SourceTableVar.Orders);
            Order = Compiler.OrderFromKey(plan, Compiler.FindClusteringKey(plan, TableVar));

                        #if UseReferenceDerivation
                        #if UseElaborable
            if (plan.CursorContext.CursorCapabilities.HasFlag(CursorCapability.Elaborable))
                        #endif
            CopyReferences(plan, SourceTableVar);
                        #endif
        }
Пример #16
0
 public static bool IsColumnVisible(Schema.TableVarColumn column, string pageType)
 {
     return(Convert.ToBoolean(GetTag(column.MetaData, "Visible", pageType, "True")));
 }
Пример #17
0
        protected virtual SearchColumnElement CreateSearchColumnElement(SearchColumnElement element, Schema.TableVarColumn column, string titleSeed, string pageType, bool isReadOnly)
        {
            MetaData metaData = null;

            if (column.MetaData != null)
            {
                metaData = DerivationUtility.ExtractTags(column.MetaData.Tags, "Search", pageType);
            }
            PrepareElement(element, metaData, column.MetaData, titleSeed, pageType, isReadOnly);

            element.Title = DerivationUtility.GetTag(metaData, "Caption", pageType, (column.ColumnType == Schema.TableVarColumnType.RowExists ? String.Empty : titleSeed) + DerivationUtility.GetTag(metaData, "Title", pageType, DerivationUtility.GetTag(column.MetaData, "Title", pageType, Schema.Object.Unqualify(column.Name))));
            element.Hint  = DerivationUtility.GetTag(metaData, "Hint", pageType, DerivationUtility.GetTag(column.MetaData, "Hint", pageType, String.Empty));
            element.Width = Convert.ToInt32(DerivationUtility.GetTag(metaData, "Width", pageType, DerivationUtility.GetTag(column.MetaData, "Width", pageType, (20).ToString())));
            element.Properties.AddOrUpdate("Width", element.Width.ToString());
            element.Properties.AddOrUpdate("ColumnName", element.ColumnName);

            return(element);
        }
Пример #18
0
        protected virtual ColumnElement CreateColumnElement(ColumnElement element, ElaboratedTableVarColumn elaboratedColumn, Schema.TableVarColumn column, string titleSeed, string pageType, bool isReadOnly)
        {
            PrepareElement(element, column.MetaData, null, titleSeed, pageType, isReadOnly);

            if
            (
                (((Schema.ScalarType)column.DataType).NativeType == DAE.Runtime.Data.NativeAccessors.AsString.NativeType) &&
                (elaboratedColumn.ElaboratedReference == null) &&
                !element.Properties.Contains("NilIfBlank") &&
                (element.ElementType != "Choice")                            // TODO: Control types: need a better mechanism for determining whether or not a particular property applies to a particular control type...
            )
            {
                element.Properties.AddOrUpdate("NilIfBlank", "False");
            }

            element.Title = DerivationUtility.GetTag(column.MetaData, "Caption", pageType, DerivationUtility.GetTag(column.MetaData, "Title", pageType, Schema.Object.Unqualify(column.Name)));
            string width = DerivationUtility.GetTag(column.MetaData, "Width", pageType, String.Empty);

            if (width != String.Empty)
            {
                element.Properties.AddOrUpdate("Width", width);
            }
            element.Properties.AddOrUpdate("Source", element.Source);
            element.Properties.AddOrUpdate("ColumnName", element.ColumnName);
            if (column.ReadOnly || isReadOnly || Convert.ToBoolean(DerivationUtility.GetTag(column.MetaData, "ReadOnly", pageType, "False")))
            {
                element.Properties.AddOrUpdate("ReadOnly", "True");
            }

            return(element);
        }
Пример #19
0
 private string GetSearchParamName(Schema.TableVarColumn column)
 {
     return(column.Name);
 }