Join are lost by the queryBuilder when building a Delete Query #7106

Open
opened 2026-01-22 15:44:48 +01:00 by admin · 8 comments
Owner

Originally created by @VincentLanglet on GitHub (Feb 14, 2023).

Bug Report

Q A
BC Break no
Version 2.14.1

Summary

When writing

$this->createQueryBuilder('ur')->delete()
			->leftJoin('ur.user', 'u')
            ->where('ur.organization = :organizationId')
            ->andWhere('ur.email = :email OR u.email = :email')
            ->setParameter('organizationId', $organizationId)
            ->setParameter('email', $email)
            ->getQuery()
            ->execute();

The query generated is

DELETE App\Entity\UserRole ur WHERE ur.organization = :organizationId AND (ur.email = :email OR u.email =:email)

And the query crash with

[Semantical Error] line 0, col 96 near 'u.email =:em': Error: 'u' is not defined.

Seems like it's not a recent issue https://stackoverflow.com/questions/17301636/doctrine-querybuilder-delete-with-joins
but

  • I didn't find any issues talking about it in github
  • I don't understand why it works this way

Expected behavior

I would expect the query with the LEFT JOIN.

Originally created by @VincentLanglet on GitHub (Feb 14, 2023). ### Bug Report <!-- Fill in the relevant information below to help triage your issue. --> | Q | A |------------ | ------ | BC Break | no | Version | 2.14.1 #### Summary When writing ``` $this->createQueryBuilder('ur')->delete() ->leftJoin('ur.user', 'u') ->where('ur.organization = :organizationId') ->andWhere('ur.email = :email OR u.email = :email') ->setParameter('organizationId', $organizationId) ->setParameter('email', $email) ->getQuery() ->execute(); ``` The query generated is ``` DELETE App\Entity\UserRole ur WHERE ur.organization = :organizationId AND (ur.email = :email OR u.email =:email) ``` And the query crash with ``` [Semantical Error] line 0, col 96 near 'u.email =:em': Error: 'u' is not defined. ``` Seems like it's not a recent issue https://stackoverflow.com/questions/17301636/doctrine-querybuilder-delete-with-joins but - I didn't find any issues talking about it in github - I don't understand why it works this way #### Expected behavior I would expect the query with the LEFT JOIN.
Author
Owner

@mpdude commented on GitHub (Feb 14, 2023):

I don't think DELETE ... LEFT JOIN ... is supported at all, and I also don't see that in https://www.doctrine-project.org/projects/doctrine-orm/en/2.14/reference/dql-doctrine-query-language.html#clauses.

Maybe the QueryBuilder should throw an exception when you construct a query that way.

@mpdude commented on GitHub (Feb 14, 2023): I don't think `DELETE ... LEFT JOIN ...` is supported at all, and I also don't see that in https://www.doctrine-project.org/projects/doctrine-orm/en/2.14/reference/dql-doctrine-query-language.html#clauses. Maybe the `QueryBuilder` should throw an exception when you construct a query that way.
Author
Owner

@VincentLanglet commented on GitHub (Feb 14, 2023):

I don't think DELETE ... LEFT JOIN ... is supported at all,

Maybe the QueryBuilder should throw an exception when you construct a query that way.

Rather than throwing an exception, it seems better to add support for it because this is valid SQL https://www.mysqltutorial.org/mysql-delete-join/

@VincentLanglet commented on GitHub (Feb 14, 2023): > I don't think `DELETE ... LEFT JOIN ...` is supported at all, > > Maybe the `QueryBuilder` should throw an exception when you construct a query that way. Rather than throwing an exception, it seems better to add support for it because this is valid SQL https://www.mysqltutorial.org/mysql-delete-join/
Author
Owner

@mpdude commented on GitHub (Feb 14, 2023):

Are we talking about DQL or SQL?

@mpdude commented on GitHub (Feb 14, 2023): Are we talking about DQL or SQL?
Author
Owner

@VincentLanglet commented on GitHub (Feb 14, 2023):

Are we talking about DQL or SQL?

Why not both ?
Since it's valid SQL, it should be a valid DQL too and therefore valid Querybuilder too.

I don't know the implementation behing but seems doctrine is able to generate valid SQL or DQL for the Select query:

$this->createQueryBuilder('ur')
			->leftJoin('ur.user', 'u')
            ->where('ur.organization = :organizationId')
            ->andWhere('ur.email = :email OR u.email = :email')
            ->setParameter('organizationId', $organizationId)
            ->setParameter('email', $email)
            ->getQuery()
            ->execute();

it doesn't seem impossible to do the same if I add ->delete().

@VincentLanglet commented on GitHub (Feb 14, 2023): > Are we talking about DQL or SQL? Why not both ? Since it's valid SQL, it should be a valid DQL too and therefore valid Querybuilder too. I don't know the implementation behing but seems doctrine is able to generate valid SQL or DQL for the Select query: ``` $this->createQueryBuilder('ur') ->leftJoin('ur.user', 'u') ->where('ur.organization = :organizationId') ->andWhere('ur.email = :email OR u.email = :email') ->setParameter('organizationId', $organizationId) ->setParameter('email', $email) ->getQuery() ->execute(); ``` it doesn't seem impossible to do the same if I add `->delete()`.
Author
Owner

@mpdude commented on GitHub (Feb 14, 2023):

Maybe a subselect in the where clause can help you to identify the root entities that you’d like to delete?

@mpdude commented on GitHub (Feb 14, 2023): Maybe a subselect in the where clause can help you to identify the root entities that you’d like to delete?
Author
Owner

@VincentLanglet commented on GitHub (Feb 14, 2023):

Maybe a subselect in the where clause can help you to identify the root entities that you’d like to delete?

Sure, but that's not really the point of the issue.
I can solve my issue by writing a query to get the id and then deleting the following ids. I can also write raw SQL.

I just wanted to report the bug about the lost joins with delete querybuilder because I was suprised:

  • This was currently not supported
  • This is silently done
  • Nobody reported the issue before

Looking at the getDql methods,
https://github.com/doctrine/orm/blob/2.14.x/lib/Doctrine/ORM/QueryBuilder.php#L1427-L1478
I wonder if the

$this->getReducedDQLQueryPart('from', ['pre' => ' ', 'separator' => ', '])

part couldn't be replaced by the logic used for the Select.

@VincentLanglet commented on GitHub (Feb 14, 2023): > Maybe a subselect in the where clause can help you to identify the root entities that you’d like to delete? Sure, but that's not really the point of the issue. I can solve my issue by writing a query to get the id and then deleting the following ids. I can also write raw SQL. I just wanted to report the bug about the lost joins with delete querybuilder because I was suprised: - This was currently not supported - This is silently done - Nobody reported the issue before Looking at the getDql methods, https://github.com/doctrine/orm/blob/2.14.x/lib/Doctrine/ORM/QueryBuilder.php#L1427-L1478 I wonder if the ``` $this->getReducedDQLQueryPart('from', ['pre' => ' ', 'separator' => ', ']) ``` part couldn't be replaced by the logic used for the Select.
Author
Owner

@dmaicher commented on GitHub (Feb 15, 2023):

Related is this issue on dbal.

Joins aren't ​supported in update statements in many vendors, as far as I
know. This should probably throw an exception.

Not sure what the support for this is on various RDBMS

@dmaicher commented on GitHub (Feb 15, 2023): Related is this [issue](https://github.com/doctrine/dbal/issues/2716) on dbal. > Joins aren't ​supported in update statements in many vendors, as far as I know. This should probably throw an exception. Not sure what the support for this is on various RDBMS
Author
Owner

@moritz-ngo commented on GitHub (Apr 17, 2025):

Are there any plans to support this in the future? Otherwise I suggest closing this issue and document why this won't get implemented.

Many thanks in advance.

@moritz-ngo commented on GitHub (Apr 17, 2025): Are there any plans to support this in the future? Otherwise I suggest closing this issue and document why this won't get implemented. Many thanks in advance.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#7106