From 8c2db4ab0f87643765b6bffac7c524f5e2e54d65 Mon Sep 17 00:00:00 2001 From: Russell Keith-Magee Date: Sun, 10 May 2009 09:22:53 +0000 Subject: [PATCH] Fixed #10906 -- Added a check for PostgreSQL pre 8.2 when using StdDev/Variance aggregates. Thanks to Richard Davies for the report and patch. git-svn-id: http://code.djangoproject.com/svn/django/trunk@10731 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/db/backends/postgresql/operations.py | 9 ++++++- .../aggregation_regress/models.py | 24 +++++++++++++++---- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/django/db/backends/postgresql/operations.py b/django/db/backends/postgresql/operations.py index 7b3a6c4413..593fb6ad74 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 2a23b922b4..4476b86d64 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...}