12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 |
- """
- This file contains Microsoft SQL Server specific aggregates and overrides for
- the default Django aggregates.
- """
- from django.db.models.aggregates import Avg, StdDev, Variance
- from django.db.models.expressions import Value
- from django.db.models.functions import Length, Substr
- def as_microsoft(expression):
- """
- Decorated function is added to the provided expression as the Microsoft
- vender specific as_sql override.
- """
- def dec(func):
- setattr(expression, 'as_microsoft', func)
- return func
- return dec
- # Aggregates
- @as_microsoft(Avg)
- def cast_avg_to_float(self, compiler, connection):
- """
- Microsoft AVG doesn't cast type by default, but needs to CAST to FLOAT so
- that AVG([1, 2]) == 1.5, instead of 1.
- """
- if getattr(connection, 'cast_avg_to_float', True):
- return self.as_sql(compiler, connection, template='%(function)s(CAST(%(field)s AS FLOAT))')
- return self.as_sql(compiler, connection)
- @as_microsoft(StdDev)
- def fix_stddev_function_name(self, compiler, connection):
- """
- Fix function names to 'STDEV' or 'STDEVP' as used by mssql
- """
- function = 'STDEV'
- if self.function == 'STDDEV_POP':
- function = 'STDEVP'
- return self.as_sql(compiler, connection, function=function)
- @as_microsoft(Variance)
- def fix_variance_function_name(self, compiler, connection):
- """
- Fix function names to 'VAR' or 'VARP' as used by mssql
- """
- function = 'VAR'
- if self.function == 'VAR_POP':
- function = 'VARP'
- return self.as_sql(compiler, connection, function=function)
- # Expressions
- # Functions
- @as_microsoft(Length)
- def fix_length_function_name(self, compiler, connection):
- """
- T-SQL LEN()
- """
- self.function = 'LEN'
- return self.as_sql(compiler, connection)
- @as_microsoft(Substr)
- def ensure_three_substring_arguments(self, compiler, connection):
- """
- T-SQL SUBSTRING() requires 3 arguments. length is never implied.
- """
- if len(self.source_expressions) == 2:
- self.source_expressions.append(Value(2 ** 31 - 1))
- return self.as_sql(compiler, connection)
|