コード例 #1
0
        /// <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;
        }