diff options
-rw-r--r-- | mysql-test/r/subselect.result | 6 | ||||
-rw-r--r-- | mysql-test/t/subselect.test | 2 | ||||
-rw-r--r-- | sql/sql_parse.cc | 54 |
3 files changed, 49 insertions, 13 deletions
diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 1a4701d8d0e..41620bb6e7f 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -606,14 +606,14 @@ x 3 INSERT INTO t1 (x) select (SELECT SUM(x)+2 FROM t1) FROM t2; You can't specify target table 't1' for update in FROM clause -INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(x) FROM t2)); +INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2)); select * from t1; x 1 2 3 3 -0 +2 drop table t1, t2, t3; CREATE TABLE t1 (x int not null, y int, primary key (x)); create table t2 (a int); @@ -688,6 +688,8 @@ id 2 INSERT INTO t2 VALUES ((SELECT * FROM t2)); You can't specify target table 't2' for update in FROM clause +INSERT INTO t2 VALUES ((SELECT id FROM t2)); +You can't specify target table 't2' for update in FROM clause SELECT * FROM t2; id 1 diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 4a171c36293..8377a756c5b 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -351,7 +351,7 @@ 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 t2)); +INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2)); -- sleep 1 select * from t1; drop table t1, t2, t3; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index e6ffec7ef26..473c1dd07f6 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2285,15 +2285,23 @@ mysql_execute_command(THD *thd) TABLE_LIST *table; if (check_db_used(thd,tables)) goto error; - for (table=tables ; table ; table=table->next) + + if (check_access(thd,UPDATE_ACL,tables->db,&tables->grant.privilege)) + goto error; { - if (table->derived) - table->grant.privilege= SELECT_ACL; - else if (check_access(thd,UPDATE_ACL,table->db,&table->grant.privilege)) + // Show only 1 table for check_grant + TABLE_LIST *subselects_tables= tables->next; + tables->next= 0; + if (grant_option && check_grant(thd, UPDATE_ACL, tables)) + goto error; + tables->next= subselects_tables; + + // check rights on tables of subselect (if exists) + if (subselects_tables && + (res= check_table_access(thd, SELECT_ACL, subselects_tables))) goto error; } - if (grant_option && check_grant(thd,UPDATE_ACL,tables)) - goto error; + if (select_lex->item_list.elements != lex->value_list.elements) { send_error(thd,ER_WRONG_VALUE_COUNT); @@ -2349,8 +2357,21 @@ mysql_execute_command(THD *thd) INSERT_ACL | DELETE_ACL : INSERT_ACL | update); if (check_access(thd,privilege,tables->db,&tables->grant.privilege)) goto error; /* purecov: inspected */ - if (grant_option && check_grant(thd,privilege,tables)) - goto error; + + { + // Show only 1 table for check_grant + TABLE_LIST *subselects_tables= tables->next; + tables->next= 0; + if (grant_option && check_grant(thd, privilege, tables)) + goto error; + tables->next= subselects_tables; + + // check rights on tables of subselect (if exists) + if (subselects_tables && + (res= check_table_access(thd, SELECT_ACL, subselects_tables))) + goto error; + } + if (select_lex->item_list.elements != lex->value_list.elements) { send_error(thd,ER_WRONG_VALUE_COUNT); @@ -2434,8 +2455,21 @@ mysql_execute_command(THD *thd) { if (check_access(thd,DELETE_ACL,tables->db,&tables->grant.privilege)) goto error; /* purecov: inspected */ - if (grant_option && check_grant(thd,DELETE_ACL,tables)) - goto error; + + { + // Show only 1 table for check_grant + TABLE_LIST *subselects_tables= tables->next; + tables->next= 0; + if (grant_option && check_grant(thd, DELETE_ACL, tables)) + goto error; + tables->next= subselects_tables; + + // check rights on tables of subselect (if exists) + if (subselects_tables && + (res= check_table_access(thd, SELECT_ACL, subselects_tables))) + goto error; + } + // Set privilege for the WHERE clause tables->grant.want_privilege=(SELECT_ACL & ~tables->grant.privilege); res = mysql_delete(thd,tables, select_lex->where, |