From b0806469d5bd938f9ab4bb01eb33fba98638de83 Mon Sep 17 00:00:00 2001 From: Stefan Gehrig Date: Mon, 3 Feb 2020 13:39:28 +0100 Subject: [PATCH 1/6] adds test case for GH issue #8011 --- .../Tests/ORM/Functional/GH8011Test.php | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 tests/Doctrine/Tests/ORM/Functional/GH8011Test.php diff --git a/tests/Doctrine/Tests/ORM/Functional/GH8011Test.php b/tests/Doctrine/Tests/ORM/Functional/GH8011Test.php new file mode 100644 index 00000000000..0aa276c7660 --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Functional/GH8011Test.php @@ -0,0 +1,54 @@ +useModelSet('company'); + parent::setUp(); + + $this->generateFixture(); + } + + public function testOrderWithArithmeticExpression() + { + $dql = 'SELECT p, ' . + '(SELECT SUM(p2.salary) FROM Doctrine\Tests\Models\Company\CompanyEmployee p2 WHERE p2.department = p.department) AS HIDDEN s ' . + 'FROM Doctrine\Tests\Models\Company\CompanyEmployee p ' . + 'ORDER BY s + s DESC'; + + $result = $this->_em->createQuery($dql)->getResult(); + + $this->assertEquals(2, count($result)); + } + + public function generateFixture() + { + $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(); + } +} From f4fdcbcdcb8f153d29e850ad5d46d51c4f7c9331 Mon Sep 17 00:00:00 2001 From: Stefan Gehrig Date: Tue, 4 Feb 2020 09:07:39 +0100 Subject: [PATCH 2/6] adds more test cases --- .../Tests/ORM/Functional/GH8011Test.php | 94 ++++++++++++++++++- 1 file changed, 90 insertions(+), 4 deletions(-) diff --git a/tests/Doctrine/Tests/ORM/Functional/GH8011Test.php b/tests/Doctrine/Tests/ORM/Functional/GH8011Test.php index 0aa276c7660..c1fecfb8473 100644 --- a/tests/Doctrine/Tests/ORM/Functional/GH8011Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/GH8011Test.php @@ -22,16 +22,102 @@ protected function setUp() $this->generateFixture(); } - public function testOrderWithArithmeticExpression() + public function testOrderWithArithmeticExpressionWithSingleValuedPathExpression() { - $dql = 'SELECT p, ' . - '(SELECT SUM(p2.salary) FROM Doctrine\Tests\Models\Company\CompanyEmployee p2 WHERE p2.department = p.department) AS HIDDEN s ' . + $dql = 'SELECT p ' . 'FROM Doctrine\Tests\Models\Company\CompanyEmployee p ' . - 'ORDER BY s + s DESC'; + '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() + { + $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() + { + $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() + { + $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() + { + $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() + { + $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() + { + $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() From c429262f02503144c2ba1ebceb1fe88793c76e85 Mon Sep 17 00:00:00 2001 From: Stefan Gehrig Date: Tue, 7 Apr 2020 11:52:20 +0200 Subject: [PATCH 3/6] adds detection of literals/result variables at the beginning of an order by item with arithmetic expression Not sure whether this covers the whole problem regarding complex expressions in order by items but it fixes the provided test cases --- src/Query/Parser.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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; From 0e4786dfa874c1c0b39dbf2e775eec348813fc2d Mon Sep 17 00:00:00 2001 From: Stefan Gehrig Date: Wed, 8 Apr 2020 08:26:28 +0200 Subject: [PATCH 4/6] adds testcases for order by items enclosed in ((...)) (double brackets - just one bracket does not work) just one bracket (...) gives Exception : [Doctrine\ORM\Query\QueryException] [Syntax Error] line 0, col xx: Error: Expected Doctrine\ORM\Query\Lexer::T_IDENTIFIER, got '(' --- .../Tests/ORM/Functional/GH8011Test.php | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/tests/Doctrine/Tests/ORM/Functional/GH8011Test.php b/tests/Doctrine/Tests/ORM/Functional/GH8011Test.php index c1fecfb8473..e48261f2e85 100644 --- a/tests/Doctrine/Tests/ORM/Functional/GH8011Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/GH8011Test.php @@ -50,6 +50,20 @@ public function testOrderWithArithmeticExpressionWithLiteralAndSingleValuedPathE $this->assertEquals('Guilherme B.', $result[1]->getName()); } + public function testOrderWithArithmeticExpressionWithLiteralAndSingleValuedPathExpression2() + { + $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() { $dql = 'SELECT p ' . @@ -78,6 +92,20 @@ public function testOrderWithArithmeticExpressionWithResultVariableAndLiteral() $this->assertEquals('Benjamin E.', $result[1]->getName()); } + public function testOrderWithArithmeticExpressionWithResultVariableAndLiteral2() + { + $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() { $dql = 'SELECT p, p.salary AS HIDDEN s ' . @@ -92,6 +120,20 @@ public function testOrderWithArithmeticExpressionWithLiteralAndResultVariable() $this->assertEquals('Benjamin E.', $result[1]->getName()); } + public function testOrderWithArithmeticExpressionWithLiteralAndResultVariable2() + { + $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() { $dql = 'SELECT p, p.salary AS HIDDEN s ' . @@ -106,6 +148,20 @@ public function testOrderWithArithmeticExpressionWithResultVariableAndSingleValu $this->assertEquals('Benjamin E.', $result[1]->getName()); } + public function testOrderWithArithmeticExpressionWithResultVariableAndSingleValuedPathExpression2() + { + $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() { $dql = 'SELECT p, p.salary AS HIDDEN s ' . From d809fed52ab0f82a691bd51be2f0dff59170379a Mon Sep 17 00:00:00 2001 From: Stefan Gehrig Date: Tue, 7 Jan 2025 08:48:42 +0100 Subject: [PATCH 5/6] fixes code sniffer complaints Signed-off-by: Stefan Gehrig --- .../Tests/ORM/Functional/GH8011Test.php | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/tests/Doctrine/Tests/ORM/Functional/GH8011Test.php b/tests/Doctrine/Tests/ORM/Functional/GH8011Test.php index e48261f2e85..6726c54b44b 100644 --- a/tests/Doctrine/Tests/ORM/Functional/GH8011Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/GH8011Test.php @@ -7,6 +7,8 @@ use Doctrine\Tests\Models\Company\CompanyEmployee; use Doctrine\Tests\OrmFunctionalTestCase; +use function count; + /** * Functional tests for ordering with arithmetic expression. * @@ -14,15 +16,16 @@ */ class GH8011Test extends OrmFunctionalTestCase { - protected function setUp() + protected function setUp(): void { $this->useModelSet('company'); + parent::setUp(); $this->generateFixture(); } - public function testOrderWithArithmeticExpressionWithSingleValuedPathExpression() + public function testOrderWithArithmeticExpressionWithSingleValuedPathExpression(): void { $dql = 'SELECT p ' . 'FROM Doctrine\Tests\Models\Company\CompanyEmployee p ' . @@ -36,7 +39,7 @@ public function testOrderWithArithmeticExpressionWithSingleValuedPathExpression( $this->assertEquals('Guilherme B.', $result[1]->getName()); } - public function testOrderWithArithmeticExpressionWithLiteralAndSingleValuedPathExpression() + public function testOrderWithArithmeticExpressionWithLiteralAndSingleValuedPathExpression(): void { $dql = 'SELECT p ' . 'FROM Doctrine\Tests\Models\Company\CompanyEmployee p ' . @@ -50,7 +53,7 @@ public function testOrderWithArithmeticExpressionWithLiteralAndSingleValuedPathE $this->assertEquals('Guilherme B.', $result[1]->getName()); } - public function testOrderWithArithmeticExpressionWithLiteralAndSingleValuedPathExpression2() + public function testOrderWithArithmeticExpressionWithLiteralAndSingleValuedPathExpression2(): void { $dql = 'SELECT p ' . 'FROM Doctrine\Tests\Models\Company\CompanyEmployee p ' . @@ -64,7 +67,7 @@ public function testOrderWithArithmeticExpressionWithLiteralAndSingleValuedPathE $this->assertEquals('Guilherme B.', $result[1]->getName()); } - public function testOrderWithArithmeticExpressionWithSingleValuedPathExpressionAndLiteral() + public function testOrderWithArithmeticExpressionWithSingleValuedPathExpressionAndLiteral(): void { $dql = 'SELECT p ' . 'FROM Doctrine\Tests\Models\Company\CompanyEmployee p ' . @@ -78,7 +81,7 @@ public function testOrderWithArithmeticExpressionWithSingleValuedPathExpressionA $this->assertEquals('Guilherme B.', $result[1]->getName()); } - public function testOrderWithArithmeticExpressionWithResultVariableAndLiteral() + public function testOrderWithArithmeticExpressionWithResultVariableAndLiteral(): void { $dql = 'SELECT p, p.salary AS HIDDEN s ' . 'FROM Doctrine\Tests\Models\Company\CompanyEmployee p ' . @@ -92,7 +95,7 @@ public function testOrderWithArithmeticExpressionWithResultVariableAndLiteral() $this->assertEquals('Benjamin E.', $result[1]->getName()); } - public function testOrderWithArithmeticExpressionWithResultVariableAndLiteral2() + public function testOrderWithArithmeticExpressionWithResultVariableAndLiteral2(): void { $dql = 'SELECT p, p.salary AS HIDDEN s ' . 'FROM Doctrine\Tests\Models\Company\CompanyEmployee p ' . @@ -106,7 +109,7 @@ public function testOrderWithArithmeticExpressionWithResultVariableAndLiteral2() $this->assertEquals('Benjamin E.', $result[1]->getName()); } - public function testOrderWithArithmeticExpressionWithLiteralAndResultVariable() + public function testOrderWithArithmeticExpressionWithLiteralAndResultVariable(): void { $dql = 'SELECT p, p.salary AS HIDDEN s ' . 'FROM Doctrine\Tests\Models\Company\CompanyEmployee p ' . @@ -120,7 +123,7 @@ public function testOrderWithArithmeticExpressionWithLiteralAndResultVariable() $this->assertEquals('Benjamin E.', $result[1]->getName()); } - public function testOrderWithArithmeticExpressionWithLiteralAndResultVariable2() + public function testOrderWithArithmeticExpressionWithLiteralAndResultVariable2(): void { $dql = 'SELECT p, p.salary AS HIDDEN s ' . 'FROM Doctrine\Tests\Models\Company\CompanyEmployee p ' . @@ -134,7 +137,7 @@ public function testOrderWithArithmeticExpressionWithLiteralAndResultVariable2() $this->assertEquals('Benjamin E.', $result[1]->getName()); } - public function testOrderWithArithmeticExpressionWithResultVariableAndSingleValuedPathExpression() + public function testOrderWithArithmeticExpressionWithResultVariableAndSingleValuedPathExpression(): void { $dql = 'SELECT p, p.salary AS HIDDEN s ' . 'FROM Doctrine\Tests\Models\Company\CompanyEmployee p ' . @@ -148,7 +151,7 @@ public function testOrderWithArithmeticExpressionWithResultVariableAndSingleValu $this->assertEquals('Benjamin E.', $result[1]->getName()); } - public function testOrderWithArithmeticExpressionWithResultVariableAndSingleValuedPathExpression2() + public function testOrderWithArithmeticExpressionWithResultVariableAndSingleValuedPathExpression2(): void { $dql = 'SELECT p, p.salary AS HIDDEN s ' . 'FROM Doctrine\Tests\Models\Company\CompanyEmployee p ' . @@ -162,7 +165,7 @@ public function testOrderWithArithmeticExpressionWithResultVariableAndSingleValu $this->assertEquals('Benjamin E.', $result[1]->getName()); } - public function testOrderWithArithmeticExpressionWithSingleValuedPathExpressionAndResultVariable() + public function testOrderWithArithmeticExpressionWithSingleValuedPathExpressionAndResultVariable(): void { $dql = 'SELECT p, p.salary AS HIDDEN s ' . 'FROM Doctrine\Tests\Models\Company\CompanyEmployee p ' . @@ -176,7 +179,7 @@ public function testOrderWithArithmeticExpressionWithSingleValuedPathExpressionA $this->assertEquals('Benjamin E.', $result[1]->getName()); } - public function generateFixture() + public function generateFixture(): void { $person1 = new CompanyEmployee(); $person1->setName('Benjamin E.'); From ec6d1b9f72bfcc6c2e585e3e4fad8c6409f784ab Mon Sep 17 00:00:00 2001 From: Stefan Gehrig Date: Tue, 7 Jan 2025 08:51:19 +0100 Subject: [PATCH 6/6] fixes whitespace Signed-off-by: Stefan Gehrig --- tests/Doctrine/Tests/ORM/Functional/GH8011Test.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Doctrine/Tests/ORM/Functional/GH8011Test.php b/tests/Doctrine/Tests/ORM/Functional/GH8011Test.php index 6726c54b44b..8dcec1cb70f 100644 --- a/tests/Doctrine/Tests/ORM/Functional/GH8011Test.php +++ b/tests/Doctrine/Tests/ORM/Functional/GH8011Test.php @@ -19,7 +19,7 @@ class GH8011Test extends OrmFunctionalTestCase protected function setUp(): void { $this->useModelSet('company'); - + parent::setUp(); $this->generateFixture();