public override void Invoke(SpoolSpace Memory) { // Add spools // this.AddSpools(Memory); // Render each table // Table ltable = (this._Parameters[0]).Select(Memory); Table rtable = (this._Parameters[1]).Select(Memory); string lalias = this._Parameters[0].NameOf(); string ralias = this._Parameters[1].NameOf(); // Get the left and right join index // TreeIndex lidx = ltable.GetIndex(this._LKey) ?? TreeIndex.BuildTemporaryIndex(ltable, this._LKey); //lidx.Tree.DumpMeta(@"C:\Users\pwdlu_000\Documents\Spectre_Projects\Test\treeJoinT1.txt"); TreeIndex ridx = rtable.GetIndex(this._RKey) ?? TreeIndex.BuildTemporaryIndex(rtable, this._RKey); // Get the join tags // bool Intersection = (this._Affinity == JoinAffinity.Inner || this._Affinity == JoinAffinity.Left); bool Antisection = (this._Affinity == JoinAffinity.Left || this._Affinity == JoinAffinity.AntiLeft); // Open a read stream // RecordReader lstream = lidx.OpenReader(); RecordReader rstream = ridx.OpenReader(); // Render some null records // Record RNull = rstream.Columns.NullRecord; // Main loop through both left and right while (lstream.CanAdvance && rstream.CanAdvance) { Record lrec = lstream.Read(); Record rrec = rstream.Read(); int Compare = Record.Compare(lrec, this._LKey, rrec, this._RKey); // Left is less than right, control left if (Compare < 0) { lstream.Advance(); } // AWValue is less than left, control right, but also output an anti join record else if (Compare > 0) { if (Antisection) { Memory[lalias].Set(lrec); Memory[ralias].Set(RNull); if (this._Filter.Evaluate(Memory)) { this.InvokeChildren(Memory); } } rstream.Advance(); } else if (Intersection) // Compare == 0 { // Save the loop-result // int NestedLoopCount = 0; // Loop through all possible tuples // while (Compare == 0) { // Render the record and potentially output // Memory[lalias].Set(lstream.Read()); Memory[ralias].Set(rstream.Read()); if (this._Filter.Evaluate(Memory)) { this.InvokeChildren(Memory); } // Advance the right table // rstream.Advance(); NestedLoopCount++; // Check if this advancing pushed us to the end of the table // if (!rstream.CanAdvance) { break; } // Reset the compare token // Compare = Record.Compare(lstream.Read(), this._LKey, rstream.Read(), this._RKey); } // Revert the nested loops // rstream.Revert(NestedLoopCount); // Step the left stream // lstream.Advance(); } else { lstream.Advance(); } } // Do Anti-Join // if (Antisection) { // Assign the right table to null // Memory[ralias].Set(RNull); // Walk the rest of the left table // while (lstream.CanAdvance) { Memory[lalias].Set(lstream.ReadNext()); if (this._Filter.Evaluate(Memory)) { this.InvokeChildren(Memory); } } } // Add spools // this.RemoveSpools(Memory); }