Exemplo n.º 1
0
        private static bool ProcessJoinOverFilter(
            RuleProcessingContext context,
            System.Data.Entity.Core.Query.InternalTrees.Node joinNode,
            out System.Data.Entity.Core.Query.InternalTrees.Node newNode)
        {
            newNode = joinNode;
            TransformationRulesContext transformationRulesContext = (TransformationRulesContext)context;
            Command command = transformationRulesContext.Command;

            System.Data.Entity.Core.Query.InternalTrees.Node node1  = (System.Data.Entity.Core.Query.InternalTrees.Node)null;
            System.Data.Entity.Core.Query.InternalTrees.Node child0 = joinNode.Child0;
            if (joinNode.Child0.Op.OpType == OpType.Filter)
            {
                node1  = joinNode.Child0.Child1;
                child0 = joinNode.Child0.Child0;
            }
            System.Data.Entity.Core.Query.InternalTrees.Node node2 = joinNode.Child1;
            if (joinNode.Child1.Op.OpType == OpType.Filter && joinNode.Op.OpType != OpType.LeftOuterJoin)
            {
                node1 = node1 != null?command.CreateNode((Op)command.CreateConditionalOp(OpType.And), node1, joinNode.Child1.Child1) : joinNode.Child1.Child1;

                node2 = joinNode.Child1.Child0;
            }
            if (node1 == null)
            {
                return(false);
            }
            System.Data.Entity.Core.Query.InternalTrees.Node node3 = joinNode.Op.OpType != OpType.CrossJoin ? command.CreateNode(joinNode.Op, child0, node2, joinNode.Child2) : command.CreateNode(joinNode.Op, child0, node2);
            FilterOp filterOp = command.CreateFilterOp();

            newNode = command.CreateNode((Op)filterOp, node3, node1);
            transformationRulesContext.SuppressFilterPushdown(newNode);
            return(true);
        }
        private static bool ProcessLogOpOverConstant(
            RuleProcessingContext context, Node node,
            Node constantPredicateNode, Node otherNode,
            out Node newNode)
        {
            PlanCompiler.Assert(constantPredicateNode != null, "null constantPredicateOp?");
            var pred = (ConstantPredicateOp)constantPredicateNode.Op;

            switch (node.Op.OpType)
            {
            case OpType.And:
                newNode = pred.IsTrue ? otherNode : constantPredicateNode;
                break;

            case OpType.Or:
                newNode = pred.IsTrue ? constantPredicateNode : otherNode;
                break;

            case OpType.Not:
                PlanCompiler.Assert(otherNode == null, "Not Op with more than 1 child. Gasp!");
                newNode = context.Command.CreateNode(context.Command.CreateConstantPredicateOp(!pred.Value));
                break;

            default:
                PlanCompiler.Assert(false, "Unexpected OpType - " + node.Op.OpType);
                newNode = null;
                break;
            }
            return(true);
        }
Exemplo n.º 3
0
 internal SubTreeId(RuleProcessingContext context, Node node, Node parent, int childIndex)
 {
     m_subTreeRoot = node;
     m_parent      = parent;
     m_childIndex  = childIndex;
     m_hashCode    = context.GetHashCode(node);
 }
Exemplo n.º 4
0
        // <summary>
        // Converts a Project(Project(X, c1,...), d1,...) =>
        // Project(X, d1', d2'...)
        // where d1', d2' etc. are the "mapped" versions of d1, d2 etc.
        // </summary>
        // <param name="context"> Rule processing context </param>
        // <param name="projectNode"> Current ProjectOp node </param>
        // <param name="newNode"> modified subtree </param>
        // <returns> Transformation status </returns>
        private static bool ProcessProjectOverProject(RuleProcessingContext context, Node projectNode, out Node newNode)
        {
            newNode = projectNode;
            var projectOp      = (ProjectOp)projectNode.Op;
            var varDefListNode = projectNode.Child1;
            var subProjectNode = projectNode.Child0;
            var subProjectOp   = (ProjectOp)subProjectNode.Op;
            var trc            = (TransformationRulesContext)context;

            // If any of the defining expressions is not a scalar op tree, then simply
            // quit
            var varRefMap = new Dictionary <Var, int>();

            foreach (var varDefNode in varDefListNode.Children)
            {
                if (!trc.IsScalarOpTree(varDefNode.Child0, varRefMap))
                {
                    return(false);
                }
            }

            var varMap = trc.GetVarMap(subProjectNode.Child1, varRefMap);

            if (varMap == null)
            {
                return(false);
            }

            // create a new varDefList node...
            var newVarDefListNode = trc.Command.CreateNode(trc.Command.CreateVarDefListOp());

            // Remap any local definitions, I have
            foreach (var varDefNode in varDefListNode.Children)
            {
                // update the defining expression
                varDefNode.Child0 = trc.ReMap(varDefNode.Child0, varMap);
                trc.Command.RecomputeNodeInfo(varDefNode);
                newVarDefListNode.Children.Add(varDefNode);
            }

            // Now, pull up any definitions of the subProject that I publish myself
            var projectNodeInfo = trc.Command.GetExtendedNodeInfo(projectNode);

            foreach (var chi in subProjectNode.Child1.Children)
            {
                var varDefOp = (VarDefOp)chi.Op;
                if (projectNodeInfo.Definitions.IsSet(varDefOp.Var))
                {
                    newVarDefListNode.Children.Add(chi);
                }
            }

            //
            // now that we have remapped all our computed vars, simply bypass the subproject
            // node
            //
            projectNode.Child0 = subProjectNode.Child0;
            projectNode.Child1 = newVarDefListNode;
            return(true);
        }
