Skip to content

Allow columns index be shared between base and subclass properties #2101

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
May 29, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions src/NHibernate.Test/NHSpecificTest/GH2099/Entity.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
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 IsWaiting { get; set; }
}

class Level3 : WorkflowInstance
{
public virtual bool IsActive { get; set; }
}

class WorkflowInstance2 : PersistentObject
{
public virtual bool IsActive { get; set; }
public virtual bool IsWaiting { get; set; }
}
}
27 changes: 27 additions & 0 deletions src/NHibernate.Test/NHSpecificTest/GH2099/Fixture.cs
Original file line number Diff line number Diff line change
@@ -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 == "Level3");

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);
}
}
}
22 changes: 22 additions & 0 deletions src/NHibernate.Test/NHSpecificTest/GH2099/Mappings.hbm.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="NHibernate.Test"
namespace="NHibernate.Test.NHSpecificTest.GH2099">

<class name="PersistentObject" table="PObject" abstract="true" dynamic-update="true" lazy="true">
<id name="Id" generator="guid.comb" />
<property name="PDO_Deleted" column="PDO_Deleted" index="IDX_DELETED, CF_BASE_IDX" />
</class>

<union-subclass name="WorkflowInstance" table="WInstance" abstract="false" dynamic-update="true" lazy="true" extends="PersistentObject">
<property name="IsWaiting" column="IsWaiting" index="CF_BASE_IDX" />
</union-subclass>

<union-subclass name="WorkflowInstance2" table="WInstance2" abstract="false" dynamic-update="true" lazy="true" extends="PersistentObject">
<property name="IsActive" column="IsActive" index="CF_BASE_IDX" />
<property name="IsWaiting" column="IsWaiting" index="CF_BASE_IDX" />
</union-subclass>

<union-subclass name="Level3" table="Level3" abstract="false" dynamic-update="true" lazy="true" extends="WorkflowInstance">
<property name="IsActive" column="IsActive" index="CF_BASE_IDX" />
</union-subclass>
</hibernate-mapping>
10 changes: 9 additions & 1 deletion src/NHibernate/Mapping/DenormalizedTable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,16 @@ public override IEnumerable<Index> IndexIterator
IEnumerable<Index> includedIdxs = includedTable.IndexIterator;
foreach (Index parentIndex in includedIdxs)
{
var sharedIndex = GetIndex(parentIndex.Name);
if (sharedIndex != null)
{
sharedIndex.AddColumns(parentIndex.ColumnIterator);
sharedIndex.IsInherited = true;
continue;
}
Index index = new Index();
index.Name = Name + parentIndex.Name;
index.Name = parentIndex.Name;
index.IsInherited = true;
index.Table = this;
index.AddColumns(parentIndex.ColumnIterator);
indexes.Add(index);
Expand Down
8 changes: 7 additions & 1 deletion src/NHibernate/Mapping/Index.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ public static string BuildSqlDropIndexString(Dialect.Dialect dialect, Table tabl
/// </returns>
public string SqlCreateString(Dialect.Dialect dialect, IMapping p, string defaultCatalog, string defaultSchema)
{
return BuildSqlCreateIndexString(dialect, Name, Table, ColumnIterator, false, defaultCatalog, defaultSchema);
var indexName = IsInherited ? Table.Name + Name : Name;
Copy link
Member Author

@bahusoid bahusoid Apr 4, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Possible improvement: avoid changing index name for dialects where same index name is allowed for different tables.
According to my tests dialects that require unique index name in database:
Firebird
Oracle
SQLite
PostgreSQL

Support same index name:
SQL Server
SQL Server CE
MySql
SAP SQL Anywhere

return BuildSqlCreateIndexString(dialect, indexName, Table, ColumnIterator, false, defaultCatalog, defaultSchema);
}

/// <summary>
Expand Down Expand Up @@ -144,6 +145,11 @@ public string Name
set { name = value; }
}

/// <summary>
/// Is this index inherited from the base class mapping
/// </summary>
public bool IsInherited { get; set; }

public bool ContainsColumn(Column column)
{
return columns.Contains(column);
Expand Down