From 3bb78958e5afa818c4d5a1c2db2f58aa95c272fb Mon Sep 17 00:00:00 2001 From: Roman Artiukhin Date: Wed, 3 Apr 2019 19:21:39 +0300 Subject: [PATCH 1/5] Allow columns index be shared between columns from base and subclass classes Fixes #2099 --- .../NHSpecificTest/GH2099/Entity.cs | 22 +++++++++++++++ .../NHSpecificTest/GH2099/Fixture.cs | 27 +++++++++++++++++++ .../NHSpecificTest/GH2099/Mappings.hbm.xml | 20 ++++++++++++++ src/NHibernate/Mapping/DenormalizedTable.cs | 6 +++++ 4 files changed, 75 insertions(+) create mode 100644 src/NHibernate.Test/NHSpecificTest/GH2099/Entity.cs create mode 100644 src/NHibernate.Test/NHSpecificTest/GH2099/Fixture.cs create mode 100644 src/NHibernate.Test/NHSpecificTest/GH2099/Mappings.hbm.xml diff --git a/src/NHibernate.Test/NHSpecificTest/GH2099/Entity.cs b/src/NHibernate.Test/NHSpecificTest/GH2099/Entity.cs new file mode 100644 index 00000000000..b5ad54f711a --- /dev/null +++ b/src/NHibernate.Test/NHSpecificTest/GH2099/Entity.cs @@ -0,0 +1,22 @@ +using System; + +namespace NHibernate.Test.NHSpecificTest.GH2099 +{ + abstract class PersistentObject + { + public virtual Guid Id { get; set; } + public virtual bool PDO_Deleted { get; set; } + } + + class WorkflowInstance : PersistentObject + { + public virtual bool IsActive { get; set; } + public virtual bool IsWaiting { get; set; } + } + + class WorkflowInstance2 : PersistentObject + { + public virtual bool IsActive { get; set; } + public virtual bool IsWaiting { get; set; } + } +} diff --git a/src/NHibernate.Test/NHSpecificTest/GH2099/Fixture.cs b/src/NHibernate.Test/NHSpecificTest/GH2099/Fixture.cs new file mode 100644 index 00000000000..9df81bf522d --- /dev/null +++ b/src/NHibernate.Test/NHSpecificTest/GH2099/Fixture.cs @@ -0,0 +1,27 @@ +using System.Linq; +using NUnit.Framework; + +namespace NHibernate.Test.NHSpecificTest.GH2099 +{ + [TestFixture] + public class Fixture : BugTestCase + { + protected override void OnSetUp() + { + } + + protected override void OnTearDown() + { + } + + [Test] + public void BaseClassCanShareIndexNameWithSubclass() + { + var table = cfg.CreateMappings().IterateTables.FirstOrDefault(t => t.Name == "WFE_workflowinstance"); + + var index = table.GetIndex("CF_BASE_COMPOSITE_IDX"); + Assert.That(index?.ColumnSpan, Is.EqualTo(3)); + Assert.That(index.ColumnIterator.FirstOrDefault(c => c.Name == "PDO_Deleted"), Is.Not.Null); + } + } +} diff --git a/src/NHibernate.Test/NHSpecificTest/GH2099/Mappings.hbm.xml b/src/NHibernate.Test/NHSpecificTest/GH2099/Mappings.hbm.xml new file mode 100644 index 00000000000..e2c32a02844 --- /dev/null +++ b/src/NHibernate.Test/NHSpecificTest/GH2099/Mappings.hbm.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + diff --git a/src/NHibernate/Mapping/DenormalizedTable.cs b/src/NHibernate/Mapping/DenormalizedTable.cs index 24e2a14c5ab..38a8fbc008a 100644 --- a/src/NHibernate/Mapping/DenormalizedTable.cs +++ b/src/NHibernate/Mapping/DenormalizedTable.cs @@ -43,6 +43,12 @@ public override IEnumerable IndexIterator IEnumerable includedIdxs = includedTable.IndexIterator; foreach (Index parentIndex in includedIdxs) { + var sharedIndex = GetIndex(parentIndex.Name); + if (sharedIndex != null) + { + sharedIndex.AddColumns(parentIndex.ColumnIterator); + continue; + } Index index = new Index(); index.Name = Name + parentIndex.Name; index.Table = this; From ed87ec3d0cb33940ee0c6a7244da26dcf9237e52 Mon Sep 17 00:00:00 2001 From: Roman Artiukhin Date: Wed, 3 Apr 2019 19:58:54 +0300 Subject: [PATCH 2/5] Use base name for shared index --- src/NHibernate/Mapping/DenormalizedTable.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/NHibernate/Mapping/DenormalizedTable.cs b/src/NHibernate/Mapping/DenormalizedTable.cs index 38a8fbc008a..0659dfdae7b 100644 --- a/src/NHibernate/Mapping/DenormalizedTable.cs +++ b/src/NHibernate/Mapping/DenormalizedTable.cs @@ -43,14 +43,17 @@ public override IEnumerable IndexIterator IEnumerable includedIdxs = includedTable.IndexIterator; foreach (Index parentIndex in includedIdxs) { + //TODO: Change index name only for DB that require unique index name (like PostgreSQL) + var newName = Name + parentIndex.Name; var sharedIndex = GetIndex(parentIndex.Name); if (sharedIndex != null) { sharedIndex.AddColumns(parentIndex.ColumnIterator); + sharedIndex.Name = newName; continue; } Index index = new Index(); - index.Name = Name + parentIndex.Name; + index.Name = newName; index.Table = this; index.AddColumns(parentIndex.ColumnIterator); indexes.Add(index); From c4a30cd706ed50ece1cb0c8b412e2b5ff0460f5d Mon Sep 17 00:00:00 2001 From: Roman Artiukhin Date: Wed, 3 Apr 2019 21:41:05 +0300 Subject: [PATCH 3/5] Shorten DB object names --- .../NHSpecificTest/GH2099/Fixture.cs | 4 ++-- .../NHSpecificTest/GH2099/Mappings.hbm.xml | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/NHibernate.Test/NHSpecificTest/GH2099/Fixture.cs b/src/NHibernate.Test/NHSpecificTest/GH2099/Fixture.cs index 9df81bf522d..cf78be3dda3 100644 --- a/src/NHibernate.Test/NHSpecificTest/GH2099/Fixture.cs +++ b/src/NHibernate.Test/NHSpecificTest/GH2099/Fixture.cs @@ -17,9 +17,9 @@ protected override void OnTearDown() [Test] public void BaseClassCanShareIndexNameWithSubclass() { - var table = cfg.CreateMappings().IterateTables.FirstOrDefault(t => t.Name == "WFE_workflowinstance"); + var table = cfg.CreateMappings().IterateTables.FirstOrDefault(t => t.Name == "WInstance"); - var index = table.GetIndex("CF_BASE_COMPOSITE_IDX"); + var index = table.GetIndex("CF_BASE_IDX"); Assert.That(index?.ColumnSpan, Is.EqualTo(3)); Assert.That(index.ColumnIterator.FirstOrDefault(c => c.Name == "PDO_Deleted"), Is.Not.Null); } diff --git a/src/NHibernate.Test/NHSpecificTest/GH2099/Mappings.hbm.xml b/src/NHibernate.Test/NHSpecificTest/GH2099/Mappings.hbm.xml index e2c32a02844..0a0a8b89f6d 100644 --- a/src/NHibernate.Test/NHSpecificTest/GH2099/Mappings.hbm.xml +++ b/src/NHibernate.Test/NHSpecificTest/GH2099/Mappings.hbm.xml @@ -2,19 +2,19 @@ - + - + - - - + + + - - - + + + From 659be67d94988cf64790c9bb577085658aa24129 Mon Sep 17 00:00:00 2001 From: Roman Artiukhin Date: Thu, 4 Apr 2019 09:28:33 +0300 Subject: [PATCH 4/5] Rename base index name only if required (Add UniqueIndexNameForDatabase for now true only for PostgreSQL) Support 2+ levels of inheritance for index --- src/NHibernate.Test/NHSpecificTest/GH2099/Entity.cs | 6 +++++- src/NHibernate.Test/NHSpecificTest/GH2099/Fixture.cs | 3 ++- .../NHSpecificTest/GH2099/Mappings.hbm.xml | 4 +++- src/NHibernate/Dialect/Dialect.cs | 5 +++++ src/NHibernate/Dialect/PostgreSQLDialect.cs | 2 ++ src/NHibernate/Mapping/DenormalizedTable.cs | 7 +++---- src/NHibernate/Mapping/Index.cs | 8 +++++++- 7 files changed, 27 insertions(+), 8 deletions(-) diff --git a/src/NHibernate.Test/NHSpecificTest/GH2099/Entity.cs b/src/NHibernate.Test/NHSpecificTest/GH2099/Entity.cs index b5ad54f711a..cb0f1e2cd1a 100644 --- a/src/NHibernate.Test/NHSpecificTest/GH2099/Entity.cs +++ b/src/NHibernate.Test/NHSpecificTest/GH2099/Entity.cs @@ -10,10 +10,14 @@ abstract class PersistentObject class WorkflowInstance : PersistentObject { - public virtual bool IsActive { get; set; } public virtual bool IsWaiting { get; set; } } + class Level3 : WorkflowInstance + { + public virtual bool IsActive { get; set; } + } + class WorkflowInstance2 : PersistentObject { public virtual bool IsActive { get; set; } diff --git a/src/NHibernate.Test/NHSpecificTest/GH2099/Fixture.cs b/src/NHibernate.Test/NHSpecificTest/GH2099/Fixture.cs index cf78be3dda3..12e5ca529d2 100644 --- a/src/NHibernate.Test/NHSpecificTest/GH2099/Fixture.cs +++ b/src/NHibernate.Test/NHSpecificTest/GH2099/Fixture.cs @@ -14,10 +14,11 @@ protected override void OnTearDown() { } + //Note: If this test is failed on DB creation you need to adjust Dialect.UniqueIndexNameForDatabase [Test] public void BaseClassCanShareIndexNameWithSubclass() { - var table = cfg.CreateMappings().IterateTables.FirstOrDefault(t => t.Name == "WInstance"); + var table = cfg.CreateMappings().IterateTables.FirstOrDefault(t => t.Name == "Level3"); var index = table.GetIndex("CF_BASE_IDX"); Assert.That(index?.ColumnSpan, Is.EqualTo(3)); diff --git a/src/NHibernate.Test/NHSpecificTest/GH2099/Mappings.hbm.xml b/src/NHibernate.Test/NHSpecificTest/GH2099/Mappings.hbm.xml index 0a0a8b89f6d..128242e2aee 100644 --- a/src/NHibernate.Test/NHSpecificTest/GH2099/Mappings.hbm.xml +++ b/src/NHibernate.Test/NHSpecificTest/GH2099/Mappings.hbm.xml @@ -8,7 +8,6 @@ - @@ -17,4 +16,7 @@ + + + diff --git a/src/NHibernate/Dialect/Dialect.cs b/src/NHibernate/Dialect/Dialect.cs index 03afd28afb6..cb6ca36143c 100644 --- a/src/NHibernate/Dialect/Dialect.cs +++ b/src/NHibernate/Dialect/Dialect.cs @@ -351,6 +351,11 @@ public virtual bool QualifyIndexName get { return true; } } + /// + /// Does this dialect requires unique index name for database + /// + public virtual bool UniqueIndexNameForDatabase => false; + /// /// Does this dialect support the UNIQUE column syntax? /// diff --git a/src/NHibernate/Dialect/PostgreSQLDialect.cs b/src/NHibernate/Dialect/PostgreSQLDialect.cs index d1353bb037b..70a8520dea3 100644 --- a/src/NHibernate/Dialect/PostgreSQLDialect.cs +++ b/src/NHibernate/Dialect/PostgreSQLDialect.cs @@ -312,6 +312,8 @@ public override string CurrentTimestampSelectString get { return "SELECT CURRENT_TIMESTAMP"; } } + public override bool UniqueIndexNameForDatabase => true; + #region Overridden informational metadata public override bool SupportsEmptyInList => false; diff --git a/src/NHibernate/Mapping/DenormalizedTable.cs b/src/NHibernate/Mapping/DenormalizedTable.cs index 0659dfdae7b..bfb814e2858 100644 --- a/src/NHibernate/Mapping/DenormalizedTable.cs +++ b/src/NHibernate/Mapping/DenormalizedTable.cs @@ -43,17 +43,16 @@ public override IEnumerable IndexIterator IEnumerable includedIdxs = includedTable.IndexIterator; foreach (Index parentIndex in includedIdxs) { - //TODO: Change index name only for DB that require unique index name (like PostgreSQL) - var newName = Name + parentIndex.Name; var sharedIndex = GetIndex(parentIndex.Name); if (sharedIndex != null) { sharedIndex.AddColumns(parentIndex.ColumnIterator); - sharedIndex.Name = newName; + sharedIndex.IsInherited = true; continue; } Index index = new Index(); - index.Name = newName; + index.Name = parentIndex.Name; + index.IsInherited = true; index.Table = this; index.AddColumns(parentIndex.ColumnIterator); indexes.Add(index); diff --git a/src/NHibernate/Mapping/Index.cs b/src/NHibernate/Mapping/Index.cs index 74729189c9b..44b892d4177 100644 --- a/src/NHibernate/Mapping/Index.cs +++ b/src/NHibernate/Mapping/Index.cs @@ -68,7 +68,8 @@ public static string BuildSqlDropIndexString(Dialect.Dialect dialect, Table tabl /// public string SqlCreateString(Dialect.Dialect dialect, IMapping p, string defaultCatalog, string defaultSchema) { - return BuildSqlCreateIndexString(dialect, Name, Table, ColumnIterator, false, defaultCatalog, defaultSchema); + var indexName = (dialect.UniqueIndexNameForDatabase && IsInherited) ? Table.Name + Name : Name; + return BuildSqlCreateIndexString(dialect, indexName, Table, ColumnIterator, false, defaultCatalog, defaultSchema); } /// @@ -144,6 +145,11 @@ public string Name set { name = value; } } + /// + /// Is this index inherited from the base class mapping + /// + public bool IsInherited { get; set; } + public bool ContainsColumn(Column column) { return columns.Contains(column); From 95083482d6b303a6457e9a875f01a7f460e01735 Mon Sep 17 00:00:00 2001 From: Roman Artiukhin Date: Thu, 4 Apr 2019 13:20:50 +0300 Subject: [PATCH 5/5] Remove UniqueIndexNameForDatabase (better to add in separate PR if agreed that it's useful) --- src/NHibernate.Test/NHSpecificTest/GH2099/Fixture.cs | 1 - src/NHibernate/Dialect/Dialect.cs | 5 ----- src/NHibernate/Dialect/PostgreSQLDialect.cs | 2 -- src/NHibernate/Mapping/Index.cs | 2 +- 4 files changed, 1 insertion(+), 9 deletions(-) diff --git a/src/NHibernate.Test/NHSpecificTest/GH2099/Fixture.cs b/src/NHibernate.Test/NHSpecificTest/GH2099/Fixture.cs index 12e5ca529d2..d2ac2c46bb8 100644 --- a/src/NHibernate.Test/NHSpecificTest/GH2099/Fixture.cs +++ b/src/NHibernate.Test/NHSpecificTest/GH2099/Fixture.cs @@ -14,7 +14,6 @@ protected override void OnTearDown() { } - //Note: If this test is failed on DB creation you need to adjust Dialect.UniqueIndexNameForDatabase [Test] public void BaseClassCanShareIndexNameWithSubclass() { diff --git a/src/NHibernate/Dialect/Dialect.cs b/src/NHibernate/Dialect/Dialect.cs index cb6ca36143c..03afd28afb6 100644 --- a/src/NHibernate/Dialect/Dialect.cs +++ b/src/NHibernate/Dialect/Dialect.cs @@ -351,11 +351,6 @@ public virtual bool QualifyIndexName get { return true; } } - /// - /// Does this dialect requires unique index name for database - /// - public virtual bool UniqueIndexNameForDatabase => false; - /// /// Does this dialect support the UNIQUE column syntax? /// diff --git a/src/NHibernate/Dialect/PostgreSQLDialect.cs b/src/NHibernate/Dialect/PostgreSQLDialect.cs index 70a8520dea3..d1353bb037b 100644 --- a/src/NHibernate/Dialect/PostgreSQLDialect.cs +++ b/src/NHibernate/Dialect/PostgreSQLDialect.cs @@ -312,8 +312,6 @@ public override string CurrentTimestampSelectString get { return "SELECT CURRENT_TIMESTAMP"; } } - public override bool UniqueIndexNameForDatabase => true; - #region Overridden informational metadata public override bool SupportsEmptyInList => false; diff --git a/src/NHibernate/Mapping/Index.cs b/src/NHibernate/Mapping/Index.cs index 44b892d4177..a29ec92152a 100644 --- a/src/NHibernate/Mapping/Index.cs +++ b/src/NHibernate/Mapping/Index.cs @@ -68,7 +68,7 @@ public static string BuildSqlDropIndexString(Dialect.Dialect dialect, Table tabl /// public string SqlCreateString(Dialect.Dialect dialect, IMapping p, string defaultCatalog, string defaultSchema) { - var indexName = (dialect.UniqueIndexNameForDatabase && IsInherited) ? Table.Name + Name : Name; + var indexName = IsInherited ? Table.Name + Name : Name; return BuildSqlCreateIndexString(dialect, indexName, Table, ColumnIterator, false, defaultCatalog, defaultSchema); }