Hi Chaps,

Finally, another update on the HQL AST parser work.  I've had a few
other things on my plate the last couple of weeks, but managed to get
a few hours in on the parser.  This post was coming out on Monday, but
I thought I'd better resync with the NHibernate trunk, and alas it
broke a couple of things.   They are now fixed, so finally I think
we're nearly there.  I've got a little bit of refactoring to do, and
sort out the error handling, but it's nothing major at all, and
doesn't stop me form getting onto the LINQ side of things at last.
There are a few tests that are failing which I could use your opinions
on whether the new behaviour is acceptable or not - these are listed
below.

If anyone wants to test this, you should just be able to get the HQL
AST parser from the uNhAddins repository, build it and drop the binary
into the NHibernate.Tests\bin\Debug-2.0. Finally, add the following to
your config:

        <property
name="query.factory_class">NHibernate.Hql.Ast.ANTLR.ASTQueryTranslatorFactory,
ANTLR-HQL</property>

One last thing, there's a change you´ll need to make to a minor change
to MultiQueryImpl.AggregateQueriesInformation() - change the foreach
from
        foreach (QueryTranslator translator in queryTranslators)
to
        foreach (IQueryTranslator translator in queryTranslators)

and this line:
        SqlCommandInfo commandInfo = translator.GetQueryStringAndTypes
(session, queryParameters);
to
        SqlCommandInfo commandInfo = translator.Loader.GetQueryStringAndTypes
(session, queryParameters);

(I've sent a patch to Fabio, so hopefully this'll end up in the trunk
soon)

That's the lot.  I'm off to look at LINQ, and if you can let me know
how to handle the issues below, that would be cool.

Cheers,

Steve


========================

TestCase 'NHibernate.Test.Hql.HQLFunctions.Cast' failed:
  Expected: 1.29999995f
  But was:  1.3d
        Z:\NHibernate\Trunk\nhibernate\src\NHibernate.Test\HQL\HQLFunctions.cs
(598,0): at NHibernate.Test.Hql.HQLFunctions.Cast()

The query that is being executed here is "select cast(cast
(a.BodyWeight as string) as Double) from Animal a".  The new parser is
returning 1.3 as a double, but the test is comparing the return value
with 1.3F (i.e., a single), and the vagaries of floating point math
causes failures when doing the comparisons.  The old parser returned
Singles for this test, hence it worked.  So the question is, should
the new parser be changed to return Singles, or should the test be
updated?

========================

Error: line 1:-1 no viable alternative at input 'is'
TestCase 'NHibernate.Test.Hql.HQLFunctions.Nullif'
failed: System.InvalidCastException : Unable to cast object of type
'Antlr.Runtime.CommonErrorNode' to type
'NHibernate.Hql.Ast.ANTLR.Tree.IASTNode'.
        Z:\uNhAddins\Trunk\ANTLR-HQL\ANTLR-HQL\Output\HqlParser.cs(5698,0):
at NHibernate.Hql.Ast.ANTLR.HqlParser.relationalExpression()
        [middle of stack deleted for brevity]
        Z:\NHibernate\Trunk\nhibernate\src\NHibernate.Test\HQL\HQLFunctions.cs
(428,0): at NHibernate.Test.Hql.HQLFunctions.Nullif()

The query here is "from Human h where nullif(h.NickName, '1e1') not is
null", and the new parser doesn't understand the "not is null"
construct.  The behaviour here matches Hibernate, which also fails
with a query of this form.  I for one don't like the syntax here, so
would be happy leaving it "broken". The user can obviously re-write
the query to get the required results (i.e., by using "is not null"
rather than the sucky "not is null"). Thoughts? BTW, ignore the
InvalidCastException that shows up in the error above, I've got to
sort out the error handling bit; it's not been high on the list, since
it's "just code" - nothing that is going to cause any issues :)

========================

failed: NHibernate.TypeMismatchException : left and right hand sides
of a binary logic operator were incompatibile
[NHibernate.DomainModel.A : NHibernate.DomainModel.E]
TearDown : System.Reflection.TargetInvocationException : Exception has
been thrown by the target of an invocation.
  ----> NUnit.Framework.AssertionException : Test didn't clean up
