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; } }
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); }
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); }
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()); }
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); } }
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(); }
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 }
// 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 }
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); } }
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 }