1
0
mirror of https://github.com/postgres/postgres.git synced 2025-05-17 06:41:24 +03:00
Tom Lane 771374b34b Install a more robust solution for the problem of infinite error-processing
recursion when we are unable to convert a localized error message to the
client's encoding.  We've been over this ground before, but as reported by
Ibrar Ahmed, it still didn't work in the case of conversion failures for
the conversion-failure message itself :-(.  Fix by installing a "circuit
breaker" that disables attempts to localize this message once we get into
recursion trouble.

Patch all supported branches, because it is in fact broken in all of them;
though I had to add some missing translations to the older branches in
order to expose the failure in the particular test case I was using.
2008-10-27 19:37:56 +00:00

185 lines
5.5 KiB
C

/*-------------------------------------------------------------------------
*
* elog.h
* POSTGRES error reporting/logging definitions.
*
*
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: elog.h,v 1.63.4.1 2008/10/27 19:37:56 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef ELOG_H
#define ELOG_H
/* Error level codes */
#define DEBUG5 10 /* Debugging messages, in categories of
* decreasing detail. */
#define DEBUG4 11
#define DEBUG3 12
#define DEBUG2 13
#define DEBUG1 14 /* used by GUC debug_* variables */
#define LOG 15 /* Server operational messages; sent only
* to server log by default. */
#define COMMERROR 16 /* Client communication problems; same as
* LOG for server reporting, but never
* sent to client. */
#define INFO 17 /* Informative messages that are always
* sent to client; is not affected by
* client_min_messages */
#define NOTICE 18 /* Helpful messages to users about query
* operation; sent to client and server
* log by default. */
#define WARNING 19 /* Warnings */
#define ERROR 20 /* user error - abort transaction; return
* to known state */
/* Save ERROR value in PGERROR so it can be restored when Win32 includes
* modify it. We have to use a constant rather than ERROR because macros
* are expanded only when referenced outside macros.
*/
#ifdef WIN32
#define PGERROR 20
#endif
#define FATAL 21 /* fatal error - abort process */
#define PANIC 22 /* take down the other backends with me */
/* #define DEBUG DEBUG1 */ /* Backward compatibility with pre-7.3 */
/* macros for representing SQLSTATE strings compactly */
#define PGSIXBIT(ch) (((ch) - '0') & 0x3F)
#define PGUNSIXBIT(val) (((val) & 0x3F) + '0')
#define MAKE_SQLSTATE(ch1,ch2,ch3,ch4,ch5) \
(PGSIXBIT(ch1) + (PGSIXBIT(ch2) << 6) + (PGSIXBIT(ch3) << 12) + \
(PGSIXBIT(ch4) << 18) + (PGSIXBIT(ch5) << 24))
/* SQLSTATE codes for errors are defined in a separate file */
#include "utils/errcodes.h"
/* Which __func__ symbol do we have, if any? */
#ifdef HAVE_FUNCNAME__FUNC
#define PG_FUNCNAME_MACRO __func__
#else
#ifdef HAVE_FUNCNAME__FUNCTION
#define PG_FUNCNAME_MACRO __FUNCTION__
#else
#define PG_FUNCNAME_MACRO NULL
#endif
#endif
/*----------
* New-style error reporting API: to be used in this way:
* ereport(ERROR,
* (errcode(ERRCODE_UNDEFINED_CURSOR),
* errmsg("portal \"%s\" not found", stmt->portalname),
* ... other errxxx() fields as needed ...));
*
* The error level is required, and so is a primary error message (errmsg
* or errmsg_internal). All else is optional. errcode() defaults to
* ERRCODE_INTERNAL_ERROR if elevel is ERROR or more, ERRCODE_WARNING
* if elevel is WARNING, or ERRCODE_SUCCESSFUL_COMPLETION if elevel is
* NOTICE or below.
*----------
*/
#define ereport(elevel, rest) \
(errstart(elevel, __FILE__, __LINE__, PG_FUNCNAME_MACRO) ? \
(errfinish rest) : (void) 0)
extern bool errstart(int elevel, const char *filename, int lineno,
const char *funcname);
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
the supplied arguments. */
__attribute__((format(printf, 1, 2)));
extern int
errmsg_internal(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
errdetail(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
the supplied arguments. */
__attribute__((format(printf, 1, 2)));
extern int
errcontext(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 errfunction(const char *funcname);
extern int errposition(int cursorpos);
/*----------
* Old-style error reporting API: to be used in this way:
* elog(ERROR, "portal \"%s\" not found", stmt->portalname);
*----------
*/
#define elog errstart(ERROR, __FILE__, __LINE__, PG_FUNCNAME_MACRO), elog_finish
extern void
elog_finish(int elevel, const char *fmt,...)
/* This extension allows gcc to check the format string for consistency with
the supplied arguments. */
__attribute__((format(printf, 2, 3)));
/* Support for attaching context information to error reports */
typedef struct ErrorContextCallback
{
struct ErrorContextCallback *previous;
void (*callback) (void *arg);
void *arg;
} ErrorContextCallback;
extern DLLIMPORT ErrorContextCallback *error_context_stack;
/* GUC-configurable parameters */
typedef enum
{
PGERROR_TERSE, /* single-line error messages */
PGERROR_DEFAULT, /* recommended style */
PGERROR_VERBOSE /* all the facts, ma'am */
} PGErrorVerbosity;
extern PGErrorVerbosity Log_error_verbosity;
extern bool Log_timestamp;
extern bool Log_pid;
#ifdef HAVE_SYSLOG
extern int Use_syslog;
#endif
/* Other exported functions */
extern void DebugFileOpen(void);
extern bool in_error_recursion_trouble(void);
#endif /* ELOG_H */