c++ - PostgreSQL 的 libpq : Encoding for binary transport of ARRAY[]-data?

标签 c++ c postgresql libpq

经过几个小时的文档/板/邮件列表但没有任何进展我可能会问你:我如何“编码”我的数据以使用 libpq 的 PQexecParams(.) 将其用于二进制传输?

简单变量只是大端顺序:

PGconn *conn;
PGresult *res;
char *paramValues[1];
int paramLengths[1];
int paramFormats[1];

conn = PQconnectdb(CONNINFO);

// -- (1) -- send a float value
float val_f = 0.12345678901234567890; // float precision: ~7 decimal digits
// alloc some memory & write float (in big endian) into
paramValues[0] = (char *) malloc(sizeof(val_f));
*((uint32_t*) paramValues[0]) = htobe32(*((uint32_t*) &val_f)); // host to big endian

paramLengths[0] = sizeof(val_f);
paramFormats[0] = 1; // binary

res = PQexecParams(conn, "SELECT $1::real ;", //
        1, // number parameters
        NULL, // let the backend deduce param type
        paramValues, //
        paramLengths, //
        paramFormats, //
        0); // return text
printf("sent float: %s \n", PQgetvalue(res, 0, 0));
// --> sent float: 0.123457

像这样还有 double、int 等......

但是数组呢?

    float vals_f[] = {1.23, 9.87};
    // alloc some memory
    paramValues[0] = (char *) malloc(sizeof(float) * 2);

//  ???? paramValues[0] = ??????

    paramLengths[0] = sizeof(float) * 2;
    paramFormats[0] = 1; // binary


    res = PQexecParams(conn, "SELECT $1::real[] ;", //
            1, // number parameters
            NULL, // let the backend deduce param type
            paramValues, //
            paramLengths, //
            paramFormats, //
            0); // return text
    printf("sent float array: %s \n", PQgetvalue(res, 0, 0));

是否有以 PostgreSQL 的二进制格式传输 ARRAY 数据的工作示例? backend/utils/adt/ 中的代码对我帮助不大(除了我现在知道有一个 ARRAYTYPE,但不知道如何使用它们):-(

我只需要一个函数 char* to_PQbin(float [] input, int length) 来传递给 paramValues[.] ...

非常感谢, 特巴斯

PS:转换简单变量的建议方法是什么(而不是我的 htobe32(.))?

最佳答案

http://git.postgresql.org/gitweb?p=postgresql.git;a=blob;f=src/include/utils/array.h;h=7f7e744cb12bc872f628f90dad99dfdf074eb314;hb=master描述了 Postgres 的数组二进制格式。使用 libpq 时,省略 vl_len_ 部分。例如,一个包含 4 个整数的数组如下所示:

0x00000001 0x00000000 0x00000017 0x00000004 0x00000001 0x00000004 0x00000004 0x00000004 0x00000004

这有 OID 1007 (INT4ARRAYOID)。第一个整数是1维,第二个整数是没有NULL的位图(所以数组的值都不是NULL),第三个整数是元素的OID(23,INT4OID),第四个整数是第一个维度有多大(4)、第五个整数为第一个维度的起始索引。之后是原始数组数据,按顺序排列,每个元素以其长度为前缀(每个整数 4 个字节)。

关于c++ - PostgreSQL 的 libpq : Encoding for binary transport of ARRAY[]-data?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4016412/

相关文章:

c - 在同一 switch 语句中执行多个 case

sql - 无法让这个 PostgreSQL 查询更好地工作

c++ - 避免调用 glBindTexture()?

c - 为什么 int 变量不会在寻址方面出现在 char 数组之前,无论我如何在 C 中对其进行编码?

c - 从 C 文件中读取逗号分隔的数字

ruby-on-rails - Ransack 搜索日期作为字符串

python - 使用 Python 的正确编码从 Oracle 导入

c++ - 我可以在运行时初始化 static float 变量吗?

C++ 如何使用 find 函数在 char 数组中查找 char?

c++ - 在 QT 中关闭时从子窗口句柄中删除内存