Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / ndp / fx / src / DataEntity / System / Data / Query / PlanCompiler / VarRemapper.cs / 2 / VarRemapper.cs
//---------------------------------------------------------------------- //// Copyright (c) Microsoft Corporation. All rights reserved. // // // @owner [....], [....] //--------------------------------------------------------------------- using System; using System.Collections.Generic; //using System.Diagnostics; // Please use PlanCompiler.Assert instead of Debug.Assert in this class... using System.Data.Query.InternalTrees; namespace System.Data.Query.PlanCompiler { ////// The VarRemapper is a utility class that can be used to "remap" Var references /// in a node, or a subtree. /// internal class VarRemapper : BasicOpVisitor { #region Private state protected Dictionary m_varMap; private HashSet m_hiddenMappingKeys; protected Command m_command; #endregion #region Constructors ////// Internal constructor /// /// Current iqt command internal VarRemapper(Command command) :this(command, new Dictionary()) { } ////// Internal constructor /// /// Current iqt command /// Var map to be used internal VarRemapper(Command command, Dictionary varMap) { m_command = command; m_varMap = varMap; } #endregion #region Public surface ////// Add a mapping for "oldVar" - when the replace methods are invoked, they /// will replace all references to "oldVar" by "newVar" /// /// var to replace /// the replacement var internal void AddMapping(Var oldVar, Var newVar) { m_varMap[oldVar] = newVar; } ////// Update vars in just this node (and not the entire subtree) /// Does *not* recompute the nodeinfo - there are at least some consumers of this /// function that do not want the recomputation - transformation rules, for example /// /// current node internal virtual void RemapNode(Node node) { if (m_varMap.Count == 0) { return; } VisitNode(node); } ////// Update vars in this subtree. Recompute the nodeinfo along the way /// /// subtree to "remap" internal virtual void RemapSubtree(Node subTree) { RemapSubtree(subTree, RemapNode); } ////// Produce a a new remapped varList /// /// ///remapped varList internal VarList RemapVarList(VarList varList) { return Command.CreateVarList(MapVars(varList)); } ////// Remap the given varList using the given varMap /// /// /// /// internal static VarList RemapVarList(Command command, Dictionary varMap, VarList varList) { VarRemapper varRemapper = new VarRemapper(command, varMap); return varRemapper.RemapVarList(varList); } #endregion #region Protected methods protected delegate void VisitNodeDelegate(Node n); ////// Update vars in this subtree. Recompute the nodeinfo along the way /// The given remapNodeDelegate is invoked to remap the root /// /// /// protected void RemapSubtree(Node subTree, VisitNodeDelegate remapNodeDelegate) { if (m_varMap.Count == 0) { return; } foreach (Node chi in subTree.Children) { RemapSubtree(chi); } remapNodeDelegate(subTree); m_command.RecomputeNodeInfo(subTree); } ////// Hide the mapping for the given var. /// This means that any mapping for the given var will be ignored during remapping /// of nodes and subtrees untill UnhideMappingKey is called for that var. /// /// protected void HideMappingKey(Var var) { if (m_hiddenMappingKeys == null) { m_hiddenMappingKeys = new HashSet(); } bool added = m_hiddenMappingKeys.Add(var); PlanCompiler.Assert(added, "The VarRemapper is in an inconsistent state. HideMappingKey called over a map that has already been hidden."); } ////// Unhide the mapping for the given var. /// It is only valid to call this method for a given var if the mapping for that var /// has previously been hidden via HideMappingKey /// /// protected void UnhideMappingKey(Var var) { bool removed = m_hiddenMappingKeys.Remove(var); PlanCompiler.Assert(removed, "The VarRemapper is in an inconsistent state. UnhideMappingKey called over a map that is not hidden."); } #endregion #region Private methods ////// Get the mapping for a Var - returns the var itself, if no unhidden mapping was /// found /// /// ///private Var Map(Var v) { Var newVar; while (true) { if (IsHiddenMappingKey(v) || !m_varMap.TryGetValue(v, out newVar)) { return v; } v = newVar; } } /// /// Is the given var on the list of hidden mapping keys /// /// ///private bool IsHiddenMappingKey(Var v) { return (m_hiddenMappingKeys != null) && m_hiddenMappingKeys.Contains(v); } private IEnumerable MapVars(IEnumerable vars) { foreach (Var v in vars) { yield return Map(v); } } private void Map(VarVec vec) { VarVec newVec = m_command.CreateVarVec(MapVars(vec)); vec.InitFrom(newVec); } private void Map(VarList varList) { VarList newList = Command.CreateVarList(MapVars(varList)); varList.Clear(); varList.AddRange(newList); } private void Map(VarMap varMap) { VarMap newVarMap = new VarMap(); foreach (KeyValuePair kv in varMap) { Var newVar = Map(kv.Value); newVarMap.Add(kv.Key, newVar); } varMap.Clear(); foreach (KeyValuePair kv in newVarMap) { varMap.Add(kv.Key, kv.Value); } } private void Map(List sortKeys) { VarVec sortVars = m_command.CreateVarVec(); bool hasDuplicates = false; // // Map each var in the sort list. Remapping may introduce duplicates, and // we should get rid of duplicates, since sql doesn't like them // foreach (InternalTrees.SortKey sk in sortKeys) { sk.Var = Map(sk.Var); if (sortVars.IsSet(sk.Var)) { hasDuplicates = true; } sortVars.Set(sk.Var); } // // Get rid of any duplicates // if (hasDuplicates) { List newSortKeys = new List (sortKeys); sortKeys.Clear(); sortVars.Clear(); foreach (InternalTrees.SortKey sk in newSortKeys) { if (!sortVars.IsSet(sk.Var)) { sortKeys.Add(sk); } sortVars.Set(sk.Var); } } } #region VisitorMethods /// /// Default visitor for a node - does not visit the children /// The reason we have this method is because the default VisitDefault /// actually visits the children, and we don't want to do that /// /// protected override void VisitDefault(Node n) { // Do nothing. } #region ScalarOps public override void Visit(VarRefOp op, Node n) { VisitScalarOpDefault(op, n); Var newVar = Map(op.Var); if (newVar != op.Var) { n.Op = m_command.CreateVarRefOp(newVar); } } #endregion #region AncillaryOps #endregion #region PhysicalOps protected override void VisitNestOp(NestBaseOp op, Node n) { throw EntityUtil.NotSupported(); } public override void Visit(PhysicalProjectOp op, Node n) { VisitPhysicalOpDefault(op, n); Map(op.Outputs); SimpleCollectionColumnMap newColumnMap = (SimpleCollectionColumnMap)ColumnMapTranslator.Translate(op.ColumnMap, m_varMap); n.Op = m_command.CreatePhysicalProjectOp(op.Outputs, newColumnMap); } #endregion #region RelOps public override void Visit(GroupByOp op, Node n) { VisitRelOpDefault(op, n); Map(op.Outputs); Map(op.Keys); } public override void Visit(DistinctOp op, Node n) { VisitRelOpDefault(op, n); Map(op.Keys); } public override void Visit(ProjectOp op, Node n) { VisitRelOpDefault(op, n); Map(op.Outputs); } public override void Visit(UnnestOp op, Node n) { VisitRelOpDefault(op, n); Var newVar = Map(op.Var); if (newVar != op.Var) { n.Op = m_command.CreateUnnestOp(newVar, op.Table); } } protected override void VisitSetOp(SetOp op, Node n) { VisitRelOpDefault(op, n); Map(op.VarMap[0]); Map(op.VarMap[1]); } protected override void VisitSortOp(SortBaseOp op, Node n) { VisitRelOpDefault(op, n); Map(op.Keys); } #endregion #endregion #endregion } ////// A var remapper that allows for proving mappings that apply to entire tree except for subtree /// rooted at a given node /// internal class ScopedVarRemapper : VarRemapper { #region Private state private Dictionarym_hidingScopeNodesMap; #endregion #region Constructor /// /// Internal constructor /// /// Current iqt command internal ScopedVarRemapper(Command command) : base(command) { } #endregion #region 'Public' surface ////// Add a scoped mapping from oldVar to newVar /// This mapping applies to the entire tree except for the subtree rooted at the given hidingScopeNode /// /// /// /// internal void AddMapping(Var oldVar, Var newVar, Node hidingScopeNode) { if (m_hidingScopeNodesMap == null) { m_hidingScopeNodesMap = new Dictionary(); } PlanCompiler.Assert(!m_hidingScopeNodesMap.ContainsKey(hidingScopeNode), "The ScopedVarRemapper is in an inconsistent state. The given node has already been used as a hiding scope."); m_hidingScopeNodesMap[hidingScopeNode] = oldVar; AddMapping(oldVar, newVar); } /// /// Overriding this method to make sure we don't visit the node that should be ignored. /// /// internal override void RemapNode(Node n) { VisitHonoringHiding(n, base.RemapNode); } ////// Overriding this method to make sure we don't visit the node that should be ignored. /// /// subtree to "remap" internal override void RemapSubtree(Node subTree) { VisitHonoringHiding(subTree, RemapSubtreeUsingBaseRemapNode); } #endregion #region Private methods ////// Helper method for visiting. If needed, hides a mapping before and unhides it after /// calling the visitMethod /// /// /// private void VisitHonoringHiding(Node n, VisitNodeDelegate visitMethod) { //Hide a mapping if neeeded Var var; if (TryGetHiddenMappingKey(n, out var)) { HideMappingKey(var); } visitMethod(n); //Unhide a mapping if it was hidden if (var != null) { UnhideMappingKey(var); } } ////// Get a hidden maping key for the given node if any /// /// /// ///private bool TryGetHiddenMappingKey(Node node, out Var var) { if (m_hidingScopeNodesMap == null) { var = null; return false; } return m_hidingScopeNodesMap.TryGetValue(node, out var); } /// /// Helper method for RemapSubtree. Needed to avoid possibly /// hiding a mapping key twice. If we instead invoke the base RemapSubtree /// it would call the overritten RemapNode, which would do the hiding again. /// /// private void RemapSubtreeUsingBaseRemapNode(Node subTree) { base.RemapSubtree(subTree, base.RemapNode); } #endregion } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //---------------------------------------------------------------------- //// Copyright (c) Microsoft Corporation. All rights reserved. // // // @owner [....], [....] //--------------------------------------------------------------------- using System; using System.Collections.Generic; //using System.Diagnostics; // Please use PlanCompiler.Assert instead of Debug.Assert in this class... using System.Data.Query.InternalTrees; namespace System.Data.Query.PlanCompiler { ////// The VarRemapper is a utility class that can be used to "remap" Var references /// in a node, or a subtree. /// internal class VarRemapper : BasicOpVisitor { #region Private state protected Dictionary m_varMap; private HashSet m_hiddenMappingKeys; protected Command m_command; #endregion #region Constructors ////// Internal constructor /// /// Current iqt command internal VarRemapper(Command command) :this(command, new Dictionary()) { } ////// Internal constructor /// /// Current iqt command /// Var map to be used internal VarRemapper(Command command, Dictionary varMap) { m_command = command; m_varMap = varMap; } #endregion #region Public surface ////// Add a mapping for "oldVar" - when the replace methods are invoked, they /// will replace all references to "oldVar" by "newVar" /// /// var to replace /// the replacement var internal void AddMapping(Var oldVar, Var newVar) { m_varMap[oldVar] = newVar; } ////// Update vars in just this node (and not the entire subtree) /// Does *not* recompute the nodeinfo - there are at least some consumers of this /// function that do not want the recomputation - transformation rules, for example /// /// current node internal virtual void RemapNode(Node node) { if (m_varMap.Count == 0) { return; } VisitNode(node); } ////// Update vars in this subtree. Recompute the nodeinfo along the way /// /// subtree to "remap" internal virtual void RemapSubtree(Node subTree) { RemapSubtree(subTree, RemapNode); } ////// Produce a a new remapped varList /// /// ///remapped varList internal VarList RemapVarList(VarList varList) { return Command.CreateVarList(MapVars(varList)); } ////// Remap the given varList using the given varMap /// /// /// /// internal static VarList RemapVarList(Command command, Dictionary varMap, VarList varList) { VarRemapper varRemapper = new VarRemapper(command, varMap); return varRemapper.RemapVarList(varList); } #endregion #region Protected methods protected delegate void VisitNodeDelegate(Node n); ////// Update vars in this subtree. Recompute the nodeinfo along the way /// The given remapNodeDelegate is invoked to remap the root /// /// /// protected void RemapSubtree(Node subTree, VisitNodeDelegate remapNodeDelegate) { if (m_varMap.Count == 0) { return; } foreach (Node chi in subTree.Children) { RemapSubtree(chi); } remapNodeDelegate(subTree); m_command.RecomputeNodeInfo(subTree); } ////// Hide the mapping for the given var. /// This means that any mapping for the given var will be ignored during remapping /// of nodes and subtrees untill UnhideMappingKey is called for that var. /// /// protected void HideMappingKey(Var var) { if (m_hiddenMappingKeys == null) { m_hiddenMappingKeys = new HashSet(); } bool added = m_hiddenMappingKeys.Add(var); PlanCompiler.Assert(added, "The VarRemapper is in an inconsistent state. HideMappingKey called over a map that has already been hidden."); } ////// Unhide the mapping for the given var. /// It is only valid to call this method for a given var if the mapping for that var /// has previously been hidden via HideMappingKey /// /// protected void UnhideMappingKey(Var var) { bool removed = m_hiddenMappingKeys.Remove(var); PlanCompiler.Assert(removed, "The VarRemapper is in an inconsistent state. UnhideMappingKey called over a map that is not hidden."); } #endregion #region Private methods ////// Get the mapping for a Var - returns the var itself, if no unhidden mapping was /// found /// /// ///private Var Map(Var v) { Var newVar; while (true) { if (IsHiddenMappingKey(v) || !m_varMap.TryGetValue(v, out newVar)) { return v; } v = newVar; } } /// /// Is the given var on the list of hidden mapping keys /// /// ///private bool IsHiddenMappingKey(Var v) { return (m_hiddenMappingKeys != null) && m_hiddenMappingKeys.Contains(v); } private IEnumerable MapVars(IEnumerable vars) { foreach (Var v in vars) { yield return Map(v); } } private void Map(VarVec vec) { VarVec newVec = m_command.CreateVarVec(MapVars(vec)); vec.InitFrom(newVec); } private void Map(VarList varList) { VarList newList = Command.CreateVarList(MapVars(varList)); varList.Clear(); varList.AddRange(newList); } private void Map(VarMap varMap) { VarMap newVarMap = new VarMap(); foreach (KeyValuePair kv in varMap) { Var newVar = Map(kv.Value); newVarMap.Add(kv.Key, newVar); } varMap.Clear(); foreach (KeyValuePair kv in newVarMap) { varMap.Add(kv.Key, kv.Value); } } private void Map(List sortKeys) { VarVec sortVars = m_command.CreateVarVec(); bool hasDuplicates = false; // // Map each var in the sort list. Remapping may introduce duplicates, and // we should get rid of duplicates, since sql doesn't like them // foreach (InternalTrees.SortKey sk in sortKeys) { sk.Var = Map(sk.Var); if (sortVars.IsSet(sk.Var)) { hasDuplicates = true; } sortVars.Set(sk.Var); } // // Get rid of any duplicates // if (hasDuplicates) { List newSortKeys = new List (sortKeys); sortKeys.Clear(); sortVars.Clear(); foreach (InternalTrees.SortKey sk in newSortKeys) { if (!sortVars.IsSet(sk.Var)) { sortKeys.Add(sk); } sortVars.Set(sk.Var); } } } #region VisitorMethods /// /// Default visitor for a node - does not visit the children /// The reason we have this method is because the default VisitDefault /// actually visits the children, and we don't want to do that /// /// protected override void VisitDefault(Node n) { // Do nothing. } #region ScalarOps public override void Visit(VarRefOp op, Node n) { VisitScalarOpDefault(op, n); Var newVar = Map(op.Var); if (newVar != op.Var) { n.Op = m_command.CreateVarRefOp(newVar); } } #endregion #region AncillaryOps #endregion #region PhysicalOps protected override void VisitNestOp(NestBaseOp op, Node n) { throw EntityUtil.NotSupported(); } public override void Visit(PhysicalProjectOp op, Node n) { VisitPhysicalOpDefault(op, n); Map(op.Outputs); SimpleCollectionColumnMap newColumnMap = (SimpleCollectionColumnMap)ColumnMapTranslator.Translate(op.ColumnMap, m_varMap); n.Op = m_command.CreatePhysicalProjectOp(op.Outputs, newColumnMap); } #endregion #region RelOps public override void Visit(GroupByOp op, Node n) { VisitRelOpDefault(op, n); Map(op.Outputs); Map(op.Keys); } public override void Visit(DistinctOp op, Node n) { VisitRelOpDefault(op, n); Map(op.Keys); } public override void Visit(ProjectOp op, Node n) { VisitRelOpDefault(op, n); Map(op.Outputs); } public override void Visit(UnnestOp op, Node n) { VisitRelOpDefault(op, n); Var newVar = Map(op.Var); if (newVar != op.Var) { n.Op = m_command.CreateUnnestOp(newVar, op.Table); } } protected override void VisitSetOp(SetOp op, Node n) { VisitRelOpDefault(op, n); Map(op.VarMap[0]); Map(op.VarMap[1]); } protected override void VisitSortOp(SortBaseOp op, Node n) { VisitRelOpDefault(op, n); Map(op.Keys); } #endregion #endregion #endregion } ////// A var remapper that allows for proving mappings that apply to entire tree except for subtree /// rooted at a given node /// internal class ScopedVarRemapper : VarRemapper { #region Private state private Dictionarym_hidingScopeNodesMap; #endregion #region Constructor /// /// Internal constructor /// /// Current iqt command internal ScopedVarRemapper(Command command) : base(command) { } #endregion #region 'Public' surface ////// Add a scoped mapping from oldVar to newVar /// This mapping applies to the entire tree except for the subtree rooted at the given hidingScopeNode /// /// /// /// internal void AddMapping(Var oldVar, Var newVar, Node hidingScopeNode) { if (m_hidingScopeNodesMap == null) { m_hidingScopeNodesMap = new Dictionary(); } PlanCompiler.Assert(!m_hidingScopeNodesMap.ContainsKey(hidingScopeNode), "The ScopedVarRemapper is in an inconsistent state. The given node has already been used as a hiding scope."); m_hidingScopeNodesMap[hidingScopeNode] = oldVar; AddMapping(oldVar, newVar); } /// /// Overriding this method to make sure we don't visit the node that should be ignored. /// /// internal override void RemapNode(Node n) { VisitHonoringHiding(n, base.RemapNode); } ////// Overriding this method to make sure we don't visit the node that should be ignored. /// /// subtree to "remap" internal override void RemapSubtree(Node subTree) { VisitHonoringHiding(subTree, RemapSubtreeUsingBaseRemapNode); } #endregion #region Private methods ////// Helper method for visiting. If needed, hides a mapping before and unhides it after /// calling the visitMethod /// /// /// private void VisitHonoringHiding(Node n, VisitNodeDelegate visitMethod) { //Hide a mapping if neeeded Var var; if (TryGetHiddenMappingKey(n, out var)) { HideMappingKey(var); } visitMethod(n); //Unhide a mapping if it was hidden if (var != null) { UnhideMappingKey(var); } } ////// Get a hidden maping key for the given node if any /// /// /// ///private bool TryGetHiddenMappingKey(Node node, out Var var) { if (m_hidingScopeNodesMap == null) { var = null; return false; } return m_hidingScopeNodesMap.TryGetValue(node, out var); } /// /// Helper method for RemapSubtree. Needed to avoid possibly /// hiding a mapping key twice. If we instead invoke the base RemapSubtree /// it would call the overritten RemapNode, which would do the hiding again. /// /// private void RemapSubtreeUsingBaseRemapNode(Node subTree) { base.RemapSubtree(subTree, base.RemapNode); } #endregion } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- TextCompositionManager.cs
- XmlSignificantWhitespace.cs
- storepermissionattribute.cs
- ConfigurationSchemaErrors.cs
- _CookieModule.cs
- GroupBoxRenderer.cs
- GenericUI.cs
- FileSystemEventArgs.cs
- SimpleApplicationHost.cs
- InternalRelationshipCollection.cs
- EmptyCollection.cs
- FixedLineResult.cs
- XhtmlMobileTextWriter.cs
- HtmlProps.cs
- BitmapData.cs
- TriggerBase.cs
- WsatAdminException.cs
- ProtectedConfigurationProviderCollection.cs
- CursorConverter.cs
- XmlQueryOutput.cs
- KeyGestureValueSerializer.cs
- RichTextBox.cs
- ConfigurationSettings.cs
- Pkcs7Recipient.cs
- UniqueIdentifierService.cs
- CryptoApi.cs
- WebPartTracker.cs
- assertwrapper.cs
- XPathNodePointer.cs
- Guid.cs
- InputLanguageEventArgs.cs
- FrameworkEventSource.cs
- control.ime.cs
- TaskFormBase.cs
- Vector3DValueSerializer.cs
- WsrmFault.cs
- BordersPage.cs
- StreamSecurityUpgradeAcceptor.cs
- CodeIterationStatement.cs
- WindowsHyperlink.cs
- DataGridTextBox.cs
- TransformedBitmap.cs
- ImageInfo.cs
- ComponentDispatcherThread.cs
- StreamInfo.cs
- UnsafeNativeMethods.cs
- TreeNodeBindingCollection.cs
- XmlElementAttribute.cs
- SoapFault.cs
- ThousandthOfEmRealDoubles.cs
- ToolBarButtonClickEvent.cs
- AuthorizationSection.cs
- SafeHandles.cs
- webeventbuffer.cs
- StandardCommands.cs
- ALinqExpressionVisitor.cs
- SwitchLevelAttribute.cs
- WebBrowserHelper.cs
- ValidationRule.cs
- WebPartManager.cs
- MdiWindowListItemConverter.cs
- ExpandSegmentCollection.cs
- Math.cs
- _SpnDictionary.cs
- WebReferenceCollection.cs
- IndexOutOfRangeException.cs
- FlowDocumentPageViewerAutomationPeer.cs
- WebPartRestoreVerb.cs
- SchemaMapping.cs
- ShaderRenderModeValidation.cs
- DataTableMappingCollection.cs
- ProfileWorkflowElement.cs
- RubberbandSelector.cs
- HttpApplication.cs
- AnnotationService.cs
- BufferedStream.cs
- TransactionScopeDesigner.cs
- SHA1Cng.cs
- WebResponse.cs
- ProgressBarHighlightConverter.cs
- SpecialNameAttribute.cs
- OdbcFactory.cs
- EventPropertyMap.cs
- SyndicationSerializer.cs
- XmlUtil.cs
- AnnotationDocumentPaginator.cs
- Help.cs
- NonSerializedAttribute.cs
- CmsInterop.cs
- ForceCopyBuildProvider.cs
- XmlCharCheckingWriter.cs
- InvalidCastException.cs
- WebPartConnectionsCloseVerb.cs
- AsyncCompletedEventArgs.cs
- UserPreferenceChangedEventArgs.cs
- DirectoryInfo.cs
- BaseTemplateParser.cs
- ProtocolsConfigurationHandler.cs
- Delay.cs
- DateTimeConstantAttribute.cs