Loading mysql-test/r/create.result +14 −0 Original line number Diff line number Diff line Loading @@ -1691,4 +1691,18 @@ ERROR 42000: Identifier name 'очень_очень_очень_очень_оче drop view имя_вью_кодировке_утф8_длиной_больше_чем_42; drop table имя_таблицы_в_кодировке_утф8_длиной_больше_чем_48; set names default; drop table if exists t1,t2,t3; drop function if exists f1; create function f1() returns int begin declare res int; create temporary table t3 select 1 i; set res:= (select count(*) from t1); drop temporary table t3; return res; end| create table t1 as select 1; create table t2 as select f1() from t1; drop table t1,t2; drop function f1; End of 5.1 tests mysql-test/t/create.test +25 −0 Original line number Diff line number Diff line Loading @@ -1303,4 +1303,29 @@ return 0; drop view имя_вью_кодировке_утф8_длиной_больше_чем_42; drop table имя_таблицы_в_кодировке_утф8_длиной_больше_чем_48; set names default; # # Bug#21136 CREATE TABLE SELECT within CREATE TABLE SELECT causes server crash # --disable_warnings drop table if exists t1,t2,t3; drop function if exists f1; --enable_warnings --delimiter | create function f1() returns int begin declare res int; create temporary table t3 select 1 i; set res:= (select count(*) from t1); drop temporary table t3; return res; end| --delimiter ; create table t1 as select 1; create table t2 as select f1() from t1; drop table t1,t2; drop function f1; --echo End of 5.1 tests sql/sql_class.h +6 −1 Original line number Diff line number Diff line Loading @@ -2133,6 +2133,10 @@ class select_create: public select_insert { TABLE_LIST *select_tables; Alter_info *alter_info; Field **field; /* lock data for tmp table */ MYSQL_LOCK *m_lock; /* m_lock or thd->extra_lock */ MYSQL_LOCK **m_plock; public: select_create (TABLE_LIST *table_arg, HA_CREATE_INFO *create_info_par, Loading @@ -2143,7 +2147,8 @@ class select_create: public select_insert { create_table(table_arg), create_info(create_info_par), select_tables(select_tables_arg), alter_info(alter_info_arg) alter_info(alter_info_arg), m_plock(NULL) {} int prepare(List<Item> &list, SELECT_LEX_UNIT *u); Loading sql/sql_insert.cc +20 −7 Original line number Diff line number Diff line Loading @@ -3427,6 +3427,7 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, int select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u) { MYSQL_LOCK *extra_lock= NULL; DBUG_ENTER("select_create::prepare"); TABLEOP_HOOKS *hook_ptr= NULL; Loading Loading @@ -3496,9 +3497,21 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u) if (!(table= create_table_from_items(thd, create_info, create_table, alter_info, &values, &thd->extra_lock, hook_ptr))) &extra_lock, hook_ptr))) DBUG_RETURN(-1); // abort() deletes table if (extra_lock) { DBUG_ASSERT(m_plock == NULL); if (create_info->options & HA_LEX_CREATE_TMP_TABLE) m_plock= &m_lock; else m_plock= &thd->extra_lock; *m_plock= extra_lock; } if (table->s->fields < values.elements) { my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), 1); Loading Loading @@ -3637,10 +3650,10 @@ bool select_create::send_eof() table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY); table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE); if (thd->extra_lock) if (m_plock) { mysql_unlock_tables(thd, thd->extra_lock); thd->extra_lock=0; mysql_unlock_tables(thd, *m_plock); m_plock= 0; } } return tmp; Loading Loading @@ -3675,10 +3688,10 @@ void select_create::abort() if (thd->current_stmt_binlog_row_based) ha_rollback_stmt(thd); if (thd->extra_lock) if (m_plock) { mysql_unlock_tables(thd, thd->extra_lock); thd->extra_lock=0; mysql_unlock_tables(thd, *m_plock); m_plock= 0; } if (table) Loading Loading
mysql-test/r/create.result +14 −0 Original line number Diff line number Diff line Loading @@ -1691,4 +1691,18 @@ ERROR 42000: Identifier name 'очень_очень_очень_очень_оче drop view имя_вью_кодировке_утф8_длиной_больше_чем_42; drop table имя_таблицы_в_кодировке_утф8_длиной_больше_чем_48; set names default; drop table if exists t1,t2,t3; drop function if exists f1; create function f1() returns int begin declare res int; create temporary table t3 select 1 i; set res:= (select count(*) from t1); drop temporary table t3; return res; end| create table t1 as select 1; create table t2 as select f1() from t1; drop table t1,t2; drop function f1; End of 5.1 tests
mysql-test/t/create.test +25 −0 Original line number Diff line number Diff line Loading @@ -1303,4 +1303,29 @@ return 0; drop view имя_вью_кодировке_утф8_длиной_больше_чем_42; drop table имя_таблицы_в_кодировке_утф8_длиной_больше_чем_48; set names default; # # Bug#21136 CREATE TABLE SELECT within CREATE TABLE SELECT causes server crash # --disable_warnings drop table if exists t1,t2,t3; drop function if exists f1; --enable_warnings --delimiter | create function f1() returns int begin declare res int; create temporary table t3 select 1 i; set res:= (select count(*) from t1); drop temporary table t3; return res; end| --delimiter ; create table t1 as select 1; create table t2 as select f1() from t1; drop table t1,t2; drop function f1; --echo End of 5.1 tests
sql/sql_class.h +6 −1 Original line number Diff line number Diff line Loading @@ -2133,6 +2133,10 @@ class select_create: public select_insert { TABLE_LIST *select_tables; Alter_info *alter_info; Field **field; /* lock data for tmp table */ MYSQL_LOCK *m_lock; /* m_lock or thd->extra_lock */ MYSQL_LOCK **m_plock; public: select_create (TABLE_LIST *table_arg, HA_CREATE_INFO *create_info_par, Loading @@ -2143,7 +2147,8 @@ class select_create: public select_insert { create_table(table_arg), create_info(create_info_par), select_tables(select_tables_arg), alter_info(alter_info_arg) alter_info(alter_info_arg), m_plock(NULL) {} int prepare(List<Item> &list, SELECT_LEX_UNIT *u); Loading
sql/sql_insert.cc +20 −7 Original line number Diff line number Diff line Loading @@ -3427,6 +3427,7 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, int select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u) { MYSQL_LOCK *extra_lock= NULL; DBUG_ENTER("select_create::prepare"); TABLEOP_HOOKS *hook_ptr= NULL; Loading Loading @@ -3496,9 +3497,21 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u) if (!(table= create_table_from_items(thd, create_info, create_table, alter_info, &values, &thd->extra_lock, hook_ptr))) &extra_lock, hook_ptr))) DBUG_RETURN(-1); // abort() deletes table if (extra_lock) { DBUG_ASSERT(m_plock == NULL); if (create_info->options & HA_LEX_CREATE_TMP_TABLE) m_plock= &m_lock; else m_plock= &thd->extra_lock; *m_plock= extra_lock; } if (table->s->fields < values.elements) { my_error(ER_WRONG_VALUE_COUNT_ON_ROW, MYF(0), 1); Loading Loading @@ -3637,10 +3650,10 @@ bool select_create::send_eof() table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY); table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE); if (thd->extra_lock) if (m_plock) { mysql_unlock_tables(thd, thd->extra_lock); thd->extra_lock=0; mysql_unlock_tables(thd, *m_plock); m_plock= 0; } } return tmp; Loading Loading @@ -3675,10 +3688,10 @@ void select_create::abort() if (thd->current_stmt_binlog_row_based) ha_rollback_stmt(thd); if (thd->extra_lock) if (m_plock) { mysql_unlock_tables(thd, thd->extra_lock); thd->extra_lock=0; mysql_unlock_tables(thd, *m_plock); m_plock= 0; } if (table) Loading