Fixed #30712 -- Allowed BLOB/TEXT defaults on MySQL 8.0.13+.
This commit is contained in:
parent
5e2e57a5a1
commit
6b16c91157
|
@ -16,8 +16,8 @@ class MySQLGISSchemaEditor(DatabaseSchemaEditor):
|
|||
self.geometry_sql = []
|
||||
|
||||
def skip_default(self, field):
|
||||
# Geometry fields are stored as BLOB/TEXT, for which MySQL and MariaDB
|
||||
# < 10.2.1 don't support defaults.
|
||||
# Geometry fields are stored as BLOB/TEXT, for which MySQL < 8.0.13 and
|
||||
# MariaDB < 10.2.1 don't support defaults.
|
||||
if isinstance(field, GeometryField) and not self._supports_limited_data_type_defaults:
|
||||
return True
|
||||
return super().skip_default(field)
|
||||
|
|
|
@ -217,14 +217,15 @@ class BaseDatabaseSchemaEditor:
|
|||
include_default = include_default and not self.skip_default(field)
|
||||
if include_default:
|
||||
default_value = self.effective_default(field)
|
||||
column_default = ' DEFAULT ' + self._column_default_sql(field)
|
||||
if default_value is not None:
|
||||
if self.connection.features.requires_literal_defaults:
|
||||
# Some databases can't take defaults as a parameter (oracle)
|
||||
# If this is the case, the individual schema backend should
|
||||
# implement prepare_default
|
||||
sql += " DEFAULT %s" % self.prepare_default(default_value)
|
||||
sql += column_default % self.prepare_default(default_value)
|
||||
else:
|
||||
sql += " DEFAULT %s"
|
||||
sql += column_default
|
||||
params += [default_value]
|
||||
# Oracle treats the empty string ('') as null, so coerce the null
|
||||
# option whenever '' is a possible value.
|
||||
|
@ -263,6 +264,13 @@ class BaseDatabaseSchemaEditor:
|
|||
'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
|
||||
def _effective_default(field):
|
||||
# This method allows testing its logic without a connection.
|
||||
|
@ -826,7 +834,7 @@ class BaseDatabaseSchemaEditor:
|
|||
argument) a default to new_field's column.
|
||||
"""
|
||||
new_default = self.effective_default(new_field)
|
||||
default = '%s'
|
||||
default = self._column_default_sql(new_field)
|
||||
params = [new_default]
|
||||
|
||||
if drop:
|
||||
|
|
|
@ -131,8 +131,8 @@ class DatabaseWrapper(BaseDatabaseWrapper):
|
|||
}
|
||||
|
||||
# For these data types:
|
||||
# - MySQL and MariaDB < 10.2.1 don't accept default values and implicitly
|
||||
# treat them as nullable
|
||||
# - MySQL < 8.0.13 and MariaDB < 10.2.1 don't accept default values and
|
||||
# implicitly treat them as nullable
|
||||
# - all versions of MySQL and MariaDB don't support full width database
|
||||
# indexes
|
||||
_limited_data_types = (
|
||||
|
|
|
@ -54,10 +54,22 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
|
|||
|
||||
@property
|
||||
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:
|
||||
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):
|
||||
super().add_field(model, field)
|
||||
|
|
Loading…
Reference in New Issue