]> granicus.if.org Git - postgresql/commitdiff
PL/Python: Avoid lossiness in float conversion
authorPeter Eisentraut <peter_e@gmx.net>
Wed, 11 Mar 2015 19:44:17 +0000 (15:44 -0400)
committerPeter Eisentraut <peter_e@gmx.net>
Wed, 11 Mar 2015 19:46:06 +0000 (15:46 -0400)
PL/Python uses str() to convert Python values back to PostgreSQL, but
str() is lossy for float values, so use repr() instead in that case.

Author: Marko Kreen <markokr@gmail.com>

src/pl/plpython/expected/plpython_types.out
src/pl/plpython/plpy_typeio.c
src/pl/plpython/sql/plpython_types.sql

index 61d800b57a2b3f20d817478caf61595070219a00..17057a543d2b7f418a3b27a3558292807cf33c81 100644 (file)
@@ -354,6 +354,14 @@ CONTEXT:  PL/Python function "test_type_conversion_float8"
                             
 (1 row)
 
+SELECT * FROM test_type_conversion_float8(100100100.654321);
+INFO:  (100100100.654321, <type 'float'>)
+CONTEXT:  PL/Python function "test_type_conversion_float8"
+ test_type_conversion_float8 
+-----------------------------
+            100100100.654321
+(1 row)
+
 CREATE FUNCTION test_type_conversion_oid(x oid) RETURNS oid AS $$
 plpy.info(x, type(x))
 return x
index 524534e613ded0928fc33bac83c162bf82df0e76..8c70c7c9783c7900b5dbcee2d971e3ad3c88a443 100644 (file)
@@ -760,6 +760,18 @@ PLyObject_ToDatum(PLyObToDatum *arg, int32 typmod, PyObject *plrv)
 
        if (PyUnicode_Check(plrv))
                plrv_bo = PLyUnicode_Bytes(plrv);
+       else if (PyFloat_Check(plrv))
+       {
+               /* use repr() for floats, str() is lossy */
+#if PY_MAJOR_VERSION >= 3
+               PyObject   *s = PyObject_Repr(plrv);
+
+               plrv_bo = PLyUnicode_Bytes(s);
+               Py_XDECREF(s);
+#else
+               plrv_bo = PyObject_Repr(plrv);
+#endif
+       }
        else
        {
 #if PY_MAJOR_VERSION >= 3
index d9d0db66bccf5ec4c2fc9ff698a8bfe1eaa6e6e8..19d920d3c7ba6471168ae23e406d35f04104f39b 100644 (file)
@@ -122,6 +122,7 @@ SELECT * FROM test_type_conversion_float8(100);
 SELECT * FROM test_type_conversion_float8(-100);
 SELECT * FROM test_type_conversion_float8(5000000000.5);
 SELECT * FROM test_type_conversion_float8(null);
+SELECT * FROM test_type_conversion_float8(100100100.654321);
 
 
 CREATE FUNCTION test_type_conversion_oid(x oid) RETURNS oid AS $$