Skip to content

Commit 1b30d21

Browse files
authored
Fix random order by issue (#142)
* Fix random order by issue https://code.djangoproject.com/ticket/33531 * Fix `expr`== None issue
1 parent ee97346 commit 1b30d21

File tree

2 files changed

+22
-2
lines changed

2 files changed

+22
-2
lines changed

mssql/compiler.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from django.db.models.aggregates import Avg, Count, StdDev, Variance
99
from django.db.models.expressions import Ref, Subquery, Value
1010
from django.db.models.functions import (
11-
Chr, ConcatPair, Greatest, Least, Length, LPad, Repeat, RPad, StrIndex, Substr, Trim
11+
Chr, ConcatPair, Greatest, Least, Length, LPad, Random, Repeat, RPad, StrIndex, Substr, Trim
1212
)
1313
from django.db.models.sql import compiler
1414
from django.db.transaction import TransactionManagementError
@@ -311,7 +311,13 @@ def as_sql(self, with_limits=True, with_col_aliases=False):
311311

312312
if order_by:
313313
ordering = []
314-
for _, (o_sql, o_params, _) in order_by:
314+
for expr, (o_sql, o_params, _) in order_by:
315+
if expr:
316+
src = next(iter(expr.get_source_expressions()))
317+
if isinstance(src, Random):
318+
# ORDER BY RAND() doesn't return rows in random order
319+
# replace it with NEWID()
320+
o_sql = o_sql.replace('RAND()', 'NEWID()')
315321
ordering.append(o_sql)
316322
params.extend(o_params)
317323
result.append('ORDER BY %s' % ', '.join(ordering))

testapp/tests/test_fields.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,17 @@ def test_order_by(self):
2020
names = Customer_name.objects.select_for_update().all()
2121
addresses = Customer_address.objects.filter(Customer_address='123 Main St', Customer_name__in=names)
2222
self.assertEqual(len(addresses), 1)
23+
24+
def test_random_order_by(self):
25+
# https://code.djangoproject.com/ticket/33531
26+
Customer_name.objects.bulk_create([
27+
Customer_name(Customer_name='Jack'),
28+
Customer_name(Customer_name='Jane'),
29+
Customer_name(Customer_name='John'),
30+
])
31+
names = []
32+
# iterate 20 times to make sure we don't get the same result
33+
for _ in range(20):
34+
names.append(list(Customer_name.objects.order_by('?')))
35+
36+
self.assertNotEqual(names.count(names[0]), 20)

0 commit comments

Comments
 (0)