Skip to content

Conversation

@stof
Copy link
Member

@stof stof commented Oct 7, 2025

DQL arbitrary joins are semantically equivalent to SQL joins, so using the same keyword reduces confusion. It also means that in next major version, the WITH keyword will only be about applying adhoc filtering on relations instead of having 2 responsibilities.

Closes #12192
Closes #7891 (the confusion is solved)
Closes #3544 (that constant now produces valid code)

mpdude
mpdude previously approved these changes Oct 8, 2025
Copy link
Contributor

@mpdude mpdude left a comment

Choose a reason for hiding this comment

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

Nice work

@stof stof force-pushed the arbitrary_join_on branch from 32ed181 to 44a69c4 Compare October 8, 2025 09:05
mpdude
mpdude previously approved these changes Oct 8, 2025
@derrabus
Copy link
Member

derrabus commented Oct 8, 2025

Can you have a look at the failing tests?

mpdude
mpdude previously approved these changes Oct 9, 2025
Copy link
Contributor

@mpdude mpdude left a comment

Choose a reason for hiding this comment

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

Nice

mpdude
mpdude previously approved these changes Oct 14, 2025
$joinDeclaration->isRoot = false;

$join->conditionalExpression = $this->ConditionalExpression();
if ($this->lexer->isNextToken(TokenType::T_ON)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't have a computer near me right now, so I cannot try out... But what happens when you omit the ˋWITHˋ as well as ˋONˋ here?

Is it possible to get away with a JOIN without a condition and should we prevent that from happening?

Copy link
Member Author

@stof stof Oct 21, 2025

Choose a reason for hiding this comment

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

This was already supported before. The SqlWalker has code to deal with it (even though the doc says the join condition is required for arbitrary joins). Note that the query generated for a join without condition might have worse performance:

$isUnconditionalJoin = $conditions === [];

Copy link
Member Author

Choose a reason for hiding this comment

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

And see this if ($adhocConditions) { in the old code that was making the WITH keyword optional.

Copy link
Contributor

Choose a reason for hiding this comment

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

In that case, would it make sense to remove the

ON is required, even if it is 1 = 1

remark from the docs?

Copy link
Member Author

Choose a reason for hiding this comment

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

I will keep it for now, because I'm not sure this is something we should actually encourage, given the kind of hacks it requires for cross-platform support.
In my opinion, it might make sense to deprecate the case of an arbitrary join without a join condition. I guess the main reason it was initially supported is related to the fact that this was initially parsed on top of association joins (which is why it was implemented with the WITH keyword instead of the intended ON), where the filter condition is optional (because an association join already has a built-in condition for the association)

@mpdude
Copy link
Contributor

mpdude commented Oct 14, 2025

No objections. Unsure if the parser would now accept JOINS without conditions that it would reject previously.

@mpdude
Copy link
Contributor

mpdude commented Oct 21, 2025

@stof Maybe the "fail on deprecation" test passes if you rebase on 3.6.x?

@stof stof force-pushed the arbitrary_join_on branch from 30de04f to a308ec7 Compare October 21, 2025 15:32
@mpdude
Copy link
Contributor

mpdude commented Oct 21, 2025

😿

@stof
Copy link
Member Author

stof commented Oct 21, 2025

@mpdude there is still 1 deprecation coming from DBAL, but it is not related to this PR.

@mpdude
Copy link
Contributor

mpdude commented Oct 21, 2025

Yes. 🚀 from my POV

@mpdude
Copy link
Contributor

mpdude commented Oct 21, 2025

Oh, wait, does this deserve an entry in the UPGRADING.md?

DQL arbitrary joins are semantically equivalent to SQL joins, so using
the same keyword reduces confusion. It also means that in next major
version, the WITH keyword will only be about applying adhoc filtering on
relations instead of having 2 responsibilities.
@stof
Copy link
Member Author

stof commented Oct 21, 2025

@mpdude good catch. I added an upgrade note

@stof stof merged commit dd4e8fe into doctrine:3.6.x Oct 25, 2025
87 of 88 checks passed
@stof stof deleted the arbitrary_join_on branch October 25, 2025 09:03
@greg0ire greg0ire added this to the 3.6.0 milestone Oct 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants