Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions mssql/features.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class DatabaseFeatures(BaseDatabaseFeatures):
supports_index_on_text_field = False
supports_json_field_contains = False
supports_order_by_nulls_modifier = False
supports_over_clause = True
supports_paramstyle_pyformat = False
supports_primitives_in_json_field = False
supports_regex_backreferencing = True
Expand Down
21 changes: 18 additions & 3 deletions mssql/functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@
import json

from django import VERSION
from django.db.models import BooleanField
from django.db.models.functions import Cast
from django.db import NotSupportedError
from django.db.models import BooleanField, Value
from django.db.models.functions import Cast, NthValue
from django.db.models.functions.math import ATan2, Log, Ln, Mod, Round
from django.db.models.expressions import Case, Exists, OrderBy, When
from django.db.models.expressions import Case, Exists, OrderBy, When, Window
from django.db.models.lookups import Lookup, In
from django.db.models import lookups

Expand Down Expand Up @@ -51,10 +52,21 @@ def sqlserver_mod(self, compiler, connection):
)


def sqlserver_nth_value(self, compiler, connection, **extra_content):
raise NotSupportedError('This backend does not support the NthValue function')


def sqlserver_round(self, compiler, connection, **extra_context):
return self.as_sql(compiler, connection, template='%(function)s(%(expressions)s, 0)', **extra_context)


def sqlserver_window(self, compiler, connection, template=None):
# MSSQL window functions require an OVER clause with ORDER BY
if self.order_by is None:
self.order_by = Value('SELECT NULL')
return self.as_sql(compiler, connection, template)


def sqlserver_exists(self, compiler, connection, template=None, **extra_context):
# MS SQL doesn't allow EXISTS() in the SELECT list, so wrap it with a
# CASE WHEN expression. Change the template since the When expression
Expand Down Expand Up @@ -179,11 +191,14 @@ def json_HasKeyLookup(self, compiler, connection):
Ln.as_microsoft = sqlserver_ln
Log.as_microsoft = sqlserver_log
Mod.as_microsoft = sqlserver_mod
NthValue.as_microsoft = sqlserver_nth_value
Round.as_microsoft = sqlserver_round
Window.as_microsoft = sqlserver_window

if DJANGO3:
Lookup.as_microsoft = sqlserver_lookup
else:
Exists.as_microsoft = sqlserver_exists

OrderBy.as_microsoft = sqlserver_orderby

3 changes: 3 additions & 0 deletions testapp/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@
'expressions.tests.FTimeDeltaTests.test_duration_with_datetime_microseconds',
'expressions.tests.IterableLookupInnerExpressionsTests.test_expressions_in_lookups_join_choice',
'expressions_case.tests.CaseExpressionTests.test_annotate_with_in_clause',
'expressions_window.tests.WindowFunctionTests.test_nth_returns_null',
'expressions_window.tests.WindowFunctionTests.test_nthvalue',
'expressions_window.tests.WindowFunctionTests.test_range_n_preceding_and_following',
'ordering.tests.OrderingTests.test_orders_nulls_first_on_filtered_subquery',
'queries.test_bulk_update.BulkUpdateNoteTests.test_set_field_to_null',
'get_or_create.tests.UpdateOrCreateTransactionTests.test_creation_in_transaction',
Expand Down