Във вашия код има две грешки:
-
Опитвате се да изпратите двоични данни, но не казвате на
PQexecParamsкой тип е.Това не може да работи. При липса на информация за типа PostgreSQL ще използва типа
unknownи го третира като низ. Това означава, че вашето двоично представяне ще бъде подадено къмfloat8inфункция, която преобразува низове в стойности с двойна точност, което ще се провали ужасно. Вероятно това е, което наблюдавате.Ще трябва да използвате четвърти параметър с
Oid[]който съдържа 701 (илиFLOAT8OIDако предпочитате да използвате#defineна PostgreSQL , но ще трябва да#include <postgres.h>и<catalog/pg_type.h>за това). -
Погрешно приемате, че двоичното представяне на PostgreSQL на
double precisiontype е двоичният формат заdoubleв употреба на вашата клиентска машина.Това може случайно да проработи, ако програмата ви работи на big-endian машина, тъй като почти всяка архитектура в днешно време използва IEEE числа с плаваща запетая .
Ако прочетете изходния код, ще откриете, че двоичният формат на PostgreSQL по кабела е дефиниран в
pq_sendfloat8вsrc/backend/libpq/pqformat.c, който извикваpq_sendint64, който преобразува 8-байтовата стойност в мрежов ред на байтовете (което е същото като представянето с голям ред).
Така че ще трябва да дефинирате функция за преобразуване, подобна на тази:
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);
}
Тогава вашият код може да изглежда така:
Oid types[1];
double converted;
...
types[0] = FLOAT8OID;
to_nbo(value, &converted);
values[0] = (char *)&converted;
Но честно казано, би било много по-лесно да се използва представянето на текст. Това ще направи кода ви независим от вътрешността на PostgreSQL и вероятно не е много по-бавен.
Не изглежда така, но ако double precision стойностите се изтеглят от таблица на PostgreSQL някъде другаде, можете да зададете extra_float_digits
= 3 така че да е гарантирано, че няма да загубите никаква точност, когато стойностите се преобразуват в тяхното низово представяне.