예제 #1
0
        public static Row GetKeyValues(Program program, Schema.Key key, string keyValue)
        {
            var row = new Row(program.ValueManager, new Schema.RowType(key.Columns));

            try
            {
                var keyValues = SplitKeyValues(keyValue);
                for (var i = 0; i < keyValues.Length; i++)
                {
                    var keyScalar = new Scalar(program.ValueManager, key.Columns[i].DataType as Schema.IScalarType, null);
                    try
                    {
                        keyScalar.AsString = keyValues[i];
                        row[i]             = keyScalar;
                    }
                    finally
                    {
                        keyScalar.Dispose();
                    }
                }

                return(row);
            }
            catch
            {
                row.Dispose();
                throw;
            }
        }
예제 #2
0
        protected static Expression GetMasterDetailCondition(Schema.Key detailKey)
        {
            Expression condition = null;
            Expression equalExpression;

            for (int index = 0; index < detailKey.Columns.Count; index++)
            {
                equalExpression = new BinaryExpression
                                  (
                    new IdentifierExpression(detailKey.Columns[index].Name),
                    Instructions.Equal,
                    new IdentifierExpression(GetParameterName(detailKey.Columns[index].Name))
                                  );

                if (condition == null)
                {
                    condition = equalExpression;
                }
                else
                {
                    condition = new BinaryExpression(condition, Instructions.And, equalExpression);
                }
            }
            return(condition);
        }
예제 #3
0
 protected Schema.Keys KeyProduct(Schema.Keys keys, Schema.Key key)
 {
     Schema.Keys result = new Schema.Keys();
     foreach (Schema.Key localKey in keys)
     {
         foreach (Schema.TableVarColumn newColumn in key.Columns)
         {
             Schema.Key newKey = new Schema.Key();
             newKey.Columns.AddRange(localKey.Columns);
             newKey.Columns.Add(newColumn);
             result.Add(newKey);
         }
     }
     return(result);
 }
예제 #4
0
        protected string GetKeyNames(Schema.TableVar tableVar)
        {
            StringBuilder keyNames = new StringBuilder();

            Schema.Key clusteringKey = _program.FindClusteringKey(tableVar);
            for (int index = 0; index < clusteringKey.Columns.Count; index++)
            {
                if (index > 0)
                {
                    keyNames.Append(", ");
                }
                keyNames.Append(Schema.Object.Qualify(clusteringKey.Columns[index].Name, DerivationUtility.MainElaboratedTableName));
            }
            return(keyNames.ToString());
        }
예제 #5
0
        public override void DetermineAccessPath(Plan plan)
        {
            base.DetermineAccessPath(plan);
            if (!DeviceSupported)
            {
                _differenceAlgorithm = typeof(SearchedDifferenceTable);
                // ensure that the right side is a searchable node
                Schema.Key searchKey = new Schema.Key();
                foreach (Schema.TableVarColumn column in RightTableVar.Columns)
                {
                    searchKey.Columns.Add(column);
                }

                Nodes[1] = Compiler.EnsureSearchableNode(plan, RightNode, searchKey);
            }
        }
예제 #6
0
        protected override void InternalOpen()
        {
            _sourceRow = new Row(Manager, Node.DataType.RowType);
            _leftTable = (ITable)Node.Nodes[0].Execute(Program);
            try
            {
                _rightTable = (ITable)Node.Nodes[1].Execute(Program);
            }
            catch
            {
                _leftTable.Dispose();
                throw;
            }

            Schema.TableType      tableType = new Schema.TableType();
            Schema.BaseTableVar   tableVar  = new Schema.BaseTableVar(tableType, Program.TempDevice);
            Schema.TableVarColumn newColumn;
            foreach (Schema.TableVarColumn column in _leftTable.Node.TableVar.Columns)
            {
                newColumn = column.Inherit();
                tableType.Columns.Add(column.Column);
                tableVar.Columns.Add(column);
            }

            Schema.Key key = new Schema.Key();
            foreach (Schema.TableVarColumn column in Node.TableVar.Keys.MinimumKey(true).Columns)
            {
                key.Columns.Add(tableVar.Columns[column.Name]);
            }
            tableVar.Keys.Add(key);

            _buffer = new NativeTable(Manager, tableVar);
            PopulateBuffer();

            _scan = new Scan(Manager, _buffer, _buffer.ClusteredIndex, ScanDirection.Forward, null, null);
            _scan.Open();
        }
