1
0
mirror of https://github.com/django/django.git synced 2025-10-27 07:36:08 +00:00

Fixed #34262 -- Added support for AnyValue for SQLite, MySQL, Oracle, and Postgresql 16+.

Thanks Simon Charette for the guidance and review. Thanks Tim Schilling for the
documentation review. Thanks David Wobrock for investigation and solution proposals.
This commit is contained in:
ontowhee
2025-03-15 19:23:28 -07:00
committed by Sarah Boyce
parent f603ece016
commit ddb8529415
11 changed files with 212 additions and 11 deletions

View File

@@ -266,6 +266,9 @@ class BaseDatabaseFeatures:
# delimiter along with DISTINCT.
supports_aggregate_distinct_multiple_argument = True
# Does the database support SQL 2023 ANY_VALUE in GROUP BY?
supports_any_value = False
# Does the backend support indexing a TextField?
supports_index_on_text_field = True

View File

@@ -111,16 +111,6 @@ class DatabaseFeatures(BaseDatabaseFeatures):
},
}
)
if "ONLY_FULL_GROUP_BY" in self.connection.sql_mode:
skips.update(
{
"GROUP BY cannot contain nonaggregated column when "
"ONLY_FULL_GROUP_BY mode is enabled on MySQL, see #34262.": {
"aggregation.tests.AggregateTestCase."
"test_group_by_nested_expression_with_params",
},
}
)
if self.connection.mysql_version < (8, 0, 31):
skips.update(
{
@@ -297,3 +287,7 @@ class DatabaseFeatures(BaseDatabaseFeatures):
if self.connection.mysql_is_mariadb:
return "ONLY_FULL_GROUP_BY" not in self.connection.sql_mode
return True
@cached_property
def supports_any_value(self):
return not self.connection.mysql_is_mariadb

View File

@@ -61,6 +61,7 @@ class DatabaseFeatures(BaseDatabaseFeatures):
END;
"""
supports_callproc_kwargs = True
supports_any_value = True
supports_over_clause = True
supports_frame_range_fixed_distance = True
supports_ignore_conflicts = False

View File

@@ -162,3 +162,5 @@ class DatabaseFeatures(BaseDatabaseFeatures):
supports_nulls_distinct_unique_constraints = property(
operator.attrgetter("is_postgresql_15")
)
supports_any_value = property(operator.attrgetter("is_postgresql_16"))

View File

@@ -80,6 +80,7 @@ def register(connection):
connection.create_aggregate("STDDEV_SAMP", 1, StdDevSamp)
connection.create_aggregate("VAR_POP", 1, VarPop)
connection.create_aggregate("VAR_SAMP", 1, VarSamp)
connection.create_aggregate("ANY_VALUE", 1, AnyValue)
# Some math functions are enabled by default in SQLite 3.35+.
sql = "select sqlite_compileoption_used('ENABLE_MATH_FUNCTIONS')"
if not connection.execute(sql).fetchone()[0]:
@@ -513,3 +514,8 @@ class VarPop(ListAggregate):
class VarSamp(ListAggregate):
finalize = statistics.variance
class AnyValue(ListAggregate):
def finalize(self):
return self[0]

View File

@@ -36,6 +36,7 @@ class DatabaseFeatures(BaseDatabaseFeatures):
supports_aggregate_filter_clause = True
supports_aggregate_order_by_clause = Database.sqlite_version_info >= (3, 44, 0)
supports_aggregate_distinct_multiple_argument = False
supports_any_value = True
order_by_nulls_first = True
supports_json_field_contains = False
supports_update_conflicts = True

View File

@@ -22,6 +22,7 @@ from django.db.models.functions.mixins import (
__all__ = [
"Aggregate",
"AnyValue",
"Avg",
"Count",
"Max",
@@ -229,6 +230,20 @@ class Aggregate(Func):
return options
class AnyValue(Aggregate):
function = "ANY_VALUE"
name = "AnyValue"
arity = 1
window_compatible = False
def as_sql(self, compiler, connection, **extra_context):
if not connection.features.supports_any_value:
raise NotSupportedError(
"ANY_VALUE is not supported on this database backend."
)
return super().as_sql(compiler, connection, **extra_context)
class Avg(FixDurationInputMixin, NumericOutputFieldMixin, Aggregate):
function = "AVG"
name = "Avg"