diff --git a/mysql-test/r/bdb_notembedded.result b/mysql-test/r/bdb_notembedded.result deleted file mode 100644 index 14cb5fad915..00000000000 --- a/mysql-test/r/bdb_notembedded.result +++ /dev/null @@ -1,35 +0,0 @@ -set autocommit=1; -reset master; -create table bug16206 (a int); -insert into bug16206 values(1); -start transaction; -insert into bug16206 values(2); -commit; -show binlog events; -Log_name Pos Event_type Server_id End_log_pos Info -f n Format_desc 1 n Server ver: VERSION, Binlog ver: 4 -f n Query 1 n use `test`; create table bug16206 (a int) -f n Query 1 n use `test`; insert into bug16206 values(1) -f n Query 1 n use `test`; insert into bug16206 values(2) -drop table bug16206; -reset master; -create table bug16206 (a int) engine= bdb; -insert into bug16206 values(0); -insert into bug16206 values(1); -start transaction; -insert into bug16206 values(2); -commit; -insert into bug16206 values(3); -show binlog events; -Log_name Pos Event_type Server_id End_log_pos Info -f n Format_desc 1 n Server ver: VERSION, Binlog ver: 4 -f n Query 1 n use `test`; create table bug16206 (a int) engine= bdb -f n Query 1 n use `test`; insert into bug16206 values(0) -f n Query 1 n use `test`; insert into bug16206 values(1) -f n Query 1 n use `test`; BEGIN -f n Query 1 n use `test`; insert into bug16206 values(2) -f n Query 1 n use `test`; COMMIT -f n Query 1 n use `test`; insert into bug16206 values(3) -drop table bug16206; -set autocommit=0; -End of 5.0 tests diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result index ab5d23d6cea..006dc951297 100644 --- a/mysql-test/r/create.result +++ b/mysql-test/r/create.result @@ -750,6 +750,44 @@ t2 CREATE TABLE `t2` ( drop table t1, t2; create table t1(a set("a,b","c,d") not null); ERROR 22007: Illegal set 'a,b' value found during parsing +create database mysqltest; +use mysqltest; +grant create on mysqltest.* to mysqltest@localhost; +create table t1 (i INT); +insert into t1 values (1); +ERROR 42000: Access denied for user 'mysqltest'@'localhost' to database 'mysqltest' +create table t2 (i INT); +create table t4 (i INT); +grant select, insert on mysqltest.t2 to mysqltest@localhost; +grant insert on mysqltest.t4 to mysqltest@localhost; +grant create, insert on mysqltest.t5 to mysqltest@localhost; +grant create, insert on mysqltest.t6 to mysqltest@localhost; +flush privileges; +insert into t2 values (1); +create table if not exists t1 select * from t2; +ERROR 42000: INSERT command denied to user 'mysqltest'@'localhost' for table 't1' +create table if not exists t3 select * from t2; +ERROR 42000: INSERT command denied to user 'mysqltest'@'localhost' for table 't3' +create table if not exists t4 select * from t2; +Warnings: +Note 1050 Table 't4' already exists +create table if not exists t5 select * from t2; +create table t6 select * from t2; +create table t7 select * from t2; +ERROR 42000: INSERT command denied to user 'mysqltest'@'localhost' for table 't7' +create table t4 select * from t2; +ERROR 42S01: Table 't4' already exists +create table t1 select * from t2; +ERROR 42000: INSERT command denied to user 'mysqltest'@'localhost' for table 't1' +drop table t1,t2,t4,t5,t6; +revoke create on mysqltest.* from mysqltest@localhost; +revoke select, insert on mysqltest.t2 from mysqltest@localhost; +revoke insert on mysqltest.t4 from mysqltest@localhost; +revoke create, insert on mysqltest.t5 from mysqltest@localhost; +revoke create, insert on mysqltest.t6 from mysqltest@localhost; +flush privileges; +drop database mysqltest; +use test; create table t1 (i int) engine=myisam max_rows=100000000000; show create table t1; Table Create Table diff --git a/mysql-test/t/bdb_notembedded.test b/mysql-test/t/bdb_notembedded.test deleted file mode 100644 index 24e64ebbfb2..00000000000 --- a/mysql-test/t/bdb_notembedded.test +++ /dev/null @@ -1,38 +0,0 @@ --- source include/not_embedded.inc --- source include/have_bdb.inc - -# -# Bug #16206: Superfluous COMMIT event in binlog when updating BDB in autocommit mode -# -set autocommit=1; - -let $VERSION=`select version()`; - -reset master; -create table bug16206 (a int); -insert into bug16206 values(1); -start transaction; -insert into bug16206 values(2); -commit; ---replace_result $VERSION VERSION ---replace_column 1 f 2 n 5 n -show binlog events; -drop table bug16206; - -reset master; -create table bug16206 (a int) engine= bdb; -insert into bug16206 values(0); -insert into bug16206 values(1); -start transaction; -insert into bug16206 values(2); -commit; -insert into bug16206 values(3); ---replace_result $VERSION VERSION ---replace_column 1 f 2 n 5 n -show binlog events; -drop table bug16206; - -set autocommit=0; - - ---echo End of 5.0 tests diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test index 64081c0248a..106ecbb2586 100644 --- a/mysql-test/t/create.test +++ b/mysql-test/t/create.test @@ -654,6 +654,82 @@ drop table t1, t2; --error 1367 create table t1(a set("a,b","c,d") not null); +# +# Bug #20901 - CREATE privilege is enough to insert into a table +# + +create database mysqltest; +use mysqltest; + +grant create on mysqltest.* to mysqltest@localhost; +create table t1 (i INT); + +connect (user1,localhost,mysqltest,,mysqltest); +connection user1; +# show we don't have INSERT +--error 1044 +insert into t1 values (1); +# show we have CREATE +create table t2 (i INT); +create table t4 (i INT); + +connection default; +grant select, insert on mysqltest.t2 to mysqltest@localhost; +grant insert on mysqltest.t4 to mysqltest@localhost; +# to specify ACLs for non-existent objects, must explictly |CREATE +grant create, insert on mysqltest.t5 to mysqltest@localhost; +grant create, insert on mysqltest.t6 to mysqltest@localhost; +flush privileges; + +connection user1; +insert into t2 values (1); + + +# CREATE IF NOT EXISTS...SELECT, t1 exists, no INSERT, must fail +--error 1142 +create table if not exists t1 select * from t2; + +# CREATE IF NOT EXISTS...SELECT, no t3 yet, no INSERT, must fail +--error 1142 +create table if not exists t3 select * from t2; + +# CREATE IF NOT EXISTS...SELECT, t4 exists, have INSERT, must succeed +create table if not exists t4 select * from t2; + +# CREATE IF NOT EXISTS...SELECT, no t5 yet, have INSERT, must succeed +create table if not exists t5 select * from t2; + + +# CREATE...SELECT, no t6 yet, have INSERT, must succeed +create table t6 select * from t2; + +# CREATE...SELECT, no t7 yet, no INSERT, must fail +--error 1142 +create table t7 select * from t2; + +# CREATE...SELECT, t4 exists, have INSERT, must still fail (exists) +--error 1050 +create table t4 select * from t2; + +# CREATE...SELECT, t1 exists, no INSERT, must fail +--error 1142 +create table t1 select * from t2; + + +connection default; +drop table t1,t2,t4,t5,t6; + +revoke create on mysqltest.* from mysqltest@localhost; +revoke select, insert on mysqltest.t2 from mysqltest@localhost; +revoke insert on mysqltest.t4 from mysqltest@localhost; +revoke create, insert on mysqltest.t5 from mysqltest@localhost; +revoke create, insert on mysqltest.t6 from mysqltest@localhost; +flush privileges; + +disconnect user1; +drop database mysqltest; +use test; + # End of 4.1 tests diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 084bcfc3c76..e24f679d0fb 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -7600,8 +7600,15 @@ bool create_table_precheck(THD *thd, TABLE_LIST *tables, bool error= TRUE; // Error message is given DBUG_ENTER("create_table_precheck"); + /* + Require CREATE [TEMPORARY] privilege on new table; for + CREATE TABLE ... SELECT, also require INSERT. + */ + want_priv= ((lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) ? - CREATE_TMP_ACL : CREATE_ACL); + CREATE_TMP_ACL : CREATE_ACL) | + (select_lex->item_list.elements ? INSERT_ACL : 0); + if (check_access(thd, want_priv, create_table->db, &create_table->grant.privilege, 0, 0, test(create_table->schema_table)) ||