-<!-- $PostgreSQL: pgsql/doc/src/sgml/sources.sgml,v 2.29 2007/11/07 13:12:21 petere Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/sources.sgml,v 2.30 2008/03/24 18:08:47 tgl Exp $ -->
<chapter id="source">
<title>PostgreSQL Coding Conventions</title>
<function>errmsg</>.
</para>
</listitem>
+ <listitem>
+ <para>
+ <function>errdetail_log(const char *msg, ...)</function> is the same as
+ <function>errdetail</> except that this string goes only to the server
+ log, never to the client. If both <function>errdetail</> and
+ <function>errdetail_log</> are used then one string goes to the client
+ and the other to the log. This is useful for error details that are
+ too security-sensitive or too bulky to include in the report
+ sent to the client.
+ </para>
+ </listitem>
<listitem>
<para>
<function>errhint(const char *msg, ...)</function> supplies an optional
-# $PostgreSQL: pgsql/src/backend/nls.mk,v 1.21 2008/01/30 11:05:37 petere Exp $
+# $PostgreSQL: pgsql/src/backend/nls.mk,v 1.22 2008/03/24 18:08:47 tgl Exp $
CATALOG_NAME := postgres
AVAIL_LANGUAGES := af cs de es fr hr hu it ko nb nl pt_BR ro ru sk sl sv tr zh_CN zh_TW
GETTEXT_FILES := + gettext-files
# you can add "elog:2" and "errmsg_internal" to this list if you want to
# include internal messages in the translation list.
-GETTEXT_TRIGGERS:= _ errmsg errdetail errhint errcontext write_stderr yyerror
+GETTEXT_TRIGGERS:= _ errmsg errdetail errdetail_log errhint errcontext write_stderr yyerror
gettext-files: distprep
find $(srcdir)/ $(srcdir)/../port/ -name '*.c' -print >$@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/port/ipc_test.c,v 1.23 2008/01/01 19:45:51 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/port/ipc_test.c,v 1.24 2008/03/24 18:08:47 tgl Exp $
*
*-------------------------------------------------------------------------
*/
return 0; /* return value does not matter */
}
+int
+errdetail_log(const char *fmt,...)
+{
+ fprintf(stderr, "DETAIL: %s\n", fmt);
+ return 0; /* return value does not matter */
+}
+
int
errhint(const char *fmt,...)
{
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/error/elog.c,v 1.202 2008/03/10 12:55:13 mha Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/error/elog.c,v 1.203 2008/03/24 18:08:47 tgl Exp $
*
*-------------------------------------------------------------------------
*/
pfree(edata->message);
if (edata->detail)
pfree(edata->detail);
+ if (edata->detail_log)
+ pfree(edata->detail_log);
if (edata->hint)
pfree(edata->hint);
if (edata->context)
}
+/*
+ * errdetail_log --- add a detail_log error message text to the current error
+ */
+int
+errdetail_log(const char *fmt,...)
+{
+ ErrorData *edata = &errordata[errordata_stack_depth];
+ MemoryContext oldcontext;
+
+ recursion_depth++;
+ CHECK_STACK_DEPTH();
+ oldcontext = MemoryContextSwitchTo(ErrorContext);
+
+ EVALUATE_MESSAGE(detail_log, false);
+
+ MemoryContextSwitchTo(oldcontext);
+ recursion_depth--;
+ return 0; /* return value does not matter */
+}
+
+
/*
* errhint --- add a hint error message text to the current error
*/
newedata->message = pstrdup(newedata->message);
if (newedata->detail)
newedata->detail = pstrdup(newedata->detail);
+ if (newedata->detail_log)
+ newedata->detail_log = pstrdup(newedata->detail_log);
if (newedata->hint)
newedata->hint = pstrdup(newedata->hint);
if (newedata->context)
pfree(edata->message);
if (edata->detail)
pfree(edata->detail);
+ if (edata->detail_log)
+ pfree(edata->detail_log);
if (edata->hint)
pfree(edata->hint);
if (edata->context)
newedata->message = pstrdup(newedata->message);
if (newedata->detail)
newedata->detail = pstrdup(newedata->detail);
+ if (newedata->detail_log)
+ newedata->detail_log = pstrdup(newedata->detail_log);
if (newedata->hint)
newedata->hint = pstrdup(newedata->hint);
if (newedata->context)
appendCSVLiteral(&buf, edata->message);
appendStringInfoCharMacro(&buf, ',');
- /* errdetail */
- appendCSVLiteral(&buf, edata->detail);
+ /* errdetail or errdetail_log */
+ if (edata->detail_log)
+ appendCSVLiteral(&buf, edata->detail_log);
+ else
+ appendCSVLiteral(&buf, edata->detail);
appendStringInfoCharMacro(&buf, ',');
/* errhint */
if (Log_error_verbosity >= PGERROR_DEFAULT)
{
- if (edata->detail)
+ if (edata->detail_log)
+ {
+ log_line_prefix(&buf);
+ appendStringInfoString(&buf, _("DETAIL: "));
+ append_with_tabs(&buf, edata->detail_log);
+ appendStringInfoChar(&buf, '\n');
+ }
+ else if (edata->detail)
{
log_line_prefix(&buf);
appendStringInfoString(&buf, _("DETAIL: "));
pq_sendstring(&msgbuf, edata->detail);
}
+ /* detail_log is intentionally not used here */
+
if (edata->hint)
{
pq_sendbyte(&msgbuf, PG_DIAG_MESSAGE_HINT);
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/utils/elog.h,v 1.91 2008/03/10 12:55:13 mha Exp $
+ * $PostgreSQL: pgsql/src/include/utils/elog.h,v 1.92 2008/03/24 18:08:47 tgl Exp $
*
*-------------------------------------------------------------------------
*/
the supplied arguments. */
__attribute__((format(printf, 1, 2)));
+extern int
+errdetail_log(const char *fmt,...)
+/* This extension allows gcc to check the format string for consistency with
+ the supplied arguments. */
+__attribute__((format(printf, 1, 2)));
+
extern int
errhint(const char *fmt,...)
/* This extension allows gcc to check the format string for consistency with
int sqlerrcode; /* encoded ERRSTATE */
char *message; /* primary error message */
char *detail; /* detail error message */
+ char *detail_log; /* detail error message for server log only */
char *hint; /* hint message */
char *context; /* context message */
int cursorpos; /* cursor index into query string */