/* * Hibernate, Relational Persistence for Idiomatic Java * * License: Apache License, Version 2.0 * See the LICENSE file in the root directory or visit http://www.apache.org/licenses/LICENSE-2.0 */ package org.hibernate.sqm.test.hql; import org.hibernate.query.sqm.SemanticException; import org.hibernate.query.sqm.tree.SqmQuerySpec; import org.hibernate.query.sqm.tree.SqmSelectStatement; import org.hibernate.query.sqm.tree.expression.LiteralIntegerSqmExpression; import org.hibernate.query.sqm.tree.expression.LiteralLongSqmExpression; import org.hibernate.query.sqm.tree.expression.SqmExpression; import org.hibernate.query.sqm.tree.from.SqmFromElementSpace; import org.hibernate.query.sqm.tree.from.SqmFromClause; import org.hibernate.query.sqm.tree.predicate.AndSqmPredicate; import org.hibernate.query.sqm.tree.predicate.InSubQuerySqmPredicate; import org.hibernate.query.sqm.tree.predicate.RelationalSqmPredicate; import org.hibernate.sqm.test.domain.Person; import org.hibernate.sqm.test.domain.StandardModelTest; import org.junit.Test; import static org.hamcrest.CoreMatchers.instanceOf; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.notNullValue; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; /** * @author Steve Ebersole */ public class SimpleSemanticQueryBuilderTest extends StandardModelTest { @Test public void simpleIntegerLiteralsTest() { SqmSelectStatement selectStatement = interpretSelect( "select a.nickName from Person a where 1=2" ); assertThat( selectStatement.getQuerySpec().getWhereClause().getPredicate(), instanceOf( RelationalSqmPredicate.class ) ); final RelationalSqmPredicate predicate = (RelationalSqmPredicate) selectStatement.getQuerySpec().getWhereClause().getPredicate(); SqmExpression lhs = predicate.getLeftHandExpression(); assertNotNull( lhs ); assertTrue( lhs instanceof LiteralIntegerSqmExpression ); assertEquals( 1, ((LiteralIntegerSqmExpression) lhs).getLiteralValue().intValue() ); Object rhs = predicate.getRightHandExpression(); assertNotNull( rhs ); assertTrue( rhs instanceof LiteralIntegerSqmExpression ); assertEquals( 2, ((LiteralIntegerSqmExpression) rhs).getLiteralValue().intValue() ); } @Test public void simpleLongLiteralsTest() { SqmSelectStatement selectStatement = interpretSelect( "select a.nickName from Person a where 1L=2L" ); assertThat( selectStatement.getQuerySpec().getWhereClause().getPredicate(), instanceOf( RelationalSqmPredicate.class ) ); final RelationalSqmPredicate predicate = (RelationalSqmPredicate) selectStatement.getQuerySpec().getWhereClause().getPredicate(); SqmExpression lhs = predicate.getLeftHandExpression(); assertNotNull( lhs ); assertTrue( lhs instanceof LiteralLongSqmExpression ); assertEquals( 1L, ((LiteralLongSqmExpression) lhs).getLiteralValue().longValue() ); Object rhs = predicate.getRightHandExpression(); assertNotNull( rhs ); assertTrue( rhs instanceof LiteralLongSqmExpression ); assertEquals( 2L, ( (LiteralLongSqmExpression) rhs ).getLiteralValue().longValue() ); } @Test public void testAttributeJoinWithOnPredicate() throws Exception { final String query = "select a from Person a left outer join a.mate c on c.numberOfToes > 5 and c.numberOfToes < 20"; final SqmSelectStatement selectStatement = interpretSelect( query ); SqmQuerySpec querySpec = selectStatement.getQuerySpec(); assertNotNull( querySpec ); } @Test public void testSimpleUncorrelatedSubQuery() throws Exception { final String query = "select a from Person a where a.mate IN (select e from Person e where e.numberOfToes = 5 )"; final SqmSelectStatement selectStatement = interpretSelect( query ); SqmFromClause fromClause = selectStatement.getQuerySpec().getFromClause(); assertNotNull( fromClause ); assertThat( fromClause.getFromElementSpaces().size(), is( 1 ) ); SqmFromElementSpace fromElementSpace = fromClause.getFromElementSpaces().get( 0 ); assertThat( fromElementSpace.getRoot(), notNullValue() ); assertThat( fromElementSpace.getJoins().size(), is( 0 ) ); assertThat( fromElementSpace.getRoot().getEntityName(), is( "org.hibernate.sqm.test.domain.Person" ) ); assertThat( fromElementSpace.getRoot().getIdentificationVariable(), is( "a" ) ); // assertions against the root sqm predicate that defines the sub-sqm assertThat( selectStatement.getQuerySpec().getWhereClause().getPredicate(), notNullValue() ); assertThat( selectStatement.getQuerySpec().getWhereClause().getPredicate(), is( instanceOf( InSubQuerySqmPredicate.class ) ) ); InSubQuerySqmPredicate subQueryPredicate = (InSubQuerySqmPredicate) selectStatement.getQuerySpec() .getWhereClause() .getPredicate(); SqmFromClause subqueryFromClause = subQueryPredicate.getSubQueryExpression().getQuerySpec().getFromClause(); assertNotNull( subqueryFromClause ); assertThat( subqueryFromClause.getFromElementSpaces().size(), is( 1 ) ); SqmFromElementSpace subqueryFromElementSpace = subqueryFromClause.getFromElementSpaces().get( 0 ); assertThat( subqueryFromElementSpace.getRoot(), notNullValue() ); assertThat( subqueryFromElementSpace.getJoins().size(), is( 0 ) ); assertThat( subqueryFromElementSpace.getRoot().getEntityName(), is( Person.class.getName() ) ); assertThat( subqueryFromElementSpace.getRoot().getIdentificationVariable(), is( "e" ) ); } @Test public void testUncorrelatedSubQueries() throws Exception { final String query = "select a from Person a where a.mate IN (select e from Person e where e.numberOfToes IN (select e.numberOfToes+2 from Person b where b.nickName = 'polydactyl' ))"; final SqmSelectStatement selectStatement = interpretSelect( query ); SqmFromClause fromClause = selectStatement.getQuerySpec().getFromClause(); assertNotNull( fromClause ); assertThat( fromClause.getFromElementSpaces().size(), is( 1 ) ); SqmFromElementSpace fromElementSpace = fromClause.getFromElementSpaces().get( 0 ); assertThat( fromElementSpace.getRoot(), notNullValue() ); assertThat( fromElementSpace.getJoins().size(), is( 0 ) ); assertThat( fromElementSpace.getRoot().getEntityName(), is( "org.hibernate.sqm.test.domain.Person" ) ); assertThat( fromElementSpace.getRoot().getIdentificationVariable(), is( "a" ) ); // assertions against the root sqm predicate that defines the sub-sqm assertThat( selectStatement.getQuerySpec().getWhereClause().getPredicate(), notNullValue() ); assertThat( selectStatement.getQuerySpec().getWhereClause().getPredicate(), is( instanceOf( InSubQuerySqmPredicate.class ) ) ); InSubQuerySqmPredicate subQueryPredicate = (InSubQuerySqmPredicate) selectStatement.getQuerySpec() .getWhereClause() .getPredicate(); SqmFromClause subqueryFromClause = subQueryPredicate.getSubQueryExpression().getQuerySpec().getFromClause(); assertNotNull( subqueryFromClause ); assertThat( subqueryFromClause.getFromElementSpaces().size(), is( 1 ) ); SqmFromElementSpace subqueryFromElementSpace = subqueryFromClause.getFromElementSpaces().get( 0 ); assertThat( subqueryFromElementSpace.getRoot(), notNullValue() ); assertThat( subqueryFromElementSpace.getJoins().size(), is( 0 ) ); assertThat( subqueryFromElementSpace.getRoot().getEntityName(), is( "org.hibernate.sqm.test.domain.Person" ) ); assertThat( subqueryFromElementSpace.getRoot().getIdentificationVariable(), is( "e" ) ); // assertions against the root sqm predicate that defines the su-sqm of sub-sqm InSubQuerySqmPredicate subSubqueryPredicate = (InSubQuerySqmPredicate) subQueryPredicate.getSubQueryExpression() .getQuerySpec() .getWhereClause() .getPredicate(); SqmFromClause subSubqueryFromClause = subSubqueryPredicate.getSubQueryExpression().getQuerySpec().getFromClause(); assertNotNull( subSubqueryFromClause ); SqmFromElementSpace subSubqueryFromElementSpace = subSubqueryFromClause.getFromElementSpaces().get( 0 ); assertThat( subSubqueryFromElementSpace.getRoot(), notNullValue() ); assertThat( subSubqueryFromElementSpace.getJoins().size(), is( 0 ) ); assertThat( subSubqueryFromElementSpace.getRoot().getEntityName(), is( "org.hibernate.sqm.test.domain.Person" ) ); assertThat( subSubqueryFromElementSpace.getRoot().getIdentificationVariable(), is( "b" ) ); } @Test public void testUncorrelatedSubQueriesInAndPredicate() throws Exception { final String query = "Select a from Person a where a.mate in ( select b from Person b where b.numberOfToes = 5) and a.mate in (select c from Person c where c.numberOfToes = 6)"; final SqmSelectStatement selectStatement = interpretSelect( query ); SqmFromClause fromClause = selectStatement.getQuerySpec().getFromClause(); assertNotNull( fromClause ); assertThat( fromClause.getFromElementSpaces().size(), is( 1 ) ); SqmFromElementSpace fromElementSpace = fromClause.getFromElementSpaces().get( 0 ); assertThat( fromElementSpace.getRoot(), notNullValue() ); assertThat( fromElementSpace.getJoins().size(), is( 0 ) ); assertThat( fromElementSpace.getRoot().getEntityName(), is( "org.hibernate.sqm.test.domain.Person" ) ); assertThat( fromElementSpace.getRoot().getIdentificationVariable(), is( "a" ) ); // assertions against the root sqm predicate that defines the sub-sqm assertThat( selectStatement.getQuerySpec().getWhereClause().getPredicate(), notNullValue() ); assertThat( selectStatement.getQuerySpec().getWhereClause().getPredicate(), is( instanceOf( AndSqmPredicate.class ) ) ); AndSqmPredicate andPredicate = (AndSqmPredicate) selectStatement.getQuerySpec() .getWhereClause() .getPredicate(); assertThat( andPredicate.getLeftHandPredicate(), is( instanceOf( InSubQuerySqmPredicate.class ) ) ); assertThat( andPredicate.getRightHandPredicate(), is( instanceOf( InSubQuerySqmPredicate.class ) ) ); InSubQuerySqmPredicate leftHandPredicate = (InSubQuerySqmPredicate) andPredicate.getLeftHandPredicate(); SqmFromClause leftHandPredicateFromClause = leftHandPredicate.getSubQueryExpression() .getQuerySpec() .getFromClause(); assertNotNull( leftHandPredicateFromClause ); SqmFromElementSpace leftHandPredicateFromElementSpace = leftHandPredicateFromClause.getFromElementSpaces() .get( 0 ); assertThat( leftHandPredicateFromElementSpace.getRoot(), notNullValue() ); assertThat( leftHandPredicateFromElementSpace.getJoins().size(), is( 0 ) ); assertThat( leftHandPredicateFromElementSpace.getRoot().getEntityName(), is( "org.hibernate.sqm.test.domain.Person" ) ); assertThat( leftHandPredicateFromElementSpace.getRoot().getIdentificationVariable(), is( "b" ) ); InSubQuerySqmPredicate rightHandPredicate = (InSubQuerySqmPredicate) andPredicate.getRightHandPredicate(); SqmFromClause rightHandPredicateFromClause = rightHandPredicate.getSubQueryExpression() .getQuerySpec() .getFromClause(); assertNotNull( rightHandPredicateFromClause ); SqmFromElementSpace rightHandPredicateFromElementSpace = rightHandPredicateFromClause.getFromElementSpaces() .get( 0 ); assertThat( rightHandPredicateFromElementSpace.getRoot(), notNullValue() ); assertThat( rightHandPredicateFromElementSpace.getJoins().size(), is( 0 ) ); assertThat( rightHandPredicateFromElementSpace.getRoot().getEntityName(), is( "org.hibernate.sqm.test.domain.Person" ) ); assertThat( rightHandPredicateFromElementSpace.getRoot().getIdentificationVariable(), is( "c" ) ); } @Test public void testInvalidOnPredicateWithImplicitJoin() throws Exception { final String query = "select a from Person a left outer join a.mate c on c.mate.numberOfToes > 5 and c.numberOfToes < 20"; try { interpretSelect( query ); fail(); } catch (SemanticException expected) { } } @Test public void testSimpleDynamicInstantiation() throws Exception { final String query = "select new org.hibernate.sqm.test.hql.SimpleSemanticQueryBuilderTest$DTO(a.id as id, a.nickName as name) from Person a"; final SqmSelectStatement selectStatement = interpretSelect( query ); SqmQuerySpec querySpec = selectStatement.getQuerySpec(); assertNotNull( querySpec ); } private static class DTO { } }