आपके कोड में दो त्रुटियां हैं:
-
आप बाइनरी डेटा भेजने की कोशिश कर रहे हैं, लेकिन आप
PQexecParams
. को नहीं बताते हैं यह किस प्रकार का है।यह काम नहीं कर सकता। प्रकार की जानकारी के अभाव में, PostgreSQL
unknown
. प्रकार का उपयोग करेगा और इसे स्ट्रिंग के रूप में मानें। इसका मतलब है कि आपका बाइनरी प्रतिनिधित्वfloat8in
. पर फीड किया जाएगा फ़ंक्शन जो स्ट्रिंग्स को डबल सटीक मानों में परिवर्तित करता है, जो बुरी तरह विफल हो जाएगा। आप शायद यही देख रहे हैं।आपको चौथे पैरामीटर का उपयोग
Oid[]
. के साथ करना होगा जिसमें 701 (याFLOAT8OID
. है) यदि आप इसके बजाय PostgreSQL के#define
. का उपयोग करना चाहते हैं , लेकिन आपको#include <postgres.h>
और<catalog/pg_type.h>
उसके लिए)। -
आप गलती से मान लेते हैं कि PostgreSQL का
double precision
. का द्विआधारी प्रतिनिधित्व है प्रकार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
ताकि आपको गारंटी दी जाए कि जब मान उनके स्ट्रिंग प्रतिनिधित्व में परिवर्तित हो जाते हैं तो कोई भी सटीकता न खोएं..