Fixed #31183 -- Added a feature flag for "<db> only supports UNBOUNDED together with PRECEDING and FOLLOWING".
This commit is contained in:
parent
2a2ea4ee18
commit
227d0c7365
|
@ -246,6 +246,7 @@ class BaseDatabaseFeatures:
|
|||
# Does the backend support window expressions (expression OVER (...))?
|
||||
supports_over_clause = False
|
||||
supports_frame_range_fixed_distance = False
|
||||
only_supports_unbounded_with_preceding_and_following = False
|
||||
|
||||
# Does the backend support CAST with precision?
|
||||
supports_cast_with_precision = True
|
||||
|
|
|
@ -658,7 +658,16 @@ class BaseDatabaseOperations:
|
|||
return self.window_frame_start(start), self.window_frame_end(end)
|
||||
|
||||
def window_frame_range_start_end(self, start=None, end=None):
|
||||
return self.window_frame_rows_start_end(start, end)
|
||||
start_, end_ = self.window_frame_rows_start_end(start, end)
|
||||
if (
|
||||
self.connection.features.only_supports_unbounded_with_preceding_and_following and
|
||||
((start and start < 0) or (end and end > 0))
|
||||
):
|
||||
raise NotSupportedError(
|
||||
'%s only supports UNBOUNDED together with PRECEDING and '
|
||||
'FOLLOWING.' % self.connection.display_name
|
||||
)
|
||||
return start_, end_
|
||||
|
||||
def explain_query_prefix(self, format=None, **options):
|
||||
if not self.connection.features.supports_explaining_query_execution:
|
||||
|
|
|
@ -52,6 +52,7 @@ class DatabaseFeatures(BaseDatabaseFeatures):
|
|||
$$ LANGUAGE plpgsql;"""
|
||||
requires_casted_case_in_updates = True
|
||||
supports_over_clause = True
|
||||
only_supports_unbounded_with_preceding_and_following = True
|
||||
supports_aggregate_filter_clause = True
|
||||
supported_explain_formats = {'JSON', 'TEXT', 'XML', 'YAML'}
|
||||
validates_explain_options = False # A query will error on invalid options.
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
from psycopg2.extras import Inet
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import NotSupportedError
|
||||
from django.db.backends.base.operations import BaseDatabaseOperations
|
||||
|
||||
|
||||
|
@ -275,15 +274,6 @@ class DatabaseOperations(BaseDatabaseOperations):
|
|||
return "(interval '1 day' * (%s - %s))" % (lhs_sql, rhs_sql), params
|
||||
return super().subtract_temporals(internal_type, lhs, rhs)
|
||||
|
||||
def window_frame_range_start_end(self, start=None, end=None):
|
||||
start_, end_ = super().window_frame_range_start_end(start, end)
|
||||
if (start and start < 0) or (end and end > 0):
|
||||
raise NotSupportedError(
|
||||
'PostgreSQL only supports UNBOUNDED together with PRECEDING '
|
||||
'and FOLLOWING.'
|
||||
)
|
||||
return start_, end_
|
||||
|
||||
def explain_query_prefix(self, format=None, **options):
|
||||
prefix = super().explain_query_prefix(format)
|
||||
extra = {}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import datetime
|
||||
from unittest import mock, skipIf, skipUnless
|
||||
from unittest import mock, skipIf
|
||||
|
||||
from django.core.exceptions import FieldError
|
||||
from django.db import NotSupportedError, connection
|
||||
|
@ -750,9 +750,9 @@ class WindowFunctionTests(TestCase):
|
|||
frame=RowRange(end='a'),
|
||||
)))
|
||||
|
||||
@skipUnless(connection.vendor == 'postgresql', 'Frame construction not allowed on PostgreSQL')
|
||||
def test_postgresql_illegal_range_frame_start(self):
|
||||
msg = 'PostgreSQL only supports UNBOUNDED together with PRECEDING and FOLLOWING.'
|
||||
@skipUnlessDBFeature('only_supports_unbounded_with_preceding_and_following')
|
||||
def test_unsupported_range_frame_start(self):
|
||||
msg = '%s only supports UNBOUNDED together with PRECEDING and FOLLOWING.' % connection.display_name
|
||||
with self.assertRaisesMessage(NotSupportedError, msg):
|
||||
list(Employee.objects.annotate(test=Window(
|
||||
expression=Sum('salary'),
|
||||
|
@ -760,9 +760,9 @@ class WindowFunctionTests(TestCase):
|
|||
frame=ValueRange(start=-1),
|
||||
)))
|
||||
|
||||
@skipUnless(connection.vendor == 'postgresql', 'Frame construction not allowed on PostgreSQL')
|
||||
def test_postgresql_illegal_range_frame_end(self):
|
||||
msg = 'PostgreSQL only supports UNBOUNDED together with PRECEDING and FOLLOWING.'
|
||||
@skipUnlessDBFeature('only_supports_unbounded_with_preceding_and_following')
|
||||
def test_unsupported_range_frame_end(self):
|
||||
msg = '%s only supports UNBOUNDED together with PRECEDING and FOLLOWING.' % connection.display_name
|
||||
with self.assertRaisesMessage(NotSupportedError, msg):
|
||||
list(Employee.objects.annotate(test=Window(
|
||||
expression=Sum('salary'),
|
||||
|
|
Loading…
Reference in New Issue