diff --git a/include/mysqld_error.h b/include/mysqld_error.h index d0b3cc9aa4a..7c77d229b81 100644 --- a/include/mysqld_error.h +++ b/include/mysqld_error.h @@ -262,5 +262,6 @@ #define ER_CYCLIC_REFERENCE 1243 #define ER_AUTO_CONVERT 1244 #define ER_ILLEGAL_REFERENCE 1245 -#define ER_SELECT_REDUCED 1246 -#define ER_ERROR_MESSAGES 247 +#define ER_DERIVED_MUST_HAVE_ALIAS 1246 +#define ER_SELECT_REDUCED 1247 +#define ER_ERROR_MESSAGES 248 diff --git a/mysql-test/r/derived.result b/mysql-test/r/derived.result index b397c2f7635..95640e69d8b 100644 --- a/mysql-test/r/derived.result +++ b/mysql-test/r/derived.result @@ -17,32 +17,55 @@ select t1.a,t4.y from t1,(select t2.a as y from t2,(select t3.b from t3 where t3 a y 3 3 3 3 -SELECT a FROM (SELECT 1 FROM (SELECT 1) HAVING a=1); +SELECT a FROM (SELECT 1 FROM (SELECT 1) a HAVING a=1) b; Unknown column 'a' in 'having clause' -SELECT a,b as a FROM (SELECT '1' as a,'2' as b) HAVING a=1; +SELECT a,b as a FROM (SELECT '1' as a,'2' as b) b HAVING a=1; Column: 'a' in having clause is ambiguous -SELECT a,2 as a FROM (SELECT '1' as a) HAVING a=2; +SELECT a,2 as a FROM (SELECT '1' as a) b HAVING a=2; a a 1 2 -SELECT a,2 as a FROM (SELECT '1' as a) HAVING a=1; +SELECT a,2 as a FROM (SELECT '1' as a) b HAVING a=1; a a -SELECT 1 FROM (SELECT 1) WHERE a=2; +SELECT 1 FROM (SELECT 1) a WHERE a=2; Unknown column 'a' in 'where clause' -SELECT (SELECT 1) as a FROM (SELECT 1 FROM t1 HAVING a=1); +SELECT (SELECT 1) as a FROM (SELECT 1 FROM t1 HAVING a=1) as a; Unknown column 'a' in 'having clause' +select * from t1 as x1, (select * from t1) as x2; +a b a b +1 a 1 a +2 b 1 a +3 c 1 a +3 c 1 a +1 a 2 b +2 b 2 b +3 c 2 b +3 c 2 b +1 a 3 c +2 b 3 c +3 c 3 c +3 c 3 c +1 a 3 c +2 b 3 c +3 c 3 c +3 c 3 c +explain select * from t1 as x1, (select * from t1) as x2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY x1 ALL NULL NULL NULL NULL 4 +1 PRIMARY ALL NULL NULL NULL NULL 4 +2 DERIVED x1 ALL NULL NULL NULL NULL 4 drop table if exists t1.t2,t3; -select * from (select 1); +select * from (select 1) as a; 1 1 -select a from (select 1 as a); +select a from (select 1 as a) as b; a 1 -select 1 from (select 1); +select 1 from (select 1) as a; 1 1 drop table if exists t1; create table t1(a int not null, t char(8), index(a)); -SELECT * FROM (SELECT * FROM t1) ORDER BY a ASC LIMIT 0,20; +SELECT * FROM (SELECT * FROM t1) as b ORDER BY a ASC LIMIT 0,20; a t 1 1 2 2 @@ -64,7 +87,14 @@ a t 18 18 19 19 20 20 +explain select count(*) from t1 as tt1, (select * from t1) as tt2; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY Select tables optimized away +2 DERIVED tt1 index NULL a 4 NULL 10000 Using index drop table if exists t1; -SELECT * FROM (SELECT (SELECT * FROM (SELECT 1 as a))); -(SELECT * FROM (SELECT 1 as a)) +SELECT * FROM (SELECT (SELECT * FROM (SELECT 1 as a) as a )) as b; +(SELECT * FROM (SELECT 1 as a) as a ) 1 +select * from (select 1 as a) b left join (select 2 as a) c using(a); +a a +1 NULL diff --git a/mysql-test/r/group_by.result b/mysql-test/r/group_by.result index ead9935f824..b5a35b981db 100644 --- a/mysql-test/r/group_by.result +++ b/mysql-test/r/group_by.result @@ -1,4 +1,4 @@ -SELECT 1 FROM (SELECT 1) GROUP BY SUM(1); +SELECT 1 FROM (SELECT 1) as a GROUP BY SUM(1); Invalid use of group function drop table if exists t1,t2,t3; CREATE TABLE t1 ( diff --git a/mysql-test/r/select_found.result b/mysql-test/r/select_found.result index 8500e244d08..5b6c490b928 100644 --- a/mysql-test/r/select_found.result +++ b/mysql-test/r/select_found.result @@ -168,7 +168,7 @@ test2 2 2 SELECT FOUND_ROWS(); FOUND_ROWS() 2 -SELECT SQL_CALC_FOUND_ROWS 1 FROM (SELECT 1) LIMIT 0; +SELECT SQL_CALC_FOUND_ROWS 1 FROM (SELECT 1) as a LIMIT 0; 1 SELECT FOUND_ROWS(); FOUND_ROWS() diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index bbf70150ee0..42e9ff7012f 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -8,39 +8,39 @@ SELECT (SELECT 1) UNION SELECT (SELECT 2); SELECT (SELECT (SELECT 0 UNION SELECT 0)); (SELECT (SELECT 0 UNION SELECT 0)) 0 -SELECT (SELECT 1 FROM (SELECT 1) HAVING a=1) as a; +SELECT (SELECT 1 FROM (SELECT 1) as b HAVING a=1) as a; Reference 'a' not supported (forward reference in item list) -SELECT (SELECT 1 FROM (SELECT 1) HAVING b=1) as a,(SELECT 1 FROM (SELECT 1) HAVING a=1) as b; +SELECT (SELECT 1 FROM (SELECT 1) as b HAVING b=1) as a,(SELECT 1 FROM (SELECT 1) as c HAVING a=1) as b; Reference 'b' not supported (forward reference in item list) -SELECT (SELECT 1),MAX(1) FROM (SELECT 1); +SELECT (SELECT 1),MAX(1) FROM (SELECT 1) as a; (SELECT 1) MAX(1) 1 1 SELECT (SELECT a) as a; Reference 'a' not supported (forward reference in item list) -EXPLAIN SELECT 1 FROM (SELECT 1 as a) HAVING (SELECT a)=1; +EXPLAIN SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY system NULL NULL NULL NULL 1 3 DEPENDENT SUBSELECT No tables used 2 DERIVED No tables used -SELECT 1 FROM (SELECT 1 as a) HAVING (SELECT a)=1; +SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1; 1 1 SELECT (SELECT 1), a; Unknown column 'a' in 'field list' -SELECT 1 as a FROM (SELECT 1) HAVING (SELECT a)=1; +SELECT 1 as a FROM (SELECT 1) as b HAVING (SELECT a)=1; a 1 -SELECT 1 FROM (SELECT (SELECT a)); +SELECT 1 FROM (SELECT (SELECT a) b) c; Unknown column 'a' in 'field list' -SELECT * FROM (SELECT 1 as id) WHERE id IN (SELECT * FROM (SELECT 1 as id) ORDER BY id LIMIT 1); +SELECT * FROM (SELECT 1 as id) b WHERE id IN (SELECT * FROM (SELECT 1 as id) c ORDER BY id LIMIT 1); id 1 -SELECT * FROM (SELECT 1) WHERE 1 IN (SELECT 1,1); +SELECT * FROM (SELECT 1) a WHERE 1 IN (SELECT 1,1); Cardinality error (more/less than 1 columns) SELECT 1 IN (SELECT 1); 1 IN (SELECT 1) 1 -SELECT 1 FROM (SELECT 1 as a) WHERE 1 IN (SELECT (SELECT a)); +SELECT 1 FROM (SELECT 1 as a) b WHERE 1 IN (SELECT (SELECT a)); 1 1 drop table if exists t1,t2,t3,t4,t5,t6,t7,t8; @@ -319,7 +319,7 @@ SELECT numeropost,maxnumrep FROM t1 WHERE exists (SELECT 1 FROM t2 WHERE (mot='j numeropost maxnumrep 43506 2 40143 1 -SELECT (SELECT 1) as a FROM (SELECT 1 FROM t1 HAVING a=1); +SELECT (SELECT 1) as a FROM (SELECT 1 FROM t1 HAVING a=1) b; Unknown column 'a' in 'having clause' SELECT 1 IN (SELECT 1 FROM t2 HAVING a); Unknown column 'a' in 'having clause' @@ -368,7 +368,7 @@ Subselect returns more than 1 record drop table t1; CREATE TABLE t1 (field char(1) NOT NULL DEFAULT 'b'); INSERT INTO t1 VALUES (); -SELECT field FROM t1 WHERE 1=(SELECT 1 UNION ALL SELECT 1 FROM (SELECT 1) HAVING field='b'); +SELECT field FROM t1 WHERE 1=(SELECT 1 UNION ALL SELECT 1 FROM (SELECT 1) a HAVING field='b'); Subselect returns more than 1 record drop table t1; CREATE TABLE `t1` ( @@ -398,7 +398,7 @@ id select_type table type possible_keys key key_len ref rows Extra drop table t1; CREATE TABLE t1 (a int(1)); INSERT INTO t1 VALUES (1); -SELECT 1 FROM (SELECT a FROM t1) HAVING (SELECT a)=1; +SELECT 1 FROM (SELECT a FROM t1) b HAVING (SELECT b.a)=1; 1 1 drop table t1; @@ -411,6 +411,10 @@ a b 0 10 1 11 2 12 +update t1 set b= (select b from t1); +INSERT TABLE 't1' isn't allowed in FROM table list +update t1 set b= (select b from t2); +Subselect returns more than 1 record update t1 set b= (select b from t2 where t1.a = t2.a); select * from t1; a b @@ -430,6 +434,10 @@ a b select * from t1 where b = (select b from t2 where t1.a = t2.a); a b 2 12 +delete from t1 where b = (select b from t1); +INSERT TABLE 't1' isn't allowed in FROM table list +delete from t1 where b = (select b from t2); +Subselect returns more than 1 record delete from t1 where b = (select b from t2 where t1.a = t2.a); select * from t1; a b @@ -453,6 +461,10 @@ a b 33 10 22 11 2 12 +delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t12 where t11.a = t12.a); +INSERT TABLE 't12' isn't allowed in FROM table list +delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t2); +Subselect returns more than 1 record delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t2 where t11.a = t2.a); select * from t11; a b @@ -465,7 +477,13 @@ a b drop table t11, t12, t2; CREATE TABLE t1 (x int); create table t2 (a int); +create table t3 (a int); insert into t2 values (1); +insert into t3 values (1),(2); +INSERT INTO t1 (x) VALUES ((SELECT x FROM t1)); +INSERT TABLE 't1' isn't allowed in FROM table list +INSERT INTO t1 (x) VALUES ((SELECT a FROM t3)); +Subselect returns more than 1 record INSERT INTO t1 (x) VALUES ((SELECT a FROM t2)); select * from t1; x @@ -485,20 +503,26 @@ x 3 INSERT INTO t1 (x) select (SELECT SUM(x)+2 FROM t1) FROM t2; INSERT TABLE 't1' isn't allowed in FROM table list -INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(x) FROM t1)); +INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(x) FROM t2)); select * from t1; x 1 2 3 3 -9 -drop table t1, t2; +0 +drop table t1, t2, t3; CREATE TABLE t1 (x int not null, y int, primary key (x)); create table t2 (a int); +create table t3 (a int); insert into t2 values (1); +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)); +INSERT TABLE 't1' isn't allowed in FROM table list +replace into t1 (x, y) VALUES ((SELECT a FROM t3), (SELECT a+1 FROM t2)); +Subselect returns more than 1 record replace into t1 (x, y) VALUES ((SELECT a FROM t2), (SELECT a+1 FROM t2)); select * from t1; x y @@ -523,8 +547,8 @@ x y 1 3 4 2 2 1 -drop table t1, t2; -SELECT * FROM (SELECT 1) WHERE 1 IN (SELECT *); +drop table t1, t2, t3; +SELECT * FROM (SELECT 1) b WHERE 1 IN (SELECT *); No tables used drop table if exists t; CREATE TABLE t (id int(11) default NULL, KEY id (id)) TYPE=MyISAM CHARSET=latin1; @@ -536,7 +560,7 @@ EXPLAIN SELECT * FROM t WHERE id IN (SELECT 1); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t ref id id 5 const 1 Using where; Using index Warnings: -Note 1246 Select 2 was reduced during optimisation +Note 1247 Select 2 was reduced during optimisation SELECT * FROM t WHERE id IN (SELECT 1 UNION SELECT 3); id 1 @@ -548,7 +572,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t ref id id 5 const 1 Using where; Using index 3 SUBSELECT No tables used Warnings: -Note 1246 Select 2 was reduced during optimisation +Note 1247 Select 2 was reduced during optimisation EXPLAIN SELECT * FROM t WHERE id IN (SELECT 1 UNION SELECT 3); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t index NULL id 5 NULL 2 Using where; Using index @@ -559,4 +583,14 @@ id SELECT * FROM t WHERE id IN (SELECT 5 UNION SELECT 2); id 2 -drop table if exists t; +INSERT INTO t VALUES ((SELECT * FROM t)); +INSERT TABLE 't' isn't allowed in FROM table list +SELECT * FROM t; +id +1 +2 +CREATE TABLE t1 (id int(11) default NULL, KEY id (id)) TYPE=MyISAM CHARSET=latin1; +INSERT INTO t1 values (1),(1); +UPDATE t SET id=(SELECT * FROM t1); +Subselect returns more than 1 record +drop table t; diff --git a/mysql-test/t/derived.test b/mysql-test/t/derived.test index c1d8af4074a..8f187dd46ba 100644 --- a/mysql-test/t/derived.test +++ b/mysql-test/t/derived.test @@ -9,19 +9,21 @@ CREATE TABLE t3 (a int not null, b char (10) not null); insert into t3 values (3,'f'),(4,'y'),(5,'z'),(6,'c'); select t1.a,t4.y from t1,(select t2.a as y from t2,(select t3.b from t3 where t3.a>3) as t5 where t2.b=t5.b) as t4 where t1.a = t4.y; --error 1054 -SELECT a FROM (SELECT 1 FROM (SELECT 1) HAVING a=1); +SELECT a FROM (SELECT 1 FROM (SELECT 1) a HAVING a=1) b; --error 1052 -SELECT a,b as a FROM (SELECT '1' as a,'2' as b) HAVING a=1; -SELECT a,2 as a FROM (SELECT '1' as a) HAVING a=2; -SELECT a,2 as a FROM (SELECT '1' as a) HAVING a=1; +SELECT a,b as a FROM (SELECT '1' as a,'2' as b) b HAVING a=1; +SELECT a,2 as a FROM (SELECT '1' as a) b HAVING a=2; +SELECT a,2 as a FROM (SELECT '1' as a) b HAVING a=1; --error 1054 -SELECT 1 FROM (SELECT 1) WHERE a=2; +SELECT 1 FROM (SELECT 1) a WHERE a=2; --error 1054 -SELECT (SELECT 1) as a FROM (SELECT 1 FROM t1 HAVING a=1); +SELECT (SELECT 1) as a FROM (SELECT 1 FROM t1 HAVING a=1) as a; +select * from t1 as x1, (select * from t1) as x2; +explain select * from t1 as x1, (select * from t1) as x2; drop table if exists t1.t2,t3; -select * from (select 1); -select a from (select 1 as a); -select 1 from (select 1); +select * from (select 1) as a; +select a from (select 1 as a) as b; +select 1 from (select 1) as a; drop table if exists t1; create table t1(a int not null, t char(8), index(a)); disable_query_log; @@ -32,6 +34,8 @@ while ($1) dec $1; } enable_query_log; -SELECT * FROM (SELECT * FROM t1) ORDER BY a ASC LIMIT 0,20; +SELECT * FROM (SELECT * FROM t1) as b ORDER BY a ASC LIMIT 0,20; +explain select count(*) from t1 as tt1, (select * from t1) as tt2; drop table if exists t1; -SELECT * FROM (SELECT (SELECT * FROM (SELECT 1 as a))); +SELECT * FROM (SELECT (SELECT * FROM (SELECT 1 as a) as a )) as b; +select * from (select 1 as a) b left join (select 2 as a) c using(a); diff --git a/mysql-test/t/group_by.test b/mysql-test/t/group_by.test index 0f30fbd4cc6..4670feca500 100644 --- a/mysql-test/t/group_by.test +++ b/mysql-test/t/group_by.test @@ -1,5 +1,5 @@ -- error 1111 -SELECT 1 FROM (SELECT 1) GROUP BY SUM(1); +SELECT 1 FROM (SELECT 1) as a GROUP BY SUM(1); # # Test of group (Failed for Lars Hoss ) # diff --git a/mysql-test/t/select_found.test b/mysql-test/t/select_found.test index 316e7894344..fb57224dd19 100644 --- a/mysql-test/t/select_found.test +++ b/mysql-test/t/select_found.test @@ -84,7 +84,7 @@ INSERT INTO t1 (titre,maxnumrep) VALUES ('test1','1'),('test2','2'),('test3','3'); SELECT SQL_CALC_FOUND_ROWS titre,numeropost,maxnumrep FROM t1 WHERE numeropost IN (1,2) ORDER BY maxnumrep DESC LIMIT 0, 1; SELECT FOUND_ROWS(); -SELECT SQL_CALC_FOUND_ROWS 1 FROM (SELECT 1) LIMIT 0; +SELECT SQL_CALC_FOUND_ROWS 1 FROM (SELECT 1) as a LIMIT 0; SELECT FOUND_ROWS(); SELECT SQL_CALC_FOUND_ROWS * FROM t1 WHERE numeropost > 1 LIMIT 0; SELECT FOUND_ROWS(); diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index c875f8372b3..9ed4250976b 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -2,25 +2,24 @@ select (select 2); SELECT (SELECT 1) UNION SELECT (SELECT 2); SELECT (SELECT (SELECT 0 UNION SELECT 0)); -- error 1245 -SELECT (SELECT 1 FROM (SELECT 1) HAVING a=1) as a; +SELECT (SELECT 1 FROM (SELECT 1) as b HAVING a=1) as a; -- error 1245 -SELECT (SELECT 1 FROM (SELECT 1) HAVING b=1) as a,(SELECT 1 FROM (SELECT 1) HAVING a=1) as b; -SELECT (SELECT 1),MAX(1) FROM (SELECT 1); +SELECT (SELECT 1 FROM (SELECT 1) as b HAVING b=1) as a,(SELECT 1 FROM (SELECT 1) as c HAVING a=1) as b; +SELECT (SELECT 1),MAX(1) FROM (SELECT 1) as a; -- error 1245 SELECT (SELECT a) as a; -EXPLAIN SELECT 1 FROM (SELECT 1 as a) HAVING (SELECT a)=1; -SELECT 1 FROM (SELECT 1 as a) HAVING (SELECT a)=1; +EXPLAIN SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1; +SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1; -- error 1054 SELECT (SELECT 1), a; -SELECT 1 as a FROM (SELECT 1) HAVING (SELECT a)=1; +SELECT 1 as a FROM (SELECT 1) as b HAVING (SELECT a)=1; -- error 1054 -SELECT 1 FROM (SELECT (SELECT a)); -SELECT * FROM (SELECT 1 as id) WHERE id IN (SELECT * FROM (SELECT 1 as id) ORDER BY id LIMIT 1); +SELECT 1 FROM (SELECT (SELECT a) b) c; +SELECT * FROM (SELECT 1 as id) b WHERE id IN (SELECT * FROM (SELECT 1 as id) c ORDER BY id LIMIT 1); -- error 1239 -SELECT * FROM (SELECT 1) WHERE 1 IN (SELECT 1,1); +SELECT * FROM (SELECT 1) a WHERE 1 IN (SELECT 1,1); SELECT 1 IN (SELECT 1); -SELECT 1 FROM (SELECT 1 as a) WHERE 1 IN (SELECT (SELECT a)); - +SELECT 1 FROM (SELECT 1 as a) b WHERE 1 IN (SELECT (SELECT a)); drop table if exists t1,t2,t3,t4,t5,t6,t7,t8; create table t1 (a int); create table t2 (a int, b int); @@ -176,7 +175,7 @@ INSERT INTO t2 (mot,topic,date,pseudo) VALUES ('joce','40143','2002-10-22','joce select numeropost as a FROM t1 GROUP BY (SELECT 1 FROM t1 HAVING a=1); SELECT numeropost,maxnumrep FROM t1 WHERE exists (SELECT 1 FROM t2 WHERE (mot='joce') AND date >= '2002-10-21' AND t1.numeropost = t2.topic) ORDER BY maxnumrep DESC LIMIT 0, 20; -- error 1054 -SELECT (SELECT 1) as a FROM (SELECT 1 FROM t1 HAVING a=1); +SELECT (SELECT 1) as a FROM (SELECT 1 FROM t1 HAVING a=1) b; -- error 1054 SELECT 1 IN (SELECT 1 FROM t2 HAVING a); SELECT * from t2 where topic IN (SELECT topic FROM t2 GROUP BY date); @@ -210,7 +209,7 @@ drop table t1; CREATE TABLE t1 (field char(1) NOT NULL DEFAULT 'b'); INSERT INTO t1 VALUES (); -- error 1240 -SELECT field FROM t1 WHERE 1=(SELECT 1 UNION ALL SELECT 1 FROM (SELECT 1) HAVING field='b'); +SELECT field FROM t1 WHERE 1=(SELECT 1 UNION ALL SELECT 1 FROM (SELECT 1) a HAVING field='b'); drop table t1; # threadhardwarefr7 @@ -236,7 +235,7 @@ drop table t1; CREATE TABLE t1 (a int(1)); INSERT INTO t1 VALUES (1); -SELECT 1 FROM (SELECT a FROM t1) HAVING (SELECT a)=1; +SELECT 1 FROM (SELECT a FROM t1) b HAVING (SELECT b.a)=1; drop table t1; #update with subselects @@ -245,6 +244,10 @@ create table t2 (a int NOT NULL, b int, primary key (a)); insert into t1 values (0, 10),(1, 11),(2, 12); insert into t2 values (1, 21),(2, 22),(3, 23); select * from t1; +-- error 1093 +update t1 set b= (select b from t1); +-- error 1240 +update t1 set b= (select b from t2); update t1 set b= (select b from t2 where t1.a = t2.a); select * from t1; drop table t1, t2; @@ -256,6 +259,10 @@ insert into t1 values (0, 10),(1, 11),(2, 12); insert into t2 values (1, 21),(2, 12),(3, 23); select * from t1; select * from t1 where b = (select b from t2 where t1.a = t2.a); +-- error 1093 +delete from t1 where b = (select b from t1); +-- error 1240 +delete from t1 where b = (select b from t2); delete from t1 where b = (select b from t2 where t1.a = t2.a); select * from t1; drop table t1, t2; @@ -270,6 +277,10 @@ insert into t12 values (33, 10),(22, 11),(2, 12); insert into t2 values (1, 21),(2, 12),(3, 23); select * from t11; select * from t12; +-- error 1093 +delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t12 where t11.a = t12.a); +-- error 1240 +delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t2); delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t2 where t11.a = t2.a); select * from t11; select * from t12; @@ -278,7 +289,13 @@ drop table t11, t12, t2; #insert with subselects CREATE TABLE t1 (x int); create table t2 (a int); +create table t3 (a int); insert into t2 values (1); +insert into t3 values (1),(2); +-- error 1093 +INSERT INTO t1 (x) VALUES ((SELECT x FROM t1)); +-- error 1240 +INSERT INTO t1 (x) VALUES ((SELECT a FROM t3)); INSERT INTO t1 (x) VALUES ((SELECT a FROM t2)); select * from t1; insert into t2 values (1); @@ -289,16 +306,22 @@ INSERT INTO t1 (x) select (SELECT SUM(a)+1 FROM t2) FROM t2; select * from t1; -- error 1093 INSERT INTO t1 (x) select (SELECT SUM(x)+2 FROM t1) FROM t2; -INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(x) FROM t1)); +INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(x) FROM t2)); -- sleep 1 select * from t1; -drop table t1, t2; +drop table t1, t2, t3; #replace with subselects CREATE TABLE t1 (x int not null, y int, primary key (x)); create table t2 (a int); +create table t3 (a int); insert into t2 values (1); +insert into t3 values (1),(2); select * from t1; +-- error 1093 +replace into t1 (x, y) VALUES ((SELECT x FROM t1), (SELECT a+1 FROM t2)); +-- error 1240 +replace into t1 (x, y) VALUES ((SELECT a FROM t3), (SELECT a+1 FROM t2)); replace into t1 (x, y) VALUES ((SELECT a FROM t2), (SELECT a+1 FROM t2)); select * from t1; replace into t1 (x, y) VALUES ((SELECT a FROM t2), (SELECT a+2 FROM t2)); @@ -311,10 +334,10 @@ replace DELAYED into t1 (x, y) VALUES ((SELECT a+3 FROM t2), (SELECT a+1 FROM t2 select * from t1; replace LOW_PRIORITY into t1 (x, y) VALUES ((SELECT a+1 FROM t2), (SELECT a FROM t2)); select * from t1; -drop table t1, t2; +drop table t1, t2, t3; -- error 1096 -SELECT * FROM (SELECT 1) WHERE 1 IN (SELECT *); +SELECT * FROM (SELECT 1) b WHERE 1 IN (SELECT *); drop table if exists t; CREATE TABLE t (id int(11) default NULL, KEY id (id)) TYPE=MyISAM CHARSET=latin1; INSERT INTO t VALUES (1),(2); @@ -326,5 +349,11 @@ EXPLAIN SELECT * FROM t WHERE id IN (SELECT 1+(select 1)); EXPLAIN SELECT * FROM t WHERE id IN (SELECT 1 UNION SELECT 3); SELECT * FROM t WHERE id IN (SELECT 5 UNION SELECT 3); SELECT * FROM t WHERE id IN (SELECT 5 UNION SELECT 2); -drop table if exists t; - +-- error 1093 +INSERT INTO t VALUES ((SELECT * FROM t)); +SELECT * FROM t; +CREATE TABLE t1 (id int(11) default NULL, KEY id (id)) TYPE=MyISAM CHARSET=latin1; +INSERT INTO t1 values (1),(1); +-- error 1240 +UPDATE t SET id=(SELECT * FROM t1); +drop table t; diff --git a/sql/item_func.cc b/sql/item_func.cc index 364bea4c1f5..1611b5f2257 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -108,8 +108,6 @@ Item_func::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) Set return character set to first argument if we are returning a string. */ - if (result_type() == STRING_RESULT) - set_charset((*args)->charset()); for (arg=args, arg_end=args+arg_count; arg != arg_end ; arg++) { if ((*arg)->check_cols(allowed_arg_cols) || @@ -123,6 +121,8 @@ Item_func::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) used_tables_cache|=(*arg)->used_tables(); const_item_cache&= (*arg)->const_item(); } + if (result_type() == STRING_RESULT) + set_charset((*args)->charset()); } fix_length_and_dec(); fixed= 1; diff --git a/sql/item_sum.cc b/sql/item_sum.cc index fe7523a5fc5..63329cd3823 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -41,7 +41,7 @@ Item_sum::Item_sum(List &list) list.empty(); // Fields are used } -void Item_sum::mark_as_sum_func() +inline void Item_sum::mark_as_sum_func() { current_thd->lex.current_select->with_sum_func= with_sum_func= 1; } diff --git a/sql/item_sum.h b/sql/item_sum.h index 00803abf25d..56b36b615f4 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -34,6 +34,7 @@ public: uint arg_count; bool quick_group; /* If incremental update of fields */ + inline void mark_as_sum_func(); Item_sum() : arg_count(0),quick_group(1) { mark_as_sum_func(); @@ -54,7 +55,6 @@ public: } Item_sum(List &list); ~Item_sum() { result_field=0; } - inline void mark_as_sum_func(); enum Type type() const { return SUM_FUNC_ITEM; } virtual enum Sumfunctype sum_func () const=0; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index e8836350b8a..1bb66c2a766 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -582,6 +582,9 @@ bool close_thread_table(THD *thd, TABLE **table_ptr); void close_temporary_tables(THD *thd); TABLE_LIST * find_table_in_list(TABLE_LIST *table, const char *db_name, const char *table_name); +TABLE_LIST * find_real_table_in_list(TABLE_LIST *table, + const char *db_name, + const char *table_name); TABLE **find_temporary_table(THD *thd, const char *db, const char *table_name); bool close_temporary_table(THD *thd, const char *db, const char *table_name); void close_temporary(TABLE *table, bool delete_table=1); diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index 1a81a7e9182..31d47b821e0 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -256,4 +256,5 @@ v/* "Cyclic reference on subqueries", "Converting column '%s' from %s to %s", "Reference '%-.64s' not supported (%s)", +"Every derived table must have it's own alias" "Select %u was reduced during optimisation", diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index e2d33a06fb3..ca5a6918517 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -250,4 +250,5 @@ "Cyclic reference on subqueries", "Converting column '%s' from %s to %s", "Reference '%-.64s' not supported (%s)", +"Every derived table must have it's own alias" "Select %u was reduced during optimisation", diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index f4f2227f27f..6f5754dee76 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -258,4 +258,5 @@ "Cyclic reference on subqueries", "Converting column '%s' from %s to %s", "Reference '%-.64s' not supported (%s)", +"Every derived table must have it's own alias" "Select %u was reduced during optimisation", diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index 78c6e5185ec..66ca9eab596 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -247,4 +247,5 @@ "Cyclic reference on subqueries", "Converting column '%s' from %s to %s", "Reference '%-.64s' not supported (%s)", +"Every derived table must have it's own alias" "Select %u was reduced during optimisation", diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index 236c688a048..757ae5b6443 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -252,4 +252,5 @@ "Cyclic reference on subqueries", "Converting column '%s' from %s to %s", "Reference '%-.64s' not supported (%s)", +"Every derived table must have it's own alias" "Select %u was reduced during optimisation", diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index fa732ed10e4..43952d848c4 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -247,4 +247,5 @@ "Cyclic reference on subqueries", "Converting column '%s' from %s to %s", "Reference '%-.64s' not supported (%s)", +"Every derived table must have it's own alias" "Select %u was reduced during optimisation", diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index 62da0945799..f9a70feb549 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -250,4 +250,5 @@ "Cyclic reference on subqueries", "Converting column '%s' from %s to %s", "Reference '%-.64s' not supported (%s)", +"Every derived table must have it's own alias" "Select %u was reduced during optimisation", diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index e4b594faad3..9410c3d69bb 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -247,4 +247,5 @@ "Cyclic reference on subqueries", "Converting column '%s' from %s to %s", "Reference '%-.64s' not supported (%s)", +"Every derived table must have it's own alias" "Select %u was reduced during optimisation", diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index 161d686a0d7..1410a88af4a 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -249,4 +249,5 @@ "Cyclic reference on subqueries", "Converting column '%s' from %s to %s", "Reference '%-.64s' not supported (%s)", +"Every derived table must have it's own alias" "Select %u was reduced during optimisation", diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index 806cf1bbc2c..499c06e64dc 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -247,4 +247,5 @@ "Cyclic reference on subqueries", "Converting column '%s' from %s to %s", "Reference '%-.64s' not supported (%s)", +"Every derived table must have it's own alias" "Select %u was reduced during optimisation", diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index 06ab3e3df25..90a6e23efbd 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -249,4 +249,5 @@ "Cyclic reference on subqueries", "Converting column '%s' from %s to %s", "Reference '%-.64s' not supported (%s)", +"Every derived table must have it's own alias" "Select %u was reduced during optimisation", diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index 707b45f1cd4..f05ab3148eb 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -247,4 +247,5 @@ "Cyclic reference on subqueries", "Converting column '%s' from %s to %s", "Reference '%-.64s' not supported (%s)", +"Every derived table must have it's own alias" "Select %u was reduced during optimisation", diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index 42d3245f3fb..5e75877145c 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -249,4 +249,5 @@ "Cyclic reference on subqueries", "Converting column '%s' from %s to %s", "Reference '%-.64s' not supported (%s)", +"Every derived table must have it's own alias" "Select %u was reduced during optimisation", diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index 7db402f193c..4330827fe1c 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -249,4 +249,5 @@ "Cyclic reference on subqueries", "Converting column '%s' from %s to %s", "Reference '%-.64s' not supported (%s)", +"Every derived table must have it's own alias" "Select %u was reduced during optimisation", diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index c10c41c4c8b..db5b97554ff 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -251,4 +251,5 @@ "Cyclic reference on subqueries", "Converting column '%s' from %s to %s", "Reference '%-.64s' not supported (%s)", +"Every derived table must have it's own alias" "Select %u was reduced during optimisation", diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index 8c84b0f71cf..80c1b498345 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -247,4 +247,5 @@ "Cyclic reference on subqueries", "Converting column '%s' from %s to %s", "Reference '%-.64s' not supported (%s)", +"Every derived table must have it's own alias" "Select %u was reduced during optimisation", diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index 24d220f1f9d..59f6e550650 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -251,4 +251,5 @@ "Cyclic reference on subqueries", "Converting column '%s' from %s to %s" "Reference '%-.64s' not supported (%s)", +"Every derived table must have it's own alias" "Select %u was reduced during optimisation", diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index ec682f7778e..fafcc61f60a 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -250,4 +250,5 @@ "Циклическая ссылка на подзапрос", "Преобразование поля '%s' из %s в %s", "Ссылка '%-.64s' не поддерживается (%s)", +"Every derived table must have it's own alias" "Select %u был упразднен в процессе оптимизации", diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index 4ccbc95eefc..6bcecf9e4c9 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -243,4 +243,5 @@ "Cyclic reference on subqueries", "Converting column '%s' from %s to %s", "Reference '%-.64s' not supported (%s)", +"Every derived table must have it's own alias" "Select %u was reduced during optimisation", diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index e66ea93b021..55ead96545c 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -255,4 +255,5 @@ "Cyclic reference on subqueries", "Converting column '%s' from %s to %s", "Reference '%-.64s' not supported (%s)", +"Every derived table must have it's own alias" "Select %u was reduced during optimisation", diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index 8de5202952b..93a0abeed39 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -248,4 +248,5 @@ "Cyclic reference on subqueries", "Converting column '%s' from %s to %s", "Reference '%-.64s' not supported (%s)", +"Every derived table must have it's own alias" "Select %u was reduced during optimisation", diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index 31f4239e8e3..a996898446e 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -247,4 +247,5 @@ "Syklisk referens i subselect", "Konvertar kolumn '%s' frЕn %s till %s", "Reference '%-.64s' not supported (%s)", +"Every derived table must have it's own alias" "Select %u was reduced during optimisation", diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index 1caedcbb19c..0ec1d88e601 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -252,4 +252,5 @@ "Цикл╕чне посилання на п╕дзапит", "Перетворення стовбца '%s' з %s у %s", "Посилання '%-.64s' не пiдтримуется (%s)", +"Every derived table must have it's own alias" "Select %u was скасовано при оптимiзацii", diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 8f74903027e..fc7629caae3 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -744,7 +744,7 @@ void close_temporary_tables(THD *thd) } /* - Find first suitable table in given list. + Find first suitable table by alias in given list. SYNOPSIS find_table_in_list() @@ -767,6 +767,31 @@ TABLE_LIST * find_table_in_list(TABLE_LIST *table, return table; } +/* + Find real table in given list. + + SYNOPSIS + find_table_in_list() + table - pointer to table list + db_name - data base name + table_name - table name + + RETURN VALUES + NULL Table not found + # Pointer to found table. +*/ + +TABLE_LIST * find_real_table_in_list(TABLE_LIST *table, + const char *db_name, + const char *table_name) +{ + for (; table; table= table->next) + if (!strcmp(table->db, db_name) && + !strcmp(table->real_name, table_name)) + break; + return table; +} + TABLE **find_temporary_table(THD *thd, const char *db, const char *table_name) { char key[MAX_DBKEY_LENGTH]; @@ -1894,13 +1919,13 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables, const char *name=item->field_name; uint length=(uint) strlen(name); - if (table_name) + if (table_name && table_name[0]) { /* Qualified field */ bool found_table=0; for (; tables ; tables=tables->next) { if (!strcmp(tables->alias,table_name) && - (!db || !strcmp(db,tables->db))) + (!db || !tables->db || !tables->db[0] || !strcmp(db,tables->db))) { found_table=1; Field *find=find_field_in_table(thd,tables->table,name,length, diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 07958ebcfab..d35790da1b0 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -51,6 +51,12 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ORDER *order, if (setup_conds(thd, delete_table_list, &conds) || setup_ftfuncs(&thd->lex.select_lex)) DBUG_RETURN(-1); + if (find_real_table_in_list(table_list->next, + table_list->db, table_list->real_name)) + { + my_error(ER_INSERT_TABLE_USED, MYF(0), table_list->real_name); + DBUG_RETURN(-1); + } const_cond= (!conds || conds->const_item()); safe_update=test(thd->options & OPTION_SAFE_UPDATES); @@ -134,9 +140,11 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ORDER *order, deleted=0L; init_ftfuncs(thd, &thd->lex.select_lex, 1); thd->proc_info="updating"; - while (!(error=info.read_record(&info)) && !thd->killed) + while (!(error=info.read_record(&info)) && !thd->killed && + !thd->net.report_error) { - if (!(select && select->skipp_record())) + // thd->net.report_error is tested to disallow delete row on error + if (!(select && select->skipp_record())&& !thd->net.report_error ) { if (!(error=table->file->delete_row(table->record[0]))) { @@ -199,7 +207,7 @@ cleanup: thd->lock=0; } delete select; - if (error >= 0) // Fatal error + if (error >= 0 || thd->net.report_error) send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN: 0); else { diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index afdd1ccfdb2..76a97a2e4b8 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -106,10 +106,16 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t) t->table=table; table->derived_select_number= sl->select_number; table->tmp_table=TMP_TABLE; - if (!lex->describe) + if (lex->describe) + { + if (tables) + tables->table_list->table=tables->table; // to fix a problem in EXPLAIN + } + else sl->exclude(); t->db=(char *)""; t->derived=(SELECT_LEX *)0; // just in case ... + table->file->info(HA_STATUS_VARIABLE); } } delete derived_result; diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 1ca44046997..9ee824d0e2c 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -171,6 +171,13 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List &fields, table->time_stamp= save_time_stamp; goto abort; } + if (find_real_table_in_list(table_list->next, + table_list->db, table_list->real_name)) + { + my_error(ER_INSERT_TABLE_USED, MYF(0), table_list->real_name); + goto abort; + } + value_count= values->elements; while ((values= its++)) { @@ -228,9 +235,10 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List &fields, if (fields.elements || !value_count) { restore_record(table,2); // Get empty record - if (fill_record(fields,*values) || check_null_fields(thd,table)) + if (fill_record(fields,*values)|| thd->net.report_error || + check_null_fields(thd,table)) { - if (values_list.elements != 1) + if (values_list.elements != 1 && !thd->net.report_error) { info.records++; continue; @@ -245,9 +253,9 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List &fields, restore_record(table,2); // Get empty record else table->record[0][0]=table->record[2][0]; // Fix delete marker - if (fill_record(table->field,*values)) + if (fill_record(table->field,*values) || thd->net.report_error) { - if (values_list.elements != 1) + if (values_list.elements != 1 && ! thd->net.report_error) { info.records++; continue; @@ -1342,7 +1350,7 @@ bool select_insert::send_data(List &values) fill_record(*fields,values); else fill_record(table->field,values); - if (write_record(table,&info)) + if (thd->net.report_error || write_record(table,&info)) return 1; if (table->next_number_field) // Clear for next record { @@ -1456,7 +1464,7 @@ bool select_create::send_data(List &values) return 0; } fill_record(field,values); - if (write_record(table,&info)) + if (thd->net.report_error ||write_record(table,&info)) return 1; if (table->next_number_field) // Clear for next record { diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index be0430d4afe..d765c741932 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -442,13 +442,13 @@ inline static uint int_token(const char *str,uint length) // STATE_OPERATOR_OR_IDENT ; last state was an ident, text or number // (which can't be followed by a signed number) -int yylex(void *arg) +int yylex(void *arg, void *yythd) { reg1 uchar c; int tokval; uint length; enum lex_states state,prev_state; - LEX *lex=current_lex; + LEX *lex= &(((THD *)yythd)->lex); YYSTYPE *yylval=(YYSTYPE*) arg; lex->yylval=yylval; // The global state @@ -1205,6 +1205,8 @@ bool st_select_lex_unit::create_total_list_n_last_return(THD *thd, st_lex *lex, net_printf(thd,ER_WRONG_USAGE,"UNION","ORDER BY"); return 1; } + if (sl->linkage == DERIVED_TABLE_TYPE) + continue; for (SELECT_LEX_UNIT *inner= sl->first_inner_unit(); inner; inner= inner->next_unit()) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index cfca7420237..ac5e06fe87c 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -60,7 +60,6 @@ static int check_for_max_user_connections(THD *thd, USER_CONN *uc); static void decrease_user_connections(USER_CONN *uc); static bool check_db_used(THD *thd,TABLE_LIST *tables); static bool check_merge_table_access(THD *thd, char *db, TABLE_LIST *tables); -static bool check_dup(const char *db, const char *name, TABLE_LIST *tables); static void remove_escape(char *name); static void refresh_status(void); static bool append_file_to_dir(THD *thd, char **filename_ptr, @@ -1803,7 +1802,7 @@ mysql_execute_command(THD *thd) select_result *result; if (!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) && - check_dup(tables->db, tables->real_name, tables->next)) + find_real_table_in_list(tables->next, tables->db, tables->real_name)) { net_printf(thd,ER_INSERT_TABLE_USED,tables->real_name); DBUG_VOID_RETURN; @@ -2059,6 +2058,8 @@ mysql_execute_command(THD *thd) (ORDER *) select_lex->order_list.first, select_lex->select_limit, lex->duplicates); + if (thd->net.report_error) + res= -1; break; case SQLCOM_UPDATE_MULTI: if (check_access(thd,UPDATE_ACL,tables->db,&tables->grant.privilege)) @@ -2118,6 +2119,8 @@ mysql_execute_command(THD *thd) SELECT_NO_JOIN_CACHE, result, unit, select_lex, 0); delete result; + if (thd->net.report_error) + res= -1; } else res= -1; // Error is not sent @@ -2135,6 +2138,8 @@ mysql_execute_command(THD *thd) goto error; res = mysql_insert(thd,tables,lex->field_list,lex->many_values, lex->duplicates); + if (thd->net.report_error) + res= -1; break; } case SQLCOM_REPLACE_SELECT: @@ -2165,7 +2170,7 @@ mysql_execute_command(THD *thd) if (unit->select_limit_cnt < select_lex->select_limit) unit->select_limit_cnt= HA_POS_ERROR; // No limit - if (check_dup(tables->db, tables->real_name, tables->next)) + if (find_real_table_in_list(tables->next, tables->db, tables->real_name)) { net_printf(thd,ER_INSERT_TABLE_USED,tables->real_name); DBUG_VOID_RETURN; @@ -2179,6 +2184,8 @@ mysql_execute_command(THD *thd) if ((result=new select_insert(tables->table,&lex->field_list, lex->duplicates))) res=handle_select(thd,lex,result); + if (thd->net.report_error) + res= -1; } else res= -1; @@ -2209,6 +2216,8 @@ mysql_execute_command(THD *thd) res = mysql_delete(thd,tables, select_lex->where, (ORDER*) select_lex->order_list.first, select_lex->select_limit, select_lex->options); + if (thd->net.report_error) + res= -1; break; } case SQLCOM_DELETE_MULTI: @@ -2258,6 +2267,17 @@ mysql_execute_command(THD *thd) /* Fix tables-to-be-deleted-from list to point at opened tables */ for (auxi=(TABLE_LIST*) aux_tables ; auxi ; auxi=auxi->next) auxi->table= auxi->table_list->table; + if (&lex->select_lex != lex->all_selects_list) + for (TABLE_LIST *t= select_lex->get_table_list(); + t; t= t->next) + { + if (find_real_table_in_list(t->table_list->next, t->db, t->real_name)) + { + my_error(ER_INSERT_TABLE_USED, MYF(0), t->real_name); + res= -1; + break; + } + } fix_tables_pointers(lex->all_selects_list); if (!thd->fatal_error && (result= new multi_delete(thd,aux_tables, table_count))) @@ -2270,6 +2290,8 @@ mysql_execute_command(THD *thd) select_lex->options | thd->options | SELECT_NO_JOIN_CACHE, result, unit, select_lex, 0); + if (thd->net.report_error) + res= -1; delete result; } else @@ -3568,9 +3590,15 @@ TABLE_LIST *st_select_lex::add_table_to_list(Table_ident *table, } if (!alias) /* Alias is case sensitive */ + { + if (table->sel) + { + net_printf(thd,ER_DERIVED_MUST_HAVE_ALIAS); + DBUG_RETURN(0); + } if (!(alias_str=thd->memdup(alias_str,table->table.length+1))) DBUG_RETURN(0); - + } if (!(ptr = (TABLE_LIST *) thd->calloc(sizeof(TABLE_LIST)))) DBUG_RETURN(0); /* purecov: inspected */ if (table->db.str) @@ -3679,16 +3707,6 @@ void add_join_natural(TABLE_LIST *a,TABLE_LIST *b) b->natural_join=a; } - /* Check if name is used in table list */ - -static bool check_dup(const char *db, const char *name, TABLE_LIST *tables) -{ - for (; tables ; tables=tables->next) - if (!strcmp(name,tables->real_name) && !strcmp(db,tables->db)) - return 1; - return 0; -} - bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables) { bool result=0; diff --git a/sql/sql_union.cc b/sql/sql_union.cc index d448a5204e2..e170f6c040e 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -76,7 +76,7 @@ bool select_union::send_data(List &values) return 0; } fill_record(table->field,values); - if ((write_record(table,&info))) + if (thd->net.report_error || write_record(table,&info)) { if (thd->net.last_errno == ER_RECORD_FILE_FULL) { diff --git a/sql/sql_update.cc b/sql/sql_update.cc index c2ba65248a7..c3ae435d851 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -86,6 +86,13 @@ int mysql_update(THD *thd, setup_conds(thd,update_table_list,&conds) || setup_ftfuncs(&thd->lex.select_lex)) DBUG_RETURN(-1); /* purecov: inspected */ + if (find_real_table_in_list(table_list->next, + table_list->db, table_list->real_name)) + { + my_error(ER_INSERT_TABLE_USED, MYF(0), table_list->real_name); + DBUG_RETURN(-1); + } + old_used_keys=table->used_keys; // Keys used in WHERE /* @@ -274,7 +281,7 @@ int mysql_update(THD *thd, if (!(select && select->skipp_record())) { store_record(table,1); - if (fill_record(fields,values)) + if (fill_record(fields,values) || thd->net.report_error) break; /* purecov: inspected */ found++; if (compare_record(table, query_id)) @@ -598,7 +605,7 @@ bool multi_update::send_data(List &values) // Only one table being updated receives a completely different treatment table->status|= STATUS_UPDATED; store_record(table,1); - if (fill_record(fields,real_values)) + if (fill_record(fields,real_values) || thd->net.report_error) return 1; found++; if (/* compare_record(table, query_id) && */ @@ -637,7 +644,8 @@ bool multi_update::send_data(List &values) { table->status|= STATUS_UPDATED; store_record(table,1); - if (fill_record(*fields_by_tables[0],values_by_table)) + if (fill_record(*fields_by_tables[0], values_by_table) || + thd->net.report_error) return 1; found++; if (/*compare_record(table, query_id) && */ @@ -660,8 +668,8 @@ bool multi_update::send_data(List &values) table->file->ref_length, system_charset_info)); fill_record(tmp_tables[secure_counter]->field,values_by_table); - error= write_record(tmp_tables[secure_counter], - &(infos[secure_counter])); + error= thd->net.report_error || + write_record(tmp_tables[secure_counter], &(infos[secure_counter])); if (error) { error=-1; @@ -767,8 +775,10 @@ int multi_update::do_updates (bool from_send_error) table->status|= STATUS_UPDATED; store_record(table,1); local_error= (fill_record(*fields_by_tables[counter + 1],list) || + thd->net.report_error || /* compare_record(table, query_id) || */ - table->file->update_row(table->record[1],table->record[0])); + table->file->update_row(table->record[1], + table->record[0])); if (local_error) { table->file->print_error(local_error,MYF(0)); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index d80545dfbcb..70a1ebc79ec 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -17,10 +17,12 @@ /* sql_yacc.yy */ %{ -/* Pass thd as an arg to yyparse(). The type will be void*, so it -** must be cast to (THD*) when used. Use the YYTHD macro for this. +/* thd is passed as an arg to yyparse(), and subsequently to yylex(). +** The type will be void*, so it must be cast to (THD*) when used. +** Use the YYTHD macro for this. */ #define YYPARSE_PARAM yythd +#define YYLEX_PARAM yythd #define YYTHD ((THD *)yythd) #define MYSQL_YACC @@ -37,7 +39,7 @@ #include extern void yyerror(const char*); -int yylex(void *yylval); +int yylex(void *yylval, void *yythd); #define yyoverflow(A,B,C,D,E,F) if (my_yyoverflow((B),(D),(int*) (F))) { yyerror((char*) (A)); return 2; } @@ -2977,7 +2979,7 @@ insert_values: lex->lock_option= (using_update_log) ? TL_READ_NO_INSERT : TL_READ; mysql_init_select(lex); } - select_options select_item_list select_from select_lock_type + select_options select_item_list opt_select_from select_lock_type union_clause {} ;