aboutsummaryrefslogtreecommitdiff
path: root/src/backend/libpq/pqcomm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/libpq/pqcomm.c')
-rw-r--r--src/backend/libpq/pqcomm.c44
1 files changed, 29 insertions, 15 deletions
diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c
index 9a4f51b7786..2cf2a36b7b3 100644
--- a/src/backend/libpq/pqcomm.c
+++ b/src/backend/libpq/pqcomm.c
@@ -12,15 +12,16 @@
* No other messages can be sent while COPY OUT is in progress; and if the
* copy is aborted by an elog(ERROR), we need to close out the copy so that
* the frontend gets back into sync. Therefore, these routines have to be
- * aware of COPY OUT state.
+ * aware of COPY OUT state. (New COPY-OUT is message-based and does *not*
+ * set the DoingCopyOut flag.)
*
* NOTE: generally, it's a bad idea to emit outgoing messages directly with
* pq_putbytes(), especially if the message would require multiple calls
* to send. Instead, use the routines in pqformat.c to construct the message
- * in a buffer and then emit it in one call to pq_putmessage. This helps
- * ensure that the channel will not be clogged by an incomplete message
- * if execution is aborted by elog(ERROR) partway through the message.
- * The only non-libpq code that should call pq_putbytes directly is COPY OUT.
+ * in a buffer and then emit it in one call to pq_putmessage. This ensures
+ * that the channel will not be clogged by an incomplete message if execution
+ * is aborted by elog(ERROR) partway through the message. The only non-libpq
+ * code that should call pq_putbytes directly is old-style COPY OUT.
*
* At one time, libpq was shared between frontend and backend, but now
* the backend's "backend/libpq" is quite separate from "interfaces/libpq".
@@ -29,7 +30,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Header: /cvsroot/pgsql/src/backend/libpq/pqcomm.c,v 1.150 2003/04/19 00:02:29 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/libpq/pqcomm.c,v 1.151 2003/04/22 00:08:06 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -846,13 +847,17 @@ pq_flush(void)
* pq_putmessage - send a normal message (suppressed in COPY OUT mode)
*
* If msgtype is not '\0', it is a message type code to place before
- * the message body (len counts only the body size!).
- * If msgtype is '\0', then the buffer already includes the type code.
+ * the message body. If msgtype is '\0', then the message has no type
+ * code (this is only valid in pre-3.0 protocols).
*
- * All normal messages are suppressed while COPY OUT is in progress.
- * (In practice only a few messages might get emitted then; dropping
- * them is annoying, but at least they will still appear in the
- * postmaster log.)
+ * len is the length of the message body data at *s. In protocol 3.0
+ * and later, a message length word (equal to len+4 because it counts
+ * itself too) is inserted by this routine.
+ *
+ * All normal messages are suppressed while old-style COPY OUT is in
+ * progress. (In practice only a few notice messages might get emitted
+ * then; dropping them is annoying, but at least they will still appear
+ * in the postmaster log.)
*
* returns 0 if OK, EOF if trouble
* --------------------------------
@@ -865,6 +870,14 @@ pq_putmessage(char msgtype, const char *s, size_t len)
if (msgtype)
if (pq_putbytes(&msgtype, 1))
return EOF;
+ if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3)
+ {
+ uint32 n32;
+
+ n32 = htonl((uint32) (len + 4));
+ if (pq_putbytes((char *) &n32, 4))
+ return EOF;
+ }
return pq_putbytes(s, len);
}
@@ -880,12 +893,13 @@ pq_startcopyout(void)
}
/* --------------------------------
- * pq_endcopyout - end a COPY OUT transfer
+ * pq_endcopyout - end an old-style COPY OUT transfer
*
* If errorAbort is indicated, we are aborting a COPY OUT due to an error,
* and must send a terminator line. Since a partial data line might have
* been emitted, send a couple of newlines first (the first one could
- * get absorbed by a backslash...)
+ * get absorbed by a backslash...) Note that old-style COPY OUT does
+ * not allow binary transfers, so a textual terminator is always correct.
* --------------------------------
*/
void
@@ -893,8 +907,8 @@ pq_endcopyout(bool errorAbort)
{
if (!DoingCopyOut)
return;
+ DoingCopyOut = false;
if (errorAbort)
pq_putbytes("\n\n\\.\n", 5);
/* in non-error case, copy.c will have emitted the terminator line */
- DoingCopyOut = false;
}