diff options
author | Oleksandr Byelkin <sanja@mariadb.com> | 2019-10-17 14:08:33 +0200 |
---|---|---|
committer | Oleksandr Byelkin <sanja@mariadb.com> | 2019-10-17 17:32:14 +0200 |
commit | de2186dd2f5937a56d799f55c33078a7ad8ebddc (patch) | |
tree | 7b44a00f8fb8dcbea6145a0ae2fecf0cc764ac72 | |
parent | 6cdde9ebbf59254a81f04961818577ffd203f9d6 (diff) | |
download | mariadb-git-de2186dd2f5937a56d799f55c33078a7ad8ebddc.tar.gz |
MDEV-20074: Lost connection on update trigger
Instead of checking lex->sql_command which does not corect in case of triggers
mark tables for insert.
-rw-r--r-- | mysql-test/suite/sql_sequence/other.result | 91 | ||||
-rw-r--r-- | mysql-test/suite/sql_sequence/other.test | 136 | ||||
-rw-r--r-- | sql/sp_head.cc | 6 | ||||
-rw-r--r-- | sql/sql_base.cc | 27 | ||||
-rw-r--r-- | sql/sql_lex.h | 2 | ||||
-rw-r--r-- | sql/sql_parse.cc | 15 | ||||
-rw-r--r-- | sql/sql_view.cc | 13 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 13 | ||||
-rw-r--r-- | sql/sql_yacc_ora.yy | 13 | ||||
-rw-r--r-- | sql/table.h | 6 |
10 files changed, 305 insertions, 17 deletions
diff --git a/mysql-test/suite/sql_sequence/other.result b/mysql-test/suite/sql_sequence/other.result index ff58e35772b..abc101b3c00 100644 --- a/mysql-test/suite/sql_sequence/other.result +++ b/mysql-test/suite/sql_sequence/other.result @@ -209,4 +209,95 @@ delete s,t1 from t1,s; ERROR HY000: Storage engine SEQUENCE of the table `test`.`s` doesn't have this option DROP SEQUENCE s; DROP TABLE t1; +# +# MDEV-20074: Lost connection on update trigger +# +# INSERT & table +create sequence s1 increment by 1 start with 1; +create table t1 (p_id integer, p_name varchar(128), p_first_name varchar(128)); +create table t2 (a_id integer default nextval(s1), a_p_name varchar(128), a_p_first_name varchar(128), t timestamp default current_timestamp); +insert into t1 values +(1, 'Luo','Frank'),(2, 'Xe','Emma'),(3, 'Li','Anna'),(4, 'Lun','Serg'),(5, 'Xu','Nils'),(6, 'Ja','Ute'),(7, 'Jin','Mike'),(8, 'Lio','Carl'),(9, 'Lang','Kevin'),(10, 'Ling','Lisa'),(11, 'Fang','Frank'),(12, 'Feng','Emma'),(13, 'Tuo','Anna'),(14, 'Tua','Serg'),(15, 'Moa','Nils'),(16, 'Hua','Ute'),(17, 'Xufa','Mike'),(18, 'Lulu','Carl'),(19, 'Hoho','Kevin'),(20, 'Tata','Lisa'); +CREATE TRIGGER tr_upd +BEFORE UPDATE on t1 +FOR EACH ROW +BEGIN +INSERT INTO t2(a_p_name, a_p_first_name) VALUES(old.p_name, old.p_first_name); +END; +$$ +update t1 set p_first_name='Yunxi' where p_id=1; +drop sequence s1; +drop table t1,t2; +# INSERT & view +create sequence s1 increment by 1 start with 1; +create table t1 (p_id integer, p_name varchar(128), p_first_name varchar(128)); +create table t2 (a_id integer default nextval(s1), a_p_name varchar(128), a_p_first_name varchar(128), t timestamp default current_timestamp); +create view v2 as select * from t2; +insert into t1 values +(1, 'Luo','Frank'),(2, 'Xe','Emma'),(3, 'Li','Anna'),(4, 'Lun','Serg'),(5, 'Xu','Nils'),(6, 'Ja','Ute'),(7, 'Jin','Mike'),(8, 'Lio','Carl'),(9, 'Lang','Kevin'),(10, 'Ling','Lisa'),(11, 'Fang','Frank'),(12, 'Feng','Emma'),(13, 'Tuo','Anna'),(14, 'Tua','Serg'),(15, 'Moa','Nils'),(16, 'Hua','Ute'),(17, 'Xufa','Mike'),(18, 'Lulu','Carl'),(19, 'Hoho','Kevin'),(20, 'Tata','Lisa'); +CREATE TRIGGER tr_upd +BEFORE UPDATE on t1 +FOR EACH ROW +BEGIN +INSERT INTO v2(a_p_name, a_p_first_name) VALUES(old.p_name, old.p_first_name); +END; +$$ +update t1 set p_first_name='Yunxi' where p_id=1; +drop view v2; +drop table t1,t2; +drop sequence s1; +# INSERT SELECT & view +create sequence s1 increment by 1 start with 1; +create table t1 (p_id integer, p_name varchar(128), p_first_name varchar(128)); +create table t2 (a_id integer default nextval(s1), a_p_name varchar(128), a_p_first_name varchar(128), t timestamp default current_timestamp); +create view v2 as select * from t2; +insert into t1 values +(1, 'Luo','Frank'),(2, 'Xe','Emma'),(3, 'Li','Anna'),(4, 'Lun','Serg'),(5, 'Xu','Nils'),(6, 'Ja','Ute'),(7, 'Jin','Mike'),(8, 'Lio','Carl'),(9, 'Lang','Kevin'),(10, 'Ling','Lisa'),(11, 'Fang','Frank'),(12, 'Feng','Emma'),(13, 'Tuo','Anna'),(14, 'Tua','Serg'),(15, 'Moa','Nils'),(16, 'Hua','Ute'),(17, 'Xufa','Mike'),(18, 'Lulu','Carl'),(19, 'Hoho','Kevin'),(20, 'Tata','Lisa'); +CREATE TRIGGER tr_upd +BEFORE UPDATE on t1 +FOR EACH ROW +BEGIN +INSERT INTO v2(a_p_name, a_p_first_name) SELECT old.p_name, old.p_first_name; +END; +$$ +update t1 set p_first_name='Yunxi' where p_id=1; +drop view v2; +drop table t1,t2; +drop sequence s1; +# REPLACE & view +create sequence s1 increment by 1 start with 1; +create table t1 (p_id integer, p_name varchar(128), p_first_name varchar(128)); +create table t2 (a_id integer default nextval(s1), a_p_name varchar(128), a_p_first_name varchar(128), t timestamp default current_timestamp); +create view v2 as select * from t2; +insert into t1 values +(1, 'Luo','Frank'),(2, 'Xe','Emma'),(3, 'Li','Anna'),(4, 'Lun','Serg'),(5, 'Xu','Nils'),(6, 'Ja','Ute'),(7, 'Jin','Mike'),(8, 'Lio','Carl'),(9, 'Lang','Kevin'),(10, 'Ling','Lisa'),(11, 'Fang','Frank'),(12, 'Feng','Emma'),(13, 'Tuo','Anna'),(14, 'Tua','Serg'),(15, 'Moa','Nils'),(16, 'Hua','Ute'),(17, 'Xufa','Mike'),(18, 'Lulu','Carl'),(19, 'Hoho','Kevin'),(20, 'Tata','Lisa'); +CREATE TRIGGER tr_upd +BEFORE UPDATE on t1 +FOR EACH ROW +BEGIN +REPLACE INTO v2(a_p_name, a_p_first_name) VALUES(old.p_name, old.p_first_name); +END; +$$ +update t1 set p_first_name='Yunxi' where p_id=1; +drop view v2; +drop table t1,t2; +drop sequence s1; +# REPLACE SELECT & view +create sequence s1 increment by 1 start with 1; +create table t1 (p_id integer, p_name varchar(128), p_first_name varchar(128)); +create table t2 (a_id integer default nextval(s1), a_p_name varchar(128), a_p_first_name varchar(128), t timestamp default current_timestamp); +create view v2 as select * from t2; +insert into t1 values +(1, 'Luo','Frank'),(2, 'Xe','Emma'),(3, 'Li','Anna'),(4, 'Lun','Serg'),(5, 'Xu','Nils'),(6, 'Ja','Ute'),(7, 'Jin','Mike'),(8, 'Lio','Carl'),(9, 'Lang','Kevin'),(10, 'Ling','Lisa'),(11, 'Fang','Frank'),(12, 'Feng','Emma'),(13, 'Tuo','Anna'),(14, 'Tua','Serg'),(15, 'Moa','Nils'),(16, 'Hua','Ute'),(17, 'Xufa','Mike'),(18, 'Lulu','Carl'),(19, 'Hoho','Kevin'),(20, 'Tata','Lisa'); +CREATE TRIGGER tr_upd +BEFORE UPDATE on t1 +FOR EACH ROW +BEGIN +REPLACE INTO v2(a_p_name, a_p_first_name) SELECT old.p_name, old.p_first_name; +END; +$$ +update t1 set p_first_name='Yunxi' where p_id=1; +drop view v2; +drop table t1,t2; +drop sequence s1; # End of 10.3 tests diff --git a/mysql-test/suite/sql_sequence/other.test b/mysql-test/suite/sql_sequence/other.test index 5759b195950..70c4efa40e5 100644 --- a/mysql-test/suite/sql_sequence/other.test +++ b/mysql-test/suite/sql_sequence/other.test @@ -179,4 +179,140 @@ DROP SEQUENCE s; DROP TABLE t1; +--echo # +--echo # MDEV-20074: Lost connection on update trigger +--echo # + +--echo # INSERT & table +create sequence s1 increment by 1 start with 1; +create table t1 (p_id integer, p_name varchar(128), p_first_name varchar(128)); +create table t2 (a_id integer default nextval(s1), a_p_name varchar(128), a_p_first_name varchar(128), t timestamp default current_timestamp); + +insert into t1 values +(1, 'Luo','Frank'),(2, 'Xe','Emma'),(3, 'Li','Anna'),(4, 'Lun','Serg'),(5, 'Xu','Nils'),(6, 'Ja','Ute'),(7, 'Jin','Mike'),(8, 'Lio','Carl'),(9, 'Lang','Kevin'),(10, 'Ling','Lisa'),(11, 'Fang','Frank'),(12, 'Feng','Emma'),(13, 'Tuo','Anna'),(14, 'Tua','Serg'),(15, 'Moa','Nils'),(16, 'Hua','Ute'),(17, 'Xufa','Mike'),(18, 'Lulu','Carl'),(19, 'Hoho','Kevin'),(20, 'Tata','Lisa'); + +DELIMITER $$; + +CREATE TRIGGER tr_upd +BEFORE UPDATE on t1 +FOR EACH ROW +BEGIN +INSERT INTO t2(a_p_name, a_p_first_name) VALUES(old.p_name, old.p_first_name); +END; +$$ +DELIMITER ;$$ + +update t1 set p_first_name='Yunxi' where p_id=1; + +drop sequence s1; +drop table t1,t2; + + +--echo # INSERT & view +create sequence s1 increment by 1 start with 1; +create table t1 (p_id integer, p_name varchar(128), p_first_name varchar(128)); +create table t2 (a_id integer default nextval(s1), a_p_name varchar(128), a_p_first_name varchar(128), t timestamp default current_timestamp); +create view v2 as select * from t2; + +insert into t1 values +(1, 'Luo','Frank'),(2, 'Xe','Emma'),(3, 'Li','Anna'),(4, 'Lun','Serg'),(5, 'Xu','Nils'),(6, 'Ja','Ute'),(7, 'Jin','Mike'),(8, 'Lio','Carl'),(9, 'Lang','Kevin'),(10, 'Ling','Lisa'),(11, 'Fang','Frank'),(12, 'Feng','Emma'),(13, 'Tuo','Anna'),(14, 'Tua','Serg'),(15, 'Moa','Nils'),(16, 'Hua','Ute'),(17, 'Xufa','Mike'),(18, 'Lulu','Carl'),(19, 'Hoho','Kevin'),(20, 'Tata','Lisa'); + +DELIMITER $$; + +CREATE TRIGGER tr_upd +BEFORE UPDATE on t1 +FOR EACH ROW +BEGIN +INSERT INTO v2(a_p_name, a_p_first_name) VALUES(old.p_name, old.p_first_name); +END; +$$ +DELIMITER ;$$ + +update t1 set p_first_name='Yunxi' where p_id=1; + +drop view v2; +drop table t1,t2; +drop sequence s1; + + +--echo # INSERT SELECT & view +create sequence s1 increment by 1 start with 1; +create table t1 (p_id integer, p_name varchar(128), p_first_name varchar(128)); +create table t2 (a_id integer default nextval(s1), a_p_name varchar(128), a_p_first_name varchar(128), t timestamp default current_timestamp); +create view v2 as select * from t2; + +insert into t1 values +(1, 'Luo','Frank'),(2, 'Xe','Emma'),(3, 'Li','Anna'),(4, 'Lun','Serg'),(5, 'Xu','Nils'),(6, 'Ja','Ute'),(7, 'Jin','Mike'),(8, 'Lio','Carl'),(9, 'Lang','Kevin'),(10, 'Ling','Lisa'),(11, 'Fang','Frank'),(12, 'Feng','Emma'),(13, 'Tuo','Anna'),(14, 'Tua','Serg'),(15, 'Moa','Nils'),(16, 'Hua','Ute'),(17, 'Xufa','Mike'),(18, 'Lulu','Carl'),(19, 'Hoho','Kevin'),(20, 'Tata','Lisa'); + +DELIMITER $$; + +CREATE TRIGGER tr_upd +BEFORE UPDATE on t1 +FOR EACH ROW +BEGIN +INSERT INTO v2(a_p_name, a_p_first_name) SELECT old.p_name, old.p_first_name; +END; +$$ +DELIMITER ;$$ + +update t1 set p_first_name='Yunxi' where p_id=1; + +drop view v2; +drop table t1,t2; +drop sequence s1; + + +--echo # REPLACE & view +create sequence s1 increment by 1 start with 1; +create table t1 (p_id integer, p_name varchar(128), p_first_name varchar(128)); +create table t2 (a_id integer default nextval(s1), a_p_name varchar(128), a_p_first_name varchar(128), t timestamp default current_timestamp); +create view v2 as select * from t2; + +insert into t1 values +(1, 'Luo','Frank'),(2, 'Xe','Emma'),(3, 'Li','Anna'),(4, 'Lun','Serg'),(5, 'Xu','Nils'),(6, 'Ja','Ute'),(7, 'Jin','Mike'),(8, 'Lio','Carl'),(9, 'Lang','Kevin'),(10, 'Ling','Lisa'),(11, 'Fang','Frank'),(12, 'Feng','Emma'),(13, 'Tuo','Anna'),(14, 'Tua','Serg'),(15, 'Moa','Nils'),(16, 'Hua','Ute'),(17, 'Xufa','Mike'),(18, 'Lulu','Carl'),(19, 'Hoho','Kevin'),(20, 'Tata','Lisa'); + +DELIMITER $$; + +CREATE TRIGGER tr_upd +BEFORE UPDATE on t1 +FOR EACH ROW +BEGIN +REPLACE INTO v2(a_p_name, a_p_first_name) VALUES(old.p_name, old.p_first_name); +END; +$$ +DELIMITER ;$$ + +update t1 set p_first_name='Yunxi' where p_id=1; + +drop view v2; +drop table t1,t2; +drop sequence s1; + + +--echo # REPLACE SELECT & view +create sequence s1 increment by 1 start with 1; +create table t1 (p_id integer, p_name varchar(128), p_first_name varchar(128)); +create table t2 (a_id integer default nextval(s1), a_p_name varchar(128), a_p_first_name varchar(128), t timestamp default current_timestamp); +create view v2 as select * from t2; + +insert into t1 values +(1, 'Luo','Frank'),(2, 'Xe','Emma'),(3, 'Li','Anna'),(4, 'Lun','Serg'),(5, 'Xu','Nils'),(6, 'Ja','Ute'),(7, 'Jin','Mike'),(8, 'Lio','Carl'),(9, 'Lang','Kevin'),(10, 'Ling','Lisa'),(11, 'Fang','Frank'),(12, 'Feng','Emma'),(13, 'Tuo','Anna'),(14, 'Tua','Serg'),(15, 'Moa','Nils'),(16, 'Hua','Ute'),(17, 'Xufa','Mike'),(18, 'Lulu','Carl'),(19, 'Hoho','Kevin'),(20, 'Tata','Lisa'); + +DELIMITER $$; + +CREATE TRIGGER tr_upd +BEFORE UPDATE on t1 +FOR EACH ROW +BEGIN +REPLACE INTO v2(a_p_name, a_p_first_name) SELECT old.p_name, old.p_first_name; +END; +$$ +DELIMITER ;$$ + +update t1 set p_first_name='Yunxi' where p_id=1; + +drop view v2; +drop table t1,t2; +drop sequence s1; + --echo # End of 10.3 tests diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 458955b2d6b..48166fac4c6 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -4652,6 +4652,7 @@ typedef struct st_sp_table uint lock_count; uint query_lock_count; uint8 trg_event_map; + my_bool for_insert_data; } SP_TABLE; @@ -4747,6 +4748,7 @@ sp_head::merge_table_list(THD *thd, TABLE_LIST *table, LEX *lex_for_tmp_check) if (tab->query_lock_count > tab->lock_count) tab->lock_count++; tab->trg_event_map|= table->trg_event_map; + tab->for_insert_data|= table->for_insert_data; } else { @@ -4770,6 +4772,7 @@ sp_head::merge_table_list(THD *thd, TABLE_LIST *table, LEX *lex_for_tmp_check) tab->lock_type= table->lock_type; tab->lock_count= tab->query_lock_count= 1; tab->trg_event_map= table->trg_event_map; + tab->for_insert_data= table->for_insert_data; if (my_hash_insert(&m_sptabs, (uchar *)tab)) return FALSE; } @@ -4853,7 +4856,8 @@ sp_head::add_used_tables_to_table_list(THD *thd, TABLE_LIST::PRELOCK_ROUTINE, belong_to_view, stab->trg_event_map, - query_tables_last_ptr); + query_tables_last_ptr, + stab->for_insert_data); tab_buff+= ALIGN_SIZE(sizeof(TABLE_LIST)); result= TRUE; } diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 4bf894798de..4729612f2b0 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -4420,9 +4420,11 @@ add_internal_tables(THD *thd, Query_tables_list *prelocking_ctx, TABLE_LIST *tables) { TABLE_LIST *global_table_list= prelocking_ctx->query_tables; + DBUG_ENTER("add_internal_tables"); do { + DBUG_PRINT("info", ("table name: %s", tables->table_name.str)); /* Skip table if already in the list. Can happen with prepared statements */ @@ -4432,20 +4434,22 @@ add_internal_tables(THD *thd, Query_tables_list *prelocking_ctx, TABLE_LIST *tl= (TABLE_LIST *) thd->alloc(sizeof(TABLE_LIST)); if (!tl) - return TRUE; + DBUG_RETURN(TRUE); tl->init_one_table_for_prelocking(&tables->db, &tables->table_name, NULL, tables->lock_type, TABLE_LIST::PRELOCK_NONE, 0, 0, - &prelocking_ctx->query_tables_last); + &prelocking_ctx->query_tables_last, + tables->for_insert_data); /* Store link to the new table_list that will be used by open so that Item_func_nextval() can find it */ tables->next_local= tl; + DBUG_PRINT("info", ("table name: %s added", tables->table_name.str)); } while ((tables= tables->next_global)); - return FALSE; + DBUG_RETURN(FALSE); } @@ -4476,6 +4480,7 @@ bool DML_prelocking_strategy:: handle_table(THD *thd, Query_tables_list *prelocking_ctx, TABLE_LIST *table_list, bool *need_prelocking) { + DBUG_ENTER("handle_table"); TABLE *table= table_list->table; /* We rely on a caller to check that table is going to be changed. */ DBUG_ASSERT(table_list->lock_type >= TL_WRITE_ALLOW_WRITE || @@ -4506,7 +4511,7 @@ handle_table(THD *thd, Query_tables_list *prelocking_ctx, { if (arena) thd->restore_active_arena(arena, &backup); - return TRUE; + DBUG_RETURN(TRUE); } *need_prelocking= TRUE; @@ -4534,7 +4539,8 @@ handle_table(THD *thd, Query_tables_list *prelocking_ctx, NULL, lock_type, TABLE_LIST::PRELOCK_FK, table_list->belong_to_view, op, - &prelocking_ctx->query_tables_last); + &prelocking_ctx->query_tables_last, + table_list->for_insert_data); } if (arena) thd->restore_active_arena(arena, &backup); @@ -4542,8 +4548,11 @@ handle_table(THD *thd, Query_tables_list *prelocking_ctx, } /* Open any tables used by DEFAULT (like sequence tables) */ + DBUG_PRINT("info", ("table: %p name: %s db: %s flags: %u", + table_list, table_list->table_name.str, + table_list->db.str, table_list->for_insert_data)); if (table->internal_tables && - ((sql_command_flags[thd->lex->sql_command] & CF_INSERTS_DATA) || + (table_list->for_insert_data || thd->lex->default_used)) { Query_arena *arena, backup; @@ -4556,10 +4565,10 @@ handle_table(THD *thd, Query_tables_list *prelocking_ctx, if (unlikely(error)) { *need_prelocking= TRUE; - return TRUE; + DBUG_RETURN(TRUE); } } - return FALSE; + DBUG_RETURN(FALSE); } @@ -4576,7 +4585,7 @@ bool open_and_lock_internal_tables(TABLE *table, bool lock_table) THD *thd= table->in_use; TABLE_LIST *tl; MYSQL_LOCK *save_lock,*new_lock; - DBUG_ENTER("open_internal_tables"); + DBUG_ENTER("open_and_lock_internal_tables"); /* remove pointer to old select_lex which is already destroyed */ for (tl= table->internal_tables ; tl ; tl= tl->next_global) diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 3820ee5923d..8b6b2ca9df0 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -4060,6 +4060,8 @@ public: } bool tvc_finalize(); bool tvc_finalize_derived(); + + void mark_first_table_as_inserting(); }; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index e55f9aab35d..81eba0da8cb 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3282,6 +3282,10 @@ mysql_execute_command(THD *thd) #endif DBUG_ENTER("mysql_execute_command"); + // check that we correctly marked first table for data insertion + DBUG_ASSERT(!(sql_command_flags[lex->sql_command] & CF_INSERTS_DATA) || + first_table->for_insert_data); + DBUG_ASSERT(thd->transaction.stmt.is_empty() || thd->in_sub_stmt); /* Each statement or replication event which might produce deadlock @@ -10200,3 +10204,14 @@ CHARSET_INFO *find_bin_collation(CHARSET_INFO *cs) } return cs; } + +void LEX::mark_first_table_as_inserting() +{ + TABLE_LIST *t= select_lex.table_list.first; + DBUG_ENTER("Query_tables_list::mark_tables_with_important_flags"); + DBUG_ASSERT(sql_command_flags[sql_command] & CF_INSERTS_DATA); + t->for_insert_data= TRUE; + DBUG_PRINT("info", ("table_list: %p name: %s db: %s command: %u", + t, t->table_name.str,t->db.str, sql_command)); + DBUG_VOID_RETURN; +} diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 0bde411a977..98c1e816f31 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -1490,6 +1490,7 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table, privileges of top_view */ tbl->grant.want_privilege= SELECT_ACL; + /* After unfolding the view we lose the list of tables referenced in it (we will have only a list of underlying tables in case of MERGE @@ -1540,6 +1541,18 @@ bool mysql_make_view(THD *thd, TABLE_SHARE *share, TABLE_LIST *table, views with subqueries in select list. */ view_main_select_tables= lex->select_lex.table_list.first; + /* + Mergeable view can be used for inserting, so we move the flag down + */ + if (table->for_insert_data) + { + for (TABLE_LIST *t= view_main_select_tables; + t; + t= t->next_local) + { + t->for_insert_data= TRUE; + } + } /* Let us set proper lock type for tables of the view's main diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 00ab03cba26..235be9b0f89 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -7888,6 +7888,7 @@ alter: MYSQL_YYABORT; Lex->select_lex.db= (Lex->select_lex.table_list.first)->db; Lex->create_last_non_select_table= Lex->last_table(); + Lex->mark_first_table_as_inserting(); } alter_commands { @@ -13459,7 +13460,9 @@ insert: Lex->current_select= &Lex->select_lex; } insert_field_spec opt_insert_update - {} + { + Lex->mark_first_table_as_inserting(); + } ; replace: @@ -13476,7 +13479,9 @@ replace: Lex->current_select= &Lex->select_lex; } insert_field_spec - {} + { + Lex->mark_first_table_as_inserting(); + } ; insert_lock_option: @@ -14859,7 +14864,9 @@ load: opt_xml_rows_identified_by opt_field_term opt_line_term opt_ignore_lines opt_field_or_var_spec opt_load_data_set_spec - {} + { + Lex->mark_first_table_as_inserting(); + } ; data_or_xml: diff --git a/sql/sql_yacc_ora.yy b/sql/sql_yacc_ora.yy index f33ef8cfc68..12ac95dedee 100644 --- a/sql/sql_yacc_ora.yy +++ b/sql/sql_yacc_ora.yy @@ -7825,6 +7825,7 @@ alter: MYSQL_YYABORT; Lex->select_lex.db= (Lex->select_lex.table_list.first)->db; Lex->create_last_non_select_table= Lex->last_table(); + Lex->mark_first_table_as_inserting(); } alter_commands { @@ -13420,7 +13421,9 @@ insert: Lex->current_select= &Lex->select_lex; } insert_field_spec opt_insert_update - {} + { + Lex->mark_first_table_as_inserting(); + } ; replace: @@ -13437,7 +13440,9 @@ replace: Lex->current_select= &Lex->select_lex; } insert_field_spec - {} + { + Lex->mark_first_table_as_inserting(); + } ; insert_lock_option: @@ -14826,7 +14831,9 @@ load: opt_xml_rows_identified_by opt_field_term opt_line_term opt_ignore_lines opt_field_or_var_spec opt_load_data_set_spec - {} + { + Lex->mark_first_table_as_inserting(); + } ; data_or_xml: diff --git a/sql/table.h b/sql/table.h index 494d6628ebe..0a0f0aab77f 100644 --- a/sql/table.h +++ b/sql/table.h @@ -1985,7 +1985,8 @@ struct TABLE_LIST prelocking_types prelocking_type, TABLE_LIST *belong_to_view_arg, uint8 trg_event_map_arg, - TABLE_LIST ***last_ptr) + TABLE_LIST ***last_ptr, + my_bool insert_data) { init_one_table(db_arg, table_name_arg, alias_arg, lock_type_arg); @@ -2000,6 +2001,7 @@ struct TABLE_LIST **last_ptr= this; prev_global= *last_ptr; *last_ptr= &next_global; + for_insert_data= insert_data; } @@ -2411,6 +2413,8 @@ struct TABLE_LIST /* System Versioning */ vers_select_conds_t vers_conditions; + my_bool for_insert_data; + /** @brief Find the bottom in the chain of embedded table VIEWs. |