Exemplo n.º 5
0
        /// <summary>
        ///     If the DistinctOp includes all all the keys of the input, than it is unnecessary.
        ///     Distinct (X, distinct_keys) -> Project( X, distinct_keys) where distinct_keys includes all keys of X.
        /// </summary>
        /// <param name="context"> Rule processing context </param>
        /// <param name="n"> current subtree </param>
        /// <param name="newNode"> transformed subtree </param>
        /// <returns> transformation status </returns>
        private static bool ProcessDistinctOpOfKeys(RuleProcessingContext context, Node n, out Node newNode)
        {
            var command = context.Command;

            var nodeInfo = command.GetExtendedNodeInfo(n.Child0);

            var op = (DistinctOp)n.Op;

            //If we know the keys of the input and the list of distinct keys includes them all, omit the distinct
            if (!nodeInfo.Keys.NoKeys &&
                op.Keys.Subsumes(nodeInfo.Keys.KeyVars))
            {
                var newOp = command.CreateProjectOp(op.Keys);

                //Create empty vardef list
                var varDefListOp   = command.CreateVarDefListOp();
                var varDefListNode = command.CreateNode(varDefListOp);

                newNode = command.CreateNode(newOp, n.Child0, varDefListNode);
                return(true);
            }

            //Otherwise return the node as is
            newNode = n;
            return(false);
        }
Exemplo n.º 6
0
        private static bool ProcessSetOpOverEmptySet(
            RuleProcessingContext context,
            System.Data.Entity.Core.Query.InternalTrees.Node setOpNode,
            out System.Data.Entity.Core.Query.InternalTrees.Node newNode)
        {
            bool flag1 = context.Command.GetExtendedNodeInfo(setOpNode.Child0).MaxRows == RowCount.Zero;
            bool flag2 = context.Command.GetExtendedNodeInfo(setOpNode.Child1).MaxRows == RowCount.Zero;

            if (!flag1 && !flag2)
            {
                newNode = setOpNode;
                return(false);
            }
            SetOp op    = (SetOp)setOpNode.Op;
            int   index = !flag2 && op.OpType == OpType.UnionAll || !flag1 && op.OpType == OpType.Intersect ? 1 : 0;

            newNode = setOpNode.Children[index];
            TransformationRulesContext transformationRulesContext = (TransformationRulesContext)context;

            foreach (KeyValuePair <Var, Var> keyValuePair in (Dictionary <Var, Var>)op.VarMap[index])
            {
                transformationRulesContext.AddVarMapping(keyValuePair.Key, keyValuePair.Value);
            }
            return(true);
        }
Exemplo n.º 7
0
        // <summary>
        // Convert Filter(OuterApply(X,Y), p) into
        // Filter(CrossApply(X,Y), p)
        // if "p" is not null-preserving for Y (ie) "p" does not preserve null values from Y
        // </summary>
        // <param name="context"> Rule processing context </param>
        // <param name="filterNode"> Filter node </param>
        // <param name="newNode"> modified subtree </param>
        // <returns> transformation status </returns>
        private static bool ProcessFilterOverOuterApply(RuleProcessingContext context, Node filterNode, out Node newNode)
        {
            newNode = filterNode;
            var applyNode           = filterNode.Child0;
            var applyRightInputNode = applyNode.Child1;
            var trc     = (TransformationRulesContext)context;
            var command = trc.Command;

            //
            // Check to see if the current predicate preserves nulls for the right table.
            // If it doesn't then we can convert the outer apply into a cross-apply,
            //
            var rightTableNodeInfo = command.GetExtendedNodeInfo(applyRightInputNode);
            var predicate          = new Predicate(command, filterNode.Child1);

            if (!predicate.PreservesNulls(rightTableNodeInfo.Definitions, true))
            {
                // Allow the JoinElimination phase to eliminate redundant joins
                // and allow the NullSemantics phase to fully expand the filter
                // predicate before attempting to promote the OuterApply to CrossApply.
                if (trc.PlanCompiler.IsAfterPhase(PlanCompilerPhase.NullSemantics) &&
                    trc.PlanCompiler.IsAfterPhase(PlanCompilerPhase.JoinElimination))
                {
                    var newApplyNode  = command.CreateNode(command.CreateCrossApplyOp(), applyNode.Child0, applyRightInputNode);
                    var newFilterNode = command.CreateNode(command.CreateFilterOp(), newApplyNode, filterNode.Child1);
                    newNode = newFilterNode;
                    return(true);
                }

                trc.PlanCompiler.TransformationsDeferred = true;
            }

            return(false);
        }
