PL/Python: Avoid lossiness in float conversion

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>
This commit is contained in:
Peter Eisentraut 2015-03-11 15:44:17 -04:00
parent bc93ac12c2
commit 1ce7a57ca6
3 changed files with 21 additions and 0 deletions

View 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

View 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

View 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 $$