private ExprNode ValidateMeasureClause(ExprNode measureNode, StreamTypeService typeServiceMeasure, ISet <string> variablesMultiple, ISet <string> variablesSingle, StatementContext statementContext) { try { var exprEvaluatorContext = new ExprEvaluatorContextStatement(statementContext, false); var validationContext = new ExprValidationContext( typeServiceMeasure, statementContext.MethodResolutionService, 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); return(ExprNodeUtility.GetValidatedSubtree(ExprNodeOrigin.MATCHRECOGMEASURE, measureNode, validationContext)); } catch (ExprValidationPropertyException e) { var grouped = CollectionUtil.ToString(variablesMultiple); var single = CollectionUtil.ToString(variablesSingle); var message = e.Message; if (!variablesMultiple.IsEmpty()) { message += ", ensure that grouped variables (variables " + grouped + ") are accessed via index (i.e. variable[0].property) or appear within an aggregation"; } if (!variablesSingle.IsEmpty()) { message += ", ensure that singleton variables (variables " + single + ") are not accessed via index"; } throw new ExprValidationPropertyException(message, e); } }
public EventTable[] Index(IList<EventBean> pollResult, bool isActiveCache, StatementContext statementContext) { if (!isActiveCache) { return new EventTable[] { new UnindexedEventTableList(pollResult, _streamNum) }; } PropertySortedEventTableFactory tableFactory; if (_coercionType == null) { tableFactory = new PropertySortedEventTableFactory(_streamNum, _eventType, _propertyName); } else { tableFactory = new PropertySortedEventTableCoercedFactory( _streamNum, _eventType, _propertyName, _coercionType); } var evaluatorContextStatement = new ExprEvaluatorContextStatement(statementContext, false); EventTable[] tables = tableFactory.MakeEventTables(new EventTableFactoryTableIdentStmt(statementContext), evaluatorContextStatement); foreach (EventTable table in tables) { table.Add(pollResult.ToArray(), evaluatorContextStatement); } return tables; }
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 void Attach(EventType parentEventType, StatementContext statementContext, ViewFactory optionalParentFactory, IList <ViewFactory> parentViewFactories) { _parentEventType = parentEventType; var validatedNodes = ViewFactorySupport.Validate(_viewFactoryContext.ViewName, parentEventType, _viewFactoryContext.StatementContext, _viewParameters, true); _viewParameterArr = new Object[validatedNodes.Length]; var evaluatorContextStmt = new ExprEvaluatorContextStatement(_viewFactoryContext.StatementContext, false); for (var i = 0; i < validatedNodes.Length; i++) { try { _viewParameterArr[i] = ViewFactorySupport.EvaluateAssertNoProperties(_viewFactoryContext.ViewName, validatedNodes[i], i, evaluatorContextStmt); } catch (Exception) { // expected } } _viewParameterExp = ViewFactorySupport.Validate(_viewFactoryContext.ViewName, parentEventType, _viewFactoryContext.StatementContext, _viewParameters, true); // initialize try { _eventBeanFactory = EventAdapterServiceHelper.GetFactoryForType(parentEventType, statementContext.EventAdapterService); _virtualDataWindowFactory.Initialize(new VirtualDataWindowFactoryContext(parentEventType, _viewParameterArr, _viewParameterExp, _eventBeanFactory, _namedWindowName, _viewFactoryContext, _customConfiguration)); } catch (Exception ex) { throw new ViewParameterException("Validation exception initializing virtual data window '" + _namedWindowName + "': " + ex.Message, ex); } }
public ViewableActivator CreateStreamReuseView( EPServicesContext services, StatementContext statementContext, StatementSpecCompiled statementSpec, FilterStreamSpecCompiled filterStreamSpec, bool isJoin, ExprEvaluatorContextStatement evaluatorContextStmt, bool filterSubselectSameStream, int streamNum, bool isCanIterateUnbound) { if (ProcCreateStreamReuseView == null) { throw new NotSupportedException(); } return(ProcCreateStreamReuseView.Invoke( services, statementContext, statementSpec, filterStreamSpec, isJoin, evaluatorContextStmt, filterSubselectSameStream, streamNum, isCanIterateUnbound)); }
public static ExprNode ValidateExpr(String viewName, StatementContext statementContext, ExprNode expression, StreamTypeService streamTypeService, int expressionNumber) { ExprNode validated; try { var exprEvaluatorContext = new ExprEvaluatorContextStatement(statementContext, false); var validationContext = new ExprValidationContext( streamTypeService, 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, false, false, null, false); validated = ExprNodeUtility.GetValidatedSubtree(ExprNodeOrigin.VIEWPARAMETER, expression, validationContext); } catch (ExprValidationException ex) { var message = "Invalid parameter expression " + expressionNumber + GetViewDesc(viewName); if (ex.Message != null) { message += ": " + ex.Message; } Log.Error(message, ex); throw new ViewParameterException(message, ex); } return(validated); }
private NamedWindowOnMergeActionIns SetupInsert(string namedWindowName, InternalEventRouter internalEventRouter, EventTypeSPI eventTypeNamedWindow, int selectClauseNumber, OnTriggerMergeActionInsert desc, EventType triggeringEventType, string triggeringStreamName, StatementContext statementContext) { // Compile insert-into INFO string streamName = desc.OptionalStreamName ?? eventTypeNamedWindow.Name; var insertIntoDesc = InsertIntoDesc.FromColumns(streamName, desc.Columns); // rewrite any wildcards to use "stream.wildcard" if (triggeringStreamName == null) { triggeringStreamName = UuidGenerator.Generate(); } var selectNoWildcard = CompileSelectNoWildcard(triggeringStreamName, desc.SelectClauseCompiled); // Set up event types for select-clause evaluation: The first type does not contain anything as its the named window row which is not present for insert var dummyTypeNoProperties = new MapEventType(EventTypeMetadata.CreateAnonymous("merge_named_window_insert", ApplicationType.MAP), "merge_named_window_insert", 0, null, Collections.EmptyDataMap, null, null, null); var eventTypes = new EventType[] { dummyTypeNoProperties, triggeringEventType }; var streamNames = new string[] { UuidGenerator.Generate(), triggeringStreamName }; var streamTypeService = new StreamTypeServiceImpl(eventTypes, streamNames, new bool[1], statementContext.EngineURI, false); // Get select expr processor var selectExprEventTypeRegistry = new SelectExprEventTypeRegistry(statementContext.StatementName, statementContext.StatementEventTypeRef); var exprEvaluatorContext = new ExprEvaluatorContextStatement(statementContext, false); var insertHelper = SelectExprProcessorFactory.GetProcessor( statementContext.Container, Collections.SingletonList(selectClauseNumber), selectNoWildcard.ToArray(), false, insertIntoDesc, null, null, streamTypeService, statementContext.EventAdapterService, statementContext.StatementResultService, statementContext.ValueAddEventService, selectExprEventTypeRegistry, statementContext.EngineImportService, exprEvaluatorContext, statementContext.VariableService, statementContext.ScriptingService, statementContext.TableService, statementContext.TimeProvider, statementContext.EngineURI, statementContext.StatementId, statementContext.StatementName, statementContext.Annotations, statementContext.ContextDescriptor, statementContext.ConfigSnapshot, null, statementContext.NamedWindowMgmtService, null, null, statementContext.StatementExtensionServicesContext); var filterEval = desc.OptionalWhereClause == null ? null : desc.OptionalWhereClause.ExprEvaluator; var routerToUser = streamName.Equals(namedWindowName) ? null : internalEventRouter; var audit = AuditEnum.INSERT.GetAudit(statementContext.Annotations) != null; string insertIntoTableName = null; if (statementContext.TableService.GetTableMetadata(insertIntoDesc.EventTypeName) != null) { insertIntoTableName = insertIntoDesc.EventTypeName; } return(new NamedWindowOnMergeActionIns(filterEval, insertHelper, routerToUser, insertIntoTableName, statementContext.TableService, statementContext.EpStatementHandle, statementContext.InternalEventEngineRouteDest, audit)); }
public override EPPreparedExecuteIUDSingleStreamExec GetExecutor(FilterSpecCompiled filter, string aliasName) { var services = base.Services; var processor = base.Processor; var statementContext = base.StatementContext; var statementSpec = base.StatementSpec; var updateSpec = (FireAndForgetSpecUpdate)statementSpec.FireAndForgetSpec; var assignmentTypeService = new StreamTypeServiceImpl( new EventType[] { processor.EventTypeResultSetProcessor, null, processor.EventTypeResultSetProcessor }, new string[] { aliasName, "", EPStatementStartMethodOnTrigger.INITIAL_VALUE_STREAM_NAME }, new bool[] { true, true, true }, services.EngineURI, true); assignmentTypeService.IsStreamZeroUnambigous = true; var evaluatorContextStmt = new ExprEvaluatorContextStatement(statementContext, true); var validationContext = new ExprValidationContext( assignmentTypeService, statementContext.EngineImportService, statementContext.StatementExtensionServicesContext, null, statementContext.SchedulingService, statementContext.VariableService, statementContext.TableService, evaluatorContextStmt, statementContext.EventAdapterService, statementContext.StatementName, statementContext.StatementId, statementContext.Annotations, statementContext.ContextDescriptor, statementContext.ScriptingService, false, false, true, false, null, false); // validate update expressions try { foreach (OnTriggerSetAssignment assignment in updateSpec.Assignments) { ExprNode validated = ExprNodeUtility.GetValidatedSubtree(ExprNodeOrigin.UPDATEASSIGN, assignment.Expression, validationContext); assignment.Expression = validated; EPStatementStartMethodHelperValidate.ValidateNoAggregations(validated, "Aggregation functions may not be used within an update-clause"); } } catch (ExprValidationException e) { throw new EPException(e.Message, e); } // make updater EventBeanUpdateHelper updateHelper; TableUpdateStrategy tableUpdateStrategy = null; try { bool copyOnWrite = !(processor is FireAndForgetProcessorTable); updateHelper = EventBeanUpdateHelperFactory.Make(processor.NamedWindowOrTableName, (EventTypeSPI)processor.EventTypeResultSetProcessor, updateSpec.Assignments, aliasName, null, copyOnWrite, statementContext.StatementName, services.EngineURI, services.EventAdapterService); if (processor is FireAndForgetProcessorTable) { FireAndForgetProcessorTable tableProcessor = (FireAndForgetProcessorTable)processor; tableUpdateStrategy = services.TableService.GetTableUpdateStrategy(tableProcessor.TableMetadata, updateHelper, false); copyOnWrite = false; } } catch (ExprValidationException e) { throw new EPException(e.Message, e); } return(new EPPreparedExecuteIUDSingleStreamExecUpdate(filter, statementSpec.FilterRootNode, statementSpec.Annotations, updateHelper, tableUpdateStrategy, statementSpec.TableNodes, services)); }
internal ViewableActivatorStreamReuseView(EPServicesContext services, StatementContext statementContext, StatementSpecCompiled statementSpec, FilterStreamSpecCompiled filterStreamSpec, bool join, ExprEvaluatorContextStatement evaluatorContextStmt, bool filterSubselectSameStream, int streamNum, bool isCanIterateUnbound) { _services = services; _statementContext = statementContext; _statementSpec = statementSpec; _filterStreamSpec = filterStreamSpec; _join = join; _evaluatorContextStmt = evaluatorContextStmt; _filterSubselectSameStream = filterSubselectSameStream; _streamNum = streamNum; _isCanIterateUnbound = isCanIterateUnbound; }
public void Attach(EventType parentEventType, StatementContext statementContext, ViewFactory optionalParentFactory, IList <ViewFactory> parentViewFactories) { EventType = parentEventType; var message = NAME + " window requires a numeric size parameter and a list of expressions providing sort keys"; if (_viewParameters.Count < 2) { throw new ViewParameterException(message); } var validated = ViewFactorySupport.Validate(NAME + " window", parentEventType, statementContext, _viewParameters, true); for (var i = 1; i < validated.Length; i++) { ViewFactorySupport.AssertReturnsNonConstant(NAME + " window", validated[i], i); } var exprEvaluatorContext = new ExprEvaluatorContextStatement(statementContext, false); var sortSize = ViewFactorySupport.EvaluateAssertNoProperties(NAME + " window", validated[0], 0, exprEvaluatorContext); if ((sortSize == null) || (!sortSize.IsNumber())) { throw new ViewParameterException(message); } SortWindowSize = sortSize.AsInt(); sortCriteriaExpressions = new ExprNode[validated.Length - 1]; IsDescendingValues = new bool[sortCriteriaExpressions.Length]; for (var i = 1; i < validated.Length; i++) { if (validated[i] is ExprOrderedExpr) { IsDescendingValues[i - 1] = ((ExprOrderedExpr)validated[i]).IsDescending; sortCriteriaExpressions[i - 1] = validated[i].ChildNodes[0]; } else { sortCriteriaExpressions[i - 1] = validated[i]; } } SortCriteriaEvaluators = ExprNodeUtility.GetEvaluators(sortCriteriaExpressions); if (statementContext.ConfigSnapshot != null) { IsUseCollatorSort = statementContext.ConfigSnapshot.EngineDefaults.LanguageConfig.IsSortUsingCollator; } }
public EventTable[] Index(IList <EventBean> pollResult, bool isActiveCache, StatementContext statementContext) { if (!isActiveCache) { return(new EventTable[] { new UnindexedEventTableList(pollResult, _streamNum) }); } var tables = new EventTable[_propertyNames.Length]; var evaluatorContextStatement = new ExprEvaluatorContextStatement(statementContext, false); for (var i = 0; i < _propertyNames.Length; i++) { var factory = new PropertyIndexedEventTableSingleFactory(_streamNum, _eventType, _propertyNames[i], false, null); tables[i] = factory.MakeEventTables(new EventTableFactoryTableIdentStmt(statementContext), evaluatorContextStatement)[0]; tables[i].Add(pollResult.ToArray(), evaluatorContextStatement); } return(tables); }
public EventTable[] Index(IList <EventBean> pollResult, bool isActiveCache, StatementContext statementContext) { if (!isActiveCache) { return(new EventTable[] { new UnindexedEventTableList(pollResult, _streamNum) }); } var factory = new PropertyIndexedEventTableFactory(_streamNum, _eventType, _propertyNames, false, null); var evaluatorContextStatement = new ExprEvaluatorContextStatement(statementContext, false); var tables = factory.MakeEventTables(new EventTableFactoryTableIdentStmt(statementContext), evaluatorContextStatement); foreach (var table in tables) { table.Add(pollResult.ToArray(), evaluatorContextStatement); } return(tables); }
public override EPPreparedExecuteIUDSingleStreamExec GetExecutor(FilterSpecCompiled filter, string aliasName) { var selectNoWildcard = NamedWindowOnMergeHelper.CompileSelectNoWildcard(UuidGenerator.Generate(), StatementSpec.SelectClauseSpec.SelectExprList); StreamTypeService streamTypeService = new StreamTypeServiceImpl(StatementContext.EngineURI, true); var exprEvaluatorContextStatement = new ExprEvaluatorContextStatement(StatementContext, true); // assign names var validationContext = new ExprValidationContext( streamTypeService, StatementContext.EngineImportService, StatementContext.StatementExtensionServicesContext, null, StatementContext.TimeProvider, StatementContext.VariableService, StatementContext.TableService, exprEvaluatorContextStatement, StatementContext.EventAdapterService, StatementContext.StatementName, StatementContext.StatementId, StatementContext.Annotations, StatementContext.ContextDescriptor, StatementContext.ScriptingService, false, false, true, false, null, false); // determine whether column names are provided // if the "values" keyword was used, allow sequential automatic name assignment string[] assignedSequentialNames = null; if (StatementSpec.InsertIntoDesc.ColumnNames.IsEmpty()) { var insert = (FireAndForgetSpecInsert)StatementSpec.FireAndForgetSpec; if (insert.IsUseValuesKeyword) { assignedSequentialNames = Processor.EventTypePublic.PropertyNames; } } var count = -1; foreach (var compiled in StatementSpec.SelectClauseSpec.SelectExprList) { count++; if (compiled is SelectClauseExprCompiledSpec) { var expr = (SelectClauseExprCompiledSpec)compiled; ExprNode validatedExpression = ExprNodeUtility.GetValidatedSubtree(ExprNodeOrigin.SELECT, expr.SelectExpression, validationContext); expr.SelectExpression = validatedExpression; if (expr.AssignedName == null) { if (expr.ProvidedName == null) { if (assignedSequentialNames != null && count < assignedSequentialNames.Length) { expr.AssignedName = assignedSequentialNames[count]; } else { expr.AssignedName = ExprNodeUtility.ToExpressionStringMinPrecedenceSafe(expr.SelectExpression); } } else { expr.AssignedName = expr.ProvidedName; } } } } EventType optionalInsertIntoEventType = Processor.EventTypeResultSetProcessor; var selectExprEventTypeRegistry = new SelectExprEventTypeRegistry(StatementContext.StatementName, StatementContext.StatementEventTypeRef); var insertHelper = SelectExprProcessorFactory.GetProcessor( Collections.SingletonList(0), selectNoWildcard.ToArray(), false, StatementSpec.InsertIntoDesc, optionalInsertIntoEventType, null, streamTypeService, StatementContext.EventAdapterService, StatementContext.StatementResultService, StatementContext.ValueAddEventService, selectExprEventTypeRegistry, StatementContext.EngineImportService, exprEvaluatorContextStatement, StatementContext.VariableService, StatementContext.ScriptingService, StatementContext.TableService, StatementContext.TimeProvider, StatementContext.EngineURI, StatementContext.StatementId, StatementContext.StatementName, StatementContext.Annotations, StatementContext.ContextDescriptor, StatementContext.ConfigSnapshot, null, StatementContext.NamedWindowMgmtService, null, null, StatementContext.StatementExtensionServicesContext); return(new EPPreparedExecuteIUDSingleStreamExecInsert(exprEvaluatorContextStatement, insertHelper, StatementSpec.TableNodes, Services)); }
private static void HandleSubselectSelectClauses( int subselectStreamNumber, StatementContext statementContext, ExprSubselectNode subselect, EventType outerEventType, string outerEventTypeName, string outerStreamName, IDictionary <string, Pair <EventType, string> > taggedEventTypes, IDictionary <string, Pair <EventType, string> > arrayEventTypes) { var statementSpec = subselect.StatementSpecCompiled; var filterStreamSpec = statementSpec.StreamSpecs[0]; ViewFactoryChain viewFactoryChain; string subselecteventTypeName = null; // construct view factory chain try { if (statementSpec.StreamSpecs[0] is FilterStreamSpecCompiled) { var filterStreamSpecCompiled = (FilterStreamSpecCompiled)statementSpec.StreamSpecs[0]; subselecteventTypeName = filterStreamSpecCompiled.FilterSpec.FilterForEventTypeName; // A child view is required to limit the stream if (filterStreamSpec.ViewSpecs.Length == 0) { throw new ExprValidationException("Subqueries require one or more views to limit the stream, consider declaring a length or time window"); } // Register filter, create view factories viewFactoryChain = statementContext.ViewService.CreateFactories(subselectStreamNumber, filterStreamSpecCompiled.FilterSpec.ResultEventType, filterStreamSpec.ViewSpecs, filterStreamSpec.Options, statementContext); subselect.RawEventType = viewFactoryChain.EventType; } else { var namedSpec = (NamedWindowConsumerStreamSpec)statementSpec.StreamSpecs[0]; var processor = statementContext.NamedWindowService.GetProcessor(namedSpec.WindowName); viewFactoryChain = statementContext.ViewService.CreateFactories(0, processor.NamedWindowType, namedSpec.ViewSpecs, namedSpec.Options, statementContext); subselecteventTypeName = namedSpec.WindowName; EPLValidationUtil.ValidateContextName(false, processor.NamedWindowName, processor.ContextName, statementContext.ContextName, true); } } catch (ViewProcessingException ex) { throw new ExprValidationException("Error validating subexpression: " + ex.Message, ex); } // the final event type var eventType = viewFactoryChain.EventType; // determine a stream name unless one was supplied var subexpressionStreamName = filterStreamSpec.OptionalStreamName; if (subexpressionStreamName == null) { subexpressionStreamName = "$subselect_" + subselectStreamNumber; } // Named windows don't allow data views if (filterStreamSpec is NamedWindowConsumerStreamSpec) { EPStatementStartMethodHelperValidate.ValidateNoDataWindowOnNamedWindow(viewFactoryChain.FactoryChain); } // Streams event types are the original stream types with the stream zero the subselect stream var namesAndTypes = new LinkedHashMap <string, Pair <EventType, string> >(); namesAndTypes.Put(subexpressionStreamName, new Pair <EventType, string>(eventType, subselecteventTypeName)); namesAndTypes.Put(outerStreamName, new Pair <EventType, string>(outerEventType, outerEventTypeName)); if (taggedEventTypes != null) { foreach (KeyValuePair <string, Pair <EventType, string> > entry in taggedEventTypes) { namesAndTypes.Put(entry.Key, new Pair <EventType, string>(entry.Value.First, entry.Value.Second)); } } if (arrayEventTypes != null) { foreach (KeyValuePair <string, Pair <EventType, string> > entry in arrayEventTypes) { namesAndTypes.Put(entry.Key, new Pair <EventType, string>(entry.Value.First, entry.Value.Second)); } } StreamTypeService subselectTypeService = new StreamTypeServiceImpl(namesAndTypes, statementContext.EngineURI, true, true); var viewResourceDelegateSubselect = new ViewResourceDelegateUnverified(); subselect.FilterSubqueryStreamTypes = subselectTypeService; // Validate select expression var selectClauseSpec = subselect.StatementSpecCompiled.SelectClauseSpec; if (selectClauseSpec.SelectExprList.Length > 0) { if (selectClauseSpec.SelectExprList.Length > 1) { throw new ExprValidationException("Subquery multi-column select is not allowed in this context."); } var element = selectClauseSpec.SelectExprList[0]; if (element is SelectClauseExprCompiledSpec) { // validate var compiled = (SelectClauseExprCompiledSpec)element; var selectExpression = compiled.SelectExpression; var evaluatorContextStmt = new ExprEvaluatorContextStatement(statementContext, false); var validationContext = new ExprValidationContext( subselectTypeService, statementContext.MethodResolutionService, viewResourceDelegateSubselect, statementContext.SchedulingService, statementContext.VariableService, statementContext.TableService, evaluatorContextStmt, statementContext.EventAdapterService, statementContext.StatementName, statementContext.StatementId, statementContext.Annotations, statementContext.ContextDescriptor, statementContext.ScriptingService, false, false, true, false, null, false); selectExpression = ExprNodeUtility.GetValidatedSubtree(ExprNodeOrigin.SUBQUERYSELECT, selectExpression, validationContext); subselect.SelectClause = new ExprNode[] { selectExpression }; subselect.SelectAsNames = new string[] { compiled.AssignedName }; // handle aggregation var aggExprNodes = new List <ExprAggregateNode>(); ExprAggregateNodeUtil.GetAggregatesBottomUp(selectExpression, aggExprNodes); if (aggExprNodes.Count > 0) { // Other stream properties, if there is aggregation, cannot be under aggregation. foreach (var aggNode in aggExprNodes) { var propertiesNodesAggregated = ExprNodeUtility.GetExpressionProperties(aggNode, true); foreach (var pair in propertiesNodesAggregated) { if (pair.First != 0) { throw new ExprValidationException("Subselect aggregation function cannot aggregate across correlated properties"); } } } // This stream (stream 0) properties must either all be under aggregation, or all not be. var propertiesNotAggregated = ExprNodeUtility.GetExpressionProperties(selectExpression, false); foreach (var pair in propertiesNotAggregated) { if (pair.First == 0) { throw new ExprValidationException("Subselect properties must all be within aggregation functions"); } } } } } }
/// <summary> /// Validates expression nodes and returns a list of validated nodes. /// </summary> /// <param name="exprNodeOrigin">The expr node origin.</param> /// <param name="exprNodes">is the nodes to validate</param> /// <param name="streamTypeService">is provding type information for each stream</param> /// <param name="statementContext">context</param> /// <param name="taggedEventTypes">pattern tagged types</param> /// <param name="arrayEventTypes">@return list of validated expression nodes</param> /// <returns> /// expr nodes /// </returns> /// <exception cref="ExprValidationException"> /// Failed to validate + EPStatementStartMethodHelperSubselect.GetSubqueryInfoText(count, subselect) + : + ex.Message /// or /// Filter expression not returning a boolean value: ' + ExprNodeUtility.ToExpressionStringMinPrecedenceSafe(validated) + ' /// </exception> /// <throws>ExprValidationException for validation errors</throws> public static IList <ExprNode> ValidateAllowSubquery( ExprNodeOrigin exprNodeOrigin, IList <ExprNode> exprNodes, StreamTypeService streamTypeService, StatementContext statementContext, IDictionary <string, Pair <EventType, string> > taggedEventTypes, IDictionary <string, Pair <EventType, string> > arrayEventTypes) { IList <ExprNode> validatedNodes = new List <ExprNode>(); var evaluatorContextStmt = new ExprEvaluatorContextStatement(statementContext, false); var validationContext = new ExprValidationContext( streamTypeService, statementContext.MethodResolutionService, null, statementContext.TimeProvider, statementContext.VariableService, statementContext.TableService, evaluatorContextStmt, statementContext.EventAdapterService, statementContext.StatementName, statementContext.StatementId, statementContext.Annotations, statementContext.ContextDescriptor, statementContext.ScriptingService, false, false, true, false, null, true); foreach (var node in exprNodes) { // Determine subselects var visitor = new ExprNodeSubselectDeclaredDotVisitor(); node.Accept(visitor); // Compile subselects if (!visitor.Subselects.IsEmpty()) { // The outer event type is the filtered-type itself var subselectStreamNumber = 2048; var count = -1; foreach (var subselect in visitor.Subselects) { count++; subselectStreamNumber++; try { HandleSubselectSelectClauses(subselectStreamNumber, statementContext, subselect, streamTypeService.EventTypes[0], streamTypeService.StreamNames[0], streamTypeService.StreamNames[0], taggedEventTypes, arrayEventTypes); } catch (ExprValidationException ex) { throw new ExprValidationException("Failed to validate " + EPStatementStartMethodHelperSubselect.GetSubqueryInfoText(count, subselect) + ": " + ex.Message, ex); } } } var validated = ExprNodeUtility.GetValidatedSubtree(exprNodeOrigin, node, validationContext); validatedNodes.Add(validated); if ((validated.ExprEvaluator.ReturnType != typeof(bool?)) && ((validated.ExprEvaluator.ReturnType != typeof(bool)))) { throw new ExprValidationException("Filter expression not returning a boolean value: '" + ExprNodeUtility.ToExpressionStringMinPrecedenceSafe(validated) + "'"); } } return(validatedNodes); }
public static EPStatementStartMethodSelectDesc Prepare( StatementSpecCompiled statementSpec, EPServicesContext services, StatementContext statementContext, bool recoveringResilient, AgentInstanceContext defaultAgentInstanceContext, bool queryPlanLogging, ViewableActivatorFactory optionalViewableActivatorFactory, OutputProcessViewCallback optionalOutputProcessViewCallback, SelectExprProcessorDeliveryCallback selectExprProcessorDeliveryCallback) { // define stop and destroy var stopCallbacks = new List <StopCallback>(); var destroyCallbacks = new EPStatementDestroyCallbackList(); // determine context var contextName = statementSpec.OptionalContextName; var contextPropertyRegistry = (contextName != null) ? services.ContextManagementService.GetContextDescriptor(contextName).ContextPropertyRegistry : null; // Determine stream names for each stream - some streams may not have a name given var streamNames = EPStatementStartMethodHelperUtil.DetermineStreamNames(statementSpec.StreamSpecs); var numStreams = streamNames.Length; if (numStreams == 0) { throw new ExprValidationException("The from-clause is required but has not been specified"); } var isJoin = statementSpec.StreamSpecs.Length > 1; var hasContext = statementSpec.OptionalContextName != null; // First we create streams for subselects, if there are any var subSelectStreamDesc = EPStatementStartMethodHelperSubselect.CreateSubSelectActivation(services, statementSpec, statementContext, destroyCallbacks); // Create streams and views var eventStreamParentViewableActivators = new ViewableActivator[numStreams]; var unmaterializedViewChain = new ViewFactoryChain[numStreams]; var eventTypeNames = new string[numStreams]; var isNamedWindow = new bool[numStreams]; var historicalEventViewables = new HistoricalEventViewable[numStreams]; // verify for joins that required views are present var joinAnalysisResult = VerifyJoinViews(statementSpec, statementContext.NamedWindowMgmtService, defaultAgentInstanceContext); var evaluatorContextStmt = new ExprEvaluatorContextStatement(statementContext, false); for (var i = 0; i < statementSpec.StreamSpecs.Length; i++) { var streamSpec = statementSpec.StreamSpecs[i]; var isCanIterateUnbound = streamSpec.ViewSpecs.Length == 0 && (services.ConfigSnapshot.EngineDefaults.ViewResourcesConfig.IsIterableUnbound || AnnotationUtil.FindAttribute(statementSpec.Annotations, typeof(IterableUnboundAttribute)) != null); // Create view factories and parent view based on a filter specification if (streamSpec is FilterStreamSpecCompiled) { var filterStreamSpec = (FilterStreamSpecCompiled)streamSpec; eventTypeNames[i] = filterStreamSpec.FilterSpec.FilterForEventTypeName; // Since only for non-joins we get the existing stream's lock and try to reuse it's views var filterSubselectSameStream = EPStatementStartMethodHelperUtil.DetermineSubquerySameStream(statementSpec, filterStreamSpec); // create activator ViewableActivator activatorDeactivator; if (optionalViewableActivatorFactory != null) { activatorDeactivator = optionalViewableActivatorFactory.CreateActivatorSimple(filterStreamSpec); if (activatorDeactivator == null) { throw new IllegalStateException("Viewable activate is null for " + filterStreamSpec.FilterSpec.FilterForEventType.Name); } } else { if (!hasContext) { activatorDeactivator = services.ViewableActivatorFactory.CreateStreamReuseView(services, statementContext, statementSpec, filterStreamSpec, isJoin, evaluatorContextStmt, filterSubselectSameStream, i, isCanIterateUnbound); } else { InstrumentationAgent instrumentationAgentFilter = null; if (InstrumentationHelper.ENABLED) { var eventTypeName = filterStreamSpec.FilterSpec.FilterForEventType.Name; var streamNumber = i; instrumentationAgentFilter = new ProxyInstrumentationAgent() { ProcIndicateQ = () => { InstrumentationHelper.Get().QFilterActivationStream(eventTypeName, streamNumber); }, ProcIndicateA = () => { InstrumentationHelper.Get().AFilterActivationStream(); }, }; } activatorDeactivator = services.ViewableActivatorFactory.CreateFilterProxy(services, filterStreamSpec.FilterSpec, statementSpec.Annotations, false, instrumentationAgentFilter, isCanIterateUnbound, i); } } eventStreamParentViewableActivators[i] = activatorDeactivator; var resultEventType = filterStreamSpec.FilterSpec.ResultEventType; unmaterializedViewChain[i] = services.ViewService.CreateFactories(i, resultEventType, streamSpec.ViewSpecs, streamSpec.Options, statementContext, false, -1); } // Create view factories and parent view based on a pattern expression else if (streamSpec is PatternStreamSpecCompiled) { var patternStreamSpec = (PatternStreamSpecCompiled)streamSpec; var usedByChildViews = streamSpec.ViewSpecs.Length > 0 || (statementSpec.InsertIntoDesc != null); var patternTypeName = statementContext.StatementId + "_pattern_" + i; var eventType = services.EventAdapterService.CreateSemiAnonymousMapType(patternTypeName, patternStreamSpec.TaggedEventTypes, patternStreamSpec.ArrayEventTypes, usedByChildViews); unmaterializedViewChain[i] = services.ViewService.CreateFactories(i, eventType, streamSpec.ViewSpecs, streamSpec.Options, statementContext, false, -1); var rootFactoryNode = services.PatternNodeFactory.MakeRootNode(patternStreamSpec.EvalFactoryNode); var patternContext = statementContext.PatternContextFactory.CreateContext(statementContext, i, rootFactoryNode, patternStreamSpec.MatchedEventMapMeta, true); // create activator var patternActivator = services.ViewableActivatorFactory.CreatePattern(patternContext, rootFactoryNode, eventType, EPStatementStartMethodHelperUtil.IsConsumingFilters(patternStreamSpec.EvalFactoryNode), patternStreamSpec.IsSuppressSameEventMatches, patternStreamSpec.IsDiscardPartialsOnMatch, isCanIterateUnbound); eventStreamParentViewableActivators[i] = patternActivator; } // Create view factories and parent view based on a database SQL statement else if (streamSpec is DBStatementStreamSpec) { ValidateNoViews(streamSpec, "Historical data"); var sqlStreamSpec = (DBStatementStreamSpec)streamSpec; var typeConversionHook = (SQLColumnTypeConversion)TypeHelper.GetAnnotationHook(statementSpec.Annotations, HookType.SQLCOL, typeof(SQLColumnTypeConversion), statementContext.MethodResolutionService); var outputRowConversionHook = (SQLOutputRowConversion)TypeHelper.GetAnnotationHook(statementSpec.Annotations, HookType.SQLROW, typeof(SQLOutputRowConversion), statementContext.MethodResolutionService); var epStatementAgentInstanceHandle = defaultAgentInstanceContext.EpStatementAgentInstanceHandle; var historicalEventViewable = DatabasePollingViewableFactory.CreateDBStatementView( statementContext.StatementId, i, sqlStreamSpec, services.DatabaseRefService, services.EventAdapterService, epStatementAgentInstanceHandle, statementContext.Annotations, typeConversionHook, outputRowConversionHook, statementContext.ConfigSnapshot.EngineDefaults.LoggingConfig.IsEnableADO, services.DataCacheFactory, statementContext); historicalEventViewables[i] = historicalEventViewable; unmaterializedViewChain[i] = ViewFactoryChain.FromTypeNoViews(historicalEventViewable.EventType); eventStreamParentViewableActivators[i] = services.ViewableActivatorFactory.MakeHistorical(historicalEventViewable); stopCallbacks.Add(historicalEventViewable); } else if (streamSpec is MethodStreamSpec) { ValidateNoViews(streamSpec, "Method data"); var methodStreamSpec = (MethodStreamSpec)streamSpec; var epStatementAgentInstanceHandle = defaultAgentInstanceContext.EpStatementAgentInstanceHandle; var historicalEventViewable = MethodPollingViewableFactory.CreatePollMethodView( i, methodStreamSpec, services.EventAdapterService, epStatementAgentInstanceHandle, statementContext.MethodResolutionService, services.EngineImportService, statementContext.SchedulingService, statementContext.ScheduleBucket, evaluatorContextStmt, statementContext.VariableService, statementContext.ContextName, services.DataCacheFactory, statementContext); historicalEventViewables[i] = historicalEventViewable; unmaterializedViewChain[i] = ViewFactoryChain.FromTypeNoViews(historicalEventViewable.EventType); eventStreamParentViewableActivators[i] = services.ViewableActivatorFactory.MakeHistorical(historicalEventViewable); stopCallbacks.Add(historicalEventViewable); } else if (streamSpec is TableQueryStreamSpec) { ValidateNoViews(streamSpec, "Table data"); var tableStreamSpec = (TableQueryStreamSpec)streamSpec; if (isJoin && tableStreamSpec.FilterExpressions.Count > 0) { throw new ExprValidationException("Joins with tables do not allow table filter expressions, please add table filters to the where-clause instead"); } var metadata = services.TableService.GetTableMetadata(tableStreamSpec.TableName); ExprEvaluator[] tableFilterEvals = null; if (tableStreamSpec.FilterExpressions.Count > 0) { tableFilterEvals = ExprNodeUtility.GetEvaluators(tableStreamSpec.FilterExpressions); } EPLValidationUtil.ValidateContextName(true, metadata.TableName, metadata.ContextName, statementSpec.OptionalContextName, false); eventStreamParentViewableActivators[i] = services.ViewableActivatorFactory.CreateTable(metadata, tableFilterEvals); unmaterializedViewChain[i] = ViewFactoryChain.FromTypeNoViews(metadata.InternalEventType); eventTypeNames[i] = tableStreamSpec.TableName; joinAnalysisResult.SetTablesForStream(i, metadata); if (tableStreamSpec.Options.IsUnidirectional) { throw new ExprValidationException("Tables cannot be marked as unidirectional"); } if (tableStreamSpec.Options.IsRetainIntersection || tableStreamSpec.Options.IsRetainUnion) { throw new ExprValidationException("Tables cannot be marked with retain"); } if (isJoin) { destroyCallbacks.AddCallback(new EPStatementDestroyCallbackTableIdxRef(services.TableService, metadata, statementContext.StatementName)); } services.StatementVariableRefService.AddReferences(statementContext.StatementName, metadata.TableName); } else if (streamSpec is NamedWindowConsumerStreamSpec) { var namedSpec = (NamedWindowConsumerStreamSpec)streamSpec; var processor = services.NamedWindowMgmtService.GetProcessor(namedSpec.WindowName); var namedWindowType = processor.TailView.EventType; if (namedSpec.OptPropertyEvaluator != null) { namedWindowType = namedSpec.OptPropertyEvaluator.FragmentEventType; } eventStreamParentViewableActivators[i] = services.ViewableActivatorFactory.CreateNamedWindow(processor, namedSpec, statementContext); services.NamedWindowConsumerMgmtService.AddConsumer(statementContext, namedSpec); unmaterializedViewChain[i] = services.ViewService.CreateFactories(i, namedWindowType, namedSpec.ViewSpecs, namedSpec.Options, statementContext, false, -1); joinAnalysisResult.SetNamedWindow(i); eventTypeNames[i] = namedSpec.WindowName; isNamedWindow[i] = true; // Consumers to named windows cannot declare a data window view onto the named window to avoid duplicate remove streams EPStatementStartMethodHelperValidate.ValidateNoDataWindowOnNamedWindow(unmaterializedViewChain[i].FactoryChain); } else { throw new ExprValidationException("Unknown stream specification type: " + streamSpec); } } // handle match-recognize pattern if (statementSpec.MatchRecognizeSpec != null) { if (isJoin) { throw new ExprValidationException("Joins are not allowed when using match-recognize"); } if (joinAnalysisResult.TablesPerStream[0] != null) { throw new ExprValidationException("Tables cannot be used with match-recognize"); } var isUnbound = (unmaterializedViewChain[0].FactoryChain.IsEmpty()) && (!(statementSpec.StreamSpecs[0] is NamedWindowConsumerStreamSpec)); var factoryX = services.RegexHandlerFactory.MakeViewFactory(unmaterializedViewChain[0], statementSpec.MatchRecognizeSpec, defaultAgentInstanceContext, isUnbound, statementSpec.Annotations, services.ConfigSnapshot.EngineDefaults.MatchRecognizeConfig); unmaterializedViewChain[0].FactoryChain.Add(factoryX); EPStatementStartMethodHelperAssignExpr.AssignAggregations(factoryX.AggregationService, factoryX.AggregationExpressions); } // Obtain event types from view factory chains var streamEventTypes = new EventType[statementSpec.StreamSpecs.Length]; for (var i = 0; i < unmaterializedViewChain.Length; i++) { streamEventTypes[i] = unmaterializedViewChain[i].EventType; } // Add uniqueness information useful for joins joinAnalysisResult.AddUniquenessInfo(unmaterializedViewChain, statementSpec.Annotations); // Validate sub-select views var subSelectStrategyCollection = EPStatementStartMethodHelperSubselect.PlanSubSelect(services, statementContext, queryPlanLogging, subSelectStreamDesc, streamNames, streamEventTypes, eventTypeNames, statementSpec.DeclaredExpressions, contextPropertyRegistry); // Construct type information per stream StreamTypeService typeService = new StreamTypeServiceImpl(streamEventTypes, streamNames, EPStatementStartMethodHelperUtil.GetHasIStreamOnly(isNamedWindow, unmaterializedViewChain), services.EngineURI, false); var viewResourceDelegateUnverified = new ViewResourceDelegateUnverified(); // Validate views that require validation, specifically streams that don't have // sub-views such as DB SQL joins var historicalViewableDesc = new HistoricalViewableDesc(numStreams); for (var stream = 0; stream < historicalEventViewables.Length; stream++) { var historicalEventViewable = historicalEventViewables[stream]; if (historicalEventViewable == null) { continue; } historicalEventViewable.Validate( services.EngineImportService, typeService, statementContext.MethodResolutionService, statementContext.TimeProvider, statementContext.VariableService, statementContext.TableService, statementContext.ScriptingService, evaluatorContextStmt, services.ConfigSnapshot, services.SchedulingService, services.EngineURI, statementSpec.SqlParameters, statementContext.EventAdapterService, statementContext); historicalViewableDesc.SetHistorical(stream, historicalEventViewable.RequiredStreams); if (historicalEventViewable.RequiredStreams.Contains(stream)) { throw new ExprValidationException("Parameters for historical stream " + stream + " indicate that the stream is subordinate to itself as stream parameters originate in the same stream"); } } // unidirectional is not supported with into-table if (joinAnalysisResult.IsUnidirectional && statementSpec.IntoTableSpec != null) { throw new ExprValidationException("Into-table does not allow unidirectional joins"); } // Construct a processor for results posted by views and joins, which takes care of aggregation if required. // May return null if we don't need to post-process results posted by views or joins. var resultSetProcessorPrototypeDesc = ResultSetProcessorFactoryFactory.GetProcessorPrototype( statementSpec, statementContext, typeService, viewResourceDelegateUnverified, joinAnalysisResult.UnidirectionalInd, true, contextPropertyRegistry, selectExprProcessorDeliveryCallback, services.ConfigSnapshot, services.ResultSetProcessorHelperFactory, false, false); // Validate where-clause filter tree, outer join clause and output limit expression EPStatementStartMethodHelperValidate.ValidateNodes(statementSpec, statementContext, typeService, viewResourceDelegateUnverified); // Handle 'prior' function nodes in terms of view requirements var viewResourceDelegateVerified = EPStatementStartMethodHelperViewResources.VerifyPreviousAndPriorRequirements(unmaterializedViewChain, viewResourceDelegateUnverified); // handle join JoinSetComposerPrototype joinSetComposerPrototype = null; if (numStreams > 1) { var selectsRemoveStream = statementSpec.SelectStreamSelectorEnum.IsSelectsRStream() || statementSpec.OutputLimitSpec != null; var hasAggregations = !resultSetProcessorPrototypeDesc.AggregationServiceFactoryDesc.Expressions.IsEmpty(); joinSetComposerPrototype = JoinSetComposerPrototypeFactory.MakeComposerPrototype( statementContext.StatementName, statementContext.StatementId, statementSpec.OuterJoinDescList, statementSpec.FilterRootNode, typeService.EventTypes, streamNames, joinAnalysisResult, queryPlanLogging, statementContext, historicalViewableDesc, defaultAgentInstanceContext, selectsRemoveStream, hasAggregations, services.TableService, false, services.EventTableIndexService.AllowInitIndex(recoveringResilient)); } // obtain factory for output limiting var outputViewFactory = OutputProcessViewFactoryFactory.Make(statementSpec, services.InternalEventRouter, statementContext, resultSetProcessorPrototypeDesc.ResultSetProcessorFactory.ResultEventType, optionalOutputProcessViewCallback, services.TableService, resultSetProcessorPrototypeDesc.ResultSetProcessorFactory.ResultSetProcessorType, services.ResultSetProcessorHelperFactory, services.StatementVariableRefService); // Factory for statement-context instances var factory = new StatementAgentInstanceFactorySelect( numStreams, eventStreamParentViewableActivators, statementContext, statementSpec, services, typeService, unmaterializedViewChain, resultSetProcessorPrototypeDesc, joinAnalysisResult, recoveringResilient, joinSetComposerPrototype, subSelectStrategyCollection, viewResourceDelegateVerified, outputViewFactory); EPStatementStopMethod stopMethod = new EPStatementStopMethodImpl(statementContext, stopCallbacks); return(new EPStatementStartMethodSelectDesc(factory, subSelectStrategyCollection, viewResourceDelegateUnverified, resultSetProcessorPrototypeDesc, stopMethod, destroyCallbacks)); }
/// <summary> /// Ctor. /// </summary> /// <param name="statementSpec"> /// is a container for the definition of all statement constructs that may have been used in the /// statement, i.e. if defines the select clauses, insert into, outer joins etc. /// </param> /// <param name="services">is the service instances for dependency injection</param> /// <param name="statementContext">is statement-level information and statement services</param> /// <throws>ExprValidationException if the preparation failed</throws> public EPPreparedExecuteMethodQuery( StatementSpecCompiled statementSpec, EPServicesContext services, StatementContext statementContext) { var queryPlanLogging = services.ConfigSnapshot.EngineDefaults.Logging.IsEnableQueryPlan; if (queryPlanLogging) { QueryPlanLog.Info("Query plans for Fire-and-forget query '" + statementContext.Expression + "'"); } _hasTableAccess = (statementSpec.TableNodes != null && statementSpec.TableNodes.Length > 0); foreach (var streamSpec in statementSpec.StreamSpecs) { _hasTableAccess |= streamSpec is TableQueryStreamSpec; } _statementSpec = statementSpec; _services = services; EPPreparedExecuteMethodHelper.ValidateFAFQuery(statementSpec); var numStreams = statementSpec.StreamSpecs.Length; var typesPerStream = new EventType[numStreams]; var namesPerStream = new string[numStreams]; _processors = new FireAndForgetProcessor[numStreams]; _agentInstanceContext = new AgentInstanceContext(statementContext, null, -1, null, null, statementContext.DefaultAgentInstanceScriptContext); // resolve types and processors for (var i = 0; i < numStreams; i++) { var streamSpec = statementSpec.StreamSpecs[i]; _processors[i] = FireAndForgetProcessorFactory.ValidateResolveProcessor(streamSpec, services); string streamName = _processors[i].NamedWindowOrTableName; if (streamSpec.OptionalStreamName != null) { streamName = streamSpec.OptionalStreamName; } namesPerStream[i] = streamName; typesPerStream[i] = _processors[i].EventTypeResultSetProcessor; } // compile filter to optimize access to named window var types = new StreamTypeServiceImpl(typesPerStream, namesPerStream, new bool[numStreams], services.EngineURI, false); var excludePlanHint = ExcludePlanHint.GetHint(types.StreamNames, statementContext); _queryGraph = new QueryGraph(numStreams, excludePlanHint, false); if (statementSpec.FilterRootNode != null) { for (var i = 0; i < numStreams; i++) { try { ExprEvaluatorContextStatement evaluatorContextStmt = new ExprEvaluatorContextStatement(statementContext, false); ExprValidationContext validationContext = new ExprValidationContext( statementContext.Container, types, statementContext.EngineImportService, statementContext.StatementExtensionServicesContext, null, statementContext.TimeProvider, statementContext.VariableService, statementContext.TableService, evaluatorContextStmt, statementContext.EventAdapterService, statementContext.StatementName, statementContext.StatementId, statementContext.Annotations, statementContext.ContextDescriptor, statementContext.ScriptingService, false, false, true, false, null, true); ExprNode validated = ExprNodeUtility.GetValidatedSubtree(ExprNodeOrigin.FILTER, statementSpec.FilterRootNode, validationContext); FilterExprAnalyzer.Analyze(validated, _queryGraph, false); } catch (Exception ex) { Log.Warn("Unexpected exception analyzing filter paths: " + ex.Message, ex); } } } // obtain result set processor var isIStreamOnly = new bool[namesPerStream.Length]; CompatExtensions.Fill(isIStreamOnly, true); StreamTypeService typeService = new StreamTypeServiceImpl(typesPerStream, namesPerStream, isIStreamOnly, services.EngineURI, true); EPStatementStartMethodHelperValidate.ValidateNodes(statementSpec, statementContext, typeService, null); var resultSetProcessorPrototype = ResultSetProcessorFactoryFactory.GetProcessorPrototype(statementSpec, statementContext, typeService, null, new bool[0], true, ContextPropertyRegistryImpl.EMPTY_REGISTRY, null, services.ConfigSnapshot, services.ResultSetProcessorHelperFactory, true, false); _resultSetProcessor = EPStatementStartMethodHelperAssignExpr.GetAssignResultSetProcessor(_agentInstanceContext, resultSetProcessorPrototype, false, null, true); if (statementSpec.SelectClauseSpec.IsDistinct) { if (_resultSetProcessor.ResultEventType is EventTypeSPI) { _eventBeanReader = ((EventTypeSPI)_resultSetProcessor.ResultEventType).Reader; } if (_eventBeanReader == null) { _eventBeanReader = new EventBeanReaderDefaultImpl(_resultSetProcessor.ResultEventType); } } // check context partition use if (statementSpec.OptionalContextName != null) { if (numStreams > 1) { throw new ExprValidationException("Joins in runtime queries for context partitions are not supported"); } } // plan joins or simple queries if (numStreams > 1) { var streamJoinAnalysisResult = new StreamJoinAnalysisResult(numStreams); CompatExtensions.Fill(streamJoinAnalysisResult.NamedWindow, true); for (var i = 0; i < numStreams; i++) { var processorInstance = _processors[i].GetProcessorInstance(_agentInstanceContext); if (_processors[i].IsVirtualDataWindow) { streamJoinAnalysisResult.ViewExternal[i] = agentInstanceContext => processorInstance.VirtualDataWindow; } var uniqueIndexes = _processors[i].GetUniqueIndexes(processorInstance); streamJoinAnalysisResult.UniqueKeys[i] = uniqueIndexes; } var hasAggregations = !resultSetProcessorPrototype.AggregationServiceFactoryDesc.Expressions.IsEmpty(); _joinSetComposerPrototype = JoinSetComposerPrototypeFactory.MakeComposerPrototype(null, -1, statementSpec.OuterJoinDescList, statementSpec.FilterRootNode, typesPerStream, namesPerStream, streamJoinAnalysisResult, queryPlanLogging, statementContext, new HistoricalViewableDesc(numStreams), _agentInstanceContext, false, hasAggregations, services.TableService, true, services.EventTableIndexService.AllowInitIndex(false)); } }
/// <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.MatchRecognizeConfig 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); for (int ii = 0; ii < aggregateNode.ChildNodes.Count; ii++) { var child = aggregateNode.ChildNodes[ii]; 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 void Attach(EventType parentEventType, StatementContext statementContext, ViewFactory optionalParentFactory, IList <ViewFactory> parentViewFactories) { EventType = parentEventType; var message = NAME + " view requires a list of expressions providing unique keys, a numeric size parameter and a list of expressions providing sort keys"; if (_viewParameters.Count < 3) { throw new ViewParameterException(message); } // validate var validated = ViewFactorySupport.Validate(NAME, parentEventType, statementContext, _viewParameters, true); // find size-parameter index var indexNumericSize = -1; for (var i = 0; i < validated.Length; i++) { if (validated[i] is ExprConstantNode) { indexNumericSize = i; break; } } if (indexNumericSize == -1) { throw new ViewParameterException("Failed to find constant value for the numeric size parameter"); } if (indexNumericSize == 0) { throw new ViewParameterException("Failed to find unique value expressions that are expected to occur before the numeric size parameter"); } if (indexNumericSize == validated.Length - 1) { throw new ViewParameterException("Failed to find sort key expressions after the numeric size parameter"); } // validate non-constant for unique-keys and sort-keys for (var i = 0; i < indexNumericSize; i++) { ViewFactorySupport.AssertReturnsNonConstant(NAME, validated[i], i); } for (var i = indexNumericSize + 1; i < validated.Length; i++) { ViewFactorySupport.AssertReturnsNonConstant(NAME, validated[i], i); } // get sort size var exprEvaluatorContext = new ExprEvaluatorContextStatement(statementContext, false); var sortSize = ViewFactorySupport.EvaluateAssertNoProperties(NAME, validated[indexNumericSize], indexNumericSize, exprEvaluatorContext); if ((sortSize == null) || (!sortSize.IsNumber())) { throw new ViewParameterException(message); } SortWindowSize = sortSize.AsInt(); // compile unique expressions uniqueCriteriaExpressions = new ExprNode[indexNumericSize]; Array.Copy(validated, 0, uniqueCriteriaExpressions, 0, indexNumericSize); // compile sort expressions sortCriteriaExpressions = new ExprNode[validated.Length - indexNumericSize - 1]; IsDescendingValues = new bool[sortCriteriaExpressions.Length]; var count = 0; for (var i = indexNumericSize + 1; i < validated.Length; i++) { if (validated[i] is ExprOrderedExpr) { IsDescendingValues[count] = ((ExprOrderedExpr)validated[i]).IsDescending; sortCriteriaExpressions[count] = validated[i].ChildNodes[0]; } else { sortCriteriaExpressions[count] = validated[i]; } count++; } UniqueEvals = ExprNodeUtility.GetEvaluators(uniqueCriteriaExpressions); SortEvals = ExprNodeUtility.GetEvaluators(sortCriteriaExpressions); if (statementContext.ConfigSnapshot != null) { IsUseCollatorSort = statementContext.ConfigSnapshot.EngineDefaults.LanguageConfig.IsSortUsingCollator; } }
internal static UniformPair <int?> ValidateOuterJoinPropertyPair( StatementContext statementContext, ExprIdentNode leftNode, ExprIdentNode rightNode, int outerJoinCount, StreamTypeService typeService, ViewResourceDelegateUnverified viewResourceDelegate) { // Validate the outer join clause using an artificial equals-node on top. // Thus types are checked via equals. // Sets stream ids used for validated nodes. ExprNode equalsNode = new ExprEqualsNodeImpl(false, false); equalsNode.AddChildNode(leftNode); equalsNode.AddChildNode(rightNode); var evaluatorContextStmt = new ExprEvaluatorContextStatement(statementContext, false); try { var validationContext = new ExprValidationContext( typeService, statementContext.MethodResolutionService, viewResourceDelegate, statementContext.SchedulingService, statementContext.VariableService, statementContext.TableService, evaluatorContextStmt, statementContext.EventAdapterService, statementContext.StatementName, statementContext.StatementId, statementContext.Annotations, statementContext.ContextDescriptor, statementContext.ScriptingService, false, false, true, false, null, false); ExprNodeUtility.GetValidatedSubtree(ExprNodeOrigin.JOINON, equalsNode, validationContext); } catch (ExprValidationException ex) { Log.Debug("Validation exception for outer join node=" + ExprNodeUtility.ToExpressionStringMinPrecedenceSafe(equalsNode), ex); throw new EPStatementException("Error validating expression: " + ex.Message, statementContext.Expression); } // Make sure we have left-hand-side and right-hand-side refering to different streams var streamIdLeft = leftNode.StreamId; var streamIdRight = rightNode.StreamId; if (streamIdLeft == streamIdRight) { const string message = "Outer join ON-clause cannot refer to properties of the same stream"; throw new EPStatementException("Error validating expression: " + message, statementContext.Expression); } // Make sure one of the properties refers to the acutual stream currently being joined var expectedStreamJoined = outerJoinCount + 1; if ((streamIdLeft != expectedStreamJoined) && (streamIdRight != expectedStreamJoined)) { var message = "Outer join ON-clause must refer to at least one property of the joined stream" + " for stream " + expectedStreamJoined; throw new EPStatementException("Error validating expression: " + message, statementContext.Expression); } // Make sure neither of the streams refer to a 'future' stream String badPropertyName = null; if (streamIdLeft > outerJoinCount + 1) { badPropertyName = leftNode.ResolvedPropertyName; } if (streamIdRight > outerJoinCount + 1) { badPropertyName = rightNode.ResolvedPropertyName; } if (badPropertyName != null) { var message = "Outer join ON-clause invalid scope for property" + " '" + badPropertyName + "', expecting the current or a prior stream scope"; throw new EPStatementException("Error validating expression: " + message, statementContext.Expression); } return(new UniformPair <int?>(streamIdLeft, streamIdRight)); }
public override EPStatementStartResult StartInternal( EPServicesContext services, StatementContext statementContext, bool isNewStatement, bool isRecoveringStatement, bool isRecoveringResilient) { var createDesc = _statementSpec.CreateVariableDesc; VariableServiceUtil.CheckAlreadyDeclaredTable(createDesc.VariableName, services.TableService); // Get assignment value object value = null; if (createDesc.Assignment != null) { // Evaluate assignment expression StreamTypeService typeService = new StreamTypeServiceImpl( new EventType[0], new string[0], new bool[0], services.EngineURI, false); var evaluatorContextStmt = new ExprEvaluatorContextStatement(statementContext, false); var validationContext = new ExprValidationContext( typeService, statementContext.MethodResolutionService, null, statementContext.SchedulingService, statementContext.VariableService, statementContext.TableService, evaluatorContextStmt, statementContext.EventAdapterService, statementContext.StatementName, statementContext.StatementId, statementContext.Annotations, statementContext.ContextDescriptor, statementContext.ScriptingService, false, false, false, false, null, false); var validated = ExprNodeUtility.GetValidatedSubtree( ExprNodeOrigin.VARIABLEASSIGN, createDesc.Assignment, validationContext); value = validated.ExprEvaluator.Evaluate(new EvaluateParams(null, true, evaluatorContextStmt)); } // Create variable try { services.VariableService.CreateNewVariable( _statementSpec.OptionalContextName, createDesc.VariableName, createDesc.VariableType, createDesc.IsConstant, createDesc.IsArray, createDesc.IsArrayOfPrimitive, value, services.EngineImportService); } catch (VariableExistsException ex) { // for new statement we don't allow creating the same variable if (isNewStatement) { throw new ExprValidationException("Cannot create variable: " + ex.Message, ex); } } catch (VariableDeclarationException ex) { throw new ExprValidationException("Cannot create variable: " + ex.Message, ex); } var destroyMethod = new EPStatementDestroyCallbackList(); destroyMethod.AddCallback(new ProxyDestroyCallback(() => { try { services.StatementVariableRefService.RemoveReferencesStatement(statementContext.StatementName); } catch (Exception ex) { Log.Error("Error removing variable '" + createDesc.VariableName + "': " + ex.Message); } })); var stopMethod = new ProxyEPStatementStopMethod(() => { }); var variableMetaData = services.VariableService.GetVariableMetaData(createDesc.VariableName); Viewable outputView; var eventType = CreateVariableView.GetEventType( statementContext.StatementId, services.EventAdapterService, variableMetaData); var contextFactory = new StatementAgentInstanceFactoryCreateVariable( createDesc, _statementSpec, statementContext, services, variableMetaData, eventType); statementContext.StatementAgentInstanceFactory = contextFactory; if (_statementSpec.OptionalContextName != null) { var mergeView = new ContextMergeView(eventType); outputView = mergeView; var statement = new ContextManagedStatementCreateVariableDesc(_statementSpec, statementContext, mergeView, contextFactory); services.ContextManagementService.AddStatement( _statementSpec.OptionalContextName, statement, isRecoveringResilient); var contextManagementService = services.ContextManagementService; destroyMethod.AddCallback(new ProxyDestroyCallback(() => contextManagementService.DestroyedStatement( _statementSpec.OptionalContextName, statementContext.StatementName, statementContext.StatementId))); } else { var resultOfStart = (StatementAgentInstanceFactoryCreateVariableResult) contextFactory.NewContext(GetDefaultAgentInstanceContext(statementContext), isRecoveringResilient); outputView = resultOfStart.FinalView; if (statementContext.StatementExtensionServicesContext != null && statementContext.StatementExtensionServicesContext.StmtResources != null) { var holder = statementContext.StatementExtensionServicesContext.ExtractStatementResourceHolder(resultOfStart); statementContext.StatementExtensionServicesContext.StmtResources.Unpartitioned = holder; statementContext.StatementExtensionServicesContext.PostProcessStart(resultOfStart, isRecoveringResilient); } } services.StatementVariableRefService.AddReferences( statementContext.StatementName, Collections.SingletonList(createDesc.VariableName), null); return(new EPStatementStartResult(outputView, stopMethod, destroyMethod)); }
public override EPStatementStartResult StartInternal(EPServicesContext services, StatementContext statementContext, bool isNewStatement, bool isRecoveringStatement, bool isRecoveringResilient) { // define stop and destroy var stopCallbacks = new List <StopCallback>(); var destroyCallbacks = new EPStatementDestroyCallbackList(); // determine context var contextName = StatementSpec.OptionalContextName; if (contextName != null) { throw new ExprValidationException("Update IStream is not supported in conjunction with a context"); } // First we create streams for subselects, if there are any var subSelectStreamDesc = EPStatementStartMethodHelperSubselect.CreateSubSelectActivation( services, StatementSpec, statementContext, destroyCallbacks); var streamSpec = StatementSpec.StreamSpecs[0]; var updateSpec = StatementSpec.UpdateSpec; String triggereventTypeName; if (streamSpec is FilterStreamSpecCompiled) { var filterStreamSpec = (FilterStreamSpecCompiled)streamSpec; triggereventTypeName = filterStreamSpec.FilterSpec.FilterForEventTypeName; } else if (streamSpec is NamedWindowConsumerStreamSpec) { var namedSpec = (NamedWindowConsumerStreamSpec)streamSpec; triggereventTypeName = namedSpec.WindowName; } else if (streamSpec is TableQueryStreamSpec) { throw new ExprValidationException("Tables cannot be used in an update-istream statement"); } else { throw new ExprValidationException("Unknown stream specification streamEventType: " + streamSpec); } // determine a stream name var streamName = triggereventTypeName; if (updateSpec.OptionalStreamName != null) { streamName = updateSpec.OptionalStreamName; } var streamEventType = services.EventAdapterService.GetEventTypeByName(triggereventTypeName); StreamTypeService typeService = new StreamTypeServiceImpl(new EventType[] { streamEventType }, new String[] { streamName }, new bool[] { true }, services.EngineURI, false); // determine subscriber result types var evaluatorContextStmt = new ExprEvaluatorContextStatement(statementContext, false); statementContext.StatementResultService.SetSelectClause(new Type[] { streamEventType.UnderlyingType }, new String[] { "*" }, false, null, evaluatorContextStmt); // Materialize sub-select views var subSelectStrategyCollection = EPStatementStartMethodHelperSubselect.PlanSubSelect(services, statementContext, IsQueryPlanLogging(services), subSelectStreamDesc, new String[] { streamName }, new EventType[] { streamEventType }, new String[] { triggereventTypeName }, StatementSpec.DeclaredExpressions, null); var validationContext = new ExprValidationContext( typeService, statementContext.MethodResolutionService, null, statementContext.SchedulingService, statementContext.VariableService, statementContext.TableService, evaluatorContextStmt, statementContext.EventAdapterService, statementContext.StatementName, statementContext.StatementId, statementContext.Annotations, statementContext.ContextDescriptor, statementContext.ScriptingService, false, false, false, false, null, false); foreach (var assignment in updateSpec.Assignments) { var validated = ExprNodeUtility.GetValidatedAssignment(assignment, validationContext); assignment.Expression = validated; EPStatementStartMethodHelperValidate.ValidateNoAggregations(validated, "Aggregation functions may not be used within an update-clause"); } if (updateSpec.OptionalWhereClause != null) { var validated = ExprNodeUtility.GetValidatedSubtree( ExprNodeOrigin.WHERE, updateSpec.OptionalWhereClause, validationContext); updateSpec.OptionalWhereClause = validated; EPStatementStartMethodHelperValidate.ValidateNoAggregations(validated, "Aggregation functions may not be used within an update-clause"); } // preprocessing view var onExprView = new InternalRoutePreprocessView(streamEventType, statementContext.StatementResultService); // validation var routerDesc = services.InternalEventRouter.GetValidatePreprocessing(onExprView.EventType, updateSpec, statementContext.Annotations); // create context factory var contextFactory = new StatementAgentInstanceFactoryUpdate(statementContext, services, streamEventType, updateSpec, onExprView, routerDesc, subSelectStrategyCollection); // perform start of hook-up to start Viewable finalViewable; EPStatementStopMethod stopStatementMethod; IDictionary <ExprSubselectNode, SubSelectStrategyHolder> subselectStrategyInstances; // With context - delegate instantiation to context EPStatementStopMethod stopMethod = new EPStatementStopMethodImpl(statementContext, stopCallbacks).Stop; if (StatementSpec.OptionalContextName != null) { // use statement-wide agent-instance-specific subselects var aiRegistryExpr = statementContext.StatementAgentInstanceRegistry.AgentInstanceExprService; subselectStrategyInstances = new Dictionary <ExprSubselectNode, SubSelectStrategyHolder>(); foreach (var node in subSelectStrategyCollection.Subqueries.Keys) { var specificService = aiRegistryExpr.AllocateSubselect(node); node.Strategy = specificService; subselectStrategyInstances.Put(node, new SubSelectStrategyHolder(null, null, null, null, null, null)); } var mergeView = new ContextMergeView(onExprView.EventType); finalViewable = mergeView; var statement = new ContextManagedStatementOnTriggerDesc(StatementSpec, statementContext, mergeView, contextFactory); services.ContextManagementService.AddStatement(StatementSpec.OptionalContextName, statement, isRecoveringResilient); stopStatementMethod = () => { services.ContextManagementService.StoppedStatement(contextName, statementContext.StatementName, statementContext.StatementId); stopMethod.Invoke(); }; destroyCallbacks.AddCallback(EPStatementDestroyCallbackContext.New( services.ContextManagementService, StatementSpec.OptionalContextName, statementContext.StatementName, statementContext.StatementId)); } // Without context - start here else { var agentInstanceContext = GetDefaultAgentInstanceContext(statementContext); var resultOfStart = (StatementAgentInstanceFactoryUpdateResult) contextFactory.NewContext(agentInstanceContext, isRecoveringResilient); finalViewable = resultOfStart.FinalView; stopStatementMethod = new EPStatementStopMethod(() => { resultOfStart.StopCallback.Invoke(); stopMethod.Invoke(); }); subselectStrategyInstances = resultOfStart.SubselectStrategies; } // assign subquery nodes EPStatementStartMethodHelperAssignExpr.AssignSubqueryStrategies(subSelectStrategyCollection, subselectStrategyInstances); return(new EPStatementStartResult(finalViewable, stopStatementMethod, destroyCallbacks.Destroy)); }
public override EPStatementStartResult StartInternal(EPServicesContext services, StatementContext statementContext, bool isNewStatement, bool isRecoveringStatement, bool isRecoveringResilient) { var createDesc = StatementSpec.CreateVariableDesc; VariableServiceUtil.CheckAlreadyDeclaredTable(createDesc.VariableName, services.TableService); // Get assignment value Object value = null; if (createDesc.Assignment != null) { // Evaluate assignment expression var typeService = new StreamTypeServiceImpl(new EventType[0], new String[0], new bool[0], services.EngineURI, false); var evaluatorContextStmt = new ExprEvaluatorContextStatement(statementContext, false); var validationContext = new ExprValidationContext( typeService, statementContext.MethodResolutionService, null, statementContext.SchedulingService, statementContext.VariableService, statementContext.TableService, evaluatorContextStmt, statementContext.EventAdapterService, statementContext.StatementName, statementContext.StatementId, statementContext.Annotations, statementContext.ContextDescriptor, statementContext.ScriptingService, false, false, false, false, null, false); var validated = ExprNodeUtility.GetValidatedSubtree(ExprNodeOrigin.VARIABLEASSIGN, createDesc.Assignment, validationContext); value = validated.ExprEvaluator.Evaluate(new EvaluateParams(null, true, evaluatorContextStmt)); } // Create variable try { services.VariableService.CreateNewVariable( StatementSpec.OptionalContextName, createDesc.VariableName, createDesc.VariableType, createDesc.IsConstant, createDesc.IsArray, createDesc.IsArrayOfPrimitive, value, services.EngineImportService); } catch (VariableExistsException ex) { // for new statement we don't allow creating the same variable if (isNewStatement) { throw new ExprValidationException("Cannot create variable: " + ex.Message, ex); } } catch (VariableDeclarationException ex) { throw new ExprValidationException("Cannot create variable: " + ex.Message, ex); } var destroyMethod = new EPStatementDestroyCallbackList(); destroyMethod.AddCallback( () => { try { services.StatementVariableRefService.RemoveReferencesStatement(statementContext.StatementName); } catch (Exception ex) { Log.Error("Error removing variable '" + createDesc.VariableName + "': " + ex.Message); } }); var stopMethod = new EPStatementStopMethod(() => { }); VariableMetaData variableMetaData = services.VariableService.GetVariableMetaData(createDesc.VariableName); Viewable outputView; if (StatementSpec.OptionalContextName != null) { EventType eventType = CreateVariableView.GetEventType(statementContext.StatementId, services.EventAdapterService, variableMetaData); var contextFactory = new StatementAgentInstanceFactoryCreateVariable(statementContext, services, variableMetaData, eventType); var mergeView = new ContextMergeView(eventType); outputView = mergeView; var statement = new ContextManagedStatementCreateVariableDesc(StatementSpec, statementContext, mergeView, contextFactory); services.ContextManagementService.AddStatement(StatementSpec.OptionalContextName, statement, isRecoveringResilient); ContextManagementService contextManagementService = services.ContextManagementService; destroyMethod.AddCallback(() => contextManagementService.DestroyedStatement(StatementSpec.OptionalContextName, statementContext.StatementName, statementContext.StatementId)); } else { // allocate services.VariableService.AllocateVariableState(createDesc.VariableName, VariableServiceConstants.NOCONTEXT_AGENTINSTANCEID, statementContext.StatementExtensionServicesContext); var createView = new CreateVariableView(statementContext.StatementId, services.EventAdapterService, services.VariableService, createDesc.VariableName, statementContext.StatementResultService); services.VariableService.RegisterCallback(createDesc.VariableName, 0, createView.Update); statementContext.StatementStopService.StatementStopped += () => services.VariableService.UnregisterCallback(createDesc.VariableName, 0, createView.Update); // Create result set processor, use wildcard selection StatementSpec.SelectClauseSpec.SetSelectExprList(new SelectClauseElementWildcard()); StatementSpec.SelectStreamDirEnum = SelectClauseStreamSelectorEnum.RSTREAM_ISTREAM_BOTH; StreamTypeService typeService = new StreamTypeServiceImpl(new EventType[] { createView.EventType }, new String[] { "create_variable" }, new bool[] { true }, services.EngineURI, false); var agentInstanceContext = GetDefaultAgentInstanceContext(statementContext); var resultSetProcessorPrototype = ResultSetProcessorFactoryFactory.GetProcessorPrototype( StatementSpec, statementContext, typeService, null, new bool[0], true, ContextPropertyRegistryImpl.EMPTY_REGISTRY, null, services.ConfigSnapshot); var resultSetProcessor = EPStatementStartMethodHelperAssignExpr.GetAssignResultSetProcessor(agentInstanceContext, resultSetProcessorPrototype); // Attach output view var outputViewFactory = OutputProcessViewFactoryFactory.Make(StatementSpec, services.InternalEventRouter, agentInstanceContext.StatementContext, resultSetProcessor.ResultEventType, null, services.TableService, resultSetProcessorPrototype.ResultSetProcessorFactory.ResultSetProcessorType); var outputViewBase = outputViewFactory.MakeView(resultSetProcessor, agentInstanceContext); createView.AddView(outputViewBase); outputView = outputViewBase; } services.StatementVariableRefService.AddReferences(statementContext.StatementName, Collections.SingletonList(createDesc.VariableName), null); return(new EPStatementStartResult(outputView, stopMethod, destroyMethod.Destroy)); }
/// <summary> /// Validate filter and join expression nodes. /// </summary> /// <param name="statementSpec">the compiled statement</param> /// <param name="statementContext">the statement services</param> /// <param name="typeService">the event types for streams</param> /// <param name="viewResourceDelegate">the delegate to verify expressions that use view resources</param> internal static void ValidateNodes( StatementSpecCompiled statementSpec, StatementContext statementContext, StreamTypeService typeService, ViewResourceDelegateUnverified viewResourceDelegate) { var methodResolutionService = statementContext.MethodResolutionService; var evaluatorContextStmt = new ExprEvaluatorContextStatement(statementContext, false); var intoTableName = statementSpec.IntoTableSpec == null ? null : statementSpec.IntoTableSpec.Name; if (statementSpec.FilterRootNode != null) { var optionalFilterNode = statementSpec.FilterRootNode; // Validate where clause, initializing nodes to the stream ids used try { var validationContext = new ExprValidationContext( typeService, methodResolutionService, viewResourceDelegate, statementContext.SchedulingService, statementContext.VariableService, statementContext.TableService, evaluatorContextStmt, statementContext.EventAdapterService, statementContext.StatementName, statementContext.StatementId, statementContext.Annotations, statementContext.ContextDescriptor, statementContext.ScriptingService, false, false, true, false, intoTableName, false); optionalFilterNode = ExprNodeUtility.GetValidatedSubtree(ExprNodeOrigin.FILTER, optionalFilterNode, validationContext); if (optionalFilterNode.ExprEvaluator.ReturnType != typeof(bool) && optionalFilterNode.ExprEvaluator.ReturnType != typeof(bool?)) { throw new ExprValidationException("The where-clause filter expression must return a boolean value"); } statementSpec.FilterExprRootNode = optionalFilterNode; // Make sure there is no aggregation in the where clause var aggregateNodes = new List <ExprAggregateNode>(); ExprAggregateNodeUtil.GetAggregatesBottomUp(optionalFilterNode, aggregateNodes); if (!aggregateNodes.IsEmpty()) { throw new ExprValidationException("An aggregate function may not appear in a WHERE clause (use the HAVING clause)"); } } catch (ExprValidationException ex) { Log.Debug(".validateNodes Validation exception for filter=" + ExprNodeUtility.ToExpressionStringMinPrecedenceSafe(optionalFilterNode), ex); throw new EPStatementException("Error validating expression: " + ex.Message, ex, statementContext.Expression); } } if ((statementSpec.OutputLimitSpec != null) && ((statementSpec.OutputLimitSpec.WhenExpressionNode != null) || (statementSpec.OutputLimitSpec.AndAfterTerminateExpr != null))) { // Validate where clause, initializing nodes to the stream ids used try { var outputLimitType = OutputConditionExpressionFactory.GetBuiltInEventType(statementContext.EventAdapterService); StreamTypeService typeServiceOutputWhen = new StreamTypeServiceImpl(new EventType[] { outputLimitType }, new String[] { null }, new bool[] { true }, statementContext.EngineURI, false); var validationContext = new ExprValidationContext( typeServiceOutputWhen, methodResolutionService, null, statementContext.SchedulingService, statementContext.VariableService, statementContext.TableService, evaluatorContextStmt, statementContext.EventAdapterService, statementContext.StatementName, statementContext.StatementId, statementContext.Annotations, statementContext.ContextDescriptor, statementContext.ScriptingService, false, false, false, false, intoTableName, false); var outputLimitWhenNode = statementSpec.OutputLimitSpec.WhenExpressionNode; if (outputLimitWhenNode != null) { outputLimitWhenNode = ExprNodeUtility.GetValidatedSubtree(ExprNodeOrigin.OUTPUTLIMIT, outputLimitWhenNode, validationContext); statementSpec.OutputLimitSpec.WhenExpressionNode = outputLimitWhenNode; if (TypeHelper.GetBoxedType(outputLimitWhenNode.ExprEvaluator.ReturnType) != typeof(bool?)) { throw new ExprValidationException("The when-trigger expression in the OUTPUT WHEN clause must return a boolean-type value"); } EPStatementStartMethodHelperValidate.ValidateNoAggregations(outputLimitWhenNode, "An aggregate function may not appear in a OUTPUT LIMIT clause"); } // validate and-terminate expression if provided if (statementSpec.OutputLimitSpec.AndAfterTerminateExpr != null) { if (statementSpec.OutputLimitSpec.RateType != OutputLimitRateType.WHEN_EXPRESSION && statementSpec.OutputLimitSpec.RateType != OutputLimitRateType.TERM) { throw new ExprValidationException("A terminated-and expression must be used with the OUTPUT WHEN clause"); } var validated = ExprNodeUtility.GetValidatedSubtree(ExprNodeOrigin.OUTPUTLIMIT, statementSpec.OutputLimitSpec.AndAfterTerminateExpr, validationContext); statementSpec.OutputLimitSpec.AndAfterTerminateExpr = validated; if (validated.ExprEvaluator.ReturnType.GetBoxedType() != typeof(bool?)) { throw new ExprValidationException("The terminated-and expression must return a boolean-type value"); } EPStatementStartMethodHelperValidate.ValidateNoAggregations(validated, "An aggregate function may not appear in a terminated-and clause"); } // validate then-expression ValidateThenSetAssignments(statementSpec.OutputLimitSpec.ThenExpressions, validationContext); // validate after-terminated then-expression ValidateThenSetAssignments(statementSpec.OutputLimitSpec.AndAfterTerminateThenExpressions, validationContext); } catch (ExprValidationException ex) { throw new EPStatementException("Error validating expression: " + ex.Message, statementContext.Expression); } } for (var outerJoinCount = 0; outerJoinCount < statementSpec.OuterJoinDescList.Length; outerJoinCount++) { var outerJoinDesc = statementSpec.OuterJoinDescList[outerJoinCount]; // validate on-expression nodes, if provided if (outerJoinDesc.OptLeftNode != null) { var streamIdPair = ValidateOuterJoinPropertyPair(statementContext, outerJoinDesc.OptLeftNode, outerJoinDesc.OptRightNode, outerJoinCount, typeService, viewResourceDelegate); if (outerJoinDesc.AdditionalLeftNodes != null) { ISet <int?> streamSet = new HashSet <int?>(); streamSet.Add(streamIdPair.First); streamSet.Add(streamIdPair.Second); for (var i = 0; i < outerJoinDesc.AdditionalLeftNodes.Length; i++) { var streamIdPairAdd = ValidateOuterJoinPropertyPair(statementContext, outerJoinDesc.AdditionalLeftNodes[i], outerJoinDesc.AdditionalRightNodes[i], outerJoinCount, typeService, viewResourceDelegate); // make sure all additional properties point to the same two streams if ((!streamSet.Contains(streamIdPairAdd.First) || (!streamSet.Contains(streamIdPairAdd.Second)))) { const string message = "Outer join ON-clause columns must refer to properties of the same joined streams" + " when using multiple columns in the on-clause"; throw new EPStatementException("Error validating expression: " + message, statementContext.Expression); } } } } } }
public static OutputProcessViewFactory Make(StatementSpecCompiled statementSpec, InternalEventRouter internalEventRouter, StatementContext statementContext, EventType resultEventType, OutputProcessViewCallback optionalOutputProcessViewCallback, TableService tableService, ResultSetProcessorType resultSetProcessorType) { // determine direct-callback if (optionalOutputProcessViewCallback != null) { return(new OutputProcessViewFactoryCallback(optionalOutputProcessViewCallback)); } // determine routing var isRouted = false; var routeToFront = false; if (statementSpec.InsertIntoDesc != null) { isRouted = true; routeToFront = statementContext.NamedWindowService.IsNamedWindow(statementSpec.InsertIntoDesc.EventTypeName); } OutputStrategyPostProcessFactory outputStrategyPostProcessFactory = null; if ((statementSpec.InsertIntoDesc != null) || (statementSpec.SelectStreamSelectorEnum == SelectClauseStreamSelectorEnum.RSTREAM_ONLY)) { SelectClauseStreamSelectorEnum?insertIntoStreamSelector = null; string tableName = null; if (statementSpec.InsertIntoDesc != null) { insertIntoStreamSelector = statementSpec.InsertIntoDesc.StreamSelector; var tableMetadata = tableService.GetTableMetadata(statementSpec.InsertIntoDesc.EventTypeName); if (tableMetadata != null) { tableName = tableMetadata.TableName; EPLValidationUtil.ValidateContextName(true, tableName, tableMetadata.ContextName, statementSpec.OptionalContextName, true); } } outputStrategyPostProcessFactory = new OutputStrategyPostProcessFactory(isRouted, insertIntoStreamSelector, statementSpec.SelectStreamSelectorEnum, internalEventRouter, statementContext.EpStatementHandle, routeToFront, tableService, tableName); } // Do we need to enforce an output policy? var streamCount = statementSpec.StreamSpecs.Length; var outputLimitSpec = statementSpec.OutputLimitSpec; var isDistinct = statementSpec.SelectClauseSpec.IsDistinct; var isGrouped = statementSpec.GroupByExpressions != null && statementSpec.GroupByExpressions.GroupByNodes.Length > 0; if (outputLimitSpec != null) { var evaluatorContextStmt = new ExprEvaluatorContextStatement(statementContext, false); var validationContext = new ExprValidationContext( new StreamTypeServiceImpl(statementContext.EngineURI, false), statementContext.MethodResolutionService, null, statementContext.TimeProvider, statementContext.VariableService, statementContext.TableService, evaluatorContextStmt, statementContext.EventAdapterService, statementContext.StatementName, statementContext.StatementId, statementContext.Annotations, statementContext.ContextDescriptor, statementContext.ScriptingService, false, false, false, false, null, false); if (outputLimitSpec.AfterTimePeriodExpr != null) { var timePeriodExpr = (ExprTimePeriod)ExprNodeUtility.GetValidatedSubtree(ExprNodeOrigin.OUTPUTLIMIT, outputLimitSpec.AfterTimePeriodExpr, validationContext); outputLimitSpec.AfterTimePeriodExpr = timePeriodExpr; } if (outputLimitSpec.TimePeriodExpr != null) { var timePeriodExpr = (ExprTimePeriod)ExprNodeUtility.GetValidatedSubtree(ExprNodeOrigin.OUTPUTLIMIT, outputLimitSpec.TimePeriodExpr, validationContext); outputLimitSpec.TimePeriodExpr = timePeriodExpr; if (timePeriodExpr.IsConstantResult && timePeriodExpr.EvaluateAsSeconds(null, true, new ExprEvaluatorContextStatement(statementContext, false)) <= 0) { throw new ExprValidationException("Invalid time period expression returns a zero or negative time interval"); } } } OutputProcessViewFactory outputProcessViewFactory; if (outputLimitSpec == null) { if (!isDistinct) { outputProcessViewFactory = new OutputProcessViewDirectFactory(statementContext, outputStrategyPostProcessFactory); } else { outputProcessViewFactory = new OutputProcessViewDirectDistinctOrAfterFactory(statementContext, outputStrategyPostProcessFactory, isDistinct, null, null, resultEventType); } } else if (outputLimitSpec.RateType == OutputLimitRateType.AFTER) { outputProcessViewFactory = new OutputProcessViewDirectDistinctOrAfterFactory(statementContext, outputStrategyPostProcessFactory, isDistinct, outputLimitSpec.AfterTimePeriodExpr, outputLimitSpec.AfterNumberOfEvents, resultEventType); } else { try { var isWithHavingClause = statementSpec.HavingExprRootNode != null; var isStartConditionOnCreation = HasOnlyTables(statementSpec.StreamSpecs); var outputConditionFactory = OutputConditionFactoryFactory.CreateCondition(outputLimitSpec, statementContext, isGrouped, isWithHavingClause, isStartConditionOnCreation); var hasOrderBy = statementSpec.OrderByList != null && statementSpec.OrderByList.Length > 0; OutputProcessViewConditionFactory.ConditionType conditionType; var hasAfter = outputLimitSpec.AfterNumberOfEvents != null || outputLimitSpec.AfterTimePeriodExpr != null; var isUnaggregatedUngrouped = resultSetProcessorType == ResultSetProcessorType.HANDTHROUGH || resultSetProcessorType == ResultSetProcessorType.UNAGGREGATED_UNGROUPED; // hint checking with order-by var hasOptHint = HintEnum.ENABLE_OUTPUTLIMIT_OPT.GetHint(statementSpec.Annotations) != null; if (hasOptHint && hasOrderBy) { throw new ExprValidationException("The " + HintEnum.ENABLE_OUTPUTLIMIT_OPT + " hint is not supported with order-by"); } if (outputLimitSpec.DisplayLimit == OutputLimitLimitType.SNAPSHOT) { conditionType = OutputProcessViewConditionFactory.ConditionType.SNAPSHOT; } // For FIRST without groups we are using a special logic that integrates the first-flag, in order to still conveniently use all sorts of output conditions. // FIRST with group-by is handled by setting the output condition to null (OutputConditionNull) and letting the ResultSetProcessor handle first-per-group. // Without having-clause there is no required order of processing, thus also use regular policy. else if (outputLimitSpec.DisplayLimit == OutputLimitLimitType.FIRST && statementSpec.GroupByExpressions == null) { conditionType = OutputProcessViewConditionFactory.ConditionType.POLICY_FIRST; } else if (isUnaggregatedUngrouped && outputLimitSpec.DisplayLimit == OutputLimitLimitType.LAST) { conditionType = OutputProcessViewConditionFactory.ConditionType.POLICY_LASTALL_UNORDERED; } else if (hasOptHint && outputLimitSpec.DisplayLimit == OutputLimitLimitType.ALL && !hasOrderBy) { conditionType = OutputProcessViewConditionFactory.ConditionType.POLICY_LASTALL_UNORDERED; } else if (hasOptHint && outputLimitSpec.DisplayLimit == OutputLimitLimitType.LAST && !hasOrderBy) { conditionType = OutputProcessViewConditionFactory.ConditionType.POLICY_LASTALL_UNORDERED; } else { conditionType = OutputProcessViewConditionFactory.ConditionType.POLICY_NONFIRST; } var selectClauseStreamSelectorEnum = statementSpec.SelectStreamSelectorEnum; var terminable = outputLimitSpec.RateType == OutputLimitRateType.TERM || outputLimitSpec.IsAndAfterTerminate; outputProcessViewFactory = new OutputProcessViewConditionFactory(statementContext, outputStrategyPostProcessFactory, isDistinct, outputLimitSpec.AfterTimePeriodExpr, outputLimitSpec.AfterNumberOfEvents, resultEventType, outputConditionFactory, streamCount, conditionType, outputLimitSpec.DisplayLimit, terminable, hasAfter, isUnaggregatedUngrouped, selectClauseStreamSelectorEnum); } catch (Exception ex) { throw new ExprValidationException("Error in the output rate limiting clause: " + ex.Message, ex); } } return(outputProcessViewFactory); }
private PatternStreamSpecCompiled CompileInternal( StatementContext context, ICollection <string> eventTypeReferences, bool isInsertInto, ICollection <int> assignedTypeNumberStack, MatchEventSpec tags, IEnumerable <string> priorAllTags, bool isJoin, bool isContextDeclaration, bool isOnTrigger) { // validate if ((_suppressSameEventMatches || _discardPartialsOnMatch) && (isJoin || isContextDeclaration || isOnTrigger)) { throw new ExprValidationException( "Discard-partials and suppress-matches is not supported in a joins, context declaration and on-action"); } if (tags == null) { tags = new MatchEventSpec(); } var subexpressionIdStack = new ArrayDeque <int>(assignedTypeNumberStack); var evaluatorContextStmt = new ExprEvaluatorContextStatement(context, false); var nodeStack = new Stack <EvalFactoryNode>(); // detemine ordered tags var filterFactoryNodes = EvalNodeUtil.RecursiveGetChildNodes( _evalFactoryNode, FilterForFilterFactoryNodes.INSTANCE); var allTagNamesOrdered = new LinkedHashSet <string>(); if (priorAllTags != null) { allTagNamesOrdered.AddAll(priorAllTags); } foreach (var filterNode in filterFactoryNodes) { var factory = (EvalFilterFactoryNode)filterNode; int tagNumber; if (factory.EventAsName != null) { if (!allTagNamesOrdered.Contains(factory.EventAsName)) { allTagNamesOrdered.Add(factory.EventAsName); tagNumber = allTagNamesOrdered.Count - 1; } else { tagNumber = FindTagNumber(factory.EventAsName, allTagNamesOrdered); } factory.EventAsTagNumber = tagNumber; } } RecursiveCompile( _evalFactoryNode, context, evaluatorContextStmt, eventTypeReferences, isInsertInto, tags, subexpressionIdStack, nodeStack, allTagNamesOrdered); var auditPattern = AuditEnum.PATTERN.GetAudit(context.Annotations); var auditPatternInstance = AuditEnum.PATTERNINSTANCES.GetAudit(context.Annotations); var compiledEvalFactoryNode = _evalFactoryNode; if (context.PatternNodeFactory.IsAuditSupported && (auditPattern != null || auditPatternInstance != null)) { var instanceCount = new EvalAuditInstanceCount(); compiledEvalFactoryNode = RecursiveAddAuditNode( context.PatternNodeFactory, null, auditPattern != null, auditPatternInstance != null, _evalFactoryNode, instanceCount); } return(new PatternStreamSpecCompiled( compiledEvalFactoryNode, tags.TaggedEventTypes, tags.ArrayEventTypes, allTagNamesOrdered, ViewSpecs, OptionalStreamName, Options, _suppressSameEventMatches, _discardPartialsOnMatch)); }
public ViewableActivator CreateStreamReuseView(EPServicesContext services, StatementContext statementContext, StatementSpecCompiled statementSpec, FilterStreamSpecCompiled filterStreamSpec, bool isJoin, ExprEvaluatorContextStatement evaluatorContextStmt, bool filterSubselectSameStream, int streamNum, bool isCanIterateUnbound) { return(new ViewableActivatorStreamReuseView(services, statementContext, statementSpec, filterStreamSpec, isJoin, evaluatorContextStmt, filterSubselectSameStream, streamNum, isCanIterateUnbound)); }