Skip to content

Commit d83a099

Browse files
feat: add support for specifying explicit range bounds (#380)
1 parent 09d479f commit d83a099

File tree

21 files changed

+456
-45
lines changed

21 files changed

+456
-45
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Fixtures\MartinGeorgiev\Doctrine\Entity;
6+
7+
use Doctrine\DBAL\Types\Types;
8+
use Doctrine\ORM\Mapping as ORM;
9+
10+
#[ORM\Entity()]
11+
class ContainsNumerics extends Entity
12+
{
13+
#[ORM\Column(type: Types::INTEGER)]
14+
public int $integer1;
15+
16+
#[ORM\Column(type: Types::INTEGER)]
17+
public int $integer2;
18+
19+
#[ORM\Column(type: Types::BIGINT)]
20+
public int $bigint1;
21+
22+
#[ORM\Column(type: Types::BIGINT)]
23+
public int $bigint2;
24+
25+
#[ORM\Column(type: Types::DECIMAL, precision: 10, scale: 2)]
26+
public float $decimal1;
27+
28+
#[ORM\Column(type: Types::DECIMAL, precision: 10, scale: 2)]
29+
public float $decimal2;
30+
}

src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Daterange.php

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,28 @@
1212
*
1313
* @author Martin Georgiev <martin.georgiev@gmail.com>
1414
*/
15-
class Daterange extends BaseFunction
15+
class Daterange extends BaseVariadicFunction
1616
{
17-
protected function customizeFunction(): void
17+
protected function getFunctionName(): string
1818
{
19-
$this->setFunctionPrototype('daterange(%s, %s)');
20-
$this->addNodeMapping('StringPrimary');
21-
$this->addNodeMapping('StringPrimary');
19+
return 'daterange';
20+
}
21+
22+
/**
23+
* @return array<string>
24+
*/
25+
protected function getNodeMappingPattern(): array
26+
{
27+
return ['StringPrimary'];
28+
}
29+
30+
protected function getMinArgumentCount(): int
31+
{
32+
return 2;
33+
}
34+
35+
protected function getMaxArgumentCount(): int
36+
{
37+
return 3;
2238
}
2339
}

src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Int4range.php

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,28 @@
1212
*
1313
* @author Martin Georgiev <martin.georgiev@gmail.com>
1414
*/
15-
class Int4range extends BaseFunction
15+
class Int4range extends BaseVariadicFunction
1616
{
17-
protected function customizeFunction(): void
17+
protected function getFunctionName(): string
1818
{
19-
$this->setFunctionPrototype('int4range(%s, %s)');
20-
$this->addNodeMapping('StringPrimary');
21-
$this->addNodeMapping('StringPrimary');
19+
return 'int4range';
20+
}
21+
22+
/**
23+
* @return array<string>
24+
*/
25+
protected function getNodeMappingPattern(): array
26+
{
27+
return ['StringPrimary'];
28+
}
29+
30+
protected function getMinArgumentCount(): int
31+
{
32+
return 2;
33+
}
34+
35+
protected function getMaxArgumentCount(): int
36+
{
37+
return 3;
2238
}
2339
}

src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Int8range.php

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,28 @@
1212
*
1313
* @author Martin Georgiev <martin.georgiev@gmail.com>
1414
*/
15-
class Int8range extends BaseFunction
15+
class Int8range extends BaseVariadicFunction
1616
{
17-
protected function customizeFunction(): void
17+
protected function getFunctionName(): string
1818
{
19-
$this->setFunctionPrototype('int8range(%s, %s)');
20-
$this->addNodeMapping('StringPrimary');
21-
$this->addNodeMapping('StringPrimary');
19+
return 'int8range';
20+
}
21+
22+
/**
23+
* @return array<string>
24+
*/
25+
protected function getNodeMappingPattern(): array
26+
{
27+
return ['StringPrimary'];
28+
}
29+
30+
protected function getMinArgumentCount(): int
31+
{
32+
return 2;
33+
}
34+
35+
protected function getMaxArgumentCount(): int
36+
{
37+
return 3;
2238
}
2339
}

src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Numrange.php

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,28 @@
1212
*
1313
* @author Martin Georgiev <martin.georgiev@gmail.com>
1414
*/
15-
class Numrange extends BaseFunction
15+
class Numrange extends BaseVariadicFunction
1616
{
17-
protected function customizeFunction(): void
17+
protected function getFunctionName(): string
1818
{
19-
$this->setFunctionPrototype('numrange(%s, %s)');
20-
$this->addNodeMapping('StringPrimary');
21-
$this->addNodeMapping('StringPrimary');
19+
return 'numrange';
20+
}
21+
22+
/**
23+
* @return array<string>
24+
*/
25+
protected function getNodeMappingPattern(): array
26+
{
27+
return ['StringPrimary'];
28+
}
29+
30+
protected function getMinArgumentCount(): int
31+
{
32+
return 2;
33+
}
34+
35+
protected function getMaxArgumentCount(): int
36+
{
37+
return 3;
2238
}
2339
}

src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Tsrange.php

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,28 @@
1212
*
1313
* @author Martin Georgiev <martin.georgiev@gmail.com>
1414
*/
15-
class Tsrange extends BaseFunction
15+
class Tsrange extends BaseVariadicFunction
1616
{
17-
protected function customizeFunction(): void
17+
protected function getFunctionName(): string
1818
{
19-
$this->setFunctionPrototype('tsrange(%s, %s)');
20-
$this->addNodeMapping('StringPrimary');
21-
$this->addNodeMapping('StringPrimary');
19+
return 'tsrange';
20+
}
21+
22+
/**
23+
* @return array<string>
24+
*/
25+
protected function getNodeMappingPattern(): array
26+
{
27+
return ['StringPrimary'];
28+
}
29+
30+
protected function getMinArgumentCount(): int
31+
{
32+
return 2;
33+
}
34+
35+
protected function getMaxArgumentCount(): int
36+
{
37+
return 3;
2238
}
2339
}

src/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/Tstzrange.php

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,28 @@
1212
*
1313
* @author Martin Georgiev <martin.georgiev@gmail.com>
1414
*/
15-
class Tstzrange extends BaseFunction
15+
class Tstzrange extends BaseVariadicFunction
1616
{
17-
protected function customizeFunction(): void
17+
protected function getFunctionName(): string
1818
{
19-
$this->setFunctionPrototype('tstzrange(%s, %s)');
20-
$this->addNodeMapping('StringPrimary');
21-
$this->addNodeMapping('StringPrimary');
19+
return 'tstzrange';
20+
}
21+
22+
/**
23+
* @return array<string>
24+
*/
25+
protected function getNodeMappingPattern(): array
26+
{
27+
return ['StringPrimary'];
28+
}
29+
30+
protected function getMinArgumentCount(): int
31+
{
32+
return 2;
33+
}
34+
35+
protected function getMaxArgumentCount(): int
36+
{
37+
return 3;
2238
}
2339
}

tests/Integration/MartinGeorgiev/Doctrine/ORM/Query/AST/Functions/DateTestCase.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ protected function createTestTableForDateFixture(): void
3131
datetime1 TIMESTAMP,
3232
datetime2 TIMESTAMP,
3333
time1 TIME,
34-
time2 TIME
34+
time2 TIME,
35+
datetimetz1 TIMESTAMPTZ,
36+
datetimetz2 TIMESTAMPTZ
3537
)
3638
', $fullTableName);
3739

