From: Daniele Varrazzo Date: Mon, 16 May 2022 00:41:53 +0000 (+0200) Subject: fix: add C Float4 binary dumper X-Git-Tag: 3.1~92^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b5c7cb43626094372c3aab6e430d63adcff1fa77;p=thirdparty%2Fpsycopg.git fix: add C Float4 binary dumper This should hopefully work around issue #304, at least when C is used. When Python is used we raise an error instead. Close #304 --- diff --git a/docs/news.rst b/docs/news.rst index 408fcf2bb..e556be1b6 100644 --- a/docs/news.rst +++ b/docs/news.rst @@ -38,6 +38,7 @@ Psycopg 3.0.14 - Raise `DataError` dumping arrays of mixed types (:ticket:`#301`). - Fix handling of incorrect server results, with blank sqlstate (:ticket:`#303`). +- Fix bad Float4 conversion on ppc64le/musllinux (:ticket:`#304`). Psycopg 3.0.13 diff --git a/psycopg/psycopg/_struct.py b/psycopg/psycopg/_struct.py index d6c603cb6..5ccb7703b 100644 --- a/psycopg/psycopg/_struct.py +++ b/psycopg/psycopg/_struct.py @@ -45,8 +45,9 @@ unpack_len = cast(UnpackLen, _struct_len.unpack_from) def pack_float4_bug_304(x: float) -> bytes: raise e.InterfaceError( - "cannot dump Float4: Python affected by bug #304," - " see https://github.com/psycopg/psycopg/issues/304" + "cannot dump Float4: Python affected by bug #304. Note that the psycopg-c" + " and psycopg-binary packages are not affected by this issue." + " See https://github.com/psycopg/psycopg/issues/304" ) diff --git a/psycopg_c/psycopg_c/types/numeric.pyx b/psycopg_c/psycopg_c/types/numeric.pyx index 3f6a9082c..65f144ad5 100644 --- a/psycopg_c/psycopg_c/types/numeric.pyx +++ b/psycopg_c/psycopg_c/types/numeric.pyx @@ -328,6 +328,21 @@ cdef class FloatBinaryDumper(CDumper): return sizeof(uint64_t) +@cython.final +cdef class Float4BinaryDumper(CDumper): + + format = PQ_BINARY + oid = oids.FLOAT4_OID + + cdef Py_ssize_t cdump(self, obj, bytearray rv, Py_ssize_t offset) except -1: + cdef float f = PyFloat_AsDouble(obj) + cdef uint32_t *intptr = &f + cdef uint32_t *buf = CDumper.ensure_size( + rv, offset, sizeof(uint32_t)) + buf[0] = endian.htobe32(intptr[0]) + return sizeof(uint32_t) + + @cython.final cdef class FloatLoader(CLoader):