Skip to content

Commit

Permalink
HHH-14148 fix issue mapping order SQL fragment could produce incorrec…
Browse files Browse the repository at this point in the history
…t SQL
  • Loading branch information
NathanQingyangXu authored and beikov committed Sep 14, 2020
1 parent f91ed82 commit cf94259
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 4 deletions.
9 changes: 7 additions & 2 deletions hibernate-core/src/main/antlr/sql-gen.g
Expand Up @@ -146,7 +146,7 @@ selectStatement
from
( #(WHERE { out(" where "); } whereExpr ) )?
( #(GROUP { out(" group by "); } groupExprs ( #(HAVING { out(" having "); } booleanExpr[false]) )? ) )?
( #(ORDER { out(" order by "); } orderExprs ) )?
( #(ORDER { out(" order by "); } orderBySqlFragmentOrExprs ) )?
)
;

Expand Down Expand Up @@ -191,6 +191,11 @@ whereClauseExpr
| booleanExpr[ false ]
;
orderBySqlFragmentOrExprs
: sqlToken // for the purpose of mapping-defined orderBy SQL fragment
| orderExprs
;
orderExprs { String ordExp = null; String ordDir = null; String ordNul = null; }
// TODO: remove goofy space before the comma when we don't have to regression test anymore.
// Dialect is provided a hook to render each ORDER BY element, so the expression is being captured instead of
Expand Down Expand Up @@ -277,7 +282,7 @@ distinctOrAll
;
countExpr
// Syntacitic predicate resolves star all by itself, avoiding a conflict with STAR in expr.
// Syntactic predicate resolves star all by itself, avoiding a conflict with STAR in expr.
: ROW_STAR { out("*"); }
| simpleExpr
;
Expand Down
Expand Up @@ -24,15 +24,17 @@
import org.hibernate.Hibernate;
import org.hibernate.NullPrecedence;
import org.hibernate.Session;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.cfg.Configuration;
import org.hibernate.dialect.H2Dialect;
import org.hibernate.dialect.MySQLDialect;
import org.hibernate.dialect.Oracle8iDialect;
import org.hibernate.dialect.SQLServer2008Dialect;
import org.hibernate.dialect.SQLServer2012Dialect;
import org.hibernate.dialect.SQLServerDialect;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.graph.RootGraph;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.collection.QueryableCollection;
import org.hibernate.query.Query;
import org.hibernate.sql.SimpleSelect;
import org.hibernate.testing.RequiresDialect;
import org.hibernate.testing.TestForIssue;
Expand Down Expand Up @@ -515,6 +517,28 @@ public void testOrderByOneToManyWithJoinTable() {
s.close();
}

@Test
@TestForIssue( jiraKey = "HHH-14148" )
@RequiresDialect(value = { H2Dialect.class, MySQLDialect.class, SQLServer2008Dialect.class },
comment = "By default H2 places NULL values first, so testing 'NULLS LAST' expression. " +
"For MySQL and SQL Server 2008 testing overridden Dialect#renderOrderByElement(String, String, String, NullPrecedence) method. " +
"MySQL and SQL Server 2008 does not support NULLS FIRST / LAST syntax at the moment, so transforming the expression to 'CASE WHEN ...'.")
public void testNullPrecedenceWithOrderBySqlFragment() {
inTransaction( session -> {
final RootGraph<Order> graph = session.createEntityGraph( Order.class );
graph.addAttributeNodes( "itemList" );

Query<Order> query = session.createQuery( "from Order", Order.class );
query.applyFetchGraph( graph );
query.getResultList(); // before HHH-14148 is fixed, incorrect SQL would be generated ending with " nulls last nulls last"
} );
}

@Override
protected void configure(Configuration configuration) {
configuration.setProperty( AvailableSettings.DEFAULT_NULL_ORDERING, "last" );
}

@Override
protected Class[] getAnnotatedClasses() {
return new Class[] {
Expand Down

0 comments on commit cf94259

Please sign in to comment.