]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Open up all cx_Oracle numeric tests, finish infinity support
authorMike Bayer <mike_mp@zzzcomputing.com>
Fri, 15 Dec 2017 15:56:18 +0000 (10:56 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sun, 17 Dec 2017 16:00:55 +0000 (11:00 -0500)
Added some additional rules to fully handle ``Decimal('Infinity')``,
``Decimal('-Infinity')`` values with cx_Oracle numerics when using
``asdecimal=True``.

Allow remaining cx_Oracle numeric tests that were waiting
for the refactor to be finished and forgot to get enabled.

Change-Id: I1e2365176e34559c0230c84f800a7cfe0a034ed5
Fixes: #4064
doc/build/changelog/unreleased_12/4064.rst [new file with mode: 0644]
lib/sqlalchemy/dialects/oracle/cx_oracle.py
lib/sqlalchemy/testing/suite/test_types.py
test/dialect/oracle/test_types.py

diff --git a/doc/build/changelog/unreleased_12/4064.rst b/doc/build/changelog/unreleased_12/4064.rst
new file mode 100644 (file)
index 0000000..70db0c1
--- /dev/null
@@ -0,0 +1,7 @@
+.. change::
+    :tags: bug, oracle
+    :tickets: 4064
+
+    Added some additional rules to fully handle ``Decimal('Infinity')``,
+    ``Decimal('-Infinity')`` values with cx_Oracle numerics when using
+    ``asdecimal=True``.
index 68ecce5194a1207b66431fad59937c15b5ed8600..0288fe898138d316b8cde6ce1d2df2506bdbc105 100644 (file)
@@ -223,6 +223,8 @@ class _OracleNumeric(sqltypes.Numeric):
             def process(value):
                 if isinstance(value, (int, float)):
                     return processor(value)
+                elif value is not None and value.is_infinite():
+                    return float(value)
                 else:
                     return value
             return process
@@ -242,7 +244,12 @@ class _OracleNumeric(sqltypes.Numeric):
             outconverter = None
             if precision:
                 if self.asdecimal:
-                    if is_cx_oracle_6:
+                    if default_type == cx_Oracle.NATIVE_FLOAT:
+                        # receiving float and doing Decimal after the fact
+                        # allows for float("inf") to be handled
+                        type_ = default_type
+                        outconverter = decimal.Decimal
+                    elif is_cx_oracle_6:
                         type_ = decimal.Decimal
                     else:
                         type_ = cx_Oracle.STRING
@@ -258,7 +265,10 @@ class _OracleNumeric(sqltypes.Numeric):
                         type_ = cx_Oracle.NATIVE_FLOAT
             else:
                 if self.asdecimal:
-                    if is_cx_oracle_6:
+                    if default_type == cx_Oracle.NATIVE_FLOAT:
+                        type_ = default_type
+                        outconverter = decimal.Decimal
+                    elif is_cx_oracle_6:
                         type_ = decimal.Decimal
                     else:
                         type_ = cx_Oracle.STRING
index b9bb179aba0b5226d760f1987526d1159b767aee..e419fb450b3432025fd6f608719ac510f5943724 100644 (file)
@@ -380,8 +380,6 @@ class NumericTest(_LiteralRoundTripFixture, fixtures.TestBase):
             filter_=lambda n: n is not None and round(n, 5) or None
         )
 
-    @testing.skip_if(
-        "oracle", "temporary skip until cx_oracle refactor is merged")
     @testing.requires.precision_generic_float_type
     def test_float_custom_scale(self):
         self._do_test(
@@ -391,8 +389,6 @@ class NumericTest(_LiteralRoundTripFixture, fixtures.TestBase):
             check_scale=True
         )
 
-    @testing.skip_if(
-        "oracle", "temporary skip until cx_oracle refactor is merged")
     def test_numeric_as_decimal(self):
         self._do_test(
             Numeric(precision=8, scale=4),
@@ -400,8 +396,6 @@ class NumericTest(_LiteralRoundTripFixture, fixtures.TestBase):
             [decimal.Decimal("15.7563")],
         )
 
