Skip to content

Commit 1ce7a57

Browse files
committed
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>
1 parent bc93ac1 commit 1ce7a57

File tree

3 files changed

+21
-0
lines changed

3 files changed

+21
-0
lines changed

src/pl/plpython/expected/plpython_types.out

+8
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,14 @@ CONTEXT: PL/Python function "test_type_conversion_float8"
354354

355355
(1 row)
356356

357+
SELECT * FROM test_type_conversion_float8(100100100.654321);
358+
INFO: (100100100.654321, <type 'float'>)
359+
CONTEXT: PL/Python function "test_type_conversion_float8"
360+
test_type_conversion_float8
361+
-----------------------------
362+
100100100.654321
363+
(1 row)
364+
357365
CREATE FUNCTION test_type_conversion_oid(x oid) RETURNS oid AS $$
358366
plpy.info(x, type(x))
359367
return x

src/pl/plpython/plpy_typeio.c

+12
Original file line numberDiff line numberDiff line change
@@ -760,6 +760,18 @@ PLyObject_ToDatum(PLyObToDatum *arg, int32 typmod, PyObject *plrv)
760760

761761
if (PyUnicode_Check(plrv))
762762
plrv_bo = PLyUnicode_Bytes(plrv);
763+
else if (PyFloat_Check(plrv))
764+
{
765+
/* use repr() for floats, str() is lossy */
766+
#if PY_MAJOR_VERSION >= 3
767+
PyObject *s = PyObject_Repr(plrv);
768+
769+
plrv_bo = PLyUnicode_Bytes(s);
770+
Py_XDECREF(s);
771+
#else
772+
plrv_bo = PyObject_Repr(plrv);
773+
#endif
774+
}
763775
else
764776
{
765777
#if PY_MAJOR_VERSION >= 3

src/pl/plpython/sql/plpython_types.sql

+1
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ SELECT * FROM test_type_conversion_float8(100);
122122
SELECT * FROM test_type_conversion_float8(-100);
123123
SELECT * FROM test_type_conversion_float8(5000000000.5);
124124
SELECT * FROM test_type_conversion_float8(null);
125+
SELECT * FROM test_type_conversion_float8(100100100.654321);
125126

126127

127128
CREATE FUNCTION test_type_conversion_oid(x oid) RETURNS oid AS $$

0 commit comments

Comments
 (0)