private static SubordPropRangeKey[] GetRangeFuncsAsSubProp(IList <QueryGraphValueEntryRange> funcs) { var keys = new SubordPropRangeKey[funcs.Count]; for (var i = 0; i < funcs.Count; i++) { var func = funcs[i]; keys[i] = new SubordPropRangeKey(func, func.Expressions[0].ExprEvaluator.ReturnType); } return(keys); }
public SubordTableLookupStrategyVirtualDW( String namedWindowName, VirtualDataWindowLookup externalIndex, IList <SubordPropHashKey> hashKeys, CoercionDesc hashKeyCoercionTypes, IList <SubordPropRangeKey> rangeKeys, CoercionDesc rangeKeyCoercionTypes, bool nwOnTrigger, int numOuterStreams) { _namedWindowName = namedWindowName; _externalIndex = externalIndex; _evaluators = new ExternalEvaluator[hashKeys.Count + rangeKeys.Count]; _nwOnTrigger = nwOnTrigger; _eventsLocal = new EventBean[numOuterStreams + 1]; var count = 0; foreach (var hashKey in hashKeys) { var evaluator = hashKey.HashKey.KeyExpr.ExprEvaluator; _evaluators[count] = new ExternalEvaluatorHashRelOp(evaluator, hashKeyCoercionTypes.CoercionTypes[count]); count++; } for (var i = 0; i < rangeKeys.Count; i++) { SubordPropRangeKey rangeKey = rangeKeys[i]; if (rangeKey.RangeInfo.RangeType.IsRange()) { var range = (QueryGraphValueEntryRangeIn)rangeKey.RangeInfo; var evaluatorStart = range.ExprStart.ExprEvaluator; var evaluatorEnd = range.ExprEnd.ExprEvaluator; _evaluators[count] = new ExternalEvaluatorBtreeRange(evaluatorStart, evaluatorEnd, rangeKeyCoercionTypes.CoercionTypes[i]); } else { var relOp = (QueryGraphValueEntryRangeRelOp)rangeKey.RangeInfo; var evaluator = relOp.Expression.ExprEvaluator; _evaluators[count] = new ExternalEvaluatorHashRelOp(evaluator, rangeKeyCoercionTypes.CoercionTypes[i]); } count++; } }
public static CoercionDesc GetCoercionTypesRange(EventType viewableEventType, IDictionary <String, SubordPropRangeKey> rangeProps, EventType[] typesPerStream) { if (rangeProps.IsEmpty()) { return(new CoercionDesc(false, NULL_ARRAY)); } var coercionTypes = new Type[rangeProps.Count]; bool mustCoerce = false; int count = 0; foreach (KeyValuePair <String, SubordPropRangeKey> entry in rangeProps) { SubordPropRangeKey subQRange = entry.Value; QueryGraphValueEntryRange rangeDesc = entry.Value.RangeInfo; Type valuePropType = viewableEventType.GetPropertyType(entry.Key).GetBoxedType(); Type coercionType; if (rangeDesc.RangeType.IsRange()) { var rangeIn = (QueryGraphValueEntryRangeIn)rangeDesc; coercionType = GetCoercionTypeRangeIn(valuePropType, rangeIn.ExprStart, rangeIn.ExprEnd); } else { var relOp = (QueryGraphValueEntryRangeRelOp)rangeDesc; coercionType = GetCoercionType(valuePropType, relOp.Expression.ExprEvaluator.ReturnType); } if (coercionType == null) { coercionTypes[count++] = valuePropType; } else { mustCoerce = true; coercionTypes[count++] = coercionType; } } return(new CoercionDesc(mustCoerce, coercionTypes)); }
public static CompositeIndexQuery MakeJoinSingleLookupStream( bool isNWOnTrigger, int lookupStream, IList <QueryGraphValueEntryHashKeyed> hashKeys, IList <Type> keyCoercionTypes, IList <QueryGraphValueEntryRange> rangeProps, IList <Type> rangeCoercionTypes) { // construct chain IList <CompositeIndexQuery> queries = new List <CompositeIndexQuery>(); if (hashKeys.Count > 0) { queries.Add(new CompositeIndexQueryKeyed(false, lookupStream, -1, hashKeys, keyCoercionTypes)); } int count = 0; foreach (QueryGraphValueEntryRange rangeProp in rangeProps) { Type coercionType = rangeCoercionTypes == null ? null : rangeCoercionTypes[count]; SubordPropRangeKey rkey = new SubordPropRangeKey(rangeProp, coercionType); queries.Add( new CompositeIndexQueryRange(isNWOnTrigger, lookupStream, -1, rkey, coercionType, new List <String>())); count++; } // Hook up as chain for remove CompositeIndexQuery last = null; foreach (CompositeIndexQuery action in queries) { if (last != null) { last.SetNext(action); } last = action; } return(queries[0]); }
public CompositeIndexQueryRange(bool isNWOnTrigger, int lookupStream, int numStreams, SubordPropRangeKey subqRangeKey, Type coercionType, IList <String> expressionTexts) { QueryGraphValueEntryRange rangeProp = subqRangeKey.RangeInfo; if (rangeProp.RangeType.IsRange()) { var rangeIn = (QueryGraphValueEntryRangeIn)rangeProp; var start = rangeIn.ExprStart.ExprEvaluator; expressionTexts.Add(ExprNodeUtility.ToExpressionStringMinPrecedenceSafe(rangeIn.ExprStart)); var includeStart = rangeProp.RangeType.IsIncludeStart(); var end = rangeIn.ExprEnd.ExprEvaluator; expressionTexts.Add(ExprNodeUtility.ToExpressionStringMinPrecedenceSafe(rangeIn.ExprEnd)); var includeEnd = rangeProp.RangeType.IsIncludeEnd(); if (!rangeProp.RangeType.IsRangeInverted()) { _strategy = new CompositeAccessStrategyRangeNormal( isNWOnTrigger, lookupStream, numStreams, start, includeStart, end, includeEnd, coercionType, ((QueryGraphValueEntryRangeIn)rangeProp).IsAllowRangeReversal); } else { _strategy = new CompositeAccessStrategyRangeInverted( isNWOnTrigger, lookupStream, numStreams, start, includeStart, end, includeEnd, coercionType); } } else { var relOp = (QueryGraphValueEntryRangeRelOp)rangeProp; var key = relOp.Expression.ExprEvaluator; expressionTexts.Add(ExprNodeUtility.ToExpressionStringMinPrecedenceSafe(relOp.Expression)); if (rangeProp.RangeType == QueryGraphRangeEnum.GREATER_OR_EQUAL) { _strategy = new CompositeAccessStrategyGE(isNWOnTrigger, lookupStream, numStreams, key, coercionType); } else if (rangeProp.RangeType == QueryGraphRangeEnum.GREATER) { _strategy = new CompositeAccessStrategyGT(isNWOnTrigger, lookupStream, numStreams, key, coercionType); } else if (rangeProp.RangeType == QueryGraphRangeEnum.LESS_OR_EQUAL) { _strategy = new CompositeAccessStrategyLE(isNWOnTrigger, lookupStream, numStreams, key, coercionType); } else if (rangeProp.RangeType == QueryGraphRangeEnum.LESS) { _strategy = new CompositeAccessStrategyLT(isNWOnTrigger, lookupStream, numStreams, key, coercionType); } else { throw new ArgumentException("Comparison operator " + rangeProp.RangeType + " not supported"); } } }
public static SortedAccessStrategy Make(bool isNWOnTrigger, int lookupStream, int numStreams, SubordPropRangeKey streamRangeKey) { var rangeKeyPair = streamRangeKey.RangeInfo; if (rangeKeyPair.RangeType.IsRange()) { var rangeIn = (QueryGraphValueEntryRangeIn)rangeKeyPair; var startExpr = rangeIn.ExprStart.ExprEvaluator; var endExpr = rangeIn.ExprEnd.ExprEvaluator; var includeStart = rangeKeyPair.RangeType.IsIncludeStart(); var includeEnd = rangeKeyPair.RangeType.IsIncludeEnd(); if (!rangeKeyPair.RangeType.IsRangeInverted()) { return(new SortedAccessStrategyRange( isNWOnTrigger, lookupStream, numStreams, startExpr, includeStart, endExpr, includeEnd, rangeIn.IsAllowRangeReversal)); } return(new SortedAccessStrategyRangeInverted( isNWOnTrigger, lookupStream, numStreams, startExpr, includeStart, endExpr, includeEnd)); } var relOp = (QueryGraphValueEntryRangeRelOp)rangeKeyPair; var keyExpr = relOp.Expression.ExprEvaluator; if (rangeKeyPair.RangeType == QueryGraphRangeEnum.GREATER_OR_EQUAL) { return(new SortedAccessStrategyGE(isNWOnTrigger, lookupStream, numStreams, keyExpr)); } if (rangeKeyPair.RangeType == QueryGraphRangeEnum.GREATER) { return(new SortedAccessStrategyGT(isNWOnTrigger, lookupStream, numStreams, keyExpr)); } if (rangeKeyPair.RangeType == QueryGraphRangeEnum.LESS_OR_EQUAL) { return(new SortedAccessStrategyLE(isNWOnTrigger, lookupStream, numStreams, keyExpr)); } if (rangeKeyPair.RangeType == QueryGraphRangeEnum.LESS) { return(new SortedAccessStrategyLT(isNWOnTrigger, lookupStream, numStreams, keyExpr)); } throw new ArgumentException("Comparison operator " + rangeKeyPair.RangeType + " not supported"); }
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)); }
public static Type GetCoercionTypeRange(EventType indexedType, String indexedProp, SubordPropRangeKey rangeKey) { QueryGraphValueEntryRange desc = rangeKey.RangeInfo; if (desc.RangeType.IsRange()) { var rangeIn = (QueryGraphValueEntryRangeIn)desc; return(GetCoercionTypeRangeIn(indexedType.GetPropertyType(indexedProp), rangeIn.ExprStart, rangeIn.ExprEnd)); } var relOp = (QueryGraphValueEntryRangeRelOp)desc; return(GetCoercionType(indexedType.GetPropertyType(indexedProp), relOp.Expression.ExprEvaluator.ReturnType)); }