|
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.
|