borinquenkid commented on PR #16773:
URL: https://github.com/apache/grails-core/pull/16773#issuecomment-6539275914
Updated with clean alias classification and scope isolation.
### Architectural Context & Resolution
#### 1. Explicit User Aliases vs. Implicit Navigation Joins
- **Explicit Aliases**: Aliases declared intentionally by the developer
(such as `createAlias('homeAddress', 'ha')` or `homeAddress('ha') { ... }`).
These represent intentional correlation anchor points that outer queries,
subqueries, and nested blocks are permitted to reference.
- **Implicit Navigation Joins**: Joins generated automatically when
navigating property paths (such as `eq('country.name', 'USA')` inside an
association block or `eq('homeAddress.city', 'Springfield')` at the top level).
These are internal implementation details of query construction and must never
be treated as explicit aliases.
#### 2. Why Realization Never Confers Explicit Status
- In `AliasRegistry.isExplicit(alias)`, presence in `realizedExpressions`
has been removed from determining whether an alias is explicit. An alias is
explicit **if and only if** declared with `explicit == true` in its definition
(or inherited as an explicit definition from an ancestor context).
- Materializing or caching an implicit join in `realizedExpressions` no
longer elevates it to an explicit alias. As a consequence:
1. Implicit joins realized inside nested contexts are not propagated
upward to the parent context in `JpaQueryContext.registerAlias`, keeping parent
contexts free of unqualified property names (such as `country`). Sibling blocks
like `workAddress { eq('country.name', 'Canada') }` navigate their own
independent joins rather than resolving against a sibling's materialized join.
2. Subqueries checking `parent.isExplicit(...)` never see outer implicit
joins as correlation candidates, eliminating accidental correlation through
outer association paths.
#### 3. ExpressionResolver Isolation
- In `ExpressionResolver`, resolving and tracking implicit joins records
them locally in `JoinTracker` and `realizedExpressions` without calling
`context.registerAlias(...)` unless the alias definition was explicitly
declared by the user.
#### 4. Test Coverage
- In `SubqueryAssociationCorrelationSpec`, verified:
- Sibling association blocks with dotted paths independently constrain
their own associations without dropping or sharing joins.
- Subqueries following an outer implicit association join do not correlate
through the outer implicit path and resolve independently on their own root.
- Correlated subqueries with explicit user aliases continue to correlate
properly with the outer query.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]