-    @testing.skip_if(
-        "oracle", "temporary skip until cx_oracle refactor is merged")
     def test_numeric_as_float(self):
         self._do_test(
             Numeric(precision=8, scale=4, asdecimal=False),
@@ -409,8 +403,6 @@ class NumericTest(_LiteralRoundTripFixture, fixtures.TestBase):
             [15.7563],
         )
 
-    @testing.skip_if(
-        "oracle", "temporary skip until cx_oracle refactor is merged")
     @testing.requires.fetch_null_from_numeric
     def test_numeric_null_as_decimal(self):
         self._do_test(
@@ -427,8 +419,6 @@ class NumericTest(_LiteralRoundTripFixture, fixtures.TestBase):
             [None],
         )
 
-    @testing.skip_if(
-        "oracle", "temporary skip until cx_oracle refactor is merged")
     @testing.requires.floats_to_four_decimals
     def test_float_as_decimal(self):
         self._do_test(
@@ -437,8 +427,6 @@ class NumericTest(_LiteralRoundTripFixture, fixtures.TestBase):
             [decimal.Decimal("15.7563"), None],
         )
 
-    @testing.skip_if(
-        "oracle", "temporary skip until cx_oracle refactor is merged")
     def test_float_as_float(self):
         self._do_test(
             Float(precision=8),
@@ -464,8 +452,6 @@ class NumericTest(_LiteralRoundTripFixture, fixtures.TestBase):
     #    )
     #    eq_(val, expr)
 
-    @testing.skip_if(
-        "oracle", "temporary skip until cx_oracle refactor is merged")
     @testing.requires.precision_numerics_general
     def test_precision_decimal(self):
         numbers = set([
@@ -480,8 +466,6 @@ class NumericTest(_LiteralRoundTripFixture, fixtures.TestBase):
             numbers,
         )
 
-    @testing.skip_if(
-        "oracle", "temporary skip until cx_oracle refactor is merged")
     @testing.requires.precision_numerics_enotation_large
     def test_enotation_decimal(self):
         """test exceedingly small decimals.
index 3d08657d8a76d7d022c49bae9fdfcc654ae3d87a..394fc29a85ff39a489ccad0d9941b7bbdf8daedc 100644 (file)
@@ -282,19 +282,58 @@ class TypesTest(fixtures.TestBase):
                    Column("intcol", Integer),
                    Column("numericcol", oracle.BINARY_DOUBLE(asdecimal=False)))
         t1.create()
-        t1.insert().execute(
-            intcol=1,
-            numericcol=float("inf"),
+        t1.insert().execute([
+            dict(
+                intcol=1,
+                numericcol=float("inf")
+            ),
+            dict(
+                intcol=2,
+                numericcol=float("-inf")
+            ),
+        ])
+
+        eq_(
+            select([t1.c.numericcol]).
+            order_by(t1.c.intcol).execute().fetchall(),
+            [(float('inf'), ), (float('-inf'), )]
+        )
+
+        eq_(
+            testing.db.execute(
+                "select numericcol from t1 order by intcol").fetchall(),
+            [(float('inf'), ), (float('-inf'), )]
         )
 
+    @testing.provide_metadata
+    def test_numeric_infinity_decimal(self):
+        m = self.metadata
+        t1 = Table('t1', m,
+                   Column("intcol", Integer),
+                   Column("numericcol", oracle.BINARY_DOUBLE(asdecimal=True)))
+        t1.create()
+        t1.insert().execute([
+            dict(
+                intcol=1,
+                numericcol=decimal.Decimal("Infinity")
+            ),
+            dict(
+                intcol=2,
+                numericcol=decimal.Decimal("-Infinity")
+            ),
+        ])
+
         eq_(
-            select([t1.c.numericcol]).scalar(),
-            float("inf")
+            select([t1.c.numericcol]).
+            order_by(t1.c.intcol).execute().fetchall(),
+            [(decimal.Decimal("Infinity"), ), (decimal.Decimal("-Infinity"), )]
         )
 
         eq_(
-            testing.db.scalar("select numericcol from t1"),
-            float("inf"))
+            testing.db.execute(
+                "select numericcol from t1 order by intcol").fetchall(),
+            [(decimal.Decimal("Infinity"), ), (decimal.Decimal("-Infinity"), )]
+        )
 
     @testing.provide_metadata
     def test_numerics_broken_inspection(self):