Exemplo n.º 8
0
 private static bool ProcessNotOverConstantPredicate(
     RuleProcessingContext context,
     System.Data.Entity.Core.Query.InternalTrees.Node node,
     out System.Data.Entity.Core.Query.InternalTrees.Node newNode)
 {
     return(ScalarOpRules.ProcessLogOpOverConstant(context, node, node.Child0, (System.Data.Entity.Core.Query.InternalTrees.Node)null, out newNode));
 }
Exemplo n.º 9
0
        private static bool ProcessLogOpOverConstant(
            RuleProcessingContext context,
            System.Data.Entity.Core.Query.InternalTrees.Node node,
            System.Data.Entity.Core.Query.InternalTrees.Node constantPredicateNode,
            System.Data.Entity.Core.Query.InternalTrees.Node otherNode,
            out System.Data.Entity.Core.Query.InternalTrees.Node newNode)
        {
            System.Data.Entity.Core.Query.PlanCompiler.PlanCompiler.Assert(constantPredicateNode != null, "null constantPredicateOp?");
            ConstantPredicateOp op = (ConstantPredicateOp)constantPredicateNode.Op;

            switch (node.Op.OpType)
            {
            case OpType.And:
                newNode = op.IsTrue ? otherNode : constantPredicateNode;
                break;

            case OpType.Or:
                newNode = op.IsTrue ? constantPredicateNode : otherNode;
                break;

            case OpType.Not:
                System.Data.Entity.Core.Query.PlanCompiler.PlanCompiler.Assert(otherNode == null, "Not Op with more than 1 child. Gasp!");
                newNode = context.Command.CreateNode((Op)context.Command.CreateConstantPredicateOp(!op.Value));
                break;

            default:
                System.Data.Entity.Core.Query.PlanCompiler.PlanCompiler.Assert(false, "Unexpected OpType - " + (object)node.Op.OpType);
                newNode = (System.Data.Entity.Core.Query.InternalTrees.Node)null;
                break;
            }
            return(true);
        }
Exemplo n.º 10
0
 internal SubTreeId(RuleProcessingContext context, Node node, Node parent, int childIndex)
 {
     m_subTreeRoot = node;
     m_parent = parent;
     m_childIndex = childIndex;
     m_hashCode = context.GetHashCode(node);
 }
        // <summary>
        // We perform the following simple transformation for CaseOps. If every single
        // then/else expression in the CaseOp is equivalent, then we can simply replace
        // the Op with the first then/expression. Specifically,
        // case when w1 then t1 when w2 then t2 ... when wn then tn else e end
        // => t1
        // assuming that t1 is equivalent to t2 is equivalent to ... to e
        // </summary>
        // <param name="context"> Rule Processing context </param>
        // <param name="caseOpNode"> The current subtree for the CaseOp </param>
        // <param name="newNode"> the (possibly) modified subtree </param>
        // <returns> true, if we performed any transformations </returns>
        private static bool ProcessSimplifyCase(RuleProcessingContext context, Node caseOpNode, out Node newNode)
        {
            var caseOp = (CaseOp)caseOpNode.Op;

            newNode = caseOpNode;

            //
            // Can I collapse the entire case-expression into a single expression - yes,
            // if all the then/else clauses are the same expression
            //
            if (ProcessSimplifyCase_Collapse(caseOpNode, out newNode))
            {
                return(true);
            }

            //
            // Can I remove any unnecessary when-then pairs ?
            //
            if (ProcessSimplifyCase_EliminateWhenClauses(context, caseOp, caseOpNode, out newNode))
            {
                return(true);
            }

            // Nothing else I can think of
            return(false);
        }
