public static FilterSpecCompiled Build( IList <ExprNode> validatedNodes, EventType eventType, string eventTypeName, PropertyEvalSpec optionalPropertyEvalSpec, IDictionary <string, Pair <EventType, string> > taggedEventTypes, IDictionary <string, Pair <EventType, string> > arrayEventTypes, StreamTypeService streamTypeService, string optionalStreamName, StatementContext stmtContext, ICollection <int> assignedTypeNumberStack) { var evaluatorContextStmt = new ExprEvaluatorContextStatement(stmtContext, false); return(BuildNoStmtCtx(validatedNodes, eventType, eventTypeName, optionalPropertyEvalSpec, taggedEventTypes, arrayEventTypes, streamTypeService, optionalStreamName, assignedTypeNumberStack, evaluatorContextStmt, stmtContext.StatementId, stmtContext.StatementName, stmtContext.Annotations, stmtContext.ContextDescriptor, stmtContext.MethodResolutionService, stmtContext.EventAdapterService, stmtContext.TimeProvider, stmtContext.VariableService, stmtContext.ScriptingService, stmtContext.TableService, stmtContext.ConfigSnapshot, stmtContext.NamedWindowService)); }
public static FilterSpecCompiledDesc Build( FilterSpecValidatedDesc validatedDesc, EventType eventType, string eventTypeName, PropertyEvalSpec optionalPropertyEvalSpec, IDictionary<string, Pair<EventType, string>> taggedEventTypes, IDictionary<string, Pair<EventType, string>> arrayEventTypes, ISet<string> allTagNamesOrdered, StreamTypeService streamTypeService, string optionalStreamName, StatementRawInfo statementRawInfo, StatementCompileTimeServices compileTimeServices) { var compiled = BuildNoStmtCtx( validatedDesc.Expressions, eventType, eventTypeName, optionalStreamName, optionalPropertyEvalSpec, taggedEventTypes, arrayEventTypes, allTagNamesOrdered, streamTypeService, statementRawInfo, compileTimeServices); return new FilterSpecCompiledDesc(compiled, validatedDesc.AdditionalForgeables); }
public static FilterSpecCompiled MakeFilterSpec( EventType eventType, string eventTypeName, IList<ExprNode> filterExpessions, PropertyEvalSpec optionalPropertyEvalSpec, IDictionary<string, Pair<EventType, string>> taggedEventTypes, IDictionary<string, Pair<EventType, string>> arrayEventTypes, StreamTypeService streamTypeService, string optionalStreamName, StatementRawInfo statementRawInfo, StatementCompileTimeServices services) { // Validate all nodes, make sure each returns a boolean and types are good; // Also decompose all AND super nodes into individual expressions var validatedNodes = ValidateAllowSubquery( ExprNodeOrigin.FILTER, filterExpessions, streamTypeService, taggedEventTypes, arrayEventTypes, statementRawInfo, services); return Build( validatedNodes, eventType, eventTypeName, optionalPropertyEvalSpec, taggedEventTypes, arrayEventTypes, streamTypeService, optionalStreamName, statementRawInfo, services); }
private static ContextDetailCondition GetContextCondition( EsperEPL2GrammarParser.CreateContextRangePointContext ctx, IDictionary <ITree, ExprNode> astExprNodeMap, IDictionary <ITree, EvalFactoryNode> astPatternNodeMap, PropertyEvalSpec propertyEvalSpec, bool immediate) { if (ctx == null) { return(ContextDetailConditionNever.INSTANCE); } if (ctx.crontabLimitParameterSet() != null) { var crontab = ASTExprHelper.ExprCollectSubNodes( ctx.crontabLimitParameterSet(), 0, astExprNodeMap); return(new ContextDetailConditionCrontab(crontab, immediate)); } else if (ctx.patternInclusionExpression() != null) { var evalNode = ASTExprHelper.PatternGetRemoveTopNode( ctx.patternInclusionExpression(), astPatternNodeMap); var inclusive = false; if (ctx.i != null) { var ident = ctx.i.Text; if (ident != null && !ident.ToLowerInvariant().Equals("inclusive")) { throw ASTWalkException.From( "Expected 'inclusive' keyword after '@', found '" + ident + "' instead"); } inclusive = true; } return(new ContextDetailConditionPattern(evalNode, inclusive, immediate)); } else if (ctx.createContextFilter() != null) { var filterSpecRaw = ASTFilterSpecHelper.WalkFilterSpec( ctx.createContextFilter().eventFilterExpression(), propertyEvalSpec, astExprNodeMap); var asName = ctx.createContextFilter().i != null?ctx.createContextFilter().i.Text : null; if (immediate) { throw ASTWalkException.From( "Invalid use of 'now' with initiated-by stream, this combination is not supported"); } return(new ContextDetailConditionFilter(filterSpecRaw, asName)); } else if (ctx.AFTER() != null) { var timePeriod = (ExprTimePeriod)ASTExprHelper.ExprCollectSubNodes(ctx.timePeriod(), 0, astExprNodeMap)[0]; return(new ContextDetailConditionTimePeriod(timePeriod, immediate)); } else { throw new IllegalStateException("Unrecognized child type"); } }
private static ContextSpecConditionFilter GetContextDetailConditionFilter( EsperEPL2GrammarParser.CreateContextFilterContext ctx, PropertyEvalSpec propertyEvalSpec, IDictionary<ITree, ExprNode> astExprNodeMap) { var filterSpecRaw = ASTFilterSpecHelper.WalkFilterSpec(ctx.eventFilterExpression(), propertyEvalSpec, astExprNodeMap); var asName = ctx.i?.Text; return new ContextSpecConditionFilter(filterSpecRaw, asName); }
public static FilterSpecRaw WalkFilterSpec( EsperEPL2GrammarParser.EventFilterExpressionContext ctx, PropertyEvalSpec propertyEvalSpec, IDictionary<ITree, ExprNode> astExprNodeMap) { var eventName = ASTUtil.UnescapeClassIdent(ctx.classIdentifier()); var exprNodes = ctx.expressionList() != null ? ASTExprHelper.ExprCollectSubNodes(ctx.expressionList(), 0, astExprNodeMap) : new List<ExprNode>(1); return new FilterSpecRaw(eventName, exprNodes, propertyEvalSpec); }
public static FilterSpecCompiled BuildNoStmtCtx( IList<ExprNode> validatedNodes, EventType eventType, string eventTypeName, string optionalStreamName, PropertyEvalSpec optionalPropertyEvalSpec, IDictionary<string, Pair<EventType, string>> taggedEventTypes, IDictionary<string, Pair<EventType, string>> arrayEventTypes, ISet<string> allTagNamesOrdered, StreamTypeService streamTypeService, StatementRawInfo statementRawInfo, StatementCompileTimeServices compileTimeServices) { PropertyEvaluatorForge optionalPropertyEvaluator = null; if (optionalPropertyEvalSpec != null) { optionalPropertyEvaluator = PropertyEvaluatorForgeFactory.MakeEvaluator( optionalPropertyEvalSpec, eventType, optionalStreamName, statementRawInfo, compileTimeServices); } // unwind "and" and "or" var unwound = FilterSpecCompilerIndexPlannerUnwindAndOr.UnwindAndOr(validatedNodes); var args = new FilterSpecCompilerArgs( taggedEventTypes, arrayEventTypes, allTagNamesOrdered, streamTypeService, null, statementRawInfo, compileTimeServices); var plan = FilterSpecCompilerIndexPlanner.PlanFilterParameters(unwound, args); var hook = (FilterSpecCompileHook) ImportUtil.GetAnnotationHook( statementRawInfo.Annotations, HookType.INTERNAL_FILTERSPEC, typeof(FilterSpecCompileHook), compileTimeServices.ImportServiceCompileTime); hook?.FilterIndexPlan(eventType, unwound, plan); if (compileTimeServices.Configuration.Compiler.Logging.IsEnableFilterPlan) { LogFilterPlans(unwound, plan, eventType, optionalStreamName, statementRawInfo); } if (Log.IsDebugEnabled) { Log.Debug(".makeFilterSpec spec=" + plan); } return new FilterSpecCompiled(eventType, eventTypeName, plan, optionalPropertyEvaluator); }
private static ContextSpec WalkNested( IList<EsperEPL2GrammarParser.ContextContextNestedContext> nestedContexts, IDictionary<ITree, ExprNode> astExprNodeMap, IDictionary<ITree, EvalForgeNode> astPatternNodeMap, PropertyEvalSpec propertyEvalSpec, FilterSpecRaw filterSpec) { IList<CreateContextDesc> contexts = new List<CreateContextDesc>(nestedContexts.Count); foreach (var nestedctx in nestedContexts) { var contextDetail = WalkChoice(nestedctx.createContextChoice(), astExprNodeMap, astPatternNodeMap, propertyEvalSpec); var desc = new CreateContextDesc(nestedctx.name.Text, contextDetail); contexts.Add(desc); } return new ContextNested(contexts); }
public static FilterSpecCompiled BuildNoStmtCtx( IList<ExprNode> validatedNodes, EventType eventType, string eventTypeName, string optionalStreamName, PropertyEvalSpec optionalPropertyEvalSpec, IDictionary<string, Pair<EventType, string>> taggedEventTypes, IDictionary<string, Pair<EventType, string>> arrayEventTypes, StreamTypeService streamTypeService, StatementRawInfo statementRawInfo, StatementCompileTimeServices compileTimeServices ) { PropertyEvaluatorForge optionalPropertyEvaluator = null; if (optionalPropertyEvalSpec != null) { optionalPropertyEvaluator = PropertyEvaluatorForgeFactory.MakeEvaluator( optionalPropertyEvalSpec, eventType, optionalStreamName, statementRawInfo, compileTimeServices); } var args = new FilterSpecCompilerArgs( taggedEventTypes, arrayEventTypes, streamTypeService, null, statementRawInfo, compileTimeServices); IList<FilterSpecParamForge>[] spec = FilterSpecCompilerPlanner.PlanFilterParameters(validatedNodes, args); if (Log.IsDebugEnabled) { Log.Debug(".makeFilterSpec spec=" + spec); } return new FilterSpecCompiled(eventType, eventTypeName, spec, optionalPropertyEvaluator); }
public static CreateContextDesc WalkCreateContext( EsperEPL2GrammarParser.CreateContextExprContext ctx, IDictionary<ITree, ExprNode> astExprNodeMap, IDictionary<ITree, EvalForgeNode> astPatternNodeMap, PropertyEvalSpec propertyEvalSpec, FilterSpecRaw filterSpec) { var contextName = ctx.name.Text; ContextSpec contextDetail; var choice = ctx.createContextDetail().createContextChoice(); if (choice != null) { contextDetail = WalkChoice(choice, astExprNodeMap, astPatternNodeMap, propertyEvalSpec); } else { contextDetail = WalkNested( ctx.createContextDetail().contextContextNested(), astExprNodeMap, astPatternNodeMap, propertyEvalSpec, filterSpec); } return new CreateContextDesc(contextName, contextDetail); }
public static FilterSpecCompiled Build( IList<ExprNode> validatedNodes, EventType eventType, string eventTypeName, PropertyEvalSpec optionalPropertyEvalSpec, IDictionary<string, Pair<EventType, string>> taggedEventTypes, IDictionary<string, Pair<EventType, string>> arrayEventTypes, StreamTypeService streamTypeService, string optionalStreamName, StatementRawInfo statementRawInfo, StatementCompileTimeServices compileTimeServices) { return BuildNoStmtCtx( validatedNodes, eventType, eventTypeName, optionalStreamName, optionalPropertyEvalSpec, taggedEventTypes, arrayEventTypes, streamTypeService, statementRawInfo, compileTimeServices); }
public static FilterSpecCompiled BuildNoStmtCtx( IList <ExprNode> validatedFilterNodes, EventType eventType, string eventTypeName, PropertyEvalSpec optionalPropertyEvalSpec, IDictionary <string, Pair <EventType, string> > taggedEventTypes, IDictionary <string, Pair <EventType, string> > arrayEventTypes, StreamTypeService streamTypeService, string optionalStreamName, ICollection <int> assignedTypeNumberStack, ExprEvaluatorContext exprEvaluatorContext, string statementId, string statementName, Attribute[] annotations, ContextDescriptor contextDescriptor, MethodResolutionService methodResolutionService, EventAdapterService eventAdapterService, TimeProvider timeProvider, VariableService variableService, ScriptingService scriptingService, TableService tableService, ConfigurationInformation configurationInformation, NamedWindowService namedWindowService) { var args = new FilterSpecCompilerArgs( taggedEventTypes, arrayEventTypes, exprEvaluatorContext, statementName, statementId, streamTypeService, methodResolutionService, timeProvider, variableService, tableService, eventAdapterService, scriptingService, annotations, contextDescriptor, configurationInformation); var parameters = FilterSpecCompilerPlanner.PlanFilterParameters(validatedFilterNodes, args); PropertyEvaluator optionalPropertyEvaluator = null; if (optionalPropertyEvalSpec != null) { optionalPropertyEvaluator = PropertyEvaluatorFactory.MakeEvaluator( optionalPropertyEvalSpec, eventType, optionalStreamName, eventAdapterService, methodResolutionService, timeProvider, variableService, scriptingService, tableService, streamTypeService.EngineURIQualifier, statementId, statementName, annotations, assignedTypeNumberStack, configurationInformation, namedWindowService); } var spec = new FilterSpecCompiled(eventType, eventTypeName, parameters, optionalPropertyEvaluator); if (Log.IsDebugEnabled) { Log.Debug(".makeFilterSpec spec=" + spec); } return(spec); }
private static ContextSpec WalkChoice( EsperEPL2GrammarParser.CreateContextChoiceContext ctx, IDictionary<ITree, ExprNode> astExprNodeMap, IDictionary<ITree, EvalForgeNode> astPatternNodeMap, PropertyEvalSpec propertyEvalSpec) { // temporal fixed (start+end) and overlapping (initiated/terminated) if (ctx.START() != null || ctx.INITIATED() != null) { ExprNode[] distinctExpressions = null; if (ctx.createContextDistinct() != null) { if (ctx.createContextDistinct().expressionList() == null) { distinctExpressions = ExprNodeUtilityQuery.EMPTY_EXPR_ARRAY; } else { distinctExpressions = ASTExprHelper.ExprCollectSubNodesPerNode( ctx.createContextDistinct().expressionList().expression(), astExprNodeMap); } } ContextSpecCondition startEndpoint; if (ctx.START() != null) { var immediate = CheckNow(ctx.i); if (immediate) { startEndpoint = ContextSpecConditionImmediate.INSTANCE; } else { startEndpoint = GetContextCondition(ctx.r1, astExprNodeMap, astPatternNodeMap, propertyEvalSpec, false); } } else { var immediate = CheckNow(ctx.i); startEndpoint = GetContextCondition(ctx.r1, astExprNodeMap, astPatternNodeMap, propertyEvalSpec, immediate); } var overlapping = ctx.INITIATED() != null; var endEndpoint = GetContextCondition(ctx.r2, astExprNodeMap, astPatternNodeMap, propertyEvalSpec, false); return new ContextSpecInitiatedTerminated(startEndpoint, endEndpoint, overlapping, distinctExpressions); } // partitioned if (ctx.PARTITION() != null) { IList<EsperEPL2GrammarParser.CreateContextPartitionItemContext> partitions = ctx.createContextPartitionItem(); IList<ContextSpecKeyedItem> rawSpecs = new List<ContextSpecKeyedItem>(); foreach (var partition in partitions) { var filterSpec = ASTFilterSpecHelper.WalkFilterSpec(partition.eventFilterExpression(), propertyEvalSpec, astExprNodeMap); propertyEvalSpec = null; IList<string> propertyNames = new List<string>(); IList<EsperEPL2GrammarParser.ChainableContext> properties = partition.chainable(); foreach (var property in properties) { var propertyName = ASTUtil.GetPropertyName(property, 0); propertyNames.Add(propertyName); } ASTExprHelper.ExprCollectSubNodes(partition, 0, astExprNodeMap); // remove expressions rawSpecs.Add( new ContextSpecKeyedItem( filterSpec, propertyNames, partition.keywordAllowedIdent() == null ? null : partition.keywordAllowedIdent().GetText())); } IList<ContextSpecConditionFilter> optionalInit = null; if (ctx.createContextPartitionInit() != null) { optionalInit = GetContextPartitionInit(ctx.createContextPartitionInit().createContextFilter(), astExprNodeMap); } ContextSpecCondition optionalTermination = null; if (ctx.createContextPartitionTerm() != null) { optionalTermination = GetContextCondition( ctx.createContextPartitionTerm().createContextRangePoint(), astExprNodeMap, astPatternNodeMap, propertyEvalSpec, false); } return new ContextSpecKeyed(rawSpecs, optionalInit, optionalTermination); } if (ctx.COALESCE() != null) { // hash IList<EsperEPL2GrammarParser.CreateContextCoalesceItemContext> coalesces = ctx.createContextCoalesceItem(); IList<ContextSpecHashItem> rawSpecs = new List<ContextSpecHashItem>(coalesces.Count); foreach (var coalesce in coalesces) { var chain = ASTChainSpecHelper.GetChainables(coalesce.chainable(), astExprNodeMap); var func = chain[0]; var filterSpec = ASTFilterSpecHelper.WalkFilterSpec(coalesce.eventFilterExpression(), propertyEvalSpec, astExprNodeMap); propertyEvalSpec = null; rawSpecs.Add(new ContextSpecHashItem(func, filterSpec)); } var granularity = ctx.g.Text; if (!granularity.ToLowerInvariant().Equals("granularity")) { throw ASTWalkException.From("Expected 'granularity' keyword after list of coalesce items, found '" + granularity + "' instead"); } var num = ASTConstantHelper.Parse(ctx.number()); var preallocateStr = ctx.p?.Text; if (preallocateStr != null && !preallocateStr.ToLowerInvariant().Equals("preallocate")) { throw ASTWalkException.From( "Expected 'preallocate' keyword after list of coalesce items, found '" + preallocateStr + "' instead"); } if (!num.GetType().IsNumericNonFP() || num.GetType().GetBoxedType() == typeof(long?)) { throw ASTWalkException.From("Granularity provided must be an int-type number, received " + num.GetType() + " instead"); } return new ContextSpecHash(rawSpecs, num.AsInt32(), preallocateStr != null); } // categorized if (ctx.createContextGroupItem() != null) { IList<EsperEPL2GrammarParser.CreateContextGroupItemContext> grps = ctx.createContextGroupItem(); IList<ContextSpecCategoryItem> items = new List<ContextSpecCategoryItem>(); foreach (var grp in grps) { var exprNode = ASTExprHelper.ExprCollectSubNodes(grp, 0, astExprNodeMap)[0]; var name = grp.i.Text; items.Add(new ContextSpecCategoryItem(exprNode, name)); } var filterSpec = ASTFilterSpecHelper.WalkFilterSpec(ctx.eventFilterExpression(), propertyEvalSpec, astExprNodeMap); return new ContextSpecCategory(items, filterSpec); } throw new IllegalStateException("Unrecognized context detail type"); }
/// <summary> /// Makes the property evaluator. /// </summary> /// <param name="spec">is the property specification</param> /// <param name="sourceEventType">the event type</param> /// <param name="optionalSourceStreamName">the source stream name</param> /// <param name="eventAdapterService">for event instances</param> /// <param name="engineImportService">The engine import service.</param> /// <param name="timeProvider">provides time</param> /// <param name="variableService">for resolving variables</param> /// <param name="scriptingService">The scripting service.</param> /// <param name="tableService">The table service.</param> /// <param name="engineURI">engine URI</param> /// <param name="statementId">The statement identifier.</param> /// <param name="statementName">Name of the statement.</param> /// <param name="annotations">The annotations.</param> /// <param name="assignedTypeNumberStack">The assigned type number stack.</param> /// <param name="configuration">The configuration.</param> /// <param name="namedWindowMgmtService">The named window service.</param> /// <param name="statementExtensionSvcContext">The statement extension SVC context.</param> /// <returns> /// propert evaluator /// </returns> /// <exception cref="ExprValidationException">Missing @type(name) declaration providing the event type name of the return type for expression ' + /// ExprNodeUtility.ToExpressionStringMinPrecedenceSafe(atom.SplitterExpression) + ' /// or /// Event type by name ' + atom.OptionalResultEventType + ' could not be found /// or /// Event type ' + streamEventType.Name + ' underlying type + streamEventType.UnderlyingType.Name + /// cannot be assigned a value of type + returnType.GetTypeNameFullyQualPretty() /// or /// Return type of expression ' + ExprNodeUtility.ToExpressionStringMinPrecedenceSafe(atom.SplitterExpression) + ' is ' + returnType.Name + ', expected an Iterable or array result /// or /// Property rename ' + rawStreamSpec.MaskTypeName + ' not found in path /// or /// Expression in a property-selection may not utilize + isMinimal</exception> /// <exception cref="IllegalStateException">Unknown select clause item: + raw</exception> /// <throws>ExprValidationException if any expressions could not be verified</throws> public static PropertyEvaluator MakeEvaluator( PropertyEvalSpec spec, EventType sourceEventType, string optionalSourceStreamName, EventAdapterService eventAdapterService, EngineImportService engineImportService, TimeProvider timeProvider, VariableService variableService, ScriptingService scriptingService, TableService tableService, string engineURI, int statementId, string statementName, Attribute[] annotations, ICollection <int> assignedTypeNumberStack, ConfigurationInformation configuration, NamedWindowMgmtService namedWindowMgmtService, StatementExtensionSvcContext statementExtensionSvcContext) { var length = spec.Atoms.Count; var containedEventEvals = new ContainedEventEval[length]; var fragmentEventTypes = new FragmentEventType[length]; var currentEventType = sourceEventType; var whereClauses = new ExprEvaluator[length]; var streamEventTypes = new List <EventType>(); var streamNames = new List <string>(); var streamNameAndNumber = new Dictionary <string, int>().WithNullSupport(); var expressionTexts = new List <string>(); var validateContext = new ExprEvaluatorContextTimeOnly(timeProvider); streamEventTypes.Add(sourceEventType); streamNames.Add(optionalSourceStreamName); streamNameAndNumber.Put(optionalSourceStreamName, 0); expressionTexts.Add(sourceEventType.Name); IList <SelectClauseElementCompiled> cumulativeSelectClause = new List <SelectClauseElementCompiled>(); for (var i = 0; i < length; i++) { var atom = spec.Atoms[i]; ContainedEventEval containedEventEval = null; string expressionText = null; EventType streamEventType = null; FragmentEventType fragmentEventType = null; // Resolve directly as fragment event type if possible if (atom.SplitterExpression is ExprIdentNode) { var propertyName = ((ExprIdentNode)atom.SplitterExpression).FullUnresolvedName; fragmentEventType = currentEventType.GetFragmentType(propertyName); if (fragmentEventType != null) { var getter = currentEventType.GetGetter(propertyName); if (getter != null) { containedEventEval = new ContainedEventEvalGetter(getter); expressionText = propertyName; streamEventType = fragmentEventType.FragmentType; } } } // evaluate splitter expression if (containedEventEval == null) { ExprNodeUtility.ValidatePlainExpression( ExprNodeOrigin.CONTAINEDEVENT, ExprNodeUtility.ToExpressionStringMinPrecedenceSafe(atom.SplitterExpression), atom.SplitterExpression); var availableTypes = streamEventTypes.ToArray(); var availableStreamNames = streamNames.ToArray(); var isIStreamOnly = new bool[streamNames.Count]; isIStreamOnly.Fill(true); StreamTypeService streamTypeService = new StreamTypeServiceImpl( availableTypes, availableStreamNames, isIStreamOnly, engineURI, false); var validationContext = new ExprValidationContext( streamTypeService, engineImportService, statementExtensionSvcContext, null, timeProvider, variableService, tableService, validateContext, eventAdapterService, statementName, statementId, annotations, null, scriptingService, false, false, true, false, null, false); var validatedExprNode = ExprNodeUtility.GetValidatedSubtree( ExprNodeOrigin.CONTAINEDEVENT, atom.SplitterExpression, validationContext); var evaluator = validatedExprNode.ExprEvaluator; // determine result type if (atom.OptionalResultEventType == null) { throw new ExprValidationException( "Missing @type(name) declaration providing the event type name of the return type for expression '" + ExprNodeUtility.ToExpressionStringMinPrecedenceSafe(atom.SplitterExpression) + "'"); } streamEventType = eventAdapterService.GetEventTypeByName(atom.OptionalResultEventType); if (streamEventType == null) { throw new ExprValidationException( "Event type by name '" + atom.OptionalResultEventType + "' could not be found"); } var returnType = evaluator.ReturnType; // when the expression returns an array, allow array values to become the column of the single-column event type if (returnType.IsArray && streamEventType.PropertyNames.Length == 1 && TypeHelper.IsSubclassOrImplementsInterface( TypeHelper.GetBoxedType(returnType.GetElementType()), TypeHelper.GetBoxedType(streamEventType.GetPropertyType(streamEventType.PropertyNames[0])))) { var writables = eventAdapterService.GetWriteableProperties(streamEventType, false); if (!writables.IsEmpty()) { try { EventBeanManufacturer manufacturer = EventAdapterServiceHelper.GetManufacturer( eventAdapterService, streamEventType, new WriteablePropertyDescriptor[] { writables.First() }, engineImportService, false, eventAdapterService.EventAdapterAvroHandler); containedEventEval = new ContainedEventEvalArrayToEvent(evaluator, manufacturer); } catch (EventBeanManufactureException e) { throw new ExprValidationException( "Event type '" + streamEventType.Name + "' cannot be populated: " + e.Message, e); } } else { throw new ExprValidationException("Event type '" + streamEventType.Name + "' cannot be written to"); } } else if (returnType.IsArray() && returnType.GetElementType() == typeof(EventBean)) { containedEventEval = new ContainedEventEvalEventBeanArray(evaluator); } else { EventBeanFactory eventBeanFactory = EventAdapterServiceHelper.GetFactoryForType( streamEventType, eventAdapterService); // check expression result type against eventtype expected underlying type if (returnType.IsArray()) { if (!TypeHelper.IsSubclassOrImplementsInterface(returnType.GetElementType(), streamEventType.UnderlyingType)) { throw new ExprValidationException( "Event type '" + streamEventType.Name + "' underlying type " + streamEventType.UnderlyingType.FullName + " cannot be assigned a value of type " + TypeHelper.GetTypeNameFullyQualPretty(returnType)); } } else if (GenericExtensions.IsGenericEnumerable(returnType) || returnType.IsImplementsInterface <IEnumerable>()) { // fine, assumed to return the right type } else { throw new ExprValidationException( "Return type of expression '" + ExprNodeUtility.ToExpressionStringMinPrecedenceSafe(atom.SplitterExpression) + "' is '" + returnType.FullName + "', expected an Iterable or array result"); } containedEventEval = new ContainedEventEvalExprNode(evaluator, eventBeanFactory); } expressionText = ExprNodeUtility.ToExpressionStringMinPrecedenceSafe(validatedExprNode); fragmentEventType = new FragmentEventType(streamEventType, true, false); } // validate where clause, if any streamEventTypes.Add(streamEventType); streamNames.Add(atom.OptionalAsName); streamNameAndNumber.Put(atom.OptionalAsName, i + 1); expressionTexts.Add(expressionText); if (atom.OptionalWhereClause != null) { var whereTypes = streamEventTypes.ToArray(); var whereStreamNames = streamNames.ToArray(); var isIStreamOnly = new bool[streamNames.Count]; isIStreamOnly.Fill(true); StreamTypeService streamTypeService = new StreamTypeServiceImpl( whereTypes, whereStreamNames, isIStreamOnly, engineURI, false); var validationContext = new ExprValidationContext( streamTypeService, engineImportService, statementExtensionSvcContext, null, timeProvider, variableService, tableService, validateContext, eventAdapterService, statementName, statementId, annotations, null, scriptingService, false, false, true, false, null, false); whereClauses[i] = ExprNodeUtility.GetValidatedSubtree( ExprNodeOrigin.CONTAINEDEVENT, atom.OptionalWhereClause, validationContext).ExprEvaluator; } // validate select clause if (atom.OptionalSelectClause != null) { var whereTypes = streamEventTypes.ToArray(); var whereStreamNames = streamNames.ToArray(); var isIStreamOnly = new bool[streamNames.Count]; isIStreamOnly.Fill(true); StreamTypeService streamTypeService = new StreamTypeServiceImpl( whereTypes, whereStreamNames, isIStreamOnly, engineURI, false); var validationContext = new ExprValidationContext( streamTypeService, engineImportService, statementExtensionSvcContext, null, timeProvider, variableService, tableService, validateContext, eventAdapterService, statementName, statementId, annotations, null, scriptingService, false, false, true, false, null, false); foreach (var raw in atom.OptionalSelectClause.SelectExprList) { if (raw is SelectClauseStreamRawSpec) { var rawStreamSpec = (SelectClauseStreamRawSpec)raw; if (!streamNames.Contains(rawStreamSpec.StreamName)) { throw new ExprValidationException( "Property rename '" + rawStreamSpec.StreamName + "' not found in path"); } var streamSpec = new SelectClauseStreamCompiledSpec( rawStreamSpec.StreamName, rawStreamSpec.OptionalAsName); int streamNumber = streamNameAndNumber.Get(rawStreamSpec.StreamName); streamSpec.StreamNumber = streamNumber; cumulativeSelectClause.Add(streamSpec); } else if (raw is SelectClauseExprRawSpec) { var exprSpec = (SelectClauseExprRawSpec)raw; var exprCompiled = ExprNodeUtility.GetValidatedSubtree( ExprNodeOrigin.CONTAINEDEVENT, exprSpec.SelectExpression, validationContext); var resultName = exprSpec.OptionalAsName; if (resultName == null) { resultName = ExprNodeUtility.ToExpressionStringMinPrecedenceSafe(exprCompiled); } cumulativeSelectClause.Add( new SelectClauseExprCompiledSpec( exprCompiled, resultName, exprSpec.OptionalAsName, exprSpec.IsEvents)); var isMinimal = ExprNodeUtility.IsMinimalExpression(exprCompiled); if (isMinimal != null) { throw new ExprValidationException( "Expression in a property-selection may not utilize " + isMinimal); } } else if (raw is SelectClauseElementWildcard) { // wildcards are stream selects: we assign a stream name (any) and add a stream wildcard select var streamNameAtom = atom.OptionalAsName; if (streamNameAtom == null) { streamNameAtom = UuidGenerator.Generate(); } var streamSpec = new SelectClauseStreamCompiledSpec(streamNameAtom, atom.OptionalAsName); var streamNumber = i + 1; streamSpec.StreamNumber = streamNumber; cumulativeSelectClause.Add(streamSpec); } else { throw new IllegalStateException("Unknown select clause item:" + raw); } } } currentEventType = fragmentEventType.FragmentType; fragmentEventTypes[i] = fragmentEventType; containedEventEvals[i] = containedEventEval; } if (cumulativeSelectClause.IsEmpty()) { if (length == 1) { return(new PropertyEvaluatorSimple( containedEventEvals[0], fragmentEventTypes[0], whereClauses[0], expressionTexts[0])); } else { return(new PropertyEvaluatorNested(containedEventEvals, fragmentEventTypes, whereClauses, expressionTexts)); } } else { var accumulative = new PropertyEvaluatorAccumulative( containedEventEvals, fragmentEventTypes, whereClauses, expressionTexts); var whereTypes = streamEventTypes.ToArray(); var whereStreamNames = streamNames.ToArray(); var isIStreamOnly = new bool[streamNames.Count]; isIStreamOnly.Fill(true); StreamTypeService streamTypeService = new StreamTypeServiceImpl( whereTypes, whereStreamNames, isIStreamOnly, engineURI, false); var cumulativeSelectArr = cumulativeSelectClause.ToArray(); var selectExpr = SelectExprProcessorFactory.GetProcessor( assignedTypeNumberStack, cumulativeSelectArr, false, null, null, null, streamTypeService, eventAdapterService, null, null, null, engineImportService, validateContext, variableService, scriptingService, tableService, timeProvider, engineURI, statementId, statementName, annotations, null, configuration, null, namedWindowMgmtService, null, null, statementExtensionSvcContext); return(new PropertyEvaluatorSelect(selectExpr, accumulative)); } }
public static PropertyEvaluatorForge MakeEvaluator( PropertyEvalSpec spec, EventType sourceEventType, string optionalSourceStreamName, StatementRawInfo rawInfo, StatementCompileTimeServices services) { var length = spec.Atoms.Count; var containedEventForges = new ContainedEventEvalForge[length]; var fragmentEventTypes = new FragmentEventType[length]; var currentEventType = sourceEventType; var whereClauses = new ExprForge[length]; IList<EventType> streamEventTypes = new List<EventType>(); IList<string> streamNames = new List<string>(); IDictionary<string, int> streamNameAndNumber = new Dictionary<string, int>().WithNullKeySupport(); IList<string> expressionTexts = new List<string>(); streamEventTypes.Add(sourceEventType); streamNames.Add(optionalSourceStreamName); streamNameAndNumber.Put(optionalSourceStreamName, 0); expressionTexts.Add(sourceEventType.Name); IList<SelectClauseElementCompiled> cumulativeSelectClause = new List<SelectClauseElementCompiled>(); for (var i = 0; i < length; i++) { var atom = spec.Atoms[i]; ContainedEventEvalForge containedEventEval = null; string expressionText = null; EventType streamEventType = null; FragmentEventType fragmentEventType = null; // Resolve directly as fragment event type if possible if (atom.SplitterExpression is ExprIdentNode) { var propertyName = ((ExprIdentNode) atom.SplitterExpression).FullUnresolvedName; fragmentEventType = currentEventType.GetFragmentType(propertyName); if (fragmentEventType != null) { var getter = ((EventTypeSPI) currentEventType).GetGetterSPI(propertyName); if (getter != null) { containedEventEval = new ContainedEventEvalGetterForge(getter); expressionText = propertyName; streamEventType = fragmentEventType.FragmentType; } } } // evaluate splitter expression if (containedEventEval == null) { ExprNodeUtilityValidate.ValidatePlainExpression( ExprNodeOrigin.CONTAINEDEVENT, atom.SplitterExpression); var availableTypes = streamEventTypes.ToArray(); var availableStreamNames = streamNames.ToArray(); var isIStreamOnly = new bool[streamNames.Count]; isIStreamOnly.Fill(true); StreamTypeService streamTypeService = new StreamTypeServiceImpl( availableTypes, availableStreamNames, isIStreamOnly, false, false); var validationContext = new ExprValidationContextBuilder(streamTypeService, rawInfo, services) .WithAllowBindingConsumption(true) .Build(); var validatedExprNode = ExprNodeUtilityValidate.GetValidatedSubtree( ExprNodeOrigin.CONTAINEDEVENT, atom.SplitterExpression, validationContext); // determine result type if (atom.OptionalResultEventType == null) { throw new ExprValidationException( "Missing @type(name) declaration providing the event type name of the return type for expression '" + ExprNodeUtilityPrint.ToExpressionStringMinPrecedenceSafe(atom.SplitterExpression) + "'"); } streamEventType = services.EventTypeCompileTimeResolver.GetTypeByName(atom.OptionalResultEventType); if (streamEventType == null) { throw new ExprValidationException( "Event type by name '" + atom.OptionalResultEventType + "' could not be found"); } var returnType = validatedExprNode.Forge.EvaluationType; // when the expression returns an array, allow array values to become the column of the single-column event type if (returnType.IsArray && streamEventType.PropertyNames.Length == 1 && !(streamEventType is JsonEventType) && // since json string-array should not become itself the property TypeHelper.IsSubclassOrImplementsInterface( returnType.GetElementType().GetBoxedType(), streamEventType.GetPropertyType(streamEventType.PropertyNames[0]).GetBoxedType())) { var writables = EventTypeUtility.GetWriteableProperties(streamEventType, false, false); if (writables != null && !writables.IsEmpty()) { try { var manufacturer = EventTypeUtility.GetManufacturer( streamEventType, new[] {writables.First()}, services.ImportServiceCompileTime, false, services.EventTypeAvroHandler); containedEventEval = new ContainedEventEvalArrayToEventForge( validatedExprNode.Forge, manufacturer); } catch (EventBeanManufactureException e) { throw new ExprValidationException( "Event type '" + streamEventType.Name + "' cannot be populated: " + e.Message, e); } } else { throw new ExprValidationException( "Event type '" + streamEventType.Name + "' cannot be written to"); } } else if (returnType.IsArray && returnType.GetElementType() == typeof(EventBean)) { containedEventEval = new ContainedEventEvalEventBeanArrayForge(validatedExprNode.Forge); } else { // check expression result type against eventtype expected underlying type if (returnType.IsArray) { if (!(streamEventType is JsonEventType)) { if (!TypeHelper.IsSubclassOrImplementsInterface( returnType.GetElementType(), streamEventType.UnderlyingType)) { throw new ExprValidationException( "Event type '" + streamEventType.Name + "' underlying type " + streamEventType.UnderlyingType.CleanName() + " cannot be assigned a value of type " + returnType.CleanName()); } } else { if (returnType.GetElementType() != typeof(string)) { throw new ExprValidationException( "Event type '" + streamEventType.Name + "' requires string-type array and cannot be assigned from value of type " + returnType.CleanName()); } } } else if (GenericExtensions.IsGenericEnumerable(returnType) || TypeHelper.IsImplementsInterface<System.Collections.IEnumerable>(returnType)) { // fine, assumed to return the right type } else { throw new ExprValidationException( "Return type of expression '" + ExprNodeUtilityPrint.ToExpressionStringMinPrecedenceSafe(atom.SplitterExpression) + "' is '" + returnType.Name + "', expected an Iterable or array result"); } containedEventEval = new ContainedEventEvalExprNodeForge( validatedExprNode.Forge, streamEventType); } expressionText = ExprNodeUtilityPrint.ToExpressionStringMinPrecedenceSafe(validatedExprNode); fragmentEventType = new FragmentEventType(streamEventType, true, false); } // validate where clause, if any streamEventTypes.Add(streamEventType); streamNames.Add(atom.OptionalAsName); streamNameAndNumber.Put(atom.OptionalAsName, i + 1); expressionTexts.Add(expressionText); if (atom.OptionalWhereClause != null) { var whereTypes = streamEventTypes.ToArray(); var whereStreamNames = streamNames.ToArray(); var isIStreamOnly = new bool[streamNames.Count]; isIStreamOnly.Fill(true); StreamTypeService streamTypeService = new StreamTypeServiceImpl( whereTypes, whereStreamNames, isIStreamOnly, false, false); var validationContext = new ExprValidationContextBuilder(streamTypeService, rawInfo, services) .WithAllowBindingConsumption(true) .Build(); var whereClause = ExprNodeUtilityValidate.GetValidatedSubtree( ExprNodeOrigin.CONTAINEDEVENT, atom.OptionalWhereClause, validationContext); whereClauses[i] = whereClause.Forge; } // validate select clause if (atom.OptionalSelectClause != null && !atom.OptionalSelectClause.SelectExprList.IsEmpty()) { var whereTypes = streamEventTypes.ToArray(); var whereStreamNames = streamNames.ToArray(); var isIStreamOnly = new bool[streamNames.Count]; isIStreamOnly.Fill(true); StreamTypeService streamTypeService = new StreamTypeServiceImpl( whereTypes, whereStreamNames, isIStreamOnly, false, false); var validationContext = new ExprValidationContextBuilder(streamTypeService, rawInfo, services) .WithAllowBindingConsumption(true) .Build(); foreach (var raw in atom.OptionalSelectClause.SelectExprList) { if (raw is SelectClauseStreamRawSpec) { var rawStreamSpec = (SelectClauseStreamRawSpec) raw; if (!streamNames.Contains(rawStreamSpec.StreamName)) { throw new ExprValidationException( "Property rename '" + rawStreamSpec.StreamName + "' not found in path"); } var streamSpec = new SelectClauseStreamCompiledSpec( rawStreamSpec.StreamName, rawStreamSpec.OptionalAsName); var streamNumber = streamNameAndNumber.Get(rawStreamSpec.StreamName); streamSpec.StreamNumber = streamNumber; cumulativeSelectClause.Add(streamSpec); } else if (raw is SelectClauseExprRawSpec) { var exprSpec = (SelectClauseExprRawSpec) raw; var exprCompiled = ExprNodeUtilityValidate.GetValidatedSubtree( ExprNodeOrigin.CONTAINEDEVENT, exprSpec.SelectExpression, validationContext); var resultName = exprSpec.OptionalAsName; if (resultName == null) { resultName = ExprNodeUtilityPrint.ToExpressionStringMinPrecedenceSafe(exprCompiled); } cumulativeSelectClause.Add( new SelectClauseExprCompiledSpec( exprCompiled, resultName, exprSpec.OptionalAsName, exprSpec.IsEvents)); var isMinimal = ExprNodeUtilityValidate.IsMinimalExpression(exprCompiled); if (isMinimal != null) { throw new ExprValidationException( "Expression in a property-selection may not utilize " + isMinimal); } } else if (raw is SelectClauseElementWildcard) { // wildcards are stream selects: we assign a stream name (any) and add a stream wildcard select var streamNameAtom = atom.OptionalAsName; if (streamNameAtom == null) { streamNameAtom = UuidGenerator.Generate(); } var streamSpec = new SelectClauseStreamCompiledSpec(streamNameAtom, atom.OptionalAsName); var streamNumber = i + 1; streamSpec.StreamNumber = streamNumber; cumulativeSelectClause.Add(streamSpec); } else { throw new IllegalStateException("Unknown select clause item:" + raw); } } } currentEventType = fragmentEventType.FragmentType; fragmentEventTypes[i] = fragmentEventType; containedEventForges[i] = containedEventEval; } if (cumulativeSelectClause.IsEmpty()) { if (length == 1) { return new PropertyEvaluatorSimpleForge( containedEventForges[0], fragmentEventTypes[0], whereClauses[0], expressionTexts[0]); } return new PropertyEvaluatorNestedForge( containedEventForges, fragmentEventTypes, whereClauses, expressionTexts.ToArray()); } { var fragmentEventTypeIsIndexed = new bool[fragmentEventTypes.Length]; for (var i = 0; i < fragmentEventTypes.Length; i++) { fragmentEventTypeIsIndexed[i] = fragmentEventTypes[i].IsIndexed; } var accumulative = new PropertyEvaluatorAccumulativeForge( containedEventForges, fragmentEventTypeIsIndexed, whereClauses, expressionTexts); var whereTypes = streamEventTypes.ToArray(); var whereStreamNames = streamNames.ToArray(); var isIStreamOnly = new bool[streamNames.Count]; isIStreamOnly.Fill(true); StreamTypeService streamTypeService = new StreamTypeServiceImpl( whereTypes, whereStreamNames, isIStreamOnly, false, false); var cumulativeSelectArr = cumulativeSelectClause.ToArray(); var args = new SelectProcessorArgs( cumulativeSelectArr, null, false, null, null, streamTypeService, null, false, rawInfo.Annotations, rawInfo, services); var selectExprDesc = SelectExprProcessorFactory.GetProcessor(args, null, false); return new PropertyEvaluatorSelectForge(selectExprDesc, accumulative); } }
private static ContextDetail WalkChoice(EsperEPL2GrammarParser.CreateContextChoiceContext ctx, IDictionary <ITree, ExprNode> astExprNodeMap, IDictionary <ITree, EvalFactoryNode> astPatternNodeMap, PropertyEvalSpec propertyEvalSpec, FilterSpecRaw filterSpec) { // temporal fixed (start+end) and overlapping (initiated/terminated) if (ctx.START() != null || ctx.INITIATED() != null) { ExprNode[] distinctExpressions = null; if (ctx.createContextDistinct() != null) { if (ctx.createContextDistinct().expressionList() == null) { distinctExpressions = new ExprNode[0]; } else { distinctExpressions = ASTExprHelper.ExprCollectSubNodesPerNode(ctx.createContextDistinct().expressionList().expression(), astExprNodeMap); } } ContextDetailCondition startEndpoint; if (ctx.START() != null) { bool immediate = CheckNow(ctx.i); if (immediate) { startEndpoint = new ContextDetailConditionImmediate(); } else { startEndpoint = GetContextCondition(ctx.r1, astExprNodeMap, astPatternNodeMap, propertyEvalSpec, false); } } else { bool immediate = CheckNow(ctx.i); startEndpoint = GetContextCondition(ctx.r1, astExprNodeMap, astPatternNodeMap, propertyEvalSpec, immediate); } bool overlapping = ctx.INITIATED() != null; ContextDetailCondition endEndpoint = GetContextCondition(ctx.r2, astExprNodeMap, astPatternNodeMap, propertyEvalSpec, false); return(new ContextDetailInitiatedTerminated(startEndpoint, endEndpoint, overlapping, distinctExpressions)); } // partitioned if (ctx.PARTITION() != null) { IList <EsperEPL2GrammarParser.CreateContextPartitionItemContext> partitions = ctx.createContextPartitionItem(); IList <ContextDetailPartitionItem> rawSpecs = new List <ContextDetailPartitionItem>(); foreach (EsperEPL2GrammarParser.CreateContextPartitionItemContext partition in partitions) { filterSpec = ASTFilterSpecHelper.WalkFilterSpec(partition.eventFilterExpression(), propertyEvalSpec, astExprNodeMap); propertyEvalSpec = null; IList <String> propertyNames = new List <String>(); IList <EsperEPL2GrammarParser.EventPropertyContext> properties = partition.eventProperty(); foreach (EsperEPL2GrammarParser.EventPropertyContext property in properties) { String propertyName = ASTUtil.GetPropertyName(property, 0); propertyNames.Add(propertyName); } ASTExprHelper.ExprCollectSubNodes(partition, 0, astExprNodeMap); // remove expressions rawSpecs.Add(new ContextDetailPartitionItem(filterSpec, propertyNames)); } return(new ContextDetailPartitioned(rawSpecs)); } // hash else if (ctx.COALESCE() != null) { IList <EsperEPL2GrammarParser.CreateContextCoalesceItemContext> coalesces = ctx.createContextCoalesceItem(); IList <ContextDetailHashItem> rawSpecs = new List <ContextDetailHashItem>(coalesces.Count); foreach (EsperEPL2GrammarParser.CreateContextCoalesceItemContext coalesce in coalesces) { ExprChainedSpec func = ASTLibFunctionHelper.GetLibFunctionChainSpec(coalesce.libFunctionNoClass(), astExprNodeMap); filterSpec = ASTFilterSpecHelper.WalkFilterSpec(coalesce.eventFilterExpression(), propertyEvalSpec, astExprNodeMap); propertyEvalSpec = null; rawSpecs.Add(new ContextDetailHashItem(func, filterSpec)); } String granularity = ctx.g.Text; if (!granularity.ToLower().Equals("granularity")) { throw ASTWalkException.From("Expected 'granularity' keyword after list of coalesce items, found '" + granularity + "' instead"); } var num = ASTConstantHelper.Parse(ctx.number()); String preallocateStr = ctx.p != null ? ctx.p.Text : null; if (preallocateStr != null && !preallocateStr.ToLower().Equals("preallocate")) { throw ASTWalkException.From("Expected 'preallocate' keyword after list of coalesce items, found '" + preallocateStr + "' instead"); } if (!num.GetType().IsNumericNonFP() || num.GetType().GetBoxedType() == typeof(long?)) { throw ASTWalkException.From("Granularity provided must be an int-type number, received " + num.GetType() + " instead"); } return(new ContextDetailHash(rawSpecs, num.AsInt(), preallocateStr != null)); } // categorized if (ctx.createContextGroupItem() != null) { IList <EsperEPL2GrammarParser.CreateContextGroupItemContext> grps = ctx.createContextGroupItem(); IList <ContextDetailCategoryItem> items = new List <ContextDetailCategoryItem>(); foreach (EsperEPL2GrammarParser.CreateContextGroupItemContext grp in grps) { ExprNode exprNode = ASTExprHelper.ExprCollectSubNodes(grp, 0, astExprNodeMap)[0]; String name = grp.i.Text; items.Add(new ContextDetailCategoryItem(exprNode, name)); } filterSpec = ASTFilterSpecHelper.WalkFilterSpec(ctx.eventFilterExpression(), propertyEvalSpec, astExprNodeMap); return(new ContextDetailCategory(items, filterSpec)); } throw new IllegalStateException("Unrecognized context detail type"); }