Orm: DDC-3762: Passing "false" boolean value to eq() function in query builder does not end up SQL query

Created on 9 Jun 2015  路  8Comments  路  Source: doctrine/orm

Jira issue originally created by user danijeld:

$qb->andWhere($qb->expr()->eq('d.active', true));

produces:

   [_dql:Doctrine\ORM\Query:private] => SELECT COUNT(r.id) FROM Game:Roll r INNER JOIN r.hand d WHERE d.userId = :userId AND d.active = 1

$qb->andWhere($qb->expr()->eq('d.active', false));

produces:

   [_dql:Doctrine\ORM\Query:private] => SELECT COUNT(r.id) FROM Game:Roll r INNER JOIN r.hand d WHERE d.userId = :userId AND d.active = 

and this query fails with an error:

[Syntax Error] line 0, col -1: Error: Expected Literal, got end of string.

As a workaround I am using 1 and 0 instead of "true" and "false"

Bug

Most helpful comment

$qb->andWhere($qb->expr()->eq('a.field', false)); - not ok ???

Generates following SQL string due to PHP's (string) cast semantics:

'... WHERE ... AND a.field = '

As mentioned above: use parameter binding.

All 8 comments

Comment created by @ocramius:

You are not using parameter binding. Expressions use string concatenation internally, so this outcome is actually expected. Instead, you should do following:

$qb->andWhere($qb->expr()->eq('a.field', ':key')); $qb->setParameter('key', false);

Issue was closed with resolution "Invalid"

Comment created by @Ocramius:

You are not using parameter binding. Expressions use string concatenation internally, so this outcome is actually expected. Instead, you should do following:

$qb->andWhere($qb->expr()->eq('a.field', ':key')); $qb->setParameter('key', false);

$qb->andWhere($qb->expr()->eq('a.field', true)); - ok
$qb->andWhere($qb->expr()->eq('a.field', 12)); - ok
$qb->andWhere($qb->expr()->eq('a.field', 'text')); - ok
and
$qb->andWhere($qb->expr()->eq('a.field', false)); - not ok ???

$qb->andWhere($qb->expr()->eq('a.field', false)); - not ok ???

Generates following SQL string due to PHP's (string) cast semantics:

'... WHERE ... AND a.field = '

As mentioned above: use parameter binding.

@Ocramius I feel like this is a bug because the very similar API of Criteria works with a boolean:

$criteria = Criteria::create()
    ->where(Criteria::expr()->eq('hidden', false))
    ->where(Criteria::expr()->eq('default', true));

Also, the query builder methods work with 'true' and 'false', whereas 'false' is interpreted as true with Criteria. It would be nice to fix these inconsistencies.

Possibly types to be refined: I don't think mixed is the correct type for the operands, given the implementation of Comparison:

https://github.com/doctrine/orm/blob/8c259ea5cb632dbb57001b2262048ae7fa52b102/lib/Doctrine/ORM/Query/Expr/Comparison.php#L71

Same problem with a call to $qb->set(), which uses ExprComparison internally.

I agree with @ocramius; adding

  • phpdoc argument type for ExprComparison
  • statically or dynamically type hinting the arguments
  • and therefore phpdoc argument type of all calling methods,
    would lead to a clear error, rather than a somehow non-understandable error at the time of DQL parsing.
Was this page helpful?
0 / 5 - 0 ratings