I prefer to wait before introduce some breaking-changes for parser even if is for legacy DB. Why this query should not work ? select count(*) from Bar as bar where '1' in (from g in bar.Component.Glarch.ProxyArray.elements where g.Name='foo') Who are sure that query was not ported from Hb in some moment ?
IFAIK NHibernate.Test.Legacy was one of the first tests ported from Hb. 2009/4/14 Ayende Rahien <[email protected]> > Steve, > That is great job. > Looking at the test results, I am fine with breaking all of them, except > for: > "from E e, A a where e.Reverse = a.Forward and a = ?" > > Looking at this, I am not sure _why_ this should generate a _parser_ error. > From syntax perspective, it seems to be valid. > > My point of view is in two points: > a) if we match Hibernate's behavior, we are good, because that is our spec, > for most things > b) we _can_ break backward compat in small ways. We are going to ship both > parsers for at least a while, and give the user the configuration option to > select one. That means that if a user is hit by a backward compat bug here, > they can just revert to the old parser, and continue using that. That is an > acceptable solution from my point of view. > > > On Tue, Apr 14, 2009 at 10:16 PM, Steve <[email protected]> wrote: > >> >> 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" >> > > -- Fabio Maulo
