List:Maria Storage Engine« Previous MessageNext Message »
From:Michael Widenius Date:December 27 2008 2:05am
Subject:bzr commit into MySQL/Maria:mysql-maria branch (monty:2714)
View as plain text  
#At bzr+ssh://bk-internal.mysql.com/bzrroot/server/mysql-maria/

 2714 Michael Widenius	2008-12-27
      Fixed bugs found by pushbuild
      Added code to detect and give error when doing an insert into a view where we accessed fields in a not yet read table
      Disabled test in subselect.test as the CHECK_OPTION for views doesn't work for insert.
      This needs to be fixed properly later.
      
      The problem with views are described in Bug #41760 Inserting into multiple-table views is not working
modified:
  mysql-test/r/insert.result
  mysql-test/r/subselect.result
  mysql-test/suite/maria/r/maria.result
  mysql-test/suite/maria/t/maria.test
  mysql-test/t/insert.test
  mysql-test/t/subselect.test
  sql/sql_insert.cc
  storage/maria/ma_blockrec.c
  storage/maria/ma_check.c
  storage/maria/ma_pagecache.c
  storage/maria/ma_state.c
  storage/maria/maria_read_log.c

per-file messages:
  mysql-test/r/insert.result
    Fixed wrong usage of insert into view.
  mysql-test/r/subselect.result
    Disabled wrong test (temporary)
  mysql-test/suite/maria/r/maria.result
    Added test of size of table
  mysql-test/suite/maria/t/maria.test
    Added test of size of table
  mysql-test/t/insert.test
    Fixed wrong usage of insert into view
    The bug is that during insert/update we currently don't read any of the referenced tables of the view.
    This means that we can't get a value from another table to use as part of the update.
  mysql-test/t/subselect.test
    Disabled not working test until someone has time to fix insert into view properly
    Here we where refering to last used value in t2, which is wrong.
  sql/sql_insert.cc
    Detect if we are trying to update one table in a view based on value in another, not yet read, table.
    This fixes the problem discovered in insert.test
  storage/maria/ma_blockrec.c
    Don't ignore not critical changes to the last page in the table.
    We need to write the last page as otherwise we can during aborting of a row with a duplicate key get
    state.data_file_length and the real length of file out of sync
  storage/maria/ma_check.c
    Flush the page cache even if we got an error during zerofill.
    (This fixes a call to assert() in case of a too short data file)
  storage/maria/ma_pagecache.c
    Mark page as read when we do a write of a full page.
    This fixes a bug when we got an error during read and then used direct write to page to update it
  storage/maria/ma_state.c
    Restore info->lock.type after call to maria_versioning.
    Fixed crash in maria_recover.test
  storage/maria/maria_read_log.c
    Don't write thread id in debug log. (Not needed as maria_read_log is a single treaded program)
=== modified file 'mysql-test/r/insert.result'
--- a/mysql-test/r/insert.result	2007-12-01 12:46:01 +0000
+++ b/mysql-test/r/insert.result	2008-12-27 02:05:16 +0000
@@ -355,17 +355,17 @@ insert into t2 values (1,12), (2,24);
 insert into v1 (f1) values (3) on duplicate key update f3= f3 + 10;
 ERROR HY000: Can not modify more than one base table through a join view 'test.v1'
 insert into v1 (f1) values (3) on duplicate key update f1= f3 + 10;
+ERROR HY000: Can not modify more than one base table through a join view 'test.v1'
 select * from t1;
 f1	f2
 1	11
 2	22
-3	NULL
 insert into v1 (f1) values (3) on duplicate key update f1= f3 + 10;
+ERROR HY000: Can not modify more than one base table through a join view 'test.v1'
 select * from t1;
 f1	f2
 1	11
 2	22
-12	NULL
 drop view v1;
 drop table t1,t2;
 create table t1 (id int primary key auto_increment, data int, unique(data));

