diff --git a/mysql-test/r/insert_select.result b/mysql-test/r/insert_select.result index 89ac863b8d2..0af48d27cd5 100644 --- a/mysql-test/r/insert_select.result +++ b/mysql-test/r/insert_select.result @@ -695,6 +695,16 @@ CREATE TABLE t2 (z int, y int); CREATE TABLE t3 (a int, b int); INSERT INTO t3 (SELECT x, y FROM t1 JOIN t2 USING (y) WHERE z = 1); DROP TABLE IF EXISTS t1,t2,t3; +CREATE DATABASE bug21774_1; +CREATE DATABASE bug21774_2; +CREATE TABLE bug21774_1.t1(id VARCHAR(10) NOT NULL,label VARCHAR(255)); +CREATE TABLE bug21774_2.t1(id VARCHAR(10) NOT NULL,label VARCHAR(255)); +CREATE TABLE bug21774_1.t2(id VARCHAR(10) NOT NULL,label VARCHAR(255)); +INSERT INTO bug21774_2.t1 SELECT t1.* FROM bug21774_1.t1; +use bug21774_1; +INSERT INTO bug21774_2.t1 SELECT t1.* FROM t1; +DROP DATABASE bug21774_1; +DROP DATABASE bug21774_2; CREATE DATABASE meow; CREATE TABLE table_target ( mexs_id CHAR(8), messzeit TIMESTAMP, PRIMARY KEY (mexs_id)); CREATE TABLE table_target2 ( mexs_id CHAR(8), messzeit TIMESTAMP, PRIMARY KEY (mexs_id)); diff --git a/mysql-test/t/insert_select.test b/mysql-test/t/insert_select.test index b6b94d07e87..6f86ed897ac 100644 --- a/mysql-test/t/insert_select.test +++ b/mysql-test/t/insert_select.test @@ -248,6 +248,24 @@ CREATE TABLE t3 (a int, b int); INSERT INTO t3 (SELECT x, y FROM t1 JOIN t2 USING (y) WHERE z = 1); DROP TABLE IF EXISTS t1,t2,t3; +# +# Bug #21774: Column count doesn't match value count at row x +# +CREATE DATABASE bug21774_1; +CREATE DATABASE bug21774_2; + +CREATE TABLE bug21774_1.t1(id VARCHAR(10) NOT NULL,label VARCHAR(255)); +CREATE TABLE bug21774_2.t1(id VARCHAR(10) NOT NULL,label VARCHAR(255)); +CREATE TABLE bug21774_1.t2(id VARCHAR(10) NOT NULL,label VARCHAR(255)); + +INSERT INTO bug21774_2.t1 SELECT t1.* FROM bug21774_1.t1; + +use bug21774_1; +INSERT INTO bug21774_2.t1 SELECT t1.* FROM t1; + +DROP DATABASE bug21774_1; +DROP DATABASE bug21774_2; + # # Bug #20989: View '(null).(null)' references invalid table(s)... on # SQL SECURITY INVOKER diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 3a12477bc15..c29c610b200 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -4453,7 +4453,20 @@ bool setup_tables(THD *thd, Name_resolution_context *context, uint tablenr= 0; DBUG_ENTER("setup_tables"); - context->table_list= context->first_name_resolution_table= tables; + /* + Due to the various call paths that lead to setup_tables() it may happen + that context->table_list and context->first_name_resolution_table can be + NULL (this is typically done when creating TABLE_LISTs internally). + TODO: + Investigate all cases when this my happen, initialize the name resolution + context correctly in all those places, and remove the context reset below. + */ + if (!context->table_list || !context->first_name_resolution_table) + { + /* Test whether the context is in a consistent state. */ + DBUG_ASSERT(!context->first_name_resolution_table && !context->table_list); + context->table_list= context->first_name_resolution_table= tables; + } /* this is used for INSERT ... SELECT. diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index c08deedea72..b70d11e4b26 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -411,6 +411,15 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, table= table_list->table; context= &thd->lex->select_lex.context; + /* + These three asserts test the hypothesis that the resetting of the name + resolution context below is not necessary at all since the list of local + tables for INSERT always consists of one table. + */ + DBUG_ASSERT(!table_list->next_local); + DBUG_ASSERT(!context->table_list->next_local); + DBUG_ASSERT(!context->first_name_resolution_table->next_name_resolution_table); + /* Save the state of the current name resolution context. */ ctx_state.save_state(context, table_list); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 2acbf18f1e6..0e49eb297f5 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3344,8 +3344,6 @@ end_with_restore_list: DBUG_ASSERT(first_table == all_tables && first_table != 0); if ((res= insert_precheck(thd, all_tables))) break; - /* Skip first table, which is the table we are inserting in */ - select_lex->context.table_list= first_table->next_local; if (!thd->locked_tables && !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))