after itself
        Z:\uNhAddins\Trunk\ANTLR-HQL\ANTLR-HQL\Tree\BinaryLogicOperatorNode.cs
(85,0): at
NHibernate.Hql.Ast.ANTLR.Tree.BinaryLogicOperatorNode.MutateRowValueConstructorSyntaxesIfNecessary
(IType lhsType, IType rhsType)
        [middle of stack deleted for brevity]
        Z:\NHibernate\Trunk\nhibernate\src\NHibernate.Test\Legacy
\ABCProxyTest.cs(292,0): at
NHibernate.Test.Legacy.ABCProxyTest.OneToOne()

The query here is "from E e, A a where e.Reverse = a.Forward and a
= ?".  I think the new parser has this correct (I won't explain the
domain model here, it's probably easier if you just look at the
code).  To back up my claim, Hibernate shows the same behaviour for
this test :)  Take a look at the test and associated model, and let me
know what you think should happen.

========================

The following 4 are all from the Legacy test fixtures, and they all
fail in Hibernate in the same way.  Since they are under legacy, I've
not spent much time looking at them.  Are they things we need to
support in the new parser?

TestCase 'NHibernate.Test.Legacy.FooBarTest.CollectionsInSelect'
failed: System.NullReferenceException : Object reference not set to an
instance of an object.
TearDown : System.Reflection.TargetInvocationException : Exception has
been thrown by the target of an invocation.
  ----> NUnit.Framework.AssertionException : Test didn't clean up
after itself. session closed: False database cleaned: True connection
closed: True
        Z:\uNhAddins\Trunk\ANTLR-HQL\ANTLR-HQL\Tree\SelectExpressionList.cs
(30,0): at
NHibernate.Hql.Ast.ANTLR.Tree.SelectExpressionList.CollectSelectExpressions
()
        [middle of stack deleted for brevity]
        Z:\NHibernate\Trunk\nhibernate\src\NHibernate.Test\Legacy
\FooBarTest.cs(2471,0): at
NHibernate.Test.Legacy.FooBarTest.CollectionsInSelect()
Query was "select count(*) from Bar as bar where '1' in (from g in
bar.Component.Glarch.ProxyArray.elements where g.Name='foo')"

