private static void CompileReclaim( AggGroupByDesc groupDesc, HintAttribute reclaimGroupAged, HintAttribute reclaimGroupFrequency, VariableCompileTimeResolver variableCompileTimeResolver, string optionalContextName) { var hintValueMaxAge = HintEnum.RECLAIM_GROUP_AGED.GetHintAssignedValue(reclaimGroupAged); if (hintValueMaxAge == null) { throw new ExprValidationException( "Required hint value for hint '" + HintEnum.RECLAIM_GROUP_AGED + "' has not been provided"); } var evaluationFunctionMaxAge = GetEvaluationFunction( variableCompileTimeResolver, hintValueMaxAge, optionalContextName); groupDesc.IsReclaimAged = true; groupDesc.SetReclaimEvaluationFunctionMaxAge(evaluationFunctionMaxAge); var hintValueFrequency = HintEnum.RECLAIM_GROUP_FREQ.GetHintAssignedValue(reclaimGroupAged); AggSvcGroupByReclaimAgedEvalFuncFactoryForge evaluationFunctionFrequency; if (reclaimGroupFrequency == null || hintValueFrequency == null) { evaluationFunctionFrequency = evaluationFunctionMaxAge; } else { evaluationFunctionFrequency = GetEvaluationFunction( variableCompileTimeResolver, hintValueFrequency, optionalContextName); } groupDesc.SetReclaimEvaluationFunctionFrequency(evaluationFunctionFrequency); }
internal static IList<FilterSpecParam>[] PlanFilterParameters( IList<ExprNode> validatedNodes, FilterSpecCompilerArgs args) { if (validatedNodes.IsEmpty()) { return AllocateListArray(0); } var filterParamExprMap = new FilterParamExprMap(); // Make filter parameter for each expression node, if it can be optimized DecomposePopulateConsolidate(filterParamExprMap, validatedNodes, args); // Use all filter parameter and unassigned expressions IList<FilterSpecParam> filterParams = new List<FilterSpecParam>(); filterParams.AddAll(filterParamExprMap.FilterParams); int countUnassigned = filterParamExprMap.CountUnassignedExpressions(); // we are done if there are no remaining nodes if (countUnassigned == 0) { return AllocateListArraySizeOne(filterParams); } // determine max-width int filterServiceMaxFilterWidth = args.ConfigurationInformation.EngineDefaults.ExecutionConfig.FilterServiceMaxFilterWidth; HintAttribute hint = HintEnum.MAX_FILTER_WIDTH.GetHint(args.Annotations); if (hint != null) { string hintValue = HintEnum.MAX_FILTER_WIDTH.GetHintAssignedValue(hint); filterServiceMaxFilterWidth = int.Parse(hintValue); } IList<FilterSpecParam>[] plan = null; if (filterServiceMaxFilterWidth > 0) { plan = PlanRemainingNodesIfFeasible(filterParamExprMap, args, filterServiceMaxFilterWidth); } if (plan != null) { return plan; } // handle no-plan FilterSpecParamExprNode node = MakeRemainingNode(filterParamExprMap.UnassignedExpressions, args); filterParams.Add(node); return AllocateListArraySizeOne(filterParams); }
public AggregationServiceFactory GetGroupReclaimAged( ExprEvaluator[] evaluatorsArr, AggregationMethodFactory[] aggregatorsArr, HintAttribute reclaimGroupAged, HintAttribute reclaimGroupFrequency, VariableService variableService, AggregationAccessorSlotPair[] pairs, AggregationStateFactory[] accessAggregations, bool join, Object groupKeyBinding, String optionalContextName) { return(new AggSvcGroupByReclaimAgedFactory( evaluatorsArr, aggregatorsArr, groupKeyBinding, reclaimGroupAged, reclaimGroupFrequency, variableService, pairs, accessAggregations, join, optionalContextName)); }
public AggregationServiceFactory GetGroupReclaimAged( ExprNode[] groupByNodes, ExprEvaluator[] evaluatorsArr, AggregationMethodFactory[] aggregatorsArr, HintAttribute reclaimGroupAged, HintAttribute reclaimGroupFrequency, VariableService variableService, AggregationAccessorSlotPair[] pairs, AggregationStateFactory[] accessAggregations, bool @join, string optionalContextName, bool isUnidirectional, bool isFireAndForget, bool isOnSelect) { return(new AggSvcGroupByReclaimAgedFactory( evaluatorsArr, aggregatorsArr, reclaimGroupAged, reclaimGroupFrequency, variableService, pairs, accessAggregations, join, optionalContextName)); }
/// <summary> /// Ctor. /// </summary> /// <param name="evaluators">evaluate the sub-expression within the aggregate function (ie. sum(4*myNum))</param> /// <param name="prototypes">collect the aggregation state that evaluators evaluate to, act as prototypes for new aggregationsaggregation states for each group</param> /// <param name="groupKeyBinding">The group key binding.</param> /// <param name="reclaimGroupAged">hint to reclaim</param> /// <param name="reclaimGroupFrequency">hint to reclaim</param> /// <param name="variableService">variables</param> /// <param name="accessors">accessor definitions</param> /// <param name="accessAggregations">access aggs</param> /// <param name="isJoin">true for join, false for single-stream</param> /// <param name="optionalContextName">Name of the optional context.</param> /// <exception cref="ExprValidationException">Required hint value for hint ' + HintEnum.RECLAIM_GROUP_AGED + ' has not been provided</exception> /// <throws><seealso cref="ExprValidationException" /> when validation fails</throws> public AggSvcGroupByReclaimAgedFactory( ExprEvaluator[] evaluators, AggregationMethodFactory[] prototypes, Object groupKeyBinding, HintAttribute reclaimGroupAged, HintAttribute reclaimGroupFrequency, VariableService variableService, AggregationAccessorSlotPair[] accessors, AggregationStateFactory[] accessAggregations, bool isJoin, String optionalContextName) : base(evaluators, prototypes, groupKeyBinding) { this.Accessors = accessors; this.AccessAggregations = accessAggregations; this.IsJoin = isJoin; String hintValueMaxAge = HintEnum.RECLAIM_GROUP_AGED.GetHintAssignedValue(reclaimGroupAged); if (hintValueMaxAge == null) { throw new ExprValidationException("Required hint value for hint '" + HintEnum.RECLAIM_GROUP_AGED + "' has not been provided"); } EvaluationFunctionMaxAge = GetEvaluationFunction(variableService, hintValueMaxAge, optionalContextName); String hintValueFrequency = HintEnum.RECLAIM_GROUP_FREQ.GetHintAssignedValue(reclaimGroupAged); if ((reclaimGroupFrequency == null) || (hintValueFrequency == null)) { EvaluationFunctionFrequency = EvaluationFunctionMaxAge; } else { EvaluationFunctionFrequency = GetEvaluationFunction(variableService, hintValueFrequency, optionalContextName); } }
public static AggregationServiceFactoryDesc GetService( IList<ExprAggregateNode> selectAggregateExprNodes, IDictionary<ExprNode, string> selectClauseNamedNodes, IList<ExprDeclaredNode> declaredExpressions, ExprNode[] groupByNodes, IList<ExprAggregateNode> havingAggregateExprNodes, IList<ExprAggregateNode> orderByAggregateExprNodes, IList<ExprAggregateNodeGroupKey> groupKeyExpressions, bool hasGroupByClause, Attribute[] annotations, VariableService variableService, bool isJoin, bool isDisallowNoReclaim, ExprNode whereClause, ExprNode havingClause, AggregationServiceFactoryService factoryService, EventType[] typesPerStream, AggregationGroupByRollupDesc groupByRollupDesc, string optionalContextName, IntoTableSpec intoTableSpec, TableService tableService, bool isUnidirectional, bool isFireAndForget, bool isOnSelect, EngineImportService engineImportService) { // No aggregates used, we do not need this service if ((selectAggregateExprNodes.IsEmpty()) && (havingAggregateExprNodes.IsEmpty())) { if (intoTableSpec != null) { throw new ExprValidationException("Into-table requires at least one aggregation function"); } return new AggregationServiceFactoryDesc( factoryService.GetNullAggregationService(), Collections.GetEmptyList<AggregationServiceAggExpressionDesc>(), Collections.GetEmptyList<ExprAggregateNodeGroupKey>()); } // Validate the absence of "prev" function in where-clause: // Since the "previous" function does not post remove stream results, disallow when used with aggregations. if ((whereClause != null) || (havingClause != null)) { var visitor = new ExprNodePreviousVisitorWParent(); if (whereClause != null) { whereClause.Accept(visitor); } if (havingClause != null) { havingClause.Accept(visitor); } if ((visitor.Previous != null) && (!visitor.Previous.IsEmpty())) { string funcname = visitor.Previous[0].Second.PreviousType.ToString().ToLowerInvariant(); throw new ExprValidationException( "The '" + funcname + "' function may not occur in the where-clause or having-clause of a statement with aggregations as 'previous' does not provide remove stream data; Use the 'first','last','window' or 'count' aggregation functions instead"); } } // Compile a map of aggregation nodes and equivalent-to aggregation nodes. // Equivalent-to functions are for example "select Sum(a*b), 5*Sum(a*b)". // Reducing the total number of aggregation functions. var aggregations = new List<AggregationServiceAggExpressionDesc>(); foreach (ExprAggregateNode selectAggNode in selectAggregateExprNodes) { AddEquivalent(selectAggNode, aggregations); } foreach (ExprAggregateNode havingAggNode in havingAggregateExprNodes) { AddEquivalent(havingAggNode, aggregations); } foreach (ExprAggregateNode orderByAggNode in orderByAggregateExprNodes) { AddEquivalent(orderByAggNode, aggregations); } // Construct a list of evaluation node for the aggregation functions (regular agg). // For example "Sum(2 * 3)" would make the sum an evaluation node. var methodAggEvaluatorsList = new List<ExprEvaluator>(); foreach (AggregationServiceAggExpressionDesc aggregation in aggregations) { ExprAggregateNode aggregateNode = aggregation.AggregationNode; if (!aggregateNode.Factory.IsAccessAggregation) { ExprEvaluator evaluator = aggregateNode.Factory.GetMethodAggregationEvaluator(typesPerStream.Length > 1, typesPerStream); methodAggEvaluatorsList.Add(evaluator); } } // determine local group-by, report when hook provided AggregationGroupByLocalGroupDesc localGroupDesc = AnalyzeLocalGroupBy( aggregations, groupByNodes, groupByRollupDesc, intoTableSpec); // determine binding AggregationServiceFactory serviceFactory; if (intoTableSpec != null) { // obtain metadata TableMetadata metadata = tableService.GetTableMetadata(intoTableSpec.Name); if (metadata == null) { throw new ExprValidationException( "Invalid into-table clause: Failed to find table by name '" + intoTableSpec.Name + "'"); } EPLValidationUtil.ValidateContextName( true, intoTableSpec.Name, metadata.ContextName, optionalContextName, false); // validate group keys Type[] groupByTypes = ExprNodeUtility.GetExprResultTypes(groupByNodes); ExprTableNodeUtil.ValidateExpressions( intoTableSpec.Name, groupByTypes, "group-by", groupByNodes, metadata.KeyTypes, "group-by"); // determine how this binds to existing aggregations, assign column numbers BindingMatchResult bindingMatchResult = MatchBindingsAssignColumnNumbers( intoTableSpec, metadata, aggregations, selectClauseNamedNodes, methodAggEvaluatorsList, declaredExpressions); // return factory if (!hasGroupByClause) { serviceFactory = factoryService.GetNoGroupWBinding( bindingMatchResult.Accessors, isJoin, bindingMatchResult.MethodPairs, intoTableSpec.Name, bindingMatchResult.TargetStates, bindingMatchResult.AccessStateExpr, bindingMatchResult.Agents); } else { serviceFactory = factoryService.GetGroupWBinding( metadata, bindingMatchResult.MethodPairs, bindingMatchResult.Accessors, isJoin, intoTableSpec, bindingMatchResult.TargetStates, bindingMatchResult.AccessStateExpr, bindingMatchResult.Agents, groupByRollupDesc); } return new AggregationServiceFactoryDesc(serviceFactory, aggregations, groupKeyExpressions); } // Assign a column number to each aggregation node. The regular aggregation goes first followed by access-aggregation. int columnNumber = 0; foreach (AggregationServiceAggExpressionDesc entry in aggregations) { if (!entry.Factory.IsAccessAggregation) { entry.ColumnNum = columnNumber++; } } foreach (AggregationServiceAggExpressionDesc entry in aggregations) { if (entry.Factory.IsAccessAggregation) { entry.ColumnNum = columnNumber++; } } // determine method aggregation factories and Evaluators(non-access) ExprEvaluator[] methodAggEvaluators = methodAggEvaluatorsList.ToArray(); var methodAggFactories = new AggregationMethodFactory[methodAggEvaluators.Length]; int count = 0; foreach (AggregationServiceAggExpressionDesc aggregation in aggregations) { ExprAggregateNode aggregateNode = aggregation.AggregationNode; if (!aggregateNode.Factory.IsAccessAggregation) { methodAggFactories[count] = aggregateNode.Factory; count++; } } // handle access aggregations AggregationMultiFunctionAnalysisResult multiFunctionAggPlan = AggregationMultiFunctionAnalysisHelper.AnalyzeAccessAggregations(aggregations); AggregationAccessorSlotPair[] accessorPairs = multiFunctionAggPlan.AccessorPairs; AggregationStateFactory[] accessAggregations = multiFunctionAggPlan.StateFactories; // analyze local group by AggregationLocalGroupByPlan localGroupByPlan = null; if (localGroupDesc != null) { localGroupByPlan = AggregationGroupByLocalGroupByAnalyzer.Analyze( methodAggEvaluators, methodAggFactories, accessAggregations, localGroupDesc, groupByNodes, accessorPairs); try { var hook = (AggregationLocalLevelHook) TypeHelper.GetAnnotationHook( annotations, HookType.INTERNAL_AGGLOCALLEVEL, typeof (AggregationLocalLevelHook), engineImportService); if (hook != null) { hook.Planned(localGroupDesc, localGroupByPlan); } } catch (ExprValidationException) { throw new EPException("Failed to obtain hook for " + HookType.INTERNAL_AGGLOCALLEVEL); } } // Handle without a group-by clause: we group all into the same pot if (!hasGroupByClause) { if (localGroupByPlan != null) { serviceFactory = factoryService.GetNoGroupLocalGroupBy( isJoin, localGroupByPlan, isUnidirectional, isFireAndForget, isOnSelect); } else if ((methodAggEvaluators.Length > 0) && (accessorPairs.Length == 0)) { serviceFactory = factoryService.GetNoGroupNoAccess( methodAggEvaluators, methodAggFactories, isUnidirectional, isFireAndForget, isOnSelect); } else if ((methodAggEvaluators.Length == 0) && (accessorPairs.Length > 0)) { serviceFactory = factoryService.GetNoGroupAccessOnly( accessorPairs, accessAggregations, isJoin, isUnidirectional, isFireAndForget, isOnSelect); } else { serviceFactory = factoryService.GetNoGroupAccessMixed( methodAggEvaluators, methodAggFactories, accessorPairs, accessAggregations, isJoin, isUnidirectional, isFireAndForget, isOnSelect); } } else { bool hasNoReclaim = HintEnum.DISABLE_RECLAIM_GROUP.GetHint(annotations) != null; HintAttribute reclaimGroupAged = HintEnum.RECLAIM_GROUP_AGED.GetHint(annotations); HintAttribute reclaimGroupFrequency = HintEnum.RECLAIM_GROUP_AGED.GetHint(annotations); if (localGroupByPlan != null) { serviceFactory = factoryService.GetGroupLocalGroupBy( isJoin, localGroupByPlan, isUnidirectional, isFireAndForget, isOnSelect); } else { if (!isDisallowNoReclaim && hasNoReclaim) { if (groupByRollupDesc != null) { throw GetRollupReclaimEx(); } if ((methodAggEvaluators.Length > 0) && (accessorPairs.Length == 0)) { serviceFactory = factoryService.GetGroupedNoReclaimNoAccess( groupByNodes, methodAggEvaluators, methodAggFactories, isUnidirectional, isFireAndForget, isOnSelect); } else if ((methodAggEvaluators.Length == 0) && (accessorPairs.Length > 0)) { serviceFactory = factoryService.GetGroupNoReclaimAccessOnly( groupByNodes, accessorPairs, accessAggregations, isJoin, isUnidirectional, isFireAndForget, isOnSelect); } else { serviceFactory = factoryService.GetGroupNoReclaimMixed( groupByNodes, methodAggEvaluators, methodAggFactories, accessorPairs, accessAggregations, isJoin, isUnidirectional, isFireAndForget, isOnSelect); } } else if (!isDisallowNoReclaim && reclaimGroupAged != null) { if (groupByRollupDesc != null) { throw GetRollupReclaimEx(); } serviceFactory = factoryService.GetGroupReclaimAged( groupByNodes, methodAggEvaluators, methodAggFactories, reclaimGroupAged, reclaimGroupFrequency, variableService, accessorPairs, accessAggregations, isJoin, optionalContextName, isUnidirectional, isFireAndForget, isOnSelect); } else if (groupByRollupDesc != null) { serviceFactory = factoryService.GetGroupReclaimMixableRollup( groupByNodes, groupByRollupDesc, methodAggEvaluators, methodAggFactories, accessorPairs, accessAggregations, isJoin, groupByRollupDesc, isUnidirectional, isFireAndForget, isOnSelect); } else { if ((methodAggEvaluators.Length > 0) && (accessorPairs.Length == 0)) { serviceFactory = factoryService.GetGroupReclaimNoAccess( groupByNodes, methodAggEvaluators, methodAggFactories, accessorPairs, accessAggregations, isJoin, isUnidirectional, isFireAndForget, isOnSelect); } else { serviceFactory = factoryService.GetGroupReclaimMixable( groupByNodes, methodAggEvaluators, methodAggFactories, accessorPairs, accessAggregations, isJoin, isUnidirectional, isFireAndForget, isOnSelect); } } } } return new AggregationServiceFactoryDesc(serviceFactory, aggregations, groupKeyExpressions); }