diff --git a/django/contrib/gis/db/backends/mysql/compiler.py b/django/contrib/gis/db/backends/mysql/compiler.py new file mode 100644 index 00000000000..7079db9f6ac --- /dev/null +++ b/django/contrib/gis/db/backends/mysql/compiler.py @@ -0,0 +1,32 @@ +from django.contrib.gis.db.models.sql.compiler import GeoSQLCompiler as BaseGeoSQLCompiler +from django.db.backends.mysql import compiler + +SQLCompiler = compiler.SQLCompiler + +class GeoSQLCompiler(BaseGeoSQLCompiler, SQLCompiler): + def resolve_columns(self, row, fields=()): + """ + Integrate the cases handled both by the base GeoSQLCompiler and the + main MySQL compiler (converting 0/1 to True/False for boolean fields). + + Refs #15169. + + """ + row = BaseGeoSQLCompiler.resolve_columns(self, row, fields) + return SQLCompiler.resolve_columns(self, row, fields) + + +class SQLInsertCompiler(compiler.SQLInsertCompiler, GeoSQLCompiler): + pass + +class SQLDeleteCompiler(compiler.SQLDeleteCompiler, GeoSQLCompiler): + pass + +class SQLUpdateCompiler(compiler.SQLUpdateCompiler, GeoSQLCompiler): + pass + +class SQLAggregateCompiler(compiler.SQLAggregateCompiler, GeoSQLCompiler): + pass + +class SQLDateCompiler(compiler.SQLDateCompiler, GeoSQLCompiler): + pass diff --git a/django/contrib/gis/db/backends/mysql/operations.py b/django/contrib/gis/db/backends/mysql/operations.py index 1653636dd42..c0e5aa6691b 100644 --- a/django/contrib/gis/db/backends/mysql/operations.py +++ b/django/contrib/gis/db/backends/mysql/operations.py @@ -5,7 +5,7 @@ from django.contrib.gis.db.backends.base import BaseSpatialOperations class MySQLOperations(DatabaseOperations, BaseSpatialOperations): - compiler_module = 'django.contrib.gis.db.models.sql.compiler' + compiler_module = 'django.contrib.gis.db.backends.mysql.compiler' mysql = True name = 'mysql' select = 'AsText(%s)' diff --git a/django/contrib/gis/tests/geoapp/models.py b/django/contrib/gis/tests/geoapp/models.py index 1ac830953a7..79061e1cfc2 100644 --- a/django/contrib/gis/tests/geoapp/models.py +++ b/django/contrib/gis/tests/geoapp/models.py @@ -34,6 +34,10 @@ class Track(models.Model): objects = models.GeoManager() def __unicode__(self): return self.name +class Truth(models.Model): + val = models.BooleanField() + objects = models.GeoManager() + if not spatialite: class Feature(models.Model): name = models.CharField(max_length=20) diff --git a/django/contrib/gis/tests/geoapp/test_regress.py b/django/contrib/gis/tests/geoapp/test_regress.py index 19f31e66be3..a9d802d8f18 100644 --- a/django/contrib/gis/tests/geoapp/test_regress.py +++ b/django/contrib/gis/tests/geoapp/test_regress.py @@ -7,7 +7,7 @@ from django.contrib.gis.shortcuts import render_to_kmz from django.db.models import Count from django.test import TestCase -from .models import City, PennsylvaniaCity, State +from .models import City, PennsylvaniaCity, State, Truth class GeoRegressionTests(TestCase): @@ -64,3 +64,17 @@ class GeoRegressionTests(TestCase): "Regression for #16409. Make sure defer() and only() work with annotate()" self.assertIsInstance(list(City.objects.annotate(Count('point')).defer('name')), list) self.assertIsInstance(list(City.objects.annotate(Count('point')).only('name')), list) + + def test07_boolean_conversion(self): + "Testing Boolean value conversion with the spatial backend, see #15169." + t1 = Truth.objects.create(val=True) + t2 = Truth.objects.create(val=False) + + val1 = Truth.objects.get(pk=1).val + val2 = Truth.objects.get(pk=2).val + # verify types -- should't be 0/1 + self.assertIsInstance(val1, bool) + self.assertIsInstance(val2, bool) + # verify values + self.assertEqual(val1, True) + self.assertEqual(val2, False)