public void TestBuildNoOuter() { QueryGraph graph = MakeQueryGraph(); QueryPlan spec = TwoStreamQueryPlanBuilder.Build(_typesPerStream, graph, null, new String[2][][], new TableMetadata[2]); EPAssertionUtil.AssertEqualsExactOrder(spec.IndexSpecs[0].IndexProps[0], new String[] { "P01", "P02" }); EPAssertionUtil.AssertEqualsExactOrder(spec.IndexSpecs[1].IndexProps[0], new String[] { "P11", "P12" }); Assert.AreEqual(2, spec.ExecNodeSpecs.Length); }
// Remove plans for non-unidirectional streams private static void RemoveUnidirectionalAndTable(QueryPlan queryPlan, StreamJoinAnalysisResult streamJoinAnalysisResult) { for (int streamNum = 0; streamNum < queryPlan.ExecNodeSpecs.Length; streamNum++) { bool unidirectional = streamJoinAnalysisResult.IsUnidirectional && !streamJoinAnalysisResult.UnidirectionalInd[streamNum]; bool table = streamJoinAnalysisResult.TablesPerStream[streamNum] != null; if (unidirectional || table) { queryPlan.ExecNodeSpecs[streamNum] = new QueryPlanNodeNoOp(); } } }
/// <summary> /// Build query plan using the filter. /// </summary> /// <param name="typesPerStream">event types for each stream</param> /// <param name="outerJoinDescList">list of outer join criteria, or null if there are no outer joins</param> /// <param name="queryGraph">relationships between streams based on filter expressions and outer-join on-criteria</param> /// <param name="streamNames">names of streams</param> /// <param name="historicalViewableDesc">The historical viewable desc.</param> /// <param name="dependencyGraph">dependencies between historical streams</param> /// <param name="historicalStreamIndexLists">index management, populated for the query plan</param> /// <param name="streamJoinAnalysisResult">The stream join analysis result.</param> /// <param name="isQueryPlanLogging">if set to <c>true</c> [is query plan logging].</param> /// <param name="annotations">The annotations.</param> /// <param name="exprEvaluatorContext">The expr evaluator context.</param> /// <returns> /// query plan /// </returns> /// <exception cref="System.ArgumentException"> /// Number of join stream types is less then 2 /// or /// Too many outer join descriptors found /// </exception> /// <throws>ExprValidationException if the query plan fails</throws> public static QueryPlan GetPlan(EventType[] typesPerStream, OuterJoinDesc[] outerJoinDescList, QueryGraph queryGraph, string[] streamNames, HistoricalViewableDesc historicalViewableDesc, DependencyGraph dependencyGraph, HistoricalStreamIndexList[] historicalStreamIndexLists, StreamJoinAnalysisResult streamJoinAnalysisResult, bool isQueryPlanLogging, Attribute[] annotations, ExprEvaluatorContext exprEvaluatorContext) { string methodName = ".getPlan "; int numStreams = typesPerStream.Length; if (numStreams < 2) { throw new ArgumentException("Number of join stream types is less then 2"); } if (outerJoinDescList.Length >= numStreams) { throw new ArgumentException("Too many outer join descriptors found"); } if (numStreams == 2) { OuterJoinType?outerJoinType = null; if (outerJoinDescList.Length > 0) { outerJoinType = outerJoinDescList[0].OuterJoinType; } QueryPlan queryPlanX = TwoStreamQueryPlanBuilder.Build(typesPerStream, queryGraph, outerJoinType, streamJoinAnalysisResult.UniqueKeys, streamJoinAnalysisResult.TablesPerStream); RemoveUnidirectionalAndTable(queryPlanX, streamJoinAnalysisResult); if (log.IsDebugEnabled) { log.Debug(methodName + "2-Stream queryPlan=" + queryPlanX); } return(queryPlanX); } bool hasPreferMergeJoin = HintEnum.PREFER_MERGE_JOIN.GetHint(annotations) != null; bool hasForceNestedIter = HintEnum.FORCE_NESTED_ITER.GetHint(annotations) != null; bool isAllInnerJoins = outerJoinDescList.Length == 0 || OuterJoinDesc.ConsistsOfAllInnerJoins(outerJoinDescList); if (isAllInnerJoins && !hasPreferMergeJoin) { QueryPlan queryPlanX = NStreamQueryPlanBuilder.Build(queryGraph, typesPerStream, historicalViewableDesc, dependencyGraph, historicalStreamIndexLists, hasForceNestedIter, streamJoinAnalysisResult.UniqueKeys, streamJoinAnalysisResult.TablesPerStream); if (queryPlanX != null) { RemoveUnidirectionalAndTable(queryPlanX, streamJoinAnalysisResult); if (log.IsDebugEnabled) { log.Debug(methodName + "Count-Stream inner-join queryPlan=" + queryPlanX); } return(queryPlanX); } if (isQueryPlanLogging && queryPlanLog.IsInfoEnabled) { log.Info("Switching to Outer-NStream algorithm for query plan"); } } QueryPlan queryPlan = NStreamOuterQueryPlanBuilder.Build(queryGraph, outerJoinDescList, streamNames, typesPerStream, historicalViewableDesc, dependencyGraph, historicalStreamIndexLists, exprEvaluatorContext, streamJoinAnalysisResult.UniqueKeys, streamJoinAnalysisResult.TablesPerStream); RemoveUnidirectionalAndTable(queryPlan, streamJoinAnalysisResult); return(queryPlan); }
public void TestBuild() { QueryPlan plan = NStreamQueryPlanBuilder.Build(_queryGraph, _typesPerStream, new HistoricalViewableDesc(6), _dependencyGraph, null, false, new string[_queryGraph.NumStreams][][], new TableMetadata[_queryGraph.NumStreams]); Log.Debug(".testBuild plan=" + plan); }
private void AssertPlan(QueryPlan plan) { Assert.AreEqual(2, plan.ExecNodeSpecs.Length); Assert.AreEqual(2, plan.ExecNodeSpecs.Length); }
/// <summary> /// Build a query plan based on the stream property relationships indicated in queryGraph. /// </summary> /// <param name="queryGraph">navigation info between streams</param> /// <param name="outerJoinDescList">descriptors for all outer joins</param> /// <param name="streamNames">stream names</param> /// <param name="typesPerStream">event types for each stream</param> /// <param name="historicalViewableDesc">The historical viewable desc.</param> /// <param name="dependencyGraph">dependencies between historical streams</param> /// <param name="historicalStreamIndexLists">index management, populated for the query plan</param> /// <param name="exprEvaluatorContext">context for expression evalauation</param> /// <param name="indexedStreamsUniqueProps">The indexed streams unique props.</param> /// <param name="tablesPerStream">The tables per stream.</param> /// <returns> /// query plan /// </returns> /// <throws>ExprValidationException if the query planning failed</throws> internal static QueryPlan Build( QueryGraph queryGraph, OuterJoinDesc[] outerJoinDescList, string[] streamNames, EventType[] typesPerStream, HistoricalViewableDesc historicalViewableDesc, DependencyGraph dependencyGraph, HistoricalStreamIndexList[] historicalStreamIndexLists, ExprEvaluatorContext exprEvaluatorContext, string[][][] indexedStreamsUniqueProps, TableMetadata[] tablesPerStream) { if (Log.IsDebugEnabled) { Log.Debug(".build queryGraph=" + queryGraph); } var numStreams = queryGraph.NumStreams; var planNodeSpecs = new QueryPlanNode[numStreams]; // Build index specifications var indexSpecs = QueryPlanIndexBuilder.BuildIndexSpec(queryGraph, typesPerStream, indexedStreamsUniqueProps); if (Log.IsDebugEnabled) { Log.Debug(".build Index build completed, indexes=" + QueryPlanIndex.Print(indexSpecs)); } // any historical streams don't get indexes, the lookup strategy accounts for cached indexes if (historicalViewableDesc.HasHistorical) { 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 QueryPlanNodeNoOp(); continue; } var queryPlanNode = BuildPlanNode(numStreams, streamNo, streamNames, queryGraph, outerInnerGraph, outerJoinDescList, innerJoinGraph, indexSpecs, typesPerStream, historicalViewableDesc.Historical, dependencyGraph, historicalStreamIndexLists, exprEvaluatorContext, tablesPerStream); if (Log.IsDebugEnabled) { Log.Debug(".build spec for stream '" + streamNames[streamNo] + "' number " + streamNo + " is " + queryPlanNode); } planNodeSpecs[streamNo] = queryPlanNode; } var queryPlan = new QueryPlan(indexSpecs, planNodeSpecs); if (Log.IsDebugEnabled) { Log.Debug(".build query plan=" + queryPlan); } return(queryPlan); }