Skip to content

Commit b4ca0cd

Browse files
authored
Merge pull request #12024 from greg0ire/3.4.x
Merge 2.20.x up into 3.4.x
2 parents 92e2f6d + a49c1be commit b4ca0cd

File tree

2 files changed

+239
-1
lines changed

2 files changed

+239
-1
lines changed

src/Query/Parser.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1464,7 +1464,7 @@ public function OrderByItem(): AST\OrderByItem
14641464

14651465
assert($this->lexer->lookahead !== null);
14661466
$expr = match (true) {
1467-
$this->isMathOperator($peek) => $this->SimpleArithmeticExpression(),
1467+
$this->isMathOperator($peek) || $this->isMathOperator($glimpse) => $this->SimpleArithmeticExpression(),
14681468
$glimpse !== null && $glimpse->type === TokenType::T_DOT => $this->SingleValuedPathExpression(),
14691469
$this->lexer->peek() && $this->isMathOperator($this->peekBeyondClosingParenthesis()) => $this->ScalarExpression(),
14701470
$this->lexer->lookahead->type === TokenType::T_CASE => $this->CaseExpression(),
Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Doctrine\Tests\ORM\Functional;
6+
7+
use Doctrine\DBAL\Platforms\PostgreSQLPlatform;
8+
use Doctrine\Tests\Models\Company\CompanyEmployee;
9+
use Doctrine\Tests\OrmFunctionalTestCase;
10+
use PHPUnit\Framework\Attributes\Group;
11+
12+
use function count;
13+
14+
/**
15+
* Functional tests for ordering with arithmetic expression.
16+
*/
17+
#[Group('GH8011')]
18+
class GH8011Test extends OrmFunctionalTestCase
19+
{
20+
protected function setUp(): void
21+
{
22+
$this->useModelSet('company');
23+
24+
parent::setUp();
25+
26+
$this->generateFixture();
27+
}
28+
29+
private function skipIfPostgres(string $test): void
30+
{
31+
$platform = $this->_em->getConnection()->getDatabasePlatform();
32+
if ($platform instanceof PostgreSQLPlatform) {
33+
self::markTestSkipped(
34+
'The ' . $test . ' test does not work on postgresql (see https://github.com/doctrine/orm/pull/8012).',
35+
);
36+
}
37+
}
38+
39+
public function testOrderWithArithmeticExpressionWithSingleValuedPathExpression(): void
40+
{
41+
$dql = 'SELECT p ' .
42+
'FROM Doctrine\Tests\Models\Company\CompanyEmployee p ' .
43+
'ORDER BY p.id + p.id ASC';
44+
45+
/** @var CompanyEmployee[] $result */
46+
$result = $this->_em->createQuery($dql)->getResult();
47+
48+
$this->assertEquals(2, count($result));
49+
$this->assertEquals('Benjamin E.', $result[0]->getName());
50+
$this->assertEquals('Guilherme B.', $result[1]->getName());
51+
}
52+
53+
public function testOrderWithArithmeticExpressionWithLiteralAndSingleValuedPathExpression(): void
54+
{
55+
$dql = 'SELECT p ' .
56+
'FROM Doctrine\Tests\Models\Company\CompanyEmployee p ' .
57+
'ORDER BY 1 + p.id ASC';
58+
59+
/** @var CompanyEmployee[] $result */
60+
$result = $this->_em->createQuery($dql)->getResult();
61+
62+
$this->assertEquals(2, count($result));
63+
$this->assertEquals('Benjamin E.', $result[0]->getName());
64+
$this->assertEquals('Guilherme B.', $result[1]->getName());
65+
}
66+
67+
public function testOrderWithArithmeticExpressionWithLiteralAndSingleValuedPathExpression2(): void
68+
{
69+
$dql = 'SELECT p ' .
70+
'FROM Doctrine\Tests\Models\Company\CompanyEmployee p ' .
71+
'ORDER BY ((1 + p.id)) ASC';
72+
73+
/** @var CompanyEmployee[] $result */
74+
$result = $this->_em->createQuery($dql)->getResult();
75+
76+
$this->assertEquals(2, count($result));
77+
$this->assertEquals('Benjamin E.', $result[0]->getName());
78+
$this->assertEquals('Guilherme B.', $result[1]->getName());
79+
}
80+
81+
public function testOrderWithArithmeticExpressionWithSingleValuedPathExpressionAndLiteral(): void
82+
{
83+
$dql = 'SELECT p ' .
84+
'FROM Doctrine\Tests\Models\Company\CompanyEmployee p ' .
85+
'ORDER BY p.id + 1 ASC';
86+
87+
/** @var CompanyEmployee[] $result */
88+
$result = $this->_em->createQuery($dql)->getResult();
89+
90+
$this->assertEquals(2, count($result));
91+
$this->assertEquals('Benjamin E.', $result[0]->getName());
92+
$this->assertEquals('Guilherme B.', $result[1]->getName());
93+
}
94+
95+
public function testOrderWithArithmeticExpressionWithResultVariableAndLiteral(): void
96+
{
97+
$this->skipIfPostgres(__FUNCTION__);
98+
99+
$dql = 'SELECT p, p.salary AS HIDDEN s ' .
100+
'FROM Doctrine\Tests\Models\Company\CompanyEmployee p ' .
101+
'ORDER BY s + 1 DESC';
102+
103+
/** @var CompanyEmployee[] $result */
104+
$result = $this->_em->createQuery($dql)->getResult();
105+
106+
$this->assertEquals(2, count($result));
107+
$this->assertEquals('Guilherme B.', $result[0]->getName());
108+
$this->assertEquals('Benjamin E.', $result[1]->getName());
109+
}
110+
111+
public function testOrderWithArithmeticExpressionWithResultVariableAndLiteral2(): void
112+
{
113+
$this->skipIfPostgres(__FUNCTION__);
114+
115+
$dql = 'SELECT p, p.salary AS HIDDEN s ' .
116+
'FROM Doctrine\Tests\Models\Company\CompanyEmployee p ' .
117+
'ORDER BY ((s + 1)) DESC';
118+
119+
/** @var CompanyEmployee[] $result */
120+
$result = $this->_em->createQuery($dql)->getResult();
121+
122+
$this->assertEquals(2, count($result));
123+
$this->assertEquals('Guilherme B.', $result[0]->getName());
124+
$this->assertEquals('Benjamin E.', $result[1]->getName());
125+
}
126+
127+
public function testOrderWithArithmeticExpressionWithLiteralAndResultVariable(): void
128+
{
129+
$this->skipIfPostgres(__FUNCTION__);
130+
131+
$dql = 'SELECT p, p.salary AS HIDDEN s ' .
132+
'FROM Doctrine\Tests\Models\Company\CompanyEmployee p ' .
133+
'ORDER BY 1 + s DESC';
134+
135+
/** @var CompanyEmployee[] $result */
136+
$result = $this->_em->createQuery($dql)->getResult();
137+
138+
$this->assertEquals(2, count($result));
139+
$this->assertEquals('Guilherme B.', $result[0]->getName());
140+
$this->assertEquals('Benjamin E.', $result[1]->getName());
141+
}
142+
143+
public function testOrderWithArithmeticExpressionWithLiteralAndResultVariable2(): void
144+
{
145+
$this->skipIfPostgres(__FUNCTION__);
146+
147+
$dql = 'SELECT p, p.salary AS HIDDEN s ' .
148+
'FROM Doctrine\Tests\Models\Company\CompanyEmployee p ' .
149+
'ORDER BY ((1 + s)) DESC';
150+
151+
/** @var CompanyEmployee[] $result */
152+
$result = $this->_em->createQuery($dql)->getResult();
153+
154+
$this->assertEquals(2, count($result));
155+
$this->assertEquals('Guilherme B.', $result[0]->getName());
156+
$this->assertEquals('Benjamin E.', $result[1]->getName());
157+
}
158+
159+
public function testOrderWithArithmeticExpressionWithResultVariableAndSingleValuedPathExpression(): void
160+
{
161+
$this->skipIfPostgres(__FUNCTION__);
162+
163+
$dql = 'SELECT p, p.salary AS HIDDEN s ' .
164+
'FROM Doctrine\Tests\Models\Company\CompanyEmployee p ' .
165+
'ORDER BY s + p.id DESC';
166+
167+
/** @var CompanyEmployee[] $result */
168+
$result = $this->_em->createQuery($dql)->getResult();
169+
170+
$this->assertEquals(2, count($result));
171+
$this->assertEquals('Guilherme B.', $result[0]->getName());
172+
$this->assertEquals('Benjamin E.', $result[1]->getName());
173+
}
174+
175+
public function testOrderWithArithmeticExpressionWithResultVariableAndSingleValuedPathExpression2(): void
176+
{
177+
$this->skipIfPostgres(__FUNCTION__);
178+
179+
$dql = 'SELECT p, p.salary AS HIDDEN s ' .
180+
'FROM Doctrine\Tests\Models\Company\CompanyEmployee p ' .
181+
'ORDER BY ((s + p.id)) DESC';
182+
183+
/** @var CompanyEmployee[] $result */
184+
$result = $this->_em->createQuery($dql)->getResult();
185+
186+
$this->assertEquals(2, count($result));
187+
$this->assertEquals('Guilherme B.', $result[0]->getName());
188+
$this->assertEquals('Benjamin E.', $result[1]->getName());
189+
}
190+
191+
public function testOrderWithArithmeticExpressionWithSingleValuedPathExpressionAndResultVariable(): void
192+
{
193+
$this->skipIfPostgres(__FUNCTION__);
194+
195+
$dql = 'SELECT p, p.salary AS HIDDEN s ' .
196+
'FROM Doctrine\Tests\Models\Company\CompanyEmployee p ' .
197+
'ORDER BY p.id + s DESC';
198+
199+
/** @var CompanyEmployee[] $result */
200+
$result = $this->_em->createQuery($dql)->getResult();
201+
202+
$this->assertEquals(2, count($result));
203+
$this->assertEquals('Guilherme B.', $result[0]->getName());
204+
$this->assertEquals('Benjamin E.', $result[1]->getName());
205+
}
206+
207+
public function testOrderWithArithmeticExpressionWithLiteralAndResultVariableUsingHiddenResultVariable(): void
208+
{
209+
$dql = 'SELECT p, 1 + p.salary AS HIDDEN _order ' .
210+
'FROM Doctrine\Tests\Models\Company\CompanyEmployee p ' .
211+
'ORDER BY _order DESC';
212+
213+
/** @var CompanyEmployee[] $result */
214+
$result = $this->_em->createQuery($dql)->getResult();
215+
216+
$this->assertEquals(2, count($result));
217+
$this->assertEquals('Guilherme B.', $result[0]->getName());
218+
$this->assertEquals('Benjamin E.', $result[1]->getName());
219+
}
220+
221+
public function generateFixture(): void
222+
{
223+
$person1 = new CompanyEmployee();
224+
$person1->setName('Benjamin E.');
225+
$person1->setDepartment('IT');
226+
$person1->setSalary(200000);
227+
228+
$person2 = new CompanyEmployee();
229+
$person2->setName('Guilherme B.');
230+
$person2->setDepartment('IT2');
231+
$person2->setSalary(400000);
232+
233+
$this->_em->persist($person1);
234+
$this->_em->persist($person2);
235+
$this->_em->flush();
236+
$this->_em->clear();
237+
}
238+
}

0 commit comments

Comments
 (0)