diff --git a/django/contrib/gis/db/backends/mysql/schema.py b/django/contrib/gis/db/backends/mysql/schema.py index 152cbc3960a..1cc3186cb05 100644 --- a/django/contrib/gis/db/backends/mysql/schema.py +++ b/django/contrib/gis/db/backends/mysql/schema.py @@ -33,12 +33,7 @@ class MySQLGISSchemaEditor(DatabaseSchemaEditor): cursor, model._meta.db_table ) ) - qn = self.connection.ops.quote_name - sql = self.sql_add_spatial_index % { - "index": qn(self._create_spatial_index_name(model, field)), - "table": qn(model._meta.db_table), - "column": qn(field.column), - } + sql = self._create_spatial_index_sql(model, field) if supports_spatial_index: return [sql] else: @@ -51,8 +46,7 @@ class MySQLGISSchemaEditor(DatabaseSchemaEditor): def remove_field(self, model, field): if isinstance(field, GeometryField) and field.spatial_index and not field.null: - index_name = self._create_spatial_index_name(model, field) - sql = self._delete_index_sql(model, index_name) + sql = self._delete_spatial_index_sql(model, field) try: self.execute(sql) except OperationalError: @@ -66,3 +60,16 @@ class MySQLGISSchemaEditor(DatabaseSchemaEditor): def _create_spatial_index_name(self, model, field): return "%s_%s_id" % (model._meta.db_table, field.column) + + def _create_spatial_index_sql(self, model, field): + index_name = self._create_spatial_index_name(model, field) + qn = self.connection.ops.quote_name + return self.sql_add_spatial_index % { + "index": qn(index_name), + "table": qn(model._meta.db_table), + "column": qn(field.column), + } + + def _delete_spatial_index_sql(self, model, field): + index_name = self._create_spatial_index_name(model, field) + return self._delete_index_sql(model, index_name) diff --git a/django/contrib/gis/db/backends/oracle/schema.py b/django/contrib/gis/db/backends/oracle/schema.py index e17a4b19110..ef9b1aa9425 100644 --- a/django/contrib/gis/db/backends/oracle/schema.py +++ b/django/contrib/gis/db/backends/oracle/schema.py @@ -42,16 +42,7 @@ class OracleGISSchemaEditor(DatabaseSchemaEditor): def _field_indexes_sql(self, model, field): if isinstance(field, GeometryField) and field.spatial_index: - return [ - self.sql_add_spatial_index - % { - "index": self.quote_name( - self._create_spatial_index_name(model, field) - ), - "table": self.quote_name(model._meta.db_table), - "column": self.quote_name(field.column), - } - ] + return [self._create_spatial_index_sql(model, field)] return super()._field_indexes_sql(model, field) def column_sql(self, model, field, include_default=False): @@ -99,8 +90,7 @@ class OracleGISSchemaEditor(DatabaseSchemaEditor): } ) if field.spatial_index: - index_name = self._create_spatial_index_name(model, field) - self.execute(self._delete_index_sql(model, index_name)) + self.execute(self._delete_spatial_index_sql(model, field)) super().remove_field(model, field) def run_geometry_sql(self): @@ -114,3 +104,15 @@ class OracleGISSchemaEditor(DatabaseSchemaEditor): return truncate_name( "%s_%s_id" % (strip_quotes(model._meta.db_table), field.column), 30 ) + + def _create_spatial_index_sql(self, model, field): + index_name = self._create_spatial_index_name(model, field) + return self.sql_add_spatial_index % { + "index": self.quote_name(index_name), + "table": self.quote_name(model._meta.db_table), + "column": self.quote_name(field.column), + } + + def _delete_spatial_index_sql(self, model, field): + index_name = self._create_spatial_index_name(model, field) + return self._delete_index_sql(model, index_name) diff --git a/django/contrib/gis/db/backends/postgis/schema.py b/django/contrib/gis/db/backends/postgis/schema.py index 765953f0c6b..5c0cd25364c 100644 --- a/django/contrib/gis/db/backends/postgis/schema.py +++ b/django/contrib/gis/db/backends/postgis/schema.py @@ -26,29 +26,7 @@ class PostGISSchemaEditor(DatabaseSchemaEditor): if fields is None or len(fields) != 1 or not hasattr(fields[0], "geodetic"): return super()._create_index_sql(model, fields=fields, **kwargs) - field = fields[0] - expressions = None - opclasses = None - if field.geom_type == "RASTER": - # For raster fields, wrap index creation SQL statement with ST_ConvexHull. - # Indexes on raster columns are based on the convex hull of the raster. - expressions = Func(Col(None, field), template=self.rast_index_template) - fields = None - elif field.dim > 2 and not field.geography: - # Use "nd" ops which are fast on multidimensional cases - opclasses = [self.geom_index_ops_nd] - name = kwargs.get("name") - if not name: - name = self._create_spatial_index_name(model, field) - - return super()._create_index_sql( - model, - fields=fields, - name=name, - using=" USING %s" % self.geom_index_type, - opclasses=opclasses, - expressions=expressions, - ) + return self._create_spatial_index_sql(model, fields[0], **kwargs) def _alter_column_type_sql( self, table, old_field, new_field, new_type, old_collation, new_collation @@ -82,3 +60,27 @@ class PostGISSchemaEditor(DatabaseSchemaEditor): def _create_spatial_index_name(self, model, field): return self._create_index_name(model._meta.db_table, [field.column], "_id") + + def _create_spatial_index_sql(self, model, field, **kwargs): + expressions = None + opclasses = None + fields = [field] + if field.geom_type == "RASTER": + # For raster fields, wrap index creation SQL statement with ST_ConvexHull. + # Indexes on raster columns are based on the convex hull of the raster. + expressions = Func(Col(None, field), template=self.rast_index_template) + fields = None + elif field.dim > 2 and not field.geography: + # Use "nd" ops which are fast on multidimensional cases + opclasses = [self.geom_index_ops_nd] + if not (name := kwargs.get("name")): + name = self._create_spatial_index_name(model, field) + + return super()._create_index_sql( + model, + fields=fields, + name=name, + using=" USING %s" % self.geom_index_type, + opclasses=opclasses, + expressions=expressions, + )