diff --git a/django/contrib/gis/db/backend/mysql/query.py b/django/contrib/gis/db/backend/mysql/query.py index 4a4cca45af..3f21478240 100644 --- a/django/contrib/gis/db/backend/mysql/query.py +++ b/django/contrib/gis/db/backend/mysql/query.py @@ -19,7 +19,8 @@ GEOM_SELECT = 'AsText(%s)' # _every_ one of these lookup types is on the _bounding box_ only. MYSQL_GIS_FUNCTIONS = { 'bbcontains' : 'MBRContains', # For consistency w/PostGIS API - 'contained' : 'MBRWithin', # (ditto) + 'bboverlaps' : 'MBROverlaps', # .. .. + 'contained' : 'MBRWithin', # .. .. 'contains' : 'MBRContains', 'disjoint' : 'MBRDisjoint', 'equals' : 'MBREqual', diff --git a/django/contrib/gis/db/models/query.py b/django/contrib/gis/db/models/query.py index e779886c92..8efc720333 100644 --- a/django/contrib/gis/db/models/query.py +++ b/django/contrib/gis/db/models/query.py @@ -601,14 +601,16 @@ class GeoQuerySet(QuerySet): column. Takes into account if the geographic field is in a ForeignKey relation to the current model. """ + # If this is an aggregate spatial query, the flag needs to be + # set on the `GeoQuery` object of this queryset. + if aggregate: self.query.aggregate = True + # Is this operation going to be on a related geographic field? if not geo_field in self.model._meta.fields: # If so, it'll have to be added to the select related information # (e.g., if 'location__point' was given as the field name). self.query.add_select_related([field_name]) self.query.pre_sql_setup() - # Can't non-aggregate and aggregate selections together. - if aggregate: self.query.aggregate = True rel_table, rel_col = self.query.related_select_cols[self.query.related_select_fields.index(geo_field)] return self.query._field_column(geo_field, rel_table) else: diff --git a/django/contrib/gis/db/models/sql/query.py b/django/contrib/gis/db/models/sql/query.py index f1b4de546f..d5ea54e116 100644 --- a/django/contrib/gis/db/models/sql/query.py +++ b/django/contrib/gis/db/models/sql/query.py @@ -147,6 +147,16 @@ class GeoQuery(sql.Query): col_aliases.add(field.column) return result, aliases + def get_ordering(self): + """ + This routine is overridden to disable ordering for aggregate + spatial queries. + """ + if not self.aggregate: + return super(GeoQuery, self).get_ordering() + else: + return () + def resolve_columns(self, row, fields=()): """ This routine is necessary so that distances and geometries returned diff --git a/django/contrib/gis/tests/geoapp/tests.py b/django/contrib/gis/tests/geoapp/tests.py index e2fd392f3a..82dc5e9a9e 100644 --- a/django/contrib/gis/tests/geoapp/tests.py +++ b/django/contrib/gis/tests/geoapp/tests.py @@ -431,8 +431,11 @@ class GeoModelTest(unittest.TestCase): union2 = fromstr('MULTIPOINT(-96.801611 32.782057,-95.363151 29.763374,-98.493183 29.424170)') qs = City.objects.filter(point__within=tx) self.assertRaises(TypeError, qs.unionagg, 'name') - u1 = qs.unionagg(field_name='point') - u2 = qs.unionagg() + # Using `field_name` keyword argument in one query and specifying an + # order in the other (which should not be used because this is + # an aggregate method on a spatial column) + u1 = qs.unionagg(field_name='point') + u2 = qs.order_by('name').unionagg() tol = 0.00001 if SpatialBackend.oracle: union = union2