1
0
mirror of https://github.com/django/django.git synced 2025-06-05 03:29:12 +00:00

Fixed #30712 -- Allowed BLOB/TEXT defaults on MySQL 8.0.13+.

This commit is contained in:
Nasir Hussain 2019-08-17 15:49:52 +05:00 committed by Mariusz Felisiak
parent 5e2e57a5a1
commit 6b16c91157
4 changed files with 29 additions and 9 deletions

View File

@ -16,8 +16,8 @@ class MySQLGISSchemaEditor(DatabaseSchemaEditor):
self.geometry_sql = [] self.geometry_sql = []
def skip_default(self, field): def skip_default(self, field):
# Geometry fields are stored as BLOB/TEXT, for which MySQL and MariaDB # Geometry fields are stored as BLOB/TEXT, for which MySQL < 8.0.13 and
# < 10.2.1 don't support defaults. # MariaDB < 10.2.1 don't support defaults.
if isinstance(field, GeometryField) and not self._supports_limited_data_type_defaults: if isinstance(field, GeometryField) and not self._supports_limited_data_type_defaults:
return True return True
return super().skip_default(field) return super().skip_default(field)

View File

@ -217,14 +217,15 @@ class BaseDatabaseSchemaEditor:
include_default = include_default and not self.skip_default(field) include_default = include_default and not self.skip_default(field)
if include_default: if include_default:
default_value = self.effective_default(field) default_value = self.effective_default(field)
column_default = ' DEFAULT ' + self._column_default_sql(field)
if default_value is not None: if default_value is not None:
if self.connection.features.requires_literal_defaults: if self.connection.features.requires_literal_defaults:
# Some databases can't take defaults as a parameter (oracle) # Some databases can't take defaults as a parameter (oracle)
# If this is the case, the individual schema backend should # If this is the case, the individual schema backend should
# implement prepare_default # implement prepare_default
sql += " DEFAULT %s" % self.prepare_default(default_value) sql += column_default % self.prepare_default(default_value)
else: else:
sql += " DEFAULT %s" sql += column_default
params += [default_value] params += [default_value]
# Oracle treats the empty string ('') as null, so coerce the null # Oracle treats the empty string ('') as null, so coerce the null
# option whenever '' is a possible value. # option whenever '' is a possible value.
@ -263,6 +264,13 @@ class BaseDatabaseSchemaEditor:
'requires_literal_defaults must provide a prepare_default() method' 'requires_literal_defaults must provide a prepare_default() method'
) )
def _column_default_sql(self, field):
"""
Return the SQL to use in a DEFAULT clause. The resulting string should
contain a '%s' placeholder for a default value.
"""
return '%s'
@staticmethod @staticmethod
def _effective_default(field): def _effective_default(field):
# This method allows testing its logic without a connection. # This method allows testing its logic without a connection.
@ -826,7 +834,7 @@ class BaseDatabaseSchemaEditor:
argument) a default to new_field's column. argument) a default to new_field's column.
""" """
new_default = self.effective_default(new_field) new_default = self.effective_default(new_field)
default = '%s' default = self._column_default_sql(new_field)
params = [new_default] params = [new_default]
if drop: if drop:

View File

@ -131,8 +131,8 @@ class DatabaseWrapper(BaseDatabaseWrapper):
} }
# For these data types: # For these data types:
# - MySQL and MariaDB < 10.2.1 don't accept default values and implicitly # - MySQL < 8.0.13 and MariaDB < 10.2.1 don't accept default values and
# treat them as nullable # implicitly treat them as nullable
# - all versions of MySQL and MariaDB don't support full width database # - all versions of MySQL and MariaDB don't support full width database
# indexes # indexes
_limited_data_types = ( _limited_data_types = (

View File

@ -54,10 +54,22 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
@property @property
def _supports_limited_data_type_defaults(self): def _supports_limited_data_type_defaults(self):
# Only MariaDB >= 10.2.1 supports defaults for BLOB and TEXT. # MariaDB >= 10.2.1 and MySQL >= 8.0.13 supports defaults for BLOB
# and TEXT.
if self.connection.mysql_is_mariadb: if self.connection.mysql_is_mariadb:
return self.connection.mysql_version >= (10, 2, 1) return self.connection.mysql_version >= (10, 2, 1)
return False return self.connection.mysql_version >= (8, 0, 13)
def _column_default_sql(self, field):
if (
not self.connection.mysql_is_mariadb and
self._supports_limited_data_type_defaults and
self._is_limited_data_type(field)
):
# MySQL supports defaults for BLOB and TEXT columns only if the
# default value is written as an expression i.e. in parentheses.
return '(%s)'
return super()._column_default_sql(field)
def add_field(self, model, field): def add_field(self, model, field):
super().add_field(model, field) super().add_field(model, field)