/// <summary> /// Walks the chain of lookups and constructs lookup strategy and plan specification based /// on the index specifications. /// </summary> /// <param name="lookupStream">the stream to construct the query plan for</param> /// <param name="bestChain">the chain that the lookup follows to make best use of indexes</param> /// <param name="queryGraph">the repository for key properties to indexes</param> /// <param name="indexSpecsPerStream">specifications of indexes</param> /// <param name="typesPerStream">event types for each stream</param> /// <param name="isHistorical">indicator for each stream if it is a historical streams or not</param> /// <param name="historicalStreamIndexLists">index management, populated for the query plan</param> /// <param name="tablesPerStream">tables</param> /// <param name="streamJoinAnalysisResult">stream join analysis</param> /// <param name="raw">raw statement information</param> /// <param name="serdeResolver">serde resolver</param> /// <returns>NestedIterationNode with lookups attached underneath</returns> public static QueryPlanNodeForgeDesc CreateStreamPlan( int lookupStream, int[] bestChain, QueryGraphForge queryGraph, QueryPlanIndexForge[] indexSpecsPerStream, EventType[] typesPerStream, bool[] isHistorical, HistoricalStreamIndexListForge[] historicalStreamIndexLists, TableMetaData[] tablesPerStream, StreamJoinAnalysisResultCompileTime streamJoinAnalysisResult, StatementRawInfo raw, SerdeCompileTimeResolver serdeResolver) { var nestedIterNode = new NestedIterationNodeForge(bestChain); var currentLookupStream = lookupStream; var additionalForgeables = new List<StmtClassForgeableFactory>(); // Walk through each successive lookup for (var i = 0; i < bestChain.Length; i++) { var indexedStream = bestChain[i]; QueryPlanNodeForge node; if (isHistorical[indexedStream]) { if (historicalStreamIndexLists[indexedStream] == null) { historicalStreamIndexLists[indexedStream] = new HistoricalStreamIndexListForge( indexedStream, typesPerStream, queryGraph); } historicalStreamIndexLists[indexedStream].AddIndex(currentLookupStream); node = new HistoricalDataPlanNodeForge( indexedStream, lookupStream, currentLookupStream, typesPerStream.Length, null); } else { var tableLookupPlan = CreateLookupPlan( queryGraph, currentLookupStream, indexedStream, streamJoinAnalysisResult.IsVirtualDW(indexedStream), indexSpecsPerStream[indexedStream], typesPerStream, tablesPerStream[indexedStream], raw, serdeResolver); node = new TableLookupNodeForge(tableLookupPlan.Forge); additionalForgeables.AddAll(tableLookupPlan.AdditionalForgeables); } nestedIterNode.AddChildNode(node); currentLookupStream = bestChain[i]; } return new QueryPlanNodeForgeDesc(nestedIterNode, additionalForgeables); }
public void TestCreateStreamPlan() { QueryPlanIndexForge[] indexes = QueryPlanIndexBuilder.BuildIndexSpec(queryGraph, typesPerStream, new string[queryGraph.NumStreams][][]); for (int i = 0; i < indexes.Length; i++) { log.Debug(".testCreateStreamPlan index " + i + " = " + indexes[i]); } QueryPlanNodeForge plan = NStreamQueryPlanBuilder.CreateStreamPlan(0, new int[] { 2, 4, 3, 1 }, queryGraph, indexes, typesPerStream, new bool[5], null, new TableMetaData[queryGraph.NumStreams], new StreamJoinAnalysisResultCompileTime(5)); log.Debug(".testCreateStreamPlan plan=" + plan); Assert.IsTrue(plan is NestedIterationNodeForge); NestedIterationNodeForge nested = (NestedIterationNodeForge)plan; TableLookupNodeForge tableLookupSpec = (TableLookupNodeForge)nested.ChildNodes[0]; // Check lookup strategy for first lookup IndexedTableLookupPlanHashedOnlyForge lookupStrategySpec = (IndexedTableLookupPlanHashedOnlyForge)tableLookupSpec.LookupStrategySpec; Assert.AreEqual("P01", ((ExprIdentNode)(lookupStrategySpec.HashKeys[0]).KeyExpr).ResolvedPropertyName); Assert.AreEqual(0, lookupStrategySpec.LookupStream); Assert.AreEqual(2, lookupStrategySpec.IndexedStream); Assert.IsNotNull(lookupStrategySpec.IndexNum); // Check lookup strategy for last lookup tableLookupSpec = (TableLookupNodeForge)nested.ChildNodes[3]; FullTableScanLookupPlanForge unkeyedSpecScan = (FullTableScanLookupPlanForge)tableLookupSpec.LookupStrategySpec; Assert.AreEqual(1, unkeyedSpecScan.IndexedStream); Assert.IsNotNull(unkeyedSpecScan.IndexNum); }