Exemple #1
0
        // <summary>
        // Converts a GroupBy(Project(X, c1,..ck), agg1, agg2, .. aggm) =>
        // GroupBy(X, agg1', agg2', .. aggm')
        // where agg1', agg2', .. aggm'  are the "mapped" versions
        // of agg1, agg2, .. aggm, such that the references to c1, ... ck are
        // replaced by their definitions.
        // We only do this if each c1, ..ck is refereneced (in aggregates) at most once or it is a constant.
        // </summary>
        // <param name="context"> Rule processing context </param>
        // <param name="n"> Current ProjectOp node </param>
        // <param name="newNode"> modified subtree </param>
        // <returns> Transformation status </returns>
        private static bool ProcessGroupByOverProject(RuleProcessingContext context, Node n, out Node newNode)
        {
            newNode = n;
            var op                    = (GroupByOp)n.Op;
            var command               = (context).Command;
            var projectNode           = n.Child0;
            var projectNodeVarDefList = projectNode.Child1;

            var keys       = n.Child1;
            var aggregates = n.Child2;

            // If there are any keys, we should not remove the inner project
            if (keys.Children.Count > 0)
            {
                return(false);
            }

            //Get a list of all defining vars
            var projectDefinitions = command.GetExtendedNodeInfo(projectNode).LocalDefinitions;

            //If any of the defined vars is output, than we need the extra project anyway.
            if (op.Outputs.Overlaps(projectDefinitions))
            {
                return(false);
            }

            var createdNewProjectDefinitions = false;

            //If there are any constants remove them from the list that needs to be tested,
            //These can safely be replaced
            for (var i = 0; i < projectNodeVarDefList.Children.Count; i++)
            {
                var varDefNode = projectNodeVarDefList.Children[i];
                if (varDefNode.Child0.Op.OpType == OpType.Constant ||
                    varDefNode.Child0.Op.OpType == OpType.InternalConstant ||
                    varDefNode.Child0.Op.OpType == OpType.NullSentinel)
                {
                    //We shouldn't modify the original project definitions, thus we copy it
                    // the first time we encounter a constant
                    if (!createdNewProjectDefinitions)
                    {
                        projectDefinitions           = command.CreateVarVec(projectDefinitions);
                        createdNewProjectDefinitions = true;
                    }
                    projectDefinitions.Clear(((VarDefOp)varDefNode.Op).Var);
                }
            }

            if (VarRefUsageFinder.AnyVarUsedMoreThanOnce(projectDefinitions, aggregates, command))
            {
                return(false);
            }

            //If we got here it means that all vars were either constants, or used at most once
            // Create a dictionary to be used for remapping the keys and the aggregates
            var varToDefiningNode = new Dictionary <Var, Node>(projectNodeVarDefList.Children.Count);

            for (var j = 0; j < projectNodeVarDefList.Children.Count; j++)
            {
                var varDefNode = projectNodeVarDefList.Children[j];
                var var        = ((VarDefOp)varDefNode.Op).Var;
                varToDefiningNode.Add(var, varDefNode.Child0);
            }

            newNode.Child2 = VarRefReplacer.Replace(varToDefiningNode, aggregates, command);

            newNode.Child0 = projectNode.Child0;
            return(true);
        }
Exemple #2
0
            // <summary>
            // "Public" entry point. In the subtree rooted at the given root,
            // replace each occurance of the given vars with their definitions,
            // where each key-value pair in the dictionary is a var-definition pair.
            // </summary>
            internal static Node Replace(Dictionary <Var, Node> varReplacementTable, Node root, Command command)
            {
                var replacer = new VarRefReplacer(varReplacementTable, command);

                return(replacer.VisitNode(root));
            }
Exemple #3
0
 /// <summary>
 ///     "Public" entry point. In the subtree rooted at the given root,
 ///     replace each occurance of the given vars with their definitions,
 ///     where each key-value pair in the dictionary is a var-definition pair.
 /// </summary>
 /// <param name="varReplacementTable"> </param>
 /// <param name="root"> </param>
 /// <param name="command"> </param>
 /// <returns> </returns>
 internal static Node Replace(Dictionary<Var, Node> varReplacementTable, Node root, Command command)
 {
     var replacer = new VarRefReplacer(varReplacementTable, command);
     return replacer.VisitNode(root);
 }