Hello,

I am sending patch for errcontext() function.

I use procedural languages to do some operation, but when error occurs
,the CONTEXT error messages from procedural languages doesn't display in
local language.

for example:
--------------------------------------------------------
postgres=# CREATE OR REPLACE FUNCTION logfunc3 (logtxt text) RETURNS
timestamp AS $$
postgres$# BEGIN
postgres$# select * from db;
postgres$# RETURN 'now';
postgres$# END;
postgres$# $$ LANGUAGE plpgsql;
CREATE FUNCTION
postgres=# select logfunc3('test');
ERROR: リレーション"db"は存在しません
行 1: select * from db
QUERY: select * from db
CONTEXT: PL/pgSQL function "logfunc3" line 3 at SQL ステートメント
--------------------------------------------------------
but,“CONTEXT:  PL/pgSQL 関数 "logfunc3" の 3 行目の型 SQL ステートメント” is my expected.

There is the same problem in pl/perl and pl/python .

After checking and debuging the source code ,I found the reason.

The reason is that domian setted is wrong. For PL/pgSQL, domain "pgsql" should 
be setted, but domain setted is "postgres" .

So  I considered to fix the bug by updating errcontext() funtion.

The patched portion is at src/include/utils/elog.h and
src/backend/utils/error/elog.c

I invite any ideas how to improve this patch.


Best Regards

Huajun Chen

*** original/pgsql/src/backend/utils/error/elog.c       2012-11-06 
02:11:02.942057121 +0900
--- new/pgsql/src/backend/utils/error/elog.c    2012-11-06 02:11:02.871000898 
+0900
***************
*** 673,685 ****
   * to the edata field because the buffer might be considerably larger than
   * really necessary.
   */
! #define EVALUATE_MESSAGE(targetfield, appendval, translateit)  \
        { \
                char               *fmtbuf; \
                StringInfoData  buf; \
                /* Internationalize the error format string */ \
                if (translateit && !in_error_recursion_trouble()) \
!                       fmt = dgettext(edata->domain, fmt); \
                /* Expand %m in format string */ \
                fmtbuf = expand_fmt_string(fmt, edata); \
                initStringInfo(&buf); \
--- 673,685 ----
   * to the edata field because the buffer might be considerably larger than
   * really necessary.
   */
! #define EVALUATE_MESSAGE_DOMAIN(textdomain, targetfield, appendval, 
translateit)  \
        { \
                char               *fmtbuf; \
                StringInfoData  buf; \
                /* Internationalize the error format string */ \
                if (translateit && !in_error_recursion_trouble()) \
!                       fmt = dgettext((textdomain == NULL ? edata->domain : 
textdomain), fmt); \
                /* Expand %m in format string */ \
                fmtbuf = expand_fmt_string(fmt, edata); \
                initStringInfo(&buf); \
***************
*** 708,713 ****
--- 708,716 ----
                pfree(buf.data); \
        }
  
+ #define EVALUATE_MESSAGE(targetfield, appendval, translateit) \
+       EVALUATE_MESSAGE_DOMAIN(NULL, targetfield, appendval, translateit)
+ 
  /*
   * Same as above, except for pluralized error messages.  The calling routine
   * must be declared like "const char *fmt_singular, const char *fmt_plural,
***************
*** 952,958 ****
   * states.
   */
  int
! errcontext(const char *fmt,...)
  {
        ErrorData  *edata = &errordata[errordata_stack_depth];
        MemoryContext oldcontext;
--- 955,961 ----
   * states.
   */
  int
! errcontext_domain(const char *domain, const char *fmt,...)
  {
        ErrorData  *edata = &errordata[errordata_stack_depth];
        MemoryContext oldcontext;
***************
*** 961,974 ****
        CHECK_STACK_DEPTH();
        oldcontext = MemoryContextSwitchTo(ErrorContext);
  
!       EVALUATE_MESSAGE(context, true, true);
  
        MemoryContextSwitchTo(oldcontext);
        recursion_depth--;
        return 0;                                       /* return value does 
not matter */
  }
  
- 
  /*
   * errhidestmt --- optionally suppress STATEMENT: field of log entry
   *
--- 964,976 ----
        CHECK_STACK_DEPTH();
        oldcontext = MemoryContextSwitchTo(ErrorContext);
  
!       EVALUATE_MESSAGE_DOMAIN(domain, context, true, true);
  
        MemoryContextSwitchTo(oldcontext);
        recursion_depth--;
        return 0;                                       /* return value does 
not matter */
  }
  
  /*
   * errhidestmt --- optionally suppress STATEMENT: field of log entry
   *
*** original/pgsql/src/include/utils/elog.h     2012-11-06 02:11:02.960963602 
+0900
--- new/pgsql/src/include/utils/elog.h  2012-11-06 02:11:02.888953895 +0900
***************
*** 109,114 ****
--- 109,117 ----
  #define ereport(elevel, rest) \
        ereport_domain(elevel, TEXTDOMAIN, rest)
  
+ #define errcontext(...)       \
+       errcontext_domain(TEXTDOMAIN, __VA_ARGS__)
+ 
  #define TEXTDOMAIN NULL
  
  extern bool errstart(int elevel, const char *filename, int lineno,
***************
*** 173,182 ****
  __attribute__((format(PG_PRINTF_ATTRIBUTE, 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(PG_PRINTF_ATTRIBUTE, 1, 2)));
  
  extern int    errhidestmt(bool hide_stmt);
  
--- 176,185 ----
  __attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2)));
  
  extern int
! errcontext_domain(const char *domain, const char *fmt,...)
  /* This extension allows gcc to check the format string for consistency with
     the supplied arguments. */
! __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3)));
  
  extern int    errhidestmt(bool hide_stmt);
  
-- 
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