diff --git a/src/ORM/Query/AST/Functions/ArrayAgg.php b/src/ORM/Query/AST/Functions/ArrayAgg.php index 01ce58c..92e6055 100644 --- a/src/ORM/Query/AST/Functions/ArrayAgg.php +++ b/src/ORM/Query/AST/Functions/ArrayAgg.php @@ -15,22 +15,33 @@ * @see https://www.postgresql.org/docs/current/functions-aggregate.html#FUNCTIONS-AGGREGATE-TABLE * * @example ARRAY_AGG(entity.field) + * @example ARRAY_AGG(DISTINCT entity.field) * @example ARRAY_AGG(entity.field) FILTER (WHERE entity.field IS NOT NULL) + * @example ARRAY_AGG(DISTINCT entity.field) FILTER (WHERE entity.field IS NOT NULL) */ final class ArrayAgg extends AggregateWithFilterFunction { + private bool $distinct = false; + private Node $expr; public function parseFunction(Parser $parser): void { $parser->match(Lexer::T_IDENTIFIER); $parser->match(Lexer::T_OPEN_PARENTHESIS); + + $lexer = $parser->getLexer(); + if ($lexer->isNextToken(Lexer::T_DISTINCT)) { + $parser->match(Lexer::T_DISTINCT); + $this->distinct = true; + } + $this->expr = $parser->StringPrimary(); $parser->match(Lexer::T_CLOSE_PARENTHESIS); } public function getFunctionSql(SqlWalker $sqlWalker): string { - return "ARRAY_AGG({$this->expr->dispatch($sqlWalker)})"; + return sprintf('ARRAY_AGG(%s%s)', $this->distinct ? 'DISTINCT ' : '', $this->expr->dispatch($sqlWalker)); } } diff --git a/src/ORM/Query/AST/Functions/JsonAgg.php b/src/ORM/Query/AST/Functions/JsonAgg.php index 475f69b..b76eeff 100644 --- a/src/ORM/Query/AST/Functions/JsonAgg.php +++ b/src/ORM/Query/AST/Functions/JsonAgg.php @@ -15,22 +15,33 @@ * @see https://www.postgresql.org/docs/current/functions-aggregate.html#FUNCTIONS-AGGREGATE-TABLE * * @example JSON_AGG(entity.field) + * @example JSON_AGG(DISTINCT entity.field) * @example JSON_AGG(entity.field) FILTER (WHERE entity.field IS NOT NULL) + * @example JSON_AGG(DISTINCT entity.field) FILTER (WHERE entity.field IS NOT NULL) */ final class JsonAgg extends AggregateWithFilterFunction { + private bool $distinct = false; + private Node $expr; public function parseFunction(Parser $parser): void { $parser->match(Lexer::T_IDENTIFIER); $parser->match(Lexer::T_OPEN_PARENTHESIS); + + $lexer = $parser->getLexer(); + if ($lexer->isNextToken(Lexer::T_DISTINCT)) { + $parser->match(Lexer::T_DISTINCT); + $this->distinct = true; + } + $this->expr = $parser->StringPrimary(); $parser->match(Lexer::T_CLOSE_PARENTHESIS); } public function getFunctionSql(SqlWalker $sqlWalker): string { - return "JSON_AGG({$this->expr->dispatch($sqlWalker)})"; + return sprintf('JSON_AGG(%s%s)', $this->distinct ? 'DISTINCT ' : '', $this->expr->dispatch($sqlWalker)); } } diff --git a/src/ORM/Query/AST/Functions/JsonbAgg.php b/src/ORM/Query/AST/Functions/JsonbAgg.php index 23a2c78..922fda1 100644 --- a/src/ORM/Query/AST/Functions/JsonbAgg.php +++ b/src/ORM/Query/AST/Functions/JsonbAgg.php @@ -19,18 +19,27 @@ */ final class JsonbAgg extends AggregateWithFilterFunction { + private bool $distinct = false; + private Node $expr; public function parseFunction(Parser $parser): void { $parser->match(Lexer::T_IDENTIFIER); $parser->match(Lexer::T_OPEN_PARENTHESIS); + + $lexer = $parser->getLexer(); + if ($lexer->isNextToken(Lexer::T_DISTINCT)) { + $parser->match(Lexer::T_DISTINCT); + $this->distinct = true; + } + $this->expr = $parser->StringPrimary(); $parser->match(Lexer::T_CLOSE_PARENTHESIS); } public function getFunctionSql(SqlWalker $sqlWalker): string { - return "JSON_AGG({$this->expr->dispatch($sqlWalker)})"; + return sprintf('JSONB_AGG(%s%s)', $this->distinct ? 'DISTINCT ' : '', $this->expr->dispatch($sqlWalker)); } }