Exemplo n.º 12
0
        // <summary>
        // Convert a
        // SingleRowOp(X) => X
        // if X produces at most one row
        // </summary>
        // <param name="context"> Rule Processing context </param>
        // <param name="singleRowNode"> Current subtree </param>
        // <param name="newNode"> transformed subtree </param>
        // <returns> Transformation status </returns>
        private static bool ProcessSingleRowOpOverAnything(RuleProcessingContext context, Node singleRowNode, out Node newNode)
        {
            newNode = singleRowNode;
            var trc           = (TransformationRulesContext)context;
            var childNodeInfo = context.Command.GetExtendedNodeInfo(singleRowNode.Child0);

            // If the input to this Op can produce at most one row, then we don't need the
            // singleRowOp - simply return the input
            if (childNodeInfo.MaxRows
                <= RowCount.One)
            {
                newNode = singleRowNode.Child0;
                return(true);
            }

            //
            // if the current node is a FilterOp, then try and determine if the FilterOp
            // produces one row at most
            //
            if (singleRowNode.Child0.Op.OpType
                == OpType.Filter)
            {
                var predicate = new Predicate(context.Command, singleRowNode.Child0.Child1);
                if (predicate.SatisfiesKey(childNodeInfo.Keys.KeyVars, childNodeInfo.Definitions))
                {
                    childNodeInfo.MaxRows = RowCount.One;
                    newNode = singleRowNode.Child0;
                    return(true);
                }
            }

            // we couldn't do anything
            return(false);
        }
Exemplo n.º 13
0
 private static bool ProcessNullCast(
     RuleProcessingContext context,
     System.Data.Entity.Core.Query.InternalTrees.Node castNullOp,
     out System.Data.Entity.Core.Query.InternalTrees.Node newNode)
 {
     newNode = context.Command.CreateNode((Op)context.Command.CreateNullOp(castNullOp.Op.Type));
     return(true);
 }
Exemplo n.º 14
0
 private static bool ProcessIsNullOverNull(
     RuleProcessingContext context,
     System.Data.Entity.Core.Query.InternalTrees.Node isNullNode,
     out System.Data.Entity.Core.Query.InternalTrees.Node newNode)
 {
     newNode = context.Command.CreateNode((Op)context.Command.CreateTrueOp());
     return(true);
 }
Exemplo n.º 15
0
 private static bool ProcessJoinOverSingleRowTable(
     RuleProcessingContext context,
     System.Data.Entity.Core.Query.InternalTrees.Node joinNode,
     out System.Data.Entity.Core.Query.InternalTrees.Node newNode)
 {
     newNode = joinNode;
     newNode = joinNode.Child0.Op.OpType != OpType.SingleRowTable ? joinNode.Child0 : joinNode.Child1;
     return(true);
 }
