/// <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; }