public static void Validate3Stream(ExprNode topNode) { var streamTypeService = new SupportStreamTypeSvc3Stream(); var factoriesPerStream = new ViewFactoryChain[3]; for (var i = 0; i < factoriesPerStream.Length; i++) { var factories = new List <ViewFactory>(); factories.Add(new LengthWindowViewFactory()); factoriesPerStream[i] = new ViewFactoryChain(streamTypeService.EventTypes[i], factories); } var viewResources = new ViewResourceDelegateUnverified(); VariableService variableService = new VariableServiceImpl(0, new SchedulingServiceImpl(new TimeSourceServiceImpl()), SupportEventAdapterService.Service, null); variableService.CreateNewVariable(null, "IntPrimitive", typeof(int?).FullName, false, false, false, 10, null); variableService.AllocateVariableState("IntPrimitive", 0, null); variableService.CreateNewVariable(null, "var1", typeof(string).FullName, false, false, false, "my_variable_value", null); variableService.AllocateVariableState("var1", 0, null); ExprNodeUtility.GetValidatedSubtree( ExprNodeOrigin.SELECT, topNode, new ExprValidationContext( streamTypeService, MethodResService, viewResources, null, variableService, null, new SupportExprEvaluatorContext(null), null, null, null, null, null, null, false, false, false, false, null, false)); }
public ExprValidationContext(StreamTypeService streamTypeService, EngineImportService engineImportService, StatementExtensionSvcContext statementExtensionSvcContext, ViewResourceDelegateUnverified viewResourceDelegate, TimeProvider timeProvider, VariableService variableService, TableService tableService, ExprEvaluatorContext exprEvaluatorContext, EventAdapterService eventAdapterService, string statementName, int statementId, Attribute[] annotations, ContextDescriptor contextDescriptor, ScriptingService scriptingService, bool disablePropertyExpressionEventCollCache, bool allowRollupFunctions, bool allowBindingConsumption, bool isUnidirectionalJoin, string intoTableName, bool isFilterExpression) { StreamTypeService = streamTypeService; EngineImportService = engineImportService; StatementExtensionSvcContext = statementExtensionSvcContext; ViewResourceDelegate = viewResourceDelegate; TimeProvider = timeProvider; VariableService = variableService; TableService = tableService; ExprEvaluatorContext = exprEvaluatorContext; EventAdapterService = eventAdapterService; StatementName = statementName; StatementId = statementId; Annotations = annotations; ContextDescriptor = contextDescriptor; ScriptingService = scriptingService; IsDisablePropertyExpressionEventCollCache = disablePropertyExpressionEventCollCache; IsAllowRollupFunctions = allowRollupFunctions; IsAllowBindingConsumption = allowBindingConsumption; IsResettingAggregations = isUnidirectionalJoin; IntoTableName = intoTableName; IsFilterExpression = isFilterExpression; IsExpressionAudit = AuditEnum.EXPRESSION.GetAudit(annotations) != null; IsExpressionNestedAudit = AuditEnum.EXPRESSION_NESTED.GetAudit(annotations) != null; }
public EPStatementStartMethodSelectDesc( StatementAgentInstanceFactorySelect statementAgentInstanceFactorySelect, SubSelectStrategyCollection subSelectStrategyCollection, ViewResourceDelegateUnverified viewResourceDelegateUnverified, ResultSetProcessorFactoryDesc resultSetProcessorPrototypeDesc, EPStatementStopMethod stopMethod, EPStatementDestroyCallbackList destroyCallbacks) { StatementAgentInstanceFactorySelect = statementAgentInstanceFactorySelect; SubSelectStrategyCollection = subSelectStrategyCollection; ViewResourceDelegateUnverified = viewResourceDelegateUnverified; ResultSetProcessorPrototypeDesc = resultSetProcessorPrototypeDesc; StopMethod = stopMethod; DestroyCallbacks = destroyCallbacks; }
public static void Validate3Stream(ExprNode topNode) { var supportContainer = SupportContainer.Instance; var streamTypeService = new SupportStreamTypeSvc3Stream(); var factoriesPerStream = new ViewFactoryChain[3]; for (var i = 0; i < factoriesPerStream.Length; i++) { var factories = new List <ViewFactory>(); factories.Add(new LengthWindowViewFactory()); factoriesPerStream[i] = new ViewFactoryChain(streamTypeService.EventTypes[i], factories); } var viewResources = new ViewResourceDelegateUnverified(); EngineImportService engineImportService = SupportEngineImportServiceFactory.Make(supportContainer); VariableService variableService = new VariableServiceImpl( supportContainer, 0, new SchedulingServiceImpl(new TimeSourceServiceImpl(), supportContainer), SupportContainer.Resolve <EventAdapterService>(), null); variableService.CreateNewVariable(null, "IntPrimitive", typeof(int?).FullName, false, false, false, 10, engineImportService); variableService.AllocateVariableState("IntPrimitive", EPStatementStartMethodConst.DEFAULT_AGENT_INSTANCE_ID, null, false); variableService.CreateNewVariable(null, "var1", typeof(string).FullName, false, false, false, "my_variable_value", engineImportService); variableService.AllocateVariableState("var1", EPStatementStartMethodConst.DEFAULT_AGENT_INSTANCE_ID, null, false); ExprNodeUtility.GetValidatedSubtree( ExprNodeOrigin.SELECT, topNode, new ExprValidationContext( supportContainer, streamTypeService, SupportEngineImportServiceFactory.Make(supportContainer), null, viewResources, null, variableService, null, new SupportExprEvaluatorContext(supportContainer, null), null, null, 1, null, null, null, false, false, false, false, null, false)); }
public static ViewResourceDelegateVerified VerifyPreviousAndPriorRequirements(ViewFactoryChain[] unmaterializedViewChain, ViewResourceDelegateUnverified @delegate) { var hasPriorNodes = [email protected](); var hasPreviousNodes = [email protected](); var numStreams = unmaterializedViewChain.Length; var perStream = new ViewResourceDelegateVerifiedStream[numStreams]; // verify "previous" var previousPerStream = new IList <ExprPreviousNode> [numStreams]; foreach (var previousNode in @delegate.PreviousRequests) { var stream = previousNode.StreamNumber; var factories = unmaterializedViewChain[stream].FactoryChain; var pass = InspectViewFactoriesForPrevious(factories); if (!pass) { throw new ExprValidationException("Previous function requires a single data window view onto the stream"); } var found = factories.OfType <DataWindowViewWithPrevious>().Any(); if (!found) { throw new ExprValidationException("Required data window not found for the 'prev' function, specify a data window for which previous events are retained"); } if (previousPerStream[stream] == null) { previousPerStream[stream] = new List <ExprPreviousNode>(); } previousPerStream[stream].Add(previousNode); } // verify "prior" var priorPerStream = new IDictionary <int, IList <ExprPriorNode> > [numStreams]; foreach (var priorNode in @delegate.PriorRequests) { var stream = priorNode.StreamNumber; if (priorPerStream[stream] == null) { priorPerStream[stream] = new SortedDictionary <int, IList <ExprPriorNode> >(); } var treemap = priorPerStream[stream]; var callbackList = treemap.Get(priorNode.ConstantIndexNumber); if (callbackList == null) { callbackList = new List <ExprPriorNode>(); treemap.Put(priorNode.ConstantIndexNumber, callbackList); } callbackList.Add(priorNode); } // build per-stream info for (var i = 0; i < numStreams; i++) { if (previousPerStream[i] == null) { previousPerStream[i] = Collections.GetEmptyList <ExprPreviousNode>(); } if (priorPerStream[i] == null) { priorPerStream[i] = new OrderedDictionary <int, IList <ExprPriorNode> >(); } // determine match-recognize "prev" var matchRecognizePrevious = Collections.GetEmptySet <ExprPreviousMatchRecognizeNode>(); if (i == 0) { foreach (var viewFactory in unmaterializedViewChain[i].FactoryChain) { if (viewFactory is EventRowRegexNFAViewFactory) { var matchRecognize = (EventRowRegexNFAViewFactory)viewFactory; matchRecognizePrevious = matchRecognize.PreviousExprNodes; } } } perStream[i] = new ViewResourceDelegateVerifiedStream(previousPerStream[i], priorPerStream[i], matchRecognizePrevious); } return(new ViewResourceDelegateVerified(hasPriorNodes, hasPreviousNodes, perStream)); }
/// <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); } } } } } }
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)); }
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"); } } } } } }
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)); }