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); }