Exemple #1
0
 public IndexHintPair(
     IndexHint indexHint,
     ExcludePlanHint excludePlanHint)
 {
     IndexHint = indexHint;
     ExcludePlanHint = excludePlanHint;
 }
        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 #3
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));
        }
        public static SubordinateWMatchExprQueryPlanResult PlanOnExpression(
            ExprNode joinExpr,
            EventType filterEventType,
            IndexHint optionalIndexHint,
            bool isIndexShare,
            int subqueryNumber,
            ExcludePlanHint excludePlanHint,
            bool isVirtualDataWindow,
            EventTableIndexMetadata indexMetadata,
            EventType eventTypeIndexed,
            ICollection <string> optionalUniqueKeyProps,
            bool onlyUseExistingIndexes,
            string statementName,
            string statementId,
            Attribute[] annotations)
        {
            var allStreamsZeroIndexed = new EventType[] { eventTypeIndexed, filterEventType };
            var outerStreams          = new EventType[] { filterEventType };
            var joinedPropPlan        = QueryPlanIndexBuilder.GetJoinProps(joinExpr, 1, allStreamsZeroIndexed, excludePlanHint);

            // No join expression means all
            if (joinExpr == null && !isVirtualDataWindow)
            {
                return(new SubordinateWMatchExprQueryPlanResult(new SubordWMatchExprLookupStrategyFactoryAllUnfiltered(), null));
            }

            var queryPlanDesc = PlanSubquery(outerStreams, joinedPropPlan, true, false, optionalIndexHint, isIndexShare, subqueryNumber,
                                             isVirtualDataWindow, indexMetadata, optionalUniqueKeyProps, onlyUseExistingIndexes, statementName, statementId, annotations);

            if (queryPlanDesc == null)
            {
                return(new SubordinateWMatchExprQueryPlanResult(new SubordWMatchExprLookupStrategyFactoryAllFiltered(joinExpr.ExprEvaluator), null));
            }

            if (joinExpr == null)     // it can be null when using virtual data window
            {
                return(new SubordinateWMatchExprQueryPlanResult(
                           new SubordWMatchExprLookupStrategyFactoryIndexedUnfiltered(queryPlanDesc.LookupStrategyFactory), queryPlanDesc.IndexDescs));
            }
            else
            {
                return(new SubordinateWMatchExprQueryPlanResult(
                           new SubordWMatchExprLookupStrategyFactoryIndexedFiltered(joinExpr.ExprEvaluator, queryPlanDesc.LookupStrategyFactory), queryPlanDesc.IndexDescs));
            }
        }
        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);
        }
        public StatementAgentInstanceFactoryOnTriggerNamedWindow(StatementContext statementContext, StatementSpecCompiled statementSpec, EPServicesContext services, ViewableActivator activator, SubSelectStrategyCollection subSelectStrategyCollection, ResultSetProcessorFactoryDesc resultSetProcessorPrototype, ExprNode validatedJoin, ResultSetProcessorFactoryDesc outputResultSetProcessorPrototype, NamedWindowOnExprFactory onExprFactory, OutputProcessViewFactory outputProcessViewFactory, EventType activatorResultEventType, NamedWindowProcessor processor, IList <StopCallback> stopCallbacks)
            : base(statementContext, statementSpec, services, activator, subSelectStrategyCollection)
        {
            _resultSetProcessorPrototype       = resultSetProcessorPrototype;
            _outputResultSetProcessorPrototype = outputResultSetProcessorPrototype;
            _onExprFactory            = onExprFactory;
            _outputProcessViewFactory = outputProcessViewFactory;
            _processor = processor;

            IndexHintPair   pair            = GetIndexHintPair(statementContext, statementSpec);
            IndexHint       indexHint       = pair.IndexHint;
            ExcludePlanHint excludePlanHint = pair.ExcludePlanHint;

            _queryPlan = SubordinateQueryPlanner.PlanOnExpression(
                validatedJoin, activatorResultEventType, indexHint, processor.IsEnableSubqueryIndexShare, -1, excludePlanHint,
                processor.IsVirtualDataWindow, processor.EventTableIndexMetadataRepo, processor.NamedWindowType,
                processor.OptionalUniqueKeyProps, false, statementContext.StatementName, statementContext.StatementId, statementContext.Annotations);
            if (_queryPlan.IndexDescs != null)
            {
                SubordinateQueryPlannerUtil.AddIndexMetaAndRef(_queryPlan.IndexDescs, processor.EventTableIndexMetadataRepo, statementContext.StatementName);
                stopCallbacks.Add(new ProxyStopCallback(() =>
                {
                    for (int i = 0; i < _queryPlan.IndexDescs.Length; i++)
                    {
                        bool last = processor.EventTableIndexMetadataRepo.RemoveIndexReference(_queryPlan.IndexDescs[i].IndexMultiKey, statementContext.StatementName);
                        if (last)
                        {
                            processor.EventTableIndexMetadataRepo.RemoveIndex(_queryPlan.IndexDescs[i].IndexMultiKey);
                            processor.RemoveAllInstanceIndexes(_queryPlan.IndexDescs[i].IndexMultiKey);
                        }
                    }
                }));
            }
            SubordinateQueryPlannerUtil.QueryPlanLogOnExpr(processor.RootView.IsQueryPlanLogging, NamedWindowRootView.QueryPlanLog,
                                                           _queryPlan, statementContext.Annotations, statementContext.EngineImportService);
        }
        private static SubordinateQueryIndexSuggest FindOrSuggestIndex(
            IDictionary<string, SubordPropHashKeyForge> hashProps,
            IDictionary<string, SubordPropRangeKeyForge> rangeProps,
            IndexHint optionalIndexHint,
            bool isIndexShare,
            int subqueryNumber,
            EventTableIndexMetadata indexMetadata,
            ISet<string> optionalUniqueKeyProps,
            bool onlyUseExistingIndexes,
            EventType eventTypeIndexed,
            StatementRawInfo raw,
            StatementCompileTimeServices services)
        {
            var indexProps = GetIndexPropDesc(hashProps, rangeProps);
            var hashedAndBtreeProps = indexProps.ListPair;

            // Get or create the table for this index (exact match or property names, type of index and coercion type is expected)
            IndexKeyInfo indexKeyInfo; // how needs all of IndexKeyInfo+QueryPlanIndexItem+IndexMultiKey
            IndexMultiKey indexMultiKey;
            string indexName = null;
            string indexModuleName = null;
            QueryPlanIndexItemForge planIndexItem = null;

            if (hashedAndBtreeProps.HashedProps.IsEmpty() && hashedAndBtreeProps.BtreeProps.IsEmpty()) {
                return null;
            }

            Pair<IndexMultiKey, NameAndModule> existing = null;
            SubordinateQueryIndexPlan planned = null;

            // consider index hints
            IList<IndexHintInstruction> optionalIndexHintInstructions = null;
            if (optionalIndexHint != null) {
                optionalIndexHintInstructions = optionalIndexHint.GetInstructionsSubquery(subqueryNumber);
            }

            var indexFoundPair = EventTableIndexUtil.FindIndexConsiderTyping(
                indexMetadata.Indexes,
                hashedAndBtreeProps.HashedProps,
                hashedAndBtreeProps.BtreeProps,
                optionalIndexHintInstructions);
            if (indexFoundPair != null) {
                var hintIndex = indexMetadata.Indexes.Get(indexFoundPair);
                existing = new Pair<IndexMultiKey, NameAndModule>(
                    indexFoundPair,
                    new NameAndModule(hintIndex.OptionalIndexName, hintIndex.OptionalIndexModuleName));
            }

            // nothing found: plan one
            if (existing == null && !onlyUseExistingIndexes) {
                // not found, see if the item is declared unique
                var proposedHashedProps = hashedAndBtreeProps.HashedProps;
                var proposedBtreeProps = hashedAndBtreeProps.BtreeProps;

                // match against unique-key properties when suggesting an index
                var unique = false;
                var coerce = !isIndexShare;
                if (optionalUniqueKeyProps != null && !optionalUniqueKeyProps.IsEmpty()) {
                    IList<IndexedPropDesc> newHashProps = new List<IndexedPropDesc>();
                    foreach (var uniqueKey in optionalUniqueKeyProps) {
                        var found = false;
                        foreach (var hashProp in hashedAndBtreeProps.HashedProps) {
                            if (hashProp.IndexPropName.Equals(uniqueKey)) {
                                newHashProps.Add(hashProp);
                                found = true;
                                break;
                            }
                        }

                        if (!found) {
                            newHashProps = null;
                            break;
                        }
                    }

                    if (newHashProps != null) {
                        proposedHashedProps = newHashProps;
                        proposedBtreeProps = new EmptyList<IndexedPropDesc>();
                        unique = true;
                        coerce = false;
                    }
                }

                planned = PlanIndex(unique, proposedHashedProps, proposedBtreeProps, eventTypeIndexed, raw, services);
            }

            // compile index information
            if (existing == null && planned == null) {
                return null;
            }

            // handle existing
            IList<StmtClassForgeableFactory> multiKeyForgeables;
            if (existing != null) {
                indexKeyInfo = SubordinateQueryPlannerUtil.CompileIndexKeyInfo(
                    existing.First,
                    indexProps.HashIndexPropsProvided,
                    indexProps.HashJoinedProps,
                    indexProps.RangeIndexPropsProvided,
                    indexProps.RangeJoinedProps);
                indexName = existing.Second.Name;
                indexModuleName = existing.Second.ModuleName;
                indexMultiKey = existing.First;
                multiKeyForgeables = EmptyList<StmtClassForgeableFactory>.Instance;
            }
            else {
                // handle planned
                indexKeyInfo = SubordinateQueryPlannerUtil.CompileIndexKeyInfo(
                    planned.IndexPropKey,
                    indexProps.HashIndexPropsProvided,
                    indexProps.HashJoinedProps,
                    indexProps.RangeIndexPropsProvided,
                    indexProps.RangeJoinedProps);
                indexMultiKey = planned.IndexPropKey;
                planIndexItem = planned.IndexItem;
                multiKeyForgeables = planned.MultiKeyForgeables;
            }

            var forge = new SubordinateQueryIndexDescForge(indexKeyInfo, indexName, indexModuleName, indexMultiKey, planIndexItem);
            return new SubordinateQueryIndexSuggest(forge, multiKeyForgeables);
        }
