From 902796201d0e38ee1ca630173d111b17acca4546 Mon Sep 17 00:00:00 2001 From: CSharper2010 Date: Tue, 20 Jun 2023 08:27:24 +0200 Subject: [PATCH 1/6] Fixes #3327 AND/OR below NOT must use result of subsequent NegateNode calls to create a new result node instead of partially mutating the existing node to consider functional signature of the NegateNode method --- .../NHSpecificTest/GH3327/Entity.cs | 17 +++++ .../NHSpecificTest/GH3327/Fixture.cs | 63 +++++++++++++++++++ .../NHSpecificTest/GH3327/Mappings.hbm.xml | 16 +++++ src/NHibernate/Hql/Ast/ANTLR/HqlParser.cs | 20 +++--- 4 files changed, 106 insertions(+), 10 deletions(-) create mode 100644 src/NHibernate.Test/NHSpecificTest/GH3327/Entity.cs create mode 100644 src/NHibernate.Test/NHSpecificTest/GH3327/Fixture.cs create mode 100644 src/NHibernate.Test/NHSpecificTest/GH3327/Mappings.hbm.xml diff --git a/src/NHibernate.Test/NHSpecificTest/GH3327/Entity.cs b/src/NHibernate.Test/NHSpecificTest/GH3327/Entity.cs new file mode 100644 index 00000000000..9f9b2bafce2 --- /dev/null +++ b/src/NHibernate.Test/NHSpecificTest/GH3327/Entity.cs @@ -0,0 +1,17 @@ +using System; + +namespace NHibernate.Test.NHSpecificTest.GH3327 +{ + public class Entity + { + public virtual int Id { get; set; } + public virtual string Name { get; set; } + } + + public class ChildEntity + { + public virtual int Id { get; set; } + public virtual Entity Parent { get; set; } + public virtual string Name { get; set; } + } +} diff --git a/src/NHibernate.Test/NHSpecificTest/GH3327/Fixture.cs b/src/NHibernate.Test/NHSpecificTest/GH3327/Fixture.cs new file mode 100644 index 00000000000..65a8df7df55 --- /dev/null +++ b/src/NHibernate.Test/NHSpecificTest/GH3327/Fixture.cs @@ -0,0 +1,63 @@ +using System; +using NUnit.Framework; + +namespace NHibernate.Test.NHSpecificTest.GH3327 +{ + [TestFixture] + public class Fixture : BugTestCase + { + protected override void OnSetUp() + { + Sfi.Statistics.IsStatisticsEnabled = true; + } + + protected override void OnTearDown() + { + Sfi.Statistics.IsStatisticsEnabled = false; + using (var session = OpenSession()) + using (var transaction = session.BeginTransaction()) + { + session.CreateQuery("delete from ChildEntity").ExecuteUpdate(); + session.CreateQuery("delete from Entity").ExecuteUpdate(); + + transaction.Commit(); + } + } + + [Test] + public void NotIsCorrectlyHandled() + { + using (var session = OpenSession()) + using (var t = session.BeginTransaction()) + { + var parent = new Entity { Name = "Parent" }; + var child = new ChildEntity { Name = "Child", Parent = parent }; + session.Save(parent); + session.Save(child); + t.Commit(); + } + + using (var session = OpenSession()) + using (var _ = session.BeginTransaction()) + { + var q = session.CreateQuery( + @"SELECT COUNT(ROOT.Id) + FROM Entity AS ROOT + WHERE ( + EXISTS (FROM ChildEntity AS CHILD WHERE CHILD.Parent = ROOT) + AND ROOT.Name = 'Parent' + )"); + Assert.That(q.List()[0], Is.EqualTo(1)); + + q = session.CreateQuery( + @"SELECT COUNT(ROOT.Id) + FROM Entity AS ROOT + WHERE NOT ( + EXISTS (FROM ChildEntity AS CHILD WHERE CHILD.Parent = ROOT) + AND ROOT.Name = 'Parent' + )"); + Assert.That(q.List()[0], Is.EqualTo(0)); + } + } + } +} diff --git a/src/NHibernate.Test/NHSpecificTest/GH3327/Mappings.hbm.xml b/src/NHibernate.Test/NHSpecificTest/GH3327/Mappings.hbm.xml new file mode 100644 index 00000000000..1bf535482d7 --- /dev/null +++ b/src/NHibernate.Test/NHSpecificTest/GH3327/Mappings.hbm.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + diff --git a/src/NHibernate/Hql/Ast/ANTLR/HqlParser.cs b/src/NHibernate/Hql/Ast/ANTLR/HqlParser.cs index f33f8b13acb..fa0656c192a 100644 --- a/src/NHibernate/Hql/Ast/ANTLR/HqlParser.cs +++ b/src/NHibernate/Hql/Ast/ANTLR/HqlParser.cs @@ -212,17 +212,17 @@ public IASTNode NegateNode(IASTNode node) switch (node.Type) { case OR: - node.Type = AND; - node.Text = "{and}"; - NegateNode(node.GetChild(0)); - NegateNode(node.GetChild(1)); - return node; + IASTNode newNode = (IASTNode) TreeAdaptor.Create(AND, "{and}"); + newNode.AddChildren( + NegateNode(node.GetChild(0)), + NegateNode(node.GetChild(1))); + return newNode; case AND: - node.Type = OR; - node.Text = "{or}"; - NegateNode(node.GetChild(0)); - NegateNode(node.GetChild(1)); - return node; + newNode = (IASTNode) TreeAdaptor.Create(OR, "{or}"); + newNode.AddChildren( + NegateNode(node.GetChild(0)), + NegateNode(node.GetChild(1))); + return newNode; case EQ: node.Type = NE; node.Text = "{not}" + node.Text; From 94f3c20d83dfb31c4db3985084f868a5a95da49a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 20 Jun 2023 07:31:19 +0000 Subject: [PATCH 2/6] Generate async files --- .../Async/NHSpecificTest/GH3327/Fixture.cs | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 src/NHibernate.Test/Async/NHSpecificTest/GH3327/Fixture.cs diff --git a/src/NHibernate.Test/Async/NHSpecificTest/GH3327/Fixture.cs b/src/NHibernate.Test/Async/NHSpecificTest/GH3327/Fixture.cs new file mode 100644 index 00000000000..08158aac7ab --- /dev/null +++ b/src/NHibernate.Test/Async/NHSpecificTest/GH3327/Fixture.cs @@ -0,0 +1,74 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by AsyncGenerator. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + + +using System; +using NUnit.Framework; + +namespace NHibernate.Test.NHSpecificTest.GH3327 +{ + using System.Threading.Tasks; + [TestFixture] + public class FixtureAsync : BugTestCase + { + protected override void OnSetUp() + { + Sfi.Statistics.IsStatisticsEnabled = true; + } + + protected override void OnTearDown() + { + Sfi.Statistics.IsStatisticsEnabled = false; + using (var session = OpenSession()) + using (var transaction = session.BeginTransaction()) + { + session.CreateQuery("delete from ChildEntity").ExecuteUpdate(); + session.CreateQuery("delete from Entity").ExecuteUpdate(); + + transaction.Commit(); + } + } + + [Test] + public async Task NotIsCorrectlyHandledAsync() + { + using (var session = OpenSession()) + using (var t = session.BeginTransaction()) + { + var parent = new Entity { Name = "Parent" }; + var child = new ChildEntity { Name = "Child", Parent = parent }; + await (session.SaveAsync(parent)); + await (session.SaveAsync(child)); + await (t.CommitAsync()); + } + + using (var session = OpenSession()) + using (var _ = session.BeginTransaction()) + { + var q = session.CreateQuery( + @"SELECT COUNT(ROOT.Id) + FROM Entity AS ROOT + WHERE ( + EXISTS (FROM ChildEntity AS CHILD WHERE CHILD.Parent = ROOT) + AND ROOT.Name = 'Parent' + )"); + Assert.That((await (q.ListAsync()))[0], Is.EqualTo(1)); + + q = session.CreateQuery( + @"SELECT COUNT(ROOT.Id) + FROM Entity AS ROOT + WHERE NOT ( + EXISTS (FROM ChildEntity AS CHILD WHERE CHILD.Parent = ROOT) + AND ROOT.Name = 'Parent' + )"); + Assert.That((await (q.ListAsync()))[0], Is.EqualTo(0)); + } + } + } +} From b4dd0814fd70fa46879ae34e31acee8bd4601c8e Mon Sep 17 00:00:00 2001 From: Roman Artiukhin Date: Sun, 2 Jul 2023 21:36:28 +0300 Subject: [PATCH 3/6] Try fix tests --- src/NHibernate.Test/NHSpecificTest/GH3327/Mappings.hbm.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NHibernate.Test/NHSpecificTest/GH3327/Mappings.hbm.xml b/src/NHibernate.Test/NHSpecificTest/GH3327/Mappings.hbm.xml index 1bf535482d7..a6eee729fae 100644 --- a/src/NHibernate.Test/NHSpecificTest/GH3327/Mappings.hbm.xml +++ b/src/NHibernate.Test/NHSpecificTest/GH3327/Mappings.hbm.xml @@ -9,7 +9,7 @@ - + From ce40a2ea051eb40985141d1dfe846a7e185dcddb Mon Sep 17 00:00:00 2001 From: Roman Artiukhin Date: Tue, 18 Jul 2023 11:38:43 +0300 Subject: [PATCH 4/6] Fix without new node creation --- src/NHibernate/Hql/Ast/ANTLR/HqlParser.cs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/NHibernate/Hql/Ast/ANTLR/HqlParser.cs b/src/NHibernate/Hql/Ast/ANTLR/HqlParser.cs index fa0656c192a..6c05fc6c999 100644 --- a/src/NHibernate/Hql/Ast/ANTLR/HqlParser.cs +++ b/src/NHibernate/Hql/Ast/ANTLR/HqlParser.cs @@ -212,17 +212,17 @@ public IASTNode NegateNode(IASTNode node) switch (node.Type) { case OR: - IASTNode newNode = (IASTNode) TreeAdaptor.Create(AND, "{and}"); - newNode.AddChildren( - NegateNode(node.GetChild(0)), - NegateNode(node.GetChild(1))); - return newNode; + node.Type = AND; + node.Text = "{and}"; + node.SetChild(0, NegateNode(node.GetChild(0))); + node.SetChild(1, NegateNode(node.GetChild(1))); + return node; case AND: - newNode = (IASTNode) TreeAdaptor.Create(OR, "{or}"); - newNode.AddChildren( - NegateNode(node.GetChild(0)), - NegateNode(node.GetChild(1))); - return newNode; + node.Type = OR; + node.Text = "{or}"; + node.SetChild(0, NegateNode(node.GetChild(0))); + node.SetChild(1, NegateNode(node.GetChild(1))); + return node; case EQ: node.Type = NE; node.Text = "{not}" + node.Text; From 29262cec1740b88ce65665913955c908f07595f1 Mon Sep 17 00:00:00 2001 From: Roman Artiukhin Date: Tue, 18 Jul 2023 11:53:20 +0300 Subject: [PATCH 5/6] test cleanup --- .../NHSpecificTest/GH3327/Fixture.cs | 51 ++++++++----------- 1 file changed, 20 insertions(+), 31 deletions(-) diff --git a/src/NHibernate.Test/NHSpecificTest/GH3327/Fixture.cs b/src/NHibernate.Test/NHSpecificTest/GH3327/Fixture.cs index 65a8df7df55..aef1a40243e 100644 --- a/src/NHibernate.Test/NHSpecificTest/GH3327/Fixture.cs +++ b/src/NHibernate.Test/NHSpecificTest/GH3327/Fixture.cs @@ -1,5 +1,4 @@ -using System; -using NUnit.Framework; +using NUnit.Framework; namespace NHibernate.Test.NHSpecificTest.GH3327 { @@ -8,56 +7,46 @@ public class Fixture : BugTestCase { protected override void OnSetUp() { - Sfi.Statistics.IsStatisticsEnabled = true; + using var session = OpenSession(); + using var t = session.BeginTransaction(); + var parent = new Entity { Name = "Parent" }; + var child = new ChildEntity { Name = "Child", Parent = parent }; + session.Save(parent); + session.Save(child); + t.Commit(); } protected override void OnTearDown() { - Sfi.Statistics.IsStatisticsEnabled = false; - using (var session = OpenSession()) - using (var transaction = session.BeginTransaction()) - { - session.CreateQuery("delete from ChildEntity").ExecuteUpdate(); - session.CreateQuery("delete from Entity").ExecuteUpdate(); + using var session = OpenSession(); + using var transaction = session.BeginTransaction(); + session.CreateQuery("delete from ChildEntity").ExecuteUpdate(); + session.CreateQuery("delete from Entity").ExecuteUpdate(); - transaction.Commit(); - } + transaction.Commit(); } [Test] public void NotIsCorrectlyHandled() { - using (var session = OpenSession()) - using (var t = session.BeginTransaction()) - { - var parent = new Entity { Name = "Parent" }; - var child = new ChildEntity { Name = "Child", Parent = parent }; - session.Save(parent); - session.Save(child); - t.Commit(); - } - - using (var session = OpenSession()) - using (var _ = session.BeginTransaction()) - { - var q = session.CreateQuery( - @"SELECT COUNT(ROOT.Id) + using var session = OpenSession(); + var q = session.CreateQuery( + @"SELECT COUNT(ROOT.Id) FROM Entity AS ROOT WHERE ( EXISTS (FROM ChildEntity AS CHILD WHERE CHILD.Parent = ROOT) AND ROOT.Name = 'Parent' )"); - Assert.That(q.List()[0], Is.EqualTo(1)); + Assert.That(q.List()[0], Is.EqualTo(1)); - q = session.CreateQuery( - @"SELECT COUNT(ROOT.Id) + q = session.CreateQuery( + @"SELECT COUNT(ROOT.Id) FROM Entity AS ROOT WHERE NOT ( EXISTS (FROM ChildEntity AS CHILD WHERE CHILD.Parent = ROOT) AND ROOT.Name = 'Parent' )"); - Assert.That(q.List()[0], Is.EqualTo(0)); - } + Assert.That(q.List()[0], Is.EqualTo(0)); } } } From f4bb50c070a24541b67456104b8806b3761f07a3 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 18 Jul 2023 08:56:13 +0000 Subject: [PATCH 6/6] Generate async files --- .../Async/NHSpecificTest/GH3327/Fixture.cs | 49 +++++++------------ 1 file changed, 19 insertions(+), 30 deletions(-) diff --git a/src/NHibernate.Test/Async/NHSpecificTest/GH3327/Fixture.cs b/src/NHibernate.Test/Async/NHSpecificTest/GH3327/Fixture.cs index 08158aac7ab..b34a71f1317 100644 --- a/src/NHibernate.Test/Async/NHSpecificTest/GH3327/Fixture.cs +++ b/src/NHibernate.Test/Async/NHSpecificTest/GH3327/Fixture.cs @@ -8,7 +8,6 @@ //------------------------------------------------------------------------------ -using System; using NUnit.Framework; namespace NHibernate.Test.NHSpecificTest.GH3327 @@ -19,56 +18,46 @@ public class FixtureAsync : BugTestCase { protected override void OnSetUp() { - Sfi.Statistics.IsStatisticsEnabled = true; + using var session = OpenSession(); + using var t = session.BeginTransaction(); + var parent = new Entity { Name = "Parent" }; + var child = new ChildEntity { Name = "Child", Parent = parent }; + session.Save(parent); + session.Save(child); + t.Commit(); } protected override void OnTearDown() { - Sfi.Statistics.IsStatisticsEnabled = false; - using (var session = OpenSession()) - using (var transaction = session.BeginTransaction()) - { - session.CreateQuery("delete from ChildEntity").ExecuteUpdate(); - session.CreateQuery("delete from Entity").ExecuteUpdate(); + using var session = OpenSession(); + using var transaction = session.BeginTransaction(); + session.CreateQuery("delete from ChildEntity").ExecuteUpdate(); + session.CreateQuery("delete from Entity").ExecuteUpdate(); - transaction.Commit(); - } + transaction.Commit(); } [Test] public async Task NotIsCorrectlyHandledAsync() { - using (var session = OpenSession()) - using (var t = session.BeginTransaction()) - { - var parent = new Entity { Name = "Parent" }; - var child = new ChildEntity { Name = "Child", Parent = parent }; - await (session.SaveAsync(parent)); - await (session.SaveAsync(child)); - await (t.CommitAsync()); - } - - using (var session = OpenSession()) - using (var _ = session.BeginTransaction()) - { - var q = session.CreateQuery( - @"SELECT COUNT(ROOT.Id) + using var session = OpenSession(); + var q = session.CreateQuery( + @"SELECT COUNT(ROOT.Id) FROM Entity AS ROOT WHERE ( EXISTS (FROM ChildEntity AS CHILD WHERE CHILD.Parent = ROOT) AND ROOT.Name = 'Parent' )"); - Assert.That((await (q.ListAsync()))[0], Is.EqualTo(1)); + Assert.That((await (q.ListAsync()))[0], Is.EqualTo(1)); - q = session.CreateQuery( - @"SELECT COUNT(ROOT.Id) + q = session.CreateQuery( + @"SELECT COUNT(ROOT.Id) FROM Entity AS ROOT WHERE NOT ( EXISTS (FROM ChildEntity AS CHILD WHERE CHILD.Parent = ROOT) AND ROOT.Name = 'Parent' )"); - Assert.That((await (q.ListAsync()))[0], Is.EqualTo(0)); - } + Assert.That((await (q.ListAsync()))[0], Is.EqualTo(0)); } } }