|
From: <ric...@us...> - 2011-03-02 22:20:30
|
Revision: 5414
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=5414&view=rev
Author: ricbrown
Date: 2011-03-02 22:20:24 +0000 (Wed, 02 Mar 2011)
Log Message:
-----------
Fix NH-2400 (Linq query fail when using contains from an empty Collection)
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Linq/Visitors/ExpressionKeyVisitor.cs
trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessContains.cs
trunk/nhibernate/src/NHibernate.Test/Linq/WhereTests.cs
Modified: trunk/nhibernate/src/NHibernate/Linq/Visitors/ExpressionKeyVisitor.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/Visitors/ExpressionKeyVisitor.cs 2011-03-02 05:35:53 UTC (rev 5413)
+++ trunk/nhibernate/src/NHibernate/Linq/Visitors/ExpressionKeyVisitor.cs 2011-03-02 22:20:24 UTC (rev 5414)
@@ -1,5 +1,5 @@
+using System.Collections;
using System.Collections.Generic;
-using System.Collections.ObjectModel;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
@@ -82,6 +82,8 @@
// Nulls generate different query plans. X = variable generates a different query depending on if variable is null or not.
if (param.Value == null)
_string.Append("NULL");
+ if (param.Value is ICollection && ((ICollection)param.Value).Count == 0)
+ _string.Append("EmptyList");
else
_string.Append(param.Name);
}
Modified: trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessContains.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessContains.cs 2011-03-02 05:35:53 UTC (rev 5413)
+++ trunk/nhibernate/src/NHibernate/Linq/Visitors/ResultOperatorProcessors/ProcessContains.cs 2011-03-02 22:20:24 UTC (rev 5414)
@@ -1,4 +1,5 @@
-using System.Linq;
+using System.Collections;
+using System.Linq;
using NHibernate.Hql.Ast;
using Remotion.Data.Linq.Clauses.ResultOperators;
@@ -18,7 +19,15 @@
if (source is HqlParameter)
{
// This is an "in" style statement
- tree.SetRoot(tree.TreeBuilder.In(itemExpression, source));
+ if (IsEmptyList((HqlParameter)source, queryModelVisitor.VisitorParameters))
+ {
+ // if the list is empty the expression will always be false, so generate "1 = 0"
+ tree.SetRoot(tree.TreeBuilder.Equality(tree.TreeBuilder.Constant(1), tree.TreeBuilder.Constant(0)));
+ }
+ else
+ {
+ tree.SetRoot(tree.TreeBuilder.In(itemExpression, source));
+ }
}
else
{
@@ -39,5 +48,12 @@
{
return node.NodesPreOrder.Single(n => n is HqlRange).Children.Single(n => n is HqlAlias) as HqlAlias;
}
+
+ private static bool IsEmptyList(HqlParameter source, VisitorParameters parameters)
+ {
+ var parameterName = source.NodesPreOrder.Single(n => n is HqlIdent).AstNode.Text;
+ var parameterValue = parameters.ConstantToParameterMap.Single(p => p.Value.Name == parameterName).Key.Value;
+ return ((ICollection)parameterValue).Count == 0;
+ }
}
}
\ No newline at end of file
Modified: trunk/nhibernate/src/NHibernate.Test/Linq/WhereTests.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/Linq/WhereTests.cs 2011-03-02 05:35:53 UTC (rev 5413)
+++ trunk/nhibernate/src/NHibernate.Test/Linq/WhereTests.cs 2011-03-02 22:20:24 UTC (rev 5414)
@@ -327,6 +327,18 @@
}
[Test]
+ public void UsersWithEmptyList_NH2400()
+ {
+ var names = new List<string>();
+
+ var query = (from user in db.Users
+ where names.Contains(user.Name)
+ select user).ToList();
+
+ Assert.That(query.Count, Is.EqualTo(0));
+ }
+
+ [Test]
public void WhenTheSourceOfConstantIsICollectionThenNoThrows()
{
ICollection<string> names = new List<string> {"ayende", "rahien"};
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|