Package org.hibernate.test.hql

Source Code of org.hibernate.test.hql.HQLTest

//$Id: HQLTest.java 11374 2007-03-29 19:09:18Z steve.ebersole@jboss.com $
package org.hibernate.test.hql;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import junit.framework.Test;

import org.hibernate.Hibernate;
import org.hibernate.QueryException;
import org.hibernate.dialect.DB2Dialect;
import org.hibernate.dialect.H2Dialect;
import org.hibernate.dialect.HSQLDialect;
import org.hibernate.dialect.IngresDialect;
import org.hibernate.dialect.MySQLDialect;
import org.hibernate.dialect.Oracle8iDialect;
import org.hibernate.dialect.PostgreSQLDialect;
import org.hibernate.dialect.SQLServerDialect;
import org.hibernate.dialect.Sybase11Dialect;
import org.hibernate.dialect.SybaseASE15Dialect;
import org.hibernate.dialect.SybaseAnywhereDialect;
import org.hibernate.dialect.SybaseDialect;
import org.hibernate.dialect.function.SQLFunction;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.engine.query.HQLQueryPlan;
import org.hibernate.engine.query.ReturnMetadata;
import org.hibernate.hql.QueryTranslator;
import org.hibernate.hql.QueryTranslatorFactory;
import org.hibernate.hql.antlr.HqlTokenTypes;
import org.hibernate.hql.ast.ASTQueryTranslatorFactory;
import org.hibernate.hql.ast.DetailedSemanticException;
import org.hibernate.hql.ast.QuerySyntaxException;
import org.hibernate.hql.ast.QueryTranslatorImpl;
import org.hibernate.hql.ast.SqlGenerator;
import org.hibernate.hql.ast.tree.ConstructorNode;
import org.hibernate.hql.ast.tree.DotNode;
import org.hibernate.hql.ast.tree.FromReferenceNode;
import org.hibernate.hql.ast.tree.IndexNode;
import org.hibernate.hql.ast.tree.QueryNode;
import org.hibernate.hql.ast.tree.SelectClause;
import org.hibernate.hql.ast.util.ASTUtil;
import org.hibernate.testing.junit.functional.FunctionalTestClassTestSuite;

import antlr.RecognitionException;
import antlr.collections.AST;

/**
* Tests cases where the AST based query translator and the 'classic' query translator generate identical SQL.
*
* @author Gavin King
*/
public class HQLTest extends QueryTranslatorTestCase {

  public HQLTest(String x) {
    super( x );
  }

  public static Test suite() {
    return new FunctionalTestClassTestSuite( HQLTest.class );
  }

  public boolean createSchema() {
    return false;
  }

  public boolean recreateSchemaAfterFailure() {
    return false;
  }

  protected void prepareTest() throws Exception {
    super.prepareTest();
    SelectClause.VERSION2_SQL = true;
    DotNode.REGRESSION_STYLE_JOIN_SUPPRESSION = true;
    DotNode.ILLEGAL_COLL_DEREF_EXCP_BUILDER = new DotNode.IllegalCollectionDereferenceExceptionBuilder() {
      public QueryException buildIllegalCollectionDereferenceException(String propertyName, FromReferenceNode lhs) {
        throw new QueryException( "illegal syntax near collection: " + propertyName );
      }
    };
    SqlGenerator.REGRESSION_STYLE_CROSS_JOINS = true;
  }

  protected void cleanupTest() throws Exception {
    SelectClause.VERSION2_SQL = false;
    DotNode.REGRESSION_STYLE_JOIN_SUPPRESSION = false;
    DotNode.ILLEGAL_COLL_DEREF_EXCP_BUILDER = DotNode.DEF_ILLEGAL_COLL_DEREF_EXCP_BUILDER;
    SqlGenerator.REGRESSION_STYLE_CROSS_JOINS = false;
    super.cleanupTest();
  }

  public void testModulo() {
    assertTranslation( "from Animal a where a.bodyWeight % 2 = 0" );
  }

  public void testInvalidCollectionDereferencesFail() {
    // should fail with the same exceptions (because of the DotNode.ILLEGAL_COLL_DEREF_EXCP_BUILDER injection)
    assertTranslation( "from Animal a where a.offspring.description = 'xyz'" );
    assertTranslation( "from Animal a where a.offspring.father.description = 'xyz'" );
  }
 
    /**
     * ClassicQueryTranslatorFactory does not support translate tuple with "in" syntax to "and/or" clause
     */
    public void testRowValueConstructorSyntaxInInListFailureExpected() {
        assertTranslation( "from LineItem l where l.id in (:idList)" );
    assertTranslation( "from LineItem l where l.id in :idList" );
    }

    public void testRowValueConstructorSyntaxInInList() {
      if (!getDialect().supportsRowValueConstructorSyntaxInInList())
        return;
    QueryTranslatorImpl translator = createNewQueryTranslator("from LineItem l where l.id in (?)");
    assertInExist("'in' should be translated to 'and'", false, translator);
    translator = createNewQueryTranslator("from LineItem l where l.id in ?");
    assertInExist("'in' should be translated to 'and'", false, translator);
    translator = createNewQueryTranslator("from LineItem l where l.id in (('a1',1,'b1'),('a2',2,'b2'))");
    assertInExist("'in' should be translated to 'and'", false, translator);
    translator = createNewQueryTranslator("from Animal a where a.id in (?)");
    assertInExist("only translate tuple with 'in' syntax", true, translator);
    translator = createNewQueryTranslator("from Animal a where a.id in ?");
    assertInExist("only translate tuple with 'in' syntax", true, translator);
    translator = createNewQueryTranslator("from LineItem l where l.id in (select a1 from Animal a1 left join a1.offspring o where a1.id = 1)");
    assertInExist("do not translate subqueries", true, translator);

    }

  private void assertInExist( String message, boolean expected, QueryTranslatorImpl translator ) {
    AST ast = translator.getSqlAST().getWalker().getAST();
    QueryNode queryNode = (QueryNode) ast;
    AST inNode = ASTUtil.findTypeInChildren( queryNode, HqlTokenTypes.IN );
    assertEquals( message, expected, inNode != null );
  }
   
  public void testSubComponentReferences() {
    assertTranslation( "select c.address.zip.code from ComponentContainer c" );
    assertTranslation( "select c.address.zip from ComponentContainer c" );
    assertTranslation( "select c.address from ComponentContainer c" );
  }

