Commit 2a9d33f0 authored by Michael Widenius's avatar Michael Widenius

Fixed for Bug #39248 Maria: INSERT ON DUPLICATE KEY UPDATE gives error if using a view

The bug was that prepared statements didn't downgrade TL_WRITE_CONCURRENT properly

mysql-test/r/maria.result:
  Added test case
mysql-test/t/maria.test:
  Added test case
sql/mysql_priv.h:
  Make upgrade_lock_type() global
sql/sql_base.cc:
  Fixed indentation
sql/sql_insert.cc:
  Make upgrade_lock_type() global
sql/sql_prepare.cc:
  Call upgrade_lock_type_for_insert() to get right lock to use
sql/sql_view.cc:
  Indentation fix
parent be0b4042
...@@ -6,6 +6,7 @@ set session storage_engine=maria; ...@@ -6,6 +6,7 @@ set session storage_engine=maria;
set global maria_page_checksum=0; set global maria_page_checksum=0;
set global maria_log_file_size=4294967295; set global maria_log_file_size=4294967295;
drop table if exists t1,t2; drop table if exists t1,t2;
drop view if exists v1;
SET SQL_WARNINGS=1; SET SQL_WARNINGS=1;
CREATE TABLE t1 ( CREATE TABLE t1 (
STRING_DATA char(255) default NULL, STRING_DATA char(255) default NULL,
...@@ -2275,3 +2276,11 @@ check table t1; ...@@ -2275,3 +2276,11 @@ check table t1;
Table Op Msg_type Msg_text Table Op Msg_type Msg_text
test.t1 check status OK test.t1 check status OK
drop table t1; 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;
...@@ -17,6 +17,7 @@ set global maria_log_file_size=4294967295; ...@@ -17,6 +17,7 @@ set global maria_log_file_size=4294967295;
# Initialise # Initialise
--disable_warnings --disable_warnings
drop table if exists t1,t2; drop table if exists t1,t2;
drop view if exists v1;
--enable_warnings --enable_warnings
SET SQL_WARNINGS=1; SET SQL_WARNINGS=1;
...@@ -1559,3 +1560,18 @@ select * from t1 where a is NULL; ...@@ -1559,3 +1560,18 @@ select * from t1 where a is NULL;
select * from t1; select * from t1;
check table t1; check table t1;
drop 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;
...@@ -1191,6 +1191,9 @@ bool mysql_insert(THD *thd,TABLE_LIST *table,List<Item> &fields, ...@@ -1191,6 +1191,9 @@ bool mysql_insert(THD *thd,TABLE_LIST *table,List<Item> &fields,
List<List_item> &values, List<Item> &update_fields, List<List_item> &values, List<Item> &update_fields,
List<Item> &update_values, enum_duplicates flag, List<Item> &update_values, enum_duplicates flag,
bool ignore); 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, int check_that_all_fields_are_given_values(THD *thd, TABLE *entry,
TABLE_LIST *table_list); TABLE_LIST *table_list);
void prepare_triggers_for_insert_stmt(TABLE *table); void prepare_triggers_for_insert_stmt(TABLE *table);
......
...@@ -4387,8 +4387,8 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags) ...@@ -4387,8 +4387,8 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
/* Also used for indicating that prelocking is need */ /* Also used for indicating that prelocking is need */
TABLE_LIST **query_tables_last_own; TABLE_LIST **query_tables_last_own;
bool safe_to_ignore_table; bool safe_to_ignore_table;
DBUG_ENTER("open_tables"); DBUG_ENTER("open_tables");
/* /*
temporary mem_root for new .frm parsing. temporary mem_root for new .frm parsing.
TODO: variables for size TODO: variables for size
......
...@@ -387,10 +387,9 @@ void prepare_triggers_for_insert_stmt(TABLE *table) ...@@ -387,10 +387,9 @@ void prepare_triggers_for_insert_stmt(TABLE *table)
downgrade the lock in handler::store_lock() method. downgrade the lock in handler::store_lock() method.
*/ */
static void upgrade_lock_type_for_insert(THD *thd, thr_lock_type *lock_type,
void upgrade_lock_type(THD *thd, thr_lock_type *lock_type, enum_duplicates duplic,
enum_duplicates duplic, bool is_multi_insert)
bool is_multi_insert)
{ {
if (duplic == DUP_UPDATE || if (duplic == DUP_UPDATE ||
duplic == DUP_REPLACE && *lock_type == TL_WRITE_CONCURRENT_INSERT) duplic == DUP_REPLACE && *lock_type == TL_WRITE_CONCURRENT_INSERT)
...@@ -587,8 +586,8 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, ...@@ -587,8 +586,8 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
Upgrade lock type if the requested lock is incompatible with Upgrade lock type if the requested lock is incompatible with
the current connection mode or table operation. the current connection mode or table operation.
*/ */
upgrade_lock_type(thd, &table_list->lock_type, duplic, upgrade_lock_type_for_insert(thd, &table_list->lock_type, duplic,
values_list.elements > 1); values_list.elements > 1);
/* /*
We can't write-delayed into a table locked with LOCK TABLES: We can't write-delayed into a table locked with LOCK TABLES:
......
...@@ -1068,6 +1068,8 @@ static bool mysql_test_insert(Prepared_statement *stmt, ...@@ -1068,6 +1068,8 @@ static bool mysql_test_insert(Prepared_statement *stmt,
if (insert_precheck(thd, table_list)) if (insert_precheck(thd, table_list))
goto error; 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 open temporary memory pool for temporary data allocated by derived
tables & preparation procedure tables & preparation procedure
......
...@@ -1021,7 +1021,6 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table, ...@@ -1021,7 +1021,6 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table,
bool parse_status; bool parse_status;
bool result, view_is_mergeable; bool result, view_is_mergeable;
TABLE_LIST *view_main_select_tables; TABLE_LIST *view_main_select_tables;
DBUG_ENTER("mysql_make_view"); DBUG_ENTER("mysql_make_view");
DBUG_PRINT("info", ("table: 0x%lx (%s)", (ulong) table, table->table_name)); DBUG_PRINT("info", ("table: 0x%lx (%s)", (ulong) table, table->table_name));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment