Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ DoctrineExtensions
A set of extensions to Doctrine 2 that add support for functions available in
MySQL, Oracle, PostgreSQL and SQLite.

| DB | Functions |
|:--:|:---------:|
| MySQL | `ACOS, ADDTIME, AES_DECRYPT, AES_ENCRYPT, ANY_VALUE, ASCII, ASIN, ATAN, ATAN2, BINARY, BIT_COUNT, BIT_XOR, CAST, CEIL, CHAR_LENGTH, COLLATE, CONCAT_WS, CONVERT_TZ, COS, COT, COUNTIF, CRC32, DATE, DATE_FORMAT, DATEADD, DATEDIFF, DATESUB, DAY, DAYNAME, DAYOFWEEK, DAYOFYEAR, DEGREES, DIV, EXP, EXTRACT, FIELD, FIND_IN_SET, FLOOR, FORMAT, FROM_BASE64, FROM_UNIXTIME, GREATEST, GROUP_CONCAT, HEX, HOUR, IFELSE, IFNULL, INET_ATON, INET_NTOA, INET6_ATON, INET6_NTOA, INSTR, IS_IPV4, IS_IPV4_COMPAT, IS_IPV4_MAPPED, IS_IPV6, JSON_CONTAINS, JSON_DEPTH, JSON_LENGTH, LAG, LAST_DAY, LEAD, LEAST, LOG, LOG10, LOG2, LPAD, MAKEDATE, MATCH, MD5, MINUTE, MONTH, MONTHNAME, NOW, NULLIF, OVER, PERIOD_DIFF, PI, POWER, QUARTER, RADIANS, RAND, REGEXP, REPLACE, ROUND, RPAD, SECOND, SECTOTIME, SHA1, SHA2, SIN, SOUNDEX, STD, STDDEV, STRTODATE, STR_TO_DATE, SUBSTRING_INDEX, TAN, TIME, TIMEDIFF, TIMESTAMPADD, TIMESTAMPDIFF, TIMETOSEC, TRUNCATE, UNHEX, UNIX_TIMESTAMP, UTC_TIMESTAMP, UUID_SHORT, VARIANCE, WEEK, WEEKDAY, WEEKOFYEAR, YEAR, YEARMONTH, YEARWEEK` |
| Oracle | `CEIL, DAY, FLOOR, HOUR, LISTAGG, MINUTE, MONTH, NVL, SECOND, TO_CHAR, TO_DATE, TRUNC, YEAR` |
| SQLite | `CASE WHEN THEN ELSE END, DATE, DATE_FORMAT*, DAY, HOUR, IFNULL, JULIANDAY, MINUTE, MONTH, REPLACE, ROUND, SECOND, STRFTIME, WEEK, WEEKDAY, YEAR` |
| PostgreSQL | `AT_TIME_ZONE, COUNT_FILTER, DATE, DATE_PART, DATE_TRUNC, DAY, EXTRACT, GREATEST, HOUR, LEAST, MINUTE, MONTH, REGEXP_REPLACE, SECOND, STRING_AGG, TO_CHAR, TO_DATE, YEAR` |
| DB | Functions |
|:--:|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:|
| MySQL | `ACOS, ADDTIME, AES_DECRYPT, AES_ENCRYPT, ANY_VALUE, ASCII, ASIN, ATAN, ATAN2, BINARY, BIT_COUNT, BIT_XOR, CAST, CEIL, CHAR_LENGTH, COALESCE, COLLATE, CONCAT_WS, CONVERT_TZ, COS, COT, COUNTIF, CRC32, DATE, DATE_FORMAT, DATEADD, DATEDIFF, DATESUB, DAY, DAYNAME, DAYOFWEEK, DAYOFYEAR, DEGREES, DIV, EXP, EXTRACT, FIELD, FIND_IN_SET, FLOOR, FORMAT, FROM_BASE64, FROM_UNIXTIME, GREATEST, GROUP_CONCAT, HEX, HOUR, IFELSE, IFNULL, INET_ATON, INET_NTOA, INET6_ATON, INET6_NTOA, INSTR, IS_IPV4, IS_IPV4_COMPAT, IS_IPV4_MAPPED, IS_IPV6, JSON_CONTAINS, JSON_DEPTH, JSON_LENGTH, LAG, LAST_DAY, LEAD, LEAST, LOG, LOG10, LOG2, LPAD, MAKEDATE, MATCH, MD5, MINUTE, MONTH, MONTHNAME, NOW, NULLIF, OVER, PERIOD_DIFF, PI, POWER, QUARTER, RADIANS, RAND, REGEXP, REPLACE, ROUND, RPAD, SECOND, SECTOTIME, SHA1, SHA2, SIN, SOUNDEX, STD, STDDEV, STRTODATE, STR_TO_DATE, SUBSTRING_INDEX, TAN, TIME, TIMEDIFF, TIMESTAMPADD, TIMESTAMPDIFF, TIMETOSEC, TRUNCATE, UNHEX, UNIX_TIMESTAMP, UTC_TIMESTAMP, UUID_SHORT, VARIANCE, WEEK, WEEKDAY, WEEKOFYEAR, YEAR, YEARMONTH, YEARWEEK` |
| Oracle | `CEIL, DAY, FLOOR, HOUR, LISTAGG, MINUTE, MONTH, NVL, SECOND, TO_CHAR, TO_DATE, TRUNC, YEAR` |
| SQLite | `CASE WHEN THEN ELSE END, DATE, DATE_FORMAT*, DAY, HOUR, IFNULL, JULIANDAY, MINUTE, MONTH, REPLACE, ROUND, SECOND, STRFTIME, WEEK, WEEKDAY, YEAR` |
| PostgreSQL | `AT_TIME_ZONE, COUNT_FILTER, DATE, DATE_PART, DATE_TRUNC, DAY, EXTRACT, GREATEST, HOUR, LEAST, MINUTE, MONTH, REGEXP_REPLACE, SECOND, STRING_AGG, TO_CHAR, TO_DATE, YEAR` |

