2009-08-19 4 views
1

いくつかの整数を次のやや単純なコードでPostgresテーブルに挿入しようとしています。PostgreSQL libpq整数をバイナリとして送信するときの整数範囲外のエラー

#include <libpq-fe.h> 
#include <stdio.h> 
#include <stdint.h> 

int main() { 
    int64_t i = 0; 
    PGconn * connection = PQconnectdb("dbname='babyfood'"); 
    if(!connection || PQstatus(connection) != CONNECTION_OK) 
    return 1; 
    printf("Number: "); 
    scanf("%d", &i); 

    char * params[1]; 
    int param_lengths[1]; 
    int param_formats[1]; 
    param_lengths[0] = sizeof(i); 
    param_formats[0] = 1; 
    params[0] = (char*)&i; 
    PGresult * res = PQexecParams(connection, 
            "INSERT INTO intlist VALUES ($1::int8)", 
            1, 
            NULL, 
            params, 
            param_lengths, 
            param_formats, 
            0); 
    printf("%s\n", PQresultErrorMessage(res)); 
    PQclear(res); 
    PQfinish(connection); 
    return 0; 
} 

私は、次のような結果を得る:

 
Number:55 
ERROR: integer out of range 
 
Number:1 
ERROR: integer out of range 

私はint64_tのはいつもまともなプラットフォーム上で8バイト整数に収まることをかなり確信しています。私は間違って何をしていますか?

答えて

3

の代わりに:あなたが使用する必要があります

params[0] = (char*)&i; 

:スワップは、次の関数で行われ

#include <endian.h> 
/* ... */ 
int64_t const i_big_endian = htobe64(i); 
params[0] = (char*)&i_big_endian; 

htobe64機能はリトルエンディアンでエンディアンを切り替えて、何もしませんビッグエンディアンで。

あなたのプログラムは、PowerPC、Alpha、Motorola、SPARC、IA64などのビッグエンディアン/バイエンディアンのコンピュータと互換性がないため、flip_endian機能を使用しないでください。プログラムが実行されない場合でもそれは悪いスタイル、遅いとエラーが発生しやすいです。

-1

私はそれが32ビット整数として渡されていると思って、64ビットにキャストされます。なぜなら、あなたはフォーマットが何であるかをlibpqに伝えていないからです。

パラメータのint8(20)のoidを指定して、paramTypesの配列を指定してください。

+0

これは、:: int8キャストからそのことを判断できるようになっています。また、エンディアンを反転するだけでなく、エラーを取り除くだけでなく、実際に正しい挿入が行われるので、間違いなくエンディアンの問題です。 – Edward

+0

ああ、そうだ。私はそれを考えていたはずです:) –

1

リトルエンディアン(すなわちx86)の64ビット符号付き整数はビッグエンディアンの64ビット整数に収まる必要があり、逆も同様であるため、それはまだそれを説明していないエンディアン問題です。彼らはちょうど破損していただろう。ただし、エンディアンを整数にスワップすると正しい値が得られます。

int64_t flip_endian(int64_t endi) { 
    char* bytearray; 
    char swap; 
    int64_t orig = endi; 
    int i; 

    bytearray = (char*)&orig; 

    for(i = 0; i < sizeof(orig)/2; ++i) { 
    swap = bytearray[i]; 
    bytearray[i] = bytearray[ sizeof(orig) - i - 1 ]; 
    bytearray[ sizeof(orig) - i - 1 ] = swap; 
    } 

    return orig; 

} 
関連する問題