Exemple #1
0
        /// <summary>
        /// Processing for all JoinOps
        /// </summary>
        /// <param name="op">JoinOp</param>
        /// <param name="n">Current subtree</param>
        /// <returns>Whether the node was modified</returns>
        protected bool ProcessJoinOp(JoinBaseOp op, Node n)
        {
            VisitChildren(n); // visit all my children first

            // then check to see if we have any nested subqueries. This can only
            // occur in the join condition.
            // What we'll do in this case is to convert the join condition - "p" into
            //    p -> Exists(Filter(SingleRowTableOp, p))
            // We will then move the subqueries into an outerApply on the SingleRowTable
            List <Node> nestedSubqueries;

            if (!m_nodeSubqueries.TryGetValue(n, out nestedSubqueries))
            {
                return(false);
            }

            PlanCompiler.Assert(n.Op.OpType == OpType.InnerJoin ||
                                n.Op.OpType == OpType.LeftOuterJoin ||
                                n.Op.OpType == OpType.FullOuterJoin, "unexpected op?");
            PlanCompiler.Assert(n.HasChild2, "missing second child to JoinOp?");
            Node joinCondition = n.Child2;

            Node inputNode = m_command.CreateNode(m_command.CreateSingleRowTableOp());

            inputNode = AugmentWithSubqueries(inputNode, nestedSubqueries, true);
            Node filterNode = m_command.CreateNode(m_command.CreateFilterOp(), inputNode, joinCondition);
            Node existsNode = m_command.CreateNode(m_command.CreateExistsOp(), filterNode);

            n.Child2 = existsNode;
            return(true);
        }
Exemple #2
0
 protected override Node VisitJoinOp(JoinBaseOp op, Node n)
 {
     if (this.ProcessJoinOp(n))
     {
         n.Child2.Child0 = this.BuildDummyProjectForExists(n.Child2.Child0);
     }
     return(n);
 }
Exemple #3
0
 /// <summary>
 /// Processing for all JoinOps
 /// </summary>
 /// <param name="op">JoinOp</param>
 /// <param name="n">Current subtree</param>
 /// <returns></returns>
 protected override Node VisitJoinOp(JoinBaseOp op, Node n)
 {
     if (base.ProcessJoinOp(op, n))
     {
         // update the join condition
         // #479372: Build up a dummy project node over the input, as we always wrap the child of exists
         n.Child2.Child0 = BuildDummyProjectForExists(n.Child2.Child0);
     }
     return(n);
 }
 /// <summary>
 /// JoinOp handling
 /// CrossJoinOp handling
 /// InnerJoinOp handling
 /// LeftOuterJoinOp handling
 /// FullOuterJoinOp handling
 ///
 /// Handler for all JoinOps. For all joins except cross joins, process
 /// the predicate first, and then the inputs - the inputs can be processed
 /// in any order.
 ///
 /// For cross joins, simply process all the (relop) inputs
 /// </summary>
 /// <param name="op">join op</param>
 /// <param name="n"></param>
 protected override void VisitJoinOp(JoinBaseOp op, Node n)
 {
     if (n.Op.OpType == OpType.CrossJoin)
     {
         VisitChildren(n);
     }
     else
     {
         VisitNode(n.Child2); // the predicate first
         VisitNode(n.Child0); // then, the left input
         VisitNode(n.Child1); // the right input
     }
 }
Exemple #5
0
 protected override void VisitJoinOp(JoinBaseOp op, System.Data.Entity.Core.Query.InternalTrees.Node n)
 {
     if (n.Op.OpType == OpType.CrossJoin)
     {
         this.VisitChildren(n);
     }
     else
     {
         this.VisitNode(n.Child2);
         this.VisitNode(n.Child0);
         this.VisitNode(n.Child1);
     }
 }
Exemple #6
0
 protected override System.Data.Entity.Core.Query.InternalTrees.Node VisitJoinOp(
     JoinBaseOp op,
     System.Data.Entity.Core.Query.InternalTrees.Node n)
 {
     if (n.Op.OpType == OpType.CrossJoin)
     {
         this.VisitChildren(n);
         return(n);
     }
     n.Child2 = this.VisitNode(n.Child2);
     n.Child0 = this.VisitNode(n.Child0);
     n.Child1 = this.VisitNode(n.Child1);
     this.m_command.RecomputeNodeInfo(n);
     return(n);
 }
