aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/error/elog.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/error/elog.c')
-rw-r--r--src/backend/utils/error/elog.c93
1 files changed, 61 insertions, 32 deletions
diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c
index 3f080bac3b7..0532ce2cf9e 100644
--- a/src/backend/utils/error/elog.c
+++ b/src/backend/utils/error/elog.c
@@ -42,7 +42,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/error/elog.c,v 1.155.4.9 2008/10/27 19:37:48 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/error/elog.c,v 1.155.4.10 2009/03/02 21:19:13 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -70,6 +70,9 @@
#include "utils/ps_status.h"
+#undef _
+#define _(x) err_gettext(x)
+
/* Global variables */
ErrorContextCallback *error_context_stack = NULL;
@@ -139,6 +142,25 @@ in_error_recursion_trouble(void)
}
/*
+ * One of those fallback steps is to stop trying to localize the error
+ * message, since there's a significant probability that that's exactly
+ * what's causing the recursion.
+ */
+static inline const char *
+err_gettext(const char *str)
+{
+#ifdef ENABLE_NLS
+ if (in_error_recursion_trouble())
+ return str;
+ else
+ return gettext(str);
+#else
+ return str;
+#endif
+}
+
+
+/*
* errstart --- begin an error-reporting cycle
*
* Create a stack entry and store the given parameters in it. Subsequently,
@@ -623,7 +645,7 @@ errcode_for_socket_access(void)
char *fmtbuf; \
StringInfoData buf; \
/* Internationalize the error format string */ \
- if (translateit) \
+ if (translateit && !in_error_recursion_trouble()) \
fmt = gettext(fmt); \
/* Expand %m in format string */ \
fmtbuf = expand_fmt_string(fmt, edata); \
@@ -1755,6 +1777,26 @@ write_pipe_chunks(int fd, char *data, int len)
/*
+ * Append a text string to the error report being built for the client.
+ *
+ * This is ordinarily identical to pq_sendstring(), but if we are in
+ * error recursion trouble we skip encoding conversion, because of the
+ * possibility that the problem is a failure in the encoding conversion
+ * subsystem itself. Code elsewhere should ensure that the passed-in
+ * strings will be plain 7-bit ASCII, and thus not in need of conversion,
+ * in such cases. (In particular, we disable localization of error messages
+ * to help ensure that's true.)
+ */
+static void
+err_sendstring(StringInfo buf, const char *str)
+{
+ if (in_error_recursion_trouble())
+ pq_send_ascii_string(buf, str);
+ else
+ pq_sendstring(buf, str);
+}
+
+/*
* Write error report to client
*/
static void
@@ -1773,7 +1815,7 @@ send_message_to_frontend(ErrorData *edata)
int i;
pq_sendbyte(&msgbuf, PG_DIAG_SEVERITY);
- pq_sendstring(&msgbuf, error_severity(edata->elevel));
+ err_sendstring(&msgbuf, error_severity(edata->elevel));
/* unpack MAKE_SQLSTATE code */
ssval = edata->sqlerrcode;
@@ -1785,70 +1827,70 @@ send_message_to_frontend(ErrorData *edata)
tbuf[i] = '\0';
pq_sendbyte(&msgbuf, PG_DIAG_SQLSTATE);
- pq_sendstring(&msgbuf, tbuf);
+ err_sendstring(&msgbuf, tbuf);
/* M field is required per protocol, so always send something */
pq_sendbyte(&msgbuf, PG_DIAG_MESSAGE_PRIMARY);
if (edata->message)
- pq_sendstring(&msgbuf, edata->message);
+ err_sendstring(&msgbuf, edata->message);
else
- pq_sendstring(&msgbuf, gettext("missing error text"));
+ err_sendstring(&msgbuf, gettext("missing error text"));
if (edata->detail)
{
pq_sendbyte(&msgbuf, PG_DIAG_MESSAGE_DETAIL);
- pq_sendstring(&msgbuf, edata->detail);
+ err_sendstring(&msgbuf, edata->detail);
}
if (edata->hint)
{
pq_sendbyte(&msgbuf, PG_DIAG_MESSAGE_HINT);
- pq_sendstring(&msgbuf, edata->hint);
+ err_sendstring(&msgbuf, edata->hint);
}
if (edata->context)
{
pq_sendbyte(&msgbuf, PG_DIAG_CONTEXT);
- pq_sendstring(&msgbuf, edata->context);
+ err_sendstring(&msgbuf, edata->context);
}
if (edata->cursorpos > 0)
{
snprintf(tbuf, sizeof(tbuf), "%d", edata->cursorpos);
pq_sendbyte(&msgbuf, PG_DIAG_STATEMENT_POSITION);
- pq_sendstring(&msgbuf, tbuf);
+ err_sendstring(&msgbuf, tbuf);
}
if (edata->internalpos > 0)
{
snprintf(tbuf, sizeof(tbuf), "%d", edata->internalpos);
pq_sendbyte(&msgbuf, PG_DIAG_INTERNAL_POSITION);
- pq_sendstring(&msgbuf, tbuf);
+ err_sendstring(&msgbuf, tbuf);
}
if (edata->internalquery)
{
pq_sendbyte(&msgbuf, PG_DIAG_INTERNAL_QUERY);
- pq_sendstring(&msgbuf, edata->internalquery);
+ err_sendstring(&msgbuf, edata->internalquery);
}
if (edata->filename)
{
pq_sendbyte(&msgbuf, PG_DIAG_SOURCE_FILE);
- pq_sendstring(&msgbuf, edata->filename);
+ err_sendstring(&msgbuf, edata->filename);
}
if (edata->lineno > 0)
{
snprintf(tbuf, sizeof(tbuf), "%d", edata->lineno);
pq_sendbyte(&msgbuf, PG_DIAG_SOURCE_LINE);
- pq_sendstring(&msgbuf, tbuf);
+ err_sendstring(&msgbuf, tbuf);
}
if (edata->funcname)
{
pq_sendbyte(&msgbuf, PG_DIAG_SOURCE_FUNCTION);
- pq_sendstring(&msgbuf, edata->funcname);
+ err_sendstring(&msgbuf, edata->funcname);
}
pq_sendbyte(&msgbuf, '\0'); /* terminator */
@@ -1879,7 +1921,7 @@ send_message_to_frontend(ErrorData *edata)
appendStringInfoChar(&buf, '\n');
- pq_sendstring(&msgbuf, buf.data);
+ err_sendstring(&msgbuf, buf.data);
pfree(buf.data);
}
@@ -1994,10 +2036,6 @@ useful_strerror(int errnum)
/*
* error_severity --- get localized string representing elevel
- *
- * Note: in an error recursion situation, we stop localizing the tags
- * for ERROR and above. This is necessary because the problem might be
- * failure to convert one of these strings to the client encoding.
*/
static const char *
error_severity(int elevel)
@@ -2027,22 +2065,13 @@ error_severity(int elevel)
prefix = gettext("WARNING");
break;
case ERROR:
- if (in_error_recursion_trouble())
- prefix = "ERROR";
- else
- prefix = gettext("ERROR");
+ prefix = gettext("ERROR");
break;
case FATAL:
- if (in_error_recursion_trouble())
- prefix = "FATAL";
- else
- prefix = gettext("FATAL");
+ prefix = gettext("FATAL");
break;
case PANIC:
- if (in_error_recursion_trouble())
- prefix = "PANIC";
- else
- prefix = gettext("PANIC");
+ prefix = gettext("PANIC");
break;
default:
prefix = "???";