|
| 1 | +from django.db.models.aggregates import Avg, Count, StdDev, Variance |
1 | 2 | from django.db.models.expressions import Ref, Value |
| 3 | +from django.db.models.functions import ConcatPair, Greatest, Least, Length, Substr |
2 | 4 | from django.db.models.sql import compiler |
3 | 5 | from django.db.transaction import TransactionManagementError |
4 | 6 | from django.db.utils import DatabaseError |
5 | 7 | from django.utils import six |
6 | 8 |
|
7 | 9 |
|
| 10 | +def _as_sql_agv(self, compiler, connection): |
| 11 | + return self.as_sql(compiler, connection, template='%(function)s(CONVERT(float, %(field)s))') |
| 12 | + |
| 13 | +def _as_sql_concatpair(self, compiler, connection): |
| 14 | + if connection.sql_server_version < 2012: |
| 15 | + node = self.coalesce() |
| 16 | + node.arg_joiner = ' + ' |
| 17 | + return node.as_sql(compiler, connection, template='%(expressions)s') |
| 18 | + else: |
| 19 | + return self.as_sql(compiler, connection) |
| 20 | + |
| 21 | +def _as_sql_count(self, compiler, connection): |
| 22 | + return self.as_sql(compiler, connection, function='COUNT_BIG') |
| 23 | + |
| 24 | +def _as_sql_greatest(self, compiler, connection): |
| 25 | + # SQL Server does not provide GREATEST function, |
| 26 | + # so we emulate it with a table value constructor |
| 27 | + # https://msdn.microsoft.com/en-us/library/dd776382.aspx |
| 28 | + self.arg_joiner = '), (' |
| 29 | + template='(SELECT MAX(value) FROM (VALUES (%(expressions)s)) AS _%(function)s(value))' |
| 30 | + return self.as_sql(compiler, connection, template=template) |
| 31 | + |
| 32 | +def _as_sql_least(self, compiler, connection): |
| 33 | + # SQL Server does not provide LEAST function, |
| 34 | + # so we emulate it with a table value constructor |
| 35 | + # https://msdn.microsoft.com/en-us/library/dd776382.aspx |
| 36 | + self.arg_joiner = '), (' |
| 37 | + template='(SELECT MIN(value) FROM (VALUES (%(expressions)s)) AS _%(function)s(value))' |
| 38 | + return self.as_sql(compiler, connection, template=template) |
| 39 | + |
| 40 | +def _as_sql_length(self, compiler, connection): |
| 41 | + return self.as_sql(compiler, connection, function='LEN') |
| 42 | + |
| 43 | +def _as_sql_stddev(self, compiler, connection): |
| 44 | + function = 'STDEV' |
| 45 | + if self.function == 'STDDEV_POP': |
| 46 | + function = '%sP' % function |
| 47 | + return self.as_sql(compiler, connection, function=function) |
| 48 | + |
| 49 | +def _as_sql_substr(self, compiler, connection): |
| 50 | + if len(self.get_source_expressions()) < 3: |
| 51 | + self.get_source_expressions().append(Value(2**31-1)) |
| 52 | + return self.as_sql(compiler, connection) |
| 53 | + |
| 54 | +def _as_sql_variance(self, compiler, connection): |
| 55 | + function = 'VAR' |
| 56 | + if self.function == 'VAR_POP': |
| 57 | + function = '%sP' % function |
| 58 | + return self.as_sql(compiler, connection, function=function) |
| 59 | + |
| 60 | + |
8 | 61 | class SQLCompiler(compiler.SQLCompiler): |
9 | 62 |
|
10 | 63 | def as_sql(self, with_limits=True, with_col_aliases=False, subquery=False): |
@@ -161,36 +214,28 @@ def compile(self, node, select_format=False): |
161 | 214 | return super(SQLCompiler, self).compile(node, select_format) |
162 | 215 |
|
163 | 216 | def _as_microsoft(self, node): |
164 | | - if hasattr(node, 'function'): |
165 | | - if node.function == 'AVG': |
166 | | - node.template = '%(function)s(CONVERT(float, %(field)s))' |
167 | | - elif node.function == 'CONCAT': |
168 | | - if self.connection.sql_server_version < 2012: |
169 | | - node.arg_joiner = ' + ' |
170 | | - node.template = '%(expressions)s' |
171 | | - node = node.coalesce() |
172 | | - # SQL Server does not provide GREATEST/LEAST functions, |
173 | | - # so we emulate them with table value constructors |
174 | | - # https://msdn.microsoft.com/en-us/library/dd776382.aspx |
175 | | - elif node.function == 'GREATEST': |
176 | | - node.arg_joiner = '), (' |
177 | | - node.template = '(SELECT MAX(value) FROM (VALUES (%(expressions)s)) AS _%(function)s(value))' |
178 | | - elif node.function == 'LEAST': |
179 | | - node.arg_joiner = '), (' |
180 | | - node.template = '(SELECT MIN(value) FROM (VALUES (%(expressions)s)) AS _%(function)s(value))' |
181 | | - elif node.function == 'LENGTH': |
182 | | - node.function = 'LEN' |
183 | | - elif node.function == 'STDDEV_SAMP': |
184 | | - node.function = 'STDEV' |
185 | | - elif node.function == 'STDDEV_POP': |
186 | | - node.function = 'STDEVP' |
187 | | - elif node.function == 'SUBSTRING': |
188 | | - if len(node.get_source_expressions()) < 3: |
189 | | - node.get_source_expressions().append(Value(2**31-1)) |
190 | | - elif node.function == 'VAR_SAMP': |
191 | | - node.function = 'VAR' |
192 | | - elif node.function == 'VAR_POP': |
193 | | - node.function = 'VARP' |
| 217 | + as_microsoft = None |
| 218 | + if isinstance(node, Avg): |
| 219 | + as_microsoft = _as_sql_agv |
| 220 | + elif isinstance(node, ConcatPair): |
| 221 | + as_microsoft = _as_sql_concatpair |
| 222 | + elif isinstance(node, Count): |
| 223 | + as_microsoft = _as_sql_count |
| 224 | + elif isinstance(node, Greatest): |
| 225 | + as_microsoft = _as_sql_greatest |
| 226 | + elif isinstance(node, Least): |
| 227 | + as_microsoft = _as_sql_least |
| 228 | + elif isinstance(node, Length): |
| 229 | + as_microsoft = _as_sql_length |
| 230 | + elif isinstance(node, StdDev): |
| 231 | + as_microsoft = _as_sql_stddev |
| 232 | + elif isinstance(node, Substr): |
| 233 | + as_microsoft = _as_sql_substr |
| 234 | + elif isinstance(node, Variance): |
| 235 | + as_microsoft = _as_sql_variance |
| 236 | + if as_microsoft: |
| 237 | + node = node.copy() |
| 238 | + node.as_microsoft = six.create_bound_method(as_microsoft, node) |
194 | 239 | return node |
195 | 240 |
|
196 | 241 |
|
|
0 commit comments