Skip to content

Comments

Add a nice way to create a builder for subqueries#7040

Merged
derrabus merged 1 commit intodoctrine:4.4.xfrom
derrabus:feature/subquery-builder
Jul 21, 2025
Merged

Add a nice way to create a builder for subqueries#7040
derrabus merged 1 commit intodoctrine:4.4.xfrom
derrabus:feature/subquery-builder

Conversation

@derrabus
Copy link
Member

@derrabus derrabus commented Jul 17, 2025

Q A
Type feature
Fixed issues N/A

Summary

In DBAL 3, we could ask q query builder for its database connection. That accessor has been removed in DBAL 4 which is a good thing.

Currently, I'm migrating a codebase that used the QueryBuilder::getConnection() method in order to create a fresh builder for constructing a subquery.

$subQueryBuilder = $queryBuilder->getConnection()->createQueryBuilder();

I believe this is a valid requirement, especially given that we allow query builders for unions and CTEs.

This PR proposes a new method sub() which creates a fresh builder for the same connection, pretty much like the already existing method expr() does for the expression builder.

$subQueryBuilder = $queryBuilder->sub();

@derrabus
Copy link
Member Author

cc @sbuerk

@derrabus derrabus requested review from greg0ire and morozov July 17, 2025 14:52
Copy link
Member

@morozov morozov left a comment

Choose a reason for hiding this comment

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

I had to implement a subquery functionality for my former employer when I migrated their codebase from a proprietary database layer to the DBAL. So definitely a +1 from me.

In that case, the parameters from the subquery would automatically get merged into the higher-level one (both positional and named). As far as I understand, in this case, the parameters of the subquery need to be set on the higher-level one which may be a little confusing. We've had this discussion about some other feature recently.

It would be nice to get this taken care of, but it's not a blocker.

UPD: here's the reference to what that implementation looked like: #2305 (comment).

/**
* Returns a fresh query builder instance that can be used to build a subquery.
*/
public function sub(): self
Copy link
Member

Choose a reason for hiding this comment

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

Although it can be used to build a sub query, it does not have to, and the two instances maintain no link to each other. Did you consider other names for this method? From what I can tell , the important thing is that both QBs share the same connection. But maybe the intent expressed in the comment is more important than the implementation.

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 chose the name because creating a subquery is the usual use-case for calling that method. Yes, you can "abuse" it for other things, but why should I reflect this in the name?

That being said, we can change the name before the 4.4.x release. If you have a better idea, feel free to drop it here or open a PR. 🙂

Copy link
Contributor

Choose a reason for hiding this comment

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

@derrabus Late to the party, personnaly I would prefer createQueryBuilder() to match the naming from the connection. Some reasonings:

  • Emphasizes the method passthrough to the underlying Connection.
  • It may be (mostly) used for subqueries, but nothing limits it (yet).
  • Despite the reoccurance of the "merge parameter" topic, it may be a (hacky) way to connect the properties here so that the top container is used - which is okay for a "new instance" as no parameter needs to be merged at that state. But that would make the situation worser, and should be discussed (liked mentioned in the other comment) dedicatly.

Or createSubQueryBuilder() making it at least from the name clear ...

sub() would not be the method name coming for me in mind to get a new QueryBuilder instance.

@derrabus
Copy link
Member Author

Thanks for the reviews. I'm going to merge now because I believe we can continue all open discussions on other issues or follow-up PRs.

Regarding merging parameters: Yes, on virtually every PR that deals with multiple QBs someone opens that discussion and it is always out of scope for those kind of PRs.

We have an issue about that: #6525. Let's continue there.

@derrabus derrabus merged commit 38299bb into doctrine:4.4.x Jul 21, 2025
86 checks passed
@derrabus derrabus deleted the feature/subquery-builder branch July 21, 2025 22:40
derrabus added a commit to derrabus/dbal that referenced this pull request Jul 21, 2025
* 4.4.x:
  Add a nice way to create a builder for subqueries (doctrine#7040)
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.

5 participants