Exemple #7
0
        // <summary>
        // Convert CrossApply(X, Filter(Y, p)) => InnerJoin(X, Y, p)
        // OuterApply(X, Filter(Y, p)) => LeftOuterJoin(X, Y, p)
        // if "Y" has no external references to X
        // </summary>
        // <param name="context"> Rule processing context </param>
        // <param name="applyNode"> Current ApplyOp </param>
        // <param name="newNode"> transformed subtree </param>
        // <returns> Transformation status </returns>
        private static bool ProcessApplyOverFilter(RuleProcessingContext context, Node applyNode, out Node newNode)
        {
            newNode = applyNode;

            var trc = (TransformationRulesContext)context;

            if (trc.PlanCompiler.TransformationsDeferred)
            {
                return(false);
            }

            var filterNode = applyNode.Child1;
            var command    = context.Command;

            var filterInputNodeInfo    = command.GetNodeInfo(filterNode.Child0);
            var applyLeftChildNodeInfo = command.GetExtendedNodeInfo(applyNode.Child0);

            //
            // check to see if the inputNode to the FilterOp has any external references
            // to the left child of the ApplyOp. If it does, we simply return, we
            // can't do much more here
            //
            if (filterInputNodeInfo.ExternalReferences.Overlaps(applyLeftChildNodeInfo.Definitions))
            {
                return(false);
            }

            //
            // We've now gotten to the stage where the only external references (if any)
            // are from the filter predicate.
            // We can now simply convert the apply into an inner/leftouter join with the
            // filter predicate acting as the join condition
            //
            JoinBaseOp joinOp = null;

            if (applyNode.Op.OpType
                == OpType.CrossApply)
            {
                joinOp = command.CreateInnerJoinOp();
            }
            else
            {
                joinOp = command.CreateLeftOuterJoinOp();
            }

            newNode = command.CreateNode(joinOp, applyNode.Child0, filterNode.Child0, filterNode.Child1);
            return(true);
        }
Exemple #8
0
 protected override System.Data.Entity.Core.Query.InternalTrees.Node VisitJoinOp(
     JoinBaseOp op,
     System.Data.Entity.Core.Query.InternalTrees.Node joinNode)
 {
     System.Data.Entity.Core.Query.InternalTrees.Node n;
     if (this.NeedsJoinGraph(joinNode))
     {
         n = this.ProcessJoinGraph(joinNode);
         if (n != joinNode)
         {
             this.m_treeModified = true;
         }
     }
     else
     {
         n = joinNode;
     }
     return(this.VisitDefaultForAllNodes(n));
 }
        /// <summary>
        /// JoinOps
        ///
        /// Common handling for all join ops. For all joins (other than crossjoin),
        /// we must first visit the predicate (to capture any references from it), and
        /// then visit the relop inputs. The relop inputs can be visited in any order
        /// because there can be no correlations between them
        /// For crossjoins, we simply use the default processing - visit all children
        /// ; there can be no correlations between the nodes anyway
        /// </summary>
        /// <param name="op"></param>
        /// <param name="n">Node for the join subtree</param>
        /// <returns>modified subtree</returns>
        protected override Node VisitJoinOp(JoinBaseOp op, Node n)
        {
            // Simply visit all children for a CrossJoin
            if (n.Op.OpType == OpType.CrossJoin)
            {
                VisitChildren(n);
                return(n);
            }

            // For other joins, we first need to visit the predicate, and then the
            // other inputs
            // first visit the predicate
            n.Child2 = VisitNode(n.Child2);
            // then visit the 2 join inputs
            n.Child0 = VisitNode(n.Child0);
            n.Child1 = VisitNode(n.Child1);
            m_command.RecomputeNodeInfo(n);

            return(n);
        }
Exemple #10
0
        /// <summary>
        /// Build a join graph for this node for this node if necessary, and process it
        /// </summary>
        /// <param name="op">current join op</param>
        /// <param name="joinNode">current join node</param>
        /// <returns></returns>
        protected override Node VisitJoinOp(JoinBaseOp op, Node joinNode)
        {
            Node newNode;

            // Build and process a join graph if necessary
            if (NeedsJoinGraph(joinNode))
            {
                newNode = ProcessJoinGraph(joinNode);
                if (newNode != joinNode)
                {
                    m_treeModified = true;
                }
            }
            else
            {
                newNode = joinNode;
            }

            // Now do the default processing (ie) visit the children, compute the nodeinfo etc.
            return(VisitDefaultForAllNodes(newNode));
        }
        private static bool ProcessApplyOverFilter(
            RuleProcessingContext context,
            System.Data.Entity.Core.Query.InternalTrees.Node applyNode,
            out System.Data.Entity.Core.Query.InternalTrees.Node newNode)
        {
            newNode = applyNode;
            if (((TransformationRulesContext)context).PlanCompiler.TransformationsDeferred)
            {
                return(false);
            }
            System.Data.Entity.Core.Query.InternalTrees.Node child1 = applyNode.Child1;
            Command command = context.Command;

            if (command.GetNodeInfo(child1.Child0).ExternalReferences.Overlaps(command.GetExtendedNodeInfo(applyNode.Child0).Definitions))
            {
                return(false);
            }
            JoinBaseOp joinBaseOp = applyNode.Op.OpType != OpType.CrossApply ? (JoinBaseOp)command.CreateLeftOuterJoinOp() : (JoinBaseOp)command.CreateInnerJoinOp();

            newNode = command.CreateNode((Op)joinBaseOp, applyNode.Child0, child1.Child0, child1.Child1);
            return(true);
        }