Ejemplo n.º 1
0
        /// <summary>
        /// Helper method for removing redundant constant keys from GroupByOp and DistictOp.
        /// It only examines the keys defined in the given varDefListNode.
        /// It removes all constant and null keys that are not referenced elsewhere,
        /// but ensuring that at least one key is left.
        /// It should not be called with empty keyVec.
        /// </summary>
        /// <param name="keyVec">The keys</param>
        /// <param name="outputVec">The var vec that needs to be updated along with the keys</param>
        /// <param name="varDefListNode">Var def list node for the keys </param>
        private void RemoveRedundantConstantKeys(VarVec keyVec, VarVec outputVec, Node varDefListNode)
        {
            //Find all the keys that are nulls and constants
            List <Node> constantKeys = varDefListNode.Children.Where(d => d.Op.OpType == OpType.VarDef &&
                                                                     PlanCompilerUtil.IsConstantBaseOp(d.Child0.Op.OpType)).ToList();

            VarVec constantKeyVars = this.m_command.CreateVarVec(constantKeys.Select(d => ((VarDefOp)d.Op).Var));

            //Get the list of unreferenced  constant keys
            constantKeyVars.Minus(m_referencedVars);

            //Remove the unreferenced constant keys
            keyVec.Minus(constantKeyVars);
            outputVec.Minus(constantKeyVars);

            varDefListNode.Children.RemoveAll(c => constantKeys.Contains(c) && constantKeyVars.IsSet(((VarDefOp)c.Op).Var));

            //If no keys are left add one.
            if (keyVec.Count == 0)
            {
                Node keyNode = constantKeys.First();
                Var  keyVar  = ((VarDefOp)keyNode.Op).Var;
                keyVec.Set(keyVar);
                outputVec.Set(keyVar);
                varDefListNode.Children.Add(keyNode);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Determines whether the given Node is a constant subtree
        /// It only recognizes any of the constant base ops
        /// and possibly casts over these nodes.
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        private static bool IsConstant(Node node)
        {
            Node currentNode = node;

            while (currentNode.Op.OpType == OpType.Cast)
            {
                currentNode = currentNode.Child0;
            }
            return(PlanCompilerUtil.IsConstantBaseOp(currentNode.Op.OpType));
        }
Ejemplo n.º 3
0
        /// <summary>
        /// If the op is a collection aggregate function it checks whether its arguement can be translated over
        /// a single group aggregate var. If so, it is tracked as a candidate to be pushed into that
        /// group by into node.
        /// </summary>
        /// <param name="op"></param>
        /// <param name="n"></param>
        public override void Visit(FunctionOp op, Node n)
        {
            VisitDefault(n);
            if (!PlanCompilerUtil.IsCollectionAggregateFunction(op, n))
            {
                return;
            }
            PlanCompiler.Assert(n.Children.Count == 1, "Aggregate Function must have one argument");

            Node argumentNode = n.Child0;

            GroupAggregateVarInfo referencedGroupAggregateVarInfo;
            Node templateNode;
            bool isUnnested;

            if (GroupAggregateVarComputationTranslator.TryTranslateOverGroupAggregateVar(n.Child0, false, _command, _groupAggregateVarInfoManager, out referencedGroupAggregateVarInfo, out templateNode, out isUnnested) &&
                (isUnnested || AggregatePushdownUtil.IsVarRefOverGivenVar(templateNode, referencedGroupAggregateVarInfo.GroupAggregateVar)))
            {
                referencedGroupAggregateVarInfo.CandidateAggregateNodes.Add(new KeyValuePair <Node, Node>(n, templateNode));
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Pre-processing for a function. Does the default scalar op processing.
        /// If the function returns a collection (TVF), the method converts this expression into
        ///    Collect(PhysicalProject(Unnest(Func))).
        /// If the function is a collection aggregate, converts it into the corresponding group aggregate.
        /// </summary>
        /// <param name="op"></param>
        /// <param name="n"></param>
        /// <returns></returns>
        public override Node Visit(FunctionOp op, Node n)
        {
            VisitScalarOpDefault(op, n);
            Node newNode = null;

            // Is this a TVF?
            if (TypeSemantics.IsCollectionType(op.Type))
            {
                newNode = VisitCollectionFunction(op, n);
            }
            // Is this a collection-aggregate function?
            else if (PlanCompilerUtil.IsCollectionAggregateFunction(op, n))
            {
                newNode = VisitCollectionAggregateFunction(op, n);
            }
            else
            {
                newNode = n;
            }

            PlanCompiler.Assert(newNode != null, "failure to construct a functionOp?");
            return(newNode);
        }