]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Clarify what float are compiled to
authorFederico Caselli <cfederico87@gmail.com>
Wed, 6 Sep 2023 20:18:29 +0000 (22:18 +0200)
committerFederico Caselli <cfederico87@gmail.com>
Thu, 7 Sep 2023 18:25:09 +0000 (20:25 +0200)
Change-Id: I8b1c083ae7ccf803a94401f57a00d058a8ce7aae
References: #10300

doc/build/dialects/postgresql.rst
lib/sqlalchemy/dialects/oracle/__init__.py
lib/sqlalchemy/sql/sqltypes.py
test/dialect/mssql/test_types.py
test/dialect/mysql/test_types.py
test/dialect/oracle/test_types.py
test/dialect/postgresql/test_types.py

index 3e981f04aa7f73adf4b1802f166df656bf6ed27a..0575837185c205eca9be89376d9cbd88c95757e1 100644 (file)
@@ -363,37 +363,45 @@ they originate from :mod:`sqlalchemy.types` or from the local dialect::
         CIDR,
         CITEXT,
         DATE,
+        DATEMULTIRANGE,
+        DATERANGE,
+        DOMAIN,
         DOUBLE_PRECISION,
         ENUM,
         FLOAT,
         HSTORE,
         INET,
+        INT4MULTIRANGE,
+        INT4RANGE,
+        INT8MULTIRANGE,
+        INT8RANGE,
         INTEGER,
         INTERVAL,
         JSON,
         JSONB,
+        JSONPATH,
         MACADDR,
         MACADDR8,
         MONEY,
         NUMERIC,
+        NUMMULTIRANGE,
+        NUMRANGE,
         OID,
         REAL,
+        REGCLASS,
+        REGCONFIG,
         SMALLINT,
         TEXT,
         TIME,
         TIMESTAMP,
-        UUID,
-        VARCHAR,
-        INT4RANGE,
-        INT8RANGE,
-        NUMRANGE,
-        DATERANGE,
+        TSMULTIRANGE,
+        TSQUERY,
         TSRANGE,
+        TSTZMULTIRANGE,
         TSTZRANGE,
-        REGCONFIG,
-        REGCLASS,
-        TSQUERY,
         TSVECTOR,
+        UUID,
+        VARCHAR,
     )
 
 Types which are specific to PostgreSQL, or have PostgreSQL-specific
index 71aacd4059800cc3868c12d4774509ae2f67c709..46a5d0a2051ab244f67d42c26f665c6d4a7129d1 100644 (file)
@@ -59,4 +59,5 @@ __all__ = (
     "VARCHAR2",
     "NVARCHAR2",
     "ROWID",
+    "REAL",
 )
index fe6386f22e456c137dfea529287ba6df79612c38..da7f7300bc9fd0d1d0937ee45115fed008d31d80 100644 (file)
@@ -608,14 +608,21 @@ class Numeric(HasExpressionLookup, TypeEngine[_N]):
 
 
 class Float(Numeric[_N]):
-
     """Type representing floating point types, such as ``FLOAT`` or ``REAL``.
 
     This type returns Python ``float`` objects by default, unless the
-    :paramref:`.Float.asdecimal` flag is set to True, in which case they
+    :paramref:`.Float.asdecimal` flag is set to ``True``, in which case they
     are coerced to ``decimal.Decimal`` objects.
 
-
+    When a :paramref:`.Float.precision` is not provided in a
+    :class:`_types.Float` type some backend may compile this type as
+    an 8 bytes / 64 bit float datatype. To use a 4 bytes / 32 bit float
+    datatype a precision <= 24 can usually be provided or the
+    :class:`_types.REAL` type can be used.
+    This is known to be the case in the PostgreSQL and MSSQL dialects
+    that render the type as ``FLOAT`` that's in both an alias of
+    ``DOUBLE PRECISION``. Other third party dialects may have similar
+    behavior.
     """
 
     __visit_name__ = "float"
index 2939c097c3e231d62ff409ed3959b3439b7be45d..a225dde532e78ec78bf26a261466826e9a61a44b 100644 (file)
@@ -1627,3 +1627,22 @@ class BooleanTest(fixtures.TestBase, AssertsCompiledSQL):
             ddl,
         )
         assert isinstance(tbl.c.boo.type.as_generic(), Boolean)
+
+
+class NumberTest(fixtures.TestBase, AssertsCompiledSQL):
+    __dialect__ = mssql.dialect()
+
+    @testing.combinations(
+        ("sa", sqltypes.Float(), "FLOAT"),  # ideally it should render real
+        ("sa", sqltypes.Double(), "DOUBLE PRECISION"),
+        ("sa", sqltypes.FLOAT(), "FLOAT"),
+        ("sa", sqltypes.REAL(), "REAL"),
+        ("sa", sqltypes.DOUBLE(), "DOUBLE"),
+        ("sa", sqltypes.DOUBLE_PRECISION(), "DOUBLE PRECISION"),
+        ("mssql", mssql.FLOAT(), "FLOAT"),
+        ("mssql", mssql.DOUBLE_PRECISION(), "DOUBLE PRECISION"),
+        ("mssql", mssql.REAL(), "REAL"),
+        id_="ira",
+    )
+    def test_float_type_compile(self, type_, sql_text):
+        self.assert_compile(type_, sql_text)
index af68a24c5a818dcc272e86af41d8bb9f3e71e575..1d279e720db6480ebad6a82083e7c5be505f1a50 100644 (file)
@@ -462,6 +462,21 @@ class TypeCompileTest(fixtures.TestBase, AssertsCompiledSQL):
             datetime.time(8, 37, 35, 450),
         )
 
