Example #1
0
        public AggregationStateFactory MakeFactory()
        {
            var sortUsingCollator  = _methodResolutionService.IsSortUsingCollator;
            var comparator         = CollectionUtil.GetComparator(_evaluators, sortUsingCollator, _sortDescending);
            var criteriaKeyBinding = _methodResolutionService.GetCriteriaKeyBinding(_evaluators);

            AggregationStateFactory factory;

            if (_ever)
            {
                var spec = new AggregationStateMinMaxByEverSpec(_streamNum, _evaluators, _parent.IsMax, comparator, criteriaKeyBinding);
                factory = new ProxyAggregationStateFactory()
                {
                    ProcCreateAccess          = (methodResolutionService, agentInstanceId, groupId, aggregationId, join, groupKey) => methodResolutionService.MakeAccessAggMinMaxEver(agentInstanceId, groupId, aggregationId, spec),
                    ProcAggregationExpression = () => _parent,
                };
            }
            else
            {
                var spec = new AggregationStateSortedSpec(_streamNum, _evaluators, comparator, criteriaKeyBinding);
                factory = new ProxyAggregationStateFactory()
                {
                    ProcCreateAccess = (methodResolutionService, agentInstanceId, groupId, aggregationId, join, groupKey) => {
                        if (join)
                        {
                            return(methodResolutionService.MakeAccessAggSortedJoin(agentInstanceId, groupId, aggregationId, spec));
                        }
                        return(methodResolutionService.MakeAccessAggSortedNonJoin(agentInstanceId, groupId, aggregationId, spec));
                    },

                    ProcAggregationExpression = () => _parent,
                };
            }
            return(factory);
        }
Example #2
0
        private LinearAggregationFactoryDesc HandleCreateTable(ExprNode[] childNodes, AggregationStateType stateType, ExprValidationContext validationContext)
        {
            var message = "For tables columns, the " + stateType.GetName().ToLower() + " aggregation function requires the 'window(*)' declaration";

            if (stateType != AggregationStateType.WINDOW)
            {
                throw new ExprValidationException(message);
            }
            if (childNodes.Length == 0 || childNodes.Length > 1 || !(childNodes[0] is ExprWildcard))
            {
                throw new ExprValidationException(message);
            }
            if (validationContext.StreamTypeService.StreamNames.Length == 0)
            {
                throw new ExprValidationException(GetErrorPrefix(stateType) + " requires that the event type is provided");
            }
            var containedType = validationContext.StreamTypeService.EventTypes[0];
            var componentType = containedType.UnderlyingType;
            AggregationAccessor     accessor     = new AggregationAccessorWindowNoEval(componentType);
            ExprNode                me           = this;
            AggregationStateFactory stateFactory = new ProxyAggregationStateFactory
            {
                ProcCreateAccess = (methodResolutionService, agentInstanceId, groupId, aggregationId, join, groupKey, passThru) =>
                                   methodResolutionService.MakeAccessAggLinearNonJoin(agentInstanceId, groupId, aggregationId, 0, passThru),
                ProcAggregationExpression = () => me,
            };
            var factory = new ExprAggMultiFunctionLinearAccessNodeFactoryAccess(this, accessor, TypeHelper.GetArrayType(componentType), containedType, null, stateFactory, null);

            return(new LinearAggregationFactoryDesc(factory, factory.ContainedEventType, null));
        }
