From 7dc83c50436a36280e99f9c71006b05452d0b9fe Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Fri, 9 Jan 2009 06:11:37 +0200 Subject: [PATCH] Fixed bugs from my latest patch found by pushbuild: Bug #41962 Maria: view-related test failures (insert, view, maria, trigger tests) Added error handling for wrong update of view. See Bug #41760 Inserting into multiple-table views is not working mysql-test/r/delayed.result: Fixed test as we are now testing values before fields. Added new tests to test all error combinations mysql-test/suite/maria/r/maria.result: Added error handling for not supported update of view. mysql-test/suite/maria/t/maria.test: Added error handling for not supported update of view. mysql-test/t/delayed.test: Fixed test as we are now testing values before fields. Added new tests to test all error combinations sql/sql_base.cc: Fixed warning from valgrind sql/sql_insert.cc: Don't test from which table values are in case of INSERT ... SELECT Run fix_fields() in values before we do it on fields. This is needed becasue check_view_single_update() are accessing values. storage/maria/ma_blockrec.c: Don't call pagecache_delete_pages() if no pages to delete. This fixes a DBUG_ASSERT() error in maria_test_recovery --- mysql-test/r/delayed.result | 6 +++- mysql-test/suite/maria/r/maria.result | 2 ++ mysql-test/suite/maria/t/maria.test | 2 ++ mysql-test/t/delayed.test | 6 +++- sql/sql_base.cc | 5 ++- sql/sql_insert.cc | 50 +++++++++++++++++---------- storage/maria/ma_blockrec.c | 3 +- 7 files changed, 52 insertions(+), 22 deletions(-) diff --git a/mysql-test/r/delayed.result b/mysql-test/r/delayed.result index bcda6ddb6ab..65b358615cf 100644 --- a/mysql-test/r/delayed.result +++ b/mysql-test/r/delayed.result @@ -251,8 +251,12 @@ HEX(a) 1 DROP TABLE t1; CREATE TABLE t1 (a INT); -INSERT DELAYED INTO t1 SET b= b(); +INSERT DELAYED INTO t1 SET a= b(); +ERROR 42000: FUNCTION test.b does not exist +INSERT DELAYED INTO t1 SET b= 1; ERROR 42S22: Unknown column 'b' in 'field list' +INSERT DELAYED INTO t1 SET b= b(); +ERROR 42000: FUNCTION test.b does not exist DROP TABLE t1; End of 5.0 tests DROP TABLE IF EXISTS t1,t2; diff --git a/mysql-test/suite/maria/r/maria.result b/mysql-test/suite/maria/r/maria.result index cbda2313c73..c406efd4112 100644 --- a/mysql-test/suite/maria/r/maria.result +++ b/mysql-test/suite/maria/r/maria.result @@ -2568,7 +2568,9 @@ 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; +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' drop table t1,t2; drop view v1; CREATE TABLE t1 (id int, c varchar(10)) engine=maria; diff --git a/mysql-test/suite/maria/t/maria.test b/mysql-test/suite/maria/t/maria.test index 637b4c82db9..eddccc88b7c 100644 --- a/mysql-test/suite/maria/t/maria.test +++ b/mysql-test/suite/maria/t/maria.test @@ -1820,7 +1820,9 @@ 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); +--error 1393 insert into v1 (f1) values (3) on duplicate key update f1= f3 + 10; +--error 1393 insert into v1 (f1) values (3) on duplicate key update f1= f3 + 10; drop table t1,t2; drop view v1; diff --git a/mysql-test/t/delayed.test b/mysql-test/t/delayed.test index 9c7e825bc30..87d6ab55ee5 100644 --- a/mysql-test/t/delayed.test +++ b/mysql-test/t/delayed.test @@ -256,7 +256,11 @@ DROP TABLE t1; # Bug #32676: insert delayed crash with wrong column and function specified # CREATE TABLE t1 (a INT); ---error ER_BAD_FIELD_ERROR +--error ER_SP_DOES_NOT_EXIST +INSERT DELAYED INTO t1 SET a= b(); +--error ER_BAD_FIELD_ERROR +INSERT DELAYED INTO t1 SET b= 1; +--error ER_SP_DOES_NOT_EXIST INSERT DELAYED INTO t1 SET b= b(); DROP TABLE t1; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 52a633da4ac..4affca4434d 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -7342,7 +7342,10 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List &fields, /* make * substituting permanent */ SELECT_LEX *select_lex= thd->lex->current_select; select_lex->with_wild= 0; - select_lex->item_list= fields; +#ifdef HAVE_purify + if (&select_lex->item_list != &fields) // Avoid warning +#endif + select_lex->item_list= fields; thd->restore_active_arena(arena, &backup); } diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index b3a74b15652..175358140e1 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -88,6 +88,7 @@ static bool check_view_insertability(THD *thd, TABLE_LIST *view); SYNOPSIS check_view_single_update() fields The insert/update fields to be checked. + values Values to use for update view The view for insert. map [in/out] The insert table map. @@ -107,7 +108,7 @@ static bool check_view_insertability(THD *thd, TABLE_LIST *view); 1 Error */ -bool check_view_single_update(List &fields, List &values, +bool check_view_single_update(List &fields, List *values, TABLE_LIST *view, table_map *map) { /* it is join view => we need to find the table for update */ @@ -119,10 +120,15 @@ bool check_view_single_update(List &fields, List &values, while ((item= it++)) tables|= item->used_tables(); - it.init(values); - while ((item= it++)) - tables|= item->used_tables(); + if (values) + { + it.init(*values); + while ((item= it++)) + tables|= item->used_tables(); + } + /* Convert to real table bits */ + tables&= ~PSEUDO_TABLE_BITS; /* Check found map against provided map */ if (*map) { @@ -156,6 +162,10 @@ error: fields The insert fields. values The insert values. check_unique If duplicate values should be rejected. + fields_and_values_from_different_maps + Set to 1 if fields and values are using + different table maps, like on select ... insert + map Store here table map for used fields NOTE Clears TIMESTAMP_AUTO_SET_ON_INSERT from table->timestamp_field_type @@ -169,7 +179,9 @@ error: static int check_insert_fields(THD *thd, TABLE_LIST *table_list, List &fields, List &values, - bool check_unique, table_map *map) + bool check_unique, + bool fields_and_values_from_different_maps, + table_map *map) { TABLE *table= table_list->table; @@ -242,7 +254,10 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list, if (table_list->effective_algorithm == VIEW_ALGORITHM_MERGE) { - if (check_view_single_update(fields, values, table_list, map)) + if (check_view_single_update(fields, + fields_and_values_from_different_maps ? + (List*) 0 : &values, + table_list, map)) return -1; table= table_list->table; } @@ -325,8 +340,8 @@ static int check_update_fields(THD *thd, TABLE_LIST *insert_table_list, return -1; if (insert_table_list->effective_algorithm == VIEW_ALGORITHM_MERGE && - check_view_single_update(update_fields, update_values, insert_table_list, - map)) + check_view_single_update(update_fields, &update_values, + insert_table_list, map)) return -1; if (table->timestamp_field) @@ -1234,9 +1249,9 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, table_list->next_local= 0; context->resolve_in_table_list_only(table_list); - res= check_insert_fields(thd, context->table_list, fields, *values, - !insert_into_view, &map) || - setup_fields(thd, 0, *values, MARK_COLUMNS_READ, 0, 0); + res= (setup_fields(thd, 0, *values, MARK_COLUMNS_READ, 0, 0) || + check_insert_fields(thd, context->table_list, fields, *values, + !insert_into_view, 0, &map)); if (!res && check_fields) { @@ -1249,6 +1264,9 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, thd->abort_on_warning= saved_abort_on_warning; } + if (!res) + res= setup_fields(thd, 0, update_values, MARK_COLUMNS_READ, 0, 0); + if (!res && duplic == DUP_UPDATE) { select_lex->no_wrap_view_item= TRUE; @@ -1259,9 +1277,6 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, /* Restore the current context. */ ctx_state.restore_state(context, table_list); - - if (!res) - res= setup_fields(thd, 0, update_values, MARK_COLUMNS_READ, 0, 0); } if (res) @@ -2890,10 +2905,9 @@ select_insert::prepare(List &values, SELECT_LEX_UNIT *u) we are fixing fields from insert list. */ lex->current_select= &lex->select_lex; - res= check_insert_fields(thd, table_list, *fields, values, - !insert_into_view, &map) || - setup_fields(thd, 0, values, MARK_COLUMNS_READ, 0, 0); - + res= (setup_fields(thd, 0, values, MARK_COLUMNS_READ, 0, 0) || + check_insert_fields(thd, table_list, *fields, values, + !insert_into_view, 1, &map)); if (!res && fields->elements) { bool saved_abort_on_warning= thd->abort_on_warning; diff --git a/storage/maria/ma_blockrec.c b/storage/maria/ma_blockrec.c index 54c05b4ae9c..b8538a52cb0 100644 --- a/storage/maria/ma_blockrec.c +++ b/storage/maria/ma_blockrec.c @@ -2422,7 +2422,8 @@ static my_bool free_full_page_range(MARIA_HA *info, pgcache_page_no_t page, */ delete_count--; } - if (pagecache_delete_pages(share->pagecache, &info->dfile, + if (delete_count && + pagecache_delete_pages(share->pagecache, &info->dfile, page, delete_count, PAGECACHE_LOCK_WRITE, 0)) res= 1;