+    @testing.combinations(
+        ("sa", sqltypes.Float(), "FLOAT"),
+        ("sa", sqltypes.Double(), "DOUBLE"),
+        ("sa", sqltypes.FLOAT(), "FLOAT"),
+        ("sa", sqltypes.REAL(), "REAL"),
+        ("sa", sqltypes.DOUBLE(), "DOUBLE"),
+        ("sa", sqltypes.DOUBLE_PRECISION(), "DOUBLE PRECISION"),
+        ("mysql", mysql.FLOAT(), "FLOAT"),
+        ("mysql", mysql.DOUBLE(), "DOUBLE"),
+        ("mysql", mysql.REAL(), "REAL"),
+        id_="ira",
+    )
+    def test_float_type_compile(self, type_, sql_text):
+        self.assert_compile(type_, sql_text)
+
 
 class TypeRoundTripTest(fixtures.TestBase, AssertsExecutionResults):
     __dialect__ = mysql.dialect()
index 55fe368656fab5ddf77406315f36bef60d6ec36c..a970adc4bacddace0f897faa74c0d2ff46965ebe 100644 (file)
@@ -191,6 +191,23 @@ class DialectTypesTest(fixtures.TestBase, AssertsCompiledSQL):
         expr = column("bar", oracle.INTERVAL) == datetime.timedelta(days=1)
         eq_(expr.right.type._type_affinity, sqltypes.Interval)
 
+    @testing.combinations(
+        ("sa", sqltypes.Float(), "FLOAT"),
+        ("sa", sqltypes.Double(), "DOUBLE PRECISION"),
+        ("sa", sqltypes.FLOAT(), "FLOAT"),
+        ("sa", sqltypes.REAL(), "REAL"),
+        ("sa", sqltypes.DOUBLE(), "DOUBLE"),
+        ("sa", sqltypes.DOUBLE_PRECISION(), "DOUBLE PRECISION"),
+        ("oracle", oracle.FLOAT(), "FLOAT"),
+        ("oracle", oracle.DOUBLE_PRECISION(), "DOUBLE PRECISION"),
+        ("oracle", oracle.REAL(), "REAL"),
+        ("oracle", oracle.BINARY_DOUBLE(), "BINARY_DOUBLE"),
+        ("oracle", oracle.BINARY_FLOAT(), "BINARY_FLOAT"),
+        id_="ira",
+    )
+    def test_float_type_compile(self, type_, sql_text):
+        self.assert_compile(type_, sql_text)
+
 
 class TypesTest(fixtures.TestBase):
     __only_on__ = "oracle"
index 422e735d3d4150c571c3c9b37ce8e7b14556a65e..73a66fff612befb567f61bfc66cb813f91dc9823 100644 (file)
@@ -99,6 +99,8 @@ from ...engine.test_ddlevents import DDLEventWCreateHarness
 
 
 class MiscTypesTest(AssertsCompiledSQL, fixtures.TestBase):
+    __dialect__ = postgresql.dialect()
+
     @testing.combinations(
         ("asyncpg", "x LIKE $1::VARCHAR"),
         ("psycopg", "x LIKE %(x_1)s::VARCHAR"),
@@ -119,6 +121,21 @@ class MiscTypesTest(AssertsCompiledSQL, fixtures.TestBase):
             dialect=f"postgresql+{driver}",
         )
 
+    @testing.combinations(
+        ("sa", sqltypes.Float(), "FLOAT"),  # ideally it should render real
+        ("sa", sqltypes.Double(), "DOUBLE PRECISION"),
+        ("sa", sqltypes.FLOAT(), "FLOAT"),
+        ("sa", sqltypes.REAL(), "REAL"),
+        ("sa", sqltypes.DOUBLE(), "DOUBLE"),
+        ("sa", sqltypes.DOUBLE_PRECISION(), "DOUBLE PRECISION"),
+        ("pg", postgresql.FLOAT(), "FLOAT"),
+        ("pg", postgresql.DOUBLE_PRECISION(), "DOUBLE PRECISION"),
+        ("pg", postgresql.REAL(), "REAL"),
+        id_="ira",
+    )
+    def test_float_type_compile(self, type_, sql_text):
+        self.assert_compile(type_, sql_text)
+
 
 class FloatCoercionTest(fixtures.TablesTest, AssertsExecutionResults):
     __only_on__ = "postgresql"