Skip to content

Fix filtering sub-queries on property-ref #3685

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

Open
wants to merge 3 commits into
base: 5.4.x
Choose a base branch
from

Conversation

fredericDelaporte
Copy link
Member

@fredericDelaporte fredericDelaporte commented Aug 14, 2025

Fix #3609.

The trouble for #3609 is, when comparing an entity from a direct select to a property-ref association on the entity, the primary key of the entity ends up compared to the property-ref of the association.

This fix forces a join when comparing entities through a property-ref association, replacing the property-ref in the comparison by the primary key.

Ideally, it would be better to instead replace the primary key in the comparison by the referenced property of the compared entity without adding a join. But I cannot find how to do that. And in case of comparisons between two association, one with a property-ref, the other with the primary key, the join is mandatory.

The fix had to take into account NH-892.
In the case of NH-892, a property-ref association is compared to an entity parameter. In this case, the parameter ends up fetched with the referenced property, and so, should be directly compared to the property-ref of the association. So, this gets broken by this fix. The fix had to further change the DotNode type to no more be the property-ref association type but the entity-type, in order for the parameter value to be fetched with the primary key value instead of the property-ref value.

(Actually NH-892 was already half-broken: changing the test case association to use not-found="ignore" triggers the same failure, because this forces a join replacing the property-ref in the comparison, too. That is likely a regression from #2081.)

Overall, this fix adds a join which in many cases could theoretically be optimized out for comparing directly references property values, but that is tedious to do and bug prone. So, I settle for a simpler, less optimal solution, but more robust. For me, the first performance metric is correctness. Speed comes second.

// For property-ref associations, we also need this unless finding a way in the IdentNode for the other hand of the comparison
// to detect it should yield the property-ref columns instead of the primary key columns.
bool comparisonWithNullableEntityOrThroughPropertyRef = Walker.IsComparativeExpressionClause
&& (entityType.IsNullable || entityType.IsUniqueKeyReference);
Copy link
Member Author

Choose a reason for hiding this comment

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

The original test case does not need the IsUniqueKeyReference test, because the not-found="ignore" mapping causes the association to be considered nullable. But the trouble occurs without this attribute too.

}

if ( joinIsNeeded )
{
DereferenceEntityJoin(classAlias, entityType, implicitJoin, parent, comparisonWithNullableEntity);
if (comparisonWithNullableEntity)
var forceLeftJoin = comparisonWithNullableEntityOrThroughPropertyRef && !IsCorrelatedSubselect;
Copy link
Member Author

Choose a reason for hiding this comment

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

CorrelatedSubselect forces a theta-style join, which is not compatible with left joins. That was the cause for #3306 fixed by #3312 by ceasing to generate joins for nullable entities when in a subselect. It looks like a crutch actually. And it remains one.

@fredericDelaporte fredericDelaporte force-pushed the GH3609 branch 2 times, most recently from aabef6e to 315363f Compare August 16, 2025 16:58
{
_columns = FromElement.GetIdentityColumns();
DataType = FromElement.EntityPersister.EntityMetamodel.EntityType;
Copy link
Member Author

Choose a reason for hiding this comment

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

This fixes NH-892 regression.

@fredericDelaporte fredericDelaporte added this to the 5.6 milestone Aug 16, 2025
@fredericDelaporte fredericDelaporte marked this pull request as ready for review August 16, 2025 18:35
@fredericDelaporte fredericDelaporte changed the base branch from master to 5.5.x August 16, 2025 18:36
@fredericDelaporte fredericDelaporte changed the base branch from 5.5.x to master August 16, 2025 18:37
@fredericDelaporte
Copy link
Member Author

fredericDelaporte commented Aug 16, 2025

This is currently based on master.

As a v5.3, it should target v5.3.x, but that is so old now, I do not think it is worth it, since that would mean a new version with the recent CVE not fixed in it.

I will see to target v5.4 instead.

(Now it is done.)

@fredericDelaporte fredericDelaporte changed the title Attempt a fix for #3609 Fix for #3609 Aug 16, 2025
@fredericDelaporte fredericDelaporte changed the base branch from master to 5.4.x August 16, 2025 20:58
And fix NH-892 partly broken by the way.
@fredericDelaporte fredericDelaporte modified the milestones: 5.6, 5.4.10 Aug 16, 2025
@fredericDelaporte fredericDelaporte changed the title Fix for #3609 Fix filtering sub-queries on property-ref Aug 17, 2025
@fredericDelaporte fredericDelaporte enabled auto-merge (squash) August 17, 2025 14:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants