summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/subselect.result6
-rw-r--r--mysql-test/t/subselect.test2
-rw-r--r--sql/sql_parse.cc54
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,