Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataEntity / System / Data / Map / Update / Internal / Propagator.JoinPropagator.JoinPredicateVisitor.cs / 1305376 / Propagator.JoinPropagator.JoinPredicateVisitor.cs
//----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// @owner [....]
// @backupOwner [....]
//---------------------------------------------------------------------
using System.Data.Common.CommandTrees;
using System.Collections.Generic;
using System.Diagnostics;
using System.Collections.ObjectModel;
namespace System.Data.Mapping.Update.Internal
{
internal partial class Propagator
{
private partial class JoinPropagator
{
///
/// Extracts equi-join properties from a join condition.
///
///
/// Assumptions:
///
/// - Only conjunctions of equality predicates are supported
/// - Each equality predicate is of the form (left property == right property). The order
/// is important.
///
///
private class JoinConditionVisitor : UpdateExpressionVisitor
{
#region Constructors
///
/// Initializes a join predicate visitor. The visitor will populate the given property
/// lists with expressions describing the left and right hand side of equi-join
/// sub-clauses.
///
private JoinConditionVisitor()
{
m_leftKeySelectors = new List();
m_rightKeySelectors = new List();
}
#endregion
#region Fields
private readonly List m_leftKeySelectors;
private readonly List m_rightKeySelectors;
private static readonly string s_visitorName = typeof(JoinConditionVisitor).FullName;
#endregion
#region Properties
override protected string VisitorName
{
get { return s_visitorName; }
}
#endregion
#region Methods
#region Static helper methods
///
/// Determine properties from the left and right inputs to an equi-join participating
/// in predicate.
///
///
/// The property definitions returned are 'aligned'. If the join predicate reads:
///
/// a = b AND c = d AND e = f
///
/// then the output is as follows:
///
/// leftProperties = {a, c, e}
/// rightProperties = {b, d, f}
///
/// See Walker class for an explanation of this coding pattern.
///
static internal void GetKeySelectors(DbExpression joinCondition, out ReadOnlyCollection leftKeySelectors, out ReadOnlyCollection rightKeySelectors)
{
EntityUtil.CheckArgumentNull(joinCondition, "joinCondition");
// Constructs a new predicate visitor, which implements a visitor for expression nodes
// and returns no values. This visitor instead builds up a list of properties as leaves
// of the join predicate are visited.
JoinConditionVisitor visitor = new JoinConditionVisitor();
// Walk the predicate using the predicate visitor.
joinCondition.Accept(visitor);
// Retrieve properties discovered visiting predicate leaf nodes.
leftKeySelectors = visitor.m_leftKeySelectors.AsReadOnly();
rightKeySelectors = visitor.m_rightKeySelectors.AsReadOnly();
Debug.Assert(leftKeySelectors.Count == rightKeySelectors.Count,
"(Update/JoinPropagator) The equi-join must have an equal number of left and right properties");
}
#endregion
#region Visitor implementation
///
/// Visit and node after its children have visited. There is nothing to do here
/// because only leaf equality nodes contain properties extracted by this visitor.
///
/// And expression node
/// Results ignored by this visitor implementation.
public override object Visit(DbAndExpression node)
{
EntityUtil.CheckArgumentNull(node, "node");
Visit(node.Left);
Visit(node.Right);
return null;
}
///
/// Perform work for an equality expression node.
///
/// Equality expresion node
/// Results ignored by this visitor implementation.
public override object Visit(DbComparisonExpression node)
{
EntityUtil.CheckArgumentNull(node, "node");
if (DbExpressionKind.Equals == node.ExpressionKind)
{
m_leftKeySelectors.Add(node.Left);
m_rightKeySelectors.Add(node.Right);
return null;
}
else
{
throw ConstructNotSupportedException(node);
}
}
#endregion
#endregion
}
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// @owner [....]
// @backupOwner [....]
//---------------------------------------------------------------------
using System.Data.Common.CommandTrees;
using System.Collections.Generic;
using System.Diagnostics;
using System.Collections.ObjectModel;
namespace System.Data.Mapping.Update.Internal
{
internal partial class Propagator
{
private partial class JoinPropagator
{
///
/// Extracts equi-join properties from a join condition.
///
///
/// Assumptions:
///
/// - Only conjunctions of equality predicates are supported
/// - Each equality predicate is of the form (left property == right property). The order
/// is important.
///
///
private class JoinConditionVisitor : UpdateExpressionVisitor
{
#region Constructors
///
/// Initializes a join predicate visitor. The visitor will populate the given property
/// lists with expressions describing the left and right hand side of equi-join
/// sub-clauses.
///
private JoinConditionVisitor()
{
m_leftKeySelectors = new List();
m_rightKeySelectors = new List();
}
#endregion
#region Fields
private readonly List m_leftKeySelectors;
private readonly List m_rightKeySelectors;
private static readonly string s_visitorName = typeof(JoinConditionVisitor).FullName;
#endregion
#region Properties
override protected string VisitorName
{
get { return s_visitorName; }
}
#endregion
#region Methods
#region Static helper methods
///
/// Determine properties from the left and right inputs to an equi-join participating
/// in predicate.
///
///
/// The property definitions returned are 'aligned'. If the join predicate reads:
///
/// a = b AND c = d AND e = f
///
/// then the output is as follows:
///
/// leftProperties = {a, c, e}
/// rightProperties = {b, d, f}
///
/// See Walker class for an explanation of this coding pattern.
///
static internal void GetKeySelectors(DbExpression joinCondition, out ReadOnlyCollection leftKeySelectors, out ReadOnlyCollection rightKeySelectors)
{
EntityUtil.CheckArgumentNull(joinCondition, "joinCondition");
// Constructs a new predicate visitor, which implements a visitor for expression nodes
// and returns no values. This visitor instead builds up a list of properties as leaves
// of the join predicate are visited.
JoinConditionVisitor visitor = new JoinConditionVisitor();
// Walk the predicate using the predicate visitor.
joinCondition.Accept(visitor);
// Retrieve properties discovered visiting predicate leaf nodes.
leftKeySelectors = visitor.m_leftKeySelectors.AsReadOnly();
rightKeySelectors = visitor.m_rightKeySelectors.AsReadOnly();
Debug.Assert(leftKeySelectors.Count == rightKeySelectors.Count,
"(Update/JoinPropagator) The equi-join must have an equal number of left and right properties");
}
#endregion
#region Visitor implementation
///
/// Visit and node after its children have visited. There is nothing to do here
/// because only leaf equality nodes contain properties extracted by this visitor.
///
/// And expression node
/// Results ignored by this visitor implementation.
public override object Visit(DbAndExpression node)
{
EntityUtil.CheckArgumentNull(node, "node");
Visit(node.Left);
Visit(node.Right);
return null;
}
///
/// Perform work for an equality expression node.
///
/// Equality expresion node
/// Results ignored by this visitor implementation.
public override object Visit(DbComparisonExpression node)
{
EntityUtil.CheckArgumentNull(node, "node");
if (DbExpressionKind.Equals == node.ExpressionKind)
{
m_leftKeySelectors.Add(node.Left);
m_rightKeySelectors.Add(node.Right);
return null;
}
else
{
throw ConstructNotSupportedException(node);
}
}
#endregion
#endregion
}
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.