Fixed #10842 -- Corrected parsing of version numbers for PostgreSQL 8.4beta series. Thanks to hgdeoro for the report and fix.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@10730 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
5663258de1
commit
b97178f7ec
|
@ -121,7 +121,7 @@ class DatabaseWrapper(BaseDatabaseWrapper):
|
|||
cursor.execute("SET TIME ZONE %s", [settings_dict['TIME_ZONE']])
|
||||
if not hasattr(self, '_version'):
|
||||
self.__class__._version = get_version(cursor)
|
||||
if self._version < (8, 0):
|
||||
if self._version[0:2] < [8, 0]:
|
||||
# No savepoint support for earlier version of PostgreSQL.
|
||||
self.features.uses_savepoints = False
|
||||
cursor.execute("SET client_encoding to 'UNICODE'")
|
||||
|
|
|
@ -2,8 +2,6 @@ import re
|
|||
|
||||
from django.db.backends import BaseDatabaseOperations
|
||||
|
||||
server_version_re = re.compile(r'PostgreSQL (\d{1,2})\.(\d{1,2})\.?(\d{1,2})?')
|
||||
|
||||
# This DatabaseOperations class lives in here instead of base.py because it's
|
||||
# used by both the 'postgresql' and 'postgresql_psycopg2' backends.
|
||||
|
||||
|
@ -14,13 +12,9 @@ class DatabaseOperations(BaseDatabaseOperations):
|
|||
def _get_postgres_version(self):
|
||||
if self._postgres_version is None:
|
||||
from django.db import connection
|
||||
from django.db.backends.postgresql.version import get_version
|
||||
cursor = connection.cursor()
|
||||
cursor.execute("SELECT version()")
|
||||
version_string = cursor.fetchone()[0]
|
||||
m = server_version_re.match(version_string)
|
||||
if not m:
|
||||
raise Exception('Unable to determine PostgreSQL version from version() function string: %r' % version_string)
|
||||
self._postgres_version = [int(val) for val in m.groups() if val]
|
||||
self._postgres_version = get_version(cursor)
|
||||
return self._postgres_version
|
||||
postgres_version = property(_get_postgres_version)
|
||||
|
||||
|
@ -72,7 +66,7 @@ class DatabaseOperations(BaseDatabaseOperations):
|
|||
|
||||
def sql_flush(self, style, tables, sequences):
|
||||
if tables:
|
||||
if self.postgres_version[0] >= 8 and self.postgres_version[1] >= 1:
|
||||
if self.postgres_version[0:2] >= [8,1]:
|
||||
# Postgres 8.1+ can do 'TRUNCATE x, y, z...;'. In fact, it *has to*
|
||||
# in order to be able to truncate tables referenced by a foreign
|
||||
# key in any other table. The result is a single SQL TRUNCATE
|
||||
|
@ -157,5 +151,6 @@ class DatabaseOperations(BaseDatabaseOperations):
|
|||
NotImplementedError if this is the database in use.
|
||||
"""
|
||||
if aggregate.sql_function == 'STDDEV_POP' or aggregate.sql_function == 'VAR_POP':
|
||||
if self.postgres_version[0] == 8 and self.postgres_version[1] == 2 and 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)
|
||||
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)
|
||||
|
|
|
@ -4,20 +4,28 @@ Extracts the version of the PostgreSQL server.
|
|||
|
||||
import re
|
||||
|
||||
# This reg-exp is intentionally fairly flexible here. Require only the major
|
||||
# and minor version numbers, but need to be able to handle standard stuff like:
|
||||
# This reg-exp is intentionally fairly flexible here.
|
||||
# Needs to be able to handle stuff like:
|
||||
# PostgreSQL 8.3.6
|
||||
# EnterpriseDB 8.3
|
||||
# PostgreSQL 8.3 beta4
|
||||
VERSION_RE = re.compile(r'\S+ (\d+)\.(\d+)')
|
||||
# PostgreSQL 8.4beta1
|
||||
VERSION_RE = re.compile(r'\S+ (\d+)\.(\d+)\.?(\d+)?')
|
||||
|
||||
def _parse_version(text):
|
||||
"Internal parsing method. Factored out for testing purposes."
|
||||
major, major2, minor = VERSION_RE.search(text).groups()
|
||||
try:
|
||||
return int(major), int(major2), int(minor)
|
||||
except (ValueError, TypeError):
|
||||
return int(major), int(major2), None
|
||||
|
||||
def get_version(cursor):
|
||||
"""
|
||||
Returns a tuple representing the major and minor version number of the
|
||||
server. For example, (7, 4) or (8, 3).
|
||||
Returns a tuple representing the major, minor and revision number of the
|
||||
server. For example, (7, 4, 1) or (8, 3, 4). The revision number will be
|
||||
None in the case of initial releases (e.g., 'PostgreSQL 8.3') or in the
|
||||
case of beta and prereleases ('PostgreSQL 8.4beta1').
|
||||
"""
|
||||
cursor.execute("SELECT version()")
|
||||
version = cursor.fetchone()[0]
|
||||
major, minor = VERSION_RE.search(version).groups()
|
||||
return int(major), int(minor)
|
||||
|
||||
return _parse_version(cursor.fetchone()[0])
|
||||
|
|
|
@ -105,11 +105,11 @@ class DatabaseWrapper(BaseDatabaseWrapper):
|
|||
cursor.execute("SET TIME ZONE %s", [settings_dict['TIME_ZONE']])
|
||||
if not hasattr(self, '_version'):
|
||||
self.__class__._version = get_version(cursor)
|
||||
if self._version < (8, 0):
|
||||
if self._version[0:2] < [8, 0]:
|
||||
# No savepoint support for earlier version of PostgreSQL.
|
||||
self.features.uses_savepoints = False
|
||||
if self.features.uses_autocommit:
|
||||
if self._version < (8, 2):
|
||||
if self._version[0:2] < [8, 2]:
|
||||
# FIXME: Needs extra code to do reliable model insert
|
||||
# handling, so we forbid it for now.
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
|
|
|
@ -21,7 +21,29 @@ class Callproc(unittest.TestCase):
|
|||
def connection_created_test(sender, **kwargs):
|
||||
print 'connection_created signal'
|
||||
|
||||
__test__ = {'API_TESTS': ''}
|
||||
__test__ = {'API_TESTS': """
|
||||
# Check Postgres version parsing
|
||||
>>> from django.db.backends.postgresql import version as pg_version
|
||||
|
||||
>>> pg_version._parse_version("PostgreSQL 8.3.1 on i386-apple-darwin9.2.2, compiled by GCC i686-apple-darwin9-gcc-4.0.1 (GCC) 4.0.1 (Apple Inc. build 5478)")
|
||||
(8, 3, 1)
|
||||
|
||||
>>> pg_version._parse_version("PostgreSQL 8.3.6")
|
||||
(8, 3, 6)
|
||||
|
||||
>>> pg_version._parse_version("PostgreSQL 8.3")
|
||||
(8, 3, None)
|
||||
|
||||
>>> pg_version._parse_version("EnterpriseDB 8.3")
|
||||
(8, 3, None)
|
||||
|
||||
>>> pg_version._parse_version("PostgreSQL 8.3 beta4")
|
||||
(8, 3, None)
|
||||
|
||||
>>> pg_version._parse_version("PostgreSQL 8.4beta1")
|
||||
(8, 4, None)
|
||||
|
||||
"""}
|
||||
|
||||
# Unfortunately with sqlite3 the in-memory test database cannot be
|
||||
# closed, and so it cannot be re-opened during testing, and so we
|
||||
|
|
Loading…
Reference in New Issue