dbal icon indicating copy to clipboard operation
dbal copied to clipboard

Set parameter of inner query builders in union is not used to resovle those parameters

Open BackEndTea opened this issue 9 months ago • 1 comments

Bug Report

Q A
Version 4.2.3
Previous Version if the bug is a regression N/a

Summary

When using setParameter on an 'inner' query with unions, the parameter is forgotten when fetching the unioned query.

For example, the following would fail to set the :id parameters when querying results.

$queryBuilder1->select('name')->from('users')->where('id = :id')->setParameter('id', $value);

$queryBuilder2->select('name')->from('admin_users')->where('id = :id')->setParameter('id', $value);

$unionBuilder->union($queryBuilder1)
    ->addUnion($queryBuilder2, \Doctrine\DBAL\Query\UnionType::ALL)
->fetchAllAssociative();

Changing this behavior comes with a few caveats though. As the different queries could set different values for the same parameter, and the unioned query could override these as well, which could make it hard(er) to reason about what value a parameter will have.

If this is intended behavior, then perhaps the documentation on union queries could be updated to explicitly state how this works.

Current behavior

A syntax error due to :id not beign resolved.

Expected behavior

Inner queries being resolved, or documentation updated to mention how this works.

How to reproduce

See code example.

BackEndTea avatar Apr 17 '25 07:04 BackEndTea

That's not a bug, that is intended. You need to define the placeholder/set params on the "top" / "most outer" queryBuilder instance. (the main instance.

$queryBuilder1->select('name')->from('users')->where('id = :id');
$queryBuilder2->select('name')->from('admin_users')->where('id = :id');
$unionBuilder
  ->union($queryBuilder1)
  ->addUnion($queryBuilder2, \Doctrine\DBAL\Query\UnionType::ALL)
  ->setParameter('id', $value)
  ->executeQuery() 
  ->fetchAllAssociative();

If you want to use the same placeholder name with different values for different parts you need to use unique names. In the end it is one query string.

See also -> https://github.com/doctrine/dbal/issues/6525

sbuerk avatar May 23 '25 14:05 sbuerk