Exemplo n.º 16
0
        // <summary>
        // Convert Filter(Project(X, ...), p) => Project(Filter(X, p'), ...)
        // </summary>
        // <param name="context"> Rule processing context </param>
        // <param name="filterNode"> FilterOp subtree </param>
        // <param name="newNode"> modified subtree </param>
        // <returns> transformed subtree </returns>
        private static bool ProcessFilterOverProject(RuleProcessingContext context, Node filterNode, out Node newNode)
        {
            newNode = filterNode;
            var predicateNode = filterNode.Child1;

            //
            // If the filter is a constant predicate, then don't push the filter below the
            // project
            //
            if (predicateNode.Op.OpType
                == OpType.ConstantPredicate)
            {
                // There's a different rule to process this case. Simply return
                return(false);
            }

            var trc = (TransformationRulesContext)context;
            //
            // check to see that this is a simple predicate
            //
            var varRefMap = new Dictionary <Var, int>();

            if (!trc.IsScalarOpTree(predicateNode, varRefMap))
            {
                return(false);
            }
            //
            // check to see if all expressions in the project can be inlined
            //
            var projectNode = filterNode.Child0;
            var varMap      = trc.GetVarMap(projectNode.Child1, varRefMap);

            if (varMap == null)
            {
                return(false);
            }

            // check to see that this predicate doesn't reference user-defined functions
            if (trc.IncludeCustomFunctionOp(predicateNode, varMap))
            {
                return(false);
            }

            //
            // Try to remap the predicate in terms of the definitions of the Vars
            //
            var remappedPredicateNode = trc.ReMap(predicateNode, varMap);

            //
            // Now push the filter below the project
            //
            var newFilterNode  = trc.Command.CreateNode(trc.Command.CreateFilterOp(), projectNode.Child0, remappedPredicateNode);
            var newProjectNode = trc.Command.CreateNode(projectNode.Op, newFilterNode, projectNode.Child1);

            newNode = newProjectNode;
            return(true);
        }
        // <summary>
        // Convert Filter(Filter(X, p1), p2) => Filter(X, (p1 and p2))
        // </summary>
        // <param name="context"> rule processing context </param>
        // <param name="filterNode"> FilterOp node </param>
        // <param name="newNode"> modified subtree </param>
        // <returns> transformed subtree </returns>
        private static bool ProcessFilterOverFilter(RuleProcessingContext context, Node filterNode, out Node newNode)
        {
            var newAndNode = context.Command.CreateNode(
                context.Command.CreateConditionalOp(OpType.And),
                filterNode.Child0.Child1, filterNode.Child1);

            newNode = context.Command.CreateNode(context.Command.CreateFilterOp(), filterNode.Child0.Child0, newAndNode);
            return(true);
        }
        private static bool ProcessOuterApplyOverProject(
            RuleProcessingContext context,
            System.Data.Entity.Core.Query.InternalTrees.Node applyNode,
            out System.Data.Entity.Core.Query.InternalTrees.Node newNode)
        {
            newNode = applyNode;
            System.Data.Entity.Core.Query.InternalTrees.Node child1_1 = applyNode.Child1;
            System.Data.Entity.Core.Query.InternalTrees.Node child1_2 = child1_1.Child1;
            TransformationRulesContext transformationRulesContext     = (TransformationRulesContext)context;
            Var computedVar = context.Command.GetExtendedNodeInfo(child1_1.Child0).NonNullableDefinitions.First;

            if (computedVar == null && child1_2.Children.Count == 1 && (child1_2.Child0.Child0.Op.OpType == OpType.InternalConstant || child1_2.Child0.Child0.Op.OpType == OpType.NullSentinel))
            {
                return(false);
            }
            Command command = context.Command;

            System.Data.Entity.Core.Query.InternalTrees.Node node1 = (System.Data.Entity.Core.Query.InternalTrees.Node)null;
            InternalConstantOp internalConstantOp = (InternalConstantOp)null;
            ExtendedNodeInfo   extendedNodeInfo1  = command.GetExtendedNodeInfo(child1_1.Child0);
            bool flag = false;

            foreach (System.Data.Entity.Core.Query.InternalTrees.Node child in child1_2.Children)
            {
                System.Data.Entity.Core.Query.PlanCompiler.PlanCompiler.Assert(child.Op.OpType == OpType.VarDef, "Expected VarDefOp. Found " + (object)child.Op.OpType + " instead");
                VarRefOp op = child.Child0.Op as VarRefOp;
                if (op == null || !extendedNodeInfo1.Definitions.IsSet(op.Var))
                {
                    if (computedVar == null)
                    {
                        internalConstantOp = command.CreateInternalConstantOp(command.IntegerType, (object)1);
                        System.Data.Entity.Core.Query.InternalTrees.Node node2          = command.CreateNode((Op)internalConstantOp);
                        System.Data.Entity.Core.Query.InternalTrees.Node varDefListNode = command.CreateVarDefListNode(node2, out computedVar);
                        ProjectOp projectOp = command.CreateProjectOp(computedVar);
                        projectOp.Outputs.Or(extendedNodeInfo1.Definitions);
                        node1 = command.CreateNode((Op)projectOp, child1_1.Child0, varDefListNode);
                    }
                    System.Data.Entity.Core.Query.InternalTrees.Node node3 = internalConstantOp == null || !internalConstantOp.IsEquivalent(child.Child0.Op) && child.Child0.Op.OpType != OpType.NullSentinel ? transformationRulesContext.BuildNullIfExpression(computedVar, child.Child0) : command.CreateNode((Op)command.CreateVarRefOp(computedVar));
                    child.Child0 = node3;
                    command.RecomputeNodeInfo(child);
                    flag = true;
                }
            }
            if (flag)
            {
                command.RecomputeNodeInfo(child1_2);
            }
            applyNode.Child1 = node1 ?? child1_1.Child0;
            command.RecomputeNodeInfo(applyNode);
            child1_1.Child0 = applyNode;
            ExtendedNodeInfo extendedNodeInfo2 = command.GetExtendedNodeInfo(applyNode.Child0);

            ((ProjectOp)child1_1.Op).Outputs.Or(extendedNodeInfo2.Definitions);
            newNode = child1_1;
            return(true);
        }
