1 //---------------------------------------------------------------------
2 // <copyright file="RelOps.cs" company="Microsoft">
3 //      Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>
5 //
6 // @owner  Microsoft
7 // @backupOwner Microsoft
8 //---------------------------------------------------------------------
9 
10 using System;
11 using System.Collections.Generic;
12 using System.Data.Metadata.Edm;
13 using System.Diagnostics;
14 using System.Globalization;
15 using System.Text;
16 
17 namespace System.Data.Query.InternalTrees
18 {
19     internal abstract class ScanTableBaseOp : RelOp
20     {
21         #region private state
22         private Table m_table;
23         #endregion
24 
25         #region constructors
ScanTableBaseOp(OpType opType, Table table)26         protected ScanTableBaseOp(OpType opType, Table table)
27             : base(opType)
28         {
29             m_table = table;
30         }
ScanTableBaseOp(OpType opType)31         protected ScanTableBaseOp(OpType opType)
32             : base(opType)
33         { }
34         #endregion
35 
36         #region public methods
37         /// <summary>
38         /// Get the table instance produced by this Op
39         /// </summary>
40         internal Table Table { get { return m_table; } }
41         #endregion
42     }
43 
44     /// <summary>
45     /// Scans a table
46     /// </summary>
47     internal sealed class ScanTableOp : ScanTableBaseOp
48     {
49         #region constructors
50         /// <summary>
51         /// Scan constructor
52         /// </summary>
53         /// <param name="table"></param>
ScanTableOp(Table table)54         internal ScanTableOp(Table table)
55             : base(OpType.ScanTable, table)
56         {
57         }
58 
ScanTableOp()59         private ScanTableOp() : base(OpType.ScanTable) { }
60 #endregion
61 
62         #region public methods
63         /// <summary>
64         /// Only to be used for pattern matches
65         /// </summary>
66         internal static readonly ScanTableOp Pattern = new ScanTableOp();
67 
68         /// <summary>
69         /// No children
70         /// </summary>
71         internal override int Arity {get {return 0;} }
72 
73         /// <summary>
74         /// Visitor pattern method
75         /// </summary>
76         /// <param name="v">The BasicOpVisitor that is visiting this Op</param>
77         /// <param name="n">The Node that references this Op</param>
78         [DebuggerNonUserCode]
Accept(BasicOpVisitor v, Node n)79         internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
80 
81         /// <summary>
82         /// Visitor pattern method for visitors with a return value
83         /// </summary>
84         /// <param name="v">The visitor</param>
85         /// <param name="n">The node in question</param>
86         /// <returns>An instance of TResultType</returns>
87         [DebuggerNonUserCode]
Accept(BasicOpVisitorOfT<TResultType> v, Node n)88         internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
89 #endregion
90     }
91 
92     /// <summary>
93     /// Scans a view - very similar to a ScanTable
94     /// </summary>
95     internal sealed class ScanViewOp : ScanTableBaseOp
96     {
97         #region constructors
98         /// <summary>
99         /// Scan constructor
100         /// </summary>
101         /// <param name="table"></param>
ScanViewOp(Table table)102         internal ScanViewOp(Table table)
103             : base(OpType.ScanView, table)
104         {
105         }
ScanViewOp()106         private ScanViewOp() : base(OpType.ScanView) { }
107 #endregion
108 
109         #region public methods
110         /// <summary>
111         /// Only to be used for pattern matches
112         /// </summary>
113         internal static readonly ScanViewOp Pattern = new ScanViewOp();
114 
115         /// <summary>
116         /// Exactly 1 child
117         /// </summary>
118         internal override int Arity { get { return 1; } }
119 
120         /// <summary>
121         /// Visitor pattern method
122         /// </summary>
123         /// <param name="v">The BasicOpVisitor that is visiting this Op</param>
124         /// <param name="n">The Node that references this Op</param>
125         [DebuggerNonUserCode]
Accept(BasicOpVisitor v, Node n)126         internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
127 
128         /// <summary>
129         /// Visitor pattern method for visitors with a return value
130         /// </summary>
131         /// <param name="v">The visitor</param>
132         /// <param name="n">The node in question</param>
133         /// <returns>An instance of TResultType</returns>
134         [DebuggerNonUserCode]
Accept(BasicOpVisitorOfT<TResultType> v, Node n)135         internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
136         #endregion
137     }
138 
139     /// <summary>
140     /// Scans a virtual extent (ie) a transient collection
141     /// </summary>
142     internal sealed class UnnestOp : RelOp
143     {
144         #region private state
145         private Table m_table;
146         private Var m_var;
147         #endregion
148 
149         #region constructors
UnnestOp(Var v, Table t)150         internal UnnestOp(Var v, Table t) : this()
151         {
152             m_var = v;
153             m_table = t;
154         }
UnnestOp()155         private UnnestOp()
156             : base(OpType.Unnest)
157         {
158         }
159 #endregion
160 
161         #region publics
162         internal static readonly UnnestOp Pattern = new UnnestOp();
163 
164         /// <summary>
165         /// The (collection-typed) Var that's being unnested
166         /// </summary>
167         internal Var Var { get { return m_var; } }
168 
169         /// <summary>
170         /// The table instance produced by this Op
171         /// </summary>
172         internal Table Table { get { return m_table; } }
173 
174         /// <summary>
175         /// Exactly 1 child
176         /// </summary>
177         internal override int Arity { get { return 1; } }
178 
179         /// <summary>
180         /// Visitor pattern method
181         /// </summary>
182         /// <param name="v">The BasicOpVisitor that is visiting this Op</param>
183         /// <param name="n">The Node that references this Op</param>
184         [DebuggerNonUserCode]
Accept(BasicOpVisitor v, Node n)185         internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
186 
187         /// <summary>
188         /// Visitor pattern method for visitors with a return value
189         /// </summary>
190         /// <param name="v">The visitor</param>
191         /// <param name="n">The node in question</param>
192         /// <returns>An instance of TResultType</returns>
193         [DebuggerNonUserCode]
Accept(BasicOpVisitorOfT<TResultType> v, Node n)194         internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
195         #endregion
196     }
197 
198     /// <summary>
199     /// Base class for all Join operations
200     /// </summary>
201     internal abstract class JoinBaseOp : RelOp
202     {
203         #region constructors
JoinBaseOp(OpType opType)204         internal JoinBaseOp(OpType opType) : base(opType) { }
205         #endregion
206 
207         #region public surface
208         /// <summary>
209         /// 3 children - left, right, pred
210         /// </summary>
211         internal override int Arity { get { return 3; } }
212         #endregion
213     }
214 
215     /// <summary>
216     /// A CrossJoin (n-way)
217     /// </summary>
218     internal sealed class CrossJoinOp : JoinBaseOp
219     {
220         #region constructors
CrossJoinOp()221         private CrossJoinOp() : base(OpType.CrossJoin) { }
222         #endregion
223 
224         #region public methods
225         /// <summary>
226         /// Singleton instance
227         /// </summary>
228         internal static readonly CrossJoinOp Instance = new CrossJoinOp();
229         internal static readonly CrossJoinOp Pattern = CrossJoinOp.Instance;
230 
231         /// <summary>
232         /// varying number of children (but usually greater than 1)
233         /// </summary>
234         internal override int Arity { get { return ArityVarying; } }
235 
236         /// <summary>
237         /// Visitor pattern method
238         /// </summary>
239         /// <param name="v">The BasicOpVisitor that is visiting this Op</param>
240         /// <param name="n">The Node that references this Op</param>
241         [DebuggerNonUserCode]
Accept(BasicOpVisitor v, Node n)242         internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
243 
244         /// <summary>
245         /// Visitor pattern method for visitors with a return value
246         /// </summary>
247         /// <param name="v">The visitor</param>
248         /// <param name="n">The node in question</param>
249         /// <returns>An instance of TResultType</returns>
250         [DebuggerNonUserCode]
Accept(BasicOpVisitorOfT<TResultType> v, Node n)251         internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
252         #endregion
253     }
254 
255     /// <summary>
256     /// An InnerJoin
257     /// </summary>
258     internal sealed class InnerJoinOp : JoinBaseOp
259     {
260         #region constructors
InnerJoinOp()261         private InnerJoinOp() : base(OpType.InnerJoin) { }
262         #endregion
263 
264         #region public methods
265         internal static readonly InnerJoinOp Instance = new InnerJoinOp();
266         internal static readonly InnerJoinOp Pattern = InnerJoinOp.Instance;
267 
268         /// <summary>
269         /// Visitor pattern method
270         /// </summary>
271         /// <param name="v">The BasicOpVisitor that is visiting this Op</param>
272         /// <param name="n">The Node that references this Op</param>
273         [DebuggerNonUserCode]
Accept(BasicOpVisitor v, Node n)274         internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
275 
276         /// <summary>
277         /// Visitor pattern method for visitors with a return value
278         /// </summary>
279         /// <param name="v">The visitor</param>
280         /// <param name="n">The node in question</param>
281         /// <returns>An instance of TResultType</returns>
282         [DebuggerNonUserCode]
Accept(BasicOpVisitorOfT<TResultType> v, Node n)283         internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
284         #endregion
285     }
286 
287     /// <summary>
288     /// A LeftOuterJoin
289     /// </summary>
290     internal sealed class LeftOuterJoinOp : JoinBaseOp
291     {
292         #region constructors
LeftOuterJoinOp()293         private LeftOuterJoinOp() : base(OpType.LeftOuterJoin) { }
294         #endregion
295 
296         #region public methods
297         internal static readonly LeftOuterJoinOp Instance = new LeftOuterJoinOp();
298         internal static readonly LeftOuterJoinOp Pattern = LeftOuterJoinOp.Instance;
299 
300         /// <summary>
301         /// Visitor pattern method
302         /// </summary>
303         /// <param name="v">The BasicOpVisitor that is visiting this Op</param>
304         /// <param name="n">The Node that references this Op</param>
305         [DebuggerNonUserCode]
Accept(BasicOpVisitor v, Node n)306         internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
307 
308         /// <summary>
309         /// Visitor pattern method for visitors with a return value
310         /// </summary>
311         /// <param name="v">The visitor</param>
312         /// <param name="n">The node in question</param>
313         /// <returns>An instance of TResultType</returns>
314         [DebuggerNonUserCode]
Accept(BasicOpVisitorOfT<TResultType> v, Node n)315         internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
316         #endregion
317     }
318 
319     /// <summary>
320     /// A FullOuterJoin
321     /// </summary>
322     internal sealed class FullOuterJoinOp : JoinBaseOp
323     {
324         #region private constructors
FullOuterJoinOp()325         private FullOuterJoinOp() : base(OpType.FullOuterJoin) { }
326         #endregion
327 
328         #region public methods
329         internal static readonly FullOuterJoinOp Instance = new FullOuterJoinOp();
330         internal static readonly FullOuterJoinOp Pattern = FullOuterJoinOp.Instance;
331 
332         /// <summary>
333         /// Visitor pattern method
334         /// </summary>
335         /// <param name="v">The BasicOpVisitor that is visiting this Op</param>
336         /// <param name="n">The Node that references this Op</param>
337         [DebuggerNonUserCode]
Accept(BasicOpVisitor v, Node n)338         internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
339 
340         /// <summary>
341         /// Visitor pattern method for visitors with a return value
342         /// </summary>
343         /// <param name="v">The visitor</param>
344         /// <param name="n">The node in question</param>
345         /// <returns>An instance of TResultType</returns>
346         [DebuggerNonUserCode]
Accept(BasicOpVisitorOfT<TResultType> v, Node n)347         internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
348         #endregion
349     }
350 
351     /// <summary>
352     /// Base class for all Apply Ops
353     /// </summary>
354     internal abstract class ApplyBaseOp : RelOp
355     {
356         #region constructors
ApplyBaseOp(OpType opType)357         internal ApplyBaseOp(OpType opType) : base(opType) { }
358         #endregion
359 
360         #region public surface
361         /// <summary>
362         /// 2 children - left, right
363         /// </summary>
364         internal override int Arity { get { return 2; } }
365         #endregion
366     }
367 
368     /// <summary>
369     /// CrossApply
370     /// </summary>
371     internal sealed class CrossApplyOp : ApplyBaseOp
372     {
373         #region constructors
CrossApplyOp()374         private CrossApplyOp() : base(OpType.CrossApply) { }
375         #endregion
376 
377         #region public methods
378         internal static readonly CrossApplyOp Instance = new CrossApplyOp();
379         internal static readonly CrossApplyOp Pattern = CrossApplyOp.Instance;
380 
381         /// <summary>
382         /// Visitor pattern method
383         /// </summary>
384         /// <param name="v">The BasicOpVisitor that is visiting this Op</param>
385         /// <param name="n">The Node that references this Op</param>
386         [DebuggerNonUserCode]
Accept(BasicOpVisitor v, Node n)387         internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
388 
389         /// <summary>
390         /// Visitor pattern method for visitors with a return value
391         /// </summary>
392         /// <param name="v">The visitor</param>
393         /// <param name="n">The node in question</param>
394         /// <returns>An instance of TResultType</returns>
395         [DebuggerNonUserCode]
Accept(BasicOpVisitorOfT<TResultType> v, Node n)396         internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
397         #endregion
398     }
399 
400     /// <summary>
401     /// OuterApply
402     /// </summary>
403     internal sealed class OuterApplyOp : ApplyBaseOp
404     {
405         #region constructors
OuterApplyOp()406         private OuterApplyOp() : base(OpType.OuterApply) { }
407         #endregion
408 
409         #region public methods
410         internal static readonly OuterApplyOp Instance = new OuterApplyOp();
411         internal static readonly OuterApplyOp Pattern = OuterApplyOp.Instance;
412 
413         /// <summary>
414         /// Visitor pattern method
415         /// </summary>
416         /// <param name="v">The BasicOpVisitor that is visiting this Op</param>
417         /// <param name="n">The Node that references this Op</param>
418         [DebuggerNonUserCode]
Accept(BasicOpVisitor v, Node n)419         internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
420 
421         /// <summary>
422         /// Visitor pattern method for visitors with a return value
423         /// </summary>
424         /// <param name="v">The visitor</param>
425         /// <param name="n">The node in question</param>
426         /// <returns>An instance of TResultType</returns>
427         [DebuggerNonUserCode]
Accept(BasicOpVisitorOfT<TResultType> v, Node n)428         internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
429         #endregion
430     }
431 
432     /// <summary>
433     /// FilterOp
434     /// </summary>
435     internal sealed class FilterOp : RelOp
436     {
437         #region constructors
FilterOp()438         private FilterOp() : base(OpType.Filter) { }
439         #endregion
440 
441         #region public methods
442         internal static readonly FilterOp Instance = new FilterOp();
443         internal static readonly FilterOp Pattern = FilterOp.Instance;
444 
445         /// <summary>
446         /// 2 children - input, pred
447         /// </summary>
448         internal override int Arity { get { return 2; } }
449 
450         /// <summary>
451         /// Visitor pattern method
452         /// </summary>
453         /// <param name="v">The BasicOpVisitor that is visiting this Op</param>
454         /// <param name="n">The Node that references this Op</param>
455         [DebuggerNonUserCode]
Accept(BasicOpVisitor v, Node n)456         internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
457 
458         /// <summary>
459         /// Visitor pattern method for visitors with a return value
460         /// </summary>
461         /// <param name="v">The visitor</param>
462         /// <param name="n">The node in question</param>
463         /// <returns>An instance of TResultType</returns>
464         [DebuggerNonUserCode]
Accept(BasicOpVisitorOfT<TResultType> v, Node n)465         internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
466         #endregion
467     }
468 
469     /// <summary>
470     /// ProjectOp
471     /// </summary>
472     internal sealed class ProjectOp : RelOp
473     {
474         #region private state
475         private VarVec m_vars;
476         #endregion
477 
478         #region constructors
ProjectOp()479         private ProjectOp()
480             : base(OpType.Project)
481         { }
ProjectOp(VarVec vars)482         internal ProjectOp(VarVec vars) : this()
483         {
484             Debug.Assert(null != vars, "null vars?");
485             Debug.Assert(!vars.IsEmpty, "empty varlist?");
486             m_vars = vars;
487         }
488         #endregion
489 
490         #region public methods
491         internal static readonly ProjectOp Pattern = new ProjectOp();
492 
493         /// <summary>
494         /// 2 children - input, projections (VarDefList)
495         /// </summary>
496         internal override int Arity { get { return 2; } }
497 
498         /// <summary>
499         /// The Vars projected by this Op
500         /// </summary>
501         internal VarVec Outputs { get { return m_vars; } }
502 
503         /// <summary>
504         /// Visitor pattern method
505         /// </summary>
506         /// <param name="v">The BasicOpVisitor that is visiting this Op</param>
507         /// <param name="n">The Node that references this Op</param>
508         [DebuggerNonUserCode]
Accept(BasicOpVisitor v, Node n)509         internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
510 
511         /// <summary>
512         /// Visitor pattern method for visitors with a return value
513         /// </summary>
514         /// <param name="v">The visitor</param>
515         /// <param name="n">The node in question</param>
516         /// <returns>An instance of TResultType</returns>
517         [DebuggerNonUserCode]
Accept(BasicOpVisitorOfT<TResultType> v, Node n)518         internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
519         #endregion
520     }
521 
522     /// <summary>
523     /// A Sortkey
524     /// </summary>
525     internal class SortKey
526     {
527         #region private state
528         private Var m_var;
529         private bool m_asc;
530         private string m_collation;
531         #endregion
532 
533         #region constructors
SortKey(Var v, bool asc, string collation)534         internal SortKey(Var v, bool asc, string collation)
535         {
536             m_var = v;
537             m_asc = asc;
538             m_collation = collation;
539         }
540         #endregion
541 
542         #region public methods
543         /// <summary>
544         /// The Var being sorted
545         /// </summary>
546         internal Var Var
547         {
548             get { return m_var; }
549             set { m_var = value; }
550         }
551 
552         /// <summary>
553         /// Is this a sort asc, or a sort desc
554         /// </summary>
555         internal bool AscendingSort { get { return m_asc; } }
556 
557         /// <summary>
558         /// An optional collation (only for string types)
559         /// </summary>
560         internal string Collation { get { return m_collation; } }
561         #endregion
562     }
563 
564     /// <summary>
565     /// Base type for SortOp and ConstrainedSortOp
566     /// </summary>
567     internal abstract class SortBaseOp : RelOp
568     {
569         #region private state
570         private List<SortKey> m_keys;
571         #endregion
572 
573         #region Constructors
574         // Pattern constructor
SortBaseOp(OpType opType)575         internal SortBaseOp(OpType opType)
576             : base(opType)
577         {
578             Debug.Assert(opType == OpType.Sort || opType == OpType.ConstrainedSort, "SortBaseOp OpType must be Sort or ConstrainedSort");
579         }
580 
SortBaseOp(OpType opType, List<SortKey> sortKeys)581         internal SortBaseOp(OpType opType, List<SortKey> sortKeys)
582             : this(opType)
583         {
584             m_keys = sortKeys;
585         }
586 
587         #endregion
588 
589         /// <summary>
590         /// Sort keys
591         /// </summary>
592         internal List<SortKey> Keys { get { return m_keys; } }
593     }
594 
595     /// <summary>
596     /// A SortOp
597     /// </summary>
598     internal sealed class SortOp : SortBaseOp
599     {
600         #region constructors
SortOp()601         private SortOp() : base(OpType.Sort) { }
602 
SortOp(List<SortKey> sortKeys)603         internal SortOp(List<SortKey> sortKeys) : base(OpType.Sort, sortKeys) {}
604         #endregion
605 
606         #region public methods
607         internal static readonly SortOp Pattern = new SortOp();
608 
609         /// <summary>
610         /// 1 child - the input, SortOp must not contain local VarDefs
611         /// </summary>
612         internal override int Arity { get { return 1; } }
613 
614         /// <summary>
615         /// Visitor pattern method
616         /// </summary>
617         /// <param name="v">The BasicOpVisitor that is visiting this Op</param>
618         /// <param name="n">The Node that references this Op</param>
619         [DebuggerNonUserCode]
Accept(BasicOpVisitor v, Node n)620         internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
621 
622         /// <summary>
623         /// Visitor pattern method for visitors with a return value
624         /// </summary>
625         /// <param name="v">The visitor</param>
626         /// <param name="n">The node in question</param>
627         /// <returns>An instance of TResultType</returns>
628         [DebuggerNonUserCode]
Accept(BasicOpVisitorOfT<TResultType> v, Node n)629         internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
630         #endregion
631     }
632 
633     /// <summary>
634     /// A Constrained SortOp. Used to represent physical paging (skip, limit, skip + limit) operations.
635     /// </summary>
636     internal sealed class ConstrainedSortOp : SortBaseOp
637     {
638         #region private state
639         private bool _withTies;
640         #endregion
641 
642         #region constructors
643         // Pattern constructor
ConstrainedSortOp()644         private ConstrainedSortOp() : base(OpType.ConstrainedSort) { }
645 
ConstrainedSortOp(List<SortKey> sortKeys, bool withTies)646         internal ConstrainedSortOp(List<SortKey> sortKeys, bool withTies)
647             : base(OpType.ConstrainedSort, sortKeys)
648         {
649             _withTies = withTies;
650         }
651         #endregion
652 
653         #region public methods
654         internal bool WithTies { get { return _withTies; } set { _withTies = value; } }
655 
656         internal static readonly ConstrainedSortOp Pattern = new ConstrainedSortOp();
657 
658         /// <summary>
659         /// 3 children - the input, a possibly NullOp limit and a possibly NullOp skip count.
660         /// </summary>
661         internal override int Arity { get { return 3; } }
662 
663         /// <summary>
664         /// Visitor pattern method
665         /// </summary>
666         /// <param name="v">The BasicOpVisitor that is visiting this Op</param>
667         /// <param name="n">The Node that references this Op</param>
668         [DebuggerNonUserCode]
Accept(BasicOpVisitor v, Node n)669         internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
670 
671         /// <summary>
672         /// Visitor pattern method for visitors with a return value
673         /// </summary>
674         /// <param name="v">The visitor</param>
675         /// <param name="n">The node in question</param>
676         /// <returns>An instance of TResultType</returns>
677         [DebuggerNonUserCode]
Accept(BasicOpVisitorOfT<TResultType> v, Node n)678         internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
679         #endregion
680     }
681 
682     /// <summary>
683     /// GroupByBaseOp
684     /// </summary>
685     internal abstract class GroupByBaseOp : RelOp
686     {
687         #region private state
688         private VarVec m_keys;
689         private VarVec m_outputs;
690         #endregion
691 
692         #region constructors
GroupByBaseOp(OpType opType)693         protected GroupByBaseOp(OpType opType) : base(opType)
694         {
695             Debug.Assert(opType == OpType.GroupBy || opType == OpType.GroupByInto, "GroupByBaseOp OpType must be GroupBy or GroupByInto");
696         }
GroupByBaseOp(OpType opType, VarVec keys, VarVec outputs)697         internal GroupByBaseOp(OpType opType, VarVec keys, VarVec outputs)
698             : this(opType)
699         {
700             m_keys = keys;
701             m_outputs = outputs;
702         }
703         #endregion
704 
705         #region public methods
706         /// <summary>
707         /// GroupBy keys
708         /// </summary>
709         internal VarVec Keys { get { return m_keys; } }
710 
711         /// <summary>
712         /// All outputs of this Op - includes keys and aggregates
713         /// </summary>
714         internal VarVec Outputs { get { return m_outputs; } }
715 
716         /// <summary>
717         /// Visitor pattern method
718         /// </summary>
719         /// <param name="v">The BasicOpVisitor that is visiting this Op</param>
720         /// <param name="n">The Node that references this Op</param>
721         [DebuggerNonUserCode]
Accept(BasicOpVisitor v, Node n)722         internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
723 
724         /// <summary>
725         /// Visitor pattern method for visitors with a return value
726         /// </summary>
727         /// <param name="v">The visitor</param>
728         /// <param name="n">The node in question</param>
729         /// <returns>An instance of TResultType</returns>
730         [DebuggerNonUserCode]
Accept(BasicOpVisitorOfT<TResultType> v, Node n)731         internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
732         #endregion
733     }
734 
735     /// <summary>
736     /// GroupByOp
737     /// </summary>
738     internal sealed class GroupByOp : GroupByBaseOp
739     {
740         #region constructors
GroupByOp()741         private GroupByOp() : base(OpType.GroupBy) { }
GroupByOp(VarVec keys, VarVec outputs)742         internal GroupByOp(VarVec keys, VarVec outputs)
743             : base(OpType.GroupBy, keys, outputs)
744         {
745         }
746         #endregion
747 
748         #region public methods
749         internal static readonly GroupByOp Pattern = new GroupByOp();
750 
751         /// <summary>
752         /// 3 children - input, keys (vardeflist), aggregates (vardeflist)
753         /// </summary>
754         internal override int Arity { get { return 3; } }
755 
756         /// <summary>
757         /// Visitor pattern method
758         /// </summary>
759         /// <param name="v">The BasicOpVisitor that is visiting this Op</param>
760         /// <param name="n">The Node that references this Op</param>
761         [DebuggerNonUserCode]
Accept(BasicOpVisitor v, Node n)762         internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
763 
764         /// <summary>
765         /// Visitor pattern method for visitors with a return value
766         /// </summary>
767         /// <param name="v">The visitor</param>
768         /// <param name="n">The node in question</param>
769         /// <returns>An instance of TResultType</returns>
770         [DebuggerNonUserCode]
Accept(BasicOpVisitorOfT<TResultType> v, Node n)771         internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
772         #endregion
773     }
774 
775     /// <summary>
776     /// GroupByIntoOp
777     /// </summary>
778     internal sealed class GroupByIntoOp : GroupByBaseOp
779     {
780         #region private state
781         private readonly VarVec m_inputs;
782         #endregion
783 
784         #region constructors
GroupByIntoOp()785         private GroupByIntoOp() : base(OpType.GroupByInto) { }
GroupByIntoOp(VarVec keys, VarVec inputs, VarVec outputs)786         internal GroupByIntoOp(VarVec keys, VarVec inputs, VarVec outputs)
787             : base(OpType.GroupByInto, keys, outputs)
788         {
789             this.m_inputs = inputs;
790         }
791         #endregion
792 
793         #region public methods
794         /// <summary>
795         /// GroupBy keys
796         /// </summary>
797         internal VarVec Inputs { get { return m_inputs; } }
798 
799         internal static readonly GroupByIntoOp Pattern = new GroupByIntoOp();
800 
801         /// <summary>
802         /// 4 children - input, keys (vardeflist), aggregates (vardeflist), groupaggregates (vardeflist)
803         /// </summary>
804         internal override int Arity { get { return 4; } }
805 
806         /// <summary>
807         /// Visitor pattern method
808         /// </summary>
809         /// <param name="v">The BasicOpVisitor that is visiting this Op</param>
810         /// <param name="n">The Node that references this Op</param>
811         [DebuggerNonUserCode]
Accept(BasicOpVisitor v, Node n)812         internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
813 
814         /// <summary>
815         /// Visitor pattern method for visitors with a return value
816         /// </summary>
817         /// <param name="v">The visitor</param>
818         /// <param name="n">The node in question</param>
819         /// <returns>An instance of TResultType</returns>
820         [DebuggerNonUserCode]
Accept(BasicOpVisitorOfT<TResultType> v, Node n)821         internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
822         #endregion
823     }
824 
825     /// <summary>
826     /// Base class for set operations - union, intersect, except
827     /// </summary>
828     internal abstract class SetOp : RelOp
829     {
830         #region private state
831         private VarMap[] m_varMap;
832         private VarVec m_outputVars;
833         #endregion
834 
835         #region constructors
SetOp(OpType opType, VarVec outputs, VarMap left, VarMap right)836         internal SetOp(OpType opType, VarVec outputs, VarMap left, VarMap right)
837             : this(opType)
838         {
839             m_varMap = new VarMap[2];
840             m_varMap[0] = left;
841             m_varMap[1] = right;
842             m_outputVars = outputs;
843         }
SetOp(OpType opType)844         protected SetOp(OpType opType) : base(opType)
845         {
846         }
847         #endregion
848 
849         #region public methods
850 
851         /// <summary>
852         /// 2 children - left, right
853         /// </summary>
854         internal override int Arity { get { return 2; } }
855 
856         /// <summary>
857         /// Map of result vars to the vars of each branch of the setOp
858         /// </summary>
859         internal VarMap[] VarMap { get { return m_varMap; } }
860 
861         /// <summary>
862         /// Get the set of output vars produced
863         /// </summary>
864         internal VarVec Outputs { get { return m_outputVars; } }
865         #endregion
866     }
867 
868     /// <summary>
869     /// UnionAll (ie) no duplicate elimination
870     /// </summary>
871     internal sealed class UnionAllOp : SetOp
872     {
873         #region private state
874         private Var m_branchDiscriminator;
875         #endregion
876 
877         #region constructors
UnionAllOp()878         private UnionAllOp() : base(OpType.UnionAll) { }
879 
UnionAllOp(VarVec outputs, VarMap left, VarMap right, Var branchDiscriminator)880         internal UnionAllOp(VarVec outputs, VarMap left, VarMap right, Var branchDiscriminator) : base(OpType.UnionAll, outputs, left, right)
881         {
882             m_branchDiscriminator = branchDiscriminator;
883         }
884         #endregion
885 
886         #region public methods
887         internal static readonly UnionAllOp Pattern = new UnionAllOp();
888 
889         /// <summary>
890         /// Returns the branch discriminator var for this op.  It may be null, if
891         /// we haven't been through key pullup yet.
892         /// </summary>
893         internal Var BranchDiscriminator { get { return m_branchDiscriminator; } }
894 
895         /// <summary>
896         /// Visitor pattern method
897         /// </summary>
898         /// <param name="v">The BasicOpVisitor that is visiting this Op</param>
899         /// <param name="n">The Node that references this Op</param>
900         [DebuggerNonUserCode]
Accept(BasicOpVisitor v, Node n)901         internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
902 
903         /// <summary>
904         /// Visitor pattern method for visitors with a return value
905         /// </summary>
906         /// <param name="v">The visitor</param>
907         /// <param name="n">The node in question</param>
908         /// <returns>An instance of TResultType</returns>
909         [DebuggerNonUserCode]
Accept(BasicOpVisitorOfT<TResultType> v, Node n)910         internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
911         #endregion
912     }
913 
914     /// <summary>
915     /// An IntersectOp
916     /// </summary>
917     internal sealed class IntersectOp : SetOp
918     {
919         #region constructors
IntersectOp()920         private IntersectOp() : base(OpType.Intersect) { }
IntersectOp(VarVec outputs, VarMap left, VarMap right)921         internal IntersectOp(VarVec outputs, VarMap left, VarMap right) : base(OpType.Intersect, outputs, left,right) { }
922 #endregion
923 
924         #region public methods
925         internal static readonly IntersectOp Pattern = new IntersectOp();
926 
927         /// <summary>
928         /// Visitor pattern method
929         /// </summary>
930         /// <param name="v">The BasicOpVisitor that is visiting this Op</param>
931         /// <param name="n">The Node that references this Op</param>
932         [DebuggerNonUserCode]
Accept(BasicOpVisitor v, Node n)933         internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
934 
935         /// <summary>
936         /// Visitor pattern method for visitors with a return value
937         /// </summary>
938         /// <param name="v">The visitor</param>
939         /// <param name="n">The node in question</param>
940         /// <returns>An instance of TResultType</returns>
941         [DebuggerNonUserCode]
Accept(BasicOpVisitorOfT<TResultType> v, Node n)942         internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
943         #endregion
944     }
945 
946     /// <summary>
947     /// ExceptOp (Minus)
948     /// </summary>
949     internal sealed class ExceptOp : SetOp
950     {
951         #region constructors
ExceptOp()952         private ExceptOp() : base(OpType.Except) { }
ExceptOp(VarVec outputs, VarMap left, VarMap right)953         internal ExceptOp(VarVec outputs, VarMap left, VarMap right) : base(OpType.Except, outputs, left, right) { }
954         #endregion
955 
956         #region public methods
957         internal static readonly ExceptOp Pattern = new ExceptOp();
958 
959         /// <summary>
960         /// Visitor pattern method
961         /// </summary>
962         /// <param name="v">The BasicOpVisitor that is visiting this Op</param>
963         /// <param name="n">The Node that references this Op</param>
964         [DebuggerNonUserCode]
Accept(BasicOpVisitor v, Node n)965         internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
966 
967         /// <summary>
968         /// Visitor pattern method for visitors with a return value
969         /// </summary>
970         /// <param name="v">The visitor</param>
971         /// <param name="n">The node in question</param>
972         /// <returns>An instance of TResultType</returns>
973         [DebuggerNonUserCode]
Accept(BasicOpVisitorOfT<TResultType> v, Node n)974         internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
975         #endregion
976     }
977 
978     /// <summary>
979     /// DistinctOp
980     /// </summary>
981     internal sealed class DistinctOp : RelOp
982     {
983         #region private state
984         private VarVec m_keys;
985         #endregion
986 
987         #region constructors
DistinctOp()988         private DistinctOp() : base(OpType.Distinct)
989         {
990         }
DistinctOp(VarVec keyVars)991         internal DistinctOp(VarVec keyVars) : this()
992         {
993             Debug.Assert(keyVars != null);
994             Debug.Assert(!keyVars.IsEmpty);
995             m_keys = keyVars;
996         }
997         #endregion
998 
999         #region public methods
1000         internal static readonly DistinctOp Pattern = new DistinctOp();
1001 
1002         /// <summary>
1003         /// 1 child - input
1004         /// </summary>
1005         internal override int Arity { get { return 1; } }
1006 
1007         /// <summary>
1008         /// Get "key" vars for the distinct
1009         /// </summary>
1010         internal VarVec Keys { get { return m_keys; } }
1011 
1012         /// <summary>
1013         /// Visitor pattern method
1014         /// </summary>
1015         /// <param name="v">The BasicOpVisitor that is visiting this Op</param>
1016         /// <param name="n">The Node that references this Op</param>
1017         [DebuggerNonUserCode]
Accept(BasicOpVisitor v, Node n)1018         internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
1019 
1020         /// <summary>
1021         /// Visitor pattern method for visitors with a return value
1022         /// </summary>
1023         /// <param name="v">The visitor</param>
1024         /// <param name="n">The node in question</param>
1025         /// <returns>An instance of TResultType</returns>
1026         [DebuggerNonUserCode]
Accept(BasicOpVisitorOfT<TResultType> v, Node n)1027         internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
1028         #endregion
1029     }
1030 
1031     /// <summary>
1032     /// Selects out a single row from a underlying subquery. Two flavors of this Op exist.
1033     /// The first flavor enforces the single-row-ness (ie) an error is raised if the
1034     /// underlying subquery produces more than one row.
1035     /// The other flavor simply choses any row from the input
1036     /// </summary>
1037     internal sealed class SingleRowOp : RelOp
1038     {
1039         #region constructors
SingleRowOp()1040         private SingleRowOp() : base(OpType.SingleRow) { }
1041         #endregion
1042 
1043         #region public methods
1044         /// <summary>
1045         /// Singleton instance
1046         /// </summary>
1047         internal static readonly SingleRowOp Instance = new SingleRowOp();
1048         /// <summary>
1049         /// Pattern for transformation rules
1050         /// </summary>
1051         internal static readonly SingleRowOp Pattern = Instance;
1052 
1053         /// <summary>
1054         /// 1 child - input
1055         /// </summary>
1056         internal override int Arity { get { return 1; } }
1057 
1058         /// <summary>
1059         /// Visitor pattern method
1060         /// </summary>
1061         /// <param name="v">The BasicOpVisitor that is visiting this Op</param>
1062         /// <param name="n">The Node that references this Op</param>
1063         [DebuggerNonUserCode]
Accept(BasicOpVisitor v, Node n)1064         internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
1065 
1066         /// <summary>
1067         /// Visitor pattern method for visitors with a return value
1068         /// </summary>
1069         /// <param name="v">The visitor</param>
1070         /// <param name="n">The node in question</param>
1071         /// <returns>An instance of TResultType</returns>
1072         [DebuggerNonUserCode]
Accept(BasicOpVisitorOfT<TResultType> v, Node n)1073         internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
1074 
1075         #endregion
1076     }
1077 
1078     /// <summary>
1079     /// Represents a table with a single row
1080     /// </summary>
1081     internal sealed class SingleRowTableOp : RelOp
1082     {
1083         #region constructors
SingleRowTableOp()1084         private SingleRowTableOp() : base(OpType.SingleRowTable) { }
1085         #endregion
1086 
1087         #region public methods
1088         /// <summary>
1089         /// Singleton instance
1090         /// </summary>
1091         internal static readonly SingleRowTableOp Instance = new SingleRowTableOp();
1092         /// <summary>
1093         /// Pattern for transformation rules
1094         /// </summary>
1095         internal static readonly SingleRowTableOp Pattern = Instance;
1096 
1097         /// <summary>
1098         /// 0 children
1099         /// </summary>
1100         internal override int Arity { get { return 0; } }
1101 
1102         /// <summary>
1103         /// Visitor pattern method
1104         /// </summary>
1105         /// <param name="v">The BasicOpVisitor that is visiting this Op</param>
1106         /// <param name="n">The Node that references this Op</param>
1107         [DebuggerNonUserCode]
Accept(BasicOpVisitor v, Node n)1108         internal override void Accept(BasicOpVisitor v, Node n) { v.Visit(this, n); }
1109 
1110         /// <summary>
1111         /// Visitor pattern method for visitors with a return value
1112         /// </summary>
1113         /// <param name="v">The visitor</param>
1114         /// <param name="n">The node in question</param>
1115         /// <returns>An instance of TResultType</returns>
1116         [DebuggerNonUserCode]
Accept(BasicOpVisitorOfT<TResultType> v, Node n)1117         internal override TResultType Accept<TResultType>(BasicOpVisitorOfT<TResultType> v, Node n) { return v.Visit(this, n); }
1118 
1119         #endregion
1120     }
1121 
1122 }
1123