Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataEntity / System / Data / Query / PlanCompiler / VarRemapper.cs / 1305376 / VarRemapper.cs
//----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// @owner [....]
// @backupOwner [....]
//---------------------------------------------------------------------
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
private readonly Dictionary m_varMap;
protected readonly 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)
{
if (m_varMap.Count == 0)
{
return;
}
foreach (Node chi in subTree.Children)
{
RemapSubtree(chi);
}
RemapNode(subTree);
m_command.RecomputeNodeInfo(subTree);
}
///
/// 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 Private methods
///
/// Get the mapping for a Var - returns the var itself, mapping was found
///
///
///
private Var Map(Var v)
{
Var newVar;
while (true)
{
if (!m_varMap.TryGetValue(v, out newVar))
{
return v;
}
v = newVar;
}
}
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
protected override void VisitGroupByOp(GroupByBaseOp op, Node n)
{
VisitRelOpDefault(op, n);
Map(op.Outputs);
Map(op.Keys);
}
public override void Visit(GroupByIntoOp op, Node n)
{
VisitGroupByOp(op, n);
Map(op.Inputs);
}
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
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// @owner [....]
// @backupOwner [....]
//---------------------------------------------------------------------
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
private readonly Dictionary m_varMap;
protected readonly 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)
{
if (m_varMap.Count == 0)
{
return;
}
foreach (Node chi in subTree.Children)
{
RemapSubtree(chi);
}
RemapNode(subTree);
m_command.RecomputeNodeInfo(subTree);
}
///
/// 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 Private methods
///
/// Get the mapping for a Var - returns the var itself, mapping was found
///
///
///
private Var Map(Var v)
{
Var newVar;
while (true)
{
if (!m_varMap.TryGetValue(v, out newVar))
{
return v;
}
v = newVar;
}
}
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
protected override void VisitGroupByOp(GroupByBaseOp op, Node n)
{
VisitRelOpDefault(op, n);
Map(op.Outputs);
Map(op.Keys);
}
public override void Visit(GroupByIntoOp op, Node n)
{
VisitGroupByOp(op, n);
Map(op.Inputs);
}
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
}
}
// 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
- FunctionCommandText.cs
- Vector3DCollectionConverter.cs
- DefaultDialogButtons.cs
- CodeSnippetExpression.cs
- EntityViewGenerationConstants.cs
- ReadOnlyNameValueCollection.cs
- WpfPayload.cs
- CompilerParameters.cs
- StaticExtension.cs
- ResourceLoader.cs
- ClientBuildManagerCallback.cs
- XPathMessageFilterElementCollection.cs
- ProgramNode.cs
- PanelContainerDesigner.cs
- HandlerWithFactory.cs
- PerformanceCounterCategory.cs
- SmtpNegotiateAuthenticationModule.cs
- HttpConfigurationSystem.cs
- TriState.cs
- NavigationProperty.cs
- ConnectionConsumerAttribute.cs
- CompositeCollection.cs
- TextAdaptor.cs
- SHA256.cs
- CodeParameterDeclarationExpression.cs
- ConditionalAttribute.cs
- TransformConverter.cs
- MetadataItemEmitter.cs
- CustomLineCap.cs
- DataGridViewBindingCompleteEventArgs.cs
- ProfilePropertySettings.cs
- TypeDescriptionProvider.cs
- Win32SafeHandles.cs
- MenuRenderer.cs
- XmlHierarchicalDataSourceView.cs
- InputMethodStateChangeEventArgs.cs
- HtmlTableCellCollection.cs
- FixedSOMTextRun.cs
- SqlErrorCollection.cs
- TdsParser.cs
- DependencyPropertyKey.cs
- MemberPath.cs
- RoleManagerSection.cs
- Errors.cs
- QilReference.cs
- SemaphoreFullException.cs
- CheckedListBox.cs
- XmlTextReaderImpl.cs
- Message.cs
- EdmRelationshipRoleAttribute.cs
- IBuiltInEvidence.cs
- SerializerWriterEventHandlers.cs
- _NestedSingleAsyncResult.cs
- LongMinMaxAggregationOperator.cs
- StringResourceManager.cs
- KeyEvent.cs
- ThousandthOfEmRealDoubles.cs
- ImageListUtils.cs
- SessionStateItemCollection.cs
- ConfigurationManagerInternalFactory.cs
- EntityDataSourceReferenceGroup.cs
- InheritanceAttribute.cs
- Baml2006ReaderContext.cs
- HttpValueCollection.cs
- CheckBox.cs
- PeerCollaboration.cs
- CompositeControl.cs
- Size.cs
- FileChangesMonitor.cs
- LayoutInformation.cs
- RenderDataDrawingContext.cs
- RadioButtonRenderer.cs
- PtsContext.cs
- BitmapMetadata.cs
- MarkupProperty.cs
- UrlParameterWriter.cs
- CompilerInfo.cs
- StreamGeometryContext.cs
- DesignColumnCollection.cs
- InfoCardClaim.cs
- CounterCreationDataCollection.cs
- MdImport.cs
- HostedElements.cs
- _DisconnectOverlappedAsyncResult.cs
- SecurityHeaderElementInferenceEngine.cs
- Table.cs
- Rect3DConverter.cs
- iisPickupDirectory.cs
- DisplayClaim.cs
- HttpContext.cs
- ExceptionRoutedEventArgs.cs
- Rotation3DAnimationUsingKeyFrames.cs
- ClassDataContract.cs
- ImmComposition.cs
- sortedlist.cs
- SessionEndingEventArgs.cs
- StreamDocument.cs
- ForwardPositionQuery.cs
- Visual3D.cs
- ProjectedSlot.cs