public override void DetermineDataType(Plan plan) { DetermineModifiers(plan); _dataType = new Schema.TableType(); _tableVar = new Schema.ResultTableVar(this); _tableVar.Owner = plan.User; DataType.Columns.Add(new Schema.Column("Library_Name", plan.DataTypes.SystemString)); DataType.Columns.Add(new Schema.Column("Name", plan.DataTypes.SystemString)); DataType.Columns.Add(new Schema.Column("TimeStamp", plan.DataTypes.SystemDateTime)); DataType.Columns.Add(new Schema.Column("IsDotNetAssembly", plan.DataTypes.SystemBoolean)); DataType.Columns.Add(new Schema.Column("ShouldRegister", plan.DataTypes.SystemBoolean)); foreach (Schema.Column column in DataType.Columns) { TableVar.Columns.Add(new Schema.TableVarColumn(column)); } TableVar.Keys.Add(new Schema.Key(new Schema.TableVarColumn[] { TableVar.Columns["Name"] })); TableVar.DetermineRemotable(plan.CatalogDeviceSession); Order = Compiler.FindClusteringOrder(plan, TableVar); // Ensure the order exists in the orders list if (!TableVar.Orders.Contains(Order)) { TableVar.Orders.Add(Order); } }
public override void DetermineRemotable(Plan plan) { Schema.ResultTableVar tableVar = (Schema.ResultTableVar)TableVar; tableVar.InferredIsDefaultRemotable = !PropagateDefault || SourceTableVar.IsDefaultRemotable; tableVar.InferredIsChangeRemotable = !PropagateChange || SourceTableVar.IsChangeRemotable; tableVar.InferredIsValidateRemotable = !PropagateValidate || SourceTableVar.IsValidateRemotable; tableVar.DetermineRemotable(plan.CatalogDeviceSession); tableVar.ShouldChange = PropagateChange && (tableVar.ShouldChange || SourceTableVar.ShouldChange); tableVar.ShouldDefault = PropagateDefault && (tableVar.ShouldDefault || SourceTableVar.ShouldDefault); tableVar.ShouldValidate = PropagateValidate && (tableVar.ShouldValidate || SourceTableVar.ShouldValidate); for (int index = 0; index < tableVar.Columns.Count; index++) { Schema.TableVarColumn column = tableVar.Columns[index]; Schema.TableVarColumn sourceColumn = SourceTableVar.Columns[index]; column.ShouldChange = PropagateChange && (column.ShouldChange || sourceColumn.ShouldChange); tableVar.ShouldChange = tableVar.ShouldChange || column.ShouldChange; column.ShouldDefault = PropagateDefault && (column.ShouldDefault || sourceColumn.ShouldDefault); tableVar.ShouldDefault = tableVar.ShouldDefault || column.ShouldDefault; column.ShouldValidate = PropagateValidate && (column.ShouldValidate || sourceColumn.ShouldValidate); tableVar.ShouldValidate = tableVar.ShouldValidate || column.ShouldValidate; } }
public override void DetermineDataType(Plan plan) { DetermineModifiers(plan); _dataType = new Schema.TableType(); _tableVar = new Schema.ResultTableVar(this); _tableVar.Owner = plan.User; DataType.Columns.Add(new Schema.Column("Path", (Schema.ScalarType)Compiler.ResolveCatalogIdentifier(plan, "System.Platform.FileName", true))); foreach (Schema.Column column in DataType.Columns) { TableVar.Columns.Add(new Schema.TableVarColumn(column)); } TableVar.Keys.Add(new Schema.Key(new Schema.TableVarColumn[] { TableVar.Columns["Path"] })); TableVar.DetermineRemotable(plan.CatalogDeviceSession); Order = Compiler.FindClusteringOrder(plan, TableVar); // Ensure the order exists in the orders list if (!TableVar.Orders.Contains(Order)) { TableVar.Orders.Add(Order); } }
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); CopyTableVarColumns(LeftTableVar.Columns); DetermineRemotable(plan); CopyKeys(LeftTableVar.Keys); CopyOrders(LeftTableVar.Orders); if (LeftNode.Order != null) { Order = CopyOrder(LeftNode.Order); } #if UseReferenceDerivation #if UseElaborable if (plan.CursorContext.CursorCapabilities.HasFlag(CursorCapability.Elaborable)) #endif CopyReferences(plan, LeftTableVar); #endif #if UseScannedDifference // Scanned Difference Algorithm - Brute Force, for every row in the left, scan the right for a matching row FDifferenceAlgorithm = typeof(ScannedDifferenceTable); Schema.IRowType leftRowType = DataType.CreateRowType(Keywords.Left); APlan.Symbols.Push(new Symbol(leftRowType)); try { // Compile a row equality node Schema.IRowType rightRowType = DataType.CreateRowType(Keywords.Right); APlan.Symbols.Push(new Symbol(rightRowType)); try { FEqualNode = Compiler.CompileExpression(APlan, Compiler.BuildKeyEqualExpression(APlan, leftRowType.Columns, rightRowType.Columns)); } finally { APlan.Symbols.Pop(); } } finally { APlan.Symbols.Pop(); } #endif }
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 }
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 }
// 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(); } }
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 }
// 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 }
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 }
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 }