Exemple #1
0
 public CompositeIndexLookupRange(
     RangeIndexLookupValue lookupValue,
     Type coercionType)
 {
     this._lookupValue = lookupValue;
     this._coercionType = coercionType;
 }
Exemple #2
0
        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);
Exemple #4
0
        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 + "'");
        }
Exemple #5
0
        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 + "'");
            }
        }