public AggregationServiceFactory GetGroupLocalGroupBy(
     bool join,
     AggregationLocalGroupByPlan localGroupByPlan,
     Object groupKeyBinding)
 {
     return(new AggSvcGroupByLocalGroupByFactory(join, localGroupByPlan, groupKeyBinding));
 }
 public AggregationServiceFactory GetGroupLocalGroupBy(
     bool @join,
     AggregationLocalGroupByPlan localGroupByPlan,
     bool isUnidirectional,
     bool isFireAndForget,
     bool isOnSelect)
 {
     return(new AggSvcGroupByLocalGroupByFactory(join, localGroupByPlan));
 }
Example #3
0
 public AggSvcGroupAllLocalGroupByFactory(
     bool join,
     AggregationLocalGroupByPlan localGroupByPlan,
     object groupKeyBinding)
 {
     IsJoin = join;
     _localGroupByPlan = localGroupByPlan;
     _groupKeyBinding = groupKeyBinding;
 }
Example #4
0
 public AggregationServiceFactory GetNoGroupLocalGroupBy(
     bool join,
     AggregationLocalGroupByPlan localGroupByPlan,
     object groupKeyBinding,
     bool isUnidirectional,
     bool isFireAndForget,
     bool isOnSelect)
 {
     return(new AggSvcGroupAllLocalGroupByFactory(join, localGroupByPlan, groupKeyBinding));
 }
        protected AggSvcGroupLocalGroupByBase(bool isJoin, AggregationLocalGroupByPlan localGroupByPlan)
        {
            IsJoin           = isJoin;
            LocalGroupByPlan = localGroupByPlan;

            AggregatorsPerLevelAndGroup = new IDictionary <object, AggregationMethodPairRow> [localGroupByPlan.AllLevels.Length];
            for (var i = 0; i < localGroupByPlan.AllLevels.Length; i++)
            {
                AggregatorsPerLevelAndGroup[i] = new Dictionary <object, AggregationMethodPairRow>();
            }
            RemovedKeys = new List <Pair <int, object> >();
        }
        public AggSvcGroupLocalGroupByBase(
            MethodResolutionService methodResolutionService,
            bool isJoin,
            AggregationLocalGroupByPlan localGroupByPlan,
            object groupKeyBinding)
        {
            this.methodResolutionService = methodResolutionService;
            this.isJoin           = isJoin;
            this.localGroupByPlan = localGroupByPlan;
            this.groupKeyBinding  = groupKeyBinding;

            this.AggregatorsPerLevelAndGroup = new IDictionary <object, AggregationMethodPairRow> [localGroupByPlan.AllLevels.Length];
            for (var i = 0; i < localGroupByPlan.AllLevels.Length; i++)
            {
                this.AggregatorsPerLevelAndGroup[i] = new Dictionary <object, AggregationMethodPairRow>();
            }
            RemovedKeys = new List <Pair <int, object> >();
        }
Example #7
0
 public AggSvcGroupByLocalGroupByFactory(bool @join, AggregationLocalGroupByPlan localGroupByPlan)
 {
     Join             = join;
     LocalGroupByPlan = localGroupByPlan;
 }
 public object GetGroupKeyBinding(AggregationLocalGroupByPlan localGroupByPlan)
 {
     return(null);       // no bindings
 }
