Commit 1694c0e8 authored by Alexander Barkov's avatar Alexander Barkov

MDEV-12394 Add function is_native_function_with_warn()

parent 8af5dcb0
...@@ -880,6 +880,59 @@ bool is_lex_native_function(const LEX_STRING *name) ...@@ -880,6 +880,59 @@ bool is_lex_native_function(const LEX_STRING *name)
return (get_hash_symbol(name->str, (uint) name->length, 1) != 0); return (get_hash_symbol(name->str, (uint) name->length, 1) != 0);
} }
bool is_native_function(THD *thd, const LEX_STRING *name)
{
if (find_native_function_builder(thd, *name))
return true;
if (is_lex_native_function(name))
return true;
return false;
}
bool is_native_function_with_warn(THD *thd, const LEX_STRING *name)
{
if (!is_native_function(thd, name))
return false;
/*
This warning will be printed when
[1] A client query is parsed,
[2] A stored function is loaded by db_load_routine.
Printing the warning for [2] is intentional, to cover the
following scenario:
- A user define a SF 'foo' using MySQL 5.N
- An application uses select foo(), and works.
- MySQL 5.{N+1} defines a new native function 'foo', as
part of a new feature.
- MySQL 5.{N+1} documentation is updated, and should mention
that there is a potential incompatible change in case of
existing stored function named 'foo'.
- The user deploys 5.{N+1}. At this point, 'select foo()'
means something different, and the user code is most likely
broken (it's only safe if the code is 'select db.foo()').
With a warning printed when the SF is loaded (which has to
occur before the call), the warning will provide a hint
explaining the root cause of a later failure of 'select foo()'.
With no warning printed, the user code will fail with no
apparent reason.
Printing a warning each time db_load_routine is executed for
an ambiguous function is annoying, since that can happen a lot,
but in practice should not happen unless there *are* name
collisions.
If a collision exists, it should not be silenced but fixed.
*/
push_warning_printf(thd,
Sql_condition::WARN_LEVEL_NOTE,
ER_NATIVE_FCT_NAME_COLLISION,
ER_THD(thd, ER_NATIVE_FCT_NAME_COLLISION),
name->str);
return true;
}
/* make a copy of token before ptr and set yytoklen */ /* make a copy of token before ptr and set yytoklen */
static LEX_STRING get_token(Lex_input_stream *lip, uint skip, uint length) static LEX_STRING get_token(Lex_input_stream *lip, uint skip, uint length)
......
...@@ -3344,6 +3344,8 @@ extern void trim_whitespace(CHARSET_INFO *cs, LEX_STRING *str, ...@@ -3344,6 +3344,8 @@ extern void trim_whitespace(CHARSET_INFO *cs, LEX_STRING *str,
uint *prefix_removed); uint *prefix_removed);
extern bool is_lex_native_function(const LEX_STRING *name); extern bool is_lex_native_function(const LEX_STRING *name);
extern bool is_native_function(THD *thd, const LEX_STRING *name);
extern bool is_native_function_with_warn(THD *thd, const LEX_STRING *name);
/** /**
@} (End of group Semantic_Analysis) @} (End of group Semantic_Analysis)
......
...@@ -208,17 +208,6 @@ void turn_parser_debug_on() ...@@ -208,17 +208,6 @@ void turn_parser_debug_on()
} }
#endif #endif
static bool is_native_function(THD *thd, const LEX_STRING *name)
{
if (find_native_function_builder(thd, *name))
return true;
if (is_lex_native_function(name))
return true;
return false;
}
static sp_head *make_sp_head(THD *thd, sp_name *name, static sp_head *make_sp_head(THD *thd, sp_name *name,
enum stored_procedure_type type) enum stored_procedure_type type)
...@@ -16767,41 +16756,7 @@ sf_tail: ...@@ -16767,41 +16756,7 @@ sf_tail:
sp->set_stmt_end(thd); sp->set_stmt_end(thd);
if (!(sp->m_flags & sp_head::HAS_RETURN)) if (!(sp->m_flags & sp_head::HAS_RETURN))
my_yyabort_error((ER_SP_NORETURN, MYF(0), sp->m_qname.str)); my_yyabort_error((ER_SP_NORETURN, MYF(0), sp->m_qname.str));
if (is_native_function(thd, & sp->m_name)) (void) is_native_function_with_warn(thd, &sp->m_name);
{
/*
This warning will be printed when
[1] A client query is parsed,
[2] A stored function is loaded by db_load_routine.
Printing the warning for [2] is intentional, to cover the
following scenario:
- A user define a SF 'foo' using MySQL 5.N
- An application uses select foo(), and works.
- MySQL 5.{N+1} defines a new native function 'foo', as
part of a new feature.
- MySQL 5.{N+1} documentation is updated, and should mention
that there is a potential incompatible change in case of
existing stored function named 'foo'.
- The user deploys 5.{N+1}. At this point, 'select foo()'
means something different, and the user code is most likely
broken (it's only safe if the code is 'select db.foo()').
With a warning printed when the SF is loaded (which has to
occur before the call), the warning will provide a hint
explaining the root cause of a later failure of 'select foo()'.
With no warning printed, the user code will fail with no
apparent reason.
Printing a warning each time db_load_routine is executed for
an ambiguous function is annoying, since that can happen a lot,
but in practice should not happen unless there *are* name
collisions.
If a collision exists, it should not be silenced but fixed.
*/
push_warning_printf(thd,
Sql_condition::WARN_LEVEL_NOTE,
ER_NATIVE_FCT_NAME_COLLISION,
ER_THD(thd, ER_NATIVE_FCT_NAME_COLLISION),
sp->m_name.str);
}
sp->restore_thd_mem_root(thd); sp->restore_thd_mem_root(thd);
} }
; ;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment