[DDC-335] Refactor DQL EBNF to use JOIN FETCH as syntax for fetch joins only Created: 14/Feb/10  Updated: 19/Feb/10  Resolved: 19/Feb/10

Status: Closed
Project: Doctrine 2 - ORM
Component/s: DQL
Affects Version/s: 2.0-ALPHA4
Fix Version/s: 2.0-BETA1
Security Level: All

Type: Improvement Priority: Critical
Reporter: Benjamin Eberlei Assignee: Roman S. Borschel
Resolution: Fixed Votes: 0
Labels: None

Issue Links:
Dependency
is required for DDC-195 Ordering of associations Resolved

 Description   

There are several problems with the current approach on fetch joins:

1. There is no way to determine in the parser already if a join is fetch or not, this makes it much harder to implement things like @OrderBy or @OrderColumn
2. A DQL like "SELECT u, g.name FROM User u JOIN u.group g" currently tries to partially load the group object instead of just returning g.name as scalar. This is very unintuiative.

Solution, change the EBNF too:

Join                                       ::= ["LEFT" ["OUTER"] | "INNER"] "JOIN" [FETCH] JoinAssociationPathExpression 
                                               ["AS"] AliasIdentificationVariable [("ON" | "WITH") ConditionalExpression]

Question would be how to specify partial object selects.

Romans idea was something like:

select u.{name, other, field, stuff}

However my take is this would again put information into the select clause that might be interesting elsewhere, so

SELECT u FROM User u JOIN FETCH u.group PARTIAL id, name

That way we could add both $isFetchJoin and $isPartial flags to the AST/Join Node plus an additional $partialFields array.



 Comments   
Comment by Benjamin Eberlei [ 16/Feb/10 ]

Ah just to remember, the idea on the partial fetch syntax was something like:

select u FROM User u.{name, other, field, stuff} JOIN FETCH u.group g.{id, name, baz}
Comment by Benjamin Eberlei [ 16/Feb/10 ]

I think this will also make the HINT_PARTIAL_LOAD constant obsolet, since the DQL is already implicitly requesting a partial load.

Comment by Roman S. Borschel [ 16/Feb/10 ]

Regarding HINT_FORCE_PARTIAL_LOAD: Not necessarily, but it might need to be renamed since its still used to decide whether to stub associations with empty collections/proxies.

Anyways, I've played around a bit with different implementations in the last days and I changed my mind regarding changing the fetch join syntax. It has many complications, like more difficult sql construction in the walker, among other things, and of course the fact that it would be a huge bc break.

However, some things will change. "select u.name" will select a scalar value, as you expect. The new syntax for partial object selection will currently be:

select partial u.{id,name}, partial a.{id,city} from User u join u.address a

There will be a new AST node PartialObjectExpression that represents such a construct.

Thats the current state of my progress. Regarding the isFetchJoin/isPartial decisions, we need to find another way and I'm confident there are some other ways.

So far...

Comment by Benjamin Eberlei [ 16/Feb/10 ]

If we change u.name to retrieving a scalar value always its easy to get all the fetch joins identification variables inside the SELECT already:

If (identificiationVariable) => fetchJoin

Then when the join is found, you can mark the Join as Fetch already.

Comment by Roman S. Borschel [ 19/Feb/10 ]

Implemented.

Generated at Sun Oct 26 04:43:23 UTC 2014 using JIRA 6.2.3#6260-sha1:63ef1d6dac3f4f4d7db4c1effd405ba38ccdc558.