Пример #1
0
        /// <summary>
        /// Recursive method to run through all child nodes and, for each result set tuple returned
        /// by a child node, execute the inner child of the child node until there are no inner child nodes.
        /// </summary>
        /// <param name="lookupEvent">current event to use for lookup by child node</param>
        /// <param name="nestingOrderIndex">index within the child nodes indicating what nesting level we are at</param>
        /// <param name="currentPath">prototype result row to use by child nodes for generating result rows</param>
        /// <param name="result">result tuple rows to be populated</param>
        /// <param name="exprEvaluatorContext">context for expression evalauation</param>
        protected void RecursiveNestedJoin(
            EventBean lookupEvent,
            int nestingOrderIndex,
            EventBean[] currentPath,
            ICollection<EventBean[]> result,
            ExprEvaluatorContext exprEvaluatorContext)
        {
            IList<EventBean[]> nestedResult = new List<EventBean[]>();
            ExecNode nestedExecNode = childNodes[nestingOrderIndex];
            nestedExecNode.Process(lookupEvent, currentPath, nestedResult, exprEvaluatorContext);
            bool isLastStream = nestingOrderIndex == nestingOrderLength - 1;

            // This is not the last nesting level so no result rows are added. Invoke next nesting level for
            // each event found.
            if (!isLastStream) {
                foreach (EventBean[] row in nestedResult) {
                    EventBean lookup = row[nestedStreams[nestingOrderIndex]];
                    RecursiveNestedJoin(lookup, nestingOrderIndex + 1, row, result, exprEvaluatorContext);
                }

                return;
            }

            // Loop to add result rows
            foreach (EventBean[] row in nestedResult) {
                result.Add(row);
            }
        }
Пример #2
0
        public void Lookup(EventBean[] lookupEvents, ICollection <MultiKey <EventBean> > joinSet, ExprEvaluatorContext exprEvaluatorContext)
        {
            if ((lookupEvents != null) && (lookupEvents.Length != 0))
            {
                unchecked
                {
                    var results = new List <EventBean[]>();
                    int count   = lookupEvents.Length;
                    for (int ii = 0; ii < count; ii++)
                    {
                        var theEvent  = lookupEvents[ii];
                        var prototype = new EventBean[NumStreams];

                        // Set up _prototype row
                        prototype[ForStream] = theEvent;

                        // Perform execution
                        ExecNode.Process(theEvent, prototype, results, exprEvaluatorContext);

                        // Convert results into unique set
                        results.ForEach(row => joinSet.Add(new MultiKey <EventBean>(row)));
                        results.Clear();
                    }
                }
            }
        }
Пример #3
0
        public override ExecNode MakeExec(
            string statementName,
            string statementId,
            Attribute[] annotations,
            IDictionary <TableLookupIndexReqKey, EventTable>[] indexPerStream,
            EventType[] streamTypes,
            Viewable[] streamViews,
            HistoricalStreamIndexList[] historicalStreamIndexList,
            VirtualDWView[] viewExternal,
            ILockable[] tableSecondaryIndexLocks)
        {
            if (_childNodes.IsEmpty())
            {
                throw new IllegalStateException("Zero child nodes for nested iteration");
            }

            var execNode = new NestedIterationExecNode(_nestingOrder);

            foreach (QueryPlanNode child in _childNodes)
            {
                ExecNode childExec = child.MakeExec(
                    statementName, statementId, annotations, indexPerStream, streamTypes, streamViews,
                    historicalStreamIndexList, viewExternal, tableSecondaryIndexLocks);
                execNode.AddChildNode(childExec);
            }
            return(execNode);
        }
        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);
        }
Пример #5
0
 /// <summary>
 /// Add a child node.
 /// </summary>
 /// <param name="childNode">to add</param>
 public void AddChildNode(ExecNode childNode)
 {
     childNodes.Add(childNode);
 }
Пример #6
0
 /// <summary>CTor. </summary>
 /// <param name="forStream">stream the strategy is for</param>
 /// <param name="numStreams">number of streams in total</param>
 /// <param name="execNode">execution node for building join tuple set</param>
 public ExecNodeQueryStrategy(int forStream, int numStreams, ExecNode execNode)
 {
     ForStream  = forStream;
     NumStreams = numStreams;
     ExecNode   = execNode;
 }