/// <summary> /// Build query plan. /// </summary> /// <param name="typesPerStream">event types for each stream</param> /// <param name="queryGraph">navigability info</param> /// <param name="optionalOuterJoinType">outer join type, null if not an outer join</param> /// <param name="uniqueIndexProps">The unique index props.</param> /// <param name="tablesPerStream">The tables per stream.</param> /// <returns> /// query plan /// </returns> public static QueryPlan Build(EventType[] typesPerStream, QueryGraph queryGraph, OuterJoinType?optionalOuterJoinType, string[][][] uniqueIndexProps, TableMetadata[] tablesPerStream) { var indexSpecs = QueryPlanIndexBuilder.BuildIndexSpec(queryGraph, typesPerStream, uniqueIndexProps); var execNodeSpecs = new QueryPlanNode[2]; var lookupPlans = new TableLookupPlan[2]; // plan lookup from 1 to zero lookupPlans[1] = NStreamQueryPlanBuilder.CreateLookupPlan(queryGraph, 1, 0, indexSpecs[0], typesPerStream, tablesPerStream[0]); // plan lookup from zero to 1 lookupPlans[0] = NStreamQueryPlanBuilder.CreateLookupPlan(queryGraph, 0, 1, indexSpecs[1], typesPerStream, tablesPerStream[1]); execNodeSpecs[0] = new TableLookupNode(lookupPlans[0]); execNodeSpecs[1] = new TableLookupNode(lookupPlans[1]); if (optionalOuterJoinType != null) { if ((optionalOuterJoinType.Equals(OuterJoinType.LEFT)) || (optionalOuterJoinType.Equals(OuterJoinType.FULL))) { execNodeSpecs[0] = new TableOuterLookupNode(lookupPlans[0]); } if ((optionalOuterJoinType.Equals(OuterJoinType.RIGHT)) || (optionalOuterJoinType.Equals(OuterJoinType.FULL))) { execNodeSpecs[1] = new TableOuterLookupNode(lookupPlans[1]); } } return(new QueryPlan(indexSpecs, execNodeSpecs)); }
public void TestMakeExec() { var indexesPerStream = new IDictionary <TableLookupIndexReqKey, EventTable> [2]; indexesPerStream[1] = new HashMap <TableLookupIndexReqKey, EventTable>(); indexesPerStream[1].Put(new TableLookupIndexReqKey("idx1"), new UnindexedEventTable(0)); var spec = new TableLookupNode(new FullTableScanLookupPlan(0, 1, new TableLookupIndexReqKey("idx1"))); var execNode = spec.MakeExec("ABC", "001", null, indexesPerStream, null, new Viewable[2], null, new VirtualDWView[2], new ILockable[2]); var exec = (TableLookupExecNode)execNode; Assert.AreSame(indexesPerStream[1].Get(new TableLookupIndexReqKey("idx1")), ((FullTableScanLookupStrategy)exec.LookupStrategy).EventIndex); Assert.AreEqual(1, exec.IndexedStream); }
/// <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> /// <returns>NestedIterationNode with lookups attached underneath</returns> internal static QueryPlanNode CreateStreamPlan( int lookupStream, int[] bestChain, QueryGraph queryGraph, QueryPlanIndex[] indexSpecsPerStream, EventType[] typesPerStream, bool[] isHistorical, HistoricalStreamIndexList[] historicalStreamIndexLists, TableMetadata[] tablesPerStream) { var nestedIterNode = new NestedIterationNode(bestChain); var currentLookupStream = lookupStream; // Walk through each successive lookup for (var i = 0; i < bestChain.Length; i++) { var indexedStream = bestChain[i]; QueryPlanNode node; if (isHistorical[indexedStream]) { if (historicalStreamIndexLists[indexedStream] == null) { historicalStreamIndexLists[indexedStream] = new HistoricalStreamIndexList(indexedStream, typesPerStream, queryGraph); } historicalStreamIndexLists[indexedStream].AddIndex(currentLookupStream); node = new HistoricalDataPlanNode(indexedStream, lookupStream, currentLookupStream, typesPerStream.Length, null); } else { var tableLookupPlan = CreateLookupPlan(queryGraph, currentLookupStream, indexedStream, indexSpecsPerStream[indexedStream], typesPerStream, tablesPerStream[indexedStream]); node = new TableLookupNode(tableLookupPlan); } nestedIterNode.AddChildNode(node); currentLookupStream = bestChain[i]; } return(nestedIterNode); }