Hello, postgresmen!
 
I found incorrect execution of ereport() macro.
If we pass into ereport() function 2 or more arguments, the macro errcontext does not correct execute. So, ereport() call stack is:
 
errstart
errcontext_msg
set_errcontext_domain
errmsg
errfinish
pg_unreachable
 
This bug causes that error messages (for example, in PL/TCL) are not localized.

Solutions:
- Wrap all errcontext() macro in
brackets, that is errcontext("error message %s", "end message") -> (errcontext("error message %s", "end message"))
- Rewrite this macro
- ???
 
I am attaching to this letter a test case that shows the behavior errcontext() macro and the way to fix it.

I am using postgresql 9.4 and test it on gcc 4.7 and gcc 4.8.1.

-- Best regards, Dmitry Voronin
#include <stdio.h>

#define ereport_domain(elevel, domain, rest)	\
	do { \
		const int elevel_ = (elevel); \
		if (errstart(elevel_, __FILE__, __LINE__, PG_FUNCNAME_MACRO, domain)) \
			errfinish rest; \
		if (elevel_ >= 2) \
			pg_unreachable(); \
	} while(0)

#define ereport(elevel, rest)	\
	ereport_domain(elevel, TEXTDOMAIN, rest)

#define TEXTDOMAIN NULL
#define PG_FUNCNAME_MACRO NULL
#define ERROR 20

#define errcontext	set_errcontext_domain(TEXTDOMAIN),	errcontext_msg


int set_errcontext_domain(const char *domain)
{
	printf("set_errcontext_domain\n");
}


int
errstart(int elevel, const char *filename, int lineno,
		 const char *funcname, const char *domain)
{
	printf("errstart\n");
	return 1;
}


void pg_unreachable()
{
	printf("pg_unreachable\n");
}


void errfinish(int dummy, ...)
{
	printf("errfinish\n");
}


int
errcontext_msg(const char *fmt,...)
{
	printf("errcontext_msg\n");
	return 0;
}


int errmsg(const char *fmt, ...)
{
	printf("errmsg\n");
	return 0;
}


int main()
{
	/* this is incorrect */
	ereport(ERROR,
         	(errmsg("%s", "error message"),
             errcontext("%s\nin PL/Tcl function \"%s\"",
                        "test1", "test2")));
	printf("\n");
	/* this is correct */
	ereport(ERROR,
         	(errmsg("%s", "error message"),
             (errcontext("%s\nin PL/Tcl function \"%s\"",
                        "test1", "test2"))));

	return 0;
}
-- 
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