BUG #13462: Impossible to use COPY FORMAT BINARY in chunks through libpq

Поиск
Список
Период
Сортировка
От socketpair@gmail.com
Тема BUG #13462: Impossible to use COPY FORMAT BINARY in chunks through libpq
Дата
Msg-id 20150622203411.3873.26064@wrigleys.postgresql.org
обсуждение исходный текст
Ответы Re: BUG #13462: Impossible to use COPY FORMAT BINARY in chunks through libpq  (Tom Lane <tgl@sss.pgh.pa.us>)
Список pgsql-bugs
The following bug has been logged on the website:

Bug reference:      13462
Logged by:          Korenberg Mark
Email address:      socketpair@gmail.com
PostgreSQL version: 9.3.8
Operating system:   Linux
Description:

If I use PQputCopyData() to pass parts of the binary protocol (as documented
in http://www.postgresql.org/docs/9.3/static/sql-copy.html ), postgres
binary socket data gets corrupted (i.e. protocol is broken).

It is unexpected that libpq inserts \d\0\0\0 on every PQputCopyData() call
even in BINARY COPY mode. So, it is impossible to write a program that
generate tuples in binary form dynamically without merging them into one big
buffer.

Part of program:
====================================
   static const struct {
        char magic[11];
        int32_t zero1;
        int32_t zero2;
    } __attribute__ ((packed)) bin_header = {"PGCOPY\n\377\r\n",0,0};

    if (PQputCopyData (conn, (const char *) &bin_header, sizeof
(bin_header)) != 1)
    {
        fprintf (stderr, "PQputCopyData failed\n");
        return 4;
    }

    struct
    {
        int16_t fields;
        int32_t ip1len;
        uint32_t ip1;
        int32_t ip2len;
        uint32_t ip2;
    } __attribute__ ((packed)) binary_line =   {
        2, 4, 0x01020304, 4, 0x05060708
    };


    for (i = 0; i < repeats; i++)
    {
        if (PQputCopyData (conn, (const char *) &binary_line, sizeof
(binary_line)) != 1)
        {
            fprintf (stderr, "PQputCopyData failed\n");
            return 4;
        }
    }

    static const int16_t copy_end = -1;
    if (PQputCopyData (conn, (const char *) ©_end, sizeof (copy_end)) !=
1)
    {
        fprintf (stderr, "PQputCopyData failed\n");
        return 4;
    }

    res = PQgetResult (conn);
    if (PQresultStatus (res) != PGRES_COMMAND_OK)
    {
        fprintf (stderr, "COPY failed: %s\n", PQerrorMessage (conn));
        PQclear (res);
        return 3;
    }
    PQclear (res);
===============================================
will generate:

"d\0\0\0\27PGCOPY\n\377\r\n\0\0\0\0\0\0\0\0\0d\0\0\0\26\2\0\4\0\0\0\4\3\2\1\4\0\0\0\10\7\6\5d\0\0\0\6\377\377X\0\0\0\4"

but actually should generate (not sure about tail)

"d\0\0\0\27PGCOPY\n\377\r\n\0\0\0\0\0\0\0\0\0\2\0\4\0\0\0\4\3\2\1\4\0\0\0\10\7\6\5\377\377X\0\0\0\4"

В списке pgsql-bugs по дате отправления:

Предыдущее
От: David Gould
Дата:
Сообщение: Re: Incomplete Explain for delete
Следующее
От: Tom Lane
Дата:
Сообщение: Re: BUG #13462: Impossible to use COPY FORMAT BINARY in chunks through libpq