/// <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.LoggingConfig.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 _filters = new FilterSpecCompiled[numStreams]; if (statementSpec.FilterRootNode != null) { var tagged = new LinkedHashMap <string, Pair <EventType, string> >(); for (var i = 0; i < numStreams; i++) { try { var types = new StreamTypeServiceImpl(typesPerStream, namesPerStream, new bool[numStreams], services.EngineURI, false); _filters[i] = FilterSpecCompiler.MakeFilterSpec(typesPerStream[i], namesPerStream[i], Collections.SingletonList(statementSpec.FilterRootNode), null, tagged, tagged, types, null, statementContext, Collections.SingletonList(i)); } 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).GetReader(); } 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> /// Executes the prepared query. /// </summary> /// <returns>query results</returns> public EPPreparedQueryResult Execute(ContextPartitionSelector[] contextPartitionSelectors) { try { if (contextPartitionSelectors != null && contextPartitionSelectors.Length != 1) { throw new ArgumentException("Number of context partition selectors must be one"); } var optionalSingleSelector = contextPartitionSelectors != null && contextPartitionSelectors.Length > 0 ? contextPartitionSelectors[0] : null; // validate context if (Processor.ContextName != null && StatementSpec.OptionalContextName != null && !Processor.ContextName.Equals(StatementSpec.OptionalContextName)) { throw new EPException("Context for named window is '" + Processor.ContextName + "' and query specifies context '" + StatementSpec.OptionalContextName + "'"); } // handle non-specified context if (StatementSpec.OptionalContextName == null) { FireAndForgetInstance processorInstance = Processor.GetProcessorInstanceNoContext(); if (processorInstance != null) { var rows = Executor.Execute(processorInstance); if (rows != null && rows.Length > 0) { Dispatch(); } return(new EPPreparedQueryResult(Processor.EventTypePublic, rows)); } } // context partition runtime query var agentInstanceIds = EPPreparedExecuteMethodHelper.GetAgentInstanceIds(Processor, optionalSingleSelector, Services.ContextManagementService, Processor.ContextName); // collect events and agent instances if (agentInstanceIds.IsEmpty()) { return(new EPPreparedQueryResult(Processor.EventTypeResultSetProcessor, CollectionUtil.EVENTBEANARRAY_EMPTY)); } if (agentInstanceIds.Count == 1) { int agentInstanceId = agentInstanceIds.First(); var processorInstance = Processor.GetProcessorInstanceContextById(agentInstanceId); var rows = Executor.Execute(processorInstance); if (rows.Length > 0) { Dispatch(); } return(new EPPreparedQueryResult(Processor.EventTypeResultSetProcessor, rows)); } var allRows = new ArrayDeque <EventBean>(); foreach (int agentInstanceId in agentInstanceIds) { var processorInstance = Processor.GetProcessorInstanceContextById(agentInstanceId); if (processorInstance != null) { var rows = Executor.Execute(processorInstance); allRows.AddAll(rows); } } if (allRows.Count > 0) { Dispatch(); } return(new EPPreparedQueryResult(Processor.EventTypeResultSetProcessor, allRows.ToArray())); } finally { if (HasTableAccess) { Services.TableService.TableExprEvaluatorContext.ReleaseAcquiredLocks(); } } }
/// <summary> /// Executes the prepared query. /// </summary> /// <returns>query results</returns> public EPPreparedQueryResult Execute(ContextPartitionSelector[] contextPartitionSelectors) { try { var numStreams = _processors.Length; if (contextPartitionSelectors != null && contextPartitionSelectors.Length != numStreams) { throw new ArgumentException("Number of context partition selectors does not match the number of named windows in the from-clause"); } // handle non-context case if (_statementSpec.OptionalContextName == null) { ICollection <EventBean>[] snapshots = new ICollection <EventBean> [numStreams]; for (var i = 0; i < numStreams; i++) { var selector = contextPartitionSelectors == null ? null : contextPartitionSelectors[i]; snapshots[i] = GetStreamFilterSnapshot(i, selector); } _resultSetProcessor.Clear(); return(Process(snapshots)); } IList <ContextPartitionResult> contextPartitionResults = new List <ContextPartitionResult>(); var singleSelector = contextPartitionSelectors != null && contextPartitionSelectors.Length > 0 ? contextPartitionSelectors[0] : null; // context partition runtime query ICollection <int> agentInstanceIds = EPPreparedExecuteMethodHelper.GetAgentInstanceIds( _processors[0], singleSelector, _services.ContextManagementService, _statementSpec.OptionalContextName); // collect events and agent instances foreach (int agentInstanceId in agentInstanceIds) { var processorInstance = _processors[0].GetProcessorInstanceContextById(agentInstanceId); if (processorInstance != null) { EPPreparedExecuteTableHelper.AssignTableAccessStrategies(_services, _statementSpec.TableNodes, processorInstance.AgentInstanceContext); var coll = processorInstance.SnapshotBestEffort(this, _filters[0], _statementSpec.Annotations); contextPartitionResults.Add(new ContextPartitionResult(coll, processorInstance.AgentInstanceContext)); } } // process context partitions var events = new ArrayDeque <EventBean[]>(); foreach (var contextPartitionResult in contextPartitionResults) { var snapshot = contextPartitionResult.Events; if (_statementSpec.FilterRootNode != null) { snapshot = GetFiltered(snapshot, Collections.SingletonList(_statementSpec.FilterRootNode)); } EventBean[] rows; var snapshotAsArrayDeque = snapshot as ArrayDeque <EventBean>; if (snapshotAsArrayDeque != null) { rows = snapshotAsArrayDeque.Array; } else { rows = snapshot.ToArray(); } _resultSetProcessor.AgentInstanceContext = contextPartitionResult.Context; var results = _resultSetProcessor.ProcessViewResult(rows, null, true); if (results != null && results.First != null && results.First.Length > 0) { events.Add(results.First); } } return(new EPPreparedQueryResult(_resultSetProcessor.ResultEventType, EventBeanUtility.Flatten(events))); } finally { if (_hasTableAccess) { _services.TableService.TableExprEvaluatorContext.ReleaseAcquiredLocks(); } } }