Skip to content

Commit 1667f43

Browse files
authored
fix(mssql): ensure ibis.random() generates a new value per call (#10173)
1 parent 82e9ba0 commit 1667f43

File tree

5 files changed

+22
-4
lines changed

5 files changed

+22
-4
lines changed

ibis/backends/sql/compilers/mssql.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,12 @@ def to_sqlglot(
171171
def visit_RandomUUID(self, op, **_):
172172
return self.f.newid()
173173

174+
def visit_RandomScalar(self, op, **_):
175+
# By default RAND() will generate the same value for all calls within a
176+
# query. The standard way to work around this is to pass in a unique
177+
# value per call, which `CHECKSUM(NEWID())` provides.
178+
return self.f.rand(self.f.checksum(self.f.newid()))
179+
174180
def visit_StringLength(self, op, *, arg):
175181
"""The MSSQL LEN function doesn't count trailing spaces.
176182
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
SELECT
22
TOP 10
3-
NTILE(2) OVER (ORDER BY RAND() ASC) - 1 AS [new_col]
3+
NTILE(2) OVER (ORDER BY RAND(CHECKSUM(NEWID())) ASC) - 1 AS [new_col]
44
FROM [test] AS [t0]

ibis/backends/tests/snapshots/test_sql/test_selects_with_impure_operations_not_merged/mssql-random/out.sql

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ SELECT
66
FROM (
77
SELECT
88
[t0].[x],
9-
RAND() AS [y],
10-
RAND() AS [z]
9+
RAND(CHECKSUM(NEWID())) AS [y],
10+
RAND(CHECKSUM(NEWID())) AS [z]
1111
FROM [t] AS [t0]
1212
) AS [t1]

ibis/backends/tests/test_generic.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -569,7 +569,7 @@ def test_order_by(backend, alltypes, df, key, df_kwargs):
569569
backend.assert_frame_equal(result, expected)
570570

571571

572-
@pytest.mark.notimpl(["polars", "mssql", "druid"])
572+
@pytest.mark.notimpl(["polars", "druid"])
573573
@pytest.mark.notimpl(
574574
["risingwave"],
575575
raises=PsycoPg2InternalError,

ibis/backends/tests/test_numeric.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1309,6 +1309,18 @@ def test_random(con):
13091309
assert 0 <= result <= 1
13101310

13111311

1312+
@pytest.mark.notimpl(["polars"], raises=com.OperationNotDefinedError)
1313+
@pytest.mark.notimpl(["druid"], raises=PyDruidProgrammingError)
1314+
@pytest.mark.notimpl(
1315+
["risingwave"],
1316+
raises=PsycoPg2InternalError,
1317+
reason="function random() does not exist",
1318+
)
1319+
def test_random_different_per_row(alltypes):
1320+
result = alltypes.select("int_col", rand_col=ibis.random()).execute()
1321+
assert result.rand_col.nunique() > 1
1322+
1323+
13121324
@pytest.mark.parametrize(
13131325
("ibis_func", "pandas_func"),
13141326
[

0 commit comments

Comments
 (0)