diff --git a/django/db/backends/postgresql/base.py b/django/db/backends/postgresql/base.py
index afb7432..19d5ea7 100644
a
|
b
|
class DatabaseWrapper(BaseDatabaseWrapper):
|
121 | 121 | cursor.execute("SET TIME ZONE %s", [settings_dict['TIME_ZONE']]) |
122 | 122 | if not hasattr(self, '_version'): |
123 | 123 | self.__class__._version = get_version(cursor) |
124 | | if self._version < (8, 0): |
| 124 | if self._version[0:2] < (8, 0): |
125 | 125 | # No savepoint support for earlier version of PostgreSQL. |
126 | 126 | self.features.uses_savepoints = False |
127 | 127 | cursor.execute("SET client_encoding to 'UNICODE'") |
diff --git a/django/db/backends/postgresql/operations.py b/django/db/backends/postgresql/operations.py
index 3582460..ad75ef2 100644
a
|
b
|
import re
|
2 | 2 | |
3 | 3 | from django.db.backends import BaseDatabaseOperations |
4 | 4 | |
5 | | server_version_re = re.compile(r'PostgreSQL (\d{1,2})\.(\d{1,2})\.?(\d{1,2})?') |
6 | | |
7 | 5 | # This DatabaseOperations class lives in here instead of base.py because it's |
8 | 6 | # used by both the 'postgresql' and 'postgresql_psycopg2' backends. |
9 | 7 | |
… |
… |
class DatabaseOperations(BaseDatabaseOperations):
|
14 | 12 | def _get_postgres_version(self): |
15 | 13 | if self._postgres_version is None: |
16 | 14 | from django.db import connection |
| 15 | from django.db.backends.postgresql.version import get_version |
17 | 16 | cursor = connection.cursor() |
18 | | cursor.execute("SELECT version()") |
19 | | version_string = cursor.fetchone()[0] |
20 | | m = server_version_re.match(version_string) |
21 | | if not m: |
22 | | raise Exception('Unable to determine PostgreSQL version from version() function string: %r' % version_string) |
23 | | self._postgres_version = [int(val) for val in m.groups() if val] |
| 17 | self._postgres_version = get_version(cursor) |
24 | 18 | return self._postgres_version |
25 | 19 | postgres_version = property(_get_postgres_version) |
26 | 20 | |
… |
… |
class DatabaseOperations(BaseDatabaseOperations):
|
72 | 66 | |
73 | 67 | def sql_flush(self, style, tables, sequences): |
74 | 68 | if tables: |
75 | | if self.postgres_version[0] >= 8 and self.postgres_version[1] >= 1: |
| 69 | if (self.postgres_version[0] == 8 and self.postgres_version[1] >= 1) or \ |
| 70 | self.postgres_version[0] > 8: |
76 | 71 | # Postgres 8.1+ can do 'TRUNCATE x, y, z...;'. In fact, it *has to* |
77 | 72 | # in order to be able to truncate tables referenced by a foreign |
78 | 73 | # key in any other table. The result is a single SQL TRUNCATE |
… |
… |
class DatabaseOperations(BaseDatabaseOperations):
|
157 | 152 | NotImplementedError if this is the database in use. |
158 | 153 | """ |
159 | 154 | if aggregate.sql_function == 'STDDEV_POP' or aggregate.sql_function == 'VAR_POP': |
160 | | if self.postgres_version[0] == 8 and self.postgres_version[1] == 2 and self.postgres_version[2] <= 4: |
161 | | 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) |
| 155 | if self.postgres_version[0] == 8 and self.postgres_version[1] == 2: |
| 156 | if self.postgres_version[2] is None: |
| 157 | raise NotImplementedError('PostgreSQL 8.2 to 8.2.4 is known to have a faulty implementation of %s. Please upgrade your version of PostgreSQL. Additionally, we couldn\'t get the full version of your PostgreSQL 8.2.X' % aggregate.sql_function) |
| 158 | elif self.postgres_version[2] <= 4: |
| 159 | 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/django/db/backends/postgresql/version.py b/django/db/backends/postgresql/version.py
index ed2ad9e..4152a61 100644
a
|
b
|
import re
|
9 | 9 | # PostgreSQL 8.3.6 |
10 | 10 | # EnterpriseDB 8.3 |
11 | 11 | # PostgreSQL 8.3 beta4 |
12 | | VERSION_RE = re.compile(r'\S+ (\d+)\.(\d+)') |
| 12 | # PostgreSQL 8.4beta1 |
| 13 | VERSION_RE = re.compile(r'\S+ (\d+)\.(\d+)\.?(\d+)?') |
13 | 14 | |
14 | 15 | def get_version(cursor): |
15 | 16 | """ |
16 | | Returns a tuple representing the major and minor version number of the |
17 | | server. For example, (7, 4) or (8, 3). |
| 17 | Returns a tuple representing the two major and the minor version number of the |
| 18 | server. For example, (7, 4, 0) or (8, 3, 4). In some cases, the minor version |
| 19 | could be None: 'PostgreSQL 8.4beta1' will return ('8', '4', None) |
18 | 20 | """ |
19 | 21 | cursor.execute("SELECT version()") |
20 | 22 | version = cursor.fetchone()[0] |
21 | | major, minor = VERSION_RE.search(version).groups() |
22 | | return int(major), int(minor) |
23 | | |
| 23 | major, major2, minor = VERSION_RE.search(version).groups() |
| 24 | try: |
| 25 | return int(major), int(major2), int(minor) |
| 26 | except (ValueError, TypeError): |
| 27 | return int(major), int(major2), None |
diff --git a/django/db/backends/postgresql_psycopg2/base.py b/django/db/backends/postgresql_psycopg2/base.py
index 4d6a1e2..8dbe915 100644
a
|
b
|
class DatabaseWrapper(BaseDatabaseWrapper):
|
104 | 104 | cursor.execute("SET TIME ZONE %s", [settings_dict['TIME_ZONE']]) |
105 | 105 | if not hasattr(self, '_version'): |
106 | 106 | self.__class__._version = get_version(cursor) |
107 | | if self._version < (8, 0): |
| 107 | if self._version[0:2] < (8, 0): |
108 | 108 | # No savepoint support for earlier version of PostgreSQL. |
109 | 109 | self.features.uses_savepoints = False |
110 | 110 | if self.features.uses_autocommit: |
111 | | if self._version < (8, 2): |
| 111 | if self._version[0:2] < (8, 2): |
112 | 112 | # FIXME: Needs extra code to do reliable model insert |
113 | 113 | # handling, so we forbid it for now. |
114 | 114 | from django.core.exceptions import ImproperlyConfigured |