> Note: SQLite date functions are implemented as `strftime(format, value)`.
SQLite only supports the [most common formats](https://www.sqlite.org/lang_datefunc.html),
Expand Down
1 change: 1 addition & 0 deletions config/mysql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ doctrine:
binary: DoctrineExtensions\Query\Mysql\Binary
cast: DoctrineExtensions\Query\Mysql\Cast
char_length: DoctrineExtensions\Query\Mysql\CharLength
coalesce: DoctrineExtensions\Query\Mysql\Coalesce
collate: DoctrineExtensions\Query\Mysql\Collate
concat_ws: DoctrineExtensions\Query\Mysql\ConcatWs
countif: DoctrineExtensions\Query\Mysql\CountIf
Expand Down
45 changes: 45 additions & 0 deletions src/Query/Mysql/Coalesce.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

namespace DoctrineExtensions\Query\Mysql;

use Doctrine\ORM\Query\AST\ArithmeticExpression;
use Doctrine\ORM\Query\AST\Functions\FunctionNode;
use Doctrine\ORM\Query\Parser;
use Doctrine\ORM\Query\SqlWalker;
use Doctrine\ORM\Query\TokenType;

use function array_map;
use function implode;

/**
* @link https://dev.mysql.com/doc/refman/en/comparison-operators.html#function_coalesce
*
* @author Alexandre Bertrand <[email protected]>
*/
class Coalesce extends FunctionNode
{
private $values = [];

public function parse(Parser $parser): void
{
$parser->match(TokenType::T_IDENTIFIER);
$parser->match(TokenType::T_OPEN_PARENTHESIS);
$lexer = $parser->getLexer();

do {
$parser->match(TokenType::T_COMMA);
$this->values[] = $parser->ArithmeticExpression();
} while ($lexer->lookahead->type !== TokenType::T_CLOSE_PARENTHESIS);

$parser->match(TokenType::T_CLOSE_PARENTHESIS);
}

public function getSql(SqlWalker $sqlWalker): string
{
$values = array_map(static function (ArithmeticExpression $value) use ($sqlWalker): string {
return $value->dispatch($sqlWalker);
}, $this->values);

return 'COALESCE(' . implode(', ', $values) . ')';
}
}
16 changes: 16 additions & 0 deletions tests/Query/Mysql/CoalesceTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

namespace DoctrineExtensions\Tests\Query\Mysql;

use DoctrineExtensions\Tests\Query\MysqlTestCase;

class CoalesceTest extends MysqlTestCase
{
public function testGreatest(): void
{
$this->assertDqlProducesSql(
'SELECT COALESCE(2, 5, 8) from DoctrineExtensions\Tests\Entities\Blank b',
'SELECT COALESCE(2, 5, 8) AS sclr_0 FROM Blank b0_'
);
}
}