Tom Lane wrote:
> Alvaro Herrera <[EMAIL PROTECTED]> writes:
> > 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?
> 
> Shouldn't it just use the same locale path as the backend?  Or are you
> stuck getting hold of my_exec_path so you can call get_locale_path?
> If the latter, it would probably be reasonable for postmaster/backend
> startup to expose the exec path as a global variable.

That would work too.  I'm not sure I prefer this, or the hack to have
dfmgr.c expose it to _PG_init, per my v2 patch.

> Two minor nits about the patch itself: the domain field of ErrorData
> should be const char * (it's like funcname, not like message; in fact,
> this coding ought to be giving you a warning about casting away const)

Yeah, I had added it in v2.  I had failed to see the warning, but it was
there.

> and there seems some gratuitous inconsistency between the ordering of
> function arguments, field locations, and statements copying one to the
> other.

True, fixed.

> However ---
> 
> > !   if (!errstart(elevel, edata->filename, edata->lineno, NULL, 
> > edata->funcname))
> 
> --- this looks like it could result in passing a NULL to dgettext,
> somewhere along the line.  Probably safer to pass "postgres".

Hmm, I was trusting that dgettext is documented to accept a NULL as
meaning "use the domain previously set with textdomain", but then it is 
possible that elog() will be called before textdomain is set, so you
might be right.  Fixed in this new version.

-- 
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 22:59:45 -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 *funcname, const char *domain)
  {
  	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, TEXTDOMAIN, edata->funcname))
  		return;					/* nothing to do */
  
  	/*
Index: src/backend/utils/fmgr/dfmgr.c
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/backend/utils/fmgr/dfmgr.c,v
retrieving revision 1.97
diff -c -p -r1.97 dfmgr.c
*** src/backend/utils/fmgr/dfmgr.c	3 Sep 2008 22:34:50 -0000	1.97
--- src/backend/utils/fmgr/dfmgr.c	8 Oct 2008 22:01:37 -0000
*************** static DynamicFileList *file_tail = NULL
*** 71,76 ****
--- 71,80 ----
  
  char	   *Dynamic_library_path;
  
+ /* for _PG_init: the path of the library being loaded */
+ char	   *loading_library_path;
+ 
+ 
  static void *internal_load_library(const char *libname);
  static void incompatible_module_error(const char *libname,
  									const Pg_magic_struct *module_magic_data);
*************** internal_load_library(const char *libnam
*** 276,281 ****
--- 280,288 ----
  				   errhint("Extension libraries are required to use the PG_MODULE_MAGIC macro.")));
  		}
  
+ 		/* make the library path available to _PG_init */
+ 		loading_library_path = file_scanner->filename;
+ 
  		/*
  		 * If the library has a _PG_init() function, call it.
  		 */
*************** internal_load_library(const char *libnam
*** 283,288 ****
--- 290,297 ----
  		if (PG_init)
  			(*PG_init) ();
  
+ 		loading_library_path = NULL;
+ 
  		/* OK to link it into list */
  		if (file_list == NULL)
  			file_list = file_scanner;
Index: src/include/miscadmin.h
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/include/miscadmin.h,v
retrieving revision 1.202
diff -c -p -r1.202 miscadmin.h
*** src/include/miscadmin.h	23 Apr 2008 13:44:59 -0000	1.202
--- src/include/miscadmin.h	8 Oct 2008 21:54:32 -0000
*************** extern void process_local_preload_librar
*** 334,337 ****
--- 334,340 ----
  extern bool BackupInProgress(void);
  extern void CancelBackup(void);
  
+ /* utils/dfmgr.c */
+ extern char *loading_library_path;
+ 
  #endif   /* MISCADMIN_H */
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 22:53:33 -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,116 ----
   * 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 TEXTDOMAIN macro to their own liking.
   *----------
   */
! #define ereport_domain(elevel, domain, rest)	\
! 	(errstart(elevel, __FILE__, __LINE__, PG_FUNCNAME_MACRO, domain) ? \
  	 (errfinish rest) : (void) 0)
  
+ /* the default text domain */
+ #define TEXTDOMAIN "postgres"
+ 
+ #define ereport(level, rest)	\
+ 	ereport_domain(level, TEXTDOMAIN, rest)
+ 
  extern bool errstart(int elevel, const char *filename, int lineno,
! 		 const char *funcname, const char *domain);
  extern void errfinish(int dummy,...);
  
  extern int	errcode(int sqlerrcode);
*************** typedef struct ErrorData
*** 269,274 ****
--- 280,286 ----
  	const char *filename;		/* __FILE__ of ereport() call */
  	int			lineno;			/* __LINE__ of ereport() call */
  	const char *funcname;		/* __func__ of ereport() call */
+ 	const char *domain;			/* message domain, NULL if default */
  	int			sqlerrcode;		/* encoded ERRSTATE */
  	char	   *message;		/* primary error message */
  	char	   *detail;			/* detail error message */
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 22:34:07 -0000
*************** _PG_init(void)
*** 42,47 ****
--- 42,57 ----
  	if (inited)
  		return;
  
+ #ifdef ENABLE_NLS
+ 	if (loading_library_path)
+ 	{
+ 		char	locale_path[MAXPGPATH];
+ 
+ 		get_locale_path(loading_library_path, locale_path);
+ 		bindtextdomain(TEXTDOMAIN, locale_path);
+ 	}
+ #endif
+ 	
  	plpgsql_HashTableInit();
  	RegisterXactCallback(plpgsql_xact_cb, NULL);
  	RegisterSubXactCallback(plpgsql_subxact_cb, NULL);
Index: src/pl/plpgsql/src/plpgsql.h
===================================================================
RCS file: /home/alvherre/Code/cvs/pgsql/src/pl/plpgsql/src/plpgsql.h,v
retrieving revision 1.100
diff -c -p -r1.100 plpgsql.h
*** src/pl/plpgsql/src/plpgsql.h	15 May 2008 22:39:49 -0000	1.100
--- src/pl/plpgsql/src/plpgsql.h	8 Oct 2008 22:35:05 -0000
***************
*** 28,33 ****
--- 28,37 ----
   * Definitions
   **********************************************************************/
  
+ /* the text domain for translations */
+ #undef TEXTDOMAIN
+ #define TEXTDOMAIN "plpgsql"
+ 
  /* ----------
   * Compiler's namestack item types
   * ----------
-- 
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