=== modified file 'mysql-test/r/subselect.result'
--- a/mysql-test/r/subselect.result	2008-12-10 09:02:25 +0000
+++ b/mysql-test/r/subselect.result	2008-12-27 02:05:16 +0000
@@ -4463,15 +4463,12 @@ SELECT t2.id, t2.c AS c FROM t1, t2
 WHERE t1.id=t2.id AND 1 IN (SELECT id FROM t1) WITH CHECK OPTION;
 INSERT INTO v2(a,b) VALUES (2,2);
 ERROR HY000: CHECK OPTION failed 'test.v2'
-INSERT INTO v2(a,b) VALUES (1,2);
 SELECT * FROM v1;
 c
 1
 1
 1
 1
-2
-2
 CREATE VIEW v3 AS
 SELECT t2.c AS c FROM t2
 WHERE 1 IN (SELECT id FROM t1) WITH CHECK OPTION;

=== modified file 'mysql-test/suite/maria/r/maria.result'
--- a/mysql-test/suite/maria/r/maria.result	2008-12-22 00:17:37 +0000
+++ b/mysql-test/suite/maria/r/maria.result	2008-12-27 02:05:16 +0000
@@ -2589,4 +2589,7 @@ Warnings:
 Warning	1265	Data truncated for column 'c' at row 1
 insert into t1 values(1,repeat('a',100), repeat('b',657860));
 ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
+check table t1;
+Table	Op	Msg_type	Msg_text
+test.t1	check	status	OK
 drop table t1;

