public CompositeIndexLookupRange( RangeIndexLookupValue lookupValue, Type coercionType) { this._lookupValue = lookupValue; this._coercionType = coercionType; }
private static RangeIndexLookupValue[] CompileRangeLookupValues(string[] rangeIndexProps, FilterSpecParam[] parameters, AgentInstanceContext agentInstanceContext) { var result = new RangeIndexLookupValue[rangeIndexProps.Length]; for (var rangeIndex = 0; rangeIndex < rangeIndexProps.Length; rangeIndex++) { foreach (var param in parameters) { if (!(param.Lookupable.Expression.Equals(rangeIndexProps[rangeIndex]))) { continue; } if (param.FilterOperator == FilterOperator.EQUAL || param.FilterOperator == FilterOperator.IS) { result[rangeIndex] = new RangeIndexLookupValueEquals(param.GetFilterValue(null, agentInstanceContext)); } else if (param.FilterOperator.IsRangeOperator() || param.FilterOperator.IsInvertedRangeOperator()) { QueryGraphRangeEnum opAdd = param.FilterOperator.MapFrom(); result[rangeIndex] = new RangeIndexLookupValueRange(param.GetFilterValue(null, agentInstanceContext), opAdd, true); } else if (param.FilterOperator.IsComparisonOperator()) { var existing = result[rangeIndex]; QueryGraphRangeEnum opAdd = param.FilterOperator.MapFrom(); if (existing == null) { result[rangeIndex] = new RangeIndexLookupValueRange(param.GetFilterValue(null, agentInstanceContext), opAdd, true); } else { if (!(existing is RangeIndexLookupValueRange)) { continue; } var existingRange = (RangeIndexLookupValueRange)existing; var opExist = existingRange.Operator; var desc = QueryGraphRangeUtil.GetCanConsolidate(opExist, opAdd); if (desc != null) { var doubleRange = GetDoubleRange(desc.IsReverse, existing.Value, param.GetFilterValue(null, agentInstanceContext)); result[rangeIndex] = new RangeIndexLookupValueRange(doubleRange, desc.RangeType, false); } } } } } return(result); }
public abstract ISet<EventBean> LookupConstants(RangeIndexLookupValue lookupValueBase);
public override ISet<EventBean> LookupConstants(RangeIndexLookupValue lookupValueBase) { if (lookupValueBase is RangeIndexLookupValueEquals) { var equals = (RangeIndexLookupValueEquals) lookupValueBase; return propertyIndex.Get(equals.Value); } var lookupValue = (RangeIndexLookupValueRange) lookupValueBase; if (lookupValue.Operator == QueryGraphRangeEnum.RANGE_CLOSED) { var range = (Range) lookupValue.Value; return LookupRange(range.LowEndpoint, true, range.HighEndpoint, true, lookupValue.IsAllowRangeReverse); } if (lookupValue.Operator == QueryGraphRangeEnum.RANGE_HALF_OPEN) { var range = (Range) lookupValue.Value; return LookupRange(range.LowEndpoint, true, range.HighEndpoint, false, lookupValue.IsAllowRangeReverse); } if (lookupValue.Operator == QueryGraphRangeEnum.RANGE_HALF_CLOSED) { var range = (Range) lookupValue.Value; return LookupRange(range.LowEndpoint, false, range.HighEndpoint, true, lookupValue.IsAllowRangeReverse); } if (lookupValue.Operator == QueryGraphRangeEnum.RANGE_OPEN) { var range = (Range) lookupValue.Value; return LookupRange( range.LowEndpoint, false, range.HighEndpoint, false, lookupValue.IsAllowRangeReverse); } if (lookupValue.Operator == QueryGraphRangeEnum.NOT_RANGE_CLOSED) { var range = (Range) lookupValue.Value; return LookupRangeInverted(range.LowEndpoint, true, range.HighEndpoint, true); } if (lookupValue.Operator == QueryGraphRangeEnum.NOT_RANGE_HALF_OPEN) { var range = (Range) lookupValue.Value; return LookupRangeInverted(range.LowEndpoint, true, range.HighEndpoint, false); } if (lookupValue.Operator == QueryGraphRangeEnum.NOT_RANGE_HALF_CLOSED) { var range = (Range) lookupValue.Value; return LookupRangeInverted(range.LowEndpoint, false, range.HighEndpoint, true); } if (lookupValue.Operator == QueryGraphRangeEnum.NOT_RANGE_OPEN) { var range = (Range) lookupValue.Value; return LookupRangeInverted(range.LowEndpoint, false, range.HighEndpoint, false); } if (lookupValue.Operator == QueryGraphRangeEnum.GREATER) { return LookupGreater(lookupValue.Value); } if (lookupValue.Operator == QueryGraphRangeEnum.GREATER_OR_EQUAL) { return LookupGreaterEqual(lookupValue.Value); } if (lookupValue.Operator == QueryGraphRangeEnum.LESS) { return LookupLess(lookupValue.Value); } if (lookupValue.Operator == QueryGraphRangeEnum.LESS_OR_EQUAL) { return LookupLessEqual(lookupValue.Value); } throw new ArgumentException("Unrecognized operator '" + lookupValue.Operator + "'"); }
public static ICollection <EventBean> Snapshot( FilterSpecCompiled optionalFilter, Attribute[] annotations, VirtualDWView virtualDataWindow, EventTableIndexRepository indexRepository, bool queryPlanLogging, ILog queryPlanLogDestination, string objectName, AgentInstanceContext agentInstanceContext) { if (optionalFilter == null || optionalFilter.Parameters.Length == 0) { if (virtualDataWindow != null) { var pair = virtualDataWindow.GetFireAndForgetDesc(Collections.GetEmptySet <string>(), Collections.GetEmptySet <string>()); return(virtualDataWindow.GetFireAndForgetData(pair.Second, new object[0], new RangeIndexLookupValue[0], annotations)); } return(null); } // Determine what straight-equals keys and which ranges are available. // Widening/Coercion is part of filter spec compile. ISet <string> keysAvailable = new HashSet <string>(); ISet <string> rangesAvailable = new HashSet <string>(); if (optionalFilter.Parameters.Length == 1) { foreach (FilterSpecParam param in optionalFilter.Parameters[0]) { if (!(param is FilterSpecParamConstant || param is FilterSpecParamRange || param is FilterSpecParamIn)) { continue; } if (param.FilterOperator == FilterOperator.EQUAL || param.FilterOperator == FilterOperator.IS || param.FilterOperator == FilterOperator.IN_LIST_OF_VALUES) { keysAvailable.Add(param.Lookupable.Expression); } else if (param.FilterOperator.IsRangeOperator() || param.FilterOperator.IsInvertedRangeOperator() || param.FilterOperator.IsComparisonOperator()) { rangesAvailable.Add(param.Lookupable.Expression); } else if (param.FilterOperator.IsRangeOperator()) { rangesAvailable.Add(param.Lookupable.Expression); } } } // Find an index that matches the needs Pair <IndexMultiKey, EventTableAndNamePair> tablePair; if (virtualDataWindow != null) { var tablePairNoName = virtualDataWindow.GetFireAndForgetDesc(keysAvailable, rangesAvailable); tablePair = new Pair <IndexMultiKey, EventTableAndNamePair>(tablePairNoName.First, new EventTableAndNamePair(tablePairNoName.Second, null)); } else { var indexHint = IndexHint.GetIndexHint(annotations); IList <IndexHintInstruction> optionalIndexHintInstructions = null; if (indexHint != null) { optionalIndexHintInstructions = indexHint.InstructionsFireAndForget; } tablePair = indexRepository.FindTable(keysAvailable, rangesAvailable, optionalIndexHintInstructions); } var hook = QueryPlanIndexHookUtil.GetHook(annotations); if (queryPlanLogging && (queryPlanLogDestination.IsInfoEnabled || hook != null)) { var prefix = "Fire-and-forget from " + objectName + " "; var indexName = tablePair != null && tablePair.Second != null ? tablePair.Second.IndexName : null; var indexText = indexName != null ? "index " + indexName + " " : "full table scan "; indexText += "(snapshot only, for join see separate query plan)"; if (tablePair == null) { queryPlanLogDestination.Info(prefix + indexText); } else { queryPlanLogDestination.Info(prefix + indexText + tablePair.Second.EventTable.ToQueryPlan()); } if (hook != null) { hook.FireAndForget(new QueryPlanIndexDescFAF( new IndexNameAndDescPair[] { new IndexNameAndDescPair(indexName, tablePair != null ? tablePair.Second.EventTable.ProviderClass.Name : null) })); } } if (tablePair == null) { return(null); // indicates table scan } // Compile key sets which contain key index lookup values var keyIndexProps = IndexedPropDesc.GetIndexProperties(tablePair.First.HashIndexedProps); var hasKeyWithInClause = false; var keyValues = new object[keyIndexProps.Length]; for (var keyIndex = 0; keyIndex < keyIndexProps.Length; keyIndex++) { foreach (var param in optionalFilter.Parameters[0]) { if (param.Lookupable.Expression.Equals(keyIndexProps[keyIndex])) { if (param.FilterOperator == FilterOperator.IN_LIST_OF_VALUES) { var keyValuesList = ((MultiKeyUntyped)param.GetFilterValue(null, agentInstanceContext)).Keys; if (keyValuesList.Length == 0) { continue; } else if (keyValuesList.Length == 1) { keyValues[keyIndex] = keyValuesList[0]; } else { keyValues[keyIndex] = keyValuesList; hasKeyWithInClause = true; } } else { keyValues[keyIndex] = param.GetFilterValue(null, agentInstanceContext); } break; } } } // Analyze ranges - these may include key lookup value (EQUALS semantics) var rangeIndexProps = IndexedPropDesc.GetIndexProperties(tablePair.First.RangeIndexedProps); RangeIndexLookupValue[] rangeValues; if (rangeIndexProps.Length > 0) { rangeValues = CompileRangeLookupValues(rangeIndexProps, optionalFilter.Parameters[0], agentInstanceContext); } else { rangeValues = new RangeIndexLookupValue[0]; } var eventTable = tablePair.Second.EventTable; var indexMultiKey = tablePair.First; // table lookup without in-clause if (!hasKeyWithInClause) { return(FafTableLookup(virtualDataWindow, indexMultiKey, eventTable, keyValues, rangeValues, annotations)); } // table lookup with in-clause: determine combinations var combinations = new object[keyIndexProps.Length][]; for (var i = 0; i < keyValues.Length; i++) { if (keyValues[i] is object[]) { combinations[i] = (object[])keyValues[i]; } else { combinations[i] = new object[] { keyValues[i] }; } } // enumerate combinations var enumeration = new CombinationEnumeration(combinations); var events = new HashSet <EventBean>(); for (; enumeration.MoveNext();) { object[] keys = enumeration.Current; var result = FafTableLookup(virtualDataWindow, indexMultiKey, eventTable, keys, rangeValues, annotations); events.AddAll(result); } return(events); }
/// <summary> /// The SnapshotIndex /// </summary> /// <param name="keysAvailable">The <see cref="QueryGraphValuePairHashKeyIndex"/></param> /// <param name="rangesAvailable">The <see cref="QueryGraphValuePairRangeIndex"/></param> /// <param name="tablePair">The <see cref="Pair{IndexMultiKey, EventTableAndNamePair}"/></param> /// <param name="virtualDataWindow">The <see cref="VirtualDWView"/></param> /// <param name="attributes">The <see cref="Attribute"/> array</param> /// <param name="agentInstanceContext">The <see cref="AgentInstanceContext"/></param> /// <param name="queryPlanLogging">The <see cref="bool"/></param> /// <param name="queryPlanLogDestination">The <see cref="ILog"/></param> /// <param name="objectName">The <see cref="string"/></param> /// <returns>The <see cref="ICollection{EventBean}"/></returns> private static ICollection <EventBean> SnapshotIndex( QueryGraphValuePairHashKeyIndex keysAvailable, QueryGraphValuePairRangeIndex rangesAvailable, Pair <IndexMultiKey, EventTableAndNamePair> tablePair, VirtualDWView virtualDataWindow, Attribute[] attributes, AgentInstanceContext agentInstanceContext, bool queryPlanLogging, ILog queryPlanLogDestination, string objectName) { var evaluateParamsTrue = new EvaluateParams(null, true, agentInstanceContext); // report plan queryPlanReport(tablePair.Second.IndexName, tablePair.Second.EventTable, attributes, agentInstanceContext, queryPlanLogging, queryPlanLogDestination, objectName); // compile hash lookup values var tableHashProps = tablePair.First.HashIndexedProps; var keyValues = new Object[tableHashProps.Length]; for (var tableHashPropNum = 0; tableHashPropNum < tableHashProps.Length; tableHashPropNum++) { var tableHashProp = tableHashProps[tableHashPropNum]; for (var i = 0; i < keysAvailable.Indexed.Count; i++) { if (keysAvailable.Indexed[i].Equals(tableHashProp.IndexPropName)) { var key = keysAvailable.Keys[i]; var value = key.KeyExpr.ExprEvaluator.Evaluate(evaluateParamsTrue); if (value != null) { value = MayCoerceNonNull(value, tableHashProp.CoercionType); keyValues[tableHashPropNum] = value; } } } } // compile range lookup values var tableRangeProps = tablePair.First.RangeIndexedProps; var rangeValues = new RangeIndexLookupValue[tableRangeProps.Length]; for (var tableRangePropNum = 0; tableRangePropNum < tableRangeProps.Length; tableRangePropNum++) { var tableRangeProp = tableRangeProps[tableRangePropNum]; for (var i = 0; i < rangesAvailable.Indexed.Count; i++) { if (rangesAvailable.Indexed[i].Equals(tableRangeProp.IndexPropName)) { var range = rangesAvailable.Keys[i]; if (range is QueryGraphValueEntryRangeIn) { var between = (QueryGraphValueEntryRangeIn)range; var start = between.ExprStart.ExprEvaluator.Evaluate(evaluateParamsTrue); var end = between.ExprEnd.ExprEvaluator.Evaluate(evaluateParamsTrue); Range rangeValue; if (tableRangeProp.CoercionType.IsNumeric()) { double?startDouble = null; if (start != null) { startDouble = start.AsDouble(); } double?endDouble = null; if (end != null) { endDouble = end.AsDouble(); } rangeValue = new DoubleRange(startDouble, endDouble); } else { rangeValue = new StringRange(start == null ? null : start.ToString(), end == null ? null : end.ToString()); } rangeValues[tableRangePropNum] = new RangeIndexLookupValueRange(rangeValue, between.RangeType, between.IsAllowRangeReversal); } else { var relOp = (QueryGraphValueEntryRangeRelOp)range; var value = relOp.Expression.ExprEvaluator.Evaluate(evaluateParamsTrue); if (value != null) { value = MayCoerceNonNull(value, tableRangeProp.CoercionType); } rangeValues[tableRangePropNum] = new RangeIndexLookupValueRange(value, relOp.RangeType, true); } } } } // perform lookup return(FafTableLookup(virtualDataWindow, tablePair.First, tablePair.Second.EventTable, keyValues, rangeValues, attributes)); }
public ISet <EventBean> LookupConstants(RangeIndexLookupValue lookupValueBase) { if (lookupValueBase is RangeIndexLookupValueEquals) { var equals = (RangeIndexLookupValueEquals)lookupValueBase; return(PropertyIndex.Get(equals.Value)); } var lookupValue = (RangeIndexLookupValueRange)lookupValueBase; switch (lookupValue.Operator) { case QueryGraphRangeEnum.RANGE_CLOSED: { var range = (Range)lookupValue.Value; return(LookupRange(range.LowEndpoint, true, range.HighEndpoint, true, lookupValue.IsAllowRangeReverse)); } case QueryGraphRangeEnum.RANGE_HALF_OPEN: { var range = (Range)lookupValue.Value; return(LookupRange(range.LowEndpoint, true, range.HighEndpoint, false, lookupValue.IsAllowRangeReverse)); } case QueryGraphRangeEnum.RANGE_HALF_CLOSED: { var range = (Range)lookupValue.Value; return(LookupRange(range.LowEndpoint, false, range.HighEndpoint, true, lookupValue.IsAllowRangeReverse)); } case QueryGraphRangeEnum.RANGE_OPEN: { var range = (Range)lookupValue.Value; return(LookupRange(range.LowEndpoint, false, range.HighEndpoint, false, lookupValue.IsAllowRangeReverse)); } case QueryGraphRangeEnum.NOT_RANGE_CLOSED: { var range = (Range)lookupValue.Value; return(LookupRangeInverted(range.LowEndpoint, true, range.HighEndpoint, true)); } case QueryGraphRangeEnum.NOT_RANGE_HALF_OPEN: { var range = (Range)lookupValue.Value; return(LookupRangeInverted(range.LowEndpoint, true, range.HighEndpoint, false)); } case QueryGraphRangeEnum.NOT_RANGE_HALF_CLOSED: { var range = (Range)lookupValue.Value; return(LookupRangeInverted(range.LowEndpoint, false, range.HighEndpoint, true)); } case QueryGraphRangeEnum.NOT_RANGE_OPEN: { var range = (Range)lookupValue.Value; return(LookupRangeInverted(range.LowEndpoint, false, range.HighEndpoint, false)); } case QueryGraphRangeEnum.GREATER: return(LookupGreater(lookupValue.Value)); case QueryGraphRangeEnum.GREATER_OR_EQUAL: return(LookupGreaterEqual(lookupValue.Value)); case QueryGraphRangeEnum.LESS: return(LookupLess(lookupValue.Value)); case QueryGraphRangeEnum.LESS_OR_EQUAL: return(LookupLessEqual(lookupValue.Value)); default: throw new ArgumentException("Unrecognized operator '" + lookupValue.Operator + "'"); } }