/// <summary> /// Augments a node with a number of OuterApply's - one for each subquery /// If S1, S2, ... are the list of subqueries for the node, and D is the /// original (driver) input, we convert D into /// OuterApply(OuterApply(D, S1), S2), ... /// </summary> /// <param name="input">the input (driver) node</param> /// <param name="subqueries">List of subqueries</param> /// <param name="inputFirst">should the input node be first in the apply chain, or the last?</param> /// <returns>The resulting node tree</returns> private Node AugmentWithSubqueries(Node input, List <Node> subqueries, bool inputFirst) { Node newNode; int subqueriesStartPos; if (inputFirst) { newNode = input; subqueriesStartPos = 0; } else { newNode = subqueries[0]; subqueriesStartPos = 1; } for (int i = subqueriesStartPos; i < subqueries.Count; i++) { OuterApplyOp op = m_command.CreateOuterApplyOp(); newNode = m_command.CreateNode(op, newNode, subqueries[i]); } if (!inputFirst) { // The driver node uses a cross apply to ensure that no results are produced // for an empty driver. newNode = m_command.CreateNode(m_command.CreateCrossApplyOp(), newNode, input); } // We may need to perform join elimination m_compilerState.MarkPhaseAsNeeded(PlanCompilerPhase.JoinElimination); return(newNode); }
/// <summary> /// Visitor pattern method for OuterApplyOp /// </summary> /// <param name="op"> The OuterApplyOp being visited </param> /// <param name="n"> The Node that references the Op </param> public virtual void Visit(OuterApplyOp op, Node n) { VisitApplyOp(op, n); }
// <summary> // Clone an OuterApplyOp // </summary> // <param name="op"> The Op to Copy </param> // <param name="n"> The Node that references the Op </param> // <returns> A copy of the original Node that references a copy of the original Op </returns> public override Node Visit(OuterApplyOp op, Node n) { return CopyDefault(m_destCmd.CreateOuterApplyOp(), n); }