예제 #7
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);

            int index = 0;

            _redefineColumnOffsets = new int[_expressions.Count];
            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 sourceColumn;
                                Schema.TableVarColumn tempColumn;
                                Schema.TableVarColumn newColumn;
                                foreach (NamedColumnExpression column in _expressions)
                                {
                                    int sourceColumnIndex = TableVar.Columns.IndexOf(column.ColumnAlias);
                                    if (sourceColumnIndex < 0)
                                    {
                                        throw new CompilerException(CompilerException.Codes.UnknownIdentifier, column, column.ColumnAlias);
                                    }

                                    sourceColumn = TableVar.Columns[sourceColumnIndex];
                                    tempColumn   = CopyTableVarColumn(sourceColumn);

                                    plan.PushCreationObject(tempColumn);
                                    try
                                    {
                                        planNode = Compiler.CompileExpression(plan, column.Expression);
                                    }
                                    finally
                                    {
                                        plan.PopCreationObject();
                                    }

                                    newColumn = CopyTableVarColumn(sourceColumn);
                                    newColumn.Column.DataType = planNode.DataType;
                                    if (tempColumn.HasDependencies())
                                    {
                                        newColumn.AddDependencies(tempColumn.Dependencies);
                                    }
                                    Schema.Object objectValue;
                                    if (newColumn.HasDependencies())
                                    {
                                        for (int dependencyIndex = 0; index < newColumn.Dependencies.Count; index++)
                                        {
                                            objectValue = newColumn.Dependencies.ResolveObject(plan.CatalogDeviceSession, dependencyIndex);
                                            plan.AttachDependency(objectValue);
                                            newColumn.IsNilable          = planNode.IsNilable;
                                            newColumn.IsChangeRemotable  = newColumn.IsChangeRemotable && objectValue.IsRemotable;
                                            newColumn.IsDefaultRemotable = newColumn.IsDefaultRemotable && objectValue.IsRemotable;
                                        }
                                    }

                                    DataType.Columns[sourceColumnIndex] = newColumn.Column;
                                    TableVar.Columns[sourceColumnIndex] = newColumn;
                                    _redefineColumnOffsets[index]       = sourceColumnIndex;
                                    Nodes.Add(planNode);
                                    index++;
                                }

                                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)
            {
                bool add = true;
                foreach (Schema.TableVarColumn column in key.Columns)
                {
                    if (((IList)_redefineColumnOffsets).Contains(TableVar.Columns.IndexOfName(column.Name)))
                    {
                        add = false;
                        break;
                    }
                }

                if (add)
                {
                    TableVar.Keys.Add(CopyKey(key));
                }
            }

            _distinctRequired = TableVar.Keys.Count == 0;
            if (_distinctRequired)
            {
                Schema.Key newKey = new Schema.Key();
                foreach (Schema.TableVarColumn column in TableVar.Columns)
                {
                    newKey.Columns.Add(column);
                }
                newKey.IsInherited = true;
                TableVar.Keys.Add(newKey);
            }

            foreach (Schema.Order order in SourceTableVar.Orders)
            {
                bool add = true;
                for (int columnIndex = 0; columnIndex < order.Columns.Count; columnIndex++)
                {
                    if (((IList)_redefineColumnOffsets).Contains(TableVar.Columns.IndexOfName(order.Columns[columnIndex].Column.Name)))
                    {
                        add = false;
                        break;
                    }
                }

                if (add)
                {
                    TableVar.Orders.Add(CopyOrder(order));
                }
            }

            DetermineOrder(plan);

            // TODO: Reference derivation on a redefine should exclude affected references
                        #if UseReferenceDerivation
                        #if UseElaborable
            if (plan.CursorContext.CursorCapabilities.HasFlag(CursorCapability.Elaborable))
                        #endif
            CopyReferences(plan, SourceTableVar);
                        #endif
        }
