Example #1
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);
        }
Example #2
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);
        }
Example #3
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);
        }
Example #4
0
        /// <summary>
        /// Converts a collection aggregate function count(X), where X is a collection into
        /// two parts. Part A is a groupby subquery that looks like
        ///    GroupBy(Unnest(X), empty, count(y))
        /// where "empty" describes the fact that the groupby has no keys, and y is an
        /// element var of the Unnest
        ///
        /// Part 2 is a VarRef that refers to the aggregate var for count(y) described above.
        ///
        /// Logically, we would replace the entire functionOp by element(GroupBy...). However,
        /// since we also want to translate element() into single-row-subqueries, we do this
        /// here as well.
        ///
        /// The function itself is replaced by the VarRef, and the GroupBy is added to the list
        /// of scalar subqueries for the current relOp node on the stack
        ///
        /// </summary>
        /// <param name="op">the functionOp for the collection agg</param>
        /// <param name="n">current subtree</param>
        /// <returns>the VarRef node that should replace the function</returns>
        private Node VisitCollectionAggregateFunction(FunctionOp op, Node n)
        {
            TypeUsage softCastType = null;
            Node      argNode      = n.Child0;

            if (OpType.SoftCast == argNode.Op.OpType)
            {
                softCastType = TypeHelpers.GetEdmType <CollectionType>(argNode.Op.Type).TypeUsage;
                argNode      = argNode.Child0;

                while (OpType.SoftCast == argNode.Op.OpType)
                {
                    argNode = argNode.Child0;
                }
            }

            Node     unnestNode      = BuildUnnest(argNode);
            UnnestOp unnestOp        = unnestNode.Op as UnnestOp;
            Var      unnestOutputVar = unnestOp.Table.Columns[0];

            AggregateOp aggregateOp      = m_command.CreateAggregateOp(op.Function, false);
            VarRefOp    unnestVarRefOp   = m_command.CreateVarRefOp(unnestOutputVar);
            Node        unnestVarRefNode = m_command.CreateNode(unnestVarRefOp);

            if (softCastType != null)
            {
                unnestVarRefNode = m_command.CreateNode(m_command.CreateSoftCastOp(softCastType), unnestVarRefNode);
            }
            Node aggExprNode = m_command.CreateNode(aggregateOp, unnestVarRefNode);

            VarVec keyVars           = m_command.CreateVarVec(); // empty keys
            Node   keyVarDefListNode = m_command.CreateNode(m_command.CreateVarDefListOp());

            VarVec gbyOutputVars = m_command.CreateVarVec();
            Var    aggVar;
            Node   aggVarDefListNode = m_command.CreateVarDefListNode(aggExprNode, out aggVar);

            gbyOutputVars.Set(aggVar);
            GroupByOp gbyOp           = m_command.CreateGroupByOp(keyVars, gbyOutputVars);
            Node      gbySubqueryNode = m_command.CreateNode(gbyOp, unnestNode, keyVarDefListNode, aggVarDefListNode);

            // "Move" this subquery to my parent relop
            Node ret = AddSubqueryToParentRelOp(aggVar, gbySubqueryNode);

            return(ret);
        }
Example #5
0
        private static bool ProcessGroupByOpWithNoAggregates(
            RuleProcessingContext context,
            System.Data.Entity.Core.Query.InternalTrees.Node n,
            out System.Data.Entity.Core.Query.InternalTrees.Node newNode)
        {
            Command          command          = context.Command;
            GroupByOp        op               = (GroupByOp)n.Op;
            ExtendedNodeInfo extendedNodeInfo = command.GetExtendedNodeInfo(n.Child0);
            ProjectOp        projectOp        = command.CreateProjectOp(op.Keys);
            VarDefListOp     varDefListOp     = command.CreateVarDefListOp();

            command.CreateNode((Op)varDefListOp);
            newNode = command.CreateNode((Op)projectOp, n.Child0, n.Child1);
            if (extendedNodeInfo.Keys.NoKeys || !op.Keys.Subsumes(extendedNodeInfo.Keys.KeyVars))
            {
                newNode = command.CreateNode((Op)command.CreateDistinctOp(command.CreateVarVec(op.Keys)), newNode);
            }
            return(true);
        }
Example #6
0
 // <summary>
 // GroupByOp
 // </summary>
 // <remarks>
 // At this point in the process, there really isn't a way we should actually
 // have a NestOp as an input to the GroupByOp, and we currently aren't allowing
 // you to specify a collection as an aggregation Var or key, so if we find a
 // NestOp anywhere on the inputs, it's a NotSupported situation.
 // </remarks>
 public override Node Visit(GroupByOp op, Node n)
 {
     return NestingNotSupported(op, n);
 }
        /// <summary>
        ///     GroupBy
        ///     Again, VisitChildren - for the Keys and Properties VarDefList nodes - does
        ///     the real work.
        ///     The "Keys" and the "OutputVars" varsets are updated to flatten out
        ///     references to any structured Vars.
        /// </summary>
        /// <param name="op"> </param>
        /// <param name="n"> </param>
        /// <returns> </returns>
        public override Node Visit(GroupByOp op, Node n)
        {
            VisitChildren(n);

            // update the output Vars and the key vars with the right sets
            var newKeys = FlattenVarSet(op.Keys);
            var newOutputs = FlattenVarSet(op.Outputs);

            if (newKeys != op.Keys
                || newOutputs != op.Outputs)
            {
                n.Op = m_command.CreateGroupByOp(newKeys, newOutputs);
            }

            return n;
        }
 /// <summary>
 ///     Visitor pattern method for GroupByOp
 /// </summary>
 /// <param name="op"> The GroupByOp being visited </param>
 /// <param name="n"> The Node that references the Op </param>
 public virtual void Visit(GroupByOp op, Node n)
 {
     VisitGroupByOp(op, n);
 }
Example #9
0
 // <summary>
 // GroupByOp
 // </summary>
 public override int Visit(GroupByOp op, Node n)
 {
     return(op.Outputs.Count);
 }
 public override int Visit(GroupByOp op, System.Data.Entity.Core.Query.InternalTrees.Node n)
 {
     return(op.Outputs.Count);
 }
Example #11
0
        // <summary>
        // Copies a group-by node
        // </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(GroupByOp op, Node n)
        {
            // Visit the Node's children and map their Vars
            var children = ProcessChildren(n);

            // Create a new GroupByOp that uses copies of the Key and Output VarSets of the original GroupByOp
            var newGroupOp = m_destCmd.CreateGroupByOp(Copy(op.Keys), Copy(op.Outputs));

            // Return a new Node that references the copied GroupByOp and has the copied child Nodes as its children
            return m_destCmd.CreateNode(newGroupOp, children);
        }