Refs #26657 -- Fixed a crash induced by invalid WKT returned by MySQL 5.7.5+.
This commit is contained in:
parent
9031a4c13b
commit
4178488881
|
@ -2,7 +2,7 @@ from django.contrib.gis.db.backends.base.adapter import WKTAdapter
|
||||||
from django.contrib.gis.db.backends.base.operations import \
|
from django.contrib.gis.db.backends.base.operations import \
|
||||||
BaseSpatialOperations
|
BaseSpatialOperations
|
||||||
from django.contrib.gis.db.backends.utils import SpatialOperator
|
from django.contrib.gis.db.backends.utils import SpatialOperator
|
||||||
from django.contrib.gis.db.models import aggregates
|
from django.contrib.gis.db.models import GeometryField, aggregates
|
||||||
from django.db.backends.mysql.operations import DatabaseOperations
|
from django.db.backends.mysql.operations import DatabaseOperations
|
||||||
from django.utils.functional import cached_property
|
from django.utils.functional import cached_property
|
||||||
|
|
||||||
|
@ -22,6 +22,10 @@ class MySQLOperations(BaseSpatialOperations, DatabaseOperations):
|
||||||
def is_mysql_5_6(self):
|
def is_mysql_5_6(self):
|
||||||
return self.connection.mysql_version < (5, 7, 6)
|
return self.connection.mysql_version < (5, 7, 6)
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def uses_invalid_empty_geometry_collection(self):
|
||||||
|
return self.connection.mysql_version >= (5, 7, 5)
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def select(self):
|
def select(self):
|
||||||
if self.is_mysql_5_5:
|
if self.is_mysql_5_5:
|
||||||
|
@ -105,3 +109,16 @@ class MySQLOperations(BaseSpatialOperations, DatabaseOperations):
|
||||||
else:
|
else:
|
||||||
placeholder = '%s(%%s)' % self.from_text
|
placeholder = '%s(%%s)' % self.from_text
|
||||||
return placeholder
|
return placeholder
|
||||||
|
|
||||||
|
def get_db_converters(self, expression):
|
||||||
|
converters = super(MySQLOperations, self).get_db_converters(expression)
|
||||||
|
if isinstance(expression.output_field, GeometryField) and self.uses_invalid_empty_geometry_collection:
|
||||||
|
converters.append(self.convert_invalid_empty_geometry_collection)
|
||||||
|
return converters
|
||||||
|
|
||||||
|
# https://dev.mysql.com/doc/refman/5.7/en/spatial-function-argument-handling.html
|
||||||
|
# MySQL 5.7.5 adds support for the empty geometry collections, but they are represented with invalid WKT.
|
||||||
|
def convert_invalid_empty_geometry_collection(self, value, expression, connection, context):
|
||||||
|
if value == b'GEOMETRYCOLLECTION()':
|
||||||
|
return b'GEOMETRYCOLLECTION EMPTY'
|
||||||
|
return value
|
||||||
|
|
|
@ -223,7 +223,7 @@ class GISFunctionsTests(TestCase):
|
||||||
geom = Point(5, 23, srid=4326)
|
geom = Point(5, 23, srid=4326)
|
||||||
qs = Country.objects.annotate(inter=functions.Intersection('mpoly', geom))
|
qs = Country.objects.annotate(inter=functions.Intersection('mpoly', geom))
|
||||||
for c in qs:
|
for c in qs:
|
||||||
if spatialite or mysql or oracle:
|
if spatialite or (mysql and not connection.ops.uses_invalid_empty_geometry_collection) or oracle:
|
||||||
# When the intersection is empty, some databases return None.
|
# When the intersection is empty, some databases return None.
|
||||||
expected = None
|
expected = None
|
||||||
else:
|
else:
|
||||||
|
|
Loading…
Reference in New Issue