Bug #83001 UDFs can't use push_warning
Submitted: 14 Sep 2016 21:49
Reporter: Trey Raymond Email Updates:
Status: Open Impact on me:
None 
Category:MySQL Server: User-defined functions ( UDF ) Severity:S4 (Feature request)
Version:all OS:Any
Assigned to: CPU Architecture:Any
Tags: udf, warnings

[14 Sep 2016 21:49] Trey Raymond
Description:
I have a dream, that udfs will be able to throw warnings to clients!
example:
We have, as part of our mysql build, a variety of udfs.  two of them are deprecated (with good reason), and will be removed in version [5.7.x].  now, with thousands of people writing code that uses this, it'd be nice if we could have current versions throw a warning about the deprecation.  That gives people a nice nonbreaking notification and a grace period to move away from them.

How to repeat:
write a udf!  this is a feature request.

Suggested fix:
modify the udf api so we can call push_warning or something with the same result
[28 Sep 2017 23:17] Sasha Pachev
I was able to produce warnings in a UDF with a simple hack (tested with 5.5.54 on Linux, dynamically linked mysqld, may have issues with a statically linked mysqld binary, but should work with higher versions as I do not believe the get_current_thd() and push_warning interface has changed - if it ever does this idea should still work):

Add this at the top of your UDF or in an include file (make sure all of this is seen as C++, not extern "C"):

class MYSQL_ERROR
{
public:
	enum enum_warning_level
		{ WARN_LEVEL_NOTE, WARN_LEVEL_WARN, WARN_LEVEL_ERROR, WARN_LEVEL_END};
};

class THD;

THD* thd_get_current_thd();
void push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level,
									uint code, const char *msg);

static void hack_push_warning(const char* msg)
{
	push_warning(thd_get_current_thd(), MYSQL_ERROR::WARN_LEVEL_NOTE, 0, msg);
}

Then you can just call hack_push_warning() and you will see the output in SHOW WARNINGS post-UDF execution on the same connection.

The idea is that we declare the prototypes of get_current_thd() and push_warning() in a way that will make them match to what is in the mysqld binary.
[28 Sep 2017 23:38] Sasha Pachev
And a little addition on top of the above:

#define HACK_WARN_MSG_BUF 1024

static void hack_push_warning_printf(const char* fmt, ...)
{
	va_list ap;
	va_start(ap, fmt);
	char buf[HACK_WARN_MSG_BUF];
	vsnprintf(buf, sizeof(buf), fmt, ap);
	hack_push_warning(buf);
	va_end(ap);
}