diff --git a/src/NHibernate.Test/Async/Hql/HQLFunctions.cs b/src/NHibernate.Test/Async/Hql/HQLFunctions.cs index fb72118278d..2009abcf704 100644 --- a/src/NHibernate.Test/Async/Hql/HQLFunctions.cs +++ b/src/NHibernate.Test/Async/Hql/HQLFunctions.cs @@ -23,42 +23,6 @@ namespace NHibernate.Test.Hql [TestFixture] public class HQLFunctionsAsync : TestCase { - static readonly Hashtable notSupportedStandardFunction; - static HQLFunctionsAsync() - { - notSupportedStandardFunction = - new Hashtable - { - {"locate", new[] {typeof (SQLiteDialect)}}, - {"bit_length", new[] {typeof (SQLiteDialect)}}, - {"extract", new[] {typeof (SQLiteDialect)}}, - { - "nullif", - new[] - { - typeof (Oracle8iDialect), - // Actually not supported by the db engine. (Well, could likely still be done with a case when override.) - typeof (MsSqlCeDialect), - typeof (MsSqlCe40Dialect) - }} - }; - } - - private bool IsOracleDialect() - { - return Dialect is Oracle8iDialect; - } - - private void IgnoreIfNotSupported(string functionName) - { - if (notSupportedStandardFunction.ContainsKey(functionName)) - { - IList dialects = (IList)notSupportedStandardFunction[functionName]; - if(dialects.Contains(Dialect.GetType())) - Assert.Ignore(Dialect + " doesn't support "+functionName+" function."); - } - } - protected override string MappingsAssembly { get { return "NHibernate.Test"; } @@ -75,6 +39,7 @@ protected override void OnTearDown() { s.Delete("from Human"); s.Delete("from Animal"); + s.Delete("from MaterialResource"); s.Flush(); } } @@ -255,7 +220,7 @@ public async Task SubStringTwoParametersAsync() // the two-parameter overload - emulating it by generating the // third parameter (length) if the database requires three parameters. - IgnoreIfNotSupported("substring"); + AssumeFunctionSupported("substring"); using (ISession s = OpenSession()) { @@ -293,7 +258,7 @@ public async Task SubStringTwoParametersAsync() [Test] public async Task SubStringAsync() { - IgnoreIfNotSupported("substring"); + AssumeFunctionSupported("substring"); using (ISession s = OpenSession()) { Animal a1 = new Animal("abcdef", 20); @@ -345,7 +310,7 @@ public async Task SubStringAsync() [Test] public async Task LocateAsync() { - IgnoreIfNotSupported("locate"); + AssumeFunctionSupported("locate"); using (ISession s = OpenSession()) { Animal a1 = new Animal("abcdef", 20); @@ -367,7 +332,7 @@ public async Task LocateAsync() [Test] public async Task TrimAsync() { - IgnoreIfNotSupported("trim"); + AssumeFunctionSupported("trim"); using (ISession s = OpenSession()) { Animal a1 = new Animal("abc ", 1); @@ -425,7 +390,7 @@ public async Task TrimAsync() [Test] public async Task LengthAsync() { - IgnoreIfNotSupported("length"); + AssumeFunctionSupported("length"); using (ISession s = OpenSession()) { @@ -450,7 +415,7 @@ public async Task LengthAsync() [Test] public async Task Bit_lengthAsync() { - IgnoreIfNotSupported("bit_length"); + AssumeFunctionSupported("bit_length"); // test only the parser using (ISession s = OpenSession()) @@ -466,7 +431,7 @@ public async Task Bit_lengthAsync() [Test] public async Task CoalesceAsync() { - IgnoreIfNotSupported("coalesce"); + AssumeFunctionSupported("coalesce"); // test only the parser and render using (ISession s = OpenSession()) { @@ -481,9 +446,9 @@ public async Task CoalesceAsync() [Test] public async Task NullifAsync() { - IgnoreIfNotSupported("nullif"); + AssumeFunctionSupported("nullif"); string hql1, hql2; - if(!IsOracleDialect()) + if(!(Dialect is Oracle8iDialect)) { hql1 = "select nullif(h.NickName, '1e1') from Human h"; hql2 = "from Human h where not(nullif(h.NickName, '1e1') is null)"; @@ -505,7 +470,7 @@ public async Task NullifAsync() [Test] public async Task AbsAsync() { - IgnoreIfNotSupported("abs"); + AssumeFunctionSupported("abs"); using (ISession s = OpenSession()) { Animal a1 = new Animal("Dog", 9); @@ -531,10 +496,34 @@ public async Task AbsAsync() } } + [Test] + public async Task CeilingAsync() + { + AssumeFunctionSupported("ceiling"); + + using (var s = OpenSession()) + { + var a1 = new Animal("a1", 1.3f); + await (s.SaveAsync(a1)); + await (s.FlushAsync()); + } + using (var s = OpenSession()) + { + var ceiling = await (s.CreateQuery("select ceiling(a.BodyWeight) from Animal a").UniqueResultAsync()); + Assert.That(ceiling, Is.EqualTo(2)); + var count = + await (s + .CreateQuery("select count(*) from Animal a where ceiling(a.BodyWeight) = :c") + .SetInt32("c", 2) + .UniqueResultAsync()); + Assert.That(count, Is.EqualTo(1)); + } + } + [Test] public async Task ModAsync() { - IgnoreIfNotSupported("mod"); + AssumeFunctionSupported("mod"); using (ISession s = OpenSession()) { Animal a1 = new Animal("abcdef", 20); @@ -560,7 +549,7 @@ public async Task ModAsync() [Test] public async Task SqrtAsync() { - IgnoreIfNotSupported("sqrt"); + AssumeFunctionSupported("sqrt"); using (ISession s = OpenSession()) { Animal a1 = new Animal("abcdef", 65536f); @@ -582,7 +571,7 @@ public async Task SqrtAsync() [Test] public async Task UpperAsync() { - IgnoreIfNotSupported("upper"); + AssumeFunctionSupported("upper"); using (ISession s = OpenSession()) { Animal a1 = new Animal("abcdef", 1f); @@ -611,7 +600,7 @@ public async Task UpperAsync() [Test] public async Task LowerAsync() { - IgnoreIfNotSupported("lower"); + AssumeFunctionSupported("lower"); using (ISession s = OpenSession()) { Animal a1 = new Animal("ABCDEF", 1f); @@ -637,12 +626,60 @@ public async Task LowerAsync() } } + [Test] + public async Task AsciiAsync() + { + AssumeFunctionSupported("ascii"); + + using (var s = OpenSession()) + { + var m = new MaterialResource(" ", "000", MaterialResource.MaterialState.Available); + await (s.SaveAsync(m)); + await (s.FlushAsync()); + } + using (var s = OpenSession()) + { + var space = await (s.CreateQuery("select ascii(m.Description) from MaterialResource m").UniqueResultAsync()); + Assert.That(space, Is.EqualTo(32)); + var count = + await (s + .CreateQuery("select count(*) from MaterialResource m where ascii(m.Description) = :c") + .SetInt32("c", 32) + .UniqueResultAsync()); + Assert.That(count, Is.EqualTo(1)); + } + } + + [Test] + public async Task ChrAsync() + { + AssumeFunctionSupported("chr"); + + using (var s = OpenSession()) + { + var m = new MaterialResource("Blah", "000", (MaterialResource.MaterialState)32); + await (s.SaveAsync(m)); + await (s.FlushAsync()); + } + using (var s = OpenSession()) + { + var space = await (s.CreateQuery("select chr(m.State) from MaterialResource m").UniqueResultAsync()); + Assert.That(space, Is.EqualTo(' ')); + var count = + await (s + .CreateQuery("select count(*) from MaterialResource m where chr(m.State) = :c") + .SetCharacter("c", ' ') + .UniqueResultAsync()); + Assert.That(count, Is.EqualTo(1)); + } + } + [Test] public async Task CastAsync() { const double magicResult = 7 + 123 - 5*1.3d; - IgnoreIfNotSupported("cast"); + AssumeFunctionSupported("cast"); // The cast is used to test various cases of a function render // Cast was selected because represent a special case for: // 1) Has more then 1 argument @@ -820,7 +857,7 @@ public async Task CastAsync() [Test] public async Task CastNH1446Async() { - IgnoreIfNotSupported("cast"); + AssumeFunctionSupported("cast"); using (ISession s = OpenSession()) { Animal a1 = new Animal("abcdef", 1.3f); @@ -840,7 +877,7 @@ public async Task CastNH1446Async() [Test] public async Task CastNH1979Async() { - IgnoreIfNotSupported("cast"); + AssumeFunctionSupported("cast"); using (ISession s = OpenSession()) { Animal a1 = new Animal("abcdef", 1.3f); @@ -858,7 +895,7 @@ public async Task CastNH1979Async() [Test] public async Task Current_TimeStampAsync() { - IgnoreIfNotSupported("current_timestamp"); + AssumeFunctionSupported("current_timestamp"); using (ISession s = OpenSession()) { Animal a1 = new Animal("abcdef", 1.3f); @@ -878,9 +915,7 @@ public async Task Current_TimeStampAsync() [Test] public async Task Current_TimeStamp_OffsetAsync() { - if (!Dialect.Functions.ContainsKey("current_timestamp_offset")) - Assert.Ignore(Dialect + " doesn't support current_timestamp_offset function"); - IgnoreIfNotSupported("current_timestamp_offset"); + AssumeFunctionSupported("current_timestamp_offset"); using (ISession s = OpenSession()) { Animal a1 = new Animal("abcdef", 1.3f); @@ -897,8 +932,8 @@ public async Task Current_TimeStamp_OffsetAsync() [Test] public async Task ExtractAsync() { - IgnoreIfNotSupported("extract"); - IgnoreIfNotSupported("current_timestamp"); + AssumeFunctionSupported("extract"); + AssumeFunctionSupported("current_timestamp"); // test only the parser and render using (ISession s = OpenSession()) @@ -914,7 +949,7 @@ public async Task ExtractAsync() [Test] public async Task ConcatAsync() { - IgnoreIfNotSupported("concat"); + AssumeFunctionSupported("concat"); using (ISession s = OpenSession()) { Animal a1 = new Animal("abcdef", 1f); @@ -940,10 +975,10 @@ public async Task ConcatAsync() [Test] public async Task HourMinuteSecondAsync() { - IgnoreIfNotSupported("second"); - IgnoreIfNotSupported("minute"); - IgnoreIfNotSupported("hour"); - IgnoreIfNotSupported("current_timestamp"); + AssumeFunctionSupported("second"); + AssumeFunctionSupported("minute"); + AssumeFunctionSupported("hour"); + AssumeFunctionSupported("current_timestamp"); // test only the parser and render using (ISession s = OpenSession()) { @@ -955,9 +990,9 @@ public async Task HourMinuteSecondAsync() [Test] public async Task DayMonthYearAsync() { - IgnoreIfNotSupported("day"); - IgnoreIfNotSupported("month"); - IgnoreIfNotSupported("year"); + AssumeFunctionSupported("day"); + AssumeFunctionSupported("month"); + AssumeFunctionSupported("year"); // test only the parser and render using (ISession s = OpenSession()) { @@ -969,7 +1004,7 @@ public async Task DayMonthYearAsync() [Test] public async Task StrAsync() { - IgnoreIfNotSupported("str"); + AssumeFunctionSupported("str"); using (ISession s = OpenSession()) { Animal a1 = new Animal("abcdef", 20); @@ -991,8 +1026,7 @@ public async Task StrAsync() [Test] public async Task IifAsync() { - if (!Dialect.Functions.ContainsKey("iif")) - Assert.Ignore(Dialect + "doesn't support iif function."); + AssumeFunctionSupported("Iif"); using (ISession s = OpenSession()) { await (s.SaveAsync(new MaterialResource("Flash card 512MB", "A001/07", MaterialResource.MaterialState.Available))); @@ -1035,7 +1069,7 @@ from MaterialResource mr [Test] public async Task NH1725Async() { - IgnoreIfNotSupported("iif"); + AssumeFunctionSupported("iif"); // Only to test the parser using (ISession s = OpenSession()) { diff --git a/src/NHibernate.Test/Hql/HQLFunctions.cs b/src/NHibernate.Test/Hql/HQLFunctions.cs index 6588930bcc1..cc2f5fbeb74 100644 --- a/src/NHibernate.Test/Hql/HQLFunctions.cs +++ b/src/NHibernate.Test/Hql/HQLFunctions.cs @@ -12,42 +12,6 @@ namespace NHibernate.Test.Hql [TestFixture] public class HQLFunctions : TestCase { - static readonly Hashtable notSupportedStandardFunction; - static HQLFunctions() - { - notSupportedStandardFunction = - new Hashtable - { - {"locate", new[] {typeof (SQLiteDialect)}}, - {"bit_length", new[] {typeof (SQLiteDialect)}}, - {"extract", new[] {typeof (SQLiteDialect)}}, - { - "nullif", - new[] - { - typeof (Oracle8iDialect), - // Actually not supported by the db engine. (Well, could likely still be done with a case when override.) - typeof (MsSqlCeDialect), - typeof (MsSqlCe40Dialect) - }} - }; - } - - private bool IsOracleDialect() - { - return Dialect is Oracle8iDialect; - } - - private void IgnoreIfNotSupported(string functionName) - { - if (notSupportedStandardFunction.ContainsKey(functionName)) - { - IList dialects = (IList)notSupportedStandardFunction[functionName]; - if(dialects.Contains(Dialect.GetType())) - Assert.Ignore(Dialect + " doesn't support "+functionName+" function."); - } - } - protected override string MappingsAssembly { get { return "NHibernate.Test"; } @@ -64,6 +28,7 @@ protected override void OnTearDown() { s.Delete("from Human"); s.Delete("from Animal"); + s.Delete("from MaterialResource"); s.Flush(); } } @@ -244,7 +209,7 @@ public void SubStringTwoParameters() // the two-parameter overload - emulating it by generating the // third parameter (length) if the database requires three parameters. - IgnoreIfNotSupported("substring"); + AssumeFunctionSupported("substring"); using (ISession s = OpenSession()) { @@ -282,7 +247,7 @@ public void SubStringTwoParameters() [Test] public void SubString() { - IgnoreIfNotSupported("substring"); + AssumeFunctionSupported("substring"); using (ISession s = OpenSession()) { Animal a1 = new Animal("abcdef", 20); @@ -334,7 +299,7 @@ public void SubString() [Test] public void Locate() { - IgnoreIfNotSupported("locate"); + AssumeFunctionSupported("locate"); using (ISession s = OpenSession()) { Animal a1 = new Animal("abcdef", 20); @@ -356,7 +321,7 @@ public void Locate() [Test] public void Trim() { - IgnoreIfNotSupported("trim"); + AssumeFunctionSupported("trim"); using (ISession s = OpenSession()) { Animal a1 = new Animal("abc ", 1); @@ -414,7 +379,7 @@ public void Trim() [Test] public void Length() { - IgnoreIfNotSupported("length"); + AssumeFunctionSupported("length"); using (ISession s = OpenSession()) { @@ -439,7 +404,7 @@ public void Length() [Test] public void Bit_length() { - IgnoreIfNotSupported("bit_length"); + AssumeFunctionSupported("bit_length"); // test only the parser using (ISession s = OpenSession()) @@ -455,7 +420,7 @@ public void Bit_length() [Test] public void Coalesce() { - IgnoreIfNotSupported("coalesce"); + AssumeFunctionSupported("coalesce"); // test only the parser and render using (ISession s = OpenSession()) { @@ -470,9 +435,9 @@ public void Coalesce() [Test] public void Nullif() { - IgnoreIfNotSupported("nullif"); + AssumeFunctionSupported("nullif"); string hql1, hql2; - if(!IsOracleDialect()) + if(!(Dialect is Oracle8iDialect)) { hql1 = "select nullif(h.NickName, '1e1') from Human h"; hql2 = "from Human h where not(nullif(h.NickName, '1e1') is null)"; @@ -494,7 +459,7 @@ public void Nullif() [Test] public void Abs() { - IgnoreIfNotSupported("abs"); + AssumeFunctionSupported("abs"); using (ISession s = OpenSession()) { Animal a1 = new Animal("Dog", 9); @@ -520,10 +485,34 @@ public void Abs() } } + [Test] + public void Ceiling() + { + AssumeFunctionSupported("ceiling"); + + using (var s = OpenSession()) + { + var a1 = new Animal("a1", 1.3f); + s.Save(a1); + s.Flush(); + } + using (var s = OpenSession()) + { + var ceiling = s.CreateQuery("select ceiling(a.BodyWeight) from Animal a").UniqueResult(); + Assert.That(ceiling, Is.EqualTo(2)); + var count = + s + .CreateQuery("select count(*) from Animal a where ceiling(a.BodyWeight) = :c") + .SetInt32("c", 2) + .UniqueResult(); + Assert.That(count, Is.EqualTo(1)); + } + } + [Test] public void Mod() { - IgnoreIfNotSupported("mod"); + AssumeFunctionSupported("mod"); using (ISession s = OpenSession()) { Animal a1 = new Animal("abcdef", 20); @@ -549,7 +538,7 @@ public void Mod() [Test] public void Sqrt() { - IgnoreIfNotSupported("sqrt"); + AssumeFunctionSupported("sqrt"); using (ISession s = OpenSession()) { Animal a1 = new Animal("abcdef", 65536f); @@ -571,7 +560,7 @@ public void Sqrt() [Test] public void Upper() { - IgnoreIfNotSupported("upper"); + AssumeFunctionSupported("upper"); using (ISession s = OpenSession()) { Animal a1 = new Animal("abcdef", 1f); @@ -600,7 +589,7 @@ public void Upper() [Test] public void Lower() { - IgnoreIfNotSupported("lower"); + AssumeFunctionSupported("lower"); using (ISession s = OpenSession()) { Animal a1 = new Animal("ABCDEF", 1f); @@ -626,12 +615,60 @@ public void Lower() } } + [Test] + public void Ascii() + { + AssumeFunctionSupported("ascii"); + + using (var s = OpenSession()) + { + var m = new MaterialResource(" ", "000", MaterialResource.MaterialState.Available); + s.Save(m); + s.Flush(); + } + using (var s = OpenSession()) + { + var space = s.CreateQuery("select ascii(m.Description) from MaterialResource m").UniqueResult(); + Assert.That(space, Is.EqualTo(32)); + var count = + s + .CreateQuery("select count(*) from MaterialResource m where ascii(m.Description) = :c") + .SetInt32("c", 32) + .UniqueResult(); + Assert.That(count, Is.EqualTo(1)); + } + } + + [Test] + public void Chr() + { + AssumeFunctionSupported("chr"); + + using (var s = OpenSession()) + { + var m = new MaterialResource("Blah", "000", (MaterialResource.MaterialState)32); + s.Save(m); + s.Flush(); + } + using (var s = OpenSession()) + { + var space = s.CreateQuery("select chr(m.State) from MaterialResource m").UniqueResult(); + Assert.That(space, Is.EqualTo(' ')); + var count = + s + .CreateQuery("select count(*) from MaterialResource m where chr(m.State) = :c") + .SetCharacter("c", ' ') + .UniqueResult(); + Assert.That(count, Is.EqualTo(1)); + } + } + [Test] public void Cast() { const double magicResult = 7 + 123 - 5*1.3d; - IgnoreIfNotSupported("cast"); + AssumeFunctionSupported("cast"); // The cast is used to test various cases of a function render // Cast was selected because represent a special case for: // 1) Has more then 1 argument @@ -809,7 +846,7 @@ public void Cast() [Test] public void CastNH1446() { - IgnoreIfNotSupported("cast"); + AssumeFunctionSupported("cast"); using (ISession s = OpenSession()) { Animal a1 = new Animal("abcdef", 1.3f); @@ -829,7 +866,7 @@ public void CastNH1446() [Test] public void CastNH1979() { - IgnoreIfNotSupported("cast"); + AssumeFunctionSupported("cast"); using (ISession s = OpenSession()) { Animal a1 = new Animal("abcdef", 1.3f); @@ -847,7 +884,7 @@ public void CastNH1979() [Test] public void Current_TimeStamp() { - IgnoreIfNotSupported("current_timestamp"); + AssumeFunctionSupported("current_timestamp"); using (ISession s = OpenSession()) { Animal a1 = new Animal("abcdef", 1.3f); @@ -867,9 +904,7 @@ public void Current_TimeStamp() [Test] public void Current_TimeStamp_Offset() { - if (!Dialect.Functions.ContainsKey("current_timestamp_offset")) - Assert.Ignore(Dialect + " doesn't support current_timestamp_offset function"); - IgnoreIfNotSupported("current_timestamp_offset"); + AssumeFunctionSupported("current_timestamp_offset"); using (ISession s = OpenSession()) { Animal a1 = new Animal("abcdef", 1.3f); @@ -886,8 +921,8 @@ public void Current_TimeStamp_Offset() [Test] public void Extract() { - IgnoreIfNotSupported("extract"); - IgnoreIfNotSupported("current_timestamp"); + AssumeFunctionSupported("extract"); + AssumeFunctionSupported("current_timestamp"); // test only the parser and render using (ISession s = OpenSession()) @@ -903,7 +938,7 @@ public void Extract() [Test] public void Concat() { - IgnoreIfNotSupported("concat"); + AssumeFunctionSupported("concat"); using (ISession s = OpenSession()) { Animal a1 = new Animal("abcdef", 1f); @@ -929,10 +964,10 @@ public void Concat() [Test] public void HourMinuteSecond() { - IgnoreIfNotSupported("second"); - IgnoreIfNotSupported("minute"); - IgnoreIfNotSupported("hour"); - IgnoreIfNotSupported("current_timestamp"); + AssumeFunctionSupported("second"); + AssumeFunctionSupported("minute"); + AssumeFunctionSupported("hour"); + AssumeFunctionSupported("current_timestamp"); // test only the parser and render using (ISession s = OpenSession()) { @@ -944,9 +979,9 @@ public void HourMinuteSecond() [Test] public void DayMonthYear() { - IgnoreIfNotSupported("day"); - IgnoreIfNotSupported("month"); - IgnoreIfNotSupported("year"); + AssumeFunctionSupported("day"); + AssumeFunctionSupported("month"); + AssumeFunctionSupported("year"); // test only the parser and render using (ISession s = OpenSession()) { @@ -958,7 +993,7 @@ public void DayMonthYear() [Test] public void Str() { - IgnoreIfNotSupported("str"); + AssumeFunctionSupported("str"); using (ISession s = OpenSession()) { Animal a1 = new Animal("abcdef", 20); @@ -980,8 +1015,7 @@ public void Str() [Test] public void Iif() { - if (!Dialect.Functions.ContainsKey("iif")) - Assert.Ignore(Dialect + "doesn't support iif function."); + AssumeFunctionSupported("Iif"); using (ISession s = OpenSession()) { s.Save(new MaterialResource("Flash card 512MB", "A001/07", MaterialResource.MaterialState.Available)); @@ -1024,7 +1058,7 @@ from MaterialResource mr [Test] public void NH1725() { - IgnoreIfNotSupported("iif"); + AssumeFunctionSupported("iif"); // Only to test the parser using (ISession s = OpenSession()) { diff --git a/src/NHibernate.Test/Linq/MathTests.cs b/src/NHibernate.Test/Linq/MathTests.cs index b078c7f0f5f..4c492379738 100644 --- a/src/NHibernate.Test/Linq/MathTests.cs +++ b/src/NHibernate.Test/Linq/MathTests.cs @@ -1,7 +1,6 @@ using System; using System.Linq; using System.Linq.Expressions; -using NHibernate.Dialect; using NHibernate.DomainModel.Northwind.Entities; using NUnit.Framework; @@ -12,12 +11,6 @@ public class MathTests : LinqTestCase { private IQueryable _orderLines; - private void IgnoreIfNotSupported(string function) - { - if (!Dialect.Functions.ContainsKey(function)) - Assert.Ignore("Dialect {0} does not support '{1}' function", Dialect.GetType(), function); - } - protected override void OnSetUp() { base.OnSetUp(); @@ -29,7 +22,7 @@ protected override void OnSetUp() [Test] public void SignAllPositiveTest() { - IgnoreIfNotSupported("sign"); + AssumeFunctionSupported("sign"); var signs = (from o in db.OrderLines select Math.Sign(o.UnitPrice)).ToList(); @@ -39,7 +32,7 @@ public void SignAllPositiveTest() [Test] public void SignAllNegativeTest() { - IgnoreIfNotSupported("sign"); + AssumeFunctionSupported("sign"); var signs = (from o in db.OrderLines select Math.Sign(0m - o.UnitPrice)).ToList(); @@ -49,77 +42,77 @@ public void SignAllNegativeTest() [Test] public void SinTest() { - IgnoreIfNotSupported("sin"); + AssumeFunctionSupported("sin"); Test(o => Math.Round(Math.Sin((double) o.UnitPrice), 5)); } [Test] public void CosTest() { - IgnoreIfNotSupported("cos"); + AssumeFunctionSupported("cos"); Test(o => Math.Round(Math.Cos((double)o.UnitPrice), 5)); } [Test] public void TanTest() { - IgnoreIfNotSupported("tan"); + AssumeFunctionSupported("tan"); Test(o => Math.Round(Math.Tan((double)o.Discount), 5)); } [Test] public void SinhTest() { - IgnoreIfNotSupported("sinh"); + AssumeFunctionSupported("sinh"); Test(o => Math.Round(Math.Sinh((double)o.Discount), 5)); } [Test] public void CoshTest() { - IgnoreIfNotSupported("cosh"); + AssumeFunctionSupported("cosh"); Test(o => Math.Round(Math.Cosh((double)o.Discount), 5)); } [Test] public void TanhTest() { - IgnoreIfNotSupported("tanh"); + AssumeFunctionSupported("tanh"); Test(o => Math.Round(Math.Tanh((double)o.Discount), 5)); } [Test] public void AsinTest() { - IgnoreIfNotSupported("asin"); + AssumeFunctionSupported("asin"); Test(o => Math.Round(Math.Asin((double)o.Discount), 5)); } [Test] public void AcosTest() { - IgnoreIfNotSupported("acos"); + AssumeFunctionSupported("acos"); Test(o => Math.Round(Math.Acos((double)o.Discount), 5)); } [Test] public void AtanTest() { - IgnoreIfNotSupported("atan"); + AssumeFunctionSupported("atan"); Test(o => Math.Round(Math.Atan((double)o.UnitPrice), 5)); } [Test] public void Atan2Test() { - IgnoreIfNotSupported("atan2"); + AssumeFunctionSupported("atan2"); Test(o => Math.Round(Math.Atan2((double)o.Discount, 0.5d), 5)); } [Test] public void PowTest() { - IgnoreIfNotSupported("power"); + AssumeFunctionSupported("power"); Test(o => Math.Round(Math.Pow((double)o.Discount, 0.5d), 5)); } diff --git a/src/NHibernate.Test/TestCase.cs b/src/NHibernate.Test/TestCase.cs index 24c685ad7e4..13f82daf61e 100644 --- a/src/NHibernate.Test/TestCase.cs +++ b/src/NHibernate.Test/TestCase.cs @@ -1,5 +1,6 @@ using System; using System.Collections; +using System.Collections.Generic; using System.Data; using System.Reflection; using log4net; @@ -13,6 +14,7 @@ using NUnit.Framework; using NUnit.Framework.Interfaces; using System.Text; +using NHibernate.Dialect; using NHibernate.Driver; namespace NHibernate.Test @@ -438,7 +440,43 @@ protected DateTime RoundForDialect(DateTime value) { return AbstractDateTimeType.Round(value, Dialect.TimestampResolutionInTicks); } - + + private static readonly Dictionary> DialectsNotSupportingStandardFunction = + new Dictionary> + { + {"locate", new HashSet {typeof (SQLiteDialect)}}, + {"bit_length", new HashSet {typeof (SQLiteDialect)}}, + {"extract", new HashSet {typeof (SQLiteDialect)}}, + { + "nullif", + new HashSet + { + // Actually not supported by the db engine. (Well, could likely still be done with a case when override.) + typeof (MsSqlCeDialect), + typeof (MsSqlCe40Dialect) + }} + }; + + protected void AssumeFunctionSupported(string functionName) + { + // We could test Sfi.SQLFunctionRegistry.HasFunction(functionName) which has the advantage of + // accounting for additionnal functions added in configuration. But Dialect is normally never + // null, while Sfi could be not yet initialized, depending from where this function is called. + // Furtermore there are currently no additionnal functions added in configuration for NHibernate + // tests. + Assume.That( + Dialect.Functions, + Does.ContainKey(functionName), + $"{Dialect} doesn't support {functionName} function."); + + if (!DialectsNotSupportingStandardFunction.TryGetValue(functionName, out var dialects)) + return; + Assume.That( + dialects, + Does.Not.Contain(Dialect.GetType()), + $"{Dialect} doesn't support {functionName} standard function."); + } + #endregion } } diff --git a/src/NHibernate/Dialect/DB2Dialect.cs b/src/NHibernate/Dialect/DB2Dialect.cs index b9b785a2025..3bcd3f01da2 100644 --- a/src/NHibernate/Dialect/DB2Dialect.cs +++ b/src/NHibernate/Dialect/DB2Dialect.cs @@ -115,6 +115,7 @@ public DB2Dialect() RegisterFunction("smallint", new StandardSQLFunction("smallint", NHibernateUtil.Int16)); RegisterFunction("digits", new StandardSQLFunction("digits", NHibernateUtil.String)); + RegisterFunction("ascii", new StandardSQLFunction("ascii", NHibernateUtil.Int32)); RegisterFunction("chr", new StandardSQLFunction("chr", NHibernateUtil.Character)); RegisterFunction("upper", new StandardSQLFunction("upper")); RegisterFunction("ucase", new StandardSQLFunction("ucase")); diff --git a/src/NHibernate/Dialect/FirebirdDialect.cs b/src/NHibernate/Dialect/FirebirdDialect.cs index e84436b5a08..5fa709e15c9 100644 --- a/src/NHibernate/Dialect/FirebirdDialect.cs +++ b/src/NHibernate/Dialect/FirebirdDialect.cs @@ -453,7 +453,8 @@ private void RegisterExternalFbAndIbStandardUDFs() private void RegisterMathematicalFunctions() { RegisterFunction("abs", new StandardSQLFunction("abs", NHibernateUtil.Double)); - RegisterFunction("ceiling", new StandardSQLFunction("ceiling", NHibernateUtil.Double)); + RegisterFunction("ceiling", new StandardSQLFunction("ceiling")); + RegisterFunction("ceil", new StandardSQLFunction("ceil")); RegisterFunction("div", new StandardSQLFunction("div", NHibernateUtil.Double)); RegisterFunction("dpower", new StandardSQLFunction("dpower", NHibernateUtil.Double)); RegisterFunction("ln", new StandardSQLFunction("ln", NHibernateUtil.Double)); @@ -464,7 +465,7 @@ private void RegisterMathematicalFunctions() RegisterFunction("sign", new StandardSQLFunction("sign", NHibernateUtil.Int32)); RegisterFunction("sqtr", new StandardSQLFunction("sqtr", NHibernateUtil.Double)); RegisterFunction("truncate", new StandardSQLFunction("truncate")); - RegisterFunction("floor", new StandardSafeSQLFunction("floor", NHibernateUtil.Double, 1)); + RegisterFunction("floor", new StandardSQLFunction("floor")); RegisterFunction("round", new StandardSQLFunction("round")); } @@ -485,8 +486,10 @@ private void RegisterDateTimeFunctions() private void RegisterStringAndCharFunctions() { - RegisterFunction("ascii_char", new StandardSQLFunction("ascii_char")); - RegisterFunction("ascii_val", new StandardSQLFunction("ascii_val", NHibernateUtil.Int16)); + RegisterFunction("ascii_char", new StandardSQLFunction("ascii_char", NHibernateUtil.Character)); + RegisterFunction("chr", new StandardSQLFunction("ascii_char", NHibernateUtil.Character)); + RegisterFunction("ascii_val", new StandardSQLFunction("ascii_val", NHibernateUtil.Int32)); + RegisterFunction("ascii", new StandardSQLFunction("ascii_val", NHibernateUtil.Int32)); RegisterFunction("lpad", new StandardSQLFunction("lpad")); RegisterFunction("ltrim", new StandardSQLFunction("ltrim")); RegisterFunction("sright", new StandardSQLFunction("sright")); diff --git a/src/NHibernate/Dialect/MsSql2000Dialect.cs b/src/NHibernate/Dialect/MsSql2000Dialect.cs index 213f7152e63..7681e988d39 100644 --- a/src/NHibernate/Dialect/MsSql2000Dialect.cs +++ b/src/NHibernate/Dialect/MsSql2000Dialect.cs @@ -284,7 +284,7 @@ protected virtual void RegisterFunctions() RegisterFunction("sign", new StandardSQLFunction("sign", NHibernateUtil.Int32)); RegisterFunction("ceiling", new StandardSQLFunction("ceiling")); - RegisterFunction("ceil", new StandardSQLFunction("ceil")); + RegisterFunction("ceil", new StandardSQLFunction("ceiling")); RegisterFunction("floor", new StandardSQLFunction("floor")); RegisterFunction("round", new StandardSQLFunction("round")); @@ -326,7 +326,8 @@ protected virtual void RegisterFunctions() RegisterFunction("date", new SQLFunctionTemplate(NHibernateUtil.Date, "dateadd(dd, 0, datediff(dd, 0, ?1))")); RegisterFunction("concat", new VarArgsSQLFunction(NHibernateUtil.String, "(", "+", ")")); RegisterFunction("digits", new StandardSQLFunction("digits", NHibernateUtil.String)); - RegisterFunction("chr", new StandardSQLFunction("chr", NHibernateUtil.Character)); + RegisterFunction("ascii", new StandardSQLFunction("ascii", NHibernateUtil.Int32)); + RegisterFunction("chr", new StandardSQLFunction("char", NHibernateUtil.Character)); RegisterFunction("upper", new StandardSQLFunction("upper")); RegisterFunction("ucase", new StandardSQLFunction("ucase")); RegisterFunction("lcase", new StandardSQLFunction("lcase")); diff --git a/src/NHibernate/Dialect/MySQLDialect.cs b/src/NHibernate/Dialect/MySQLDialect.cs index fb913a92320..f38759e7964 100644 --- a/src/NHibernate/Dialect/MySQLDialect.cs +++ b/src/NHibernate/Dialect/MySQLDialect.cs @@ -284,7 +284,7 @@ protected virtual void RegisterFunctions() RegisterFunction("ucase", new StandardSQLFunction("ucase")); RegisterFunction("lcase", new StandardSQLFunction("lcase")); - RegisterFunction("chr", new StandardSQLFunction("char", NHibernateUtil.Character)); + RegisterFunction("chr", new SQLFunctionTemplate(NHibernateUtil.Character, "cast(char(?1) as char)")); RegisterFunction("ascii", new StandardSQLFunction("ascii", NHibernateUtil.Int32)); RegisterFunction("instr", new StandardSQLFunction("instr", NHibernateUtil.Int32)); RegisterFunction("lpad", new StandardSQLFunction("lpad", NHibernateUtil.String)); diff --git a/src/NHibernate/Dialect/Oracle8iDialect.cs b/src/NHibernate/Dialect/Oracle8iDialect.cs index 45e15891cc9..321237c3a05 100644 --- a/src/NHibernate/Dialect/Oracle8iDialect.cs +++ b/src/NHibernate/Dialect/Oracle8iDialect.cs @@ -230,6 +230,7 @@ protected virtual void RegisterFunctions() RegisterFunction("round", new StandardSQLFunction("round")); RegisterFunction("trunc", new StandardSQLFunction("trunc")); RegisterFunction("ceil", new StandardSQLFunction("ceil")); + RegisterFunction("ceiling", new StandardSQLFunction("ceil")); RegisterFunction("floor", new StandardSQLFunction("floor")); RegisterFunction("chr", new StandardSQLFunction("chr", NHibernateUtil.Character)); diff --git a/src/NHibernate/Dialect/OracleLiteDialect.cs b/src/NHibernate/Dialect/OracleLiteDialect.cs index d0945678fe9..9b6259f36dc 100644 --- a/src/NHibernate/Dialect/OracleLiteDialect.cs +++ b/src/NHibernate/Dialect/OracleLiteDialect.cs @@ -69,6 +69,7 @@ public OracleLiteDialect() RegisterFunction("round", new StandardSQLFunction("round")); RegisterFunction("trunc", new StandardSQLFunction("trunc")); RegisterFunction("ceil", new StandardSQLFunction("ceil")); + RegisterFunction("ceiling", new StandardSQLFunction("ceil")); RegisterFunction("floor", new StandardSQLFunction("floor")); RegisterFunction("chr", new StandardSQLFunction("chr", NHibernateUtil.Character)); diff --git a/src/NHibernate/Dialect/PostgreSQLDialect.cs b/src/NHibernate/Dialect/PostgreSQLDialect.cs index cb1f5086ab2..3ddc692c767 100644 --- a/src/NHibernate/Dialect/PostgreSQLDialect.cs +++ b/src/NHibernate/Dialect/PostgreSQLDialect.cs @@ -79,6 +79,12 @@ public PostgreSQLDialect() RegisterFunction("power", new StandardSQLFunction("power", NHibernateUtil.Double)); + RegisterFunction("floor", new StandardSQLFunction("floor")); + RegisterFunction("ceiling", new StandardSQLFunction("ceiling")); + RegisterFunction("ceil", new StandardSQLFunction("ceil")); + RegisterFunction("chr", new StandardSQLFunction("chr", NHibernateUtil.Character)); + RegisterFunction("ascii", new StandardSQLFunction("ascii", NHibernateUtil.Int32)); + // Register the date function, since when used in LINQ select clauses, NH must know the data type. RegisterFunction("date", new SQLFunctionTemplate(NHibernateUtil.Date, "cast(?1 as date)")); diff --git a/src/NHibernate/Dialect/SQLiteDialect.cs b/src/NHibernate/Dialect/SQLiteDialect.cs index 48236f82949..87904958221 100644 --- a/src/NHibernate/Dialect/SQLiteDialect.cs +++ b/src/NHibernate/Dialect/SQLiteDialect.cs @@ -78,6 +78,7 @@ protected virtual void RegisterFunctions() RegisterFunction("left", new SQLFunctionTemplate(NHibernateUtil.String, "substr(?1,1,?2)")); RegisterFunction("trim", new AnsiTrimEmulationFunction()); RegisterFunction("replace", new StandardSafeSQLFunction("replace", NHibernateUtil.String, 3)); + RegisterFunction("chr", new StandardSQLFunction("char", NHibernateUtil.Character)); RegisterFunction("mod", new SQLFunctionTemplate(NHibernateUtil.Int32, "((?1) % (?2))"));