@@ -171,6 +171,66 @@ def test_array_string_renders_as_array_of_string(self):
171171 )
172172
173173
174+ class TestFloatPrecisionPromotion (CompilationTestBase ):
175+ """Regression coverage for the pandas ``to_sql`` ``float64`` precision loss.
176+
177+ Databricks ``FLOAT`` is 32-bit; ``DOUBLE`` is 64-bit. SQLAlchemy's default
178+ ``visit_float`` drops the precision argument when rendering for Databricks,
179+ so ``Float(precision=53)`` (what ``pandas.DataFrame.to_sql`` emits for
180+ ``float64`` columns) was silently truncating to a 32-bit ``FLOAT`` column.
181+
182+ The fix is to promote ``Float`` to ``DOUBLE`` when ``precision > 24``,
183+ matching the SQL standard cutover from single to double precision.
184+ """
185+
186+ def test_float_with_no_precision_remains_float (self ):
187+ self ._assert_compiled_value_explicit (sqlalchemy .types .Float (), "FLOAT" )
188+
189+ def test_float_at_single_precision_boundary_remains_float (self ):
190+ """``precision=24`` is the upper bound of IEEE 754 single precision."""
191+ self ._assert_compiled_value_explicit (
192+ sqlalchemy .types .Float (precision = 24 ), "FLOAT"
193+ )
194+
195+ def test_float_above_single_precision_boundary_promotes_to_double (self ):
196+ self ._assert_compiled_value_explicit (
197+ sqlalchemy .types .Float (precision = 25 ), "DOUBLE"
198+ )
199+
200+ def test_float_precision_53_promotes_to_double (self ):
201+ """``pandas.DataFrame.to_sql`` maps ``float64`` to ``Float(precision=53)``."""
202+ self ._assert_compiled_value_explicit (
203+ sqlalchemy .types .Float (precision = 53 ), "DOUBLE"
204+ )
205+
206+ def test_uppercase_float_with_high_precision_stays_float (self ):
207+ """``sqlalchemy.types.FLOAT`` is the backend-specific 32-bit type — a
208+ caller who reaches for the uppercase form is explicitly asking for
209+ ``FLOAT``, so the precision argument should not promote it to DOUBLE.
210+ """
211+ self ._assert_compiled_value_explicit (
212+ sqlalchemy .types .FLOAT (precision = 53 ), "FLOAT"
213+ )
214+
215+ def test_double_is_unaffected_by_float_compiler (self ):
216+ """The ``@compiles(Float)`` dispatch is keyed on ``__visit_name__`` —
217+ ``Double`` has its own (``'double'``) so it must not be affected."""
218+ self ._assert_compiled_value_explicit (sqlalchemy .types .Double (), "DOUBLE" )
219+ self ._assert_compiled_value_explicit (
220+ sqlalchemy .types .Double (precision = 53 ), "DOUBLE"
221+ )
222+
223+ def test_create_table_with_float64_emits_double_column (self ):
224+ """End-to-end: what pandas ``to_sql`` of a ``float64`` column produces."""
225+ from sqlalchemy .schema import CreateTable
226+
227+ meta = MetaData ()
228+ t = Table ("df" , meta , Column ("value" , sqlalchemy .types .Float (precision = 53 )))
229+ ddl = str (CreateTable (t ).compile (dialect = self .dialect ))
230+ assert "value DOUBLE" in ddl
231+ assert "value FLOAT" not in ddl
232+
233+
174234class TestDatabricksUUID :
175235 """Regression coverage for github.com/databricks/databricks-sqlalchemy/issues/50.
176236
0 commit comments