HHH-11511 - QuerySyntaxException when sorting by a column using a JPQL reserved keyword

This commit is contained in:
Andrea Boriero 2017-02-23 09:31:48 +00:00 committed by Vlad Mihalcea
parent c53939b181
commit dc714695e4
3 changed files with 98 additions and 3 deletions

View File

@ -200,6 +200,9 @@ tokens
public void firstPathTokenWeakKeywords() throws TokenStreamException {
}
public void handlePrimaryExpressionDotIdent() throws TokenStreamException {
}
/**
* Manages the case of an optional FROM allowing the path to start with the "from" keyword
*/
@ -456,7 +459,7 @@ propertyFetch
//## GROUP_BY path ( COMMA path )*;
groupByClause
: GROUP^
: GROUP^
"by"! expression ( COMMA! expression )*
(havingClause)?
;
@ -706,7 +709,7 @@ quantifiedExpression
// * method call ( '.' ident '(' exprList ') )
// * function : differentiated from method call via explicit keyword
atom
: primaryExpression
: {handlePrimaryExpressionDotIdent();} primaryExpression
(
DOT^ identifier
( options { greedy=true; } :
@ -785,7 +788,7 @@ vectorExpr
// the method looks a head to find keywords after DOT and turns them into identifiers.
identPrimary
: i:identPrimaryBase { handleDotIdent(); }
( options { greedy=true; } : DOT^ ( identifier | ELEMENTS | o:OBJECT { #o.setType(IDENT); } ) )*
( options { greedy=true; } : DOT^ ( identifier { handleDotIdent(); } | ELEMENTS | o:OBJECT { #o.setType(IDENT); } ) )*
( options { greedy=true; } :
( op:OPEN^ { #op.setType(METHOD_CALL);} e:exprList CLOSE! ) {
AST path = #e.getFirstChild();

View File

@ -389,6 +389,21 @@ public final class HqlParser extends HqlBaseParser {
}
}
@Override
public void handlePrimaryExpressionDotIdent() throws TokenStreamException {
if ( LA( 2 ) == DOT && LA( 3 ) != IDENT ) {
// See if the second lookahead token can be an identifier.
HqlToken t = (HqlToken) LT( 3 );
if ( t.isPossibleID() ) {
// Set it!
t.setType( IDENT );
if ( LOG.isDebugEnabled() ) {
LOG.debugf( "handleDotIdent() : new LT(3) token - %s", LT( 1 ) );
}
}
}
}
@Override
public void weakKeywords() throws TokenStreamException {

View File

@ -0,0 +1,77 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.test.ordered;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Version;
import org.hibernate.Session;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.junit.Test;
/**
* @author Andrea Boriero
*/
public class UseReservedKeywordInOrderByTest extends BaseCoreFunctionalTestCase {
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class[]{Person.class, Location.class};
}
@Test
public void testOrderBy(){
try(Session s = openSession();){
s.createQuery( "from Person p order by p.update" );
}
}
@Test
public void testMultipleOrderBy(){
try(Session s = openSession();){
s.createQuery( "from Person p order by p.name,p.update" );
}
}
@Test
public void testOrderByOfAssociationEntityField(){
try(Session s = openSession();){
s.createQuery( "from Person p order by p.location.update" );
}
}
@Entity(name = "Person")
public static class Person {
@Id
private Integer id;
private String name;
@Column(name = "update_date")
private Date update;
@OneToOne
Location location;
}
@Entity(name = "Location")
public static class Location{
@Id
private Integer id;
private String city;
@Column(name = "update_date")
private Date update;
}
}