mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 20:12:31 +01:00
MDEV-10972: Insert from select / view / union -- repeatable crash in 10.1, 10.2 Linux/Mac/Windows
save thd->select_number between parsing and executions (in case it was not complete executed due to errors (for example epsent table))
This commit is contained in:
parent
be45f083e6
commit
17589989ee
5 changed files with 82 additions and 1 deletions
|
@ -8079,4 +8079,32 @@ CALL sp1();
|
|||
CALL sp1();
|
||||
drop user 'foo'@'%';
|
||||
drop procedure sp1;
|
||||
#
|
||||
# MDEV-10972: Insert from select / view / union --
|
||||
# repeatable crash in 10.1, 10.2 Linux/Mac/Windows
|
||||
#
|
||||
create table t (id int auto_increment primary key);
|
||||
insert into t values (9494),(9495),(9496),(9497),(9498),(9499),(9500),(9501),(9502),(9503);
|
||||
create VIEW v AS
|
||||
select id from t
|
||||
union
|
||||
select id from t
|
||||
;
|
||||
drop procedure if exists p;
|
||||
Warnings:
|
||||
Note 1305 PROCEDURE test.p does not exist
|
||||
create procedure p()
|
||||
insert into tmp_t select t.id from (
|
||||
select id from v
|
||||
union
|
||||
select id from v
|
||||
) sq
|
||||
inner join t on (sq.id = t.id);
|
||||
CALL p();
|
||||
ERROR 42S02: Table 'test.tmp_t' doesn't exist
|
||||
create table tmp_t (id int null);
|
||||
CALL p();
|
||||
drop procedure p;
|
||||
drop view v;
|
||||
drop table t, tmp_t;
|
||||
#End of 10.1 tests
|
||||
|
|
|
@ -9556,5 +9556,36 @@ CALL sp1();
|
|||
drop user 'foo'@'%';
|
||||
drop procedure sp1;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-10972: Insert from select / view / union --
|
||||
--echo # repeatable crash in 10.1, 10.2 Linux/Mac/Windows
|
||||
--echo #
|
||||
|
||||
create table t (id int auto_increment primary key);
|
||||
insert into t values (9494),(9495),(9496),(9497),(9498),(9499),(9500),(9501),(9502),(9503);
|
||||
|
||||
create VIEW v AS
|
||||
select id from t
|
||||
union
|
||||
select id from t
|
||||
;
|
||||
|
||||
drop procedure if exists p;
|
||||
create procedure p()
|
||||
insert into tmp_t select t.id from (
|
||||
select id from v
|
||||
union
|
||||
select id from v
|
||||
) sq
|
||||
inner join t on (sq.id = t.id);
|
||||
|
||||
--error ER_NO_SUCH_TABLE
|
||||
CALL p();
|
||||
create table tmp_t (id int null);
|
||||
CALL p();
|
||||
|
||||
drop procedure p;
|
||||
drop view v;
|
||||
drop table t, tmp_t;
|
||||
|
||||
--echo #End of 10.1 tests
|
||||
|
|
|
@ -760,6 +760,7 @@ static sp_head *sp_compile(THD *thd, String *defstr, ulonglong sql_mode,
|
|||
else
|
||||
{
|
||||
sp= thd->lex->sphead;
|
||||
sp->set_select_number(thd->select_number);
|
||||
}
|
||||
|
||||
thd->pop_internal_handler();
|
||||
|
|
|
@ -598,7 +598,7 @@ sp_head::sp_head()
|
|||
m_flags(0),
|
||||
m_sp_cache_version(0),
|
||||
m_creation_ctx(0),
|
||||
unsafe_flags(0),
|
||||
unsafe_flags(0), m_select_number(1),
|
||||
m_recursion_level(0),
|
||||
m_next_cached_sp(0),
|
||||
m_cont_level(0)
|
||||
|
@ -2100,8 +2100,26 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
|
|||
|
||||
if (!err_status)
|
||||
{
|
||||
/*
|
||||
Normally the counter is not reset between parsing and first execution,
|
||||
but it is possible in case of error to have parsing on one CALL and
|
||||
first execution (where VIEW will be parsed and added). So we store the
|
||||
counter after parsing and restore it before execution just to avoid
|
||||
repeating SELECT numbers.
|
||||
*/
|
||||
thd->select_number= m_select_number;
|
||||
|
||||
err_status= execute(thd, TRUE);
|
||||
DBUG_PRINT("info", ("execute returned %d", (int) err_status));
|
||||
/*
|
||||
This execution of the SP was aborted with an error (e.g. "Table not
|
||||
found"). However it might still have consumed some numbers from the
|
||||
thd->select_number counter. The next sp->exec() call must not use the
|
||||
consumed numbers, so we remember the first free number (We know that
|
||||
nobody will use it as this execution has stopped with an error).
|
||||
*/
|
||||
if (err_status)
|
||||
set_select_number(thd->select_number);
|
||||
}
|
||||
|
||||
if (save_log_general)
|
||||
|
|
|
@ -232,6 +232,7 @@ private:
|
|||
*/
|
||||
uint32 unsafe_flags;
|
||||
|
||||
uint m_select_number;
|
||||
public:
|
||||
inline Stored_program_creation_ctx *get_creation_ctx()
|
||||
{
|
||||
|
@ -521,6 +522,8 @@ public:
|
|||
|
||||
sp_pcontext *get_parse_context() { return m_pcont; }
|
||||
|
||||
void set_select_number(uint num) { m_select_number= num; }
|
||||
|
||||
private:
|
||||
|
||||
MEM_ROOT *m_thd_root; ///< Temp. store for thd's mem_root
|
||||
|
|
Loading…
Reference in a new issue