Skip to content
/ server Public

Commit 21740cc

Browse files
committed
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.
1 parent 123fde1 commit 21740cc

File tree

7 files changed

+146
-36
lines changed

7 files changed

+146
-36
lines changed

mysql-test/suite/compat/oracle/r/sp-package-code.result

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,36 @@ Pos Instruction
243243
7 jump 11
244244
DROP PACKAGE pkg1;
245245
DROP TABLE t1;
246+
# Start of 10.11 tests
247+
#
248+
# MDEV-38451 `SHOW FUNCTION CODE package_func` crashes on the second execution
249+
#
250+
CREATE PACKAGE pkg1 AS
251+
PROCEDURE p1();
252+
END;
253+
$$
254+
CREATE PACKAGE BODY pkg1 AS
255+
FUNCTION f1() RETURN INT AS
256+
BEGIN
257+
RETURN 10;
258+
END;
259+
PROCEDURE p1() AS
260+
BEGIN
261+
SHOW FUNCTION CODE f1;
262+
END;
263+
END;
264+
$$
265+
CALL pkg1.p1;
266+
Pos Instruction
267+
0 freturn int 10
268+
CALL pkg1.p1;
269+
Pos Instruction
270+
0 freturn int 10
271+
CALL pkg1.p1;
272+
Pos Instruction
273+
0 freturn int 10
274+
DROP PACKAGE pkg1;
275+
# End of 10.11 tests
246276
# Start of 11.4 tests
247277
#
248278
# MDEV-36047 Package body variables are not allowed as FETCH targets

mysql-test/suite/compat/oracle/t/sp-package-code.test

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,35 @@ SHOW PACKAGE BODY CODE pkg1;
181181
DROP PACKAGE pkg1;
182182
DROP TABLE t1;
183183

184+
--echo # Start of 10.11 tests
185+
186+
--echo #
187+
--echo # MDEV-38451 `SHOW FUNCTION CODE package_func` crashes on the second execution
188+
--echo #
189+
190+
DELIMITER $$;
191+
CREATE PACKAGE pkg1 AS
192+
PROCEDURE p1();
193+
END;
194+
$$
195+
CREATE PACKAGE BODY pkg1 AS
196+
FUNCTION f1() RETURN INT AS
197+
BEGIN
198+
RETURN 10;
199+
END;
200+
PROCEDURE p1() AS
201+
BEGIN
202+
SHOW FUNCTION CODE f1;
203+
END;
204+
END;
205+
$$
206+
DELIMITER ;$$
207+
CALL pkg1.p1;
208+
CALL pkg1.p1;
209+
CALL pkg1.p1;
210+
DROP PACKAGE pkg1;
211+
212+
--echo # End of 10.11 tests
184213

185214
--echo # Start of 11.4 tests
186215

sql/sql_cmd.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,4 +458,38 @@ class Sql_cmd_call : public Sql_cmd
458458
}
459459
};
460460

461+
462+
#ifndef DBUG_OFF
463+
/**
464+
Sql_cmd_call represents the SHOW CODE statement:
465+
- SHOW PROCEDURE CODE
466+
- SHOW FUNCTION CODE
467+
- SHOW PACKAGE BODY CODE
468+
*/
469+
class Sql_cmd_show_routine_code : public Sql_cmd
470+
{
471+
public:
472+
class sp_name *m_name;
473+
const class Sp_handler *m_handler;
474+
enum_sql_command m_sql_command;
475+
Sql_cmd_show_routine_code(class sp_name *name,
476+
const class Sp_handler *handler,
477+
enum_sql_command sql_command)
478+
:m_name(name),
479+
m_handler(handler),
480+
m_sql_command(sql_command)
481+
{}
482+
483+
virtual ~Sql_cmd_show_routine_code() = default;
484+
485+
bool execute(THD *thd) override;
486+
487+
enum_sql_command sql_command_code() const override
488+
{
489+
return m_sql_command;
490+
}
491+
};
492+
#endif // DBUG_OFF
493+
494+
461495
#endif // SQL_CMD_INCLUDED

sql/sql_lex.cc

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10192,6 +10192,27 @@ bool LEX::add_create_view(THD *thd, DDL_options_st ddl,
1019210192
}
1019310193

1019410194