예제 #8
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();
            }
        }
예제 #9
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
        }
예제 #10
0
        // DetermineDataType
        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);

            DetermineColumns(plan);
            DetermineRemotable(plan);

            // copy all non-sparse keys with all fields preserved in the projection
            CopyPreservedKeys(SourceTableVar.Keys, false, false);

            // if at least one non-sparse key is preserved, then we are free to copy preserved sparse keys as well
            if (TableVar.Keys.Count > 0)
            {
                CopyPreservedKeys(SourceTableVar.Keys, false, true);
            }

            CopyPreservedOrders(SourceTableVar.Orders);

            _distinctRequired = (TableVar.Keys.Count == 0);
            if (_distinctRequired)
            {
                Schema.Key newKey = new Schema.Key();
                newKey.IsInherited = true;
                var isComparable = true;
                foreach (Schema.TableVarColumn column in TableVar.Columns)
                {
                    newKey.Columns.Add(column);
                    if (!Compiler.SupportsComparison(plan, column.DataType))
                    {
                        isComparable = false;
                    }
                }

                TableVar.Keys.Add(newKey);
                _key = newKey;

                if (isComparable)
                {
                    if (newKey.Columns.Count > 0)
                    {
                        Nodes[0] = Compiler.EmitOrderNode(plan, SourceNode, newKey, true);
                    }

                    plan.EnterRowContext();
                    try
                    {
                                                #if USENAMEDROWVARIABLES
                        plan.Symbols.Push(new Symbol(Keywords.Left, DataType.RowType));
                                                #else
                        APlan.Symbols.Push(new Symbol(String.Empty, DataType.CreateRowType(Keywords.Left)));
                                                #endif
                        try
                        {
                                                        #if USENAMEDROWVARIABLES
                            plan.Symbols.Push(new Symbol(Keywords.Right, DataType.RowType));
                                                        #else
                            APlan.Symbols.Push(new Symbol(String.Empty, DataType.CreateRowType(Keywords.Right)));
                                                        #endif
                            try
                            {
                                _equalNode =
                                    Compiler.CompileExpression
                                    (
                                        plan,
                                                                                #if USENAMEDROWVARIABLES
                                        Compiler.BuildRowEqualExpression
                                        (
                                            plan,
                                            Keywords.Left,
                                            Keywords.Right,
                                            newKey.Columns,
                                            newKey.Columns
                                        )
                                                                                #else
                                        Compiler.BuildRowEqualExpression
                                        (
                                            APlan,
                                            new Schema.RowType(LNewKey.Columns, Keywords.Left).Columns,
                                            new Schema.RowType(LNewKey.Columns, Keywords.Right).Columns
                                        )
                                                                                #endif
                                    );
                            }
                            finally
                            {
                                plan.Symbols.Pop();
                            }
                        }
                        finally
                        {
                            plan.Symbols.Pop();
                        }
                    }
                    finally
                    {
                        plan.ExitRowContext();
                    }

                    Order = Compiler.OrderFromKey(plan, Compiler.FindClusteringKey(plan, TableVar));
                }
                else
                {
                    _equalitySorts = new Dictionary <String, Schema.Sort>();
                    foreach (var column in Key.Columns)
                    {
                        var equalitySort = Compiler.GetEqualitySort(plan, column.DataType);
                        _equalitySorts.Add(column.Name, equalitySort);
                        plan.AttachDependency(equalitySort);
                    }
                }
            }
            else
            {
                if ((SourceNode.Order != null) && SourceNode.Order.Columns.IsSubsetOf(TableVar.Columns))
                {
                    Order = CopyOrder(SourceNode.Order);
                }
            }

            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
        }
