#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 Widenius | 27 Dec |