  public void testManyToAnyReferences() {
    assertTranslation( "from PropertySet p where p.someSpecificProperty.id is not null" );
    assertTranslation( "from PropertySet p join p.generalProperties gp where gp.id is not null" );
  }

  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
    // handle correlated subqueries (but fails miserably) even though this
    // is not a correlated subquery.  HHH-1248
    assertTranslation(
        "select a.id, a.description" +
        " from Animal a" +
        "       left join a.offspring" +
        " where a in (" +
        "       select a1 from Animal a1" +
        "           left join a1.offspring o" +
        "       where a1.id=1" +
            ")"
    );
    assertTranslation(
        "select h.id, h.description" +
            " from Human h" +
        "      left join h.friends" +
        " where h in (" +
        "      select h1" +
        "      from Human h1" +
        "          left join h1.friends f" +
        "      where h1.id=1" +
        ")"
    );
  }

  public void testEmptyInListFailureExpected() {
    assertTranslation( "select a from Animal a where a.description in ()" );
  }

  public void testDateTimeArithmeticReturnTypesAndParameterGuessing() {
    QueryTranslatorImpl translator = createNewQueryTranslator( "select o.orderDate - o.orderDate from Order o" );
    assertEquals( "incorrect return type count", 1, translator.getReturnTypes().length );
    assertEquals( "incorrect return type", Hibernate.DOUBLE, translator.getReturnTypes()[0] );
    translator = createNewQueryTranslator( "select o.orderDate + 2 from Order o" );
    assertEquals( "incorrect return type count", 1, translator.getReturnTypes().length );
    assertEquals( "incorrect return type", Hibernate.CALENDAR_DATE, translator.getReturnTypes()[0] );
    translator = createNewQueryTranslator( "select o.orderDate -2 from Order o" );
    assertEquals( "incorrect return type count", 1, translator.getReturnTypes().length );
    assertEquals( "incorrect return type", Hibernate.CALENDAR_DATE, translator.getReturnTypes()[0] );

    translator = createNewQueryTranslator( "from Order o where o.orderDate > ?" );
    assertEquals( "incorrect expected param type", Hibernate.CALENDAR_DATE, translator.getParameterTranslations().getOrdinalParameterExpectedType( 1 ) );

    translator = createNewQueryTranslator( "select o.orderDate + ? from Order o" );
    assertEquals( "incorrect return type count", 1, translator.getReturnTypes().length );
    assertEquals( "incorrect return type", Hibernate.CALENDAR_DATE, translator.getReturnTypes()[0] );
    assertEquals( "incorrect expected param type", Hibernate.DOUBLE, translator.getParameterTranslations().getOrdinalParameterExpectedType( 1 ) );

  }

  public void testReturnMetadata() {
    HQLQueryPlan plan = createQueryPlan( "from Animal a" );
    check( plan.getReturnMetadata(), false, true );

    plan = createQueryPlan( "select a as animal from Animal a" );
    check( plan.getReturnMetadata(), false, false );

    plan = createQueryPlan( "from java.lang.Object" );
    check( plan.getReturnMetadata(), true, true );

    plan = createQueryPlan( "select o as entity from java.lang.Object o" );
    check( plan.getReturnMetadata(), true, false );
  }

  private void check(
      ReturnMetadata returnMetadata,
          boolean expectingEmptyTypes,
          boolean expectingEmptyAliases) {
    assertNotNull( "null return metadata", returnMetadata );
    assertNotNull( "null return metadata - types", returnMetadata );
    assertEquals( "unexpected return size", 1, returnMetadata.getReturnTypes().length );
    if ( expectingEmptyTypes ) {
      assertNull( "non-empty types", returnMetadata.getReturnTypes()[0] );
    }
    else {
      assertNotNull( "empty types", returnMetadata.getReturnTypes()[0] );
    }
    if ( expectingEmptyAliases ) {
      assertNull( "non-empty aliases", returnMetadata.getReturnAliases() );
    }
    else {
      assertNotNull( "empty aliases", returnMetadata.getReturnAliases() );
      assertNotNull( "empty aliases", returnMetadata.getReturnAliases()[0] );
    }
  }

  public void testImplicitJoinsAlongWithCartesianProduct() {
    DotNode.useThetaStyleImplicitJoins = true;
    assertTranslation( "select foo.foo from Foo foo, Foo foo2" );
    assertTranslation( "select foo.foo.foo from Foo foo, Foo foo2" );
    DotNode.useThetaStyleImplicitJoins = false;
  }

  public void testSubselectBetween() {
    assertTranslation("from Animal x where (select max(a.bodyWeight) from Animal a) between :min and :max");
    assertTranslation("from Animal x where (select max(a.description) from Animal a) like 'big%'");
    assertTranslation("from Animal x where (select max(a.bodyWeight) from Animal a) is not null");
    assertTranslation("from Animal x where exists (select max(a.bodyWeight) from Animal a)");
    assertTranslation("from Animal x where (select max(a.bodyWeight) from Animal a) in (1,2,3)");
  }

  public void testFetchOrderBy() {
    assertTranslation("from Animal a left outer join fetch a.offspring where a.mother.id = :mid order by a.description");
  }

  public void testCollectionOrderBy() {
    assertTranslation("from Animal a join a.offspring o order by a.description");
    assertTranslation("from Animal a join fetch a.offspring order by a.description");
    assertTranslation("from Animal a join fetch a.offspring o order by o.description");
    assertTranslation("from Animal a join a.offspring o order by a.description, o.description");
  }

  public void testExpressionWithParamInFunction() {
    assertTranslation("from Animal a where abs(a.bodyWeight-:param) < 2.0");
    assertTranslation("from Animal a where abs(:param - a.bodyWeight) < 2.0");
    assertTranslation("from Animal where abs(:x - :y) < 2.0");
    assertTranslation("from Animal where lower(upper(:foo)) like 'f%'");
    if ( ! ( getDialect() instanceof SybaseDialect ) &&  ! ( getDialect() instanceof Sybase11Dialect ) &&  ! ( getDialect() instanceof SybaseASE15Dialect ) && ! ( getDialect() instanceof SQLServerDialect ) ) {
      // Transact-SQL dialects (except SybaseAnywhereDialect) map the length function -> len;
      // classic translator does not consider that *when nested*;
      // SybaseAnywhereDialect supports the length function

      assertTranslation("from Animal a where abs(abs(a.bodyWeight - 1.0 + :param) * abs(length('ffobar')-3)) = 3.0");
    }
    if ( !( getDialect() instanceof MySQLDialect ) && ! ( getDialect() instanceof SybaseDialect ) && ! ( getDialect() instanceof Sybase11Dialect ) && !( getDialect() instanceof SybaseASE15Dialect ) && ! ( getDialect() instanceof SybaseAnywhereDialect ) && ! ( getDialect() instanceof SQLServerDialect ) ) {
      assertTranslation("from Animal where lower(upper('foo') || upper(:bar)) like 'f%'");
    }
    if ( getDialect() instanceof PostgreSQLDialect ) {
      return;
    }
    assertTranslation("from Animal where abs(cast(1 as float) - cast(:param as float)) = 1.0");
  }

  public void testCompositeKeysWithPropertyNamedId() {
    assertTranslation( "select e.id.id from EntityWithCrazyCompositeKey e" );
    assertTranslation( "select max(e.id.id) from EntityWithCrazyCompositeKey e" );
  }

  public void testMaxindexHqlFunctionInElementAccessorFailureExpected() {
    //TODO: broken SQL
    //      steve (2005.10.06) - this is perfect SQL, but fairly different from the old parser
    //              tested : HSQLDB (1.8), Oracle8i
    assertTranslation( "select c from ContainerX c where c.manyToMany[ maxindex(c.manyToMany) ].count = 2" );
    assertTranslation( "select c from Container c where c.manyToMany[ maxIndex(c.manyToMany) ].count = 2" );
  }

  public void testMultipleElementAccessorOperatorsFailureExpected() throws Exception {
    //TODO: broken SQL
    //      steve (2005.10.06) - Yes, this is all hosed ;)
    assertTranslation( "select c from ContainerX c where c.oneToMany[ c.manyToMany[0].count ].name = 's'" );
    assertTranslation( "select c from ContainerX c where c.manyToMany[ c.oneToMany[0].count ].name = 's'" );
  }

  /*public void testSelectMaxElements() throws Exception {
    //TODO: this is almost correct, but missing a select-clause column alias!
    assertTranslation("select max( elements(one.manies) ) from org.hibernate.test.legacy.One one");
  }*/

  public void testKeyManyToOneJoinFailureExpected() {
    //TODO: new parser generates unnecessary joins (though the query results are correct)
    assertTranslation( "from Order o left join fetch o.lineItems li left join fetch li.product p" );
    assertTranslation( "from Outer o where o.id.master.id.sup.dudu is not null" );
    assertTranslation( "from Outer o where o.id.master.id.sup.dudu is not null" );
  }

  public void testDuplicateExplicitJoinFailureExpected() throws Exception {
    //very minor issue with select clause:
    assertTranslation( "from Animal a join a.mother m1 join a.mother m2" );
    assertTranslation( "from Zoo zoo join zoo.animals an join zoo.mammals m" );
    assertTranslation( "from Zoo zoo join zoo.mammals an join zoo.mammals m" );
  }

  // TESTS THAT FAIL ONLY ON DIALECTS WITH THETA-STYLE OUTERJOINS:

  public void testIndexWithExplicitJoin() throws Exception {
    //TODO: broken on dialects with theta-style outerjoins:
    //      steve (2005.10.06) - this works perfectly for me on Oracle8i
    assertTranslation( "from Zoo zoo join zoo.animals an where zoo.mammals[ index(an) ] = an" );
    assertTranslation( "from Zoo zoo join zoo.mammals dog where zoo.mammals[ index(dog) ] = dog" );
    assertTranslation( "from Zoo zoo join zoo.mammals dog where dog = zoo.mammals[ index(dog) ]" );
  }

  public void testOneToManyMapIndex() throws Exception {
    //TODO: this breaks on dialects with theta-style outerjoins:
    //      steve (2005.10.06) - this works perfectly for me on Oracle8i
    assertTranslation( "from Zoo zoo where zoo.mammals['dog'].description like '%black%'" );
    assertTranslation( "from Zoo zoo where zoo.mammals['dog'].father.description like '%black%'" );
    assertTranslation( "from Zoo zoo where zoo.mammals['dog'].father.id = 1234" );
    assertTranslation( "from Zoo zoo where zoo.animals['1234'].description like '%black%'" );
  }

  public void testExplicitJoinMapIndex() throws Exception {
    //TODO: this breaks on dialects with theta-style outerjoins:
    //      steve (2005.10.06) - this works perfectly for me on Oracle8i
    assertTranslation( "from Zoo zoo, Dog dog where zoo.mammals['dog'] = dog" );
    assertTranslation( "from Zoo zoo join zoo.mammals dog where zoo.mammals['dog'] = dog" );
  }

  public void testIndexFunction() throws Exception {
    // Instead of doing the pre-processor trick like the existing QueryTranslator, this
    // is handled by MethodNode.
    //      steve (2005.10.06) - this works perfectly for me on Oracle8i
    //TODO: broken on dialects with theta-style outerjoins:
    assertTranslation( "from Zoo zoo join zoo.mammals dog where index(dog) = 'dog'" );
    assertTranslation( "from Zoo zoo join zoo.animals an where index(an) = '1234'" );
  }

  public void testSelectCollectionOfValues() throws Exception {
    //TODO: broken on dialects with theta-style joins
    ///old parser had a bug where the collection element was not included in return types!
    //      steve (2005.10.06) - this works perfectly for me on Oracle8i
    assertTranslation( "select baz, date from Baz baz join baz.stringDateMap date where index(date) = 'foo'" );
  }

  public void testCollectionOfValues() throws Exception {
    //old parser had a bug where the collection element was not returned!
    //TODO: broken on dialects with theta-style joins
    //      steve (2005.10.06) - this works perfectly for me on Oracle8i
    assertTranslation( "from Baz baz join baz.stringDateMap date where index(date) = 'foo'" );
  }

    public void testHHH719() throws Exception {
        assertTranslation("from Baz b order by org.bazco.SpecialFunction(b.id)");
        assertTranslation("from Baz b order by anypackage.anyFunction(b.id)");
    }


  //PASSING TESTS:

  public void testParameterListExpansion() {
    assertTranslation( "from Animal as animal where animal.id in (:idList_1, :idList_2)" );
  }

  public void testComponentManyToOneDereferenceShortcut() {
    assertTranslation( "from Zoo z where z.address.stateProvince.id is null" );
  }

  public void testNestedCollectionImplicitJoins() {
    // HHH-770
    assertTranslation( "select h.friends.offspring from Human h" );
  }

  public void testExplicitJoinsInSubquery() {
    // test for HHH-557,
    // TODO : this passes regardless because the only difference between the two sqls is one extra comma
    // (commas are eaten by the tokenizer during asserTranslation when building the token maps).
    assertTranslation(
            "from org.hibernate.test.hql.Animal as animal " +
            "where animal.id in (" +
            "        select a.id " +
            "        from org.hibernate.test.hql.Animal as a " +
            "               left join a.mother as mo" +
            ")"
    );
  }

  public void testImplicitJoinsInGroupBy() {
    assertTranslation(
            "select o.mother.bodyWeight, count(distinct o) " +
            "from Animal an " +
            "   join an.offspring as o " +
            "group by o.mother.bodyWeight"
    );
  }

  public void testCrazyIdFieldNames() {
    DotNode.useThetaStyleImplicitJoins = true;
    // only regress against non-scalar forms as there appears to be a bug in the classic translator
    // in regards to this issue also.  Specifically, it interprets the wrong return type, though it gets
    // the sql "correct" :/

    String hql = "select e.heresAnotherCrazyIdFieldName from MoreCrazyIdFieldNameStuffEntity e where e.heresAnotherCrazyIdFieldName is not null";
    assertTranslation( hql, new HashMap(), false, ( String ) null );

      hql = "select e.heresAnotherCrazyIdFieldName.heresAnotherCrazyIdFieldName from MoreCrazyIdFieldNameStuffEntity e where e.heresAnotherCrazyIdFieldName is not null";
    assertTranslation( hql, new HashMap(), false, ( String ) null );

    DotNode.useThetaStyleImplicitJoins = false;
  }

  public void testSizeFunctionAndProperty() {
    assertTranslation("from Animal a where a.offspring.size > 0");
    assertTranslation("from Animal a join a.offspring where a.offspring.size > 1");
    assertTranslation("from Animal a where size(a.offspring) > 0");
    assertTranslation("from Animal a join a.offspring o where size(a.offspring) > 1");
    assertTranslation("from Animal a where size(a.offspring) > 1 and size(a.offspring) < 100");

    assertTranslation("from Human a where a.family.size > 0");
    assertTranslation("from Human a join a.family where a.family.size > 1");
    assertTranslation("from Human a where size(a.family) > 0");
    assertTranslation("from Human a join a.family o where size(a.family) > 1");
    assertTranslation("from Human a where a.family.size > 0 and a.family.size < 100");
}

  // Do the simplest test first!
  public void testFromOnly() throws Exception {
    // 2004-06-21 [jsd] This test now works with the new AST based QueryTranslatorImpl.
    assertTranslation( "from Animal" );
    assertTranslation( "from Model" );
  }

  public void testJoinPathEndingInValueCollection() {
    assertTranslation( "select h from Human as h join h.nickNames as nn where h.nickName=:nn1 and (nn=:nn2 or nn=:nn3)" );
  }

  public void testSerialJoinPathEndingInValueCollection() {
    // HHH-242
    assertTranslation( "select h from Human as h join h.friends as f join f.nickNames as nn where h.nickName=:nn1 and (nn=:nn2 or nn=:nn3)" );
  }

  public void testImplicitJoinContainedByCollectionFunction() {
    // HHH-281 : Implied joins in a collection function (i.e., indices or elements)
    assertTranslation( "from Human as h where 'shipping' in indices(h.father.addresses)" );
    assertTranslation( "from Human as h where 'shipping' in indices(h.father.father.addresses)" );
    assertTranslation( "from Human as h where 'sparky' in elements(h.father.nickNames)" );
    assertTranslation( "from Human as h where 'sparky' in elements(h.father.father.nickNames)" );
  }


  public void testImpliedJoinInSubselectFrom() {
    // HHH-276 : Implied joins in a from in a subselect.
    assertTranslation( "from Animal a where exists( from a.mother.offspring )" );
  }

  public void testSubselectImplicitJoins() {
    // HHH-276 : Implied joins in a from in a subselect.
    assertTranslation( "from Simple s where s = some( select sim from Simple sim where sim.other.count=s.other.count )" );
  }


  public void testCollectionOfValuesSize() throws Exception {
    //SQL *was* missing a comma
    assertTranslation( "select size(baz.stringDateMap) from org.hibernate.test.legacy.Baz baz" );
  }

  public void testCollectionFunctions() throws Exception {
    //these are both broken, a join that belongs in the subselect finds its way into the main query
    assertTranslation( "from Zoo zoo where size(zoo.animals) > 100" );
    assertTranslation( "from Zoo zoo where maxindex(zoo.mammals) = 'dog'" );
  }

  public void testImplicitJoinInExplicitJoin() throws Exception {
    assertTranslation( "from Animal an inner join an.mother.mother gm" );
    assertTranslation( "from Animal an inner join an.mother.mother.mother ggm" );
    assertTranslation( "from Animal an inner join an.mother.mother.mother.mother gggm" );
  }

  public void testImpliedManyToManyProperty() throws Exception {
    //missing a table join (SQL correct for a one-to-many, not for a many-to-many)
    assertTranslation( "select c from ContainerX c where c.manyToMany[0].name = 's'" );
  }

  public void testCollectionSize() throws Exception {
    //SQL is correct, query spaces *was* missing a table
    assertTranslation( "select size(zoo.animals) from Zoo zoo" );
  }

  /*public void testCollectionIndexFunctionsInSelect() throws Exception {
    assertTranslation("select maxindex(zoo.animals) from Zoo zoo");
    assertTranslation("select minindex(zoo.animals) from Zoo zoo");
    assertTranslation("select indices(zoo.animals) from Zoo zoo");
  }

  public void testCollectionElementFunctionsInSelect() throws Exception {
    assertTranslation("select maxelement(zoo.animals) from Zoo zoo");
    assertTranslation("select minelement(zoo.animals) from Zoo zoo");
    assertTranslation("select elements(zoo.animals) from Zoo zoo");
  }*/

  public void testFetchCollectionOfValues() throws Exception {
    assertTranslation( "from Baz baz left join fetch baz.stringSet" );
  }

  public void testFetchList() throws Exception {
    assertTranslation( "from User u join fetch u.permissions" );
  }

  public void testCollectionFetchWithExplicitThetaJoin() {
    assertTranslation( "select m from Master m1, Master m left join fetch m.details where m.name=m1.name" );
  }

  /*public void testListElementFunctionInSelect() throws Exception {
    //wrong pk column in select clause! (easy fix?)
    assertTranslation("select maxelement(u.permissions) from User u");
    assertTranslation("select elements(u.permissions) from User u");
  }*/

  public void testListElementFunctionInWhere() throws Exception {
    assertTranslation( "from User u where 'read' in elements(u.permissions)" );
    assertTranslation( "from User u where 'write' <> all elements(u.permissions)" );
  }

  /*public void testManyToManyElementFunctionInSelect() throws Exception {
    assertTranslation("select maxelement(human.friends) from Human human");
    assertTranslation("select elements(human.friends) from Human human");
  }*/

  public void testManyToManyMaxElementFunctionInWhere() throws Exception {
    //completely broken!!
    assertTranslation( "from Human human where 5 = maxelement(human.friends)" );
  }

  public void testCollectionIndexFunctionsInWhere() throws Exception {
    assertTranslation( "from Zoo zoo where 4 = maxindex(zoo.animals)" );
    assertTranslation( "from Zoo zoo where 2 = minindex(zoo.animals)" );
  }

  public void testCollectionIndicesInWhere() throws Exception {
    assertTranslation( "from Zoo zoo where 4 > some indices(zoo.animals)" );
    assertTranslation( "from Zoo zoo where 4 > all indices(zoo.animals)" );
  }

  public void testIndicesInWhere() throws Exception {
    assertTranslation( "from Zoo zoo where 4 in indices(zoo.animals)" );
    assertTranslation( "from Zoo zoo where exists indices(zoo.animals)" );
  }

  public void testCollectionElementInWhere() throws Exception {
    assertTranslation( "from Zoo zoo where 4 > some elements(zoo.animals)" );
    assertTranslation( "from Zoo zoo where 4 > all elements(zoo.animals)" );
  }

  public void testElementsInWhere() throws Exception {
    assertTranslation( "from Zoo zoo where 4 in elements(zoo.animals)" );
    assertTranslation( "from Zoo zoo where exists elements(zoo.animals)" );
  }

  public void testNull() throws Exception {
    assertTranslation( "from Human h where h.nickName is null" );
    assertTranslation( "from Human h where h.nickName is not null" );
  }

  public void testSubstitutions() throws Exception {
    Map replacements = buildTrueFalseReplacementMapForDialect();
    replacements.put("yes", "'Y'");
    assertTranslation( "from Human h where h.pregnant = true", replacements );
    assertTranslation( "from Human h where h.pregnant = yes", replacements );
    assertTranslation( "from Human h where h.pregnant = foo", replacements );
  }

  public void testWhere() throws Exception {
    assertTranslation( "from Animal an where an.bodyWeight > 10" );
    // 2004-06-26 [jsd] This one requires NOT GT => LE transform.
    assertTranslation( "from Animal an where not an.bodyWeight > 10" );
    assertTranslation( "from Animal an where an.bodyWeight between 0 and 10" );
    assertTranslation( "from Animal an where an.bodyWeight not between 0 and 10" );
    assertTranslation( "from Animal an where sqrt(an.bodyWeight)/2 > 10" );
    // 2004-06-27 [jsd] Recognize 'is null' properly.  Generate 'and' and 'or' as well.
    assertTranslation( "from Animal an where (an.bodyWeight > 10 and an.bodyWeight < 100) or an.bodyWeight is null" );
  }

  public void testEscapedQuote() throws Exception {
    assertTranslation( "from Human h where h.nickName='1 ov''tha''few'");
  }

  public void testCaseWhenElse() {
    assertTranslation( "from Human h where case when h.nickName='1ovthafew' then 'Gavin' when h.nickName='turin' then 'Christian' else h.nickName end = h.name.first" );
  }

  public void testCaseExprWhenElse() {
    assertTranslation( "from Human h where case h.nickName when '1ovthafew' then 'Gavin' when 'turin' then 'Christian' else h.nickName end = h.name.first" );
  }

  public void testInvalidHql() throws Exception {
    Exception newException = compileBadHql( "from Animal foo where an.bodyWeight > 10", false );
    assertTrue( "Wrong exception type!", newException instanceof QuerySyntaxException );
    newException = compileBadHql( "select an.name from Animal foo", false );
    assertTrue( "Wrong exception type!", newException instanceof QuerySyntaxException );
    newException = compileBadHql( "from Animal foo where an.verybogus > 10", false );
    assertTrue( "Wrong exception type!", newException instanceof QuerySyntaxException );
    newException = compileBadHql( "select an.boguspropertyname from Animal foo", false );
    assertTrue( "Wrong exception type!", newException instanceof QuerySyntaxException );
    newException = compileBadHql( "select an.name", false );
    assertTrue( "Wrong exception type!", newException instanceof QuerySyntaxException );
    newException = compileBadHql( "from Animal an where (((an.bodyWeight > 10 and an.bodyWeight < 100)) or an.bodyWeight is null", false );
    assertTrue( "Wrong exception type!", newException instanceof QuerySyntaxException );
    newException = compileBadHql( "from Animal an where an.bodyWeight is null where an.bodyWeight is null", false );
    assertTrue( "Wrong exception type!", newException instanceof QuerySyntaxException );
    newException = compileBadHql( "from where name='foo'", false );
    assertTrue( "Wrong exception type!", newException instanceof QuerySyntaxException );
    newException = compileBadHql( "from NonexistentClass where name='foo'", false );
    assertTrue( "Wrong exception type!", newException instanceof QuerySyntaxException );
    newException = compileBadHql( "select new FOO_BOGUS_Animal(an.description, an.bodyWeight) from Animal an", false );
    assertTrue( "Wrong exception type!", newException instanceof QuerySyntaxException );
    newException = compileBadHql( "select new Animal(an.description, an.bodyWeight, 666) from Animal an", false );
    assertTrue( "Wrong exception type!", newException instanceof QuerySyntaxException );

  }

  public void testWhereBetween() throws Exception {
    // 2004-08-31 [jsd] This "just worked"! Woohoo!
    assertTranslation( "from Animal an where an.bodyWeight between 1 and 10" );
  }

  public void testConcatenation() {
    if ( getDialect() instanceof MySQLDialect || getDialect() instanceof SybaseDialect
        || getDialect() instanceof Sybase11Dialect
        || getDialect() instanceof SybaseASE15Dialect
        || getDialect() instanceof SybaseAnywhereDialect
        || getDialect() instanceof SQLServerDialect
        || getDialect() instanceof IngresDialect) {
      // SybaseASE15Dialect and SybaseAnywhereDialect support '||'
      // MySQL uses concat(x, y, z)
      // SQL Server replaces '||' with '+'
      //
      // this is syntax checked in {@link ASTParserLoadingTest#testConcatenation}
      // Ingres supports both "||" and '+' but IngresDialect originally
      // uses '+' operator; updated Ingres9Dialect to use "||".
      return;
    }
    assertTranslation("from Human h where h.nickName = '1' || 'ov' || 'tha' || 'few'");
  }

  public void testWhereLike() throws Exception {
    assertTranslation( "from Animal a where a.description like '%black%'" );
    assertTranslation( "from Animal an where an.description like '%fat%'" );
    assertTranslation( "from Animal an where lower(an.description) like '%fat%'" );
  }

  public void testWhereIn() throws Exception {
    assertTranslation( "from Animal an where an.description in ('fat', 'skinny')" );
  }

  public void testLiteralInFunction() throws Exception {
    assertTranslation( "from Animal an where an.bodyWeight > abs(5)" );
    assertTranslation( "from Animal an where an.bodyWeight > abs(-5)" );
  }

  public void testExpressionInFunction() throws Exception {
    assertTranslation( "from Animal an where an.bodyWeight > abs(3-5)" );
    assertTranslation( "from Animal an where an.bodyWeight > abs(3/5)" );
    assertTranslation( "from Animal an where an.bodyWeight > abs(3+5)" );
    assertTranslation( "from Animal an where an.bodyWeight > abs(3*5)" );
    SQLFunction concat = getSessionFactoryImplementor().getSqlFunctionRegistry().findSQLFunction( "concat");
    List list = new ArrayList(); list.add("'fat'"); list.add("'skinny'");
    assertTranslation( "from Animal an where an.description = " + concat.render(Hibernate.STRING, list, getSessionFactoryImplementor()) );
  }

  public void testNotOrWhereClause() {
    assertTranslation( "from Simple s where 'foo'='bar' or not 'foo'='foo'" );
    assertTranslation( "from Simple s where 'foo'='bar' or not ('foo'='foo')" );
    assertTranslation( "from Simple s where not ( 'foo'='bar' or 'foo'='foo' )" );
    assertTranslation( "from Simple s where not ( 'foo'='bar' and 'foo'='foo' )" );
    assertTranslation( "from Simple s where not ( 'foo'='bar' and 'foo'='foo' ) or not ('x'='y')" );
    assertTranslation( "from Simple s where not ( 'foo'='bar' or 'foo'='foo' ) and not ('x'='y')" );
    assertTranslation( "from Simple s where not ( 'foo'='bar' or 'foo'='foo' ) and 'x'='y'" );
    assertTranslation( "from Simple s where not ( 'foo'='bar' and 'foo'='foo' ) or 'x'='y'" );
    assertTranslation( "from Simple s where 'foo'='bar' and 'foo'='foo' or not 'x'='y'" );
    assertTranslation( "from Simple s where 'foo'='bar' or 'foo'='foo' and not 'x'='y'" );
    assertTranslation( "from Simple s where ('foo'='bar' and 'foo'='foo') or 'x'='y'" );
    assertTranslation( "from Simple s where ('foo'='bar' or 'foo'='foo') and 'x'='y'" );
    assertTranslation( "from Simple s where not( upper( s.name ) ='yada' or 1=2 or 'foo'='bar' or not('foo'='foo') or 'foo' like 'bar' )" );
  }

  public void testComplexExpressionInFunction() throws Exception {
    assertTranslation( "from Animal an where an.bodyWeight > abs((3-5)/4)" );
  }

  public void testStandardFunctions() throws Exception {
    assertTranslation( "from Animal where current_date = current_time" );
    assertTranslation( "from Animal a where upper(a.description) = 'FAT'" );
    assertTranslation( "select lower(a.description) from Animal a" );
  }

  public void testOrderBy() throws Exception {
    assertTranslation( "from Animal an order by an.bodyWeight" );
    assertTranslation( "from Animal an order by an.bodyWeight asc" );
    assertTranslation( "from Animal an order by an.bodyWeight desc" );
    assertTranslation( "from Animal an order by sqrt(an.bodyWeight*4)/2" );
    assertTranslation( "from Animal an order by an.mother.bodyWeight" );
    assertTranslation( "from Animal an order by an.bodyWeight, an.description" );
    assertTranslation( "from Animal an order by an.bodyWeight asc, an.description desc" );
    if ( getDialect() instanceof HSQLDialect || getDialect() instanceof DB2Dialect ) {
      assertTranslation( "from Human h order by sqrt(h.bodyWeight), year(h.birthdate)" );
    }
  }

  public void testGroupByFunction() {
    if ( getDialect() instanceof Oracle8iDialect ) return; // the new hiearchy...
    if ( getDialect() instanceof PostgreSQLDialect ) return;
    if ( ! H2Dialect.class.isInstance( getDialect() ) ) {
      // H2 has no year function
      assertTranslation( "select count(*) from Human h group by year(h.birthdate)" );
      assertTranslation( "select count(*) from Human h group by year(sysdate)" );
    }
    assertTranslation( "select count(*) from Human h group by trunc( sqrt(h.bodyWeight*4)/2 )" );
  }


  public void testPolymorphism() throws Exception {
    Map replacements = buildTrueFalseReplacementMapForDialect();
    assertTranslation( "from Mammal" );
    assertTranslation( "from Dog" );
    assertTranslation( "from Mammal m where m.pregnant = false and m.bodyWeight > 10", replacements );
    assertTranslation( "from Dog d where d.pregnant = false and d.bodyWeight > 10", replacements );
  }

  private Map buildTrueFalseReplacementMapForDialect() {
    HashMap replacements = new HashMap();
    try {
      String dialectTrueRepresentation = getDialect().toBooleanValueString( true );
      // if this call succeeds, then the dialect is saying to represent true/false as int values...
      Integer.parseInt( dialectTrueRepresentation );
      replacements.put( "true", "1" );
      replacements.put( "false", "0" );
    }
    catch( NumberFormatException nfe ) {
      // the Integer#parseInt call failed...
    }
    return replacements;
  }

  public void testTokenReplacement() throws Exception {
    Map replacements = buildTrueFalseReplacementMapForDialect();
    assertTranslation( "from Mammal m where m.pregnant = false and m.bodyWeight > 10", replacements );
  }

  public void testProduct() throws Exception {
    Map replacements = buildTrueFalseReplacementMapForDialect();
    assertTranslation( "from Animal, Animal" );
    assertTranslation( "from Animal x, Animal y where x.bodyWeight = y.bodyWeight" );
    assertTranslation( "from Animal x, Mammal y where x.bodyWeight = y.bodyWeight and not y.pregnant = true", replacements );
    assertTranslation( "from Mammal, Mammal" );
  }

  public void testJoinedSubclassProduct() throws Exception {
    assertTranslation( "from PettingZoo, PettingZoo" ); //product of two subclasses
  }

  public void testProjectProduct() throws Exception {
    assertTranslation( "select x from Human x, Human y where x.nickName = y.nickName" );
    assertTranslation( "select x, y from Human x, Human y where x.nickName = y.nickName" );
  }

  public void testExplicitEntityJoins() throws Exception {
    assertTranslation( "from Animal an inner join an.mother mo" );
    assertTranslation( "from Animal an left outer join an.mother mo" );
    assertTranslation( "from Animal an left outer join fetch an.mother" );
  }

  public void testMultipleExplicitEntityJoins() throws Exception {
    assertTranslation( "from Animal an inner join an.mother mo inner join mo.mother gm" );
    assertTranslation( "from Animal an left outer join an.mother mo left outer join mo.mother gm" );
    assertTranslation( "from Animal an inner join an.mother m inner join an.father f" );
    assertTranslation( "from Animal an left join fetch an.mother m left join fetch an.father f" );
  }

  public void testMultipleExplicitJoins() throws Exception {
    assertTranslation( "from Animal an inner join an.mother mo inner join an.offspring os" );
    assertTranslation( "from Animal an left outer join an.mother mo left outer join an.offspring os" );
  }

  public void testExplicitEntityJoinsWithRestriction() throws Exception {
    assertTranslation( "from Animal an inner join an.mother mo where an.bodyWeight < mo.bodyWeight" );
  }

  public void testIdProperty() throws Exception {
    assertTranslation( "from Animal a where a.mother.id = 12" );
  }

  public void testSubclassAssociation() throws Exception {
    assertTranslation( "from DomesticAnimal da join da.owner o where o.nickName = 'Gavin'" );
    assertTranslation( "from DomesticAnimal da left join fetch da.owner" );
    assertTranslation( "from Human h join h.pets p where p.pregnant = 1" );
    assertTranslation( "from Human h join h.pets p where p.bodyWeight > 100" );
    assertTranslation( "from Human h left join fetch h.pets" );
  }

  public void testExplicitCollectionJoins() throws Exception {
    assertTranslation( "from Animal an inner join an.offspring os" );
    assertTranslation( "from Animal an left outer join an.offspring os" );
  }

  public void testExplicitOuterJoinFetch() throws Exception {
    assertTranslation( "from Animal an left outer join fetch an.offspring" );
  }

  public void testExplicitOuterJoinFetchWithSelect() throws Exception {
    assertTranslation( "select an from Animal an left outer join fetch an.offspring" );
  }

  public void testExplicitJoins() throws Exception {
    Map replacements = buildTrueFalseReplacementMapForDialect();
    assertTranslation( "from Zoo zoo join zoo.mammals mam where mam.pregnant = true and mam.description like '%white%'", replacements );
    assertTranslation( "from Zoo zoo join zoo.animals an where an.description like '%white%'" );
  }

    /**
     * Test for HHH-559
     */
    public void testMultibyteCharacterConstant() throws Exception {
        assertTranslation( "from Zoo zoo join zoo.animals an where an.description like '%\u4e2d%'" );
    }

  public void testImplicitJoins() throws Exception {
    // Two dots...
    assertTranslation( "from Animal an where an.mother.bodyWeight > ?" );
    assertTranslation( "from Animal an where an.mother.bodyWeight > 10" );
    assertTranslation( "from Dog dog where dog.mother.bodyWeight > 10" );
    // Three dots...
    assertTranslation( "from Animal an where an.mother.mother.bodyWeight > 10" );
    // The new QT doesn't throw an exception here, so this belongs in ASTQueryTranslator test. [jsd]
//    assertTranslation( "from Animal an where an.offspring.mother.bodyWeight > 10" );
    // Is not null (unary postfix operator)
    assertTranslation( "from Animal an where an.mother is not null" );
    // ID property shortut (no implicit join)
    assertTranslation( "from Animal an where an.mother.id = 123" );
  }

  public void testImplicitJoinInSelect() {
    assertTranslation( "select foo, foo.long from Foo foo" );
    DotNode.useThetaStyleImplicitJoins = true;
    assertTranslation( "select foo.foo from Foo foo" );
    assertTranslation( "select foo, foo.foo from Foo foo" );
    assertTranslation( "select foo.foo from Foo foo where foo.foo is not null" );
    DotNode.useThetaStyleImplicitJoins = false;
  }

  public void testSelectExpressions() {
    DotNode.useThetaStyleImplicitJoins = true;
    assertTranslation( "select an.mother.mother from Animal an" );
    assertTranslation( "select an.mother.mother.mother from Animal an" );
    assertTranslation( "select an.mother.mother.bodyWeight from Animal an" );
    assertTranslation( "select an.mother.zoo.id from Animal an" );
    assertTranslation( "select user.human.zoo.id from User user" );
    assertTranslation( "select u.userName, u.human.name.first from User u" );
    assertTranslation( "select u.human.name.last, u.human.name.first from User u" );
    assertTranslation( "select bar.baz.name from Bar bar" );
    assertTranslation( "select bar.baz.name, bar.baz.count from Bar bar" );
    DotNode.useThetaStyleImplicitJoins = false;
  }

  public void testSelectStandardFunctionsNoParens() throws Exception {
    assertTranslation( "select current_date, current_time, current_timestamp from Animal" );
  }

  public void testMapIndex() throws Exception {
    assertTranslation( "from User u where u.permissions['hibernate']='read'" );
  }

  /*public void testCollectionFunctionsInSelect() {
    //sql is correct, just different order in select clause
    assertTranslation("select baz, size(baz.stringSet), count( distinct elements(baz.stringSet) ), max( elements(baz.stringSet) ) from Baz baz group by baz");
  }

  public void testSelectElements() throws Exception {
    assertTranslation( "select elements(fum1.friends) from org.hibernate.test.legacy.Fum fum1" );
    assertTranslation( "select elements(one.manies) from org.hibernate.test.legacy.One one" );
  }*/

  public void testNamedParameters() throws Exception {
    assertTranslation( "from Animal an where an.mother.bodyWeight > :weight" );
  }

  // Second set of examples....

  public void testClassProperty() throws Exception {
    // This test causes failures on theta-join dialects because the SQL is different.
    // The queries are semantically the same however.
    if ( getDialect() instanceof Oracle8iDialect ) return;
    assertTranslation( "from Animal a where a.mother.class = Reptile" );
  }

  public void testComponent() throws Exception {
    assertTranslation( "from Human h where h.name.first = 'Gavin'" );
  }

  public void testSelectEntity() throws Exception {
    assertTranslation( "select an from Animal an inner join an.mother mo where an.bodyWeight < mo.bodyWeight" );
    assertTranslation( "select mo, an from Animal an inner join an.mother mo where an.bodyWeight < mo.bodyWeight" );
  }

  public void testValueAggregate() {
    assertTranslation( "select max(p), min(p) from User u join u.permissions p" );
  }

  public void testAggregation() throws Exception {
    assertTranslation( "select count(an) from Animal an" );
    assertTranslation( "select count(*) from Animal an" );
    assertTranslation( "select count(distinct an) from Animal an" );
    assertTranslation( "select count(distinct an.id) from Animal an" );
    assertTranslation( "select count(all an.id) from Animal an" );
  }

  public void testSelectProperty() throws Exception {
    assertTranslation( "select an.bodyWeight, mo.bodyWeight from Animal an inner join an.mother mo where an.bodyWeight < mo.bodyWeight" );
  }

  public void testSelectEntityProperty() throws Exception {
    DotNode.useThetaStyleImplicitJoins = true;
    assertTranslation( "select an.mother from Animal an" );
    assertTranslation( "select an, an.mother from Animal an" );
    DotNode.useThetaStyleImplicitJoins = false;
  }

  public void testSelectDistinctAll() throws Exception {
    assertTranslation( "select distinct an.description, an.bodyWeight from Animal an" );
    assertTranslation( "select all an from Animal an" );
  }

  public void testSelectAssociatedEntityId() throws Exception {
    assertTranslation( "select an.mother.id from Animal an" );
  }

  public void testGroupBy() throws Exception {
    assertTranslation( "select an.mother.id, max(an.bodyWeight) from Animal an group by an.mother.id" );
    assertTranslation( "select an.mother.id, max(an.bodyWeight) from Animal an group by an.mother.id having max(an.bodyWeight)>1.0" );
  }

  public void testGroupByMultiple() throws Exception {
    assertTranslation( "select s.id, s.count, count(t), max(t.date) from org.hibernate.test.legacy.Simple s, org.hibernate.test.legacy.Simple t where s.count = t.count group by s.id, s.count order by s.count" );
  }

  public void testManyToMany() throws Exception {
    assertTranslation( "from Human h join h.friends f where f.nickName = 'Gavin'" );
    assertTranslation( "from Human h join h.friends f where f.bodyWeight > 100" );
  }

  public void testManyToManyElementFunctionInWhere() throws Exception {
    assertTranslation( "from Human human where human in elements(human.friends)" );
    assertTranslation( "from Human human where human = some elements(human.friends)" );
  }

  public void testManyToManyElementFunctionInWhere2() throws Exception {
    assertTranslation( "from Human h1, Human h2 where h2 in elements(h1.family)" );
    assertTranslation( "from Human h1, Human h2 where 'father' in indices(h1.family)" );
  }

  public void testManyToManyFetch() throws Exception {
    assertTranslation( "from Human h left join fetch h.friends" );
  }

  public void testManyToManyIndexAccessor() throws Exception {
    // From ParentChildTest.testCollectionQuery()
    assertTranslation( "select c from ContainerX c, Simple s where c.manyToMany[2] = s" );
    assertTranslation( "select s from ContainerX c, Simple s where c.manyToMany[2] = s" );
    assertTranslation( "from ContainerX c, Simple s where c.manyToMany[2] = s" );
    //would be nice to have:
    //assertTranslation( "select c.manyToMany[2] from ContainerX c" );
  }

  public void testSelectNew() throws Exception {
    assertTranslation( "select new Animal(an.description, an.bodyWeight) from Animal an" );
    assertTranslation( "select new org.hibernate.test.hql.Animal(an.description, an.bodyWeight) from Animal an" );
  }

  public void testSimpleCorrelatedSubselect() throws Exception {
    assertTranslation( "from Animal a where a.bodyWeight = (select o.bodyWeight from a.offspring o)" );
    assertTranslation( "from Animal a where a = (from a.offspring o)" );
  }

  public void testSimpleUncorrelatedSubselect() throws Exception {
    assertTranslation( "from Animal a where a.bodyWeight = (select an.bodyWeight from Animal an)" );
    assertTranslation( "from Animal a where a = (from Animal an)" );
  }

  public void testSimpleCorrelatedSubselect2() throws Exception {
    assertTranslation( "from Animal a where a = (select o from a.offspring o)" );
    assertTranslation( "from Animal a where a in (select o from a.offspring o)" );
  }

  public void testSimpleUncorrelatedSubselect2() throws Exception {
    assertTranslation( "from Animal a where a = (select an from Animal an)" );
    assertTranslation( "from Animal a where a in (select an from Animal an)" );
  }

  public void testUncorrelatedSubselect2() throws Exception {
    assertTranslation( "from Animal a where a.bodyWeight = (select max(an.bodyWeight) from Animal an)" );
  }

  public void testCorrelatedSubselect2() throws Exception {
    assertTranslation( "from Animal a where a.bodyWeight > (select max(o.bodyWeight) from a.offspring o)" );
  }

  public void testManyToManyJoinInSubselect() throws Exception {
    DotNode.useThetaStyleImplicitJoins = true;
    assertTranslation( "select foo from Foo foo where foo in (select elt from Baz baz join baz.fooArray elt)" );
    DotNode.useThetaStyleImplicitJoins = false;
  }

  public void testImplicitJoinInSubselect() throws Exception {
    assertTranslation( "from Animal a where a = (select an.mother from Animal an)" );
    assertTranslation( "from Animal a where a.id = (select an.mother.id from Animal an)" );
  }

  public void testManyToOneSubselect() {
    //TODO: the join in the subselect also shows up in the outer query!
    assertTranslation( "from Animal a where 'foo' in (select m.description from a.mother m)" );
  }

  public void testPositionalParameters() throws Exception {
    assertTranslation( "from Animal an where an.bodyWeight > ?" );
  }

  public void testKeywordPropertyName() throws Exception {
    assertTranslation( "from Glarch g order by g.order asc" );
    assertTranslation( "select g.order from Glarch g where g.order = 3" );
  }

  public void testJavaConstant() throws Exception {
    assertTranslation( "from org.hibernate.test.legacy.Category c where c.name = org.hibernate.test.legacy.Category.ROOT_CATEGORY" );
    assertTranslation( "from org.hibernate.test.legacy.Category c where c.id = org.hibernate.test.legacy.Category.ROOT_ID" );
    // todo : additional desired functionality
    //assertTranslation( "from Category c where c.name = Category.ROOT_CATEGORY" );
    //assertTranslation( "select c.name, Category.ROOT_ID from Category as c");
  }

  public void testClassName() throws Exception {
    // The Zoo reference is OK; Zoo is discriminator-based;
    // the old parser could handle these correctly
    //
    // However, the Animal one ares not; Animal is joined subclassing;
    // the old parser does not handle thee correctly.  The new parser
    // previously did not handle them correctly in that same way.  So they
    // used to pass regression even though the output was bogus SQL...
    //
    // I have moved the Animal ones (plus duplicating the Zoo one)
    // to ASTParserLoadingTest for syntax checking.
    assertTranslation( "from Zoo zoo where zoo.class = PettingZoo" );
//    assertTranslation( "from DomesticAnimal an where an.class = Dog" );
//    assertTranslation( "from Animal an where an.class = Dog" );
  }

  public void testSelectDialectFunction() throws Exception {
    // From SQLFunctionsTest.testDialectSQLFunctions...
    if ( getDialect() instanceof HSQLDialect ) {
      assertTranslation( "select mod(s.count, 2) from org.hibernate.test.legacy.Simple as s where s.id = 10" );
      //assertTranslation( "from org.hibernate.test.legacy.Simple as s where mod(s.count, 2) = 0" );
    }
    assertTranslation( "select upper(human.name.first) from Human human" );
    assertTranslation( "from Human human where lower(human.name.first) like 'gav%'" );
    assertTranslation( "select upper(a.description) from Animal a" );
    assertTranslation( "select max(a.bodyWeight) from Animal a" );
  }

  public void testTwoJoins() throws Exception {
    assertTranslation( "from Human human join human.friends, Human h join h.mother" );
    assertTranslation( "from Human human join human.friends f, Animal an join an.mother m where f=m" );
    assertTranslation( "from Baz baz left join baz.fooToGlarch, Bar bar join bar.foo" );
  }

  public void testToOneToManyManyJoinSequence() throws Exception {
    assertTranslation( "from Dog d join d.owner h join h.friends f where f.name.first like 'joe%'" );
  }

  public void testToOneToManyJoinSequence() throws Exception {
    assertTranslation( "from Animal a join a.mother m join m.offspring" );
    assertTranslation( "from Dog d join d.owner m join m.offspring" );
    assertTranslation( "from Animal a join a.mother m join m.offspring o where o.bodyWeight > a.bodyWeight" );
  }

  public void testSubclassExplicitJoin() throws Exception {
    assertTranslation( "from DomesticAnimal da join da.owner o where o.nickName = 'gavin'" );
    assertTranslation( "from DomesticAnimal da join da.owner o where o.bodyWeight > 0" );
  }

  public void testMultipleExplicitCollectionJoins() throws Exception {
    assertTranslation( "from Animal an inner join an.offspring os join os.offspring gc" );
    assertTranslation( "from Animal an left outer join an.offspring os left outer join os.offspring gc" );
  }

  public void testSelectDistinctComposite() throws Exception {
    // This is from CompositeElementTest.testHandSQL.
    assertTranslation( "select distinct p from org.hibernate.test.compositeelement.Parent p join p.children c where c.name like 'Child%'" );
  }

  public void testDotComponent() throws Exception {
    // from FumTest.testListIdentifiers()
    assertTranslation( "select fum.id from org.hibernate.test.legacy.Fum as fum where not fum.fum='FRIEND'" );
  }

  public void testOrderByCount() throws Exception {
    assertTranslation( "from Animal an group by an.zoo.id order by an.zoo.id, count(*)" );
  }

  public void testHavingCount() throws Exception {
    assertTranslation( "from Animal an group by an.zoo.id having count(an.zoo.id) > 1" );
  }

  public void selectWhereElements() throws Exception {
    assertTranslation( "select foo from Foo foo, Baz baz where foo in elements(baz.fooArray)" );
  }

  public void testCollectionOfComponents() throws Exception {
    assertTranslation( "from Baz baz inner join baz.components comp where comp.name='foo'" );
  }

  public void testNestedComponentIsNull() {
    // From MapTest...
    assertTranslation( "from Commento c where c.marelo.commento.mcompr is null" );
  }

  public void testOneToOneJoinedFetch() throws Exception {
    // From OneToOneTest.testOneToOneOnSubclass
    assertTranslation( "from org.hibernate.test.onetoone.joined.Person p join fetch p.address left join fetch p.mailingAddress" );
  }

  public void testSubclassImplicitJoin() throws Exception {
    assertTranslation( "from DomesticAnimal da where da.owner.nickName like 'Gavin%'" );
    assertTranslation( "from DomesticAnimal da where da.owner.nickName = 'gavin'" );
    assertTranslation( "from DomesticAnimal da where da.owner.bodyWeight > 0" );
  }

  public void testComponent2() throws Exception {
    assertTranslation( "from Dog dog where dog.owner.name.first = 'Gavin'" );
  }

  public void testOneToOne() throws Exception {
    assertTranslation( "from User u where u.human.nickName='Steve'" );
    assertTranslation( "from User u where u.human.name.first='Steve'" );
  }

  public void testSelectClauseImplicitJoin() throws Exception {
    //assertTranslation( "select d.owner.mother from Dog d" ); //bug in old qt
    assertTranslation( "select d.owner.mother.description from Dog d" );
    //assertTranslation( "select d.owner.mother from Dog d, Dog h" );
  }

  public void testFromClauseImplicitJoin() throws Exception {
    assertTranslation( "from DomesticAnimal da join da.owner.mother m where m.bodyWeight > 10" );
  }

  public void testJoinedSubclassWithOrCondition() {
    assertTranslation( "from Animal an where (an.bodyWeight > 10 and an.bodyWeight < 100) or an.bodyWeight is null" );
  }

  public void testImplicitJoinInFrom() {
    assertTranslation( "from Human h join h.mother.mother.offspring o" );
  }

  public void testDuplicateImplicitJoinInSelect() {
    // This test causes failures on theta-join dialects because the SQL is different.  The old parser
    // duplicates the condition, whereas the new parser does not.  The queries are semantically the
    // same however.
    if ( getDialect() instanceof Oracle8iDialect ) return;
// the classic translator handles this incorrectly; the explicit join and the implicit ones should create separate physical SQL joins...
//    assertTranslation( "select an.mother.bodyWeight from Animal an join an.mother m where an.mother.bodyWeight > 10" );
    assertTranslation( "select an.mother.bodyWeight from Animal an where an.mother.bodyWeight > 10" );
    //assertTranslation("select an.mother from Animal an where an.mother.bodyWeight is not null");
    assertTranslation( "select an.mother.bodyWeight from Animal an order by an.mother.bodyWeight" );
  }

  public void testConstructorNode() throws Exception {
    ConstructorNode n = new ConstructorNode();
    assertNull( n.getFromElement() );
    assertFalse( n.isReturnableEntity() );
  }

  public void testIndexNode() throws Exception {
    IndexNode n = new IndexNode();
    Exception ex = null;
    try {
      n.setScalarColumn( 0 );
    }
    catch ( UnsupportedOperationException e ) {
      ex = e;
    }
    assertNotNull( ex );
  }

  public void testExceptions() throws Exception {
    DetailedSemanticException dse = new DetailedSemanticException( "test" );
    dse.printStackTrace();
    dse.printStackTrace( new PrintWriter( new StringWriter() ) );
    QuerySyntaxException qse = QuerySyntaxException.convert( new RecognitionException( "test" ), "from bozo b where b.clown = true" );
    assertNotNull( qse.getMessage() );
  }

  public void testSelectProperty2() throws Exception {
    assertTranslation( "select an, mo.bodyWeight from Animal an inner join an.mother mo where an.bodyWeight < mo.bodyWeight" );
    assertTranslation( "select an, mo, an.bodyWeight, mo.bodyWeight from Animal an inner join an.mother mo where an.bodyWeight < mo.bodyWeight" );
  }

  public void testSubclassWhere() throws Exception {
    // TODO: The classic QT generates lots of extra parens, etc.
    assertTranslation( "from PettingZoo pz1, PettingZoo pz2 where pz1.id = pz2.id" );
    assertTranslation( "from PettingZoo pz1, PettingZoo pz2 where pz1.id = pz2" );
    assertTranslation( "from PettingZoo pz where pz.id > 0 " );
  }

  public void testNestedImplicitJoinsInSelect() throws Exception {
    // NOTE: This test is not likely to generate the exact SQL because of the where clause.  The synthetic
    // theta style joins come out differently in the new QT.
    // From FooBarTest.testQuery()
    // Missing the foo2_ join, and foo3_ should include subclasses, but it doesn't.
//    assertTranslation("select foo.foo.foo.foo.string from org.hibernate.test.legacy.Foo foo where foo.foo.foo = 'bar'");
    assertTranslation( "select foo.foo.foo.foo.string from org.hibernate.test.legacy.Foo foo" );
  }

  public void testNestedComponent() throws Exception {
    // From FooBarTest.testQuery()
    //an extra set of parens in new SQL
    assertTranslation( "from org.hibernate.test.legacy.Foo foo where foo.component.subcomponent.name='bar'" );
  }

  public void testNull2() throws Exception {
    //old parser generates useless extra parens
    assertTranslation( "from Human h where not( h.nickName is null )" );
    assertTranslation( "from Human h where not( h.nickName is not null )" );
  }

  public void testUnknownFailureFromMultiTableTest() {
    assertTranslation( "from Lower s where s.yetanother.name='name'" );
  }

  public void testJoinInSubselect() throws Exception {
    //new parser uses ANSI-style inner join syntax
    DotNode.useThetaStyleImplicitJoins = true;
    assertTranslation( "from Animal a where a in (select m from Animal an join an.mother m)" );
    assertTranslation( "from Animal a where a in (select o from Animal an join an.offspring o)" );
    DotNode.useThetaStyleImplicitJoins = false;
  }

  public void testJoinedSubclassImplicitJoin() throws Exception {
    // From MultiTableTest.testQueries()
    // TODO: This produces the proper from clause now, but the parens in the where clause are different.
    assertTranslation( "from org.hibernate.test.legacy.Lower s where s.yetanother.name='name'" );
  }

  public void testProjectProductJoinedSubclass() throws Exception {
    // TODO: The old QT generates the discriminator and the theta join in a strange order, and with two extra sets of parens, this is okay, right?
    assertTranslation( "select zoo from Zoo zoo, PettingZoo pz where zoo=pz" );
    assertTranslation( "select zoo, pz from Zoo zoo, PettingZoo pz where zoo=pz" );
  }

  public void testCorrelatedSubselect1() throws Exception {
    // The old translator generates the theta join before the condition in the sub query.
    // TODO: Decide if we want to bother generating the theta join in the same order (non simple).
    assertTranslation( "from Animal a where exists (from a.offspring o where o.bodyWeight>10)" );
  }

  public void testOuterAliasInSubselect() {
    assertTranslation( "from Human h where h = (from Animal an where an = h)" );
  }

  public void testFetch() throws Exception {
    assertTranslation( "from Zoo zoo left join zoo.mammals" );
    assertTranslation( "from Zoo zoo left join fetch zoo.mammals" );
  }

  public void testOneToManyElementFunctionInWhere() throws Exception {
    assertTranslation( "from Zoo zoo where 'dog' in indices(zoo.mammals)" );
    assertTranslation( "from Zoo zoo, Dog dog where dog in elements(zoo.mammals)" );
  }

  /*public void testManyToManyElementFunctionInSelect() throws Exception {
    assertTranslation("select elements(zoo.mammals) from Zoo zoo");
    assertTranslation("select indices(zoo.mammals) from Zoo zoo");
  }*/

  public void testManyToManyInJoin() throws Exception {
    assertTranslation( "select x.id from Human h1 join h1.family x" );
    //assertTranslation("select index(h2) from Human h1 join h1.family h2");
  }

  public void testManyToManyInSubselect() throws Exception {
    assertTranslation( "from Human h1, Human h2 where h2 in (select x.id from h1.family x)" );
    assertTranslation( "from Human h1, Human h2 where 'father' in indices(h1.family)" );
  }

  public void testOneToManyIndexAccess() throws Exception {
    assertTranslation( "from Zoo zoo where zoo.mammals['dog'] is not null" );
  }

  public void testImpliedSelect() throws Exception {
    assertTranslation( "select zoo from Zoo zoo" );
    assertTranslation( "from Zoo zoo" );
    assertTranslation( "from Zoo zoo join zoo.mammals m" );
    assertTranslation( "from Zoo" );
    assertTranslation( "from Zoo zoo join zoo.mammals" );
  }

  public void testVectorSubselect() {
    assertTranslation( "from Animal a where ('foo', 'bar') in (select m.description, m.bodyWeight from a.mother m)" );
  }

  public void testWierdSubselectImplicitJoinStuff() {
    //note that the new qt used to eliminate unnecessary join, but no more
    assertTranslation("from Simple s where s = some( select sim from Simple sim where sim.other.count=s.other.count ) and s.other.count > 0");
  }

  /*public void testSelectElementsOfCollectionOfValues() throws Exception {
    // From FooBarTest.testQuery()
    // TODO: This produces the where clause in a different order, but it seems okay.
    assertTranslation("select foo.component.name, elements(foo.component.importantDates) from org.hibernate.test.legacy.Foo foo where foo.foo.id=?");
  }*/

  //public void testMultiTableElements() throws Exception {
  /*
  HQL    : select elements(ls.bag), elements(ls.set) from org.hibernate.test.legacy.Lower ls
  OLD SQL:
  select top2_.id1_ as col_0_0_, top4_.id1_ as col_1_0_
  from leafsubclass lower0_ inner join rootclass lower0_1_ on lower0_.id__=lower0_1_.id1_, simple_simple bag1_, rootclass top2_, rootclass set3_, rootclass top4_
  where lower0_1_.id1_ is not null and lower0_.id__=bag1_.simple1 and bag1_.simple2=top2_.id1_ and lower0_.id__=set3_.parent and set3_.id1_=top4_.id1_
  */

  //assertTranslation("select elements(ls.bag), elements(ls.set) from org.hibernate.test.legacy.Lower ls");
  //}

  public void testCollectionsInSelect2() throws Exception {
    // This one looks okay now, it just generates extra parens in the where clause.
    assertTranslation( "select foo.string from Bar bar left join bar.baz.fooArray foo where bar.string = foo.string" );
  }


  //public void testCollectionsInSelect() throws Exception {
  // From FooBarTest.testCollectionsInSelect
  /*
  HQL    : select baz, baz.stringSet.size, count( distinct elements(baz.stringSet) ), max( elements(baz.stringSet) ) from org.hibernate.test.legacy.Baz baz group by baz
  OLD SQL:
  select
    baz0_.baz_id_column_ as baz_id_c1_, baz0_.count_count as count_co2_37_, baz0_.name_b as name_b37_, baz0_.foo as foo37_, baz0_.superBaz as superBaz37_, baz0_.str as str37_, baz0_.baz_id_column_ as col_0_0_,
    count(*) as col_1_0_,
    count(distinct stringset2_.element) as col_2_0_, max(stringset3_.element) as col_3_0_
  from baz baz0_, stringSet stringset1_, stringSet stringset2_, stringSet stringset3_
  where baz0_.baz_id_column_=stringset1_.id_ and baz0_.baz_id_column_=stringset2_.id_ and baz0_.baz_id_column_=stringset3_.id_
  group by  baz0_.baz_id_column_

  NEW SQL:
  select
    // TODO: Remove the extra 'id' column select.
    baz0_.baz_id_column_ as col_0_0_,
    // TODO: Figure out how the classic translator knows to use count(*)
    (select count(*) from stringSet stringset1_ where baz0_.baz_id_column_=stringset1_.id_) as col_1_0_,
    // This is also correct.
    count(distinct stringset2_.element) as col_2_0_, max(stringset3_.element) as col_3_0_,
    // The properties of baz are correct, they're just in the wrong place.
    baz0_.baz_id_column_ as baz_id_c1_, baz0_.count_count as count_co2_37_, baz0_.name_b as name_b37_, baz0_.foo as foo37_, baz0_.superBaz as superBaz37_, baz0_.str as str37_
//     FROM is okay.
  from baz baz0_ stringSet stringset1_, stringSet stringset3_, stringSet stringset2_
//     WHERE is okay.
  where (baz0_.baz_id_column_=stringset1_.id_ and baz0_.baz_id_column_=stringset2_.id_ baz0_.baz_id_column_=stringset3_.id_)
//     GROUP BY is okay.
  group by  baz0_.baz_id_column_
  */
  //assertTranslation( "select baz, size(baz.stringSet), count( distinct elements(baz.stringSet) ), max( elements(baz.stringSet) ) from org.hibernate.test.legacy.Baz baz group by baz");

  //}

  public void testAssociationPropertyWithoutAlias() throws Exception {
    // The classic translator doesn't do this right, so don't bother asserting.
    compileWithAstQueryTranslator("from Animal where zoo is null", false);
  }

  private void compileWithAstQueryTranslator(String hql, boolean scalar) {
    Map replacements = new HashMap();
    QueryTranslatorFactory ast = new ASTQueryTranslatorFactory();
    SessionFactoryImplementor factory = getSessionFactoryImplementor();
    QueryTranslator newQueryTranslator = ast.createQueryTranslator( hql, hql, Collections.EMPTY_MAP, factory );
    newQueryTranslator.compile( replacements, scalar );
  }

  public void testComponentNoAlias() throws Exception {
    // The classic translator doesn't do this right, so don't bother asserting.
    compileWithAstQueryTranslator( "from Human where name.first = 'Gavin'", false);
  }

}
TOP

Related Classes of org.hibernate.test.hql.HQLTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.