Skip to content

Commit ed7a6d8

Browse files
authored
Fix support for null datetime parameters for Npgsql 6+ (nhibernate#3299)
Fixes nhibernate#3291
1 parent cddbac1 commit ed7a6d8

File tree

6 files changed

+187
-8
lines changed

6 files changed

+187
-8
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
//------------------------------------------------------------------------------
2+
// <auto-generated>
3+
// This code was generated by AsyncGenerator.
4+
//
5+
// Changes to this file may cause incorrect behavior and will be lost if
6+
// the code is regenerated.
7+
// </auto-generated>
8+
//------------------------------------------------------------------------------
9+
10+
11+
using System;
12+
using System.Linq;
13+
using NHibernate.Criterion;
14+
using NUnit.Framework;
15+
using NHibernate.Linq;
16+
17+
namespace NHibernate.Test.NHSpecificTest.GH3291
18+
{
19+
using System.Threading.Tasks;
20+
[TestFixture]
21+
public class FixtureAsync : BugTestCase
22+
{
23+
protected override void OnSetUp()
24+
{
25+
using var session = OpenSession();
26+
using var transaction = session.BeginTransaction();
27+
28+
var e1 = new Person { Name = "Bob", DateOfBirth = new DateTime(2009, 12, 23) };
29+
session.Save(e1);
30+
31+
var e2 = new Person { Name = "Sally", DateOfBirth = new DateTime(2018, 9, 30) };
32+
session.Save(e2);
33+
34+
transaction.Commit();
35+
}
36+
37+
protected override void OnTearDown()
38+
{
39+
using var session = OpenSession();
40+
using var transaction = session.BeginTransaction();
41+
42+
session.CreateQuery("delete from System.Object").ExecuteUpdate();
43+
44+
transaction.Commit();
45+
}
46+
47+
[Test]
48+
public async Task LinqAsync()
49+
{
50+
using var session = OpenSession();
51+
using var _ = session.BeginTransaction();
52+
53+
DateTime? dateOfSearch = null;
54+
55+
var result = await ((
56+
from person in session.Query<Person>()
57+
where dateOfSearch == null || person.DateOfBirth > dateOfSearch
58+
select person).ToListAsync());
59+
60+
Assert.That(result, Has.Count.EqualTo(2));
61+
}
62+
63+
[Test]
64+
public async Task HqlAsync()
65+
{
66+
using var session = OpenSession();
67+
using var _ = session.BeginTransaction();
68+
69+
DateTime? dateOfSearch = null;
70+
71+
var result =
72+
await (session.CreateQuery("from Person where :DateOfSearch is null OR DateOfBirth > :DateOfSearch")
73+
.SetParameter("DateOfSearch", dateOfSearch, NHibernateUtil.DateTime)
74+
.ListAsync<Person>());
75+
76+
Assert.That(result, Has.Count.EqualTo(2));
77+
}
78+
}
79+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
using System;
2+
using System.Linq;
3+
using NHibernate.Criterion;
4+
using NUnit.Framework;
5+
6+
namespace NHibernate.Test.NHSpecificTest.GH3291
7+
{
8+
[TestFixture]
9+
public class Fixture : BugTestCase
10+
{
11+
protected override void OnSetUp()
12+
{
13+
using var session = OpenSession();
14+
using var transaction = session.BeginTransaction();
15+
16+
var e1 = new Person { Name = "Bob", DateOfBirth = new DateTime(2009, 12, 23) };
17+
session.Save(e1);
18+
19+
var e2 = new Person { Name = "Sally", DateOfBirth = new DateTime(2018, 9, 30) };
20+
session.Save(e2);
21+
22+
transaction.Commit();
23+
}
24+
25+
protected override void OnTearDown()
26+
{
27+
using var session = OpenSession();
28+
using var transaction = session.BeginTransaction();
29+
30+
session.CreateQuery("delete from System.Object").ExecuteUpdate();
31+
32+
transaction.Commit();
33+
}
34+
35+
[Test]
36+
public void Linq()
37+
{
38+
using var session = OpenSession();
39+
using var _ = session.BeginTransaction();
40+
41+
DateTime? dateOfSearch = null;
42+
43+
var result = (
44+
from person in session.Query<Person>()
45+
where dateOfSearch == null || person.DateOfBirth > dateOfSearch
46+
select person).ToList();
47+
48+
Assert.That(result, Has.Count.EqualTo(2));
49+
}
50+
51+
[Test]
52+
public void Hql()
53+
{
54+
using var session = OpenSession();
55+
using var _ = session.BeginTransaction();
56+
57+
DateTime? dateOfSearch = null;
58+
59+
var result =
60+
session.CreateQuery("from Person where :DateOfSearch is null OR DateOfBirth > :DateOfSearch")
61+
.SetParameter("DateOfSearch", dateOfSearch, NHibernateUtil.DateTime)
62+
.List<Person>();
63+
64+
Assert.That(result, Has.Count.EqualTo(2));
65+
}
66+
}
67+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="NHibernate.Test"
3+
namespace="NHibernate.Test.NHSpecificTest.GH3291">
4+
5+
<class name="Person">
6+
<id name="Id" generator="guid.comb"/>
7+
<property name="Name"/>
8+
<property name="DateOfBirth" />
9+
</class>
10+
11+
</hibernate-mapping>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
using System;
2+
3+
namespace NHibernate.Test.NHSpecificTest.GH3291
4+
{
5+
class Person
6+
{
7+
public virtual Guid Id { get; set; }
8+
public virtual string Name { get; set; }
9+
public virtual DateTime? DateOfBirth { get; set; }
10+
}
11+
}

src/NHibernate.TestDatabaseSetup/TestDatabaseSetup.cs

+1-5
Original file line numberDiff line numberDiff line change
@@ -182,11 +182,7 @@ private static void SetupNpgsql(Cfg.Configuration cfg)
182182

183183
using (var cmd = conn.CreateCommand())
184184
{
185-
cmd.CommandText =
186-
@"CREATE OR REPLACE FUNCTION uuid_generate_v4()
187-
RETURNS uuid
188-
AS '$libdir/uuid-ossp', 'uuid_generate_v4'
189-
VOLATILE STRICT LANGUAGE C;";
185+
cmd.CommandText = "CREATE EXTENSION IF NOT EXISTS \"uuid-ossp\";";
190186

191187
cmd.ExecuteNonQuery();
192188
}

src/NHibernate/Driver/NpgsqlDriver.cs

+18-3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System;
12
using System.Data;
23
using System.Data.Common;
34
using NHibernate.AdoNet;
@@ -74,14 +75,28 @@ protected override void InitializeParameter(DbParameter dbParam, string name, Sq
7475
// Since the .NET currency type has 4 decimal places, we use a decimal type in PostgreSQL instead of its native 2 decimal currency type.
7576
dbParam.DbType = DbType.Decimal;
7677
}
77-
else if (DriverVersionMajor < 6 || sqlType.DbType != DbType.DateTime)
78+
else
7879
{
7980
dbParam.DbType = sqlType.DbType;
8081
}
81-
else
82+
}
83+
84+
public override void AdjustCommand(DbCommand command)
85+
{
86+
if (DriverVersionMajor >= 6)
8287
{
83-
// Let Npgsql 6 driver to decide parameter type
88+
for (var i = 0; i < command.Parameters.Count; i++)
89+
{
90+
var parameter = command.Parameters[i];
91+
if (parameter.Value is DateTime)
92+
{
93+
// Let Npgsql 6 driver to decide parameter type
94+
parameter.ResetDbType();
95+
}
96+
}
8497
}
98+
99+
base.AdjustCommand(command);
85100
}
86101

87102
// Prior to v3, Npgsql was expecting DateTime for time.

0 commit comments

Comments
 (0)