public void TestGraphOuterJoins() { var descList = new OuterJoinDesc[2]; descList[0] = SupportOuterJoinDescFactory.MakeDesc("IntPrimitive", "s0", "IntBoxed", "s1", OuterJoinType.RIGHT); descList[1] = SupportOuterJoinDescFactory.MakeDesc("SimpleProperty", "s2", "TheString", "s1", OuterJoinType.FULL); var graph = NStreamOuterQueryPlanBuilder.GraphOuterJoins(3, descList); // assert the inner and outer streams for each stream AssertInners(new int[][] { null, new int[] { 0, 2 }, new int[] { 1 } }, graph); AssertOuters(new int[][] { new int[] { 1 }, new int[] { 2 }, new int[] { 1 } }, graph); descList[0] = SupportOuterJoinDescFactory.MakeDesc("IntPrimitive", "s1", "IntBoxed", "s0", OuterJoinType.LEFT); descList[1] = SupportOuterJoinDescFactory.MakeDesc("SimpleProperty", "s2", "TheString", "s1", OuterJoinType.RIGHT); graph = NStreamOuterQueryPlanBuilder.GraphOuterJoins(3, descList); // assert the inner and outer streams for each stream AssertInners(new int[][] { new int[] { 1 }, null, new int[] { 1 } }, graph); AssertOuters(new int[][] { null, new int[] { 0, 2 }, null }, graph); try { NStreamOuterQueryPlanBuilder.GraphOuterJoins(3, new OuterJoinDesc[0]); Assert.Fail(); } catch (ArgumentException) { // expected } }
public void TestRecursiveBuild() { var streamNum = 2; var queryGraph = new QueryGraph(6, null, false); var outerInnerGraph = new OuterInnerDirectionalGraph(6); var completedStreams = new HashSet <int>(); var substreamsPerStream = new LinkedHashMap <int, int[]>(); var requiredPerStream = new bool[6]; outerInnerGraph.Add(3, 2).Add(2, 1).Add(4, 3).Add(1, 0).Add(3, 5); queryGraph.AddStrictEquals(2, "", null, 3, "", null); queryGraph.AddStrictEquals(3, "", null, 4, "", null); queryGraph.AddStrictEquals(3, "", null, 5, "", null); queryGraph.AddStrictEquals(2, "", null, 1, "", null); queryGraph.AddStrictEquals(1, "", null, 0, "", null); ICollection <InterchangeablePair <int, int> > innerJoins = new HashSet <InterchangeablePair <int, int> >(); var innerJoinGraph = new InnerJoinGraph(6, innerJoins); var streamStack = new Stack <int>(); NStreamOuterQueryPlanBuilder.RecursiveBuild(streamNum, streamStack, queryGraph, outerInnerGraph, innerJoinGraph, completedStreams, substreamsPerStream, requiredPerStream, new DependencyGraph(6, false)); Assert.AreEqual(6, substreamsPerStream.Count); EPAssertionUtil.AssertEqualsExactOrder(substreamsPerStream[2], new int[] { 3, 1 }); EPAssertionUtil.AssertEqualsExactOrder(substreamsPerStream.Get(3), new int[] { 4, 5 }); EPAssertionUtil.AssertEqualsExactOrder(substreamsPerStream[1], new int[] { 0 }); EPAssertionUtil.AssertEqualsExactOrder(substreamsPerStream.Get(4), new int[] {}); EPAssertionUtil.AssertEqualsExactOrder(substreamsPerStream.Get(5), new int[] {}); EPAssertionUtil.AssertEqualsExactOrder(substreamsPerStream[0], new int[] {}); NStreamOuterQueryPlanBuilder.VerifyJoinedPerStream(2, substreamsPerStream); EPAssertionUtil.AssertEqualsExactOrder(requiredPerStream, new bool[] { false, false, false, true, true, false } ); }
private void TryVerifyJoinedPerStream(IDictionary <int, int[]> map) { try { NStreamOuterQueryPlanBuilder.VerifyJoinedPerStream(0, map); Assert.Fail(); } catch (ArgumentException) { // expected } }
/// <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); }