From 59c1a6daf1e657a01aefd8b98714a703a1b1e969 Mon Sep 17 00:00:00 2001 From: Daniel Mesejo Date: Fri, 14 Nov 2025 16:50:30 +0100 Subject: [PATCH] fix(sqlite): precision loss in divide --- ibis/backends/sql/compilers/sqlite.py | 8 ++++++++ ibis/backends/sqlite/tests/test_numeric.py | 22 ++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 ibis/backends/sqlite/tests/test_numeric.py diff --git a/ibis/backends/sql/compilers/sqlite.py b/ibis/backends/sql/compilers/sqlite.py index ee61e026d7c0..b6d35c23342d 100644 --- a/ibis/backends/sql/compilers/sqlite.py +++ b/ibis/backends/sql/compilers/sqlite.py @@ -545,5 +545,13 @@ def visit_DateDelta(self, op, *, left, right, part): ) return self.f._ibis_date_delta(left, right) + def visit_Divide(self, op, *, left, right): + left = ( + sge.cast(left, sge.DataType.Type.FLOAT, copy=False) + if all(arg.dtype.is_integer() for arg in op.args) + else left + ) + return self.binop(sge.Div, left, right) + compiler = SQLiteCompiler() diff --git a/ibis/backends/sqlite/tests/test_numeric.py b/ibis/backends/sqlite/tests/test_numeric.py new file mode 100644 index 000000000000..c96eb54f4728 --- /dev/null +++ b/ibis/backends/sqlite/tests/test_numeric.py @@ -0,0 +1,22 @@ +from __future__ import annotations + +import pandas as pd +import pandas.testing as tm + +import ibis + + +def test_divide_precision(con): + df = pd.DataFrame({"a": [10, 20, 30], "b": [2, 3, 4], "c": [5, 10, 15]}) + + t = ibis.memtable(df) + + expr = (t.a + t.b) * t.c - t.a / t.b + + actual = con.execute(expr).squeeze() + + expected = pd.Series([55.0, 223.333, 502.5]) + + tm.assert_series_equal( + actual, expected, check_exact=False, check_names=False, atol=0.001 + )