1
0
mirror of https://github.com/django/django.git synced 2025-06-26 22:09:15 +00:00

Fixed #36471 -- Added support for __coveredby GIS lookup and Collect, GeoHash, IsValid on MariaDB 12.0.1+.

This commit is contained in:
Mariusz Felisiak 2025-06-18 17:51:08 +02:00 committed by Sarah Boyce
parent b2407e4d7d
commit 7091801e04
6 changed files with 101 additions and 66 deletions

View File

@ -45,6 +45,7 @@ class MySQLOperations(BaseSpatialOperations, DatabaseOperations):
"bboverlaps": SpatialOperator(func="MBROverlaps"), # ...
"contained": SpatialOperator(func="MBRWithin"), # ...
"contains": SpatialOperator(func="ST_Contains"),
"coveredby": SpatialOperator(func="MBRCoveredBy"),
"crosses": SpatialOperator(func="ST_Crosses"),
"disjoint": SpatialOperator(func="ST_Disjoint"),
"equals": SpatialOperator(func="ST_Equals"),
@ -57,9 +58,10 @@ class MySQLOperations(BaseSpatialOperations, DatabaseOperations):
}
if self.connection.mysql_is_mariadb:
operators["relate"] = SpatialOperator(func="ST_Relate")
if self.connection.mysql_version < (12, 0, 1):
del operators["coveredby"]
else:
operators["covers"] = SpatialOperator(func="MBRCovers")
operators["coveredby"] = SpatialOperator(func="MBRCoveredBy")
return operators
@cached_property
@ -71,7 +73,10 @@ class MySQLOperations(BaseSpatialOperations, DatabaseOperations):
models.Union,
]
is_mariadb = self.connection.mysql_is_mariadb
if is_mariadb or self.connection.mysql_version < (8, 0, 24):
if is_mariadb:
if self.connection.mysql_version < (12, 0, 1):
disallowed_aggregates.insert(0, models.Collect)
elif self.connection.mysql_version < (8, 0, 24):
disallowed_aggregates.insert(0, models.Collect)
return tuple(disallowed_aggregates)
@ -106,7 +111,8 @@ class MySQLOperations(BaseSpatialOperations, DatabaseOperations):
}
if self.connection.mysql_is_mariadb:
unsupported.remove("PointOnSurface")
unsupported.update({"GeoHash", "IsValid"})
if self.connection.mysql_version < (12, 0, 1):
unsupported.update({"GeoHash", "IsValid"})
return unsupported
def geo_db_type(self, f):

View File

