-
Notifications
You must be signed in to change notification settings - Fork 928
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support evaluation of Random.Next and NextDouble on db side
Fixes #959, along with two previous commits
- Loading branch information
1 parent
58272eb
commit 3a8a1ba
Showing
18 changed files
with
572 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
//------------------------------------------------------------------------------ | ||
// <auto-generated> | ||
// This code was generated by AsyncGenerator. | ||
// | ||
// Changes to this file may cause incorrect behavior and will be lost if | ||
// the code is regenerated. | ||
// </auto-generated> | ||
//------------------------------------------------------------------------------ | ||
|
||
|
||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using NHibernate.Cfg; | ||
using NHibernate.SqlTypes; | ||
using NUnit.Framework; | ||
using Environment = NHibernate.Cfg.Environment; | ||
using NHibernate.Linq; | ||
|
||
namespace NHibernate.Test.Linq | ||
{ | ||
using System.Threading.Tasks; | ||
[TestFixture(false, false)] | ||
[TestFixture(true, false)] | ||
[TestFixture(false, true)] | ||
public class PreEvaluationTestsAsync : LinqTestCase | ||
{ | ||
private readonly bool LegacyPreEvaluation; | ||
private readonly bool FallbackOnPreEvaluation; | ||
|
||
public PreEvaluationTestsAsync(bool legacy, bool fallback) | ||
{ | ||
LegacyPreEvaluation = legacy; | ||
FallbackOnPreEvaluation = fallback; | ||
} | ||
|
||
protected override void Configure(Configuration configuration) | ||
{ | ||
base.Configure(configuration); | ||
|
||
configuration.SetProperty(Environment.FormatSql, "false"); | ||
configuration.SetProperty(Environment.LinqToHqlLegacyPreEvaluation, LegacyPreEvaluation.ToString()); | ||
configuration.SetProperty(Environment.LinqToHqlFallbackOnPreEvaluation, FallbackOnPreEvaluation.ToString()); | ||
} | ||
|
||
private void RunTest(bool isSupported, Action<SqlLogSpy> test) | ||
{ | ||
using (var spy = new SqlLogSpy()) | ||
{ | ||
try | ||
{ | ||
test(spy); | ||
} | ||
catch (QueryException) | ||
{ | ||
if (!isSupported && !FallbackOnPreEvaluation) | ||
// Expected failure | ||
return; | ||
throw; | ||
} | ||
} | ||
|
||
if (!isSupported && !FallbackOnPreEvaluation) | ||
Assert.Fail("The test should have thrown a QueryException, but has not thrown anything"); | ||
} | ||
|
||
[Test] | ||
public async Task CanQueryByRandomIntAsync() | ||
{ | ||
var isSupported = IsFunctionSupported("random") && IsFunctionSupported("floor"); | ||
var idMin = await (db.Orders.MinAsync(o => o.OrderId)); | ||
RunTest( | ||
isSupported, | ||
spy => | ||
{ | ||
var random = new Random(); | ||
// Dodge a Firebird driver limitation by putting the constants before the order id. | ||
// This driver cast parameters to their types in some cases for avoiding Firebird complaining of not | ||
// knowing the type of the condition. For some reasons the driver considers the casting should not be | ||
// done next to the conditional operator. Having the cast only on one side is enough for avoiding | ||
// Firebird complain, so moving the constants on the left side have been put before the order id, in | ||
// order for these constants to be casted by the driver. | ||
var x = db.Orders.Count(o => -idMin - 1 + o.OrderId < random.Next()); | ||
Assert.That(x, Is.GreaterThan(0)); | ||
// Next requires support of both floor and rand | ||
AssertFunctionInSql(IsFunctionSupported("floor") ? "random" : "floor", spy); | ||
}); | ||
} | ||
|
||
[Test] | ||
public async Task CanQueryByRandomIntWithMaxAsync() | ||
{ | ||
var isSupported = IsFunctionSupported("random") && IsFunctionSupported("floor"); | ||
var idMin = await (db.Orders.MinAsync(o => o.OrderId)); | ||
RunTest( | ||
isSupported, | ||
spy => | ||
{ | ||
var random = new Random(); | ||
// Dodge a Firebird driver limitation by putting the constants before the order id. | ||
// This driver cast parameters to their types in some cases for avoiding Firebird complaining of not | ||
// knowing the type of the condition. For some reasons the driver considers the casting should not be | ||
// done next to the conditional operator. Having the cast only on one side is enough for avoiding | ||
// Firebird complain, so moving the constants on the left side have been put before the order id, in | ||
// order for these constants to be casted by the driver. | ||
var x = db.Orders.Count(o => -idMin + o.OrderId <= random.Next(10)); | ||
Assert.That(x, Is.GreaterThan(0).And.LessThan(11)); | ||
// Next requires support of both floor and rand | ||
AssertFunctionInSql(IsFunctionSupported("floor") ? "random" : "floor", spy); | ||
}); | ||
} | ||
|
||
[Test] | ||
public async Task CanQueryByRandomIntWithMinMaxAsync() | ||
{ | ||
var isSupported = IsFunctionSupported("random") && IsFunctionSupported("floor"); | ||
var idMin = await (db.Orders.MinAsync(o => o.OrderId)); | ||
RunTest( | ||
isSupported, | ||
spy => | ||
{ | ||
var random = new Random(); | ||
// Dodge a Firebird driver limitation by putting the constants before the order id. | ||
// This driver cast parameters to their types in some cases for avoiding Firebird complaining of not | ||
// knowing the type of the condition. For some reasons the driver considers the casting should not be | ||
// done next to the conditional operator. Having the cast only on one side is enough for avoiding | ||
// Firebird complain, so moving the constants on the left side have been put before the order id, in | ||
// order for these constants to be casted by the driver. | ||
var x = db.Orders.Count(o => -idMin + o.OrderId < random.Next(1, 10)); | ||
Assert.That(x, Is.GreaterThan(0).And.LessThan(10)); | ||
// Next requires support of both floor and rand | ||
AssertFunctionInSql(IsFunctionSupported("floor") ? "random" : "floor", spy); | ||
}); | ||
} | ||
|
||
private void AssertFunctionInSql(string functionName, SqlLogSpy spy) | ||
{ | ||
if (!IsFunctionSupported(functionName)) | ||
Assert.Inconclusive($"{functionName} is not supported by the dialect"); | ||
|
||
var function = Dialect.Functions[functionName].Render(new List<object>(), Sfi).ToString(); | ||
|
||
if (LegacyPreEvaluation) | ||
Assert.That(spy.GetWholeLog(), Does.Not.Contain(function)); | ||
else | ||
Assert.That(spy.GetWholeLog(), Does.Contain(function)); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.