Exemple #9
0
        public SubSelectStrategyFactoryIndexShare(
            string statementName,
            int statementId,
            int subqueryNum,
            EventType[] outerEventTypesSelect,
            NamedWindowProcessor optionalNamedWindowProcessor,
            TableMetadata optionalTableMetadata,
            bool fullTableScan,
            IndexHint optionalIndexHint,
            SubordPropPlan joinedPropPlan,
            ExprEvaluator filterExprEval,
            AggregationServiceFactoryDesc aggregationServiceFactory,
            ExprEvaluator[] groupByKeys,
            TableService tableService,
            Attribute[] annotations,
            StatementStopService statementStopService)
        {
            _optionalNamedWindowProcessor = optionalNamedWindowProcessor;
            _optionalTableMetadata        = optionalTableMetadata;
            _filterExprEval            = filterExprEval;
            _aggregationServiceFactory = aggregationServiceFactory;
            _groupByKeys  = groupByKeys;
            _tableService = tableService;

            bool isLogging;
            ILog log;

            if (optionalTableMetadata != null)
            {
                isLogging  = optionalTableMetadata.IsQueryPlanLogging;
                log        = TableServiceImpl.QueryPlanLog;
                _queryPlan = SubordinateQueryPlanner.PlanSubquery(outerEventTypesSelect, joinedPropPlan, false, fullTableScan, optionalIndexHint, true, subqueryNum,
                                                                  false, optionalTableMetadata.EventTableIndexMetadataRepo, optionalTableMetadata.UniqueKeyProps, true, statementName, statementId, annotations);
                if (_queryPlan != null)
                {
                    for (int i = 0; i < _queryPlan.IndexDescs.Length; i++)
                    {
                        optionalTableMetadata.AddIndexReference(_queryPlan.IndexDescs[i].IndexName, statementName);
                    }
                }
            }
            else
            {
                isLogging  = optionalNamedWindowProcessor.RootView.IsQueryPlanLogging;
                log        = NamedWindowRootView.QueryPlanLog;
                _queryPlan = SubordinateQueryPlanner.PlanSubquery(outerEventTypesSelect, joinedPropPlan, false, fullTableScan, optionalIndexHint, true, subqueryNum,
                                                                  optionalNamedWindowProcessor.IsVirtualDataWindow, optionalNamedWindowProcessor.EventTableIndexMetadataRepo, optionalNamedWindowProcessor.OptionalUniqueKeyProps, false, statementName, statementId, annotations);
                if (_queryPlan != null && _queryPlan.IndexDescs != null)
                {
                    SubordinateQueryPlannerUtil.AddIndexMetaAndRef(_queryPlan.IndexDescs, optionalNamedWindowProcessor.EventTableIndexMetadataRepo, statementName);
                    statementStopService.StatementStopped += () =>
                    {
                        for (int i = 0; i < _queryPlan.IndexDescs.Length; i++)
                        {
                            bool last = optionalNamedWindowProcessor.EventTableIndexMetadataRepo.RemoveIndexReference(_queryPlan.IndexDescs[i].IndexMultiKey, statementName);
                            if (last)
                            {
                                optionalNamedWindowProcessor.EventTableIndexMetadataRepo.RemoveIndex(_queryPlan.IndexDescs[i].IndexMultiKey);
                                optionalNamedWindowProcessor.RemoveAllInstanceIndexes(_queryPlan.IndexDescs[i].IndexMultiKey);
                            }
                        }
                    };
                }
            }

            SubordinateQueryPlannerUtil.QueryPlanLogOnSubq(isLogging, log, _queryPlan, subqueryNum, annotations);
        }
        public static SubordinateQueryPlan PlanSubquery(
            EventType[] outerStreams,
            SubordPropPlan joinDesc,
            bool isNWOnTrigger,
            bool forceTableScan,
            IndexHint optionalIndexHint,
            bool indexShare,
            int subqueryNumber,
            bool isVirtualDataWindow,
            EventTableIndexMetadata indexMetadata,
            ISet<string> optionalUniqueKeyProps,
            bool onlyUseExistingIndexes,
            EventType eventTypeIndexed,
            StatementRawInfo statementRawInfo,
            StatementCompileTimeServices services)
        {
            if (isVirtualDataWindow) {
                var indexProps = GetIndexPropDesc(joinDesc.HashProps, joinDesc.RangeProps);
                var lookupStrategyFactoryX = new SubordTableLookupStrategyFactoryForgeVDW(
                    statementRawInfo.StatementName,
                    statementRawInfo.Annotations,
                    outerStreams,
                    indexProps.HashJoinedProps,
                    new CoercionDesc(false, indexProps.HashIndexCoercionType),
                    indexProps.RangeJoinedProps,
                    new CoercionDesc(false, indexProps.RangeIndexCoercionType),
                    isNWOnTrigger,
                    joinDesc,
                    forceTableScan,
                    indexProps.ListPair);
                var forge = new SubordinateQueryPlanDescForge(lookupStrategyFactoryX, null);
                return new SubordinateQueryPlan(forge, EmptyList<StmtClassForgeableFactory>.Instance);
            }

            if (joinDesc.CustomIndexOps != null && !joinDesc.CustomIndexOps.IsEmpty()) {
                foreach (var op
                    in joinDesc.CustomIndexOps) {
                    foreach (var index in indexMetadata.Indexes) {
                        if (IsCustomIndexMatch(index, op)) {
                            var provisionDesc =
                                index.Value.OptionalQueryPlanIndexItem.AdvancedIndexProvisionDesc;
                            var lookupStrategyFactoryX =
                                provisionDesc.Factory.Forge.GetSubordinateLookupStrategy(
                                    op.Key.OperationName,
                                    op.Value.PositionalExpressions,
                                    isNWOnTrigger,
                                    outerStreams.Length);
                            var provisionCompileTime =
                                provisionDesc.ToCompileTime(eventTypeIndexed, statementRawInfo, services);
                            var indexItemForge = new QueryPlanIndexItemForge(
                                new string[0],
                                new Type[0],
                                new string[0],
                                new Type[0],
                                false,
                                provisionCompileTime,
                                eventTypeIndexed);
                            var indexDesc = new SubordinateQueryIndexDescForge(
                                null,
                                index.Value.OptionalIndexName,
                                index.Value.OptionalIndexModuleName,
                                index.Key,
                                indexItemForge);
                            var forge = new SubordinateQueryPlanDescForge(lookupStrategyFactoryX, new SubordinateQueryIndexDescForge[]{indexDesc});
                            return new SubordinateQueryPlan(forge, EmptyList<StmtClassForgeableFactory>.Instance);
                        }
                    }
                }
            }

            var hashKeys = Collections.GetEmptyList<SubordPropHashKeyForge>();
            CoercionDesc hashKeyCoercionTypes = null;
            var rangeKeys = Collections.GetEmptyList<SubordPropRangeKeyForge>();
            CoercionDesc rangeKeyCoercionTypes = null;
            IList<ExprNode> inKeywordSingleIdxKeys = null;
            ExprNode inKeywordMultiIdxKey = null;

            SubordinateQueryIndexDescForge[] indexDescs;
            var additionalForgeables = new List<StmtClassForgeableFactory>();
            MultiKeyClassRef multiKeyClasses = null;
            if (joinDesc.InKeywordSingleIndex != null) {
                var single = joinDesc.InKeywordSingleIndex;
                var keyInfo = new SubordPropHashKeyForge(
                    new QueryGraphValueEntryHashKeyedForgeExpr(single.Expressions[0], false),
                    null,
                    single.CoercionType);
                var index = FindOrSuggestIndex(
                    Collections.SingletonMap(single.IndexedProp, keyInfo),
                    EmptyDictionary<string, SubordPropRangeKeyForge>.Instance,
                    optionalIndexHint,
                    indexShare,
                    subqueryNumber,
                    indexMetadata,
                    optionalUniqueKeyProps,
                    onlyUseExistingIndexes,
                    eventTypeIndexed,
                    statementRawInfo,
                    services);
                
                if (index == null) {
                    return null;
                }

                var indexDesc = index.Forge;
                var desc = new SubordinateQueryIndexDescForge(
                    indexDesc.OptionalIndexKeyInfo,
                    indexDesc.IndexName,
                    indexDesc.IndexModuleName,
                    indexDesc.IndexMultiKey,
                    indexDesc.OptionalQueryPlanIndexItem);
                indexDescs = new[] {desc};
                inKeywordSingleIdxKeys = single.Expressions;
                additionalForgeables.AddAll(index.MultiKeyForgeables);
            }
            else if (joinDesc.InKeywordMultiIndex != null) {
                var multi = joinDesc.InKeywordMultiIndex;

                indexDescs = new SubordinateQueryIndexDescForge[multi.IndexedProp.Length];
                for (var i = 0; i < multi.IndexedProp.Length; i++) {
                    var keyInfo = new SubordPropHashKeyForge(
                        new QueryGraphValueEntryHashKeyedForgeExpr(multi.Expression, false),
                        null,
                        multi.CoercionType);
                    var index = FindOrSuggestIndex(
                        Collections.SingletonMap(multi.IndexedProp[i], keyInfo),
                        EmptyDictionary<string, SubordPropRangeKeyForge>.Instance,
                        optionalIndexHint,
                        indexShare,
                        subqueryNumber,
                        indexMetadata,
                        optionalUniqueKeyProps,
                        onlyUseExistingIndexes,
                        eventTypeIndexed,
                        statementRawInfo,
                        services);
                    var indexDesc = index.Forge;
                    additionalForgeables.AddAll(index.MultiKeyForgeables);
                    if (indexDesc == null) {
                        return null;
                    }

                    indexDescs[i] = indexDesc;
                }

                inKeywordMultiIdxKey = multi.Expression;
            }
            else {
                var index = FindOrSuggestIndex(
                    joinDesc.HashProps,
                    joinDesc.RangeProps,
                    optionalIndexHint,
                    false,
                    subqueryNumber,
                    indexMetadata,
                    optionalUniqueKeyProps,
                    onlyUseExistingIndexes,
                    eventTypeIndexed,
                    statementRawInfo,
                    services);
                if (index == null) {
                    return null;
                }
                var indexDesc = index.Forge;
                additionalForgeables.AddRange(index.MultiKeyForgeables);
                var indexKeyInfo = indexDesc.OptionalIndexKeyInfo;

                hashKeys = indexKeyInfo.OrderedHashDesc;
                hashKeyCoercionTypes = indexKeyInfo.OrderedKeyCoercionTypes;
                rangeKeys = indexKeyInfo.OrderedRangeDesc;
                rangeKeyCoercionTypes = indexKeyInfo.OrderedRangeCoercionTypes;
                var desc = new SubordinateQueryIndexDescForge(
                    indexDesc.OptionalIndexKeyInfo,
                    indexDesc.IndexName,
                    indexDesc.IndexModuleName,
                    indexDesc.IndexMultiKey,
                    indexDesc.OptionalQueryPlanIndexItem);
                indexDescs = new[] {desc};
                
                if (indexDesc.OptionalQueryPlanIndexItem == null) {
                    var multiKeyPlan = MultiKeyPlanner.PlanMultiKey(hashKeyCoercionTypes.CoercionTypes, true, statementRawInfo, services.SerdeResolver);
                    multiKeyClasses = multiKeyPlan.ClassRef;
                    additionalForgeables.AddRange(multiKeyPlan.MultiKeyForgeables);
                } else {
                    multiKeyClasses = indexDesc.OptionalQueryPlanIndexItem.HashMultiKeyClasses;
                }
            }

            if (forceTableScan) {
                return null;
            }

            var lookupStrategyFactory = SubordinateTableLookupStrategyUtil.GetLookupStrategy(
                outerStreams,
                hashKeys,
                hashKeyCoercionTypes,
                multiKeyClasses,
                rangeKeys,
                rangeKeyCoercionTypes,
                inKeywordSingleIdxKeys,
                inKeywordMultiIdxKey,
                isNWOnTrigger);
            var forgeX = new SubordinateQueryPlanDescForge(lookupStrategyFactory, indexDescs);
            return new SubordinateQueryPlan(forgeX, additionalForgeables);
        }
