internal override DbExpression AsCqt(bool isTopLevel) { // The FROM part: // - build a tree of binary joins out of the inputs (this.Children). // - update each child block with its relative position in the join tree, // so that QualifiedSlot and QualifiedCellIdBoolean objects could find their // designated block areas inside the cumulative join row passed into their AsCqt(row) method. CqlBlock leftmostBlock = this.Children[0]; DbExpression left = leftmostBlock.AsCqt(false); List <string> joinTreeCtxParentQualifiers = new List <string>(); for (int i = 1; i < this.Children.Count; ++i) { // Join the current left expression (a tree) to the current right block. CqlBlock rightBlock = this.Children[i]; DbExpression right = rightBlock.AsCqt(false); Func <DbExpression, DbExpression, DbExpression> joinConditionFunc = m_onClauses[i - 1].AsCqt; DbJoinExpression join; switch (m_opType) { case CellTreeOpType.FOJ: join = left.FullOuterJoin(right, joinConditionFunc); break; case CellTreeOpType.IJ: join = left.InnerJoin(right, joinConditionFunc); break; case CellTreeOpType.LOJ: join = left.LeftOuterJoin(right, joinConditionFunc); break; default: Debug.Fail("Unknown operator"); return(null); } if (i == 1) { // Assign the joinTreeContext to the leftmost block. leftmostBlock.SetJoinTreeContext(joinTreeCtxParentQualifiers, join.Left.VariableName); } else { // Update the joinTreeCtxParentQualifiers. // Note that all blocks that already participate in the left expression tree share the same copy of the joinTreeContext. joinTreeCtxParentQualifiers.Add(join.Left.VariableName); } // Assign the joinTreeContext to the right block. rightBlock.SetJoinTreeContext(joinTreeCtxParentQualifiers, join.Right.VariableName); left = join; } // The SELECT part. return(left.Select(row => GenerateProjectionCqt(row, false))); }
internal override DbExpression AsCqt(bool isTopLevel) { CqlBlock child1 = this.Children[0]; DbExpression dbExpression = child1.AsCqt(false); List <string> stringList = new List <string>(); for (int index = 1; index < this.Children.Count; ++index) { CqlBlock child2 = this.Children[index]; DbExpression right = child2.AsCqt(false); Func <DbExpression, DbExpression, DbExpression> joinCondition = new Func <DbExpression, DbExpression, DbExpression>(this.m_onClauses[index - 1].AsCqt); DbJoinExpression dbJoinExpression; switch (this.m_opType) { case CellTreeOpType.FOJ: dbJoinExpression = dbExpression.FullOuterJoin(right, joinCondition); break; case CellTreeOpType.LOJ: dbJoinExpression = dbExpression.LeftOuterJoin(right, joinCondition); break; case CellTreeOpType.IJ: dbJoinExpression = dbExpression.InnerJoin(right, joinCondition); break; default: return((DbExpression)null); } if (index == 1) { child1.SetJoinTreeContext((IList <string>)stringList, dbJoinExpression.Left.VariableName); } else { stringList.Add(dbJoinExpression.Left.VariableName); } child2.SetJoinTreeContext((IList <string>)stringList, dbJoinExpression.Right.VariableName); dbExpression = (DbExpression)dbJoinExpression; } return((DbExpression)dbExpression.Select <DbExpression>((Func <DbExpression, DbExpression>)(row => this.GenerateProjectionCqt(row, false)))); }