Skip to content

Commit 57401b9

Browse files
committed
HHH-1689 - Support subqueries in HQL as CASE statement alternatives;
SQM-30 - test
1 parent caf902d commit 57401b9

File tree

3 files changed

+109
-11
lines changed

3 files changed

+109
-11
lines changed

hibernate-core/src/main/antlr/hql-sql.g

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -611,10 +611,36 @@ arithmeticExpr
611611
;
612612
613613
caseExpr
614-
: #(CASE { inCase = true; } (#(WHEN logicalExpr expr))+ (#(ELSE expr))?) { inCase = false; }
615-
| #(CASE2 { inCase = true; } expr (#(WHEN expr expr))+ (#(ELSE expr))?) { inCase = false; }
614+
: simpleCaseExpression
615+
| searchedCaseExpression
616616
;
617617
618+
expressionOrSubQuery
619+
: expr
620+
| query
621+
;
622+
623+
simpleCaseExpression
624+
: #(CASE2 {inCase=true;} expressionOrSubQuery (simpleCaseWhenClause)+ (elseClause)?) {inCase=false;}
625+
;
626+
627+
simpleCaseWhenClause
628+
: #(WHEN expressionOrSubQuery expressionOrSubQuery)
629+
;
630+
631+
elseClause
632+
: #(ELSE expressionOrSubQuery)
633+
;
634+
635+
searchedCaseExpression
636+
: #(CASE {inCase = true;} (searchedCaseWhenClause)+ (elseClause)?) {inCase = false;}
637+
;
638+
639+
searchedCaseWhenClause
640+
: #(WHEN logicalExpr expressionOrSubQuery)
641+
;
642+
643+
618644
//TODO: I don't think we need this anymore .. how is it different to
619645
// maxelements, etc, which are handled by functionCall
620646
collectionFunction

hibernate-core/src/main/antlr/hql.g

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -639,23 +639,34 @@ unaryExpression
639639
| quantifiedExpression
640640
| atom
641641
;
642-
642+
643643
caseExpression
644-
: CASE^ (whenClause)+ (elseClause)? END!
645-
| CASE^ { #CASE.setType(CASE2); } unaryExpression (altWhenClause)+ (elseClause)? END!
644+
// NOTE : the unaryExpression rule contains the subQuery rule
645+
: simpleCaseStatement
646+
| searchedCaseStatement
646647
;
647-
648-
whenClause
649-
: (WHEN^ logicalExpression THEN! unaryExpression)
648+
649+
simpleCaseStatement
650+
: CASE^ unaryExpression (simpleCaseWhenClause)+ (elseClause)? END! {
651+
#simpleCaseStatement.setType(CASE2);
652+
}
650653
;
651-
652-
altWhenClause
654+
655+
simpleCaseWhenClause
653656
: (WHEN^ unaryExpression THEN! unaryExpression)
654657
;
655-
658+
656659
elseClause
657660
: (ELSE^ unaryExpression)
658661
;
662+
663+
searchedCaseStatement
664+
: CASE^ (searchedCaseWhenClause)+ (elseClause)? END!
665+
;
666+
667+
searchedCaseWhenClause
668+
: (WHEN^ logicalExpression THEN! unaryExpression)
669+
;
659670

660671
quantifiedExpression
661672
: ( SOME^ | EXISTS^ | ALL^ | ANY^ )

hibernate-core/src/test/java/org/hibernate/test/hql/SubQueryTest.java

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import org.hibernate.Session;
1919

20+
import org.hibernate.testing.FailureExpected;
2021
import org.hibernate.testing.TestForIssue;
2122
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
2223
import org.junit.Test;
@@ -155,4 +156,64 @@ public void testCorrelatedJoin() {
155156
s.close();
156157

157158
}
159+
160+
@Test
161+
@TestForIssue( jiraKey = "HHH-1689, SQM-30" )
162+
public void testSubQueryAsSearchedCaseResultExpression() {
163+
final String query = "SELECT CASE WHEN l.id IS NOT NULL THEN (SELECT COUNT(r.id) FROM Root r) ELSE 0 END FROM Leaf l";
164+
// simple syntax check
165+
Session s = openSession();
166+
s.beginTransaction();
167+
s.createQuery( query ).list();
168+
s.getTransaction().commit();
169+
s.close();
170+
}
171+
172+
@Test
173+
@TestForIssue( jiraKey = "HHH-1689, SQM-30" )
174+
public void testSubQueryAsSearchedCaseExpression() {
175+
final String query = "SELECT CASE WHEN (SELECT COUNT(r.id) FROM Root r) > 1 THEN 1 ELSE 0 END FROM Leaf l";
176+
// simple syntax check
177+
Session s = openSession();
178+
s.beginTransaction();
179+
s.createQuery( query ).list();
180+
s.getTransaction().commit();
181+
s.close();
182+
}
183+
184+
@Test
185+
@TestForIssue( jiraKey = "HHH-1689, SQM-30" )
186+
public void testSubQueryAsCaseElseResultExpression() {
187+
final String query = "SELECT CASE WHEN l.id > 1 THEN 1 ELSE (SELECT COUNT(r.id) FROM Root r) END FROM Leaf l";
188+
// simple syntax check
189+
Session s = openSession();
190+
s.beginTransaction();
191+
s.createQuery( query ).list();
192+
s.getTransaction().commit();
193+
s.close();
194+
}
195+
196+
@Test
197+
@TestForIssue( jiraKey = "HHH-1689, SQM-30" )
198+
public void testSubQueryAsSimpleCaseTestExpression() {
199+
final String query = "SELECT CASE (SELECT COUNT(r.id) FROM Root r) WHEN 1 THEN 1 ELSE 0 END FROM Leaf l";
200+
// simple syntax check
201+
Session s = openSession();
202+
s.beginTransaction();
203+
s.createQuery( query ).list();
204+
s.getTransaction().commit();
205+
s.close();
206+
}
207+
208+
@Test
209+
@TestForIssue( jiraKey = "HHH-1689, SQM-30" )
210+
public void testSubQueryAsSimpleCaseWhenExpression() {
211+
final String query = "SELECT CASE l.id WHEN (SELECT COUNT(r.id) FROM Root r) THEN 1 ELSE 0 END FROM Leaf l";
212+
// simple syntax check
213+
Session s = openSession();
214+
s.beginTransaction();
215+
s.createQuery( query ).list();
216+
s.getTransaction().commit();
217+
s.close();
218+
}
158219
}

0 commit comments

Comments
 (0)