Beispiel #1
0
 public ExprAggMultiFunctionLinearAccessNodeFactoryAccess(ExprAggMultiFunctionLinearAccessNode parent, AggregationAccessor accessor, Type accessorResultType, EventType containedEventType, AggregationStateKey optionalStateKey, AggregationStateFactory optionalStateFactory, AggregationAgent optionalAgent)
 {
     _parent               = parent;
     _accessor             = accessor;
     _accessorResultType   = accessorResultType;
     _containedEventType   = containedEventType;
     _optionalStateKey     = optionalStateKey;
     _optionalStateFactory = optionalStateFactory;
     _optionalAgent        = optionalAgent;
 }
Beispiel #2
0
        // Obtain those method and state factories for each level
        private static AggregationLocalGroupByLevel GetLevel(
            int levelNumber,
            AggregationGroupByLocalGroupLevel level,
            ExprEvaluator[] methodEvaluatorsAll,
            AggregationMethodFactory[] methodFactoriesAll,
            AggregationStateFactory[] stateFactoriesAll,
            AggregationLocalGroupByColumn[] columns,
            bool defaultLevel,
            AggregationAccessorSlotPair[] accessors)
        {
            ExprNode[] partitionExpr = level.PartitionExpr;
            ExprEvaluator[] partitionEvaluators = ExprNodeUtility.GetEvaluators(partitionExpr);

            IList<ExprEvaluator> methodEvaluators = new List<ExprEvaluator>();
            IList<AggregationMethodFactory> methodFactories = new List<AggregationMethodFactory>();
            IList<AggregationStateFactory> stateFactories = new List<AggregationStateFactory>();

            foreach (AggregationServiceAggExpressionDesc expr in level.Expressions)
            {
                int column = expr.ColumnNum.Value;
                int methodOffset = -1;
                bool methodAgg = true;
                AggregationAccessorSlotPair pair = null;

                if (column < methodEvaluatorsAll.Length)
                {
                    methodEvaluators.Add(methodEvaluatorsAll[column]);
                    methodFactories.Add(methodFactoriesAll[column]);
                    methodOffset = methodFactories.Count - 1;
                }
                else
                {
                    // slot gives us the number of the state factory
                    int absoluteSlot = accessors[column - methodEvaluatorsAll.Length].Slot;
                    AggregationAccessor accessor = accessors[column - methodEvaluatorsAll.Length].Accessor;
                    AggregationStateFactory factory = stateFactoriesAll[absoluteSlot];
                    int relativeSlot = stateFactories.IndexOf(factory);
                    if (relativeSlot == -1)
                    {
                        stateFactories.Add(factory);
                        relativeSlot = stateFactories.Count - 1;
                    }
                    methodAgg = false;
                    pair = new AggregationAccessorSlotPair(relativeSlot, accessor);
                }
                columns[column] = new AggregationLocalGroupByColumn(
                    defaultLevel, partitionEvaluators, methodOffset, methodAgg, pair, levelNumber);
            }

            return new AggregationLocalGroupByLevel(
                methodEvaluators.ToArray(),
                methodFactories.ToArray(),
                stateFactories.ToArray(), partitionEvaluators, defaultLevel);
        }
        // handle accessor aggregation (direct data window by-group access to properties)
        public static AggregationMultiFunctionAnalysisResult AnalyzeAccessAggregations(IList <AggregationServiceAggExpressionDesc> aggregations)
        {
            var currentSlot         = 0;
            var accessProviderSlots = new ArrayDeque <AggregationMFIdentifier>();
            var accessorPairs       = new List <AggregationAccessorSlotPair>();
            var stateFactories      = new List <AggregationStateFactory>();

            foreach (var aggregation in aggregations)
            {
                var aggregateNode = aggregation.AggregationNode;
                if (!aggregateNode.Factory.IsAccessAggregation)
                {
                    continue;
                }

                var providerKey = aggregateNode.Factory.GetAggregationStateKey(false);
                var existing    = FindExisting(accessProviderSlots, providerKey, aggregateNode.OptionalLocalGroupBy);

                int slot;
                if (existing == null)
                {
                    accessProviderSlots.Add(new AggregationMFIdentifier(providerKey, aggregateNode.OptionalLocalGroupBy, currentSlot));
                    slot = currentSlot++;
                    AggregationStateFactory providerFactory = aggregateNode.Factory.GetAggregationStateFactory(false);
                    stateFactories.Add(providerFactory);
                }
                else
                {
                    slot = existing.Slot;
                }

                var accessor = aggregateNode.Factory.Accessor;
                accessorPairs.Add(new AggregationAccessorSlotPair(slot, accessor));
            }

            var pairs = accessorPairs.ToArray();
            var accessAggregations = stateFactories.ToArray();

            return(new AggregationMultiFunctionAnalysisResult(pairs, accessAggregations));
        }
Beispiel #4
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);
            AggregationStateFactory stateFactory = validationContext.EngineImportService.AggregationFactoryFactory.MakeLinear(validationContext.StatementExtensionSvcContext, this, 0);
            var factory = new ExprAggMultiFunctionLinearAccessNodeFactoryAccess(this, accessor, TypeHelper.GetArrayType(componentType), containedType, null, stateFactory, null);

            return(new LinearAggregationFactoryDesc(factory, factory.ContainedEventType, null));
        }
Beispiel #5
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]);

            AggregationStateFactory stateFactory = validationContext.EngineImportService.AggregationFactoryFactory.MakeLinear(
                validationContext.StatementExtensionSvcContext, this, streamNum);

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

            return(new LinearAggregationFactoryDesc(factory, enumerationType, scalarCollectionComponentType));
        }
Beispiel #6
0
        private TableAccessAnalysisResult AnalyzePlanAggregations(
            string tableName,
            StatementContext statementContext,
            IList <TableColumnDesc> columns,
            EPServicesContext services,
            string internalTypeName,
            string publicTypeName)
        {
            // once upfront: obtains aggregation factories for each aggregation
            // we do this once as a factory may be a heavier object
            IDictionary <TableColumnDesc, AggregationMethodFactory> aggregationFactories = new Dictionary <TableColumnDesc, AggregationMethodFactory>();

            foreach (var column in columns)
            {
                if (column is TableColumnDescAgg)
                {
                    var agg     = (TableColumnDescAgg)column;
                    var factory = agg.Aggregation.Factory;
                    aggregationFactories.Put(column, factory);
                }
            }

            // sort into these categories:
            // plain / method-agg / access-agg
            // compile all-column public types
            IList <TableColumnDescTyped> plainColumns          = new List <TableColumnDescTyped>();
            IList <TableColumnDescAgg>   methodAggColumns      = new List <TableColumnDescAgg>();
            IList <TableColumnDescAgg>   accessAggColumns      = new List <TableColumnDescAgg>();
            IDictionary <string, object> allColumnsPublicTypes = new LinkedHashMap <string, object>();

            foreach (var column in columns)
            {
                // handle plain types
                if (column is TableColumnDescTyped)
                {
                    var typed = (TableColumnDescTyped)column;
                    plainColumns.Add(typed);
                    allColumnsPublicTypes.Put(column.ColumnName, typed.UnresolvedType);
                    continue;
                }

                // handle aggs
                var agg        = (TableColumnDescAgg)column;
                var aggFactory = aggregationFactories.Get(agg);
                if (aggFactory.IsAccessAggregation)
                {
                    accessAggColumns.Add(agg);
                }
                else
                {
                    methodAggColumns.Add(agg);
                }
                allColumnsPublicTypes.Put(column.ColumnName, agg.Aggregation.ReturnType);
            }

            // determine column metadata
            //
            IDictionary <string, TableMetadataColumn> columnMetadata = new LinkedHashMap <string, TableMetadataColumn>();

            // handle typed columns
            IDictionary <string, object> allColumnsInternalTypes = new LinkedHashMap <string, object>();

            allColumnsInternalTypes.Put(TableServiceConstants.INTERNAL_RESERVED_PROPERTY, typeof(object));
            var         indexPlain       = 1;
            IList <int> groupKeyIndexes  = new List <int>();
            var         assignPairsPlain = new TableMetadataColumnPairPlainCol[plainColumns.Count];

            foreach (var typedColumn in plainColumns)
            {
                allColumnsInternalTypes.Put(typedColumn.ColumnName, typedColumn.UnresolvedType);
                columnMetadata.Put(typedColumn.ColumnName, new TableMetadataColumnPlain(typedColumn.ColumnName, typedColumn.IsKey, indexPlain));
                if (typedColumn.IsKey)
                {
                    groupKeyIndexes.Add(indexPlain);
                }
                assignPairsPlain[indexPlain - 1] = new TableMetadataColumnPairPlainCol(typedColumn.PositionInDeclaration, indexPlain);
                indexPlain++;
            }

            // determine internally-used event type
            // for use by indexes and lookups
            ObjectArrayEventType internalEventType;
            ObjectArrayEventType publicEventType;

            try
            {
                internalEventType = (ObjectArrayEventType)services.EventAdapterService.AddNestableObjectArrayType(internalTypeName, allColumnsInternalTypes, null, false, false, false, false, false, true, tableName);
                publicEventType   = (ObjectArrayEventType)services.EventAdapterService.AddNestableObjectArrayType(publicTypeName, allColumnsPublicTypes, null, false, false, false, false, false, false, null);
            }
            catch (EPException ex)
            {
                throw new ExprValidationException("Invalid type information: " + ex.Message, ex);
            }
            services.StatementEventTypeRefService.AddReferences(statementContext.StatementName, new string[] { internalTypeName, publicTypeName });

            // handle aggregation-methods single-func first.
            var methodFactories   = new AggregationMethodFactory[methodAggColumns.Count];
            var index             = 0;
            var assignPairsMethod = new TableMetadataColumnPairAggMethod[methodAggColumns.Count];

            foreach (var column in methodAggColumns)
            {
                var factory = aggregationFactories.Get(column);
                var optionalEnumerationType = EPTypeHelper.OptionalFromEnumerationExpr(statementContext.StatementId, statementContext.EventAdapterService, column.Aggregation);
                methodFactories[index] = factory;
                columnMetadata.Put(column.ColumnName, new TableMetadataColumnAggregation(column.ColumnName, factory, index, null, optionalEnumerationType, column.OptionalAssociatedType));
                assignPairsMethod[index] = new TableMetadataColumnPairAggMethod(column.PositionInDeclaration);
                index++;
            }

            // handle access-aggregation (sharable, multi-value) aggregations
            var stateFactories    = new AggregationStateFactory[accessAggColumns.Count];
            var assignPairsAccess = new TableMetadataColumnPairAggAccess[accessAggColumns.Count];

            index = 0;
            foreach (var column in accessAggColumns)
            {
                var factory = aggregationFactories.Get(column);
                stateFactories[index] = factory.GetAggregationStateFactory(false);
                var pair = new AggregationAccessorSlotPair(index, factory.Accessor);
                var optionalEnumerationType = EPTypeHelper.OptionalFromEnumerationExpr(statementContext.StatementId, statementContext.EventAdapterService, column.Aggregation);
                columnMetadata.Put(column.ColumnName, new TableMetadataColumnAggregation(column.ColumnName, factory, -1, pair, optionalEnumerationType, column.OptionalAssociatedType));
                assignPairsAccess[index] = new TableMetadataColumnPairAggAccess(column.PositionInDeclaration, factory.Accessor);
                index++;
            }

            // create state factory
            var groupKeyIndexesArr = CollectionUtil.IntArray(groupKeyIndexes);
            var stateRowFactory    = new TableStateRowFactory(
                internalEventType, statementContext.EngineImportService, methodFactories, stateFactories, groupKeyIndexesArr, services.EventAdapterService);

            // create public event provision
            var eventToPublic = new TableMetadataInternalEventToPublic(publicEventType,
                                                                       assignPairsPlain, assignPairsMethod, assignPairsAccess, services.EventAdapterService);

            return(new TableAccessAnalysisResult(stateRowFactory, columnMetadata, methodAggColumns.Count, internalEventType, publicEventType, eventToPublic));
        }