diff --git a/mysql-test/r/maria.result b/mysql-test/r/maria.result index 031cb894daa..fb8537551c8 100644 --- a/mysql-test/r/maria.result +++ b/mysql-test/r/maria.result @@ -6,6 +6,7 @@ set session storage_engine=maria; set global maria_page_checksum=0; set global maria_log_file_size=4294967295; drop table if exists t1,t2; +drop view if exists v1; SET SQL_WARNINGS=1; CREATE TABLE t1 ( STRING_DATA char(255) default NULL, @@ -2275,3 +2276,11 @@ check table t1; Table Op Msg_type Msg_text test.t1 check status OK drop table t1; +create table t1 (f1 int unique, f2 int) engine=maria; +create table t2 (f3 int, f4 int) engine=maria; +create view v1 as select * from t1, t2 where f1= f3; +insert into t1 values (1,11), (2,22); +insert into v1 (f1) values (3) on duplicate key update f1= f3 + 10; +insert into v1 (f1) values (3) on duplicate key update f1= f3 + 10; +drop table t1,t2; +drop view v1; diff --git a/mysql-test/t/maria.test b/mysql-test/t/maria.test index 0ad4c4d29e1..e35276f698d 100644 --- a/mysql-test/t/maria.test +++ b/mysql-test/t/maria.test @@ -17,6 +17,7 @@ set global maria_log_file_size=4294967295; # Initialise --disable_warnings drop table if exists t1,t2; +drop view if exists v1; --enable_warnings SET SQL_WARNINGS=1; @@ -1559,3 +1560,18 @@ select * from t1 where a is NULL; select * from t1; check table t1; drop table t1; + +# +# Bug39248 INSERT ON DUPLICATE KEY UPDATE gives error if using a view +# Note that this only crashes when using +# --mysqld=--binlog-format=row --ps-protocol +# + +create table t1 (f1 int unique, f2 int) engine=maria; +create table t2 (f3 int, f4 int) engine=maria; +create view v1 as select * from t1, t2 where f1= f3; +insert into t1 values (1,11), (2,22); +insert into v1 (f1) values (3) on duplicate key update f1= f3 + 10; +insert into v1 (f1) values (3) on duplicate key update f1= f3 + 10; +drop table t1,t2; +drop view v1; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 84604706326..d186ae54f7d 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -1191,6 +1191,9 @@ bool mysql_insert(THD *thd,TABLE_LIST *table,List &fields, List &values, List &update_fields, List &update_values, enum_duplicates flag, bool ignore); +void upgrade_lock_type_for_insert(THD *thd, thr_lock_type *lock_type, + enum_duplicates duplic, + bool is_multi_insert); int check_that_all_fields_are_given_values(THD *thd, TABLE *entry, TABLE_LIST *table_list); void prepare_triggers_for_insert_stmt(TABLE *table); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index dbd5c833bd7..34395332118 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -4387,8 +4387,8 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags) /* Also used for indicating that prelocking is need */ TABLE_LIST **query_tables_last_own; bool safe_to_ignore_table; - DBUG_ENTER("open_tables"); + /* temporary mem_root for new .frm parsing. TODO: variables for size diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index a3610385725..8ea912ac13f 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -387,10 +387,9 @@ void prepare_triggers_for_insert_stmt(TABLE *table) downgrade the lock in handler::store_lock() method. */ -static -void upgrade_lock_type(THD *thd, thr_lock_type *lock_type, - enum_duplicates duplic, - bool is_multi_insert) +void upgrade_lock_type_for_insert(THD *thd, thr_lock_type *lock_type, + enum_duplicates duplic, + bool is_multi_insert) { if (duplic == DUP_UPDATE || duplic == DUP_REPLACE && *lock_type == TL_WRITE_CONCURRENT_INSERT) @@ -587,8 +586,8 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, Upgrade lock type if the requested lock is incompatible with the current connection mode or table operation. */ - upgrade_lock_type(thd, &table_list->lock_type, duplic, - values_list.elements > 1); + upgrade_lock_type_for_insert(thd, &table_list->lock_type, duplic, + values_list.elements > 1); /* We can't write-delayed into a table locked with LOCK TABLES: diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index a1cdd0742d3..233dcefa4e0 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1068,6 +1068,8 @@ static bool mysql_test_insert(Prepared_statement *stmt, if (insert_precheck(thd, table_list)) goto error; + upgrade_lock_type_for_insert(thd, &table_list->lock_type, duplic, + values_list.elements > 1); /* open temporary memory pool for temporary data allocated by derived tables & preparation procedure diff --git a/sql/sql_view.cc b/sql/sql_view.cc index a654721de37..1761a7b1957 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -1021,7 +1021,6 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table, bool parse_status; bool result, view_is_mergeable; TABLE_LIST *view_main_select_tables; - DBUG_ENTER("mysql_make_view"); DBUG_PRINT("info", ("table: 0x%lx (%s)", (ulong) table, table->table_name));