e79aa3c0ed
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
1626 lines
57 KiB
C#
1626 lines
57 KiB
C#
//---------------------------------------------------------------------
|
|
// <copyright file="ScalarOps.cs" company="Microsoft">
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
// </copyright>
|
|
//
|
|
// @owner [....]
|
|
// @backupOwner [....]
|
|
//---------------------------------------------------------------------
|
|
|
|
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
|
|
|
|
/// <summary>
|
|
/// Base class for all constant Ops
|
|
/// </summary>
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Constructor overload for rules
|
|
/// </summary>
|
|
/// <param name="opType"></param>
|
|
protected ConstantBaseOp(OpType opType)
|
|
: base(opType)
|
|
{
|
|
}
|
|
#endregion
|
|
|
|
#region public properties and methods
|
|
/// <summary>
|
|
/// Get the constant value
|
|
/// </summary>
|
|
internal virtual Object Value { get { return m_value; } }
|
|
|
|
/// <summary>
|
|
/// 0 children
|
|
/// </summary>
|
|
internal override int Arity { get { return 0; } }
|
|
|
|
/// <summary>
|
|
/// Two CostantBaseOps are equivalent if they are of the same
|
|
/// derived type and have the same type and value.
|
|
/// </summary>
|
|
/// <param name="other">the other Op</param>
|
|
/// <returns>true, if these are equivalent (not a strict equality test)</returns>
|
|
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
|
|
}
|
|
|
|
/// <summary>
|
|
/// Represents an external constant
|
|
/// </summary>
|
|
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
|
|
/// <summary>
|
|
/// Pattern for transformation rules
|
|
/// </summary>
|
|
internal static readonly ConstantOp Pattern = new ConstantOp();
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method
|
|
/// </summary>
|
|
/// <param name="v">The BasicOpVisitor that is visiting this Op</param>
|
|
/// <param name="n">The Node that references this Op</param>
|
|
[DebuggerNonUserCode]
|
|
internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method for visitors with a return value
|
|
/// </summary>
|
|
/// <param name="v">The visitor</param>
|
|
/// <param name="n">The node in question</param>
|
|
/// <returns>An instance of TResultType</returns>
|
|
[DebuggerNonUserCode]
|
|
internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
|
|
|
|
#endregion
|
|
}
|
|
|
|
/// <summary>
|
|
/// Represents null constants
|
|
/// </summary>
|
|
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
|
|
|
|
/// <summary>
|
|
/// Pattern for transformation rules
|
|
/// </summary>
|
|
internal static readonly NullOp Pattern = new NullOp();
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method
|
|
/// </summary>
|
|
/// <param name="v">The BasicOpVisitor that is visiting this Op</param>
|
|
/// <param name="n">The Node that references this Op</param>
|
|
[DebuggerNonUserCode]
|
|
internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method for visitors with a return value
|
|
/// </summary>
|
|
/// <param name="v">The visitor</param>
|
|
/// <param name="n">The node in question</param>
|
|
/// <returns>An instance of TResultType</returns>
|
|
[DebuggerNonUserCode]
|
|
internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
|
|
|
|
#endregion
|
|
}
|
|
|
|
/// <summary>
|
|
/// Represents internally generated constants
|
|
/// </summary>
|
|
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
|
|
|
|
/// <summary>
|
|
/// Pattern for transformation rules
|
|
/// </summary>
|
|
internal static readonly InternalConstantOp Pattern = new InternalConstantOp();
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method
|
|
/// </summary>
|
|
/// <param name="v">The BasicOpVisitor that is visiting this Op</param>
|
|
/// <param name="n">The Node that references this Op</param>
|
|
[DebuggerNonUserCode]
|
|
internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method for visitors with a return value
|
|
/// </summary>
|
|
/// <param name="v">The visitor</param>
|
|
/// <param name="n">The node in question</param>
|
|
/// <returns>An instance of TResultType</returns>
|
|
[DebuggerNonUserCode]
|
|
internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
|
|
|
|
#endregion
|
|
}
|
|
|
|
/// <summary>
|
|
/// Represents an internally generated constant that is used to serve as a null sentinel,
|
|
/// i.e. to be checked whether it is null.
|
|
/// </summary>
|
|
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
|
|
/// <summary>
|
|
/// Pattern for transformation rules
|
|
/// </summary>
|
|
internal static readonly NullSentinelOp Pattern = new NullSentinelOp();
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method
|
|
/// </summary>
|
|
/// <param name="v">The BasicOpVisitor that is visiting this Op</param>
|
|
/// <param name="n">The Node that references this Op</param>
|
|
[DebuggerNonUserCode]
|
|
internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method for visitors with a return value
|
|
/// </summary>
|
|
/// <param name="v">The visitor</param>
|
|
/// <param name="n">The node in question</param>
|
|
/// <returns>An instance of TResultType</returns>
|
|
[DebuggerNonUserCode]
|
|
internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
|
|
|
|
#endregion
|
|
}
|
|
|
|
/// <summary>
|
|
/// Represents a constant predicate (with a value of either true or false)
|
|
/// </summary>
|
|
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
|
|
/// <summary>
|
|
/// Pattern for transformation rules
|
|
/// </summary>
|
|
internal static readonly ConstantPredicateOp Pattern = new ConstantPredicateOp();
|
|
|
|
/// <summary>
|
|
/// Value of the constant predicate
|
|
/// </summary>
|
|
internal new bool Value { get { return (bool)base.Value; } }
|
|
|
|
/// <summary>
|
|
/// Is this the true predicate
|
|
/// </summary>
|
|
internal bool IsTrue { get { return this.Value; } }
|
|
|
|
/// <summary>
|
|
/// Is this the 'false' predicate
|
|
/// </summary>
|
|
internal bool IsFalse { get { return this.Value == false; } }
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method
|
|
/// </summary>
|
|
/// <param name="v">The BasicOpVisitor that is visiting this Op</param>
|
|
/// <param name="n">The Node that references this Op</param>
|
|
[DebuggerNonUserCode]
|
|
internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method for visitors with a return value
|
|
/// </summary>
|
|
/// <param name="v">The visitor</param>
|
|
/// <param name="n">The node in question</param>
|
|
/// <returns>An instance of TResultType</returns>
|
|
[DebuggerNonUserCode]
|
|
internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
|
|
|
|
#endregion
|
|
}
|
|
|
|
#endregion
|
|
|
|
/// <summary>
|
|
/// A reference to an existing variable
|
|
/// </summary>
|
|
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
|
|
/// <summary>
|
|
/// Singleton used for pattern matching
|
|
/// </summary>
|
|
internal static readonly VarRefOp Pattern = new VarRefOp();
|
|
|
|
/// <summary>
|
|
/// 0 children
|
|
/// </summary>
|
|
internal override int Arity { get { return 0; } }
|
|
|
|
/// <summary>
|
|
/// Two VarRefOps are equivalent, if they reference the same Var
|
|
/// </summary>
|
|
/// <param name="other">the other Op</param>
|
|
/// <returns>true, if these are equivalent</returns>
|
|
internal override bool IsEquivalent(Op other)
|
|
{
|
|
VarRefOp otherVarRef = other as VarRefOp;
|
|
return (otherVarRef != null && otherVarRef.Var.Equals(this.Var));
|
|
}
|
|
|
|
/// <summary>
|
|
/// The Var that this Op is referencing
|
|
/// </summary>
|
|
internal Var Var { get { return m_var; } }
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method
|
|
/// </summary>
|
|
/// <param name="v">The BasicOpVisitor that is visiting this Op</param>
|
|
/// <param name="n">The Node that references this Op</param>
|
|
[DebuggerNonUserCode]
|
|
internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method for visitors with a return value
|
|
/// </summary>
|
|
/// <param name="v">The visitor</param>
|
|
/// <param name="n">The node in question</param>
|
|
/// <returns>An instance of TResultType</returns>
|
|
[DebuggerNonUserCode]
|
|
internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
|
|
#endregion
|
|
}
|
|
|
|
/// <summary>
|
|
/// Represents an arbitrary function call
|
|
/// </summary>
|
|
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
|
|
/// <summary>
|
|
/// Singleton instance used for patterns in transformation rules
|
|
/// </summary>
|
|
internal static readonly FunctionOp Pattern = new FunctionOp();
|
|
|
|
/// <summary>
|
|
/// The function that's being invoked
|
|
/// </summary>
|
|
internal EdmFunction Function { get { return m_function; } }
|
|
|
|
/// <summary>
|
|
/// Two FunctionOps are equivalent if they reference the same EdmFunction
|
|
/// </summary>
|
|
/// <param name="other">the other Op</param>
|
|
/// <returns>true, if these are equivalent</returns>
|
|
internal override bool IsEquivalent(Op other)
|
|
{
|
|
FunctionOp otherFunctionOp = other as FunctionOp;
|
|
return (otherFunctionOp != null && otherFunctionOp.Function.EdmEquals(this.Function));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method
|
|
/// </summary>
|
|
/// <param name="v">The BasicOpVisitor that is visiting this Op</param>
|
|
/// <param name="n">The Node that references this Op</param>
|
|
[DebuggerNonUserCode]
|
|
internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method for visitors with a return value
|
|
/// </summary>
|
|
/// <param name="v">The visitor</param>
|
|
/// <param name="n">The node in question</param>
|
|
/// <returns>An instance of TResultType</returns>
|
|
[DebuggerNonUserCode]
|
|
internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
|
|
#endregion
|
|
}
|
|
|
|
/// <summary>
|
|
/// Represents a property access
|
|
/// </summary>
|
|
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
|
|
/// <summary>
|
|
/// Used for patterns in transformation rules
|
|
/// </summary>
|
|
internal static readonly PropertyOp Pattern = new PropertyOp();
|
|
|
|
/// <summary>
|
|
/// 1 child - the instance
|
|
/// </summary>
|
|
internal override int Arity { get { return 1; } }
|
|
|
|
/// <summary>
|
|
/// The property metadata
|
|
/// </summary>
|
|
internal EdmMember PropertyInfo { get { return m_property; } }
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method
|
|
/// </summary>
|
|
/// <param name="v">The BasicOpVisitor that is visiting this Op</param>
|
|
/// <param name="n">The Node that references this Op</param>
|
|
[DebuggerNonUserCode]
|
|
internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method for visitors with a return value
|
|
/// </summary>
|
|
/// <param name="v">The visitor</param>
|
|
/// <param name="n">The node in question</param>
|
|
/// <returns>An instance of TResultType</returns>
|
|
[DebuggerNonUserCode]
|
|
internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
|
|
#endregion
|
|
}
|
|
|
|
/// <summary>
|
|
/// Represents a TREAT AS operation
|
|
/// </summary>
|
|
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
|
|
/// <summary>
|
|
/// Used as patterns in transformation rules
|
|
/// </summary>
|
|
internal static readonly TreatOp Pattern = new TreatOp();
|
|
|
|
/// <summary>
|
|
/// 1 child - instance
|
|
/// </summary>
|
|
internal override int Arity { get { return 1; } }
|
|
|
|
/// <summary>
|
|
/// Is this a "fake" treat?
|
|
/// </summary>
|
|
internal bool IsFakeTreat { get { return m_isFake; } }
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method
|
|
/// </summary>
|
|
/// <param name="v">The BasicOpVisitor that is visiting this Op</param>
|
|
/// <param name="n">The Node that references this Op</param>
|
|
[DebuggerNonUserCode]
|
|
internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method for visitors with a return value
|
|
/// </summary>
|
|
/// <param name="v">The visitor</param>
|
|
/// <param name="n">The node in question</param>
|
|
/// <returns>An instance of TResultType</returns>
|
|
[DebuggerNonUserCode]
|
|
internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
|
|
#endregion
|
|
}
|
|
|
|
/// <summary>
|
|
/// An IS OF operation
|
|
/// </summary>
|
|
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
|
|
/// <summary>
|
|
/// Pattern used for transformation rules
|
|
/// </summary>
|
|
internal static readonly IsOfOp Pattern = new IsOfOp();
|
|
|
|
/// <summary>
|
|
/// 1 child - instance
|
|
/// </summary>
|
|
internal override int Arity { get { return 1; } }
|
|
|
|
/// <summary>
|
|
/// The type being checked for
|
|
/// </summary>
|
|
internal TypeUsage IsOfType { get { return m_isOfType; } }
|
|
|
|
internal bool IsOfOnly { get { return m_isOfOnly; } }
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method
|
|
/// </summary>
|
|
/// <param name="v">The BasicOpVisitor that is visiting this Op</param>
|
|
/// <param name="n">The Node that references this Op</param>
|
|
[DebuggerNonUserCode]
|
|
internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method for visitors with a return value
|
|
/// </summary>
|
|
/// <param name="v">The visitor</param>
|
|
/// <param name="n">The node in question</param>
|
|
/// <returns>An instance of TResultType</returns>
|
|
[DebuggerNonUserCode]
|
|
internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
|
|
#endregion
|
|
}
|
|
|
|
/// <summary>
|
|
/// Cast operation. Convert a type instance into an instance of another type
|
|
/// </summary>
|
|
internal sealed class CastOp : ScalarOp
|
|
{
|
|
#region constructors
|
|
internal CastOp(TypeUsage type) : base(OpType.Cast, type) { }
|
|
private CastOp() : base(OpType.Cast) { }
|
|
#endregion
|
|
|
|
#region public methods
|
|
/// <summary>
|
|
/// Pattern for transformation rules
|
|
/// </summary>
|
|
internal static readonly CastOp Pattern = new CastOp();
|
|
|
|
/// <summary>
|
|
/// 1 child - instance
|
|
/// </summary>
|
|
internal override int Arity { get { return 1; } }
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method
|
|
/// </summary>
|
|
/// <param name="v">The BasicOpVisitor that is visiting this Op</param>
|
|
/// <param name="n">The Node that references this Op</param>
|
|
[DebuggerNonUserCode]
|
|
internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method for visitors with a return value
|
|
/// </summary>
|
|
/// <param name="v">The visitor</param>
|
|
/// <param name="n">The node in question</param>
|
|
/// <returns>An instance of TResultType</returns>
|
|
[DebuggerNonUserCode]
|
|
internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
|
|
#endregion
|
|
}
|
|
|
|
/// <summary>
|
|
/// 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
|
|
///
|
|
/// </summary>
|
|
internal sealed class SoftCastOp : ScalarOp
|
|
{
|
|
#region constructors
|
|
internal SoftCastOp(TypeUsage type) : base(OpType.SoftCast, type) { }
|
|
private SoftCastOp() : base(OpType.SoftCast) { }
|
|
#endregion
|
|
|
|
#region public methods
|
|
/// <summary>
|
|
/// Pattern for transformation rules
|
|
/// </summary>
|
|
internal static readonly SoftCastOp Pattern = new SoftCastOp();
|
|
|
|
/// <summary>
|
|
/// 1 child - input expression
|
|
/// </summary>
|
|
internal override int Arity { get { return 1; } }
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method
|
|
/// </summary>
|
|
/// <param name="v">The BasicOpVisitor that is visiting this Op</param>
|
|
/// <param name="n">The Node that references this Op</param>
|
|
[DebuggerNonUserCode]
|
|
internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method for visitors with a return value
|
|
/// </summary>
|
|
/// <param name="v">The visitor</param>
|
|
/// <param name="n">The node in question</param>
|
|
/// <returns>An instance of TResultType</returns>
|
|
[DebuggerNonUserCode]
|
|
internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
|
|
#endregion
|
|
}
|
|
|
|
/// <summary>
|
|
/// Represents a comparision operation (LT, GT etc.)
|
|
/// </summary>
|
|
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
|
|
/// <summary>
|
|
/// Patterns for use in transformation rules
|
|
/// </summary>
|
|
internal static readonly ComparisonOp PatternEq = new ComparisonOp(OpType.EQ);
|
|
|
|
/// <summary>
|
|
/// 2 children - left, right
|
|
/// </summary>
|
|
internal override int Arity { get { return 2; } }
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method
|
|
/// </summary>
|
|
/// <param name="v">The BasicOpVisitor that is visiting this Op</param>
|
|
/// <param name="n">The Node that references this Op</param>
|
|
[DebuggerNonUserCode]
|
|
internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method for visitors with a return value
|
|
/// </summary>
|
|
/// <param name="v">The visitor</param>
|
|
/// <param name="n">The node in question</param>
|
|
/// <returns>An instance of TResultType</returns>
|
|
[DebuggerNonUserCode]
|
|
internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
|
|
#endregion
|
|
}
|
|
|
|
/// <summary>
|
|
/// Represents a string comparison operation
|
|
/// </summary>
|
|
internal sealed class LikeOp : ScalarOp
|
|
{
|
|
#region constructors
|
|
internal LikeOp(TypeUsage boolType)
|
|
: base(OpType.Like, boolType) { }
|
|
private LikeOp() : base(OpType.Like) { }
|
|
#endregion
|
|
|
|
#region public surface
|
|
/// <summary>
|
|
/// Pattern for use in transformation rules
|
|
/// </summary>
|
|
internal static readonly LikeOp Pattern = new LikeOp();
|
|
|
|
/// <summary>
|
|
/// 3 children - string, pattern , escape
|
|
/// </summary>
|
|
internal override int Arity { get { return 3; } }
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method
|
|
/// </summary>
|
|
/// <param name="v">The BasicOpVisitor that is visiting this Op</param>
|
|
/// <param name="n">The Node that references this Op</param>
|
|
[DebuggerNonUserCode]
|
|
internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method for visitors with a return value
|
|
/// </summary>
|
|
/// <param name="v">The visitor</param>
|
|
/// <param name="n">The node in question</param>
|
|
/// <returns>An instance of TResultType</returns>
|
|
[DebuggerNonUserCode]
|
|
internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
|
|
#endregion
|
|
}
|
|
|
|
/// <summary>
|
|
/// 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?
|
|
/// </summary>
|
|
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
|
|
/// <summary>
|
|
/// Patterns for use in transformation rules
|
|
/// </summary>
|
|
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);
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method
|
|
/// </summary>
|
|
/// <param name="v">The BasicOpVisitor that is visiting this Op</param>
|
|
/// <param name="n">The Node that references this Op</param>
|
|
[DebuggerNonUserCode]
|
|
internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method for visitors with a return value
|
|
/// </summary>
|
|
/// <param name="v">The visitor</param>
|
|
/// <param name="n">The node in question</param>
|
|
/// <returns>An instance of TResultType</returns>
|
|
[DebuggerNonUserCode]
|
|
internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
|
|
#endregion
|
|
}
|
|
|
|
/// <summary>
|
|
/// ANSI switched Case expression.
|
|
/// </summary>
|
|
internal sealed class CaseOp : ScalarOp
|
|
{
|
|
#region constructors
|
|
internal CaseOp(TypeUsage type) : base(OpType.Case, type) { }
|
|
private CaseOp() : base(OpType.Case) { }
|
|
#endregion
|
|
|
|
#region public methods
|
|
/// <summary>
|
|
/// Pattern for use in transformation rules
|
|
/// </summary>
|
|
internal static readonly CaseOp Pattern = new CaseOp();
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method
|
|
/// </summary>
|
|
/// <param name="v">The BasicOpVisitor that is visiting this Op</param>
|
|
/// <param name="n">The Node that references this Op</param>
|
|
[DebuggerNonUserCode]
|
|
internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method for visitors with a return value
|
|
/// </summary>
|
|
/// <param name="v">The visitor</param>
|
|
/// <param name="n">The node in question</param>
|
|
/// <returns>An instance of TResultType</returns>
|
|
[DebuggerNonUserCode]
|
|
internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
|
|
#endregion
|
|
}
|
|
|
|
/// <summary>
|
|
/// Basic Aggregates
|
|
/// </summary>
|
|
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
|
|
/// <summary>
|
|
/// Pattern for transformation rules
|
|
/// </summary>
|
|
internal static readonly AggregateOp Pattern = new AggregateOp();
|
|
|
|
/// <summary>
|
|
/// The Aggregate function's metadata
|
|
/// </summary>
|
|
internal EdmFunction AggFunc { get { return m_aggFunc; } }
|
|
|
|
/// <summary>
|
|
/// Is this a "distinct" aggregate
|
|
/// </summary>
|
|
internal bool IsDistinctAggregate { get { return m_distinctAgg; } }
|
|
|
|
/// <summary>
|
|
/// Yes; this is an aggregate
|
|
/// </summary>
|
|
internal override bool IsAggregateOp {get{return true;}}
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method
|
|
/// </summary>
|
|
/// <param name="v">The BasicOpVisitor that is visiting this Op</param>
|
|
/// <param name="n">The Node that references this Op</param>
|
|
[DebuggerNonUserCode]
|
|
internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method for visitors with a return value
|
|
/// </summary>
|
|
/// <param name="v">The visitor</param>
|
|
/// <param name="n">The node in question</param>
|
|
/// <returns>An instance of TResultType</returns>
|
|
[DebuggerNonUserCode]
|
|
internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
|
|
#endregion
|
|
}
|
|
|
|
/// <summary>
|
|
/// Represents an arbitrary nest operation - can be used anywhere
|
|
/// </summary>
|
|
internal sealed class CollectOp : ScalarOp
|
|
{
|
|
#region constructors
|
|
internal CollectOp(TypeUsage type) : base(OpType.Collect, type) { }
|
|
private CollectOp() : base(OpType.Collect) { }
|
|
#endregion
|
|
|
|
#region public methods
|
|
/// <summary>
|
|
/// Pattern for use in transformation rules
|
|
/// </summary>
|
|
internal static readonly CollectOp Pattern = new CollectOp();
|
|
|
|
/// <summary>
|
|
/// 1 child - instance
|
|
/// </summary>
|
|
internal override int Arity { get { return 1; } }
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method
|
|
/// </summary>
|
|
/// <param name="v">The BasicOpVisitor that is visiting this Op</param>
|
|
/// <param name="n">The Node that references this Op</param>
|
|
[DebuggerNonUserCode]
|
|
internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method for visitors with a return value
|
|
/// </summary>
|
|
/// <param name="v">The visitor</param>
|
|
/// <param name="n">The node in question</param>
|
|
/// <returns>An instance of TResultType</returns>
|
|
[DebuggerNonUserCode]
|
|
internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
|
|
#endregion
|
|
}
|
|
|
|
/// <summary>
|
|
/// Almost identical to a PropertyOp - the only difference being that we're dealing with an
|
|
/// "extended" property (a rel property) this time
|
|
/// </summary>
|
|
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
|
|
/// <summary>
|
|
/// Pattern for transformation rules
|
|
/// </summary>
|
|
internal static readonly RelPropertyOp Pattern = new RelPropertyOp();
|
|
|
|
/// <summary>
|
|
/// 1 child - the entity instance
|
|
/// </summary>
|
|
internal override int Arity { get { return 1; } }
|
|
|
|
/// <summary>
|
|
/// Get the property metadata
|
|
/// </summary>
|
|
public RelProperty PropertyInfo { get { return m_property; } }
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method
|
|
/// </summary>
|
|
/// <param name="v">The BasicOpVisitor that is visiting this Op</param>
|
|
/// <param name="n">The Node that references this Op</param>
|
|
[DebuggerNonUserCode]
|
|
internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method for visitors with a return value
|
|
/// </summary>
|
|
/// <param name="v">The visitor</param>
|
|
/// <param name="n">The node in question</param>
|
|
/// <returns>An instance of TResultType</returns>
|
|
[DebuggerNonUserCode]
|
|
internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
|
|
|
|
#endregion
|
|
}
|
|
|
|
/// <summary>
|
|
/// Base class for DiscriminatedNewEntityOp and NewEntityOp
|
|
/// </summary>
|
|
internal abstract class NewEntityBaseOp : ScalarOp
|
|
{
|
|
#region private state
|
|
private readonly bool m_scoped;
|
|
private readonly EntitySet m_entitySet;
|
|
private readonly List<RelProperty> 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<RelProperty> 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
|
|
/// <summary>
|
|
/// 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.
|
|
/// </summary>
|
|
internal bool Scoped { get { return m_scoped; } }
|
|
|
|
/// <summary>
|
|
/// Get the entityset (if any) associated with this constructor
|
|
/// </summary>
|
|
internal EntitySet EntitySet { get { return m_entitySet; } }
|
|
|
|
/// <summary>
|
|
/// get the list of relationship properties (if any) specified for this constructor
|
|
/// </summary>
|
|
internal List<RelProperty> RelationshipProperties { get { return m_relProperties; } }
|
|
#endregion
|
|
}
|
|
|
|
/// <summary>
|
|
/// A new entity instance constructor
|
|
/// </summary>
|
|
internal sealed class NewEntityOp : NewEntityBaseOp
|
|
{
|
|
#region constructors
|
|
private NewEntityOp() : base(OpType.NewEntity) { }
|
|
|
|
internal NewEntityOp(TypeUsage type, List<RelProperty> relProperties, bool scoped, EntitySet entitySet)
|
|
: base(OpType.NewEntity, type, scoped, entitySet, relProperties)
|
|
{
|
|
}
|
|
#endregion
|
|
|
|
#region public methods
|
|
/// <summary>
|
|
/// Pattern for transformation rules
|
|
/// </summary>
|
|
internal static readonly NewEntityOp Pattern = new NewEntityOp();
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method
|
|
/// </summary>
|
|
/// <param name="v">The BasicOpVisitor that is visiting this Op</param>
|
|
/// <param name="n">The Node that references this Op</param>
|
|
[DebuggerNonUserCode]
|
|
internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method for visitors with a return value
|
|
/// </summary>
|
|
/// <param name="v">The visitor</param>
|
|
/// <param name="n">The node in question</param>
|
|
/// <returns>An instance of TResultType</returns>
|
|
[DebuggerNonUserCode]
|
|
internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
|
|
#endregion
|
|
}
|
|
|
|
/// <summary>
|
|
/// A new instance creation
|
|
/// </summary>
|
|
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
|
|
/// <summary>
|
|
/// Pattern for transformation rules
|
|
/// </summary>
|
|
internal static readonly NewInstanceOp Pattern = new NewInstanceOp();
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method
|
|
/// </summary>
|
|
/// <param name="v">The BasicOpVisitor that is visiting this Op</param>
|
|
/// <param name="n">The Node that references this Op</param>
|
|
[DebuggerNonUserCode]
|
|
internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method for visitors with a return value
|
|
/// </summary>
|
|
/// <param name="v">The visitor</param>
|
|
/// <param name="n">The node in question</param>
|
|
/// <returns>An instance of TResultType</returns>
|
|
[DebuggerNonUserCode]
|
|
internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
|
|
#endregion
|
|
}
|
|
|
|
/// <summary>
|
|
/// Polymorphic new instance creation (takes all properties of all types in the hierarchy + discriminator)
|
|
/// </summary>
|
|
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<RelProperty> 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();
|
|
|
|
/// <summary>
|
|
/// Gets discriminator and type information used in construction of type.
|
|
/// </summary>
|
|
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<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
|
|
#endregion
|
|
}
|
|
|
|
/// <summary>
|
|
/// Represents a new record constructor
|
|
/// </summary>
|
|
internal sealed class NewRecordOp : ScalarOp
|
|
{
|
|
#region private state
|
|
private List<EdmProperty> m_fields; // list of fields with specified values
|
|
#endregion
|
|
|
|
#region constructors
|
|
/// <summary>
|
|
/// Basic constructor. All fields have a value specified
|
|
/// </summary>
|
|
/// <param name="type"></param>
|
|
internal NewRecordOp(TypeUsage type) : base(OpType.NewRecord, type)
|
|
{
|
|
m_fields = new List<EdmProperty>(TypeHelpers.GetEdmType<RowType>(type).Properties);
|
|
}
|
|
/// <summary>
|
|
/// 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"
|
|
/// </summary>
|
|
/// <param name="type"></param>
|
|
/// <param name="fields"></param>
|
|
internal NewRecordOp(TypeUsage type, List<EdmProperty> 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
|
|
/// <summary>
|
|
/// Pattern for transformation rules
|
|
/// </summary>
|
|
internal static readonly NewRecordOp Pattern = new NewRecordOp();
|
|
|
|
/// <summary>
|
|
/// 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
|
|
/// </summary>
|
|
/// <param name="field"></param>
|
|
/// <param name="fieldPosition"></param>
|
|
/// <returns></returns>
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// List of all properties that have values specified
|
|
/// </summary>
|
|
internal List<EdmProperty> Properties { get { return m_fields; } }
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method
|
|
/// </summary>
|
|
/// <param name="v">The BasicOpVisitor that is visiting this Op</param>
|
|
/// <param name="n">The Node that references this Op</param>
|
|
[DebuggerNonUserCode]
|
|
internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method for visitors with a return value
|
|
/// </summary>
|
|
/// <param name="v">The visitor</param>
|
|
/// <param name="n">The node in question</param>
|
|
/// <returns>An instance of TResultType</returns>
|
|
[DebuggerNonUserCode]
|
|
internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> 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
|
|
/// <summary>
|
|
/// Pattern for transformation rules
|
|
/// </summary>
|
|
internal static readonly NewMultisetOp Pattern = new NewMultisetOp();
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method
|
|
/// </summary>
|
|
/// <param name="v">The BasicOpVisitor that is visiting this Op</param>
|
|
/// <param name="n">The Node that references this Op</param>
|
|
[DebuggerNonUserCode]
|
|
internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method for visitors with a return value
|
|
/// </summary>
|
|
/// <param name="v">The visitor</param>
|
|
/// <param name="n">The node in question</param>
|
|
/// <returns>An instance of TResultType</returns>
|
|
[DebuggerNonUserCode]
|
|
internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
|
|
#endregion
|
|
}
|
|
|
|
/// <summary>
|
|
/// Represents arithmetic operators - Plus,Minus,Multiply,Divide,Modulo,UnaryMinus
|
|
/// </summary>
|
|
internal sealed class ArithmeticOp : ScalarOp
|
|
{
|
|
#region constructors
|
|
internal ArithmeticOp(OpType opType, TypeUsage type)
|
|
: base(opType, type) { }
|
|
#endregion
|
|
|
|
#region public methods
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method
|
|
/// </summary>
|
|
/// <param name="v">The BasicOpVisitor that is visiting this Op</param>
|
|
/// <param name="n">The Node that references this Op</param>
|
|
[DebuggerNonUserCode]
|
|
internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method for visitors with a return value
|
|
/// </summary>
|
|
/// <param name="v">The visitor</param>
|
|
/// <param name="n">The node in question</param>
|
|
/// <returns>An instance of TResultType</returns>
|
|
[DebuggerNonUserCode]
|
|
internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
|
|
#endregion
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
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
|
|
/// <summary>
|
|
/// Pattern for transformation rules
|
|
/// </summary>
|
|
internal static readonly RefOp Pattern = new RefOp();
|
|
|
|
/// <summary>
|
|
/// 1 child - key
|
|
/// </summary>
|
|
internal override int Arity { get { return 1; } }
|
|
|
|
/// <summary>
|
|
/// The EntitySet to which the reference refers
|
|
/// </summary>
|
|
internal EntitySet EntitySet { get { return m_entitySet; } }
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method
|
|
/// </summary>
|
|
/// <param name="v">The BasicOpVisitor that is visiting this Op</param>
|
|
/// <param name="n">The Node that references this Op</param>
|
|
[DebuggerNonUserCode]
|
|
internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method for visitors with a return value
|
|
/// </summary>
|
|
/// <param name="v">The visitor</param>
|
|
/// <param name="n">The node in question</param>
|
|
/// <returns>An instance of TResultType</returns>
|
|
[DebuggerNonUserCode]
|
|
internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
|
|
#endregion
|
|
}
|
|
|
|
/// <summary>
|
|
/// Represents an EXISTS subquery?
|
|
/// </summary>
|
|
internal sealed class ExistsOp : ScalarOp
|
|
{
|
|
#region constructors
|
|
internal ExistsOp(TypeUsage type)
|
|
: base(OpType.Exists, type)
|
|
{
|
|
}
|
|
private ExistsOp() : base(OpType.Exists) { }
|
|
#endregion
|
|
|
|
#region public methods
|
|
/// <summary>
|
|
/// Pattern for transformation rules
|
|
/// </summary>
|
|
internal static readonly ExistsOp Pattern = new ExistsOp();
|
|
|
|
/// <summary>
|
|
/// 1 child - collection input
|
|
/// </summary>
|
|
internal override int Arity { get { return 1; } }
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method
|
|
/// </summary>
|
|
/// <param name="v">The BasicOpVisitor that is visiting this Op</param>
|
|
/// <param name="n">The Node that references this Op</param>
|
|
[DebuggerNonUserCode]
|
|
internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method for visitors with a return value
|
|
/// </summary>
|
|
/// <param name="v">The visitor</param>
|
|
/// <param name="n">The node in question</param>
|
|
/// <returns>An instance of TResultType</returns>
|
|
[DebuggerNonUserCode]
|
|
internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
|
|
#endregion
|
|
}
|
|
|
|
/// <summary>
|
|
/// Represents an Element() op - extracts the scalar value from a collection
|
|
/// </summary>
|
|
internal sealed class ElementOp : ScalarOp
|
|
{
|
|
#region constructors
|
|
internal ElementOp(TypeUsage type) : base(OpType.Element, type) { }
|
|
private ElementOp() : base(OpType.Element) { }
|
|
#endregion
|
|
|
|
#region public methods
|
|
/// <summary>
|
|
/// Pattern for transformation rules
|
|
/// </summary>
|
|
internal static readonly ElementOp Pattern = new ElementOp();
|
|
|
|
/// <summary>
|
|
/// 1 child - collection instance
|
|
/// </summary>
|
|
internal override int Arity { get { return 1; } }
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method
|
|
/// </summary>
|
|
/// <param name="v">The BasicOpVisitor that is visiting this Op</param>
|
|
/// <param name="n">The Node that references this Op</param>
|
|
[DebuggerNonUserCode]
|
|
internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method for visitors with a return value
|
|
/// </summary>
|
|
/// <param name="v">The visitor</param>
|
|
/// <param name="n">The node in question</param>
|
|
/// <returns>An instance of TResultType</returns>
|
|
[DebuggerNonUserCode]
|
|
internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
|
|
#endregion
|
|
}
|
|
|
|
/// <summary>
|
|
/// extracts the key from a ref
|
|
/// </summary>
|
|
internal sealed class GetRefKeyOp : ScalarOp
|
|
{
|
|
#region constructors
|
|
internal GetRefKeyOp(TypeUsage type) : base(OpType.GetRefKey, type) { }
|
|
private GetRefKeyOp() : base(OpType.GetRefKey) { }
|
|
#endregion
|
|
|
|
#region public methods
|
|
/// <summary>
|
|
/// Pattern for transformation rules
|
|
/// </summary>
|
|
internal static readonly GetRefKeyOp Pattern = new GetRefKeyOp();
|
|
|
|
/// <summary>
|
|
/// 1 child - ref instance
|
|
/// </summary>
|
|
internal override int Arity { get { return 1; } }
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method
|
|
/// </summary>
|
|
/// <param name="v">The BasicOpVisitor that is visiting this Op</param>
|
|
/// <param name="n">The Node that references this Op</param>
|
|
[DebuggerNonUserCode]
|
|
internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method for visitors with a return value
|
|
/// </summary>
|
|
/// <param name="v">The visitor</param>
|
|
/// <param name="n">The node in question</param>
|
|
/// <returns>An instance of TResultType</returns>
|
|
[DebuggerNonUserCode]
|
|
internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
|
|
#endregion
|
|
}
|
|
|
|
/// <summary>
|
|
/// Extracts the ref from an entity instance
|
|
/// </summary>
|
|
internal sealed class GetEntityRefOp : ScalarOp
|
|
{
|
|
#region constructors
|
|
internal GetEntityRefOp(TypeUsage type) : base(OpType.GetEntityRef, type) { }
|
|
private GetEntityRefOp() : base(OpType.GetEntityRef) { }
|
|
#endregion
|
|
|
|
#region public methods
|
|
/// <summary>
|
|
/// Pattern for transformation rules
|
|
/// </summary>
|
|
internal static readonly GetEntityRefOp Pattern = new GetEntityRefOp();
|
|
|
|
/// <summary>
|
|
/// 1 child - entity instance
|
|
/// </summary>
|
|
internal override int Arity { get { return 1; } }
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method
|
|
/// </summary>
|
|
/// <param name="v">The BasicOpVisitor that is visiting this Op</param>
|
|
/// <param name="n">The Node that references this Op</param>
|
|
[DebuggerNonUserCode]
|
|
internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method for visitors with a return value
|
|
/// </summary>
|
|
/// <param name="v">The visitor</param>
|
|
/// <param name="n">The node in question</param>
|
|
/// <returns>An instance of TResultType</returns>
|
|
[DebuggerNonUserCode]
|
|
internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
|
|
#endregion
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the target entity pointed at by a reference
|
|
/// </summary>
|
|
internal sealed class DerefOp : ScalarOp
|
|
{
|
|
#region constructors
|
|
internal DerefOp(TypeUsage type) : base(OpType.Deref, type) { }
|
|
private DerefOp() : base(OpType.Deref) { }
|
|
#endregion
|
|
|
|
#region public methods
|
|
/// <summary>
|
|
/// Pattern for transformation rules
|
|
/// </summary>
|
|
internal static readonly DerefOp Pattern = new DerefOp();
|
|
|
|
/// <summary>
|
|
/// 1 child - entity instance
|
|
/// </summary>
|
|
internal override int Arity { get { return 1; } }
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method
|
|
/// </summary>
|
|
/// <param name="v">The BasicOpVisitor that is visiting this Op</param>
|
|
/// <param name="n">The Node that references this Op</param>
|
|
[DebuggerNonUserCode]
|
|
internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method for visitors with a return value
|
|
/// </summary>
|
|
/// <param name="v">The visitor</param>
|
|
/// <param name="n">The node in question</param>
|
|
/// <returns>An instance of TResultType</returns>
|
|
[DebuggerNonUserCode]
|
|
internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
|
|
#endregion
|
|
}
|
|
|
|
/// <summary>
|
|
/// Navigate a relationship, and get the reference(s) of the target end
|
|
/// </summary>
|
|
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
|
|
/// <summary>
|
|
/// Pattern for transformation rules
|
|
/// </summary>
|
|
internal static readonly NavigateOp Pattern = new NavigateOp();
|
|
|
|
/// <summary>
|
|
/// 1 child - entity instance
|
|
/// </summary>
|
|
internal override int Arity { get { return 1; } }
|
|
|
|
/// <summary>
|
|
/// The rel property that describes this nvaigation
|
|
/// </summary>
|
|
internal RelProperty RelProperty { get { return m_property; } }
|
|
|
|
/// <summary>
|
|
/// The relationship we're traversing
|
|
/// </summary>
|
|
internal RelationshipType Relationship { get { return m_property.Relationship; } }
|
|
/// <summary>
|
|
/// The starting point of the traversal
|
|
/// </summary>
|
|
internal RelationshipEndMember FromEnd { get { return m_property.FromEnd; } }
|
|
/// <summary>
|
|
/// The end-point of the traversal
|
|
/// </summary>
|
|
internal RelationshipEndMember ToEnd { get { return m_property.ToEnd; } }
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method
|
|
/// </summary>
|
|
/// <param name="v">The BasicOpVisitor that is visiting this Op</param>
|
|
/// <param name="n">The Node that references this Op</param>
|
|
[DebuggerNonUserCode]
|
|
internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
|
|
|
|
/// <summary>
|
|
/// Visitor pattern method for visitors with a return value
|
|
/// </summary>
|
|
/// <param name="v">The visitor</param>
|
|
/// <param name="n">The node in question</param>
|
|
/// <returns>An instance of TResultType</returns>
|
|
[DebuggerNonUserCode]
|
|
internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
|
|
#endregion
|
|
}
|
|
}
|