//--------------------------------------------------------------------- // // Copyright (c) Microsoft Corporation. All rights reserved. // // // @owner Microsoft // @backupOwner Microsoft //--------------------------------------------------------------------- namespace System.Data.Query.InternalTrees { using System.Data.Metadata.Edm; using System.Diagnostics; /// /// The operator types. Includes both scalar and relational operators, /// and physical and logical operators, and rule operators /// internal enum OpType { #region ScalarOpType /// /// Constants /// Constant, /// /// An internally generated constant /// InternalConstant, /// /// An internally generated constant used as a null sentinel /// NullSentinel, /// /// A null constant /// Null, /// /// ConstantPredicate /// ConstantPredicate, /// /// A Var reference /// VarRef, /// /// GreaterThan /// GT, /// /// >= /// GE, /// /// Lessthan or equals /// LE, /// /// Less than /// LT, /// /// Equals /// EQ, /// /// Not equals /// NE, /// /// String comparison /// Like, /// /// Addition /// Plus, /// /// Subtraction /// Minus, /// /// Multiplication /// Multiply, /// /// Division /// Divide, /// /// Modulus /// Modulo, /// /// Unary Minus /// UnaryMinus, /// /// And /// And, /// /// Or /// Or, /// /// Not /// Not, /// /// is null /// IsNull, /// /// switched case expression /// Case, /// /// treat-as /// Treat, /// /// is-of /// IsOf, /// /// Cast /// Cast, /// /// Internal cast /// SoftCast, /// /// a basic aggregate /// Aggregate, /// /// function call /// Function, /// /// Reference to a "relationship" property /// RelProperty, /// /// property reference /// Property, /// /// entity constructor /// NewEntity, /// /// new instance constructor for a named type(other than multiset, record) /// NewInstance, /// /// new instance constructor for a named type and sub-types /// DiscriminatedNewEntity, /// /// Multiset constructor /// NewMultiset, /// /// record constructor /// NewRecord, /// /// Get the key from a Ref /// GetRefKey, /// /// Get the ref from an entity instance /// GetEntityRef, /// /// create a reference /// Ref, /// /// exists /// Exists, /// /// get the singleton element from a collection /// Element, /// /// Builds up a collection /// Collect, /// /// gets the target entity pointed at by a reference /// Deref, /// /// Traverse a relationship and get the references of the other end /// Navigate, #endregion #region RelOpType /// /// A table scan /// ScanTable, /// /// A view scan /// ScanView, /// /// Filter /// Filter, /// /// Project /// Project, /// /// InnerJoin /// InnerJoin, /// /// LeftOuterJoin /// LeftOuterJoin, /// /// FullOuter join /// FullOuterJoin, /// /// Cross join /// CrossJoin, /// /// cross apply /// CrossApply, /// /// outer apply /// OuterApply, /// /// Unnest /// Unnest, /// /// Sort /// Sort, /// /// Constrained Sort (physical paging - Limit and Skip) /// ConstrainedSort, /// /// GroupBy /// GroupBy, /// /// GroupByInto (projects the group as well) /// GroupByInto, /// /// UnionAll /// UnionAll, /// /// Intersect /// Intersect, /// /// Except /// Except, /// /// Distinct /// Distinct, /// /// Select a single row from a subquery /// SingleRow, /// /// A table with exactly one row /// SingleRowTable, #endregion #region AncillaryOpType /// /// Variable definition /// VarDef, /// /// List of variable definitions /// VarDefList, #endregion #region RulePatternOpType /// /// Leaf /// Leaf, #endregion #region PhysicalOpType /// /// Physical Project /// PhysicalProject, /// /// single-stream nest aggregation /// SingleStreamNest, /// /// multi-stream nest aggregation /// MultiStreamNest, #endregion /// /// NotValid /// MaxMarker, NotValid = MaxMarker } /// /// Represents an operator /// internal abstract class Op { #region private state private OpType m_opType; #endregion #region constructors /// /// Basic constructor /// internal Op(OpType opType) { m_opType = opType; } #endregion #region public methods /// /// Represents an unknown arity. Usually for Ops that can have a varying number of Args /// internal const int ArityVarying = -1; /// /// Kind of Op /// internal OpType OpType { get { return m_opType; } } /// /// The Arity of this Op (ie) how many arguments can it have. /// Returns -1 if the arity is not known a priori /// internal virtual int Arity { get { return ArityVarying; } } /// /// Is this a ScalarOp /// internal virtual bool IsScalarOp { get { return false; } } /// /// Is this a RulePatternOp /// internal virtual bool IsRulePatternOp { get { return false; } } /// /// Is this a RelOp /// internal virtual bool IsRelOp { get { return false; } } /// /// Is this an AncillaryOp /// internal virtual bool IsAncillaryOp { get { return false; } } /// /// Is this a PhysicalOp /// internal virtual bool IsPhysicalOp { get { return false; } } /// /// Is the other Op equivalent? /// /// the other Op to compare /// true, if the Ops are equivalent internal virtual bool IsEquivalent(Op other) { return false; } /// /// Simple mechanism to get the type for an Op. Applies only to scalar and ancillaryOps /// internal virtual TypeUsage Type { get { return null; } set { throw System.Data.Entity.Error.NotSupported(); } } /// /// Visitor pattern method /// /// The BasicOpVisitor that is visiting this Op /// The Node that references this Op [DebuggerNonUserCode] internal virtual 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 virtual TResultType Accept(BasicOpVisitorOfT v, Node n) { return v.Visit(this, n); } #endregion } /// /// All scalars fall into this category /// internal abstract class ScalarOp : Op { #region private state private TypeUsage m_type; #endregion #region constructors /// /// Default constructor /// /// kind of Op /// type of value produced by this Op internal ScalarOp(OpType opType, TypeUsage type) : this(opType) { Debug.Assert(type != null, "No type specified for ScalarOp"); m_type = type; } protected ScalarOp(OpType opType) : base(opType) { } #endregion #region public methods /// /// ScalarOp /// internal override bool IsScalarOp { get { return true; } } /// /// Two scalarOps are equivalent (usually) if their OpTypes and types are the /// same. Obviously, their arguments need to be equivalent as well - but that's /// checked elsewhere /// /// The other Op to compare against /// true, if the Ops are indeed equivalent internal override bool IsEquivalent(Op other) { return (other.OpType == this.OpType && TypeSemantics.IsStructurallyEqual(this.Type, other.Type)); } /// /// Datatype of result /// internal override TypeUsage Type { get { return m_type; } set { m_type = value; } } /// /// Is this an Aggregate /// internal virtual bool IsAggregateOp { get{return false;} } #endregion } /// /// All relational operators - filter, project, join etc. /// internal abstract class RelOp : Op { #region constructors /// /// Basic constructor. /// /// kind of Op internal RelOp(OpType opType) : base(opType) { } #endregion #region public methods /// /// RelOp /// internal override bool IsRelOp { get { return true; } } #endregion } /// /// AncillaryOp /// internal abstract class AncillaryOp : Op { #region constructors /// /// Default constructor /// /// kind of Op internal AncillaryOp(OpType opType) : base(opType) { } #endregion #region public methods /// /// AncillaryOp /// internal override bool IsAncillaryOp { get { return true; } } #endregion } /// /// Represents all physical operators /// internal abstract class PhysicalOp : Op { #region constructors /// /// Default constructor /// /// the op type internal PhysicalOp(OpType opType) : base(opType) { } #endregion #region public methods /// /// This is a physical Op /// internal override bool IsPhysicalOp { get { return true; } } #endregion } /// /// All rule pattern operators - Leaf, Tree /// internal abstract class RulePatternOp : Op { #region constructors /// /// Default constructor /// /// kind of Op internal RulePatternOp(OpType opType) : base(opType) { } #endregion #region public methods /// /// RulePatternOp /// internal override bool IsRulePatternOp { get { return true; } } #endregion } }