public JoinSetComposerDesc Create( Viewable[] streamViews, bool isFireAndForget, AgentInstanceContext agentInstanceContext) { var queryStrategies = new QueryStrategy[_streamTypes.Length]; var viewable = (HistoricalEventViewable)streamViews[_polledViewNum]; var outerJoinEqualsNodeEval = _outerJoinEqualsNode == null ? null : _outerJoinEqualsNode.ExprEvaluator; queryStrategies[_streamViewNum] = new HistoricalDataQueryStrategy( _streamViewNum, _polledViewNum, viewable, _isOuterJoin, outerJoinEqualsNodeEval, _indexStrategies.First, _indexStrategies.Second); // for strictly historical joins, create a query strategy for the non-subordinate historical view if (_isAllHistoricalNoSubordinate) { var isOuterJoin = false; if (_outerJoinDescList.Length > 0) { var outerJoinDesc = _outerJoinDescList[0]; if (outerJoinDesc.OuterJoinType.Equals(OuterJoinType.FULL)) { isOuterJoin = true; } else if ((outerJoinDesc.OuterJoinType.Equals(OuterJoinType.LEFT)) && (_polledViewNum == 0)) { isOuterJoin = true; } else if ((outerJoinDesc.OuterJoinType.Equals(OuterJoinType.RIGHT)) && (_polledViewNum == 1)) { isOuterJoin = true; } } viewable = (HistoricalEventViewable)streamViews[_streamViewNum]; queryStrategies[_polledViewNum] = new HistoricalDataQueryStrategy( _polledViewNum, _streamViewNum, viewable, isOuterJoin, outerJoinEqualsNodeEval, new HistoricalIndexLookupStrategyNoIndex(), new PollResultIndexingStrategyNoIndex()); } JoinSetComposer composer = new JoinSetComposerHistoricalImpl( null, queryStrategies, streamViews, _exprEvaluatorContext); var postJoinEval = _optionalFilterNode == null ? null : _optionalFilterNode.ExprEvaluator; return(new JoinSetComposerDesc(composer, postJoinEval)); }
public JoinSetComposerDesc Create(Viewable[] streamViews, bool isFireAndForget, AgentInstanceContext agentInstanceContext) { // Build indexes var indexesPerStream = new IDictionary <TableLookupIndexReqKey, EventTable> [_indexSpecs.Length]; var tableSecondaryIndexLocks = new ILockable[_indexSpecs.Length]; var hasTable = false; for (var streamNo = 0; streamNo < _indexSpecs.Length; streamNo++) { if (_indexSpecs[streamNo] == null) { continue; } var items = _indexSpecs[streamNo].Items; indexesPerStream[streamNo] = new LinkedHashMap <TableLookupIndexReqKey, EventTable>(); if (_streamJoinAnalysisResult.TablesPerStream[streamNo] != null) { // build for tables var metadata = _streamJoinAnalysisResult.TablesPerStream[streamNo]; var state = _tableService.GetState(metadata.TableName, agentInstanceContext.AgentInstanceId); foreach (var indexName in state.SecondaryIndexes) // add secondary indexes { var eventTable = state.GetIndex(indexName); indexesPerStream[streamNo].Put(new TableLookupIndexReqKey(indexName, metadata.TableName), eventTable); } var index = state.GetIndex(metadata.TableName); // add primary index indexesPerStream[streamNo].Put(new TableLookupIndexReqKey(metadata.TableName, metadata.TableName), index); hasTable = true; tableSecondaryIndexLocks[streamNo] = agentInstanceContext.StatementContext.IsWritesToTables ? state.TableLevelRWLock.WriteLock : state.TableLevelRWLock.ReadLock; } else { // build tables for implicit indexes foreach (var entry in items) { EventTable index; if (_streamJoinAnalysisResult.ViewExternal[streamNo] != null) { var view = _streamJoinAnalysisResult.ViewExternal[streamNo].Invoke(agentInstanceContext); index = view.GetJoinIndexTable(items.Get(entry.Key)); } else { index = EventTableUtil.BuildIndex(streamNo, items.Get(entry.Key), _streamTypes[streamNo], false, entry.Value.IsUnique, null); } indexesPerStream[streamNo].Put(entry.Key, index); } } } // obtain any external views var externalViewProviders = _streamJoinAnalysisResult.ViewExternal; var externalViews = new VirtualDWView[externalViewProviders.Length]; for (var i = 0; i < externalViews.Length; i++) { if (externalViewProviders[i] != null) { externalViews[i] = _streamJoinAnalysisResult.ViewExternal[i].Invoke(agentInstanceContext); } } // Build strategies var queryExecSpecs = _queryPlan.ExecNodeSpecs; var queryStrategies = new QueryStrategy[queryExecSpecs.Length]; for (var i = 0; i < queryExecSpecs.Length; i++) { var planNode = queryExecSpecs[i]; if (planNode == null) { Log.Debug(".makeComposer No execution node for stream " + i + " '" + _streamNames[i] + "'"); continue; } var executionNode = planNode.MakeExec(_statementName, _statementId, _annotations, indexesPerStream, _streamTypes, streamViews, _historicalStreamIndexLists, externalViews, tableSecondaryIndexLocks); if (Log.IsDebugEnabled) { Log.Debug(".makeComposer Execution nodes for stream " + i + " '" + _streamNames[i] + "' : \n" + ExecNode.Print(executionNode)); } queryStrategies[i] = new ExecNodeQueryStrategy(i, _streamTypes.Length, executionNode); } // Remove indexes that are from tables as these are only available to query strategies if (hasTable) { indexesPerStream = RemoveTableIndexes(indexesPerStream, _streamJoinAnalysisResult.TablesPerStream); } // If this is not unidirectional and not a self-join (excluding self-outer-join) JoinSetComposerDesc joinSetComposerDesc; if ((!_streamJoinAnalysisResult.IsUnidirectional) && (!_streamJoinAnalysisResult.IsPureSelfJoin || _outerJoinDescList.Length > 0)) { JoinSetComposer composer; if (_historicalViewableDesc.HasHistorical) { composer = new JoinSetComposerHistoricalImpl(indexesPerStream, queryStrategies, streamViews, _exprEvaluatorContext); } else { if (isFireAndForget) { composer = new JoinSetComposerFAFImpl(indexesPerStream, queryStrategies, _streamJoinAnalysisResult.IsPureSelfJoin, _exprEvaluatorContext, _joinRemoveStream, _isOuterJoins); } else { composer = new JoinSetComposerImpl(indexesPerStream, queryStrategies, _streamJoinAnalysisResult.IsPureSelfJoin, _exprEvaluatorContext, _joinRemoveStream); } } // rewrite the filter expression for all-inner joins in case "on"-clause outer join syntax was used to include those expressions var filterExpression = GetFilterExpressionInclOnClause(_optionalFilterNode, _outerJoinDescList); var postJoinEval = filterExpression == null ? null : filterExpression.ExprEvaluator; joinSetComposerDesc = new JoinSetComposerDesc(composer, postJoinEval); } else { QueryStrategy driver; int unidirectionalStream; if (_streamJoinAnalysisResult.UnidirectionalStreamNumber != -1) { unidirectionalStream = _streamJoinAnalysisResult.UnidirectionalStreamNumber; driver = queryStrategies[unidirectionalStream]; } else { unidirectionalStream = 0; driver = queryStrategies[0]; } JoinSetComposer composer = new JoinSetComposerStreamToWinImpl(indexesPerStream, _streamJoinAnalysisResult.IsPureSelfJoin, unidirectionalStream, driver, _streamJoinAnalysisResult.UnidirectionalNonDriving); var postJoinEval = _optionalFilterNode == null ? null : _optionalFilterNode.ExprEvaluator; joinSetComposerDesc = new JoinSetComposerDesc(composer, postJoinEval); } // compile prior events per stream to preload any indexes var eventsPerStream = new EventBean[_streamNames.Length][]; var events = new List <EventBean>(); for (var i = 0; i < eventsPerStream.Length; i++) { // For named windows and tables, we don't need to preload indexes from the iterators as this is always done already if (_streamJoinAnalysisResult.NamedWindow[i] || _streamJoinAnalysisResult.TablesPerStream[i] != null) { continue; } IEnumerator <EventBean> en = null; if (!(streamViews[i] is HistoricalEventViewable) && !(streamViews[i] is DerivedValueView)) { try { en = streamViews[i].GetEnumerator(); } catch (UnsupportedOperationException) { // Joins do not support the iterator } } if (en != null) { while (en.MoveNext()) { events.Add(en.Current); } eventsPerStream[i] = events.ToArray(); events.Clear(); } else { eventsPerStream[i] = new EventBean[0]; } } // init joinSetComposerDesc.JoinSetComposer.Init(eventsPerStream); return(joinSetComposerDesc); }