Exemple #1
0
        public static QueryPlanForgeDesc Build(
            QueryGraphForge queryGraph,
            EventType[] typesPerStream,
            HistoricalViewableDesc historicalViewableDesc,
            DependencyGraph dependencyGraph,
            HistoricalStreamIndexListForge[] historicalStreamIndexLists,
            bool hasForceNestedIter,
            string[][][] indexedStreamsUniqueProps,
            TableMetaData[] tablesPerStream,
            StreamJoinAnalysisResultCompileTime streamJoinAnalysisResult,
            StatementRawInfo raw,
            SerdeCompileTimeResolver serdeResolver)
        {
            if (Log.IsDebugEnabled) {
                Log.Debug(".build filterQueryGraph=" + queryGraph);
            }

            var numStreams = queryGraph.NumStreams;
            var additionalForgeables = new List<StmtClassForgeableFactory>();   
            var indexSpecs = QueryPlanIndexBuilder.BuildIndexSpec(
                queryGraph,
                typesPerStream,
                indexedStreamsUniqueProps);
            if (Log.IsDebugEnabled) {
                Log.Debug(".build Index build completed, indexes=" + QueryPlanIndexForge.Print(indexSpecs));
            }

            // any historical streams don't get indexes, the lookup strategy accounts for cached indexes
            if (historicalViewableDesc.IsHistorical) {
                for (var i = 0; i < historicalViewableDesc.Historical.Length; i++) {
                    if (historicalViewableDesc.Historical[i]) {
                        indexSpecs[i] = null;
                    }
                }
            }

            var planNodeSpecs = new QueryPlanNodeForge[numStreams];
            var worstDepth = int.MaxValue;
            for (var streamNo = 0; streamNo < numStreams; streamNo++) {
                // no plan for historical streams that are dependent upon other streams
                if (historicalViewableDesc.Historical[streamNo] && dependencyGraph.HasDependency(streamNo)) {
                    planNodeSpecs[streamNo] = new QueryPlanNodeNoOpForge();
                    continue;
                }

                var bestChainResult = ComputeBestPath(streamNo, queryGraph, dependencyGraph);
                var bestChain = bestChainResult.Chain;
                if (Log.IsDebugEnabled) {
                    Log.Debug(".build For stream " + streamNo + " bestChain=" + bestChain.RenderAny());
                }

                if (bestChainResult.Depth < worstDepth) {
                    worstDepth = bestChainResult.Depth;
                }

                var planDesc = CreateStreamPlan(
                    streamNo,
                    bestChain,
                    queryGraph,
                    indexSpecs,
                    typesPerStream,
                    historicalViewableDesc.Historical,
                    historicalStreamIndexLists,
                    tablesPerStream,
                    streamJoinAnalysisResult,
                    raw,
                    serdeResolver);

                planNodeSpecs[streamNo] = planDesc.Forge;
                additionalForgeables.AddAll(planDesc.AdditionalForgeables);
                
                if (Log.IsDebugEnabled) {
                    Log.Debug(".build spec=" + planNodeSpecs[streamNo]);
                }
            }

            // We use the merge/nested (outer) join algorithm instead.
            if (worstDepth < numStreams - 1 && !hasForceNestedIter) {
                return null;
            }

            // build historical index and lookup strategies
            for (var i = 0; i < numStreams; i++) {
                var plan = planNodeSpecs[i];
                QueryPlanNodeForgeVisitor visitor = new ProxyQueryPlanNodeForgeVisitor {
                    ProcVisit = node => {
                        if (node is HistoricalDataPlanNodeForge) {
                            var historical = (HistoricalDataPlanNodeForge) node;
                            JoinSetComposerPrototypeHistoricalDesc desc = historicalStreamIndexLists[historical.StreamNum].GetStrategy(
                                historical.LookupStreamNum, raw, serdeResolver);
                            historical.PollResultIndexingStrategy = desc.IndexingForge;
                            historical.HistoricalIndexLookupStrategy = desc.LookupForge;
                            additionalForgeables.AddAll(desc.AdditionalForgeables);
                        }
                    }
                };
                plan.Accept(visitor);
            }

            var forge = new QueryPlanForge(indexSpecs, planNodeSpecs);
            return new QueryPlanForgeDesc(forge, additionalForgeables);
        }
        internal static QueryPlanForgeDesc Build(
            QueryGraphForge queryGraph,
            OuterJoinDesc[] outerJoinDescList,
            string[] streamNames,
            EventType[] typesPerStream,
            HistoricalViewableDesc historicalViewableDesc,
            DependencyGraph dependencyGraph,
            HistoricalStreamIndexListForge[] historicalStreamIndexLists,
            string[][][] indexedStreamsUniqueProps,
            TableMetaData[] tablesPerStream,
            StreamJoinAnalysisResultCompileTime streamJoinAnalysisResult,
            StatementRawInfo statementRawInfo,
            StatementCompileTimeServices services)
        {
            if (Log.IsDebugEnabled) {
                Log.Debug(".build filterQueryGraph=" + queryGraph);
            }

            var numStreams = queryGraph.NumStreams;
            var planNodeSpecs = new QueryPlanNodeForge[numStreams];
            var additionalForgeables = new List<StmtClassForgeableFactory>();

            // Build index specifications
            var indexSpecs = QueryPlanIndexBuilder.BuildIndexSpec(
                queryGraph,
                typesPerStream,
                indexedStreamsUniqueProps);

            // any historical streams don't get indexes, the lookup strategy accounts for cached indexes
            if (historicalViewableDesc.IsHistorical) {
                for (var i = 0; i < historicalViewableDesc.Historical.Length; i++) {
                    if (historicalViewableDesc.Historical[i]) {
                        indexSpecs[i] = null;
                    }
                }
            }

            // Build graph of the outer join to inner table relationships.
            // Build a map of inner joins.
            OuterInnerDirectionalGraph outerInnerGraph;
            InnerJoinGraph innerJoinGraph;
            if (outerJoinDescList.Length > 0) {
                outerInnerGraph = GraphOuterJoins(numStreams, outerJoinDescList);
                innerJoinGraph = InnerJoinGraph.GraphInnerJoins(numStreams, outerJoinDescList);
            }
            else {
                // all inner joins - thereby no (or empty) directional graph
                outerInnerGraph = new OuterInnerDirectionalGraph(numStreams);
                innerJoinGraph = new InnerJoinGraph(numStreams, true);
            }

            if (Log.IsDebugEnabled) {
                Log.Debug(".build directional graph=" + outerInnerGraph.Print());
            }

            // For each stream determine the query plan
            for (var streamNo = 0; streamNo < numStreams; streamNo++) {
                // no plan for historical streams that are dependent upon other streams
                if (historicalViewableDesc.Historical[streamNo] && dependencyGraph.HasDependency(streamNo)) {
                    planNodeSpecs[streamNo] = new QueryPlanNodeNoOpForge();
                    continue;
                }

                QueryPlanNodeForgeDesc desc = BuildPlanNode(
                    numStreams,
                    streamNo,
                    streamNames,
                    queryGraph,
                    outerInnerGraph,
                    outerJoinDescList,
                    innerJoinGraph,
                    indexSpecs,
                    typesPerStream,
                    historicalViewableDesc.Historical,
                    dependencyGraph,
                    historicalStreamIndexLists,
                    tablesPerStream,
                    streamJoinAnalysisResult,
                    statementRawInfo,
                    services);
                QueryPlanNodeForge queryPlanNode = desc.Forge;
                additionalForgeables.AddAll(desc.AdditionalForgeables);

                if (Log.IsDebugEnabled) {
                    Log.Debug(
                        ".build spec for stream '" +
                        streamNames[streamNo] +
                        "' number " +
                        streamNo +
                        " is " +
                        queryPlanNode);
                }

                planNodeSpecs[streamNo] = queryPlanNode;
            }

            var queryPlan = new QueryPlanForge(indexSpecs, planNodeSpecs);
            if (Log.IsDebugEnabled) {
                Log.Debug(".build query plan=" + queryPlan);
            }

            return new QueryPlanForgeDesc(queryPlan, additionalForgeables);
        }