Example #3
0
        private LinearAggregationFactoryDesc HandleNonIntoTable(ExprNode[] childNodes, AggregationStateType stateType, ExprValidationContext validationContext)
        {
            var           streamTypeService = validationContext.StreamTypeService;
            int           streamNum;
            Type          resultType;
            ExprEvaluator evaluator;
            ExprNode      evaluatorIndex = null;
            bool          istreamOnly;
            EventType     containedType;
            Type          scalarCollectionComponentType = null;

            // validate wildcard use
            var isWildcard = childNodes.Length == 0 || childNodes.Length > 0 && childNodes[0] is ExprWildcard;

            if (isWildcard)
            {
                ExprAggMultiFunctionUtil.ValidateWildcardStreamNumbers(validationContext.StreamTypeService, stateType.ToString().ToLower());
                streamNum     = 0;
                containedType = streamTypeService.EventTypes[0];
                resultType    = containedType.UnderlyingType;
                TableMetadata tableMetadata = validationContext.TableService.GetTableMetadataFromEventType(containedType);
                evaluator   = ExprNodeUtility.MakeUnderlyingEvaluator(0, resultType, tableMetadata);
                istreamOnly = GetIstreamOnly(streamTypeService, 0);
                if ((stateType == AggregationStateType.WINDOW) && istreamOnly && !streamTypeService.IsOnDemandStreams)
                {
                    throw MakeUnboundValidationEx(stateType);
                }
            }
            // validate "stream.*"
            else if (childNodes.Length > 0 && childNodes[0] is ExprStreamUnderlyingNode)
            {
                streamNum   = ExprAggMultiFunctionUtil.ValidateStreamWildcardGetStreamNum(childNodes[0]);
                istreamOnly = GetIstreamOnly(streamTypeService, streamNum);
                if ((stateType == AggregationStateType.WINDOW) && istreamOnly && !streamTypeService.IsOnDemandStreams)
                {
                    throw MakeUnboundValidationEx(stateType);
                }
                var type = streamTypeService.EventTypes[streamNum];
                containedType = type;
                resultType    = type.UnderlyingType;
                TableMetadata tableMetadata = validationContext.TableService.GetTableMetadataFromEventType(type);
                evaluator = ExprNodeUtility.MakeUnderlyingEvaluator(streamNum, resultType, tableMetadata);
            }
            // validate when neither wildcard nor "stream.*"
            else
            {
                var child   = childNodes[0];
                var streams = ExprNodeUtility.GetIdentStreamNumbers(child);
                if ((streams.IsEmpty() || (streams.Count > 1)))
                {
                    throw new ExprValidationException(GetErrorPrefix(stateType) + " requires that any child expressions evaluate properties of the same stream; Use 'firstever' or 'lastever' or 'nth' instead");
                }
                streamNum   = streams.First();
                istreamOnly = GetIstreamOnly(streamTypeService, streamNum);
                if ((stateType == AggregationStateType.WINDOW) && istreamOnly && !streamTypeService.IsOnDemandStreams)
                {
                    throw MakeUnboundValidationEx(stateType);
                }
                resultType = childNodes[0].ExprEvaluator.ReturnType;
                evaluator  = childNodes[0].ExprEvaluator;
                if (streamNum >= streamTypeService.EventTypes.Length)
                {
                    containedType = streamTypeService.EventTypes[0];
                }
                else
                {
                    containedType = streamTypeService.EventTypes[streamNum];
                }
                scalarCollectionComponentType = resultType;
            }

            if (childNodes.Length > 1)
            {
                if (stateType == AggregationStateType.WINDOW)
                {
                    throw new ExprValidationException(GetErrorPrefix(stateType) + " does not accept an index expression; Use 'first' or 'last' instead");
                }
                evaluatorIndex = childNodes[1];
                if (evaluatorIndex.ExprEvaluator.ReturnType != typeof(int?))
                {
                    throw new ExprValidationException(GetErrorPrefix(stateType) + " requires an index expression that returns an integer value");
                }
            }

            // determine accessor
            AggregationAccessor accessor;

            if (evaluatorIndex != null)
            {
                var isFirst  = stateType == AggregationStateType.FIRST;
                var constant = -1;
                if (evaluatorIndex.IsConstantResult)
                {
                    constant = evaluatorIndex.ExprEvaluator.Evaluate(new EvaluateParams(null, true, null)).AsInt();
                }
                accessor = new AggregationAccessorFirstLastIndexWEval(streamNum, evaluator, evaluatorIndex.ExprEvaluator, constant, isFirst);
            }
            else
            {
                if (stateType == AggregationStateType.FIRST)
                {
                    accessor = new AggregationAccessorFirstWEval(streamNum, evaluator);
                }
                else if (stateType == AggregationStateType.LAST)
                {
                    accessor = new AggregationAccessorLastWEval(streamNum, evaluator);
                }
                else if (stateType == AggregationStateType.WINDOW)
                {
                    accessor = new AggregationAccessorWindowWEval(streamNum, evaluator, resultType);
                }
                else
                {
                    throw new IllegalStateException("Access type is undefined or not known as code '" + stateType + "'");
                }
            }

            var accessorResultType = resultType;

            if (stateType == AggregationStateType.WINDOW)
            {
                accessorResultType = TypeHelper.GetArrayType(resultType);
            }

            var           isFafWindow    = streamTypeService.IsOnDemandStreams && stateType == AggregationStateType.WINDOW;
            TableMetadata tableMetadataX = validationContext.TableService.GetTableMetadataFromEventType(containedType);

            if (tableMetadataX == null && !isFafWindow && (istreamOnly || streamTypeService.IsOnDemandStreams))
            {
                var factoryX = new ExprAggMultiFunctionLinearAccessNodeFactoryMethod(this, containedType, accessorResultType, streamNum);
                return(new LinearAggregationFactoryDesc(factoryX, containedType, scalarCollectionComponentType));
            }

            var stateKey = new AggregationStateKeyWStream(streamNum, containedType, AggregationStateTypeWStream.DATAWINDOWACCESS_LINEAR, new ExprNode[0]);

            ExprNode me           = this;
            var      theStreamNum = streamNum;
            AggregationStateFactory stateFactory = new ProxyAggregationStateFactory
            {
                ProcCreateAccess = (methodResolutionService, agentInstanceId, groupId, aggregationId, join, groupKey, passThru) =>
                {
                    if (join)
                    {
                        return(methodResolutionService.MakeAccessAggLinearJoin(agentInstanceId, groupId, aggregationId, theStreamNum, passThru));
                    }
                    return(methodResolutionService.MakeAccessAggLinearNonJoin(agentInstanceId, groupId, aggregationId, theStreamNum, passThru));
                },

                ProcAggregationExpression = () => me
            };

            var factory = new ExprAggMultiFunctionLinearAccessNodeFactoryAccess(this, accessor, accessorResultType, containedType,
                                                                                stateKey, stateFactory, AggregationAgentDefault.INSTANCE);
            var enumerationType = scalarCollectionComponentType == null ? containedType : null;

            return(new LinearAggregationFactoryDesc(factory, enumerationType, scalarCollectionComponentType));
        }