1 //---------------------------------------------------------------------
2 // <copyright file="ScalarOps.cs" company="Microsoft">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
7 // @backupOwner Microsoft
8 //---------------------------------------------------------------------
11 using System.Collections.Generic;
12 using System.Globalization;
13 using System.Diagnostics;
14 using System.Data.Common;
15 using System.Data.Metadata.Edm;
17 namespace System.Data.Query.InternalTrees
22 /// Base class for all constant Ops
24 internal abstract class ConstantBaseOp : ScalarOp
27 private readonly object m_value;
31 protected ConstantBaseOp(OpType opType, TypeUsage type, object value)
38 /// Constructor overload for rules
40 /// <param name="opType"></param>
41 protected ConstantBaseOp(OpType opType)
47 #region public properties and methods
49 /// Get the constant value
51 internal virtual Object Value { get { return m_value; } }
56 internal override int Arity { get { return 0; } }
59 /// Two CostantBaseOps are equivalent if they are of the same
60 /// derived type and have the same type and value.
62 /// <param name="other">the other Op</param>
63 /// <returns>true, if these are equivalent (not a strict equality test)</returns>
64 internal override bool IsEquivalent(Op other)
66 ConstantBaseOp otherConstant = other as ConstantBaseOp;
68 otherConstant != null &&
69 this.OpType == other.OpType &&
70 otherConstant.Type.EdmEquals(this.Type) &&
71 ((otherConstant.Value == null && this.Value == null) || otherConstant.Value.Equals(this.Value));
77 /// Represents an external constant
79 internal sealed class ConstantOp : ConstantBaseOp
82 internal ConstantOp(TypeUsage type, object value)
83 : base(OpType.Constant, type, value)
85 Debug.Assert(value != null, "ConstantOp with a null value?");
87 private ConstantOp() : base(OpType.Constant) { }
90 #region public methods
92 /// Pattern for transformation rules
94 internal static readonly ConstantOp Pattern = new ConstantOp();
97 /// Visitor pattern method
99 /// <param name="v">The BasicOpVisitor that is visiting this Op</param>
100 /// <param name="n">The Node that references this Op</param>
101 [DebuggerNonUserCode]
102 internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
105 /// Visitor pattern method for visitors with a return value
107 /// <param name="v">The visitor</param>
108 /// <param name="n">The node in question</param>
109 /// <returns>An instance of TResultType</returns>
110 [DebuggerNonUserCode]
111 internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
117 /// Represents null constants
119 internal sealed class NullOp : ConstantBaseOp
122 internal NullOp(TypeUsage type)
123 : base(OpType.Null, type, null)
126 private NullOp() : base(OpType.Null) { }
132 /// Pattern for transformation rules
134 internal static readonly NullOp Pattern = new NullOp();
137 /// Visitor pattern method
139 /// <param name="v">The BasicOpVisitor that is visiting this Op</param>
140 /// <param name="n">The Node that references this Op</param>
141 [DebuggerNonUserCode]
142 internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
145 /// Visitor pattern method for visitors with a return value
147 /// <param name="v">The visitor</param>
148 /// <param name="n">The node in question</param>
149 /// <returns>An instance of TResultType</returns>
150 [DebuggerNonUserCode]
151 internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
157 /// Represents internally generated constants
159 internal sealed class InternalConstantOp : ConstantBaseOp
162 internal InternalConstantOp(TypeUsage type, object value)
163 : base(OpType.InternalConstant, type, value)
165 Debug.Assert(value != null, "InternalConstantOp with a null value?");
167 private InternalConstantOp() : base(OpType.InternalConstant) { }
173 /// Pattern for transformation rules
175 internal static readonly InternalConstantOp Pattern = new InternalConstantOp();
178 /// Visitor pattern method
180 /// <param name="v">The BasicOpVisitor that is visiting this Op</param>
181 /// <param name="n">The Node that references this Op</param>
182 [DebuggerNonUserCode]
183 internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
186 /// Visitor pattern method for visitors with a return value
188 /// <param name="v">The visitor</param>
189 /// <param name="n">The node in question</param>
190 /// <returns>An instance of TResultType</returns>
191 [DebuggerNonUserCode]
192 internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
198 /// Represents an internally generated constant that is used to serve as a null sentinel,
199 /// i.e. to be checked whether it is null.
201 internal sealed class NullSentinelOp : ConstantBaseOp
204 internal NullSentinelOp(TypeUsage type, object value)
205 : base(OpType.NullSentinel, type, value)
208 private NullSentinelOp() : base(OpType.NullSentinel) { }
213 /// Pattern for transformation rules
215 internal static readonly NullSentinelOp Pattern = new NullSentinelOp();
218 /// Visitor pattern method
220 /// <param name="v">The BasicOpVisitor that is visiting this Op</param>
221 /// <param name="n">The Node that references this Op</param>
222 [DebuggerNonUserCode]
223 internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
226 /// Visitor pattern method for visitors with a return value
228 /// <param name="v">The visitor</param>
229 /// <param name="n">The node in question</param>
230 /// <returns>An instance of TResultType</returns>
231 [DebuggerNonUserCode]
232 internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
238 /// Represents a constant predicate (with a value of either true or false)
240 internal sealed class ConstantPredicateOp : ConstantBaseOp
243 internal ConstantPredicateOp(TypeUsage type, bool value)
244 : base(OpType.ConstantPredicate, type, value)
247 private ConstantPredicateOp()
248 : base(OpType.ConstantPredicate)
252 #region public methods
254 /// Pattern for transformation rules
256 internal static readonly ConstantPredicateOp Pattern = new ConstantPredicateOp();
259 /// Value of the constant predicate
261 internal new bool Value { get { return (bool)base.Value; } }
264 /// Is this the true predicate
266 internal bool IsTrue { get { return this.Value; } }
269 /// Is this the 'false' predicate
271 internal bool IsFalse { get { return this.Value == false; } }
274 /// Visitor pattern method
276 /// <param name="v">The BasicOpVisitor that is visiting this Op</param>
277 /// <param name="n">The Node that references this Op</param>
278 [DebuggerNonUserCode]
279 internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
282 /// Visitor pattern method for visitors with a return value
284 /// <param name="v">The visitor</param>
285 /// <param name="n">The node in question</param>
286 /// <returns>An instance of TResultType</returns>
287 [DebuggerNonUserCode]
288 internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
296 /// A reference to an existing variable
298 internal sealed class VarRefOp : ScalarOp
300 #region private state
305 internal VarRefOp(Var v) : base(OpType.VarRef, v.Type)
309 private VarRefOp() : base(OpType.VarRef) { }
312 #region public methods
314 /// Singleton used for pattern matching
316 internal static readonly VarRefOp Pattern = new VarRefOp();
321 internal override int Arity { get { return 0; } }
324 /// Two VarRefOps are equivalent, if they reference the same Var
326 /// <param name="other">the other Op</param>
327 /// <returns>true, if these are equivalent</returns>
328 internal override bool IsEquivalent(Op other)
330 VarRefOp otherVarRef = other as VarRefOp;
331 return (otherVarRef != null && otherVarRef.Var.Equals(this.Var));
335 /// The Var that this Op is referencing
337 internal Var Var { get { return m_var; } }
340 /// Visitor pattern method
342 /// <param name="v">The BasicOpVisitor that is visiting this Op</param>
343 /// <param name="n">The Node that references this Op</param>
344 [DebuggerNonUserCode]
345 internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
348 /// Visitor pattern method for visitors with a return value
350 /// <param name="v">The visitor</param>
351 /// <param name="n">The node in question</param>
352 /// <returns>An instance of TResultType</returns>
353 [DebuggerNonUserCode]
354 internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
359 /// Represents an arbitrary function call
361 internal sealed class FunctionOp : ScalarOp
363 #region private state
364 private EdmFunction m_function;
368 internal FunctionOp(EdmFunction function)
369 : base(OpType.Function, function.ReturnParameter.TypeUsage)
371 m_function = function;
373 private FunctionOp() : base(OpType.Function) { }
376 #region public methods
378 /// Singleton instance used for patterns in transformation rules
380 internal static readonly FunctionOp Pattern = new FunctionOp();
383 /// The function that's being invoked
385 internal EdmFunction Function { get { return m_function; } }
388 /// Two FunctionOps are equivalent if they reference the same EdmFunction
390 /// <param name="other">the other Op</param>
391 /// <returns>true, if these are equivalent</returns>
392 internal override bool IsEquivalent(Op other)
394 FunctionOp otherFunctionOp = other as FunctionOp;
395 return (otherFunctionOp != null && otherFunctionOp.Function.EdmEquals(this.Function));
399 /// Visitor pattern method
401 /// <param name="v">The BasicOpVisitor that is visiting this Op</param>
402 /// <param name="n">The Node that references this Op</param>
403 [DebuggerNonUserCode]
404 internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
407 /// Visitor pattern method for visitors with a return value
409 /// <param name="v">The visitor</param>
410 /// <param name="n">The node in question</param>
411 /// <returns>An instance of TResultType</returns>
412 [DebuggerNonUserCode]
413 internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
418 /// Represents a property access
420 internal sealed class PropertyOp : ScalarOp
422 #region private state
423 private EdmMember m_property;
427 internal PropertyOp(TypeUsage type, EdmMember property)
428 : base(OpType.Property, type)
430 Debug.Assert((property is EdmProperty) || (property is RelationshipEndMember) || (property is NavigationProperty), "Unexpected EdmMember type");
431 m_property = property;
433 private PropertyOp() : base(OpType.Property) { }
436 #region public methods
438 /// Used for patterns in transformation rules
440 internal static readonly PropertyOp Pattern = new PropertyOp();
443 /// 1 child - the instance
445 internal override int Arity { get { return 1; } }
448 /// The property metadata
450 internal EdmMember PropertyInfo { get { return m_property; } }
453 /// Visitor pattern method
455 /// <param name="v">The BasicOpVisitor that is visiting this Op</param>
456 /// <param name="n">The Node that references this Op</param>
457 [DebuggerNonUserCode]
458 internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
461 /// Visitor pattern method for visitors with a return value
463 /// <param name="v">The visitor</param>
464 /// <param name="n">The node in question</param>
465 /// <returns>An instance of TResultType</returns>
466 [DebuggerNonUserCode]
467 internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
472 /// Represents a TREAT AS operation
474 internal sealed class TreatOp : ScalarOp
476 #region private state
477 private bool m_isFake;
481 internal TreatOp(TypeUsage type, bool isFake)
482 : base(OpType.Treat, type)
486 private TreatOp() : base(OpType.Treat) { }
489 #region public methods
491 /// Used as patterns in transformation rules
493 internal static readonly TreatOp Pattern = new TreatOp();
496 /// 1 child - instance
498 internal override int Arity { get { return 1; } }
501 /// Is this a "fake" treat?
503 internal bool IsFakeTreat { get { return m_isFake; } }
506 /// Visitor pattern method
508 /// <param name="v">The BasicOpVisitor that is visiting this Op</param>
509 /// <param name="n">The Node that references this Op</param>
510 [DebuggerNonUserCode]
511 internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
514 /// Visitor pattern method for visitors with a return value
516 /// <param name="v">The visitor</param>
517 /// <param name="n">The node in question</param>
518 /// <returns>An instance of TResultType</returns>
519 [DebuggerNonUserCode]
520 internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
525 /// An IS OF operation
527 internal sealed class IsOfOp : ScalarOp
529 #region private state
530 private TypeUsage m_isOfType;
531 private bool m_isOfOnly;
535 internal IsOfOp(TypeUsage isOfType, bool isOfOnly, TypeUsage type)
536 : base(OpType.IsOf, type)
538 m_isOfType = isOfType;
539 m_isOfOnly = isOfOnly;
541 private IsOfOp() : base(OpType.IsOf) { }
544 #region public methods
546 /// Pattern used for transformation rules
548 internal static readonly IsOfOp Pattern = new IsOfOp();
551 /// 1 child - instance
553 internal override int Arity { get { return 1; } }
556 /// The type being checked for
558 internal TypeUsage IsOfType { get { return m_isOfType; } }
560 internal bool IsOfOnly { get { return m_isOfOnly; } }
563 /// Visitor pattern method
565 /// <param name="v">The BasicOpVisitor that is visiting this Op</param>
566 /// <param name="n">The Node that references this Op</param>
567 [DebuggerNonUserCode]
568 internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
571 /// Visitor pattern method for visitors with a return value
573 /// <param name="v">The visitor</param>
574 /// <param name="n">The node in question</param>
575 /// <returns>An instance of TResultType</returns>
576 [DebuggerNonUserCode]
577 internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
582 /// Cast operation. Convert a type instance into an instance of another type
584 internal sealed class CastOp : ScalarOp
587 internal CastOp(TypeUsage type) : base(OpType.Cast, type) { }
588 private CastOp() : base(OpType.Cast) { }
591 #region public methods
593 /// Pattern for transformation rules
595 internal static readonly CastOp Pattern = new CastOp();
598 /// 1 child - instance
600 internal override int Arity { get { return 1; } }
603 /// Visitor pattern method
605 /// <param name="v">The BasicOpVisitor that is visiting this Op</param>
606 /// <param name="n">The Node that references this Op</param>
607 [DebuggerNonUserCode]
608 internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
611 /// Visitor pattern method for visitors with a return value
613 /// <param name="v">The visitor</param>
614 /// <param name="n">The node in question</param>
615 /// <returns>An instance of TResultType</returns>
616 [DebuggerNonUserCode]
617 internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
622 /// An internal cast operation. (Softly) Convert a type instance into an instance of another type
624 /// This Op is intended to capture "promotion" semantics. (ie) int16 promotes to an int32; Customer promotes to Person
625 /// etc. This Op is intended to shield the PlanCompiler from having to reason about
626 /// the promotion semantics; and is intended to make the query tree very
630 internal sealed class SoftCastOp : ScalarOp
633 internal SoftCastOp(TypeUsage type) : base(OpType.SoftCast, type) { }
634 private SoftCastOp() : base(OpType.SoftCast) { }
637 #region public methods
639 /// Pattern for transformation rules
641 internal static readonly SoftCastOp Pattern = new SoftCastOp();
644 /// 1 child - input expression
646 internal override int Arity { get { return 1; } }
649 /// Visitor pattern method
651 /// <param name="v">The BasicOpVisitor that is visiting this Op</param>
652 /// <param name="n">The Node that references this Op</param>
653 [DebuggerNonUserCode]
654 internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
657 /// Visitor pattern method for visitors with a return value
659 /// <param name="v">The visitor</param>
660 /// <param name="n">The node in question</param>
661 /// <returns>An instance of TResultType</returns>
662 [DebuggerNonUserCode]
663 internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
668 /// Represents a comparision operation (LT, GT etc.)
670 internal sealed class ComparisonOp : ScalarOp
673 internal ComparisonOp(OpType opType, TypeUsage type)
677 private ComparisonOp(OpType opType) : base(opType) { }
680 #region public methods
682 /// Patterns for use in transformation rules
684 internal static readonly ComparisonOp PatternEq = new ComparisonOp(OpType.EQ);
687 /// 2 children - left, right
689 internal override int Arity { get { return 2; } }
692 /// Visitor pattern method
694 /// <param name="v">The BasicOpVisitor that is visiting this Op</param>
695 /// <param name="n">The Node that references this Op</param>
696 [DebuggerNonUserCode]
697 internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
700 /// Visitor pattern method for visitors with a return value
702 /// <param name="v">The visitor</param>
703 /// <param name="n">The node in question</param>
704 /// <returns>An instance of TResultType</returns>
705 [DebuggerNonUserCode]
706 internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
711 /// Represents a string comparison operation
713 internal sealed class LikeOp : ScalarOp
716 internal LikeOp(TypeUsage boolType)
717 : base(OpType.Like, boolType) { }
718 private LikeOp() : base(OpType.Like) { }
721 #region public surface
723 /// Pattern for use in transformation rules
725 internal static readonly LikeOp Pattern = new LikeOp();
728 /// 3 children - string, pattern , escape
730 internal override int Arity { get { return 3; } }
733 /// Visitor pattern method
735 /// <param name="v">The BasicOpVisitor that is visiting this Op</param>
736 /// <param name="n">The Node that references this Op</param>
737 [DebuggerNonUserCode]
738 internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
741 /// Visitor pattern method for visitors with a return value
743 /// <param name="v">The visitor</param>
744 /// <param name="n">The node in question</param>
745 /// <returns>An instance of TResultType</returns>
746 [DebuggerNonUserCode]
747 internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
752 /// Represents a conditional operation - and,or,not, is null
753 /// A little hacky - since it represents and/or/not as optypes - could I not
754 /// have done the same with the comparison operators?
756 internal sealed class ConditionalOp : ScalarOp
759 internal ConditionalOp(OpType optype, TypeUsage type) : base(optype, type)
762 private ConditionalOp(OpType opType) : base(opType) { }
765 #region public methods
767 /// Patterns for use in transformation rules
769 internal static readonly ConditionalOp PatternAnd = new ConditionalOp(OpType.And);
770 internal static readonly ConditionalOp PatternOr = new ConditionalOp(OpType.Or);
771 internal static readonly ConditionalOp PatternNot = new ConditionalOp(OpType.Not);
772 internal static readonly ConditionalOp PatternIsNull = new ConditionalOp(OpType.IsNull);
775 /// Visitor pattern method
777 /// <param name="v">The BasicOpVisitor that is visiting this Op</param>
778 /// <param name="n">The Node that references this Op</param>
779 [DebuggerNonUserCode]
780 internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
783 /// Visitor pattern method for visitors with a return value
785 /// <param name="v">The visitor</param>
786 /// <param name="n">The node in question</param>
787 /// <returns>An instance of TResultType</returns>
788 [DebuggerNonUserCode]
789 internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
794 /// ANSI switched Case expression.
796 internal sealed class CaseOp : ScalarOp
799 internal CaseOp(TypeUsage type) : base(OpType.Case, type) { }
800 private CaseOp() : base(OpType.Case) { }
803 #region public methods
805 /// Pattern for use in transformation rules
807 internal static readonly CaseOp Pattern = new CaseOp();
810 /// Visitor pattern method
812 /// <param name="v">The BasicOpVisitor that is visiting this Op</param>
813 /// <param name="n">The Node that references this Op</param>
814 [DebuggerNonUserCode]
815 internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
818 /// Visitor pattern method for visitors with a return value
820 /// <param name="v">The visitor</param>
821 /// <param name="n">The node in question</param>
822 /// <returns>An instance of TResultType</returns>
823 [DebuggerNonUserCode]
824 internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
831 internal sealed class AggregateOp : ScalarOp
833 #region private state
834 private EdmFunction m_aggFunc;
835 private bool m_distinctAgg;
839 internal AggregateOp(EdmFunction aggFunc, bool distinctAgg)
840 : base(OpType.Aggregate, aggFunc.ReturnParameter.TypeUsage)
843 m_distinctAgg = distinctAgg;
845 private AggregateOp() : base(OpType.Aggregate) { }
848 #region public methods
850 /// Pattern for transformation rules
852 internal static readonly AggregateOp Pattern = new AggregateOp();
855 /// The Aggregate function's metadata
857 internal EdmFunction AggFunc { get { return m_aggFunc; } }
860 /// Is this a "distinct" aggregate
862 internal bool IsDistinctAggregate { get { return m_distinctAgg; } }
865 /// Yes; this is an aggregate
867 internal override bool IsAggregateOp {get{return true;}}
870 /// Visitor pattern method
872 /// <param name="v">The BasicOpVisitor that is visiting this Op</param>
873 /// <param name="n">The Node that references this Op</param>
874 [DebuggerNonUserCode]
875 internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
878 /// Visitor pattern method for visitors with a return value
880 /// <param name="v">The visitor</param>
881 /// <param name="n">The node in question</param>
882 /// <returns>An instance of TResultType</returns>
883 [DebuggerNonUserCode]
884 internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
889 /// Represents an arbitrary nest operation - can be used anywhere
891 internal sealed class CollectOp : ScalarOp
894 internal CollectOp(TypeUsage type) : base(OpType.Collect, type) { }
895 private CollectOp() : base(OpType.Collect) { }
898 #region public methods
900 /// Pattern for use in transformation rules
902 internal static readonly CollectOp Pattern = new CollectOp();
905 /// 1 child - instance
907 internal override int Arity { get { return 1; } }
910 /// Visitor pattern method
912 /// <param name="v">The BasicOpVisitor that is visiting this Op</param>
913 /// <param name="n">The Node that references this Op</param>
914 [DebuggerNonUserCode]
915 internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
918 /// Visitor pattern method for visitors with a return value
920 /// <param name="v">The visitor</param>
921 /// <param name="n">The node in question</param>
922 /// <returns>An instance of TResultType</returns>
923 [DebuggerNonUserCode]
924 internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
929 /// Almost identical to a PropertyOp - the only difference being that we're dealing with an
930 /// "extended" property (a rel property) this time
932 internal sealed class RelPropertyOp : ScalarOp
934 #region private state
935 private readonly RelProperty m_property;
939 private RelPropertyOp() : base(OpType.RelProperty) { }
941 internal RelPropertyOp(TypeUsage type, RelProperty property)
942 : base(OpType.RelProperty, type)
944 m_property = property;
950 /// Pattern for transformation rules
952 internal static readonly RelPropertyOp Pattern = new RelPropertyOp();
955 /// 1 child - the entity instance
957 internal override int Arity { get { return 1; } }
960 /// Get the property metadata
962 public RelProperty PropertyInfo { get { return m_property; } }
965 /// Visitor pattern method
967 /// <param name="v">The BasicOpVisitor that is visiting this Op</param>
968 /// <param name="n">The Node that references this Op</param>
969 [DebuggerNonUserCode]
970 internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
973 /// Visitor pattern method for visitors with a return value
975 /// <param name="v">The visitor</param>
976 /// <param name="n">The node in question</param>
977 /// <returns>An instance of TResultType</returns>
978 [DebuggerNonUserCode]
979 internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
985 /// Base class for DiscriminatedNewEntityOp and NewEntityOp
987 internal abstract class NewEntityBaseOp : ScalarOp
989 #region private state
990 private readonly bool m_scoped;
991 private readonly EntitySet m_entitySet;
992 private readonly List<RelProperty> m_relProperties; // list of relationship properties for which we have values
996 internal NewEntityBaseOp(OpType opType, TypeUsage type, bool scoped, EntitySet entitySet, List<RelProperty> relProperties)
999 Debug.Assert(scoped || entitySet == null, "entitySet cann't be set of constructor isn't scoped");
1000 Debug.Assert(relProperties != null, "expected non-null list of rel-properties");
1002 m_entitySet = entitySet;
1003 m_relProperties = relProperties;
1006 protected NewEntityBaseOp(OpType opType) : base(opType) { }
1011 /// True if the entity constructor is scoped to a particular entity set or null (scoped as "unscoped").
1012 /// False if the scope is not yet known. Scope is determined in PreProcessor.
1014 internal bool Scoped { get { return m_scoped; } }
1017 /// Get the entityset (if any) associated with this constructor
1019 internal EntitySet EntitySet { get { return m_entitySet; } }
1022 /// get the list of relationship properties (if any) specified for this constructor
1024 internal List<RelProperty> RelationshipProperties { get { return m_relProperties; } }
1029 /// A new entity instance constructor
1031 internal sealed class NewEntityOp : NewEntityBaseOp
1033 #region constructors
1034 private NewEntityOp() : base(OpType.NewEntity) { }
1036 internal NewEntityOp(TypeUsage type, List<RelProperty> relProperties, bool scoped, EntitySet entitySet)
1037 : base(OpType.NewEntity, type, scoped, entitySet, relProperties)
1042 #region public methods
1044 /// Pattern for transformation rules
1046 internal static readonly NewEntityOp Pattern = new NewEntityOp();
1049 /// Visitor pattern method
1051 /// <param name="v">The BasicOpVisitor that is visiting this Op</param>
1052 /// <param name="n">The Node that references this Op</param>
1053 [DebuggerNonUserCode]
1054 internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
1057 /// Visitor pattern method for visitors with a return value
1059 /// <param name="v">The visitor</param>
1060 /// <param name="n">The node in question</param>
1061 /// <returns>An instance of TResultType</returns>
1062 [DebuggerNonUserCode]
1063 internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
1068 /// A new instance creation
1070 internal sealed class NewInstanceOp : ScalarOp
1072 #region constructors
1073 internal NewInstanceOp(TypeUsage type) : base(OpType.NewInstance, type)
1075 Debug.Assert(!type.EdmType.Abstract, "cannot create new instance of abstract type");
1076 Debug.Assert(!TypeSemantics.IsEntityType(type), "cannot use this Op for entity construction");
1078 private NewInstanceOp() : base(OpType.NewInstance) { }
1081 #region public methods
1083 /// Pattern for transformation rules
1085 internal static readonly NewInstanceOp Pattern = new NewInstanceOp();
1088 /// Visitor pattern method
1090 /// <param name="v">The BasicOpVisitor that is visiting this Op</param>
1091 /// <param name="n">The Node that references this Op</param>
1092 [DebuggerNonUserCode]
1093 internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
1096 /// Visitor pattern method for visitors with a return value
1098 /// <param name="v">The visitor</param>
1099 /// <param name="n">The node in question</param>
1100 /// <returns>An instance of TResultType</returns>
1101 [DebuggerNonUserCode]
1102 internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
1107 /// Polymorphic new instance creation (takes all properties of all types in the hierarchy + discriminator)
1109 internal sealed class DiscriminatedNewEntityOp : NewEntityBaseOp
1111 #region Private state
1112 private readonly ExplicitDiscriminatorMap m_discriminatorMap;
1115 #region Constructors
1116 internal DiscriminatedNewEntityOp(TypeUsage type, ExplicitDiscriminatorMap discriminatorMap,
1117 EntitySet entitySet, List<RelProperty> relProperties)
1118 : base(OpType.DiscriminatedNewEntity, type, true, entitySet, relProperties)
1120 Debug.Assert(null != discriminatorMap, "null discriminator map");
1121 m_discriminatorMap = discriminatorMap;
1123 private DiscriminatedNewEntityOp() : base(OpType.DiscriminatedNewEntity) { }
1126 #region "Public" members
1127 internal static readonly DiscriminatedNewEntityOp Pattern = new DiscriminatedNewEntityOp();
1130 /// Gets discriminator and type information used in construction of type.
1132 internal ExplicitDiscriminatorMap DiscriminatorMap
1134 get { return m_discriminatorMap; }
1137 [DebuggerNonUserCode]
1138 internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
1140 [DebuggerNonUserCode]
1141 internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
1146 /// Represents a new record constructor
1148 internal sealed class NewRecordOp : ScalarOp
1150 #region private state
1151 private List<EdmProperty> m_fields; // list of fields with specified values
1154 #region constructors
1156 /// Basic constructor. All fields have a value specified
1158 /// <param name="type"></param>
1159 internal NewRecordOp(TypeUsage type) : base(OpType.NewRecord, type)
1161 m_fields = new List<EdmProperty>(TypeHelpers.GetEdmType<RowType>(type).Properties);
1164 /// Alternate form of the constructor. Only some fields have a value specified
1165 /// The arguments to the corresponding Node are exactly 1-1 with the fields
1167 /// The missing fields are considered to be "null"
1169 /// <param name="type"></param>
1170 /// <param name="fields"></param>
1171 internal NewRecordOp(TypeUsage type, List<EdmProperty> fields)
1172 : base(OpType.NewRecord, type)
1175 foreach (EdmProperty p in fields)
1177 Debug.Assert(Object.ReferenceEquals(p.DeclaringType, this.Type.EdmType));
1182 private NewRecordOp() : base(OpType.NewRecord) { }
1185 #region public methods
1187 /// Pattern for transformation rules
1189 internal static readonly NewRecordOp Pattern = new NewRecordOp();
1192 /// Determine if a value has been provided for the specified field.
1193 /// Returns the position of this field (ie) the specific argument in the Node's
1194 /// children. If no value has been provided for this field, then simply
1197 /// <param name="field"></param>
1198 /// <param name="fieldPosition"></param>
1199 /// <returns></returns>
1200 internal bool GetFieldPosition(EdmProperty field, out int fieldPosition)
1202 Debug.Assert(Object.ReferenceEquals(field.DeclaringType, this.Type.EdmType),
1203 "attempt to get invalid field from this record type");
1206 for (int i = 0; i < m_fields.Count; i++)
1208 if (m_fields[i] == field)
1218 /// List of all properties that have values specified
1220 internal List<EdmProperty> Properties { get { return m_fields; } }
1223 /// Visitor pattern method
1225 /// <param name="v">The BasicOpVisitor that is visiting this Op</param>
1226 /// <param name="n">The Node that references this Op</param>
1227 [DebuggerNonUserCode]
1228 internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
1231 /// Visitor pattern method for visitors with a return value
1233 /// <param name="v">The visitor</param>
1234 /// <param name="n">The node in question</param>
1235 /// <returns>An instance of TResultType</returns>
1236 [DebuggerNonUserCode]
1237 internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
1241 internal sealed class NewMultisetOp : ScalarOp
1243 #region constructors
1244 internal NewMultisetOp(TypeUsage type) : base(OpType.NewMultiset, type) { }
1245 private NewMultisetOp() : base(OpType.NewMultiset) { }
1248 #region public methods
1250 /// Pattern for transformation rules
1252 internal static readonly NewMultisetOp Pattern = new NewMultisetOp();
1255 /// Visitor pattern method
1257 /// <param name="v">The BasicOpVisitor that is visiting this Op</param>
1258 /// <param name="n">The Node that references this Op</param>
1259 [DebuggerNonUserCode]
1260 internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
1263 /// Visitor pattern method for visitors with a return value
1265 /// <param name="v">The visitor</param>
1266 /// <param name="n">The node in question</param>
1267 /// <returns>An instance of TResultType</returns>
1268 [DebuggerNonUserCode]
1269 internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
1274 /// Represents arithmetic operators - Plus,Minus,Multiply,Divide,Modulo,UnaryMinus
1276 internal sealed class ArithmeticOp : ScalarOp
1278 #region constructors
1279 internal ArithmeticOp(OpType opType, TypeUsage type)
1280 : base(opType, type) { }
1283 #region public methods
1286 /// Visitor pattern method
1288 /// <param name="v">The BasicOpVisitor that is visiting this Op</param>
1289 /// <param name="n">The Node that references this Op</param>
1290 [DebuggerNonUserCode]
1291 internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
1294 /// Visitor pattern method for visitors with a return value
1296 /// <param name="v">The visitor</param>
1297 /// <param name="n">The node in question</param>
1298 /// <returns>An instance of TResultType</returns>
1299 [DebuggerNonUserCode]
1300 internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
1307 internal sealed class RefOp : ScalarOp
1309 #region private state
1310 private EntitySet m_entitySet;
1313 #region constructors
1314 internal RefOp(EntitySet entitySet, TypeUsage type)
1315 : base(OpType.Ref, type)
1317 m_entitySet = entitySet;
1319 private RefOp() : base(OpType.Ref) { }
1322 #region public methods
1324 /// Pattern for transformation rules
1326 internal static readonly RefOp Pattern = new RefOp();
1331 internal override int Arity { get { return 1; } }
1334 /// The EntitySet to which the reference refers
1336 internal EntitySet EntitySet { get { return m_entitySet; } }
1339 /// Visitor pattern method
1341 /// <param name="v">The BasicOpVisitor that is visiting this Op</param>
1342 /// <param name="n">The Node that references this Op</param>
1343 [DebuggerNonUserCode]
1344 internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
1347 /// Visitor pattern method for visitors with a return value
1349 /// <param name="v">The visitor</param>
1350 /// <param name="n">The node in question</param>
1351 /// <returns>An instance of TResultType</returns>
1352 [DebuggerNonUserCode]
1353 internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
1358 /// Represents an EXISTS subquery?
1360 internal sealed class ExistsOp : ScalarOp
1362 #region constructors
1363 internal ExistsOp(TypeUsage type)
1364 : base(OpType.Exists, type)
1367 private ExistsOp() : base(OpType.Exists) { }
1370 #region public methods
1372 /// Pattern for transformation rules
1374 internal static readonly ExistsOp Pattern = new ExistsOp();
1377 /// 1 child - collection input
1379 internal override int Arity { get { return 1; } }
1382 /// Visitor pattern method
1384 /// <param name="v">The BasicOpVisitor that is visiting this Op</param>
1385 /// <param name="n">The Node that references this Op</param>
1386 [DebuggerNonUserCode]
1387 internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
1390 /// Visitor pattern method for visitors with a return value
1392 /// <param name="v">The visitor</param>
1393 /// <param name="n">The node in question</param>
1394 /// <returns>An instance of TResultType</returns>
1395 [DebuggerNonUserCode]
1396 internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
1401 /// Represents an Element() op - extracts the scalar value from a collection
1403 internal sealed class ElementOp : ScalarOp
1405 #region constructors
1406 internal ElementOp(TypeUsage type) : base(OpType.Element, type) { }
1407 private ElementOp() : base(OpType.Element) { }
1410 #region public methods
1412 /// Pattern for transformation rules
1414 internal static readonly ElementOp Pattern = new ElementOp();
1417 /// 1 child - collection instance
1419 internal override int Arity { get { return 1; } }
1422 /// Visitor pattern method
1424 /// <param name="v">The BasicOpVisitor that is visiting this Op</param>
1425 /// <param name="n">The Node that references this Op</param>
1426 [DebuggerNonUserCode]
1427 internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
1430 /// Visitor pattern method for visitors with a return value
1432 /// <param name="v">The visitor</param>
1433 /// <param name="n">The node in question</param>
1434 /// <returns>An instance of TResultType</returns>
1435 [DebuggerNonUserCode]
1436 internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
1441 /// extracts the key from a ref
1443 internal sealed class GetRefKeyOp : ScalarOp
1445 #region constructors
1446 internal GetRefKeyOp(TypeUsage type) : base(OpType.GetRefKey, type) { }
1447 private GetRefKeyOp() : base(OpType.GetRefKey) { }
1450 #region public methods
1452 /// Pattern for transformation rules
1454 internal static readonly GetRefKeyOp Pattern = new GetRefKeyOp();
1457 /// 1 child - ref instance
1459 internal override int Arity { get { return 1; } }
1462 /// Visitor pattern method
1464 /// <param name="v">The BasicOpVisitor that is visiting this Op</param>
1465 /// <param name="n">The Node that references this Op</param>
1466 [DebuggerNonUserCode]
1467 internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
1470 /// Visitor pattern method for visitors with a return value
1472 /// <param name="v">The visitor</param>
1473 /// <param name="n">The node in question</param>
1474 /// <returns>An instance of TResultType</returns>
1475 [DebuggerNonUserCode]
1476 internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
1481 /// Extracts the ref from an entity instance
1483 internal sealed class GetEntityRefOp : ScalarOp
1485 #region constructors
1486 internal GetEntityRefOp(TypeUsage type) : base(OpType.GetEntityRef, type) { }
1487 private GetEntityRefOp() : base(OpType.GetEntityRef) { }
1490 #region public methods
1492 /// Pattern for transformation rules
1494 internal static readonly GetEntityRefOp Pattern = new GetEntityRefOp();
1497 /// 1 child - entity instance
1499 internal override int Arity { get { return 1; } }
1502 /// Visitor pattern method
1504 /// <param name="v">The BasicOpVisitor that is visiting this Op</param>
1505 /// <param name="n">The Node that references this Op</param>
1506 [DebuggerNonUserCode]
1507 internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
1510 /// Visitor pattern method for visitors with a return value
1512 /// <param name="v">The visitor</param>
1513 /// <param name="n">The node in question</param>
1514 /// <returns>An instance of TResultType</returns>
1515 [DebuggerNonUserCode]
1516 internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
1521 /// Gets the target entity pointed at by a reference
1523 internal sealed class DerefOp : ScalarOp
1525 #region constructors
1526 internal DerefOp(TypeUsage type) : base(OpType.Deref, type) { }
1527 private DerefOp() : base(OpType.Deref) { }
1530 #region public methods
1532 /// Pattern for transformation rules
1534 internal static readonly DerefOp Pattern = new DerefOp();
1537 /// 1 child - entity instance
1539 internal override int Arity { get { return 1; } }
1542 /// Visitor pattern method
1544 /// <param name="v">The BasicOpVisitor that is visiting this Op</param>
1545 /// <param name="n">The Node that references this Op</param>
1546 [DebuggerNonUserCode]
1547 internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
1550 /// Visitor pattern method for visitors with a return value
1552 /// <param name="v">The visitor</param>
1553 /// <param name="n">The node in question</param>
1554 /// <returns>An instance of TResultType</returns>
1555 [DebuggerNonUserCode]
1556 internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
1561 /// Navigate a relationship, and get the reference(s) of the target end
1563 internal sealed class NavigateOp : ScalarOp
1565 #region private state
1566 private readonly RelProperty m_property;
1569 #region constructors
1570 internal NavigateOp(TypeUsage type, RelProperty relProperty)
1571 : base(OpType.Navigate, type)
1573 m_property = relProperty;
1575 private NavigateOp() : base(OpType.Navigate) { }
1578 #region public methods
1580 /// Pattern for transformation rules
1582 internal static readonly NavigateOp Pattern = new NavigateOp();
1585 /// 1 child - entity instance
1587 internal override int Arity { get { return 1; } }
1590 /// The rel property that describes this nvaigation
1592 internal RelProperty RelProperty { get { return m_property; } }
1595 /// The relationship we're traversing
1597 internal RelationshipType Relationship { get { return m_property.Relationship; } }
1599 /// The starting point of the traversal
1601 internal RelationshipEndMember FromEnd { get { return m_property.FromEnd; } }
1603 /// The end-point of the traversal
1605 internal RelationshipEndMember ToEnd { get { return m_property.ToEnd; } }
1608 /// Visitor pattern method
1610 /// <param name="v">The BasicOpVisitor that is visiting this Op</param>
1611 /// <param name="n">The Node that references this Op</param>
1612 [DebuggerNonUserCode]
1613 internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
1616 /// Visitor pattern method for visitors with a return value
1618 /// <param name="v">The visitor</param>
1619 /// <param name="n">The node in question</param>
1620 /// <returns>An instance of TResultType</returns>
1621 [DebuggerNonUserCode]
1622 internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }