From: <pa...@us...> - 2011-01-13 22:46:31
|
Revision: 5347 http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5347&view=rev Author: patearl Date: 2011-01-13 22:46:25 +0000 (Thu, 13 Jan 2011) Log Message: ----------- Improved flexibility in determining type of CASE statement result. Finds the first THEN clause with a known type and uses that. The original code only worked if the very first THEN clause had a known type. Modified Paths: -------------- trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/CaseNode.cs trunk/nhibernate/src/NHibernate.Test/HQL/Ast/HqlFixture.cs Modified: trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/CaseNode.cs =================================================================== --- trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/CaseNode.cs 2011-01-13 18:24:22 UTC (rev 5346) +++ trunk/nhibernate/src/NHibernate/Hql/Ast/ANTLR/Tree/CaseNode.cs 2011-01-13 22:46:25 UTC (rev 5347) @@ -20,15 +20,39 @@ public override IType DataType { - get { return GetFirstThenNode().DataType; } - set { base.DataType = value; } + get + { + for (int i = 0; i < ChildCount; i++) + { + IASTNode whenOrElseClause = GetChild(i); + if (whenOrElseClause.Type == HqlParser.WHEN) + { + // WHEN Child(0) THEN Child(1) + IASTNode thenClause = whenOrElseClause.GetChild(1); + if (thenClause is ISelectExpression) + { + return (thenClause as ISelectExpression).DataType; + } + } + else if (whenOrElseClause.Type == HqlParser.ELSE) + { + // ELSE Child(0) + IASTNode elseClause = whenOrElseClause.GetChild(0); + if (elseClause is ISelectExpression) + { + return (elseClause as ISelectExpression).DataType; + } + } + else + { + throw new HibernateException("Was expecting a WHEN or ELSE, but found a: " + whenOrElseClause.Text); + } + } + throw new HibernateException("Unable to determine data type of CASE statement."); + } + set { base.DataType = value; } } - private ISelectExpression GetFirstThenNode() - { - return (ISelectExpression) GetChild(0).GetChild(0).NextSibling; - } - public override void SetScalarColumnText(int i) { ColumnHelper.GenerateSingleScalarColumn(ASTFactory, this, i ); Modified: trunk/nhibernate/src/NHibernate.Test/HQL/Ast/HqlFixture.cs =================================================================== --- trunk/nhibernate/src/NHibernate.Test/HQL/Ast/HqlFixture.cs 2011-01-13 18:24:22 UTC (rev 5346) +++ trunk/nhibernate/src/NHibernate.Test/HQL/Ast/HqlFixture.cs 2011-01-13 22:46:25 UTC (rev 5347) @@ -137,6 +137,69 @@ } } + [Test] + public void ParameterInCaseThenClause() + { + using (ISession s = OpenSession()) + using (s.BeginTransaction()) + { + s.Save(new Animal { BodyWeight = 12, Description = "Polliwog" }); + s.Transaction.Commit(); + } + + try + { + using (ISession s = OpenSession()) + { + var result = s.CreateQuery("select case when 2=2 then ? else 0 end from Animal a") + .SetParameter(0, 1) + .UniqueResult(); + Assert.AreEqual(1, result); + } + } + finally + { + using (ISession s = OpenSession()) + using (s.BeginTransaction()) + { + s.CreateQuery("delete from Animal").ExecuteUpdate(); + s.Transaction.Commit(); + } + } + } + + [Test] + public void ParameterInCaseThenAndElseClausesWithCast() + { + using (ISession s = OpenSession()) + using (s.BeginTransaction()) + { + s.Save(new Animal { BodyWeight = 12, Description = "Polliwog" }); + s.Transaction.Commit(); + } + + try + { + using (ISession s = OpenSession()) + { + var result = s.CreateQuery("select case when 2=2 then cast(? as integer) else ? end from Animal a") + .SetParameter(0, 1) + .SetParameter(1, 0) + .UniqueResult(); + Assert.AreEqual(1, result); + } + } + finally + { + using (ISession s = OpenSession()) + using (s.BeginTransaction()) + { + s.CreateQuery("delete from Animal").ExecuteUpdate(); + s.Transaction.Commit(); + } + } + } + [Test, Ignore("Not fixed yet.")] public void SumShouldReturnDouble() { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |