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 (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers