diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2009-06-04 18:33:08 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2009-06-04 18:33:08 +0000 |
commit | 76d4abf2d974ffa578ddc7ff40984cc05c1d48b1 (patch) | |
tree | c3f8bab555f06d141026d34df4c7402f279f8ab8 /src | |
parent | fd416db406f9efdbbdbd7b63ea4f9ccf47eec8b3 (diff) | |
download | postgresql-76d4abf2d974ffa578ddc7ff40984cc05c1d48b1.tar.gz postgresql-76d4abf2d974ffa578ddc7ff40984cc05c1d48b1.zip |
Improve the recently-added support for properly pluralized error messages
by extending the ereport() API to cater for pluralization directly. This
is better than the original method of calling ngettext outside the elog.c
code because (1) it avoids double translation, which wastes cycles and in
the worst case could give a wrong result; and (2) it avoids having to use
a different coding method in PL code than in the core backend. The
client-side uses of ngettext are not touched since neither of these concerns
is very pressing in the client environment. Per my proposal of yesterday.
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/catalog/dependency.c | 10 | ||||
-rw-r--r-- | src/backend/catalog/pg_proc.c | 10 | ||||
-rw-r--r-- | src/backend/catalog/pg_shdepend.c | 7 | ||||
-rw-r--r-- | src/backend/executor/execQual.c | 27 | ||||
-rw-r--r-- | src/backend/nls.mk | 4 | ||||
-rw-r--r-- | src/backend/parser/parse_func.c | 42 | ||||
-rw-r--r-- | src/backend/postmaster/bgwriter.c | 10 | ||||
-rw-r--r-- | src/backend/utils/error/elog.c | 89 | ||||
-rw-r--r-- | src/include/utils/elog.h | 22 | ||||
-rw-r--r-- | src/pl/plperl/nls.mk | 4 | ||||
-rw-r--r-- | src/pl/plpgsql/src/nls.mk | 4 | ||||
-rw-r--r-- | src/pl/plpgsql/src/pl_exec.c | 10 | ||||
-rw-r--r-- | src/pl/plpython/nls.mk | 4 | ||||
-rw-r--r-- | src/pl/plpython/plpython.c | 42 | ||||
-rw-r--r-- | src/pl/tcl/nls.mk | 4 |
15 files changed, 212 insertions, 77 deletions
diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c index 957cac49f38..377ae8b712b 100644 --- a/src/backend/catalog/dependency.c +++ b/src/backend/catalog/dependency.c @@ -8,7 +8,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/catalog/dependency.c,v 1.87 2009/03/26 22:26:06 petere Exp $ + * $PostgreSQL: pgsql/src/backend/catalog/dependency.c,v 1.88 2009/06/04 18:33:06 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -914,10 +914,10 @@ reportDependentObjects(const ObjectAddresses *targetObjects, { ereport(msglevel, /* translator: %d always has a value larger than 1 */ - (errmsg(ngettext("drop cascades to %d other object", - "drop cascades to %d other objects", - numReportedClient + numNotReportedClient), - numReportedClient + numNotReportedClient), + (errmsg_plural("drop cascades to %d other object", + "drop cascades to %d other objects", + numReportedClient + numNotReportedClient, + numReportedClient + numNotReportedClient), errdetail("%s", clientdetail.data), errdetail_log("%s", logdetail.data))); } diff --git a/src/backend/catalog/pg_proc.c b/src/backend/catalog/pg_proc.c index ad9539234f3..ce42910e785 100644 --- a/src/backend/catalog/pg_proc.c +++ b/src/backend/catalog/pg_proc.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/catalog/pg_proc.c,v 1.162 2009/03/26 22:26:06 petere Exp $ + * $PostgreSQL: pgsql/src/backend/catalog/pg_proc.c,v 1.163 2009/06/04 18:33:06 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -112,10 +112,10 @@ ProcedureCreate(const char *procedureName, if (parameterCount < 0 || parameterCount > FUNC_MAX_ARGS) ereport(ERROR, (errcode(ERRCODE_TOO_MANY_ARGUMENTS), - errmsg(ngettext("functions cannot have more than %d argument", - "functions cannot have more than %d arguments", - FUNC_MAX_ARGS), - FUNC_MAX_ARGS))); + errmsg_plural("functions cannot have more than %d argument", + "functions cannot have more than %d arguments", + FUNC_MAX_ARGS, + FUNC_MAX_ARGS))); /* note: the above is correct, we do NOT count output arguments */ if (allParameterTypes != PointerGetDatum(NULL)) diff --git a/src/backend/catalog/pg_shdepend.c b/src/backend/catalog/pg_shdepend.c index a4de276b8d6..19cfe08f4f8 100644 --- a/src/backend/catalog/pg_shdepend.c +++ b/src/backend/catalog/pg_shdepend.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/catalog/pg_shdepend.c,v 1.32 2009/03/26 22:26:06 petere Exp $ + * $PostgreSQL: pgsql/src/backend/catalog/pg_shdepend.c,v 1.33 2009/06/04 18:33:06 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1049,7 +1049,10 @@ storeObjectDescription(StringInfo descs, objectType type, case REMOTE_OBJECT: /* translator: %s will always be "database %s" */ - appendStringInfo(descs, ngettext("%d object in %s", "%d objects in %s", count), count, objdesc); + appendStringInfo(descs, ngettext("%d object in %s", + "%d objects in %s", + count), + count, objdesc); break; default: diff --git a/src/backend/executor/execQual.c b/src/backend/executor/execQual.c index d9cbb1d763a..c7bfe7c76ca 100644 --- a/src/backend/executor/execQual.c +++ b/src/backend/executor/execQual.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.246 2009/04/08 21:51:38 petere Exp $ + * $PostgreSQL: pgsql/src/backend/executor/execQual.c,v 1.247 2009/06/04 18:33:07 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -616,10 +616,11 @@ ExecEvalVar(ExprState *exprstate, ExprContext *econtext, ereport(ERROR, (errcode(ERRCODE_DATATYPE_MISMATCH), errmsg("table row type and query-specified row type do not match"), - errdetail(ngettext("Table row contains %d attribute, but query expects %d.", - "Table row contains %d attributes, but query expects %d.", - slot_tupdesc->natts), - slot_tupdesc->natts, var_tupdesc->natts))); + errdetail_plural("Table row contains %d attribute, but query expects %d.", + "Table row contains %d attributes, but query expects %d.", + slot_tupdesc->natts, + slot_tupdesc->natts, + var_tupdesc->natts))); else if (var_tupdesc->natts < slot_tupdesc->natts) needslow = true; @@ -1043,10 +1044,10 @@ init_fcache(Oid foid, FuncExprState *fcache, if (list_length(fcache->args) > FUNC_MAX_ARGS) ereport(ERROR, (errcode(ERRCODE_TOO_MANY_ARGUMENTS), - errmsg(ngettext("cannot pass more than %d argument to a function", - "cannot pass more than %d arguments to a function", - FUNC_MAX_ARGS), - FUNC_MAX_ARGS))); + errmsg_plural("cannot pass more than %d argument to a function", + "cannot pass more than %d arguments to a function", + FUNC_MAX_ARGS, + FUNC_MAX_ARGS))); /* Set up the primary fmgr lookup information */ fmgr_info_cxt(foid, &(fcache->func), fcacheCxt); @@ -1314,10 +1315,10 @@ tupledesc_match(TupleDesc dst_tupdesc, TupleDesc src_tupdesc) ereport(ERROR, (errcode(ERRCODE_DATATYPE_MISMATCH), errmsg("function return row and query-specified return row do not match"), - errdetail(ngettext("Returned row contains %d attribute, but query expects %d.", - "Returned row contains %d attributes, but query expects %d.", - src_tupdesc->natts), - src_tupdesc->natts, dst_tupdesc->natts))); + errdetail_plural("Returned row contains %d attribute, but query expects %d.", + "Returned row contains %d attributes, but query expects %d.", + src_tupdesc->natts, + src_tupdesc->natts, dst_tupdesc->natts))); for (i = 0; i < dst_tupdesc->natts; i++) { diff --git a/src/backend/nls.mk b/src/backend/nls.mk index 8e66d2d1999..3a79ca50488 100644 --- a/src/backend/nls.mk +++ b/src/backend/nls.mk @@ -1,8 +1,8 @@ -# $PostgreSQL: pgsql/src/backend/nls.mk,v 1.25 2009/05/14 21:41:50 alvherre Exp $ +# $PostgreSQL: pgsql/src/backend/nls.mk,v 1.26 2009/06/04 18:33:07 tgl Exp $ CATALOG_NAME := postgres AVAIL_LANGUAGES := af cs de es fr hr hu it ja ko nb nl pt_BR ro ru sk sl sv tr zh_CN zh_TW pl GETTEXT_FILES := + gettext-files -GETTEXT_TRIGGERS:= _ errmsg errdetail errdetail_log errhint errcontext write_stderr yyerror +GETTEXT_TRIGGERS:= _ errmsg errmsg_plural:1,2 errdetail errdetail_log errdetail_plural:1,2 errhint errcontext write_stderr yyerror gettext-files: distprep find $(srcdir)/ $(srcdir)/../port/ -name '*.c' -print >$@ diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c index 38008b9cea9..260f74d5957 100644 --- a/src/backend/parser/parse_func.c +++ b/src/backend/parser/parse_func.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/parser/parse_func.c,v 1.214 2009/05/12 00:56:05 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/parser/parse_func.c,v 1.215 2009/06/04 18:33:07 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -85,10 +85,10 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, if (list_length(fargs) > FUNC_MAX_ARGS) ereport(ERROR, (errcode(ERRCODE_TOO_MANY_ARGUMENTS), - errmsg(ngettext("cannot pass more than %d argument to a function", - "cannot pass more than %d arguments to a function", - FUNC_MAX_ARGS), - FUNC_MAX_ARGS), + errmsg_plural("cannot pass more than %d argument to a function", + "cannot pass more than %d arguments to a function", + FUNC_MAX_ARGS, + FUNC_MAX_ARGS), parser_errposition(pstate, location))); /* @@ -257,10 +257,10 @@ ParseFuncOrColumn(ParseState *pstate, List *funcname, List *fargs, if (nargsplusdefs >= FUNC_MAX_ARGS) ereport(ERROR, (errcode(ERRCODE_TOO_MANY_ARGUMENTS), - errmsg(ngettext("cannot pass more than %d argument to a function", - "cannot pass more than %d arguments to a function", - FUNC_MAX_ARGS), - FUNC_MAX_ARGS), + errmsg_plural("cannot pass more than %d argument to a function", + "cannot pass more than %d arguments to a function", + FUNC_MAX_ARGS, + FUNC_MAX_ARGS), parser_errposition(pstate, location))); actual_arg_types[nargsplusdefs++] = exprType(expr); @@ -538,10 +538,10 @@ func_select_candidate(int nargs, if (nargs > FUNC_MAX_ARGS) ereport(ERROR, (errcode(ERRCODE_TOO_MANY_ARGUMENTS), - errmsg(ngettext("cannot pass more than %d argument to a function", - "cannot pass more than %d arguments to a function", - FUNC_MAX_ARGS), - FUNC_MAX_ARGS))); + errmsg_plural("cannot pass more than %d argument to a function", + "cannot pass more than %d arguments to a function", + FUNC_MAX_ARGS, + FUNC_MAX_ARGS))); /* * If any input types are domains, reduce them to their base types. This @@ -1332,10 +1332,10 @@ LookupFuncNameTypeNames(List *funcname, List *argtypes, bool noError) if (argcount > FUNC_MAX_ARGS) ereport(ERROR, (errcode(ERRCODE_TOO_MANY_ARGUMENTS), - errmsg(ngettext("functions cannot have more than %d argument", - "functions cannot have more than %d arguments", - FUNC_MAX_ARGS), - FUNC_MAX_ARGS))); + errmsg_plural("functions cannot have more than %d argument", + "functions cannot have more than %d arguments", + FUNC_MAX_ARGS, + FUNC_MAX_ARGS))); args_item = list_head(argtypes); for (i = 0; i < argcount; i++) @@ -1372,10 +1372,10 @@ LookupAggNameTypeNames(List *aggname, List *argtypes, bool noError) if (argcount > FUNC_MAX_ARGS) ereport(ERROR, (errcode(ERRCODE_TOO_MANY_ARGUMENTS), - errmsg(ngettext("functions cannot have more than %d argument", - "functions cannot have more than %d arguments", - FUNC_MAX_ARGS), - FUNC_MAX_ARGS))); + errmsg_plural("functions cannot have more than %d argument", + "functions cannot have more than %d arguments", + FUNC_MAX_ARGS, + FUNC_MAX_ARGS))); i = 0; foreach(lc, argtypes) diff --git a/src/backend/postmaster/bgwriter.c b/src/backend/postmaster/bgwriter.c index 7a23c0130da..b2a90528b65 100644 --- a/src/backend/postmaster/bgwriter.c +++ b/src/backend/postmaster/bgwriter.c @@ -37,7 +37,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/postmaster/bgwriter.c,v 1.58 2009/05/15 15:56:39 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/postmaster/bgwriter.c,v 1.59 2009/06/04 18:33:07 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -459,10 +459,10 @@ BackgroundWriterMain(void) (flags & CHECKPOINT_CAUSE_XLOG) && elapsed_secs < CheckPointWarning) ereport(LOG, - (errmsg(ngettext("checkpoints are occurring too frequently (%d second apart)", - "checkpoints are occurring too frequently (%d seconds apart)", - elapsed_secs), - elapsed_secs), + (errmsg_plural("checkpoints are occurring too frequently (%d second apart)", + "checkpoints are occurring too frequently (%d seconds apart)", + elapsed_secs, + elapsed_secs), errhint("Consider increasing the configuration parameter \"checkpoint_segments\"."))); /* diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c index 0439c4c1d18..d93aaeb54d6 100644 --- a/src/backend/utils/error/elog.c +++ b/src/backend/utils/error/elog.c @@ -42,7 +42,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/error/elog.c,v 1.213 2009/03/02 21:18:43 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/utils/error/elog.c,v 1.214 2009/06/04 18:33:07 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -681,6 +681,47 @@ errcode_for_socket_access(void) pfree(buf.data); \ } +/* + * Same as above, except for pluralized error messages. The calling routine + * must be declared like "const char *fmt_singular, const char *fmt_plural, + * unsigned long n, ...". Translation is assumed always wanted. + */ +#define EVALUATE_MESSAGE_PLURAL(targetfield, appendval) \ + { \ + const char *fmt; \ + char *fmtbuf; \ + StringInfoData buf; \ + /* Internationalize the error format string */ \ + if (!in_error_recursion_trouble()) \ + fmt = dngettext(edata->domain, fmt_singular, fmt_plural, n); \ + else \ + fmt = (n == 1 ? fmt_singular : fmt_plural); \ + /* Expand %m in format string */ \ + fmtbuf = expand_fmt_string(fmt, edata); \ + initStringInfo(&buf); \ + if ((appendval) && edata->targetfield) \ + appendStringInfo(&buf, "%s\n", edata->targetfield); \ + /* Generate actual output --- have to use appendStringInfoVA */ \ + for (;;) \ + { \ + va_list args; \ + bool success; \ + va_start(args, n); \ + success = appendStringInfoVA(&buf, fmtbuf, args); \ + va_end(args); \ + if (success) \ + break; \ + enlargeStringInfo(&buf, buf.maxlen); \ + } \ + /* Done with expanded fmt */ \ + pfree(fmtbuf); \ + /* Save the completed message into the stack item */ \ + if (edata->targetfield) \ + pfree(edata->targetfield); \ + edata->targetfield = pstrdup(buf.data); \ + pfree(buf.data); \ + } + /* * errmsg --- add a primary error message text to the current error @@ -739,6 +780,29 @@ errmsg_internal(const char *fmt,...) /* + * errmsg_plural --- add a primary error message text to the current error, + * with support for pluralization of the message text + */ +int +errmsg_plural(const char *fmt_singular, const char *fmt_plural, + unsigned long n, ...) +{ + ErrorData *edata = &errordata[errordata_stack_depth]; + MemoryContext oldcontext; + + recursion_depth++; + CHECK_STACK_DEPTH(); + oldcontext = MemoryContextSwitchTo(ErrorContext); + + EVALUATE_MESSAGE_PLURAL(message, false); + + MemoryContextSwitchTo(oldcontext); + recursion_depth--; + return 0; /* return value does not matter */ +} + + +/* * errdetail --- add a detail error message text to the current error */ int @@ -781,6 +845,29 @@ errdetail_log(const char *fmt,...) /* + * errdetail_plural --- add a detail error message text to the current error, + * with support for pluralization of the message text + */ +int +errdetail_plural(const char *fmt_singular, const char *fmt_plural, + unsigned long n, ...) +{ + ErrorData *edata = &errordata[errordata_stack_depth]; + MemoryContext oldcontext; + + recursion_depth++; + CHECK_STACK_DEPTH(); + oldcontext = MemoryContextSwitchTo(ErrorContext); + + EVALUATE_MESSAGE_PLURAL(detail, false); + + MemoryContextSwitchTo(oldcontext); + recursion_depth--; + return 0; /* return value does not matter */ +} + + +/* * errhint --- add a hint error message text to the current error */ int diff --git a/src/include/utils/elog.h b/src/include/utils/elog.h index 6c906965696..81ddb9fc377 100644 --- a/src/include/utils/elog.h +++ b/src/include/utils/elog.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/utils/elog.h,v 1.99 2009/01/06 16:39:52 tgl Exp $ + * $PostgreSQL: pgsql/src/include/utils/elog.h,v 1.100 2009/06/04 18:33:07 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -106,8 +106,8 @@ (errstart(elevel, __FILE__, __LINE__, PG_FUNCNAME_MACRO, domain) ? \ (errfinish rest) : (void) 0) -#define ereport(level, rest) \ - ereport_domain(level, TEXTDOMAIN, rest) +#define ereport(elevel, rest) \ + ereport_domain(elevel, TEXTDOMAIN, rest) #define TEXTDOMAIN NULL @@ -133,6 +133,14 @@ errmsg_internal(const char *fmt,...) __attribute__((format(printf, 1, 2))); extern int +errmsg_plural(const char *fmt_singular, const char *fmt_plural, + unsigned long n, ...) +/* This extension allows gcc to check the format string for consistency with + the supplied arguments. */ +__attribute__((format(printf, 1, 4))) +__attribute__((format(printf, 2, 4))); + +extern int errdetail(const char *fmt,...) /* This extension allows gcc to check the format string for consistency with the supplied arguments. */ @@ -145,6 +153,14 @@ errdetail_log(const char *fmt,...) __attribute__((format(printf, 1, 2))); extern int +errdetail_plural(const char *fmt_singular, const char *fmt_plural, + unsigned long n, ...) +/* This extension allows gcc to check the format string for consistency with + the supplied arguments. */ +__attribute__((format(printf, 1, 4))) +__attribute__((format(printf, 2, 4))); + +extern int errhint(const char *fmt,...) /* This extension allows gcc to check the format string for consistency with the supplied arguments. */ diff --git a/src/pl/plperl/nls.mk b/src/pl/plperl/nls.mk index 8eaf6dd773f..030886c0bb9 100644 --- a/src/pl/plperl/nls.mk +++ b/src/pl/plperl/nls.mk @@ -1,5 +1,5 @@ -# $PostgreSQL: pgsql/src/pl/plperl/nls.mk,v 1.5 2009/05/14 21:41:53 alvherre Exp $ +# $PostgreSQL: pgsql/src/pl/plperl/nls.mk,v 1.6 2009/06/04 18:33:07 tgl Exp $ CATALOG_NAME := plperl AVAIL_LANGUAGES := de es fr pt_BR tr GETTEXT_FILES := plperl.c SPI.c -GETTEXT_TRIGGERS:= errmsg errdetail errdetail_log errhint errcontext +GETTEXT_TRIGGERS:= errmsg errmsg_plural:1,2 errdetail errdetail_log errdetail_plural:1,2 errhint errcontext diff --git a/src/pl/plpgsql/src/nls.mk b/src/pl/plpgsql/src/nls.mk index 7f17b88eece..ffebf4b21e9 100644 --- a/src/pl/plpgsql/src/nls.mk +++ b/src/pl/plpgsql/src/nls.mk @@ -1,8 +1,8 @@ -# $PostgreSQL: pgsql/src/pl/plpgsql/src/nls.mk,v 1.7 2009/05/14 21:41:53 alvherre Exp $ +# $PostgreSQL: pgsql/src/pl/plpgsql/src/nls.mk,v 1.8 2009/06/04 18:33:07 tgl Exp $ CATALOG_NAME := plpgsql AVAIL_LANGUAGES := de es fr ja ro tr GETTEXT_FILES := pl_comp.c pl_exec.c pl_gram.c pl_funcs.c pl_handler.c pl_scan.c -GETTEXT_TRIGGERS:= _ errmsg errdetail errdetail_log errhint errcontext validate_tupdesc_compat:3 yyerror plpgsql_yyerror +GETTEXT_TRIGGERS:= _ errmsg errmsg_plural:1,2 errdetail errdetail_log errdetail_plural:1,2 errhint errcontext validate_tupdesc_compat:3 yyerror plpgsql_yyerror .PHONY: gettext-files gettext-files: distprep diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c index e436e053b1b..b5f00069188 100644 --- a/src/pl/plpgsql/src/pl_exec.c +++ b/src/pl/plpgsql/src/pl_exec.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.241 2009/05/02 17:27:57 tgl Exp $ + * $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.242 2009/06/04 18:33:07 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -4083,9 +4083,11 @@ exec_eval_expr(PLpgSQL_execstate *estate, if (estate->eval_tuptable->tupdesc->natts != 1) ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), - errmsg(dngettext(TEXTDOMAIN, "query \"%s\" returned %d column", "query \"%s\" returned %d columns", estate->eval_tuptable->tupdesc->natts), - expr->query, - estate->eval_tuptable->tupdesc->natts))); + errmsg_plural("query \"%s\" returned %d column", + "query \"%s\" returned %d columns", + estate->eval_tuptable->tupdesc->natts, + expr->query, + estate->eval_tuptable->tupdesc->natts))); /* * Return the result and its type diff --git a/src/pl/plpython/nls.mk b/src/pl/plpython/nls.mk index 5721dbf445e..6e54a353120 100644 --- a/src/pl/plpython/nls.mk +++ b/src/pl/plpython/nls.mk @@ -1,5 +1,5 @@ -# $PostgreSQL: pgsql/src/pl/plpython/nls.mk,v 1.4 2009/05/14 21:41:53 alvherre Exp $ +# $PostgreSQL: pgsql/src/pl/plpython/nls.mk,v 1.5 2009/06/04 18:33:08 tgl Exp $ CATALOG_NAME := plpython AVAIL_LANGUAGES := de es fr pt_BR tr GETTEXT_FILES := plpython.c -GETTEXT_TRIGGERS:= errmsg errdetail errdetail_log errhint errcontext PLy_elog:2 PLy_exception_set:2 +GETTEXT_TRIGGERS:= errmsg errmsg_plural:1,2 errdetail errdetail_log errdetail_plural:1,2 errhint errcontext PLy_elog:2 PLy_exception_set:2 PLy_exception_set_plural:2,3 diff --git a/src/pl/plpython/plpython.c b/src/pl/plpython/plpython.c index 61e4772e8bc..345f3f65236 100644 --- a/src/pl/plpython/plpython.c +++ b/src/pl/plpython/plpython.c @@ -1,7 +1,7 @@ /********************************************************************** * plpython.c - python as a procedural language for PostgreSQL * - * $PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.120 2009/04/03 16:59:42 tgl Exp $ + * $PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.121 2009/06/04 18:33:08 tgl Exp $ * ********************************************************************* */ @@ -205,9 +205,13 @@ static void PLy_init_interp(void); static void PLy_init_plpy(void); /* call PyErr_SetString with a vprint interface and translation support */ -static void -PLy_exception_set(PyObject *, const char *,...) +static void PLy_exception_set(PyObject *, const char *,...) __attribute__((format(printf, 2, 3))); +/* same, with pluralized message */ +static void PLy_exception_set_plural(PyObject *, const char *, const char *, + unsigned long n,...) +__attribute__((format(printf, 2, 5))) +__attribute__((format(printf, 3, 5))); /* Get the innermost python procedure called from the backend */ static char *PLy_procedure_name(PLyProcedure *); @@ -2525,9 +2529,11 @@ PLy_spi_execute_plan(PyObject * ob, PyObject * list, long limit) PLy_elog(ERROR, "PL/Python function \"%s\" could not execute plan", PLy_procedure_name(PLy_curr_procedure)); sv = PyString_AsString(so); - PLy_exception_set(PLy_exc_spi_error, - dngettext(TEXTDOMAIN, "Expected sequence of %d argument, got %d: %s", "Expected sequence of %d arguments, got %d: %s", plan->nargs), - plan->nargs, nargs, sv); + PLy_exception_set_plural(PLy_exc_spi_error, + "Expected sequence of %d argument, got %d: %s", + "Expected sequence of %d arguments, got %d: %s", + plan->nargs, + plan->nargs, nargs, sv); Py_DECREF(so); return NULL; @@ -2941,8 +2947,8 @@ PLy_procedure_name(PLyProcedure * proc) return proc->proname; } -/* output a python traceback/exception via the postgresql elog - * function. not pretty. +/* + * Call PyErr_SetString with a vprint interface and translation support */ static void PLy_exception_set(PyObject * exc, const char *fmt,...) @@ -2957,6 +2963,26 @@ PLy_exception_set(PyObject * exc, const char *fmt,...) PyErr_SetString(exc, buf); } +/* + * The same, pluralized. + */ +static void +PLy_exception_set_plural(PyObject *exc, + const char *fmt_singular, const char *fmt_plural, + unsigned long n,...) +{ + char buf[1024]; + va_list ap; + + va_start(ap, n); + vsnprintf(buf, sizeof(buf), + dngettext(TEXTDOMAIN, fmt_singular, fmt_plural, n), + ap); + va_end(ap); + + PyErr_SetString(exc, buf); +} + /* Emit a PG error or notice, together with any available info about the * current Python error. This should be used to propagate Python errors * into PG. diff --git a/src/pl/tcl/nls.mk b/src/pl/tcl/nls.mk index 9188911f762..f331e658a98 100644 --- a/src/pl/tcl/nls.mk +++ b/src/pl/tcl/nls.mk @@ -1,5 +1,5 @@ -# $PostgreSQL: pgsql/src/pl/tcl/nls.mk,v 1.4 2009/05/14 21:41:53 alvherre Exp $ +# $PostgreSQL: pgsql/src/pl/tcl/nls.mk,v 1.5 2009/06/04 18:33:08 tgl Exp $ CATALOG_NAME := pltcl AVAIL_LANGUAGES := de es fr pt_BR tr GETTEXT_FILES := pltcl.c -GETTEXT_TRIGGERS:= errmsg errdetail errdetail_log errhint errcontext +GETTEXT_TRIGGERS:= errmsg errmsg_plural:1,2 errdetail errdetail_log errdetail_plural:1,2 errhint errcontext |