Tom Lane wrote:
> It seems like something like that could work. I'd be inclined to change
> the ereport() macro itself, not errmsg/errdetail/etc. The domain name
> could be passed in at ereport and then used when evaluating the
> messages.
This seems to work fine. Modules would provide their message domain by
overriding the ereport() definition to pass a different domain to
ereport_domain(), like the attached plpgsql_i18n.h.
Now, the obvious big problem I have with this patch is that I have to
pass plpgsql's locale path to bindtextdomain(), but I'm not seeing any
decent way to do that ... ideas?
Note that I didn't bother changing the elog() macros to provide a
message domain ... I'm sure that can be fixed but it's very low
priority, given that most of the time those messages do not get
translated.
--
Alvaro Herrera http://www.CommandPrompt.com/
PostgreSQL Replication, Consulting, Custom Development, 24x7 support
Index: src/backend/utils/error/elog.c
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/utils/error/elog.c,v
retrieving revision 1.206
diff -c -p -r1.206 elog.c
*** src/backend/utils/error/elog.c 1 Sep 2008 20:42:45 -0000 1.206
--- src/backend/utils/error/elog.c 8 Oct 2008 20:20:19 -0000
*************** static void write_csvlog(ErrorData *edat
*** 160,166 ****
*/
bool
errstart(int elevel, const char *filename, int lineno,
! const char *funcname)
{
ErrorData *edata;
bool output_to_server;
--- 160,166 ----
*/
bool
errstart(int elevel, const char *filename, int lineno,
! const char *domain, const char *funcname)
{
ErrorData *edata;
bool output_to_server;
*************** errstart(int elevel, const char *filenam
*** 290,295 ****
--- 290,296 ----
edata->filename = filename;
edata->lineno = lineno;
edata->funcname = funcname;
+ edata->domain = domain;
/* Select default errcode based on elevel */
if (elevel >= ERROR)
edata->sqlerrcode = ERRCODE_INTERNAL_ERROR;
*************** errcode_for_socket_access(void)
*** 611,617 ****
char *fmtbuf; \
StringInfoData buf; \
/* Internationalize the error format string */ \
! fmt = _(fmt); \
/* Expand %m in format string */ \
fmtbuf = expand_fmt_string(fmt, edata); \
initStringInfo(&buf); \
--- 612,618 ----
char *fmtbuf; \
StringInfoData buf; \
/* Internationalize the error format string */ \
! fmt = dgettext(edata->domain, fmt); \
/* Expand %m in format string */ \
fmtbuf = expand_fmt_string(fmt, edata); \
initStringInfo(&buf); \
*************** elog_finish(int elevel, const char *fmt,
*** 982,988 ****
*/
errordata_stack_depth--;
errno = edata->saved_errno;
! if (!errstart(elevel, edata->filename, edata->lineno, edata->funcname))
return; /* nothing to do */
/*
--- 983,989 ----
*/
errordata_stack_depth--;
errno = edata->saved_errno;
! if (!errstart(elevel, edata->filename, edata->lineno, NULL, edata->funcname))
return; /* nothing to do */
/*
Index: src/include/utils/elog.h
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/include/utils/elog.h,v
retrieving revision 1.94
diff -c -p -r1.94 elog.h
*** src/include/utils/elog.h 1 Sep 2008 20:42:45 -0000 1.94
--- src/include/utils/elog.h 8 Oct 2008 20:25:41 -0000
***************
*** 92,105 ****
* 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);
--- 92,113 ----
* 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.
+ *
+ * ereport_domain() allows a message domain to be specified, for modules that
+ * wish to use a different message catalog from the backend's. Modules can
+ * either use ereport_domain() directly, or preferrably they can just override
+ * the ereport() macro definition with their own domain.
*----------
*/
! #define ereport_domain(elevel, domain, rest) \
! (errstart(elevel, __FILE__, __LINE__, domain, PG_FUNCNAME_MACRO) ? \
(errfinish rest) : (void) 0)
+ #define ereport(level, rest) \
+ ereport_domain(level, "postgres", rest)
+
extern bool errstart(int elevel, const char *filename, int lineno,
! const char *domain, const char *funcname);
extern void errfinish(int dummy,...);
extern int errcode(int sqlerrcode);
*************** typedef struct ErrorData
*** 270,275 ****
--- 278,284 ----
int lineno; /* __LINE__ of ereport() call */
const char *funcname; /* __func__ of ereport() call */
int sqlerrcode; /* encoded ERRSTATE */
+ char *domain; /* message domain, NULL if default */
char *message; /* primary error message */
char *detail; /* detail error message */
char *detail_log; /* detail error message for server log only */
Index: src/pl/plpgsql/src/pl_comp.c
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/pl/plpgsql/src/pl_comp.c,v
retrieving revision 1.130
diff -c -p -r1.130 pl_comp.c
*** src/pl/plpgsql/src/pl_comp.c 1 Sep 2008 20:42:46 -0000 1.130
--- src/pl/plpgsql/src/pl_comp.c 8 Oct 2008 18:14:31 -0000
***************
*** 37,42 ****
--- 37,43 ----
#include "utils/memutils.h"
#include "utils/syscache.h"
+ #include "plpgsql_i18n.h"
/* ----------
* Our own local and global variables
Index: src/pl/plpgsql/src/pl_exec.c
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/pl/plpgsql/src/pl_exec.c,v
retrieving revision 1.221
diff -c -p -r1.221 pl_exec.c
*** src/pl/plpgsql/src/pl_exec.c 24 Sep 2008 14:40:00 -0000 1.221
--- src/pl/plpgsql/src/pl_exec.c 8 Oct 2008 17:44:31 -0000
***************
*** 32,37 ****
--- 32,38 ----
#include "utils/snapmgr.h"
#include "utils/typcache.h"
+ #include "plpgsql_i18n.h" /* must be last */
static const char *const raise_skip_msg = "RAISE";
Index: src/pl/plpgsql/src/pl_handler.c
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/pl/plpgsql/src/pl_handler.c,v
retrieving revision 1.40
diff -c -p -r1.40 pl_handler.c
*** src/pl/plpgsql/src/pl_handler.c 29 Aug 2008 13:02:33 -0000 1.40
--- src/pl/plpgsql/src/pl_handler.c 8 Oct 2008 20:22:08 -0000
*************** _PG_init(void)
*** 42,47 ****
--- 42,51 ----
if (inited)
return;
+ #ifdef ENABLE_NLS
+ bindtextdomain("plpgsql", "/pgsql/install/00head/share/locale");
+ #endif
+
plpgsql_HashTableInit();
RegisterXactCallback(plpgsql_xact_cb, NULL);
RegisterSubXactCallback(plpgsql_subxact_cb, NULL);
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers