From 66a842c143d669707de5eb3149c2ac3143dd6977 Mon Sep 17 00:00:00 2001 From: Alexander Date: Sun, 26 May 2013 07:41:01 +0200 Subject: [PATCH] [DDC-2471] Fix EQ/NEQ null handling of criteria --- .../ORM/Persisters/BasicEntityPersister.php | 10 +++- .../ORM/Persisters/SqlValueVisitor.php | 9 ++- .../EntityRepositoryCriteriaTest.php | 56 +++++++++++++++++++ .../BasicEntityPersisterTypeValueSqlTest.php | 14 ++++- 4 files changed, 86 insertions(+), 3 deletions(-) diff --git a/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php b/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php index 8f921f2b8..f101fda13 100644 --- a/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php +++ b/lib/Doctrine/ORM/Persisters/BasicEntityPersister.php @@ -85,7 +85,7 @@ class BasicEntityPersister */ static private $comparisonMap = array( Comparison::EQ => '= %s', - Comparison::IS => 'IS %s', + Comparison::IS => '= %s', Comparison::NEQ => '!= %s', Comparison::GT => '> %s', Comparison::GTE => '>= %s', @@ -1608,6 +1608,14 @@ class BasicEntityPersister } if ($comparison !== null) { + + // special case null value handling + if (($comparison === Comparison::EQ || $comparison === Comparison::IS) && $value === null) { + return $condition . ' IS NULL'; + } else if ($comparison === Comparison::NEQ && $value === null) { + return $condition . ' IS NOT NULL'; + } + return $condition . ' ' . sprintf(self::$comparisonMap[$comparison], $placeholder); } diff --git a/lib/Doctrine/ORM/Persisters/SqlValueVisitor.php b/lib/Doctrine/ORM/Persisters/SqlValueVisitor.php index 79e5150e5..0e680ad07 100644 --- a/lib/Doctrine/ORM/Persisters/SqlValueVisitor.php +++ b/lib/Doctrine/ORM/Persisters/SqlValueVisitor.php @@ -52,7 +52,14 @@ class SqlValueVisitor extends ExpressionVisitor { $value = $this->getValueFromComparison($comparison); $field = $comparison->getField(); - + $operator = $comparison->getOperator(); + + if (($operator === Comparison::EQ || $operator === Comparison::IS) && $value === null) { + return; + } else if ($operator === Comparison::NEQ && $value === null) { + return; + } + $this->values[] = $value; $this->types[] = array($field, $value); } diff --git a/tests/Doctrine/Tests/ORM/Functional/EntityRepositoryCriteriaTest.php b/tests/Doctrine/Tests/ORM/Functional/EntityRepositoryCriteriaTest.php index 8631e529d..83c26b432 100644 --- a/tests/Doctrine/Tests/ORM/Functional/EntityRepositoryCriteriaTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/EntityRepositoryCriteriaTest.php @@ -84,4 +84,60 @@ class EntityRepositoryCriteriaTest extends \Doctrine\Tests\OrmFunctionalTestCase $this->assertEquals(2, count($dates)); } + + private function loadNullFieldFixtures() + { + $today = new DateTimeModel(); + $today->datetime = + $today->date = + new \DateTime('today'); + + $this->_em->persist($today); + + $tomorrow = new DateTimeModel(); + $tomorrow->datetime = + $tomorrow->date = + $tomorrow->time = + new \DateTime('tomorrow'); + $this->_em->persist($tomorrow); + + $this->_em->flush(); + $this->_em->clear(); + } + + public function testIsNullComparison() + { + $this->loadNullFieldFixtures(); + $repository = $this->_em->getRepository('Doctrine\Tests\Models\Generic\DateTimeModel'); + + $dates = $repository->matching(new Criteria( + Criteria::expr()->isNull('time') + )); + + $this->assertEquals(1, count($dates)); + } + + public function testEqNullComparison() + { + $this->loadNullFieldFixtures(); + $repository = $this->_em->getRepository('Doctrine\Tests\Models\Generic\DateTimeModel'); + + $dates = $repository->matching(new Criteria( + Criteria::expr()->eq('time', null) + )); + + $this->assertEquals(1, count($dates)); + } + + public function testNotEqNullComparison() + { + $this->loadNullFieldFixtures(); + $repository = $this->_em->getRepository('Doctrine\Tests\Models\Generic\DateTimeModel'); + + $dates = $repository->matching(new Criteria( + Criteria::expr()->neq('time', null) + )); + + $this->assertEquals(1, count($dates)); + } } diff --git a/tests/Doctrine/Tests/ORM/Persisters/BasicEntityPersisterTypeValueSqlTest.php b/tests/Doctrine/Tests/ORM/Persisters/BasicEntityPersisterTypeValueSqlTest.php index 018044c03..668ff13a0 100644 --- a/tests/Doctrine/Tests/ORM/Persisters/BasicEntityPersisterTypeValueSqlTest.php +++ b/tests/Doctrine/Tests/ORM/Persisters/BasicEntityPersisterTypeValueSqlTest.php @@ -96,6 +96,18 @@ class BasicEntityPersisterTypeValueSqlTest extends \Doctrine\Tests\OrmTestCase public function testSelectConditionStatementIsNull() { $statement = $this->_persister->getSelectConditionStatementSQL('test', null, array(), Comparison::IS); - $this->assertEquals('test IS ?', $statement); + $this->assertEquals('test IS NULL', $statement); + } + + public function testSelectConditionStatementEqNull() + { + $statement = $this->_persister->getSelectConditionStatementSQL('test', null, array(), Comparison::EQ); + $this->assertEquals('test IS NULL', $statement); + } + + public function testSelectConditionStatementNeqNull() + { + $statement = $this->_persister->getSelectConditionStatementSQL('test', null, array(), Comparison::NEQ); + $this->assertEquals('test IS NOT NULL', $statement); } }