From: | Robert Haas <robertmhaas(at)gmail(dot)com> |
---|---|
To: | Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> |
Cc: | "pgsql-hackers(at)postgresql(dot)org" <pgsql-hackers(at)postgresql(dot)org> |
Subject: | Re: PQputCopyEnd doesn't adhere to its API contract |
Date: | 2014-05-08 16:27:16 |
Message-ID: | CA+TgmobWtpuX7-zMRuEyMe3+KrVcTEeYbk__rt7P0DwmsXoTHQ@mail.gmail.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-hackers |
On Thu, May 8, 2014 at 12:09 PM, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> wrote:
> Robert Haas <robertmhaas(at)gmail(dot)com> writes:
>> According to the documentation for PQputCopyEnd:
>>> The result is 1 if the termination data was sent, zero if it was not sent because the attempt would block (this case is only possible if the connection is in
>>> nonblocking mode), or -1 if an error occurred. (Use PQerrorMessage to retrieve details if the return value is -1. If the value is zero, wait for write-ready and try again.)
>
>> However, pqPutCopyEnd contains no return statement that can ever
>> possibly return 0.
>
> IIRC, for some of the libpq functions, the API spec was intended to allow
> for future async behavior that wasn't actually implemented. So the mere
> fact that it can't return zero today is not a problem. If it might block
> instead, then we have a problem, but that's not what you're saying.
>
> Also, what the API spec says is that clients should retry PQputCopyEnd
> on a zero return. We do *not* want them to do that here; once we've
> changed asyncStatus, a retry would report an error. So the API spec
> in this case is intended to require a retry loop that the current
> implementation doesn't actually need, but that conceivably could be
> needed after some future refactoring. In particular, we might want
> to fix the code so that it returns zero if it fails to queue the
> COPY END message at all.
Yeah, good point. I think what confused me is the fact that the
documentation says that when PQputCopyEnd() returns 1, that means that
"the termination data was sent". So my application sat there and
waited for a server response that never showed up, because in fact the
termination data had *not* been sent.
What I'm now thinking I need to do is something like this:
1. If PQputCopyEnd returns -1, error.
2. while ((rc = PQflush(conn)) != 0) { if (rc < 0) { error; } else {
wait for socket to become read-ready or write-ready; } }
3. while (PQisBusy(conn)) { wait for the socket to become read-ready; }
4. PQgetResult()
Does that sound right?
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
From | Date | Subject | |
---|---|---|---|
Next Message | Andres Freund | 2014-05-08 16:29:00 | A couple logical decoding fixes/patches |
Previous Message | Tomas Vondra | 2014-05-08 16:21:16 | Re: Sending out a request for more buildfarm animals? |