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)
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 */
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,
uint *prefix_removed);
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)
......
......@@ -208,17 +208,6 @@ void turn_parser_debug_on()
}
#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,
enum stored_procedure_type type)
......@@ -16767,41 +16756,7 @@ sf_tail:
sp->set_stmt_end(thd);
if (!(sp->m_flags & sp_head::HAS_RETURN))
my_yyabort_error((ER_SP_NORETURN, MYF(0), sp->m_qname.str));
if (is_native_function(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);
}
(void) is_native_function_with_warn(thd, &sp->m_name);
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