mirror of
https://github.com/django/django.git
synced 2025-10-31 09:41:08 +00:00
Fixed #21181 -- Added Collate database function.
Thanks Simon Charette for reviews.
This commit is contained in:
committed by
Mariusz Felisiak
parent
60626162f7
commit
63300f7e68
@@ -302,6 +302,13 @@ class BaseDatabaseFeatures:
|
||||
# {'d': [{'f': 'g'}]}?
|
||||
json_key_contains_list_matching_requires_list = False
|
||||
|
||||
# Collation names for use by the Django test suite.
|
||||
test_collations = {
|
||||
'ci': None, # Case-insensitive.
|
||||
'cs': None, # Case-sensitive.
|
||||
'swedish-ci': None # Swedish case-insensitive.
|
||||
}
|
||||
|
||||
def __init__(self, connection):
|
||||
self.connection = connection
|
||||
|
||||
|
||||
@@ -44,6 +44,10 @@ class DatabaseFeatures(BaseDatabaseFeatures):
|
||||
supports_partial_indexes = False
|
||||
supports_order_by_nulls_modifier = False
|
||||
order_by_nulls_first = True
|
||||
test_collations = {
|
||||
'ci': 'utf8_general_ci',
|
||||
'swedish-ci': 'utf8_swedish_ci',
|
||||
}
|
||||
|
||||
@cached_property
|
||||
def _mysql_storage_engine(self):
|
||||
|
||||
@@ -61,6 +61,11 @@ class DatabaseFeatures(BaseDatabaseFeatures):
|
||||
supports_boolean_expr_in_select_clause = False
|
||||
supports_primitives_in_json_field = False
|
||||
supports_json_field_contains = False
|
||||
test_collations = {
|
||||
'ci': 'BINARY_CI',
|
||||
'cs': 'BINARY',
|
||||
'swedish_ci': 'SWEDISH_CI',
|
||||
}
|
||||
|
||||
@cached_property
|
||||
def introspected_field_types(self):
|
||||
|
||||
@@ -58,6 +58,9 @@ class DatabaseFeatures(BaseDatabaseFeatures):
|
||||
supports_deferrable_unique_constraints = True
|
||||
has_json_operators = True
|
||||
json_key_contains_list_matching_requires_list = True
|
||||
test_collations = {
|
||||
'swedish-ci': 'sv-x-icu',
|
||||
}
|
||||
|
||||
@cached_property
|
||||
def introspected_field_types(self):
|
||||
|
||||
@@ -44,6 +44,10 @@ class DatabaseFeatures(BaseDatabaseFeatures):
|
||||
supports_order_by_nulls_modifier = Database.sqlite_version_info >= (3, 30, 0)
|
||||
order_by_nulls_first = True
|
||||
supports_json_field_contains = False
|
||||
test_collations = {
|
||||
'ci': 'nocase',
|
||||
'cs': 'binary',
|
||||
}
|
||||
|
||||
@cached_property
|
||||
def supports_atomic_references_rename(self):
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from .comparison import Cast, Coalesce, Greatest, Least, NullIf
|
||||
from .comparison import Cast, Coalesce, Collate, Greatest, Least, NullIf
|
||||
from .datetime import (
|
||||
Extract, ExtractDay, ExtractHour, ExtractIsoWeekDay, ExtractIsoYear,
|
||||
ExtractMinute, ExtractMonth, ExtractQuarter, ExtractSecond, ExtractWeek,
|
||||
@@ -22,7 +22,7 @@ from .window import (
|
||||
|
||||
__all__ = [
|
||||
# comparison and conversion
|
||||
'Cast', 'Coalesce', 'Greatest', 'Least', 'NullIf',
|
||||
'Cast', 'Coalesce', 'Collate', 'Greatest', 'Least', 'NullIf',
|
||||
# datetime
|
||||
'Extract', 'ExtractDay', 'ExtractHour', 'ExtractMinute', 'ExtractMonth',
|
||||
'ExtractQuarter', 'ExtractSecond', 'ExtractWeek', 'ExtractIsoWeekDay',
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
"""Database functions that do comparisons or type conversions."""
|
||||
from django.db.models.expressions import Func, Value
|
||||
from django.utils.regex_helper import _lazy_re_compile
|
||||
|
||||
|
||||
class Cast(Func):
|
||||
@@ -74,6 +75,23 @@ class Coalesce(Func):
|
||||
return self.as_sql(compiler, connection, **extra_context)
|
||||
|
||||
|
||||
class Collate(Func):
|
||||
function = 'COLLATE'
|
||||
template = '%(expressions)s %(function)s %(collation)s'
|
||||
# Inspired from https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS
|
||||
collation_re = _lazy_re_compile(r'^[\w\-]+$')
|
||||
|
||||
def __init__(self, expression, collation):
|
||||
if not (collation and self.collation_re.match(collation)):
|
||||
raise ValueError('Invalid collation name: %r.' % collation)
|
||||
self.collation = collation
|
||||
super().__init__(expression)
|
||||
|
||||
def as_sql(self, compiler, connection, **extra_context):
|
||||
extra_context.setdefault('collation', connection.ops.quote_name(self.collation))
|
||||
return super().as_sql(compiler, connection, **extra_context)
|
||||
|
||||
|
||||
class Greatest(Func):
|
||||
"""
|
||||
Return the maximum expression.
|
||||
|
||||
Reference in New Issue
Block a user