|
From: <aye...@us...> - 2008-07-18 07:32:52
|
Revision: 3640
http://nhibernate.svn.sourceforge.net/nhibernate/?rev=3640&view=rev
Author: ayenderahien
Date: 2008-07-18 07:32:56 +0000 (Fri, 18 Jul 2008)
Log Message:
-----------
NH-1359 - Applying patch from Will Shaver to create an IProjection from a DetachedCriteria
Modified Paths:
--------------
trunk/nhibernate/src/NHibernate/Criterion/Projections.cs
trunk/nhibernate/src/NHibernate/Criterion/Subqueries.cs
trunk/nhibernate/src/NHibernate/Criterion/SubqueryExpression.cs
trunk/nhibernate/src/NHibernate/Dialect/MsSql2005Dialect.cs
trunk/nhibernate/src/NHibernate/Loader/Loader.cs
trunk/nhibernate/src/NHibernate/NHibernate-2.0.csproj
trunk/nhibernate/src/NHibernate/NHibernate-3.5.csproj
trunk/nhibernate/src/NHibernate/SqlCommand/InFragment.cs
trunk/nhibernate/src/NHibernate/SqlCommand/SubselectClauseExtractor.cs
trunk/nhibernate/src/NHibernate.Test/DialectTest/MsSql2005DialectFixture.cs
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1101/Domain.cs
trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-2.0.csproj
trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-3.5.csproj
Added Paths:
-----------
trunk/nhibernate/src/NHibernate/Criterion/SelectSubqueryExpression.cs
trunk/nhibernate/src/NHibernate/Criterion/SubqueryProjection.cs
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1359/
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1359/Fixture.cs
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1359/Mappings.hbm.xml
trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1359/Person.cs
Modified: trunk/nhibernate/src/NHibernate/Criterion/Projections.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/Projections.cs 2008-07-18 06:52:02 UTC (rev 3639)
+++ trunk/nhibernate/src/NHibernate/Criterion/Projections.cs 2008-07-18 07:32:56 UTC (rev 3640)
@@ -241,5 +241,11 @@
{
return new ConditionalProjection(criterion, whenTrue, whenFalse);
}
+
+ public static IProjection SubQuery(DetachedCriteria detachedCriteria)
+ {
+ SelectSubqueryExpression expr = new SelectSubqueryExpression(detachedCriteria);
+ return new SubqueryProjection(expr);
+ }
}
-}
\ No newline at end of file
+}
Added: trunk/nhibernate/src/NHibernate/Criterion/SelectSubqueryExpression.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/SelectSubqueryExpression.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Criterion/SelectSubqueryExpression.cs 2008-07-18 07:32:56 UTC (rev 3640)
@@ -0,0 +1,23 @@
+using System;
+using NHibernate.SqlCommand;
+
+namespace NHibernate.Criterion
+{
+ /// <summary>
+ /// A comparison between a property value in the outer query and the
+ /// result of a subquery
+ /// </summary>
+ [Serializable]
+ public class SelectSubqueryExpression : SubqueryExpression
+ {
+ internal SelectSubqueryExpression(DetachedCriteria dc)
+ : base(null, null, dc)
+ {
+ }
+
+ protected override SqlString ToLeftSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery)
+ {
+ return SqlString.Empty;
+ }
+ }
+}
Modified: trunk/nhibernate/src/NHibernate/Criterion/Subqueries.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/Subqueries.cs 2008-07-18 06:52:02 UTC (rev 3639)
+++ trunk/nhibernate/src/NHibernate/Criterion/Subqueries.cs 2008-07-18 07:32:56 UTC (rev 3640)
@@ -190,5 +190,10 @@
{
return new SimpleSubqueryExpression(value, "<=", "some", dc);
}
+
+ public static AbstractCriterion Select(DetachedCriteria detachedCriteria)
+ {
+ return new SelectSubqueryExpression(detachedCriteria);
+ }
}
-}
\ No newline at end of file
+}
Modified: trunk/nhibernate/src/NHibernate/Criterion/SubqueryExpression.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/SubqueryExpression.cs 2008-07-18 06:52:02 UTC (rev 3639)
+++ trunk/nhibernate/src/NHibernate/Criterion/SubqueryExpression.cs 2008-07-18 07:32:56 UTC (rev 3640)
@@ -27,7 +27,7 @@
this.op = op;
}
- protected IType[] GetTypes()
+ public IType[] GetTypes()
{
return types;
}
@@ -98,7 +98,7 @@
return null;
}
- private void InitializeInnerQueryAndParameters(ICriteriaQuery criteriaQuery)
+ public void InitializeInnerQueryAndParameters(ICriteriaQuery criteriaQuery)
{
ISessionFactoryImplementor factory = criteriaQuery.Factory;
innerQuery =
@@ -115,4 +115,4 @@
get { return criteriaImpl; }
}
}
-}
\ No newline at end of file
+}
Added: trunk/nhibernate/src/NHibernate/Criterion/SubqueryProjection.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Criterion/SubqueryProjection.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate/Criterion/SubqueryProjection.cs 2008-07-18 07:32:56 UTC (rev 3640)
@@ -0,0 +1,59 @@
+using System;
+using NHibernate.Impl;
+using NHibernate.SqlCommand;
+using NHibernate.Type;
+
+namespace NHibernate.Criterion
+{
+ using System.Collections.Generic;
+
+ /// <summary>
+ /// A property value, or grouped property value
+ /// </summary>
+ [Serializable]
+ public class SubqueryProjection : SimpleProjection
+ {
+ private SelectSubqueryExpression _subQuery;
+
+ protected internal SubqueryProjection(SelectSubqueryExpression subquery)
+ {
+ _subQuery = subquery;
+ }
+ public override string ToString()
+ {
+ return _subQuery.ToString();
+ }
+
+ public override bool IsGrouped
+ {
+ get { return false; }
+ }
+
+ public override bool IsAggregate
+ {
+ get { return false; }
+ }
+
+ public override IType[] GetTypes(ICriteria criteria, ICriteriaQuery criteriaQuery)
+ {
+ _subQuery.InitializeInnerQueryAndParameters(criteriaQuery);
+ return _subQuery.GetTypes();
+ }
+
+ public override SqlString ToSqlString(ICriteria criteria, int loc, ICriteriaQuery criteriaQuery, IDictionary<string, IFilter> enabledFilters)
+ {
+ SqlString sqlStringSubquery = _subQuery.ToSqlString(criteria, criteriaQuery, enabledFilters);
+ return sqlStringSubquery.Append(new SqlString(new object[]
+ {
+ " as y",
+ loc.ToString(),
+ "_"
+ }));
+ }
+
+ public override SqlString ToGroupSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, IDictionary<string, IFilter> enabledFilters)
+ {
+ throw new InvalidOperationException("not a grouping projection");
+ }
+ }
+}
Modified: trunk/nhibernate/src/NHibernate/Dialect/MsSql2005Dialect.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Dialect/MsSql2005Dialect.cs 2008-07-18 06:52:02 UTC (rev 3639)
+++ trunk/nhibernate/src/NHibernate/Dialect/MsSql2005Dialect.cs 2008-07-18 07:32:56 UTC (rev 3640)
@@ -73,7 +73,7 @@
.Add(StringHelper.Join(", ", columnsOrAliases))
.Add(" FROM (SELECT ROW_NUMBER() OVER(ORDER BY ");
- AppendSortExpressions(sortExpressions, result);
+ AppendSortExpressions(columnsOrAliases, sortExpressions, result);
result.Add(") as row, ");
@@ -84,22 +84,27 @@
if (notLastColumn)
result.Add(", ");
}
-
- for (int i = 1; i <= sortExpressions.Length; ++i)
+ for (int i = 0; i < sortExpressions.Length; i++)
{
- result.Add(", query.__hibernate_sort_expr_")
- .Add(i.ToString())
- .Add("__");
+ string sortExpression = RemoveSortOrderDirection(sortExpressions[i]);
+ if(!columnsOrAliases.Contains(sortExpression))
+ {
+ result.Add(", query.__hibernate_sort_expr_")
+ .Add(i.ToString())
+ .Add("__");
+ }
}
result.Add(" FROM (")
.Add(select);
- for (int i = 1; i <= sortExpressions.Length; i++)
+ for (int i = 0; i < sortExpressions.Length; i++)
{
- // Drop the ASC/DESC at the end of the sort expression which might look like "count(distinct frog.Id)desc" or "frog.Name asc".
- string sortExpression = Regex.Replace(sortExpressions[i - 1].Trim(), @"(\)|\s)(?i:asc|desc)$", "$1").Trim();
+ string sortExpression = RemoveSortOrderDirection(sortExpressions[i]);
+ if(columnsOrAliases.Contains(sortExpression))
+ continue;
+
if (aliasToColumn.ContainsKey(sortExpression))
sortExpression = aliasToColumn[sortExpression];
@@ -116,23 +121,36 @@
.Add(offset.ToString())
.Add(" ORDER BY ");
- AppendSortExpressions(sortExpressions, result);
+ AppendSortExpressions(columnsOrAliases, sortExpressions, result);
return result.ToSqlString();
}
- private void AppendSortExpressions(string[] sortExpressions, SqlStringBuilder result)
+ private static string RemoveSortOrderDirection(string sortExpression)
{
- for (int i = 1; i <= sortExpressions.Length; i++)
+ // Drop the ASC/DESC at the end of the sort expression which might look like "count(distinct frog.Id)desc" or "frog.Name asc".
+ return Regex.Replace(sortExpression.Trim(), @"(\)|\s)(?i:asc|desc)$", "$1").Trim();
+ }
+
+ private static void AppendSortExpressions(ICollection<string> columnsOrAliases, string[] sortExpressions, SqlStringBuilder result)
+ {
+ for (int i = 0; i < sortExpressions.Length; i++)
{
- if (i > 1)
+ if(i > 1)
result.Add(", ");
- result.Add("__hibernate_sort_expr_")
- .Add(i.ToString())
- .Add("__");
-
- if (sortExpressions[i - 1].Trim().ToLower().EndsWith("desc"))
+ string sortExpression = RemoveSortOrderDirection(sortExpressions[i]);
+ if(columnsOrAliases.Contains(sortExpression))
+ {
+ result.Add(sortExpression);
+ }
+ else
+ {
+ result.Add("__hibernate_sort_expr_")
+ .Add(i.ToString())
+ .Add("__");
+ }
+ if (sortExpressions[i].Trim().ToLower().EndsWith("desc"))
result.Add(" DESC");
}
}
@@ -181,6 +199,8 @@
index += 1;
}
+ string alias = token;
+
bool isFunctionCallOrQuotedString = token.Contains("'") || token.Contains("(");
// this is heuristic guess, if the expression contains ' or (, it is probably
// not appropriate to just slice parts off of it
@@ -188,11 +208,9 @@
{
int dot = token.IndexOf('.');
if (dot != -1)
- token = token.Substring(dot + 1);
+ alias = token.Substring(dot + 1);
}
- string alias = token;
-
// notice! we are checking here the existence of "as" "alias", two
// tokens from the current one
if (index + 1 < tokens.Count &&
Modified: trunk/nhibernate/src/NHibernate/Loader/Loader.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/Loader/Loader.cs 2008-07-18 06:52:02 UTC (rev 3639)
+++ trunk/nhibernate/src/NHibernate/Loader/Loader.cs 2008-07-18 07:32:56 UTC (rev 3640)
@@ -391,7 +391,7 @@
int entitySpan = EntityPersisters.Length;
ArrayList hydratedObjects = entitySpan == 0 ? null : new ArrayList(entitySpan * 10);
- ;
+
IDbCommand st = PrepareQueryCommand(queryParameters, false, session);
IDataReader rs =
@@ -1830,4 +1830,4 @@
#endregion
}
-}
\ No newline at end of file
+}
Modified: trunk/nhibernate/src/NHibernate/NHibernate-2.0.csproj
===================================================================
--- trunk/nhibernate/src/NHibernate/NHibernate-2.0.csproj 2008-07-18 06:52:02 UTC (rev 3639)
+++ trunk/nhibernate/src/NHibernate/NHibernate-2.0.csproj 2008-07-18 07:32:56 UTC (rev 3640)
@@ -586,6 +586,7 @@
<Compile Include="Dialect\Lock\UpdateLockingStrategy.cs" />
<Compile Include="Dialect\MsSqlCeDialect.cs" />
<Compile Include="Dialect\MySQL5Dialect.cs" />
+ <Compile Include="Criterion\SelectSubqueryExpression.cs" />
<Compile Include="Dialect\PostgreSQL82Dialect.cs" />
<Compile Include="Dialect\Schema\FirebirdMetaData.cs" />
<Compile Include="Dialect\Schema\ITableMetadata.cs" />
@@ -594,6 +595,7 @@
<Compile Include="Dialect\Sybase11Dialect.cs" />
<Compile Include="Driver\ISqlParameterFormatter.cs" />
<Compile Include="Driver\SqlStringFormatter.cs" />
+ <Compile Include="Criterion\SubqueryProjection.cs" />
<Compile Include="EmptyInterceptor.cs" />
<Compile Include="Engine\ActionQueue.cs" />
<Compile Include="Engine\AssociationKey.cs" />
Modified: trunk/nhibernate/src/NHibernate/NHibernate-3.5.csproj
===================================================================
--- trunk/nhibernate/src/NHibernate/NHibernate-3.5.csproj 2008-07-18 06:52:02 UTC (rev 3639)
+++ trunk/nhibernate/src/NHibernate/NHibernate-3.5.csproj 2008-07-18 07:32:56 UTC (rev 3640)
@@ -586,6 +586,7 @@
<Compile Include="Criterion\Restrictions.cs" />
<Compile Include="Criterion\RowCountInt64Projection.cs" />
<Compile Include="Criterion\RowCountProjection.cs" />
+ <Compile Include="Criterion\SelectSubqueryExpression.cs" />
<Compile Include="Criterion\SimpleExpression.cs" />
<Compile Include="Criterion\SimpleProjection.cs" />
<Compile Include="Criterion\SimpleSubqueryExpression.cs" />
@@ -594,6 +595,7 @@
<Compile Include="Criterion\SQLProjection.cs" />
<Compile Include="Criterion\Subqueries.cs" />
<Compile Include="Criterion\SubqueryExpression.cs" />
+ <Compile Include="Criterion\SubqueryProjection.cs" />
<Compile Include="DebugHelpers\DictionaryProxy.cs" />
<Compile Include="DebugHelpers\CollectionProxy.cs" />
<Compile Include="Dialect\Function\AnsiExtractFunction.cs" />
Modified: trunk/nhibernate/src/NHibernate/SqlCommand/InFragment.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/SqlCommand/InFragment.cs 2008-07-18 06:52:02 UTC (rev 3639)
+++ trunk/nhibernate/src/NHibernate/SqlCommand/InFragment.cs 2008-07-18 07:32:56 UTC (rev 3640)
@@ -1,3 +1,4 @@
+
using System;
using System.Collections;
using NHibernate.Util;
@@ -119,6 +120,8 @@
}
else
{
+ if(values.Count == 0)
+ throw new ArgumentOutOfRangeException("Attempting to parse a null value into an sql string.");
object value = values[0];
if (Null.Equals(value))
{
@@ -136,4 +139,4 @@
return buf.ToSqlString();
}
}
-}
\ No newline at end of file
+}
Modified: trunk/nhibernate/src/NHibernate/SqlCommand/SubselectClauseExtractor.cs
===================================================================
--- trunk/nhibernate/src/NHibernate/SqlCommand/SubselectClauseExtractor.cs 2008-07-18 06:52:02 UTC (rev 3639)
+++ trunk/nhibernate/src/NHibernate/SqlCommand/SubselectClauseExtractor.cs 2008-07-18 07:32:56 UTC (rev 3640)
@@ -16,7 +16,7 @@
private int lastOrderByIndex;
private int lastOrderByPartIndex;
-
+ private int parenNestCount;
private object[] sqlParts;
/// <summary>
@@ -72,7 +72,7 @@
public SqlString GetSqlString()
{
IEnumerator partEnumerator = sqlParts.GetEnumerator();
-
+ parenNestCount = 0;
// Process the parts until FROM is found
while (partEnumerator.MoveNext())
{
@@ -94,12 +94,11 @@
return builder.ToSqlString();
}
- private static int FindFromClauseInPart(string part)
+ private int FindFromClauseInPart(string part)
{
int afterLastClosingParenIndex = 0;
int fromIndex = StringHelper.IndexOfCaseInsensitive(part, FromClauseToken);
- int parenNestCount = 0;
-
+
for (int i = 0; i < part.Length; i++)
{
if (parenNestCount == 0 && i > fromIndex)
@@ -129,6 +128,9 @@
fromIndex = StringHelper.IndexOfCaseInsensitive(part, FromClauseToken);
}
+ if(parenNestCount > 0)
+ return -1;
+
return fromIndex;
}
Modified: trunk/nhibernate/src/NHibernate.Test/DialectTest/MsSql2005DialectFixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/DialectTest/MsSql2005DialectFixture.cs 2008-07-18 06:52:02 UTC (rev 3639)
+++ trunk/nhibernate/src/NHibernate.Test/DialectTest/MsSql2005DialectFixture.cs 2008-07-18 07:32:56 UTC (rev 3640)
@@ -17,49 +17,49 @@
SqlString str = d.GetLimitString(new SqlString("SELECT fish.id FROM fish"), 0, 10);
Assert.AreEqual(
- "SELECT TOP 10 id FROM (SELECT ROW_NUMBER() OVER(ORDER BY __hibernate_sort_expr_1__) as row, query.id, query.__hibernate_sort_expr_1__ FROM (SELECT fish.id, CURRENT_TIMESTAMP as __hibernate_sort_expr_1__ FROM fish) query ) page WHERE page.row > 0 ORDER BY __hibernate_sort_expr_1__",
+ "SELECT TOP 10 id FROM (SELECT ROW_NUMBER() OVER(ORDER BY __hibernate_sort_expr_0__) as row, query.id, query.__hibernate_sort_expr_0__ FROM (SELECT fish.id, CURRENT_TIMESTAMP as __hibernate_sort_expr_0__ FROM fish) query ) page WHERE page.row > 0 ORDER BY __hibernate_sort_expr_0__",
str.ToString());
str = d.GetLimitString(new SqlString("SELECT DISTINCT fish_.id FROM fish fish_"), 0, 10);
Assert.AreEqual(
- "SELECT TOP 10 id FROM (SELECT ROW_NUMBER() OVER(ORDER BY __hibernate_sort_expr_1__) as row, query.id, query.__hibernate_sort_expr_1__ FROM (SELECT DISTINCT fish_.id, CURRENT_TIMESTAMP as __hibernate_sort_expr_1__ FROM fish fish_) query ) page WHERE page.row > 0 ORDER BY __hibernate_sort_expr_1__",
+ "SELECT TOP 10 id FROM (SELECT ROW_NUMBER() OVER(ORDER BY __hibernate_sort_expr_0__) as row, query.id, query.__hibernate_sort_expr_0__ FROM (SELECT DISTINCT fish_.id, CURRENT_TIMESTAMP as __hibernate_sort_expr_0__ FROM fish fish_) query ) page WHERE page.row > 0 ORDER BY __hibernate_sort_expr_0__",
str.ToString());
str = d.GetLimitString(new SqlString("SELECT DISTINCT fish_.id as ixx9_ FROM fish fish_"), 0, 10);
Assert.AreEqual(
- "SELECT TOP 10 ixx9_ FROM (SELECT ROW_NUMBER() OVER(ORDER BY __hibernate_sort_expr_1__) as row, query.ixx9_, query.__hibernate_sort_expr_1__ FROM (SELECT DISTINCT fish_.id as ixx9_, CURRENT_TIMESTAMP as __hibernate_sort_expr_1__ FROM fish fish_) query ) page WHERE page.row > 0 ORDER BY __hibernate_sort_expr_1__",
+ "SELECT TOP 10 ixx9_ FROM (SELECT ROW_NUMBER() OVER(ORDER BY __hibernate_sort_expr_0__) as row, query.ixx9_, query.__hibernate_sort_expr_0__ FROM (SELECT DISTINCT fish_.id as ixx9_, CURRENT_TIMESTAMP as __hibernate_sort_expr_0__ FROM fish fish_) query ) page WHERE page.row > 0 ORDER BY __hibernate_sort_expr_0__",
str.ToString());
str = d.GetLimitString(new SqlString("SELECT * FROM fish ORDER BY name"), 5, 15);
Assert.AreEqual(
- "SELECT TOP 15 * FROM (SELECT ROW_NUMBER() OVER(ORDER BY __hibernate_sort_expr_1__) as row, query.*, query.__hibernate_sort_expr_1__ FROM (SELECT *, name as __hibernate_sort_expr_1__ FROM fish) query ) page WHERE page.row > 5 ORDER BY __hibernate_sort_expr_1__",
+ "SELECT TOP 15 * FROM (SELECT ROW_NUMBER() OVER(ORDER BY __hibernate_sort_expr_0__) as row, query.*, query.__hibernate_sort_expr_0__ FROM (SELECT *, name as __hibernate_sort_expr_0__ FROM fish) query ) page WHERE page.row > 5 ORDER BY __hibernate_sort_expr_0__",
str.ToString());
str = d.GetLimitString(new SqlString("SELECT fish.id, fish.name FROM fish ORDER BY name DESC"), 7, 28);
Assert.AreEqual(
- "SELECT TOP 28 id, name FROM (SELECT ROW_NUMBER() OVER(ORDER BY __hibernate_sort_expr_1__ DESC) as row, query.id, query.name, query.__hibernate_sort_expr_1__ FROM (SELECT fish.id, fish.name, name as __hibernate_sort_expr_1__ FROM fish) query ) page WHERE page.row > 7 ORDER BY __hibernate_sort_expr_1__ DESC",
+ "SELECT TOP 28 id, name FROM (SELECT ROW_NUMBER() OVER(ORDER BY name DESC) as row, query.id, query.name FROM (SELECT fish.id, fish.name FROM fish) query ) page WHERE page.row > 7 ORDER BY name DESC",
str.ToString());
str =
d.GetLimitString(
new SqlString("SELECT * FROM fish LEFT JOIN (SELECT * FROM meat ORDER BY weight) AS t ORDER BY name DESC"), 10, 20);
Assert.AreEqual(
- "SELECT TOP 20 * FROM (SELECT ROW_NUMBER() OVER(ORDER BY __hibernate_sort_expr_1__ DESC) as row, query.*, query.__hibernate_sort_expr_1__ FROM (SELECT *, name as __hibernate_sort_expr_1__ FROM fish LEFT JOIN (SELECT * FROM meat ORDER BY weight) AS t) query ) page WHERE page.row > 10 ORDER BY __hibernate_sort_expr_1__ DESC",
+ "SELECT TOP 20 * FROM (SELECT ROW_NUMBER() OVER(ORDER BY __hibernate_sort_expr_0__ DESC) as row, query.*, query.__hibernate_sort_expr_0__ FROM (SELECT *, name as __hibernate_sort_expr_0__ FROM fish LEFT JOIN (SELECT * FROM meat ORDER BY weight) AS t) query ) page WHERE page.row > 10 ORDER BY __hibernate_sort_expr_0__ DESC",
str.ToString());
str = d.GetLimitString(new SqlString("SELECT *, (SELECT COUNT(1) FROM fowl WHERE fish_id = fish.id) AS some_count FROM fish"), 0, 10);
Assert.AreEqual(
- "SELECT TOP 10 *, some_count FROM (SELECT ROW_NUMBER() OVER(ORDER BY __hibernate_sort_expr_1__) as row, query.*, query.some_count, query.__hibernate_sort_expr_1__ FROM (SELECT *, (SELECT COUNT(1) FROM fowl WHERE fish_id = fish.id) AS some_count, CURRENT_TIMESTAMP as __hibernate_sort_expr_1__ FROM fish) query ) page WHERE page.row > 0 ORDER BY __hibernate_sort_expr_1__",
+ "SELECT TOP 10 *, some_count FROM (SELECT ROW_NUMBER() OVER(ORDER BY __hibernate_sort_expr_0__) as row, query.*, query.some_count, query.__hibernate_sort_expr_0__ FROM (SELECT *, (SELECT COUNT(1) FROM fowl WHERE fish_id = fish.id) AS some_count, CURRENT_TIMESTAMP as __hibernate_sort_expr_0__ FROM fish) query ) page WHERE page.row > 0 ORDER BY __hibernate_sort_expr_0__",
str.ToString());
str = d.GetLimitString(new SqlString("SELECT * FROM fish WHERE scales = ", Parameter.Placeholder), 0, 10);
Assert.AreEqual(
- "SELECT TOP 10 * FROM (SELECT ROW_NUMBER() OVER(ORDER BY __hibernate_sort_expr_1__) as row, query.*, query.__hibernate_sort_expr_1__ FROM (SELECT *, CURRENT_TIMESTAMP as __hibernate_sort_expr_1__ FROM fish WHERE scales = ?) query ) page WHERE page.row > 0 ORDER BY __hibernate_sort_expr_1__",
+ "SELECT TOP 10 * FROM (SELECT ROW_NUMBER() OVER(ORDER BY __hibernate_sort_expr_0__) as row, query.*, query.__hibernate_sort_expr_0__ FROM (SELECT *, CURRENT_TIMESTAMP as __hibernate_sort_expr_0__ FROM fish WHERE scales = ?) query ) page WHERE page.row > 0 ORDER BY __hibernate_sort_expr_0__",
str.ToString());
str = d.GetLimitString(new SqlString("SELECT f.Type, COUNT(DISTINCT f.Name) AS Name FROM Fish f GROUP BY f.Type ORDER BY COUNT(DISTINCT f.Name)"), 0, 10);
Assert.AreEqual(
- "SELECT TOP 10 Type, Name FROM (SELECT ROW_NUMBER() OVER(ORDER BY __hibernate_sort_expr_1__) as row, query.Type, query.Name, query.__hibernate_sort_expr_1__ FROM (SELECT f.Type, COUNT(DISTINCT f.Name) AS Name, COUNT(DISTINCT f.Name) as __hibernate_sort_expr_1__ FROM Fish f GROUP BY f.Type) query ) page WHERE page.row > 0 ORDER BY __hibernate_sort_expr_1__",
+ "SELECT TOP 10 Type, Name FROM (SELECT ROW_NUMBER() OVER(ORDER BY __hibernate_sort_expr_0__) as row, query.Type, query.Name, query.__hibernate_sort_expr_0__ FROM (SELECT f.Type, COUNT(DISTINCT f.Name) AS Name, COUNT(DISTINCT f.Name) as __hibernate_sort_expr_0__ FROM Fish f GROUP BY f.Type) query ) page WHERE page.row > 0 ORDER BY __hibernate_sort_expr_0__",
str.ToString());
}
@@ -69,13 +69,13 @@
MsSql2005Dialect d = new MsSql2005Dialect();
SqlString result =
d.GetLimitString(new SqlString("select concat(a.Description,', ', a.Description) as desc from Animal a"), 0, 10);
- Assert.AreEqual("SELECT TOP 10 desc FROM (SELECT ROW_NUMBER() OVER(ORDER BY __hibernate_sort_expr_1__) as row, query.desc, query.__hibernate_sort_expr_1__ FROM (select concat(a.Description,', ', a.Description) as desc, CURRENT_TIMESTAMP as __hibernate_sort_expr_1__ from Animal a) query ) page WHERE page.row > 0 ORDER BY __hibernate_sort_expr_1__", result.ToString());
+ Assert.AreEqual("SELECT TOP 10 desc FROM (SELECT ROW_NUMBER() OVER(ORDER BY __hibernate_sort_expr_0__) as row, query.desc, query.__hibernate_sort_expr_0__ FROM (select concat(a.Description,', ', a.Description) as desc, CURRENT_TIMESTAMP as __hibernate_sort_expr_0__ from Animal a) query ) page WHERE page.row > 0 ORDER BY __hibernate_sort_expr_0__", result.ToString());
// The test use the function "cast" because cast need the keyWork "as" too
SqlString str =
d.GetLimitString(new SqlString("SELECT fish.id, cast('astring, with,comma' as string) as bar FROM fish"), 0, 10);
Assert.AreEqual(
- "SELECT TOP 10 id, bar FROM (SELECT ROW_NUMBER() OVER(ORDER BY __hibernate_sort_expr_1__) as row, query.id, query.bar, query.__hibernate_sort_expr_1__ FROM (SELECT fish.id, cast('astring, with,comma' as string) as bar, CURRENT_TIMESTAMP as __hibernate_sort_expr_1__ FROM fish) query ) page WHERE page.row > 0 ORDER BY __hibernate_sort_expr_1__",
+ "SELECT TOP 10 id, bar FROM (SELECT ROW_NUMBER() OVER(ORDER BY __hibernate_sort_expr_0__) as row, query.id, query.bar, query.__hibernate_sort_expr_0__ FROM (SELECT fish.id, cast('astring, with,comma' as string) as bar, CURRENT_TIMESTAMP as __hibernate_sort_expr_0__ FROM fish) query ) page WHERE page.row > 0 ORDER BY __hibernate_sort_expr_0__",
str.ToString());
}
[Test]
Modified: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1101/Domain.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1101/Domain.cs 2008-07-18 06:52:02 UTC (rev 3639)
+++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1101/Domain.cs 2008-07-18 07:32:56 UTC (rev 3640)
@@ -2,7 +2,9 @@
{
public class A
{
+#pragma warning disable 649
private int id;
+#pragma warning restore 649
private string descript;
private B b;
public A() {}
Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1359/Fixture.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1359/Fixture.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1359/Fixture.cs 2008-07-18 07:32:56 UTC (rev 3640)
@@ -0,0 +1,196 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Text;
+using NHibernate.Criterion;
+using NHibernate.Transform;
+using NUnit.Framework;
+
+namespace NHibernate.Test.NHSpecificTest.NH1359
+{
+ [TestFixture]
+ public class Fixture : BugTestCase
+ {
+ public override string BugNumber
+ {
+ get { return "NH1359"; }
+ }
+
+ protected override void OnTearDown()
+ {
+ base.OnTearDown();
+ using(ISession session = OpenSession())
+ {
+ using(ITransaction tx = session.BeginTransaction())
+ {
+ session.Delete("from Person");
+ tx.Commit();
+ }
+ }
+ }
+
+ protected override void OnSetUp()
+ {
+ using(ISession s = OpenSession())
+ {
+ using(ITransaction tx = s.BeginTransaction())
+ {
+ Person e1 = new Person("Joe", 10, 9);
+ Person e2 = new Person("Sally", 20, 8);
+ Person e3 = new Person("Tim", 20, 7); //20
+ Person e4 = new Person("Fred", 40, 40);
+ Person e5 = new Person("Fred", 50, 50);
+ s.Save(e1);
+ s.Save(e2);
+ s.Save(e3);
+ s.Save(e4);
+ s.Save(e5);
+ Pet p = new Pet("Fido", "Dog", 25, e1);
+ Pet p2 = new Pet("Biff", "Dog", 10, e1);
+ s.Save(p);
+ s.Save(p2);
+ tx.Commit();
+ }
+ }
+ }
+
+ [Test]
+ public void CanSetSubQueryProjectionFromDetachedCriteriaWithCountProjection()
+ {
+ using(ISession s = OpenSession())
+ {
+ // This query doesn't make sense at all
+ DetachedCriteria dc = DetachedCriteria.For<Person>()
+ .SetProjection(Projections.Count("Id"));
+
+ ICriteria c = s.CreateCriteria(typeof(Person))
+ .SetProjection(Projections.SubQuery(dc))
+ .Add(Expression.Eq("Name", "Fred"));
+
+ IList list = c.List();
+ Assert.AreEqual(2, list.Count);
+ foreach(object item in list)
+ {
+ Assert.AreEqual(5, item);
+ }
+ }
+ }
+
+ public class HeaviestPet
+ {
+ public string Name;
+ public double Weight;
+ }
+
+ [Test]
+ public void CanSubqueryRelatedObjectsNotInMainQuery()
+ {
+ using(ISession s = OpenSession())
+ {
+ DetachedCriteria dc = DetachedCriteria.For<Person>().CreateCriteria("Pets", "pets")
+ .SetProjection(Projections.Max("pets.Weight"));
+ ICriteria c = s.CreateCriteria(typeof(Person))
+ .SetProjection(Projections.ProjectionList()
+ .Add(Projections.SubQuery(dc), "Weight")
+ .Add(Projections.Property("Name"), "Name"))
+ .Add(Restrictions.Eq("Name", "Joe"));
+ c.SetResultTransformer(Transformers.AliasToBean(typeof(HeaviestPet)));
+
+ IList<HeaviestPet> list = c.List<HeaviestPet>();
+ Assert.AreEqual(1, list.Count);
+ foreach(HeaviestPet pet in list)
+ {
+ Assert.AreEqual("Joe", pet.Name);
+ Assert.AreEqual(25, pet.Weight);
+ }
+ }
+ }
+
+ [Test]
+ public void CanGetSelectSubqueryWithSpecifiedParameter()
+ {
+ using (ISession s = OpenSession())
+ {
+ DetachedCriteria dc = DetachedCriteria.For<Person>().Add(Restrictions.Eq("Name", "Joe"))
+ .SetProjection(Projections.Max("Name"));
+ ICriteria c = s.CreateCriteria(typeof(Person))
+ .SetProjection(Projections.ProjectionList()
+ .Add(Projections.SubQuery(dc), "Name"))
+ .Add(Restrictions.Eq("Name", "Joe"));
+ c.SetResultTransformer(Transformers.AliasToBean(typeof(HeaviestPet)));
+ IList<HeaviestPet> list = c.List<HeaviestPet>();
+ Assert.AreEqual(1, list.Count);
+ foreach(HeaviestPet pet in list)
+ {
+ Assert.AreEqual("Joe", pet.Name);
+ }
+ }
+ }
+
+
+ [Test]
+ public void CanPageAndSortResultsWithParametersAndFilters()
+ {
+ using(ISession s = OpenSession())
+ {
+ s.EnableFilter("ExampleFilter").SetParameter("WeightVal", 100);
+ DetachedCriteria dc = DetachedCriteria.For<Person>().CreateCriteria("Pets", "pets")
+ .SetProjection(Projections.Max("pets.Weight"))
+ .Add(Restrictions.Eq("pets.Weight", 10.0));
+ ICriteria c = s.CreateCriteria(typeof(Person))
+ .SetProjection(Projections.ProjectionList()
+ .Add(Projections.SubQuery(dc), "Weight")
+ .Add(Projections.Property("Name"), "Name"))
+ .Add(Restrictions.Eq("Name", "Joe"));
+
+ c.SetResultTransformer(Transformers.AliasToBean(typeof(HeaviestPet)));
+ c.SetMaxResults(1);
+ c.AddOrder(new Order("Id", true));
+ IList<HeaviestPet> list = c.List<HeaviestPet>();
+ Assert.AreEqual(1, list.Count);
+ foreach(HeaviestPet pet in list)
+ {
+ Assert.AreEqual("Joe", pet.Name);
+ Assert.AreEqual(10.0, pet.Weight);
+ }
+ }
+ }
+
+ [Test]
+ public void CanPageAndSortWithMultipleColumnsOfSameName()
+ {
+ using(ISession s = OpenSession())
+ {
+ ICriteria c = s.CreateCriteria(typeof(Person),"root")
+ .CreateCriteria("root.Pets","pets")
+ .SetProjection(Projections.ProjectionList()
+ .Add(Projections.Property("root.Id"), "Id")
+ .Add(Projections.Property("root.Name"), "Name"))
+ .Add(Restrictions.Eq("Name", "Fido"));
+ c.AddOrder(new Order("Id", true));
+ c.SetResultTransformer(Transformers.AliasToBean(typeof(Person)));
+ c.SetMaxResults(1);
+ IList<Person> list = c.List<Person>();
+ Assert.AreEqual(1, list.Count);
+ }
+ }
+
+ [Test]
+ public void CanOrderByNamedSubquery()
+ {
+ using(ISession s = OpenSession())
+ {
+ DetachedCriteria dc = DetachedCriteria.For<Person>().Add(Restrictions.Eq("Name", "Joe"))
+ .SetProjection(Projections.Max("Name"));
+ ICriteria c = s.CreateCriteria(typeof(Person))
+ .SetProjection(Projections.ProjectionList()
+ .Add(Projections.SubQuery(dc), "NameSubquery"))
+ .Add(Restrictions.Eq("Name", "Joe"));
+ c.AddOrder(new Order("NameSubquery", true));
+ c.SetMaxResults(1);
+ IList list = c.List();
+ Assert.AreEqual(1, list.Count);
+ }
+ }
+ }
+}
Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1359/Mappings.hbm.xml
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1359/Mappings.hbm.xml (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1359/Mappings.hbm.xml 2008-07-18 07:32:56 UTC (rev 3640)
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
+ assembly="NHibernate.Test"
+ namespace="NHibernate.Test.NHSpecificTest.NH1359">
+
+ <class name="Person" lazy="false">
+ <id name="Id">
+ <generator class="native" />
+ </id>
+ <bag name="Pets" inverse="true" lazy="false" cascade="all-delete-orphan">
+ <key column="PersonId" />
+ <one-to-many class="Pet"/>
+ <filter name="ExampleFilter" condition=":WeightVal >= Weight" />
+ </bag>
+ <property name="Name"/>
+ <property name="IQ"/>
+ <property name="ShoeSize"/>
+ </class>
+
+ <class name="Pet" lazy="false">
+ <id name="Id">
+ <generator class="native" />
+ </id>
+ <many-to-one name="Owner" column="PersonId" not-null="true"/>
+ <property name="Name"/>
+ <property name="Species"/>
+ <property name="Weight"/>
+ </class>
+
+ <filter-def name="ExampleFilter">
+ <filter-param name="WeightVal" type="int"/>
+ </filter-def>
+
+</hibernate-mapping>
Added: trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1359/Person.cs
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1359/Person.cs (rev 0)
+++ trunk/nhibernate/src/NHibernate.Test/NHSpecificTest/NH1359/Person.cs 2008-07-18 07:32:56 UTC (rev 3640)
@@ -0,0 +1,107 @@
+using System.Collections;
+
+namespace NHibernate.Test.NHSpecificTest.NH1359
+{
+ public class Person
+ {
+ private int id;
+ private int iq;
+ private string name;
+ private IList pets;
+ private int shoeSize;
+
+ public Person()
+ {
+ Pets = new ArrayList();
+ }
+
+ public Person(string name, int iq, int shoeSize)
+ {
+ this.name = name;
+ this.iq = iq;
+ this.shoeSize = shoeSize;
+ Pets = new ArrayList();
+ }
+
+ public virtual int Id
+ {
+ get { return id; }
+ set { id = value; }
+ }
+
+ public virtual string Name
+ {
+ get { return name; }
+ set { name = value; }
+ }
+
+ public virtual int IQ
+ {
+ get { return iq; }
+ set { iq = value; }
+ }
+
+ public virtual int ShoeSize
+ {
+ get { return shoeSize; }
+ set { shoeSize = value; }
+ }
+
+ public virtual IList Pets
+ {
+ get { return pets; }
+ protected set { pets = value; }
+ }
+ }
+
+ public class Pet
+ {
+ private int id;
+ private string name;
+ private Person owner;
+ private string species;
+ private double weight;
+
+ public Pet()
+ {
+ }
+
+ public Pet(string name, string species, int weight, Person owner)
+ {
+ this.name = name;
+ this.species = species;
+ this.weight = weight;
+ this.owner = owner;
+ }
+
+ public virtual int Id
+ {
+ get { return id; }
+ set { id = value; }
+ }
+
+ public virtual string Name
+ {
+ get { return name; }
+ set { name = value; }
+ }
+
+ public virtual string Species
+ {
+ get { return species; }
+ set { species = value; }
+ }
+
+ public virtual double Weight
+ {
+ get { return weight; }
+ set { weight = value; }
+ }
+
+ public virtual Person Owner
+ {
+ get { return owner; }
+ set { owner = value; }
+ }
+ }
+}
Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-2.0.csproj
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-2.0.csproj 2008-07-18 06:52:02 UTC (rev 3639)
+++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-2.0.csproj 2008-07-18 07:32:56 UTC (rev 3640)
@@ -390,6 +390,8 @@
<Compile Include="NHSpecificTest\Docs\Associations\BiM21\Person.cs" />
<Compile Include="NHSpecificTest\Docs\ExampleParentChild\Child.cs" />
<Compile Include="NHSpecificTest\Docs\ExampleParentChild\Parent.cs" />
+ <Compile Include="NHSpecificTest\NH1359\Fixture.cs" />
+ <Compile Include="NHSpecificTest\NH1359\Person.cs" />
<Compile Include="NHSpecificTest\Docs\ExampleParentChild\UpdateFixture.cs" />
<Compile Include="NHSpecificTest\Docs\PersistentClasses\Cat.cs" />
<Compile Include="NHSpecificTest\EmptyMappingsFixture.cs" />
@@ -1316,6 +1318,7 @@
<EmbeddedResource Include="UserCollection\Parameterized\Mapping.hbm.xml" />
</ItemGroup>
<ItemGroup>
+ <EmbeddedResource Include="NHSpecificTest\NH1359\Mappings.hbm.xml" />
<EmbeddedResource Include="IdTest\Car.hbm.xml" />
<EmbeddedResource Include="IdTest\Plane.hbm.xml" />
<EmbeddedResource Include="IdTest\Product.hbm.xml" />
Modified: trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-3.5.csproj
===================================================================
--- trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-3.5.csproj 2008-07-18 06:52:02 UTC (rev 3639)
+++ trunk/nhibernate/src/NHibernate.Test/NHibernate.Test-3.5.csproj 2008-07-18 07:32:56 UTC (rev 3640)
@@ -390,6 +390,8 @@
<Compile Include="NHSpecificTest\NH1355\UserTypeTimestamp.cs">
<SubType>Code</SubType>
</Compile>
+ <Compile Include="NHSpecificTest\NH1359\Fixture.cs" />
+ <Compile Include="NHSpecificTest\NH1359\Person.cs" />
<Compile Include="NHSpecificTest\NH1362\Fixture.cs">
<SubType>Code</SubType>
</Compile>
@@ -1316,6 +1318,9 @@
<EmbeddedResource Include="NHSpecificTest\NH693\SpaceTableName.hbm.xml" />
</ItemGroup>
<ItemGroup>
+ <EmbeddedResource Include="NHSpecificTest\NH1359\Mappings.hbm.xml" />
+ </ItemGroup>
+ <ItemGroup>
<Folder Include="Properties\" />
<Folder Include="Unionsubclass2\" />
</ItemGroup>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|