public StatementAgentInstanceFactoryOnTriggerTable(StatementContext statementContext, StatementSpecCompiled statementSpec, EPServicesContext services, ViewableActivator activator, SubSelectStrategyCollection subSelectStrategyCollection, ResultSetProcessorFactoryDesc resultSetProcessorPrototype, ExprNode validatedJoin, TableOnViewFactory onExprFactory, EventType activatorResultEventType, TableMetadata tableMetadata, ResultSetProcessorFactoryDesc outputResultSetProcessorPrototype, OutputProcessViewFactory outputProcessViewFactory) : base(statementContext, statementSpec, services, activator, subSelectStrategyCollection) { _resultSetProcessorPrototype = resultSetProcessorPrototype; _onExprFactory = onExprFactory; _outputResultSetProcessorPrototype = outputResultSetProcessorPrototype; _outputProcessViewFactory = outputProcessViewFactory; var pair = StatementAgentInstanceFactoryOnTriggerNamedWindow.GetIndexHintPair(statementContext, statementSpec); var indexHint = pair.IndexHint; var excludePlanHint = pair.ExcludePlanHint; _queryPlanResult = SubordinateQueryPlanner.PlanOnExpression( validatedJoin, activatorResultEventType, indexHint, true, -1, excludePlanHint, false, tableMetadata.EventTableIndexMetadataRepo, tableMetadata.InternalEventType, tableMetadata.UniqueKeyProps, true, statementContext.StatementName, statementContext.StatementId, statementContext.Annotations); if (_queryPlanResult.IndexDescs != null) { for (var i = 0; i < _queryPlanResult.IndexDescs.Length; i++) { tableMetadata.AddIndexReference(_queryPlanResult.IndexDescs[i].IndexName, statementContext.StatementName); } } SubordinateQueryPlannerUtil.QueryPlanLogOnExpr(tableMetadata.IsQueryPlanLogging, TableServiceImpl.QueryPlanLog, _queryPlanResult, statementContext.Annotations); }
public override OnExprViewResult DetermineOnExprView(AgentInstanceContext agentInstanceContext, IList <StopCallback> stopCallbacks, bool isRecoveringResilient) { // get result set processor and aggregation services Pair <ResultSetProcessor, AggregationService> pair = EPStatementStartMethodHelperUtil.StartResultSetAndAggregation(_resultSetProcessorPrototype, agentInstanceContext, false, null); // get named window processor instance NamedWindowProcessorInstance processorInstance = _processor.GetProcessorInstance(agentInstanceContext); // obtain on-expr view EventTable[] indexes = null; if (_queryPlan.IndexDescs != null) { indexes = SubordinateQueryPlannerUtil.RealizeTables( _queryPlan.IndexDescs, _processor.NamedWindowType, processorInstance.RootViewInstance.IndexRepository, processorInstance.RootViewInstance.DataWindowContents, processorInstance.TailViewInstance.AgentInstanceContext, isRecoveringResilient); } SubordWMatchExprLookupStrategy strategy = _queryPlan.Factory.Realize(indexes, agentInstanceContext, processorInstance.RootViewInstance.DataWindowContents, processorInstance.RootViewInstance.VirtualDataWindow); NamedWindowOnExprBaseView onExprBaseView = _onExprFactory.Make(strategy, processorInstance.RootViewInstance, agentInstanceContext, pair.First); return(new OnExprViewResult(onExprBaseView, pair.Second)); }
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); }
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 SubSelectStrategyRealization Instantiate( EPServicesContext services, Viewable viewableRoot, AgentInstanceContext agentInstanceContext, IList <StopCallback> stopCallbackList, int subqueryNumber, bool isRecoveringResilient) { SubselectAggregationPreprocessorBase subselectAggregationPreprocessor = null; AggregationService aggregationService = null; if (_aggregationServiceFactory != null) { aggregationService = _aggregationServiceFactory.AggregationServiceFactory.MakeService( agentInstanceContext, agentInstanceContext.StatementContext.EngineImportService, true, subqueryNumber); if (_groupByKeys == null) { if (_filterExprEval == null) { subselectAggregationPreprocessor = new SubselectAggregationPreprocessorUnfilteredUngrouped( aggregationService, _filterExprEval, null); } else { subselectAggregationPreprocessor = new SubselectAggregationPreprocessorFilteredUngrouped(aggregationService, _filterExprEval, null); } } else { if (_filterExprEval == null) { subselectAggregationPreprocessor = new SubselectAggregationPreprocessorUnfilteredGrouped( aggregationService, _filterExprEval, _groupByKeys); } else { subselectAggregationPreprocessor = new SubselectAggregationPreprocessorFilteredGrouped( aggregationService, _filterExprEval, _groupByKeys); } } } SubordTableLookupStrategy subqueryLookup; if (_optionalNamedWindowProcessor != null) { NamedWindowProcessorInstance instance = _optionalNamedWindowProcessor.GetProcessorInstance(agentInstanceContext); if (_queryPlan == null) { if (instance.RootViewInstance.IsQueryPlanLogging && NamedWindowRootView.QueryPlanLog.IsInfoEnabled) { NamedWindowRootView.QueryPlanLog.Info("shared, full table scan"); } subqueryLookup = new SubordFullTableScanLookupStrategyLocking( instance.RootViewInstance.DataWindowContents, agentInstanceContext.EpStatementAgentInstanceHandle.StatementAgentInstanceLock); } else { EventTable[] tables = null; if (!_optionalNamedWindowProcessor.IsVirtualDataWindow) { tables = SubordinateQueryPlannerUtil.RealizeTables( _queryPlan.IndexDescs, instance.RootViewInstance.EventType, instance.RootViewInstance.IndexRepository, instance.RootViewInstance.DataWindowContents, agentInstanceContext, isRecoveringResilient); } SubordTableLookupStrategy strategy = _queryPlan.LookupStrategyFactory.MakeStrategy( tables, instance.RootViewInstance.VirtualDataWindow); subqueryLookup = new SubordIndexedTableLookupStrategyLocking( strategy, instance.TailViewInstance.AgentInstanceContext.AgentInstanceLock); } } else { TableStateInstance state = _tableService.GetState( _optionalTableMetadata.TableName, agentInstanceContext.AgentInstanceId); ILockable iLock = agentInstanceContext.StatementContext.IsWritesToTables ? state.TableLevelRWLock.WriteLock : state.TableLevelRWLock.ReadLock; if (_queryPlan == null) { subqueryLookup = new SubordFullTableScanTableLookupStrategy(iLock, state.IterableTableScan); } else { EventTable[] indexes = new EventTable[_queryPlan.IndexDescs.Length]; for (int i = 0; i < indexes.Length; i++) { indexes[i] = state.IndexRepository.GetIndexByDesc(_queryPlan.IndexDescs[i].IndexMultiKey); } subqueryLookup = _queryPlan.LookupStrategyFactory.MakeStrategy(indexes, null); subqueryLookup = new SubordIndexedTableLookupTableStrategy(subqueryLookup, iLock); } } return(new SubSelectStrategyRealization( subqueryLookup, subselectAggregationPreprocessor, aggregationService, Collections.GetEmptyMap <ExprPriorNode, ExprPriorEvalStrategy>(), Collections.GetEmptyMap <ExprPreviousNode, ExprPreviousEvalStrategy>(), null, null)); }
/// <summary> /// Create the table lookup plan for a from-stream to look up in an indexed stream /// using the columns supplied in the query graph and looking at the actual indexes available /// and their index number. /// </summary> /// <param name="queryGraph">contains properties joining the 2 streams</param> /// <param name="currentLookupStream">stream to use key values from</param> /// <param name="indexedStream">stream to look up in</param> /// <param name="indexSpecs">index specification defining indexes to be created for stream</param> /// <param name="typesPerStream">event types for each stream</param> /// <returns>plan for performing a lookup in a given table using one of the indexes supplied</returns> public static TableLookupPlan CreateLookupPlan(QueryGraph queryGraph, int currentLookupStream, int indexedStream, QueryPlanIndex indexSpecs, EventType[] typesPerStream, TableMetadata indexedStreamTableMeta) { var queryGraphValue = queryGraph.GetGraphValue(currentLookupStream, indexedStream); var hashKeyProps = queryGraphValue.HashKeyProps; var hashPropsKeys = hashKeyProps.Keys; var hashIndexProps = hashKeyProps.Indexed.ToArray(); var rangeProps = queryGraphValue.RangeProps; var rangePropsKeys = rangeProps.Keys; var rangeIndexProps = rangeProps.Indexed.ToArray(); var pairIndexHashRewrite = indexSpecs.GetIndexNum(hashIndexProps, rangeIndexProps); var indexNum = pairIndexHashRewrite == null ? null : pairIndexHashRewrite.First; // handle index redirection towards unique index if (pairIndexHashRewrite != null && pairIndexHashRewrite.Second != null) { var indexes = pairIndexHashRewrite.Second; var newHashIndexProps = new string[indexes.Length]; IList <QueryGraphValueEntryHashKeyed> newHashKeys = new List <QueryGraphValueEntryHashKeyed>(); for (var i = 0; i < indexes.Length; i++) { newHashIndexProps[i] = hashIndexProps[indexes[i]]; newHashKeys.Add(hashPropsKeys[indexes[i]]); } hashIndexProps = newHashIndexProps; hashPropsKeys = newHashKeys; rangeIndexProps = new string[0]; rangePropsKeys = Collections.GetEmptyList <QueryGraphValueEntryRange>(); } // no direct hash or range lookups if (hashIndexProps.Length == 0 && rangeIndexProps.Length == 0) { // handle single-direction 'in' keyword var singles = queryGraphValue.InKeywordSingles; if (!singles.Key.IsEmpty()) { QueryGraphValueEntryInKeywordSingleIdx single = null; indexNum = null; if (indexedStreamTableMeta != null) { var indexes = singles.Indexed; var count = 0; foreach (var index in indexes) { Pair <IndexMultiKey, EventTableIndexEntryBase> indexPairFound = EventTableIndexUtil.FindIndexBestAvailable( indexedStreamTableMeta.EventTableIndexMetadataRepo.Indexes, Collections.SingletonSet(index), Collections.GetEmptySet <string>(), null); if (indexPairFound != null) { indexNum = new TableLookupIndexReqKey(indexPairFound.Second.OptionalIndexName, indexedStreamTableMeta.TableName); single = singles.Key[count]; } count++; } } else { single = singles.Key[0]; var pairIndex = indexSpecs.GetIndexNum(new string[] { singles.Indexed[0] }, null); indexNum = pairIndex.First; } if (indexNum != null) { return(new InKeywordTableLookupPlanSingleIdx(currentLookupStream, indexedStream, indexNum, single.KeyExprs)); } } // handle multi-direction 'in' keyword var multis = queryGraphValue.InKeywordMulti; if (!multis.IsEmpty()) { if (indexedStreamTableMeta != null) { return(GetFullTableScanTable(currentLookupStream, indexedStream, indexedStreamTableMeta)); } QueryGraphValuePairInKWMultiIdx multi = multis[0]; var indexNameArray = new TableLookupIndexReqKey[multi.Indexed.Length]; var foundAll = true; for (var i = 0; i < multi.Indexed.Length; i++) { var identNode = (ExprIdentNode)multi.Indexed[i]; var pairIndex = indexSpecs.GetIndexNum(new string[] { identNode.ResolvedPropertyName }, null); if (pairIndex == null) { foundAll = false; } else { indexNameArray[i] = pairIndex.First; } } if (foundAll) { return(new InKeywordTableLookupPlanMultiIdx(currentLookupStream, indexedStream, indexNameArray, multi.Key.KeyExpr)); } } // We don't use a keyed index but use the full stream set as the stream does not have any indexes // If no such full set index exists yet, add to specs if (indexedStreamTableMeta != null) { return(GetFullTableScanTable(currentLookupStream, indexedStream, indexedStreamTableMeta)); } if (indexNum == null) { indexNum = new TableLookupIndexReqKey(indexSpecs.AddIndex(null, null)); } return(new FullTableScanLookupPlan(currentLookupStream, indexedStream, indexNum)); } if (indexNum == null) { throw new IllegalStateException("Failed to query plan as index for " + hashIndexProps.Render() + " and " + rangeIndexProps.Render() + " in the index specification"); } if (indexedStreamTableMeta != null) { var indexPairFound = EventTableIndexUtil.FindIndexBestAvailable(indexedStreamTableMeta.EventTableIndexMetadataRepo.Indexes, ToSet(hashIndexProps), ToSet(rangeIndexProps), null); if (indexPairFound != null) { var indexKeyInfo = SubordinateQueryPlannerUtil.CompileIndexKeyInfo(indexPairFound.First, hashIndexProps, GetHashKeyFuncsAsSubProp(hashPropsKeys), rangeIndexProps, GetRangeFuncsAsSubProp(rangePropsKeys)); if (indexKeyInfo.OrderedKeyCoercionTypes.IsCoerce || indexKeyInfo.OrderedRangeCoercionTypes.IsCoerce) { return(GetFullTableScanTable(currentLookupStream, indexedStream, indexedStreamTableMeta)); } hashPropsKeys = ToHashKeyFuncs(indexKeyInfo.OrderedHashDesc); hashIndexProps = IndexedPropDesc.GetIndexProperties(indexPairFound.First.HashIndexedProps); rangePropsKeys = ToRangeKeyFuncs(indexKeyInfo.OrderedRangeDesc); rangeIndexProps = IndexedPropDesc.GetIndexProperties(indexPairFound.First.RangeIndexedProps); indexNum = new TableLookupIndexReqKey(indexPairFound.Second.OptionalIndexName, indexedStreamTableMeta.TableName); // the plan will be created below if (hashIndexProps.Length == 0 && rangeIndexProps.Length == 0) { return(GetFullTableScanTable(currentLookupStream, indexedStream, indexedStreamTableMeta)); } } else { return(GetFullTableScanTable(currentLookupStream, indexedStream, indexedStreamTableMeta)); } } // straight keyed-index lookup if (hashIndexProps.Length > 0 && rangeIndexProps.Length == 0) { TableLookupPlan tableLookupPlan; if (hashPropsKeys.Count == 1) { tableLookupPlan = new IndexedTableLookupPlanSingle(currentLookupStream, indexedStream, indexNum, hashPropsKeys[0]); } else { tableLookupPlan = new IndexedTableLookupPlanMulti(currentLookupStream, indexedStream, indexNum, hashPropsKeys); } // Determine coercion required var coercionTypes = CoercionUtil.GetCoercionTypesHash(typesPerStream, currentLookupStream, indexedStream, hashPropsKeys, hashIndexProps); if (coercionTypes.IsCoerce) { // check if there already are coercion types for this index var existCoercionTypes = indexSpecs.GetCoercionTypes(hashIndexProps); if (existCoercionTypes != null) { for (var i = 0; i < existCoercionTypes.Length; i++) { coercionTypes.CoercionTypes[i] = TypeHelper.GetCompareToCoercionType(existCoercionTypes[i], coercionTypes.CoercionTypes[i]); } } indexSpecs.SetCoercionTypes(hashIndexProps, coercionTypes.CoercionTypes); } return(tableLookupPlan); } // sorted index lookup if (hashIndexProps.Length == 0 && rangeIndexProps.Length == 1) { QueryGraphValueEntryRange range = rangePropsKeys[0]; return(new SortedTableLookupPlan(currentLookupStream, indexedStream, indexNum, range)); } // composite range and index lookup else { return(new CompositeTableLookupPlan(currentLookupStream, indexedStream, indexNum, hashPropsKeys, rangePropsKeys)); } }
/// <summary> /// Create the table lookup plan for a from-stream to look up in an indexed stream /// using the columns supplied in the query graph and looking at the actual indexes available /// and their index number. /// </summary> /// <param name="queryGraph">contains properties joining the 2 streams</param> /// <param name="currentLookupStream">stream to use key values from</param> /// <param name="indexedStream">stream to look up in</param> /// <param name="indexSpecs">index specification defining indexes to be created for stream</param> /// <param name="typesPerStream">event types for each stream</param> /// <param name="indexedStreamTableMeta">table info</param> /// <param name="indexedStreamIsVDW">vdw indicators</param> /// <param name="raw">raw statement information</param> /// <param name="serdeResolver">serde resolver</param> /// <returns>plan for performing a lookup in a given table using one of the indexes supplied</returns> public static TableLookupPlanDesc CreateLookupPlan( QueryGraphForge queryGraph, int currentLookupStream, int indexedStream, bool indexedStreamIsVDW, QueryPlanIndexForge indexSpecs, EventType[] typesPerStream, TableMetaData indexedStreamTableMeta, StatementRawInfo raw, SerdeCompileTimeResolver serdeResolver) { var queryGraphValue = queryGraph.GetGraphValue(currentLookupStream, indexedStream); var hashKeyProps = queryGraphValue.HashKeyProps; var hashPropsKeys = hashKeyProps.Keys; var hashIndexProps = hashKeyProps.Indexed; var rangeProps = queryGraphValue.RangeProps; var rangePropsKeys = rangeProps.Keys; var rangeIndexProps = rangeProps.Indexed; var pairIndexHashRewrite = indexSpecs.GetIndexNum(hashIndexProps, rangeIndexProps); var indexNum = pairIndexHashRewrite == null ? null : pairIndexHashRewrite.First; // handle index redirection towards unique index if (pairIndexHashRewrite != null && pairIndexHashRewrite.Second != null) { var indexes = pairIndexHashRewrite.Second; var newHashIndexProps = new string[indexes.Length]; IList<QueryGraphValueEntryHashKeyedForge> newHashKeys = new List<QueryGraphValueEntryHashKeyedForge>(); for (var i = 0; i < indexes.Length; i++) { newHashIndexProps[i] = hashIndexProps[indexes[i]]; newHashKeys.Add(hashPropsKeys[indexes[i]]); } hashIndexProps = newHashIndexProps; hashPropsKeys = newHashKeys; rangeIndexProps = new string[0]; rangePropsKeys = Collections.GetEmptyList<QueryGraphValueEntryRangeForge>(); } // no direct hash or range lookups if (hashIndexProps.Length == 0 && rangeIndexProps.Length == 0) { // handle single-direction 'in' keyword var singles = queryGraphValue.InKeywordSingles; if (!singles.Key.IsEmpty()) { QueryGraphValueEntryInKeywordSingleIdxForge single = null; indexNum = null; if (indexedStreamTableMeta != null) { var indexes = singles.Indexed; var count = 0; foreach (var index in indexes) { var indexPairFound = EventTableIndexUtil.FindIndexBestAvailable( indexedStreamTableMeta.IndexMetadata.Indexes, Collections.SingletonSet(index), Collections.GetEmptySet<string>(), null); if (indexPairFound != null) { indexNum = new TableLookupIndexReqKey( indexPairFound.Second.OptionalIndexName, indexPairFound.Second.OptionalIndexModuleName, indexedStreamTableMeta.TableName); single = singles.Key[count]; } count++; } } else { single = singles.Key[0]; var pairIndex = indexSpecs.GetIndexNum( new[] {singles.Indexed[0]}, new string[0]); indexNum = pairIndex.First; } if (indexNum != null) { var forge = new InKeywordTableLookupPlanSingleIdxForge( currentLookupStream, indexedStream, indexedStreamIsVDW, typesPerStream, indexNum, single.KeyExprs); return new TableLookupPlanDesc(forge, EmptyList<StmtClassForgeableFactory>.Instance); } } // handle multi-direction 'in' keyword var multis = queryGraphValue.InKeywordMulti; if (!multis.IsEmpty()) { if (indexedStreamTableMeta != null) { return GetFullTableScanTable( currentLookupStream, indexedStream, indexedStreamIsVDW, typesPerStream, indexedStreamTableMeta); } var multi = multis[0]; var indexNameArray = new TableLookupIndexReqKey[multi.Indexed.Length]; var foundAll = true; for (var i = 0; i < multi.Indexed.Length; i++) { var identNode = (ExprIdentNode) multi.Indexed[i]; var pairIndex = indexSpecs.GetIndexNum( new[] {identNode.ResolvedPropertyName}, new string[0]); if (pairIndex == null) { foundAll = false; } else { indexNameArray[i] = pairIndex.First; } } if (foundAll) { var forge = new InKeywordTableLookupPlanMultiIdxForge( currentLookupStream, indexedStream, indexedStreamIsVDW, typesPerStream, indexNameArray, multi.Key.KeyExpr); return new TableLookupPlanDesc(forge, EmptyList<StmtClassForgeableFactory>.Instance); } } // We don't use a keyed index but use the full stream set as the stream does not have any indexes // If no such full set index exists yet, add to specs if (indexedStreamTableMeta != null) { return GetFullTableScanTable( currentLookupStream, indexedStream, indexedStreamIsVDW, typesPerStream, indexedStreamTableMeta); } if (indexNum == null) { indexNum = new TableLookupIndexReqKey( indexSpecs.AddIndex(new string[0], new Type[0], typesPerStream[indexedStream]), null); } var forgeX = new FullTableScanLookupPlanForge(currentLookupStream, indexedStream, indexedStreamIsVDW, typesPerStream, indexNum); return new TableLookupPlanDesc(forgeX, EmptyList<StmtClassForgeableFactory>.Instance); } if (indexNum == null) { throw new IllegalStateException( "Failed to query plan as index for " + hashIndexProps.RenderAny() + " and " + rangeIndexProps.RenderAny() + " in the index specification"); } if (indexedStreamTableMeta != null) { var indexPairFound = EventTableIndexUtil.FindIndexBestAvailable( indexedStreamTableMeta.IndexMetadata.Indexes, ToSet(hashIndexProps), ToSet(rangeIndexProps), null); if (indexPairFound != null) { var indexKeyInfo = SubordinateQueryPlannerUtil.CompileIndexKeyInfo( indexPairFound.First, hashIndexProps, GetHashKeyFuncsAsSubProp(hashPropsKeys), rangeIndexProps, GetRangeFuncsAsSubProp(rangePropsKeys)); if (indexKeyInfo.OrderedKeyCoercionTypes.IsCoerce || indexKeyInfo.OrderedRangeCoercionTypes.IsCoerce) { return GetFullTableScanTable( currentLookupStream, indexedStream, indexedStreamIsVDW, typesPerStream, indexedStreamTableMeta); } hashPropsKeys = ToHashKeyFuncs(indexKeyInfo.OrderedHashDesc); hashIndexProps = IndexedPropDesc.GetIndexProperties(indexPairFound.First.HashIndexedProps); rangePropsKeys = ToRangeKeyFuncs(indexKeyInfo.OrderedRangeDesc); rangeIndexProps = IndexedPropDesc.GetIndexProperties(indexPairFound.First.RangeIndexedProps); indexNum = new TableLookupIndexReqKey( indexPairFound.Second.OptionalIndexName, indexPairFound.Second.OptionalIndexModuleName, indexedStreamTableMeta.TableName); // the plan will be created below if (hashIndexProps.Length == 0 && rangeIndexProps.Length == 0) { return GetFullTableScanTable( currentLookupStream, indexedStream, indexedStreamIsVDW, typesPerStream, indexedStreamTableMeta); } } else { return GetFullTableScanTable( currentLookupStream, indexedStream, indexedStreamIsVDW, typesPerStream, indexedStreamTableMeta); } } // straight keyed-index lookup if (hashIndexProps.Length > 0 && rangeIndexProps.Length == 0) { // Determine coercion required var coercionTypes = CoercionUtil.GetCoercionTypesHash( typesPerStream, currentLookupStream, indexedStream, hashPropsKeys, hashIndexProps); if (coercionTypes.IsCoerce) { // check if there already are coercion types for this index var existCoercionTypes = indexSpecs.GetCoercionTypes(hashIndexProps); if (existCoercionTypes != null) { for (var i = 0; i < existCoercionTypes.Length; i++) { coercionTypes.CoercionTypes[i] = existCoercionTypes[i] .GetCompareToCoercionType(coercionTypes.CoercionTypes[i]); } } if (!indexSpecs.Items.IsEmpty()) { indexSpecs.SetCoercionTypes(hashIndexProps, coercionTypes.CoercionTypes); } } var coercionTypesArray = coercionTypes.CoercionTypes; MultiKeyClassRef tableLookupMultiKey = null; IList<StmtClassForgeableFactory> additionalForgeables = EmptyList<StmtClassForgeableFactory>.Instance; if (indexNum.TableName != null) { var tableMultiKeyPlan = MultiKeyPlanner.PlanMultiKey(coercionTypesArray, true, raw, serdeResolver); tableLookupMultiKey = tableMultiKeyPlan.ClassRef; additionalForgeables = tableMultiKeyPlan.MultiKeyForgeables; } var forge = new IndexedTableLookupPlanHashedOnlyForge( currentLookupStream, indexedStream, indexedStreamIsVDW, typesPerStream, indexNum, hashPropsKeys.ToArray(), indexSpecs, coercionTypesArray, tableLookupMultiKey); return new TableLookupPlanDesc(forge, additionalForgeables); } // sorted index lookup var coercionTypesRange = CoercionUtil.GetCoercionTypesRange( typesPerStream, indexedStream, rangeIndexProps, rangePropsKeys); var coercionTypesHash = CoercionUtil.GetCoercionTypesHash( typesPerStream, currentLookupStream, indexedStream, hashPropsKeys, hashIndexProps); if (hashIndexProps.Length == 0 && rangeIndexProps.Length == 1) { var range = rangePropsKeys[0]; Type coercionType = null; if (coercionTypesRange.IsCoerce) { coercionType = coercionTypesRange.CoercionTypes[0]; } SortedTableLookupPlanForge forge = new SortedTableLookupPlanForge( currentLookupStream, indexedStream, indexedStreamIsVDW, typesPerStream, indexNum, range, coercionType); return new TableLookupPlanDesc(forge, EmptyList<StmtClassForgeableFactory>.Instance); } else { MultiKeyClassRef tableLookupMultiKey = null; IList<StmtClassForgeableFactory> additionalForgeables = EmptyList<StmtClassForgeableFactory>.Instance; if (indexNum.TableName != null) { MultiKeyPlan tableMultiKeyPlan = MultiKeyPlanner.PlanMultiKey(coercionTypesHash.CoercionTypes, true, raw, serdeResolver); tableLookupMultiKey = tableMultiKeyPlan.ClassRef; additionalForgeables = tableMultiKeyPlan.MultiKeyForgeables; } // composite range and index lookup CompositeTableLookupPlanForge forge = new CompositeTableLookupPlanForge( currentLookupStream, indexedStream, indexedStreamIsVDW, typesPerStream, indexNum, hashPropsKeys, coercionTypesHash.CoercionTypes, rangePropsKeys, coercionTypesRange.CoercionTypes, indexSpecs, tableLookupMultiKey); return new TableLookupPlanDesc(forge, additionalForgeables); } }
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 OnTriggerPlan HandleContextFactoryOnTrigger( string className, CodegenNamespaceScope namespaceScope, string classPostfix, NamedWindowMetaData namedWindow, TableMetaData table, OnTriggerWindowPlan planDesc, StatementBaseInfo @base, StatementCompileTimeServices services) { // validate context var infraName = planDesc.OnTriggerDesc.WindowName; var infraTitle = (namedWindow != null ? "Named window" : "Table") + " '" + infraName + "'"; var infraContextName = namedWindow != null ? namedWindow.ContextName : table.OptionalContextName; var infraModuleName = namedWindow != null ? namedWindow.NamedWindowModuleName : table.TableModuleName; var infraEventType = namedWindow != null ? namedWindow.EventType : table.InternalEventType; var resultEventType = namedWindow != null ? namedWindow.EventType : table.PublicEventType; var infraVisibility = namedWindow != null ? namedWindow.EventType.Metadata.AccessModifier : table.TableVisibility; ValidateOnExpressionContext(planDesc.ContextName, infraContextName, infraTitle); List<StmtClassForgeableFactory> additionalForgeables = new List<StmtClassForgeableFactory>(); // validate expressions and plan subselects var validationResult = OnTriggerPlanValidator.ValidateOnTriggerPlan( infraEventType, planDesc.OnTriggerDesc, planDesc.StreamSpec, planDesc.ActivatorResult, planDesc.SubselectActivation, @base, services); additionalForgeables.AddAll(validationResult.AdditionalForgeables); var validatedJoin = validationResult.ValidatedJoin; var activatorResultEventType = planDesc.ActivatorResult.ActivatorResultEventType; var pair = IndexHintPair.GetIndexHintPair( planDesc.OnTriggerDesc, @base.StatementSpec.StreamSpecs[0].OptionalStreamName, @base.StatementRawInfo, services); var indexHint = pair.IndexHint; var excludePlanHint = pair.ExcludePlanHint; var enabledSubqueryIndexShare = namedWindow != null && namedWindow.IsEnableIndexShare; var isVirtualWindow = namedWindow != null && namedWindow.IsVirtualDataWindow; var indexMetadata = namedWindow != null ? namedWindow.IndexMetadata : table.IndexMetadata; var optionalUniqueKeySet = namedWindow != null ? namedWindow.UniquenessAsSet : table.UniquenessAsSet; // query plan var onlyUseExistingIndexes = table != null; SubordinateWMatchExprQueryPlanResult planResult = SubordinateQueryPlanner.PlanOnExpression( validatedJoin, activatorResultEventType, indexHint, enabledSubqueryIndexShare, -1, excludePlanHint, isVirtualWindow, indexMetadata, infraEventType, optionalUniqueKeySet, onlyUseExistingIndexes, @base.StatementRawInfo, services); SubordinateWMatchExprQueryPlanForge queryPlan = planResult.Forge; additionalForgeables.AddAll(planResult.AdditionalForgeables); // indicate index dependencies if (queryPlan.Indexes != null && infraVisibility == NameAccessModifier.PUBLIC) { foreach (var index in queryPlan.Indexes) { services.ModuleDependenciesCompileTime.AddPathIndex( namedWindow != null, infraName, infraModuleName, index.IndexName, index.IndexModuleName, services.NamedWindowCompileTimeRegistry, services.TableCompileTimeRegistry); } } var onTriggerType = planDesc.OnTriggerDesc.OnTriggerType; var activator = planDesc.ActivatorResult.Activator; var subselectForges = validationResult.SubselectForges; var tableAccessForges = validationResult.TableAccessForges; IList<StmtClassForgeable> forgeables = new List<StmtClassForgeable>(2); StatementAgentInstanceFactoryOnTriggerInfraBaseForge forge; var classNameRSP = CodeGenerationIDGenerator.GenerateClassNameSimple( typeof(ResultSetProcessorFactoryProvider), classPostfix); ResultSetProcessorDesc resultSetProcessor; if (onTriggerType == OnTriggerType.ON_SELECT) { resultSetProcessor = validationResult.ResultSetProcessorPrototype; var outputEventType = resultSetProcessor.ResultEventType; var insertInto = false; TableMetaData optionalInsertIntoTable = null; var insertIntoDesc = @base.StatementSpec.Raw.InsertIntoDesc; var addToFront = false; if (insertIntoDesc != null) { insertInto = true; optionalInsertIntoTable = services.TableCompileTimeResolver.Resolve(insertIntoDesc.EventTypeName); var optionalInsertIntoNamedWindow = services.NamedWindowCompileTimeResolver.Resolve(insertIntoDesc.EventTypeName); addToFront = optionalInsertIntoNamedWindow != null || optionalInsertIntoTable != null; } var selectAndDelete = planDesc.OnTriggerDesc.IsDeleteAndSelect; var distinct = @base.StatementSpec.SelectClauseCompiled.IsDistinct; MultiKeyPlan distinctMultiKeyPlan = MultiKeyPlanner.PlanMultiKeyDistinct( distinct, outputEventType, @base.StatementRawInfo, services.SerdeResolver); additionalForgeables.AddAll(distinctMultiKeyPlan.MultiKeyForgeables); forge = new StatementAgentInstanceFactoryOnTriggerInfraSelectForge( activator, outputEventType, subselectForges, tableAccessForges, namedWindow, table, queryPlan, classNameRSP, insertInto, addToFront, optionalInsertIntoTable, selectAndDelete, distinct, distinctMultiKeyPlan.ClassRef); } else { var defaultSelectAllSpec = new StatementSpecCompiled(); defaultSelectAllSpec.SelectClauseCompiled.WithSelectExprList(new SelectClauseElementWildcard()); defaultSelectAllSpec.Raw.SelectStreamDirEnum = SelectClauseStreamSelectorEnum.RSTREAM_ISTREAM_BOTH; StreamTypeService typeService = new StreamTypeServiceImpl( new[] {resultEventType}, new[] {infraName}, new[] {false}, false, false); resultSetProcessor = ResultSetProcessorFactoryFactory.GetProcessorPrototype( new ResultSetSpec(defaultSelectAllSpec), typeService, null, new bool[1], false, @base.ContextPropertyRegistry, false, false, @base.StatementRawInfo, services); if (onTriggerType == OnTriggerType.ON_DELETE) { forge = new StatementAgentInstanceFactoryOnTriggerInfraDeleteForge( activator, resultEventType, subselectForges, tableAccessForges, classNameRSP, namedWindow, table, queryPlan); } else if (onTriggerType == OnTriggerType.ON_UPDATE) { var updateDesc = (OnTriggerWindowUpdateDesc) planDesc.OnTriggerDesc; EventBeanUpdateHelperForge updateHelper = EventBeanUpdateHelperForgeFactory.Make( infraName, (EventTypeSPI) infraEventType, updateDesc.Assignments, validationResult.ZeroStreamAliasName, activatorResultEventType, namedWindow != null, @base.StatementName, services.EventTypeAvroHandler); forge = new StatementAgentInstanceFactoryOnTriggerInfraUpdateForge( activator, resultEventType, subselectForges, tableAccessForges, classNameRSP, namedWindow, table, queryPlan, updateHelper); } else if (onTriggerType == OnTriggerType.ON_MERGE) { var onMergeTriggerDesc = (OnTriggerMergeDesc) planDesc.OnTriggerDesc; var onMergeHelper = new InfraOnMergeHelperForge( onMergeTriggerDesc, activatorResultEventType, planDesc.StreamSpec.OptionalStreamName, infraName, (EventTypeSPI) infraEventType, @base.StatementRawInfo, services, table); forge = new StatementAgentInstanceFactoryOnTriggerInfraMergeForge( activator, resultEventType, subselectForges, tableAccessForges, classNameRSP, namedWindow, table, queryPlan, onMergeHelper); } else { throw new IllegalStateException("Unrecognized trigger type " + onTriggerType); } } forgeables.Add( new StmtClassForgeableRSPFactoryProvider( classNameRSP, resultSetProcessor, namespaceScope, @base.StatementRawInfo)); var queryPlanLogging = services.Configuration.Common.Logging.IsEnableQueryPlan; SubordinateQueryPlannerUtil.QueryPlanLogOnExpr( queryPlanLogging, QUERY_PLAN_LOG, queryPlan, @base.StatementSpec.Annotations, services.ImportServiceCompileTime); StmtClassForgeableAIFactoryProviderOnTrigger onTrigger = new StmtClassForgeableAIFactoryProviderOnTrigger(className, namespaceScope, forge); return new OnTriggerPlan(onTrigger, forgeables, resultSetProcessor.SelectSubscriberDescriptor, additionalForgeables); }