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_)); }
public override bool Appliable(CGroupMember expr) { return(expr.logic_ is LogicCteAnchor); }
public override bool Appliable(CGroupMember expr) { return(expr.logic_ is LogicJoin lj && lj.IsInnerJoin()); }