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
|
||||
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;
|
||||
|
||||
--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 #
|
||||
|
||||
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
|
||||
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
|
||||
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.*;
|
||||
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);
|
||||
--error ER_UPDATE_TABLE_USED
|
||||
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
|
||||
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 v3Aa as select v2Aa.col1 from v2aA,t2Aa where v2Aa.col1 = t2aA.col1;
|
||||
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));
|
||||
ERROR HY000: The definition of table 'v1Aa' prevents operation INSERT on table 't1aA'
|
||||
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));
|
||||
ERROR HY000: The definition of table 'v2Aa' prevents operation INSERT on table 'v2Aa'
|
||||
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));
|
||||
ERROR HY000: The definition of table 'v2aA' prevents operation INSERT on table '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));
|
||||
ERROR HY000: The definition of table 'v2Aa' prevents operation INSERT on table 't1Aa'
|
||||
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));
|
||||
ERROR HY000: The definition of table 'v1Aa' prevents operation INSERT on table 'v3Aa'
|
||||
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));
|
||||
ERROR HY000: The definition of table 'v2aA' prevents operation INSERT on table 'v3Aa'
|
||||
drop view v3aA,v2Aa,v1aA;
|
||||
drop table t1Aa,t2Aa;
|
||||
create table t1Aa (col1 int);
|
||||
|
@ -23,29 +23,17 @@ create table t2aA (col1 int);
|
||||
create view v1Aa as select * from t1aA;
|
||||
create view v2aA as select * from v1aA;
|
||||
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));
|
||||
-- error 1443
|
||||
insert into t1aA values ((select max(col1) from v1Aa));
|
||||
-- error 1443
|
||||
insert into v2aA values ((select max(col1) from v1aA));
|
||||
-- error 1443
|
||||
insert into v2Aa values ((select max(col1) from t1Aa));
|
||||
-- error 1093
|
||||
insert into t1aA values ((select max(col1) from t1Aa));
|
||||
-- error 1443
|
||||
insert into v2aA values ((select max(col1) from t1aA));
|
||||
-- error 1093
|
||||
insert into v2Aa values ((select max(col1) from v2aA));
|
||||
-- error 1443
|
||||
insert into t1Aa values ((select max(col1) from v2Aa));
|
||||
-- error 1093
|
||||
insert into v2aA values ((select max(col1) from v2Aa));
|
||||
-- error 1443
|
||||
insert into v3Aa (col1) values ((select max(col1) from v1Aa));
|
||||
-- error 1443
|
||||
insert into v3aA (col1) values ((select max(col1) from t1aA));
|
||||
-- error 1443
|
||||
insert into v3Aa (col1) values ((select max(col1) from v2aA));
|
||||
drop view v3aA,v2Aa,v1aA;
|
||||
drop table t1Aa,t2Aa;
|
||||
|
@ -3689,33 +3689,22 @@ insert into tmp (b) values (1);
|
||||
insert into t1 (a) values (1);
|
||||
insert into t3 (b) values (1);
|
||||
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));
|
||||
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));
|
||||
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));
|
||||
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));
|
||||
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));
|
||||
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));
|
||||
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));
|
||||
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));
|
||||
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));
|
||||
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));
|
||||
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));
|
||||
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));
|
||||
ERROR HY000: The definition of table 'v1' prevents operation INSERT on table 'm1'
|
||||
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 temporary table tmp;
|
||||
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 t3 (b) values (1);
|
||||
--error ER_UPDATE_TABLE_USED
|
||||
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));
|
||||
--error ER_UPDATE_TABLE_USED
|
||||
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));
|
||||
|
||||
--error ER_UPDATE_TABLE_USED
|
||||
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));
|
||||
--error ER_UPDATE_TABLE_USED
|
||||
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));
|
||||
|
||||
--error ER_UPDATE_TABLE_USED
|
||||
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));
|
||||
--error ER_UPDATE_TABLE_USED
|
||||
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));
|
||||
|
||||
--error ER_VIEW_PREVENT_UPDATE
|
||||
|
||||
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));
|
||||
select count(*) from m1;
|
||||
|
||||
|
||||
drop view v1;
|
||||
|
@ -679,22 +679,24 @@ create table t3 (b int);
|
||||
insert into t2 values (1);
|
||||
insert into t3 values (1),(2);
|
||||
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));
|
||||
ERROR 21000: Subquery returns more than 1 row
|
||||
INSERT INTO t1 (x) VALUES ((SELECT a FROM t2));
|
||||
select * from t1;
|
||||
x
|
||||
NULL
|
||||
1
|
||||
insert into t2 values (1);
|
||||
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
|
||||
select * from t1;
|
||||
x
|
||||
NULL
|
||||
1
|
||||
2
|
||||
INSERT INTO t1 (x) select (SELECT SUM(a)+1 FROM t2) FROM t2;
|
||||
select * from t1;
|
||||
x
|
||||
NULL
|
||||
1
|
||||
2
|
||||
3
|
||||
@ -702,6 +704,7 @@ x
|
||||
INSERT INTO t1 (x) select (SELECT SUM(x)+2 FROM t1) FROM t2;
|
||||
select * from t1;
|
||||
x
|
||||
NULL
|
||||
1
|
||||
2
|
||||
3
|
||||
@ -711,6 +714,7 @@ x
|
||||
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
|
||||
select * from t1;
|
||||
x
|
||||
NULL
|
||||
1
|
||||
2
|
||||
3
|
||||
@ -727,7 +731,7 @@ insert into t3 values (1),(2);
|
||||
select * from t1;
|
||||
x y
|
||||
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));
|
||||
ERROR 21000: Subquery returns more than 1 row
|
||||
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
|
||||
2
|
||||
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));
|
||||
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;
|
||||
id
|
||||
1
|
||||
2
|
||||
2
|
||||
2
|
||||
CREATE TABLE t1 (id int(11) default NULL, KEY id (id)) ENGINE=MyISAM CHARSET=latin1;
|
||||
INSERT INTO t1 values (1),(1);
|
||||
UPDATE t2 SET id=(SELECT * FROM t1);
|
||||
|
@ -415,7 +415,6 @@ create table t2 (a int) ENGINE=MyISAM;
|
||||
create table t3 (b int);
|
||||
insert into t2 values (1);
|
||||
insert into t3 values (1),(2);
|
||||
-- error ER_UPDATE_TABLE_USED
|
||||
INSERT INTO t1 (x) VALUES ((SELECT x FROM t1));
|
||||
-- error ER_SUBQUERY_NO_1_ROW
|
||||
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 t3 values (1),(2);
|
||||
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));
|
||||
-- error ER_SUBQUERY_NO_1_ROW
|
||||
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);
|
||||
SELECT * FROM t2 WHERE id IN (SELECT 5 UNION SELECT 3);
|
||||
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));
|
||||
-- error ER_UPDATE_TABLE_USED
|
||||
-- error ER_SUBQUERY_NO_1_ROW
|
||||
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;
|
||||
CREATE TABLE t1 (id int(11) default NULL, KEY id (id)) ENGINE=MyISAM CHARSET=latin1;
|
||||
INSERT INTO t1 values (1),(1);
|
||||
|
@ -136,12 +136,22 @@ DROP TABLE t1;
|
||||
# access within null pointer
|
||||
CREATE TABLE x (x INT) ENGINE=InnoDB;
|
||||
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
|
||||
(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));
|
||||
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;
|
||||
# MDEV-28622: Item_subselect eliminated flag set but Item still
|
||||
# evaluated/used.
|
||||
|
@ -133,12 +133,17 @@ DROP TABLE t1;
|
||||
|
||||
CREATE TABLE x (x INT) ENGINE=InnoDB;
|
||||
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
|
||||
(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));
|
||||
select * from x;
|
||||
DROP TABLE x;
|
||||
|
||||
--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 t3 values (1),(2);
|
||||
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));
|
||||
ERROR 21000: Subquery returns more than 1 row
|
||||
INSERT INTO t1 (x) VALUES ((SELECT a FROM t2));
|
||||
select * from t1;
|
||||
x
|
||||
NULL
|
||||
1
|
||||
insert into t2 values (1);
|
||||
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
|
||||
select * from t1;
|
||||
x
|
||||
NULL
|
||||
1
|
||||
2
|
||||
INSERT INTO t1 (x) select (SELECT SUM(a)+1 FROM t2) FROM t2;
|
||||
select * from t1;
|
||||
x
|
||||
NULL
|
||||
1
|
||||
2
|
||||
3
|
||||
@ -706,6 +708,7 @@ x
|
||||
INSERT INTO t1 (x) select (SELECT SUM(x)+2 FROM t1) FROM t2;
|
||||
select * from t1;
|
||||
x
|
||||
NULL
|
||||
1
|
||||
2
|
||||
3
|
||||
@ -715,6 +718,7 @@ x
|
||||
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
|
||||
select * from t1;
|
||||
x
|
||||
NULL
|
||||
1
|
||||
2
|
||||
3
|
||||
@ -731,7 +735,7 @@ insert into t3 values (1),(2);
|
||||
select * from t1;
|
||||
x y
|
||||
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));
|
||||
ERROR 21000: Subquery returns more than 1 row
|
||||
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
|
||||
2
|
||||
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));
|
||||
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;
|
||||
id
|
||||
1
|
||||
2
|
||||
2
|
||||
2
|
||||
CREATE TABLE t1 (id int(11) default NULL, KEY id (id)) ENGINE=MyISAM CHARSET=latin1;
|
||||
INSERT INTO t1 values (1),(1);
|
||||
UPDATE t2 SET id=(SELECT * FROM t1);
|
||||
|
@ -686,22 +686,24 @@ create table t3 (b int);
|
||||
insert into t2 values (1);
|
||||
insert into t3 values (1),(2);
|
||||
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));
|
||||
ERROR 21000: Subquery returns more than 1 row
|
||||
INSERT INTO t1 (x) VALUES ((SELECT a FROM t2));
|
||||
select * from t1;
|
||||
x
|
||||
NULL
|
||||
1
|
||||
insert into t2 values (1);
|
||||
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
|
||||
select * from t1;
|
||||
x
|
||||
NULL
|
||||
1
|
||||
2
|
||||
INSERT INTO t1 (x) select (SELECT SUM(a)+1 FROM t2) FROM t2;
|
||||
select * from t1;
|
||||
x
|
||||
NULL
|
||||
1
|
||||
2
|
||||
3
|
||||
@ -709,6 +711,7 @@ x
|
||||
INSERT INTO t1 (x) select (SELECT SUM(x)+2 FROM t1) FROM t2;
|
||||
select * from t1;
|
||||
x
|
||||
NULL
|
||||
1
|
||||
2
|
||||
3
|
||||
@ -718,6 +721,7 @@ x
|
||||
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
|
||||
select * from t1;
|
||||
x
|
||||
NULL
|
||||
1
|
||||
2
|
||||
3
|
||||
@ -734,7 +738,7 @@ insert into t3 values (1),(2);
|
||||
select * from t1;
|
||||
x y
|
||||
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));
|
||||
ERROR 21000: Subquery returns more than 1 row
|
||||
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
|
||||
2
|
||||
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));
|
||||
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;
|
||||
id
|
||||
1
|
||||
2
|
||||
2
|
||||
2
|
||||
CREATE TABLE t1 (id int(11) default NULL, KEY id (id)) ENGINE=MyISAM CHARSET=latin1;
|
||||
INSERT INTO t1 values (1),(1);
|
||||
UPDATE t2 SET id=(SELECT * FROM t1);
|
||||
|
@ -682,22 +682,24 @@ create table t3 (b int);
|
||||
insert into t2 values (1);
|
||||
insert into t3 values (1),(2);
|
||||
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));
|
||||
ERROR 21000: Subquery returns more than 1 row
|
||||
INSERT INTO t1 (x) VALUES ((SELECT a FROM t2));
|
||||
select * from t1;
|
||||
x
|
||||
NULL
|
||||
1
|
||||
insert into t2 values (1);
|
||||
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
|
||||
select * from t1;
|
||||
x
|
||||
NULL
|
||||
1
|
||||
2
|
||||
INSERT INTO t1 (x) select (SELECT SUM(a)+1 FROM t2) FROM t2;
|
||||
select * from t1;
|
||||
x
|
||||
NULL
|
||||
1
|
||||
2
|
||||
3
|
||||
@ -705,6 +707,7 @@ x
|
||||
INSERT INTO t1 (x) select (SELECT SUM(x)+2 FROM t1) FROM t2;
|
||||
select * from t1;
|
||||
x
|
||||
NULL
|
||||
1
|
||||
2
|
||||
3
|
||||
@ -714,6 +717,7 @@ x
|
||||
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
|
||||
select * from t1;
|
||||
x
|
||||
NULL
|
||||
1
|
||||
2
|
||||
3
|
||||
@ -730,7 +734,7 @@ insert into t3 values (1),(2);
|
||||
select * from t1;
|
||||
x y
|
||||
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));
|
||||
ERROR 21000: Subquery returns more than 1 row
|
||||
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
|
||||
2
|
||||
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));
|
||||
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;
|
||||
id
|
||||
1
|
||||
2
|
||||
2
|
||||
2
|
||||
CREATE TABLE t1 (id int(11) default NULL, KEY id (id)) ENGINE=MyISAM CHARSET=latin1;
|
||||
INSERT INTO t1 values (1),(1);
|
||||
UPDATE t2 SET id=(SELECT * FROM t1);
|
||||
|
@ -685,22 +685,24 @@ create table t3 (b int);
|
||||
insert into t2 values (1);
|
||||
insert into t3 values (1),(2);
|
||||
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));
|
||||
ERROR 21000: Subquery returns more than 1 row
|
||||
INSERT INTO t1 (x) VALUES ((SELECT a FROM t2));
|
||||
select * from t1;
|
||||
x
|
||||
NULL
|
||||
1
|
||||
insert into t2 values (1);
|
||||
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
|
||||
select * from t1;
|
||||
x
|
||||
NULL
|
||||
1
|
||||
2
|
||||
INSERT INTO t1 (x) select (SELECT SUM(a)+1 FROM t2) FROM t2;
|
||||
select * from t1;
|
||||
x
|
||||
NULL
|
||||
1
|
||||
2
|
||||
3
|
||||
@ -708,6 +710,7 @@ x
|
||||
INSERT INTO t1 (x) select (SELECT SUM(x)+2 FROM t1) FROM t2;
|
||||
select * from t1;
|
||||
x
|
||||
NULL
|
||||
1
|
||||
2
|
||||
3
|
||||
@ -717,6 +720,7 @@ x
|
||||
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
|
||||
select * from t1;
|
||||
x
|
||||
NULL
|
||||
1
|
||||
2
|
||||
3
|
||||
@ -733,7 +737,7 @@ insert into t3 values (1),(2);
|
||||
select * from t1;
|
||||
x y
|
||||
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));
|
||||
ERROR 21000: Subquery returns more than 1 row
|
||||
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
|
||||
2
|
||||
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));
|
||||
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;
|
||||
id
|
||||
1
|
||||
2
|
||||
2
|
||||
2
|
||||
CREATE TABLE t1 (id int(11) default NULL, KEY id (id)) ENGINE=MyISAM CHARSET=latin1;
|
||||
INSERT INTO t1 values (1),(1);
|
||||
UPDATE t2 SET id=(SELECT * FROM t1);
|
||||
|
@ -682,22 +682,24 @@ create table t3 (b int);
|
||||
insert into t2 values (1);
|
||||
insert into t3 values (1),(2);
|
||||
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));
|
||||
ERROR 21000: Subquery returns more than 1 row
|
||||
INSERT INTO t1 (x) VALUES ((SELECT a FROM t2));
|
||||
select * from t1;
|
||||
x
|
||||
NULL
|
||||
1
|
||||
insert into t2 values (1);
|
||||
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
|
||||
select * from t1;
|
||||
x
|
||||
NULL
|
||||
1
|
||||
2
|
||||
INSERT INTO t1 (x) select (SELECT SUM(a)+1 FROM t2) FROM t2;
|
||||
select * from t1;
|
||||
x
|
||||
NULL
|
||||
1
|
||||
2
|
||||
3
|
||||
@ -705,6 +707,7 @@ x
|
||||
INSERT INTO t1 (x) select (SELECT SUM(x)+2 FROM t1) FROM t2;
|
||||
select * from t1;
|
||||
x
|
||||
NULL
|
||||
1
|
||||
2
|
||||
3
|
||||
@ -714,6 +717,7 @@ x
|
||||
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2));
|
||||
select * from t1;
|
||||
x
|
||||
NULL
|
||||
1
|
||||
2
|
||||
3
|
||||
@ -730,7 +734,7 @@ insert into t3 values (1),(2);
|
||||
select * from t1;
|
||||
x y
|
||||
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));
|
||||
ERROR 21000: Subquery returns more than 1 row
|
||||
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
|
||||
2
|
||||
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));
|
||||
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;
|
||||
id
|
||||
1
|
||||
2
|
||||
2
|
||||
2
|
||||
CREATE TABLE t1 (id int(11) default NULL, KEY id (id)) ENGINE=MyISAM CHARSET=latin1;
|
||||
INSERT INTO t1 values (1),(1);
|
||||
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 v3 as select v2.col1 from v2,t2 where v2.col1 = t2.col1;
|
||||
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));
|
||||
ERROR HY000: The definition of table 'v1' prevents operation INSERT on table 't1'
|
||||
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));
|
||||
ERROR HY000: The definition of table 'v2' prevents operation INSERT on table 'v2'
|
||||
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));
|
||||
ERROR HY000: The definition of table 'v2' prevents operation INSERT on table '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));
|
||||
ERROR HY000: The definition of table 'v2' prevents operation INSERT on table 't1'
|
||||
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));
|
||||
ERROR HY000: The definition of table 'v1' prevents operation INSERT on table 'v3'
|
||||
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));
|
||||
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));
|
||||
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));
|
||||
ERROR 22003: Out of range value for column 'col1' at row 2
|
||||
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));
|
||||
ERROR 23000: Column 'col1' cannot be null
|
||||
@ -978,6 +966,18 @@ insert into t1 (col1) values ((select max(col1) from v4));
|
||||
select * from t1;
|
||||
col1
|
||||
NULL
|
||||
NULL
|
||||
NULL
|
||||
NULL
|
||||
NULL
|
||||
NULL
|
||||
NULL
|
||||
NULL
|
||||
NULL
|
||||
NULL
|
||||
NULL
|
||||
NULL
|
||||
NULL
|
||||
1
|
||||
2
|
||||
3
|
||||
@ -1332,9 +1332,26 @@ create view v3 as select * from t1 where 20 < (select (s1) from v2);
|
||||
insert into v3 values (30);
|
||||
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);
|
||||
select * from t1;
|
||||
s1
|
||||
insert into v4 values (30);
|
||||
ERROR HY000: The target table v4 of the INSERT is not insertable-into
|
||||
drop view v4, v3, v2, v1;
|
||||
select * from t1;
|
||||
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;
|
||||
create table t1 (a int);
|
||||
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 v2 as select * from v1;
|
||||
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));
|
||||
-- error ER_VIEW_PREVENT_UPDATE
|
||||
insert into t1 values ((select max(col1) from v1));
|
||||
-- error ER_VIEW_PREVENT_UPDATE
|
||||
insert into v2 values ((select max(col1) from v1));
|
||||
-- error ER_VIEW_PREVENT_UPDATE
|
||||
insert into v2 values ((select max(col1) from t1));
|
||||
-- error ER_UPDATE_TABLE_USED
|
||||
insert into t1 values ((select max(col1) from t1));
|
||||
-- error ER_VIEW_PREVENT_UPDATE
|
||||
insert into v2 values ((select max(col1) from t1));
|
||||
-- error ER_UPDATE_TABLE_USED
|
||||
insert into v2 values ((select max(col1) from v2));
|
||||
-- error ER_VIEW_PREVENT_UPDATE
|
||||
insert into t1 values ((select max(col1) from v2));
|
||||
-- error ER_UPDATE_TABLE_USED
|
||||
insert into v2 values ((select max(col1) from v2));
|
||||
-- error ER_VIEW_PREVENT_UPDATE
|
||||
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));
|
||||
-- error ER_VIEW_PREVENT_UPDATE
|
||||
insert into v3 (col1) values ((select max(col1) from v2));
|
||||
# check with TZ tables in list
|
||||
-- error ER_VIEW_PREVENT_UPDATE
|
||||
insert into v3 (col1) values ((select CONVERT_TZ('20050101000000','UTC','MET') from v2));
|
||||
--error ER_WARN_DATA_OUT_OF_RANGE
|
||||
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));
|
||||
-- error ER_BAD_NULL_ERROR
|
||||
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
|
||||
insert into v3 values (30);
|
||||
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);
|
||||
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;
|
||||
|
||||
#
|
||||
|
@ -48,7 +48,6 @@ create sequence s2;
|
||||
insert into s1 (next_not_cached_value, minimum_value) values (100,1000);
|
||||
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);
|
||||
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);
|
||||
ERROR HY000: Sequence 'test.s1' has out of range value for options
|
||||
insert into s1 values(0,9223372036854775806,1,1,1,1000,0,0);
|
||||
|
@ -38,7 +38,6 @@ create sequence s1;
|
||||
create sequence s2;
|
||||
--error ER_NO_DEFAULT_FOR_FIELD
|
||||
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);
|
||||
--error ER_SEQUENCE_INVALID_DATA
|
||||
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; }
|
||||
};
|
||||
|
||||
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);
|
||||
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
|
||||
|
@ -7078,3 +7078,27 @@ void Subq_materialization_tracker::report_partial_merge_keys(
|
||||
for (uint i= 0; i < merge_keys_count; i++)
|
||||
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;
|
||||
}
|
||||
bool subselect_table_finder_processor(void *arg) override;
|
||||
|
||||
void register_as_with_rec_ref(With_element *with_elem);
|
||||
void init_expr_cache_tracker(THD *thd);
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
#include "mariadb.h"
|
||||
#include "sql_base.h" // setup_table_map
|
||||
#include "sql_list.h"
|
||||
#include "sql_priv.h"
|
||||
#include "unireg.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_alias= &table->alias;
|
||||
|
||||
retry:
|
||||
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)
|
||||
{
|
||||
@ -1184,37 +1184,53 @@ retry:
|
||||
DBUG_PRINT("info",
|
||||
("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);
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
or (in case of MyISAMMRG) one of its children are not used later
|
||||
@ -1233,6 +1249,25 @@ retry:
|
||||
TABLE_LIST*
|
||||
unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list,
|
||||
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;
|
||||
|
||||
@ -1264,12 +1299,12 @@ unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list,
|
||||
if (!tmp_parent)
|
||||
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;
|
||||
}
|
||||
}
|
||||
else
|
||||
dup= find_dup_table(thd, table, table_list, check_flag);
|
||||
dup= (*callback)(thd, table, table_list, check_flag, sel);
|
||||
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_FOR_CREATE 2
|
||||
#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);
|
||||
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);
|
||||
int decide_logging_format(THD *thd, TABLE_LIST *tables);
|
||||
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,
|
||||
uint check_flag);
|
||||
bool is_equal(const LEX_CSTRING *a, const LEX_CSTRING *b);
|
||||
|
@ -57,6 +57,7 @@
|
||||
*/
|
||||
|
||||
#include "mariadb.h" /* NO_EMBEDDED_ACCESS_CHECKS */
|
||||
#include "sql_list.h"
|
||||
#include "sql_priv.h"
|
||||
#include "sql_insert.h"
|
||||
#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;
|
||||
SELECT_LEX *returning= thd->lex->has_returning() ? thd->lex->returning() : 0;
|
||||
unsigned char *readbuff= NULL;
|
||||
List<List_item> insert_values_cache;
|
||||
bool cache_insert_values= FALSE;
|
||||
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
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,
|
||||
update_fields, update_values, duplic,
|
||||
&unused_conds, FALSE)))
|
||||
&unused_conds, FALSE, &cache_insert_values)))
|
||||
{
|
||||
retval= thd->is_error();
|
||||
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
|
||||
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
|
||||
{
|
||||
List_iterator_fast<List_item> itc(insert_values_cache);
|
||||
List_iterator_fast<List_item> *itr;
|
||||
|
||||
DBUG_PRINT("info", ("iteration %llu", iteration));
|
||||
if (iteration && bulk_parameters_set(thd))
|
||||
{
|
||||
@ -1009,7 +1046,24 @@ bool mysql_insert(THD *thd, TABLE_LIST *table_list,
|
||||
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)
|
||||
{
|
||||
@ -1112,7 +1166,7 @@ bool mysql_insert(THD *thd, TABLE_LIST *table_list,
|
||||
break;
|
||||
thd->get_stmt_da()->inc_current_row_for_warning();
|
||||
}
|
||||
its.rewind();
|
||||
itr->rewind();
|
||||
iteration++;
|
||||
} 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
|
||||
where Where clause (for insert ... select)
|
||||
select_insert TRUE if INSERT ... SELECT statement
|
||||
cache_insert_values insert's VALUES(...) has to be pre-computed
|
||||
|
||||
TODO (in far future)
|
||||
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> &update_fields, List<Item> &update_values,
|
||||
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();
|
||||
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.
|
||||
Queries like INSERT INTO t1 VALUES ((SELECT ... FROM t1...)) are not
|
||||
allowed.
|
||||
Queries like INSERT INTO t1 VALUES ((SELECT ... FROM t1...)) have
|
||||
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
|
||||
buffering to handle it correctly.
|
||||
INSERT...SELECT detects this case in select_insert::prepare and also
|
||||
uses buffering to handle it correcly.
|
||||
*/
|
||||
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,
|
||||
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);
|
||||
|
||||
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
|
||||
@ -3857,6 +3933,7 @@ int mysql_insert_select_prepare(THD *thd, select_result *sel_res)
|
||||
int res;
|
||||
LEX *lex= thd->lex;
|
||||
SELECT_LEX *select_lex= lex->first_select_lex();
|
||||
bool cache_insert_values= false;
|
||||
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,
|
||||
lex->update_list, lex->value_list,
|
||||
lex->duplicates,
|
||||
&select_lex->where, TRUE)))
|
||||
&select_lex->where, TRUE, &cache_insert_values)))
|
||||
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
|
||||
query
|
||||
*/
|
||||
if (unique_table(thd, table_list, table_list->next_global,
|
||||
CHECK_DUP_FOR_INSERT_SELECT))
|
||||
if (unique_table(thd, table_list, table_list->next_global, 0))
|
||||
{
|
||||
/* Using same table for INSERT and SELECT */
|
||||
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> &update_fields,
|
||||
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,
|
||||
List<List_item> &values, List<Item> &update_fields,
|
||||
List<Item> &update_values, enum_duplicates flag,
|
||||
|
@ -12047,3 +12047,45 @@ bool SELECT_LEX_UNIT::explainable() const
|
||||
derived->is_materialized_derived() : // (3)
|
||||
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);
|
||||
bool is_unit_nest() { return (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;
|
||||
|
||||
|
@ -1287,6 +1287,7 @@ static bool mysql_test_insert(Prepared_statement *stmt,
|
||||
THD *thd= stmt->thd;
|
||||
List_iterator_fast<List_item> its(values_list);
|
||||
List_item *values;
|
||||
bool cache_results= FALSE;
|
||||
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,
|
||||
update_values, duplic, &unused_conds, FALSE))
|
||||
update_values, duplic, &unused_conds, FALSE,
|
||||
&cache_results))
|
||||
goto error;
|
||||
|
||||
value_count= values->elements;
|
||||
|
@ -3023,6 +3023,8 @@ private:
|
||||
ulong m_table_ref_version;
|
||||
};
|
||||
|
||||
#define ERROR_TABLE ((TABLE_LIST*) 0x1)
|
||||
|
||||
class Item;
|
||||
|
||||
/*
|
||||
|
@ -22626,6 +22626,164 @@ static void test_mdev_34958()
|
||||
rc= mysql_query(mysql, "DROP TABLE t1, t2");
|
||||
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
|
||||
|
||||
/*
|
||||
@ -22980,6 +23138,7 @@ static struct my_tests_st my_tests[]= {
|
||||
{ "test_mdev_34718_bd", test_mdev_34718_bd },
|
||||
{ "test_mdev_34718_ad", test_mdev_34718_ad },
|
||||
{ "test_mdev_34958", test_mdev_34958 },
|
||||
{ "test_mdev_32086", test_mdev_32086 },
|
||||
#endif
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user