예제 #11
0
        protected void FormAccepted(IFormInterface form)
        {
            if
            (
                _sourceLinkRefresh &&
                (_sourceLink != null) &&
                (_sourceLink.Source != null) &&
                (_sourceLink.Source.DataView.State == DataSetState.Browse) &&
                (form.MainSource != null)                 //&&
                //!Object.ReferenceEquals(FSourceLink.Source.DataView, AForm.MainSource.DataView) // Do not refresh if this is a surrogate
            )
            {
                switch (Mode)
                {
                case FormMode.Delete:
                    form.MainSource.DataView.Close();                             // Close the data view first to prevent the following refresh from causing an unnecessary requery
                    _sourceLink.Source.DataView.Refresh();
                    break;

                case FormMode.Insert:
                case FormMode.Edit:
                    // Find the nearest row in current set
                    DataView sourceView = _sourceLink.Source.DataView;
                    DataView targetView = form.MainSource.DataView;

                    if (sourceView != targetView)
                    {
                        // Determine RefreshSourceKey
                        // Determine RefreshKey

                        // if SourceLinkRefreshKeyNames and RefreshKeyNames are specified, use them, otherwise
                        // if the current order of the source link data view is a subset of the columns in the detail view, use it, otherwise
                        // find the minimum key in the source link data view that is a subset of the columns in the detail view and use it

                        Schema.Order sourceKey = null;
                        Schema.Order targetKey = null;

                        if ((SourceLinkRefreshKeyNames != "") && (RefreshKeyNames != ""))
                        {
                            string[] sourceKeyNames = SourceLinkRefreshKeyNames.Split(new char[] { ';', ',' });
                            string[] targetKeyNames = RefreshKeyNames.Split(new char[] { ';', ',' });
                            if (sourceKeyNames.Length == targetKeyNames.Length)
                            {
                                sourceKey = new Schema.Order();
                                targetKey = new Schema.Order();
                                for (int index = 0; index < sourceKeyNames.Length; index++)
                                {
                                    sourceKey.Columns.Add(new Schema.OrderColumn(sourceView.TableVar.Columns[sourceKeyNames[index]], true));
                                    targetKey.Columns.Add(new Schema.OrderColumn(targetView.TableVar.Columns[targetKeyNames[index]], true));
                                }
                            }
                        }

                        if (sourceKey == null)
                        {
                            if ((sourceView.Order != null) && sourceView.Order.Columns.IsSubsetOf(targetView.TableVar.Columns))
                            {
                                sourceKey = sourceView.Order;
                                targetKey = sourceView.Order;
                            }
                            else
                            {
                                Schema.Key minimumKey = sourceView.TableVar.Keys.MinimumSubsetKey(targetView.TableVar.Columns);
                                if (minimumKey != null)
                                {
                                    sourceKey = new Schema.Order(minimumKey);
                                    targetKey = sourceKey;
                                }
                            }
                        }

                        if (sourceKey != null)
                        {
                            using (Row row = new Row(sourceView.Process.ValueManager, new Schema.RowType(sourceKey.Columns)))
                            {
                                for (int index = 0; index < sourceKey.Columns.Count; index++)
                                {
                                    DataField targetField = targetView[targetKey.Columns[index].Column.Name];
                                    if (targetField.HasValue())
                                    {
                                        row[index] = targetField.Value;
                                    }
                                    else
                                    {
                                        row.ClearValue(index);
                                    }
                                }

                                targetView.Close();                                         // to prevent unnecessary requery

                                string saveOrder = String.Empty;
                                if (!sourceView.Order.Equals(sourceKey))
                                {
                                    saveOrder = sourceView.OrderString;
                                    try
                                    {
                                        sourceView.Order = sourceKey;
                                    }
                                    catch (Exception exception)
                                    {
                                        if (sourceView.OrderString != saveOrder)
                                        {
                                            sourceView.OrderString = saveOrder;
                                        }
                                        else
                                        {
                                            sourceView.Refresh();
                                        }
                                        throw new ClientException(ClientException.Codes.UnableToFindModifiedRow, exception);
                                    }
                                }
                                try
                                {
                                    sourceView.Refresh(row);
                                }
                                finally
                                {
                                    if ((saveOrder != String.Empty) && (sourceView.OrderString != saveOrder))
                                    {
                                        sourceView.OrderString = saveOrder;
                                    }
                                }
                            }
                        }
                        else
                        {
                            targetView.Close();
                            sourceView.Refresh();
                        }
                    }
                    break;
                }
            }

            if ((Mode == FormMode.Insert) && _autoAcceptAfterInsertOnQuery)
            {
                IFormInterface localForm = (IFormInterface)FindParent(typeof(IFormInterface));
                if (localForm.Mode == FormMode.Query)
                {
                    localForm.Close(CloseBehavior.AcceptOrClose);
                }
            }

            if (_onFormAccepted != null)
            {
                _onFormAccepted.Execute(this, new EventParams("AForm", form));
            }

            if (OnFormAcceptedEvent != null)
            {
                OnFormAcceptedEvent(form);
            }
        }
