// <summary> // Registers the group aggregate var with the group aggregate var info manager // </summary> public override void Visit(GroupByIntoOp op, Node n) { VisitGroupByOp(op, n); foreach (var child in n.Child3.Children) { var groupAggregateVar = ((VarDefOp)child.Op).Var; GroupAggregateVarRefInfo groupAggregateVarRefInfo; // If the group by is over a group, it may be already tracked as referencing a group var // An optimization would be to separately track this groupAggregateVar too, for the cases when the aggregate can // not be pushed to the group by node over which this one is defined but can be propagated to this group by node. if (!_groupAggregateVarInfoManager.TryGetReferencedGroupAggregateVarInfo(groupAggregateVar, out groupAggregateVarRefInfo)) { _groupAggregateVarInfoManager.Add( groupAggregateVar, new GroupAggregateVarInfo(n, groupAggregateVar), _command.CreateNode(_command.CreateVarRefOp(groupAggregateVar)), false); } } }
private Node VisitCollect(Node n) { //Make sure the only children are projects over unnest var currentNode = n.Child0; var constantDefinitions = new Dictionary <Var, Node>(); while (currentNode.Child0.Op.OpType == OpType.Project) { currentNode = currentNode.Child0; //Visit the VarDefListOp child if (VisitDefault(currentNode.Child1) == null) { return(null); } foreach (var definitionNode in currentNode.Child1.Children) { if (IsConstant(definitionNode.Child0)) { constantDefinitions.Add(((VarDefOp)definitionNode.Op).Var, definitionNode.Child0); } } } if (currentNode.Child0.Op.OpType != OpType.Unnest) { return(null); } // Handle the unnest var unnestOp = (UnnestOp)currentNode.Child0.Op; GroupAggregateVarRefInfo groupAggregateVarRefInfo; if (_groupAggregateVarInfoManager.TryGetReferencedGroupAggregateVarInfo(unnestOp.Var, out groupAggregateVarRefInfo)) { if (_targetGroupAggregateVarInfo == null) { _targetGroupAggregateVarInfo = groupAggregateVarRefInfo.GroupAggregateVarInfo; } else if (_targetGroupAggregateVarInfo != groupAggregateVarRefInfo.GroupAggregateVarInfo) { return(null); } if (!_isUnnested) { return(null); } } else { return(null); } var physicalProjectOp = (PhysicalProjectOp)n.Child0.Op; PlanCompiler.Assert(physicalProjectOp.Outputs.Count == 1, "Physical project should only have one output at this stage"); var outputVar = physicalProjectOp.Outputs[0]; var computationTemplate = TranslateOverGroupAggregateVar(outputVar, null); if (computationTemplate != null) { _isUnnested = true; return(computationTemplate); } Node constantDefinitionNode; if (constantDefinitions.TryGetValue(outputVar, out constantDefinitionNode)) { _isUnnested = true; return(constantDefinitionNode); } return(null); }