Re: Protocol Question - Mailing list pgsql-interfaces

From Thomas Heller
Subject Re: Protocol Question
Date
Msg-id CAGTxmOuW94eHab4==QxzPFxVkBB16jQ2UXpYH7CRjH3r+vimNg@mail.gmail.com
Whole thread Raw
In response to Re: Protocol Question  (Tom Lane <tgl@sss.pgh.pa.us>)
Responses Re: Protocol Question  (Tom Lane <tgl@sss.pgh.pa.us>)
List pgsql-interfaces
Thanks, explicit test included.

Another quick Question about the request flow.

In an Extended Query Lifecycle, in order to prepare a query I send the Commands

Parse('P') / Describe('D') / Sync('S')

read 1/t/T/Z then to execute

Bind('B') / Execute('E') / Flush('H')

then read until either CommandComplete('C') or PortalSuspended('s')

on 's' I send another 'E' (only happens when I executed with a limit before)

once I arrive at 'C' I send the final 'S'.

That all works perfectly fine, I am unsure however on the 'H' (Flush) part.

I looked at a tcpdump for a ruby and pgjdbc query flow but couldn't figure out how to execute with a limit. Anyways they send:

P/B/D/E/S

"The Flush message does not cause any specific output to be generated, but forces the backend to deliver any data pending in its output buffers. A Flush must be sent after any extended-query command except Sync, if the frontend wishes to examine the results of that command before issuing more commands. Without Flush, messages returned by the backend will be combined into the minimum possible number of packets to minimize network overhead."

If I skip the Flush after Execute I receive no data, if I Execute and Sync I receive the the Limit of rows and a ReadyForQuery('Z').

Is it ok to send a Flush or should I Sync always? I'm leaning towards Sync, but I don't really need the ReadyForQuery cause I'm still reading. (Only related to Execute with a Limit).

Hope that wasn't too confusing, just trying to cover an edge case.

Regards,
/thomas



On Mon, Aug 11, 2014 at 5:06 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
Thomas Heller <info@zilence.net> writes:
> The first 16 bits (well skip the first 40) in every DataRow ('D') packet
> refer to the number of columns following. Is there any way that this number
> is different from the number received in the RowDescription ('T')?

A quick look into libpq says that it doesn't support them being different:

    /* Get the field count and make sure it's what we expect */
    if (pqGetInt(&tupnfields, 2, conn))
    {
        /* We should not run out of data here, so complain */
        errmsg = libpq_gettext("insufficient data in \"D\" message");
        goto advance_and_error;
    }

    if (tupnfields != nfields)
    {
        errmsg = libpq_gettext("unexpected field count in \"D\" message");
        goto advance_and_error;
    }

> Currently I use an assert since I assume it always is the same, however I
> only have tested with a very limited dataset so far.

An assert seems overly optimistic.  libpq has an explicit test with an
error recovery path, you should too.

                        regards, tom lane

pgsql-interfaces by date:

Previous
From: Tom Lane
Date:
Subject: Re: Protocol Question
Next
From: Tom Lane
Date:
Subject: Re: Protocol Question