internal static IndexHintPair GetIndexHintPair(StatementContext statementContext, StatementSpecCompiled statementSpec)
        {
            IndexHint       indexHint       = IndexHint.GetIndexHint(statementContext.Annotations);
            ExcludePlanHint excludePlanHint = null;

            if (statementSpec.OnTriggerDesc is OnTriggerWindowDesc)
            {
                OnTriggerWindowDesc onTriggerWindowDesc = (OnTriggerWindowDesc)statementSpec.OnTriggerDesc;
                string[]            streamNames         = { onTriggerWindowDesc.OptionalAsName, statementSpec.StreamSpecs[0].OptionalStreamName };
                excludePlanHint = ExcludePlanHint.GetHint(streamNames, statementContext);
            }
            return(new IndexHintPair(indexHint, excludePlanHint));
        }
Exemple #2
0
        public static IndexHintPair GetIndexHintPair(
            OnTriggerDesc onTriggerDesc,
            string streamZeroAsName,
            StatementRawInfo statementRawInfo,
            StatementCompileTimeServices services)
        {
            IndexHint indexHint = IndexHint.GetIndexHint(statementRawInfo.Annotations);
            ExcludePlanHint excludePlanHint = null;
            if (onTriggerDesc is OnTriggerWindowDesc) {
                var onTriggerWindowDesc = (OnTriggerWindowDesc) onTriggerDesc;
                string[] streamNames = {onTriggerWindowDesc.OptionalAsName, streamZeroAsName};
                excludePlanHint = ExcludePlanHint.GetHint(streamNames, statementRawInfo, services);
            }

            return new IndexHintPair(indexHint, excludePlanHint);
        }
        /// <summary>
        /// The FindIndex
        /// </summary>
        /// <param name="keyNamesAvailable">The key names available.</param>
        /// <param name="rangeNamesAvailable">The range names available.</param>
        /// <param name="indexRepository">The <see cref="EventTableIndexRepository" /></param>
        /// <param name="virtualDataWindow">The <see cref="VirtualDWView" /></param>
        /// <param name="attributes">The <see cref="Attribute" /> array</param>
        /// <returns></returns>
        private static Pair <IndexMultiKey, EventTableAndNamePair> FindIndex(
            ISet <string> keyNamesAvailable,
            ISet <string> rangeNamesAvailable,
            EventTableIndexRepository indexRepository,
            VirtualDWView virtualDataWindow,
            Attribute[] attributes)
        {
            if (virtualDataWindow != null)
            {
                var tablePairNoName = virtualDataWindow.GetFireAndForgetDesc(keyNamesAvailable, rangeNamesAvailable);
                return(new Pair <IndexMultiKey, EventTableAndNamePair>(tablePairNoName.First, new EventTableAndNamePair(tablePairNoName.Second, null)));
            }
            var indexHint = IndexHint.GetIndexHint(attributes);
            var optionalIndexHintInstructions = indexHint != null ? indexHint.InstructionsFireAndForget : null;

            return(indexRepository.FindTable(keyNamesAvailable, rangeNamesAvailable, optionalIndexHintInstructions));
        }
        private static Pair<IndexMultiKey, EventTableAndNamePair> FindIndex(
            ISet<string> keyNamesAvailable,
            ISet<string> rangeNamesAvailable,
            EventTableIndexRepository indexRepository,
            VirtualDWView virtualDataWindow,
            Attribute[] annotations)
        {
            if (virtualDataWindow != null) {
                var tablePairNoName = VirtualDWQueryPlanUtil.GetFireAndForgetDesc(
                    virtualDataWindow.EventType,
                    keyNamesAvailable,
                    rangeNamesAvailable);
                return new Pair<IndexMultiKey, EventTableAndNamePair>(
                    tablePairNoName.First,
                    new EventTableAndNamePair(tablePairNoName.Second, null));
            }

            var indexHint = IndexHint.GetIndexHint(annotations);
            IList<IndexHintInstruction> optionalIndexHintInstructions =
                indexHint != null ? indexHint.GetInstructionsFireAndForget() : null;
            return indexRepository.FindTable(keyNamesAvailable, rangeNamesAvailable, optionalIndexHintInstructions);
        }
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);
        }