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)); }
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); }
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); }
public void Visit(IndexHint node) { }
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); }
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)); }