/// <summary> /// Private constructor /// </summary> /// <param name="command"></param> /// <param name="groupAggregateVarInfoManager"></param> private GroupAggregateVarComputationTranslator( Command command, GroupAggregateVarInfoManager groupAggregateVarInfoManager) { _command = command; _groupAggregateVarInfoManager = groupAggregateVarInfoManager; }
/// <summary> /// Private constructor /// </summary> /// <param name="command"></param> /// <param name="groupAggregateVarInfoManager"></param> private GroupAggregateVarComputationTranslator( Command command, GroupAggregateVarInfoManager groupAggregateVarInfoManager) { this._command = command; this._groupAggregateVarInfoManager = groupAggregateVarInfoManager; }
/// <summary> /// Try to produce an equivalent tree to the input subtree, over a single group aggregate variable. /// Such translation can only be produced if all external references of the input subtree are to a /// single group aggregate var, or to vars that are can be translated over that single group /// aggregate var /// </summary> /// <param name="subtree">The input subtree</param> /// <param name="isVarDefinition"></param> /// <param name="command"></param> /// <param name="groupAggregateVarInfoManager"></param> /// <param name="groupAggregateVarInfo">The groupAggregateVarInfo over which the input subtree can be translated </param> /// <param name="templateNode">A tree that is equvalent to the input tree, but over the group aggregate variable /// represented by the groupAggregetVarInfo</param> /// <param name="isUnnested"></param> /// <returns>True, if the translation can be done, false otherwise</returns> public static bool TryTranslateOverGroupAggregateVar( Node subtree, bool isVarDefinition, Command command, GroupAggregateVarInfoManager groupAggregateVarInfoManager, out GroupAggregateVarInfo groupAggregateVarInfo, out Node templateNode, out bool isUnnested) { var handler = new GroupAggregateVarComputationTranslator(command, groupAggregateVarInfoManager); var inputNode = subtree; SoftCastOp softCastOp = null; bool isCollect; if (inputNode.Op.OpType == OpType.SoftCast) { softCastOp = (SoftCastOp)inputNode.Op; inputNode = inputNode.Child0; } if (inputNode.Op.OpType == OpType.Collect) { templateNode = handler.VisitCollect(inputNode); isCollect = true; } else { templateNode = handler.VisitNode(inputNode); isCollect = false; } groupAggregateVarInfo = handler._targetGroupAggregateVarInfo; isUnnested = handler._isUnnested; if (handler._targetGroupAggregateVarInfo == null || templateNode == null) { return false; } if (softCastOp != null) { SoftCastOp newSoftCastOp; // // The type needs to be fixed only if the unnesting happened during this translation. // That can be recognized by these two cases: // 1) if the input node was a collect, or // 2) if the input did not represent a var definition, but a function aggregate argument and // the template is VarRef of a group aggregate var. // if (isCollect || !isVarDefinition && AggregatePushdownUtil.IsVarRefOverGivenVar(templateNode, handler._targetGroupAggregateVarInfo.GroupAggregateVar)) { newSoftCastOp = command.CreateSoftCastOp(TypeHelpers.GetEdmType<CollectionType>(softCastOp.Type).TypeUsage); } else { newSoftCastOp = softCastOp; } templateNode = command.CreateNode(newSoftCastOp, templateNode); } return true; }
/// <summary> /// Try to produce an equivalent tree to the input subtree, over a single group aggregate variable. /// Such translation can only be produced if all external references of the input subtree are to a /// single group aggregate var, or to vars that are can be translated over that single group /// aggregate var /// </summary> /// <param name="subtree">The input subtree</param> /// <param name="isVarDefinition"></param> /// <param name="command"></param> /// <param name="groupAggregateVarInfoManager"></param> /// <param name="groupAggregateVarInfo">The groupAggregateVarInfo over which the input subtree can be translated </param> /// <param name="templateNode">A tree that is equvalent to the input tree, but over the group aggregate variable /// represented by the groupAggregetVarInfo</param> /// <param name="isUnnested"></param> /// <returns>True, if the translation can be done, false otherwise</returns> public static bool TryTranslateOverGroupAggregateVar( Node subtree, bool isVarDefinition, Command command, GroupAggregateVarInfoManager groupAggregateVarInfoManager, out GroupAggregateVarInfo groupAggregateVarInfo, out Node templateNode, out bool isUnnested) { GroupAggregateVarComputationTranslator handler = new GroupAggregateVarComputationTranslator(command, groupAggregateVarInfoManager); Node inputNode = subtree; SoftCastOp softCastOp = null; bool isCollect; if (inputNode.Op.OpType == OpType.SoftCast) { softCastOp = (SoftCastOp)inputNode.Op; inputNode = inputNode.Child0; } if (inputNode.Op.OpType == OpType.Collect) { templateNode = handler.VisitCollect(inputNode); isCollect = true; } else { templateNode = handler.VisitNode(inputNode); isCollect = false; } groupAggregateVarInfo = handler._targetGroupAggregateVarInfo; isUnnested = handler._isUnnested; if (handler._targetGroupAggregateVarInfo == null || templateNode == null) { return(false); } if (softCastOp != null) { SoftCastOp newSoftCastOp; // // The type needs to be fixed only if the unnesting happened during this translation. // That can be recognized by these two cases: // 1) if the input node was a collect, or // 2) if the input did not represent a var definition, but a function aggregate argument and // the template is VarRef of a group aggregate var. // if (isCollect || !isVarDefinition && AggregatePushdownUtil.IsVarRefOverGivenVar(templateNode, handler._targetGroupAggregateVarInfo.GroupAggregateVar)) { newSoftCastOp = command.CreateSoftCastOp(TypeHelpers.GetEdmType <CollectionType>(softCastOp.Type).TypeUsage); } else { newSoftCastOp = softCastOp; } templateNode = command.CreateNode(newSoftCastOp, templateNode); } return(true); }