mirror of
https://github.com/MariaDB/server.git
synced 2026-10-23 18:49:29 +03:00
MDEV-38451 SHOW FUNCTION CODE package_func crashes on the second execution
Routine name resolution performed on a temporary memory root during execution. So on the second execution LEX::spname members pointed to a cleared memory. Fixing to peform the resolution to parse time, like the CALL statement does. During the execution time LEX::spname members now stay untouched.
This commit is contained in:
@@ -243,3 +243,33 @@ Pos Instruction
|
||||
7 jump 11
|
||||
DROP PACKAGE pkg1;
|
||||
DROP TABLE t1;
|
||||
# Start of 10.11 tests
|
||||
#
|
||||
# MDEV-38451 `SHOW FUNCTION CODE package_func` crashes on the second execution
|
||||
#
|
||||
CREATE PACKAGE pkg1 AS
|
||||
PROCEDURE p1();
|
||||
END;
|
||||
$$
|
||||
CREATE PACKAGE BODY pkg1 AS
|
||||
FUNCTION f1() RETURN INT AS
|
||||
BEGIN
|
||||
RETURN 10;
|
||||
END;
|
||||
PROCEDURE p1() AS
|
||||
BEGIN
|
||||
SHOW FUNCTION CODE f1;
|
||||
END;
|
||||
END;
|
||||
$$
|
||||
CALL pkg1.p1;
|
||||
Pos Instruction
|
||||
0 freturn int 10
|
||||
CALL pkg1.p1;
|
||||
Pos Instruction
|
||||
0 freturn int 10
|
||||
CALL pkg1.p1;
|
||||
Pos Instruction
|
||||
0 freturn int 10
|
||||
DROP PACKAGE pkg1;
|
||||
# End of 10.11 tests
|
||||
|
||||
@@ -180,3 +180,33 @@ SHOW PROCEDURE CODE pkg1.p1;
|
||||
SHOW PACKAGE BODY CODE pkg1;
|
||||
DROP PACKAGE pkg1;
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo # Start of 10.11 tests
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-38451 `SHOW FUNCTION CODE package_func` crashes on the second execution
|
||||
--echo #
|
||||
|
||||
DELIMITER $$;
|
||||
CREATE PACKAGE pkg1 AS
|
||||
PROCEDURE p1();
|
||||
END;
|
||||
$$
|
||||
CREATE PACKAGE BODY pkg1 AS
|
||||
FUNCTION f1() RETURN INT AS
|
||||
BEGIN
|
||||
RETURN 10;
|
||||
END;
|
||||
PROCEDURE p1() AS
|
||||
BEGIN
|
||||
SHOW FUNCTION CODE f1;
|
||||
END;
|
||||
END;
|
||||
$$
|
||||
DELIMITER ;$$
|
||||
CALL pkg1.p1;
|
||||
CALL pkg1.p1;
|
||||
CALL pkg1.p1;
|
||||
DROP PACKAGE pkg1;
|
||||
|
||||
--echo # End of 10.11 tests
|
||||
|
||||
@@ -8120,6 +8120,8 @@ class Database_qualified_name
|
||||
public:
|
||||
LEX_CSTRING m_db;
|
||||
LEX_CSTRING m_name;
|
||||
Database_qualified_name()
|
||||
{ }
|
||||
Database_qualified_name(const LEX_CSTRING *db, const LEX_CSTRING *name)
|
||||
:m_db(*db), m_name(*name)
|
||||
{ }
|
||||
|
||||
@@ -180,4 +180,38 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#ifndef DBUG_OFF
|
||||
/**
|
||||
Sql_cmd_call represents the SHOW CODE statement:
|
||||
- SHOW PROCEDURE CODE
|
||||
- SHOW FUNCTION CODE
|
||||
- SHOW PACKAGE BODY CODE
|
||||
*/
|
||||
class Sql_cmd_show_routine_code : public Sql_cmd
|
||||
{
|
||||
public:
|
||||
class sp_name *m_name;
|
||||
const class Sp_handler *m_handler;
|
||||
enum_sql_command m_sql_command;
|
||||
Sql_cmd_show_routine_code(class sp_name *name,
|
||||
const class Sp_handler *handler,
|
||||
enum_sql_command sql_command)
|
||||
:m_name(name),
|
||||
m_handler(handler),
|
||||
m_sql_command(sql_command)
|
||||
{}
|
||||
|
||||
virtual ~Sql_cmd_show_routine_code() = default;
|
||||
|
||||
bool execute(THD *thd) override;
|
||||
|
||||
enum_sql_command sql_command_code() const override
|
||||
{
|
||||
return m_sql_command;
|
||||
}
|
||||
};
|
||||
#endif // DBUG_OFF
|
||||
|
||||
|
||||
#endif // SQL_CMD_INCLUDED
|
||||
|
||||
@@ -9390,6 +9390,27 @@ bool LEX::add_create_view(THD *thd, DDL_options_st ddl,
|
||||
}
|
||||
|
||||
|
||||
bool LEX::show_routine_code_start(THD *thd, enum_sql_command cmd, sp_name *name)
|
||||
{
|
||||
#ifdef DBUG_OFF
|
||||
my_error(ER_FEATURE_DISABLED, MYF(0),
|
||||
"SHOW PROCEDURE|FUNCTION CODE", "--with-debug");
|
||||
return true;
|
||||
#else
|
||||
sql_command= cmd;
|
||||
Database_qualified_name pkgname;
|
||||
const Sp_handler *sph= Sp_handler::handler(cmd);
|
||||
if (sph->sp_resolve_package_routine(thd, thd->lex->sphead,
|
||||
name, &sph, &pkgname))
|
||||
return true;
|
||||
if (!(m_sql_cmd= new (thd->mem_root) Sql_cmd_show_routine_code(name, sph,
|
||||
cmd)))
|
||||
return true;
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
bool LEX::call_statement_start(THD *thd, sp_name *name)
|
||||
{
|
||||
Database_qualified_name pkgname(&null_clex_str, &null_clex_str);
|
||||
|
||||
@@ -3971,6 +3971,7 @@ public:
|
||||
const sp_name *name,
|
||||
const sp_name *name2,
|
||||
const char *cpp_body_end);
|
||||
bool show_routine_code_start(THD *thd, enum_sql_command cmd, sp_name *name);
|
||||
bool call_statement_start(THD *thd, sp_name *name);
|
||||
bool call_statement_start(THD *thd, const Lex_ident_sys_st *name);
|
||||
bool call_statement_start(THD *thd, const Lex_ident_sys_st *name1,
|
||||
|
||||
@@ -3288,6 +3288,24 @@ static bool prepare_db_action(THD *thd, privilege_t want_access,
|
||||
}
|
||||
|
||||
|
||||
#ifndef DBUG_OFF
|
||||
bool Sql_cmd_show_routine_code::execute(THD *thd)
|
||||
{
|
||||
sp_head *sp;
|
||||
if (m_handler->sp_cache_routine(thd, m_name, &sp))
|
||||
return true;
|
||||
if (!sp || sp->show_routine_code(thd))
|
||||
{
|
||||
/* We don't distinguish between errors for now */
|
||||
my_error(ER_SP_DOES_NOT_EXIST, MYF(0),
|
||||
m_handler->type_str(), m_name->m_name.str);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif // DBUG_OFF
|
||||
|
||||
|
||||
bool Sql_cmd_call::execute(THD *thd)
|
||||
{
|
||||
TABLE_LIST *all_tables= thd->lex->query_tables;
|
||||
@@ -5967,34 +5985,6 @@ mysql_execute_command(THD *thd, bool is_called_from_prepared_stmt)
|
||||
goto error;
|
||||
break;
|
||||
}
|
||||
case SQLCOM_SHOW_PROC_CODE:
|
||||
case SQLCOM_SHOW_FUNC_CODE:
|
||||
case SQLCOM_SHOW_PACKAGE_BODY_CODE:
|
||||
{
|
||||
#ifndef DBUG_OFF
|
||||
Database_qualified_name pkgname(&null_clex_str, &null_clex_str);
|
||||
sp_head *sp;
|
||||
const Sp_handler *sph= Sp_handler::handler(lex->sql_command);
|
||||
WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_SHOW);
|
||||
if (sph->sp_resolve_package_routine(thd, thd->lex->sphead,
|
||||
lex->spname, &sph, &pkgname))
|
||||
return true;
|
||||
if (sph->sp_cache_routine(thd, lex->spname, &sp))
|
||||
goto error;
|
||||
if (!sp || sp->show_routine_code(thd))
|
||||
{
|
||||
/* We don't distinguish between errors for now */
|
||||
my_error(ER_SP_DOES_NOT_EXIST, MYF(0),
|
||||
sph->type_str(), lex->spname->m_name.str);
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
#else
|
||||
my_error(ER_FEATURE_DISABLED, MYF(0),
|
||||
"SHOW PROCEDURE|FUNCTION CODE", "--with-debug");
|
||||
goto error;
|
||||
#endif // ifndef DBUG_OFF
|
||||
}
|
||||
case SQLCOM_SHOW_CREATE_TRIGGER:
|
||||
{
|
||||
if (check_ident_length(&lex->spname->m_name))
|
||||
@@ -6199,6 +6189,9 @@ mysql_execute_command(THD *thd, bool is_called_from_prepared_stmt)
|
||||
case SQLCOM_SIGNAL:
|
||||
case SQLCOM_RESIGNAL:
|
||||
case SQLCOM_GET_DIAGNOSTICS:
|
||||
case SQLCOM_SHOW_PROC_CODE:
|
||||
case SQLCOM_SHOW_FUNC_CODE:
|
||||
case SQLCOM_SHOW_PACKAGE_BODY_CODE:
|
||||
case SQLCOM_CALL:
|
||||
case SQLCOM_REVOKE:
|
||||
case SQLCOM_GRANT:
|
||||
|
||||
@@ -14024,23 +14024,25 @@ show_param:
|
||||
}
|
||||
| PROCEDURE_SYM CODE_SYM sp_name
|
||||
{
|
||||
Lex->sql_command= SQLCOM_SHOW_PROC_CODE;
|
||||
Lex->spname= $3;
|
||||
if (Lex->show_routine_code_start(thd, SQLCOM_SHOW_PROC_CODE, $3))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
| FUNCTION_SYM CODE_SYM sp_name
|
||||
{
|
||||
Lex->sql_command= SQLCOM_SHOW_FUNC_CODE;
|
||||
Lex->spname= $3;
|
||||
if (Lex->show_routine_code_start(thd, SQLCOM_SHOW_FUNC_CODE, $3))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
| PACKAGE_MARIADB_SYM BODY_MARIADB_SYM CODE_SYM sp_name
|
||||
{
|
||||
Lex->sql_command= SQLCOM_SHOW_PACKAGE_BODY_CODE;
|
||||
Lex->spname= $4;
|
||||
if (Lex->show_routine_code_start(thd, SQLCOM_SHOW_PACKAGE_BODY_CODE,
|
||||
$4))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
| PACKAGE_ORACLE_SYM BODY_ORACLE_SYM CODE_SYM sp_name
|
||||
{
|
||||
Lex->sql_command= SQLCOM_SHOW_PACKAGE_BODY_CODE;
|
||||
Lex->spname= $4;
|
||||
if (Lex->show_routine_code_start(thd, SQLCOM_SHOW_PACKAGE_BODY_CODE,
|
||||
$4))
|
||||
MYSQL_YYABORT;
|
||||
}
|
||||
| CREATE EVENT_SYM sp_name
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user