=== modified file 'mysql-test/suite/maria/t/maria.test'
--- a/mysql-test/suite/maria/t/maria.test	2008-12-22 00:17:37 +0000
+++ b/mysql-test/suite/maria/t/maria.test	2008-12-27 02:05:16 +0000
@@ -1855,6 +1855,7 @@ create table t1(a int primary key, b blo
 insert into t1 values(1,repeat('a',100), repeat('b',657860));
 --error ER_DUP_ENTRY
 insert into t1 values(1,repeat('a',100), repeat('b',657860));
+check table t1;
 drop table t1;
 
 # Set defaults back

=== modified file 'mysql-test/t/insert.test'
--- a/mysql-test/t/insert.test	2007-12-02 11:18:27 +0000
+++ b/mysql-test/t/insert.test	2008-12-27 02:05:16 +0000
@@ -235,8 +235,10 @@ insert into t1 values (1,11), (2,22);
 insert into t2 values (1,12), (2,24);
 --error 1393
 insert into v1 (f1) values (3) on duplicate key update f3= f3 + 10;
+--error 1393
 insert into v1 (f1) values (3) on duplicate key update f1= f3 + 10;
 select * from t1;
+--error 1393
 insert into v1 (f1) values (3) on duplicate key update f1= f3 + 10;
 select * from t1;
 drop view v1;

=== modified file 'mysql-test/t/subselect.test'
--- a/mysql-test/t/subselect.test	2008-12-10 09:02:25 +0000
+++ b/mysql-test/t/subselect.test	2008-12-27 02:05:16 +0000
@@ -3379,7 +3379,11 @@ CREATE VIEW v2 (a,b) AS
 
 --error 1369
 INSERT INTO v2(a,b) VALUES (2,2);
+
+# disabled for now as this refers to old content of t2
+--disable_parsing
 INSERT INTO v2(a,b) VALUES (1,2);
+--enable_parsing
 SELECT * FROM v1;
 
 CREATE VIEW v3 AS

=== modified file 'sql/sql_insert.cc'
--- a/sql/sql_insert.cc	2008-12-03 04:07:50 +0000
+++ b/sql/sql_insert.cc	2008-12-27 02:05:16 +0000
@@ -107,8 +107,8 @@ static bool check_view_insertability(THD
     1   Error
 */
 
-bool check_view_single_update(List<Item> &fields, TABLE_LIST *view,
-                              table_map *map)
+bool check_view_single_update(List<Item> &fields, List<Item> &values,
+                              TABLE_LIST *view, table_map *map)
 {
   /* it is join view => we need to find the table for update */
   List_iterator_fast<Item> it(fields);
@@ -119,6 +119,10 @@ bool check_view_single_update(List<Item>
   while ((item= it++))
     tables|= item->used_tables();
 
+  it.init(values);
+  while ((item= it++))
+    tables|= item->used_tables();
+
   /* Check found map against provided map */
   if (*map)
   {
@@ -238,7 +242,7 @@ static int check_insert_fields(THD *thd,
 
     if (table_list->effective_algorithm == VIEW_ALGORITHM_MERGE)
     {
-      if (check_view_single_update(fields, table_list, map))
+      if (check_view_single_update(fields, values, table_list, map))
         return -1;
       table= table_list->table;
     }
@@ -298,7 +302,8 @@ static int check_insert_fields(THD *thd,
 */
 
 static int check_update_fields(THD *thd, TABLE_LIST *insert_table_list,
-                               List<Item> &update_fields, table_map *map)
+                               List<Item> &update_fields,
+                               List<Item> &update_values, table_map *map)
 {
   TABLE *table= insert_table_list->table;
   my_bool timestamp_mark;
@@ -320,7 +325,8 @@ static int check_update_fields(THD *thd,
     return -1;
 
   if (insert_table_list->effective_algorithm == VIEW_ALGORITHM_MERGE &&
-      check_view_single_update(update_fields, insert_table_list, map))
+      check_view_single_update(update_fields, update_values, insert_table_list,
+                               map))
     return -1;
 
   if (table->timestamp_field)
@@ -1246,7 +1252,8 @@ bool mysql_prepare_insert(THD *thd, TABL
     if (!res && duplic == DUP_UPDATE)
     {
       select_lex->no_wrap_view_item= TRUE;
-      res= check_update_fields(thd, context->table_list, update_fields, &map);
+      res= check_update_fields(thd, context->table_list, update_fields,
+                               update_values, &map);
       select_lex->no_wrap_view_item= FALSE;
     }
 
@@ -2912,7 +2919,8 @@ select_insert::prepare(List<Item> &value
 
     lex->select_lex.no_wrap_view_item= TRUE;
     res= res || check_update_fields(thd, context->table_list,
-                                    *info.update_fields, &map);
+                                    *info.update_fields, *info.update_values,
+                                    &map);
     lex->select_lex.no_wrap_view_item= FALSE;
     /*
       When we are not using GROUP BY and there are no ungrouped aggregate functions 
@@ -3580,7 +3588,7 @@ select_create::prepare(List<Item> &value
     DBUG_RETURN(-1);
   }
 
- /* First field to copy */
+  /* First field to copy */
   field= table->field+table->s->fields - values.elements;
 
   /* Mark all fields that are given values */

=== modified file 'storage/maria/ma_blockrec.c'
--- a/storage/maria/ma_blockrec.c	2008-12-22 00:17:37 +0000
+++ b/storage/maria/ma_blockrec.c	2008-12-27 02:05:16 +0000
@@ -2408,11 +2408,22 @@ static my_bool free_full_page_range(MARI
                                     uint count)
 {
   my_bool res= 0;
+  uint delete_count;
   MARIA_SHARE *share= info->s;
   DBUG_ENTER("free_full_page_range");
 
+  delete_count= count;
+  if (share->state.state.data_file_length ==
+      (page + count) * share->block_size)
+  {
+    /*
+      Don't delete last page from pagecache as this will make the file
+      shorter than expected if the last operation extended the file
+    */
+    delete_count--;
+  }
   if (pagecache_delete_pages(share->pagecache, &info->dfile,
-                             page, count, PAGECACHE_LOCK_WRITE, 0))
+                             page, delete_count, PAGECACHE_LOCK_WRITE, 0))
     res= 1;
 
   if (share->now_transactional)

=== modified file 'storage/maria/ma_check.c'
--- a/storage/maria/ma_check.c	2008-10-15 10:46:40 +0000
+++ b/storage/maria/ma_check.c	2008-12-27 02:05:16 +0000
@@ -3249,7 +3249,7 @@ static my_bool maria_zerofill_data(HA_CH
   pgcache_page_no_t page;
   uint block_size= share->block_size;
   MARIA_FILE_BITMAP *bitmap= &share->bitmap;
-  my_bool zero_lsn= !(param->testflag & T_ZEROFILL_KEEP_LSN);
+  my_bool zero_lsn= !(param->testflag & T_ZEROFILL_KEEP_LSN), error;
   DBUG_ENTER("maria_zerofill_data");
 
   /* This works only with BLOCK_RECORD files */
@@ -3344,15 +3344,22 @@ static my_bool maria_zerofill_data(HA_CH
                              PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
                              LSN_IMPOSSIBLE, 1, FALSE);
   }
-  DBUG_RETURN(_ma_bitmap_flush(share) ||
-              flush_pagecache_blocks(share->pagecache, &info->dfile,
-                                     FLUSH_FORCE_WRITE));
+  error= _ma_bitmap_flush(share);
+  if (flush_pagecache_blocks(share->pagecache, &info->dfile,
+                             FLUSH_FORCE_WRITE))
+    error= 1;
+  DBUG_RETURN(error);
 
 err:
   pagecache_unlock_by_link(share->pagecache, page_link.link,
                            PAGECACHE_LOCK_WRITE_UNLOCK,
                            PAGECACHE_UNPIN, LSN_IMPOSSIBLE,
                            LSN_IMPOSSIBLE, 0, FALSE);
+  /* flush what was changed so far */
+  (void) _ma_bitmap_flush(share);
+  (void) flush_pagecache_blocks(share->pagecache, &info->dfile,
+                                FLUSH_FORCE_WRITE);
+
   DBUG_RETURN(1);
 }
 

=== modified file 'storage/maria/ma_pagecache.c'
--- a/storage/maria/ma_pagecache.c	2008-11-24 07:48:21 +0000
+++ b/storage/maria/ma_pagecache.c	2008-12-27 02:05:16 +0000
@@ -2974,7 +2974,11 @@ void pagecache_unlock_by_link(PAGECACHE 
     }
     if (lsn != LSN_IMPOSSIBLE)
       check_and_set_lsn(pagecache, lsn, block);
-    block->status&= ~PCBLOCK_ERROR;
+    /*
+      Reset error flag. Mark also that page is active; This may not have
+      been the case if there was an error reading the page
+    */
+    block->status= (block->status & ~PCBLOCK_ERROR) | PCBLOCK_READ;
   }
 
   /* if we lock for write we must link the block to changed blocks */

=== modified file 'storage/maria/ma_state.c'
--- a/storage/maria/ma_state.c	2008-12-22 00:17:37 +0000
+++ b/storage/maria/ma_state.c	2008-12-27 02:05:16 +0000
@@ -616,10 +616,14 @@ void maria_versioning(MARIA_HA *info, my
   /* For now, this is a hack */
   if (info->s->have_versioning)
   {
+    enum thr_lock_type save_lock_type;
     /* Assume is a non threaded application (for now) */
     info->s->lock_key_trees= 0;
+    /* Set up info->lock.type temporary for _ma_block_get_status() */
+    save_lock_type= info->lock.type;
     info->lock.type= versioning ? TL_WRITE_CONCURRENT_INSERT : TL_WRITE;
     _ma_block_get_status((void*) info, versioning);
+    info->lock.type= save_lock_type;
   }
 }
 

=== modified file 'storage/maria/maria_read_log.c'
--- a/storage/maria/maria_read_log.c	2008-05-29 18:39:25 +0000
+++ b/storage/maria/maria_read_log.c	2008-12-27 02:05:16 +0000
@@ -23,9 +23,9 @@ static const char *load_default_groups[]
 static void get_options(int *argc,char * * *argv);
 #ifndef DBUG_OFF
 #if defined(__WIN__)
-const char *default_dbug_option= "d:t:i:O,\\maria_read_log.trace";
+const char *default_dbug_option= "d:t:O,\\maria_read_log.trace";
 #else
-const char *default_dbug_option= "d:t:i:o,/tmp/maria_read_log.trace";
+const char *default_dbug_option= "d:t:o,/tmp/maria_read_log.trace";
 #endif
 #endif /* DBUG_OFF */
 static my_bool opt_display_only, opt_apply, opt_apply_undo, opt_silent;

Thread
bzr commit into MySQL/Maria:mysql-maria branch (monty:2714) Michael Widenius27 Dec