TestCase 'NHibernate.Test.Legacy.FooBarTest.Query'
failed: NHibernate.ADOException : could not execute query
[SQL: select bar0_.[foo_id] as foo1_517_, bar0_.Version as
Version517_, bar0_.foo as foo517_, bar0_.long_ as long5_517_, bar0_.
[@@##integer_  *] as column6_517_, bar0_.float_ as float7_517_,
bar0_.X as X517_, bar0_.date_ as date9_517_, bar0_.timestamp_ as
timestamp10_517_, bar0_.boolean_ as boolean11_517_, bar0_.bool_ as
bool12_517_, bar0_.null_ as null13_517_, bar0_.short_ as short14_517_,
bar0_.char_ as char15_517_, bar0_.zero_ as zero16_517_, bar0_.int_ as
int17_517_, bar0_.string_ as string18_517_, bar0_.byte_ as
byte19_517_, bar0_.YesNo as YesNo517_, bar0_.[stat...@###] as
status21_517_, bar0_.[localeayzabc1...@#$] as localea22_517_,
bar0_.first_name as first23_517_, bar0_.surname as surname517_,
bar0_.Dependent as Dependent517_, bar0_.count_ as count26_517_,
bar0_.name_ as name27_517_, bar0_.g__ as g28_517_, bar0_.cmpnt_null_
as cmpnt29_517_, bar0_.subcount as subcount517_, bar0_.subname as
subname517_, bar0_.fee_sub as fee32_517_, bar0_.null_cmpnt_ as
null33_517_, bar0_.the_time as the34_517_, bar0_.Baz as Baz517_,
bar0_.bar_String as bar36_517_, bar0_.name_name as name37_517_,
bar0_.bar_count as bar38_517_, bar0_.Name as Name517_, bar0_.clazz as
clazz517_, bar0_.[gen_id] as gen41_517_, 2 * bar0_.int_ as formula37_
from [foos] bar0_, StringDateMap stringdate2_ where bar0_.
[$foo_subclass^]='B' and bar0_.Baz=baz1_.baz_id and
baz1_.baz_id=stringdate2_.id_ and stringdate2_.map_key = 'now' and
(stringdate2_.map_value is not null)]
  ----> System.Data.SqlClient.SqlException : The multi-part identifier
"baz1_.baz_id" could not be bound.
The multi-part identifier "baz1_.baz_id" could not be bound.
TearDown : System.Reflection.TargetInvocationException : Exception has
been thrown by the target of an invocation.
  ----> NUnit.Framework.AssertionException : Test didn't clean up
after itself. session closed: False database cleaned: False connection
closed: True
        Z:\NHibernate\Trunk\nhibernate\src\NHibernate\Loader\Loader.cs
(1661,0): at NHibernate.Loader.Loader.DoList(ISessionImplementor
session, QueryParameters queryParameters)
        [middle of stack deleted for brevity]
        Z:\NHibernate\Trunk\nhibernate\src\NHibernate.Test\Legacy
\FooBarTest.cs(855,0): at NHibernate.Test.Legacy.FooBarTest.Query()
Query was "select bar from Bar bar where bar.Baz.StringDateMap['now']
is not null"

TestCase 'NHibernate.Test.Legacy.MasterDetailTest.CollectionQuery'
failed: System.NullReferenceException : Object reference not set to an
instance of an object.
TearDown : System.Reflection.TargetInvocationException : Exception has
been thrown by the target of an invocation.
  ----> NUnit.Framework.AssertionException : Test didn't clean up
after itself. session closed: False database cleaned: True connection
closed: True
        Z:\uNhAddins\Trunk\ANTLR-HQL\ANTLR-HQL\Tree\SelectExpressionList.cs
(30,0): at
NHibernate.Hql.Ast.ANTLR.Tree.SelectExpressionList.CollectSelectExpressions
()
        [middle of stack deleted for brevity]
        Z:\NHibernate\Trunk\nhibernate\src\NHibernate.Test\Legacy
\MasterDetailTest.cs(371,0): at
NHibernate.Test.Legacy.MasterDetailTest.CollectionQuery()
Query was "FROM m IN CLASS Master WHERE NOT EXISTS ( FROM d in
m.Details.elements WHERE NOT d.I=5 )"

TestCase 'NHibernate.Test.Legacy.MasterDetailTest.MasterDetail'
failed: NHibernate.QueryException : query specified join fetching, but
the owner of the fetched association was not present in the select
list [FromElement{explicit,not a collection join,fetch join,fetch non-
lazy
properties,classAlias=,role=NHibernate.DomainModel.Master.Details,tableName=Detail,tableAlias=details1_,origin=Master
master0_,colums=
{master0_.master_key_column ,className=NHibernate.DomainModel.Detail}}]
[select m.id from NHibernate.DomainModel.Master m inner join fetch
m.Details]
TearDown : System.Reflection.TargetInvocationException : Exception has
been thrown by the target of an invocation.
  ----> NUnit.Framework.AssertionException : Test didn't clean up
after itself. session closed: False database cleaned: False connection
closed: True
        Z:\uNhAddins\Trunk\ANTLR-HQL\ANTLR-HQL\Tree\SelectClause.cs(200,0):
at
NHibernate.Hql.Ast.ANTLR.Tree.SelectClause.InitializeExplicitSelectClause
(FromClause fromClause)
        [middle of stack deleted for brevity]
        Z:\NHibernate\Trunk\nhibernate\src\NHibernate.Test\Legacy
\MasterDetailTest.cs(465,0): at
NHibernate.Test.Legacy.MasterDetailTest.MasterDetail()
Query was: "select m.id from Master m inner join fetch m.Details"

Reply via email to