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;
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;
......@@ -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;
......@@ -1191,6 +1191,9 @@ bool mysql_insert(THD *thd,TABLE_LIST *table,List<Item> &fields,
List<List_item> &values, List<Item> &update_fields,
List<Item> &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);
......
......@@ -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
......
......@@ -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:
......
......@@ -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
......
......@@ -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));
......
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