]> git.ipfire.org Git - thirdparty/psycopg.git/commitdiff
fix: add C Float4 binary dumper
authorDaniele Varrazzo <daniele.varrazzo@gmail.com>
Mon, 16 May 2022 00:41:53 +0000 (02:41 +0200)
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>
Mon, 16 May 2022 01:19:17 +0000 (03:19 +0200)
This should hopefully work around issue #304, at least when C is used.
When Python is used we raise an error instead.

Close #304

docs/news.rst
psycopg/psycopg/_struct.py
psycopg_c/psycopg_c/types/numeric.pyx

index 408fcf2bbb97df26eb253103d3184e8857336011..e556be1b6c33ef6b1a05037c6714d1a1206d20a1 100644 (file)
@@ -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
index d6c603cb616bfd44d9f7b2aad905083fbe8d0c1d..5ccb7703b63530d906731bb973bd652d13ee42df 100644 (file)
@@ -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"
     )
 
 
index 3f6a9082cbb292d6f5ecd86fc29518afc4c24ac5..65f144ad5e461ac63c0a72f88b1de2debe1781b9 100644 (file)
@@ -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 = <float>PyFloat_AsDouble(obj)
+        cdef uint32_t *intptr = <uint32_t *>&f
+        cdef uint32_t *buf = <uint32_t *>CDumper.ensure_size(
+            rv, offset, sizeof(uint32_t))
+        buf[0] = endian.htobe32(intptr[0])
+        return sizeof(uint32_t)
+
+
 @cython.final
 cdef class FloatLoader(CLoader):