//--------------------------------------------------------------------- // // Copyright (c) Microsoft Corporation. All rights reserved. // // // @owner Microsoft // @backupOwner Microsoft //--------------------------------------------------------------------- using System; using System.Collections.Generic; using System.Globalization; using System.Diagnostics; using System.Data.Common; using System.Data.Metadata.Edm; namespace System.Data.Query.InternalTrees { #region Constants /// /// Base class for all constant Ops /// internal abstract class ConstantBaseOp : ScalarOp { #region private state private readonly object m_value; #endregion #region constructors protected ConstantBaseOp(OpType opType, TypeUsage type, object value) : base(opType, type) { m_value = value; } /// /// Constructor overload for rules /// /// protected ConstantBaseOp(OpType opType) : base(opType) { } #endregion #region public properties and methods /// /// Get the constant value /// internal virtual Object Value { get { return m_value; } } /// /// 0 children /// internal override int Arity { get { return 0; } } /// /// Two CostantBaseOps are equivalent if they are of the same /// derived type and have the same type and value. /// /// the other Op /// true, if these are equivalent (not a strict equality test) internal override bool IsEquivalent(Op other) { ConstantBaseOp otherConstant = other as ConstantBaseOp; return otherConstant != null && this.OpType == other.OpType && otherConstant.Type.EdmEquals(this.Type) && ((otherConstant.Value == null && this.Value == null) || otherConstant.Value.Equals(this.Value)); } #endregion } /// /// Represents an external constant /// internal sealed class ConstantOp : ConstantBaseOp { #region constructors internal ConstantOp(TypeUsage type, object value) : base(OpType.Constant, type, value) { Debug.Assert(value != null, "ConstantOp with a null value?"); } private ConstantOp() : base(OpType.Constant) { } #endregion #region public methods /// /// Pattern for transformation rules /// internal static readonly ConstantOp Pattern = new ConstantOp(); /// /// Visitor pattern method /// /// The BasicOpVisitor that is visiting this Op /// The Node that references this Op [DebuggerNonUserCode] internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); } /// /// Visitor pattern method for visitors with a return value /// /// The visitor /// The node in question /// An instance of TResultType [DebuggerNonUserCode] internal override TResultType Accept(BasicOpVisitorOfT v, Node n) { return v.Visit(this, n); } #endregion } /// /// Represents null constants /// internal sealed class NullOp : ConstantBaseOp { #region constructors internal NullOp(TypeUsage type) : base(OpType.Null, type, null) { } private NullOp() : base(OpType.Null) { } #endregion #region public apis /// /// Pattern for transformation rules /// internal static readonly NullOp Pattern = new NullOp(); /// /// Visitor pattern method /// /// The BasicOpVisitor that is visiting this Op /// The Node that references this Op [DebuggerNonUserCode] internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); } /// /// Visitor pattern method for visitors with a return value /// /// The visitor /// The node in question /// An instance of TResultType [DebuggerNonUserCode] internal override TResultType Accept(BasicOpVisitorOfT v, Node n) { return v.Visit(this, n); } #endregion } /// /// Represents internally generated constants /// internal sealed class InternalConstantOp : ConstantBaseOp { #region constructors internal InternalConstantOp(TypeUsage type, object value) : base(OpType.InternalConstant, type, value) { Debug.Assert(value != null, "InternalConstantOp with a null value?"); } private InternalConstantOp() : base(OpType.InternalConstant) { } #endregion #region public apis /// /// Pattern for transformation rules /// internal static readonly InternalConstantOp Pattern = new InternalConstantOp(); /// /// Visitor pattern method /// /// The BasicOpVisitor that is visiting this Op /// The Node that references this Op [DebuggerNonUserCode] internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); } /// /// Visitor pattern method for visitors with a return value /// /// The visitor /// The node in question /// An instance of TResultType [DebuggerNonUserCode] internal override TResultType Accept(BasicOpVisitorOfT v, Node n) { return v.Visit(this, n); } #endregion } /// /// Represents an internally generated constant that is used to serve as a null sentinel, /// i.e. to be checked whether it is null. /// internal sealed class NullSentinelOp : ConstantBaseOp { #region constructors internal NullSentinelOp(TypeUsage type, object value) : base(OpType.NullSentinel, type, value) { } private NullSentinelOp() : base(OpType.NullSentinel) { } #endregion #region public apis /// /// Pattern for transformation rules /// internal static readonly NullSentinelOp Pattern = new NullSentinelOp(); /// /// Visitor pattern method /// /// The BasicOpVisitor that is visiting this Op /// The Node that references this Op [DebuggerNonUserCode] internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); } /// /// Visitor pattern method for visitors with a return value /// /// The visitor /// The node in question /// An instance of TResultType [DebuggerNonUserCode] internal override TResultType Accept(BasicOpVisitorOfT v, Node n) { return v.Visit(this, n); } #endregion } /// /// Represents a constant predicate (with a value of either true or false) /// internal sealed class ConstantPredicateOp : ConstantBaseOp { #region constructors internal ConstantPredicateOp(TypeUsage type, bool value) : base(OpType.ConstantPredicate, type, value) { } private ConstantPredicateOp() : base(OpType.ConstantPredicate) { } #endregion #region public methods /// /// Pattern for transformation rules /// internal static readonly ConstantPredicateOp Pattern = new ConstantPredicateOp(); /// /// Value of the constant predicate /// internal new bool Value { get { return (bool)base.Value; } } /// /// Is this the true predicate /// internal bool IsTrue { get { return this.Value; } } /// /// Is this the 'false' predicate /// internal bool IsFalse { get { return this.Value == false; } } /// /// Visitor pattern method /// /// The BasicOpVisitor that is visiting this Op /// The Node that references this Op [DebuggerNonUserCode] internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); } /// /// Visitor pattern method for visitors with a return value /// /// The visitor /// The node in question /// An instance of TResultType [DebuggerNonUserCode] internal override TResultType Accept(BasicOpVisitorOfT v, Node n) { return v.Visit(this, n); } #endregion } #endregion /// /// A reference to an existing variable /// internal sealed class VarRefOp : ScalarOp { #region private state private Var m_var; #endregion #region constructors internal VarRefOp(Var v) : base(OpType.VarRef, v.Type) { m_var = v; } private VarRefOp() : base(OpType.VarRef) { } #endregion #region public methods /// /// Singleton used for pattern matching /// internal static readonly VarRefOp Pattern = new VarRefOp(); /// /// 0 children /// internal override int Arity { get { return 0; } } /// /// Two VarRefOps are equivalent, if they reference the same Var /// /// the other Op /// true, if these are equivalent internal override bool IsEquivalent(Op other) { VarRefOp otherVarRef = other as VarRefOp; return (otherVarRef != null && otherVarRef.Var.Equals(this.Var)); } /// /// The Var that this Op is referencing /// internal Var Var { get { return m_var; } } /// /// Visitor pattern method /// /// The BasicOpVisitor that is visiting this Op /// The Node that references this Op [DebuggerNonUserCode] internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); } /// /// Visitor pattern method for visitors with a return value /// /// The visitor /// The node in question /// An instance of TResultType [DebuggerNonUserCode] internal override TResultType Accept(BasicOpVisitorOfT v, Node n) { return v.Visit(this, n); } #endregion } /// /// Represents an arbitrary function call /// internal sealed class FunctionOp : ScalarOp { #region private state private EdmFunction m_function; #endregion #region constructors internal FunctionOp(EdmFunction function) : base(OpType.Function, function.ReturnParameter.TypeUsage) { m_function = function; } private FunctionOp() : base(OpType.Function) { } #endregion #region public methods /// /// Singleton instance used for patterns in transformation rules /// internal static readonly FunctionOp Pattern = new FunctionOp(); /// /// The function that's being invoked /// internal EdmFunction Function { get { return m_function; } } /// /// Two FunctionOps are equivalent if they reference the same EdmFunction /// /// the other Op /// true, if these are equivalent internal override bool IsEquivalent(Op other) { FunctionOp otherFunctionOp = other as FunctionOp; return (otherFunctionOp != null && otherFunctionOp.Function.EdmEquals(this.Function)); } /// /// Visitor pattern method /// /// The BasicOpVisitor that is visiting this Op /// The Node that references this Op [DebuggerNonUserCode] internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); } /// /// Visitor pattern method for visitors with a return value /// /// The visitor /// The node in question /// An instance of TResultType [DebuggerNonUserCode] internal override TResultType Accept(BasicOpVisitorOfT v, Node n) { return v.Visit(this, n); } #endregion } /// /// Represents a property access /// internal sealed class PropertyOp : ScalarOp { #region private state private EdmMember m_property; #endregion #region constructors internal PropertyOp(TypeUsage type, EdmMember property) : base(OpType.Property, type) { Debug.Assert((property is EdmProperty) || (property is RelationshipEndMember) || (property is NavigationProperty), "Unexpected EdmMember type"); m_property = property; } private PropertyOp() : base(OpType.Property) { } #endregion #region public methods /// /// Used for patterns in transformation rules /// internal static readonly PropertyOp Pattern = new PropertyOp(); /// /// 1 child - the instance /// internal override int Arity { get { return 1; } } /// /// The property metadata /// internal EdmMember PropertyInfo { get { return m_property; } } /// /// Visitor pattern method /// /// The BasicOpVisitor that is visiting this Op /// The Node that references this Op [DebuggerNonUserCode] internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); } /// /// Visitor pattern method for visitors with a return value /// /// The visitor /// The node in question /// An instance of TResultType [DebuggerNonUserCode] internal override TResultType Accept(BasicOpVisitorOfT v, Node n) { return v.Visit(this, n); } #endregion } /// /// Represents a TREAT AS operation /// internal sealed class TreatOp : ScalarOp { #region private state private bool m_isFake; #endregion #region constructors internal TreatOp(TypeUsage type, bool isFake) : base(OpType.Treat, type) { m_isFake = isFake; } private TreatOp() : base(OpType.Treat) { } #endregion #region public methods /// /// Used as patterns in transformation rules /// internal static readonly TreatOp Pattern = new TreatOp(); /// /// 1 child - instance /// internal override int Arity { get { return 1; } } /// /// Is this a "fake" treat? /// internal bool IsFakeTreat { get { return m_isFake; } } /// /// Visitor pattern method /// /// The BasicOpVisitor that is visiting this Op /// The Node that references this Op [DebuggerNonUserCode] internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); } /// /// Visitor pattern method for visitors with a return value /// /// The visitor /// The node in question /// An instance of TResultType [DebuggerNonUserCode] internal override TResultType Accept(BasicOpVisitorOfT v, Node n) { return v.Visit(this, n); } #endregion } /// /// An IS OF operation /// internal sealed class IsOfOp : ScalarOp { #region private state private TypeUsage m_isOfType; private bool m_isOfOnly; #endregion #region constructors internal IsOfOp(TypeUsage isOfType, bool isOfOnly, TypeUsage type) : base(OpType.IsOf, type) { m_isOfType = isOfType; m_isOfOnly = isOfOnly; } private IsOfOp() : base(OpType.IsOf) { } #endregion #region public methods /// /// Pattern used for transformation rules /// internal static readonly IsOfOp Pattern = new IsOfOp(); /// /// 1 child - instance /// internal override int Arity { get { return 1; } } /// /// The type being checked for /// internal TypeUsage IsOfType { get { return m_isOfType; } } internal bool IsOfOnly { get { return m_isOfOnly; } } /// /// Visitor pattern method /// /// The BasicOpVisitor that is visiting this Op /// The Node that references this Op [DebuggerNonUserCode] internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); } /// /// Visitor pattern method for visitors with a return value /// /// The visitor /// The node in question /// An instance of TResultType [DebuggerNonUserCode] internal override TResultType Accept(BasicOpVisitorOfT v, Node n) { return v.Visit(this, n); } #endregion } /// /// Cast operation. Convert a type instance into an instance of another type /// internal sealed class CastOp : ScalarOp { #region constructors internal CastOp(TypeUsage type) : base(OpType.Cast, type) { } private CastOp() : base(OpType.Cast) { } #endregion #region public methods /// /// Pattern for transformation rules /// internal static readonly CastOp Pattern = new CastOp(); /// /// 1 child - instance /// internal override int Arity { get { return 1; } } /// /// Visitor pattern method /// /// The BasicOpVisitor that is visiting this Op /// The Node that references this Op [DebuggerNonUserCode] internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); } /// /// Visitor pattern method for visitors with a return value /// /// The visitor /// The node in question /// An instance of TResultType [DebuggerNonUserCode] internal override TResultType Accept(BasicOpVisitorOfT v, Node n) { return v.Visit(this, n); } #endregion } /// /// An internal cast operation. (Softly) Convert a type instance into an instance of another type /// /// This Op is intended to capture "promotion" semantics. (ie) int16 promotes to an int32; Customer promotes to Person /// etc. This Op is intended to shield the PlanCompiler from having to reason about /// the promotion semantics; and is intended to make the query tree very /// explicit /// /// internal sealed class SoftCastOp : ScalarOp { #region constructors internal SoftCastOp(TypeUsage type) : base(OpType.SoftCast, type) { } private SoftCastOp() : base(OpType.SoftCast) { } #endregion #region public methods /// /// Pattern for transformation rules /// internal static readonly SoftCastOp Pattern = new SoftCastOp(); /// /// 1 child - input expression /// internal override int Arity { get { return 1; } } /// /// Visitor pattern method /// /// The BasicOpVisitor that is visiting this Op /// The Node that references this Op [DebuggerNonUserCode] internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); } /// /// Visitor pattern method for visitors with a return value /// /// The visitor /// The node in question /// An instance of TResultType [DebuggerNonUserCode] internal override TResultType Accept(BasicOpVisitorOfT v, Node n) { return v.Visit(this, n); } #endregion } /// /// Represents a comparision operation (LT, GT etc.) /// internal sealed class ComparisonOp : ScalarOp { #region constructors internal ComparisonOp(OpType opType, TypeUsage type) : base(opType, type) { } private ComparisonOp(OpType opType) : base(opType) { } #endregion #region public methods /// /// Patterns for use in transformation rules /// internal static readonly ComparisonOp PatternEq = new ComparisonOp(OpType.EQ); /// /// 2 children - left, right /// internal override int Arity { get { return 2; } } /// /// Visitor pattern method /// /// The BasicOpVisitor that is visiting this Op /// The Node that references this Op [DebuggerNonUserCode] internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); } /// /// Visitor pattern method for visitors with a return value /// /// The visitor /// The node in question /// An instance of TResultType [DebuggerNonUserCode] internal override TResultType Accept(BasicOpVisitorOfT v, Node n) { return v.Visit(this, n); } #endregion } /// /// Represents a string comparison operation /// internal sealed class LikeOp : ScalarOp { #region constructors internal LikeOp(TypeUsage boolType) : base(OpType.Like, boolType) { } private LikeOp() : base(OpType.Like) { } #endregion #region public surface /// /// Pattern for use in transformation rules /// internal static readonly LikeOp Pattern = new LikeOp(); /// /// 3 children - string, pattern , escape /// internal override int Arity { get { return 3; } } /// /// Visitor pattern method /// /// The BasicOpVisitor that is visiting this Op /// The Node that references this Op [DebuggerNonUserCode] internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); } /// /// Visitor pattern method for visitors with a return value /// /// The visitor /// The node in question /// An instance of TResultType [DebuggerNonUserCode] internal override TResultType Accept(BasicOpVisitorOfT v, Node n) { return v.Visit(this, n); } #endregion } /// /// Represents a conditional operation - and,or,not, is null /// A little hacky - since it represents and/or/not as optypes - could I not /// have done the same with the comparison operators? /// internal sealed class ConditionalOp : ScalarOp { #region constructors internal ConditionalOp(OpType optype, TypeUsage type) : base(optype, type) { } private ConditionalOp(OpType opType) : base(opType) { } #endregion #region public methods /// /// Patterns for use in transformation rules /// internal static readonly ConditionalOp PatternAnd = new ConditionalOp(OpType.And); internal static readonly ConditionalOp PatternOr = new ConditionalOp(OpType.Or); internal static readonly ConditionalOp PatternNot = new ConditionalOp(OpType.Not); internal static readonly ConditionalOp PatternIsNull = new ConditionalOp(OpType.IsNull); /// /// Visitor pattern method /// /// The BasicOpVisitor that is visiting this Op /// The Node that references this Op [DebuggerNonUserCode] internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); } /// /// Visitor pattern method for visitors with a return value /// /// The visitor /// The node in question /// An instance of TResultType [DebuggerNonUserCode] internal override TResultType Accept(BasicOpVisitorOfT v, Node n) { return v.Visit(this, n); } #endregion } /// /// ANSI switched Case expression. /// internal sealed class CaseOp : ScalarOp { #region constructors internal CaseOp(TypeUsage type) : base(OpType.Case, type) { } private CaseOp() : base(OpType.Case) { } #endregion #region public methods /// /// Pattern for use in transformation rules /// internal static readonly CaseOp Pattern = new CaseOp(); /// /// Visitor pattern method /// /// The BasicOpVisitor that is visiting this Op /// The Node that references this Op [DebuggerNonUserCode] internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); } /// /// Visitor pattern method for visitors with a return value /// /// The visitor /// The node in question /// An instance of TResultType [DebuggerNonUserCode] internal override TResultType Accept(BasicOpVisitorOfT v, Node n) { return v.Visit(this, n); } #endregion } /// /// Basic Aggregates /// internal sealed class AggregateOp : ScalarOp { #region private state private EdmFunction m_aggFunc; private bool m_distinctAgg; #endregion #region constructors internal AggregateOp(EdmFunction aggFunc, bool distinctAgg) : base(OpType.Aggregate, aggFunc.ReturnParameter.TypeUsage) { m_aggFunc = aggFunc; m_distinctAgg = distinctAgg; } private AggregateOp() : base(OpType.Aggregate) { } #endregion #region public methods /// /// Pattern for transformation rules /// internal static readonly AggregateOp Pattern = new AggregateOp(); /// /// The Aggregate function's metadata /// internal EdmFunction AggFunc { get { return m_aggFunc; } } /// /// Is this a "distinct" aggregate /// internal bool IsDistinctAggregate { get { return m_distinctAgg; } } /// /// Yes; this is an aggregate /// internal override bool IsAggregateOp {get{return true;}} /// /// Visitor pattern method /// /// The BasicOpVisitor that is visiting this Op /// The Node that references this Op [DebuggerNonUserCode] internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); } /// /// Visitor pattern method for visitors with a return value /// /// The visitor /// The node in question /// An instance of TResultType [DebuggerNonUserCode] internal override TResultType Accept(BasicOpVisitorOfT v, Node n) { return v.Visit(this, n); } #endregion } /// /// Represents an arbitrary nest operation - can be used anywhere /// internal sealed class CollectOp : ScalarOp { #region constructors internal CollectOp(TypeUsage type) : base(OpType.Collect, type) { } private CollectOp() : base(OpType.Collect) { } #endregion #region public methods /// /// Pattern for use in transformation rules /// internal static readonly CollectOp Pattern = new CollectOp(); /// /// 1 child - instance /// internal override int Arity { get { return 1; } } /// /// Visitor pattern method /// /// The BasicOpVisitor that is visiting this Op /// The Node that references this Op [DebuggerNonUserCode] internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); } /// /// Visitor pattern method for visitors with a return value /// /// The visitor /// The node in question /// An instance of TResultType [DebuggerNonUserCode] internal override TResultType Accept(BasicOpVisitorOfT v, Node n) { return v.Visit(this, n); } #endregion } /// /// Almost identical to a PropertyOp - the only difference being that we're dealing with an /// "extended" property (a rel property) this time /// internal sealed class RelPropertyOp : ScalarOp { #region private state private readonly RelProperty m_property; #endregion #region constructors private RelPropertyOp() : base(OpType.RelProperty) { } internal RelPropertyOp(TypeUsage type, RelProperty property) : base(OpType.RelProperty, type) { m_property = property; } #endregion #region public APIs /// /// Pattern for transformation rules /// internal static readonly RelPropertyOp Pattern = new RelPropertyOp(); /// /// 1 child - the entity instance /// internal override int Arity { get { return 1; } } /// /// Get the property metadata /// public RelProperty PropertyInfo { get { return m_property; } } /// /// Visitor pattern method /// /// The BasicOpVisitor that is visiting this Op /// The Node that references this Op [DebuggerNonUserCode] internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); } /// /// Visitor pattern method for visitors with a return value /// /// The visitor /// The node in question /// An instance of TResultType [DebuggerNonUserCode] internal override TResultType Accept(BasicOpVisitorOfT v, Node n) { return v.Visit(this, n); } #endregion } /// /// Base class for DiscriminatedNewEntityOp and NewEntityOp /// internal abstract class NewEntityBaseOp : ScalarOp { #region private state private readonly bool m_scoped; private readonly EntitySet m_entitySet; private readonly List m_relProperties; // list of relationship properties for which we have values #endregion #region constructors internal NewEntityBaseOp(OpType opType, TypeUsage type, bool scoped, EntitySet entitySet, List relProperties) : base(opType, type) { Debug.Assert(scoped || entitySet == null, "entitySet cann't be set of constructor isn't scoped"); Debug.Assert(relProperties != null, "expected non-null list of rel-properties"); m_scoped = scoped; m_entitySet = entitySet; m_relProperties = relProperties; } protected NewEntityBaseOp(OpType opType) : base(opType) { } #endregion #region public APIs /// /// True if the entity constructor is scoped to a particular entity set or null (scoped as "unscoped"). /// False if the scope is not yet known. Scope is determined in PreProcessor. /// internal bool Scoped { get { return m_scoped; } } /// /// Get the entityset (if any) associated with this constructor /// internal EntitySet EntitySet { get { return m_entitySet; } } /// /// get the list of relationship properties (if any) specified for this constructor /// internal List RelationshipProperties { get { return m_relProperties; } } #endregion } /// /// A new entity instance constructor /// internal sealed class NewEntityOp : NewEntityBaseOp { #region constructors private NewEntityOp() : base(OpType.NewEntity) { } internal NewEntityOp(TypeUsage type, List relProperties, bool scoped, EntitySet entitySet) : base(OpType.NewEntity, type, scoped, entitySet, relProperties) { } #endregion #region public methods /// /// Pattern for transformation rules /// internal static readonly NewEntityOp Pattern = new NewEntityOp(); /// /// Visitor pattern method /// /// The BasicOpVisitor that is visiting this Op /// The Node that references this Op [DebuggerNonUserCode] internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); } /// /// Visitor pattern method for visitors with a return value /// /// The visitor /// The node in question /// An instance of TResultType [DebuggerNonUserCode] internal override TResultType Accept(BasicOpVisitorOfT v, Node n) { return v.Visit(this, n); } #endregion } /// /// A new instance creation /// internal sealed class NewInstanceOp : ScalarOp { #region constructors internal NewInstanceOp(TypeUsage type) : base(OpType.NewInstance, type) { Debug.Assert(!type.EdmType.Abstract, "cannot create new instance of abstract type"); Debug.Assert(!TypeSemantics.IsEntityType(type), "cannot use this Op for entity construction"); } private NewInstanceOp() : base(OpType.NewInstance) { } #endregion #region public methods /// /// Pattern for transformation rules /// internal static readonly NewInstanceOp Pattern = new NewInstanceOp(); /// /// Visitor pattern method /// /// The BasicOpVisitor that is visiting this Op /// The Node that references this Op [DebuggerNonUserCode] internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); } /// /// Visitor pattern method for visitors with a return value /// /// The visitor /// The node in question /// An instance of TResultType [DebuggerNonUserCode] internal override TResultType Accept(BasicOpVisitorOfT v, Node n) { return v.Visit(this, n); } #endregion } /// /// Polymorphic new instance creation (takes all properties of all types in the hierarchy + discriminator) /// internal sealed class DiscriminatedNewEntityOp : NewEntityBaseOp { #region Private state private readonly ExplicitDiscriminatorMap m_discriminatorMap; #endregion #region Constructors internal DiscriminatedNewEntityOp(TypeUsage type, ExplicitDiscriminatorMap discriminatorMap, EntitySet entitySet, List relProperties) : base(OpType.DiscriminatedNewEntity, type, true, entitySet, relProperties) { Debug.Assert(null != discriminatorMap, "null discriminator map"); m_discriminatorMap = discriminatorMap; } private DiscriminatedNewEntityOp() : base(OpType.DiscriminatedNewEntity) { } #endregion #region "Public" members internal static readonly DiscriminatedNewEntityOp Pattern = new DiscriminatedNewEntityOp(); /// /// Gets discriminator and type information used in construction of type. /// internal ExplicitDiscriminatorMap DiscriminatorMap { get { return m_discriminatorMap; } } [DebuggerNonUserCode] internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); } [DebuggerNonUserCode] internal override TResultType Accept(BasicOpVisitorOfT v, Node n) { return v.Visit(this, n); } #endregion } /// /// Represents a new record constructor /// internal sealed class NewRecordOp : ScalarOp { #region private state private List m_fields; // list of fields with specified values #endregion #region constructors /// /// Basic constructor. All fields have a value specified /// /// internal NewRecordOp(TypeUsage type) : base(OpType.NewRecord, type) { m_fields = new List(TypeHelpers.GetEdmType(type).Properties); } /// /// Alternate form of the constructor. Only some fields have a value specified /// The arguments to the corresponding Node are exactly 1-1 with the fields /// described here. /// The missing fields are considered to be "null" /// /// /// internal NewRecordOp(TypeUsage type, List fields) : base(OpType.NewRecord, type) { #if DEBUG foreach (EdmProperty p in fields) { Debug.Assert(Object.ReferenceEquals(p.DeclaringType, this.Type.EdmType)); } #endif m_fields = fields; } private NewRecordOp() : base(OpType.NewRecord) { } #endregion #region public methods /// /// Pattern for transformation rules /// internal static readonly NewRecordOp Pattern = new NewRecordOp(); /// /// Determine if a value has been provided for the specified field. /// Returns the position of this field (ie) the specific argument in the Node's /// children. If no value has been provided for this field, then simply /// return false /// /// /// /// internal bool GetFieldPosition(EdmProperty field, out int fieldPosition) { Debug.Assert(Object.ReferenceEquals(field.DeclaringType, this.Type.EdmType), "attempt to get invalid field from this record type"); fieldPosition = 0; for (int i = 0; i < m_fields.Count; i++) { if (m_fields[i] == field) { fieldPosition = i; return true; } } return false; } /// /// List of all properties that have values specified /// internal List Properties { get { return m_fields; } } /// /// Visitor pattern method /// /// The BasicOpVisitor that is visiting this Op /// The Node that references this Op [DebuggerNonUserCode] internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); } /// /// Visitor pattern method for visitors with a return value /// /// The visitor /// The node in question /// An instance of TResultType [DebuggerNonUserCode] internal override TResultType Accept(BasicOpVisitorOfT v, Node n) { return v.Visit(this, n); } #endregion } internal sealed class NewMultisetOp : ScalarOp { #region constructors internal NewMultisetOp(TypeUsage type) : base(OpType.NewMultiset, type) { } private NewMultisetOp() : base(OpType.NewMultiset) { } #endregion #region public methods /// /// Pattern for transformation rules /// internal static readonly NewMultisetOp Pattern = new NewMultisetOp(); /// /// Visitor pattern method /// /// The BasicOpVisitor that is visiting this Op /// The Node that references this Op [DebuggerNonUserCode] internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); } /// /// Visitor pattern method for visitors with a return value /// /// The visitor /// The node in question /// An instance of TResultType [DebuggerNonUserCode] internal override TResultType Accept(BasicOpVisitorOfT v, Node n) { return v.Visit(this, n); } #endregion } /// /// Represents arithmetic operators - Plus,Minus,Multiply,Divide,Modulo,UnaryMinus /// internal sealed class ArithmeticOp : ScalarOp { #region constructors internal ArithmeticOp(OpType opType, TypeUsage type) : base(opType, type) { } #endregion #region public methods /// /// Visitor pattern method /// /// The BasicOpVisitor that is visiting this Op /// The Node that references this Op [DebuggerNonUserCode] internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); } /// /// Visitor pattern method for visitors with a return value /// /// The visitor /// The node in question /// An instance of TResultType [DebuggerNonUserCode] internal override TResultType Accept(BasicOpVisitorOfT v, Node n) { return v.Visit(this, n); } #endregion } /// /// /// internal sealed class RefOp : ScalarOp { #region private state private EntitySet m_entitySet; #endregion #region constructors internal RefOp(EntitySet entitySet, TypeUsage type) : base(OpType.Ref, type) { m_entitySet = entitySet; } private RefOp() : base(OpType.Ref) { } #endregion #region public methods /// /// Pattern for transformation rules /// internal static readonly RefOp Pattern = new RefOp(); /// /// 1 child - key /// internal override int Arity { get { return 1; } } /// /// The EntitySet to which the reference refers /// internal EntitySet EntitySet { get { return m_entitySet; } } /// /// Visitor pattern method /// /// The BasicOpVisitor that is visiting this Op /// The Node that references this Op [DebuggerNonUserCode] internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); } /// /// Visitor pattern method for visitors with a return value /// /// The visitor /// The node in question /// An instance of TResultType [DebuggerNonUserCode] internal override TResultType Accept(BasicOpVisitorOfT v, Node n) { return v.Visit(this, n); } #endregion } /// /// Represents an EXISTS subquery? /// internal sealed class ExistsOp : ScalarOp { #region constructors internal ExistsOp(TypeUsage type) : base(OpType.Exists, type) { } private ExistsOp() : base(OpType.Exists) { } #endregion #region public methods /// /// Pattern for transformation rules /// internal static readonly ExistsOp Pattern = new ExistsOp(); /// /// 1 child - collection input /// internal override int Arity { get { return 1; } } /// /// Visitor pattern method /// /// The BasicOpVisitor that is visiting this Op /// The Node that references this Op [DebuggerNonUserCode] internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); } /// /// Visitor pattern method for visitors with a return value /// /// The visitor /// The node in question /// An instance of TResultType [DebuggerNonUserCode] internal override TResultType Accept(BasicOpVisitorOfT v, Node n) { return v.Visit(this, n); } #endregion } /// /// Represents an Element() op - extracts the scalar value from a collection /// internal sealed class ElementOp : ScalarOp { #region constructors internal ElementOp(TypeUsage type) : base(OpType.Element, type) { } private ElementOp() : base(OpType.Element) { } #endregion #region public methods /// /// Pattern for transformation rules /// internal static readonly ElementOp Pattern = new ElementOp(); /// /// 1 child - collection instance /// internal override int Arity { get { return 1; } } /// /// Visitor pattern method /// /// The BasicOpVisitor that is visiting this Op /// The Node that references this Op [DebuggerNonUserCode] internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); } /// /// Visitor pattern method for visitors with a return value /// /// The visitor /// The node in question /// An instance of TResultType [DebuggerNonUserCode] internal override TResultType Accept(BasicOpVisitorOfT v, Node n) { return v.Visit(this, n); } #endregion } /// /// extracts the key from a ref /// internal sealed class GetRefKeyOp : ScalarOp { #region constructors internal GetRefKeyOp(TypeUsage type) : base(OpType.GetRefKey, type) { } private GetRefKeyOp() : base(OpType.GetRefKey) { } #endregion #region public methods /// /// Pattern for transformation rules /// internal static readonly GetRefKeyOp Pattern = new GetRefKeyOp(); /// /// 1 child - ref instance /// internal override int Arity { get { return 1; } } /// /// Visitor pattern method /// /// The BasicOpVisitor that is visiting this Op /// The Node that references this Op [DebuggerNonUserCode] internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); } /// /// Visitor pattern method for visitors with a return value /// /// The visitor /// The node in question /// An instance of TResultType [DebuggerNonUserCode] internal override TResultType Accept(BasicOpVisitorOfT v, Node n) { return v.Visit(this, n); } #endregion } /// /// Extracts the ref from an entity instance /// internal sealed class GetEntityRefOp : ScalarOp { #region constructors internal GetEntityRefOp(TypeUsage type) : base(OpType.GetEntityRef, type) { } private GetEntityRefOp() : base(OpType.GetEntityRef) { } #endregion #region public methods /// /// Pattern for transformation rules /// internal static readonly GetEntityRefOp Pattern = new GetEntityRefOp(); /// /// 1 child - entity instance /// internal override int Arity { get { return 1; } } /// /// Visitor pattern method /// /// The BasicOpVisitor that is visiting this Op /// The Node that references this Op [DebuggerNonUserCode] internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); } /// /// Visitor pattern method for visitors with a return value /// /// The visitor /// The node in question /// An instance of TResultType [DebuggerNonUserCode] internal override TResultType Accept(BasicOpVisitorOfT v, Node n) { return v.Visit(this, n); } #endregion } /// /// Gets the target entity pointed at by a reference /// internal sealed class DerefOp : ScalarOp { #region constructors internal DerefOp(TypeUsage type) : base(OpType.Deref, type) { } private DerefOp() : base(OpType.Deref) { } #endregion #region public methods /// /// Pattern for transformation rules /// internal static readonly DerefOp Pattern = new DerefOp(); /// /// 1 child - entity instance /// internal override int Arity { get { return 1; } } /// /// Visitor pattern method /// /// The BasicOpVisitor that is visiting this Op /// The Node that references this Op [DebuggerNonUserCode] internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); } /// /// Visitor pattern method for visitors with a return value /// /// The visitor /// The node in question /// An instance of TResultType [DebuggerNonUserCode] internal override TResultType Accept(BasicOpVisitorOfT v, Node n) { return v.Visit(this, n); } #endregion } /// /// Navigate a relationship, and get the reference(s) of the target end /// internal sealed class NavigateOp : ScalarOp { #region private state private readonly RelProperty m_property; #endregion #region constructors internal NavigateOp(TypeUsage type, RelProperty relProperty) : base(OpType.Navigate, type) { m_property = relProperty; } private NavigateOp() : base(OpType.Navigate) { } #endregion #region public methods /// /// Pattern for transformation rules /// internal static readonly NavigateOp Pattern = new NavigateOp(); /// /// 1 child - entity instance /// internal override int Arity { get { return 1; } } /// /// The rel property that describes this nvaigation /// internal RelProperty RelProperty { get { return m_property; } } /// /// The relationship we're traversing /// internal RelationshipType Relationship { get { return m_property.Relationship; } } /// /// The starting point of the traversal /// internal RelationshipEndMember FromEnd { get { return m_property.FromEnd; } } /// /// The end-point of the traversal /// internal RelationshipEndMember ToEnd { get { return m_property.ToEnd; } } /// /// Visitor pattern method /// /// The BasicOpVisitor that is visiting this Op /// The Node that references this Op [DebuggerNonUserCode] internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); } /// /// Visitor pattern method for visitors with a return value /// /// The visitor /// The node in question /// An instance of TResultType [DebuggerNonUserCode] internal override TResultType Accept(BasicOpVisitorOfT v, Node n) { return v.Visit(this, n); } #endregion } }