diff options
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/access/common/printtup.c | 32 | ||||
-rw-r--r-- | src/backend/commands/async.c | 10 | ||||
-rw-r--r-- | src/backend/commands/copy.c | 151 | ||||
-rw-r--r-- | src/backend/libpq/auth.c | 5 | ||||
-rw-r--r-- | src/backend/libpq/pqcomm.c | 44 | ||||
-rw-r--r-- | src/backend/libpq/pqformat.c | 44 | ||||
-rw-r--r-- | src/backend/postmaster/postmaster.c | 22 | ||||
-rw-r--r-- | src/backend/tcop/dest.c | 16 | ||||
-rw-r--r-- | src/backend/tcop/fastpath.c | 5 | ||||
-rw-r--r-- | src/backend/tcop/postgres.c | 7 | ||||
-rw-r--r-- | src/backend/utils/error/elog.c | 21 |
11 files changed, 236 insertions, 121 deletions
diff --git a/src/backend/access/common/printtup.c b/src/backend/access/common/printtup.c index f1f96f18868..c88dedd93fd 100644 --- a/src/backend/access/common/printtup.c +++ b/src/backend/access/common/printtup.c @@ -9,7 +9,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/access/common/printtup.c,v 1.65 2002/09/04 20:31:08 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/access/common/printtup.c,v 1.66 2003/04/22 00:08:06 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -77,15 +77,18 @@ static void printtup_setup(DestReceiver *self, int operation, const char *portalName, TupleDesc typeinfo) { - /* - * Send portal name to frontend. - * - * If portal name not specified, use "blank" portal. - */ - if (portalName == NULL) - portalName = "blank"; - - pq_puttextmessage('P', portalName); + if (PG_PROTOCOL_MAJOR(FrontendProtocol) < 3) + { + /* + * Send portal name to frontend (obsolete cruft, gone in proto 3.0) + * + * If portal name not specified, use "blank" portal. + */ + if (portalName == NULL) + portalName = "blank"; + + pq_puttextmessage('P', portalName); + } /* * if this is a retrieve, then we send back the tuple descriptor of @@ -98,8 +101,7 @@ printtup_setup(DestReceiver *self, int operation, int i; StringInfoData buf; - pq_beginmessage(&buf); - pq_sendbyte(&buf, 'T'); /* tuple descriptor message type */ + pq_beginmessage(&buf, 'T'); /* tuple descriptor message type */ pq_sendint(&buf, natts, 2); /* # of attrs in tuples */ for (i = 0; i < natts; ++i) @@ -174,8 +176,7 @@ printtup(HeapTuple tuple, TupleDesc typeinfo, DestReceiver *self) /* * tell the frontend to expect new tuple data (in ASCII style) */ - pq_beginmessage(&buf); - pq_sendbyte(&buf, 'D'); + pq_beginmessage(&buf, 'D'); /* * send a bitmap of which attributes are not null @@ -388,8 +389,7 @@ printtup_internal(HeapTuple tuple, TupleDesc typeinfo, DestReceiver *self) /* * tell the frontend to expect new tuple data (in binary style) */ - pq_beginmessage(&buf); - pq_sendbyte(&buf, 'B'); + pq_beginmessage(&buf, 'B'); /* * send a bitmap of which attributes are not null diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index 169c4ce278c..1d9fbf65809 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.92 2003/02/18 02:53:29 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.93 2003/04/22 00:08:06 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -847,10 +847,14 @@ NotifyMyFrontEnd(char *relname, int32 listenerPID) { StringInfoData buf; - pq_beginmessage(&buf); - pq_sendbyte(&buf, 'A'); + pq_beginmessage(&buf, 'A'); pq_sendint(&buf, listenerPID, sizeof(int32)); pq_sendstring(&buf, relname); + if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3) + { + /* XXX Add parameter string here later */ + pq_sendstring(&buf, ""); + } pq_endmessage(&buf); /* diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c index 32e2362e99b..40948e3a3b5 100644 --- a/src/backend/commands/copy.c +++ b/src/backend/commands/copy.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.194 2003/04/19 20:36:03 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.195 2003/04/22 00:08:06 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -50,13 +50,6 @@ #define ISOCTAL(c) (((c) >= '0') && ((c) <= '7')) #define OCTVALUE(c) ((c) - '0') -/* Default line termination */ -#ifndef WIN32 -#define PGEOL "\n" -#else -#define PGEOL "\r\n" -#endif - /* * Represents the different source/dest cases we need to worry about at * the bottom level @@ -92,7 +85,7 @@ typedef enum EolType /* non-export function prototypes */ static void CopyTo(Relation rel, List *attnumlist, bool binary, bool oids, - bool pipe, char *delim, char *null_print); + char *delim, char *null_print); static void CopyFrom(Relation rel, List *attnumlist, bool binary, bool oids, char *delim, char *null_print); static Oid GetInputFunction(Oid type); @@ -101,8 +94,7 @@ static char *CopyReadAttribute(const char *delim, CopyReadResult *result); static void CopyAttributeOut(char *string, char *delim); static List *CopyGetAttnums(Relation rel, List *attnamelist); -/* The trailing null is part of the signature */ -static const char BinarySignature[] = "PGBCOPY\n\377\r\n"; +static const char BinarySignature[12] = "PGBCOPY\n\377\r\n\0"; /* * Static communication variables ... pretty grotty, but COPY has @@ -135,10 +127,11 @@ static int server_encoding; */ static void SendCopyBegin(bool binary); static void ReceiveCopyBegin(bool binary); -static void SendCopyEnd(bool binary, bool pipe); +static void SendCopyEnd(bool binary); static void CopySendData(void *databuf, int datasize); static void CopySendString(const char *str); static void CopySendChar(char c); +static void CopySendEndOfRow(bool binary); static void CopyGetData(void *databuf, int datasize); static int CopyGetChar(void); #define CopyGetEof() (fe_eof) @@ -154,22 +147,32 @@ SendCopyBegin(bool binary) { if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3) { - pq_putbytes("H", 1); /* new way */ - /* XXX grottiness needed for old protocol */ - pq_startcopyout(); + /* new way */ + StringInfoData buf; + + pq_beginmessage(&buf, 'H'); + pq_sendbyte(&buf, binary ? 1 : 0); + pq_endmessage(&buf); copy_dest = COPY_NEW_FE; + copy_msgbuf = makeStringInfo(); } else if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 2) { - pq_putbytes("H", 1); /* old way */ - /* grottiness needed for old protocol */ + /* old way */ + if (binary) + elog(ERROR, "COPY BINARY is not supported to stdout or from stdin"); + pq_putemptymessage('H'); + /* grottiness needed for old COPY OUT protocol */ pq_startcopyout(); copy_dest = COPY_OLD_FE; } else { - pq_putbytes("B", 1); /* very old way */ - /* grottiness needed for old protocol */ + /* very old way */ + if (binary) + elog(ERROR, "COPY BINARY is not supported to stdout or from stdin"); + pq_putemptymessage('B'); + /* grottiness needed for old COPY OUT protocol */ pq_startcopyout(); copy_dest = COPY_OLD_FE; } @@ -180,18 +183,29 @@ ReceiveCopyBegin(bool binary) { if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3) { - pq_putbytes("G", 1); /* new way */ + /* new way */ + StringInfoData buf; + + pq_beginmessage(&buf, 'G'); + pq_sendbyte(&buf, binary ? 1 : 0); + pq_endmessage(&buf); copy_dest = COPY_NEW_FE; copy_msgbuf = makeStringInfo(); } else if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 2) { - pq_putbytes("G", 1); /* old way */ + /* old way */ + if (binary) + elog(ERROR, "COPY BINARY is not supported to stdout or from stdin"); + pq_putemptymessage('G'); copy_dest = COPY_OLD_FE; } else { - pq_putbytes("D", 1); /* very old way */ + /* very old way */ + if (binary) + elog(ERROR, "COPY BINARY is not supported to stdout or from stdin"); + pq_putemptymessage('D'); copy_dest = COPY_OLD_FE; } /* We *must* flush here to ensure FE knows it can send. */ @@ -199,22 +213,39 @@ ReceiveCopyBegin(bool binary) } static void -SendCopyEnd(bool binary, bool pipe) +SendCopyEnd(bool binary) { - if (!binary) + if (copy_dest == COPY_NEW_FE) { - CopySendString("\\."); - CopySendString(!pipe ? PGEOL : "\n"); + if (binary) + { + /* Need to flush out file trailer word */ + CopySendEndOfRow(true); + } + else + { + /* Shouldn't have any unsent data */ + Assert(copy_msgbuf->len == 0); + } + /* Send Copy Done message */ + pq_putemptymessage('c'); + } + else + { + /* The FE/BE protocol uses \n as newline for all platforms */ + CopySendData("\\.\n", 3); + pq_endcopyout(false); } - pq_endcopyout(false); } -/* +/*---------- * CopySendData sends output data to the destination (file or frontend) * CopySendString does the same for null-terminated strings * CopySendChar does the same for single characters + * CopySendEndOfRow does the appropriate thing at end of each data row * * NB: no data conversion is applied by these functions + *---------- */ static void CopySendData(void *databuf, int datasize) @@ -228,12 +259,13 @@ CopySendData(void *databuf, int datasize) break; case COPY_OLD_FE: if (pq_putbytes((char *) databuf, datasize)) - fe_eof = true; + { + /* no hope of recovering connection sync, so FATAL */ + elog(FATAL, "CopySendData: connection lost"); + } break; case COPY_NEW_FE: - /* XXX fix later */ - if (pq_putbytes((char *) databuf, datasize)) - fe_eof = true; + appendBinaryStringInfo(copy_msgbuf, (char *) databuf, datasize); break; } } @@ -250,6 +282,40 @@ CopySendChar(char c) CopySendData(&c, 1); } +static void +CopySendEndOfRow(bool binary) +{ + switch (copy_dest) + { + case COPY_FILE: + if (!binary) + { + /* Default line termination depends on platform */ +#ifndef WIN32 + CopySendChar('\n'); +#else + CopySendString("\r\n"); +#endif + } + break; + case COPY_OLD_FE: + /* The FE/BE protocol uses \n as newline for all platforms */ + if (!binary) + CopySendChar('\n'); + break; + case COPY_NEW_FE: + /* The FE/BE protocol uses \n as newline for all platforms */ + if (!binary) + CopySendChar('\n'); + /* Dump the accumulated row as one CopyData message */ + (void) pq_putmessage('d', copy_msgbuf->data, copy_msgbuf->len); + /* Reset copy_msgbuf to empty */ + copy_msgbuf->len = 0; + copy_msgbuf->data[0] = '\0'; + break; + } +} + /* * CopyGetData reads data from the source (file or frontend) * CopyGetChar does the same for single characters @@ -569,13 +635,6 @@ DoCopy(const CopyStmt *stmt) "from stdin. Psql's \\copy command also works for anyone."); /* - * This restriction is unfortunate, but necessary until the frontend - * COPY protocol is redesigned to be binary-safe... - */ - if (pipe && binary) - elog(ERROR, "COPY BINARY is not supported to stdout or from stdin"); - - /* * Presently, only single-character delimiter strings are supported. */ if (strlen(delim) != 1) @@ -698,13 +757,13 @@ DoCopy(const CopyStmt *stmt) elog(ERROR, "COPY: %s is a directory", filename); } } - CopyTo(rel, attnumlist, binary, oids, pipe, delim, null_print); + CopyTo(rel, attnumlist, binary, oids, delim, null_print); } if (!pipe) FreeFile(copy_file); else if (IsUnderPostmaster && !is_from) - SendCopyEnd(binary, pipe); + SendCopyEnd(binary); pfree(attribute_buf.data); /* @@ -721,7 +780,7 @@ DoCopy(const CopyStmt *stmt) * Copy from relation TO file. */ static void -CopyTo(Relation rel, List *attnumlist, bool binary, bool oids, bool pipe, +CopyTo(Relation rel, List *attnumlist, bool binary, bool oids, char *delim, char *null_print) { HeapTuple tuple; @@ -786,7 +845,7 @@ CopyTo(Relation rel, List *attnumlist, bool binary, bool oids, bool pipe, int32 tmp; /* Signature */ - CopySendData((char *) BinarySignature, sizeof(BinarySignature)); + CopySendData((char *) BinarySignature, 12); /* Integer layout field */ tmp = 0x01020304; CopySendData(&tmp, sizeof(int32)); @@ -918,8 +977,7 @@ CopyTo(Relation rel, List *attnumlist, bool binary, bool oids, bool pipe, } } - if (!binary) - CopySendString(!pipe ? PGEOL : "\n"); + CopySendEndOfRow(binary); MemoryContextSwitchTo(oldcontext); } @@ -1100,8 +1158,7 @@ CopyFrom(Relation rel, List *attnumlist, bool binary, bool oids, /* Signature */ CopyGetData(readSig, 12); - if (CopyGetEof() || memcmp(readSig, BinarySignature, - sizeof(BinarySignature)) != 0) + if (CopyGetEof() || memcmp(readSig, BinarySignature, 12) != 0) elog(ERROR, "COPY BINARY: file signature not recognized"); /* Integer layout field */ CopyGetData(&tmp, sizeof(int32)); diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c index a5dc8eff2da..2edc919c6d2 100644 --- a/src/backend/libpq/auth.c +++ b/src/backend/libpq/auth.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/libpq/auth.c,v 1.99 2003/04/19 00:02:29 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/libpq/auth.c,v 1.100 2003/04/22 00:08:06 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -512,8 +512,7 @@ sendAuthRequest(Port *port, AuthRequest areq) { StringInfoData buf; - pq_beginmessage(&buf); - pq_sendbyte(&buf, 'R'); + pq_beginmessage(&buf, 'R'); pq_sendint(&buf, (int32) areq, sizeof(int32)); /* Add the salt for encrypted passwords. */ 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; } diff --git a/src/backend/libpq/pqformat.c b/src/backend/libpq/pqformat.c index 80ca3190999..dacfa93ecc7 100644 --- a/src/backend/libpq/pqformat.c +++ b/src/backend/libpq/pqformat.c @@ -18,7 +18,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/pqformat.c,v 1.27 2003/04/19 00:02:29 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/libpq/pqformat.c,v 1.28 2003/04/22 00:08:06 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -38,6 +38,7 @@ * * Special-case message output: * pq_puttextmessage - generate a character set-converted message in one step + * pq_putemptymessage - convenience routine for message with empty body * * Message parsing after input: * pq_getmsgbyte - get a raw byte from a message buffer @@ -64,6 +65,22 @@ /* -------------------------------- + * pq_beginmessage - initialize for sending a message + * -------------------------------- + */ +void +pq_beginmessage(StringInfo buf, char msgtype) +{ + initStringInfo(buf); + /* + * We stash the message type into the buffer's cursor field, expecting + * that the pq_sendXXX routines won't touch it. We could alternatively + * make it the first byte of the buffer contents, but this seems easier. + */ + buf->cursor = msgtype; +} + +/* -------------------------------- * pq_sendbyte - append a raw byte to a StringInfo buffer * -------------------------------- */ @@ -176,7 +193,8 @@ pq_sendint(StringInfo buf, int i, int b) void pq_endmessage(StringInfo buf) { - (void) pq_putmessage('\0', buf->data, buf->len); + /* msgtype was saved in cursor field */ + (void) pq_putmessage(buf->cursor, buf->data, buf->len); /* no need to complain about any failure, since pqcomm.c already did */ pfree(buf->data); buf->data = NULL; @@ -188,11 +206,9 @@ pq_endmessage(StringInfo buf) * This is the same as the pqcomm.c routine pq_putmessage, except that * the message body is a null-terminated string to which encoding * conversion applies. - * - * returns 0 if OK, EOF if trouble * -------------------------------- */ -int +void pq_puttextmessage(char msgtype, const char *str) { int slen = strlen(str); @@ -201,12 +217,22 @@ pq_puttextmessage(char msgtype, const char *str) p = (char *) pg_server_to_client((unsigned char *) str, slen); if (p != str) /* actual conversion has been done? */ { - int result = pq_putmessage(msgtype, p, strlen(p) + 1); - + (void) pq_putmessage(msgtype, p, strlen(p) + 1); pfree(p); - return result; + return; } - return pq_putmessage(msgtype, str, slen + 1); + (void) pq_putmessage(msgtype, str, slen + 1); +} + + +/* -------------------------------- + * pq_putemptymessage - convenience routine for message with empty body + * -------------------------------- + */ +void +pq_putemptymessage(char msgtype) +{ + (void) pq_putmessage(msgtype, NULL, 0); } diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index d6beb0fc1a6..834b03ab628 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -37,7 +37,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.313 2003/04/19 00:02:29 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.314 2003/04/22 00:08:06 tgl Exp $ * * NOTES * @@ -1118,7 +1118,13 @@ ProcessStartupPacket(Port *port, bool SSLdone) if (pq_getbytes((char *) &len, 4) == EOF) { - elog(COMMERROR, "incomplete startup packet"); + /* + * EOF after SSLdone probably means the client didn't like our + * response to NEGOTIATE_SSL_CODE. That's not an error condition, + * so don't clutter the log with a complaint. + */ + if (!SSLdone) + elog(COMMERROR, "incomplete startup packet"); return STATUS_ERROR; } @@ -1127,7 +1133,10 @@ ProcessStartupPacket(Port *port, bool SSLdone) if (len < (int32) sizeof(ProtocolVersion) || len > MAX_STARTUP_PACKET_LENGTH) - elog(FATAL, "invalid length of startup packet"); + { + elog(COMMERROR, "invalid length of startup packet"); + return STATUS_ERROR; + } /* * Allocate at least the size of an old-style startup packet, plus one @@ -1173,7 +1182,7 @@ ProcessStartupPacket(Port *port, bool SSLdone) #endif if (send(port->sock, &SSLok, 1, 0) != 1) { - elog(LOG, "failed to send SSL negotiation response: %m"); + elog(COMMERROR, "failed to send SSL negotiation response: %m"); return STATUS_ERROR; /* close the connection */ } @@ -1188,6 +1197,11 @@ ProcessStartupPacket(Port *port, bool SSLdone) /* Could add additional special packet types here */ + /* + * Set FrontendProtocol now so that elog() knows what format to send + * if we fail during startup. + */ + FrontendProtocol = proto; /* * XXX temporary for 3.0 protocol development: we are using the minor diff --git a/src/backend/tcop/dest.c b/src/backend/tcop/dest.c index 07e4614e799..5ccaa60995c 100644 --- a/src/backend/tcop/dest.c +++ b/src/backend/tcop/dest.c @@ -8,7 +8,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/tcop/dest.c,v 1.52 2003/04/19 00:02:29 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/tcop/dest.c,v 1.53 2003/04/22 00:08:07 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -141,7 +141,9 @@ EndCommand(const char *commandTag, CommandDest dest) * libpq's crufty way of determining whether a multiple-command * query string is done. In protocol 2.0 it's probably not really * necessary to distinguish empty queries anymore, but we still do it - * for backwards compatibility with 1.0. + * for backwards compatibility with 1.0. In protocol 3.0 it has some + * use again, since it ensures that there will be a recognizable end + * to the response to an Execute message. * ---------------- */ void @@ -153,9 +155,13 @@ NullCommand(CommandDest dest) case Remote: /* - * tell the fe that we saw an empty query string + * tell the fe that we saw an empty query string. In protocols + * before 3.0 this has a useless empty-string message body. */ - pq_putbytes("I", 2); /* note we send I and \0 */ + if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3) + pq_putemptymessage('I'); + else + pq_puttextmessage('I', ""); break; case Debug: @@ -184,7 +190,7 @@ ReadyForQuery(CommandDest dest) case RemoteInternal: case Remote: if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 2) - pq_putbytes("Z", 1); + pq_putemptymessage('Z'); /* Flush output at end of cycle in any case. */ pq_flush(); break; diff --git a/src/backend/tcop/fastpath.c b/src/backend/tcop/fastpath.c index eeddea6f6eb..b8750957349 100644 --- a/src/backend/tcop/fastpath.c +++ b/src/backend/tcop/fastpath.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/tcop/fastpath.c,v 1.58 2003/04/19 00:02:29 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/tcop/fastpath.c,v 1.59 2003/04/22 00:08:07 tgl Exp $ * * NOTES * This cruft is the server side of PQfn. @@ -119,8 +119,7 @@ SendFunctionResult(Datum retval, bool retbyval, int retlen) { StringInfoData buf; - pq_beginmessage(&buf); - pq_sendbyte(&buf, 'V'); + pq_beginmessage(&buf, 'V'); if (retlen != 0) { diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index fcc6591f7c0..5c51a1056a2 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.322 2003/04/19 00:02:29 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.323 2003/04/22 00:08:07 tgl Exp $ * * NOTES * this is the "main" module of the postgres backend and @@ -1821,8 +1821,7 @@ PostgresMain(int argc, char *argv[], const char *username) { StringInfoData buf; - pq_beginmessage(&buf); - pq_sendbyte(&buf, 'K'); + pq_beginmessage(&buf, 'K'); pq_sendint(&buf, (int32) MyProcPid, sizeof(int32)); pq_sendint(&buf, (int32) MyCancelKey, sizeof(int32)); pq_endmessage(&buf); @@ -1832,7 +1831,7 @@ PostgresMain(int argc, char *argv[], const char *username) if (!IsUnderPostmaster) { puts("\nPOSTGRES backend interactive interface "); - puts("$Revision: 1.322 $ $Date: 2003/04/19 00:02:29 $\n"); + puts("$Revision: 1.323 $ $Date: 2003/04/22 00:08:07 $\n"); } /* diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c index 763024b5773..01250f9a2f0 100644 --- a/src/backend/utils/error/elog.c +++ b/src/backend/utils/error/elog.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/error/elog.c,v 1.107 2003/03/20 03:34:56 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/error/elog.c,v 1.108 2003/04/22 00:08:07 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -406,20 +406,19 @@ elog(int lev, const char *fmt,...) */ oldcxt = MemoryContextSwitchTo(ErrorContext); - if (lev <= WARNING) - /* exclude the timestamp from msg sent to frontend */ - send_message_to_frontend(lev, msg_buf + timestamp_size); - else + if (lev >= ERROR) { /* * Abort any COPY OUT in progress when an error is detected. - * This hack is necessary because of poor design of copy - * protocol. + * This hack is necessary because of poor design of old-style + * copy protocol. */ pq_endcopyout(true); - send_message_to_frontend(ERROR, msg_buf + timestamp_size); } + /* Exclude the timestamp from msg sent to frontend */ + send_message_to_frontend(lev, msg_buf + timestamp_size); + MemoryContextSwitchTo(oldcxt); } @@ -745,11 +744,9 @@ send_message_to_frontend(int type, const char *msg) { StringInfoData buf; - AssertArg(type <= ERROR); - - pq_beginmessage(&buf); /* 'N' (Notice) is for nonfatal conditions, 'E' is for errors */ - pq_sendbyte(&buf, type < ERROR ? 'N' : 'E'); + pq_beginmessage(&buf, (type < ERROR) ? 'N' : 'E'); + /* XXX more to do here */ pq_sendstring(&buf, msg); pq_endmessage(&buf); |