Exemple #1
0
        public override CGroupMember Apply(CGroupMember expr)
        {
            // for manually binding the expression
            void manualbindexpr(Expr e)
            {
                e.bounded_ = true;
                e.type_    = new BoolType();
            }

            // for transforming original having according to the new agg func
            BinExpr processhaving(Expr e, Dictionary <Expr, Expr> dict)
            {
                var be = e as BinExpr;

                Debug.Assert(be != null);
                bool        isreplace = false;
                List <Expr> children  = new List <Expr>();

                foreach (var child in be.children_)
                {
                    if (dict.ContainsKey(child))
                    {
                        children.Add(dict[child]);
                        isreplace = true;
                    }
                    else
                    {
                        children.Add(child);
                    }
                }
                Debug.Assert(isreplace);
                return(new BinExpr(children[0], children[1], be.op_));
            }

            LogicAgg origAggNode = (expr.logic_ as LogicAgg);
            var      childNode   = (origAggNode.child_() as LogicMemoRef).Deref <LogicNode>();

            var groupby = origAggNode.groupby_?.CloneList();
            var having  = origAggNode.having_?.Clone();

            // process the aggregation functions
            origAggNode.GenerateAggrFns(false);

            List <AggFunc> aggfns = new List <AggFunc>();

            origAggNode.aggrFns_.ForEach(x => aggfns.Add(x.Clone() as AggFunc));
            // need to make aggrFns_ back to null list
            origAggNode.aggrFns_ = new List <AggFunc>();

            var globalfns = new List <Expr>();
            var localfns  = new List <Expr>();

            // record the processed aggregate functions
            var derivedAggFuncDict = new Dictionary <Expr, Expr>();

            foreach (var func in aggfns)
            {
                Expr processed = func.SplitAgg();
                // if splitagg is returning null, end the transformation process
                if (processed is null)
                {
                    return(expr);
                }

                // force the id to be equal.
                processed._ = func._;

                globalfns.Add(processed);
                derivedAggFuncDict.Add(func, processed);
            }

            var local = new LogicAgg(childNode, groupby, localfns, null)
            {
                isLocal_ = true
            };

            // having is placed on the global agg and the agg func need to be processed
            var newhaving = having;

            if (having != null)
            {
                newhaving = processhaving(having, derivedAggFuncDict);
                manualbindexpr(newhaving);
            }

            // assuming having is an expression involving agg func,
            // it is only placed on the global agg
            var global = new LogicAgg(local, groupby, globalfns, newhaving)
            {
                isDerived_ = true
            };

            global.Overridesign(origAggNode);
            global.deriveddict_ = derivedAggFuncDict;

            return(new CGroupMember(global, expr.group_));
        }
Exemple #2
0
 public override bool Appliable(CGroupMember expr)
 {
     return(expr.logic_ is LogicCteAnchor);
 }
Exemple #3
0
 public override bool Appliable(CGroupMember expr)
 {
     return(expr.logic_ is LogicJoin lj && lj.IsInnerJoin());
 }