Skip to content

Fix NRE in linq processing of custom components #2941

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
Nov 14, 2021
Merged
Show file tree
Hide file tree
Changes from 2 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
6 changes: 3 additions & 3 deletions src/NHibernate.Test/Async/Hql/EntityJoinHqlTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -346,9 +346,9 @@ public async Task NullableEntityProjectionAsync()
var withNullManyToOneList = await (session.Query<NullableOwner>().Where(x => x.ManyToOne == null).ToListAsync());
var withNullManyToOneJoinedList =
await ((from x in session.Query<NullableOwner>()
from x2 in session.Query<NullableOwner>()
where x == x2 && x.ManyToOne == null && x.OneToOne.Name == null
select x2).ToListAsync());
from x2 in session.Query<NullableOwner>()
where x == x2 && x.ManyToOne == null && x.OneToOne.Name == null
select x2).ToListAsync());
Comment on lines -349 to +351
Copy link
Member Author

@fredericDelaporte fredericDelaporte Nov 11, 2021

Choose a reason for hiding this comment

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

I am not sure why those changes occur. Let's get rid of them, if that is not an unstable generation artifact.

Copy link
Member

Choose a reason for hiding this comment

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

I think I just made some whitespace changes for #2772 and forgot to regenerate async code.

Assert.That(fullList.Count, Is.EqualTo(2));
Assert.That(withValidManyToOneList.Count, Is.EqualTo(0));
Assert.That(withValidManyToOneList2.Count, Is.EqualTo(0));
Expand Down
14 changes: 13 additions & 1 deletion src/NHibernate.Test/Linq/TryGetMappedTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,18 @@ public void NestedComponentPropertyCastTest()
o => o?.Name == "component[OtherProperty1]");
}

[Test]
public void CompositePropertyTest()
{
var query = session.Query<Glarch>().Select(o => o.Multiple.count);
AssertSupported(
query,
typeof(Glarch).FullName,
"Multiple.count",
o => o is Int32Type,
o => o?.Name == typeof(MultiplicityType).FullName);
}

[Test]
public void ManyToOneTest()
{
Expand Down Expand Up @@ -807,7 +819,7 @@ private void AssertResult(
Assert.That(() => expectedMemberType(memberType), $"Invalid member type: {memberType?.Name ?? "null"}");
Assert.That(() => expectedComponentType(componentType), $"Invalid component type: {componentType?.Name ?? "null"}");

if (found)
if (found && (componentType == null || componentType.PropertyNullability != null))
Copy link
Member

Choose a reason for hiding this comment

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

Maybe instead make nullability parameter nullable. And check that _tryGetMappedNullability returns false when it's null.

Copy link
Member Author

@fredericDelaporte fredericDelaporte Nov 11, 2021

Choose a reason for hiding this comment

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

I am adding a commit doing what I think you are meaning, but I do not see this as an improvement. It looks to me as a less understandable way of testing, and maybe more brittle, subject to cause the test to fail if we start implementing that nullability property for custom composite type.

Copy link
Member

Choose a reason for hiding this comment

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

But with your initial change TryGetMappedNullability call is not tested at all for problematic case. Isn't it? So your changes were not covered.

subject to cause the test to fail if we start implementing that nullability property for custom composite type.

I see no problem with adjusting existing test cases when behavior is changed.

nit: I would also add optional nullability parameter to AssertResult method and keep AssertResult call it test case

Copy link
Member Author

Choose a reason for hiding this comment

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

Ok, I thought the test parsing the query would also cause the method to be called, but I had not checked. I have added your nit.

{
Assert.That(_tryGetMappedNullability(Sfi, queryModel.SelectClause.Selector, out var isNullable), Is.True, "Expression should be supported");
Assert.That(nullability, Is.EqualTo(isNullable), "Nullability is not correct");
Expand Down
9 changes: 8 additions & 1 deletion src/NHibernate/Util/ExpressionsHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -160,10 +160,17 @@ internal static bool TryGetMappedNullability(
int index;
if (componentType != null)
{
var propertyNullability = componentType.PropertyNullability;
if (propertyNullability == null)
{
nullable = false;
return false;
}

index = Array.IndexOf(
componentType.PropertyNames,
memberPath.Substring(memberPath.LastIndexOf('.') + 1));
nullable = componentType.PropertyNullability[index];
nullable = propertyNullability[index];
return true;
}

Expand Down