Skip to content

Commit c04b420

Browse files
authored
Merge pull request #41 from timnyborg/patch-1
Enable support for window functions
2 parents fd4b929 + 6cce3b2 commit c04b420

File tree

3 files changed

+22
-3
lines changed

3 files changed

+22
-3
lines changed

mssql/features.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ class DatabaseFeatures(BaseDatabaseFeatures):
3333
supports_index_on_text_field = False
3434
supports_json_field_contains = False
3535
supports_order_by_nulls_modifier = False
36+
supports_over_clause = True
3637
supports_paramstyle_pyformat = False
3738
supports_primitives_in_json_field = False
3839
supports_regex_backreferencing = True

mssql/functions.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@
44
import json
55

66
from django import VERSION
7-
from django.db.models import BooleanField
8-
from django.db.models.functions import Cast
7+
from django.db import NotSupportedError
8+
from django.db.models import BooleanField, Value
9+
from django.db.models.functions import Cast, NthValue
910
from django.db.models.functions.math import ATan2, Log, Ln, Mod, Round
10-
from django.db.models.expressions import Case, Exists, OrderBy, When
11+
from django.db.models.expressions import Case, Exists, OrderBy, When, Window
1112
from django.db.models.lookups import Lookup, In
1213
from django.db.models import lookups
1314

@@ -51,10 +52,21 @@ def sqlserver_mod(self, compiler, connection):
5152
)
5253

5354

55+
def sqlserver_nth_value(self, compiler, connection, **extra_content):
56+
raise NotSupportedError('This backend does not support the NthValue function')
57+
58+
5459
def sqlserver_round(self, compiler, connection, **extra_context):
5560
return self.as_sql(compiler, connection, template='%(function)s(%(expressions)s, 0)', **extra_context)
5661

5762

63+
def sqlserver_window(self, compiler, connection, template=None):
64+
# MSSQL window functions require an OVER clause with ORDER BY
65+
if self.order_by is None:
66+
self.order_by = Value('SELECT NULL')
67+
return self.as_sql(compiler, connection, template)
68+
69+
5870
def sqlserver_exists(self, compiler, connection, template=None, **extra_context):
5971
# MS SQL doesn't allow EXISTS() in the SELECT list, so wrap it with a
6072
# CASE WHEN expression. Change the template since the When expression
@@ -179,11 +191,14 @@ def json_HasKeyLookup(self, compiler, connection):
179191
Ln.as_microsoft = sqlserver_ln
180192
Log.as_microsoft = sqlserver_log
181193
Mod.as_microsoft = sqlserver_mod
194+
NthValue.as_microsoft = sqlserver_nth_value
182195
Round.as_microsoft = sqlserver_round
196+
Window.as_microsoft = sqlserver_window
183197

184198
if DJANGO3:
185199
Lookup.as_microsoft = sqlserver_lookup
186200
else:
187201
Exists.as_microsoft = sqlserver_exists
188202

189203
OrderBy.as_microsoft = sqlserver_orderby
204+

testapp/settings.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@
5454
'expressions.tests.FTimeDeltaTests.test_duration_with_datetime_microseconds',
5555
'expressions.tests.IterableLookupInnerExpressionsTests.test_expressions_in_lookups_join_choice',
5656
'expressions_case.tests.CaseExpressionTests.test_annotate_with_in_clause',
57+
'expressions_window.tests.WindowFunctionTests.test_nth_returns_null',
58+
'expressions_window.tests.WindowFunctionTests.test_nthvalue',
59+
'expressions_window.tests.WindowFunctionTests.test_range_n_preceding_and_following',
5760
'ordering.tests.OrderingTests.test_orders_nulls_first_on_filtered_subquery',
5861
'queries.test_bulk_update.BulkUpdateNoteTests.test_set_field_to_null',
5962
'get_or_create.tests.UpdateOrCreateTransactionTests.test_creation_in_transaction',

0 commit comments

Comments
 (0)