#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.
This commit is contained in:
parent
68c55462ef
commit
c4cf9fc0bb
@ -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);
|
|||||||
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;
|
|||||||
# 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);
|
|||||||
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);
|
|||||||
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,
|
|||||||
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:
|
|||||||
|
|
||||||
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,
|
|||||||
|
|
||||||
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,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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)
|
|||||||
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)
|
|||||||
|
|
||||||
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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user