From: <hib...@li...> - 2006-03-02 03:13:37
|
Author: ste...@jb... Date: 2006-03-01 22:13:33 -0500 (Wed, 01 Mar 2006) New Revision: 9530 Modified: trunk/Hibernate3/src/org/hibernate/hql/ast/tree/FromElementFactory.java trunk/Hibernate3/test/org/hibernate/test/hql/ASTParserLoadingTest.java trunk/Hibernate3/test/org/hibernate/test/hql/HQLTest.java Log: HHH-1248 : explicit joins to collections in subquery result in join conditions being dropped from sql Modified: trunk/Hibernate3/src/org/hibernate/hql/ast/tree/FromElementFactory.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/hql/ast/tree/FromElementFactory.java 2006-03-01 17:44:27 UTC (rev 9529) +++ trunk/Hibernate3/src/org/hibernate/hql/ast/tree/FromElementFactory.java 2006-03-02 03:13:33 UTC (rev 9530) @@ -16,6 +16,7 @@ import org.hibernate.type.CollectionType; import org.hibernate.type.EntityType; import org.hibernate.type.Type; +import org.hibernate.util.StringHelper; import antlr.ASTFactory; import antlr.SemanticException; @@ -182,12 +183,15 @@ collectionType = queryableCollection.getCollectionType(); String roleAlias = fromClause.getAliasGenerator().createName( role ); - // Subqueries create 'special' implied from nodes - // because correlated subselects can't use an - // ANSI-style join + // Correlated subqueries create 'special' implied from nodes + // because correlated subselects can't use an ANSI-style join boolean explicitSubqueryFromElement = fromClause.isSubQuery() && !implied; if ( explicitSubqueryFromElement ) { - implied = true; + String pathRoot = StringHelper.root( path ); + FromElement origin = fromClause.getFromElement( pathRoot ); + if ( origin == null || origin.getFromClause() != fromClause ) { + implied = true; + } } Type elementType = queryableCollection.getElementType(); Modified: trunk/Hibernate3/test/org/hibernate/test/hql/ASTParserLoadingTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/hql/ASTParserLoadingTest.java 2006-03-01 17:44:27 UTC (rev 9529) +++ trunk/Hibernate3/test/org/hibernate/test/hql/ASTParserLoadingTest.java 2006-03-02 03:13:33 UTC (rev 9530) @@ -68,6 +68,50 @@ }; } + public void testCollectionJoinsInSubselect() { + // HHH-1248 : initially FromElementFactory treated any explicit join + // as an implied join so that theta-style joins would always be used. + // This was because correlated subqueries cannot use ANSI-style joins + // for the correlation. However, this special treatment was not limited + // to only correlated subqueries; it was applied to any subqueries -> + // which in-and-of-itself is not necessarily bad. But somewhere later + // the choices made there caused joins to be dropped. + Session s = openSession(); + String qryString = + "select a.id, a.description" + + " from Animal a" + + " left join a.offspring" + + " where a in (" + + " select a1 from Animal a1" + + " left join a1.offspring o" + + " where a1.id=1" + + ")"; + s.createQuery( qryString ).list(); + qryString = + "select h.id, h.description" + + " from Human h" + + " left join h.friends" + + " where h in (" + + " select h1" + + " from Human h1" + + " left join h1.friends f" + + " where h1.id=1" + + ")"; + s.createQuery( qryString ).list(); + qryString = + "select h.id, h.description" + + " from Human h" + + " left join h.friends f" + + " where f in (" + + " select h1" + + " from Human h1" + + " left join h1.friends f1" + + " where h = f1" + + ")"; + s.createQuery( qryString ).list(); + s.close(); + } + public void testCollectionFetchWithDistinctionAndLimit() { // create some test data... Session s = openSession(); Modified: trunk/Hibernate3/test/org/hibernate/test/hql/HQLTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/hql/HQLTest.java 2006-03-01 17:44:27 UTC (rev 9529) +++ trunk/Hibernate3/test/org/hibernate/test/hql/HQLTest.java 2006-03-02 03:13:33 UTC (rev 9530) @@ -53,7 +53,7 @@ assertTranslation( "select h from Human as h join fetch h.nickNames" ); } - public void testCollectionJoinsInSubselectFailureExpected() { + public void testCollectionJoinsInSubselect() { // caused by some goofiness in FromElementFactory that tries to // handle correlated subqueries (but fails miserably) even though this // is not a correlated subquery. HHH-1248 @@ -67,6 +67,17 @@ " where a1.id=1" + ")" ); + assertTranslation( + "select h.id, h.description" + + " from Human h" + + " left join h.friends" + + " where h in (" + + " select h1" + + " from Human h1" + + " left join h1.friends f" + + " where h1.id=1" + + ")" + ); } public void testEmptyInListFailureExpected() { |