Skip to content

Commit 8af88fd

Browse files
committed
feat: add support for distance operator <@>
1 parent fac26cd commit 8af88fd

File tree

7 files changed

+75
-1
lines changed

7 files changed

+75
-1
lines changed

docs/AVAILABLE-FUNCTIONS-AND-OPERATORS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
| !~* | NOT_IREGEXP | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\NotIRegexp` |
2424
| @@ | TSMATCH | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Tsmatch` |
2525
| \|\| | STRCONCAT | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\StrConcat` |
26+
| <@> | DISTANCE | `MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Distance` |
2627

2728
# Available functions
2829

docs/INTEGRATING-WITH-DOCTRINE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ $configuration->addCustomStringFunction('REGEXP_MATCH', MartinGeorgiev\Doctrine\
164164
$configuration->addCustomStringFunction('STRCONCAT', MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\StrConcat::class);
165165
$configuration->addCustomStringFunction('REGEXP_REPLACE', MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\RegexpReplace::class);
166166
$configuration->addCustomStringFunction('ROW', MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Row::class);
167+
$configuration->addCustomStringFunction('DISTANCE', MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Distance::class);
167168

168169
# aggregation functions
169170
$configuration->addCustomStringFunction('ARRAY_AGG', MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ArrayAgg::class);

docs/INTEGRATING-WITH-LARAVEL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ return [
216216
'REGEXP_SUBSTR' => MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\RegexpSubstr::class,
217217
'STRCONCAT' => MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\StrConcat::class, // the `||` operator
218218
'ROW' => MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Row::class,
219+
'DISTANCE' => MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Distance::class,
219220

220221
# aggregation functions
221222
'ARRAY_AGG' => MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ArrayAgg::class,
@@ -224,7 +225,6 @@ return [
224225
'JSONB_AGG' => MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonbAgg::class,
225226
'JSONB_OBJECT_AGG' => MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\JsonbObjectAgg::class,
226227
'STRING_AGG' => MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\StringAgg::class,
227-
'XML_AGG' => MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\XmlAgg::class,
228228
],
229229

230230
...

docs/INTEGRATING-WITH-SYMFONY.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ doctrine:
2828
inet[]: MartinGeorgiev\Doctrine\DBAL\Types\InetArray
2929
macaddr: MartinGeorgiev\Doctrine\DBAL\Types\Macaddr
3030
macaddr[]: MartinGeorgiev\Doctrine\DBAL\Types\MacaddrArray
31+
3132
point: MartinGeorgiev\Doctrine\DBAL\Types\Point
3233
point[]: MartinGeorgiev\Doctrine\DBAL\Types\PointArray
3334
```
@@ -211,6 +212,7 @@ doctrine:
211212
REGEXP_SUBSTR: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\RegexpSubstr
212213
ROW: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Row
213214
STRCONCAT: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\StrConcat
215+
DISTANCE: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Distance
214216
215217
# aggregation functions
216218
ARRAY_AGG: MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\ArrayAgg
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Fixtures\MartinGeorgiev\Doctrine\Entity;
6+
7+
use Doctrine\ORM\Mapping as ORM;
8+
use MartinGeorgiev\Doctrine\DBAL\Types\ValueObject\Point;
9+
10+
#[ORM\Entity()]
11+
class ContainsPoints extends Entity
12+
{
13+
#[ORM\Column(type: 'point')]
14+
public Point $point;
15+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace MartinGeorgiev\Doctrine\ORM\Query\AST\Functions;
6+
7+
/**
8+
* Implementation of PostgreSQL's distance operator (using `<@>`).
9+
*
10+
* @see https://www.postgresql.org/docs/17/earthdistance.html#EARTHDISTANCE-POINT-BASED
11+
* @since 3.1
12+
*
13+
* @author Sébastien Jean <sebastien.jean76@gmail.com>
14+
*/
15+
class Distance extends BaseFunction
16+
{
17+
protected function customizeFunction(): void
18+
{
19+
$this->setFunctionPrototype('(%s <@> %s)');
20+
$this->addNodeMapping('StringPrimary');
21+
$this->addNodeMapping('StringPrimary');
22+
}
23+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tests\MartinGeorgiev\Doctrine\ORM\Query\AST\Functions;
6+
7+
use Fixtures\MartinGeorgiev\Doctrine\Entity\ContainsPoints;
8+
use MartinGeorgiev\Doctrine\ORM\Query\AST\Functions\Distance;
9+
10+
class DistanceTest extends TestCase
11+
{
12+
protected function getStringFunctions(): array
13+
{
14+
return [
15+
'DISTANCE' => Distance::class,
16+
];
17+
}
18+
19+
protected function getExpectedSqlStatements(): array
20+
{
21+
return [
22+
"SELECT (c0_.point <@> '(2.320041, 48.858889)') AS sclr_0 FROM ContainsPoints c0_",
23+
];
24+
}
25+
26+
protected function getDqlStatements(): array
27+
{
28+
return [
29+
\sprintf("SELECT DISTANCE(e.point, '(2.320041, 48.858889)') FROM %s e", ContainsPoints::class),
30+
];
31+
}
32+
}

0 commit comments

Comments
 (0)