Der er to fejl i din kode:
-
Du forsøger at sende binære data, men du fortæller ikke
PQexecParamshvilken type det er.Det kan ikke fungere. Manglende typeoplysninger vil PostgreSQL bruge typen
unknownog behandle det som snor. Det betyder, at din binære repræsentation vil blive ført tilfloat8infunktion, der konverterer strenge til dobbelte præcisionsværdier, hvilket vil fejle frygteligt. Det er sandsynligvis det, du observerer.Du bliver nødt til at bruge en fjerde parameter med en
Oid[]der indeholder 701 (ellerFLOAT8OIDhvis du hellere vil bruge PostgreSQL's#define, men du skal#include <postgres.h>og<catalog/pg_type.h>for det). -
Du antager fejlagtigt, at PostgreSQL's binære repræsentation af
double precisiontype er det binære format fordoublei brug på din klientmaskine.Dette virker muligvis ved et uheld, hvis dit program kører på en big-endian maskine, da stort set alle arkitekturer i disse dage bruger IEEE flydende kommatal .
Hvis du læser kildekoden, vil du opdage, at PostgreSQL's over-the-wire binære format er defineret i
pq_sendfloat8isrc/backend/libpq/pqformat.c, som kalderpq_sendint64, som konverterer 8-byte-værdien til netværksbyte-rækkefølge (hvilket er det samme som big-endian-repræsentation).
Så du bliver nødt til at definere en konverteringsfunktion, der ligner denne:
static void to_nbo(double in, double *out) {
uint64_t *i = (uint64_t *)∈
uint32_t *r = (uint32_t *)out;
/* convert input to network byte order */
r[0] = htonl((uint32_t)((*i) >> 32));
r[1] = htonl((uint32_t)*i);
}
Så kunne din kode se sådan ud:
Oid types[1];
double converted;
...
types[0] = FLOAT8OID;
to_nbo(value, &converted);
values[0] = (char *)&converted;
Men ærligt talt ville det være meget nemmere at bruge tekstgengivelsen. Det vil gøre din kode uafhængig af PostgreSQL internals og er sandsynligvis ikke så meget langsommere.
Det ser ikke sådan ud, men hvis double precision værdier hentes fra en PostgreSQL-tabel et andet sted, kan du indstille extra_float_digits
= 3 så du er garanteret ikke at miste nogen præcision, når værdierne konverteres til deres strengrepræsentation.