internal TableAccessAnalysisResult(TableStateRowFactory stateRowFactory, IDictionary <String, TableMetadataColumn> tableColumns, int numberMethodAggregations, ObjectArrayEventType internalEventType, ObjectArrayEventType publicEventType, TableMetadataInternalEventToPublic eventToPublic) { StateRowFactory = stateRowFactory; TableColumns = tableColumns; NumberMethodAggregations = numberMethodAggregations; InternalEventType = internalEventType; PublicEventType = publicEventType; EventToPublic = eventToPublic; }
public EnumEvalCountOfSelectorScalar(ExprEvaluator innerExpression, int streamCountIncoming, ObjectArrayEventType type) : base(innerExpression, streamCountIncoming, type) { }
public EnumSelectFromScalar( ExprDotEvalParamLambda lambda, ObjectArrayEventType resultEventType, int numParameters) : base(lambda, resultEventType, numParameters) { }
public EnumEvalMostLeastFrequentScalarLamda(ExprEvaluator innerExpression, int streamCountIncoming, bool mostFrequent, ObjectArrayEventType resultEventType) : base(innerExpression, streamCountIncoming) { _isMostFrequent = mostFrequent; _resultEventType = resultEventType; }
public override ExprNode Validate(ExprValidationContext validationContext) { this.exprValidationContext = validationContext; var prototype = PrototypeWVisibility; if (prototype.IsAlias) { if (!ChainParameters.IsEmpty()) { throw new ExprValidationException("Expression '" + prototype.Name + " is an expression-alias and does not allow parameters"); } try { ExpressionBodyCopy = ExprNodeUtilityValidate.GetValidatedSubtree( ExprNodeOrigin.ALIASEXPRBODY, ExpressionBodyCopy, validationContext); } catch (ExprValidationException ex) { var message = "Failed to validate expression alias '" + prototype.Name + "': " + ex.Message; throw new ExprValidationException(message, ex); } forge = ExpressionBodyCopy.Forge; return null; } if (forge != null) { return null; // already evaluated } if (ChildNodes.Length > 0) { throw new IllegalStateException("Execution node has its own child nodes"); } // validate chain IList<ExprNode> validated = new List<ExprNode>(); foreach (var expr in ChainParameters) { validated.Add( ExprNodeUtilityValidate.GetValidatedSubtree( ExprNodeOrigin.DECLAREDEXPRPARAM, expr, validationContext)); } ChainParameters = validated; // validate parameter count CheckParameterCount(); // collect event and value (non-event) parameters List<int> valueParameters = new List<int>(); List<int> eventParameters = new List<int>(); for (int i = 0; i < prototype.ParametersNames.Length; i++) { ExprNode parameter = ChainParameters[i]; if (parameter is ExprWildcard) { if (validationContext.StreamTypeService.EventTypes.Length != 1) { throw new ExprValidationException("Expression '" + prototype.Name + "' only allows a wildcard parameter if there is a single stream available, please use a stream or tag name instead"); } } if (IsEventProviding(parameter, validationContext)) { eventParameters.Add(i); } else { valueParameters.Add(i); } } // determine value event type for holding non-event parameter values, if any ObjectArrayEventType valueEventType = null; List<ExprNode> valueExpressions = new List<ExprNode>(valueParameters.Count); if (!valueParameters.IsEmpty()) { var valuePropertyTypes = new LinkedHashMap<string, object>(); foreach (int index in valueParameters) { String name = prototype.ParametersNames[index]; ExprNode expr = ChainParameters[index]; var result = Boxing.GetBoxedType(expr.Forge.EvaluationType); valuePropertyTypes.Put(name, result); valueExpressions.Add(expr); } valueEventType = ExprDotNodeUtility.MakeTransientOAType( PrototypeWVisibility.Name, valuePropertyTypes, validationContext.StatementRawInfo, validationContext.StatementCompileTimeService); } // create context for expression body int numEventTypes = eventParameters.Count + (valueEventType == null ? 0 : 1); EventType[] eventTypes = new EventType[numEventTypes]; String[] streamNames = new String[numEventTypes]; bool[] isIStreamOnly = new bool[numEventTypes]; ExprEnumerationForge[] eventEnumerationForges = new ExprEnumerationForge[numEventTypes]; allStreamIdsMatch = true; int offsetEventType = 0; if (valueEventType != null) { offsetEventType = 1; eventTypes[0] = valueEventType; streamNames[0] = INTERNAL_VALUE_STREAMNAME; isIStreamOnly[0] = true; allStreamIdsMatch = false; } bool forceOptionalStream = false; foreach (int index in eventParameters) { ExprNode parameter = ChainParameters[index]; streamNames[offsetEventType] = prototype.ParametersNames[index]; int streamId; bool istreamOnlyFlag; ExprEnumerationForge forge; if (parameter is ExprEnumerationForgeProvider) { ExprEnumerationForgeProvider enumerationForgeProvider = (ExprEnumerationForgeProvider) parameter; ExprEnumerationForgeDesc desc = enumerationForgeProvider.GetEnumerationForge( validationContext.StreamTypeService, validationContext.ContextDescriptor); forge = desc.Forge; streamId = desc.DirectIndexStreamNumber; istreamOnlyFlag = desc.IsIstreamOnly; } else { forge = (ExprEnumerationForge) parameter.Forge; istreamOnlyFlag = false; streamId = -1; forceOptionalStream = true; // since they may return null, i.e. subquery returning no row or multiple rows etc. } isIStreamOnly[offsetEventType] = istreamOnlyFlag; eventEnumerationForges[offsetEventType] = forge; eventTypes[offsetEventType] = forge.GetEventTypeSingle(validationContext.StatementRawInfo, validationContext.StatementCompileTimeService); if (streamId != index) { allStreamIdsMatch = false; } offsetEventType++; } var streamTypeService = validationContext.StreamTypeService; var optionalStream = forceOptionalStream || streamTypeService.IsOptionalStreams; var copyTypes = new StreamTypeServiceImpl( eventTypes, streamNames, isIStreamOnly, streamTypeService.IsOnDemandStreams, optionalStream); copyTypes.RequireStreamNames = true; // validate expression body in this context try { var expressionBodyContext = new ExprValidationContext(copyTypes, validationContext); ExpressionBodyCopy = ExprNodeUtilityValidate.GetValidatedSubtree( ExprNodeOrigin.DECLAREDEXPRBODY, ExpressionBodyCopy, expressionBodyContext); } catch (ExprValidationException ex) { var message = "Failed to validate expression declaration '" + prototype.Name + "': " + ex.Message; throw new ExprValidationException(message, ex); } // analyze child node var summaryVisitor = new ExprNodeSummaryVisitor(); ExpressionBodyCopy.Accept(summaryVisitor); var isCache = !(summaryVisitor.HasAggregation || summaryVisitor.HasPreviousPrior); isCache &= validationContext.StatementCompileTimeService.Configuration.Compiler.Execution .IsEnabledDeclaredExprValueCache; // determine a suitable evaluation var audit = AuditEnum.EXPRDEF.GetAudit(validationContext.Annotations) != null; var statementName = validationContext.StatementName; if (ExpressionBodyCopy.Forge.ForgeConstantType.IsConstant) { // pre-evaluated forge = new ExprDeclaredForgeConstant( this, ExpressionBodyCopy.Forge.EvaluationType, prototype, ExpressionBodyCopy.Forge.ExprEvaluator.Evaluate(null, true, null), audit, statementName); } else if (valueEventType == null && prototype.ParametersNames.Length == 0 || allStreamIdsMatch && prototype.ParametersNames.Length == streamTypeService.EventTypes.Length) { forge = new ExprDeclaredForgeNoRewrite( this, ExpressionBodyCopy.Forge, isCache, audit, statementName); } else if (valueEventType == null) { forge = new ExprDeclaredForgeRewrite( this, ExpressionBodyCopy.Forge, isCache, eventEnumerationForges, audit, statementName); } else { // cache is always false forge = new ExprDeclaredForgeRewriteWValue( this, ExpressionBodyCopy.Forge, false, audit, statementName, eventEnumerationForges, valueEventType, valueExpressions); } return null; }
public EnumAverageDoubleScalar( ExprDotEvalParamLambda lambda, ObjectArrayEventType fieldEventType, int numParameters) : base(lambda, fieldEventType, numParameters) { }
public EnumEvalMinMaxScalarLambda(ExprEvaluator innerExpression, int streamCountIncoming, bool max, ObjectArrayEventType resultEventType) : base(innerExpression, streamCountIncoming) { _max = max; _resultEventType = resultEventType; }
public EnumEvalToMapScalarLambda(ExprEvaluator innerExpression, int streamCountIncoming, ExprEvaluator secondExpression, ObjectArrayEventType resultEventType) : base(innerExpression, streamCountIncoming) { _secondExpression = secondExpression; _resultEventType = resultEventType; }
private static EnumForgeLambdaDesc MakeDesc(ObjectArrayEventType type) { return(new EnumForgeLambdaDesc(new EventType[] { type }, new string[] { type.Name })); }
public EnumEvalAverageDecimalScalarLambda(ExprEvaluator innerExpression, int streamCountIncoming, ObjectArrayEventType resultEventType, MathContext optionalMathContext) : base(innerExpression, streamCountIncoming) { _resultEventType = resultEventType; _optionalMathContext = optionalMathContext; }
public EnumEvalAggregateScalar(ExprEvaluator initialization, ExprEvaluator innerExpression, int streamNumLambda, ObjectArrayEventType resultEventType, ObjectArrayEventType evalEventType) : base(initialization, innerExpression, streamNumLambda, resultEventType) { _evalEventType = evalEventType; }
/// <summary> /// Ctor. /// </summary> /// <param name="viewChain">views</param> /// <param name="matchRecognizeSpec">specification</param> /// <param name="agentInstanceContext">The agent instance context.</param> /// <param name="isUnbound">true for unbound stream</param> /// <param name="annotations">annotations</param> /// <exception cref="ExprValidationException"> /// Variable ' + defineItem.Identifier + ' has already been defined /// or /// An aggregate function may not appear in a DEFINE clause /// or /// Failed to validate condition expression for variable ' + defineItem.Identifier + ': + ex.Message /// or /// Aggregation functions in the measure-clause must only refer to properties of exactly one group variable returning multiple events /// or /// Aggregation functions in the measure-clause must refer to one or more properties of exactly one group variable returning multiple events /// or /// The measures clause requires that each expression utilizes the AS keyword to assign a column name /// </exception> /// <throws>ExprValidationException if validation fails</throws> public EventRowRegexNFAViewFactory( ViewFactoryChain viewChain, MatchRecognizeSpec matchRecognizeSpec, AgentInstanceContext agentInstanceContext, bool isUnbound, Attribute[] annotations, ConfigurationEngineDefaults.MatchRecognize matchRecognizeConfig) { var parentViewType = viewChain.EventType; _matchRecognizeSpec = matchRecognizeSpec; _isUnbound = isUnbound; _isIterateOnly = HintEnum.ITERATE_ONLY.GetHint(annotations) != null; _matchRecognizeConfig = matchRecognizeConfig; var statementContext = agentInstanceContext.StatementContext; // Expand repeats and permutations _expandedPatternNode = RegexPatternExpandUtil.Expand(matchRecognizeSpec.Pattern); // Determine single-row and multiple-row variables _variablesSingle = new LinkedHashSet <string>(); ISet <string> variablesMultiple = new LinkedHashSet <string>(); EventRowRegexHelper.RecursiveInspectVariables(_expandedPatternNode, false, _variablesSingle, variablesMultiple); // each variable gets associated with a stream number (multiple-row variables as well to hold the current event for the expression). var streamNum = 0; _variableStreams = new LinkedHashMap <string, Pair <int, bool> >(); foreach (var variableSingle in _variablesSingle) { _variableStreams.Put(variableSingle, new Pair <int, bool>(streamNum, false)); streamNum++; } foreach (var variableMultiple in variablesMultiple) { _variableStreams.Put(variableMultiple, new Pair <int, bool>(streamNum, true)); streamNum++; } // mapping of stream to variable _streamVariables = new SortedDictionary <int, string>(); foreach (var entry in _variableStreams) { _streamVariables.Put(entry.Value.First, entry.Key); } // determine visibility rules var visibility = EventRowRegexHelper.DetermineVisibility(_expandedPatternNode); // assemble all single-row variables for expression validation var allStreamNames = new string[_variableStreams.Count]; var allTypes = new EventType[_variableStreams.Count]; streamNum = 0; foreach (var variableSingle in _variablesSingle) { allStreamNames[streamNum] = variableSingle; allTypes[streamNum] = parentViewType; streamNum++; } foreach (var variableMultiple in variablesMultiple) { allStreamNames[streamNum] = variableMultiple; allTypes[streamNum] = parentViewType; streamNum++; } // determine type service for use with DEFINE // validate each DEFINE clause expression ISet <string> definedVariables = new HashSet <string>(); IList <ExprAggregateNode> aggregateNodes = new List <ExprAggregateNode>(); var exprEvaluatorContext = new ExprEvaluatorContextStatement(statementContext, false); _isExprRequiresMultimatchState = new bool[_variableStreams.Count]; for (var defineIndex = 0; defineIndex < matchRecognizeSpec.Defines.Count; defineIndex++) { var defineItem = matchRecognizeSpec.Defines[defineIndex]; if (definedVariables.Contains(defineItem.Identifier)) { throw new ExprValidationException("Variable '" + defineItem.Identifier + "' has already been defined"); } definedVariables.Add(defineItem.Identifier); // stream-type visibilities handled here var typeServiceDefines = EventRowRegexNFAViewFactoryHelper.BuildDefineStreamTypeServiceDefine(statementContext, _variableStreams, defineItem, visibility, parentViewType); var exprNodeResult = HandlePreviousFunctions(defineItem.Expression); var validationContext = new ExprValidationContext( typeServiceDefines, statementContext.EngineImportService, statementContext.StatementExtensionServicesContext, null, statementContext.SchedulingService, statementContext.VariableService, statementContext.TableService, exprEvaluatorContext, statementContext.EventAdapterService, statementContext.StatementName, statementContext.StatementId, statementContext.Annotations, statementContext.ContextDescriptor, statementContext.ScriptingService, true, false, true, false, null, false); ExprNode validated; try { // validate validated = ExprNodeUtility.GetValidatedSubtree(ExprNodeOrigin.MATCHRECOGDEFINE, exprNodeResult, validationContext); // check aggregates defineItem.Expression = validated; ExprAggregateNodeUtil.GetAggregatesBottomUp(validated, aggregateNodes); if (!aggregateNodes.IsEmpty()) { throw new ExprValidationException("An aggregate function may not appear in a DEFINE clause"); } } catch (ExprValidationException ex) { throw new ExprValidationException("Failed to validate condition expression for variable '" + defineItem.Identifier + "': " + ex.Message, ex); } // determine access to event properties from multi-matches var visitor = new ExprNodeStreamRequiredVisitor(); validated.Accept(visitor); var streamsRequired = visitor.StreamsRequired; foreach (var streamRequired in streamsRequired) { if (streamRequired >= _variableStreams.Count) { var streamNumIdent = _variableStreams.Get(defineItem.Identifier).First; _isExprRequiresMultimatchState[streamNumIdent] = true; break; } } } _isDefineAsksMultimatches = CollectionUtil.IsAnySet(_isExprRequiresMultimatchState); _defineMultimatchEventBean = _isDefineAsksMultimatches ? EventRowRegexNFAViewFactoryHelper.GetDefineMultimatchBean(statementContext, _variableStreams, parentViewType) : null; // assign "prev" node indexes // Since an expression such as "prior(2, price), prior(8, price)" translates into {2, 8} the relative index is {0, 1}. // Map the expression-supplied index to a relative index var countPrev = 0; foreach (var entry in _callbacksPerIndex) { foreach (var callback in entry.Value) { callback.AssignedIndex = countPrev; } countPrev++; } // determine type service for use with MEASURE IDictionary <string, object> measureTypeDef = new LinkedHashMap <string, object>(); foreach (var variableSingle in _variablesSingle) { measureTypeDef.Put(variableSingle, parentViewType); } foreach (var variableMultiple in variablesMultiple) { measureTypeDef.Put(variableMultiple, new EventType[] { parentViewType }); } var outputEventTypeName = statementContext.StatementId + "_rowrecog"; _compositeEventType = (ObjectArrayEventType)statementContext.EventAdapterService.CreateAnonymousObjectArrayType(outputEventTypeName, measureTypeDef); StreamTypeService typeServiceMeasure = new StreamTypeServiceImpl(_compositeEventType, "MATCH_RECOGNIZE", true, statementContext.EngineURI); // find MEASURE clause aggregations var measureReferencesMultivar = false; IList <ExprAggregateNode> measureAggregateExprNodes = new List <ExprAggregateNode>(); foreach (var measureItem in matchRecognizeSpec.Measures) { ExprAggregateNodeUtil.GetAggregatesBottomUp(measureItem.Expr, measureAggregateExprNodes); } if (!measureAggregateExprNodes.IsEmpty()) { var isIStreamOnly = new bool[allStreamNames.Length]; CompatExtensions.Fill(isIStreamOnly, true); var typeServiceAggregateMeasure = new StreamTypeServiceImpl(allTypes, allStreamNames, isIStreamOnly, statementContext.EngineURI, false); var measureExprAggNodesPerStream = new Dictionary <int, IList <ExprAggregateNode> >(); foreach (var aggregateNode in measureAggregateExprNodes) { // validate absence of group-by aggregateNode.ValidatePositionals(); if (aggregateNode.OptionalLocalGroupBy != null) { throw new ExprValidationException("Match-recognize does not allow aggregation functions to specify a group-by"); } // validate node and params var count = 0; var visitor = new ExprNodeIdentifierVisitor(true); var validationContext = new ExprValidationContext( typeServiceAggregateMeasure, statementContext.EngineImportService, statementContext.StatementExtensionServicesContext, null, statementContext.SchedulingService, statementContext.VariableService, statementContext.TableService, exprEvaluatorContext, statementContext.EventAdapterService, statementContext.StatementName, statementContext.StatementId, statementContext.Annotations, statementContext.ContextDescriptor, statementContext.ScriptingService, false, false, true, false, null, false); foreach (var child in aggregateNode.ChildNodes) { var validated = ExprNodeUtility.GetValidatedSubtree(ExprNodeOrigin.MATCHRECOGMEASURE, child, validationContext); validated.Accept(visitor); aggregateNode.SetChildNode(count++, new ExprNodeValidated(validated)); } validationContext = new ExprValidationContext( typeServiceMeasure, statementContext.EngineImportService, statementContext.StatementExtensionServicesContext, null, statementContext.SchedulingService, statementContext.VariableService, statementContext.TableService, exprEvaluatorContext, statementContext.EventAdapterService, statementContext.StatementName, statementContext.StatementId, statementContext.Annotations, statementContext.ContextDescriptor, statementContext.ScriptingService, false, false, true, false, null, false); aggregateNode.Validate(validationContext); // verify properties used within the aggregation var aggregatedStreams = new HashSet <int>(); foreach (var pair in visitor.ExprProperties) { aggregatedStreams.Add(pair.First); } int?multipleVarStream = null; foreach (int streamNumAggregated in aggregatedStreams) { var variable = _streamVariables.Get(streamNumAggregated); if (variablesMultiple.Contains(variable)) { measureReferencesMultivar = true; if (multipleVarStream == null) { multipleVarStream = streamNumAggregated; continue; } throw new ExprValidationException("Aggregation functions in the measure-clause must only refer to properties of exactly one group variable returning multiple events"); } } if (multipleVarStream == null) { throw new ExprValidationException("Aggregation functions in the measure-clause must refer to one or more properties of exactly one group variable returning multiple events"); } var aggNodesForStream = measureExprAggNodesPerStream.Get(multipleVarStream.Value); if (aggNodesForStream == null) { aggNodesForStream = new List <ExprAggregateNode>(); measureExprAggNodesPerStream.Put(multipleVarStream.Value, aggNodesForStream); } aggNodesForStream.Add(aggregateNode); } var factoryDesc = AggregationServiceFactoryFactory.GetServiceMatchRecognize(_streamVariables.Count, measureExprAggNodesPerStream, typeServiceAggregateMeasure.EventTypes); _aggregationService = factoryDesc.AggregationServiceFactory.MakeService(agentInstanceContext); _aggregationExpressions = factoryDesc.Expressions; } else { _aggregationService = null; _aggregationExpressions = Collections.GetEmptyList <AggregationServiceAggExpressionDesc>(); } // validate each MEASURE clause expression IDictionary <string, object> rowTypeDef = new LinkedHashMap <string, object>(); var streamRefVisitor = new ExprNodeStreamUseCollectVisitor(); foreach (var measureItem in matchRecognizeSpec.Measures) { if (measureItem.Name == null) { throw new ExprValidationException("The measures clause requires that each expression utilizes the AS keyword to assign a column name"); } var validated = ValidateMeasureClause(measureItem.Expr, typeServiceMeasure, variablesMultiple, _variablesSingle, statementContext); measureItem.Expr = validated; rowTypeDef.Put(measureItem.Name, validated.ExprEvaluator.ReturnType); validated.Accept(streamRefVisitor); } // Determine if any of the multi-var streams are referenced in the measures (non-aggregated only) foreach (var @ref in streamRefVisitor.Referenced) { var rootPropName = @ref.RootPropertyNameIfAny; if (rootPropName != null) { if (variablesMultiple.Contains(rootPropName)) { measureReferencesMultivar = true; break; } } var streamRequired = @ref.StreamReferencedIfAny; if (streamRequired != null) { var streamVariable = _streamVariables.Get(streamRequired.Value); if (streamVariable != null) { var def = _variableStreams.Get(streamVariable); if (def != null && def.Second) { measureReferencesMultivar = true; break; } } } } _isCollectMultimatches = measureReferencesMultivar || _isDefineAsksMultimatches; // create rowevent type var rowEventTypeName = statementContext.StatementId + "_rowrecogrow"; _rowEventType = statementContext.EventAdapterService.CreateAnonymousMapType(rowEventTypeName, rowTypeDef, true); // validate partition-by expressions, if any if (!matchRecognizeSpec.PartitionByExpressions.IsEmpty()) { var typeServicePartition = new StreamTypeServiceImpl(parentViewType, "MATCH_RECOGNIZE_PARTITION", true, statementContext.EngineURI); var validated = new List <ExprNode>(); var validationContext = new ExprValidationContext( typeServicePartition, statementContext.EngineImportService, statementContext.StatementExtensionServicesContext, null, statementContext.SchedulingService, statementContext.VariableService, statementContext.TableService, exprEvaluatorContext, statementContext.EventAdapterService, statementContext.StatementName, statementContext.StatementId, statementContext.Annotations, statementContext.ContextDescriptor, statementContext.ScriptingService, false, false, true, false, null, false); foreach (var partitionExpr in matchRecognizeSpec.PartitionByExpressions) { validated.Add(ExprNodeUtility.GetValidatedSubtree(ExprNodeOrigin.MATCHRECOGPARTITION, partitionExpr, validationContext)); } matchRecognizeSpec.PartitionByExpressions = validated; } // validate interval if present if (matchRecognizeSpec.Interval != null) { var validationContext = new ExprValidationContext( new StreamTypeServiceImpl(statementContext.EngineURI, false), statementContext.EngineImportService, statementContext.StatementExtensionServicesContext, null, statementContext.SchedulingService, statementContext.VariableService, statementContext.TableService, exprEvaluatorContext, statementContext.EventAdapterService, statementContext.StatementName, statementContext.StatementId, statementContext.Annotations, statementContext.ContextDescriptor, statementContext.ScriptingService, false, false, true, false, null, false); matchRecognizeSpec.Interval.Validate(validationContext); } }
public TableMetadata(string tableName, string eplExpression, string statementName, Type[] keyTypes, IDictionary <String, TableMetadataColumn> tableColumns, TableStateRowFactory rowFactory, int numberMethodAggregations, StatementResourceService createTableResources, string contextName, ObjectArrayEventType internalEventType, ObjectArrayEventType publicEventType, TableMetadataInternalEventToPublic eventToPublic, bool queryPlanLogging, string createTableStatementName) { _tableName = tableName; _eplExpression = eplExpression; _statementName = statementName; KeyTypes = keyTypes; TableColumns = tableColumns; RowFactory = rowFactory; NumberMethodAggregations = numberMethodAggregations; _createTableResources = createTableResources; ContextName = contextName; InternalEventType = internalEventType; _publicEventType = publicEventType; _eventToPublic = eventToPublic; _queryPlanLogging = queryPlanLogging; if (keyTypes.Length > 0) { var pair = TableServiceUtil.GetIndexMultikeyForKeys(tableColumns, internalEventType); _eventTableIndexMetadataRepo.AddIndex(true, pair.Second, tableName, createTableStatementName, true); _tableRowKeyFactory = new TableRowKeyFactory(pair.First); } }