diff --git a/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php b/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php index db1dfa482..63c20d56d 100644 --- a/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php +++ b/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php @@ -1541,7 +1541,13 @@ class BasicEntityPersister implements EntityPersister } if (is_array($value)) { - return sprintf('%s IN (%s)' , $condition, $placeholder); + $in = sprintf('%s IN (%s)' , $condition, $placeholder); + + if (false !== array_search(null, $value, true)) { + return sprintf('(%s OR %s IS NULL)' , $in, $condition); + } + + return $in; } if ($value === null) { diff --git a/tests/Doctrine/Tests/ORM/Functional/EntityRepositoryTest.php b/tests/Doctrine/Tests/ORM/Functional/EntityRepositoryTest.php index 502eda0ec..f20ba88e5 100644 --- a/tests/Doctrine/Tests/ORM/Functional/EntityRepositoryTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/EntityRepositoryTest.php @@ -928,5 +928,89 @@ class EntityRepositoryTest extends \Doctrine\Tests\OrmFunctionalTestCase $repository = $this->_em->getRepository('Doctrine\Tests\Models\CMS\CmsUser'); $repository->find(array('username = ?; DELETE FROM cms_users; SELECT 1 WHERE 1' => 'test', 'id' => 1)); } + + /** + * @group DDC-3056 + */ + public function testFindByNullValueInInCondition() + { + $user1 = new CmsUser(); + $user2 = new CmsUser(); + + $user1->username = 'ocramius'; + $user1->name = 'Marco'; + $user2->status = null; + $user2->username = 'deeky666'; + $user2->name = 'Steve'; + $user2->status = 'dbal maintainer'; + + $this->_em->persist($user1); + $this->_em->persist($user2); + $this->_em->flush(); + + $users = $this->_em->getRepository('Doctrine\Tests\Models\CMS\CmsUser')->findBy(array('status' => array(null))); + + $this->assertCount(1, $users); + $this->assertSame($user1, reset($users)); + } + + /** + * @group DDC-3056 + */ + public function testFindByNullValueInMultipleInCriteriaValues() + { + $user1 = new CmsUser(); + $user2 = new CmsUser(); + + $user1->username = 'ocramius'; + $user1->name = 'Marco'; + $user2->status = null; + $user2->username = 'deeky666'; + $user2->name = 'Steve'; + $user2->status = 'dbal maintainer'; + + $this->_em->persist($user1); + $this->_em->persist($user2); + $this->_em->flush(); + + $users = $this + ->_em + ->getRepository('Doctrine\Tests\Models\CMS\CmsUser') + ->findBy(array('status' => array('foo', null))); + + $this->assertCount(1, $users); + $this->assertSame($user1, reset($users)); + } + + /** + * @group DDC-3056 + */ + public function testFindMultipleByNullValueInMultipleInCriteriaValues() + { + $user1 = new CmsUser(); + $user2 = new CmsUser(); + + $user1->username = 'ocramius'; + $user1->name = 'Marco'; + $user2->status = null; + $user2->username = 'deeky666'; + $user2->name = 'Steve'; + $user2->status = 'dbal maintainer'; + + $this->_em->persist($user1); + $this->_em->persist($user2); + $this->_em->flush(); + + $users = $this + ->_em + ->getRepository('Doctrine\Tests\Models\CMS\CmsUser') + ->findBy(array('status' => array('dbal maintainer', null))); + + $this->assertCount(2, $users); + + foreach ($users as $user) { + $this->assertTrue(in_array($user, array($user1, $user2))); + } + } } diff --git a/tests/Doctrine/Tests/ORM/Persisters/BasicEntityPersisterTypeValueSqlTest.php b/tests/Doctrine/Tests/ORM/Persisters/BasicEntityPersisterTypeValueSqlTest.php index 653ec2d52..bbe8875e3 100644 --- a/tests/Doctrine/Tests/ORM/Persisters/BasicEntityPersisterTypeValueSqlTest.php +++ b/tests/Doctrine/Tests/ORM/Persisters/BasicEntityPersisterTypeValueSqlTest.php @@ -11,9 +11,19 @@ use Doctrine\Common\Collections\Expr\Comparison; class BasicEntityPersisterTypeValueSqlTest extends \Doctrine\Tests\OrmTestCase { + /** + * @var BasicEntityPersister + */ protected $_persister; + + /** + * @var \Doctrine\ORM\EntityManager + */ protected $_em; + /** + * {@inheritDoc} + */ protected function setUp() { parent::setUp(); @@ -108,4 +118,25 @@ class BasicEntityPersisterTypeValueSqlTest extends \Doctrine\Tests\OrmTestCase $statement = $this->_persister->getSelectConditionStatementSQL('test', null, array(), Comparison::NEQ); $this->assertEquals('test IS NOT NULL', $statement); } + + /** + * @group DDC-3056 + */ + public function testSelectConditionStatementWithMultipleValuesContainingNull() + { + $this->assertEquals( + '(t0.id IN (?) OR t0.id IS NULL)', + $this->_persister->getSelectConditionStatementSQL('id', array(null)) + ); + + $this->assertEquals( + '(t0.id IN (?) OR t0.id IS NULL)', + $this->_persister->getSelectConditionStatementSQL('id', array(null, 123)) + ); + + $this->assertEquals( + '(t0.id IN (?) OR t0.id IS NULL)', + $this->_persister->getSelectConditionStatementSQL('id', array(123, null)) + ); + } }