List:Maria Storage Engine« Previous MessageNext Message »
From:Guilhem Bichot Date:July 10 2008 9:36am
Subject:bzr commit into MySQL/Maria:mysql-maria branch (guilhem:2661)
View as plain text  
#At bzr+ssh://bk-internal.mysql.com/bzrroot/server/mysql-maria/

 2661 Guilhem Bichot	2008-07-10
      Fix for bug: INSERT SELECT ON DUPLICATE KEY UPDATE and LOAD DATA CONCURRENT REPLACE
      used TL_WRITE_CONCURRENT_INSERT though they may update/delete a row.
modified:
  mysql-test/r/maria2.result
  mysql-test/t/maria2.test
  sql/sql_parse.cc
  storage/maria/ha_maria.cc

per-file messages:
  mysql-test/r/maria2.result
    result. Without the code fix, the assertion added to ha_maria::update_row() would fire twice.
  mysql-test/t/maria2.test
    test when INSERT ON DUPLICATE KEY UPDATE and LOAD DATA INFILE REPLACE do update rows
  sql/sql_parse.cc
    INSERT SELECT ON DUPLICATE KEY UPDATE and LOAD DATA CONCURRENT REPLACE should not use TL_WRITE_CONCURRENT_INSERT,
    because they may update/delete a row. REPLACE (see sql_yacc.yy), and INSERT VALUES ON DUPLICATE KEY UPDATE
    (see upgrade_lock_type()) were already fine.
  storage/maria/ha_maria.cc
    TL_WRITE_LOW_PRIORITY is ok for bulk-insert-repair too.
    Assert that update_row and delete_row never see TL_WRITE_CONCURRENT_INSERT.
=== modified file 'mysql-test/r/maria2.result'
--- a/mysql-test/r/maria2.result	2008-06-10 14:44:44 +0000
+++ b/mysql-test/r/maria2.result	2008-07-10 09:36:48 +0000
@@ -16,3 +16,19 @@ check table t1 extended;
 Table	Op	Msg_type	Msg_text
 test.t1	check	status	OK
 drop table t1;
+create table t1(id int, s char(1), unique(s)) engine=maria;
+insert into t1 values(1,"a") on duplicate key update t1.id=t1.id+1;
+insert into t1 values(1,"a") on duplicate key update t1.id=t1.id+1;
+insert into t1 select 1,"a" on duplicate key update t1.id=t1.id+1;
+select * from t1;
+id	s
+3	a
+drop table t1;
+create table t1 (pk int primary key, apk int unique, data int) engine=maria;
+insert into t1 values (1, 1, 1), (4, 4, 4), (6, 6, 6);
+load data concurrent infile '../std_data_ln/loaddata5.dat' replace into table t1 fields terminated by '' enclosed by '' ignore 1 lines (pk, apk);
+select * from t1 order by pk;
+pk	apk	data
+1	1	1
+3	4	NULL
+5	6	NULL

=== modified file 'mysql-test/t/maria2.test'
--- a/mysql-test/t/maria2.test	2008-06-10 14:44:44 +0000
+++ b/mysql-test/t/maria2.test	2008-07-10 09:36:48 +0000
@@ -64,3 +64,17 @@ select count(*) from t1;
 select name from t1;
 check table t1 extended;
 drop table t1;
+
+# test INSERT ON DUPLICATE KEY UPDATE
+create table t1(id int, s char(1), unique(s)) engine=maria;
+insert into t1 values(1,"a") on duplicate key update t1.id=t1.id+1;
+insert into t1 values(1,"a") on duplicate key update t1.id=t1.id+1;
+insert into t1 select 1,"a" on duplicate key update t1.id=t1.id+1;
+select * from t1;
+drop table t1;
+
+# test LOAD DATA INFILE REPLACE
+create table t1 (pk int primary key, apk int unique, data int) engine=maria;
+insert into t1 values (1, 1, 1), (4, 4, 4), (6, 6, 6);
+load data concurrent infile '../std_data_ln/loaddata5.dat' replace into table t1 fields terminated by '' enclosed by '' ignore 1 lines (pk, apk);
+select * from t1 order by pk;

=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc	2008-07-09 20:47:46 +0000
+++ b/sql/sql_parse.cc	2008-07-10 09:36:48 +0000
@@ -2978,6 +2978,9 @@ end_with_restore_list:
     /* Fix lock for first table */
     if (first_table->lock_type == TL_WRITE_DELAYED)
       first_table->lock_type= TL_WRITE;
+    else if ((first_table->lock_type == TL_WRITE_CONCURRENT_INSERT) &&
+             (lex->duplicates == DUP_UPDATE))
+      first_table->lock_type= TL_WRITE_DEFAULT;
 
     /* Don't unlock tables until command is written to binary log */
     select_lex->options|= SELECT_NO_UNLOCK;
@@ -3233,6 +3236,10 @@ end_with_restore_list:
     if (check_one_table_access(thd, privilege, all_tables))
       goto error;
 
+    if ((first_table->lock_type == TL_WRITE_CONCURRENT_INSERT) &&
+        (lex->duplicates == DUP_REPLACE))
+      first_table->lock_type= TL_WRITE_DEFAULT;
+
     res= mysql_load(thd, lex->exchange, first_table, lex->field_list,
                     lex->update_list, lex->value_list, lex->duplicates,
                     lex->ignore, (bool) lex->local_file);

=== modified file 'storage/maria/ha_maria.cc'
--- a/storage/maria/ha_maria.cc	2008-07-09 20:47:46 +0000
+++ b/storage/maria/ha_maria.cc	2008-07-10 09:36:48 +0000
@@ -1817,7 +1817,7 @@ void ha_maria::start_bulk_insert(ha_rows
     */
     if (file->state->records == 0 && can_enable_indexes &&
         (!rows || rows >= MARIA_MIN_ROWS_TO_DISABLE_INDEXES) &&
-        (file->lock.type == TL_WRITE))
+        (file->lock.type >= TL_WRITE_LOW_PRIORITY))
     {
       /**
          @todo for a single-row INSERT SELECT, we will go into repair, which
@@ -1961,6 +1961,7 @@ bool ha_maria::is_crashed() const
 
 int ha_maria::update_row(const uchar * old_data, uchar * new_data)
 {
+  DBUG_ASSERT(file->lock.type != TL_WRITE_CONCURRENT_INSERT);
   ha_statistic_increment(&SSV::ha_update_count);
   if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
     table->timestamp_field->set_time();
@@ -1970,6 +1971,7 @@ int ha_maria::update_row(const uchar * o
 
 int ha_maria::delete_row(const uchar * buf)
 {
+  DBUG_ASSERT(file->lock.type != TL_WRITE_CONCURRENT_INSERT);
   ha_statistic_increment(&SSV::ha_delete_count);
   return maria_delete(file, buf);
 }

Thread
bzr commit into MySQL/Maria:mysql-maria branch (guilhem:2661) Guilhem Bichot10 Jul
  • Re: bzr commit into MySQL/Maria:mysql-maria branch (guilhem:2661)Sergei Golubchik10 Jul
    • Re: bzr commit into MySQL/Maria:mysql-maria branch (guilhem:2661)Guilhem Bichot10 Jul