Skip to content

Commit 1784f2e

Browse files
authored
Add operator class support for PostgreSQL GiST spatial indexes (#56324)
This change allows specifying an operator class when creating spatial indexes on PostgreSQL, which is required for certain data types like inet. - Add optional operatorClass parameter to Blueprint::spatialIndex() - Update PostgresGrammar to handle operator class in SQL generation - Add tests for spatial index with operator class functionality Fixes #56261
1 parent 2f70782 commit 1784f2e

File tree

3 files changed

+64
-5
lines changed

3 files changed

+64
-5
lines changed

src/Illuminate/Database/Schema/Blueprint.php

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -684,11 +684,12 @@ public function fullText($columns, $name = null, $algorithm = null)
684684
*
685685
* @param string|array $columns
686686
* @param string|null $name
687+
* @param string|null $operatorClass
687688
* @return \Illuminate\Database\Schema\IndexDefinition
688689
*/
689-
public function spatialIndex($columns, $name = null)
690+
public function spatialIndex($columns, $name = null, $operatorClass = null)
690691
{
691-
return $this->indexCommand('spatialIndex', $columns, $name);
692+
return $this->indexCommand('spatialIndex', $columns, $name, null, $operatorClass);
692693
}
693694

694695
/**
@@ -1641,15 +1642,16 @@ public function comment($comment)
16411642
}
16421643

16431644
/**
1644-
* Add a new index command to the blueprint.
1645+
* Create a new index command on the blueprint.
16451646
*
16461647
* @param string $type
16471648
* @param string|array $columns
16481649
* @param string $index
16491650
* @param string|null $algorithm
1651+
* @param string|null $operatorClass
16501652
* @return \Illuminate\Support\Fluent
16511653
*/
1652-
protected function indexCommand($type, $columns, $index, $algorithm = null)
1654+
protected function indexCommand($type, $columns, $index, $algorithm = null, $operatorClass = null)
16531655
{
16541656
$columns = (array) $columns;
16551657

@@ -1659,7 +1661,7 @@ protected function indexCommand($type, $columns, $index, $algorithm = null)
16591661
$index = $index ?: $this->createIndexName($type, $columns);
16601662

16611663
return $this->addCommand(
1662-
$type, compact('index', 'columns', 'algorithm')
1664+
$type, compact('index', 'columns', 'algorithm', 'operatorClass')
16631665
);
16641666
}
16651667

src/Illuminate/Database/Schema/Grammars/PostgresGrammar.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,9 +403,46 @@ public function compileSpatialIndex(Blueprint $blueprint, Fluent $command)
403403
{
404404
$command->algorithm = 'gist';
405405

406+
if (! is_null($command->operatorClass)) {
407+
return $this->compileIndexWithOperatorClass($blueprint, $command);
408+
}
409+
406410
return $this->compileIndex($blueprint, $command);
407411
}
408412

413+
/**
414+
* Compile a spatial index with operator class key command.
415+
*
416+
* @param \Illuminate\Database\Schema\Blueprint $blueprint
417+
* @param \Illuminate\Support\Fluent $command
418+
* @return string
419+
*/
420+
protected function compileIndexWithOperatorClass(Blueprint $blueprint, Fluent $command)
421+
{
422+
$columns = $this->columnizeWithOperatorClass($command->columns, $command->operatorClass);
423+
424+
return sprintf('create index %s on %s%s (%s)',
425+
$this->wrap($command->index),
426+
$this->wrapTable($blueprint),
427+
$command->algorithm ? ' using '.$command->algorithm : '',
428+
$columns
429+
);
430+
}
431+
432+
/**
433+
* Convert an array of column names to a delimited string with operator class.
434+
*
435+
* @param array $columns
436+
* @param string $operatorClass
437+
* @return string
438+
*/
439+
protected function columnizeWithOperatorClass(array $columns, $operatorClass)
440+
{
441+
return implode(', ', array_map(function ($column) use ($operatorClass) {
442+
return $this->wrap($column).' '.$operatorClass;
443+
}, $columns));
444+
}
445+
409446
/**
410447
* Compile a foreign key command.
411448
*

tests/Database/DatabasePostgresSchemaGrammarTest.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,26 @@ public function testAddingFluentSpatialIndex()
386386
$this->assertSame('create index "geo_coordinates_spatialindex" on "geo" using gist ("coordinates")', $statements[1]);
387387
}
388388

389+
public function testAddingSpatialIndexWithOperatorClass()
390+
{
391+
$blueprint = new Blueprint($this->getConnection(), 'geo');
392+
$blueprint->spatialIndex('coordinates', 'my_index', 'point_ops');
393+
$statements = $blueprint->toSql();
394+
395+
$this->assertCount(1, $statements);
396+
$this->assertSame('create index "my_index" on "geo" using gist ("coordinates" point_ops)', $statements[0]);
397+
}
398+
399+
public function testAddingSpatialIndexWithOperatorClassMultipleColumns()
400+
{
401+
$blueprint = new Blueprint($this->getConnection(), 'geo');
402+
$blueprint->spatialIndex(['coordinates', 'location'], 'my_index', 'point_ops');
403+
$statements = $blueprint->toSql();
404+
405+
$this->assertCount(1, $statements);
406+
$this->assertSame('create index "my_index" on "geo" using gist ("coordinates" point_ops, "location" point_ops)', $statements[0]);
407+
}
408+
389409
public function testAddingRawIndex()
390410
{
391411
$blueprint = new Blueprint($this->getConnection(), 'users');

0 commit comments

Comments
 (0)