1 //---------------------------------------------------------------------
2 // <copyright file="Ops.cs" company="Microsoft">
3 //      Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>
5 //
6 // @owner  Microsoft
7 // @backupOwner Microsoft
8 //---------------------------------------------------------------------
9 
10 namespace System.Data.Query.InternalTrees
11 {
12     using System.Data.Metadata.Edm;
13     using System.Diagnostics;
14 
15     /// <summary>
16     /// The operator types. Includes both scalar and relational operators,
17     /// and physical and logical operators, and rule operators
18     /// </summary>
19     internal enum OpType
20     {
21         #region ScalarOpType
22         /// <summary>
23         /// Constants
24         /// </summary>
25         Constant,
26 
27         /// <summary>
28         /// An internally generated constant
29         /// </summary>
30         InternalConstant,
31 
32         /// <summary>
33         /// An internally generated constant used as a null sentinel
34         /// </summary>
35         NullSentinel,
36 
37         /// <summary>
38         /// A null constant
39         /// </summary>
40         Null,
41 
42         /// <summary>
43         /// ConstantPredicate
44         /// </summary>
45         ConstantPredicate,
46 
47         /// <summary>
48         /// A Var reference
49         /// </summary>
50         VarRef,
51 
52         /// <summary>
53         /// GreaterThan
54         /// </summary>
55         GT,
56 
57         /// <summary>
58         /// >=
59         /// </summary>
60         GE,
61 
62         /// <summary>
63         /// Lessthan or equals
64         /// </summary>
65         LE,
66 
67         /// <summary>
68         /// Less than
69         /// </summary>
70         LT,
71 
72         /// <summary>
73         /// Equals
74         /// </summary>
75         EQ,
76 
77         /// <summary>
78         /// Not equals
79         /// </summary>
80         NE,
81 
82         /// <summary>
83         /// String comparison
84         /// </summary>
85         Like,
86 
87         /// <summary>
88         /// Addition
89         /// </summary>
90         Plus,
91 
92         /// <summary>
93         /// Subtraction
94         /// </summary>
95         Minus,
96 
97         /// <summary>
98         /// Multiplication
99         /// </summary>
100         Multiply,
101 
102         /// <summary>
103         /// Division
104         /// </summary>
105         Divide,
106 
107         /// <summary>
108         /// Modulus
109         /// </summary>
110         Modulo,
111 
112         /// <summary>
113         /// Unary Minus
114         /// </summary>
115         UnaryMinus,
116 
117         /// <summary>
118         /// And
119         /// </summary>
120         And,
121 
122         /// <summary>
123         /// Or
124         /// </summary>
125         Or,
126 
127         /// <summary>
128         /// Not
129         /// </summary>
130         Not,
131 
132         /// <summary>
133         /// is null
134         /// </summary>
135         IsNull,
136 
137         /// <summary>
138         /// switched case expression
139         /// </summary>
140         Case,
141 
142         /// <summary>
143         /// treat-as
144         /// </summary>
145         Treat,
146 
147         /// <summary>
148         /// is-of
149         /// </summary>
150         IsOf,
151 
152         /// <summary>
153         /// Cast
154         /// </summary>
155         Cast,
156 
157         /// <summary>
158         /// Internal cast
159         /// </summary>
160         SoftCast,
161 
162         /// <summary>
163         /// a basic aggregate
164         /// </summary>
165         Aggregate,
166 
167         /// <summary>
168         /// function call
169         /// </summary>
170         Function,
171 
172         /// <summary>
173         /// Reference to a "relationship" property
174         /// </summary>
175         RelProperty,
176 
177         /// <summary>
178         /// property reference
179         /// </summary>
180         Property,
181 
182         /// <summary>
183         /// entity constructor
184         /// </summary>
185         NewEntity,
186 
187         /// <summary>
188         /// new instance constructor for a named type(other than multiset, record)
189         /// </summary>
190         NewInstance,
191 
192         /// <summary>
193         /// new instance constructor for a named type and sub-types
194         /// </summary>
195         DiscriminatedNewEntity,
196 
197         /// <summary>
198         /// Multiset constructor
199         /// </summary>
200         NewMultiset,
201 
202         /// <summary>
203         /// record constructor
204         /// </summary>
205         NewRecord,
206 
207         /// <summary>
208         /// Get the key from a Ref
209         /// </summary>
210         GetRefKey,
211 
212        /// <summary>
213         /// Get the ref from an entity instance
214         /// </summary>
215         GetEntityRef,
216 
217         /// <summary>
218         /// create a reference
219         /// </summary>
220         Ref,
221 
222         /// <summary>
223         /// exists
224         /// </summary>
225         Exists,
226 
227         /// <summary>
228         /// get the singleton element from a collection
229         /// </summary>
230         Element,
231 
232         /// <summary>
233         /// Builds up a collection
234         /// </summary>
235         Collect,
236 
237         /// <summary>
238         /// gets the target entity pointed at by a reference
239         /// </summary>
240         Deref,
241 
242         /// <summary>
243         /// Traverse a relationship and get the references of the other end
244         /// </summary>
245         Navigate,
246         #endregion
247 
248         #region RelOpType
249         /// <summary>
250         /// A table scan
251         /// </summary>
252         ScanTable,
253         /// <summary>
254         /// A view scan
255         /// </summary>
256         ScanView,
257 
258         /// <summary>
259         /// Filter
260         /// </summary>
261         Filter,
262 
263         /// <summary>
264         /// Project
265         /// </summary>
266         Project,
267 
268         /// <summary>
269         /// InnerJoin
270         /// </summary>
271         InnerJoin,
272 
273         /// <summary>
274         /// LeftOuterJoin
275         /// </summary>
276         LeftOuterJoin,
277 
278         /// <summary>
279         /// FullOuter join
280         /// </summary>
281         FullOuterJoin,
282 
283         /// <summary>
284         /// Cross join
285         /// </summary>
286         CrossJoin,
287 
288         /// <summary>
289         /// cross apply
290         /// </summary>
291         CrossApply,
292 
293         /// <summary>
294         /// outer apply
295         /// </summary>
296         OuterApply,
297 
298         /// <summary>
299         /// Unnest
300         /// </summary>
301         Unnest,
302 
303         /// <summary>
304         /// Sort
305         /// </summary>
306         Sort,
307 
308         /// <summary>
309         /// Constrained Sort (physical paging - Limit and Skip)
310         /// </summary>
311         ConstrainedSort,
312 
313         /// <summary>
314         /// GroupBy
315         /// </summary>
316         GroupBy,
317 
318         /// <summary>
319         /// GroupByInto (projects the group as well)
320         /// </summary>
321         GroupByInto,
322 
323         /// <summary>
324         /// UnionAll
325         /// </summary>
326         UnionAll,
327         /// <summary>
328         /// Intersect
329         /// </summary>
330         Intersect,
331         /// <summary>
332         /// Except
333         /// </summary>
334         Except,
335 
336         /// <summary>
337         /// Distinct
338         /// </summary>
339         Distinct,
340 
341         /// <summary>
342         /// Select a single row from a subquery
343         /// </summary>
344         SingleRow,
345 
346         /// <summary>
347         /// A table with exactly one row
348         /// </summary>
349         SingleRowTable,
350 
351         #endregion
352 
353         #region AncillaryOpType
354         /// <summary>
355         /// Variable definition
356         /// </summary>
357         VarDef,
358         /// <summary>
359         /// List of variable definitions
360         /// </summary>
361         VarDefList,
362         #endregion
363 
364         #region RulePatternOpType
365         /// <summary>
366         /// Leaf
367         /// </summary>
368         Leaf,
369         #endregion
370 
371         #region PhysicalOpType
372         /// <summary>
373         /// Physical Project
374         /// </summary>
375         PhysicalProject,
376 
377         /// <summary>
378         /// single-stream nest aggregation
379         /// </summary>
380         SingleStreamNest,
381         /// <summary>
382         /// multi-stream nest aggregation
383         /// </summary>
384         MultiStreamNest,
385         #endregion
386 
387         /// <summary>
388         /// NotValid
389         /// </summary>
390         MaxMarker,
391         NotValid = MaxMarker
392     }
393 
394     /// <summary>
395     /// Represents an operator
396     /// </summary>
397     internal abstract class Op
398     {
399         #region private state
400         private OpType m_opType;
401         #endregion
402 
403         #region constructors
404         /// <summary>
405         /// Basic constructor
406         /// </summary>
Op(OpType opType)407         internal Op(OpType opType)
408         {
409             m_opType = opType;
410         }
411         #endregion
412 
413         #region public methods
414         /// <summary>
415         /// Represents an unknown arity. Usually for Ops that can have a varying number of Args
416         /// </summary>
417         internal const int ArityVarying = -1;
418 
419         /// <summary>
420         /// Kind of Op
421         /// </summary>
422         internal OpType OpType { get { return m_opType; } }
423 
424         /// <summary>
425         /// The Arity of this Op (ie) how many arguments can it have.
426         /// Returns -1 if the arity is not known a priori
427         /// </summary>
428         internal virtual int Arity { get { return ArityVarying; } }
429 
430         /// <summary>
431         /// Is this a ScalarOp
432         /// </summary>
433         internal virtual bool IsScalarOp { get { return false; } }
434 
435         /// <summary>
436         /// Is this a RulePatternOp
437         /// </summary>
438         internal virtual bool IsRulePatternOp { get { return false; } }
439 
440         /// <summary>
441         /// Is this a RelOp
442         /// </summary>
443         internal virtual bool IsRelOp { get { return false; } }
444 
445         /// <summary>
446         /// Is this an AncillaryOp
447         /// </summary>
448         internal virtual bool IsAncillaryOp { get { return false; } }
449 
450         /// <summary>
451         /// Is this a PhysicalOp
452         /// </summary>
453         internal virtual bool IsPhysicalOp { get { return false; } }
454 
455         /// <summary>
456         /// Is the other Op equivalent?
457         /// </summary>
458         /// <param name="other">the other Op to compare</param>
459         /// <returns>true, if the Ops are equivalent</returns>
IsEquivalent(Op other)460         internal virtual bool IsEquivalent(Op other)
461         {
462             return false;
463         }
464 
465         /// <summary>
466         /// Simple mechanism to get the type for an Op. Applies only to scalar and ancillaryOps
467         /// </summary>
468         internal virtual TypeUsage Type
469         {
470             get { return null; }
471             set { throw System.Data.Entity.Error.NotSupported(); }
472         }
473 
474         /// <summary>
475         /// Visitor pattern method
476         /// </summary>
477         /// <param name="v">The BasicOpVisitor that is visiting this Op</param>
478         /// <param name="n">The Node that references this Op</param>
479         [DebuggerNonUserCode]
Accept(BasicOpVisitor v, Node n)480         internal virtual void Accept(BasicOpVisitor v, Node n)
481         {
482             v.Visit(this, n);
483         }
484 
485         /// <summary>
486         /// Visitor pattern method for visitors with a return value
487         /// </summary>
488         /// <param name="v">The visitor</param>
489         /// <param name="n">The node in question</param>
490         /// <returns>An instance of TResultType</returns>
491         [DebuggerNonUserCode]
Accept(BasicOpVisitorOfT<TResultType> v, Node n)492         internal virtual TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n)
493         {
494             return v.Visit(this, n);
495         }
496         #endregion
497     }
498 
499     /// <summary>
500     /// All scalars fall into this category
501     /// </summary>
502     internal abstract class ScalarOp : Op
503     {
504         #region private state
505         private TypeUsage m_type;
506         #endregion
507 
508         #region constructors
509         /// <summary>
510         /// Default constructor
511         /// </summary>
512         /// <param name="opType">kind of Op</param>
513         /// <param name="type">type of value produced by this Op</param>
ScalarOp(OpType opType, TypeUsage type)514         internal ScalarOp(OpType opType, TypeUsage type)
515             : this(opType)
516         {
517             Debug.Assert(type != null, "No type specified for ScalarOp");
518             m_type = type;
519         }
520 
ScalarOp(OpType opType)521         protected ScalarOp(OpType opType) : base(opType) { }
522         #endregion
523 
524         #region public methods
525         /// <summary>
526         /// ScalarOp
527         /// </summary>
528         internal override bool IsScalarOp { get { return true; } }
529 
530         /// <summary>
531         /// Two scalarOps are equivalent (usually) if their OpTypes and types are the
532         /// same. Obviously, their arguments need to be equivalent as well - but that's
533         /// checked elsewhere
534         /// </summary>
535         /// <param name="other">The other Op to compare against</param>
536         /// <returns>true, if the Ops are indeed equivalent</returns>
IsEquivalent(Op other)537         internal override bool IsEquivalent(Op other)
538         {
539             return (other.OpType == this.OpType && TypeSemantics.IsStructurallyEqual(this.Type, other.Type));
540         }
541 
542         /// <summary>
543         /// Datatype of result
544         /// </summary>
545         internal override TypeUsage Type
546         {
547             get { return m_type; }
548             set { m_type = value; }
549         }
550 
551         /// <summary>
552         /// Is this an Aggregate
553         /// </summary>
554         internal virtual bool IsAggregateOp
555         {
556             get{return false;}
557         }
558         #endregion
559     }
560 
561     /// <summary>
562     /// All relational operators - filter, project, join etc.
563     /// </summary>
564     internal abstract class RelOp : Op
565     {
566         #region constructors
567         /// <summary>
568         /// Basic constructor.
569         /// </summary>
570         /// <param name="opType">kind of Op</param>
RelOp(OpType opType)571         internal RelOp(OpType opType) : base(opType) { }
572         #endregion
573 
574         #region public methods
575         /// <summary>
576         /// RelOp
577         /// </summary>
578         internal override bool IsRelOp { get { return true; } }
579         #endregion
580     }
581 
582     /// <summary>
583     /// AncillaryOp
584     /// </summary>
585     internal abstract class AncillaryOp : Op
586     {
587         #region constructors
588         /// <summary>
589         /// Default constructor
590         /// </summary>
591         /// <param name="opType">kind of Op</param>
AncillaryOp(OpType opType)592         internal AncillaryOp(OpType opType) : base(opType) { }
593         #endregion
594 
595         #region public methods
596         /// <summary>
597         /// AncillaryOp
598         /// </summary>
599         internal override bool IsAncillaryOp { get { return true; } }
600         #endregion
601     }
602 
603     /// <summary>
604     /// Represents all physical operators
605     /// </summary>
606     internal abstract class PhysicalOp : Op
607     {
608         #region constructors
609         /// <summary>
610         /// Default constructor
611         /// </summary>
612         /// <param name="opType">the op type</param>
PhysicalOp(OpType opType)613         internal PhysicalOp(OpType opType) : base(opType) { }
614         #endregion
615 
616         #region public methods
617         /// <summary>
618         /// This is a physical Op
619         /// </summary>
620         internal override bool IsPhysicalOp { get { return true; } }
621         #endregion
622     }
623 
624     /// <summary>
625     /// All rule pattern operators - Leaf, Tree
626     /// </summary>
627     internal abstract class RulePatternOp : Op
628     {
629         #region constructors
630         /// <summary>
631         /// Default constructor
632         /// </summary>
633         /// <param name="opType">kind of Op</param>
RulePatternOp(OpType opType)634         internal RulePatternOp(OpType opType) : base(opType) { }
635         #endregion
636 
637         #region public methods
638         /// <summary>
639         /// RulePatternOp
640         /// </summary>
641         internal override bool IsRulePatternOp { get { return true; } }
642         #endregion
643     }
644 }
645