Example #9
0
 public AggSvcGroupAllLocalGroupByFactory(bool @join, AggregationLocalGroupByPlan localGroupByPlan)
 {
     IsJoin = join;
     _localGroupByPlan = localGroupByPlan;
 }
        /// <summary>
        /// Returns an instance to handle the aggregation required by the aggregation expression nodes, depending on
        /// whether there are any group-by nodes.
        /// </summary>
        /// <param name="selectAggregateExprNodes">aggregation nodes extracted out of the select expression</param>
        /// <param name="selectClauseNamedNodes">The select clause named nodes.</param>
        /// <param name="declaredExpressions">The declared expressions.</param>
        /// <param name="groupByNodes">The group by nodes.</param>
        /// <param name="havingAggregateExprNodes">aggregation nodes extracted out of the select expression</param>
        /// <param name="orderByAggregateExprNodes">aggregation nodes extracted out of the select expression</param>
        /// <param name="groupKeyExpressions">The group key expressions.</param>
        /// <param name="hasGroupByClause">indicator on whethere there is group-by required, or group-all</param>
        /// <param name="annotations">statement annotations</param>
        /// <param name="variableService">variable</param>
        /// <param name="isJoin">true for joins</param>
        /// <param name="isDisallowNoReclaim">if set to <c>true</c> [is disallow no reclaim].</param>
        /// <param name="whereClause">the where-clause function if any</param>
        /// <param name="havingClause">the having-clause function if any</param>
        /// <param name="factoryService">The factory service.</param>
        /// <param name="typesPerStream">The types per stream.</param>
        /// <param name="methodResolutionService">The method resolution service.</param>
        /// <param name="groupByRollupDesc">The group by rollup desc.</param>
        /// <param name="optionalContextName">Name of the optional context.</param>
        /// <param name="intoTableSpec">The into table spec.</param>
        /// <param name="tableService">The table service.</param>
        /// <param name="isUnidirectional">if set to <c>true</c> [is unidirectional].</param>
        /// <param name="isFireAndForget">if set to <c>true</c> [is fire and forget].</param>
        /// <param name="isOnSelect">if set to <c>true</c> [is on select].</param>
        /// <returns>
        /// instance for aggregation handling
        /// </returns>
        /// <exception cref="ExprValidationException">
        /// Into-table requires at least one aggregation function
        /// or
        /// 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
        /// or
        /// Invalid into-table clause: Failed to find table by name ' + intoTableSpec.Name + '
        /// </exception>
        /// <exception cref="EPException">Failed to obtain hook for  + HookType.INTERNAL_AGGLOCALLEVEL</exception>
        /// <throws>com.espertech.esper.epl.expression.core.ExprValidationException if validation fails</throws>
        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,
            MethodResolutionService methodResolutionService,
            AggregationGroupByRollupDesc groupByRollupDesc,
            string optionalContextName,
            IntoTableSpec intoTableSpec,
            TableService tableService,
            bool isUnidirectional,
            bool isFireAndForget,
            bool isOnSelect)
        {
            // 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().ToLower();
                    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.
            IList <AggregationServiceAggExpressionDesc> aggregations = new List <AggregationServiceAggExpressionDesc>();

            foreach (var selectAggNode in selectAggregateExprNodes)
            {
                AddEquivalent(selectAggNode, aggregations);
            }
            foreach (var havingAggNode in havingAggregateExprNodes)
            {
                AddEquivalent(havingAggNode, aggregations);
            }
            foreach (var 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.
            IList <ExprEvaluator> methodAggEvaluatorsList = new List <ExprEvaluator>();

            foreach (var aggregation in aggregations)
            {
                var aggregateNode = aggregation.AggregationNode;
                if (!aggregateNode.Factory.IsAccessAggregation)
                {
                    var 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
            if (intoTableSpec != null)
            {
                // obtain metadata
                var 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
                var 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
                var bindingMatchResult = MatchBindingsAssignColumnNumbers(intoTableSpec, metadata, aggregations, selectClauseNamedNodes, methodAggEvaluatorsList, declaredExpressions);

                // return factory
                AggregationServiceFactory aggregationServiceFactory;
                if (!hasGroupByClause)
                {
                    aggregationServiceFactory = factoryService.GetNoGroupWBinding(bindingMatchResult.Accessors, isJoin, bindingMatchResult.MethodPairs, intoTableSpec.Name, bindingMatchResult.TargetStates, bindingMatchResult.AccessStateExpr, bindingMatchResult.Agents);
                }
                else
                {
                    aggregationServiceFactory = factoryService.GetGroupWBinding(metadata, bindingMatchResult.MethodPairs, bindingMatchResult.Accessors, isJoin, intoTableSpec, bindingMatchResult.TargetStates, bindingMatchResult.AccessStateExpr, bindingMatchResult.Agents, groupByRollupDesc);
                }
                return(new AggregationServiceFactoryDesc(aggregationServiceFactory, aggregations, groupKeyExpressions));
            }

            // Assign a column number to each aggregation node. The regular aggregation goes first followed by access-aggregation.
            var columnNumber = 0;

            foreach (var entry in aggregations)
            {
                if (!entry.Factory.IsAccessAggregation)
                {
                    entry.ColumnNum = columnNumber++;
                }
            }
            foreach (var 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];
            var             count = 0;

            foreach (var aggregation in aggregations)
            {
                var aggregateNode = aggregation.AggregationNode;
                if (!aggregateNode.Factory.IsAccessAggregation)
                {
                    methodAggFactories[count] = aggregateNode.Factory;
                    count++;
                }
            }

            // handle access aggregations
            var multiFunctionAggPlan = AggregationMultiFunctionAnalysisHelper.AnalyzeAccessAggregations(aggregations);
            var accessorPairs        = multiFunctionAggPlan.AccessorPairs;
            var accessAggregations   = multiFunctionAggPlan.StateFactories;

            AggregationServiceFactory serviceFactory;

            // analyze local group by
            AggregationLocalGroupByPlan localGroupByPlan = null;

            if (localGroupDesc != null)
            {
                localGroupByPlan = AggregationGroupByLocalGroupByAnalyzer.Analyze(methodAggEvaluators, methodAggFactories, accessAggregations, localGroupDesc, groupByNodes, accessorPairs);
                try {
                    AggregationLocalLevelHook hook = (AggregationLocalLevelHook)TypeHelper.GetAnnotationHook(annotations, HookType.INTERNAL_AGGLOCALLEVEL, typeof(AggregationLocalLevelHook), null);
                    if (hook != null)
                    {
                        hook.Planned(localGroupDesc, localGroupByPlan);
                    }
                }
                catch (ExprValidationException e) {
                    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)
                {
                    var groupKeyBinding = methodResolutionService.GetGroupKeyBinding(localGroupByPlan);
                    serviceFactory = factoryService.GetNoGroupLocalGroupBy(isJoin, localGroupByPlan, groupKeyBinding, 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
            {
                var hasNoReclaim          = HintEnum.DISABLE_RECLAIM_GROUP.GetHint(annotations) != null;
                var reclaimGroupAged      = HintEnum.RECLAIM_GROUP_AGED.GetHint(annotations);
                var reclaimGroupFrequency = HintEnum.RECLAIM_GROUP_AGED.GetHint(annotations);
                if (localGroupByPlan != null)
                {
                    var groupKeyBinding = methodResolutionService.GetGroupKeyBinding(localGroupByPlan);
                    serviceFactory = factoryService.GetGroupLocalGroupBy(isJoin, localGroupByPlan, groupKeyBinding, isUnidirectional, isFireAndForget, isOnSelect);
                }
                else
                {
                    var groupKeyBinding = methodResolutionService.GetGroupKeyBinding(groupByNodes, groupByRollupDesc);
                    if (!isDisallowNoReclaim && hasNoReclaim)
                    {
                        if (groupByRollupDesc != null)
                        {
                            throw GetRollupReclaimEx();
                        }
                        if ((methodAggEvaluators.Length > 0) && (accessorPairs.Length == 0))
                        {
                            serviceFactory = factoryService.GetGroupedNoReclaimNoAccess(methodAggEvaluators, methodAggFactories, groupKeyBinding, isUnidirectional, isFireAndForget, isOnSelect);
                        }
                        else if ((methodAggEvaluators.Length == 0) && (accessorPairs.Length > 0))
                        {
                            serviceFactory = factoryService.GetGroupNoReclaimAccessOnly(accessorPairs, accessAggregations, groupKeyBinding, isJoin, isUnidirectional, isFireAndForget, isOnSelect);
                        }
                        else
                        {
                            serviceFactory = factoryService.GetGroupNoReclaimMixed(methodAggEvaluators, methodAggFactories, accessorPairs, accessAggregations, isJoin, groupKeyBinding, isUnidirectional, isFireAndForget, isOnSelect);
                        }
                    }
                    else if (!isDisallowNoReclaim && reclaimGroupAged != null)
                    {
                        if (groupByRollupDesc != null)
                        {
                            throw GetRollupReclaimEx();
                        }
                        serviceFactory = factoryService.GetGroupReclaimAged(methodAggEvaluators, methodAggFactories, reclaimGroupAged, reclaimGroupFrequency, variableService, accessorPairs, accessAggregations, isJoin, groupKeyBinding, optionalContextName, isUnidirectional, isFireAndForget, isOnSelect);
                    }
                    else if (groupByRollupDesc != null)
                    {
                        serviceFactory = factoryService.GetGroupReclaimMixableRollup(methodAggEvaluators, methodAggFactories, accessorPairs, accessAggregations, isJoin, groupKeyBinding, groupByRollupDesc, isUnidirectional, isFireAndForget, isOnSelect);
                    }
                    else
                    {
                        if ((methodAggEvaluators.Length > 0) && (accessorPairs.Length == 0))
                        {
                            serviceFactory = factoryService.GetGroupReclaimNoAccess(methodAggEvaluators, methodAggFactories, accessorPairs, accessAggregations, isJoin, groupKeyBinding, isUnidirectional, isFireAndForget, isOnSelect);
                        }
                        else
                        {
                            serviceFactory = factoryService.GetGroupReclaimMixable(methodAggEvaluators, methodAggFactories, accessorPairs, accessAggregations, isJoin, groupKeyBinding, isUnidirectional, isFireAndForget, isOnSelect);
                        }
                    }
                }
            }

            return(new AggregationServiceFactoryDesc(serviceFactory, aggregations, groupKeyExpressions));
        }
 public AggSvcGroupByLocalGroupBy(bool isJoin, AggregationLocalGroupByPlan localGroupByPlan)
     : base(isJoin, localGroupByPlan)
 {
 }
 public void Planned(AggregationGroupByLocalGroupDesc localGroupDesc, AggregationLocalGroupByPlan localGroupByPlan)
 {
     desc = new Pair <AggregationGroupByLocalGroupDesc, AggregationLocalGroupByPlan>(localGroupDesc, localGroupByPlan);
 }
Example #13
0
 public AggSvcGroupByLocalGroupBy(MethodResolutionService methodResolutionService, bool isJoin, AggregationLocalGroupByPlan localGroupByPlan, object groupKeyBinding)
     : base(methodResolutionService, isJoin, localGroupByPlan, groupKeyBinding)
 {
 }
 public AggSvcGroupByLocalGroupByFactory(bool join, AggregationLocalGroupByPlan localGroupByPlan, object groupKeyBinding)
 {
     this.join             = join;
     this.localGroupByPlan = localGroupByPlan;
     this.groupKeyBinding  = groupKeyBinding;
 }