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

Reply via email to