MDEV-32086 (part 2) Server crash when inserting from derived table containing insert target table
Get rid of need of matherialization for usual INSERT (cache results in Item_cache* if needed) - subqueries in VALUE do not see new records in the table we are inserting to - subqueries in RETIRNING prohibited to use the table we are inserting to
This commit is contained in:
parent
9b313d2de1
commit
4fc9dc84b0
@ -806,5 +806,75 @@ a
|
|||||||
8
|
8
|
||||||
drop table t1;
|
drop table t1;
|
||||||
#
|
#
|
||||||
# End of 10.5 tests
|
# MDEV-32086 Server crash when inserting from derived table containing insert target table
|
||||||
|
# (part 2)
|
||||||
#
|
#
|
||||||
|
create table t1 (pk int, id int);
|
||||||
|
insert into t1 values (2,2), (3,3), (4,4);
|
||||||
|
select * from t1;
|
||||||
|
pk id
|
||||||
|
2 2
|
||||||
|
3 3
|
||||||
|
4 4
|
||||||
|
select 101+count(*)
|
||||||
|
from
|
||||||
|
(
|
||||||
|
select dt2.id
|
||||||
|
from (select id from t1) dt2, t1 t where t.id=dt2.id
|
||||||
|
) dt
|
||||||
|
where dt.id<1000;
|
||||||
|
101+count(*)
|
||||||
|
104
|
||||||
|
prepare s from '
|
||||||
|
insert into t1 values(
|
||||||
|
(select 101+count(*)
|
||||||
|
from
|
||||||
|
(
|
||||||
|
select dt2.id
|
||||||
|
from (select id from t1) dt2, t1 t where t.id=dt2.id
|
||||||
|
) dt
|
||||||
|
where dt.id<1000
|
||||||
|
), 123
|
||||||
|
)
|
||||||
|
';
|
||||||
|
execute s;
|
||||||
|
select * from t1;
|
||||||
|
pk id
|
||||||
|
2 2
|
||||||
|
3 3
|
||||||
|
4 4
|
||||||
|
104 123
|
||||||
|
select 101+count(*)
|
||||||
|
from
|
||||||
|
(
|
||||||
|
select dt2.id
|
||||||
|
from (select id from t1) dt2, t1 t where t.id=dt2.id
|
||||||
|
) dt
|
||||||
|
where dt.id<1000;
|
||||||
|
101+count(*)
|
||||||
|
105
|
||||||
|
execute s;
|
||||||
|
select * from t1;
|
||||||
|
pk id
|
||||||
|
2 2
|
||||||
|
3 3
|
||||||
|
4 4
|
||||||
|
104 123
|
||||||
|
105 123
|
||||||
|
drop table t1;
|
||||||
|
#
|
||||||
|
# Try this: INSERT INTO t1 VALUES ... reference to t1
|
||||||
|
# RETURNING (subquery not touching t1)
|
||||||
|
create table t1 (a int, b int);
|
||||||
|
create table t2 (a int, b int);
|
||||||
|
# This is accepted:
|
||||||
|
insert into t1 (a) values
|
||||||
|
(3),
|
||||||
|
((select max(a) from t1))
|
||||||
|
returning
|
||||||
|
a, b, (select max(a) from t2);
|
||||||
|
a b (select max(a) from t2)
|
||||||
|
3 NULL NULL
|
||||||
|
NULL NULL NULL
|
||||||
|
drop table t1,t2;
|
||||||
|
# End of 10.5 tests
|
||||||
|
@ -675,5 +675,59 @@ select * from t1;
|
|||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # End of 10.5 tests
|
--echo # MDEV-32086 Server crash when inserting from derived table containing insert target table
|
||||||
|
--echo # (part 2)
|
||||||
--echo #
|
--echo #
|
||||||
|
|
||||||
|
create table t1 (pk int, id int);
|
||||||
|
insert into t1 values (2,2), (3,3), (4,4);
|
||||||
|
select * from t1;
|
||||||
|
select 101+count(*)
|
||||||
|
from
|
||||||
|
(
|
||||||
|
select dt2.id
|
||||||
|
from (select id from t1) dt2, t1 t where t.id=dt2.id
|
||||||
|
) dt
|
||||||
|
where dt.id<1000;
|
||||||
|
prepare s from '
|
||||||
|
insert into t1 values(
|
||||||
|
(select 101+count(*)
|
||||||
|
from
|
||||||
|
(
|
||||||
|
select dt2.id
|
||||||
|
from (select id from t1) dt2, t1 t where t.id=dt2.id
|
||||||
|
) dt
|
||||||
|
where dt.id<1000
|
||||||
|
), 123
|
||||||
|
)
|
||||||
|
';
|
||||||
|
execute s;
|
||||||
|
select * from t1;
|
||||||
|
select 101+count(*)
|
||||||
|
from
|
||||||
|
(
|
||||||
|
select dt2.id
|
||||||
|
from (select id from t1) dt2, t1 t where t.id=dt2.id
|
||||||
|
) dt
|
||||||
|
where dt.id<1000;
|
||||||
|
execute s;
|
||||||
|
select * from t1;
|
||||||
|
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Try this: INSERT INTO t1 VALUES ... reference to t1
|
||||||
|
--echo # RETURNING (subquery not touching t1)
|
||||||
|
create table t1 (a int, b int);
|
||||||
|
create table t2 (a int, b int);
|
||||||
|
|
||||||
|
--echo # This is accepted:
|
||||||
|
insert into t1 (a) values
|
||||||
|
(3),
|
||||||
|
((select max(a) from t1))
|
||||||
|
returning
|
||||||
|
a, b, (select max(a) from t2);
|
||||||
|
|
||||||
|
drop table t1,t2;
|
||||||
|
|
||||||
|
--echo # End of 10.5 tests
|
||||||
|
@ -498,6 +498,8 @@ t1 WHERE id1=1)
|
|||||||
5 6
|
5 6
|
||||||
INSERT INTO t2(id2,val2) VALUES(5,'f') RETURNING (SELECT id2 FROM t2);
|
INSERT INTO t2(id2,val2) VALUES(5,'f') RETURNING (SELECT id2 FROM t2);
|
||||||
ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data
|
ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data
|
||||||
|
INSERT INTO t2(id2,val2) VALUES(5,'f') RETURNING (SELECT 1 UNION SELECT id2 FROM t2);
|
||||||
|
ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data
|
||||||
INSERT INTO t2 (id2, val2) VALUES (6,'f') RETURNING t1.*;
|
INSERT INTO t2 (id2, val2) VALUES (6,'f') RETURNING t1.*;
|
||||||
ERROR 42S02: Unknown table 'test.t1'
|
ERROR 42S02: Unknown table 'test.t1'
|
||||||
#
|
#
|
||||||
|
@ -199,6 +199,8 @@ INSERT INTO t2(id2,val2) VALUES(5,'e') RETURNING id2, (SELECT id1+id2 FROM
|
|||||||
t1 WHERE id1=1);
|
t1 WHERE id1=1);
|
||||||
--error ER_UPDATE_TABLE_USED
|
--error ER_UPDATE_TABLE_USED
|
||||||
INSERT INTO t2(id2,val2) VALUES(5,'f') RETURNING (SELECT id2 FROM t2);
|
INSERT INTO t2(id2,val2) VALUES(5,'f') RETURNING (SELECT id2 FROM t2);
|
||||||
|
--error ER_UPDATE_TABLE_USED
|
||||||
|
INSERT INTO t2(id2,val2) VALUES(5,'f') RETURNING (SELECT 1 UNION SELECT id2 FROM t2);
|
||||||
--error ER_BAD_TABLE_ERROR
|
--error ER_BAD_TABLE_ERROR
|
||||||
INSERT INTO t2 (id2, val2) VALUES (6,'f') RETURNING t1.*;
|
INSERT INTO t2 (id2, val2) VALUES (6,'f') RETURNING t1.*;
|
||||||
|
|
||||||
|
@ -16,29 +16,17 @@ create view v1Aa as select * from t1aA;
|
|||||||
create view v2aA as select * from v1aA;
|
create view v2aA as select * from v1aA;
|
||||||
create view v3Aa as select v2Aa.col1 from v2aA,t2Aa where v2Aa.col1 = t2aA.col1;
|
create view v3Aa as select v2Aa.col1 from v2aA,t2Aa where v2Aa.col1 = t2aA.col1;
|
||||||
insert into v2Aa values ((select max(col1) from v1aA));
|
insert into v2Aa values ((select max(col1) from v1aA));
|
||||||
ERROR HY000: The definition of table 'v1aA' prevents operation INSERT on table 'v2Aa'
|
|
||||||
insert into t1aA values ((select max(col1) from v1Aa));
|
insert into t1aA values ((select max(col1) from v1Aa));
|
||||||
ERROR HY000: The definition of table 'v1Aa' prevents operation INSERT on table 't1aA'
|
|
||||||
insert into v2aA values ((select max(col1) from v1aA));
|
insert into v2aA values ((select max(col1) from v1aA));
|
||||||
ERROR HY000: The definition of table 'v1aA' prevents operation INSERT on table 'v2aA'
|
|
||||||
insert into v2Aa values ((select max(col1) from t1Aa));
|
insert into v2Aa values ((select max(col1) from t1Aa));
|
||||||
ERROR HY000: The definition of table 'v2Aa' prevents operation INSERT on table 'v2Aa'
|
|
||||||
insert into t1aA values ((select max(col1) from t1Aa));
|
insert into t1aA values ((select max(col1) from t1Aa));
|
||||||
ERROR HY000: Table 't1aA' is specified twice, both as a target for 'INSERT' and as a separate source for data
|
|
||||||
insert into v2aA values ((select max(col1) from t1aA));
|
insert into v2aA values ((select max(col1) from t1aA));
|
||||||
ERROR HY000: The definition of table 'v2aA' prevents operation INSERT on table 'v2aA'
|
|
||||||
insert into v2Aa values ((select max(col1) from v2aA));
|
insert into v2Aa values ((select max(col1) from v2aA));
|
||||||
ERROR HY000: Table 'v2Aa' is specified twice, both as a target for 'INSERT' and as a separate source for data
|
|
||||||
insert into t1Aa values ((select max(col1) from v2Aa));
|
insert into t1Aa values ((select max(col1) from v2Aa));
|
||||||
ERROR HY000: The definition of table 'v2Aa' prevents operation INSERT on table 't1Aa'
|
|
||||||
insert into v2aA values ((select max(col1) from v2Aa));
|
insert into v2aA values ((select max(col1) from v2Aa));
|
||||||
ERROR HY000: Table 'v2aA' is specified twice, both as a target for 'INSERT' and as a separate source for data
|
|
||||||
insert into v3Aa (col1) values ((select max(col1) from v1Aa));
|
insert into v3Aa (col1) values ((select max(col1) from v1Aa));
|
||||||
ERROR HY000: The definition of table 'v1Aa' prevents operation INSERT on table 'v3Aa'
|
|
||||||
insert into v3aA (col1) values ((select max(col1) from t1aA));
|
insert into v3aA (col1) values ((select max(col1) from t1aA));
|
||||||
ERROR HY000: The definition of table 'v3aA' prevents operation INSERT on table 'v3aA'
|
|
||||||
insert into v3Aa (col1) values ((select max(col1) from v2aA));
|
insert into v3Aa (col1) values ((select max(col1) from v2aA));
|
||||||
ERROR HY000: The definition of table 'v2aA' prevents operation INSERT on table 'v3Aa'
|
|
||||||
drop view v3aA,v2Aa,v1aA;
|
drop view v3aA,v2Aa,v1aA;
|
||||||
drop table t1Aa,t2Aa;
|
drop table t1Aa,t2Aa;
|
||||||
create table t1Aa (col1 int);
|
create table t1Aa (col1 int);
|
||||||
|
@ -23,29 +23,17 @@ create table t2aA (col1 int);
|
|||||||
create view v1Aa as select * from t1aA;
|
create view v1Aa as select * from t1aA;
|
||||||
create view v2aA as select * from v1aA;
|
create view v2aA as select * from v1aA;
|
||||||
create view v3Aa as select v2Aa.col1 from v2aA,t2Aa where v2Aa.col1 = t2aA.col1;
|
create view v3Aa as select v2Aa.col1 from v2aA,t2Aa where v2Aa.col1 = t2aA.col1;
|
||||||
-- error 1443
|
|
||||||
insert into v2Aa values ((select max(col1) from v1aA));
|
insert into v2Aa values ((select max(col1) from v1aA));
|
||||||
-- error 1443
|
|
||||||
insert into t1aA values ((select max(col1) from v1Aa));
|
insert into t1aA values ((select max(col1) from v1Aa));
|
||||||
-- error 1443
|
|
||||||
insert into v2aA values ((select max(col1) from v1aA));
|
insert into v2aA values ((select max(col1) from v1aA));
|
||||||
-- error 1443
|
|
||||||
insert into v2Aa values ((select max(col1) from t1Aa));
|
insert into v2Aa values ((select max(col1) from t1Aa));
|
||||||
-- error 1093
|
|
||||||
insert into t1aA values ((select max(col1) from t1Aa));
|
insert into t1aA values ((select max(col1) from t1Aa));
|
||||||
-- error 1443
|
|
||||||
insert into v2aA values ((select max(col1) from t1aA));
|
insert into v2aA values ((select max(col1) from t1aA));
|
||||||
-- error 1093
|
|
||||||
insert into v2Aa values ((select max(col1) from v2aA));
|
insert into v2Aa values ((select max(col1) from v2aA));
|
||||||
-- error 1443
|
|
||||||
insert into t1Aa values ((select max(col1) from v2Aa));
|
insert into t1Aa values ((select max(col1) from v2Aa));
|
||||||
-- error 1093
|
|
||||||
insert into v2aA values ((select max(col1) from v2Aa));
|
insert into v2aA values ((select max(col1) from v2Aa));
|
||||||
-- error 1443
|
|
||||||
insert into v3Aa (col1) values ((select max(col1) from v1Aa));
|
insert into v3Aa (col1) values ((select max(col1) from v1Aa));
|
||||||
-- error 1443
|
|
||||||
insert into v3aA (col1) values ((select max(col1) from t1aA));
|
insert into v3aA (col1) values ((select max(col1) from t1aA));
|
||||||
-- error 1443
|
|
||||||
insert into v3Aa (col1) values ((select max(col1) from v2aA));
|
insert into v3Aa (col1) values ((select max(col1) from v2aA));
|
||||||
drop view v3aA,v2Aa,v1aA;
|
drop view v3aA,v2Aa,v1aA;
|
||||||
drop table t1Aa,t2Aa;
|
drop table t1Aa,t2Aa;
|
||||||
|
@ -3689,33 +3689,22 @@ insert into tmp (b) values (1);
|
|||||||
insert into t1 (a) values (1);
|
insert into t1 (a) values (1);
|
||||||
insert into t3 (b) values (1);
|
insert into t3 (b) values (1);
|
||||||
insert into m1 (a) values ((select max(a) from m1));
|
insert into m1 (a) values ((select max(a) from m1));
|
||||||
ERROR HY000: Table 'm1' is specified twice, both as a target for 'INSERT' and as a separate source for data
|
|
||||||
insert into m1 (a) values ((select max(a) from m2));
|
insert into m1 (a) values ((select max(a) from m2));
|
||||||
ERROR HY000: Table 'm1' is specified twice, both as a target for 'INSERT' and as a separate source for data
|
|
||||||
insert into m1 (a) values ((select max(a) from t1));
|
insert into m1 (a) values ((select max(a) from t1));
|
||||||
ERROR HY000: Table 'm1' is specified twice, both as a target for 'INSERT' and as a separate source for data
|
|
||||||
insert into m1 (a) values ((select max(a) from t2));
|
insert into m1 (a) values ((select max(a) from t2));
|
||||||
ERROR HY000: Table 'm1' is specified twice, both as a target for 'INSERT' and as a separate source for data
|
|
||||||
insert into m1 (a) values ((select max(a) from t3, m1));
|
insert into m1 (a) values ((select max(a) from t3, m1));
|
||||||
ERROR HY000: Table 'm1' is specified twice, both as a target for 'INSERT' and as a separate source for data
|
|
||||||
insert into m1 (a) values ((select max(a) from t3, m2));
|
insert into m1 (a) values ((select max(a) from t3, m2));
|
||||||
ERROR HY000: Table 'm1' is specified twice, both as a target for 'INSERT' and as a separate source for data
|
|
||||||
insert into m1 (a) values ((select max(a) from t3, t1));
|
insert into m1 (a) values ((select max(a) from t3, t1));
|
||||||
ERROR HY000: Table 'm1' is specified twice, both as a target for 'INSERT' and as a separate source for data
|
|
||||||
insert into m1 (a) values ((select max(a) from t3, t2));
|
insert into m1 (a) values ((select max(a) from t3, t2));
|
||||||
ERROR HY000: Table 'm1' is specified twice, both as a target for 'INSERT' and as a separate source for data
|
|
||||||
insert into m1 (a) values ((select max(a) from tmp, m1));
|
insert into m1 (a) values ((select max(a) from tmp, m1));
|
||||||
ERROR HY000: Table 'm1' is specified twice, both as a target for 'INSERT' and as a separate source for data
|
|
||||||
insert into m1 (a) values ((select max(a) from tmp, m2));
|
insert into m1 (a) values ((select max(a) from tmp, m2));
|
||||||
ERROR HY000: Table 'm1' is specified twice, both as a target for 'INSERT' and as a separate source for data
|
|
||||||
insert into m1 (a) values ((select max(a) from tmp, t1));
|
insert into m1 (a) values ((select max(a) from tmp, t1));
|
||||||
ERROR HY000: Table 'm1' is specified twice, both as a target for 'INSERT' and as a separate source for data
|
|
||||||
insert into m1 (a) values ((select max(a) from tmp, t2));
|
insert into m1 (a) values ((select max(a) from tmp, t2));
|
||||||
ERROR HY000: Table 'm1' is specified twice, both as a target for 'INSERT' and as a separate source for data
|
|
||||||
insert into m1 (a) values ((select max(a) from v1));
|
insert into m1 (a) values ((select max(a) from v1));
|
||||||
ERROR HY000: The definition of table 'v1' prevents operation INSERT on table 'm1'
|
|
||||||
insert into m1 (a) values ((select max(a) from tmp, v1));
|
insert into m1 (a) values ((select max(a) from tmp, v1));
|
||||||
ERROR HY000: The definition of table 'v1' prevents operation INSERT on table 'm1'
|
select count(*) from m1;
|
||||||
|
count(*)
|
||||||
|
15
|
||||||
drop view v1;
|
drop view v1;
|
||||||
drop temporary table tmp;
|
drop temporary table tmp;
|
||||||
drop table t1, t2, t3, m1, m2;
|
drop table t1, t2, t3, m1, m2;
|
||||||
|
@ -2704,37 +2704,24 @@ insert into tmp (b) values (1);
|
|||||||
|
|
||||||
insert into t1 (a) values (1);
|
insert into t1 (a) values (1);
|
||||||
insert into t3 (b) values (1);
|
insert into t3 (b) values (1);
|
||||||
--error ER_UPDATE_TABLE_USED
|
|
||||||
insert into m1 (a) values ((select max(a) from m1));
|
insert into m1 (a) values ((select max(a) from m1));
|
||||||
--error ER_UPDATE_TABLE_USED
|
|
||||||
insert into m1 (a) values ((select max(a) from m2));
|
insert into m1 (a) values ((select max(a) from m2));
|
||||||
--error ER_UPDATE_TABLE_USED
|
|
||||||
insert into m1 (a) values ((select max(a) from t1));
|
insert into m1 (a) values ((select max(a) from t1));
|
||||||
--error ER_UPDATE_TABLE_USED
|
|
||||||
insert into m1 (a) values ((select max(a) from t2));
|
insert into m1 (a) values ((select max(a) from t2));
|
||||||
|
|
||||||
--error ER_UPDATE_TABLE_USED
|
|
||||||
insert into m1 (a) values ((select max(a) from t3, m1));
|
insert into m1 (a) values ((select max(a) from t3, m1));
|
||||||
--error ER_UPDATE_TABLE_USED
|
|
||||||
insert into m1 (a) values ((select max(a) from t3, m2));
|
insert into m1 (a) values ((select max(a) from t3, m2));
|
||||||
--error ER_UPDATE_TABLE_USED
|
|
||||||
insert into m1 (a) values ((select max(a) from t3, t1));
|
insert into m1 (a) values ((select max(a) from t3, t1));
|
||||||
--error ER_UPDATE_TABLE_USED
|
|
||||||
insert into m1 (a) values ((select max(a) from t3, t2));
|
insert into m1 (a) values ((select max(a) from t3, t2));
|
||||||
|
|
||||||
--error ER_UPDATE_TABLE_USED
|
|
||||||
insert into m1 (a) values ((select max(a) from tmp, m1));
|
insert into m1 (a) values ((select max(a) from tmp, m1));
|
||||||
--error ER_UPDATE_TABLE_USED
|
|
||||||
insert into m1 (a) values ((select max(a) from tmp, m2));
|
insert into m1 (a) values ((select max(a) from tmp, m2));
|
||||||
--error ER_UPDATE_TABLE_USED
|
|
||||||
insert into m1 (a) values ((select max(a) from tmp, t1));
|
insert into m1 (a) values ((select max(a) from tmp, t1));
|
||||||
--error ER_UPDATE_TABLE_USED
|
|
||||||
insert into m1 (a) values ((select max(a) from tmp, t2));
|
insert into m1 (a) values ((select max(a) from tmp, t2));
|
||||||
|
|
||||||
--error ER_VIEW_PREVENT_UPDATE
|
|
||||||
insert into m1 (a) values ((select max(a) from v1));
|
insert into m1 (a) values ((select max(a) from v1));
|
||||||
--error ER_VIEW_PREVENT_UPDATE
|
|
||||||
insert into m1 (a) values ((select max(a) from tmp, v1));
|
insert into m1 (a) values ((select max(a) from tmp, v1));
|
||||||
|
select count(*) from m1;
|
||||||
|
|
||||||
|
|
||||||
drop view v1;
|
drop view v1;
|
||||||
|
@ -679,22 +679,24 @@ create table t3 (b int);
|
|||||||
insert into t2 values (1);
|
insert into t2 values (1);
|
||||||
insert into t3 values (1),(2);
|
insert into t3 values (1),(2);
|
||||||
INSERT INTO t1 (x) VALUES ((SELECT x FROM t1));
|
INSERT INTO t1 (x) VALUES ((SELECT x FROM t1));
|
||||||
ERROR HY000: Table 't1' is specified twice, both as a target for 'INSERT' and as a separate source for data
|
|
||||||
INSERT INTO t1 (x) VALUES ((SELECT b FROM t3));
|
INSERT INTO t1 (x) VALUES ((SELECT b FROM t3));
|
||||||
ERROR 21000: Subquery returns more than 1 row
|
ERROR 21000: Subquery returns more than 1 row
|
||||||
INSERT INTO t1 (x) VALUES ((SELECT a FROM t2));
|
INSERT INTO t1 (x) VALUES ((SELECT a FROM t2));
|
||||||
select * from t1;
|
select * from t1;
|
||||||
x
|
x
|
||||||
|
NULL
|
||||||
1
|
1
|
||||||
insert into t2 values (1);
|
insert into t2 values (1);
|
||||||
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
|
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
|
||||||
select * from t1;
|
select * from t1;
|
||||||
x
|
x
|
||||||
|
NULL
|
||||||
1
|
1
|
||||||
2
|
2
|
||||||
INSERT INTO t1 (x) select (SELECT SUM(a)+1 FROM t2) FROM t2;
|
INSERT INTO t1 (x) select (SELECT SUM(a)+1 FROM t2) FROM t2;
|
||||||
select * from t1;
|
select * from t1;
|
||||||
x
|
x
|
||||||
|
NULL
|
||||||
1
|
1
|
||||||
2
|
2
|
||||||
3
|
3
|
||||||
@ -702,6 +704,7 @@ x
|
|||||||
INSERT INTO t1 (x) select (SELECT SUM(x)+2 FROM t1) FROM t2;
|
INSERT INTO t1 (x) select (SELECT SUM(x)+2 FROM t1) FROM t2;
|
||||||
select * from t1;
|
select * from t1;
|
||||||
x
|
x
|
||||||
|
NULL
|
||||||
1
|
1
|
||||||
2
|
2
|
||||||
3
|
3
|
||||||
@ -711,6 +714,7 @@ x
|
|||||||
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
|
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
|
||||||
select * from t1;
|
select * from t1;
|
||||||
x
|
x
|
||||||
|
NULL
|
||||||
1
|
1
|
||||||
2
|
2
|
||||||
3
|
3
|
||||||
@ -727,7 +731,7 @@ insert into t3 values (1),(2);
|
|||||||
select * from t1;
|
select * from t1;
|
||||||
x y
|
x y
|
||||||
replace into t1 (x, y) VALUES ((SELECT x FROM t1), (SELECT a+1 FROM t2));
|
replace into t1 (x, y) VALUES ((SELECT x FROM t1), (SELECT a+1 FROM t2));
|
||||||
ERROR HY000: Table 't1' is specified twice, both as a target for 'INSERT' and as a separate source for data
|
ERROR 23000: Column 'x' cannot be null
|
||||||
replace into t1 (x, y) VALUES ((SELECT a FROM t3), (SELECT a+1 FROM t2));
|
replace into t1 (x, y) VALUES ((SELECT a FROM t3), (SELECT a+1 FROM t2));
|
||||||
ERROR 21000: Subquery returns more than 1 row
|
ERROR 21000: Subquery returns more than 1 row
|
||||||
replace into t1 (x, y) VALUES ((SELECT a FROM t2), (SELECT a+1 FROM t2));
|
replace into t1 (x, y) VALUES ((SELECT a FROM t2), (SELECT a+1 FROM t2));
|
||||||
@ -795,13 +799,21 @@ SELECT * FROM t2 WHERE id IN (SELECT 5 UNION SELECT 2);
|
|||||||
id
|
id
|
||||||
2
|
2
|
||||||
INSERT INTO t2 VALUES ((SELECT * FROM t2));
|
INSERT INTO t2 VALUES ((SELECT * FROM t2));
|
||||||
ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data
|
ERROR 21000: Subquery returns more than 1 row
|
||||||
INSERT INTO t2 VALUES ((SELECT id FROM t2));
|
INSERT INTO t2 VALUES ((SELECT id FROM t2));
|
||||||
ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data
|
ERROR 21000: Subquery returns more than 1 row
|
||||||
|
select * from t2;
|
||||||
|
id
|
||||||
|
1
|
||||||
|
2
|
||||||
|
INSERT INTO t2 VALUES ((SELECT count(*) FROM t2));
|
||||||
|
INSERT INTO t2 VALUES ((SELECT max(id) FROM t2));
|
||||||
SELECT * FROM t2;
|
SELECT * FROM t2;
|
||||||
id
|
id
|
||||||
1
|
1
|
||||||
2
|
2
|
||||||
|
2
|
||||||
|
2
|
||||||
CREATE TABLE t1 (id int(11) default NULL, KEY id (id)) ENGINE=MyISAM CHARSET=latin1;
|
CREATE TABLE t1 (id int(11) default NULL, KEY id (id)) ENGINE=MyISAM CHARSET=latin1;
|
||||||
INSERT INTO t1 values (1),(1);
|
INSERT INTO t1 values (1),(1);
|
||||||
UPDATE t2 SET id=(SELECT * FROM t1);
|
UPDATE t2 SET id=(SELECT * FROM t1);
|
||||||
|
@ -415,7 +415,6 @@ create table t2 (a int) ENGINE=MyISAM;
|
|||||||
create table t3 (b int);
|
create table t3 (b int);
|
||||||
insert into t2 values (1);
|
insert into t2 values (1);
|
||||||
insert into t3 values (1),(2);
|
insert into t3 values (1),(2);
|
||||||
-- error ER_UPDATE_TABLE_USED
|
|
||||||
INSERT INTO t1 (x) VALUES ((SELECT x FROM t1));
|
INSERT INTO t1 (x) VALUES ((SELECT x FROM t1));
|
||||||
-- error ER_SUBQUERY_NO_1_ROW
|
-- error ER_SUBQUERY_NO_1_ROW
|
||||||
INSERT INTO t1 (x) VALUES ((SELECT b FROM t3));
|
INSERT INTO t1 (x) VALUES ((SELECT b FROM t3));
|
||||||
@ -450,7 +449,7 @@ create table t3 (a int);
|
|||||||
insert into t2 values (1);
|
insert into t2 values (1);
|
||||||
insert into t3 values (1),(2);
|
insert into t3 values (1),(2);
|
||||||
select * from t1;
|
select * from t1;
|
||||||
-- error ER_UPDATE_TABLE_USED
|
-- error ER_BAD_NULL_ERROR
|
||||||
replace into t1 (x, y) VALUES ((SELECT x FROM t1), (SELECT a+1 FROM t2));
|
replace into t1 (x, y) VALUES ((SELECT x FROM t1), (SELECT a+1 FROM t2));
|
||||||
-- error ER_SUBQUERY_NO_1_ROW
|
-- error ER_SUBQUERY_NO_1_ROW
|
||||||
replace into t1 (x, y) VALUES ((SELECT a FROM t3), (SELECT a+1 FROM t2));
|
replace into t1 (x, y) VALUES ((SELECT a FROM t3), (SELECT a+1 FROM t2));
|
||||||
@ -486,10 +485,13 @@ EXPLAIN EXTENDED SELECT * FROM t2 WHERE id IN (SELECT 1+(select 1));
|
|||||||
EXPLAIN EXTENDED SELECT * FROM t2 WHERE id IN (SELECT 1 UNION SELECT 3);
|
EXPLAIN EXTENDED SELECT * FROM t2 WHERE id IN (SELECT 1 UNION SELECT 3);
|
||||||
SELECT * FROM t2 WHERE id IN (SELECT 5 UNION SELECT 3);
|
SELECT * FROM t2 WHERE id IN (SELECT 5 UNION SELECT 3);
|
||||||
SELECT * FROM t2 WHERE id IN (SELECT 5 UNION SELECT 2);
|
SELECT * FROM t2 WHERE id IN (SELECT 5 UNION SELECT 2);
|
||||||
-- error ER_UPDATE_TABLE_USED
|
-- error ER_SUBQUERY_NO_1_ROW
|
||||||
INSERT INTO t2 VALUES ((SELECT * FROM t2));
|
INSERT INTO t2 VALUES ((SELECT * FROM t2));
|
||||||
-- error ER_UPDATE_TABLE_USED
|
-- error ER_SUBQUERY_NO_1_ROW
|
||||||
INSERT INTO t2 VALUES ((SELECT id FROM t2));
|
INSERT INTO t2 VALUES ((SELECT id FROM t2));
|
||||||
|
select * from t2;
|
||||||
|
INSERT INTO t2 VALUES ((SELECT count(*) FROM t2));
|
||||||
|
INSERT INTO t2 VALUES ((SELECT max(id) FROM t2));
|
||||||
SELECT * FROM t2;
|
SELECT * FROM t2;
|
||||||
CREATE TABLE t1 (id int(11) default NULL, KEY id (id)) ENGINE=MyISAM CHARSET=latin1;
|
CREATE TABLE t1 (id int(11) default NULL, KEY id (id)) ENGINE=MyISAM CHARSET=latin1;
|
||||||
INSERT INTO t1 values (1),(1);
|
INSERT INTO t1 values (1),(1);
|
||||||
|
@ -136,12 +136,22 @@ DROP TABLE t1;
|
|||||||
# access within null pointer
|
# access within null pointer
|
||||||
CREATE TABLE x (x INT) ENGINE=InnoDB;
|
CREATE TABLE x (x INT) ENGINE=InnoDB;
|
||||||
INSERT INTO x (x) VALUES (0);
|
INSERT INTO x (x) VALUES (0);
|
||||||
|
select NULL IN (SELECT (SELECT x FROM (SELECT x FROM
|
||||||
|
(SELECT 0 IN (SELECT x=0 FROM (SELECT x FROM (SELECT (SELECT (SELECT (SELECT
|
||||||
|
(SELECT 0 AS x) FROM x AS x) IN (SELECT 0 AS x) AS x) FROM x AS x) IN
|
||||||
|
(SELECT x WHERE x=0) AS x FROM x AS x) AS x) AS x GROUP BY x) AS x FROM x) AS x)
|
||||||
|
AS x) IN (SELECT 0 AS x) AS x FROM x) as exp;
|
||||||
|
exp
|
||||||
|
NULL
|
||||||
INSERT INTO x (x) VALUES (x IN (SELECT (SELECT x FROM (SELECT x FROM
|
INSERT INTO x (x) VALUES (x IN (SELECT (SELECT x FROM (SELECT x FROM
|
||||||
(SELECT 0 IN (SELECT x=0 FROM (SELECT x FROM (SELECT (SELECT (SELECT (SELECT
|
(SELECT 0 IN (SELECT x=0 FROM (SELECT x FROM (SELECT (SELECT (SELECT (SELECT
|
||||||
(SELECT 0 AS x) FROM x AS x) IN (SELECT 0 AS x) AS x) FROM x AS x) IN
|
(SELECT 0 AS x) FROM x AS x) IN (SELECT 0 AS x) AS x) FROM x AS x) IN
|
||||||
(SELECT x WHERE x=0) AS x FROM x AS x) AS x) AS x GROUP BY x) AS x FROM x) AS x)
|
(SELECT x WHERE x=0) AS x FROM x AS x) AS x) AS x GROUP BY x) AS x FROM x) AS x)
|
||||||
AS x) IN (SELECT 0 AS x) AS x FROM x));
|
AS x) IN (SELECT 0 AS x) AS x FROM x));
|
||||||
ERROR HY000: Table 'x' is specified twice, both as a target for 'INSERT' and as a separate source for data
|
select * from x;
|
||||||
|
x
|
||||||
|
0
|
||||||
|
NULL
|
||||||
DROP TABLE x;
|
DROP TABLE x;
|
||||||
# MDEV-28622: Item_subselect eliminated flag set but Item still
|
# MDEV-28622: Item_subselect eliminated flag set but Item still
|
||||||
# evaluated/used.
|
# evaluated/used.
|
||||||
|
@ -133,12 +133,17 @@ DROP TABLE t1;
|
|||||||
|
|
||||||
CREATE TABLE x (x INT) ENGINE=InnoDB;
|
CREATE TABLE x (x INT) ENGINE=InnoDB;
|
||||||
INSERT INTO x (x) VALUES (0);
|
INSERT INTO x (x) VALUES (0);
|
||||||
--error ER_UPDATE_TABLE_USED
|
select NULL IN (SELECT (SELECT x FROM (SELECT x FROM
|
||||||
|
(SELECT 0 IN (SELECT x=0 FROM (SELECT x FROM (SELECT (SELECT (SELECT (SELECT
|
||||||
|
(SELECT 0 AS x) FROM x AS x) IN (SELECT 0 AS x) AS x) FROM x AS x) IN
|
||||||
|
(SELECT x WHERE x=0) AS x FROM x AS x) AS x) AS x GROUP BY x) AS x FROM x) AS x)
|
||||||
|
AS x) IN (SELECT 0 AS x) AS x FROM x) as exp;
|
||||||
INSERT INTO x (x) VALUES (x IN (SELECT (SELECT x FROM (SELECT x FROM
|
INSERT INTO x (x) VALUES (x IN (SELECT (SELECT x FROM (SELECT x FROM
|
||||||
(SELECT 0 IN (SELECT x=0 FROM (SELECT x FROM (SELECT (SELECT (SELECT (SELECT
|
(SELECT 0 IN (SELECT x=0 FROM (SELECT x FROM (SELECT (SELECT (SELECT (SELECT
|
||||||
(SELECT 0 AS x) FROM x AS x) IN (SELECT 0 AS x) AS x) FROM x AS x) IN
|
(SELECT 0 AS x) FROM x AS x) IN (SELECT 0 AS x) AS x) FROM x AS x) IN
|
||||||
(SELECT x WHERE x=0) AS x FROM x AS x) AS x) AS x GROUP BY x) AS x FROM x) AS x)
|
(SELECT x WHERE x=0) AS x FROM x AS x) AS x) AS x GROUP BY x) AS x FROM x) AS x)
|
||||||
AS x) IN (SELECT 0 AS x) AS x FROM x));
|
AS x) IN (SELECT 0 AS x) AS x FROM x));
|
||||||
|
select * from x;
|
||||||
DROP TABLE x;
|
DROP TABLE x;
|
||||||
|
|
||||||
--echo # MDEV-28622: Item_subselect eliminated flag set but Item still
|
--echo # MDEV-28622: Item_subselect eliminated flag set but Item still
|
||||||
|
@ -683,22 +683,24 @@ create table t3 (b int);
|
|||||||
insert into t2 values (1);
|
insert into t2 values (1);
|
||||||
insert into t3 values (1),(2);
|
insert into t3 values (1),(2);
|
||||||
INSERT INTO t1 (x) VALUES ((SELECT x FROM t1));
|
INSERT INTO t1 (x) VALUES ((SELECT x FROM t1));
|
||||||
ERROR HY000: Table 't1' is specified twice, both as a target for 'INSERT' and as a separate source for data
|
|
||||||
INSERT INTO t1 (x) VALUES ((SELECT b FROM t3));
|
INSERT INTO t1 (x) VALUES ((SELECT b FROM t3));
|
||||||
ERROR 21000: Subquery returns more than 1 row
|
ERROR 21000: Subquery returns more than 1 row
|
||||||
INSERT INTO t1 (x) VALUES ((SELECT a FROM t2));
|
INSERT INTO t1 (x) VALUES ((SELECT a FROM t2));
|
||||||
select * from t1;
|
select * from t1;
|
||||||
x
|
x
|
||||||
|
NULL
|
||||||
1
|
1
|
||||||
insert into t2 values (1);
|
insert into t2 values (1);
|
||||||
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
|
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
|
||||||
select * from t1;
|
select * from t1;
|
||||||
x
|
x
|
||||||
|
NULL
|
||||||
1
|
1
|
||||||
2
|
2
|
||||||
INSERT INTO t1 (x) select (SELECT SUM(a)+1 FROM t2) FROM t2;
|
INSERT INTO t1 (x) select (SELECT SUM(a)+1 FROM t2) FROM t2;
|
||||||
select * from t1;
|
select * from t1;
|
||||||
x
|
x
|
||||||
|
NULL
|
||||||
1
|
1
|
||||||
2
|
2
|
||||||
3
|
3
|
||||||
@ -706,6 +708,7 @@ x
|
|||||||
INSERT INTO t1 (x) select (SELECT SUM(x)+2 FROM t1) FROM t2;
|
INSERT INTO t1 (x) select (SELECT SUM(x)+2 FROM t1) FROM t2;
|
||||||
select * from t1;
|
select * from t1;
|
||||||
x
|
x
|
||||||
|
NULL
|
||||||
1
|
1
|
||||||
2
|
2
|
||||||
3
|
3
|
||||||
@ -715,6 +718,7 @@ x
|
|||||||
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
|
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
|
||||||
select * from t1;
|
select * from t1;
|
||||||
x
|
x
|
||||||
|
NULL
|
||||||
1
|
1
|
||||||
2
|
2
|
||||||
3
|
3
|
||||||
@ -731,7 +735,7 @@ insert into t3 values (1),(2);
|
|||||||
select * from t1;
|
select * from t1;
|
||||||
x y
|
x y
|
||||||
replace into t1 (x, y) VALUES ((SELECT x FROM t1), (SELECT a+1 FROM t2));
|
replace into t1 (x, y) VALUES ((SELECT x FROM t1), (SELECT a+1 FROM t2));
|
||||||
ERROR HY000: Table 't1' is specified twice, both as a target for 'INSERT' and as a separate source for data
|
ERROR 23000: Column 'x' cannot be null
|
||||||
replace into t1 (x, y) VALUES ((SELECT a FROM t3), (SELECT a+1 FROM t2));
|
replace into t1 (x, y) VALUES ((SELECT a FROM t3), (SELECT a+1 FROM t2));
|
||||||
ERROR 21000: Subquery returns more than 1 row
|
ERROR 21000: Subquery returns more than 1 row
|
||||||
replace into t1 (x, y) VALUES ((SELECT a FROM t2), (SELECT a+1 FROM t2));
|
replace into t1 (x, y) VALUES ((SELECT a FROM t2), (SELECT a+1 FROM t2));
|
||||||
@ -799,13 +803,21 @@ SELECT * FROM t2 WHERE id IN (SELECT 5 UNION SELECT 2);
|
|||||||
id
|
id
|
||||||
2
|
2
|
||||||
INSERT INTO t2 VALUES ((SELECT * FROM t2));
|
INSERT INTO t2 VALUES ((SELECT * FROM t2));
|
||||||
ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data
|
ERROR 21000: Subquery returns more than 1 row
|
||||||
INSERT INTO t2 VALUES ((SELECT id FROM t2));
|
INSERT INTO t2 VALUES ((SELECT id FROM t2));
|
||||||
ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data
|
ERROR 21000: Subquery returns more than 1 row
|
||||||
|
select * from t2;
|
||||||
|
id
|
||||||
|
1
|
||||||
|
2
|
||||||
|
INSERT INTO t2 VALUES ((SELECT count(*) FROM t2));
|
||||||
|
INSERT INTO t2 VALUES ((SELECT max(id) FROM t2));
|
||||||
SELECT * FROM t2;
|
SELECT * FROM t2;
|
||||||
id
|
id
|
||||||
1
|
1
|
||||||
2
|
2
|
||||||
|
2
|
||||||
|
2
|
||||||
CREATE TABLE t1 (id int(11) default NULL, KEY id (id)) ENGINE=MyISAM CHARSET=latin1;
|
CREATE TABLE t1 (id int(11) default NULL, KEY id (id)) ENGINE=MyISAM CHARSET=latin1;
|
||||||
INSERT INTO t1 values (1),(1);
|
INSERT INTO t1 values (1),(1);
|
||||||
UPDATE t2 SET id=(SELECT * FROM t1);
|
UPDATE t2 SET id=(SELECT * FROM t1);
|
||||||
|
@ -686,22 +686,24 @@ create table t3 (b int);
|
|||||||
insert into t2 values (1);
|
insert into t2 values (1);
|
||||||
insert into t3 values (1),(2);
|
insert into t3 values (1),(2);
|
||||||
INSERT INTO t1 (x) VALUES ((SELECT x FROM t1));
|
INSERT INTO t1 (x) VALUES ((SELECT x FROM t1));
|
||||||
ERROR HY000: Table 't1' is specified twice, both as a target for 'INSERT' and as a separate source for data
|
|
||||||
INSERT INTO t1 (x) VALUES ((SELECT b FROM t3));
|
INSERT INTO t1 (x) VALUES ((SELECT b FROM t3));
|
||||||
ERROR 21000: Subquery returns more than 1 row
|
ERROR 21000: Subquery returns more than 1 row
|
||||||
INSERT INTO t1 (x) VALUES ((SELECT a FROM t2));
|
INSERT INTO t1 (x) VALUES ((SELECT a FROM t2));
|
||||||
select * from t1;
|
select * from t1;
|
||||||
x
|
x
|
||||||
|
NULL
|
||||||
1
|
1
|
||||||
insert into t2 values (1);
|
insert into t2 values (1);
|
||||||
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
|
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
|
||||||
select * from t1;
|
select * from t1;
|
||||||
x
|
x
|
||||||
|
NULL
|
||||||
1
|
1
|
||||||
2
|
2
|
||||||
INSERT INTO t1 (x) select (SELECT SUM(a)+1 FROM t2) FROM t2;
|
INSERT INTO t1 (x) select (SELECT SUM(a)+1 FROM t2) FROM t2;
|
||||||
select * from t1;
|
select * from t1;
|
||||||
x
|
x
|
||||||
|
NULL
|
||||||
1
|
1
|
||||||
2
|
2
|
||||||
3
|
3
|
||||||
@ -709,6 +711,7 @@ x
|
|||||||
INSERT INTO t1 (x) select (SELECT SUM(x)+2 FROM t1) FROM t2;
|
INSERT INTO t1 (x) select (SELECT SUM(x)+2 FROM t1) FROM t2;
|
||||||
select * from t1;
|
select * from t1;
|
||||||
x
|
x
|
||||||
|
NULL
|
||||||
1
|
1
|
||||||
2
|
2
|
||||||
3
|
3
|
||||||
@ -718,6 +721,7 @@ x
|
|||||||
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
|
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
|
||||||
select * from t1;
|
select * from t1;
|
||||||
x
|
x
|
||||||
|
NULL
|
||||||
1
|
1
|
||||||
2
|
2
|
||||||
3
|
3
|
||||||
@ -734,7 +738,7 @@ insert into t3 values (1),(2);
|
|||||||
select * from t1;
|
select * from t1;
|
||||||
x y
|
x y
|
||||||
replace into t1 (x, y) VALUES ((SELECT x FROM t1), (SELECT a+1 FROM t2));
|
replace into t1 (x, y) VALUES ((SELECT x FROM t1), (SELECT a+1 FROM t2));
|
||||||
ERROR HY000: Table 't1' is specified twice, both as a target for 'INSERT' and as a separate source for data
|
ERROR 23000: Column 'x' cannot be null
|
||||||
replace into t1 (x, y) VALUES ((SELECT a FROM t3), (SELECT a+1 FROM t2));
|
replace into t1 (x, y) VALUES ((SELECT a FROM t3), (SELECT a+1 FROM t2));
|
||||||
ERROR 21000: Subquery returns more than 1 row
|
ERROR 21000: Subquery returns more than 1 row
|
||||||
replace into t1 (x, y) VALUES ((SELECT a FROM t2), (SELECT a+1 FROM t2));
|
replace into t1 (x, y) VALUES ((SELECT a FROM t2), (SELECT a+1 FROM t2));
|
||||||
@ -802,13 +806,21 @@ SELECT * FROM t2 WHERE id IN (SELECT 5 UNION SELECT 2);
|
|||||||
id
|
id
|
||||||
2
|
2
|
||||||
INSERT INTO t2 VALUES ((SELECT * FROM t2));
|
INSERT INTO t2 VALUES ((SELECT * FROM t2));
|
||||||
ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data
|
ERROR 21000: Subquery returns more than 1 row
|
||||||
INSERT INTO t2 VALUES ((SELECT id FROM t2));
|
INSERT INTO t2 VALUES ((SELECT id FROM t2));
|
||||||
ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data
|
ERROR 21000: Subquery returns more than 1 row
|
||||||
|
select * from t2;
|
||||||
|
id
|
||||||
|
1
|
||||||
|
2
|
||||||
|
INSERT INTO t2 VALUES ((SELECT count(*) FROM t2));
|
||||||
|
INSERT INTO t2 VALUES ((SELECT max(id) FROM t2));
|
||||||
SELECT * FROM t2;
|
SELECT * FROM t2;
|
||||||
id
|
id
|
||||||
1
|
1
|
||||||
2
|
2
|
||||||
|
2
|
||||||
|
2
|
||||||
CREATE TABLE t1 (id int(11) default NULL, KEY id (id)) ENGINE=MyISAM CHARSET=latin1;
|
CREATE TABLE t1 (id int(11) default NULL, KEY id (id)) ENGINE=MyISAM CHARSET=latin1;
|
||||||
INSERT INTO t1 values (1),(1);
|
INSERT INTO t1 values (1),(1);
|
||||||
UPDATE t2 SET id=(SELECT * FROM t1);
|
UPDATE t2 SET id=(SELECT * FROM t1);
|
||||||
|
@ -682,22 +682,24 @@ create table t3 (b int);
|
|||||||
insert into t2 values (1);
|
insert into t2 values (1);
|
||||||
insert into t3 values (1),(2);
|
insert into t3 values (1),(2);
|
||||||
INSERT INTO t1 (x) VALUES ((SELECT x FROM t1));
|
INSERT INTO t1 (x) VALUES ((SELECT x FROM t1));
|
||||||
ERROR HY000: Table 't1' is specified twice, both as a target for 'INSERT' and as a separate source for data
|
|
||||||
INSERT INTO t1 (x) VALUES ((SELECT b FROM t3));
|
INSERT INTO t1 (x) VALUES ((SELECT b FROM t3));
|
||||||
ERROR 21000: Subquery returns more than 1 row
|
ERROR 21000: Subquery returns more than 1 row
|
||||||
INSERT INTO t1 (x) VALUES ((SELECT a FROM t2));
|
INSERT INTO t1 (x) VALUES ((SELECT a FROM t2));
|
||||||
select * from t1;
|
select * from t1;
|
||||||
x
|
x
|
||||||
|
NULL
|
||||||
1
|
1
|
||||||
insert into t2 values (1);
|
insert into t2 values (1);
|
||||||
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
|
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
|
||||||
select * from t1;
|
select * from t1;
|
||||||
x
|
x
|
||||||
|
NULL
|
||||||
1
|
1
|
||||||
2
|
2
|
||||||
INSERT INTO t1 (x) select (SELECT SUM(a)+1 FROM t2) FROM t2;
|
INSERT INTO t1 (x) select (SELECT SUM(a)+1 FROM t2) FROM t2;
|
||||||
select * from t1;
|
select * from t1;
|
||||||
x
|
x
|
||||||
|
NULL
|
||||||
1
|
1
|
||||||
2
|
2
|
||||||
3
|
3
|
||||||
@ -705,6 +707,7 @@ x
|
|||||||
INSERT INTO t1 (x) select (SELECT SUM(x)+2 FROM t1) FROM t2;
|
INSERT INTO t1 (x) select (SELECT SUM(x)+2 FROM t1) FROM t2;
|
||||||
select * from t1;
|
select * from t1;
|
||||||
x
|
x
|
||||||
|
NULL
|
||||||
1
|
1
|
||||||
2
|
2
|
||||||
3
|
3
|
||||||
@ -714,6 +717,7 @@ x
|
|||||||
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
|
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
|
||||||
select * from t1;
|
select * from t1;
|
||||||
x
|
x
|
||||||
|
NULL
|
||||||
1
|
1
|
||||||
2
|
2
|
||||||
3
|
3
|
||||||
@ -730,7 +734,7 @@ insert into t3 values (1),(2);
|
|||||||
select * from t1;
|
select * from t1;
|
||||||
x y
|
x y
|
||||||
replace into t1 (x, y) VALUES ((SELECT x FROM t1), (SELECT a+1 FROM t2));
|
replace into t1 (x, y) VALUES ((SELECT x FROM t1), (SELECT a+1 FROM t2));
|
||||||
ERROR HY000: Table 't1' is specified twice, both as a target for 'INSERT' and as a separate source for data
|
ERROR 23000: Column 'x' cannot be null
|
||||||
replace into t1 (x, y) VALUES ((SELECT a FROM t3), (SELECT a+1 FROM t2));
|
replace into t1 (x, y) VALUES ((SELECT a FROM t3), (SELECT a+1 FROM t2));
|
||||||
ERROR 21000: Subquery returns more than 1 row
|
ERROR 21000: Subquery returns more than 1 row
|
||||||
replace into t1 (x, y) VALUES ((SELECT a FROM t2), (SELECT a+1 FROM t2));
|
replace into t1 (x, y) VALUES ((SELECT a FROM t2), (SELECT a+1 FROM t2));
|
||||||
@ -798,13 +802,21 @@ SELECT * FROM t2 WHERE id IN (SELECT 5 UNION SELECT 2);
|
|||||||
id
|
id
|
||||||
2
|
2
|
||||||
INSERT INTO t2 VALUES ((SELECT * FROM t2));
|
INSERT INTO t2 VALUES ((SELECT * FROM t2));
|
||||||
ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data
|
ERROR 21000: Subquery returns more than 1 row
|
||||||
INSERT INTO t2 VALUES ((SELECT id FROM t2));
|
INSERT INTO t2 VALUES ((SELECT id FROM t2));
|
||||||
ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data
|
ERROR 21000: Subquery returns more than 1 row
|
||||||
|
select * from t2;
|
||||||
|
id
|
||||||
|
1
|
||||||
|
2
|
||||||
|
INSERT INTO t2 VALUES ((SELECT count(*) FROM t2));
|
||||||
|
INSERT INTO t2 VALUES ((SELECT max(id) FROM t2));
|
||||||
SELECT * FROM t2;
|
SELECT * FROM t2;
|
||||||
id
|
id
|
||||||
1
|
1
|
||||||
2
|
2
|
||||||
|
2
|
||||||
|
2
|
||||||
CREATE TABLE t1 (id int(11) default NULL, KEY id (id)) ENGINE=MyISAM CHARSET=latin1;
|
CREATE TABLE t1 (id int(11) default NULL, KEY id (id)) ENGINE=MyISAM CHARSET=latin1;
|
||||||
INSERT INTO t1 values (1),(1);
|
INSERT INTO t1 values (1),(1);
|
||||||
UPDATE t2 SET id=(SELECT * FROM t1);
|
UPDATE t2 SET id=(SELECT * FROM t1);
|
||||||
|
@ -685,22 +685,24 @@ create table t3 (b int);
|
|||||||
insert into t2 values (1);
|
insert into t2 values (1);
|
||||||
insert into t3 values (1),(2);
|
insert into t3 values (1),(2);
|
||||||
INSERT INTO t1 (x) VALUES ((SELECT x FROM t1));
|
INSERT INTO t1 (x) VALUES ((SELECT x FROM t1));
|
||||||
ERROR HY000: Table 't1' is specified twice, both as a target for 'INSERT' and as a separate source for data
|
|
||||||
INSERT INTO t1 (x) VALUES ((SELECT b FROM t3));
|
INSERT INTO t1 (x) VALUES ((SELECT b FROM t3));
|
||||||
ERROR 21000: Subquery returns more than 1 row
|
ERROR 21000: Subquery returns more than 1 row
|
||||||
INSERT INTO t1 (x) VALUES ((SELECT a FROM t2));
|
INSERT INTO t1 (x) VALUES ((SELECT a FROM t2));
|
||||||
select * from t1;
|
select * from t1;
|
||||||
x
|
x
|
||||||
|
NULL
|
||||||
1
|
1
|
||||||
insert into t2 values (1);
|
insert into t2 values (1);
|
||||||
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
|
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
|
||||||
select * from t1;
|
select * from t1;
|
||||||
x
|
x
|
||||||
|
NULL
|
||||||
1
|
1
|
||||||
2
|
2
|
||||||
INSERT INTO t1 (x) select (SELECT SUM(a)+1 FROM t2) FROM t2;
|
INSERT INTO t1 (x) select (SELECT SUM(a)+1 FROM t2) FROM t2;
|
||||||
select * from t1;
|
select * from t1;
|
||||||
x
|
x
|
||||||
|
NULL
|
||||||
1
|
1
|
||||||
2
|
2
|
||||||
3
|
3
|
||||||
@ -708,6 +710,7 @@ x
|
|||||||
INSERT INTO t1 (x) select (SELECT SUM(x)+2 FROM t1) FROM t2;
|
INSERT INTO t1 (x) select (SELECT SUM(x)+2 FROM t1) FROM t2;
|
||||||
select * from t1;
|
select * from t1;
|
||||||
x
|
x
|
||||||
|
NULL
|
||||||
1
|
1
|
||||||
2
|
2
|
||||||
3
|
3
|
||||||
@ -717,6 +720,7 @@ x
|
|||||||
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
|
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
|
||||||
select * from t1;
|
select * from t1;
|
||||||
x
|
x
|
||||||
|
NULL
|
||||||
1
|
1
|
||||||
2
|
2
|
||||||
3
|
3
|
||||||
@ -733,7 +737,7 @@ insert into t3 values (1),(2);
|
|||||||
select * from t1;
|
select * from t1;
|
||||||
x y
|
x y
|
||||||
replace into t1 (x, y) VALUES ((SELECT x FROM t1), (SELECT a+1 FROM t2));
|
replace into t1 (x, y) VALUES ((SELECT x FROM t1), (SELECT a+1 FROM t2));
|
||||||
ERROR HY000: Table 't1' is specified twice, both as a target for 'INSERT' and as a separate source for data
|
ERROR 23000: Column 'x' cannot be null
|
||||||
replace into t1 (x, y) VALUES ((SELECT a FROM t3), (SELECT a+1 FROM t2));
|
replace into t1 (x, y) VALUES ((SELECT a FROM t3), (SELECT a+1 FROM t2));
|
||||||
ERROR 21000: Subquery returns more than 1 row
|
ERROR 21000: Subquery returns more than 1 row
|
||||||
replace into t1 (x, y) VALUES ((SELECT a FROM t2), (SELECT a+1 FROM t2));
|
replace into t1 (x, y) VALUES ((SELECT a FROM t2), (SELECT a+1 FROM t2));
|
||||||
@ -801,13 +805,21 @@ SELECT * FROM t2 WHERE id IN (SELECT 5 UNION SELECT 2);
|
|||||||
id
|
id
|
||||||
2
|
2
|
||||||
INSERT INTO t2 VALUES ((SELECT * FROM t2));
|
INSERT INTO t2 VALUES ((SELECT * FROM t2));
|
||||||
ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data
|
ERROR 21000: Subquery returns more than 1 row
|
||||||
INSERT INTO t2 VALUES ((SELECT id FROM t2));
|
INSERT INTO t2 VALUES ((SELECT id FROM t2));
|
||||||
ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data
|
ERROR 21000: Subquery returns more than 1 row
|
||||||
|
select * from t2;
|
||||||
|
id
|
||||||
|
1
|
||||||
|
2
|
||||||
|
INSERT INTO t2 VALUES ((SELECT count(*) FROM t2));
|
||||||
|
INSERT INTO t2 VALUES ((SELECT max(id) FROM t2));
|
||||||
SELECT * FROM t2;
|
SELECT * FROM t2;
|
||||||
id
|
id
|
||||||
1
|
1
|
||||||
2
|
2
|
||||||
|
2
|
||||||
|
2
|
||||||
CREATE TABLE t1 (id int(11) default NULL, KEY id (id)) ENGINE=MyISAM CHARSET=latin1;
|
CREATE TABLE t1 (id int(11) default NULL, KEY id (id)) ENGINE=MyISAM CHARSET=latin1;
|
||||||
INSERT INTO t1 values (1),(1);
|
INSERT INTO t1 values (1),(1);
|
||||||
UPDATE t2 SET id=(SELECT * FROM t1);
|
UPDATE t2 SET id=(SELECT * FROM t1);
|
||||||
|
@ -682,22 +682,24 @@ create table t3 (b int);
|
|||||||
insert into t2 values (1);
|
insert into t2 values (1);
|
||||||
insert into t3 values (1),(2);
|
insert into t3 values (1),(2);
|
||||||
INSERT INTO t1 (x) VALUES ((SELECT x FROM t1));
|
INSERT INTO t1 (x) VALUES ((SELECT x FROM t1));
|
||||||
ERROR HY000: Table 't1' is specified twice, both as a target for 'INSERT' and as a separate source for data
|
|
||||||
INSERT INTO t1 (x) VALUES ((SELECT b FROM t3));
|
INSERT INTO t1 (x) VALUES ((SELECT b FROM t3));
|
||||||
ERROR 21000: Subquery returns more than 1 row
|
ERROR 21000: Subquery returns more than 1 row
|
||||||
INSERT INTO t1 (x) VALUES ((SELECT a FROM t2));
|
INSERT INTO t1 (x) VALUES ((SELECT a FROM t2));
|
||||||
select * from t1;
|
select * from t1;
|
||||||
x
|
x
|
||||||
|
NULL
|
||||||
1
|
1
|
||||||
insert into t2 values (1);
|
insert into t2 values (1);
|
||||||
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
|
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
|
||||||
select * from t1;
|
select * from t1;
|
||||||
x
|
x
|
||||||
|
NULL
|
||||||
1
|
1
|
||||||
2
|
2
|
||||||
INSERT INTO t1 (x) select (SELECT SUM(a)+1 FROM t2) FROM t2;
|
INSERT INTO t1 (x) select (SELECT SUM(a)+1 FROM t2) FROM t2;
|
||||||
select * from t1;
|
select * from t1;
|
||||||
x
|
x
|
||||||
|
NULL
|
||||||
1
|
1
|
||||||
2
|
2
|
||||||
3
|
3
|
||||||
@ -705,6 +707,7 @@ x
|
|||||||
INSERT INTO t1 (x) select (SELECT SUM(x)+2 FROM t1) FROM t2;
|
INSERT INTO t1 (x) select (SELECT SUM(x)+2 FROM t1) FROM t2;
|
||||||
select * from t1;
|
select * from t1;
|
||||||
x
|
x
|
||||||
|
NULL
|
||||||
1
|
1
|
||||||
2
|
2
|
||||||
3
|
3
|
||||||
@ -714,6 +717,7 @@ x
|
|||||||
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
|
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
|
||||||
select * from t1;
|
select * from t1;
|
||||||
x
|
x
|
||||||
|
NULL
|
||||||
1
|
1
|
||||||
2
|
2
|
||||||
3
|
3
|
||||||
@ -730,7 +734,7 @@ insert into t3 values (1),(2);
|
|||||||
select * from t1;
|
select * from t1;
|
||||||
x y
|
x y
|
||||||
replace into t1 (x, y) VALUES ((SELECT x FROM t1), (SELECT a+1 FROM t2));
|
replace into t1 (x, y) VALUES ((SELECT x FROM t1), (SELECT a+1 FROM t2));
|
||||||
ERROR HY000: Table 't1' is specified twice, both as a target for 'INSERT' and as a separate source for data
|
ERROR 23000: Column 'x' cannot be null
|
||||||
replace into t1 (x, y) VALUES ((SELECT a FROM t3), (SELECT a+1 FROM t2));
|
replace into t1 (x, y) VALUES ((SELECT a FROM t3), (SELECT a+1 FROM t2));
|
||||||
ERROR 21000: Subquery returns more than 1 row
|
ERROR 21000: Subquery returns more than 1 row
|
||||||
replace into t1 (x, y) VALUES ((SELECT a FROM t2), (SELECT a+1 FROM t2));
|
replace into t1 (x, y) VALUES ((SELECT a FROM t2), (SELECT a+1 FROM t2));
|
||||||
@ -798,13 +802,21 @@ SELECT * FROM t2 WHERE id IN (SELECT 5 UNION SELECT 2);
|
|||||||
id
|
id
|
||||||
2
|
2
|
||||||
INSERT INTO t2 VALUES ((SELECT * FROM t2));
|
INSERT INTO t2 VALUES ((SELECT * FROM t2));
|
||||||
ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data
|
ERROR 21000: Subquery returns more than 1 row
|
||||||
INSERT INTO t2 VALUES ((SELECT id FROM t2));
|
INSERT INTO t2 VALUES ((SELECT id FROM t2));
|
||||||
ERROR HY000: Table 't2' is specified twice, both as a target for 'INSERT' and as a separate source for data
|
ERROR 21000: Subquery returns more than 1 row
|
||||||
|
select * from t2;
|
||||||
|
id
|
||||||
|
1
|
||||||
|
2
|
||||||
|
INSERT INTO t2 VALUES ((SELECT count(*) FROM t2));
|
||||||
|
INSERT INTO t2 VALUES ((SELECT max(id) FROM t2));
|
||||||
SELECT * FROM t2;
|
SELECT * FROM t2;
|
||||||
id
|
id
|
||||||
1
|
1
|
||||||
2
|
2
|
||||||
|
2
|
||||||
|
2
|
||||||
CREATE TABLE t1 (id int(11) default NULL, KEY id (id)) ENGINE=MyISAM CHARSET=latin1;
|
CREATE TABLE t1 (id int(11) default NULL, KEY id (id)) ENGINE=MyISAM CHARSET=latin1;
|
||||||
INSERT INTO t1 values (1),(1);
|
INSERT INTO t1 values (1),(1);
|
||||||
UPDATE t2 SET id=(SELECT * FROM t1);
|
UPDATE t2 SET id=(SELECT * FROM t1);
|
||||||
|
@ -944,31 +944,19 @@ create view v1 as select * from t1;
|
|||||||
create view v2 as select * from v1;
|
create view v2 as select * from v1;
|
||||||
create view v3 as select v2.col1 from v2,t2 where v2.col1 = t2.col1;
|
create view v3 as select v2.col1 from v2,t2 where v2.col1 = t2.col1;
|
||||||
insert into v2 values ((select max(col1) from v1));
|
insert into v2 values ((select max(col1) from v1));
|
||||||
ERROR HY000: The definition of table 'v1' prevents operation INSERT on table 'v2'
|
|
||||||
insert into t1 values ((select max(col1) from v1));
|
insert into t1 values ((select max(col1) from v1));
|
||||||
ERROR HY000: The definition of table 'v1' prevents operation INSERT on table 't1'
|
|
||||||
insert into v2 values ((select max(col1) from v1));
|
insert into v2 values ((select max(col1) from v1));
|
||||||
ERROR HY000: The definition of table 'v1' prevents operation INSERT on table 'v2'
|
|
||||||
insert into v2 values ((select max(col1) from t1));
|
insert into v2 values ((select max(col1) from t1));
|
||||||
ERROR HY000: The definition of table 'v2' prevents operation INSERT on table 'v2'
|
|
||||||
insert into t1 values ((select max(col1) from t1));
|
insert into t1 values ((select max(col1) from t1));
|
||||||
ERROR HY000: Table 't1' is specified twice, both as a target for 'INSERT' and as a separate source for data
|
|
||||||
insert into v2 values ((select max(col1) from t1));
|
insert into v2 values ((select max(col1) from t1));
|
||||||
ERROR HY000: The definition of table 'v2' prevents operation INSERT on table 'v2'
|
|
||||||
insert into v2 values ((select max(col1) from v2));
|
insert into v2 values ((select max(col1) from v2));
|
||||||
ERROR HY000: Table 'v2' is specified twice, both as a target for 'INSERT' and as a separate source for data
|
|
||||||
insert into t1 values ((select max(col1) from v2));
|
insert into t1 values ((select max(col1) from v2));
|
||||||
ERROR HY000: The definition of table 'v2' prevents operation INSERT on table 't1'
|
|
||||||
insert into v2 values ((select max(col1) from v2));
|
insert into v2 values ((select max(col1) from v2));
|
||||||
ERROR HY000: Table 'v2' is specified twice, both as a target for 'INSERT' and as a separate source for data
|
|
||||||
insert into v3 (col1) values ((select max(col1) from v1));
|
insert into v3 (col1) values ((select max(col1) from v1));
|
||||||
ERROR HY000: The definition of table 'v1' prevents operation INSERT on table 'v3'
|
|
||||||
insert into v3 (col1) values ((select max(col1) from t1));
|
insert into v3 (col1) values ((select max(col1) from t1));
|
||||||
ERROR HY000: The definition of table 'v3' prevents operation INSERT on table 'v3'
|
|
||||||
insert into v3 (col1) values ((select max(col1) from v2));
|
insert into v3 (col1) values ((select max(col1) from v2));
|
||||||
ERROR HY000: The definition of table 'v2' prevents operation INSERT on table 'v3'
|
insert into v3 (col1) values ((select CONVERT_TZ('20050101000000','UTC','MET') from v2 LIMIT 1));
|
||||||
insert into v3 (col1) values ((select CONVERT_TZ('20050101000000','UTC','MET') from v2));
|
ERROR 22003: Out of range value for column 'col1' at row 2
|
||||||
ERROR HY000: The definition of table 'v2' prevents operation INSERT on table 'v3'
|
|
||||||
insert into v3 (col1) values ((select CONVERT_TZ('20050101000000','UTC','MET') from t2));
|
insert into v3 (col1) values ((select CONVERT_TZ('20050101000000','UTC','MET') from t2));
|
||||||
insert into t3 values ((select CONVERT_TZ('20050101000000','UTC','MET') from t2));
|
insert into t3 values ((select CONVERT_TZ('20050101000000','UTC','MET') from t2));
|
||||||
ERROR 23000: Column 'col1' cannot be null
|
ERROR 23000: Column 'col1' cannot be null
|
||||||
@ -978,6 +966,18 @@ insert into t1 (col1) values ((select max(col1) from v4));
|
|||||||
select * from t1;
|
select * from t1;
|
||||||
col1
|
col1
|
||||||
NULL
|
NULL
|
||||||
|
NULL
|
||||||
|
NULL
|
||||||
|
NULL
|
||||||
|
NULL
|
||||||
|
NULL
|
||||||
|
NULL
|
||||||
|
NULL
|
||||||
|
NULL
|
||||||
|
NULL
|
||||||
|
NULL
|
||||||
|
NULL
|
||||||
|
NULL
|
||||||
1
|
1
|
||||||
2
|
2
|
||||||
3
|
3
|
||||||
@ -1332,9 +1332,26 @@ create view v3 as select * from t1 where 20 < (select (s1) from v2);
|
|||||||
insert into v3 values (30);
|
insert into v3 values (30);
|
||||||
ERROR HY000: The target table v3 of the INSERT is not insertable-into
|
ERROR HY000: The target table v3 of the INSERT is not insertable-into
|
||||||
create view v4 as select * from v2 where 20 < (select (s1) from t1);
|
create view v4 as select * from v2 where 20 < (select (s1) from t1);
|
||||||
|
select * from t1;
|
||||||
|
s1
|
||||||
insert into v4 values (30);
|
insert into v4 values (30);
|
||||||
ERROR HY000: The target table v4 of the INSERT is not insertable-into
|
select * from t1;
|
||||||
drop view v4, v3, v2, v1;
|
s1
|
||||||
|
30
|
||||||
|
create view v5 as select * from v2 where s1 < (select min(s1) from t1) WITH CHECK OPTION;
|
||||||
|
# can't insert only less then minimum
|
||||||
|
insert into v5 values (40);
|
||||||
|
ERROR 44000: CHECK OPTION failed `test`.`v5`
|
||||||
|
# allow insert the new minimum
|
||||||
|
insert into v5 values (10);
|
||||||
|
# always emply view (can't be something less than minimum)
|
||||||
|
select * from v5;
|
||||||
|
s1
|
||||||
|
select * from t1;
|
||||||
|
s1
|
||||||
|
30
|
||||||
|
10
|
||||||
|
drop view v5, v4, v3, v2, v1;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
create table t1 (a int);
|
create table t1 (a int);
|
||||||
create view v1 as select * from t1;
|
create view v1 as select * from t1;
|
||||||
|
@ -865,33 +865,21 @@ create table t3 (col1 datetime not null);
|
|||||||
create view v1 as select * from t1;
|
create view v1 as select * from t1;
|
||||||
create view v2 as select * from v1;
|
create view v2 as select * from v1;
|
||||||
create view v3 as select v2.col1 from v2,t2 where v2.col1 = t2.col1;
|
create view v3 as select v2.col1 from v2,t2 where v2.col1 = t2.col1;
|
||||||
-- error ER_VIEW_PREVENT_UPDATE
|
|
||||||
insert into v2 values ((select max(col1) from v1));
|
insert into v2 values ((select max(col1) from v1));
|
||||||
-- error ER_VIEW_PREVENT_UPDATE
|
|
||||||
insert into t1 values ((select max(col1) from v1));
|
insert into t1 values ((select max(col1) from v1));
|
||||||
-- error ER_VIEW_PREVENT_UPDATE
|
|
||||||
insert into v2 values ((select max(col1) from v1));
|
insert into v2 values ((select max(col1) from v1));
|
||||||
-- error ER_VIEW_PREVENT_UPDATE
|
|
||||||
insert into v2 values ((select max(col1) from t1));
|
insert into v2 values ((select max(col1) from t1));
|
||||||
-- error ER_UPDATE_TABLE_USED
|
|
||||||
insert into t1 values ((select max(col1) from t1));
|
insert into t1 values ((select max(col1) from t1));
|
||||||
-- error ER_VIEW_PREVENT_UPDATE
|
|
||||||
insert into v2 values ((select max(col1) from t1));
|
insert into v2 values ((select max(col1) from t1));
|
||||||
-- error ER_UPDATE_TABLE_USED
|
|
||||||
insert into v2 values ((select max(col1) from v2));
|
insert into v2 values ((select max(col1) from v2));
|
||||||
-- error ER_VIEW_PREVENT_UPDATE
|
|
||||||
insert into t1 values ((select max(col1) from v2));
|
insert into t1 values ((select max(col1) from v2));
|
||||||
-- error ER_UPDATE_TABLE_USED
|
|
||||||
insert into v2 values ((select max(col1) from v2));
|
insert into v2 values ((select max(col1) from v2));
|
||||||
-- error ER_VIEW_PREVENT_UPDATE
|
|
||||||
insert into v3 (col1) values ((select max(col1) from v1));
|
insert into v3 (col1) values ((select max(col1) from v1));
|
||||||
-- error ER_VIEW_PREVENT_UPDATE
|
|
||||||
insert into v3 (col1) values ((select max(col1) from t1));
|
insert into v3 (col1) values ((select max(col1) from t1));
|
||||||
-- error ER_VIEW_PREVENT_UPDATE
|
|
||||||
insert into v3 (col1) values ((select max(col1) from v2));
|
insert into v3 (col1) values ((select max(col1) from v2));
|
||||||
# check with TZ tables in list
|
# check with TZ tables in list
|
||||||
-- error ER_VIEW_PREVENT_UPDATE
|
--error ER_WARN_DATA_OUT_OF_RANGE
|
||||||
insert into v3 (col1) values ((select CONVERT_TZ('20050101000000','UTC','MET') from v2));
|
insert into v3 (col1) values ((select CONVERT_TZ('20050101000000','UTC','MET') from v2 LIMIT 1));
|
||||||
insert into v3 (col1) values ((select CONVERT_TZ('20050101000000','UTC','MET') from t2));
|
insert into v3 (col1) values ((select CONVERT_TZ('20050101000000','UTC','MET') from t2));
|
||||||
-- error ER_BAD_NULL_ERROR
|
-- error ER_BAD_NULL_ERROR
|
||||||
insert into t3 values ((select CONVERT_TZ('20050101000000','UTC','MET') from t2));
|
insert into t3 values ((select CONVERT_TZ('20050101000000','UTC','MET') from t2));
|
||||||
@ -1209,9 +1197,19 @@ create view v3 as select * from t1 where 20 < (select (s1) from v2);
|
|||||||
-- error ER_NON_INSERTABLE_TABLE
|
-- error ER_NON_INSERTABLE_TABLE
|
||||||
insert into v3 values (30);
|
insert into v3 values (30);
|
||||||
create view v4 as select * from v2 where 20 < (select (s1) from t1);
|
create view v4 as select * from v2 where 20 < (select (s1) from t1);
|
||||||
-- error ER_NON_INSERTABLE_TABLE
|
select * from t1;
|
||||||
insert into v4 values (30);
|
insert into v4 values (30);
|
||||||
drop view v4, v3, v2, v1;
|
select * from t1;
|
||||||
|
create view v5 as select * from v2 where s1 < (select min(s1) from t1) WITH CHECK OPTION;
|
||||||
|
--echo # can't insert only less then minimum
|
||||||
|
--error ER_VIEW_CHECK_FAILED
|
||||||
|
insert into v5 values (40);
|
||||||
|
--echo # allow insert the new minimum
|
||||||
|
insert into v5 values (10);
|
||||||
|
--echo # always emply view (can't be something less than minimum)
|
||||||
|
select * from v5;
|
||||||
|
select * from t1;
|
||||||
|
drop view v5, v4, v3, v2, v1;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -48,7 +48,6 @@ create sequence s2;
|
|||||||
insert into s1 (next_not_cached_value, minimum_value) values (100,1000);
|
insert into s1 (next_not_cached_value, minimum_value) values (100,1000);
|
||||||
ERROR HY000: Field 'maximum_value' doesn't have a default value
|
ERROR HY000: Field 'maximum_value' doesn't have a default value
|
||||||
insert into s1 values (next value for s1, 1,9223372036854775806,1,1,1000,0,0);
|
insert into s1 values (next value for s1, 1,9223372036854775806,1,1,1000,0,0);
|
||||||
ERROR HY000: Table 's1' is specified twice, both as a target for 'INSERT' and as a separate source for data
|
|
||||||
insert into s1 values(1000,9223372036854775806,1,1,1,1000,0,0);
|
insert into s1 values(1000,9223372036854775806,1,1,1,1000,0,0);
|
||||||
ERROR HY000: Sequence 'test.s1' has out of range value for options
|
ERROR HY000: Sequence 'test.s1' has out of range value for options
|
||||||
insert into s1 values(0,9223372036854775806,1,1,1,1000,0,0);
|
insert into s1 values(0,9223372036854775806,1,1,1,1000,0,0);
|
||||||
|
@ -38,7 +38,6 @@ create sequence s1;
|
|||||||
create sequence s2;
|
create sequence s2;
|
||||||
--error ER_NO_DEFAULT_FOR_FIELD
|
--error ER_NO_DEFAULT_FOR_FIELD
|
||||||
insert into s1 (next_not_cached_value, minimum_value) values (100,1000);
|
insert into s1 (next_not_cached_value, minimum_value) values (100,1000);
|
||||||
--error ER_UPDATE_TABLE_USED
|
|
||||||
insert into s1 values (next value for s1, 1,9223372036854775806,1,1,1000,0,0);
|
insert into s1 values (next value for s1, 1,9223372036854775806,1,1,1000,0,0);
|
||||||
--error ER_SEQUENCE_INVALID_DATA
|
--error ER_SEQUENCE_INVALID_DATA
|
||||||
insert into s1 values(1000,9223372036854775806,1,1,1,1000,0,0);
|
insert into s1 values(1000,9223372036854775806,1,1,1,1000,0,0);
|
||||||
|
12
sql/item.h
12
sql/item.h
@ -723,6 +723,17 @@ public:
|
|||||||
virtual const String *const_ptr_string() const { return NULL; }
|
virtual const String *const_ptr_string() const { return NULL; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct subselect_table_finder_param
|
||||||
|
{
|
||||||
|
THD *thd;
|
||||||
|
/*
|
||||||
|
We're searching for different TABLE_LIST objects referring to the same
|
||||||
|
table as this one
|
||||||
|
*/
|
||||||
|
const TABLE_LIST *find;
|
||||||
|
/* NUL - not found, ERROR_TABLE - search error, or the found table reference */
|
||||||
|
TABLE_LIST *dup;
|
||||||
|
};
|
||||||
|
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
|
|
||||||
@ -2068,6 +2079,7 @@ public:
|
|||||||
set_extraction_flag(*(int*)arg);
|
set_extraction_flag(*(int*)arg);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
virtual bool subselect_table_finder_processor(void *arg) { return 0; };
|
||||||
|
|
||||||
/*
|
/*
|
||||||
TRUE if the expression depends only on the table indicated by tab_map
|
TRUE if the expression depends only on the table indicated by tab_map
|
||||||
|
@ -7078,3 +7078,27 @@ void Subq_materialization_tracker::report_partial_merge_keys(
|
|||||||
for (uint i= 0; i < merge_keys_count; i++)
|
for (uint i= 0; i < merge_keys_count; i++)
|
||||||
partial_match_array_sizes[i]= merge_keys[i]->get_key_buff_elements();
|
partial_match_array_sizes[i]= merge_keys[i]->get_key_buff_elements();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Check if somewhere inside this subselect we read the table. This means a
|
||||||
|
full read "(SELECT ... FROM tbl)", outside reference to tbl.column does not
|
||||||
|
count
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool
|
||||||
|
Item_subselect::subselect_table_finder_processor(void *arg)
|
||||||
|
{
|
||||||
|
subselect_table_finder_param *param= (subselect_table_finder_param *)arg;
|
||||||
|
for (SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select())
|
||||||
|
{
|
||||||
|
TABLE_LIST *dup;
|
||||||
|
if ((dup= sl->find_table(param->thd, ¶m->find->db,
|
||||||
|
¶m->find->table_name)))
|
||||||
|
{
|
||||||
|
param->dup= dup;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
};
|
||||||
|
@ -277,6 +277,7 @@ public:
|
|||||||
{
|
{
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
bool subselect_table_finder_processor(void *arg) override;
|
||||||
|
|
||||||
void register_as_with_rec_ref(With_element *with_elem);
|
void register_as_with_rec_ref(With_element *with_elem);
|
||||||
void init_expr_cache_tracker(THD *thd);
|
void init_expr_cache_tracker(THD *thd);
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
#include "mariadb.h"
|
#include "mariadb.h"
|
||||||
#include "sql_base.h" // setup_table_map
|
#include "sql_base.h" // setup_table_map
|
||||||
|
#include "sql_list.h"
|
||||||
#include "sql_priv.h"
|
#include "sql_priv.h"
|
||||||
#include "unireg.h"
|
#include "unireg.h"
|
||||||
#include "debug_sync.h"
|
#include "debug_sync.h"
|
||||||
@ -1122,7 +1123,6 @@ TABLE_LIST* find_dup_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list,
|
|||||||
t_name= &table->table_name;
|
t_name= &table->table_name;
|
||||||
t_alias= &table->alias;
|
t_alias= &table->alias;
|
||||||
|
|
||||||
retry:
|
|
||||||
DBUG_PRINT("info", ("real table: %s.%s", d_name->str, t_name->str));
|
DBUG_PRINT("info", ("real table: %s.%s", d_name->str, t_name->str));
|
||||||
for (TABLE_LIST *tl= table_list; tl ; tl= tl->next_global, res= 0)
|
for (TABLE_LIST *tl= table_list; tl ; tl= tl->next_global, res= 0)
|
||||||
{
|
{
|
||||||
@ -1184,37 +1184,53 @@ retry:
|
|||||||
DBUG_PRINT("info",
|
DBUG_PRINT("info",
|
||||||
("found same copy of table or table which we should skip"));
|
("found same copy of table or table which we should skip"));
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
If we've found a duplicate in a derived table, try to work around that.
|
|
||||||
|
|
||||||
For INSERT...SELECT, do not do any workarounds, return the duplicate. The
|
|
||||||
caller will enable buffering to handle this.
|
|
||||||
*/
|
|
||||||
if (res && res->belong_to_derived &&
|
|
||||||
!(check_flag & CHECK_DUP_FOR_INSERT_SELECT))
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
We come here for queries like this:
|
|
||||||
|
|
||||||
INSERT INTO t1 VALUES ((SELECT tmp.a FROM (select * FROM t1)));
|
|
||||||
DELETE FROM t1 WHERE ( ... (SELECT ... FROM t1) ) ;
|
|
||||||
|
|
||||||
Try to fix by materializing the derived table
|
|
||||||
*/
|
|
||||||
TABLE_LIST *derived= res->belong_to_derived;
|
|
||||||
if (derived->is_merged_derived() && !derived->derived->is_excluded())
|
|
||||||
{
|
|
||||||
DBUG_PRINT("info",
|
|
||||||
("convert merged to materialization to resolve the conflict"));
|
|
||||||
derived->change_refs_to_fields();
|
|
||||||
derived->set_materialized_derived();
|
|
||||||
goto retry;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DBUG_RETURN(res);
|
DBUG_RETURN(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TABLE_LIST* unique_table_in_select_list(THD *thd, TABLE_LIST *table, SELECT_LEX *sel)
|
||||||
|
{
|
||||||
|
subselect_table_finder_param param= {thd, table, NULL};
|
||||||
|
List_iterator_fast<Item> it(sel->item_list);
|
||||||
|
Item *item;
|
||||||
|
while ((item= it++))
|
||||||
|
{
|
||||||
|
if (item->walk(&Item::subselect_table_finder_processor, FALSE, ¶m))
|
||||||
|
{
|
||||||
|
if (param.dup == NULL)
|
||||||
|
return ERROR_TABLE;
|
||||||
|
return param.dup;
|
||||||
|
}
|
||||||
|
DBUG_ASSERT(param.dup == NULL);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
typedef TABLE_LIST* (*find_table_callback)(THD *thd, TABLE_LIST *table,
|
||||||
|
TABLE_LIST *table_list,
|
||||||
|
uint check_flag, SELECT_LEX *sel);
|
||||||
|
|
||||||
|
static
|
||||||
|
TABLE_LIST*
|
||||||
|
find_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list,
|
||||||
|
uint check_flag, SELECT_LEX *sel, find_table_callback callback );
|
||||||
|
|
||||||
|
TABLE_LIST* unique_table_callback(THD *thd, TABLE_LIST *table,
|
||||||
|
TABLE_LIST *table_list,
|
||||||
|
uint check_flag, SELECT_LEX *sel)
|
||||||
|
{
|
||||||
|
return find_dup_table(thd, table, table_list, check_flag);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TABLE_LIST* unique_in_sel_table_callback(THD *thd, TABLE_LIST *table,
|
||||||
|
TABLE_LIST *table_list,
|
||||||
|
uint check_flag, SELECT_LEX *sel)
|
||||||
|
{
|
||||||
|
return unique_table_in_select_list(thd, table, sel);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Test that the subject table of INSERT/UPDATE/DELETE/CREATE
|
Test that the subject table of INSERT/UPDATE/DELETE/CREATE
|
||||||
or (in case of MyISAMMRG) one of its children are not used later
|
or (in case of MyISAMMRG) one of its children are not used later
|
||||||
@ -1233,6 +1249,25 @@ retry:
|
|||||||
TABLE_LIST*
|
TABLE_LIST*
|
||||||
unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list,
|
unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list,
|
||||||
uint check_flag)
|
uint check_flag)
|
||||||
|
{
|
||||||
|
return find_table(thd, table, table_list, check_flag, NULL,
|
||||||
|
&unique_table_callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TABLE_LIST*
|
||||||
|
unique_table_in_insert_returning_subselect(THD *thd, TABLE_LIST *table, SELECT_LEX *sel)
|
||||||
|
{
|
||||||
|
return find_table(thd, table, NULL, 0, sel,
|
||||||
|
&unique_in_sel_table_callback);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
TABLE_LIST*
|
||||||
|
find_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list,
|
||||||
|
uint check_flag, SELECT_LEX *sel, find_table_callback callback )
|
||||||
{
|
{
|
||||||
TABLE_LIST *dup;
|
TABLE_LIST *dup;
|
||||||
|
|
||||||
@ -1264,12 +1299,12 @@ unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list,
|
|||||||
if (!tmp_parent)
|
if (!tmp_parent)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if ((dup= find_dup_table(thd, child, child->next_global, check_flag)))
|
if ((dup= (*callback)(thd, child, child->next_global, check_flag, sel)))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
dup= find_dup_table(thd, table, table_list, check_flag);
|
dup= (*callback)(thd, table, table_list, check_flag, sel);
|
||||||
return dup;
|
return dup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,7 +72,6 @@ enum find_item_error_report_type {REPORT_ALL_ERRORS, REPORT_EXCEPT_NOT_FOUND,
|
|||||||
#define CHECK_DUP_ALLOW_DIFFERENT_ALIAS 1
|
#define CHECK_DUP_ALLOW_DIFFERENT_ALIAS 1
|
||||||
#define CHECK_DUP_FOR_CREATE 2
|
#define CHECK_DUP_FOR_CREATE 2
|
||||||
#define CHECK_DUP_SKIP_TEMP_TABLE 4
|
#define CHECK_DUP_SKIP_TEMP_TABLE 4
|
||||||
#define CHECK_DUP_FOR_INSERT_SELECT 8
|
|
||||||
|
|
||||||
uint get_table_def_key(const TABLE_LIST *table_list, const char **key);
|
uint get_table_def_key(const TABLE_LIST *table_list, const char **key);
|
||||||
TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type update,
|
TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type update,
|
||||||
@ -290,6 +289,8 @@ bool open_and_lock_internal_tables(TABLE *table, bool lock);
|
|||||||
bool lock_tables(THD *thd, TABLE_LIST *tables, uint counter, uint flags);
|
bool lock_tables(THD *thd, TABLE_LIST *tables, uint counter, uint flags);
|
||||||
int decide_logging_format(THD *thd, TABLE_LIST *tables);
|
int decide_logging_format(THD *thd, TABLE_LIST *tables);
|
||||||
void close_thread_table(THD *thd, TABLE **table_ptr);
|
void close_thread_table(THD *thd, TABLE **table_ptr);
|
||||||
|
TABLE_LIST*
|
||||||
|
unique_table_in_insert_returning_subselect(THD *thd, TABLE_LIST *table, SELECT_LEX *sel);
|
||||||
TABLE_LIST *unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list,
|
TABLE_LIST *unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list,
|
||||||
uint check_flag);
|
uint check_flag);
|
||||||
bool is_equal(const LEX_CSTRING *a, const LEX_CSTRING *b);
|
bool is_equal(const LEX_CSTRING *a, const LEX_CSTRING *b);
|
||||||
|
@ -57,6 +57,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "mariadb.h" /* NO_EMBEDDED_ACCESS_CHECKS */
|
#include "mariadb.h" /* NO_EMBEDDED_ACCESS_CHECKS */
|
||||||
|
#include "sql_list.h"
|
||||||
#include "sql_priv.h"
|
#include "sql_priv.h"
|
||||||
#include "sql_insert.h"
|
#include "sql_insert.h"
|
||||||
#include "sql_update.h" // compare_record
|
#include "sql_update.h" // compare_record
|
||||||
@ -714,6 +715,8 @@ bool mysql_insert(THD *thd, TABLE_LIST *table_list,
|
|||||||
Name_resolution_context_state ctx_state;
|
Name_resolution_context_state ctx_state;
|
||||||
SELECT_LEX *returning= thd->lex->has_returning() ? thd->lex->returning() : 0;
|
SELECT_LEX *returning= thd->lex->has_returning() ? thd->lex->returning() : 0;
|
||||||
unsigned char *readbuff= NULL;
|
unsigned char *readbuff= NULL;
|
||||||
|
List<List_item> insert_values_cache;
|
||||||
|
bool cache_insert_values= FALSE;
|
||||||
|
|
||||||
#ifndef EMBEDDED_LIBRARY
|
#ifndef EMBEDDED_LIBRARY
|
||||||
char *query= thd->query();
|
char *query= thd->query();
|
||||||
@ -771,7 +774,7 @@ bool mysql_insert(THD *thd, TABLE_LIST *table_list,
|
|||||||
|
|
||||||
if ((res= mysql_prepare_insert(thd, table_list, fields, values,
|
if ((res= mysql_prepare_insert(thd, table_list, fields, values,
|
||||||
update_fields, update_values, duplic,
|
update_fields, update_values, duplic,
|
||||||
&unused_conds, FALSE)))
|
&unused_conds, FALSE, &cache_insert_values)))
|
||||||
{
|
{
|
||||||
retval= thd->is_error();
|
retval= thd->is_error();
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
@ -1000,8 +1003,42 @@ bool mysql_insert(THD *thd, TABLE_LIST *table_list,
|
|||||||
restore_record(table,s->default_values); // Get empty record
|
restore_record(table,s->default_values); // Get empty record
|
||||||
thd->reconsider_logging_format_for_iodup(table);
|
thd->reconsider_logging_format_for_iodup(table);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cache_insert_values)
|
||||||
|
{
|
||||||
|
insert_values_cache.empty();
|
||||||
|
while ((values= its++))
|
||||||
|
{
|
||||||
|
List<Item> *caches= new (thd->mem_root) List_item;
|
||||||
|
List_iterator_fast<Item> iv(*values);
|
||||||
|
Item *item;
|
||||||
|
if (caches == 0)
|
||||||
|
{
|
||||||
|
error= 1;
|
||||||
|
goto values_loop_end;
|
||||||
|
}
|
||||||
|
caches->empty();
|
||||||
|
while((item= iv++))
|
||||||
|
{
|
||||||
|
Item_cache *cache= item->get_cache(thd);
|
||||||
|
if (!cache)
|
||||||
|
{
|
||||||
|
error= 1;
|
||||||
|
goto values_loop_end;
|
||||||
|
}
|
||||||
|
cache->setup(thd, item);
|
||||||
|
caches->push_back(cache);
|
||||||
|
}
|
||||||
|
insert_values_cache.push_back(caches);
|
||||||
|
}
|
||||||
|
its.rewind();
|
||||||
|
}
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
List_iterator_fast<List_item> itc(insert_values_cache);
|
||||||
|
List_iterator_fast<List_item> *itr;
|
||||||
|
|
||||||
DBUG_PRINT("info", ("iteration %llu", iteration));
|
DBUG_PRINT("info", ("iteration %llu", iteration));
|
||||||
if (iteration && bulk_parameters_set(thd))
|
if (iteration && bulk_parameters_set(thd))
|
||||||
{
|
{
|
||||||
@ -1009,7 +1046,24 @@ bool mysql_insert(THD *thd, TABLE_LIST *table_list,
|
|||||||
goto values_loop_end;
|
goto values_loop_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((values= its++))
|
if (cache_insert_values)
|
||||||
|
{
|
||||||
|
List_item *caches;
|
||||||
|
while ((caches= itc++))
|
||||||
|
{
|
||||||
|
List_iterator_fast<Item> ic(*caches);
|
||||||
|
Item_cache *cache;
|
||||||
|
while((cache= (Item_cache*) ic++))
|
||||||
|
{
|
||||||
|
cache->cache_value();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
itc.rewind();
|
||||||
|
itr= &itc;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
itr= &its;
|
||||||
|
while ((values= (*itr)++))
|
||||||
{
|
{
|
||||||
if (fields.elements || !value_count)
|
if (fields.elements || !value_count)
|
||||||
{
|
{
|
||||||
@ -1112,7 +1166,7 @@ bool mysql_insert(THD *thd, TABLE_LIST *table_list,
|
|||||||
break;
|
break;
|
||||||
thd->get_stmt_da()->inc_current_row_for_warning();
|
thd->get_stmt_da()->inc_current_row_for_warning();
|
||||||
}
|
}
|
||||||
its.rewind();
|
itr->rewind();
|
||||||
iteration++;
|
iteration++;
|
||||||
} while (bulk_parameters_iterations(thd));
|
} while (bulk_parameters_iterations(thd));
|
||||||
|
|
||||||
@ -1601,6 +1655,7 @@ static void prepare_for_positional_update(TABLE *table, TABLE_LIST *tables)
|
|||||||
table_list Global/local table list
|
table_list Global/local table list
|
||||||
where Where clause (for insert ... select)
|
where Where clause (for insert ... select)
|
||||||
select_insert TRUE if INSERT ... SELECT statement
|
select_insert TRUE if INSERT ... SELECT statement
|
||||||
|
cache_insert_values insert's VALUES(...) has to be pre-computed
|
||||||
|
|
||||||
TODO (in far future)
|
TODO (in far future)
|
||||||
In cases of:
|
In cases of:
|
||||||
@ -1622,7 +1677,7 @@ int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
|
|||||||
List<Item> &fields, List_item *values,
|
List<Item> &fields, List_item *values,
|
||||||
List<Item> &update_fields, List<Item> &update_values,
|
List<Item> &update_fields, List<Item> &update_values,
|
||||||
enum_duplicates duplic, COND **where,
|
enum_duplicates duplic, COND **where,
|
||||||
bool select_insert)
|
bool select_insert, bool * const cache_insert_values)
|
||||||
{
|
{
|
||||||
SELECT_LEX *select_lex= thd->lex->first_select_lex();
|
SELECT_LEX *select_lex= thd->lex->first_select_lex();
|
||||||
Name_resolution_context *context= &select_lex->context;
|
Name_resolution_context *context= &select_lex->context;
|
||||||
@ -1712,11 +1767,12 @@ int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
Check if we read from the same table we're inserting into.
|
Check if we read from the same table we're inserting into.
|
||||||
Queries like INSERT INTO t1 VALUES ((SELECT ... FROM t1...)) are not
|
Queries like INSERT INTO t1 VALUES ((SELECT ... FROM t1...)) have
|
||||||
allowed.
|
to pre-compute the VALUES part.
|
||||||
|
Reading from the same table in the RETURNING clause is not allowed.
|
||||||
|
|
||||||
INSERT...SELECT is an exception: it will detect this case and use
|
INSERT...SELECT detects this case in select_insert::prepare and also
|
||||||
buffering to handle it correctly.
|
uses buffering to handle it correcly.
|
||||||
*/
|
*/
|
||||||
if (!select_insert)
|
if (!select_insert)
|
||||||
{
|
{
|
||||||
@ -1725,10 +1781,30 @@ int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
|
|||||||
if ((duplicate= unique_table(thd, table_list, table_list->next_global,
|
if ((duplicate= unique_table(thd, table_list, table_list->next_global,
|
||||||
CHECK_DUP_ALLOW_DIFFERENT_ALIAS)))
|
CHECK_DUP_ALLOW_DIFFERENT_ALIAS)))
|
||||||
{
|
{
|
||||||
update_non_unique_table_error(table_list, "INSERT", duplicate);
|
/*
|
||||||
DBUG_RETURN(1);
|
This is INSERT INTO ... VALUES (...) and it must pre-compute the
|
||||||
|
values to be inserted.
|
||||||
|
*/
|
||||||
|
(*cache_insert_values)= true;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
(*cache_insert_values)= false;
|
||||||
|
|
||||||
select_lex->fix_prepare_information(thd, &fake_conds, &fake_conds);
|
select_lex->fix_prepare_information(thd, &fake_conds, &fake_conds);
|
||||||
|
|
||||||
|
if ((*cache_insert_values) && thd->lex->has_returning())
|
||||||
|
{
|
||||||
|
// Check if the table we're inserting into is also in RETURNING clause
|
||||||
|
TABLE_LIST *dup=
|
||||||
|
unique_table_in_insert_returning_subselect(thd, table_list,
|
||||||
|
thd->lex->returning());
|
||||||
|
if (dup)
|
||||||
|
{
|
||||||
|
if (dup != ERROR_TABLE)
|
||||||
|
update_non_unique_table_error(table_list, "INSERT", duplicate);
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
Only call prepare_for_posistion() if we are not performing a DELAYED
|
Only call prepare_for_posistion() if we are not performing a DELAYED
|
||||||
@ -3857,6 +3933,7 @@ int mysql_insert_select_prepare(THD *thd, select_result *sel_res)
|
|||||||
int res;
|
int res;
|
||||||
LEX *lex= thd->lex;
|
LEX *lex= thd->lex;
|
||||||
SELECT_LEX *select_lex= lex->first_select_lex();
|
SELECT_LEX *select_lex= lex->first_select_lex();
|
||||||
|
bool cache_insert_values= false;
|
||||||
DBUG_ENTER("mysql_insert_select_prepare");
|
DBUG_ENTER("mysql_insert_select_prepare");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -3867,7 +3944,7 @@ int mysql_insert_select_prepare(THD *thd, select_result *sel_res)
|
|||||||
if ((res= mysql_prepare_insert(thd, lex->query_tables, lex->field_list, 0,
|
if ((res= mysql_prepare_insert(thd, lex->query_tables, lex->field_list, 0,
|
||||||
lex->update_list, lex->value_list,
|
lex->update_list, lex->value_list,
|
||||||
lex->duplicates,
|
lex->duplicates,
|
||||||
&select_lex->where, TRUE)))
|
&select_lex->where, TRUE, &cache_insert_values)))
|
||||||
DBUG_RETURN(res);
|
DBUG_RETURN(res);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -4050,8 +4127,7 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
|
|||||||
Is table which we are changing used somewhere in other parts of
|
Is table which we are changing used somewhere in other parts of
|
||||||
query
|
query
|
||||||
*/
|
*/
|
||||||
if (unique_table(thd, table_list, table_list->next_global,
|
if (unique_table(thd, table_list, table_list->next_global, 0))
|
||||||
CHECK_DUP_FOR_INSERT_SELECT))
|
|
||||||
{
|
{
|
||||||
/* Using same table for INSERT and SELECT */
|
/* Using same table for INSERT and SELECT */
|
||||||
lex->current_select->options|= OPTION_BUFFER_RESULT;
|
lex->current_select->options|= OPTION_BUFFER_RESULT;
|
||||||
|
@ -27,7 +27,7 @@ int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
|
|||||||
List<Item> &fields, List_item *values,
|
List<Item> &fields, List_item *values,
|
||||||
List<Item> &update_fields,
|
List<Item> &update_fields,
|
||||||
List<Item> &update_values, enum_duplicates duplic,
|
List<Item> &update_values, enum_duplicates duplic,
|
||||||
COND **where, bool select_insert);
|
COND **where, bool select_insert, bool * const cache_results);
|
||||||
bool mysql_insert(THD *thd,TABLE_LIST *table,List<Item> &fields,
|
bool mysql_insert(THD *thd,TABLE_LIST *table,List<Item> &fields,
|
||||||
List<List_item> &values, List<Item> &update_fields,
|
List<List_item> &values, List<Item> &update_fields,
|
||||||
List<Item> &update_values, enum_duplicates flag,
|
List<Item> &update_values, enum_duplicates flag,
|
||||||
|
@ -12047,3 +12047,45 @@ bool SELECT_LEX_UNIT::explainable() const
|
|||||||
derived->is_materialized_derived() : // (3)
|
derived->is_materialized_derived() : // (3)
|
||||||
false;
|
false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Find the real table in prepared SELECT tree
|
||||||
|
|
||||||
|
NOTE: all SELECT must be prepared (to have leaf table list).
|
||||||
|
|
||||||
|
NOTE: it looks only for real tables (not view or derived)
|
||||||
|
|
||||||
|
@param thd the current thread handle
|
||||||
|
@param db_name name of db of the table to look for
|
||||||
|
@param db_name name of db of the table to look for
|
||||||
|
|
||||||
|
@return first found table, NULL or ERROR_TABLE
|
||||||
|
*/
|
||||||
|
|
||||||
|
TABLE_LIST *SELECT_LEX::find_table(THD *thd,
|
||||||
|
const LEX_CSTRING *db_name,
|
||||||
|
const LEX_CSTRING *table_name)
|
||||||
|
{
|
||||||
|
uchar buff[STACK_BUFF_ALLOC]; // Max argument in function
|
||||||
|
if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
List_iterator_fast <TABLE_LIST> ti(leaf_tables);
|
||||||
|
TABLE_LIST *table;
|
||||||
|
while ((table= ti++))
|
||||||
|
{
|
||||||
|
if (cmp(&table->db, db_name) == 0 &&
|
||||||
|
cmp(&table->table_name, table_name) == 0)
|
||||||
|
return table;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (SELECT_LEX_UNIT *u= first_inner_unit(); u; u= u->next_unit())
|
||||||
|
{
|
||||||
|
for (st_select_lex *sl= u->first_select(); sl; sl=sl->next_select())
|
||||||
|
{
|
||||||
|
if ((table= sl->find_table(thd, db_name, table_name)))
|
||||||
|
return table;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
@ -1666,6 +1666,10 @@ public:
|
|||||||
void lex_start(LEX *plex);
|
void lex_start(LEX *plex);
|
||||||
bool is_unit_nest() { return (nest_flags & UNIT_NEST_FL); }
|
bool is_unit_nest() { return (nest_flags & UNIT_NEST_FL); }
|
||||||
void mark_as_unit_nest() { nest_flags= UNIT_NEST_FL; }
|
void mark_as_unit_nest() { nest_flags= UNIT_NEST_FL; }
|
||||||
|
|
||||||
|
TABLE_LIST *find_table(THD *thd,
|
||||||
|
const LEX_CSTRING *db_name,
|
||||||
|
const LEX_CSTRING *table_name);
|
||||||
};
|
};
|
||||||
typedef class st_select_lex SELECT_LEX;
|
typedef class st_select_lex SELECT_LEX;
|
||||||
|
|
||||||
|
@ -1287,6 +1287,7 @@ static bool mysql_test_insert(Prepared_statement *stmt,
|
|||||||
THD *thd= stmt->thd;
|
THD *thd= stmt->thd;
|
||||||
List_iterator_fast<List_item> its(values_list);
|
List_iterator_fast<List_item> its(values_list);
|
||||||
List_item *values;
|
List_item *values;
|
||||||
|
bool cache_results= FALSE;
|
||||||
DBUG_ENTER("mysql_test_insert");
|
DBUG_ENTER("mysql_test_insert");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1330,7 +1331,8 @@ static bool mysql_test_insert(Prepared_statement *stmt,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mysql_prepare_insert(thd, table_list, fields, values, update_fields,
|
if (mysql_prepare_insert(thd, table_list, fields, values, update_fields,
|
||||||
update_values, duplic, &unused_conds, FALSE))
|
update_values, duplic, &unused_conds, FALSE,
|
||||||
|
&cache_results))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
value_count= values->elements;
|
value_count= values->elements;
|
||||||
|
@ -3023,6 +3023,8 @@ private:
|
|||||||
ulong m_table_ref_version;
|
ulong m_table_ref_version;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define ERROR_TABLE ((TABLE_LIST*) 0x1)
|
||||||
|
|
||||||
class Item;
|
class Item;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -22626,6 +22626,164 @@ static void test_mdev_34958()
|
|||||||
rc= mysql_query(mysql, "DROP TABLE t1, t2");
|
rc= mysql_query(mysql, "DROP TABLE t1, t2");
|
||||||
myquery(rc);
|
myquery(rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Server crash when inserting from derived table containing insert target table */
|
||||||
|
static void test_mdev_32086()
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
MYSQL_STMT *stmt_insert;
|
||||||
|
MYSQL_BIND bind[2];
|
||||||
|
MYSQL_RES *result;
|
||||||
|
MYSQL_ROW row;
|
||||||
|
unsigned int vals[] = { 123, 124};
|
||||||
|
unsigned int vals_array_len = 2;
|
||||||
|
const char *insert_stmt= "\
|
||||||
|
insert into t1 values(\
|
||||||
|
(select 101+count(*)\
|
||||||
|
from\
|
||||||
|
(\
|
||||||
|
select dt2.id\
|
||||||
|
from (select id from t1) dt2, t1 t where t.id=dt2.id\
|
||||||
|
) dt\
|
||||||
|
where dt.id<1000\
|
||||||
|
), ?\
|
||||||
|
)";
|
||||||
|
|
||||||
|
/* Set up test's environment */
|
||||||
|
|
||||||
|
|
||||||
|
rc= mysql_query(mysql, "create table t1 (pk int, id int);");
|
||||||
|
myquery(rc);
|
||||||
|
|
||||||
|
rc= mysql_query(mysql, "insert into t1 values (2,2), (3,3), (4,4);");
|
||||||
|
myquery(rc);
|
||||||
|
|
||||||
|
stmt_insert = mysql_stmt_init(mysql);
|
||||||
|
if (!stmt_insert)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "mysql_stmt_init failed: Error: %s\n",
|
||||||
|
mysql_error(mysql));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
rc= mysql_stmt_prepare(stmt_insert, insert_stmt, strlen(insert_stmt));
|
||||||
|
if (rc)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "mysql_stmt_prepare failed: %s\n",
|
||||||
|
mysql_stmt_error(stmt_insert));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&bind[0], 0, sizeof(MYSQL_BIND));
|
||||||
|
|
||||||
|
bind[0].buffer_type= MYSQL_TYPE_LONG;
|
||||||
|
bind[0].buffer= vals;
|
||||||
|
|
||||||
|
rc= mysql_stmt_attr_set(stmt_insert, STMT_ATTR_ARRAY_SIZE, &vals_array_len);
|
||||||
|
if (rc)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "mysql_stmt_prepare failed: %s\n",
|
||||||
|
mysql_stmt_error(stmt_insert));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
rc= mysql_stmt_bind_param(stmt_insert, bind);
|
||||||
|
if (rc)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "mysql_stmt_bind_param failed: %s\n",
|
||||||
|
mysql_stmt_error(stmt_insert));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
rc= mysql_stmt_execute(stmt_insert);
|
||||||
|
if (rc)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "mysql_stmt_execute failed: %s\n",
|
||||||
|
mysql_stmt_error(stmt_insert));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
pk id
|
||||||
|
2 2
|
||||||
|
3 3
|
||||||
|
4 4
|
||||||
|
104 123
|
||||||
|
104 124
|
||||||
|
*/
|
||||||
|
rc= mysql_query(mysql, "select * from t1");
|
||||||
|
if (rc)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Query failed: %s\n", mysql_error(mysql));
|
||||||
|
}
|
||||||
|
result= mysql_store_result(mysql);
|
||||||
|
row= mysql_fetch_row(result);
|
||||||
|
DIE_UNLESS(atoi(row[0]) == 2 && atoi(row[1]) == 2);
|
||||||
|
row= mysql_fetch_row(result);
|
||||||
|
DIE_UNLESS(atoi(row[0]) == 3 && atoi(row[1]) == 3);
|
||||||
|
row= mysql_fetch_row(result);
|
||||||
|
DIE_UNLESS(atoi(row[0]) == 4 && atoi(row[1]) == 4);
|
||||||
|
row= mysql_fetch_row(result);
|
||||||
|
printf("\n %d, %d \n", atoi(row[0]), atoi(row[1]));
|
||||||
|
DIE_UNLESS(atoi(row[0]) == 104 && atoi(row[1]) == 123);
|
||||||
|
row= mysql_fetch_row(result);
|
||||||
|
printf("\n %d, %d \n", atoi(row[0]), atoi(row[1]));
|
||||||
|
DIE_UNLESS(atoi(row[0]) == 104 && atoi(row[1]) == 124);
|
||||||
|
row= mysql_fetch_row(result);
|
||||||
|
DIE_UNLESS(row == NULL);
|
||||||
|
|
||||||
|
mysql_free_result(result);
|
||||||
|
|
||||||
|
rc= mysql_stmt_execute(stmt_insert);
|
||||||
|
if (rc)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "mysql_stmt_execute failed: %s\n",
|
||||||
|
mysql_stmt_error(stmt_insert));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
pk id
|
||||||
|
2 2
|
||||||
|
3 3
|
||||||
|
4 4
|
||||||
|
104 123
|
||||||
|
104 124
|
||||||
|
106 123
|
||||||
|
106 124
|
||||||
|
*/
|
||||||
|
rc= mysql_query(mysql, "select * from t1");
|
||||||
|
if (rc)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Query failed: %s\n", mysql_error(mysql));
|
||||||
|
}
|
||||||
|
result= mysql_store_result(mysql);
|
||||||
|
row= mysql_fetch_row(result);
|
||||||
|
DIE_UNLESS(atoi(row[0]) == 2 && atoi(row[1]) == 2);
|
||||||
|
row= mysql_fetch_row(result);
|
||||||
|
DIE_UNLESS(atoi(row[0]) == 3 && atoi(row[1]) == 3);
|
||||||
|
row= mysql_fetch_row(result);
|
||||||
|
DIE_UNLESS(atoi(row[0]) == 4 && atoi(row[1]) == 4);
|
||||||
|
row= mysql_fetch_row(result);
|
||||||
|
DIE_UNLESS(atoi(row[0]) == 104 && atoi(row[1]) == 123);
|
||||||
|
row= mysql_fetch_row(result);
|
||||||
|
DIE_UNLESS(atoi(row[0]) == 104 && atoi(row[1]) == 124);
|
||||||
|
row= mysql_fetch_row(result);
|
||||||
|
printf("\n %d, %d \n", atoi(row[0]), atoi(row[1]));
|
||||||
|
DIE_UNLESS(atoi(row[0]) == 106 && atoi(row[1]) == 123);
|
||||||
|
row= mysql_fetch_row(result);
|
||||||
|
printf("\n %d, %d \n", atoi(row[0]), atoi(row[1]));
|
||||||
|
DIE_UNLESS(atoi(row[0]) == 106 && atoi(row[1]) == 124);
|
||||||
|
row= mysql_fetch_row(result);
|
||||||
|
DIE_UNLESS(row == NULL);
|
||||||
|
|
||||||
|
mysql_free_result(result);
|
||||||
|
|
||||||
|
mysql_stmt_close(stmt_insert);
|
||||||
|
|
||||||
|
/* Clean up */
|
||||||
|
rc= mysql_query(mysql, "DROP TABLE t1");
|
||||||
|
myquery(rc);
|
||||||
|
}
|
||||||
#endif // EMBEDDED_LIBRARY
|
#endif // EMBEDDED_LIBRARY
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -22980,6 +23138,7 @@ static struct my_tests_st my_tests[]= {
|
|||||||
{ "test_mdev_34718_bd", test_mdev_34718_bd },
|
{ "test_mdev_34718_bd", test_mdev_34718_bd },
|
||||||
{ "test_mdev_34718_ad", test_mdev_34718_ad },
|
{ "test_mdev_34718_ad", test_mdev_34718_ad },
|
||||||
{ "test_mdev_34958", test_mdev_34958 },
|
{ "test_mdev_34958", test_mdev_34958 },
|
||||||
|
{ "test_mdev_32086", test_mdev_32086 },
|
||||||
#endif
|
#endif
|
||||||
{ 0, 0 }
|
{ 0, 0 }
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user