Exemplo n.º 19
0
        private static bool ProcessGroupByWithSimpleVarRedefinitions(
            RuleProcessingContext context,
            System.Data.Entity.Core.Query.InternalTrees.Node n,
            out System.Data.Entity.Core.Query.InternalTrees.Node newNode)
        {
            newNode = n;
            GroupByOp op1 = (GroupByOp)n.Op;

            if (n.Child1.Children.Count == 0)
            {
                return(false);
            }
            TransformationRulesContext transformationRulesContext = (TransformationRulesContext)context;
            Command          command          = transformationRulesContext.Command;
            ExtendedNodeInfo extendedNodeInfo = command.GetExtendedNodeInfo(n);
            bool             flag             = false;

            foreach (System.Data.Entity.Core.Query.InternalTrees.Node child in n.Child1.Children)
            {
                System.Data.Entity.Core.Query.InternalTrees.Node child0 = child.Child0;
                if (child0.Op.OpType == OpType.VarRef)
                {
                    VarRefOp op2 = (VarRefOp)child0.Op;
                    if (!extendedNodeInfo.ExternalReferences.IsSet(op2.Var))
                    {
                        flag = true;
                    }
                }
            }
            if (!flag)
            {
                return(false);
            }
            List <System.Data.Entity.Core.Query.InternalTrees.Node> args = new List <System.Data.Entity.Core.Query.InternalTrees.Node>();

            foreach (System.Data.Entity.Core.Query.InternalTrees.Node child in n.Child1.Children)
            {
                VarDefOp op2 = (VarDefOp)child.Op;
                VarRefOp op3 = child.Child0.Op as VarRefOp;
                if (op3 != null && !extendedNodeInfo.ExternalReferences.IsSet(op3.Var))
                {
                    op1.Outputs.Clear(op2.Var);
                    op1.Outputs.Set(op3.Var);
                    op1.Keys.Clear(op2.Var);
                    op1.Keys.Set(op3.Var);
                    transformationRulesContext.AddVarMapping(op2.Var, op3.Var);
                }
                else
                {
                    args.Add(child);
                }
            }
            System.Data.Entity.Core.Query.InternalTrees.Node node = command.CreateNode((Op)command.CreateVarDefListOp(), args);
            n.Child1 = node;
            return(true);
        }
Exemplo n.º 20
0
        private static bool ProcessSimplifyCase(
            RuleProcessingContext context,
            System.Data.Entity.Core.Query.InternalTrees.Node caseOpNode,
            out System.Data.Entity.Core.Query.InternalTrees.Node newNode)
        {
            CaseOp op = (CaseOp)caseOpNode.Op;

            newNode = caseOpNode;
            return(ScalarOpRules.ProcessSimplifyCase_Collapse(caseOpNode, out newNode) || ScalarOpRules.ProcessSimplifyCase_EliminateWhenClauses(context, op, caseOpNode, out newNode));
        }
Exemplo n.º 21
0
        private static bool ProcessGroupByOverProject(
            RuleProcessingContext context,
            System.Data.Entity.Core.Query.InternalTrees.Node n,
            out System.Data.Entity.Core.Query.InternalTrees.Node newNode)
        {
            newNode = n;
            GroupByOp op      = (GroupByOp)n.Op;
            Command   command = context.Command;

            System.Data.Entity.Core.Query.InternalTrees.Node child0   = n.Child0;
            System.Data.Entity.Core.Query.InternalTrees.Node child1_1 = child0.Child1;
            System.Data.Entity.Core.Query.InternalTrees.Node child1_2 = n.Child1;
            System.Data.Entity.Core.Query.InternalTrees.Node child2   = n.Child2;
            if (child1_2.Children.Count > 0)
            {
                return(false);
            }
            VarVec varVec = command.GetExtendedNodeInfo(child0).LocalDefinitions;

            if (op.Outputs.Overlaps(varVec))
            {
                return(false);
            }
            bool flag = false;

            for (int index = 0; index < child1_1.Children.Count; ++index)
            {
                System.Data.Entity.Core.Query.InternalTrees.Node child = child1_1.Children[index];
                if (child.Child0.Op.OpType == OpType.Constant || child.Child0.Op.OpType == OpType.InternalConstant || child.Child0.Op.OpType == OpType.NullSentinel)
                {
                    if (!flag)
                    {
                        varVec = command.CreateVarVec(varVec);
                        flag   = true;
                    }
                    varVec.Clear(((VarDefOp)child.Op).Var);
                }
            }
            if (GroupByOpRules.VarRefUsageFinder.AnyVarUsedMoreThanOnce(varVec, child2, command))
            {
                return(false);
            }
            Dictionary <Var, System.Data.Entity.Core.Query.InternalTrees.Node> varReplacementTable = new Dictionary <Var, System.Data.Entity.Core.Query.InternalTrees.Node>(child1_1.Children.Count);

            for (int index = 0; index < child1_1.Children.Count; ++index)
            {
                System.Data.Entity.Core.Query.InternalTrees.Node child = child1_1.Children[index];
                Var var = ((VarDefOp)child.Op).Var;
                varReplacementTable.Add(var, child.Child0);
            }
            newNode.Child2 = GroupByOpRules.VarRefReplacer.Replace(varReplacementTable, child2, command);
            newNode.Child0 = child0.Child0;
            return(true);
        }
