public void TestAnalyzeAnd() { ExprAndNode andNode = SupportExprNodeFactory.Make2SubNodeAnd(); QueryGraph graph = new QueryGraph(2, null, false); FilterExprAnalyzer.AnalyzeAndNode(andNode, graph, false); Assert.IsTrue(graph.IsNavigableAtAll(0, 1)); EPAssertionUtil.AssertEqualsExactOrder(QueryGraphTestUtil.GetStrictKeyProperties(graph, 0, 1), new String[] { "IntPrimitive", "TheString" }); EPAssertionUtil.AssertEqualsExactOrder(QueryGraphTestUtil.GetIndexProperties(graph, 1, 0), new String[] { "IntPrimitive", "TheString" }); EPAssertionUtil.AssertEqualsExactOrder(QueryGraphTestUtil.GetStrictKeyProperties(graph, 1, 0), new String[] { "IntBoxed", "TheString" }); EPAssertionUtil.AssertEqualsExactOrder(QueryGraphTestUtil.GetIndexProperties(graph, 0, 1), new String[] { "IntBoxed", "TheString" }); }
public void TestAnalyzeEquals() { // s0.IntPrimitive = s1.IntBoxed ExprEqualsNode equalsNode = SupportExprNodeFactory.MakeEqualsNode(); QueryGraph graph = new QueryGraph(2, null, false); FilterExprAnalyzer.AnalyzeEqualsNode(equalsNode, graph, false); Assert.IsTrue(graph.IsNavigableAtAll(0, 1)); EPAssertionUtil.AssertEqualsExactOrder(new String[] { "IntPrimitive" }, QueryGraphTestUtil.GetStrictKeyProperties(graph, 0, 1)); EPAssertionUtil.AssertEqualsExactOrder(new String[] { "IntPrimitive" }, QueryGraphTestUtil.GetIndexProperties(graph, 1, 0)); EPAssertionUtil.AssertEqualsExactOrder(new String[] { "IntBoxed" }, QueryGraphTestUtil.GetStrictKeyProperties(graph, 1, 0)); EPAssertionUtil.AssertEqualsExactOrder(new String[] { "IntBoxed" }, QueryGraphTestUtil.GetIndexProperties(graph, 0, 1)); }
public void TestGetPlan() { var descList = new OuterJoinDesc[] { SupportOuterJoinDescFactory.MakeDesc("IntPrimitive", "s0", "IntBoxed", "s1", OuterJoinType.LEFT) }; var queryGraph = new QueryGraph(2, null, false); var plan = QueryPlanBuilder.GetPlan(_typesPerStream, new OuterJoinDesc[0], queryGraph, null, new HistoricalViewableDesc(5), _dependencyGraph, null, new StreamJoinAnalysisResult(2), true, null, null); AssertPlan(plan); plan = QueryPlanBuilder.GetPlan(_typesPerStream, descList, queryGraph, null, new HistoricalViewableDesc(5), _dependencyGraph, null, new StreamJoinAnalysisResult(2), true, null, null); AssertPlan(plan); FilterExprAnalyzer.Analyze(SupportExprNodeFactory.MakeEqualsNode(), queryGraph, false); plan = QueryPlanBuilder.GetPlan(_typesPerStream, descList, queryGraph, null, new HistoricalViewableDesc(5), _dependencyGraph, null, new StreamJoinAnalysisResult(2), true, null, null); AssertPlan(plan); plan = QueryPlanBuilder.GetPlan(_typesPerStream, new OuterJoinDesc[0], queryGraph, null, new HistoricalViewableDesc(5), _dependencyGraph, null, new StreamJoinAnalysisResult(2), true, null, null); AssertPlan(plan); }
public static SubordPropPlan GetJoinProps(ExprNode filterExpr, int outsideStreamCount, EventType[] allStreamTypesZeroIndexed, ExcludePlanHint excludePlanHint) { // No filter expression means full table scan if (filterExpr == null) { return(new SubordPropPlan()); } // analyze query graph var queryGraph = new QueryGraph(outsideStreamCount + 1, excludePlanHint, true); FilterExprAnalyzer.Analyze(filterExpr, queryGraph, false); // Build a list of streams and indexes var joinProps = new LinkedHashMap <String, SubordPropHashKey>(); var rangeProps = new LinkedHashMap <String, SubordPropRangeKey>(); for (int stream = 0; stream < outsideStreamCount; stream++) { int lookupStream = stream + 1; QueryGraphValue queryGraphValue = queryGraph.GetGraphValue(lookupStream, 0); QueryGraphValuePairHashKeyIndex hashKeysAndIndexes = queryGraphValue.HashKeyProps; // handle key-lookups var keyPropertiesJoin = hashKeysAndIndexes.Keys; var indexPropertiesJoin = hashKeysAndIndexes.Indexed; if (keyPropertiesJoin.IsNotEmpty()) { if (keyPropertiesJoin.Count != indexPropertiesJoin.Count) { throw new IllegalStateException("Invalid query key and index property collection for stream " + stream); } for (int i = 0; i < keyPropertiesJoin.Count; i++) { QueryGraphValueEntryHashKeyed keyDesc = keyPropertiesJoin[i]; ExprNode compareNode = keyDesc.KeyExpr; var keyPropType = compareNode.ExprEvaluator.ReturnType.GetBoxedType(); var indexedPropType = allStreamTypesZeroIndexed[0].GetPropertyType(indexPropertiesJoin[i]).GetBoxedType(); var coercionType = indexedPropType; if (keyPropType != indexedPropType) { coercionType = keyPropType.GetCompareToCoercionType(indexedPropType); } SubordPropHashKey desc; if (keyPropertiesJoin[i] is QueryGraphValueEntryHashKeyedExpr) { var keyExpr = (QueryGraphValueEntryHashKeyedExpr)keyPropertiesJoin[i]; var keyStreamNum = keyExpr.IsRequiresKey ? stream : (int?)null; desc = new SubordPropHashKey(keyDesc, keyStreamNum, coercionType); } else { var prop = (QueryGraphValueEntryHashKeyedProp)keyDesc; desc = new SubordPropHashKey(prop, stream, coercionType); } joinProps.Put(indexPropertiesJoin[i], desc); } } // handle range lookups QueryGraphValuePairRangeIndex rangeKeysAndIndexes = queryGraphValue.RangeProps; var rangeIndexes = rangeKeysAndIndexes.Indexed; var rangeDescs = rangeKeysAndIndexes.Keys; if (rangeDescs.IsEmpty()) { continue; } // get all ranges lookups int count = -1; foreach (QueryGraphValueEntryRange rangeDesc in rangeDescs) { count++; String rangeIndexProp = rangeIndexes[count]; SubordPropRangeKey subqRangeDesc = rangeProps.Get(rangeIndexProp); // other streams may specify the start or end endpoint of a range, therefore this operation can be additive if (subqRangeDesc != null) { if (subqRangeDesc.RangeInfo.RangeType.IsRange()) { continue; } // see if we can make this additive by using a range var relOpOther = (QueryGraphValueEntryRangeRelOp)subqRangeDesc.RangeInfo; var relOpThis = (QueryGraphValueEntryRangeRelOp)rangeDesc; QueryGraphRangeConsolidateDesc opsDesc = QueryGraphRangeUtil.GetCanConsolidate( relOpThis.RangeType, relOpOther.RangeType); if (opsDesc != null) { ExprNode start; ExprNode end; if (!opsDesc.IsReverse) { start = relOpOther.Expression; end = relOpThis.Expression; } else { start = relOpThis.Expression; end = relOpOther.Expression; } var allowRangeReversal = relOpOther.IsBetweenPart && relOpThis.IsBetweenPart; var rangeIn = new QueryGraphValueEntryRangeIn(opsDesc.RangeType, start, end, allowRangeReversal); var indexedPropType = allStreamTypesZeroIndexed[0].GetPropertyType(rangeIndexProp).GetBoxedType(); var coercionType = indexedPropType; var proposedType = CoercionUtil.GetCoercionTypeRangeIn(indexedPropType, rangeIn.ExprStart, rangeIn.ExprEnd); if (proposedType != null && proposedType != indexedPropType) { coercionType = proposedType; } subqRangeDesc = new SubordPropRangeKey(rangeIn, coercionType); rangeProps.Put(rangeIndexProp, subqRangeDesc); } // ignore continue; } // an existing entry has not been found if (rangeDesc.RangeType.IsRange()) { var rangeIn = (QueryGraphValueEntryRangeIn)rangeDesc; var indexedPropType = allStreamTypesZeroIndexed[0].GetPropertyType(rangeIndexProp).GetBoxedType(); var coercionType = indexedPropType; var proposedType = CoercionUtil.GetCoercionTypeRangeIn(indexedPropType, rangeIn.ExprStart, rangeIn.ExprEnd); if (proposedType != null && proposedType != indexedPropType) { coercionType = proposedType; } subqRangeDesc = new SubordPropRangeKey(rangeDesc, coercionType); } else { var relOp = (QueryGraphValueEntryRangeRelOp)rangeDesc; var keyPropType = relOp.Expression.ExprEvaluator.ReturnType; var indexedPropType = allStreamTypesZeroIndexed[0].GetPropertyType(rangeIndexProp).GetBoxedType(); var coercionType = indexedPropType; if (keyPropType != indexedPropType) { coercionType = keyPropType.GetCompareToCoercionType(indexedPropType); } subqRangeDesc = new SubordPropRangeKey(rangeDesc, coercionType); } rangeProps.Put(rangeIndexProp, subqRangeDesc); } } SubordPropInKeywordSingleIndex inKeywordSingleIdxProp = null; SubordPropInKeywordMultiIndex inKeywordMultiIdxProp = null; if (joinProps.IsEmpty() && rangeProps.IsEmpty()) { for (int stream = 0; stream < outsideStreamCount; stream++) { int lookupStream = stream + 1; QueryGraphValue queryGraphValue = queryGraph.GetGraphValue(lookupStream, 0); QueryGraphValuePairInKWSingleIdx inkwSingles = queryGraphValue.InKeywordSingles; if (inkwSingles.Indexed.Length != 0) { ExprNode[] keys = inkwSingles.Key[0].KeyExprs; String key = inkwSingles.Indexed[0]; if (inKeywordSingleIdxProp != null) { continue; } var coercionType = keys[0].ExprEvaluator.ReturnType; // for in-comparison the same type is required inKeywordSingleIdxProp = new SubordPropInKeywordSingleIndex(key, coercionType, keys); } IList <QueryGraphValuePairInKWMultiIdx> inkwMultis = queryGraphValue.InKeywordMulti; if (!inkwMultis.IsEmpty()) { QueryGraphValuePairInKWMultiIdx multi = inkwMultis[0]; inKeywordMultiIdxProp = new SubordPropInKeywordMultiIndex(ExprNodeUtility.GetIdentResolvedPropertyNames(multi.Indexed), multi.Indexed[0].ExprEvaluator.ReturnType, multi.Key.KeyExpr); } if (inKeywordSingleIdxProp != null && inKeywordMultiIdxProp != null) { inKeywordMultiIdxProp = null; } } } return(new SubordPropPlan(joinProps, rangeProps, inKeywordSingleIdxProp, inKeywordMultiIdxProp)); }