diff --git a/ibis/backends/sql/compilers/mssql.py b/ibis/backends/sql/compilers/mssql.py index 70215fed821ac..dbb0e3f9fe2c3 100644 --- a/ibis/backends/sql/compilers/mssql.py +++ b/ibis/backends/sql/compilers/mssql.py @@ -171,6 +171,12 @@ def to_sqlglot( def visit_RandomUUID(self, op, **_): return self.f.newid() + def visit_RandomScalar(self, op, **_): + # By default RAND() will generate the same value for all calls within a + # query. The standard way to work around this is to pass in a unique + # value per call, which `CHECKSUM(NEWID())` provides. + return self.f.rand(self.f.checksum(self.f.newid())) + def visit_StringLength(self, op, *, arg): """The MSSQL LEN function doesn't count trailing spaces. diff --git a/ibis/backends/tests/test_numeric.py b/ibis/backends/tests/test_numeric.py index d5c16e9d08ac1..4d23680c7cf40 100644 --- a/ibis/backends/tests/test_numeric.py +++ b/ibis/backends/tests/test_numeric.py @@ -1309,6 +1309,18 @@ def test_random(con): assert 0 <= result <= 1 +@pytest.mark.notimpl(["polars"], raises=com.OperationNotDefinedError) +@pytest.mark.notimpl(["druid"], raises=PyDruidProgrammingError) +@pytest.mark.notimpl( + ["risingwave"], + raises=PsycoPg2InternalError, + reason="function random() does not exist", +) +def test_random_different_per_row(alltypes): + result = alltypes.select("int_col", rand_col=ibis.random()).execute() + assert result.rand_col.nunique() > 1 + + @pytest.mark.parametrize( ("ibis_func", "pandas_func"), [