@@ -41,8 +43,8 @@ protected function createTestTableForDateFixture(): void
4143
protected function insertTestDataForDateFixture(): void
4244
{
4345
$sql = \sprintf('
44-
INSERT INTO %s.containsdates (date1, date2, datetime1, datetime2, time1, time2) VALUES
45-
(\'2023-06-15\', \'2023-06-16\', \'2023-06-15 10:30:00\', \'2023-06-16 11:45:00\', \'10:30:00\', \'11:45:00\')
46+
INSERT INTO %s.containsdates (date1, date2, datetime1, datetime2, time1, time2, datetimetz1, datetimetz2) VALUES
47+
(\'2023-06-15\', \'2023-06-16\', \'2023-06-15 10:30:00\', \'2023-06-16 11:45:00\', \'10:30:00\', \'11:45:00\', \'2023-06-15 10:30:00+00\', \'2023-06-16 11:45:00+00\')
4648
', self::DATABASE_SCHEMA);
4749
$this->connection->executeStatement($sql);
4850
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tests\Integration\MartinGeorgiev\Doctrine\ORM\Query\AST\Functions;
6+
7+
use MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Daterange;
8+
9+
class DaterangeTest extends DateTestCase
10+
{
11+
protected function getStringFunctions(): array
12+
{
13+
return [
14+
'DATERANGE' => Daterange::class,
15+
];
16+
}
17+
18+
public function test_daterange(): void
19+
{
20+
$dql = 'SELECT DATERANGE(t.date1, t.date2) as result FROM Fixtures\MartinGeorgiev\Doctrine\Entity\ContainsDates t WHERE t.id = 1';
21+
$result = $this->executeDqlQuery($dql);
22+
$this->assertIsArray($result);
23+
$this->assertNotEmpty($result[0]['result']);
24+
$this->assertIsString($result[0]['result']);
25+
$this->assertSame('[2023-06-15,2023-06-16)', $result[0]['result']);
26+
}
27+
28+
public function test_daterange_with_bounds(): void
29+
{
30+
$dql = "SELECT DATERANGE(t.date1, t.date2, '[)') as result FROM Fixtures\\MartinGeorgiev\\Doctrine\\Entity\\ContainsDates t WHERE t.id = 1";
31+
$result = $this->executeDqlQuery($dql);
32+
$this->assertIsArray($result);
33+
$this->assertNotEmpty($result[0]['result']);
34+
$this->assertIsString($result[0]['result']);
35+
$this->assertSame('[2023-06-15,2023-06-16)', $result[0]['result']);
36+
}
37+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tests\Integration\MartinGeorgiev\Doctrine\ORM\Query\AST\Functions;
6+
7+
use MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Int4range;
8+
9+
class Int4rangeTest extends NumericTestCase
10+
{
11+
protected function getStringFunctions(): array
12+
{
13+
return [
14+
'INT4RANGE' => Int4range::class,
15+
];
16+
}
17+
18+
public function test_int4range(): void
19+
{
20+
$dql = 'SELECT INT4RANGE(t.integer1, t.integer2) as result FROM Fixtures\MartinGeorgiev\Doctrine\Entity\ContainsNumerics t WHERE t.id = 1';
21+
$result = $this->executeDqlQuery($dql);
22+
$this->assertIsArray($result);
23+
$this->assertNotEmpty($result[0]['result']);
24+
$this->assertIsString($result[0]['result']);
25+
$this->assertSame('[10,20)', $result[0]['result']);
26+
}
27+
28+
public function test_int4range_with_bounds(): void
29+
{
30+
$dql = "SELECT INT4RANGE(t.integer1, t.integer2, '[)') as result FROM Fixtures\\MartinGeorgiev\\Doctrine\\Entity\\ContainsNumerics t WHERE t.id = 1";
31+
$result = $this->executeDqlQuery($dql);
32+
$this->assertIsArray($result);
33+
$this->assertNotEmpty($result[0]['result']);
34+
$this->assertIsString($result[0]['result']);
35+
$this->assertSame('[10,20)', $result[0]['result']);
36+
}
37+
}

0 commit comments

Comments
 (0)