Skip to content

Fix table group join issue with subclasses #3109

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 2 commits into from
Aug 16, 2022
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
13 changes: 13 additions & 0 deletions src/NHibernate.Test/Async/Linq/ByMethod/JoinTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,19 @@ from o2 in db.Animals.Where(x => x.BodyWeight > 50)
select new {o, o2}).Take(1).ToListAsync());
}

[Test]
public async Task CanInnerJoinOnEntityWithSubclassesAsync()
{
//inner joined animal is not used in output (no need to join subclasses)
var resultsFromOuter1 = await (db.Animals.Join(db.Animals, o => o.Id, i => i.Id, (o, i) => o).Take(1).ToListAsync());

//inner joined mammal is not used in output (but subclass join is needed for mammal)
var resultsFromOuter2 = await (db.Animals.Join(db.Mammals, o => o.Id, i => i.Id, (o, i) => o).Take(1).ToListAsync());

//inner joined animal is used in output (all subclass joins are required)
var resultsFromInner1 = await (db.Animals.Join(db.Animals, o => o.Id, i => i.Id, (o, i) => i).Take(1).ToListAsync());
}

[Test(Description = "GH-2580")]
public async Task CanInnerJoinOnSubclassWithBaseTableReferenceInOnClauseAsync()
{
Expand Down
13 changes: 13 additions & 0 deletions src/NHibernate.Test/Linq/ByMethod/JoinTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,19 @@ from o2 in db.Animals.Where(x => x.BodyWeight > 50)
select new {o, o2}).Take(1).ToList();
}

[Test]
public void CanInnerJoinOnEntityWithSubclasses()
{
//inner joined animal is not used in output (no need to join subclasses)
var resultsFromOuter1 = db.Animals.Join(db.Animals, o => o.Id, i => i.Id, (o, i) => o).Take(1).ToList();

//inner joined mammal is not used in output (but subclass join is needed for mammal)
var resultsFromOuter2 = db.Animals.Join(db.Mammals, o => o.Id, i => i.Id, (o, i) => o).Take(1).ToList();

//inner joined animal is used in output (all subclass joins are required)
var resultsFromInner1 = db.Animals.Join(db.Animals, o => o.Id, i => i.Id, (o, i) => i).Take(1).ToList();
}

[Test(Description = "GH-2580")]
public void CanInnerJoinOnSubclassWithBaseTableReferenceInOnClause()
{
Expand Down
6 changes: 3 additions & 3 deletions src/NHibernate/Engine/TableGroupJoinHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ internal class TableGroupJoinHelper
{
internal static bool ProcessAsTableGroupJoin(IReadOnlyList<IJoin> tableGroupJoinables, SqlString[] withClauseFragments, bool includeAllSubclassJoins, JoinFragment joinFragment, Func<string, bool> isSubclassIncluded, ISessionFactoryImplementor sessionFactoryImplementor)
{
if (!NeedsTableGroupJoin(tableGroupJoinables, withClauseFragments, includeAllSubclassJoins))
if (!NeedsTableGroupJoin(tableGroupJoinables, withClauseFragments, includeAllSubclassJoins, isSubclassIncluded))
return false;

var first = tableGroupJoinables[0];
Expand Down Expand Up @@ -58,7 +58,7 @@ internal static bool ProcessAsTableGroupJoin(IReadOnlyList<IJoin> tableGroupJoin
}

// detect cases when withClause is used on multiple tables or when join keys depend on subclass columns
private static bool NeedsTableGroupJoin(IReadOnlyList<IJoin> joins, SqlString[] withClauseFragments, bool includeSubclasses)
private static bool NeedsTableGroupJoin(IReadOnlyList<IJoin> joins, SqlString[] withClauseFragments, bool includeSubclasses, Func<string, bool> isSubclassIncluded)
{
bool hasWithClause = withClauseFragments.Any(x => SqlStringHelper.IsNotEmpty(x));

Expand All @@ -69,7 +69,7 @@ private static bool NeedsTableGroupJoin(IReadOnlyList<IJoin> joins, SqlString[]
foreach (var join in joins)
{
var entityPersister = GetEntityPersister(join.Joinable);
if (entityPersister?.HasSubclassJoins(includeSubclasses) != true)
if (entityPersister?.HasSubclassJoins(includeSubclasses && isSubclassIncluded(join.Alias)) != true)
continue;

if (hasWithClause)
Expand Down