diff --git a/django/contrib/gis/db/backends/mysql/introspection.py b/django/contrib/gis/db/backends/mysql/introspection.py index ba125ec4af..9e19522267 100644 --- a/django/contrib/gis/db/backends/mysql/introspection.py +++ b/django/contrib/gis/db/backends/mysql/introspection.py @@ -29,9 +29,10 @@ class MySQLIntrospection(DatabaseIntrospection): return field_type, field_params def supports_spatial_index(self, cursor, table_name): - # Supported with MyISAM, or InnoDB on MySQL 5.7.5+ + # Supported with MyISAM/Aria, or InnoDB on MySQL 5.7.5+/MariaDB 10.2.2+ storage_engine = self.get_storage_engine(cursor, table_name) - return ( - (storage_engine == 'InnoDB' and self.connection.mysql_version >= (5, 7, 5)) or - storage_engine == 'MyISAM' - ) + if storage_engine == 'InnoDB': + return self.connection.mysql_version >= ( + (10, 2, 2) if self.connection.mysql_is_mariadb else (5, 7, 5) + ) + return storage_engine in ('MyISAM', 'Aria') diff --git a/django/contrib/gis/db/backends/mysql/operations.py b/django/contrib/gis/db/backends/mysql/operations.py index 3432444b1d..138b5a3c9f 100644 --- a/django/contrib/gis/db/backends/mysql/operations.py +++ b/django/contrib/gis/db/backends/mysql/operations.py @@ -19,10 +19,6 @@ class MySQLOperations(BaseSpatialOperations, DatabaseOperations): Adapter = WKTAdapter - @cached_property - def is_mysql_5_6(self): - return self.connection.mysql_version < (5, 7, 6) - @cached_property def select(self): return self.geom_func_prefix + 'AsBinary(%s)' @@ -33,7 +29,9 @@ class MySQLOperations(BaseSpatialOperations, DatabaseOperations): @cached_property def gis_operators(self): - MBREquals = 'MBREqual' if self.is_mysql_5_6 else 'MBREquals' + MBREquals = 'MBREqual' if ( + self.connection.mysql_is_mariadb or self.connection.mysql_version < (5, 7, 6) + ) else 'MBREquals' return { 'bbcontains': SpatialOperator(func='MBRContains'), # For consistency w/PostGIS API 'bboverlaps': SpatialOperator(func='MBROverlaps'), # ... @@ -62,7 +60,11 @@ class MySQLOperations(BaseSpatialOperations, DatabaseOperations): 'MemSize', 'Perimeter', 'PointOnSurface', 'Reverse', 'Scale', 'SnapToGrid', 'Transform', 'Translate', } - if self.connection.mysql_version < (5, 7, 5): + if self.connection.mysql_is_mariadb: + unsupported.update({'GeoHash', 'IsValid'}) + if self.connection.mysql_version < (10, 2, 4): + unsupported.add('AsGeoJSON') + elif self.connection.mysql_version < (5, 7, 5): unsupported.update({'AsGeoJSON', 'GeoHash', 'IsValid'}) return unsupported diff --git a/tests/gis_tests/inspectapp/tests.py b/tests/gis_tests/inspectapp/tests.py index f499bbdbe0..a57bfcabbd 100644 --- a/tests/gis_tests/inspectapp/tests.py +++ b/tests/gis_tests/inspectapp/tests.py @@ -141,8 +141,10 @@ class OGRInspectTest(TestCase): else: self.assertIn(' f_decimal = models.DecimalField(max_digits=0, decimal_places=0)', model_def) self.assertIn(' f_int = models.IntegerField()', model_def) - self.assertIn(' f_datetime = models.DateTimeField()', model_def) - self.assertIn(' f_time = models.TimeField()', model_def) + if connection.vendor != 'mysql' or not connection.mysql_is_mariadb: + # Probably a bug between GDAL and MariaDB on time fields. + self.assertIn(' f_datetime = models.DateTimeField()', model_def) + self.assertIn(' f_time = models.TimeField()', model_def) if connection.vendor == 'sqlite': self.assertIn(' f_float = models.CharField(max_length=0)', model_def) else: