//---------------------------------------------------------------------
//
// 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
}
}