Exemplo n.º 22
0
        private static bool ProcessGroupByOpOnAllInputColumnsWithAggregateOperation(
            RuleProcessingContext context,
            System.Data.Entity.Core.Query.InternalTrees.Node n,
            out System.Data.Entity.Core.Query.InternalTrees.Node newNode)
        {
            newNode = n;
            PhysicalProjectOp op1 = context.Command.Root.Op as PhysicalProjectOp;

            if (op1 == null || op1.Outputs.Count > 1 || (n.Child0.Op.OpType != OpType.ScanTable || n.Child2 == null) || (n.Child2.Child0 == null || n.Child2.Child0.Child0 == null || n.Child2.Child0.Child0.Op.OpType != OpType.Aggregate))
            {
                return(false);
            }
            GroupByOp op2     = (GroupByOp)n.Op;
            Table     table   = ((ScanTableBaseOp)n.Child0.Op).Table;
            VarList   columns = table.Columns;

            foreach (Var v in (List <Var>)columns)
            {
                if (!op2.Keys.IsSet(v))
                {
                    return(false);
                }
            }
            foreach (Var v in (List <Var>)columns)
            {
                op2.Outputs.Clear(v);
                op2.Keys.Clear(v);
            }
            Command     command     = context.Command;
            ScanTableOp scanTableOp = command.CreateScanTableOp(table.TableMetadata);

            System.Data.Entity.Core.Query.InternalTrees.Node node1 = command.CreateNode((Op)scanTableOp);
            System.Data.Entity.Core.Query.InternalTrees.Node node2 = command.CreateNode((Op)command.CreateOuterApplyOp(), node1, n);
            Var computedVar;

            System.Data.Entity.Core.Query.InternalTrees.Node varDefListNode = command.CreateVarDefListNode(command.CreateNode((Op)command.CreateVarRefOp(op2.Outputs.First)), out computedVar);
            newNode = command.CreateNode((Op)command.CreateProjectOp(computedVar), node2, varDefListNode);
            System.Data.Entity.Core.Query.InternalTrees.Node node3 = (System.Data.Entity.Core.Query.InternalTrees.Node)null;
            IEnumerator <Var> enumerator1 = scanTableOp.Table.Keys.GetEnumerator();
            IEnumerator <Var> enumerator2 = table.Keys.GetEnumerator();

            for (int index = 0; index < table.Keys.Count; ++index)
            {
                enumerator1.MoveNext();
                enumerator2.MoveNext();
                System.Data.Entity.Core.Query.InternalTrees.Node node4 = command.CreateNode((Op)command.CreateComparisonOp(OpType.EQ, false), command.CreateNode((Op)command.CreateVarRefOp(enumerator1.Current)), command.CreateNode((Op)command.CreateVarRefOp(enumerator2.Current)));
                node3 = node3 == null ? node4 : command.CreateNode((Op)command.CreateConditionalOp(OpType.And), node3, node4);
            }
            System.Data.Entity.Core.Query.InternalTrees.Node node5 = command.CreateNode((Op)command.CreateFilterOp(), n.Child0, node3);
            n.Child0 = node5;
            return(true);
        }
Exemplo n.º 23
0
 private static bool ProcessProjectWithNoLocalDefinitions(
     RuleProcessingContext context,
     System.Data.Entity.Core.Query.InternalTrees.Node n,
     out System.Data.Entity.Core.Query.InternalTrees.Node newNode)
 {
     newNode = n;
     if (!context.Command.GetNodeInfo(n).ExternalReferences.IsEmpty)
     {
         return(false);
     }
     newNode = n.Child0;
     return(true);
 }
Exemplo n.º 24
0
 private static bool ProcessConstrainedSortOpOverEmptySet(
     RuleProcessingContext context,
     Node n,
     out Node newNode)
 {
     if (context.Command.GetExtendedNodeInfo(n.Child0).MaxRows == RowCount.Zero)
     {
         newNode = n.Child0;
         return(true);
     }
     newNode = n;
     return(false);
 }
Exemplo n.º 25
0
        /// <summary>
        ///     Convert
        ///     SingleRowOp(Project) => Project(SingleRowOp)
        /// </summary>
        /// <param name="context"> Rule Processing context </param>
        /// <param name="singleRowNode"> current subtree </param>
        /// <param name="newNode"> transformeed subtree </param>
        /// <returns> transformation status </returns>
        private static bool ProcessSingleRowOpOverProject(RuleProcessingContext context, Node singleRowNode, out Node newNode)
        {
            newNode = singleRowNode;
            var projectNode      = singleRowNode.Child0;
            var projectNodeInput = projectNode.Child0;

            // Simply push the SingleRowOp below the ProjectOp
            singleRowNode.Child0 = projectNodeInput;
            context.Command.RecomputeNodeInfo(singleRowNode);
            projectNode.Child0 = singleRowNode;

            newNode = projectNode;
            return(true); // subtree modified internally
        }
