Skip to content

Commit 92ff9c9

Browse files
webda2lastepin
andauthored
Allow arithmetic expressions within IN operator (#9242)
* allow arithmetic expressions within IN operator Co-authored-by: Artem Stepin <[email protected]>
1 parent f1483f8 commit 92ff9c9

File tree

5 files changed

+52
-5
lines changed

5 files changed

+52
-5
lines changed

docs/en/reference/dql-doctrine-query-language.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1724,7 +1724,7 @@ Literal Values
17241724
.. code-block:: php
17251725
17261726
Literal ::= string | char | integer | float | boolean
1727-
InParameter ::= Literal | InputParameter
1727+
InParameter ::= ArithmeticExpression | InputParameter
17281728
17291729
Input Parameter
17301730
~~~~~~~~~~~~~~~

lib/Doctrine/ORM/Query/Parser.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2758,17 +2758,17 @@ public function Literal()
27582758
}
27592759

27602760
/**
2761-
* InParameter ::= Literal | InputParameter
2761+
* InParameter ::= ArithmeticExpression | InputParameter
27622762
*
2763-
* @return AST\InputParameter|AST\Literal
2763+
* @return AST\InputParameter|AST\ArithmeticExpression
27642764
*/
27652765
public function InParameter()
27662766
{
27672767
if ($this->lexer->lookahead['type'] === Lexer::T_INPUT_PARAMETER) {
27682768
return $this->InputParameter();
27692769
}
27702770

2771-
return $this->Literal();
2771+
return $this->ArithmeticExpression();
27722772
}
27732773

27742774
/**

lib/Doctrine/ORM/Query/SqlWalker.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2106,7 +2106,7 @@ public function walkInParameter($inParam)
21062106
{
21072107
return $inParam instanceof AST\InputParameter
21082108
? $this->walkInputParameter($inParam)
2109-
: $this->walkLiteral($inParam);
2109+
: $this->walkArithmeticExpression($inParam);
21102110
}
21112111

21122112
/**

tests/Doctrine/Tests/ORM/Functional/QueryDqlFunctionTest.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,39 @@ public function testBitAndComparison(): void
420420
self::assertEquals($result[3][0]['salary'] / 100000 & 2, $result[3]['salary_bit_and']);
421421
}
422422

423+
public function testInArithmeticExpression1(): void
424+
{
425+
$dql = <<<'SQL'
426+
SELECT m, m.name AS m_name
427+
FROM Doctrine\Tests\Models\Company\CompanyManager m
428+
WHERE m.salary IN (800000 / 8, 100000 * 2)
429+
SQL;
430+
431+
$result = $this->_em->createQuery($dql)->getArrayResult();
432+
433+
self::assertCount(2, $result);
434+
self::assertEquals('Roman B.', $result[0]['m_name']);
435+
self::assertEquals('Benjamin E.', $result[1]['m_name']);
436+
}
437+
438+
public function testInArithmeticExpression2(): void
439+
{
440+
$this->_em->getConfiguration()->addCustomStringFunction('FOO', static function ($funcName) {
441+
return new NoOp($funcName); // See Doctrine/Tests/ORM/Functional/CustomFunctionsTest
442+
});
443+
444+
$dql = <<<'SQL'
445+
SELECT m, m.name AS m_name
446+
FROM Doctrine\Tests\Models\Company\CompanyManager m
447+
WHERE m.department IN (FOO('Administration'))
448+
SQL;
449+
450+
$result = $this->_em->createQuery($dql)->getArrayResult();
451+
452+
self::assertCount(1, $result);
453+
self::assertEquals('Jonathan W.', $result[0]['m_name']);
454+
}
455+
423456
protected function generateFixture(): void
424457
{
425458
$manager1 = new CompanyManager();

tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -643,6 +643,20 @@ public function testInvalidInExpressionWithSingleValuedAssociationPathExpression
643643
);
644644
}
645645

646+
public function testInExpressionWithArithmeticExpression(): void
647+
{
648+
$this->entityManager->getConfiguration()->addCustomStringFunction('FOO', MyAbsFunction::class);
649+
650+
$this->assertSqlGeneration(
651+
"SELECT u FROM Doctrine\Tests\Models\Forum\ForumUser u WHERE u.username IN (FOO('Lo'), 'Lo', :name)",
652+
"SELECT f0_.id AS id_0, f0_.username AS username_1 FROM forum_users f0_ WHERE f0_.username IN (ABS('Lo'), 'Lo', ?)"
653+
);
654+
$this->assertSqlGeneration(
655+
'SELECT u FROM Doctrine\Tests\Models\Forum\ForumUser u WHERE u.id IN (1 + 1)',
656+
'SELECT f0_.id AS id_0, f0_.username AS username_1 FROM forum_users f0_ WHERE f0_.id IN (1 + 1)'
657+
);
658+
}
659+
646660
public function testSupportsConcatFunctionForMysqlAndPostgresql(): void
647661
{
648662
$connMock = $this->entityManager->getConnection();

0 commit comments

Comments
 (0)