@ -339,42 +339,42 @@ divided into the three categories described in the :ref:`raster lookup details
<spatial-lookup-raster>`: native support ``N``, bilateral native support ``B``,
and geometry conversion support ``C``.
================================= ========= ======== ========== ============ ========== ========
Lookup Type PostGIS Oracle MariaDB MySQL [#]_ SpatiaLite PGRaster
================================= ========= ======== ========== ============ ========== ========
:lookup:`bbcontains` X X X X N
:lookup:`bboverlaps` X X X X N
:lookup:`contained` X X X X N
:lookup:`contains <gis-contains>` X X X X X B
:lookup:`contains_properly` X B
:lookup:`coveredby` X X X X B
:lookup:`covers` X X X X B
:lookup:`crosses` X X X X C
:lookup:`disjoint` X X X X X B
:lookup:`distance_gt` X X X X X N
:lookup:`distance_gte` X X X X X N
:lookup:`distance_lt` X X X X X N
:lookup:`distance_lte` X X X X X N
:lookup:`dwithin` X X X B
:lookup:`equals` X X X X X C
:lookup:`exact <same_as>` X X X X X B
:lookup:`intersects` X X X X X B
================================= ========= ======== ============ ============ ========== ========
Lookup Type PostGIS Oracle MariaDB MySQL [#]_ SpatiaLite PGRaster
================================= ========= ======== ============ ============ ========== ========
:lookup:`bbcontains` X X X X N
:lookup:`bboverlaps` X X X X N
:lookup:`contained` X X X X N
:lookup:`contains <gis-contains>` X X X X X B
:lookup:`contains_properly` X B
:lookup:`coveredby` X X X (≥ 12.0.1) X X B
:lookup:`covers` X X X X B
:lookup:`crosses` X X X X C
:lookup:`disjoint` X X X X X B
:lookup:`distance_gt` X X X X X N
:lookup:`distance_gte` X X X X X N
:lookup:`distance_lt` X X X X X N
:lookup:`distance_lte` X X X X X N
:lookup:`dwithin` X X X B
:lookup:`equals` X X X X X C
:lookup:`exact <same_as>` X X X X X B
:lookup:`intersects` X X X X X B
:lookup:`isempty` X
:lookup:`isvalid` X X X X
:lookup:`overlaps` X X X X X B
:lookup:`relate` X X X X C
:lookup:`same_as` X X X X X B
:lookup:`touches` X X X X X B
:lookup:`within` X X X X X B
:lookup:`left` X C
:lookup:`right` X C
:lookup:`overlaps_left` X B
:lookup:`overlaps_right` X B
:lookup:`overlaps_above` X C
:lookup:`overlaps_below` X C
:lookup:`strictly_above` X C
:lookup:`strictly_below` X C
================================= ========= ======== ========== ============ ========== ========
:lookup:`isvalid` X X X (≥ 12.0.1) X X
:lookup:`overlaps` X X X X X B
:lookup:`relate` X X X X C
:lookup:`same_as` X X X X X B
:lookup:`touches` X X X X X B
:lookup:`within` X X X X X B
:lookup:`left` X C
:lookup:`right` X C
:lookup:`overlaps_left` X B
:lookup:`overlaps_right` X B
:lookup:`overlaps_above` X C
:lookup:`overlaps_below` X C
:lookup:`strictly_above` X C
:lookup:`strictly_below` X C
================================= ========= ======== ============ ============ ========== ========
.. _database-functions-compatibility:
@ -406,11 +406,11 @@ Function PostGIS Oracle MariaDB MySQL
:class:`ForcePolygonCW` X X
:class:`FromWKB` X X X X X
:class:`FromWKT` X X X X X
:class:`GeoHash` X X X (LWGEOM/RTTOPO)
:class:`GeoHash` X X (≥ 12.0.1) X X (LWGEOM/RTTOPO)
:class:`GeometryDistance` X
:class:`Intersection` X X X X X
:class:`IsEmpty` X
:class:`IsValid` X X X X
:class:`IsValid` X X X (≥ 12.0.1) X X
:class:`Length` X X X X X
:class:`LineLocatePoint` X X
:class:`MakeValid` X X (LWGEOM/RTTOPO)
@ -433,20 +433,19 @@ Aggregate Functions
-------------------
The following table provides a summary of what GIS-specific aggregate functions
are available on each spatial backend. Please note that MariaDB does not
support any of these aggregates, and is thus excluded from the table.
are available on each spatial backend.
.. currentmodule:: django.contrib.gis.db.models
======================= ======= ====== ============ ==========
Aggregate PostGIS Oracle MySQL SpatiaLite
======================= ======= ====== ============ ==========
:class:`Collect` X X (≥ 8.0.24) X
:class:`Extent` X X X
======================= ======= ====== ============ ============ ==========
Aggregate PostGIS Oracle MariaDB MySQL SpatiaLite
======================= ======= ====== ============ ============ ==========
:class:`Collect` X X (≥ 12.0.1) X (≥ 8.0.24) X
:class:`Extent` X X X
:class:`Extent3D` X
:class:`MakeLine` X X
:class:`Union` X X X
======================= ======= ====== ============ ==========
:class:`MakeLine` X X
:class:`Union` X X X
======================= ======= ====== ============ ============ ==========
.. rubric:: Footnotes
.. [#fnwkt] *See* Open Geospatial Consortium, Inc., `OpenGIS Simple Feature Specification For SQL <https://portal.ogc.org/files/?artifact_id=829>`_, Document 99-049 (May 5, 1999), at Ch. 3.2.5, p. 3-11 (SQL Textual Representation of Geometry).

View File

@ -589,7 +589,7 @@ Example:
.. class:: GeoHash(expression, precision=None, **extra)
*Availability*: `MySQL
*Availability*: MariaDB, `MySQL
<https://dev.mysql.com/doc/refman/en/spatial-geohash-functions.html#function_st-geohash>`__,
`PostGIS <https://postgis.net/docs/ST_GeoHash.html>`__, SpatiaLite
(LWGEOM/RTTOPO)
@ -602,6 +602,10 @@ result.
__ https://en.wikipedia.org/wiki/Geohash
.. versionchanged:: 6.0
MariaDB 12.0.1+ support was added.
Miscellaneous
=============
@ -620,13 +624,17 @@ geometry. Returns ``True`` if its value is empty and ``False`` otherwise.
.. class:: IsValid(expr)
*Availability*: `MySQL
*Availability*: MariaDB, `MySQL
<https://dev.mysql.com/doc/refman/en/spatial-convenience-functions.html#function_st-isvalid>`__,
`PostGIS <https://postgis.net/docs/ST_IsValid.html>`__, Oracle, SpatiaLite
Accepts a geographic field or expression and tests if the value is well formed.
Returns ``True`` if its value is a valid geometry and ``False`` otherwise.
.. versionchanged:: 6.0
MariaDB 12.0.1+ support was added.
``MemSize``
-----------

View File

@ -183,7 +183,7 @@ PostGIS ``ST_ContainsProperly(poly, geom)``
-------------
*Availability*: `PostGIS <https://postgis.net/docs/ST_CoveredBy.html>`__,
Oracle, MySQL, PGRaster (Bilateral), SpatiaLite
Oracle, MariaDB, MySQL, PGRaster (Bilateral), SpatiaLite
Tests if no point in the geometry field is outside the lookup geometry.
[#fncovers]_
@ -197,6 +197,7 @@ Backend SQL Equivalent
========== =============================
PostGIS ``ST_CoveredBy(poly, geom)``
Oracle ``SDO_COVEREDBY(poly, geom)``
MariaDB ``MBRCoveredBy(poly, geom)``
MySQL ``MBRCoveredBy(poly, geom)``
SpatiaLite ``CoveredBy(poly, geom)``
========== =============================
@ -205,6 +206,10 @@ SpatiaLite ``CoveredBy(poly, geom)``
MySQL support was added.
.. versionchanged:: 6.0
MariaDB 12.0.1+ support was added.
.. fieldlookup:: covers
``covers``
@ -374,8 +379,8 @@ Example::
``isvalid``
-----------
*Availability*: MySQL, `PostGIS <https://postgis.net/docs/ST_IsValid.html>`__,
Oracle, SpatiaLite
*Availability*: MariaDB, MySQL,
`PostGIS <https://postgis.net/docs/ST_IsValid.html>`__, Oracle, SpatiaLite
Tests if the geometry is valid.
@ -383,12 +388,16 @@ Example::
Zipcode.objects.filter(poly__isvalid=True)
========================== ================================================================
Backend SQL Equivalent
========================== ================================================================
MySQL, PostGIS, SpatiaLite ``ST_IsValid(poly)``
Oracle ``SDO_GEOM.VALIDATE_GEOMETRY_WITH_CONTEXT(poly, 0.05) = 'TRUE'``
========================== ================================================================
=================================== ================================================================
Backend SQL Equivalent
=================================== ================================================================
MariaDB, MySQL, PostGIS, SpatiaLite ``ST_IsValid(poly)``
Oracle ``SDO_GEOM.VALIDATE_GEOMETRY_WITH_CONTEXT(poly, 0.05) = 'TRUE'``
=================================== ================================================================
.. versionchanged:: 6.0
MariaDB 12.0.1+ support was added.
.. fieldlookup:: overlaps
@ -880,8 +889,8 @@ Example:
.. class:: Collect(geo_field, filter=None)
*Availability*: `PostGIS <https://postgis.net/docs/ST_Collect.html>`__, MySQL,
SpatiaLite
*Availability*: `PostGIS <https://postgis.net/docs/ST_Collect.html>`__,
MariaDB, MySQL, SpatiaLite
Returns a ``GEOMETRYCOLLECTION`` or a ``MULTI`` geometry object from the geometry
column. This is analogous to a simplified version of the :class:`Union`
@ -889,6 +898,10 @@ aggregate, except it can be several orders of magnitude faster than performing
a union because it rolls up geometries into a collection or multi object, not
caring about dissolving boundaries.
.. versionchanged:: 6.0
MariaDB 12.0.1+ support was added.
``Extent``
~~~~~~~~~~

View File

@ -76,6 +76,12 @@ Minor features
* The new :attr:`.BaseGeometryWidget.base_layer` attribute allows specifying a
JavaScript map base layer, enabling customization of map tile providers.
* :lookup:`coveredby` and :lookup:`isvalid` lookups,
:class:`~django.contrib.gis.db.models.Collect` aggregation, and
:class:`~django.contrib.gis.db.models.functions.GeoHash` and
:class:`~django.contrib.gis.db.models.functions.IsValid` database functions
are now supported on MariaDB 12.0.1+.
:mod:`django.contrib.messages`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -346,9 +346,12 @@ class RelatedGeoModelTest(TestCase):
)
)
city = qs.get(name="Aurora")
self.assertIsInstance(city.parcel_centroid, Point)
self.assertAlmostEqual(city.parcel_centroid[0], 3.2128, 4)
self.assertAlmostEqual(city.parcel_centroid[1], 1.5, 4)
if connection.ops.mariadb:
self.assertIsNone(city.parcel_centroid)
else:
self.assertIsInstance(city.parcel_centroid, Point)
self.assertAlmostEqual(city.parcel_centroid[0], 3.2128, 4)
self.assertAlmostEqual(city.parcel_centroid[1], 1.5, 4)
@skipUnlessDBFeature("supports_make_line_aggr")
def test_make_line_filter(self):