private AggregationForgeFactoryAccessSorted HandleNonTable(ExprValidationContext validationContext) { if (positionalParams.Length == 0) { throw new ExprValidationException("Missing the sort criteria expression"); } // validate that the streams referenced in the criteria are a single stream's var streams = ExprNodeUtilityQuery.GetIdentStreamNumbers(positionalParams[0]); if (streams.Count > 1 || streams.IsEmpty()) { throw new ExprValidationException( ErrorPrefix + " requires that any parameter expressions evaluate properties of the same stream"); } var streamNum = streams.First(); // validate that there is a remove stream, use "ever" if not if (!ever && ExprAggMultiFunctionLinearAccessNode.GetIstreamOnly( validationContext.StreamTypeService, streamNum)) { if (sortedwin) { throw new ExprValidationException( ErrorPrefix + " requires that a data window is declared for the stream"); } } // determine typing and evaluation containedType = validationContext.StreamTypeService.EventTypes[streamNum]; var componentType = containedType.UnderlyingType; var accessorResultType = componentType; AggregationAccessorForge accessor; var tableMetadata = validationContext.TableCompileTimeResolver.ResolveTableFromEventType(containedType); if (!sortedwin) { if (tableMetadata != null) { accessor = new AggregationAccessorMinMaxByTable(IsMax, tableMetadata); } else { accessor = new AggregationAccessorMinMaxByNonTable(IsMax); } } else { if (tableMetadata != null) { accessor = new AggregationAccessorSortedTable(IsMax, componentType, tableMetadata); } else { accessor = new AggregationAccessorSortedNonTable(IsMax, componentType); } accessorResultType = TypeHelper.GetArrayType(accessorResultType); } var criteriaExpressions = CriteriaExpressions; AggregationStateTypeWStream type; if (ever) { type = IsMax ? AggregationStateTypeWStream.MAXEVER : AggregationStateTypeWStream.MINEVER; } else { type = AggregationStateTypeWStream.SORTED; } var stateKey = new AggregationStateKeyWStream( streamNum, containedType, type, criteriaExpressions.First, optionalFilter); var optionalFilterForge = optionalFilter == null ? null : optionalFilter.Forge; var streamEventType = validationContext.StreamTypeService.EventTypes[streamNum]; var criteriaTypes = ExprNodeUtilityQuery.GetExprResultTypes(criteriaExpressions.First); var sortedDesc = new SortedAggregationStateDesc( IsMax, validationContext.ImportService, criteriaExpressions.First, criteriaTypes, criteriaExpressions.Second, ever, streamNum, this, optionalFilterForge, streamEventType); return new AggregationForgeFactoryAccessSorted( this, accessor, accessorResultType, containedType, stateKey, sortedDesc, AggregationAgentDefault.INSTANCE); }
private ExprAggMultiFunctionSortedMinMaxByNodeFactory HandleNonTable(ExprValidationContext validationContext) { if (PositionalParams.Length == 0) { throw new ExprValidationException("Missing the sort criteria expression"); } // validate that the streams referenced in the criteria are a single stream's var streams = ExprNodeUtility.GetIdentStreamNumbers(PositionalParams[0]); if (streams.Count > 1 || streams.IsEmpty()) { throw new ExprValidationException(ErrorPrefix + " requires that any parameter expressions evaluate properties of the same stream"); } int streamNum = streams.First(); // validate that there is a remove stream, use "ever" if not var forceEver = false; if (!_ever && ExprAggMultiFunctionLinearAccessNode.GetIstreamOnly(validationContext.StreamTypeService, streamNum)) { if (_sortedwin) { throw new ExprValidationException(ErrorPrefix + " requires that a data window is declared for the stream"); } forceEver = true; } // determine typing and evaluation _containedType = validationContext.StreamTypeService.EventTypes[streamNum]; var componentType = _containedType.UnderlyingType; var accessorResultType = componentType; AggregationAccessor accessor; TableMetadata tableMetadata = validationContext.TableService.GetTableMetadataFromEventType(_containedType); if (!_sortedwin) { if (tableMetadata != null) { accessor = new AggregationAccessorMinMaxByTable(_max, tableMetadata); } else { accessor = new AggregationAccessorMinMaxByNonTable(_max); } } else { if (tableMetadata != null) { accessor = new AggregationAccessorSortedTable(_max, componentType, tableMetadata); } else { accessor = new AggregationAccessorSortedNonTable(_max, componentType); } accessorResultType = TypeHelper.GetArrayType(accessorResultType); } Pair <ExprNode[], bool[]> criteriaExpressions = CriteriaExpressions; AggregationStateTypeWStream type; if (_ever) { type = _max ? AggregationStateTypeWStream.MAXEVER : AggregationStateTypeWStream.MINEVER; } else { type = AggregationStateTypeWStream.SORTED; } var stateKey = new AggregationStateKeyWStream(streamNum, _containedType, type, criteriaExpressions.First); var stateFactoryFactory = new SortedAggregationStateFactoryFactory(validationContext.MethodResolutionService, ExprNodeUtility.GetEvaluators(criteriaExpressions.First), criteriaExpressions.Second, _ever, streamNum, this); return(new ExprAggMultiFunctionSortedMinMaxByNodeFactory(this, accessor, accessorResultType, _containedType, stateKey, stateFactoryFactory, AggregationAgentDefault.INSTANCE)); }
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().ToLowerInvariant()); streamNum = 0; containedType = streamTypeService.EventTypes[0]; resultType = containedType.UnderlyingType; var 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); } else if (childNodes.Length > 0 && childNodes[0] is ExprStreamUnderlyingNode) { // validate "stream.*" 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; var tableMetadata = validationContext.TableService.GetTableMetadataFromEventType(type); evaluator = ExprNodeUtility.MakeUnderlyingEvaluator(streamNum, resultType, tableMetadata); } else { // validate when neither wildcard nor "stream.*" 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.IsInt32()) { 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(EvaluateParams.EmptyTrue).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; var tableMetadataX = validationContext.TableService.GetTableMetadataFromEventType(containedType); var optionalFilter = OptionalFilter; if (tableMetadataX == null && !isFafWindow && (istreamOnly || streamTypeService.IsOnDemandStreams)) { if (optionalFilter != null) PositionalParams = ExprNodeUtility.AddExpression(PositionalParams, optionalFilter); var factory = validationContext.EngineImportService.AggregationFactoryFactory.MakeLinearUnbounded( validationContext.StatementExtensionSvcContext, this, containedType, accessorResultType, streamNum, optionalFilter != null); return new LinearAggregationFactoryDesc(factory, containedType, scalarCollectionComponentType); } var stateKey = new AggregationStateKeyWStream( streamNum, containedType, AggregationStateTypeWStream.DATAWINDOWACCESS_LINEAR, new ExprNode[0], optionalFilter); var optionalFilterEval = optionalFilter?.ExprEvaluator; var stateFactory = validationContext.EngineImportService.AggregationFactoryFactory.MakeLinear( validationContext.StatementExtensionSvcContext, this, streamNum, optionalFilterEval); var factoryX = new ExprAggMultiFunctionLinearAccessNodeFactoryAccess(this, accessor, accessorResultType, containedType, stateKey, stateFactory, AggregationAgentDefault.INSTANCE); var enumerationType = scalarCollectionComponentType == null ? containedType : null; return new LinearAggregationFactoryDesc(factoryX, enumerationType, scalarCollectionComponentType); }
private ExprAggMultiFunctionSortedMinMaxByNodeFactory HandleNonTable(ExprValidationContext validationContext) { var positionalParams = PositionalParams; if (positionalParams.Length == 0) throw new ExprValidationException("Missing the sort criteria expression"); // validate that the streams referenced in the criteria are a single stream's var streams = ExprNodeUtility.GetIdentStreamNumbers(positionalParams[0]); if (streams.Count > 1 || streams.IsEmpty()) throw new ExprValidationException( GetErrorPrefix() + " requires that any parameter expressions evaluate properties of the same stream"); var streamNum = streams.First(); // validate that there is a remove stream, use "ever" if not if (!_ever && ExprAggMultiFunctionLinearAccessNode.GetIstreamOnly(validationContext.StreamTypeService, streamNum)) if (_sortedwin) throw new ExprValidationException( GetErrorPrefix() + " requires that a data window is declared for the stream"); // determine typing and evaluation _containedType = validationContext.StreamTypeService.EventTypes[streamNum]; var componentType = _containedType.UnderlyingType; var accessorResultType = componentType; AggregationAccessor accessor; var tableMetadata = validationContext.TableService.GetTableMetadataFromEventType(_containedType); if (!_sortedwin) { if (tableMetadata != null) accessor = new AggregationAccessorMinMaxByTable(IsMax, tableMetadata); else accessor = new AggregationAccessorMinMaxByNonTable(IsMax); } else { if (tableMetadata != null) accessor = new AggregationAccessorSortedTable(IsMax, componentType, tableMetadata); else accessor = new AggregationAccessorSortedNonTable(IsMax, componentType); accessorResultType = TypeHelper.GetArrayType(accessorResultType); } var criteriaExpressions = CriteriaExpressions; AggregationStateTypeWStream type; if (_ever) type = IsMax ? AggregationStateTypeWStream.MAXEVER : AggregationStateTypeWStream.MINEVER; else type = AggregationStateTypeWStream.SORTED; var optionalFilter = OptionalFilter; var stateKey = new AggregationStateKeyWStream( streamNum, _containedType, type, criteriaExpressions.First, optionalFilter); var optionalFilterEval = optionalFilter?.ExprEvaluator; var stateFactoryFactory = new SortedAggregationStateFactoryFactory(validationContext.EngineImportService, validationContext.StatementExtensionSvcContext, ExprNodeUtility.GetEvaluators(criteriaExpressions.First), criteriaExpressions.Second, _ever, streamNum, this, optionalFilterEval); return new ExprAggMultiFunctionSortedMinMaxByNodeFactory(this, accessor, accessorResultType, _containedType, stateKey, stateFactoryFactory, AggregationAgentDefault.INSTANCE); }
private AggregationForgeFactoryAccessSorted HandleNonTable(ExprValidationContext validationContext) { if (positionalParams.Length == 0) { throw new ExprValidationException("Missing the sort criteria expression"); } // validate that the streams referenced in the criteria are a single stream's ISet <int> streams = ExprNodeUtilityQuery.GetIdentStreamNumbers(positionalParams[0]); if (streams.Count > 1 || streams.IsEmpty()) { throw new ExprValidationException(ErrorPrefix + " requires that any parameter expressions evaluate properties of the same stream"); } int streamNum = streams.First(); // validate that there is a remove stream, use "ever" if not if (!_ever && ExprAggMultiFunctionLinearAccessNode.GetIstreamOnly(validationContext.StreamTypeService, streamNum)) { if (_sortedwin) { throw new ExprValidationException(ErrorPrefix + " requires that a data window is declared for the stream"); } } // determine typing and evaluation _containedType = validationContext.StreamTypeService.EventTypes[streamNum]; Type componentType = _containedType.UnderlyingType; Type accessorResultType = componentType; AggregationAccessorForge accessor; TableMetaData tableMetadata = validationContext.TableCompileTimeResolver.ResolveTableFromEventType(_containedType); if (!_sortedwin) { if (tableMetadata != null) { accessor = new AggregationAccessorMinMaxByTable(_max, tableMetadata); } else { accessor = new AggregationAccessorMinMaxByNonTable(_max); } } else { if (tableMetadata != null) { accessor = new AggregationAccessorSortedTable(_max, componentType, tableMetadata); } else { accessor = new AggregationAccessorSortedNonTable(_max, componentType); } accessorResultType = TypeHelper.GetArrayType(accessorResultType); } Pair <ExprNode[], bool[]> criteriaExpressions = CriteriaExpressions; AggregationStateTypeWStream type; if (_ever) { type = _max ? AggregationStateTypeWStream.MAXEVER : AggregationStateTypeWStream.MINEVER; } else { type = AggregationStateTypeWStream.SORTED; } AggregationStateKeyWStream stateKey = new AggregationStateKeyWStream(streamNum, _containedType, type, criteriaExpressions.First, optionalFilter); ExprForge optionalFilterForge = optionalFilter == null ? null : optionalFilter.Forge; EventType streamEventType = validationContext.StreamTypeService.EventTypes[streamNum]; Type[] criteriaTypes = ExprNodeUtilityQuery.GetExprResultTypes(criteriaExpressions.First); DataInputOutputSerdeForge[] criteriaSerdes = new DataInputOutputSerdeForge[criteriaTypes.Length]; for (int i = 0; i < criteriaTypes.Length; i++) { criteriaSerdes[i] = validationContext.SerdeResolver.SerdeForAggregation(criteriaTypes[i], validationContext.StatementRawInfo); } SortedAggregationStateDesc sortedDesc = new SortedAggregationStateDesc( _max, validationContext.ImportService, criteriaExpressions.First, criteriaTypes, criteriaSerdes, criteriaExpressions.Second, _ever, streamNum, this, optionalFilterForge, streamEventType); IList <StmtClassForgeableFactory> serdeForgables = SerdeEventTypeUtility.Plan( _containedType, validationContext.StatementRawInfo, validationContext.SerdeEventTypeRegistry, validationContext.SerdeResolver); validationContext.AdditionalForgeables.AddAll(serdeForgables); return(new AggregationForgeFactoryAccessSorted( this, accessor, accessorResultType, _containedType, stateKey, sortedDesc, AggregationAgentDefault.INSTANCE)); }
private AggregationLinearFactoryDesc HandleNonIntoTable( ExprNode[] childNodes, AggregationAccessorLinearType?stateType, ExprValidationContext validationContext) { var streamTypeService = validationContext.StreamTypeService; int streamNum; Type resultType; ExprForge forge; 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?.GetNameInvariant()); streamNum = 0; containedType = streamTypeService.EventTypes[0]; resultType = containedType.UnderlyingType; var tableMetadataX = validationContext.TableCompileTimeResolver.ResolveTableFromEventType(containedType); forge = ExprNodeUtilityMake.MakeUnderlyingForge(0, resultType, tableMetadataX); istreamOnly = GetIstreamOnly(streamTypeService, 0); if ((stateType == AggregationAccessorLinearType.WINDOW) && istreamOnly && !streamTypeService.IsOnDemandStreams) { throw MakeUnboundValidationEx(stateType); } } else if (childNodes.Length > 0 && childNodes[0] is ExprStreamUnderlyingNode) { // validate "stream.*" streamNum = ExprAggMultiFunctionUtil.ValidateStreamWildcardGetStreamNum(childNodes[0]); istreamOnly = GetIstreamOnly(streamTypeService, streamNum); if ((stateType == AggregationAccessorLinearType.WINDOW) && istreamOnly && !streamTypeService.IsOnDemandStreams) { throw MakeUnboundValidationEx(stateType); } var type = streamTypeService.EventTypes[streamNum]; containedType = type; resultType = type.UnderlyingType; var tableMetadataX = validationContext.TableCompileTimeResolver.ResolveTableFromEventType(type); forge = ExprNodeUtilityMake.MakeUnderlyingForge(streamNum, resultType, tableMetadataX); } else { // validate when neither wildcard nor "stream.*" var child = childNodes[0]; var streams = ExprNodeUtilityQuery.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 == AggregationAccessorLinearType.WINDOW) && istreamOnly && !streamTypeService.IsOnDemandStreams) { throw MakeUnboundValidationEx(stateType); } resultType = childNodes[0].Forge.EvaluationType; forge = childNodes[0].Forge; if (streamNum >= streamTypeService.EventTypes.Length) { containedType = streamTypeService.EventTypes[0]; } else { containedType = streamTypeService.EventTypes[streamNum]; } scalarCollectionComponentType = resultType; } if (childNodes.Length > 1) { if (stateType == AggregationAccessorLinearType.WINDOW) { throw new ExprValidationException(GetErrorPrefix(stateType) + " does not accept an index expression; Use 'first' or 'last' instead"); } evaluatorIndex = childNodes[1]; var indexResultType = evaluatorIndex.Forge.EvaluationType; if (indexResultType != typeof(int?) && indexResultType != typeof(int)) { throw new ExprValidationException(GetErrorPrefix(stateType) + " requires an index expression that returns an integer value"); } } // determine accessor AggregationAccessorForge accessor; if (evaluatorIndex != null) { var isFirst = stateType == AggregationAccessorLinearType.FIRST; var constant = -1; ExprForge forgeIndex; if (evaluatorIndex.Forge.ForgeConstantType.IsCompileTimeConstant) { constant = evaluatorIndex.Forge.ExprEvaluator.Evaluate(null, true, null).AsInt32(); forgeIndex = null; } else { forgeIndex = evaluatorIndex.Forge; } accessor = new AggregationAccessorFirstLastIndexWEvalForge(streamNum, forge, forgeIndex, constant, isFirst); } else { if (stateType == AggregationAccessorLinearType.FIRST) { accessor = new AggregationAccessorFirstWEvalForge(streamNum, forge); } else if (stateType == AggregationAccessorLinearType.LAST) { accessor = new AggregationAccessorLastWEvalForge(streamNum, forge); } else if (stateType == AggregationAccessorLinearType.WINDOW) { accessor = new AggregationAccessorWindowWEvalForge(streamNum, forge, resultType); } else { throw new IllegalStateException("Access type is undefined or not known as code '" + stateType + "'"); } } var accessorResultType = resultType; if (stateType == AggregationAccessorLinearType.WINDOW) { accessorResultType = TypeHelper.GetArrayType(resultType); } var isFafWindow = streamTypeService.IsOnDemandStreams && stateType == AggregationAccessorLinearType.WINDOW; var tableMetadata = validationContext.TableCompileTimeResolver.ResolveTableFromEventType(containedType); if (tableMetadata == null && !isFafWindow && (istreamOnly || streamTypeService.IsOnDemandStreams)) { if (optionalFilter != null) { positionalParams = ExprNodeUtilityMake.AddExpression(positionalParams, optionalFilter); } var serde = validationContext.SerdeResolver.SerdeForAggregation(accessorResultType, validationContext.StatementRawInfo); AggregationForgeFactory factoryX = new AggregationForgeFactoryFirstLastUnbound(this, accessorResultType, optionalFilter != null, serde); return(new AggregationLinearFactoryDesc(factoryX, containedType, scalarCollectionComponentType, streamNum)); } var stateKey = new AggregationStateKeyWStream( streamNum, containedType, AggregationStateTypeWStream.DATAWINDOWACCESS_LINEAR, ExprNodeUtilityQuery.EMPTY_EXPR_ARRAY, optionalFilter); var optionalFilterForge = optionalFilter == null ? null : optionalFilter.Forge; AggregationStateFactoryForge stateFactory = new AggregationStateLinearForge(this, streamNum, optionalFilterForge); var factory = new AggregationForgeFactoryAccessLinear( this, accessor, accessorResultType, stateKey, stateFactory, AggregationAgentDefault.INSTANCE, containedType); var enumerationType = scalarCollectionComponentType == null ? containedType : null; var serdeForgables = SerdeEventTypeUtility.Plan( containedType, validationContext.StatementRawInfo, validationContext.SerdeEventTypeRegistry, validationContext.SerdeResolver); validationContext.AdditionalForgeables.AddAll(serdeForgables); return(new AggregationLinearFactoryDesc(factory, enumerationType, scalarCollectionComponentType, streamNum)); }
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)); }