Commit b05d3ae1 authored by Tom Lane's avatar Tom Lane

Error message editing in backend/libpq, backend/postmaster, backend/tcop.

Along the way, fix some logic problems in pgstat_initstats, notably the
bogus assumption that malloc returns zeroed memory.
parent 277dbb0c
<!--
$Header: /cvsroot/pgsql/doc/src/sgml/sources.sgml,v 2.9 2003/07/18 23:20:32 tgl Exp $
$Header: /cvsroot/pgsql/doc/src/sgml/sources.sgml,v 2.10 2003/07/22 19:00:07 tgl Exp $
-->
<chapter id="source">
......@@ -234,6 +234,13 @@ less -x4
primary error message text.
</para>
</listitem>
<listitem>
<para>
<function>errcode_for_socket_access</>() is a convenience function that
selects an appropriate SQLSTATE error identifier for a failure in a
socket-related system call.
</para>
</listitem>
</itemizedlist>
</para>
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/alter.c,v 1.2 2003/07/20 21:56:32 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/alter.c,v 1.3 2003/07/22 19:00:07 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -29,41 +29,12 @@
#include "commands/user.h"
#include "miscadmin.h"
#include "parser/parse_clause.h"
#include "tcop/utility.h"
#include "utils/acl.h"
#include "utils/lsyscache.h"
#include "utils/syscache.h"
static void
CheckOwnership(RangeVar *rel, bool noCatalogs)
{
Oid relOid;
HeapTuple tuple;
relOid = RangeVarGetRelid(rel, false);
tuple = SearchSysCache(RELOID,
ObjectIdGetDatum(relOid),
0, 0, 0);
if (!HeapTupleIsValid(tuple)) /* should not happen */
elog(ERROR, "cache lookup failed for relation %u", relOid);
if (!pg_class_ownercheck(relOid, GetUserId()))
aclcheck_error(ACLCHECK_NOT_OWNER, rel->relname);
if (noCatalogs)
{
if (!allowSystemTableMods &&
IsSystemClass((Form_pg_class) GETSTRUCT(tuple)))
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("relation \"%s\" is a system catalog",
rel->relname)));
}
ReleaseSysCache(tuple);
}
void
ExecRenameStmt(RenameStmt *stmt)
{
......@@ -111,7 +82,7 @@ ExecRenameStmt(RenameStmt *stmt)
{
Oid relid;
CheckOwnership(stmt->relation, true);
CheckRelationOwnership(stmt->relation, true);
relid = RangeVarGetRelid(stmt->relation, false);
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.203 2003/07/21 17:04:58 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.204 2003/07/22 19:00:07 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -1923,7 +1923,7 @@ CopyReadBinaryAttribute(int column_no, FmgrInfo *flinfo, Oid typelem,
/* Trouble if it didn't eat the whole buffer */
if (attribute_buf.cursor != attribute_buf.len)
ereport(ERROR,
(errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
errmsg("incorrect binary data format in field %d",
column_no)));
......
This diff is collapsed.
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/libpq/be-fsstubs.c,v 1.64 2003/05/27 17:49:46 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/libpq/be-fsstubs.c,v 1.65 2003/07/22 19:00:10 tgl Exp $
*
* NOTES
* This should be moved to a more appropriate place. It is here
......@@ -119,7 +119,9 @@ lo_close(PG_FUNCTION_ARGS)
if (fd < 0 || fd >= cookies_size || cookies[fd] == NULL)
{
elog(ERROR, "lo_close: invalid large obj descriptor (%d)", fd);
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("invalid large-object descriptor: %d", fd)));
PG_RETURN_INT32(-1);
}
#if FSDB
......@@ -155,7 +157,9 @@ lo_read(int fd, char *buf, int len)
if (fd < 0 || fd >= cookies_size || cookies[fd] == NULL)
{
elog(ERROR, "lo_read: invalid large obj descriptor (%d)", fd);
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("invalid large-object descriptor: %d", fd)));
return -1;
}
......@@ -177,7 +181,9 @@ lo_write(int fd, char *buf, int len)
if (fd < 0 || fd >= cookies_size || cookies[fd] == NULL)
{
elog(ERROR, "lo_write: invalid large obj descriptor (%d)", fd);
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("invalid large-object descriptor: %d", fd)));
return -1;
}
......@@ -203,7 +209,9 @@ lo_lseek(PG_FUNCTION_ARGS)
if (fd < 0 || fd >= cookies_size || cookies[fd] == NULL)
{
elog(ERROR, "lo_lseek: invalid large obj descriptor (%d)", fd);
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("invalid large-object descriptor: %d", fd)));
PG_RETURN_INT32(-1);
}
......@@ -258,7 +266,9 @@ lo_tell(PG_FUNCTION_ARGS)
if (fd < 0 || fd >= cookies_size || cookies[fd] == NULL)
{
elog(ERROR, "lo_tell: invalid large object descriptor (%d)", fd);
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("invalid large-object descriptor: %d", fd)));
PG_RETURN_INT32(-1);
}
......@@ -360,9 +370,10 @@ lo_import(PG_FUNCTION_ARGS)
#ifndef ALLOW_DANGEROUS_LO_FUNCTIONS
if (!superuser())
elog(ERROR, "You must have Postgres superuser privilege to use "
"server-side lo_import().\n\tAnyone can use the "
"client-side lo_import() provided by libpq.");
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("must be superuser to use server-side lo_import()"),
errhint("Anyone can use the client-side lo_import() provided by libpq.")));
#endif
/*
......@@ -375,16 +386,15 @@ lo_import(PG_FUNCTION_ARGS)
fnamebuf[nbytes] = '\0';
fd = PathNameOpenFile(fnamebuf, O_RDONLY | PG_BINARY, 0666);
if (fd < 0)
elog(ERROR, "lo_import: can't open unix file \"%s\": %m",
fnamebuf);
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not open server file \"%s\": %m",
fnamebuf)));
/*
* create an inversion "object"
* create an inversion object
*/
lobj = inv_create(INV_READ | INV_WRITE);
if (lobj == NULL)
elog(ERROR, "lo_import: can't create inv object for \"%s\"",
fnamebuf);
lobjOid = lobj->id;
/*
......@@ -393,11 +403,15 @@ lo_import(PG_FUNCTION_ARGS)
while ((nbytes = FileRead(fd, buf, BUFSIZE)) > 0)
{
tmp = inv_write(lobj, buf, nbytes);
if (tmp != nbytes)
elog(ERROR, "lo_import: error while reading \"%s\"",
fnamebuf);
Assert(tmp == nbytes);
}
if (nbytes < 0)
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not read server file \"%s\": %m",
fnamebuf)));
FileClose(fd);
inv_close(lobj);
......@@ -423,17 +437,16 @@ lo_export(PG_FUNCTION_ARGS)
#ifndef ALLOW_DANGEROUS_LO_FUNCTIONS
if (!superuser())
elog(ERROR, "You must have Postgres superuser privilege to use "
"server-side lo_export().\n\tAnyone can use the "
"client-side lo_export() provided by libpq.");
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("must be superuser to use server-side lo_export()"),
errhint("Anyone can use the client-side lo_export() provided by libpq.")));
#endif
/*
* open the inversion "object"
* open the inversion object (no need to test for failure)
*/
lobj = inv_open(lobjId, INV_READ);
if (lobj == NULL)
elog(ERROR, "lo_export: can't open inv object %u", lobjId);
/*
* open the file to be written to
......@@ -451,8 +464,10 @@ lo_export(PG_FUNCTION_ARGS)
fd = PathNameOpenFile(fnamebuf, O_CREAT | O_WRONLY | O_TRUNC | PG_BINARY, 0666);
umask(oumask);
if (fd < 0)
elog(ERROR, "lo_export: can't open unix file \"%s\": %m",
fnamebuf);
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not create server file \"%s\": %m",
fnamebuf)));
/*
* read in from the inversion file and write to the Unix file
......@@ -461,12 +476,14 @@ lo_export(PG_FUNCTION_ARGS)
{
tmp = FileWrite(fd, buf, nbytes);
if (tmp != nbytes)
elog(ERROR, "lo_export: error while writing \"%s\"",
fnamebuf);
ereport(ERROR,
(errcode_for_file_access(),
errmsg("could not write server file \"%s\": %m",
fnamebuf)));
}
inv_close(lobj);
FileClose(fd);
inv_close(lobj);
PG_RETURN_INT32(1);
}
......
......@@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/libpq/be-secure.c,v 1.35 2003/07/01 13:49:47 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/libpq/be-secure.c,v 1.36 2003/07/22 19:00:10 tgl Exp $
*
* Since the server static private key ($DataDir/server.key)
* will normally be stored unencrypted so that the database
......@@ -277,12 +277,18 @@ secure_read(Port *port, void *ptr, size_t len)
goto rloop;
case SSL_ERROR_SYSCALL:
if (n == -1)
elog(COMMERROR, "SSL SYSCALL error: %m");
ereport(COMMERROR,
(errcode_for_socket_access(),
errmsg("SSL SYSCALL error: %m")));
else
elog(COMMERROR, "SSL SYSCALL error: EOF detected");
ereport(COMMERROR,
(errcode(ERRCODE_PROTOCOL_VIOLATION),
errmsg("SSL SYSCALL error: EOF detected")));
break;
case SSL_ERROR_SSL:
elog(COMMERROR, "SSL error: %s", SSLerrmessage());
ereport(COMMERROR,
(errcode(ERRCODE_PROTOCOL_VIOLATION),
errmsg("SSL error: %s", SSLerrmessage())));
/* fall through */
case SSL_ERROR_ZERO_RETURN:
secure_close(port);
......@@ -290,7 +296,9 @@ secure_read(Port *port, void *ptr, size_t len)
n = -1;
break;
default:
elog(COMMERROR, "Unknown SSL error code");
ereport(COMMERROR,
(errcode(ERRCODE_PROTOCOL_VIOLATION),
errmsg("unrecognized SSL error code")));
break;
}
}
......@@ -317,15 +325,23 @@ secure_write(Port *port, void *ptr, size_t len)
SSL_set_session_id_context(port->ssl, (void *) &SSL_context,
sizeof(SSL_context));
if (SSL_renegotiate(port->ssl) <= 0)
elog(COMMERROR, "SSL renegotiation failure");
ereport(COMMERROR,
(errcode(ERRCODE_PROTOCOL_VIOLATION),
errmsg("SSL renegotiation failure")));
if (SSL_do_handshake(port->ssl) <= 0)
elog(COMMERROR, "SSL renegotiation failure");
ereport(COMMERROR,
(errcode(ERRCODE_PROTOCOL_VIOLATION),
errmsg("SSL renegotiation failure")));
if (port->ssl->state != SSL_ST_OK)
elog(COMMERROR, "SSL failed to send renegotiation request");
ereport(COMMERROR,
(errcode(ERRCODE_PROTOCOL_VIOLATION),
errmsg("SSL failed to send renegotiation request")));
port->ssl->state |= SSL_ST_ACCEPT;
SSL_do_handshake(port->ssl);
if (port->ssl->state != SSL_ST_OK)
elog(COMMERROR, "SSL renegotiation failure");
ereport(COMMERROR,
(errcode(ERRCODE_PROTOCOL_VIOLATION),
errmsg("SSL renegotiation failure")));
port->count = 0;
}
......@@ -341,12 +357,18 @@ secure_write(Port *port, void *ptr, size_t len)
goto wloop;
case SSL_ERROR_SYSCALL:
if (n == -1)
elog(COMMERROR, "SSL SYSCALL error: %m");
ereport(COMMERROR,
(errcode_for_socket_access(),
errmsg("SSL SYSCALL error: %m")));
else
elog(COMMERROR, "SSL SYSCALL error: EOF detected");
ereport(COMMERROR,
(errcode(ERRCODE_PROTOCOL_VIOLATION),
errmsg("SSL SYSCALL error: EOF detected")));
break;
case SSL_ERROR_SSL:
elog(COMMERROR, "SSL error: %s", SSLerrmessage());
ereport(COMMERROR,
(errcode(ERRCODE_PROTOCOL_VIOLATION),
errmsg("SSL error: %s", SSLerrmessage())));
/* fall through */
case SSL_ERROR_ZERO_RETURN:
secure_close(port);
......@@ -354,7 +376,9 @@ secure_write(Port *port, void *ptr, size_t len)
n = -1;
break;
default:
elog(COMMERROR, "Unknown SSL error code");
ereport(COMMERROR,
(errcode(ERRCODE_PROTOCOL_VIOLATION),
errmsg("unrecognized SSL error code")));
break;
}
}
......@@ -690,7 +714,10 @@ open_server_SSL(Port *port)
!SSL_set_fd(port->ssl, port->sock) ||
SSL_accept(port->ssl) <= 0)
{
elog(COMMERROR, "failed to initialize SSL connection: %s", SSLerrmessage());
ereport(COMMERROR,
(errcode(ERRCODE_PROTOCOL_VIOLATION),
errmsg("failed to initialize SSL connection: %s",
SSLerrmessage())));
close_SSL(port);
return -1;
}
......@@ -712,7 +739,7 @@ open_server_SSL(Port *port)
NID_commonName, port->peer_cn, sizeof(port->peer_cn));
port->peer_cn[sizeof(port->peer_cn) - 1] = '\0';
}
elog(DEBUG2, "secure connection from '%s'", port->peer_cn);
elog(DEBUG2, "secure connection from \"%s\"", port->peer_cn);
/* set up debugging/info callback */
SSL_CTX_set_info_callback(SSL_context, info_cb);
......
......@@ -9,7 +9,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/crypt.c,v 1.53 2003/05/12 23:08:50 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/libpq/crypt.c,v 1.54 2003/07/22 19:00:10 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -58,8 +58,8 @@ md5_crypt_verify(const Port *port, const char *user, char *client_pass)
/* We can't do crypt with pg_shadow MD5 passwords */
if (isMD5(shadow_pass) && port->auth_method == uaCrypt)
{
elog(LOG, "Password is stored MD5 encrypted. "
"'crypt' auth method cannot be used.");
ereport(LOG,
(errmsg("cannot use CRYPT auth method because password is MD5-encrypted")));
return STATUS_ERROR;
}
......
This diff is collapsed.
......@@ -10,7 +10,7 @@
* Unfortunately, COPY OUT was designed to commandeer the communication
* channel (it just transfers data without wrapping it into messages).
* 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
* copy is aborted by an ereport(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. (New COPY-OUT is message-based and does *not*
* set the DoingCopyOut flag.)
......@@ -20,8 +20,8 @@
* 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 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.
* is aborted by ereport(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".
......@@ -30,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.157 2003/06/12 07:36:51 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/libpq/pqcomm.c,v 1.158 2003/07/22 19:00:10 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -237,8 +237,9 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
ret = getaddrinfo2(hostName, service, &hint, &addrs);
if (ret || addrs == NULL)
{
elog(LOG, "server socket failure: getaddrinfo2(): %s",
gai_strerror(ret));
ereport(LOG,
(errmsg("failed to translate hostname to address: %s",
gai_strerror(ret))));
freeaddrinfo2(hint.ai_family, addrs);
return STATUS_ERROR;
}
......@@ -269,8 +270,9 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
if ((fd = socket(addr->ai_family, addr->ai_socktype,
addr->ai_protocol)) < 0)
{
elog(LOG, "server socket failure: socket(): %s",
strerror(errno));
ereport(LOG,
(errcode_for_socket_access(),
errmsg("failed to create socket: %m")));
continue;
}
......@@ -281,9 +283,9 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
if ((setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
(char *) &one, sizeof(one))) == -1)
{
elog(LOG, "server socket failure: "
"setsockopt(SO_REUSEADDR): %s",
strerror(errno));
ereport(LOG,
(errcode_for_socket_access(),
errmsg("setsockopt(SO_REUSEADDR) failed: %m")));
closesocket(fd);
continue;
}
......@@ -295,9 +297,9 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY,
(char *)&one, sizeof(one)) == -1)
{
elog(LOG, "server socket failure: "
"setsockopt(IPV6_V6ONLY): %s",
strerror(errno));
ereport(LOG,
(errcode_for_socket_access(),
errmsg("setsockopt(IPV6_V6ONLY) failed: %m")));
closesocket(fd);
continue;
}
......@@ -313,19 +315,16 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
err = bind(fd, addr->ai_addr, addr->ai_addrlen);
if (err < 0)
{
elog(LOG, "server socket failure: bind(): %s\n"
"\tIs another postmaster already running on "
"port %d?", strerror(errno), (int) portNumber);
if (addr->ai_family == AF_UNIX)
{
elog(LOG, "\tIf not, remove socket node (%s) "
"and retry.", sock_path);
}
else
{
elog(LOG, "\tIf not, wait a few seconds and "
"retry.");
}
ereport(LOG,
(errcode_for_socket_access(),
errmsg("failed to bind server socket: %m"),
(addr->ai_family == AF_UNIX) ?
errhint("Is another postmaster already running on port %d?"
" If not, remove socket node \"%s\" and retry.",
(int) portNumber, sock_path) :
errhint("Is another postmaster already running on port %d?"
" If not, wait a few seconds and retry.",
(int) portNumber)));
closesocket(fd);
continue;
}
......@@ -354,8 +353,9 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
err = listen(fd, maxconn);
if (err < 0)
{
elog(LOG, "server socket failure: listen(): %s",
strerror(errno));
ereport(LOG,
(errcode_for_socket_access(),
errmsg("failed to listen on server socket: %m")));
closesocket(fd);
continue;
}
......@@ -417,7 +417,7 @@ Setup_AF_UNIX(void)
if (Unix_socket_group[0] != '\0')
{
#ifdef WIN32
elog(FATAL, "Config value 'unix_socket_group' not supported on this platform");
elog(WARNING, "configuration item unix_socket_group is not supported on this platform");
#else
char *endptr;
unsigned long int val;
......@@ -435,16 +435,19 @@ Setup_AF_UNIX(void)
gr = getgrnam(Unix_socket_group);
if (!gr)
{
elog(LOG, "server socket failure: no such group '%s'",
Unix_socket_group);
ereport(LOG,
(errmsg("group \"%s\" does not exist",
Unix_socket_group)));
return STATUS_ERROR;
}
gid = gr->gr_gid;
}
if (chown(sock_path, -1, gid) == -1)
{
elog(LOG, "server socket failure: could not set group of %s: %s",
sock_path, strerror(errno));
ereport(LOG,
(errcode_for_file_access(),
errmsg("could not set group of \"%s\": %m",
sock_path)));
return STATUS_ERROR;
}
#endif
......@@ -452,8 +455,10 @@ Setup_AF_UNIX(void)
if (chmod(sock_path, Unix_socket_permissions) == -1)
{
elog(LOG, "server socket failure: could not set permissions on %s: %s",
sock_path, strerror(errno));
ereport(LOG,
(errcode_for_file_access(),
errmsg("could not set permissions of \"%s\": %m",
sock_path)));
return STATUS_ERROR;
}
return STATUS_OK;
......@@ -475,13 +480,15 @@ Setup_AF_UNIX(void)
int
StreamConnection(int server_fd, Port *port)
{
/* accept connection (and fill in the client (remote) address) */
/* accept connection and fill in the client (remote) address */
port->raddr.salen = sizeof(port->raddr.addr);
if ((port->sock = accept(server_fd,
(struct sockaddr *) &port->raddr.addr,
&port->raddr.salen)) < 0)
{
elog(LOG, "StreamConnection: accept() failed: %m");
ereport(LOG,
(errcode_for_socket_access(),
errmsg("could not accept new connection: %m")));
return STATUS_ERROR;
}
......@@ -496,30 +503,33 @@ StreamConnection(int server_fd, Port *port)
/* fill in the server (local) address */
port->laddr.salen = sizeof(port->laddr.addr);
if (getsockname(port->sock, (struct sockaddr *) & port->laddr.addr,
if (getsockname(port->sock,
(struct sockaddr *) & port->laddr.addr,
&port->laddr.salen) < 0)
{
elog(LOG, "StreamConnection: getsockname() failed: %m");
elog(LOG, "getsockname() failed: %m");
return STATUS_ERROR;
}
/* select NODELAY and KEEPALIVE options if it's a TCP connection */
if (!IS_AF_UNIX(port->laddr.addr.ss_family))
{
int on = 1;
int on;
#ifdef TCP_NODELAY
on = 1;
if (setsockopt(port->sock, IPPROTO_TCP, TCP_NODELAY,
(char *) &on, sizeof(on)) < 0)
{
elog(LOG, "StreamConnection: setsockopt(TCP_NODELAY) failed: %m");
elog(LOG, "setsockopt(TCP_NODELAY) failed: %m");
return STATUS_ERROR;
}
#endif
on = 1;
if (setsockopt(port->sock, SOL_SOCKET, SO_KEEPALIVE,
(char *) &on, sizeof(on)) < 0)
{
elog(LOG, "StreamConnection: setsockopt(SO_KEEPALIVE) failed: %m");
elog(LOG, "setsockopt(SO_KEEPALIVE) failed: %m");
return STATUS_ERROR;
}
}
......@@ -622,11 +632,13 @@ pq_recvbuf(void)
continue; /* Ok if interrupted */
/*
* Careful: an elog() that tries to write to the client would
* Careful: an ereport() that tries to write to the client would
* cause recursion to here, leading to stack overflow and core
* dump! This message must go *only* to the postmaster log.
*/
elog(COMMERROR, "pq_recvbuf: recv() failed: %m");
ereport(COMMERROR,
(errcode_for_socket_access(),
errmsg("could not receive data from client: %m")));
return EOF;
}
if (r == 0)
......@@ -787,7 +799,9 @@ pq_getmessage(StringInfo s, int maxlen)
/* Read message length word */
if (pq_getbytes((char *) &len, 4) == EOF)
{
elog(COMMERROR, "unexpected EOF within message length word");
ereport(COMMERROR,
(errcode(ERRCODE_PROTOCOL_VIOLATION),
errmsg("unexpected EOF within message length word")));
return EOF;
}
......@@ -797,7 +811,9 @@ pq_getmessage(StringInfo s, int maxlen)
if (len < 0 ||
(maxlen > 0 && len > maxlen))
{
elog(COMMERROR, "invalid message length");
ereport(COMMERROR,
(errcode(ERRCODE_PROTOCOL_VIOLATION),
errmsg("invalid message length")));
return EOF;
}
......@@ -809,7 +825,9 @@ pq_getmessage(StringInfo s, int maxlen)
/* And grab the message */
if (pq_getbytes(s->data, len) == EOF)
{
elog(COMMERROR, "incomplete client message");
ereport(COMMERROR,
(errcode(ERRCODE_PROTOCOL_VIOLATION),
errmsg("incomplete message from client")));
return EOF;
}
s->len = len;
......@@ -874,7 +892,7 @@ pq_flush(void)
continue; /* Ok if we were interrupted */
/*
* Careful: an elog() that tries to write to the client would
* Careful: an ereport() that tries to write to the client would
* cause recursion to here, leading to stack overflow and core
* dump! This message must go *only* to the postmaster log.
*
......@@ -885,7 +903,9 @@ pq_flush(void)
if (errno != last_reported_send_errno)
{
last_reported_send_errno = errno;
elog(COMMERROR, "pq_flush: send() failed: %m");
ereport(COMMERROR,
(errcode_for_socket_access(),
errmsg("could not send data to client: %m")));
}
/*
......
......@@ -24,7 +24,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.31 2003/05/09 21:19:49 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/libpq/pqformat.c,v 1.32 2003/07/22 19:00:10 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -231,7 +231,7 @@ pq_sendint(StringInfo buf, int i, int b)
appendBinaryStringInfo(buf, (char *) &n32, 4);
break;
default:
elog(ERROR, "pq_sendint: unsupported size %d", b);
elog(ERROR, "unsupported integer size %d", b);
break;
}
}
......@@ -440,7 +440,9 @@ int
pq_getmsgbyte(StringInfo msg)
{
if (msg->cursor >= msg->len)
elog(ERROR, "pq_getmsgbyte: no data left in message");
ereport(ERROR,
(errcode(ERRCODE_PROTOCOL_VIOLATION),
errmsg("no data left in message")));
return (unsigned char) msg->data[msg->cursor++];
}
......@@ -473,7 +475,7 @@ pq_getmsgint(StringInfo msg, int b)
result = ntohl(n32);
break;
default:
elog(ERROR, "pq_getmsgint: unsupported size %d", b);
elog(ERROR, "unsupported integer size %d", b);
result = 0; /* keep compiler quiet */
break;
}
......@@ -586,7 +588,9 @@ pq_getmsgbytes(StringInfo msg, int datalen)
const char *result;
if (datalen < 0 || datalen > (msg->len - msg->cursor))
elog(ERROR, "pq_getmsgbytes: insufficient data left in message");
ereport(ERROR,
(errcode(ERRCODE_PROTOCOL_VIOLATION),
errmsg("insufficient data left in message")));
result = &msg->data[msg->cursor];
msg->cursor += datalen;
return result;
......@@ -602,7 +606,9 @@ void
pq_copymsgbytes(StringInfo msg, char *buf, int datalen)
{
if (datalen < 0 || datalen > (msg->len - msg->cursor))
elog(ERROR, "pq_copymsgbytes: insufficient data left in message");
ereport(ERROR,
(errcode(ERRCODE_PROTOCOL_VIOLATION),
errmsg("insufficient data left in message")));
memcpy(buf, &msg->data[msg->cursor], datalen);
msg->cursor += datalen;
}
......@@ -621,7 +627,9 @@ pq_getmsgtext(StringInfo msg, int rawbytes, int *nbytes)
char *p;
if (rawbytes < 0 || rawbytes > (msg->len - msg->cursor))
elog(ERROR, "pq_getmsgtext: insufficient data left in message");
ereport(ERROR,
(errcode(ERRCODE_PROTOCOL_VIOLATION),
errmsg("insufficient data left in message")));
str = &msg->data[msg->cursor];
msg->cursor += rawbytes;
......@@ -661,7 +669,9 @@ pq_getmsgstring(StringInfo msg)
*/
slen = strlen(str);
if (msg->cursor + slen >= msg->len)
elog(ERROR, "pq_getmsgstring: invalid string in message");
ereport(ERROR,
(errcode(ERRCODE_PROTOCOL_VIOLATION),
errmsg("invalid string in message")));
msg->cursor += slen + 1;
return (const char *) pg_client_to_server((unsigned char *) str, slen);
......@@ -675,5 +685,7 @@ void
pq_getmsgend(StringInfo msg)
{
if (msg->cursor != msg->len)
elog(ERROR, "pq_getmsgend: invalid message format");
ereport(ERROR,
(errcode(ERRCODE_PROTOCOL_VIOLATION),
errmsg("invalid message format")));
}
This diff is collapsed.
This diff is collapsed.
......@@ -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.58 2003/05/08 18:16:36 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/tcop/dest.c,v 1.59 2003/07/22 19:00:11 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -104,7 +104,7 @@ CreateDestReceiver(CommandDest dest, Portal portal)
case Remote:
case RemoteExecute:
if (portal == NULL)
elog(ERROR, "CreateDestReceiver: no portal specified");
elog(ERROR, "no portal specified for Remote receiver");
return printtup_create_DR(dest, portal);
case None:
......@@ -118,10 +118,10 @@ CreateDestReceiver(CommandDest dest, Portal portal)
case Tuplestore:
if (portal == NULL)
elog(ERROR, "CreateDestReceiver: no portal specified");
elog(ERROR, "no portal specified for Tuplestore receiver");
if (portal->holdStore == NULL ||
portal->holdContext == NULL)
elog(ERROR, "CreateDestReceiver: portal has no holdStore");
elog(ERROR, "portal has no holdStore");
return CreateTuplestoreDestReceiver(portal->holdStore,
portal->holdContext);
}
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/tcop/fastpath.c,v 1.64 2003/05/09 18:18:54 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/tcop/fastpath.c,v 1.65 2003/07/22 19:00:11 tgl Exp $
*
* NOTES
* This cruft is the server side of PQfn.
......@@ -101,8 +101,10 @@ GetOldFunctionMessage(StringInfo buf)
if (argsize < -1)
{
/* FATAL here since no hope of regaining message sync */
elog(FATAL, "HandleFunctionRequest: bogus argsize %d",
argsize);
ereport(FATAL,
(errcode(ERRCODE_PROTOCOL_VIOLATION),
errmsg("invalid argument size %d in function call message",
argsize)));
}
/* and arg contents */
if (argsize > 0)
......@@ -180,7 +182,9 @@ SendFunctionResult(Datum retval, bool isnull, Oid rettype, int16 format)
pfree(outputbytes);
}
else
elog(ERROR, "Invalid format code %d", format);
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("unsupported format code: %d", format)));
}
if (!newstyle)
......@@ -208,7 +212,7 @@ fetch_fp_info(Oid func_id, struct fp_info * fip)
* Since the validity of this structure is determined by whether the
* funcid is OK, we clear the funcid here. It must not be set to the
* correct value until we are about to return with a good struct
* fp_info, since we can be interrupted (i.e., with an elog(ERROR,
* fp_info, since we can be interrupted (i.e., with an ereport(ERROR,
* ...)) at any time. [No longer really an issue since we don't save
* the struct fp_info across transactions anymore, but keep it
* anyway.]
......@@ -222,8 +226,9 @@ fetch_fp_info(Oid func_id, struct fp_info * fip)
ObjectIdGetDatum(func_id),
0, 0, 0);
if (!HeapTupleIsValid(func_htp))
elog(ERROR, "fetch_fp_info: cache lookup for function %u failed",
func_id);
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_FUNCTION),
errmsg("function with OID %u does not exist", func_id)));
pp = (Form_pg_proc) GETSTRUCT(func_htp);
fip->namespace = pp->pronamespace;
......@@ -254,8 +259,8 @@ fetch_fp_info(Oid func_id, struct fp_info * fip)
* RETURNS:
* 0 if successful completion, EOF if frontend connection lost.
*
* Note: All ordinary errors result in elog(ERROR,...). However,
* if we lose the frontend connection there is no one to elog to,
* Note: All ordinary errors result in ereport(ERROR,...). However,
* if we lose the frontend connection there is no one to ereport to,
* and no use in proceeding...
*
* Note: palloc()s done here and in the called function do not need to be
......@@ -282,19 +287,23 @@ HandleFunctionRequest(StringInfo msgBuf)
{
if (GetOldFunctionMessage(msgBuf))
{
elog(COMMERROR, "unexpected EOF on client connection");
ereport(COMMERROR,
(errcode(ERRCODE_PROTOCOL_VIOLATION),
errmsg("unexpected EOF on client connection")));
return EOF;
}
}
/*
* Now that we've eaten the input message, check to see if we actually
* want to do the function call or not. It's now safe to elog(); we won't
* lose sync with the frontend.
* want to do the function call or not. It's now safe to ereport();
* we won't lose sync with the frontend.
*/
if (IsAbortedTransactionBlockState())
elog(ERROR, "current transaction is aborted, "
"queries ignored until end of transaction block");
ereport(ERROR,
(errcode(ERRCODE_IN_FAILED_SQL_TRANSACTION),
errmsg("current transaction is aborted, "
"queries ignored until end of transaction block")));
/*
* Begin parsing the buffer contents.
......@@ -404,14 +413,18 @@ parse_fcall_arguments(StringInfo msgBuf, struct fp_info *fip,
nargs = pq_getmsgint(msgBuf, 2); /* # of arguments */
if (fip->flinfo.fn_nargs != nargs || nargs > FUNC_MAX_ARGS)
elog(ERROR, "HandleFunctionRequest: actual arguments (%d) != registered arguments (%d)",
nargs, fip->flinfo.fn_nargs);
ereport(ERROR,
(errcode(ERRCODE_PROTOCOL_VIOLATION),
errmsg("function call message contains %d arguments but function requires %d",
nargs, fip->flinfo.fn_nargs)));
fcinfo->nargs = nargs;
if (numAFormats > 1 && numAFormats != nargs)
elog(ERROR, "Function Call message has %d argument formats but %d arguments",
numAFormats, nargs);
ereport(ERROR,
(errcode(ERRCODE_PROTOCOL_VIOLATION),
errmsg("function call message contains %d argument formats but %d arguments",
numAFormats, nargs)));
initStringInfo(&abuf);
......@@ -430,8 +443,10 @@ parse_fcall_arguments(StringInfo msgBuf, struct fp_info *fip,
continue;
}
if (argsize < 0)
elog(ERROR, "HandleFunctionRequest: bogus argsize %d",
argsize);
ereport(ERROR,
(errcode(ERRCODE_PROTOCOL_VIOLATION),
errmsg("invalid argument size %d in function call message",
argsize)));
/* Reset abuf to empty, and insert raw data into it */
abuf.len = 0;
......@@ -489,11 +504,15 @@ parse_fcall_arguments(StringInfo msgBuf, struct fp_info *fip,
/* Trouble if it didn't eat the whole buffer */
if (abuf.cursor != abuf.len)
elog(ERROR, "Improper binary format in function argument %d",
i + 1);
ereport(ERROR,
(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
errmsg("incorrect binary data format in function argument %d",
i + 1)));
}
else
elog(ERROR, "Invalid format code %d", aformat);
ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("unsupported format code: %d", aformat)));
}
/* Return result format code */
......@@ -517,8 +536,10 @@ parse_fcall_arguments_20(StringInfo msgBuf, struct fp_info *fip,
nargs = pq_getmsgint(msgBuf, 4); /* # of arguments */
if (fip->flinfo.fn_nargs != nargs || nargs > FUNC_MAX_ARGS)
elog(ERROR, "HandleFunctionRequest: actual arguments (%d) != registered arguments (%d)",
nargs, fip->flinfo.fn_nargs);
ereport(ERROR,
(errcode(ERRCODE_PROTOCOL_VIOLATION),
errmsg("function call message contains %d arguments but function requires %d",
nargs, fip->flinfo.fn_nargs)));
fcinfo->nargs = nargs;
......@@ -545,8 +566,10 @@ parse_fcall_arguments_20(StringInfo msgBuf, struct fp_info *fip,
continue;
}
if (argsize < 0)
elog(ERROR, "HandleFunctionRequest: bogus argsize %d",
argsize);
ereport(ERROR,
(errcode(ERRCODE_PROTOCOL_VIOLATION),
errmsg("invalid argument size %d in function call message",
argsize)));
/* Reset abuf to empty, and insert raw data into it */
abuf.len = 0;
......@@ -566,8 +589,10 @@ parse_fcall_arguments_20(StringInfo msgBuf, struct fp_info *fip,
/* Trouble if it didn't eat the whole buffer */
if (abuf.cursor != abuf.len)
elog(ERROR, "Improper binary format in function argument %d",
i + 1);
ereport(ERROR,
(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
errmsg("incorrect binary data format in function argument %d",
i + 1)));
}
/* Desired result format is always binary in protocol 2.0 */
......
This diff is collapsed.
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/tcop/pquery.c,v 1.66 2003/05/28 16:03:58 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/tcop/pquery.c,v 1.67 2003/07/22 19:00:12 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -341,8 +341,10 @@ PortalSetResultFormat(Portal portal, int nFormats, int16 *formats)
{
/* format specified for each column */
if (nFormats != natts)
elog(ERROR, "BIND message has %d result formats but query has %d columns",
nFormats, natts);
ereport(ERROR,
(errcode(ERRCODE_PROTOCOL_VIOLATION),
errmsg("bind message has %d result formats but query has %d columns",
nFormats, natts)));
memcpy(portal->formats, formats, natts * sizeof(int16));
} else if (nFormats > 0)
{
......@@ -401,9 +403,13 @@ PortalRun(Portal portal, long count,
* Check for improper portal use, and mark portal active.
*/
if (portal->portalDone)
elog(ERROR, "Portal \"%s\" cannot be run anymore", portal->name);
ereport(ERROR,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("portal \"%s\" cannot be run anymore", portal->name)));
if (portal->portalActive)
elog(ERROR, "Portal \"%s\" already active", portal->name);
ereport(ERROR,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("portal \"%s\" already active", portal->name)));
portal->portalActive = true;
/*
......@@ -468,7 +474,8 @@ PortalRun(Portal portal, long count,
break;
default:
elog(ERROR, "PortalRun: bogus portal strategy");
elog(ERROR, "unrecognized portal strategy: %d",
(int) portal->strategy);
result = false; /* keep compiler quiet */
break;
}
......@@ -577,8 +584,10 @@ PortalRunSelect(Portal portal,
else
{
if (portal->cursorOptions & CURSOR_OPT_NO_SCROLL)
elog(ERROR, "Cursor can only scan forward"
"\n\tDeclare it with SCROLL option to enable backward scan");
ereport(ERROR,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("cursor can only scan forward"),
errhint("Declare it with SCROLL option to enable backward scan.")));
if (portal->atStart || count <= 0)
direction = NoMovementScanDirection;
......@@ -900,9 +909,13 @@ PortalRunFetch(Portal portal,
* Check for improper portal use, and mark portal active.
*/
if (portal->portalDone)
elog(ERROR, "Portal \"%s\" cannot be run anymore", portal->name);
ereport(ERROR,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("portal \"%s\" cannot be run anymore", portal->name)));
if (portal->portalActive)
elog(ERROR, "Portal \"%s\" already active", portal->name);
ereport(ERROR,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("portal \"%s\" already active", portal->name)));
portal->portalActive = true;
/*
......@@ -922,7 +935,7 @@ PortalRunFetch(Portal portal,
break;
default:
elog(ERROR, "PortalRunFetch: unsupported portal strategy");
elog(ERROR, "unsupported portal strategy");
result = 0; /* keep compiler quiet */
break;
}
......@@ -1053,7 +1066,7 @@ DoPortalRunFetch(Portal portal,
}
break;
default:
elog(ERROR, "PortalRunFetch: bogus direction");
elog(ERROR, "bogus direction");
break;
}
......
This diff is collapsed.
......@@ -37,7 +37,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/error/elog.c,v 1.113 2003/07/18 23:20:32 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/error/elog.c,v 1.114 2003/07/22 19:00:12 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -572,6 +572,42 @@ errcode_for_file_access(void)
return 0; /* return value does not matter */
}
/*
* errcode_for_socket_access --- add SQLSTATE error code to the current error
*
* The SQLSTATE code is chosen based on the saved errno value. We assume
* that the failing operation was some type of socket access.
*
* NOTE: the primary error message string should generally include %m
* when this is used.
*/
int
errcode_for_socket_access(void)
{
ErrorData *edata = &errordata[errordata_stack_depth];
/* we don't bother incrementing recursion_depth */
CHECK_STACK_DEPTH();
switch (edata->saved_errno)
{
/* Loss of connection */
case EPIPE:
#ifdef ECONNRESET
case ECONNRESET:
#endif
edata->sqlerrcode = ERRCODE_CONNECTION_FAILURE;
break;
/* All else is classified as internal errors */
default:
edata->sqlerrcode = ERRCODE_INTERNAL_ERROR;
break;
}
return 0; /* return value does not matter */
}
/*
* This macro handles expansion of a format string and associated parameters;
......
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: utility.h,v 1.18 2003/05/06 20:26:28 tgl Exp $
* $Id: utility.h,v 1.19 2003/07/22 19:00:12 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -25,4 +25,6 @@ extern TupleDesc UtilityTupleDescriptor(Node *parsetree);
extern const char *CreateCommandTag(Node *parsetree);
extern void CheckRelationOwnership(RangeVar *rel, bool noCatalogs);
#endif /* UTILITY_H */
......@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: elog.h,v 1.53 2003/07/21 20:29:39 tgl Exp $
* $Id: elog.h,v 1.54 2003/07/22 19:00:12 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -155,6 +155,8 @@
#define ERRCODE_UNTERMINATED_C_STRING MAKE_SQLSTATE('2','2', '0','2','4')
#define ERRCODE_ZERO_LENGTH_CHARACTER_STRING MAKE_SQLSTATE('2','2', '0','0','F')
#define ERRCODE_BAD_COPY_FILE_FORMAT MAKE_SQLSTATE('2','2', 'P','0','1')
#define ERRCODE_INVALID_BINARY_REPRESENTATION MAKE_SQLSTATE('2','2', 'P','0','2')
#define ERRCODE_FLOATING_POINT_EXCEPTION MAKE_SQLSTATE('2','2', 'P','0','3')
/* Class 23 - Integrity Constraint Violation */
#define ERRCODE_INTEGRITY_CONSTRAINT_VIOLATION MAKE_SQLSTATE('2','3', '0','0','0')
......@@ -178,6 +180,7 @@
#define ERRCODE_READ_ONLY_SQL_TRANSACTION MAKE_SQLSTATE('2','5', '0','0','6')
#define ERRCODE_SCHEMA_AND_DATA_STATEMENT_MIXING_NOT_SUPPORTED MAKE_SQLSTATE('2','5', '0','0','7')
#define ERRCODE_NO_ACTIVE_SQL_TRANSACTION MAKE_SQLSTATE('2','5', 'P','0','1')
#define ERRCODE_IN_FAILED_SQL_TRANSACTION MAKE_SQLSTATE('2','5', 'P','0','2')
/* Class 26 - Invalid SQL Statement Name */
/* (we take this to mean prepared statements) */
......@@ -244,6 +247,7 @@
#define ERRCODE_NAME_TOO_LONG MAKE_SQLSTATE('4','2', '6','2','2')
#define ERRCODE_RESERVED_NAME MAKE_SQLSTATE('4','2', '9','3','9')
#define ERRCODE_DATATYPE_MISMATCH MAKE_SQLSTATE('4','2', '8','0','4')
#define ERRCODE_INDETERMINATE_DATATYPE MAKE_SQLSTATE('4','2', 'P','1','8')
#define ERRCODE_WRONG_OBJECT_TYPE MAKE_SQLSTATE('4','2', '8','0','9')
/*
* Note: for ERRCODE purposes, we divide namable objects into these categories:
......@@ -314,11 +318,17 @@
/* Class 57 - Operator Intervention (class borrowed from DB2) */
#define ERRCODE_OPERATOR_INTERVENTION MAKE_SQLSTATE('5','7', '0','0','0')
#define ERRCODE_QUERY_CANCELED MAKE_SQLSTATE('5','7', '0','1','4')
#define ERRCODE_ADMIN_SHUTDOWN MAKE_SQLSTATE('5','7', 'P','0','1')
#define ERRCODE_CRASH_SHUTDOWN MAKE_SQLSTATE('5','7', 'P','0','2')
#define ERRCODE_CANNOT_CONNECT_NOW MAKE_SQLSTATE('5','7', 'P','0','3')
/* Class 58 - System Error (class borrowed from DB2) */
/* (we define this as errors external to PostgreSQL itself) */
#define ERRCODE_IO_ERROR MAKE_SQLSTATE('5','8', '0','3','0')
/* Class F0 - Configuration File Error (PostgreSQL-specific error class) */
#define ERRCODE_CONFIG_FILE_ERROR MAKE_SQLSTATE('F','0', '0','0','0')
/* Class XX - Internal Error (PostgreSQL-specific error class) */
/* (this is for "can't-happen" conditions and software bugs) */
#define ERRCODE_INTERNAL_ERROR MAKE_SQLSTATE('X','X', '0','0','0')
......@@ -361,6 +371,7 @@ extern void errfinish(int dummy, ...);
extern int errcode(int sqlerrcode);
extern int errcode_for_file_access(void);
extern int errcode_for_socket_access(void);
extern int errmsg(const char *fmt, ...)
/* This extension allows gcc to check the format string for consistency with
......
......@@ -689,8 +689,8 @@ FETCH 1 FROM foo24;
(1 row)
FETCH BACKWARD 1 FROM foo24; -- should fail
ERROR: Cursor can only scan forward
Declare it with SCROLL option to enable backward scan
ERROR: cursor can only scan forward
HINT: Declare it with SCROLL option to enable backward scan.
END;
--
-- Cursors outside transaction blocks
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment