/// <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)); }
private static IList <LookupInstructionPlan> BuildLookupInstructions( int rootStreamNum, LinkedHashMap <int, int[]> substreamsPerStream, bool[] requiredPerStream, string[] streamNames, QueryGraph queryGraph, QueryPlanIndex[] indexSpecs, EventType[] typesPerStream, OuterJoinDesc[] outerJoinDescList, bool[] isHistorical, HistoricalStreamIndexList[] historicalStreamIndexLists, ExprEvaluatorContext exprEvaluatorContext, TableMetadata[] tablesPerStream) { IList <LookupInstructionPlan> result = new List <LookupInstructionPlan>(); foreach (int fromStream in substreamsPerStream.Keys) { var substreams = substreamsPerStream.Get(fromStream); // for streams with no substreams we don't need to look up if (substreams.Length == 0) { continue; } var plans = new TableLookupPlan[substreams.Length]; var historicalPlans = new HistoricalDataPlanNode[substreams.Length]; for (var i = 0; i < substreams.Length; i++) { var toStream = substreams[i]; if (isHistorical[toStream]) { // There may not be an outer-join descriptor, use if provided to build the associated expression ExprNode outerJoinExpr = null; if (outerJoinDescList.Length > 0) { OuterJoinDesc outerJoinDesc; if (toStream == 0) { outerJoinDesc = outerJoinDescList[0]; } else { outerJoinDesc = outerJoinDescList[toStream - 1]; } outerJoinExpr = outerJoinDesc.MakeExprNode(exprEvaluatorContext); } if (historicalStreamIndexLists[toStream] == null) { historicalStreamIndexLists[toStream] = new HistoricalStreamIndexList(toStream, typesPerStream, queryGraph); } historicalStreamIndexLists[toStream].AddIndex(fromStream); historicalPlans[i] = new HistoricalDataPlanNode(toStream, rootStreamNum, fromStream, typesPerStream.Length, outerJoinExpr); } else { plans[i] = NStreamQueryPlanBuilder.CreateLookupPlan(queryGraph, fromStream, toStream, indexSpecs[toStream], typesPerStream, tablesPerStream[toStream]); } } var fromStreamName = streamNames[fromStream]; var instruction = new LookupInstructionPlan(fromStream, fromStreamName, substreams, plans, historicalPlans, requiredPerStream); result.Add(instruction); } return(result); }