diff --git a/lib/Doctrine/ORM/AbstractQuery.php b/lib/Doctrine/ORM/AbstractQuery.php index ba013bbbb..10af39053 100644 --- a/lib/Doctrine/ORM/AbstractQuery.php +++ b/lib/Doctrine/ORM/AbstractQuery.php @@ -321,14 +321,14 @@ abstract class AbstractQuery public function getParameter($key) { $filteredParameters = $this->parameters->filter( - function ($parameter) use ($key) - { - // Must not be identical because of string to integer conversion - return ($key == $parameter->getName()); + function (Query\Parameter $parameter) use ($key) : bool { + $parameterName = $parameter->getName(); + + return $key === $parameterName || (string) $key === (string) $parameterName; } ); - return count($filteredParameters) ? $filteredParameters->first() : null; + return ! $filteredParameters->isEmpty() ? $filteredParameters->first() : null; } /** @@ -369,17 +369,10 @@ abstract class AbstractQuery */ public function setParameter($key, $value, $type = null) { - $filteredParameters = $this->parameters->filter( - function ($parameter) use ($key) - { - // Must not be identical because of string to integer conversion - return ($key == $parameter->getName()); - } - ); + $existingParameter = $this->getParameter($key); - if (count($filteredParameters)) { - $parameter = $filteredParameters->first(); - $parameter->setValue($value, $type); + if ($existingParameter !== null) { + $existingParameter->setValue($value, $type); return $this; } diff --git a/tests/Doctrine/Tests/ORM/Query/QueryTest.php b/tests/Doctrine/Tests/ORM/Query/QueryTest.php index 5a2a295fe..354586f15 100644 --- a/tests/Doctrine/Tests/ORM/Query/QueryTest.php +++ b/tests/Doctrine/Tests/ORM/Query/QueryTest.php @@ -12,6 +12,7 @@ use Doctrine\ORM\Query\QueryException; use Doctrine\Tests\Mocks\DriverConnectionMock; use Doctrine\Tests\Mocks\StatementArrayMock; use Doctrine\Tests\Models\CMS\CmsAddress; +use Doctrine\Tests\Models\CMS\CmsUser; use Doctrine\Tests\OrmTestCase; class QueryTest extends OrmTestCase @@ -303,4 +304,66 @@ class QueryTest extends OrmTestCase $this->expectExceptionMessage('Subquery'); $query->getSQL(); } + + /** + * @group 6699 + */ + public function testGetParameterTypeJuggling() : void + { + $query = $this->_em->createQuery('select u from ' . CmsUser::class . ' u where u.id = ?0'); + + $query->setParameter(0, 0); + + self::assertCount(1, $query->getParameters()); + self::assertSame(0, $query->getParameter(0)->getValue()); + self::assertSame(0, $query->getParameter('0')->getValue()); + } + + /** + * @group 6699 + */ + public function testSetParameterWithNameZeroIsNotOverridden() : void + { + $query = $this->_em->createQuery('select u from ' . CmsUser::class . ' u where u.id != ?0 and u.username = :name'); + + $query->setParameter(0, 0); + $query->setParameter('name', 'Doctrine'); + + self::assertCount(2, $query->getParameters()); + self::assertSame(0, $query->getParameter('0')->getValue()); + self::assertSame('Doctrine', $query->getParameter('name')->getValue()); + } + + /** + * @group 6699 + */ + public function testSetParameterWithNameZeroDoesNotOverrideAnotherParameter() : void + { + $query = $this->_em->createQuery('select u from ' . CmsUser::class . ' u where u.id != ?0 and u.username = :name'); + + $query->setParameter('name', 'Doctrine'); + $query->setParameter(0, 0); + + self::assertCount(2, $query->getParameters()); + self::assertSame(0, $query->getParameter(0)->getValue()); + self::assertSame('Doctrine', $query->getParameter('name')->getValue()); + } + + /** + * @group 6699 + */ + public function testSetParameterWithTypeJugglingWorks() : void + { + $query = $this->_em->createQuery('select u from ' . CmsUser::class . ' u where u.id != ?0 and u.username = :name'); + + $query->setParameter('0', 1); + $query->setParameter('name', 'Doctrine'); + $query->setParameter(0, 2); + $query->setParameter('0', 3); + + self::assertCount(2, $query->getParameters()); + self::assertSame(3, $query->getParameter(0)->getValue()); + self::assertSame(3, $query->getParameter('0')->getValue()); + self::assertSame('Doctrine', $query->getParameter('name')->getValue()); + } }