Example #1
0
        /// <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));
        }
Example #2
0
        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);
        }
Example #3
0
        /// <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);
        }