Beispiel #1
0
        // <summary>
        // Converts a Apply(X,Y) => Project(X, Y1), where Y1 is a scalar subquery version of Y
        // The transformation is valid only if all of the following conditions hold:
        // 1. Y produces only one output
        // 2. Y produces at most one row
        // 3. Y produces at least one row, or the Apply operator in question is an OuterApply
        // </summary>
        // <param name="context"> Rule processing context </param>
        // <param name="applyNode"> The ApplyOp subtree </param>
        // <param name="newNode"> transformed subtree </param>
        // <returns> the transformation status </returns>
        private static bool ProcessApplyIntoScalarSubquery(RuleProcessingContext context, Node applyNode, out Node newNode)
        {
            var command = context.Command;
            var applyRightChildNodeInfo = command.GetExtendedNodeInfo(applyNode.Child1);
            var applyKind = applyNode.Op.OpType;

            if (!CanRewriteApply(applyNode.Child1, applyRightChildNodeInfo, applyKind))
            {
                newNode = applyNode;
                return(false);
            }

            // Create the project node over the original input with element over the apply as new projected var
            var applyLeftChildNodeInfo = command.GetExtendedNodeInfo(applyNode.Child0);

            var oldVar = applyRightChildNodeInfo.Definitions.First;

            // Project all the outputs from the left child
            var projectOpOutputs = command.CreateVarVec(applyLeftChildNodeInfo.Definitions);

            //
            // Remap the var defining tree to get it into a consistent state
            // and then remove all references to oldVar from it to avoid them being wrongly remapped to newVar
            // in subsequent remappings.
            //
            var trc = (TransformationRulesContext)context;

            trc.RemapSubtree(applyNode.Child1);
            VarDefinitionRemapper.RemapSubtree(applyNode.Child1, command, oldVar);

            var elementNode = command.CreateNode(command.CreateElementOp(oldVar.Type), applyNode.Child1);

            Var newVar;
            var varDefListNode = command.CreateVarDefListNode(elementNode, out newVar);

            projectOpOutputs.Set(newVar);

            newNode = command.CreateNode(
                command.CreateProjectOp(projectOpOutputs),
                applyNode.Child0,
                varDefListNode);

            // Add the var mapping from oldVar to newVar
            trc.AddVarMapping(oldVar, newVar);
            return(true);
        }
Beispiel #2
0
            // <summary>
            // Public entry point.
            // Remaps the subtree rooted at the given tree
            // </summary>
            internal static void RemapSubtree(Node root, Command command, Var oldVar)
            {
                var remapper = new VarDefinitionRemapper(oldVar, command);

                remapper.RemapSubtree(root);
            }