private void AssertRanges(object[][] ranges, QueryGraphValue value) { Assert.AreEqual(ranges.Length, value.Items.Count); var count = -1; foreach (var desc in value.Items) { count++; var r = (QueryGraphValueEntryRange)desc.Entry; Assert.AreEqual(ranges[count][3], r.RangeType); Assert.AreEqual(ranges[count][4], desc.IndexExprs[0].ToExpressionStringMinPrecedenceSafe()); if (r is QueryGraphValueEntryRangeRelOp) { var relOp = (QueryGraphValueEntryRangeRelOp)r; Assert.AreEqual(ranges[count][0], GetProp(relOp.Expression)); } else { var rangeIn = (QueryGraphValueEntryRangeIn)r; Assert.AreEqual(ranges[count][1], GetProp(rangeIn.ExprStart)); Assert.AreEqual(ranges[count][2], GetProp(rangeIn.ExprEnd)); } } }
public static IList <string> GetIndexProperties(QueryGraph graph, int lookup, int indexed) { QueryGraphValue val = graph.GetGraphValue(lookup, indexed); QueryGraphValuePairHashKeyIndex pair = val.HashKeyProps; return(pair.Indexed); }
private QueryGraphValue GetCreateValue(int streamKey, int streamValue) { Check(streamValue, streamKey); var key = new QueryGraphKey(streamKey, streamValue); var value = _streamJoinMap.Get(key); if (value == null) { value = new QueryGraphValue(); _streamJoinMap.Put(key, value); } return value; }
public void TestNoDup() { var value = new QueryGraphValue(); value.AddRelOp(MakeIdent("B"), QueryGraphRangeEnum.LESS_OR_EQUAL, MakeIdent("A"), false); value.AddRelOp(MakeIdent("B"), QueryGraphRangeEnum.LESS_OR_EQUAL, MakeIdent("A"), false); AssertRanges(new object[][] { new object[] { "B", null, null, QueryGraphRangeEnum.LESS_OR_EQUAL, "A" } }, value); value = new QueryGraphValue(); value.AddRange(QueryGraphRangeEnum.RANGE_CLOSED, MakeIdent("B"), MakeIdent("C"), MakeIdent("A")); value.AddRange(QueryGraphRangeEnum.RANGE_CLOSED, MakeIdent("B"), MakeIdent("C"), MakeIdent("A")); AssertRanges(new object[][] { new object[] { null, "B", "C", QueryGraphRangeEnum.RANGE_CLOSED, "A" } }, value); }
private void TryAdd(string propertyKeyOne, QueryGraphRangeEnum opOne, ExprIdentNode valueOne, string propertyKeyTwo, QueryGraphRangeEnum opTwo, ExprIdentNode valueTwo, object[][] expected) { var value = new QueryGraphValue(); value.AddRelOp(MakeIdent(propertyKeyOne), opOne, valueOne, true); value.AddRelOp(MakeIdent(propertyKeyTwo), opTwo, valueTwo, true); AssertRanges(expected, value); value = new QueryGraphValue(); value.AddRelOp(MakeIdent(propertyKeyTwo), opTwo, valueTwo, true); value.AddRelOp(MakeIdent(propertyKeyOne), opOne, valueOne, true); AssertRanges(expected, value); }
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)); }