代码之家  ›  专栏  ›  技术社区  ›  Tebas

PostgreSQL的libpq:数组[]-数据二进制传输编码?

  •  9
  • Tebas  · 技术社区  · 14 年前

    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二进制格式传输数组数据的工作示例? 密码输入 backend/utils/adt/

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

    特巴斯

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

    2 回复  |  直到 14 年前
        1
  •  5
  •   Ilia Choly    11 年前

    作为 记事 int4 忽略任何空值。

    #define   INT4OID   23
    
    /*! Structure of array header to determine array type */
    struct array_int4 {
      int32_t ndim; /* Number of dimensions */
      int32_t _ign; /* offset for data, removed by libpq */
      Oid elemtype; /* type of element in the array */
    
      /* First dimension */
      int32_t size; /* Number of elements */
      int32_t index; /* Index of first element */
      int32_t first_value; /* Beginning of integer data */
    };
    
    static int extract_int4_array (char *raw_array, 
                                   int32_t **values, 
                                   int *num_values) {
      /* Array information header */
      struct array_int4 *array = (struct array_int4 *) raw_array; 
      /* Pointer to traverse int array */
      int32_t *p_value = &(array->first_value);
      /* int value in host byte order */
      int32_t hval;
    
      /* Check if we have a 1-dimensional INT4 array */
      if (ntohl(array->ndim) != 1 
      || ntohl(array->elemtype) != INT4OID) {
        return -1;
      }
      /* Number of elements including NULLs */
      int array_elements = ntohl (array->size);
    
      *num_values = 0;
      /* Get size of array */
      for (int i=0; i<array_elements; ++i) {
        /* Check size to see if this is a NULL value */
        hval = ntohl (*p_value);
        if (hval != -1) {
          ++p_value;
          (*num_values) += 1;
        } 
    
        ++p_value;
      }
      *values = malloc (*num_values * sizeof **values);
    
      /* Fill output int array. Skip every other value as it contains the size of 
       * the element */
      *num_values = 0; /* Use num_values as the index of the output array */
      p_value = &(array->first_value);
      for (int i=0; i<array_elements; ++i) {
        /* Check size to see if this is a NULL value */
        hval = ntohl (*p_value);
        if (hval != -1) {
          ++p_value;
      (*values)[*num_values] = ntohl (*p_value);
          (*num_values) += 1;
        } 
    
        ++p_value;
      }
    
      return 0;
    }
    

    似乎还有一个名为 libpqtypes

        2
  •  9
  •   ccutrer    14 年前

    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 0x00000004

    推荐文章