Във вашия код има две грешки:
-
Опитвате се да изпратите двоични данни, но не казвате на
PQexecParams
кой тип е.Това не може да работи. При липса на информация за типа PostgreSQL ще използва типа
unknown
и го третира като низ. Това означава, че вашето двоично представяне ще бъде подадено къмfloat8in
функция, която преобразува низове в стойности с двойна точност, което ще се провали ужасно. Вероятно това е, което наблюдавате.Ще трябва да използвате четвърти параметър с
Oid[]
който съдържа 701 (илиFLOAT8OID
ако предпочитате да използвате#define
на PostgreSQL , но ще трябва да#include <postgres.h>
и<catalog/pg_type.h>
за това). -
Погрешно приемате, че двоичното представяне на PostgreSQL на
double precision
type е двоичният формат за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
така че да е гарантирано, че няма да загубите никаква точност, когато стойностите се преобразуват в тяхното низово представяне.