Skip to content

Commit fccc6a9

Browse files
jeffersonvantuirstevelacey
authored andcommitted
Oracle CEIL/FLOOR functions + TO_CHAR nlsparam (beberlei#336)
1 parent fa9aab0 commit fccc6a9

File tree

9 files changed

+185
-1
lines changed

9 files changed

+185
-1
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ MySQL, Oracle, PostgreSQL and SQLite.
1414
| DB | Functions |
1515
|:--:|:---------:|
1616
| 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_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, 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, UNHEX, UNIX_TIMESTAMP, UTC_TIMESTAMP, UUID_SHORT, VARIANCE, WEEK, WEEKDAY, YEAR, YEARMONTH, YEARWEEK` |
17-
| Oracle | `DAY, LISTAGG, MONTH, NVL, TO_CHAR, TO_DATE, TRUNC, YEAR` |
17+
| Oracle | `CEIL, DAY, FLOOR, LISTAGG, MONTH, NVL, TO_CHAR, TO_DATE, TRUNC, YEAR` |
1818
| Sqlite | `DATE, MINUTE, HOUR, DAY, WEEK, WEEKDAY, MONTH, YEAR, JULIANDAY, STRFTIME, DATE_FORMAT*, CASE WHEN THEN ELSE END, IFNULL, REPLACE, ROUND` |
1919
| PostgreSQL | `AT_TIME_ZONE, COUNT_FILTER, DATE_PART, EXTRACT, GREATEST, LEAST, REGEXP_REPLACE, STRING_AGG, TO_CHAR, TO_DATE` |
2020

config/oracle.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,7 @@ doctrine:
1212
nvl: DoctrineExtensions\Query\Oracle\Nvl
1313
listagg: DoctrineExtensions\Query\Oracle\Listagg
1414
to_date: DoctrineExtensions\Query\Oracle\ToDate
15+
16+
numeric_functions:
17+
ceil: DoctrineExtensions\Query\Oracle\Ceil
18+
floor: DoctrineExtensions\Query\Oracle\Floor

src/Query/Oracle/Ceil.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
namespace DoctrineExtensions\Query\Oracle;
4+
5+
use Doctrine\ORM\Query\AST\Functions\FunctionNode;
6+
use Doctrine\ORM\Query\Lexer;
7+
8+
/**
9+
* @author Jefferson Vantuir <[email protected]>
10+
*/
11+
class Ceil extends FunctionNode
12+
{
13+
private $number;
14+
15+
public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
16+
{
17+
return sprintf(
18+
'CEIL(%s)',
19+
$sqlWalker->walkArithmeticPrimary($this->number)
20+
);
21+
}
22+
23+
public function parse(\Doctrine\ORM\Query\Parser $parser)
24+
{
25+
$parser->match(Lexer::T_IDENTIFIER);
26+
$parser->match(Lexer::T_OPEN_PARENTHESIS);
27+
$this->number = $parser->ArithmeticExpression();
28+
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
29+
}
30+
}

src/Query/Oracle/Floor.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
namespace DoctrineExtensions\Query\Oracle;
4+
5+
use Doctrine\ORM\Query\AST\Functions\FunctionNode;
6+
use Doctrine\ORM\Query\Lexer;
7+
8+
/**
9+
* @author Jefferson Vantuir <[email protected]>
10+
*/
11+
class Floor extends FunctionNode
12+
{
13+
private $number;
14+
15+
public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
16+
{
17+
return sprintf(
18+
'FLOOR(%s)',
19+
$sqlWalker->walkArithmeticPrimary($this->number)
20+
);
21+
}
22+
23+
public function parse(\Doctrine\ORM\Query\Parser $parser)
24+
{
25+
$parser->match(Lexer::T_IDENTIFIER);
26+
$parser->match(Lexer::T_OPEN_PARENTHESIS);
27+
$this->number = $parser->ArithmeticExpression();
28+
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
29+
}
30+
}

src/Query/Oracle/ToChar.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,19 @@ class ToChar extends FunctionNode
1414

1515
private $fmt;
1616

17+
private $nls = null;
18+
1719
public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
1820
{
21+
if ($this->nls) {
22+
return sprintf(
23+
'TO_CHAR(%s, %s, %s)',
24+
$sqlWalker->walkArithmeticPrimary($this->datetime),
25+
$sqlWalker->walkArithmeticPrimary($this->fmt),
26+
$sqlWalker->walkArithmeticPrimary($this->nls)
27+
);
28+
}
29+
1930
return sprintf(
2031
'TO_CHAR(%s, %s)',
2132
$sqlWalker->walkArithmeticPrimary($this->datetime),
@@ -25,11 +36,19 @@ public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
2536

2637
public function parse(\Doctrine\ORM\Query\Parser $parser)
2738
{
39+
$lexer = $parser->getLexer();
40+
2841
$parser->match(Lexer::T_IDENTIFIER);
2942
$parser->match(Lexer::T_OPEN_PARENTHESIS);
3043
$this->datetime = $parser->ArithmeticExpression();
3144
$parser->match(Lexer::T_COMMA);
3245
$this->fmt = $parser->StringExpression();
46+
47+
if ($lexer->isNextToken(Lexer::T_COMMA)) {
48+
$parser->match(Lexer::T_COMMA);
49+
$this->nls = $parser->StringExpression();
50+
}
51+
3352
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
3453
}
3554
}

tests/Entities/Product.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
namespace DoctrineExtensions\Tests\Entities;
4+
5+
/**
6+
* @Entity
7+
*/
8+
class Product
9+
{
10+
/** @Id @Column(type="string") @GeneratedValue */
11+
public $id;
12+
13+
/**
14+
* @Column(type="string")
15+
*/
16+
public $name;
17+
18+
/**
19+
* @Column(type="DateTime")
20+
*/
21+
public $created;
22+
23+
/**
24+
* @Column(type="decimal", precision=10, scale=2)
25+
*/
26+
public $price;
27+
28+
/**
29+
* @Column(type="decimal", precision=5, scale=2)
30+
*/
31+
public $weight;
32+
}

tests/Query/Oracle/CeilTest.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
namespace DoctrineExtensions\Tests\Query\Oracle;
4+
5+
use Doctrine\ORM\QueryBuilder;
6+
use DoctrineExtensions\Tests\Entities\Product;
7+
use DoctrineExtensions\Tests\Query\OracleTestCase;
8+
9+
/**
10+
* @author Jefferson Vantuir <[email protected]>
11+
*/
12+
class CeilTest extends OracleTestCase
13+
{
14+
public function testFullQuery()
15+
{
16+
$queryBuilder = new QueryBuilder($this->entityManager);
17+
$queryBuilder->select('CEIL(p.weight)')
18+
->from(Product::class, 'p');
19+
20+
$sql = 'SELECT CEIL(p0_.weight) AS sclr_0 FROM Product p0_';
21+
$this->assertEquals($sql, $queryBuilder->getQuery()->getSQL());
22+
}
23+
}

tests/Query/Oracle/FloorTest.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
namespace DoctrineExtensions\Tests\Query\Oracle;
4+
5+
use Doctrine\ORM\QueryBuilder;
6+
use DoctrineExtensions\Tests\Entities\Product;
7+
use DoctrineExtensions\Tests\Query\OracleTestCase;
8+
9+
/**
10+
* @author Jefferson Vantuir <[email protected]>
11+
*/
12+
class FloorTest extends OracleTestCase
13+
{
14+
public function testFullQuery()
15+
{
16+
$queryBuilder = new QueryBuilder($this->entityManager);
17+
$queryBuilder->select('FLOOR(p.weight)')
18+
->from(Product::class, 'p');
19+
20+
$sql = 'SELECT FLOOR(p0_.weight) AS sclr_0 FROM Product p0_';
21+
$this->assertEquals($sql, $queryBuilder->getQuery()->getSQL());
22+
}
23+
}

tests/Query/Oracle/ToCharTest.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
namespace DoctrineExtensions\Tests\Query\Oracle;
4+
5+
use Doctrine\ORM\QueryBuilder;
6+
use DoctrineExtensions\Tests\Entities\Date;
7+
use DoctrineExtensions\Tests\Query\OracleTestCase;
8+
9+
/**
10+
* @author Jefferson Vantuir <[email protected]>
11+
*/
12+
class ToCharTest extends OracleTestCase
13+
{
14+
public function testFullQuery()
15+
{
16+
$queryBuilder = new QueryBuilder($this->entityManager);
17+
$queryBuilder->select('TO_CHAR(d.created, \'DD-MON-YYYY HH24:MI:SSxFF\', \'german\')')
18+
->from(Date::class, 'd');
19+
20+
$sql = 'SELECT TO_CHAR(d0_.created, \'DD-MON-YYYY HH24:MI:SSxFF\', \'german\') AS sclr_0 FROM Date d0_';
21+
$this->assertEquals($sql, $queryBuilder->getQuery()->getSQL());
22+
}
23+
}

0 commit comments

Comments
 (0)