Exemplo n.º 1
0
        // <summary>
        // Determines whether an applyNode can be rewritten into a projection with a scalar subquery.
        // It can be done if all of the following conditions hold:
        // 1. The right child or the apply has only one output
        // 2. The right child of the apply produces at most one row
        // 3. The right child of the apply produces at least one row, or the Apply operator in question is an OuterApply
        // </summary>
        private static bool CanRewriteApply(Node rightChild, ExtendedNodeInfo applyRightChildNodeInfo, OpType applyKind)
        {
            //Check whether it produces only one definition
            if (applyRightChildNodeInfo.Definitions.Count != 1)
            {
                return(false);
            }

            //Check whether it produces at most one row
            if (applyRightChildNodeInfo.MaxRows
                != RowCount.One)
            {
                return(false);
            }

            //For cross apply it must also return exactly one row
            if (applyKind == OpType.CrossApply &&
                (applyRightChildNodeInfo.MinRows != RowCount.One))
            {
                return(false);
            }

            //Dev10 #488632: Make sure the right child not only declares to produce only one definition,
            // but has exactly one output. For example, ScanTableOp really outputs all the columns from the table,
            // but in its ExtendedNodeInfo.Definitions only these that are referenced are shown.
            // This is to allow for projection pruning of the unreferenced columns.
            if (OutputCountVisitor.CountOutputs(rightChild) != 1)
            {
                return(false);
            }

            return(true);
        }
Exemplo n.º 2
0
            // <summary>
            // Calculates the number of output columns for the subtree
            // rooted at the given node
            // </summary>
            internal static int CountOutputs(Node node)
            {
                var visitor = new OutputCountVisitor();

                return(visitor.VisitNode(node));
            }