Exemplo n.º 26
0
        // <summary>
        // Convert a CrossJoin(SingleRowTable, X) or CrossJoin(X, SingleRowTable) or LeftOuterJoin(X, SingleRowTable)
        // into just "X"
        // </summary>
        // <param name="context"> rule processing context </param>
        // <param name="joinNode"> the join node </param>
        // <param name="newNode"> transformed subtree </param>
        // <returns> transformation status </returns>
        private static bool ProcessJoinOverSingleRowTable(RuleProcessingContext context, Node joinNode, out Node newNode)
        {
            newNode = joinNode;

            if (joinNode.Child0.Op.OpType
                == OpType.SingleRowTable)
            {
                newNode = joinNode.Child1;
            }
            else
            {
                newNode = joinNode.Child0;
            }
            return(true);
        }
Exemplo n.º 27
0
        // <summary>
        // If the ConstrainedSortOp's input is guaranteed to produce no rows, remove the ConstrainedSortOp completly:
        // CSort(EmptySet) => EmptySet
        // </summary>
        // <param name="context"> Rule processing context </param>
        // <param name="n"> current subtree </param>
        // <param name="newNode"> transformed subtree </param>
        // <returns> transformation status </returns>
        private static bool ProcessConstrainedSortOpOverEmptySet(RuleProcessingContext context, Node n, out Node newNode)
        {
            var nodeInfo = (context).Command.GetExtendedNodeInfo(n.Child0);

            //If the input has no rows, remove the ConstraintSortOp node completly
            if (nodeInfo.MaxRows
                == RowCount.Zero)
            {
                newNode = n.Child0;
                return(true);
            }

            newNode = n;
            return(false);
        }
 private static bool ProcessCrossApplyOverLeftOuterJoinOverSingleRowTable(
     RuleProcessingContext context,
     System.Data.Entity.Core.Query.InternalTrees.Node applyNode,
     out System.Data.Entity.Core.Query.InternalTrees.Node newNode)
 {
     newNode = applyNode;
     System.Data.Entity.Core.Query.InternalTrees.Node child1 = applyNode.Child1;
     if (((ConstantPredicateOp)child1.Child2.Op).IsFalse)
     {
         return(false);
     }
     applyNode.Op     = (Op)context.Command.CreateOuterApplyOp();
     applyNode.Child1 = child1.Child1;
     return(true);
 }
Exemplo n.º 29
0
 private static bool ProcessFlattenCase(
     RuleProcessingContext context,
     System.Data.Entity.Core.Query.InternalTrees.Node caseOpNode,
     out System.Data.Entity.Core.Query.InternalTrees.Node newNode)
 {
     newNode = caseOpNode;
     System.Data.Entity.Core.Query.InternalTrees.Node child = caseOpNode.Children[caseOpNode.Children.Count - 1];
     if (child.Op.OpType != OpType.Case)
     {
         return(false);
     }
     caseOpNode.Children.RemoveAt(caseOpNode.Children.Count - 1);
     caseOpNode.Children.AddRange((IEnumerable <System.Data.Entity.Core.Query.InternalTrees.Node>)child.Children);
     return(true);
 }
Exemplo n.º 30
0
        private static bool ProcessIsNullOverVarRef(
            RuleProcessingContext context,
            System.Data.Entity.Core.Query.InternalTrees.Node isNullNode,
            out System.Data.Entity.Core.Query.InternalTrees.Node newNode)
        {
            Command command = context.Command;

            if (((TransformationRulesContext)context).IsNonNullable(((VarRefOp)isNullNode.Child0.Op).Var))
            {
                newNode = command.CreateNode((Op)context.Command.CreateFalseOp());
                return(true);
            }
            newNode = isNullNode;
            return(false);
        }
Exemplo n.º 31
0
        private static bool ProcessSortOpOverAtMostOneRow(
            RuleProcessingContext context,
            Node n,
            out Node newNode)
        {
            ExtendedNodeInfo extendedNodeInfo = context.Command.GetExtendedNodeInfo(n.Child0);

            if (extendedNodeInfo.MaxRows == RowCount.Zero || extendedNodeInfo.MaxRows == RowCount.One)
            {
                newNode = n.Child0;
                return(true);
            }
            newNode = n;
            return(false);
        }