diff --git a/django/db/backends/postgresql/operations.py b/django/db/backends/postgresql/operations.py index 7b3a6c44138..593fb6ad74f 100644 --- a/django/db/backends/postgresql/operations.py +++ b/django/db/backends/postgresql/operations.py @@ -146,11 +146,18 @@ class DatabaseOperations(BaseDatabaseOperations): def check_aggregate_support(self, aggregate): """Check that the backend fully supports the provided aggregate. + The population and sample statistics (STDDEV_POP, STDDEV_SAMP, + VAR_POP, VAR_SAMP) were first implemented in Postgres 8.2. + The implementation of population statistics (STDDEV_POP and VAR_POP) under Postgres 8.2 - 8.2.4 is known to be faulty. Raise NotImplementedError if this is the database in use. """ - if aggregate.sql_function == 'STDDEV_POP' or aggregate.sql_function == 'VAR_POP': + if aggregate.sql_function in ('STDDEV_POP', 'STDDEV_SAMP', 'VAR_POP', 'VAR_SAMP'): + if self.postgres_version[0:2] < [8,2]: + raise NotImplementedError('PostgreSQL does not support %s prior to version 8.2. Please upgrade your version of PostgreSQL.' % aggregate.sql_function) + + if aggregate.sql_function in ('STDDEV_POP', 'VAR_POP'): if self.postgres_version[0:2] == [8,2]: if self.postgres_version[2] is None or self.postgres_version[2] <= 4: raise NotImplementedError('PostgreSQL 8.2 to 8.2.4 is known to have a faulty implementation of %s. Please upgrade your version of PostgreSQL.' % aggregate.sql_function) diff --git a/tests/regressiontests/aggregation_regress/models.py b/tests/regressiontests/aggregation_regress/models.py index 2a23b922b44..4476b86d644 100644 --- a/tests/regressiontests/aggregation_regress/models.py +++ b/tests/regressiontests/aggregation_regress/models.py @@ -1,7 +1,7 @@ # coding: utf-8 import pickle -from django.db import models +from django.db import connection, models from django.conf import settings try: @@ -321,10 +321,26 @@ FieldError: Cannot compute Avg('mean_age'): 'mean_age' is an aggregate """ } -if settings.DATABASE_ENGINE != 'sqlite3': - __test__['API_TESTS'] += """ -# Stddev and Variance are not guaranteed to be available for SQLite. +def run_stddev_tests(): + """Check to see if StdDev/Variance tests should be run. + Stddev and Variance are not guaranteed to be available for SQLite, and + are not available for PostgreSQL before 8.2. + """ + if settings.DATABASE_ENGINE == 'sqlite3': + return False + + class StdDevPop(object): + sql_function = 'STDDEV_POP' + + try: + connection.ops.check_aggregate_support(StdDevPop()) + except: + return False + return True + +if run_stddev_tests(): + __test__['API_TESTS'] += """ >>> Book.objects.aggregate(StdDev('pages')) {'pages__stddev': 311.46...}