Commit c4cf9fc0 authored by Evgeny Potemkin's avatar Evgeny Potemkin

#41760 Inserting into multiple-table views is not working

During insert, we are not reading the rows in a referring table but
instead using the last read row that happens to be in table->record[0].

Now INSERT into such view is denied. 
parent 68c55462
...@@ -252,7 +252,7 @@ HEX(a) ...@@ -252,7 +252,7 @@ HEX(a)
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1 (a INT); CREATE TABLE t1 (a INT);
INSERT DELAYED INTO t1 SET b= b(); 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; DROP TABLE t1;
End of 5.0 tests End of 5.0 tests
DROP TABLE IF EXISTS t1,t2; DROP TABLE IF EXISTS t1,t2;
......
...@@ -355,17 +355,17 @@ insert into t2 values (1,12), (2,24); ...@@ -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; 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' 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; 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; select * from t1;
f1 f2 f1 f2
1 11 1 11
2 22 2 22
3 NULL
insert into v1 (f1) values (3) on duplicate key update f1= f3 + 10; 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; select * from t1;
f1 f2 f1 f2
1 11 1 11
2 22 2 22
12 NULL
drop view v1; drop view v1;
drop table t1,t2; drop table t1,t2;
create table t1 (id int primary key auto_increment, data int, unique(data)); create table t1 (id int primary key auto_increment, data int, unique(data));
......
...@@ -247,7 +247,7 @@ DROP TABLE t1; ...@@ -247,7 +247,7 @@ DROP TABLE t1;
# Bug #32676: insert delayed crash with wrong column and function specified # Bug #32676: insert delayed crash with wrong column and function specified
# #
CREATE TABLE t1 (a INT); CREATE TABLE t1 (a INT);
--error ER_BAD_FIELD_ERROR --error 1305
INSERT DELAYED INTO t1 SET b= b(); INSERT DELAYED INTO t1 SET b= b();
DROP TABLE t1; DROP TABLE t1;
......
...@@ -235,8 +235,10 @@ insert into t1 values (1,11), (2,22); ...@@ -235,8 +235,10 @@ insert into t1 values (1,11), (2,22);
insert into t2 values (1,12), (2,24); insert into t2 values (1,12), (2,24);
--error 1393 --error 1393
insert into v1 (f1) values (3) on duplicate key update f3= f3 + 10; 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; insert into v1 (f1) values (3) on duplicate key update f1= f3 + 10;
select * from t1; select * from t1;
--error 1393
insert into v1 (f1) values (3) on duplicate key update f1= f3 + 10; insert into v1 (f1) values (3) on duplicate key update f1= f3 + 10;
select * from t1; select * from t1;
drop view v1; drop view v1;
......
...@@ -107,8 +107,8 @@ static bool check_view_insertability(THD *thd, TABLE_LIST *view); ...@@ -107,8 +107,8 @@ static bool check_view_insertability(THD *thd, TABLE_LIST *view);
1 Error 1 Error
*/ */
bool check_view_single_update(List<Item> &fields, TABLE_LIST *view, bool check_view_single_update(List<Item> &fields, List<Item> *values,
table_map *map) TABLE_LIST *view, table_map *map)
{ {
/* it is join view => we need to find the table for update */ /* it is join view => we need to find the table for update */
List_iterator_fast<Item> it(fields); List_iterator_fast<Item> it(fields);
...@@ -119,6 +119,17 @@ bool check_view_single_update(List<Item> &fields, TABLE_LIST *view, ...@@ -119,6 +119,17 @@ bool check_view_single_update(List<Item> &fields, TABLE_LIST *view,
while ((item= it++)) while ((item= it++))
tables|= item->used_tables(); 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 */ /* Check found map against provided map */
if (*map) if (*map)
{ {
...@@ -165,7 +176,9 @@ error: ...@@ -165,7 +176,9 @@ error:
static int check_insert_fields(THD *thd, TABLE_LIST *table_list, static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
List<Item> &fields, List<Item> &values, 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; TABLE *table= table_list->table;
...@@ -238,7 +251,10 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list, ...@@ -238,7 +251,10 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
if (table_list->effective_algorithm == VIEW_ALGORITHM_MERGE) 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; return -1;
table= table_list->table; table= table_list->table;
} }
...@@ -298,7 +314,8 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list, ...@@ -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, 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; TABLE *table= insert_table_list->table;
my_bool timestamp_mark= 0; my_bool timestamp_mark= 0;
...@@ -318,7 +335,8 @@ static int check_update_fields(THD *thd, TABLE_LIST *insert_table_list, ...@@ -318,7 +335,8 @@ static int check_update_fields(THD *thd, TABLE_LIST *insert_table_list,
return -1; return -1;
if (insert_table_list->effective_algorithm == VIEW_ALGORITHM_MERGE && 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; return -1;
if (table->timestamp_field) if (table->timestamp_field)
...@@ -1242,9 +1260,9 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, ...@@ -1242,9 +1260,9 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
table_list->next_local= 0; table_list->next_local= 0;
context->resolve_in_table_list_only(table_list); context->resolve_in_table_list_only(table_list);
res= check_insert_fields(thd, context->table_list, fields, *values, res= (setup_fields(thd, 0, *values, MARK_COLUMNS_READ, 0, 0) ||
!insert_into_view, &map) || check_insert_fields(thd, context->table_list, fields, *values,
setup_fields(thd, 0, *values, MARK_COLUMNS_READ, 0, 0); !insert_into_view, 0, &map));
if (!res && check_fields) if (!res && check_fields)
{ {
...@@ -1257,18 +1275,19 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, ...@@ -1257,18 +1275,19 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
thd->abort_on_warning= saved_abort_on_warning; 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) if (!res && duplic == DUP_UPDATE)
{ {
select_lex->no_wrap_view_item= TRUE; 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; select_lex->no_wrap_view_item= FALSE;
} }
/* Restore the current context. */ /* Restore the current context. */
ctx_state.restore_state(context, table_list); ctx_state.restore_state(context, table_list);
if (!res)
res= setup_fields(thd, 0, update_values, MARK_COLUMNS_READ, 0, 0);
} }
if (res) if (res)
...@@ -2931,9 +2950,9 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u) ...@@ -2931,9 +2950,9 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
we are fixing fields from insert list. we are fixing fields from insert list.
*/ */
lex->current_select= &lex->select_lex; lex->current_select= &lex->select_lex;
res= check_insert_fields(thd, table_list, *fields, values, res= (setup_fields(thd, 0, values, MARK_COLUMNS_READ, 0, 0) ||
!insert_into_view, &map) || check_insert_fields(thd, table_list, *fields, values,
setup_fields(thd, 0, values, MARK_COLUMNS_READ, 0, 0); !insert_into_view, 1, &map));
if (!res && fields->elements) if (!res && fields->elements)
{ {
...@@ -2960,7 +2979,8 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u) ...@@ -2960,7 +2979,8 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
lex->select_lex.no_wrap_view_item= TRUE; lex->select_lex.no_wrap_view_item= TRUE;
res= res || check_update_fields(thd, context->table_list, 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; lex->select_lex.no_wrap_view_item= FALSE;
/* /*
When we are not using GROUP BY and there are no ungrouped aggregate functions When we are not using GROUP BY and there are no ungrouped aggregate functions
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment