コード例 #1
0
        // A scan order can be any order which includes all the columns in closed conditions, in any order,
        // followed by all the columns in open conditions, in any order,
        // if there is a scan condition, it must be the last order column, open or closed
        protected Schema.Order FindScanOrder(Plan plan)
        {
            Schema.Order newOrder;

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

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

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

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

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

            return(newOrder);
        }
コード例 #2
0
        public virtual void DetermineOrder(Plan plan)
        {
            // Set up the order columns
            Order             = new Schema.Order(_requestedOrder.MetaData);
            Order.IsInherited = false;

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

            Compiler.EnsureOrderUnique(plan, TableVar, Order);
        }
コード例 #3
0
 private void EnsureEqualitySorts(Plan plan)
 {
     _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);
     }
 }
コード例 #4
0
ファイル: RenameNode.cs プロジェクト: laszlo-kiss/Dataphor
 private void DetermineOrder(Plan plan)
 {
     Order = null;
     if (SourceNode.Order != null)
     {
         Schema.Order       newOrder = new Schema.Order();
         Schema.OrderColumn orderColumn;
         Schema.OrderColumn newOrderColumn;
         newOrder.InheritMetaData(SourceNode.Order.MetaData);
         newOrder.IsInherited = true;
         for (int index = 0; index < SourceNode.Order.Columns.Count; index++)
         {
             orderColumn    = SourceNode.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);
         }
         Order = newOrder;
     }
 }
コード例 #5
0
ファイル: RedefineNode.cs プロジェクト: laszlo-kiss/Dataphor
        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
        }
コード例 #6
0
ファイル: ExtendNode.cs プロジェクト: laszlo-kiss/Dataphor
        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
        }
コード例 #7
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
        }
コード例 #8
0
ファイル: RenameNode.cs プロジェクト: laszlo-kiss/Dataphor
        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
        }
コード例 #9
0
ファイル: AdornNode.cs プロジェクト: laszlo-kiss/Dataphor
        public override void DetermineDataType(Plan plan)
        {
            DetermineModifiers(plan);
            _dataType       = new Schema.TableType();
            _tableVar       = new Schema.ResultTableVar(this);
            _tableVar.Owner = plan.User;
            _tableVar.InheritMetaData(SourceTableVar.MetaData);
            _tableVar.MergeMetaData(MetaData);
            AlterNode.AlterMetaData(_tableVar, AlterMetaData, true);
            CopyTableVarColumns(SourceTableVar.Columns);
            int sourceColumnIndex;

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

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

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

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

                            newColumn.Constraints.Add(newConstraint);

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

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

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

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

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

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

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

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

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

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

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

            // Orders
            CopyOrders(SourceTableVar.Orders);

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

                TableVar.Orders.SafeRemove(oldOrder);
            }

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

            Compiler.CompileTableVarOrders(plan, _tableVar, _orders);

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

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

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

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

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

            DetermineRemotable(plan);

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

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

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

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

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

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

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

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

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

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

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

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

                TableVar.References.Add(reference);
            }

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

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

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

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

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

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

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

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

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

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