Skip to content

Commit 20f35ac

Browse files
committed
NH1978 - NH will now generate proper aliases for legacy tables that starts with numbers
NH-1248 - Subqueries.IsNull SVN: trunk@4913
1 parent 23f5058 commit 20f35ac

File tree

11 files changed

+165
-7
lines changed

11 files changed

+165
-7
lines changed

src/NHibernate.Test/Criteria/CriteriaQueryTest.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,33 @@ public void AllowToSetLimitOnSubqueries()
127127
}
128128
}
129129

130+
[Test]
131+
public void TestSubcriteriaBeingNull()
132+
{
133+
ISession session = OpenSession();
134+
ITransaction t = session.BeginTransaction();
135+
136+
Course hibernateCourse = new Course();
137+
hibernateCourse.CourseCode = "HIB";
138+
hibernateCourse.Description = "Hibernate Training";
139+
session.Save(hibernateCourse);
140+
141+
DetachedCriteria subcriteria = DetachedCriteria.For<Enrolment>("e");
142+
subcriteria.Add(Expression.EqProperty("e.CourseCode", "c.CourseCode"));
143+
subcriteria.SetProjection(Projections.Avg("Semester"));
144+
145+
DetachedCriteria criteria = DetachedCriteria.For<Course>("c");
146+
criteria.SetProjection(Projections.Count("id"));
147+
criteria.Add(Expression.Or(Subqueries.Le(5, subcriteria), Subqueries.IsNull(subcriteria)));
148+
149+
object o = criteria.GetExecutableCriteria(session).UniqueResult();
150+
Assert.AreEqual(1, o);
151+
152+
session.Delete(hibernateCourse);
153+
t.Commit();
154+
session.Close();
155+
}
156+
130157
[Test]
131158
public void Subselect()
132159
{
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using NHibernate.Cfg;
2+
using NUnit.Framework;
3+
4+
namespace NHibernate.Test.NHSpecificTest.NH1978
5+
{
6+
[TestFixture]
7+
public class AliasTest : BugTestCase
8+
{
9+
[Test]
10+
public void ShouldReturnPlanFromEmployee()
11+
{
12+
using(var s = OpenSession())
13+
using (var trans = s.BeginTransaction())
14+
{
15+
var plan = new _401k {PlanName = "test"};
16+
s.Save(plan);
17+
s.Refresh(plan);
18+
var emp = new Employee {EmpName = "name", PlanParent = plan};
19+
s.Save(emp);
20+
21+
trans.Rollback();
22+
}
23+
}
24+
}
25+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
namespace NHibernate.Test.NHSpecificTest.NH1978
2+
{
3+
/// <summary>
4+
/// Category object for NHibernate mapped table 'Categories'.
5+
/// </summary>
6+
public class Employee
7+
{
8+
public virtual int ID { get; set; }
9+
public virtual string EmpName { get; set; }
10+
public virtual _401k PlanParent { get; set; }
11+
}
12+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<hibernate-mapping
3+
namespace="NHibernate.Test.NHSpecificTest.NH1978"
4+
assembly="NHibernate.Test"
5+
xmlns="urn:nhibernate-mapping-2.2">
6+
<class name="Employee" lazy="true" table="Employee">
7+
<id name="ID" type="Int32" unsaved-value="0">
8+
<generator class="native" />
9+
</id>
10+
<property name="EmpName" type="String">
11+
</property>
12+
<many-to-one name="PlanParent" class="_401k" >
13+
<column name="Plan401kID" sql-type="int" not-null="false" />
14+
</many-to-one>
15+
</class>
16+
<class name="_401k" lazy="true" table="[401k]">
17+
<id name="ID" type="Int32" unsaved-value="0">
18+
<generator class="native" />
19+
</id>
20+
<property name="PlanName" type="String">
21+
</property>
22+
<bag name="Employees" inverse="true" lazy="true" cascade="all-delete-orphan" >
23+
<key column="Plan401kID" />
24+
<one-to-many class="Employee"/>
25+
</bag>
26+
</class>
27+
</hibernate-mapping>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using System.Collections.Generic;
2+
3+
namespace NHibernate.Test.NHSpecificTest.NH1978
4+
{
5+
/// <summary>
6+
/// Product object for NHibernate mapped table 'Products'.
7+
/// </summary>
8+
public class _401k
9+
{
10+
public virtual int ID { get; set; }
11+
public virtual string PlanName { get; set; }
12+
public virtual IList<Employee> Employees { get; set; }
13+
}
14+
}

src/NHibernate.Test/NHibernate.Test.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -658,6 +658,9 @@
658658
<Compile Include="NHSpecificTest\NH1938\Model.cs" />
659659
<Compile Include="NHSpecificTest\NH1939\AuxType.cs" />
660660
<Compile Include="NHSpecificTest\NH1939\Fixture.cs" />
661+
<Compile Include="NHSpecificTest\NH1978\AliasTest.cs" />
662+
<Compile Include="NHSpecificTest\NH1978\Employee.cs" />
663+
<Compile Include="NHSpecificTest\NH1978\_401k.cs" />
661664
<Compile Include="NHSpecificTest\NH2044\DomainClass.cs" />
662665
<Compile Include="NHSpecificTest\NH2044\SampleTest.cs" />
663666
<Compile Include="NHSpecificTest\NH2055\AuxType.cs" />
@@ -2100,6 +2103,7 @@
21002103
<EmbeddedResource Include="CfgTest\Loquacious\EntityToCache.hbm.xml" />
21012104
<EmbeddedResource Include="DriverTest\SqlServerCeEntity.hbm.xml" />
21022105
<Content Include="DynamicEntity\package.html" />
2106+
<EmbeddedResource Include="NHSpecificTest\NH1978\Mappings.hbm.xml" />
21032107
<EmbeddedResource Include="NHSpecificTest\NH2044\Mappings.hbm.xml" />
21042108
<EmbeddedResource Include="NHSpecificTest\NH2030\Mappings.hbm.xml" />
21052109
<EmbeddedResource Include="Linq\Mappings\Patient.hbm.xml" />
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
using System;
2+
using NHibernate.SqlCommand;
3+
4+
namespace NHibernate.Criterion
5+
{
6+
[Serializable]
7+
public class NullSubqueryExpression : SubqueryExpression
8+
{
9+
protected override SqlString ToLeftSqlString(ICriteria criteria, ICriteriaQuery outerQuery)
10+
{
11+
return SqlString.Empty;
12+
}
13+
14+
internal NullSubqueryExpression(String quantifier, DetachedCriteria dc)
15+
: base(null, quantifier, dc, false)
16+
{
17+
}
18+
}
19+
}

src/NHibernate/Criterion/Subqueries.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,5 +318,14 @@ public static AbstractCriterion WhereNotExists<U>(QueryOver<U> detachedQuery)
318318
return Subqueries.NotExists(detachedQuery.DetachedCriteria);
319319
}
320320

321+
public static AbstractCriterion IsNull(DetachedCriteria dc)
322+
{
323+
return new NullSubqueryExpression("IS NULL", dc);
324+
}
325+
326+
public static AbstractCriterion IsNotNull(DetachedCriteria dc)
327+
{
328+
return new NullSubqueryExpression("IS NOT NULL", dc);
329+
}
321330
}
322331
}

