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