diff --git a/src/Query/Parser.php b/src/Query/Parser.php index 8ee44061467..33764941047 100644 --- a/src/Query/Parser.php +++ b/src/Query/Parser.php @@ -1554,7 +1554,7 @@ public function OrderByItem() assert($this->lexer->lookahead !== null); switch (true) { - case $this->isMathOperator($peek): + case $this->isMathOperator($peek) || $this->isMathOperator($glimpse): $expr = $this->SimpleArithmeticExpression(); break; diff --git a/tests/Doctrine/Tests/ORM/Functional/GH8011Test.php b/tests/Doctrine/Tests/ORM/Functional/GH8011Test.php new file mode 100644 index 00000000000..8dcec1cb70f --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Functional/GH8011Test.php @@ -0,0 +1,199 @@ +useModelSet('company'); + + parent::setUp(); + + $this->generateFixture(); + } + + public function testOrderWithArithmeticExpressionWithSingleValuedPathExpression(): void + { + $dql = 'SELECT p ' . + 'FROM Doctrine\Tests\Models\Company\CompanyEmployee p ' . + 'ORDER BY p.id + p.id ASC'; + + /** @var CompanyEmployee[] $result */ + $result = $this->_em->createQuery($dql)->getResult(); + + $this->assertEquals(2, count($result)); + $this->assertEquals('Benjamin E.', $result[0]->getName()); + $this->assertEquals('Guilherme B.', $result[1]->getName()); + } + + public function testOrderWithArithmeticExpressionWithLiteralAndSingleValuedPathExpression(): void + { + $dql = 'SELECT p ' . + 'FROM Doctrine\Tests\Models\Company\CompanyEmployee p ' . + 'ORDER BY 1 + p.id ASC'; + + /** @var CompanyEmployee[] $result */ + $result = $this->_em->createQuery($dql)->getResult(); + + $this->assertEquals(2, count($result)); + $this->assertEquals('Benjamin E.', $result[0]->getName()); + $this->assertEquals('Guilherme B.', $result[1]->getName()); + } + + public function testOrderWithArithmeticExpressionWithLiteralAndSingleValuedPathExpression2(): void + { + $dql = 'SELECT p ' . + 'FROM Doctrine\Tests\Models\Company\CompanyEmployee p ' . + 'ORDER BY ((1 + p.id)) ASC'; + + /** @var CompanyEmployee[] $result */ + $result = $this->_em->createQuery($dql)->getResult(); + + $this->assertEquals(2, count($result)); + $this->assertEquals('Benjamin E.', $result[0]->getName()); + $this->assertEquals('Guilherme B.', $result[1]->getName()); + } + + public function testOrderWithArithmeticExpressionWithSingleValuedPathExpressionAndLiteral(): void + { + $dql = 'SELECT p ' . + 'FROM Doctrine\Tests\Models\Company\CompanyEmployee p ' . + 'ORDER BY p.id + 1 ASC'; + + /** @var CompanyEmployee[] $result */ + $result = $this->_em->createQuery($dql)->getResult(); + + $this->assertEquals(2, count($result)); + $this->assertEquals('Benjamin E.', $result[0]->getName()); + $this->assertEquals('Guilherme B.', $result[1]->getName()); + } + + public function testOrderWithArithmeticExpressionWithResultVariableAndLiteral(): void + { + $dql = 'SELECT p, p.salary AS HIDDEN s ' . + 'FROM Doctrine\Tests\Models\Company\CompanyEmployee p ' . + 'ORDER BY s + 1 DESC'; + + /** @var CompanyEmployee[] $result */ + $result = $this->_em->createQuery($dql)->getResult(); + + $this->assertEquals(2, count($result)); + $this->assertEquals('Guilherme B.', $result[0]->getName()); + $this->assertEquals('Benjamin E.', $result[1]->getName()); + } + + public function testOrderWithArithmeticExpressionWithResultVariableAndLiteral2(): void + { + $dql = 'SELECT p, p.salary AS HIDDEN s ' . + 'FROM Doctrine\Tests\Models\Company\CompanyEmployee p ' . + 'ORDER BY ((s + 1)) DESC'; + + /** @var CompanyEmployee[] $result */ + $result = $this->_em->createQuery($dql)->getResult(); + + $this->assertEquals(2, count($result)); + $this->assertEquals('Guilherme B.', $result[0]->getName()); + $this->assertEquals('Benjamin E.', $result[1]->getName()); + } + + public function testOrderWithArithmeticExpressionWithLiteralAndResultVariable(): void + { + $dql = 'SELECT p, p.salary AS HIDDEN s ' . + 'FROM Doctrine\Tests\Models\Company\CompanyEmployee p ' . + 'ORDER BY 1 + s DESC'; + + /** @var CompanyEmployee[] $result */ + $result = $this->_em->createQuery($dql)->getResult(); + + $this->assertEquals(2, count($result)); + $this->assertEquals('Guilherme B.', $result[0]->getName()); + $this->assertEquals('Benjamin E.', $result[1]->getName()); + } + + public function testOrderWithArithmeticExpressionWithLiteralAndResultVariable2(): void + { + $dql = 'SELECT p, p.salary AS HIDDEN s ' . + 'FROM Doctrine\Tests\Models\Company\CompanyEmployee p ' . + 'ORDER BY ((1 + s)) DESC'; + + /** @var CompanyEmployee[] $result */ + $result = $this->_em->createQuery($dql)->getResult(); + + $this->assertEquals(2, count($result)); + $this->assertEquals('Guilherme B.', $result[0]->getName()); + $this->assertEquals('Benjamin E.', $result[1]->getName()); + } + + public function testOrderWithArithmeticExpressionWithResultVariableAndSingleValuedPathExpression(): void + { + $dql = 'SELECT p, p.salary AS HIDDEN s ' . + 'FROM Doctrine\Tests\Models\Company\CompanyEmployee p ' . + 'ORDER BY s + p.id DESC'; + + /** @var CompanyEmployee[] $result */ + $result = $this->_em->createQuery($dql)->getResult(); + + $this->assertEquals(2, count($result)); + $this->assertEquals('Guilherme B.', $result[0]->getName()); + $this->assertEquals('Benjamin E.', $result[1]->getName()); + } + + public function testOrderWithArithmeticExpressionWithResultVariableAndSingleValuedPathExpression2(): void + { + $dql = 'SELECT p, p.salary AS HIDDEN s ' . + 'FROM Doctrine\Tests\Models\Company\CompanyEmployee p ' . + 'ORDER BY ((s + p.id)) DESC'; + + /** @var CompanyEmployee[] $result */ + $result = $this->_em->createQuery($dql)->getResult(); + + $this->assertEquals(2, count($result)); + $this->assertEquals('Guilherme B.', $result[0]->getName()); + $this->assertEquals('Benjamin E.', $result[1]->getName()); + } + + public function testOrderWithArithmeticExpressionWithSingleValuedPathExpressionAndResultVariable(): void + { + $dql = 'SELECT p, p.salary AS HIDDEN s ' . + 'FROM Doctrine\Tests\Models\Company\CompanyEmployee p ' . + 'ORDER BY p.id + s DESC'; + + /** @var CompanyEmployee[] $result */ + $result = $this->_em->createQuery($dql)->getResult(); + + $this->assertEquals(2, count($result)); + $this->assertEquals('Guilherme B.', $result[0]->getName()); + $this->assertEquals('Benjamin E.', $result[1]->getName()); + } + + public function generateFixture(): void + { + $person1 = new CompanyEmployee(); + $person1->setName('Benjamin E.'); + $person1->setDepartment('IT'); + $person1->setSalary(200000); + + $person2 = new CompanyEmployee(); + $person2->setName('Guilherme B.'); + $person2->setDepartment('IT2'); + $person2->setSalary(400000); + + $this->_em->persist($person1); + $this->_em->persist($person2); + $this->_em->flush(); + $this->_em->clear(); + } +}