src/NHibernate/Criterion/SubqueryExpression.cs

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,25 @@ public abstract class SubqueryExpression : AbstractCriterion
1414
{
1515
private readonly CriteriaImpl criteriaImpl;
1616
private readonly String quantifier;
17-
private readonly String op;
17+
private readonly bool prefixOp;
18+
private readonly String op;
1819
private QueryParameters parameters;
1920
private IType[] types;
2021

2122
[NonSerialized] private CriteriaQueryTranslator innerQuery;
2223

23-
protected SubqueryExpression(String op, String quantifier, DetachedCriteria dc)
24+
protected SubqueryExpression(String op, String quantifier, DetachedCriteria dc)
25+
:this(op, quantifier, dc, true)
26+
{
27+
28+
}
29+
30+
protected SubqueryExpression(String op, String quantifier, DetachedCriteria dc, bool prefixOp)
2431
{
2532
criteriaImpl = dc.GetCriteriaImpl();
2633
this.quantifier = quantifier;
27-
this.op = op;
34+
this.prefixOp = prefixOp;
35+
this.op = op;
2836
}
2937

3038
public IType[] GetTypes()
@@ -68,16 +76,27 @@ public override SqlString ToSqlString(ICriteria criteria, ICriteriaQuery criteri
6876
buf.Add(" ").Add(op).Add(" ");
6977
}
7078

71-
if (quantifier != null)
79+
if (quantifier != null && prefixOp)
7280
{
7381
buf.Add(quantifier).Add(" ");
7482
}
75-
return buf.Add("(").Add(sql).Add(")").ToSqlString();
83+
84+
buf.Add("(").Add(sql).Add(")");
85+
86+
if(quantifier!=null && prefixOp==false)
87+
{
88+
buf.Add(" ").Add(quantifier);
89+
}
90+
91+
return buf.ToSqlString();
7692
}
7793

7894
public override string ToString()
7995
{
80-
return string.Format("{0} {1} ({2})", op, quantifier, criteriaImpl);
96+
if(prefixOp)
97+
return string.Format("{0} {1} ({2})", op, quantifier, criteriaImpl);
98+
return string.Format("{0} ({1}) {2}", op, criteriaImpl, quantifier);
99+
81100
}
82101

83102
public override TypedValue[] GetTypedValues(ICriteria criteria, ICriteriaQuery criteriaQuery)

src/NHibernate/NHibernate.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -579,6 +579,7 @@
579579
<Compile Include="Criterion\Lambda\QueryOverRestrictionBuilder.cs" />
580580
<Compile Include="Criterion\Lambda\QueryOverSubqueryBuilder.cs" />
581581
<Compile Include="Criterion\Lambda\QueryOverSubqueryPropertyBuilder.cs" />
582+
<Compile Include="Criterion\NullSubqueryExpression.cs" />
582583
<Compile Include="Criterion\ProjectionsExtensions.cs" />
583584
<Compile Include="Dialect\MsSql2008Dialect.cs" />
584585
<Compile Include="Dialect\InformixDialect0940.cs" />

src/NHibernate/Util/StringHelper.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -620,10 +620,11 @@ private static string GenerateAliasRoot(string description)
620620
{
621621
return result + "x"; //ick!
622622
}
623-
else
623+
if(char.IsLetter(result[0]) || '_' == result[0])
624624
{
625625
return result;
626626
}
627+
return "alias_" + result;
627628
}
628629

629630
public static string MoveAndToBeginning(string filter)

0 commit comments

Comments
 (0)