diff options
-rw-r--r-- | mysql-test/r/delayed.result | 2 | ||||
-rw-r--r-- | mysql-test/r/insert.result | 4 | ||||
-rw-r--r-- | mysql-test/t/delayed.test | 2 | ||||
-rw-r--r-- | mysql-test/t/insert.test | 2 | ||||
-rw-r--r-- | sql/sql_insert.cc | 54 |
5 files changed, 43 insertions, 21 deletions
diff --git a/mysql-test/r/delayed.result b/mysql-test/r/delayed.result index 4d5d656f3ce..b26b029759c 100644 --- a/mysql-test/r/delayed.result +++ b/mysql-test/r/delayed.result @@ -252,7 +252,7 @@ HEX(a) DROP TABLE t1; CREATE TABLE t1 (a INT); INSERT DELAYED INTO t1 SET b= b(); -ERROR 42S22: Unknown column 'b' in 'field list' +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/r/insert.result b/mysql-test/r/insert.result index 3f91039d592..4ed56bf3c56 100644 --- a/mysql-test/r/insert.result +++ b/mysql-test/r/insert.result @@ -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)); diff --git a/mysql-test/t/delayed.test b/mysql-test/t/delayed.test index 94ad22b80d0..14833b8f837 100644 --- a/mysql-test/t/delayed.test +++ b/mysql-test/t/delayed.test @@ -247,7 +247,7 @@ 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 1305 INSERT DELAYED INTO t1 SET b= b(); DROP TABLE t1; diff --git a/mysql-test/t/insert.test b/mysql-test/t/insert.test index 8f9ed6c7d06..155ae6937ef 100644 --- a/mysql-test/t/insert.test +++ b/mysql-test/t/insert.test @@ -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; diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 1ef4d5827ec..b9c32bfb430 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -107,8 +107,8 @@ static bool check_view_insertability(THD *thd, TABLE_LIST *view); 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,17 @@ bool check_view_single_update(List<Item> &fields, TABLE_LIST *view, 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) { @@ -165,7 +176,9 @@ error: static int check_insert_fields(THD *thd, TABLE_LIST *table_list, List<Item> &fields, List<Item> &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; @@ -238,7 +251,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, table_list, map)) + if (check_view_single_update(fields, + fields_and_values_from_different_maps ? + (List<Item>*) 0 : &values, + table_list, map)) return -1; table= table_list->table; } @@ -298,7 +314,8 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list, */ 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= 0; @@ -318,7 +335,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, insert_table_list, map)) + check_view_single_update(update_fields, &update_values, + insert_table_list, map)) return -1; if (table->timestamp_field) @@ -1242,9 +1260,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) { @@ -1257,18 +1275,19 @@ 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; - 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; } /* 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) @@ -2931,9 +2950,9 @@ select_insert::prepare(List<Item> &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) { @@ -2960,7 +2979,8 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u) 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 |