10195+
bool LEX::show_routine_code_start(THD *thd, enum_sql_command cmd, sp_name *name)
10196+
{
10197+
#ifdef DBUG_OFF
10198+
my_error(ER_FEATURE_DISABLED, MYF(0),
10199+
"SHOW PROCEDURE|FUNCTION CODE", "--with-debug");
10200+
return true;
10201+
#else
10202+
sql_command= cmd;
10203+
Database_qualified_name pkgname;
10204+
const Sp_handler *sph= Sp_handler::handler(cmd);
10205+
if (sph->sp_resolve_package_routine(thd, thd->lex->sphead,
10206+
name, &sph, &pkgname))
10207+
return true;
10208+
if (!(m_sql_cmd= new (thd->mem_root) Sql_cmd_show_routine_code(name, sph,
10209+
cmd)))
10210+
return true;
10211+
return false;
10212+
#endif
10213+
}
10214+
10215+
1019510216
bool LEX::call_statement_start(THD *thd, sp_name *name)
1019610217
{
1019710218
Database_qualified_name pkgname;

sql/sql_lex.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3947,6 +3947,7 @@ struct LEX: public Query_tables_list
39473947
const sp_name *name,
39483948
const sp_name *name2,
39493949
const char *cpp_body_end);
3950+
bool show_routine_code_start(THD *thd, enum_sql_command cmd, sp_name *name);
39503951
bool call_statement_start(THD *thd, sp_name *name);
39513952
bool call_statement_start(THD *thd, const Lex_ident_sys_st *name);
39523953
bool call_statement_start(THD *thd, const Lex_ident_sys_st *name1,

sql/sql_parse.cc

Lines changed: 21 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3221,6 +3221,24 @@ static bool prepare_db_action(THD *thd, privilege_t want_access,
32213221
}
32223222

32233223

3224+
#ifndef DBUG_OFF
3225+
bool Sql_cmd_show_routine_code::execute(THD *thd)
3226+
{
3227+
sp_head *sp;
3228+
if (m_handler->sp_cache_routine(thd, m_name, &sp))
3229+
return true;
3230+
if (!sp || sp->show_routine_code(thd))
3231+
{
3232+
/* We don't distinguish between errors for now */
3233+
my_error(ER_SP_DOES_NOT_EXIST, MYF(0),
3234+
m_handler->type_str(), m_name->m_name.str);
3235+
return true;
3236+
}
3237+
return false;
3238+
}
3239+
#endif // DBUG_OFF
3240+
3241+
32243242
bool Sql_cmd_call::execute(THD *thd)
32253243
{
32263244
TABLE_LIST *all_tables= thd->lex->query_tables;
@@ -5621,34 +5639,6 @@ mysql_execute_command(THD *thd, bool is_called_from_prepared_stmt)
56215639
goto error;
56225640
break;
56235641
}
5624-
case SQLCOM_SHOW_PROC_CODE:
5625-
case SQLCOM_SHOW_FUNC_CODE:
5626-
case SQLCOM_SHOW_PACKAGE_BODY_CODE:
5627-
{
5628-
#ifndef DBUG_OFF
5629-
Database_qualified_name pkgname;
5630-
sp_head *sp;
5631-
const Sp_handler *sph= Sp_handler::handler(lex->sql_command);
5632-
WSREP_SYNC_WAIT(thd, WSREP_SYNC_WAIT_BEFORE_SHOW);
5633-
if (sph->sp_resolve_package_routine(thd, thd->lex->sphead,
5634-
lex->spname, &sph, &pkgname))
5635-
return true;
5636-
if (sph->sp_cache_routine(thd, lex->spname, &sp))
5637-
goto error;
5638-
if (!sp || sp->show_routine_code(thd))
5639-
{
5640-
/* We don't distinguish between errors for now */
5641-
my_error(ER_SP_DOES_NOT_EXIST, MYF(0),
5642-
sph->type_str(), lex->spname->m_name.str);
5643-
goto error;
5644-
}
5645-
break;
5646-
#else
5647-
my_error(ER_FEATURE_DISABLED, MYF(0),
5648-
"SHOW PROCEDURE|FUNCTION CODE", "--with-debug");
5649-
goto error;
5650-
#endif // ifndef DBUG_OFF
5651-
}
56525642
case SQLCOM_SHOW_CREATE_TRIGGER:
56535643
{
56545644
if (check_ident_length(&lex->spname->m_name))
@@ -5852,6 +5842,9 @@ mysql_execute_command(THD *thd, bool is_called_from_prepared_stmt)
58525842
case SQLCOM_SIGNAL:
58535843
case SQLCOM_RESIGNAL:
58545844
case SQLCOM_GET_DIAGNOSTICS:
5845+
case SQLCOM_SHOW_PROC_CODE:
5846+
case SQLCOM_SHOW_FUNC_CODE:
5847+
case SQLCOM_SHOW_PACKAGE_BODY_CODE:
58555848
case SQLCOM_CALL:
58565849
case SQLCOM_REVOKE:
58575850
case SQLCOM_GRANT:

sql/sql_yacc.yy

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14839,23 +14839,25 @@ show_param:
1483914839
}
1484014840
| PROCEDURE_SYM CODE_SYM sp_name
1484114841
{
14842-
Lex->sql_command= SQLCOM_SHOW_PROC_CODE;
14843-
Lex->spname= $3;
14842+
if (Lex->show_routine_code_start(thd, SQLCOM_SHOW_PROC_CODE, $3))
14843+
MYSQL_YYABORT;
1484414844
}
1484514845
| FUNCTION_SYM CODE_SYM sp_name
1484614846
{
14847-
Lex->sql_command= SQLCOM_SHOW_FUNC_CODE;
14848-
Lex->spname= $3;
14847+
if (Lex->show_routine_code_start(thd, SQLCOM_SHOW_FUNC_CODE, $3))
14848+
MYSQL_YYABORT;
1484914849
}
1485014850
| PACKAGE_MARIADB_SYM BODY_MARIADB_SYM CODE_SYM sp_name
1485114851
{
14852-
Lex->sql_command= SQLCOM_SHOW_PACKAGE_BODY_CODE;
14853-
Lex->spname= $4;
14852+
if (Lex->show_routine_code_start(thd, SQLCOM_SHOW_PACKAGE_BODY_CODE,
14853+
$4))
14854+
MYSQL_YYABORT;
1485414855
}
1485514856
| PACKAGE_ORACLE_SYM BODY_ORACLE_SYM CODE_SYM sp_name
1485614857
{
14857-
Lex->sql_command= SQLCOM_SHOW_PACKAGE_BODY_CODE;
14858-
Lex->spname= $4;
14858+
if (Lex->show_routine_code_start(thd, SQLCOM_SHOW_PACKAGE_BODY_CODE,
14859+
$4))
14860+
MYSQL_YYABORT;
1485914861
}
1486014862
| CREATE EVENT_SYM sp_name
1486114863
{

0 commit comments

Comments
 (0)