Author: stliu
Date: 2011-01-11 04:37:46 -0500 (Tue, 11 Jan 2011)
New Revision: 20875
Modified:
core/branches/Branch_3_3_2_GA_CP/core/src/main/antlr/hql.g
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/hql/classic/FromParser.java
core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/hql/HQLTest.java
Log:
JBPAPP-5405 HHH-5727 : Collection member declaration not handling optional AS in HQL.
Modified: core/branches/Branch_3_3_2_GA_CP/core/src/main/antlr/hql.g
===================================================================
--- core/branches/Branch_3_3_2_GA_CP/core/src/main/antlr/hql.g 2011-01-08 16:10:57 UTC
(rev 20874)
+++ core/branches/Branch_3_3_2_GA_CP/core/src/main/antlr/hql.g 2011-01-11 09:37:46 UTC
(rev 20875)
@@ -355,7 +355,7 @@
;
inCollectionDeclaration!
- : IN! OPEN! p:path CLOSE! a:alias {
+ : IN! OPEN! p:path CLOSE! a:asAlias {
#inCollectionDeclaration = #([JOIN, "join"], [INNER,
"inner"], #p, #a);
}
;
Modified:
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/hql/classic/FromParser.java
===================================================================
---
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/hql/classic/FromParser.java 2011-01-08
16:10:57 UTC (rev 20874)
+++
core/branches/Branch_3_3_2_GA_CP/core/src/main/java/org/hibernate/hql/classic/FromParser.java 2011-01-11
09:37:46 UTC (rev 20875)
@@ -51,7 +51,14 @@
private boolean afterJoinType;
private int joinType;
private boolean afterFetch;
-
+
+ //support collection member declarations
+ //e.g. "from Customer c, in(c.orders) as o"
+ private boolean memberDeclarations;
+ private boolean expectingPathExpression;
+ private boolean afterMemberDeclarations;
+ private String collectionName;
+
private static final int NONE = -666;
private static final Map JOIN_TYPES = new HashMap();
@@ -113,15 +120,34 @@
afterClass = true;
}
else if ( lcToken.equals( "in" ) ) {
- if ( !expectingIn ) throw new QueryException( "unexpected token: in" );
- afterIn = true;
- expectingIn = false;
+ if (alias == null ){
+ memberDeclarations = true;
+ afterMemberDeclarations = false;
+ }
+ else if ( !expectingIn ) {
+ throw new QueryException( "unexpected token: in" );
+ } else {
+ afterIn = true;
+ expectingIn = false;
+ }
+
}
else if ( lcToken.equals( "as" ) ) {
if ( !expectingAs ) throw new QueryException( "unexpected token: as" );
afterAs = true;
expectingAs = false;
}
+ else if ( "(".equals( token ) ){
+ if( !memberDeclarations ) throw new QueryException( "unexpected token: ("
);
+ //TODO alias should be null here
+ expectingPathExpression = true;
+
+ }
+ else if ( ")".equals( token ) ){
+// memberDeclarations = false;
+// expectingPathExpression = false;
+ afterMemberDeclarations = true;
+ }
else {
if ( afterJoinType ) throw new QueryException( "join expected: " + token );
@@ -141,6 +167,9 @@
if ( entityName != null ) {
q.setAliasName( token, entityName );
}
+ else if(collectionName != null ) {
+ q.setAliasName( token, collectionName );
+ }
else {
throw new QueryException( "unexpected: as " + token );
}
@@ -148,6 +177,10 @@
expectingJoin = true;
expectingAs = false;
entityName = null;
+ collectionName = null;
+ memberDeclarations = false;
+ expectingPathExpression = false;
+ afterMemberDeclarations = false;
}
else if ( afterIn ) {
@@ -180,6 +213,16 @@
afterClass = false;
expectingJoin = true;
}
+ else if( memberDeclarations && expectingPathExpression ){
+ expectingAs = true;
+ peParser.setJoinType( JoinFragment.INNER_JOIN );
+ peParser.setUseThetaStyleJoin( false );
+ ParserHelper.parse( peParser, q.unalias( token ), ParserHelper.PATH_SEPARATORS, q );
+ if ( !peParser.isCollectionValued() ) throw new QueryException( "path expression
did not resolve to collection: " + token );
+ collectionName = peParser.addFromCollection( q );
+ expectingPathExpression = false;
+ memberDeclarations = false;
+ }
else {
// handle a path expression or class name that
@@ -238,6 +281,7 @@
public void start(QueryTranslatorImpl q) {
entityName = null;
+ collectionName = null;
alias = null;
afterIn = false;
afterAs = false;
@@ -245,10 +289,19 @@
expectingJoin = false;
expectingIn = false;
expectingAs = false;
+ memberDeclarations = false;
+ expectingPathExpression = false;
+ afterMemberDeclarations = false;
joinType = NONE;
}
public void end(QueryTranslatorImpl q) {
+ if( afterMemberDeclarations ){
+ //The exception throwned by the AST query translator contains the error token
location, respensent by line and colum,
+ //but it hard to get that info here.
+ throw new QueryException("alias not specified for IN");
+ }
+
}
}
Modified:
core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/hql/HQLTest.java
===================================================================
---
core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/hql/HQLTest.java 2011-01-08
16:10:57 UTC (rev 20874)
+++
core/branches/Branch_3_3_2_GA_CP/testsuite/src/test/java/org/hibernate/test/hql/HQLTest.java 2011-01-11
09:37:46 UTC (rev 20875)
@@ -103,6 +103,18 @@
public void testJoinFetchCollectionOfValues() {
assertTranslation( "select h from Human as h join fetch h.nickNames" );
}
+ public void testCollectionMemberDeclarations() {
+ assertTranslation( "from Customer c, in(c.orders) o" );
+ assertTranslation( "from Customer c, in(c.orders) as o" );
+ assertTranslation( "select c.name from Customer c, in(c.orders) as o where c.id =
o.id.customerId" );
+ }
+ public void testCollectionMemberDeclarationsFailureExpected(){
+ // both these two query translators throw exeptions for this HQL since
+ // IN asks an alias, but the difference is that the error message from AST
+ // contains the error token location (by lines and columns), which is hardly
+ // to get from Classic query translator --stliu
+ assertTranslation( "from Customer c, in(c.orders)" );
+ }
public void testCollectionJoinsInSubselect() {
// caused by some goofiness in FromElementFactory that tries to
Show replies by date