Exemple #11
0
 public void Visit(IndexHint node)
 {
 }
Exemple #12
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);
        }
Exemple #13
0
 public virtual void Visit(IndexHint node)
 {
 }
        public SubSelectStrategyFactoryIndexShareForge(
            int subqueryNumber,
            SubSelectActivationPlan subselectActivation,
            EventType[] outerEventTypesSelect,
            NamedWindowMetaData namedWindow,
            TableMetaData table,
            bool fullTableScan,
            IndexHint indexHint,
            SubordPropPlan joinedPropPlan,
            ExprForge filterExprEval,
            ExprNode[] groupKeys,
            AggregationServiceForgeDesc aggregationServiceForgeDesc,
            StatementBaseInfo statement,
            StatementCompileTimeServices services)
        {
            _subqueryNumber = subqueryNumber;
            _namedWindow    = namedWindow;
            _table          = table;
            _filterExprEval = filterExprEval;
            _groupKeys      = groupKeys;
            _aggregationServiceForgeDesc = aggregationServiceForgeDesc;

            bool queryPlanLogging = services.Configuration.Common.Logging.IsEnableQueryPlan;

            // We only use existing indexes in all cases. This means "create index" is required.
            SubordinateQueryPlan plan;

            if (table != null)
            {
                plan = SubordinateQueryPlanner.PlanSubquery(
                    outerEventTypesSelect,
                    joinedPropPlan,
                    false,
                    fullTableScan,
                    indexHint,
                    true,
                    subqueryNumber,
                    false,
                    table.IndexMetadata,
                    table.UniquenessAsSet,
                    true,
                    table.InternalEventType,
                    statement.StatementRawInfo,
                    services);
            }
            else
            {
                plan = SubordinateQueryPlanner.PlanSubquery(
                    outerEventTypesSelect,
                    joinedPropPlan,
                    false,
                    fullTableScan,
                    indexHint,
                    true,
                    subqueryNumber,
                    namedWindow.IsVirtualDataWindow,
                    namedWindow.IndexMetadata,
                    namedWindow.UniquenessAsSet,
                    true,
                    namedWindow.EventType,
                    statement.StatementRawInfo,
                    services);
            }

            _queryPlan = plan == null ? null : plan.Forge;
            if (plan != null)
            {
                _additionalForgeables.AddAll(plan.AdditionalForgeables);
            }

            if (_queryPlan != null && _queryPlan.IndexDescs != null)
            {
                for (int i = 0; i < _queryPlan.IndexDescs.Length; i++)
                {
                    SubordinateQueryIndexDescForge index = _queryPlan.IndexDescs[i];

                    if (table != null)
                    {
                        if (table.TableVisibility == NameAccessModifier.PUBLIC)
                        {
                            services.ModuleDependenciesCompileTime.AddPathIndex(
                                false,
                                table.TableName,
                                table.TableModuleName,
                                index.IndexName,
                                index.IndexModuleName,
                                services.NamedWindowCompileTimeRegistry,
                                services.TableCompileTimeRegistry);
                        }
                    }
                    else
                    {
                        if (namedWindow.EventType.Metadata.AccessModifier == NameAccessModifier.PUBLIC)
                        {
                            services.ModuleDependenciesCompileTime.AddPathIndex(
                                true,
                                namedWindow.EventType.Name,
                                namedWindow.NamedWindowModuleName,
                                index.IndexName,
                                index.IndexModuleName,
                                services.NamedWindowCompileTimeRegistry,
                                services.TableCompileTimeRegistry);
                        }
                    }
                }
            }

            SubordinateQueryPlannerUtil.QueryPlanLogOnSubq(
                queryPlanLogging,
                QUERY_PLAN_LOG,
                _queryPlan,
                subqueryNumber,
                statement.StatementRawInfo.Annotations,
                services.ImportServiceCompileTime);

            if (groupKeys == null || groupKeys.Length == 0)
            {
                _groupByMultiKey = null;
            }
            else
            {
                MultiKeyPlan mkplan = MultiKeyPlanner.PlanMultiKey(groupKeys, false, statement.StatementRawInfo, services.SerdeResolver);
                _additionalForgeables.AddAll(mkplan.MultiKeyForgeables);
                _groupByMultiKey = mkplan.ClassRef;
            }
        }
        public static SubordinateQueryPlanDesc PlanSubquery(EventType[] outerStreams,
                                                            SubordPropPlan joinDesc,
                                                            bool isNWOnTrigger,
                                                            bool forceTableScan,
                                                            IndexHint optionalIndexHint,
                                                            bool indexShare,
                                                            int subqueryNumber,
                                                            bool isVirtualDataWindow,
                                                            EventTableIndexMetadata indexMetadata,
                                                            ICollection <string> optionalUniqueKeyProps,
                                                            bool onlyUseExistingIndexes,
                                                            string statementName,
                                                            string statementId,
                                                            Attribute[] annotations)
        {
            if (isVirtualDataWindow)
            {
                var indexProps = GetIndexPropDesc(joinDesc.HashProps, joinDesc.RangeProps);
                var lookupStrategyFactoryVdw = new SubordTableLookupStrategyFactoryVDW(statementName, statementId, annotations,
                                                                                       outerStreams,
                                                                                       indexProps.HashJoinedProps,
                                                                                       new CoercionDesc(false, indexProps.HashIndexCoercionType),
                                                                                       indexProps.RangeJoinedProps,
                                                                                       new CoercionDesc(false, indexProps.RangeIndexCoercionType),
                                                                                       isNWOnTrigger,
                                                                                       joinDesc, forceTableScan, indexProps.ListPair);
                return(new SubordinateQueryPlanDesc(lookupStrategyFactoryVdw, null));
            }

            var          hashKeys              = Collections.GetEmptyList <SubordPropHashKey>();
            CoercionDesc hashKeyCoercionTypes  = null;
            var          rangeKeys             = Collections.GetEmptyList <SubordPropRangeKey>();
            CoercionDesc rangeKeyCoercionTypes = null;

            ExprNode[] inKeywordSingleIdxKeys = null;
            ExprNode   inKeywordMultiIdxKey   = null;

            SubordinateQueryIndexDesc[] indexDescs;
            if (joinDesc.InKeywordSingleIndex != null)
            {
                var single    = joinDesc.InKeywordSingleIndex;
                var keyInfo   = new SubordPropHashKey(new QueryGraphValueEntryHashKeyedExpr(single.Expressions[0], false), null, single.CoercionType);
                var indexDesc = FindOrSuggestIndex(
                    Collections.SingletonMap(single.IndexedProp, keyInfo),
                    Collections.GetEmptyMap <string, SubordPropRangeKey>(), optionalIndexHint, indexShare, subqueryNumber,
                    indexMetadata, optionalUniqueKeyProps, onlyUseExistingIndexes);
                if (indexDesc == null)
                {
                    return(null);
                }
                var desc = new SubordinateQueryIndexDesc(indexDesc.IndexKeyInfo, indexDesc.IndexName, indexDesc.IndexMultiKey, indexDesc.QueryPlanIndexItem);
                indexDescs             = new SubordinateQueryIndexDesc[] { desc };
                inKeywordSingleIdxKeys = single.Expressions;
            }
            else if (joinDesc.InKeywordMultiIndex != null)
            {
                var multi = joinDesc.InKeywordMultiIndex;

                indexDescs = new SubordinateQueryIndexDesc[multi.IndexedProp.Length];
                for (var i = 0; i < multi.IndexedProp.Length; i++)
                {
                    var keyInfo   = new SubordPropHashKey(new QueryGraphValueEntryHashKeyedExpr(multi.Expression, false), null, multi.CoercionType);
                    var indexDesc = FindOrSuggestIndex(
                        Collections.SingletonMap(multi.IndexedProp[i], keyInfo),
                        Collections.GetEmptyMap <string, SubordPropRangeKey>(), optionalIndexHint, indexShare, subqueryNumber,
                        indexMetadata, optionalUniqueKeyProps, onlyUseExistingIndexes);
                    if (indexDesc == null)
                    {
                        return(null);
                    }
                    indexDescs[i] = indexDesc;
                }
                inKeywordMultiIdxKey = multi.Expression;
            }
            else
            {
                var indexDesc = FindOrSuggestIndex(joinDesc.HashProps,
                                                   joinDesc.RangeProps, optionalIndexHint, false, subqueryNumber,
                                                   indexMetadata, optionalUniqueKeyProps, onlyUseExistingIndexes);
                if (indexDesc == null)
                {
                    return(null);
                }
                var indexKeyInfo = indexDesc.IndexKeyInfo;
                hashKeys              = indexKeyInfo.OrderedHashDesc;
                hashKeyCoercionTypes  = indexKeyInfo.OrderedKeyCoercionTypes;
                rangeKeys             = indexKeyInfo.OrderedRangeDesc;
                rangeKeyCoercionTypes = indexKeyInfo.OrderedRangeCoercionTypes;
                var desc = new SubordinateQueryIndexDesc(indexDesc.IndexKeyInfo, indexDesc.IndexName, indexDesc.IndexMultiKey, indexDesc.QueryPlanIndexItem);
                indexDescs = new SubordinateQueryIndexDesc[] { desc };
            }

            if (forceTableScan)
            {
                return(null);
            }

            var lookupStrategyFactory = SubordinateTableLookupStrategyUtil.GetLookupStrategy(outerStreams,
                                                                                             hashKeys, hashKeyCoercionTypes, rangeKeys, rangeKeyCoercionTypes, inKeywordSingleIdxKeys, inKeywordMultiIdxKey, isNWOnTrigger);

            return(new SubordinateQueryPlanDesc(lookupStrategyFactory, indexDescs));
        }
        public static SubordinateWMatchExprQueryPlanResult PlanOnExpression(
            ExprNode joinExpr,
            EventType filterEventType,
            IndexHint optionalIndexHint,
            bool isIndexShare,
            int subqueryNumber,
            ExcludePlanHint excludePlanHint,
            bool isVirtualDataWindow,
            EventTableIndexMetadata indexMetadata,
            EventType eventTypeIndexed,
            ISet<string> optionalUniqueKeyProps,
            bool onlyUseExistingIndexes,
            StatementRawInfo statementRawInfo,
            StatementCompileTimeServices compileTimeServices)
        {
            var allStreamsZeroIndexed = new EventType[] {eventTypeIndexed, filterEventType};
            var outerStreams = new EventType[] {filterEventType};
            var joinedPropPlan = QueryPlanIndexBuilder.GetJoinProps(
                joinExpr,
                1,
                allStreamsZeroIndexed,
                excludePlanHint);

            // No join expression means all
            if (joinExpr == null && !isVirtualDataWindow) {
                var forgeX = new SubordinateWMatchExprQueryPlanForge(new SubordWMatchExprLookupStrategyAllUnfilteredForge(), null);
                return new SubordinateWMatchExprQueryPlanResult(forgeX, EmptyList<StmtClassForgeableFactory>.Instance);
            }

            var queryPlan = PlanSubquery(
                outerStreams,
                joinedPropPlan,
                true,
                false,
                optionalIndexHint,
                isIndexShare,
                subqueryNumber,
                isVirtualDataWindow,
                indexMetadata,
                optionalUniqueKeyProps,
                onlyUseExistingIndexes,
                eventTypeIndexed,
                statementRawInfo,
                compileTimeServices);

            if (queryPlan == null) {
                var forgeX = new SubordinateWMatchExprQueryPlanForge(new SubordWMatchExprLookupStrategyAllFilteredForge(joinExpr), null);
                return new SubordinateWMatchExprQueryPlanResult(forgeX, EmptyList<StmtClassForgeableFactory>.Instance);
            }

            var queryPlanDesc = queryPlan.Forge;
            SubordinateWMatchExprQueryPlanForge forge;
            if (joinExpr == null) {   // it can be null when using virtual data window
                forge = new SubordinateWMatchExprQueryPlanForge(
                    new SubordWMatchExprLookupStrategyIndexedUnfilteredForge(queryPlanDesc.LookupStrategyFactory), queryPlanDesc.IndexDescs);
            } else {
                var filteredForge =
                    new SubordWMatchExprLookupStrategyIndexedFilteredForge(joinExpr.Forge, queryPlanDesc.LookupStrategyFactory);
                forge = new SubordinateWMatchExprQueryPlanForge(filteredForge, queryPlanDesc.IndexDescs);
            }

            return new SubordinateWMatchExprQueryPlanResult(forge, queryPlan.AdditionalForgeables);
        }
        private static SubordinateQueryIndexDesc FindOrSuggestIndex(
            IDictionary <String, SubordPropHashKey> hashProps,
            IDictionary <String, SubordPropRangeKey> rangeProps,
            IndexHint optionalIndexHint,
            bool isIndexShare,
            int subqueryNumber,
            EventTableIndexMetadata indexMetadata,
            ICollection <string> optionalUniqueKeyProps,
            bool onlyUseExistingIndexes)
        {
            var indexProps          = GetIndexPropDesc(hashProps, rangeProps);
            var hashedAndBtreeProps = indexProps.ListPair;

            // Get or create the table for this index (exact match or property names, type of index and coercion type is expected)
            IndexKeyInfo       indexKeyInfo; // how needs all of IndexKeyInfo+QueryPlanIndexItem+IndexMultiKey
            IndexMultiKey      indexMultiKey;
            string             indexName     = null;
            QueryPlanIndexItem planIndexItem = null;

            if (hashedAndBtreeProps.HashedProps.IsEmpty() && hashedAndBtreeProps.BtreeProps.IsEmpty())
            {
                return(null);
            }

            Pair <IndexMultiKey, string>             existing = null;
            Pair <QueryPlanIndexItem, IndexMultiKey> planned  = null;

            // consider index hints
            IList <IndexHintInstruction> optionalIndexHintInstructions = null;

            if (optionalIndexHint != null)
            {
                optionalIndexHintInstructions = optionalIndexHint.GetInstructionsSubquery(subqueryNumber);
            }

            var indexFoundPair = EventTableIndexUtil.FindIndexConsiderTyping(indexMetadata.Indexes, hashedAndBtreeProps.HashedProps, hashedAndBtreeProps.BtreeProps, optionalIndexHintInstructions);

            if (indexFoundPair != null)
            {
                var hintIndex = indexMetadata.Indexes.Get(indexFoundPair);
                existing = new Pair <IndexMultiKey, string>(indexFoundPair, hintIndex.OptionalIndexName);
            }

            // nothing found: plan one
            if (existing == null && !onlyUseExistingIndexes)
            {
                // not found, see if the item is declared unique
                var proposedHashedProps = hashedAndBtreeProps.HashedProps;
                var proposedBtreeProps  = hashedAndBtreeProps.BtreeProps;

                // match against unique-key properties when suggesting an index
                var unique = false;
                var coerce = !isIndexShare;
                if (optionalUniqueKeyProps != null && !optionalUniqueKeyProps.IsEmpty())
                {
                    IList <IndexedPropDesc> newHashProps = new List <IndexedPropDesc>();
                    foreach (var uniqueKey in optionalUniqueKeyProps)
                    {
                        var found = false;
                        foreach (var hashProp in hashedAndBtreeProps.HashedProps)
                        {
                            if (hashProp.IndexPropName.Equals(uniqueKey))
                            {
                                newHashProps.Add(hashProp);
                                found = true;
                                break;
                            }
                        }
                        if (!found)
                        {
                            newHashProps = null;
                            break;
                        }
                    }
                    if (newHashProps != null)
                    {
                        proposedHashedProps = newHashProps;
                        proposedBtreeProps  = Collections.GetEmptyList <IndexedPropDesc>();
                        unique = true;
                        coerce = false;
                    }
                }

                planned = PlanIndex(unique, proposedHashedProps, proposedBtreeProps, coerce);
            }

            // compile index information
            if (existing == null && planned == null)
            {
                return(null);
            }
            // handle existing
            if (existing != null)
            {
                indexKeyInfo = SubordinateQueryPlannerUtil.CompileIndexKeyInfo(existing.First,
                                                                               indexProps.HashIndexPropsProvided, indexProps.HashJoinedProps,
                                                                               indexProps.RangeIndexPropsProvided, indexProps.RangeJoinedProps);
                indexName     = existing.Second;
                indexMultiKey = existing.First;
            }
            // handle planned
            else
            {
                indexKeyInfo = SubordinateQueryPlannerUtil.CompileIndexKeyInfo(planned.Second,
                                                                               indexProps.HashIndexPropsProvided, indexProps.HashJoinedProps,
                                                                               indexProps.RangeIndexPropsProvided, indexProps.RangeJoinedProps);
                indexMultiKey = planned.Second;
                planIndexItem = planned.First;
            }

            return(new SubordinateQueryIndexDesc(indexKeyInfo, indexName, indexMultiKey, planIndexItem));
        }