From 89c370148500d1e7067e8cdbd96dfe827a8d2e58 Mon Sep 17 00:00:00 2001 From: Christopher Georg Date: Sat, 17 Jun 2023 00:22:43 +0200 Subject: [PATCH] feat: improve string_agg() for postgres --- src/Query/Postgresql/StringAgg.php | 8 +++++--- tests/Query/Postgresql/StringAggTest.php | 13 +++++++++++++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/Query/Postgresql/StringAgg.php b/src/Query/Postgresql/StringAgg.php index 5f8f9a552..7a5054e7b 100644 --- a/src/Query/Postgresql/StringAgg.php +++ b/src/Query/Postgresql/StringAgg.php @@ -3,6 +3,7 @@ namespace DoctrineExtensions\Query\Postgresql; use Doctrine\ORM\Query\AST\Functions\FunctionNode; +use Doctrine\ORM\Query\AST\Functions\LowerFunction; use Doctrine\ORM\Query\AST\OrderByClause; use Doctrine\ORM\Query\AST\PathExpression; use Doctrine\ORM\Query\Lexer; @@ -12,12 +13,13 @@ /** * @author Roberto JĂșnior * @author Vaskevich Eugeniy + * @author Allan Simon */ class StringAgg extends FunctionNode { private OrderByClause|null $orderBy = null; - private PathExpression|null $expression = null; + private PathExpression|LowerFunction|null $expression = null; private $delimiter = null; @@ -35,7 +37,7 @@ public function parse(Parser $parser): void $this->isDistinct = true; } - $this->expression = $parser->PathExpression(PathExpression::TYPE_STATE_FIELD); + $this->expression = $parser->ArithmeticPrimary(); $parser->match(Lexer::T_COMMA); $this->delimiter = $parser->StringPrimary(); @@ -51,7 +53,7 @@ public function getSql(SqlWalker $sqlWalker): string return \sprintf( 'string_agg(%s%s, %s%s)', ($this->isDistinct ? 'DISTINCT ' : ''), - $sqlWalker->walkPathExpression($this->expression), + $this->expression->dispatch($sqlWalker), $sqlWalker->walkStringPrimary($this->delimiter), ($this->orderBy ? $sqlWalker->walkOrderByClause($this->orderBy) : '') ); diff --git a/tests/Query/Postgresql/StringAggTest.php b/tests/Query/Postgresql/StringAggTest.php index 375a2ad33..954745d48 100644 --- a/tests/Query/Postgresql/StringAggTest.php +++ b/tests/Query/Postgresql/StringAggTest.php @@ -72,4 +72,17 @@ public function testStringAggFullDeclaration():void $this->assertEquals($expected, $queryBuilder->getQuery()->getSQL()); } + + public function testStringAggWithInnerFunction(): void + { + $queryBuilder = new QueryBuilder($this->entityManager); + $queryBuilder + ->select("string_agg(DISTINCT LOWER(bpt.latitude), '-' ORDER BY bpt.latitude DESC)") + ->from(BlogPost::class, 'bpt') + ->groupBy('bpt.created'); + + $expected = 'SELECT string_agg(DISTINCT LOWER(b0_.latitude), \'-\' ORDER BY b0_.latitude DESC) AS sclr_0 FROM BlogPost b0_ GROUP BY b0_.created'; + + $this->assertEquals($expected, $queryBuilder->getQuery()->getSQL()); + } }