예제 #12
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);

            if (_expressions == null)
            {
                // This is a rename all expression, merge metadata and inherit columns
                _tableVar.MergeMetaData(_metaData);

                // Inherit columns
                Schema.TableVarColumn newColumn;
                foreach (Schema.TableVarColumn column in SourceTableVar.Columns)
                {
                    newColumn = column.Inherit(_tableAlias);
                    DataType.Columns.Add(newColumn.Column);
                    TableVar.Columns.Add(newColumn);
                }
            }
            else
            {
                bool columnAdded;
                Schema.TableVarColumn column;
                int renameColumnIndex;
                for (int index = 0; index < SourceTableVar.Columns.Count; index++)
                {
                    columnAdded = false;
                    foreach (RenameColumnExpression renameColumn in _expressions)
                    {
                        renameColumnIndex = SourceTableVar.Columns.IndexOf(renameColumn.ColumnName);
                        if (renameColumnIndex < 0)
                        {
                            throw new Schema.SchemaException(Schema.SchemaException.Codes.ObjectNotFound, renameColumn.ColumnName);
                        }
                        else if (renameColumnIndex == index)
                        {
                            if (columnAdded)
                            {
                                throw new CompilerException(CompilerException.Codes.DuplicateRenameColumn, renameColumn.ColumnName);
                            }

                            column = SourceTableVar.Columns[index].InheritAndRename(renameColumn.ColumnAlias);
                            column.MergeMetaData(renameColumn.MetaData);
                            DataType.Columns.Add(column.Column);
                            TableVar.Columns.Add(column);
                            columnAdded = true;
                        }
                    }
                    if (!columnAdded)
                    {
                        column = SourceTableVar.Columns[index].Inherit();
                        DataType.Columns.Add(column.Column);
                        TableVar.Columns.Add(column);
                    }
                }
            }

            DetermineRemotable(plan);

            // Inherit keys
            Schema.Key newKey;
            foreach (Schema.Key key in SourceTableVar.Keys)
            {
                newKey = new Schema.Key();
                newKey.InheritMetaData(key.MetaData);
                newKey.IsInherited = true;
                newKey.IsSparse    = key.IsSparse;
                foreach (Schema.TableVarColumn keyColumn in key.Columns)
                {
                    newKey.Columns.Add(TableVar.Columns[SourceTableVar.Columns.IndexOfName(keyColumn.Name)]);
                }
                TableVar.Keys.Add(newKey);
            }

            // Inherit orders
            Schema.Order       newOrder;
            Schema.OrderColumn orderColumn;
            Schema.OrderColumn newOrderColumn;
            foreach (Schema.Order order in SourceTableVar.Orders)
            {
                newOrder = new Schema.Order();
                newOrder.InheritMetaData(order.MetaData);
                newOrder.IsInherited = true;
                for (int index = 0; index < order.Columns.Count; index++)
                {
                    orderColumn    = order.Columns[index];
                    newOrderColumn =
                        new Schema.OrderColumn
                        (
                            TableVar.Columns[SourceTableVar.Columns.IndexOfName(orderColumn.Column.Name)],
                            orderColumn.Ascending,
                            orderColumn.IncludeNils
                        );
                    newOrderColumn.Sort          = orderColumn.Sort;
                    newOrderColumn.IsDefaultSort = orderColumn.IsDefaultSort;
                    Error.AssertWarn(newOrderColumn.Sort != null, "Sort is null");
                    if (newOrderColumn.IsDefaultSort)
                    {
                        plan.AttachDependency(newOrderColumn.Sort);
                    }
                    else
                    {
                        if (newOrderColumn.Sort.HasDependencies())
                        {
                            plan.AttachDependencies(newOrderColumn.Sort.Dependencies);
                        }
                    }
                    newOrder.Columns.Add(newOrderColumn);
                }
                TableVar.Orders.Add(newOrder);
            }

            DetermineOrder(plan);

                        #if UseReferenceDerivation
            // Copy references
                        #if UseElaborable
            if (plan.CursorContext.CursorCapabilities.HasFlag(CursorCapability.Elaborable))
                        #endif
            {
                if (SourceTableVar.HasReferences())
                {
                    foreach (Schema.ReferenceBase reference in SourceTableVar.References)
                    {
                        if (reference.SourceTable.Equals(SourceTableVar))
                        {
                            Schema.JoinKey sourceKey = new Schema.JoinKey();
                            foreach (Schema.TableVarColumn column in reference.SourceKey.Columns)
                            {
                                sourceKey.Columns.Add(TableVar.Columns[SourceTableVar.Columns.IndexOfName(column.Name)]);
                            }

                            int    newReferenceID   = Schema.Object.GetNextObjectID();
                            string newReferenceName = DeriveSourceReferenceName(reference, newReferenceID, sourceKey);

                            Schema.DerivedReference newReference = new Schema.DerivedReference(newReferenceID, newReferenceName, reference);
                            newReference.IsExcluded = reference.IsExcluded;
                            newReference.InheritMetaData(reference.MetaData);
                            newReference.SourceTable = _tableVar;
                            newReference.AddDependency(_tableVar);
                            newReference.TargetTable = reference.TargetTable;
                            newReference.AddDependency(reference.TargetTable);
                            newReference.SourceKey.IsUnique = reference.SourceKey.IsUnique;
                            foreach (Schema.TableVarColumn column in sourceKey.Columns)
                            {
                                newReference.SourceKey.Columns.Add(column);
                            }
                            newReference.TargetKey.IsUnique = reference.TargetKey.IsUnique;
                            foreach (Schema.TableVarColumn column in reference.TargetKey.Columns)
                            {
                                newReference.TargetKey.Columns.Add(column);
                            }
                            //newReference.UpdateReferenceAction = reference.UpdateReferenceAction;
                            //newReference.DeleteReferenceAction = reference.DeleteReferenceAction;
                            _tableVar.References.Add(newReference);
                        }
                        else if (reference.TargetTable.Equals(SourceTableVar))
                        {
                            Schema.JoinKey targetKey = new Schema.JoinKey();
                            foreach (Schema.TableVarColumn column in reference.TargetKey.Columns)
                            {
                                targetKey.Columns.Add(TableVar.Columns[SourceTableVar.Columns.IndexOfName(column.Name)]);
                            }

                            int    newReferenceID   = Schema.Object.GetNextObjectID();
                            string newReferenceName = DeriveTargetReferenceName(reference, newReferenceID, targetKey);

                            Schema.DerivedReference newReference = new Schema.DerivedReference(newReferenceID, newReferenceName, reference);
                            newReference.IsExcluded = reference.IsExcluded;
                            newReference.InheritMetaData(reference.MetaData);
                            newReference.SourceTable = reference.SourceTable;
                            newReference.AddDependency(reference.SourceTable);
                            newReference.TargetTable = _tableVar;
                            newReference.AddDependency(_tableVar);
                            newReference.SourceKey.IsUnique = reference.SourceKey.IsUnique;
                            foreach (Schema.TableVarColumn column in reference.SourceKey.Columns)
                            {
                                newReference.SourceKey.Columns.Add(column);
                            }
                            newReference.TargetKey.IsUnique = reference.TargetKey.IsUnique;
                            foreach (Schema.TableVarColumn column in targetKey.Columns)
                            {
                                newReference.TargetKey.Columns.Add(column);
                            }
                            //newReference.UpdateReferenceAction = reference.UpdateReferenceAction;
                            //newReference.DeleteReferenceAction = reference.DeleteReferenceAction;
                            _tableVar.References.Add(newReference);
                        }
                    }
                }
            }
                        #endif
        }
