Пример #1
0
        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);
        }
Пример #2
0
        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);
        }