Exemplo n.º 1
0
        public void TestRecursiveBuild()
        {
            var streamNum           = 2;
            var queryGraph          = new QueryGraphForge(6, null, false);
            var outerInnerGraph     = new OuterInnerDirectionalGraph(6);
            var completedStreams    = new HashSet <int>();
            var substreamsPerStream = new LinkedHashMap <int, int[]>();
            var requiredPerStream   = new bool[6];

            outerInnerGraph.Add(3, 2).Add(2, 1).Add(4, 3).Add(1, 0).Add(3, 5);
            var fake = supportExprNodeFactory.MakeIdentNode("TheString", "s0");

            queryGraph.AddStrictEquals(2, "", fake, 3, "", fake);
            queryGraph.AddStrictEquals(3, "", fake, 4, "", fake);
            queryGraph.AddStrictEquals(3, "", fake, 5, "", fake);
            queryGraph.AddStrictEquals(2, "", fake, 1, "", fake);
            queryGraph.AddStrictEquals(1, "", fake, 0, "", fake);

            ISet <InterchangeablePair <int, int> > innerJoins = new HashSet <InterchangeablePair <int, int> >();
            var innerJoinGraph = new InnerJoinGraph(6, innerJoins);
            var streamStack    = new Stack <int>();

            NStreamOuterQueryPlanBuilder.RecursiveBuild(
                streamNum,
                streamStack,
                queryGraph,
                outerInnerGraph,
                innerJoinGraph,
                completedStreams,
                substreamsPerStream,
                requiredPerStream,
                new DependencyGraph(6, false));

            Assert.AreEqual(6, substreamsPerStream.Count);
            EPAssertionUtil.AssertEqualsExactOrder(substreamsPerStream.Get(2), new[] { 3, 1 });
            EPAssertionUtil.AssertEqualsExactOrder(substreamsPerStream.Get(3), new[] { 4, 5 });
            EPAssertionUtil.AssertEqualsExactOrder(substreamsPerStream.Get(1), new[] { 0 });
            EPAssertionUtil.AssertEqualsExactOrder(substreamsPerStream.Get(4), new int[] { });
            EPAssertionUtil.AssertEqualsExactOrder(substreamsPerStream.Get(5), new int[] { });
            EPAssertionUtil.AssertEqualsExactOrder(substreamsPerStream.Get(0), new int[] { });

            NStreamOuterQueryPlanBuilder.VerifyJoinedPerStream(2, substreamsPerStream);
            EPAssertionUtil.AssertEqualsExactOrder(
                requiredPerStream,
                new[] { false, false, false, true, true, false }
                );
        }
        /// <summary>
        ///     Builds a graph of outer joins given the outer join information from the statement.
        ///     Eliminates right and left joins and full joins by placing the information in a graph object.
        /// </summary>
        /// <param name="numStreams">is the number of streams</param>
        /// <param name="outerJoinDescList">list of outer join stream numbers and property names</param>
        /// <returns>graph object</returns>
        public static OuterInnerDirectionalGraph GraphOuterJoins(
            int numStreams,
            OuterJoinDesc[] outerJoinDescList)
        {
            if (outerJoinDescList.Length + 1 != numStreams) {
                throw new ArgumentException("Number of outer join descriptors and number of streams not matching up");
            }

            var graph = new OuterInnerDirectionalGraph(numStreams);

            for (var i = 0; i < outerJoinDescList.Length; i++) {
                var desc = outerJoinDescList[i];
                var streamMax = i + 1; // the outer join must references streams less then streamMax

                // Check outer join on-expression, if provided
                int streamOne;
                int streamTwo;
                int lowerStream;
                int higherStream;
                if (desc.OptLeftNode != null) {
                    streamOne = desc.OptLeftNode.StreamId;
                    streamTwo = desc.OptRightNode.StreamId;

                    if (streamOne > streamMax ||
                        streamTwo > streamMax ||
                        streamOne == streamTwo) {
                        throw new ArgumentException("Outer join descriptors reference future streams, or same streams");
                    }

                    // Determine who is the first stream in the streams listed
                    lowerStream = streamOne;
                    higherStream = streamTwo;
                    if (streamOne > streamTwo) {
                        lowerStream = streamTwo;
                        higherStream = streamOne;
                    }
                }
                else {
                    streamOne = i;
                    streamTwo = i + 1;
                    lowerStream = i;
                    higherStream = i + 1;

                    graph.AddUnqualifiedNavigable(streamOne, streamTwo);
                }

                // Add to graph
                if (desc.OuterJoinType == OuterJoinType.FULL) {
                    graph.Add(streamOne, streamTwo);
                    graph.Add(streamTwo, streamOne);
                }
                else if (desc.OuterJoinType == OuterJoinType.LEFT) {
                    graph.Add(lowerStream, higherStream);
                }
                else if (desc.OuterJoinType == OuterJoinType.RIGHT) {
                    graph.Add(higherStream, lowerStream);
                }
                else if (desc.OuterJoinType == OuterJoinType.INNER) {
                    // no navigability for inner joins
                }
                else {
                    throw new ArgumentException(
                        "Outer join descriptors join type not handled, type=" + desc.OuterJoinType);
                }
            }

            return graph;
        }