예제 #13
0
        public override void DetermineDataType(Plan plan)
        {
            DetermineModifiers(plan);
            if (Nodes[0].DataType.Is(Nodes[1].DataType))
            {
                Nodes[0] = Compiler.Upcast(plan, Nodes[0], Nodes[1].DataType);
            }
            else if (Nodes[1].DataType.Is(Nodes[0].DataType))
            {
                Nodes[1] = Compiler.Upcast(plan, Nodes[1], Nodes[0].DataType);
            }
            else
            {
                ConversionContext context = Compiler.FindConversionPath(plan, Nodes[0].DataType, Nodes[1].DataType);
                if (context.CanConvert)
                {
                    Nodes[0] = Compiler.Upcast(plan, Compiler.ConvertNode(plan, Nodes[0], context), Nodes[1].DataType);
                }
                else
                {
                    context = Compiler.FindConversionPath(plan, Nodes[1].DataType, Nodes[0].DataType);
                    Compiler.CheckConversionContext(plan, context);
                    Nodes[1] = Compiler.Upcast(plan, Compiler.ConvertNode(plan, Nodes[1], context), Nodes[0].DataType);
                }
            }

            _dataType       = new Schema.TableType();
            _tableVar       = new Schema.ResultTableVar(this);
            _tableVar.Owner = plan.User;
            _tableVar.InheritMetaData(LeftTableVar.MetaData);
            _tableVar.JoinInheritMetaData(RightTableVar.MetaData);

            // Determine columns
            CopyTableVarColumns(LeftTableVar.Columns);

            Schema.TableVarColumn leftColumn;
            foreach (Schema.TableVarColumn rightColumn in RightTableVar.Columns)
            {
                leftColumn = TableVar.Columns[TableVar.Columns.IndexOfName(rightColumn.Name)];
                leftColumn.IsDefaultRemotable  = leftColumn.IsDefaultRemotable && rightColumn.IsDefaultRemotable;
                leftColumn.IsChangeRemotable   = leftColumn.IsChangeRemotable && rightColumn.IsChangeRemotable;
                leftColumn.IsValidateRemotable = leftColumn.IsValidateRemotable && rightColumn.IsValidateRemotable;
                leftColumn.JoinInheritMetaData(rightColumn.MetaData);
            }

            DetermineRemotable(plan);

            // Determine key
            Schema.Key key = new Schema.Key();
            key.IsInherited = true;
            foreach (Schema.TableVarColumn column in TableVar.Columns)
            {
                key.Columns.Add(column);
            }
            TableVar.Keys.Add(key);

            DetermineOrder(plan);

            // Determine orders
            CopyOrders(LeftTableVar.Orders);
            foreach (Schema.Order order in RightTableVar.Orders)
            {
                if (!TableVar.Orders.Contains(order))
                {
                    TableVar.Orders.Add(CopyOrder(order));
                }
            }

                        #if UseReferenceDerivation
            // NOTE: This isn't exactly the same, as the previous logic would copy source references from both tables, then target references from both tables. Shouldn't be an issue but....
                        #if UseElaborable
            if (plan.CursorContext.CursorCapabilities.HasFlag(CursorCapability.Elaborable))
                        #endif
            {
                CopyReferences(plan, LeftTableVar);
                CopyReferences(plan, RightTableVar);
            }
                        #endif
        }