Merge bk-internal.mysql.com:/data0/bk/mysql-5.0

into  bk-internal.mysql.com:/data0/bk/mysql-5.0-marvel


client/mysql.cc:
  Auto merged
heap/hp_write.c:
  Auto merged
sql/ha_ndbcluster.cc:
  Auto merged
sql/handler.cc:
  Auto merged
sql/item.cc:
  Auto merged
sql/mysqld.cc:
  Auto merged
sql/opt_range.cc:
  Auto merged
sql/sql_base.cc:
  Auto merged
sql/sql_class.cc:
  Auto merged
sql/sql_class.h:
  Auto merged
sql/sql_delete.cc:
  Auto merged
sql/sql_insert.cc:
  Auto merged
sql/sql_load.cc:
  Auto merged
sql/sql_select.cc:
  Auto merged
sql/sql_table.cc:
  Auto merged
This commit is contained in:
unknown 2007-04-03 13:55:20 +02:00
commit bceecfa820
49 changed files with 1554 additions and 411 deletions

View File

@ -51,5 +51,5 @@ enum options_client
OPT_TRIGGERS,
OPT_IGNORE_TABLE,OPT_INSERT_IGNORE,OPT_SHOW_WARNINGS,OPT_DROP_DATABASE,
OPT_TZ_UTC, OPT_AUTO_CLOSE, OPT_SSL_VERIFY_SERVER_CERT,
OPT_DEBUG_INFO
OPT_DEBUG_INFO, OPT_ERROR_LOG_FILE
};

View File

@ -1042,7 +1042,7 @@ static int dump_remote_log_entries(PRINT_EVENT_INFO *print_event_info,
uint logname_len;
NET* net;
int error= 0;
my_off_t old_off= start_position_mot;
my_off_t old_off= min(start_position_mot, BIN_LOG_HEADER_SIZE);
char fname[FN_REFLEN+1];
DBUG_ENTER("dump_remote_log_entries");
@ -1105,7 +1105,7 @@ could be out of memory");
}
if (len < 8 && net->read_pos[0] == 254)
break; // end of data
DBUG_PRINT("info",( "len: %lu, net->read_pos[5]: %d\n",
DBUG_PRINT("info",( "len: %lu net->read_pos[5]: %d\n",
len, net->read_pos[5]));
if (!(ev= Log_event::read_log_event((const char*) net->read_pos + 1 ,
len - 1, &error_msg,
@ -1195,8 +1195,15 @@ could be out of memory");
}
/*
Let's adjust offset for remote log as for local log to produce
similar text.
similar text and to have --stop-position to work identically.
Exception - the server sends Format_description_log_event
in the beginning of the dump, and only after it the event from
start_position. Let the old_off reflect it.
*/
if (old_off < start_position_mot)
old_off= start_position_mot;
else
old_off+= len-1;
}

View File

@ -105,7 +105,8 @@ static char *opt_password=0,*current_user=0,
*lines_terminated=0, *enclosed=0, *opt_enclosed=0, *escaped=0,
*where=0, *order_by=0,
*opt_compatible_mode_str= 0,
*err_ptr= 0;
*err_ptr= 0,
*log_error_file= NULL;
static char **defaults_argv= 0;
static char compatible_mode_normal_str[255];
static ulong opt_compatible_mode= 0;
@ -117,6 +118,8 @@ static int first_error=0;
static DYNAMIC_STRING extended_row;
#include <sslopt-vars.h>
FILE *md_result_file= 0;
FILE *stderror_file=0;
#ifdef HAVE_SMEM
static char *shared_memory_base_name=0;
#endif
@ -293,6 +296,9 @@ static struct my_option my_long_options[] =
0, 0, 0, 0, 0, 0},
{"lock-tables", 'l', "Lock all tables for read.", (gptr*) &lock_tables,
(gptr*) &lock_tables, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
{"log-error", OPT_ERROR_LOG_FILE, "Append warnings and errors to given file.",
(gptr*) &log_error_file, (gptr*) &log_error_file, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"master-data", OPT_MASTER_DATA,
"This causes the binary log position and filename to be appended to the "
"output. If equal to 1, will print it as a CHANGE MASTER command; if equal"
@ -3694,6 +3700,16 @@ int main(int argc, char **argv)
free_resources(0);
exit(exit_code);
}
if (log_error_file)
{
if(!(stderror_file= freopen(log_error_file, "a+", stderr)))
{
free_resources(0);
exit(EX_MYSQLERR);
}
}
if (connect_to_db(current_host, current_user, opt_password))
{
free_resources(0);
@ -3746,5 +3762,9 @@ err:
if (!path)
write_footer(md_result_file);
free_resources();
if (stderror_file)
fclose(stderror_file);
return(first_error);
} /* main */

View File

@ -140,7 +140,7 @@ class RaidFd {
inline void Calculate()
{
DBUG_ENTER("RaidFd::_Calculate");
DBUG_PRINT("info",("_position: %lu _raid_chunksize: %d, _size: %lu",
DBUG_PRINT("info",("_position: %lu _raid_chunksize: %lu _size: %lu",
(ulong) _position, _raid_chunksize, (ulong) _size));
_total_block = (ulong) (_position / _raid_chunksize);
@ -148,7 +148,7 @@ class RaidFd {
_remaining_bytes = (uint) (_raid_chunksize -
(_position - _total_block * _raid_chunksize));
DBUG_PRINT("info",
("_total_block: %d this_block: %d _remaining_bytes:%d",
("_total_block: %lu this_block: %d _remaining_bytes: %d",
_total_block, _this_block, _remaining_bytes));
DBUG_VOID_RETURN;
}

View File

@ -972,4 +972,126 @@ REVOKE EXECUTE ON PROCEDURE t1 FROM some_user_name@1234567890abcdefghij123456789
ERROR HY000: String '1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY' is too long for host name (should be no longer than 60)
GRANT PROCESS ON * TO user@localhost;
ERROR 3D000: No database selected
DROP DATABASE IF EXISTS mysqltest1;
DROP DATABASE IF EXISTS mysqltest2;
DROP DATABASE IF EXISTS mysqltest3;
DROP DATABASE IF EXISTS mysqltest4;
CREATE DATABASE mysqltest1;
CREATE DATABASE mysqltest2;
CREATE DATABASE mysqltest3;
CREATE DATABASE mysqltest4;
CREATE PROCEDURE mysqltest1.p_def() SQL SECURITY DEFINER
SELECT 1;
CREATE PROCEDURE mysqltest2.p_inv() SQL SECURITY INVOKER
SELECT 1;
CREATE FUNCTION mysqltest3.f_def() RETURNS INT SQL SECURITY DEFINER
RETURN 1;
CREATE FUNCTION mysqltest4.f_inv() RETURNS INT SQL SECURITY INVOKER
RETURN 1;
GRANT EXECUTE ON PROCEDURE mysqltest1.p_def TO mysqltest_1@localhost;
GRANT EXECUTE ON PROCEDURE mysqltest2.p_inv TO mysqltest_1@localhost;
GRANT EXECUTE ON FUNCTION mysqltest3.f_def TO mysqltest_1@localhost;
GRANT EXECUTE ON FUNCTION mysqltest4.f_inv TO mysqltest_1@localhost;
GRANT ALL PRIVILEGES ON test.* TO mysqltest_1@localhost;
---> connection: bug9504_con1
use mysqltest1;
use mysqltest2;
use mysqltest3;
use mysqltest4;
use test;
CALL mysqltest1.p_def();
1
1
CALL mysqltest2.p_inv();
1
1
SELECT mysqltest3.f_def();
mysqltest3.f_def()
1
SELECT mysqltest4.f_inv();
mysqltest4.f_inv()
1
---> connection: default
DROP DATABASE mysqltest1;
DROP DATABASE mysqltest2;
DROP DATABASE mysqltest3;
DROP DATABASE mysqltest4;
DROP USER mysqltest_1@localhost;
DROP DATABASE IF EXISTS mysqltest1;
DROP DATABASE IF EXISTS mysqltest2;
CREATE DATABASE mysqltest1;
CREATE DATABASE mysqltest2;
GRANT ALL PRIVILEGES ON mysqltest1.* TO mysqltest_1@localhost;
GRANT SELECT ON mysqltest2.* TO mysqltest_1@localhost;
CREATE PROCEDURE mysqltest1.p1() SQL SECURITY INVOKER
SELECT 1;
---> connection: bug27337_con1
CREATE TABLE t1(c INT);
ERROR 42000: CREATE command denied to user 'mysqltest_1'@'localhost' for table 't1'
CALL mysqltest1.p1();
1
1
CREATE TABLE t1(c INT);
ERROR 42000: CREATE command denied to user 'mysqltest_1'@'localhost' for table 't1'
---> connection: bug27337_con2
CREATE TABLE t1(c INT);
ERROR 42000: CREATE command denied to user 'mysqltest_1'@'localhost' for table 't1'
SHOW TABLES;
Tables_in_mysqltest2
---> connection: default
DROP DATABASE mysqltest1;
DROP DATABASE mysqltest2;
DROP USER mysqltest_1@localhost;
DROP DATABASE IF EXISTS mysqltest1;
DROP DATABASE IF EXISTS mysqltest2;
CREATE DATABASE mysqltest1;
CREATE DATABASE mysqltest2;
CREATE TABLE mysqltest1.t1(c INT);
CREATE TABLE mysqltest2.t2(c INT);
GRANT SELECT ON mysqltest1.t1 TO mysqltest_1@localhost;
GRANT SELECT ON mysqltest2.t2 TO mysqltest_2@localhost;
---> connection: bug27337_con1
SHOW TABLES FROM mysqltest1;
Tables_in_mysqltest1
t1
PREPARE stmt1 FROM 'SHOW TABLES FROM mysqltest1';
EXECUTE stmt1;
Tables_in_mysqltest1
t1
---> connection: bug27337_con2
SHOW COLUMNS FROM mysqltest2.t2;
Field Type Null Key Default Extra
c int(11) YES NULL
PREPARE stmt2 FROM 'SHOW COLUMNS FROM mysqltest2.t2';
EXECUTE stmt2;
Field Type Null Key Default Extra
c int(11) YES NULL
---> connection: default
REVOKE SELECT ON mysqltest1.t1 FROM mysqltest_1@localhost;
REVOKE SELECT ON mysqltest2.t2 FROM mysqltest_2@localhost;
---> connection: bug27337_con1
SHOW TABLES FROM mysqltest1;
ERROR 42000: Access denied for user 'mysqltest_1'@'localhost' to database 'mysqltest1'
EXECUTE stmt1;
ERROR 42000: Access denied for user 'mysqltest_1'@'localhost' to database 'mysqltest1'
---> connection: bug27337_con2
SHOW COLUMNS FROM mysqltest2.t2;
ERROR 42000: SELECT command denied to user 'mysqltest_2'@'localhost' for table 't2'
EXECUTE stmt2;
ERROR 42000: SELECT command denied to user 'mysqltest_2'@'localhost' for table 't2'
---> connection: default
DROP DATABASE mysqltest1;
DROP DATABASE mysqltest2;
DROP USER mysqltest_1@localhost;
End of 5.0 tests

View File

@ -106,16 +106,82 @@ use testdb_1;
create table t1 (f1 char(4));
create view v1 as select f1 from t1;
grant insert on v1 to testdb_2@localhost;
create view v5 as select f1 from t1;
grant show view on v5 to testdb_2@localhost;
create definer=`no_such_user`@`no_such_host` view v6 as select f1 from t1;
ERROR 42000: Access denied; you need the SUPER privilege for this operation
use testdb_1;
create view v6 as select f1 from t1;
grant show view on v6 to testdb_2@localhost;
create table t2 (f1 char(4));
create definer=`no_such_user`@`no_such_host` view v7 as select * from t2;
Warnings:
Note 1449 There is no 'no_such_user'@'no_such_host' registered
show fields from testdb_1.v6;
Field Type Null Key Default Extra
f1 char(4) YES NULL
show create view testdb_1.v6;
View Create View
v6 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v6` AS select `t1`.`f1` AS `f1` from `t1`
show create view testdb_1.v7;
View Create View
v7 CREATE ALGORITHM=UNDEFINED DEFINER=`no_such_user`@`no_such_host` SQL SECURITY DEFINER VIEW `v7` AS select `testdb_1`.`t2`.`f1` AS `f1` from `t2`
Warnings:
Warning 1356 View 'testdb_1.v7' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
show fields from testdb_1.v7;
Field Type Null Key Default Extra
f1 null YES NULL
Warnings:
Note 1449 There is no 'no_such_user'@'no_such_host' registered
create table t3 (f1 char(4), f2 char(4));
create view v3 as select f1,f2 from t3;
grant insert(f1), insert(f2) on v3 to testdb_2@localhost;
create view v2 as select f1 from testdb_1.v1;
create view v4 as select f1,f2 from testdb_1.v3;
show fields from testdb_1.v5;
Field Type Null Key Default Extra
f1 char(4) YES NULL
show create view testdb_1.v5;
View Create View
v5 CREATE ALGORITHM=UNDEFINED DEFINER=`testdb_1`@`localhost` SQL SECURITY DEFINER VIEW `testdb_1`.`v5` AS select `testdb_1`.`t1`.`f1` AS `f1` from `testdb_1`.`t1`
show fields from testdb_1.v6;
Field Type Null Key Default Extra
f1 char(4) YES NULL
show create view testdb_1.v6;
View Create View
v6 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `testdb_1`.`v6` AS select `testdb_1`.`t1`.`f1` AS `f1` from `testdb_1`.`t1`
show fields from testdb_1.v7;
Field Type Null Key Default Extra
f1 null YES NULL
Warnings:
Note 1449 There is no 'no_such_user'@'no_such_host' registered
show create view testdb_1.v7;
View Create View
v7 CREATE ALGORITHM=UNDEFINED DEFINER=`no_such_user`@`no_such_host` SQL SECURITY DEFINER VIEW `v7` AS select `testdb_1`.`t2`.`f1` AS `f1` from `t2`
Warnings:
Warning 1356 View 'testdb_1.v7' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
revoke insert(f1) on v3 from testdb_2@localhost;
revoke show view on v5 from testdb_2@localhost;
use testdb_1;
revoke show view on v6 from testdb_2@localhost;
show fields from testdb_1.v5;
ERROR 42000: SELECT command denied to user 'testdb_2'@'localhost' for table 'v5'
show create view testdb_1.v5;
ERROR 42000: SELECT command denied to user 'testdb_2'@'localhost' for table 'v5'
show fields from testdb_1.v6;
ERROR 42000: SELECT command denied to user 'testdb_2'@'localhost' for table 'v6'
show create view testdb_1.v6;
ERROR 42000: SELECT command denied to user 'testdb_2'@'localhost' for table 'v6'
show fields from testdb_1.v7;
ERROR 42000: SELECT command denied to user 'testdb_2'@'localhost' for table 'v7'
show create view testdb_1.v7;
ERROR 42000: SELECT command denied to user 'testdb_2'@'localhost' for table 'v7'
show create view v4;
ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
show fields from v4;
ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
Field Type Null Key Default Extra
f1 null YES NULL
f2 char(4) YES NULL
show fields from v2;
Field Type Null Key Default Extra
f1 char(4) YES NULL
@ -140,7 +206,8 @@ where a.table_name = 'testdb_1.v1';
view_definition
select * from v2;
ERROR HY000: View 'test.v2' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
drop view testdb_1.v1,v2, testdb_1.v3, v4;
use test;
drop view testdb_1.v1, v2, testdb_1.v3, v4;
drop database testdb_1;
drop user testdb_1@localhost;
drop user testdb_2@localhost;

View File

@ -122,6 +122,24 @@ DELIMITER ;
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
--- start and stop positions ---
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
SET INSERT_ID=4/*!*/;
use test/*!*/;
SET TIMESTAMP=1579609946/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1/*!*/;
SET @@session.sql_mode=0/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
insert into t1 values(null, "d")/*!*/;
SET INSERT_ID=5/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
--- start-datetime --
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
@ -481,6 +499,24 @@ DELIMITER ;
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
--- start and stop positions ---
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
SET INSERT_ID=4/*!*/;
use test/*!*/;
SET TIMESTAMP=1579609946/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1/*!*/;
SET @@session.sql_mode=0/*!*/;
/*!\C latin1 *//*!*/;
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
insert into t1 values(null, "d")/*!*/;
SET INSERT_ID=5/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
--- start-datetime --
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;

View File

@ -8,22 +8,29 @@ create procedure db1_secret.dummy() begin end;
drop procedure db1_secret.dummy;
use db1_secret;
create table t1 ( u varchar(64), i int );
insert into t1 values('test', 0);
create procedure stamp(i int)
insert into db1_secret.t1 values (user(), i);
show procedure status like 'stamp';
Db Name Type Definer Modified Created Security_type Comment
db1_secret stamp PROCEDURE root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 DEFINER
create function db() returns varchar(64) return database();
create function db() returns varchar(64)
begin
declare v varchar(64);
select u into v from t1 limit 1;
return v;
end|
show function status like 'db';
Db Name Type Definer Modified Created Security_type Comment
db1_secret db FUNCTION root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 DEFINER
call stamp(1);
select * from t1;
u i
test 0
root@localhost 1
select db();
db()
db1_secret
test
grant execute on procedure db1_secret.stamp to user1@'%';
grant execute on function db1_secret.db to user1@'%';
grant execute on procedure db1_secret.stamp to ''@'%';
@ -31,25 +38,34 @@ grant execute on function db1_secret.db to ''@'%';
call db1_secret.stamp(2);
select db1_secret.db();
db1_secret.db()
db1_secret
test
select * from db1_secret.t1;
ERROR 42000: SELECT command denied to user 'user1'@'localhost' for table 't1'
create procedure db1_secret.dummy() begin end;
ERROR 42000: Access denied for user 'user1'@'localhost' to database 'db1_secret'
drop procedure db1_secret.dummy;
ERROR 42000: PROCEDURE db1_secret.dummy does not exist
drop procedure db1_secret.stamp;
ERROR 42000: alter routine command denied to user 'user1'@'localhost' for routine 'db1_secret.stamp'
drop function db1_secret.db;
ERROR 42000: alter routine command denied to user 'user1'@'localhost' for routine 'db1_secret.db'
call db1_secret.stamp(3);
select db1_secret.db();
db1_secret.db()
db1_secret
test
select * from db1_secret.t1;
ERROR 42000: SELECT command denied to user ''@'localhost' for table 't1'
create procedure db1_secret.dummy() begin end;
ERROR 42000: Access denied for user ''@'%' to database 'db1_secret'
drop procedure db1_secret.dummy;
ERROR 42000: PROCEDURE db1_secret.dummy does not exist
drop procedure db1_secret.stamp;
ERROR 42000: alter routine command denied to user ''@'%' for routine 'db1_secret.stamp'
drop function db1_secret.db;
ERROR 42000: alter routine command denied to user ''@'%' for routine 'db1_secret.db'
select * from t1;
u i
test 0
root@localhost 1
user1@localhost 2
anon@localhost 3
@ -64,21 +80,22 @@ db1_secret db FUNCTION root@localhost 0000-00-00 00:00:00 0000-00-00 00:00:00 IN
call stamp(4);
select * from t1;
u i
test 0
root@localhost 1
user1@localhost 2
anon@localhost 3
root@localhost 4
select db();
db()
db1_secret
test
call db1_secret.stamp(5);
ERROR 42000: Access denied for user 'user1'@'localhost' to database 'db1_secret'
ERROR 42000: INSERT command denied to user 'user1'@'localhost' for table 't1'
select db1_secret.db();
ERROR 42000: Access denied for user 'user1'@'localhost' to database 'db1_secret'
ERROR 42000: SELECT command denied to user 'user1'@'localhost' for table 't1'
call db1_secret.stamp(6);
ERROR 42000: Access denied for user ''@'%' to database 'db1_secret'
ERROR 42000: INSERT command denied to user ''@'localhost' for table 't1'
select db1_secret.db();
ERROR 42000: Access denied for user ''@'%' to database 'db1_secret'
ERROR 42000: SELECT command denied to user ''@'localhost' for table 't1'
drop database if exists db2;
create database db2;
use db2;

View File

@ -5969,4 +5969,44 @@ SUM(f2) bug25373(f1)
21.300000071526 NULL
DROP FUNCTION bug25373|
DROP TABLE t3|
DROP DATABASE IF EXISTS mysqltest1|
DROP DATABASE IF EXISTS mysqltest2|
CREATE DATABASE mysqltest1|
CREATE DATABASE mysqltest2|
CREATE PROCEDURE mysqltest1.p1()
DROP DATABASE mysqltest2|
use mysqltest2|
CALL mysqltest1.p1()|
Warnings:
Note 1049 Unknown database 'mysqltest2'
SELECT DATABASE()|
DATABASE()
NULL
DROP DATABASE mysqltest1|
use test|
drop table t1,t2;
CREATE TABLE t1 (a int auto_increment primary key) engine=MyISAM;
CREATE TABLE t2 (a int auto_increment primary key, b int) engine=innodb;
set @a=0;
CREATE function bug27354() RETURNS int deterministic
begin
insert into t1 values (null);
set @a=@a+1;
return @a;
end|
update t2 set b=1 where a=bug27354();
select count(t_1.a),count(t_2.a) from t1 as t_1, t2 as t_2 /* must be 0,0 */;
count(t_1.a) count(t_2.a)
0 0
insert into t2 values (1,1),(2,2),(3,3);
update t2 set b=-b where a=bug27354();
select * from t2 /* must return 1,-1 ... */;
a b
1 -1
2 -2
3 -3
select count(*) from t1 /* must be 3 */;
count(*)
3
drop table t1,t2;
drop function bug27354;

View File

@ -530,3 +530,24 @@ count(*)
drop table t3, t4|
drop procedure bug14210|
set @@session.max_heap_table_size=default|
drop function if exists bug23333|
drop table if exists t1,t2|
CREATE TABLE t1 (a int NOT NULL auto_increment primary key) ENGINE=MyISAM|
CREATE TABLE t2 (a int NOT NULL auto_increment, b int, PRIMARY KEY (a)) ENGINE=InnoDB|
insert into t2 values (1,1)|
create function bug23333()
RETURNS int(11)
DETERMINISTIC
begin
insert into t1 values (null);
select count(*) from t1 into @a;
return @a;
end|
reset master|
insert into t2 values (bug23333(),1)|
ERROR 23000: Duplicate entry '1' for key 1
show binlog events from 98 /* with fixes for #23333 will show there is the query */|
Log_name Pos Event_type Server_id End_log_pos Info
select count(*),@a from t1 /* must be 1,1 */|
count(*) @a
1 1

View File

@ -282,15 +282,6 @@ create view mysqltest.v3 as select b from mysqltest.t2;
grant create view, update on mysqltest.v3 to mysqltest_1@localhost;
drop view mysqltest.v3;
create view mysqltest.v3 as select b from mysqltest.t2;
grant create view, update, insert on mysqltest.v3 to mysqltest_1@localhost;
drop view mysqltest.v3;
create view mysqltest.v3 as select b from mysqltest.t2;
ERROR 42000: create view command denied to user 'mysqltest_1'@'localhost' for column 'b' in table 'v3'
create table mysqltest.v3 (b int);
grant select(b) on mysqltest.v3 to mysqltest_1@localhost;
drop table mysqltest.v3;
create view mysqltest.v3 as select b from mysqltest.t2;
ERROR 42000: create view command denied to user 'mysqltest_1'@'localhost' for column 'b' in table 'v3'
create view v4 as select b+1 from mysqltest.t2;
ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for column 'b' in table 't2'
grant create view,update,select on test.* to mysqltest_1@localhost;
@ -794,4 +785,92 @@ View Create View
v3 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v3` AS select `t1`.`f2` AS `f2` from `t1`
DROP USER u26813@localhost;
DROP DATABASE db26813;
DROP DATABASE IF EXISTS mysqltest1;
DROP DATABASE IF EXISTS mysqltest2;
CREATE DATABASE mysqltest1;
CREATE DATABASE mysqltest2;
CREATE TABLE mysqltest1.t1(c1 INT);
CREATE TABLE mysqltest1.t2(c2 INT);
CREATE TABLE mysqltest1.t3(c3 INT);
CREATE TABLE mysqltest1.t4(c4 INT);
INSERT INTO mysqltest1.t1 VALUES (11), (12), (13), (14);
INSERT INTO mysqltest1.t2 VALUES (21), (22), (23), (24);
INSERT INTO mysqltest1.t3 VALUES (31), (32), (33), (34);
INSERT INTO mysqltest1.t4 VALUES (41), (42), (43), (44);
GRANT SELECT ON mysqltest1.t1 TO mysqltest_u1@localhost;
GRANT INSERT ON mysqltest1.t2 TO mysqltest_u1@localhost;
GRANT SELECT, UPDATE ON mysqltest1.t3 TO mysqltest_u1@localhost;
GRANT SELECT, DELETE ON mysqltest1.t4 TO mysqltest_u1@localhost;
GRANT ALL PRIVILEGES ON mysqltest2.* TO mysqltest_u1@localhost;
---> connection: bug24040_con
SELECT * FROM mysqltest1.t1;
c1
11
12
13
14
INSERT INTO mysqltest1.t2 VALUES(25);
UPDATE mysqltest1.t3 SET c3 = 331 WHERE c3 = 31;
DELETE FROM mysqltest1.t4 WHERE c4 = 44;
CREATE VIEW v1 AS SELECT * FROM mysqltest1.t1;
CREATE VIEW v2 AS SELECT * FROM mysqltest1.t2;
CREATE VIEW v3 AS SELECT * FROM mysqltest1.t3;
CREATE VIEW v4 AS SELECT * FROM mysqltest1.t4;
SELECT * FROM v1;
c1
11
12
13
14
INSERT INTO v2 VALUES(26);
UPDATE v3 SET c3 = 332 WHERE c3 = 32;
DELETE FROM v4 WHERE c4 = 43;
CREATE VIEW v12 AS SELECT c1, c2 FROM mysqltest1.t1, mysqltest1.t2;
ERROR 42000: create view command denied to user 'mysqltest_u1'@'localhost' for column 'c2' in table 'v12'
CREATE VIEW v13 AS SELECT c1, c3 FROM mysqltest1.t1, mysqltest1.t3;
CREATE VIEW v14 AS SELECT c1, c4 FROM mysqltest1.t1, mysqltest1.t4;
CREATE VIEW v21 AS SELECT c2, c1 FROM mysqltest1.t2, mysqltest1.t1;
ERROR 42000: create view command denied to user 'mysqltest_u1'@'localhost' for column 'c1' in table 'v21'
CREATE VIEW v23 AS SELECT c2, c3 FROM mysqltest1.t2, mysqltest1.t3;
ERROR 42000: create view command denied to user 'mysqltest_u1'@'localhost' for column 'c3' in table 'v23'
CREATE VIEW v24 AS SELECT c2, c4 FROM mysqltest1.t2, mysqltest1.t4;
ERROR 42000: create view command denied to user 'mysqltest_u1'@'localhost' for column 'c4' in table 'v24'
CREATE VIEW v31 AS SELECT c3, c1 FROM mysqltest1.t3, mysqltest1.t1;
CREATE VIEW v32 AS SELECT c3, c2 FROM mysqltest1.t3, mysqltest1.t2;
ERROR 42000: create view command denied to user 'mysqltest_u1'@'localhost' for column 'c2' in table 'v32'
CREATE VIEW v34 AS SELECT c3, c4 FROM mysqltest1.t3, mysqltest1.t4;
CREATE VIEW v41 AS SELECT c4, c1 FROM mysqltest1.t4, mysqltest1.t1;
CREATE VIEW v42 AS SELECT c4, c2 FROM mysqltest1.t4, mysqltest1.t2;
ERROR 42000: create view command denied to user 'mysqltest_u1'@'localhost' for column 'c2' in table 'v42'
CREATE VIEW v43 AS SELECT c4, c3 FROM mysqltest1.t4, mysqltest1.t3;
---> connection: default
SELECT * FROM mysqltest1.t1;
c1
11
12
13
14
SELECT * FROM mysqltest1.t2;
c2
21
22
23
24
25
26
SELECT * FROM mysqltest1.t3;
c3
331
332
33
34
SELECT * FROM mysqltest1.t4;
c4
41
42
DROP DATABASE mysqltest1;
DROP DATABASE mysqltest2;
DROP USER mysqltest_u1@localhost;
End of 5.0 tests.

View File

@ -875,4 +875,231 @@ GRANT PROCESS ON * TO user@localhost;
disconnect con1;
connection default;
#
# BUG#9504: Stored procedures: execute privilege doesn't make 'use database'
# okay.
#
# Prepare.
--disable_warnings
DROP DATABASE IF EXISTS mysqltest1;
DROP DATABASE IF EXISTS mysqltest2;
DROP DATABASE IF EXISTS mysqltest3;
DROP DATABASE IF EXISTS mysqltest4;
--enable_warnings
CREATE DATABASE mysqltest1;
CREATE DATABASE mysqltest2;
CREATE DATABASE mysqltest3;
CREATE DATABASE mysqltest4;
CREATE PROCEDURE mysqltest1.p_def() SQL SECURITY DEFINER
SELECT 1;
CREATE PROCEDURE mysqltest2.p_inv() SQL SECURITY INVOKER
SELECT 1;
CREATE FUNCTION mysqltest3.f_def() RETURNS INT SQL SECURITY DEFINER
RETURN 1;
CREATE FUNCTION mysqltest4.f_inv() RETURNS INT SQL SECURITY INVOKER
RETURN 1;
GRANT EXECUTE ON PROCEDURE mysqltest1.p_def TO mysqltest_1@localhost;
GRANT EXECUTE ON PROCEDURE mysqltest2.p_inv TO mysqltest_1@localhost;
GRANT EXECUTE ON FUNCTION mysqltest3.f_def TO mysqltest_1@localhost;
GRANT EXECUTE ON FUNCTION mysqltest4.f_inv TO mysqltest_1@localhost;
GRANT ALL PRIVILEGES ON test.* TO mysqltest_1@localhost;
# Test.
--connect (bug9504_con1,localhost,mysqltest_1,,)
--echo
--echo ---> connection: bug9504_con1
# - Check that we can switch to the db;
use mysqltest1;
use mysqltest2;
use mysqltest3;
use mysqltest4;
# - Check that we can call stored routines;
use test;
CALL mysqltest1.p_def();
CALL mysqltest2.p_inv();
SELECT mysqltest3.f_def();
SELECT mysqltest4.f_inv();
# Cleanup.
--connection default
--echo
--echo ---> connection: default
--disconnect bug9504_con1
DROP DATABASE mysqltest1;
DROP DATABASE mysqltest2;
DROP DATABASE mysqltest3;
DROP DATABASE mysqltest4;
DROP USER mysqltest_1@localhost;
#
# BUG#27337: Privileges are not restored properly.
#
# Actually, the patch for this bugs fixes two problems. So, here are two test
# cases.
# Test case 1: privileges are not restored properly after calling a stored
# routine defined with SQL SECURITY INVOKER clause.
# Prepare.
--disable_warnings
DROP DATABASE IF EXISTS mysqltest1;
DROP DATABASE IF EXISTS mysqltest2;
--enable_warnings
CREATE DATABASE mysqltest1;
CREATE DATABASE mysqltest2;
GRANT ALL PRIVILEGES ON mysqltest1.* TO mysqltest_1@localhost;
GRANT SELECT ON mysqltest2.* TO mysqltest_1@localhost;
CREATE PROCEDURE mysqltest1.p1() SQL SECURITY INVOKER
SELECT 1;
# Test.
--connect (bug27337_con1,localhost,mysqltest_1,,mysqltest2)
--echo
--echo ---> connection: bug27337_con1
--error ER_TABLEACCESS_DENIED_ERROR
CREATE TABLE t1(c INT);
CALL mysqltest1.p1();
--error ER_TABLEACCESS_DENIED_ERROR
CREATE TABLE t1(c INT);
--disconnect bug27337_con1
--connect (bug27337_con2,localhost,mysqltest_1,,mysqltest2)
--echo
--echo ---> connection: bug27337_con2
--error ER_TABLEACCESS_DENIED_ERROR
CREATE TABLE t1(c INT);
SHOW TABLES;
# Cleanup.
--connection default
--echo
--echo ---> connection: default
--disconnect bug27337_con2
DROP DATABASE mysqltest1;
DROP DATABASE mysqltest2;
DROP USER mysqltest_1@localhost;
# Test case 2: priveleges are not checked properly for prepared statements.
# Prepare.
--disable_warnings
DROP DATABASE IF EXISTS mysqltest1;
DROP DATABASE IF EXISTS mysqltest2;
--enable_warnings
CREATE DATABASE mysqltest1;
CREATE DATABASE mysqltest2;
CREATE TABLE mysqltest1.t1(c INT);
CREATE TABLE mysqltest2.t2(c INT);
GRANT SELECT ON mysqltest1.t1 TO mysqltest_1@localhost;
GRANT SELECT ON mysqltest2.t2 TO mysqltest_2@localhost;
# Test.
--connect (bug27337_con1,localhost,mysqltest_1,,mysqltest1)
--echo
--echo ---> connection: bug27337_con1
SHOW TABLES FROM mysqltest1;
PREPARE stmt1 FROM 'SHOW TABLES FROM mysqltest1';
EXECUTE stmt1;
--connect (bug27337_con2,localhost,mysqltest_2,,mysqltest2)
--echo
--echo ---> connection: bug27337_con2
SHOW COLUMNS FROM mysqltest2.t2;
PREPARE stmt2 FROM 'SHOW COLUMNS FROM mysqltest2.t2';
EXECUTE stmt2;
--connection default
--echo
--echo ---> connection: default
REVOKE SELECT ON mysqltest1.t1 FROM mysqltest_1@localhost;
REVOKE SELECT ON mysqltest2.t2 FROM mysqltest_2@localhost;
--connection bug27337_con1
--echo
--echo ---> connection: bug27337_con1
--error ER_DBACCESS_DENIED_ERROR
SHOW TABLES FROM mysqltest1;
--error ER_DBACCESS_DENIED_ERROR
EXECUTE stmt1;
--connection bug27337_con2
--echo
--echo ---> connection: bug27337_con2
--error ER_TABLEACCESS_DENIED_ERROR
SHOW COLUMNS FROM mysqltest2.t2;
--error ER_TABLEACCESS_DENIED_ERROR
EXECUTE stmt2;
# Cleanup.
--connection default
--echo
--echo ---> connection: default
--disconnect bug27337_con2
DROP DATABASE mysqltest1;
DROP DATABASE mysqltest2;
DROP USER mysqltest_1@localhost;
--echo End of 5.0 tests

View File

@ -121,6 +121,28 @@ create table t1 (f1 char(4));
create view v1 as select f1 from t1;
grant insert on v1 to testdb_2@localhost;
create view v5 as select f1 from t1;
grant show view on v5 to testdb_2@localhost;
--error 1227
create definer=`no_such_user`@`no_such_host` view v6 as select f1 from t1;
connection default;
use testdb_1;
create view v6 as select f1 from t1;
grant show view on v6 to testdb_2@localhost;
create table t2 (f1 char(4));
create definer=`no_such_user`@`no_such_host` view v7 as select * from t2;
show fields from testdb_1.v6;
show create view testdb_1.v6;
show create view testdb_1.v7;
show fields from testdb_1.v7;
connection testdb_1;
create table t3 (f1 char(4), f2 char(4));
create view v3 as select f1,f2 from t3;
grant insert(f1), insert(f2) on v3 to testdb_2@localhost;
@ -129,13 +151,41 @@ connect (testdb_2,localhost,testdb_2,,test);
create view v2 as select f1 from testdb_1.v1;
create view v4 as select f1,f2 from testdb_1.v3;
show fields from testdb_1.v5;
show create view testdb_1.v5;
show fields from testdb_1.v6;
show create view testdb_1.v6;
connection testdb_1;
show fields from testdb_1.v7;
show create view testdb_1.v7;
revoke insert(f1) on v3 from testdb_2@localhost;
revoke show view on v5 from testdb_2@localhost;
connection default;
use testdb_1;
revoke show view on v6 from testdb_2@localhost;
connection testdb_2;
--error 1142
show fields from testdb_1.v5;
--error 1142
show create view testdb_1.v5;
--error 1142
show fields from testdb_1.v6;
--error 1142
show create view testdb_1.v6;
--error 1142
show fields from testdb_1.v7;
--error 1142
show create view testdb_1.v7;
--error 1345
show create view v4;
--error 1345
#--error 1345
show fields from v4;
show fields from v2;
@ -155,7 +205,8 @@ where a.table_name = 'testdb_1.v1';
select * from v2;
connection default;
drop view testdb_1.v1,v2, testdb_1.v3, v4;
use test;
drop view testdb_1.v1, v2, testdb_1.v3, v4;
drop database testdb_1;
drop user testdb_1@localhost;
drop user testdb_2@localhost;

View File

@ -55,6 +55,10 @@ select "--- stop-position --" as "";
--enable_query_log
--exec $MYSQL_BINLOG --short-form --stop-position=600 $MYSQLTEST_VARDIR/log/master-bin.000001
--disable_query_log
select "--- start and stop positions ---" as "";
--enable_query_log
--exec $MYSQL_BINLOG --short-form --start-position=600 --stop-position 725 $MYSQLTEST_VARDIR/log/master-bin.000001
--disable_query_log
select "--- start-datetime --" as "";
--enable_query_log
--exec $MYSQL_BINLOG --short-form "--start-datetime=2020-01-21 15:32:24" $MYSQLTEST_VARDIR/log/master-bin.000001
@ -111,6 +115,10 @@ select "--- stop-position --" as "";
--enable_query_log
--exec $MYSQL_BINLOG --short-form --stop-position=600 --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001
--disable_query_log
select "--- start and stop positions ---" as "";
--enable_query_log
--exec $MYSQL_BINLOG --short-form --start-position=600 --stop-position 725 --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001
--disable_query_log
select "--- start-datetime --" as "";
--enable_query_log
--exec $MYSQL_BINLOG --short-form "--start-datetime=2020-01-21 15:32:24" --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001

View File

@ -28,6 +28,7 @@ drop procedure db1_secret.dummy;
use db1_secret;
create table t1 ( u varchar(64), i int );
insert into t1 values('test', 0);
# A test procedure and function
create procedure stamp(i int)
@ -35,7 +36,16 @@ create procedure stamp(i int)
--replace_column 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
show procedure status like 'stamp';
create function db() returns varchar(64) return database();
delimiter |;
create function db() returns varchar(64)
begin
declare v varchar(64);
select u into v from t1 limit 1;
return v;
end|
delimiter ;|
--replace_column 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
show function status like 'db';
@ -63,14 +73,18 @@ call db1_secret.stamp(2);
select db1_secret.db();
# ...but not this
--error 1142
--error ER_TABLEACCESS_DENIED_ERROR
select * from db1_secret.t1;
# ...and not this
--error 1044
--error ER_DBACCESS_DENIED_ERROR
create procedure db1_secret.dummy() begin end;
--error 1305
--error ER_SP_DOES_NOT_EXIST
drop procedure db1_secret.dummy;
--error ER_PROCACCESS_DENIED_ERROR
drop procedure db1_secret.stamp;
--error ER_PROCACCESS_DENIED_ERROR
drop function db1_secret.db;
#
@ -83,14 +97,18 @@ call db1_secret.stamp(3);
select db1_secret.db();
# ...but not this
--error 1142
--error ER_TABLEACCESS_DENIED_ERROR
select * from db1_secret.t1;
# ...and not this
--error 1044
--error ER_DBACCESS_DENIED_ERROR
create procedure db1_secret.dummy() begin end;
--error 1305
--error ER_SP_DOES_NOT_EXIST
drop procedure db1_secret.dummy;
--error ER_PROCACCESS_DENIED_ERROR
drop procedure db1_secret.stamp;
--error ER_PROCACCESS_DENIED_ERROR
drop function db1_secret.db;
#
@ -121,9 +139,9 @@ select db();
connection con2user1;
# This should not work
--error 1044
--error ER_TABLEACCESS_DENIED_ERROR
call db1_secret.stamp(5);
--error 1044
--error ER_TABLEACCESS_DENIED_ERROR
select db1_secret.db();
#
@ -132,9 +150,9 @@ select db1_secret.db();
connection con3anon;
# This should not work
--error 1044
--error ER_TABLEACCESS_DENIED_ERROR
call db1_secret.stamp(6);
--error 1044
--error ER_TABLEACCESS_DENIED_ERROR
select db1_secret.db();
#
@ -165,7 +183,7 @@ use db2;
create procedure p () insert into t2 values (1);
# Check that this doesn't work.
--error 1142
--error ER_TABLEACCESS_DENIED_ERROR
call p();
connect (con4user2,localhost,user2,,);
@ -174,7 +192,7 @@ connection con4user2;
use db2;
# This should not work, since p is executed with definer's (user1's) rights.
--error 1370
--error ER_PROCACCESS_DENIED_ERROR
call p();
select * from t2;
@ -207,9 +225,9 @@ alter procedure p modifies sql data;
drop procedure p;
# This should NOT work
--error 1370
--error ER_PROCACCESS_DENIED_ERROR
alter procedure q modifies sql data;
--error 1370
--error ER_PROCACCESS_DENIED_ERROR
drop procedure q;
connection con1root;
@ -260,30 +278,30 @@ connect (con4userc,localhost,userc,,);
connection con2usera;
call sptest.p1(1);
--error 1370
--error ER_PROCACCESS_DENIED_ERROR
grant execute on procedure sptest.p1 to userb@localhost;
--error 1370
--error ER_PROCACCESS_DENIED_ERROR
drop procedure sptest.p1;
connection con3userb;
--error 1370
--error ER_PROCACCESS_DENIED_ERROR
call sptest.p1(2);
--error 1370
--error ER_PROCACCESS_DENIED_ERROR
grant execute on procedure sptest.p1 to userb@localhost;
--error 1370
--error ER_PROCACCESS_DENIED_ERROR
drop procedure sptest.p1;
connection con4userc;
call sptest.p1(3);
grant execute on procedure sptest.p1 to userb@localhost;
--error 1370
--error ER_PROCACCESS_DENIED_ERROR
drop procedure sptest.p1;
connection con3userb;
call sptest.p1(4);
--error 1370
--error ER_PROCACCESS_DENIED_ERROR
grant execute on procedure sptest.p1 to userb@localhost;
--error 1370
--error ER_PROCACCESS_DENIED_ERROR
drop procedure sptest.p1;
connection con1root;
@ -332,7 +350,7 @@ delimiter ;//
connect (user1,localhost,user1,,test);
connection user1;
use mysqltest;
-- error 1370
-- error ER_PROCACCESS_DENIED_ERROR
select bug_9503();
connection root;
@ -401,13 +419,13 @@ grant usage on *.* to mysqltest_1@localhost;
connect (n1,localhost,mysqltest_1,,information_schema,$MASTER_MYPORT,$MASTER_MYSOCK);
connection n1;
--error 1370
--error ER_PROCACCESS_DENIED_ERROR
call mysqltest_1.p1();
disconnect n1;
# Test also without a current database
connect (n2,localhost,mysqltest_1,,*NO-ONE*,$MASTER_MYPORT,$MASTER_MYSOCK);
connection n2;
--error 1370
--error ER_PROCACCESS_DENIED_ERROR
call mysqltest_1.p1();
disconnect n2;
@ -433,9 +451,9 @@ end;
create user user_bug12812@localhost IDENTIFIED BY 'ABC'|
--replace_result $MASTER_MYPORT MYSQL_PORT $MASTER_MYSOCK MYSQL_SOCK
connect (test_user_12812,localhost,user_bug12812,ABC,test)|
--error 1370
--error ER_PROCACCESS_DENIED_ERROR
SELECT test.bug12812()|
--error 1370
--error ER_PROCACCESS_DENIED_ERROR
CREATE VIEW v1 AS SELECT test.bug12812()|
# Cleanup
connection default|
@ -489,7 +507,8 @@ drop database db_bug14834;
#
# BUG#14533: 'desc tbl' in stored procedure causes error 1142
# BUG#14533: 'desc tbl' in stored procedure causes error
# ER_TABLEACCESS_DENIED_ERROR
#
create database db_bug14533;
use db_bug14533;

View File

@ -6929,6 +6929,47 @@ INSERT INTO t3 VALUES (1, 3.4), (1, 2), (1, 0.9), (2, 8), (2, 7)|
SELECT SUM(f2), bug25373(f1) FROM t3 GROUP BY bug25373(f1) WITH ROLLUP|
DROP FUNCTION bug25373|
DROP TABLE t3|
#
# BUG#25082: Default database change on trigger execution breaks replication.
#
# As it turned out, this bug has actually two bugs. So, here we have two test
# cases -- one in sp.test, the other in sp-security.test.
#
#
# Test case 1: error on dropping the current database.
#
# Prepare.
--disable_warnings
DROP DATABASE IF EXISTS mysqltest1|
DROP DATABASE IF EXISTS mysqltest2|
--enable_warnings
CREATE DATABASE mysqltest1|
CREATE DATABASE mysqltest2|
# Test.
CREATE PROCEDURE mysqltest1.p1()
DROP DATABASE mysqltest2|
use mysqltest2|
CALL mysqltest1.p1()|
SELECT DATABASE()|
# Cleanup.
DROP DATABASE mysqltest1|
use test|
#
# NOTE: The delimiter is `|`, and not `;`. It is changed to `;`
# at the end of the file!
@ -6946,3 +6987,27 @@ DROP TABLE t3|
# practical, or create table t3, t4 etc temporarily (and drop them).
delimiter ;|
drop table t1,t2;
CREATE TABLE t1 (a int auto_increment primary key) engine=MyISAM;
CREATE TABLE t2 (a int auto_increment primary key, b int) engine=innodb;
set @a=0;
delimiter |;
CREATE function bug27354() RETURNS int deterministic
begin
insert into t1 values (null);
set @a=@a+1;
return @a;
end|
delimiter ;|
update t2 set b=1 where a=bug27354();
select count(t_1.a),count(t_2.a) from t1 as t_1, t2 as t_2 /* must be 0,0 */;
insert into t2 values (1,1),(2,2),(3,3);
update t2 set b=-b where a=bug27354();
select * from t2 /* must return 1,-1 ... */;
select count(*) from t1 /* must be 3 */;
drop table t1,t2;
drop function bug27354;

View File

@ -553,6 +553,37 @@ drop procedure bug14210|
set @@session.max_heap_table_size=default|
#
# Bug #13270 INSERT,UPDATE,etc that calls func with side-effect does not binlog
# Bug #23333 stored function + non-transac table + transac table =
# breaks stmt-based binlog
# Bug #27395 OPTION_STATUS_NO_TRANS_UPDATE is not preserved at the end of SF()
#
--disable_warnings
drop function if exists bug23333|
drop table if exists t1,t2|
--enable_warnings
CREATE TABLE t1 (a int NOT NULL auto_increment primary key) ENGINE=MyISAM|
CREATE TABLE t2 (a int NOT NULL auto_increment, b int, PRIMARY KEY (a)) ENGINE=InnoDB|
insert into t2 values (1,1)|
create function bug23333()
RETURNS int(11)
DETERMINISTIC
begin
insert into t1 values (null);
select count(*) from t1 into @a;
return @a;
end|
reset master|
--error ER_DUP_ENTRY
insert into t2 values (bug23333(),1)|
--replace_column 2 # 5 # 6 #
show binlog events from 98 /* with fixes for #23333 will show there is the query */|
select count(*),@a from t1 /* must be 1,1 */|
#
# BUG#NNNN: New bug synopsis
#

View File

@ -350,25 +350,6 @@ drop view mysqltest.v3;
connection user1;
create view mysqltest.v3 as select b from mysqltest.t2;
# give UPDATE and INSERT privilege (to get more privileges then underlying
# table)
connection root;
grant create view, update, insert on mysqltest.v3 to mysqltest_1@localhost;
drop view mysqltest.v3;
connection user1;
-- error 1143
create view mysqltest.v3 as select b from mysqltest.t2;
# If we would get more privileges on VIEW then we have on
# underlying tables => creation prohibited
connection root;
create table mysqltest.v3 (b int);
grant select(b) on mysqltest.v3 to mysqltest_1@localhost;
drop table mysqltest.v3;
connection user1;
-- error 1143
create view mysqltest.v3 as select b from mysqltest.t2;
# Expression need select privileges
-- error 1143
@ -1066,4 +1047,95 @@ DROP USER u26813@localhost;
DROP DATABASE db26813;
disconnect u1;
#
# BUG#24040: Create View don't succed with "all privileges" on a database.
#
# Prepare.
--disable_warnings
DROP DATABASE IF EXISTS mysqltest1;
DROP DATABASE IF EXISTS mysqltest2;
--enable_warnings
CREATE DATABASE mysqltest1;
CREATE DATABASE mysqltest2;
# Test.
CREATE TABLE mysqltest1.t1(c1 INT);
CREATE TABLE mysqltest1.t2(c2 INT);
CREATE TABLE mysqltest1.t3(c3 INT);
CREATE TABLE mysqltest1.t4(c4 INT);
INSERT INTO mysqltest1.t1 VALUES (11), (12), (13), (14);
INSERT INTO mysqltest1.t2 VALUES (21), (22), (23), (24);
INSERT INTO mysqltest1.t3 VALUES (31), (32), (33), (34);
INSERT INTO mysqltest1.t4 VALUES (41), (42), (43), (44);
GRANT SELECT ON mysqltest1.t1 TO mysqltest_u1@localhost;
GRANT INSERT ON mysqltest1.t2 TO mysqltest_u1@localhost;
GRANT SELECT, UPDATE ON mysqltest1.t3 TO mysqltest_u1@localhost;
GRANT SELECT, DELETE ON mysqltest1.t4 TO mysqltest_u1@localhost;
GRANT ALL PRIVILEGES ON mysqltest2.* TO mysqltest_u1@localhost;
--connect (bug24040_con,localhost,mysqltest_u1,,mysqltest2)
--echo
--echo ---> connection: bug24040_con
SELECT * FROM mysqltest1.t1;
INSERT INTO mysqltest1.t2 VALUES(25);
UPDATE mysqltest1.t3 SET c3 = 331 WHERE c3 = 31;
DELETE FROM mysqltest1.t4 WHERE c4 = 44;
CREATE VIEW v1 AS SELECT * FROM mysqltest1.t1;
CREATE VIEW v2 AS SELECT * FROM mysqltest1.t2;
CREATE VIEW v3 AS SELECT * FROM mysqltest1.t3;
CREATE VIEW v4 AS SELECT * FROM mysqltest1.t4;
SELECT * FROM v1;
INSERT INTO v2 VALUES(26);
UPDATE v3 SET c3 = 332 WHERE c3 = 32;
DELETE FROM v4 WHERE c4 = 43;
--error ER_COLUMNACCESS_DENIED_ERROR
CREATE VIEW v12 AS SELECT c1, c2 FROM mysqltest1.t1, mysqltest1.t2;
CREATE VIEW v13 AS SELECT c1, c3 FROM mysqltest1.t1, mysqltest1.t3;
CREATE VIEW v14 AS SELECT c1, c4 FROM mysqltest1.t1, mysqltest1.t4;
--error ER_COLUMNACCESS_DENIED_ERROR
CREATE VIEW v21 AS SELECT c2, c1 FROM mysqltest1.t2, mysqltest1.t1;
--error ER_COLUMNACCESS_DENIED_ERROR
CREATE VIEW v23 AS SELECT c2, c3 FROM mysqltest1.t2, mysqltest1.t3;
--error ER_COLUMNACCESS_DENIED_ERROR
CREATE VIEW v24 AS SELECT c2, c4 FROM mysqltest1.t2, mysqltest1.t4;
CREATE VIEW v31 AS SELECT c3, c1 FROM mysqltest1.t3, mysqltest1.t1;
--error ER_COLUMNACCESS_DENIED_ERROR
CREATE VIEW v32 AS SELECT c3, c2 FROM mysqltest1.t3, mysqltest1.t2;
CREATE VIEW v34 AS SELECT c3, c4 FROM mysqltest1.t3, mysqltest1.t4;
CREATE VIEW v41 AS SELECT c4, c1 FROM mysqltest1.t4, mysqltest1.t1;
--error ER_COLUMNACCESS_DENIED_ERROR
CREATE VIEW v42 AS SELECT c4, c2 FROM mysqltest1.t4, mysqltest1.t2;
CREATE VIEW v43 AS SELECT c4, c3 FROM mysqltest1.t4, mysqltest1.t3;
--connection default
--echo
--echo ---> connection: default
SELECT * FROM mysqltest1.t1;
SELECT * FROM mysqltest1.t2;
SELECT * FROM mysqltest1.t3;
SELECT * FROM mysqltest1.t4;
# Cleanup.
-- disconnect bug24040_con
DROP DATABASE mysqltest1;
DROP DATABASE mysqltest2;
DROP USER mysqltest_u1@localhost;
--echo End of 5.0 tests.

View File

@ -557,4 +557,3 @@ HA_KEYSEG *ha_find_null(HA_KEYSEG *keyseg, uchar *a)
}
return keyseg;
}

View File

@ -627,7 +627,7 @@ int my_fstat(int Filedes, MY_STAT *stat_area,
myf MyFlags __attribute__((unused)))
{
DBUG_ENTER("my_fstat");
DBUG_PRINT("my",("fd: %d MyFlags: %d",Filedes,MyFlags));
DBUG_PRINT("my",("fd: %d MyFlags: %d", Filedes, MyFlags));
DBUG_RETURN(fstat(Filedes, (struct stat *) stat_area));
}
@ -636,7 +636,7 @@ MY_STAT *my_stat(const char *path, MY_STAT *stat_area, myf my_flags)
{
int m_used;
DBUG_ENTER("my_stat");
DBUG_PRINT("my", ("path: '%s', stat_area: 0x%lx, MyFlags: %d", path,
DBUG_PRINT("my", ("path: '%s' stat_area: 0x%lx MyFlags: %d", path,
(long) stat_area, my_flags));
if ((m_used= (stat_area == NULL)))

View File

@ -60,7 +60,7 @@ my_off_t my_seek(File fd, my_off_t pos, int whence,
if (newpos == (os_off_t) -1)
{
my_errno=errno;
DBUG_PRINT("error",("lseek: %lu, errno: %d", (ulong) newpos,errno));
DBUG_PRINT("error",("lseek: %lu errno: %d", (ulong) newpos,errno));
DBUG_RETURN(MY_FILEPOS_ERROR);
}
if ((my_off_t) newpos != pos)

View File

@ -232,7 +232,7 @@ extern "C" {
{
DBUG_ENTER("my_raid_pwrite");
DBUG_PRINT("enter",
("Fd: %d Buffer: 0x %lx Count: %u offset: %u MyFlags: %d",
("Fd: %d Buffer: 0x%lx Count: %u offset: %u MyFlags: %d",
Filedes, Buffer, Count, offset, MyFlags));
if (is_raid(Filedes))
{
@ -251,8 +251,8 @@ extern "C" {
myf MyFlags)
{
DBUG_ENTER("my_raid_lock");
DBUG_PRINT("enter",("Fd: %d start: %u length: %u MyFlags: %d",
fd, start, length, MyFlags));
DBUG_PRINT("enter",("Fd: %d start: %lu length: %lu MyFlags: %d",
fd, (ulong) start, (ulong) length, MyFlags));
if (my_disable_locking)
DBUG_RETURN(0);
if (is_raid(fd))
@ -285,8 +285,8 @@ extern "C" {
int my_raid_chsize(File fd, my_off_t newlength, int filler, myf MyFlags)
{
DBUG_ENTER("my_raid_chsize");
DBUG_PRINT("enter",("Fd: %d newlength: %u MyFlags: %d",
fd, newlength, MyFlags));
DBUG_PRINT("enter",("Fd: %d newlength: %lu MyFlags: %d",
fd, (ulong) newlength, MyFlags));
if (is_raid(fd))
{
RaidFd *raid= (*dynamic_element(&RaidFd::_raid_map,fd,RaidFd**));
@ -414,7 +414,7 @@ RaidFd(uint raid_type, uint raid_chunks, ulong raid_chunksize)
_fd_vector(0)
{
DBUG_ENTER("RaidFd::RaidFd");
DBUG_PRINT("enter",("RaidFd_type: %u Disks: %u Chunksize: %d",
DBUG_PRINT("enter",("RaidFd_type: %u Disks: %u Chunksize: %lu",
raid_type, raid_chunks, raid_chunksize));
/* TODO: Here we should add checks if the malloc fails */
@ -623,7 +623,7 @@ Lock(int locktype, my_off_t start, my_off_t length, myf MyFlags)
{
DBUG_ENTER("RaidFd::Lock");
DBUG_PRINT("enter",("locktype: %d start: %lu length: %lu MyFlags: %d",
locktype, start, length, MyFlags));
locktype, (ulong) start, (ulong) length, MyFlags));
my_off_t bufptr = start;
// Loop until all data is locked
while(length)
@ -733,8 +733,8 @@ my_off_t RaidFd::
Tell(myf MyFlags)
{
DBUG_ENTER("RaidFd::Tell");
DBUG_PRINT("enter",("MyFlags: %d _position %d",
MyFlags,_position));
DBUG_PRINT("enter",("MyFlags: %d _position: %lu",
MyFlags, (ulong) _position));
DBUG_RETURN(_position);
}
@ -742,8 +742,8 @@ int RaidFd::
Chsize(File fd, my_off_t newlength, int filler, myf MyFlags)
{
DBUG_ENTER("RaidFd::Chsize");
DBUG_PRINT("enter",("Fd: %d, newlength: %d, MyFlags: %d",
fd, newlength,MyFlags));
DBUG_PRINT("enter",("Fd: %d newlength: %lu MyFlags: %d",
fd, (ulong) newlength, MyFlags));
_position = newlength;
Calculate();
uint _rounds = _total_block / _raid_chunks; // INT() assumed

View File

@ -658,7 +658,7 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_OWNER *owner,
goto end;
}
}
DBUG_PRINT("lock",("write locked by thread: %ld, type: %d",
DBUG_PRINT("lock",("write locked by thread: %ld type: %d",
lock->read.data->owner->info->thread_id, data->type));
}
wait_queue= &lock->write_wait;

View File

@ -753,7 +753,7 @@ int ha_ndbcluster::set_ndb_value(NdbOperation *ndb_op, Field *field,
blob_ptr= (char*)"";
}
DBUG_PRINT("value", ("set blob ptr=%p len=%u",
DBUG_PRINT("value", ("set blob ptr: %p len: %u",
blob_ptr, blob_len));
DBUG_DUMP("value", (char*)blob_ptr, min(blob_len, 26));
@ -3659,8 +3659,7 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
{
m_transaction_on= FALSE;
/* Would be simpler if has_transactions() didn't always say "yes" */
thd->options|= OPTION_STATUS_NO_TRANS_UPDATE;
thd->no_trans_update= TRUE;
thd->no_trans_update.all= thd->no_trans_update.stmt= TRUE;
}
else if (!thd->transaction.on)
m_transaction_on= FALSE;
@ -4411,7 +4410,7 @@ int ha_ndbcluster::create(const char *name,
for (i= 0; i < form->s->fields; i++)
{
Field *field= form->field[i];
DBUG_PRINT("info", ("name: %s, type: %u, pack_length: %d",
DBUG_PRINT("info", ("name: %s type: %u pack_length: %d",
field->field_name, field->real_type(),
field->pack_length()));
if ((my_errno= create_ndb_column(col, field, create_info)))
@ -5992,7 +5991,7 @@ static int packfrm(const void *data, uint len,
uint blob_len;
frm_blob_struct* blob;
DBUG_ENTER("packfrm");
DBUG_PRINT("enter", ("data: 0x%lx, len: %d", (long) data, len));
DBUG_PRINT("enter", ("data: 0x%lx len: %d", (long) data, len));
error= 1;
org_len= len;
@ -6019,7 +6018,8 @@ static int packfrm(const void *data, uint len,
*pack_len= blob_len;
error= 0;
DBUG_PRINT("exit", ("pack_data: 0x%lx, pack_len: %d", (long) *pack_data, *pack_len));
DBUG_PRINT("exit", ("pack_data: 0x%lx pack_len: %d", (long) *pack_data,
*pack_len));
err:
DBUG_RETURN(error);
@ -6058,7 +6058,8 @@ static int unpackfrm(const void **unpack_data, uint *unpack_len,
*unpack_data= data;
*unpack_len= complen;
DBUG_PRINT("exit", ("frmdata: 0x%lx, len: %d", (long) *unpack_data, *unpack_len));
DBUG_PRINT("exit", ("frmdata: 0x%lx len: %d", (long) *unpack_data,
*unpack_len));
DBUG_RETURN(0);
}

View File

@ -830,7 +830,7 @@ int ha_rollback_trans(THD *thd, bool all)
the error log; but we don't want users to wonder why they have this
message in the error log, so we don't send it.
*/
if (is_real_trans && (thd->options & OPTION_STATUS_NO_TRANS_UPDATE) &&
if (is_real_trans && thd->no_trans_update.all &&
!thd->slave_thread)
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARNING_NOT_COMPLETE_ROLLBACK,

View File

@ -2367,7 +2367,7 @@ byte *in_row::get_value(Item *item)
void in_row::set(uint pos, Item *item)
{
DBUG_ENTER("in_row::set");
DBUG_PRINT("enter", ("pos %u item 0x%lx", pos, (ulong) item));
DBUG_PRINT("enter", ("pos: %u item: 0x%lx", pos, (ulong) item));
((cmp_item_row*) base)[pos].store_value_by_template(&tmp, item);
DBUG_VOID_RETURN;
}

View File

@ -1422,6 +1422,8 @@ public:
virtual ~Item_func_sp()
{}
table_map used_tables() const { return RAND_TABLE_BIT; }
void cleanup();
const char *func_name() const;

View File

@ -162,7 +162,7 @@ static int binlog_rollback(THD *thd, bool all)
table. Such cases should be rare (updating a
non-transactional table inside a transaction...)
*/
if (unlikely(thd->options & OPTION_STATUS_NO_TRANS_UPDATE))
if (unlikely(thd->no_trans_update.all))
{
Query_log_event qev(thd, STRING_WITH_LEN("ROLLBACK"), TRUE, FALSE);
qev.error_code= 0; // see comment in MYSQL_LOG::write(THD, IO_CACHE)
@ -217,7 +217,7 @@ static int binlog_savepoint_rollback(THD *thd, void *sv)
non-transactional table. Otherwise, truncate the binlog cache starting
from the SAVEPOINT command.
*/
if (unlikely(thd->options & OPTION_STATUS_NO_TRANS_UPDATE))
if (unlikely(thd->no_trans_update.all))
{
Query_log_event qinfo(thd, thd->query, thd->query_length, TRUE, FALSE);
DBUG_RETURN(mysql_bin_log.write(&qinfo));

View File

@ -347,9 +347,6 @@ MY_LOCALE *my_locale_by_number(uint number);
in the user query has requested */
#define SELECT_ALL (ULL(1) << 24) // SELECT, user, parser
/* Set if we are updating a non-transaction safe table */
#define OPTION_STATUS_NO_TRANS_UPDATE (ULL(1) << 25) // THD, intern
/* The following can be set when importing tables in a 'wrong order'
to suppress foreign key checks */
#define OPTION_NO_FOREIGN_KEY_CHECKS (ULL(1) << 26) // THD, user, binlog
@ -696,7 +693,8 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list);
bool do_rename(THD *thd, TABLE_LIST *ren_table, char *new_db,
char *new_table_name, char *new_table_alias,
bool skip_error);
bool mysql_change_db(THD *thd,const char *name,bool no_access_check);
bool mysql_change_db(THD *thd, const LEX_STRING *new_db_name,
bool force_switch);
void mysql_parse(THD *thd,char *inBuf,uint length);
bool mysql_test_parse_for_slave(THD *thd,char *inBuf,uint length);
bool is_update_query(enum enum_sql_command command);
@ -940,7 +938,7 @@ void append_definer(THD *thd, String *buffer, const LEX_STRING *definer_user,
/* information schema */
extern LEX_STRING information_schema_name;
extern LEX_STRING INFORMATION_SCHEMA_NAME;
LEX_STRING *make_lex_string(THD *thd, LEX_STRING *lex_str,
const char* str, uint length,
bool allocate_lex_string);
@ -957,8 +955,10 @@ int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, COND *cond);
int fill_schema_column_privileges(THD *thd, TABLE_LIST *tables, COND *cond);
bool get_schema_tables_result(JOIN *join,
enum enum_schema_table_state executed_place);
enum enum_schema_tables get_schema_table_idx(ST_SCHEMA_TABLE *schema_table);
#define is_schema_db(X) \
!my_strcasecmp(system_charset_info, information_schema_name.str, (X))
!my_strcasecmp(system_charset_info, INFORMATION_SCHEMA_NAME.str, (X))
/* sql_prepare.cc */

View File

@ -818,7 +818,7 @@ my_real_read(NET *net, ulong *complen)
{
my_bool interrupted = vio_should_retry(net->vio);
DBUG_PRINT("info",("vio_read returned %ld, errno: %d",
DBUG_PRINT("info",("vio_read returned %ld errno: %d",
length, vio_errno(net->vio)));
#if (!defined(__WIN__) && !defined(__EMX__) && !defined(OS2)) || defined(MYSQL_SERVER)
/*

View File

@ -2873,14 +2873,15 @@ static bool set_option_autocommit(THD *thd, set_var *var)
if ((org_options & OPTION_NOT_AUTOCOMMIT))
{
/* We changed to auto_commit mode */
thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
thd->options&= ~(ulong) OPTION_BEGIN;
thd->no_trans_update.all= FALSE;
thd->server_status|= SERVER_STATUS_AUTOCOMMIT;
if (ha_commit(thd))
return 1;
}
else
{
thd->options&= ~(ulong) (OPTION_STATUS_NO_TRANS_UPDATE);
thd->no_trans_update.all= FALSE;
thd->server_status&= ~SERVER_STATUS_AUTOCOMMIT;
}
}

View File

@ -441,14 +441,14 @@ db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp,
{
sp_head *sp= newlex.sphead;
if (dbchanged && (ret= mysql_change_db(thd, old_db.str, 1)))
if (dbchanged && (ret= mysql_change_db(thd, &old_db, TRUE)))
goto end;
delete sp;
ret= SP_PARSE_ERROR;
}
else
{
if (dbchanged && (ret= mysql_change_db(thd, old_db.str, 1)))
if (dbchanged && (ret= mysql_change_db(thd, &old_db, TRUE)))
goto end;
*sphp= newlex.sphead;
(*sphp)->set_definer(&definer_user_name, &definer_host_name);
@ -1896,7 +1896,7 @@ sp_use_new_db(THD *thd, LEX_STRING new_db, LEX_STRING *old_db,
DBUG_RETURN(0);
}
ret= mysql_change_db(thd, new_db.str, no_access_check);
ret= mysql_change_db(thd, &new_db, no_access_check);
*dbchangedp= ret == 0;
DBUG_RETURN(ret);

View File

@ -337,13 +337,13 @@ sp_eval_expr(THD *thd, Field *result_field, Item **expr_item_ptr)
enum_check_fields save_count_cuted_fields= thd->count_cuted_fields;
bool save_abort_on_warning= thd->abort_on_warning;
bool save_no_trans_update= thd->no_trans_update;
bool save_no_trans_update_stmt= thd->no_trans_update.stmt;
thd->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
thd->abort_on_warning=
thd->variables.sql_mode &
(MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES);
thd->no_trans_update= 0;
thd->no_trans_update.stmt= FALSE;
/* Save the value in the field. Convert the value if needed. */
@ -351,7 +351,7 @@ sp_eval_expr(THD *thd, Field *result_field, Item **expr_item_ptr)
thd->count_cuted_fields= save_count_cuted_fields;
thd->abort_on_warning= save_abort_on_warning;
thd->no_trans_update= save_no_trans_update;
thd->no_trans_update.stmt= save_no_trans_update_stmt;
if (thd->net.report_error)
{
@ -1130,7 +1130,7 @@ sp_head::execute(THD *thd)
(It would generate an error from mysql_change_db() when old_db=="")
*/
if (! thd->killed)
err_status|= mysql_change_db(thd, old_db.str, 1);
err_status|= mysql_change_db(thd, &old_db, TRUE);
}
m_flags&= ~IS_INVOKED;
DBUG_PRINT("info",

View File

@ -3893,6 +3893,26 @@ err2:
}
static bool check_grant_db_routine(THD *thd, const char *db, HASH *hash)
{
Security_context *sctx= thd->security_ctx;
for (uint idx= 0; idx < hash->records; ++idx)
{
GRANT_NAME *item= (GRANT_NAME*) hash_element(hash, idx);
if (strcmp(item->user, sctx->priv_user) == 0 &&
strcmp(item->db, db) == 0 &&
compare_hostname(&item->host, sctx->host, sctx->ip))
{
return FALSE;
}
}
return TRUE;
}
/*
Check if a user has the right to access a database
Access is accepted if he has a grant for any table/routine in the database
@ -3904,9 +3924,10 @@ bool check_grant_db(THD *thd,const char *db)
Security_context *sctx= thd->security_ctx;
char helping [NAME_LEN+USERNAME_LENGTH+2];
uint len;
bool error= 1;
bool error= TRUE;
len= (uint) (strmov(strmov(helping, sctx->priv_user) + 1, db) - helping) + 1;
rw_rdlock(&LOCK_grant);
for (uint idx=0 ; idx < column_priv_hash.records ; idx++)
@ -3917,11 +3938,17 @@ bool check_grant_db(THD *thd,const char *db)
!memcmp(grant_table->hash_key,helping,len) &&
compare_hostname(&grant_table->host, sctx->host, sctx->ip))
{
error=0; // Found match
error= FALSE; /* Found match. */
break;
}
}
if (error)
error= check_grant_db_routine(thd, db, &proc_priv_hash) &&
check_grant_db_routine(thd, db, &func_priv_hash);
rw_unlock(&LOCK_grant);
return error;
}

View File

@ -3576,15 +3576,36 @@ find_field_in_tables(THD *thd, Item_ident *item,
{
Field *cur_field= find_field_in_table_ref(thd, cur_table, name, length,
item->name, db, table_name, ref,
check_privileges, allow_rowid,
check_privileges,
allow_rowid,
&(item->cached_field_index),
register_tree_change,
&actual_table);
if (cur_field)
{
if (cur_field == WRONG_GRANT)
{
if (thd->lex->sql_command != SQLCOM_SHOW_FIELDS)
return (Field*) 0;
thd->clear_error();
cur_field= find_field_in_table_ref(thd, cur_table, name, length,
item->name, db, table_name, ref,
false,
allow_rowid,
&(item->cached_field_index),
register_tree_change,
&actual_table);
if (cur_field)
{
Field *nf=new Field_null(NULL,0,Field::NONE,
cur_field->field_name,
cur_field->table,
&my_charset_bin);
cur_field= nf;
}
}
/*
Store the original table of the field, which may be different from
cur_table in the case of NATURAL/USING join.

View File

@ -381,7 +381,7 @@ inline Query_cache_block * Query_cache_block_table::block()
void Query_cache_block::init(ulong block_length)
{
DBUG_ENTER("Query_cache_block::init");
DBUG_PRINT("qcache", ("init block 0x%lx length: %lu", (ulong) this,
DBUG_PRINT("qcache", ("init block: 0x%lx length: %lu", (ulong) this,
block_length));
length = block_length;
used = 0;
@ -3675,7 +3675,7 @@ void Query_cache::queries_dump()
Query_cache_query_flags flags;
memcpy(&flags, str+len, QUERY_CACHE_FLAGS_SIZE);
str[len]= 0; // make zero ending DB name
DBUG_PRINT("qcache", ("F:%u C:%u L:%lu T:'%s' (%u) '%s' '%s'",
DBUG_PRINT("qcache", ("F: %u C: %u L: %lu T: '%s' (%u) '%s' '%s'",
flags.client_long_flag,
flags.character_set_client_num,
(ulong)flags.limit,
@ -3998,7 +3998,7 @@ my_bool Query_cache::check_integrity(bool locked)
} while (block != bins[i].free_blocks);
if (count != bins[i].number)
{
DBUG_PRINT("error", ("bins[%d].number = %d, but bin have %d blocks",
DBUG_PRINT("error", ("bins[%d].number= %d, but bin have %d blocks",
i, bins[i].number, count));
result = 1;
}

View File

@ -333,6 +333,7 @@ void THD::init(void)
if (variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES)
server_status|= SERVER_STATUS_NO_BACKSLASH_ESCAPES;
options= thd_startup_options;
no_trans_update.stmt= no_trans_update.all= FALSE;
open_options=ha_open_options;
update_lock_default= (variables.low_priority_updates ?
TL_WRITE_LOW_PRIORITY :
@ -760,7 +761,8 @@ void THD::add_changed_table(const char *key, long key_length)
{
list_include(prev_changed, curr, changed_table_dup(key, key_length));
DBUG_PRINT("info",
("key_length %ld %u", key_length, (*prev_changed)->key_length));
("key_length: %ld %u", key_length,
(*prev_changed)->key_length));
DBUG_VOID_RETURN;
}
else if (cmp == 0)
@ -770,7 +772,7 @@ void THD::add_changed_table(const char *key, long key_length)
{
list_include(prev_changed, curr, changed_table_dup(key, key_length));
DBUG_PRINT("info",
("key_length %ld %u", key_length,
("key_length: %ld %u", key_length,
(*prev_changed)->key_length));
DBUG_VOID_RETURN;
}
@ -782,7 +784,7 @@ void THD::add_changed_table(const char *key, long key_length)
}
}
*prev_changed = changed_table_dup(key, key_length);
DBUG_PRINT("info", ("key_length %ld %u", key_length,
DBUG_PRINT("info", ("key_length: %ld %u", key_length,
(*prev_changed)->key_length));
DBUG_VOID_RETURN;
}

View File

@ -1440,7 +1440,11 @@ public:
bool charset_is_system_charset, charset_is_collation_connection;
bool charset_is_character_set_filesystem;
bool enable_slow_log; /* enable slow log for current statement */
bool no_trans_update, abort_on_warning;
struct {
bool all:1;
bool stmt:1;
} no_trans_update;
bool abort_on_warning;
bool got_warning; /* Set on call to push_warning() */
bool no_warnings_for_error; /* no warnings on call to my_error() */
/* set during loop of derived table processing */
@ -1664,7 +1668,7 @@ public:
inline bool really_abort_on_warning()
{
return (abort_on_warning &&
(!no_trans_update ||
(!no_trans_update.stmt ||
(variables.sql_mode & MODE_STRICT_ALL_TABLES)));
}
void set_status_var_init();

View File

@ -461,7 +461,7 @@ bool mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info,
DBUG_ENTER("mysql_create_db");
/* do not create 'information_schema' db */
if (!my_strcasecmp(system_charset_info, db, information_schema_name.str))
if (!my_strcasecmp(system_charset_info, db, INFORMATION_SCHEMA_NAME.str))
{
my_error(ER_DB_CREATE_EXISTS, MYF(0), db);
DBUG_RETURN(-1);
@ -1126,154 +1126,253 @@ err:
}
/*
Change the current database.
/**
@brief Internal implementation: switch current database to a valid one.
SYNOPSIS
mysql_change_db()
thd thread handle
name database name
no_access_check if TRUE, don't do access check. In this
case name may be ""
DESCRIPTION
Check that the database name corresponds to a valid and
existent database, check access rights (unless called with
no_access_check), and set the current database. This function
is called to change the current database upon user request
(COM_CHANGE_DB command) or temporarily, to execute a stored
routine.
NOTES
This function is not the only way to switch the database that
is currently employed. When the replication slave thread
switches the database before executing a query, it calls
thd->set_db directly. However, if the query, in turn, uses
a stored routine, the stored routine will use this function,
even if it's run on the slave.
This function allocates the name of the database on the system
heap: this is necessary to be able to uniformly change the
database from any module of the server. Up to 5.0 different
modules were using different memory to store the name of the
database, and this led to memory corruption: a stack pointer
set by Stored Procedures was used by replication after the
stack address was long gone.
This function does not send anything, including error
messages, to the client. If that should be sent to the client,
call net_send_error after this function.
RETURN VALUES
0 OK
1 error
@param thd Thread context.
@param new_db_name Name of the database to switch to. The function will
take ownership of the name (the caller must not free
the allocated memory). If the name is NULL, we're
going to switch to NULL db.
@param new_db_access Privileges of the new database.
@param new_db_charset Character set of the new database.
*/
bool mysql_change_db(THD *thd, const char *name, bool no_access_check)
static void mysql_change_db_impl(THD *thd,
LEX_STRING *new_db_name,
ulong new_db_access,
CHARSET_INFO *new_db_charset)
{
int db_length;
char *db_name;
bool system_db= 0;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
ulong db_access;
Security_context *sctx= thd->security_ctx;
LINT_INIT(db_access);
#endif
DBUG_ENTER("mysql_change_db");
DBUG_PRINT("enter",("name: '%s'",name));
/* 1. Change current database in THD. */
if (name == NULL || name[0] == '\0' && no_access_check == FALSE)
if (new_db_name == NULL)
{
/*
THD::set_db() does all the job -- it frees previous database name and
sets the new one.
*/
thd->set_db(NULL, 0);
}
else if (new_db_name == &INFORMATION_SCHEMA_NAME)
{
/*
Here we must use THD::set_db(), because we want to copy
INFORMATION_SCHEMA_NAME constant.
*/
thd->set_db(INFORMATION_SCHEMA_NAME.str, INFORMATION_SCHEMA_NAME.length);
}
else
{
/*
Here we already have a copy of database name to be used in THD. So,
we just call THD::reset_db(). Since THD::reset_db() does not releases
the previous database name, we should do it explicitly.
*/
x_free(thd->db);
thd->reset_db(new_db_name->str, new_db_name->length);
}
/* 2. Update security context. */
#ifndef NO_EMBEDDED_ACCESS_CHECKS
thd->security_ctx->db_access= new_db_access;
#endif
/* 3. Update db-charset environment variables. */
thd->db_charset= new_db_charset;
thd->variables.collation_database= new_db_charset;
}
/**
@brief Change the current database.
@param thd thread handle
@param name database name
@param force_switch if this flag is set (TRUE), mysql_change_db() will
switch to NULL db if the specified database is not
available anymore. Corresponding warning will be
thrown in this case. This flag is used to change
database in stored-routine-execution code.
@details Check that the database name corresponds to a valid and existent
database, check access rights (unless called with no_access_check), and
set the current database. This function is called to change the current
database upon user request (COM_CHANGE_DB command) or temporarily, to
execute a stored routine.
This function is not the only way to switch the database that is
currently employed. When the replication slave thread switches the
database before executing a query, it calls thd->set_db directly.
However, if the query, in turn, uses a stored routine, the stored routine
will use this function, even if it's run on the slave.
This function allocates the name of the database on the system heap: this
is necessary to be able to uniformly change the database from any module
of the server. Up to 5.0 different modules were using different memory to
store the name of the database, and this led to memory corruption:
a stack pointer set by Stored Procedures was used by replication after
the stack address was long gone.
@return Operation status
@retval FALSE Success
@retval TRUE Error
*/
bool mysql_change_db(THD *thd, const LEX_STRING *new_db_name, bool force_switch)
{
LEX_STRING new_db_file_name;
Security_context *sctx= thd->security_ctx;
ulong db_access= sctx->db_access;
DBUG_ENTER("mysql_change_db");
DBUG_PRINT("enter",("name: '%s'", new_db_name->str));
if (new_db_name == NULL ||
new_db_name->length == 0 ||
new_db_name->str == NULL)
{
if (force_switch)
{
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR));
/* Change db to NULL. */
mysql_change_db_impl(thd, NULL, 0, thd->variables.collation_server);
DBUG_RETURN(FALSE);
}
else
{
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
DBUG_RETURN(1); /* purecov: inspected */
DBUG_RETURN(TRUE);
}
else if (name[0] == '\0')
{
/* Called from SP to restore the original database, which was NULL */
DBUG_ASSERT(no_access_check);
system_db= 1;
db_name= NULL;
db_length= 0;
goto end;
}
/*
Now we need to make a copy because check_db_name requires a
non-constant argument. TODO: fix check_db_name.
*/
if ((db_name= my_strdup(name, MYF(MY_WME))) == NULL)
DBUG_RETURN(1); /* the error is set */
db_length= strlen(db_name);
if (check_db_name(db_name))
{
my_error(ER_WRONG_DB_NAME, MYF(0), db_name);
my_free(db_name, MYF(0));
DBUG_RETURN(1);
}
DBUG_PRINT("info",("Use database: %s", db_name));
if (!my_strcasecmp(system_charset_info, db_name, information_schema_name.str))
{
system_db= 1;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
db_access= SELECT_ACL;
#endif
goto end;
}
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (!no_access_check)
if (my_strcasecmp(system_charset_info, new_db_name->str,
INFORMATION_SCHEMA_NAME.str) == 0)
{
if (test_all_bits(sctx->master_access, DB_ACLS))
db_access=DB_ACLS;
else
db_access= (acl_get(sctx->host, sctx->ip, sctx->priv_user, db_name, 0) |
sctx->master_access);
if (!(db_access & DB_ACLS) && (!grant_option ||
check_grant_db(thd,db_name)))
/* Switch database to INFORMATION_SCHEMA. */
mysql_change_db_impl(thd, &INFORMATION_SCHEMA_NAME, SELECT_ACL,
system_charset_info);
DBUG_RETURN(FALSE);
}
/*
Now we need to make a copy because check_db_name requires a
non-constant argument. Actually, it takes database file name.
TODO: fix check_db_name().
*/
new_db_file_name.str= my_strdup(new_db_name->str, MYF(MY_WME));
new_db_file_name.length= new_db_name->length;
if (new_db_file_name.str == NULL)
DBUG_RETURN(TRUE); /* the error is set */
/*
NOTE: if check_db_name() fails, we should throw an error in any case,
even if we are called from sp_head::execute().
It's next to impossible however to get this error when we are called
from sp_head::execute(). But let's switch database to NULL in this case
to be sure.
*/
if (check_db_name(new_db_file_name.str))
{
my_error(ER_WRONG_DB_NAME, MYF(0), new_db_file_name.str);
my_free(new_db_file_name.str, MYF(0));
if (force_switch)
{
/* Change db to NULL. */
mysql_change_db_impl(thd, NULL, 0, thd->variables.collation_server);
}
DBUG_RETURN(TRUE);
}
DBUG_PRINT("info",("Use database: %s", new_db_file_name.str));
#ifndef NO_EMBEDDED_ACCESS_CHECKS
db_access=
test_all_bits(sctx->master_access, DB_ACLS) ?
DB_ACLS :
acl_get(sctx->host,
sctx->ip,
sctx->priv_user,
new_db_file_name.str,
FALSE) | sctx->master_access;
if (!force_switch &&
!(db_access & DB_ACLS) &&
(!grant_option || check_grant_db(thd, new_db_file_name.str)))
{
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
sctx->priv_user,
sctx->priv_host,
db_name);
new_db_file_name.str);
mysql_log.write(thd, COM_INIT_DB, ER(ER_DBACCESS_DENIED_ERROR),
sctx->priv_user, sctx->priv_host, db_name);
my_free(db_name, MYF(0));
DBUG_RETURN(1);
}
sctx->priv_user, sctx->priv_host, new_db_file_name.str);
my_free(new_db_file_name.str, MYF(0));
DBUG_RETURN(TRUE);
}
#endif
if (check_db_dir_existence(db_name))
if (check_db_dir_existence(new_db_file_name.str))
{
my_error(ER_BAD_DB_ERROR, MYF(0), db_name);
my_free(db_name, MYF(0));
DBUG_RETURN(1);
}
if (force_switch)
{
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_BAD_DB_ERROR, ER(ER_BAD_DB_ERROR),
new_db_file_name.str);
end:
x_free(thd->db);
DBUG_ASSERT(db_name == NULL || db_name[0] != '\0');
thd->reset_db(db_name, db_length); // THD::~THD will free this
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (!no_access_check)
sctx->db_access= db_access;
#endif
if (system_db)
{
thd->db_charset= system_charset_info;
thd->variables.collation_database= system_charset_info;
my_free(new_db_file_name.str, MYF(0));
/* Change db to NULL. */
mysql_change_db_impl(thd, NULL, 0, thd->variables.collation_server);
DBUG_RETURN(FALSE);
}
else
{
HA_CREATE_INFO create;
load_db_opt_by_name(thd, db_name, &create);
thd->db_charset= create.default_table_charset ?
create.default_table_charset :
thd->variables.collation_server;
thd->variables.collation_database= thd->db_charset;
my_error(ER_BAD_DB_ERROR, MYF(0), new_db_file_name.str);
my_free(new_db_file_name.str, MYF(0));
DBUG_RETURN(TRUE);
}
DBUG_RETURN(0);
}
/*
NOTE: in mysql_change_db_impl() new_db_file_name is assigned to THD
attributes and will be freed in THD::~THD().
*/
{
HA_CREATE_INFO db_options;
load_db_opt_by_name(thd, new_db_name->str, &db_options);
mysql_change_db_impl(thd, &new_db_file_name, db_access,
db_options.default_table_charset ?
db_options.default_table_charset :
thd->variables.collation_server);
}
DBUG_RETURN(FALSE);
}

View File

@ -316,7 +316,7 @@ cleanup:
error=1;
}
if (!transactional_table)
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
thd->no_trans_update.all= TRUE;
}
free_underlaid_joins(thd, select_lex);
if (transactional_table)
@ -796,7 +796,7 @@ bool multi_delete::send_eof()
local_error=1; // Log write failed: roll back the SQL statement
}
if (!transactional_tables)
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
thd->no_trans_update.all= TRUE;
}
/* Commit or rollback the current SQL statement */
if (transactional_tables)

View File

@ -584,7 +584,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
if (lock_type != TL_WRITE_DELAYED && !thd->prelocked_mode)
table->file->start_bulk_insert(values_list.elements);
thd->no_trans_update= 0;
thd->no_trans_update.stmt= FALSE;
thd->abort_on_warning= (!ignore && (thd->variables.sql_mode &
(MODE_STRICT_TRANS_TABLES |
MODE_STRICT_ALL_TABLES)));
@ -731,7 +731,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
error=1;
}
if (!transactional_table)
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
thd->no_trans_update.all= TRUE;
}
}
if (transactional_table)
@ -1130,7 +1130,7 @@ static int last_uniq_key(TABLE *table,uint keynr)
then both on update triggers will work instead. Similarly both on
delete triggers will be invoked if we will delete conflicting records.
Sets thd->no_trans_update if table which is updated didn't have
Sets thd->no_trans_update.stmt to TRUE if table which is updated didn't have
transactions.
RETURN VALUE
@ -1296,7 +1296,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
goto err;
info->deleted++;
if (!table->file->has_transactions())
thd->no_trans_update= 1;
thd->no_trans_update.stmt= TRUE;
if (table->triggers &&
table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
TRG_ACTION_AFTER, TRUE))
@ -1328,7 +1328,7 @@ ok_or_after_trg_err:
if (key)
my_safe_afree(key,table->s->max_unique_length,MAX_KEY_LENGTH);
if (!table->file->has_transactions())
thd->no_trans_update= 1;
thd->no_trans_update.stmt= TRUE;
DBUG_RETURN(trg_error);
err:
@ -2519,7 +2519,7 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
table->file->extra(HA_EXTRA_WRITE_CAN_REPLACE);
table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS);
}
thd->no_trans_update= 0;
thd->no_trans_update.stmt= FALSE;
thd->abort_on_warning= (!info.ignore &&
(thd->variables.sql_mode &
(MODE_STRICT_TRANS_TABLES |
@ -2678,7 +2678,7 @@ void select_insert::send_error(uint errcode,const char *err)
mysql_bin_log.write(&qinfo);
}
if (!table->s->tmp_table)
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
thd->no_trans_update.all= TRUE;
}
if (info.copied || info.deleted || info.updated)
{
@ -2707,7 +2707,7 @@ bool select_insert::send_eof()
{
query_cache_invalidate3(thd, table, 1);
if (!(table->file->has_transactions() || table->s->tmp_table))
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
thd->no_trans_update.all= TRUE;
}
if (last_insert_id)
@ -2933,7 +2933,7 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
}
if (!thd->prelocked_mode)
table->file->start_bulk_insert((ha_rows) 0);
thd->no_trans_update= 0;
thd->no_trans_update.stmt= FALSE;
thd->abort_on_warning= (!info.ignore &&
(thd->variables.sql_mode &
(MODE_STRICT_TRANS_TABLES |

View File

@ -377,7 +377,7 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
table->file->start_bulk_insert((ha_rows) 0);
table->copy_blobs=1;
thd->no_trans_update= 0;
thd->no_trans_update.stmt= FALSE;
thd->abort_on_warning= (!ignore &&
(thd->variables.sql_mode &
(MODE_STRICT_TRANS_TABLES |
@ -467,7 +467,7 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
(ulong) (info.records - info.copied), (ulong) thd->cuted_fields);
if (!transactional_table)
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
thd->no_trans_update.all= TRUE;
#ifndef EMBEDDED_LIBRARY
if (mysql_bin_log.is_open())
{
@ -532,7 +532,7 @@ read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
Item_field *sql_field;
TABLE *table= table_list->table;
ulonglong id;
bool no_trans_update;
bool no_trans_update_stmt;
DBUG_ENTER("read_fixed_length");
id= 0;
@ -560,7 +560,7 @@ read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
#ifdef HAVE_purify
read_info.row_end[0]=0;
#endif
no_trans_update= !table->file->has_transactions();
no_trans_update_stmt= !table->file->has_transactions();
restore_record(table, s->default_values);
/*
@ -626,7 +626,7 @@ read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
if (write_record(thd, table, &info))
DBUG_RETURN(1);
thd->no_trans_update= no_trans_update;
thd->no_trans_update.stmt= no_trans_update_stmt;
/*
If auto_increment values are used, save the first one for
@ -669,12 +669,12 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
TABLE *table= table_list->table;
uint enclosed_length;
ulonglong id;
bool no_trans_update;
bool no_trans_update_stmt;
DBUG_ENTER("read_sep_field");
enclosed_length=enclosed.length();
id= 0;
no_trans_update= !table->file->has_transactions();
no_trans_update_stmt= !table->file->has_transactions();
for (;;it.rewind())
{
@ -816,7 +816,7 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
We don't need to reset auto-increment field since we are restoring
its default value at the beginning of each loop iteration.
*/
thd->no_trans_update= no_trans_update;
thd->no_trans_update.stmt= no_trans_update_stmt;
if (read_info.next_line()) // Skip to next line
break;
if (read_info.line_cuted)

View File

@ -147,7 +147,8 @@ static bool end_active_trans(THD *thd)
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
if (ha_commit(thd))
error=1;
thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
thd->options&= ~(ulong) OPTION_BEGIN;
thd->no_trans_update.all= FALSE;
}
DBUG_RETURN(error);
}
@ -171,8 +172,8 @@ static bool begin_trans(THD *thd)
else
{
LEX *lex= thd->lex;
thd->options= ((thd->options & (ulong) ~(OPTION_STATUS_NO_TRANS_UPDATE)) |
OPTION_BEGIN);
thd->no_trans_update.all= FALSE;
thd->options|= (ulong) OPTION_BEGIN;
thd->server_status|= SERVER_STATUS_IN_TRANS;
if (lex->start_transaction_opt & MYSQL_START_TRANS_OPT_WITH_CONS_SNAPSHOT)
error= ha_start_consistent_snapshot(thd);
@ -289,6 +290,7 @@ int check_user(THD *thd, enum enum_server_command command,
bool check_count)
{
DBUG_ENTER("check_user");
LEX_STRING db_str= { (char *) db, db ? strlen(db) : 0 };
#ifdef NO_EMBEDDED_ACCESS_CHECKS
thd->main_security_ctx.master_access= GLOBAL_ACLS; // Full rights
@ -300,7 +302,7 @@ int check_user(THD *thd, enum enum_server_command command,
function returns 0
*/
thd->reset_db(NULL, 0);
if (mysql_change_db(thd, db, FALSE))
if (mysql_change_db(thd, &db_str, FALSE))
{
/* Send the error to the client */
net_send_error(thd);
@ -442,7 +444,7 @@ int check_user(THD *thd, enum enum_server_command command,
/* Change database if necessary */
if (db && db[0])
{
if (mysql_change_db(thd, db, FALSE))
if (mysql_change_db(thd, &db_str, FALSE))
{
/* Send error to the client */
net_send_error(thd);
@ -1463,7 +1465,8 @@ int end_trans(THD *thd, enum enum_mysql_completiontype completion)
*/
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
res= ha_commit(thd);
thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
thd->options&= ~(ulong) OPTION_BEGIN;
thd->no_trans_update.all= FALSE;
break;
case COMMIT_RELEASE:
do_release= 1; /* fall through */
@ -1480,7 +1483,8 @@ int end_trans(THD *thd, enum enum_mysql_completiontype completion)
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
if (ha_rollback(thd))
res= -1;
thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
thd->options&= ~(ulong) OPTION_BEGIN;
thd->no_trans_update.all= FALSE;
if (!res && (completion == ROLLBACK_AND_CHAIN))
res= begin_trans(thd);
break;
@ -1635,7 +1639,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
&LOCK_status);
thd->convert_string(&tmp, system_charset_info,
packet, strlen(packet), thd->charset());
if (!mysql_change_db(thd, tmp.str, FALSE))
if (!mysql_change_db(thd, &tmp, FALSE))
{
mysql_log.write(thd,command,"%s",thd->db);
send_ok(thd);
@ -1859,7 +1863,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
packet= pend+1;
if (!my_strcasecmp(system_charset_info, table_list.db,
information_schema_name.str))
INFORMATION_SCHEMA_NAME.str))
{
ST_SCHEMA_TABLE *schema_table= find_schema_table(thd, table_list.alias);
if (schema_table)
@ -2233,7 +2237,8 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
enum enum_schema_tables schema_table_idx)
{
DBUG_ENTER("prepare_schema_table");
SELECT_LEX *sel= 0;
SELECT_LEX *schema_select_lex= NULL;
switch (schema_table_idx) {
case SCH_SCHEMATA:
#if defined(DONT_ALLOW_SHOW_COMMANDS)
@ -2241,11 +2246,9 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
ER(ER_NOT_ALLOWED_COMMAND), MYF(0)); /* purecov: inspected */
DBUG_RETURN(1);
#else
if ((specialflag & SPECIAL_SKIP_SHOW_DB) &&
check_global_access(thd, SHOW_DB_ACL))
DBUG_RETURN(1);
break;
#endif
case SCH_TABLE_NAMES:
case SCH_TABLES:
case SCH_VIEWS:
@ -2255,32 +2258,25 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
ER(ER_NOT_ALLOWED_COMMAND), MYF(0)); /* purecov: inspected */
DBUG_RETURN(1);
#else
{
char *db;
if (lex->select_lex.db == NULL &&
thd->copy_db_to(&lex->select_lex.db, 0))
thd->copy_db_to(&lex->select_lex.db, NULL))
{
DBUG_RETURN(1);
}
db= lex->select_lex.db;
remove_escape(db); // Fix escaped '_'
if (check_db_name(db))
schema_select_lex= new SELECT_LEX();
schema_select_lex->db= lex->select_lex.db;
schema_select_lex->table_list.first= NULL;
remove_escape(schema_select_lex->db); // Fix escaped '_'
if (check_db_name(schema_select_lex->db))
{
my_error(ER_WRONG_DB_NAME, MYF(0), db);
DBUG_RETURN(1);
}
if (check_access(thd, SELECT_ACL, db, &thd->col_access, 0, 0,
is_schema_db(db)))
DBUG_RETURN(1); /* purecov: inspected */
if (!thd->col_access && check_grant_db(thd,db))
{
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
thd->security_ctx->priv_user, thd->security_ctx->priv_host,
db);
my_error(ER_WRONG_DB_NAME, MYF(0), schema_select_lex->db);
DBUG_RETURN(1);
}
break;
}
#endif
case SCH_COLUMNS:
case SCH_STATISTICS:
@ -2289,28 +2285,23 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
ER(ER_NOT_ALLOWED_COMMAND), MYF(0)); /* purecov: inspected */
DBUG_RETURN(1);
#else
if (table_ident)
{
DBUG_ASSERT(table_ident);
TABLE_LIST **query_tables_last= lex->query_tables_last;
sel= new SELECT_LEX();
schema_select_lex= new SELECT_LEX();
/* 'parent_lex' is used in init_query() so it must be before it. */
sel->parent_lex= lex;
sel->init_query();
if (!sel->add_table_to_list(thd, table_ident, 0, 0, TL_READ,
schema_select_lex->parent_lex= lex;
schema_select_lex->init_query();
if (!schema_select_lex->add_table_to_list(thd, table_ident, 0, 0, TL_READ,
(List<String> *) 0, (List<String> *) 0))
DBUG_RETURN(1);
lex->query_tables_last= query_tables_last;
TABLE_LIST *table_list= (TABLE_LIST*) sel->table_list.first;
char *db= table_list->db;
remove_escape(db); // Fix escaped '_'
remove_escape(table_list->table_name);
if (check_access(thd,SELECT_ACL | EXTRA_ACL,db,
&table_list->grant.privilege, 0, 0,
test(table_list->schema_table)))
DBUG_RETURN(1); /* purecov: inspected */
if (grant_option && check_grant(thd, SELECT_ACL, table_list, 2,
UINT_MAX, 0))
DBUG_RETURN(1);
TABLE_LIST *dst_table= (TABLE_LIST*) schema_select_lex->table_list.first;
remove_escape(dst_table->db); // Fix escaped '_'
remove_escape(dst_table->table_name);
break;
}
#endif
@ -2337,7 +2328,7 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
DBUG_RETURN(1);
}
TABLE_LIST *table_list= (TABLE_LIST*) select_lex->table_list.first;
table_list->schema_select_lex= sel;
table_list->schema_select_lex= schema_select_lex;
table_list->schema_table_reformed= 1;
statistic_increment(thd->status_var.com_stat[lex->orig_sql_command],
&LOCK_status);
@ -2933,7 +2924,7 @@ mysql_execute_command(THD *thd)
else
{
/* So that CREATE TEMPORARY TABLE gets to binlog at commit/rollback */
thd->options|= OPTION_STATUS_NO_TRANS_UPDATE;
thd->no_trans_update.all= TRUE;
}
DBUG_ASSERT(first_table == all_tables && first_table != 0);
bool link_to_local;
@ -3710,7 +3701,7 @@ end_with_restore_list:
lex->drop_if_exists= 1;
/* So that DROP TEMPORARY TABLE gets to binlog at commit/rollback */
thd->options|= OPTION_STATUS_NO_TRANS_UPDATE;
thd->no_trans_update.all= TRUE;
}
/* DDL and binlog write order protected by LOCK_open */
res= mysql_rm_table(thd, first_table, lex->drop_if_exists,
@ -3750,9 +3741,14 @@ end_with_restore_list:
}
#endif
case SQLCOM_CHANGE_DB:
if (!mysql_change_db(thd,select_lex->db,FALSE))
{
LEX_STRING db_str= { (char *) select_lex->db, strlen(select_lex->db) };
if (!mysql_change_db(thd, &db_str, FALSE))
send_ok(thd);
break;
}
case SQLCOM_LOAD:
{
@ -4296,7 +4292,7 @@ end_with_restore_list:
res= TRUE; // cannot happen
else
{
if ((thd->options & OPTION_STATUS_NO_TRANS_UPDATE) &&
if (thd->no_trans_update.all &&
!thd->slave_thread)
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARNING_NOT_COMPLETE_ROLLBACK,
@ -4939,8 +4935,8 @@ create_sp_error:
thd->transaction.xid_state.xa_state=XA_ACTIVE;
thd->transaction.xid_state.xid.set(thd->lex->xid);
xid_cache_insert(&thd->transaction.xid_state);
thd->options= ((thd->options & (ulong) ~(OPTION_STATUS_NO_TRANS_UPDATE)) |
OPTION_BEGIN);
thd->no_trans_update.all= FALSE;
thd->options|= (ulong) OPTION_BEGIN;
thd->server_status|= SERVER_STATUS_IN_TRANS;
send_ok(thd);
break;
@ -5033,7 +5029,8 @@ create_sp_error:
xa_state_names[thd->transaction.xid_state.xa_state]);
break;
}
thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
thd->options&= ~(ulong) OPTION_BEGIN;
thd->no_trans_update.all= FALSE;
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
xid_cache_delete(&thd->transaction.xid_state);
thd->transaction.xid_state.xa_state=XA_NOTR;
@ -5063,7 +5060,8 @@ create_sp_error:
my_error(ER_XAER_RMERR, MYF(0));
else
send_ok(thd);
thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
thd->options&= ~(ulong) OPTION_BEGIN;
thd->no_trans_update.all= FALSE;
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
xid_cache_delete(&thd->transaction.xid_state);
thd->transaction.xid_state.xa_state=XA_NOTR;
@ -5159,7 +5157,10 @@ bool check_single_table_access(THD *thd, ulong privilege,
goto deny;
/* Show only 1 table for check_grant */
if (grant_option && check_grant(thd, privilege, all_tables, 0, 1, 0))
if (grant_option &&
!(all_tables->belong_to_view &&
(thd->lex->sql_command == SQLCOM_SHOW_FIELDS)) &&
check_grant(thd, privilege, all_tables, 0, 1, 0))
goto deny;
thd->security_ctx= backup_ctx;
@ -5376,6 +5377,83 @@ bool check_global_access(THD *thd, ulong want_access)
}
static bool check_show_access(THD *thd, TABLE_LIST *table)
{
switch (get_schema_table_idx(table->schema_table))
{
case SCH_SCHEMATA:
return (specialflag & SPECIAL_SKIP_SHOW_DB) &&
check_global_access(thd, SHOW_DB_ACL);
case SCH_TABLE_NAMES:
case SCH_TABLES:
case SCH_VIEWS:
case SCH_TRIGGERS:
{
const char *dst_db_name= table->schema_select_lex->db;
DBUG_ASSERT(dst_db_name);
if (check_access(thd, SELECT_ACL, dst_db_name,
&thd->col_access, FALSE, FALSE,
is_schema_db(dst_db_name)))
{
return TRUE;
}
if (!thd->col_access && check_grant_db(thd, dst_db_name))
{
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
thd->security_ctx->priv_user,
thd->security_ctx->priv_host,
dst_db_name);
return TRUE;
}
return FALSE;
}
case SCH_COLUMNS:
case SCH_STATISTICS:
{
TABLE_LIST *dst_table=
(TABLE_LIST *) table->schema_select_lex->table_list.first;
DBUG_ASSERT(dst_table);
if (check_access(thd, SELECT_ACL | EXTRA_ACL,
dst_table->db,
&dst_table->grant.privilege,
FALSE, FALSE,
test(dst_table->schema_table)))
{
return FALSE;
}
return grant_option &&
check_grant(thd, SELECT_ACL, dst_table, 2, UINT_MAX, FALSE);
}
case SCH_OPEN_TABLES:
case SCH_VARIABLES:
case SCH_STATUS:
case SCH_PROCEDURES:
case SCH_CHARSETS:
case SCH_COLLATIONS:
case SCH_COLLATION_CHARACTER_SET_APPLICABILITY:
case SCH_USER_PRIVILEGES:
case SCH_SCHEMA_PRIVILEGES:
case SCH_TABLE_PRIVILEGES:
case SCH_COLUMN_PRIVILEGES:
case SCH_TABLE_CONSTRAINTS:
case SCH_KEY_COLUMN_USAGE:
break;
}
return FALSE;
}
/*
Check the privilege for all used tables.
@ -5428,7 +5506,7 @@ check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables,
if (!no_errors)
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
sctx->priv_user, sctx->priv_host,
information_schema_name.str);
INFORMATION_SCHEMA_NAME.str);
return TRUE;
}
/*
@ -5436,7 +5514,16 @@ check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables,
Remove SHOW_VIEW_ACL, because it will be checked during making view
*/
tables->grant.orig_want_privilege= (want_access & ~SHOW_VIEW_ACL);
if (tables->derived || tables->schema_table ||
if (tables->schema_table_reformed)
{
if (check_show_access(thd, tables))
goto deny;
continue;
}
if (tables->derived ||
(tables->table && (int)tables->table->s->tmp_table) ||
my_tz_check_n_skip_implicit_tables(&tables,
thd->lex->time_zone_tables_used))
@ -6248,7 +6335,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
ptr->ignore_leaves= test(table_options & TL_OPTION_IGNORE_LEAVES);
ptr->derived= table->sel;
if (!ptr->derived && !my_strcasecmp(system_charset_info, ptr->db,
information_schema_name.str))
INFORMATION_SCHEMA_NAME.str))
{
ST_SCHEMA_TABLE *schema_table= find_schema_table(thd, ptr->table_name);
if (!schema_table ||
@ -6256,7 +6343,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
lex->orig_sql_command == SQLCOM_END)) // not a 'show' command
{
my_error(ER_UNKNOWN_TABLE, MYF(0),
ptr->table_name, information_schema_name.str);
ptr->table_name, INFORMATION_SCHEMA_NAME.str);
DBUG_RETURN(0);
}
ptr->schema_table_name= ptr->table_name;

View File

@ -1668,7 +1668,7 @@ static bool check_prepared_statement(Prepared_statement *stmt,
enum enum_sql_command sql_command= lex->sql_command;
int res= 0;
DBUG_ENTER("check_prepared_statement");
DBUG_PRINT("enter",("command: %d, param_count: %u",
DBUG_PRINT("enter",("command: %d param_count: %u",
sql_command, stmt->param_count));
lex->first_lists_tables_same();

View File

@ -496,9 +496,9 @@ bool mysqld_show_create_db(THD *thd, char *dbname,
}
#endif
if (!my_strcasecmp(system_charset_info, dbname,
information_schema_name.str))
INFORMATION_SCHEMA_NAME.str))
{
dbname= information_schema_name.str;
dbname= INFORMATION_SCHEMA_NAME.str;
create.default_table_charset= system_charset_info;
}
else
@ -1823,7 +1823,8 @@ LEX_STRING *make_lex_string(THD *thd, LEX_STRING *lex_str,
/* INFORMATION_SCHEMA name */
LEX_STRING information_schema_name= {(char*)"information_schema", 18};
LEX_STRING INFORMATION_SCHEMA_NAME=
{ (char *) STRING_WITH_LEN("information_schema") };
/* This is only used internally, but we need it here as a forward reference */
extern ST_SCHEMA_TABLE schema_tables[];
@ -2039,11 +2040,11 @@ int make_db_list(THD *thd, List<char> *files,
*/
if (!idx_field_vals->db_value ||
!wild_case_compare(system_charset_info,
information_schema_name.str,
INFORMATION_SCHEMA_NAME.str,
idx_field_vals->db_value))
{
*with_i_schema= 1;
if (files->push_back(thd->strdup(information_schema_name.str)))
if (files->push_back(thd->strdup(INFORMATION_SCHEMA_NAME.str)))
return 1;
}
return (find_files(thd, files, NullS, mysql_data_home,
@ -2058,11 +2059,11 @@ int make_db_list(THD *thd, List<char> *files,
*/
if (lex->orig_sql_command != SQLCOM_END)
{
if (!my_strcasecmp(system_charset_info, information_schema_name.str,
if (!my_strcasecmp(system_charset_info, INFORMATION_SCHEMA_NAME.str,
idx_field_vals->db_value))
{
*with_i_schema= 1;
return files->push_back(thd->strdup(information_schema_name.str));
return files->push_back(thd->strdup(INFORMATION_SCHEMA_NAME.str));
}
return files->push_back(thd->strdup(idx_field_vals->db_value));
}
@ -2071,7 +2072,7 @@ int make_db_list(THD *thd, List<char> *files,
Create list of existing databases. It is used in case
of select from information schema table
*/
if (files->push_back(thd->strdup(information_schema_name.str)))
if (files->push_back(thd->strdup(INFORMATION_SCHEMA_NAME.str)))
return 1;
*with_i_schema= 1;
return (find_files(thd, files, NullS,
@ -2147,7 +2148,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
*/
thd->reset_n_backup_open_tables_state(&open_tables_state_backup);
if (lsel)
if (lsel && lsel->table_list.first)
{
TABLE_LIST *show_table_list= (TABLE_LIST*) lsel->table_list.first;
bool res;
@ -3927,8 +3928,8 @@ int make_schema_select(THD *thd, SELECT_LEX *sel,
We have to make non const db_name & table_name
because of lower_case_table_names
*/
make_lex_string(thd, &db, information_schema_name.str,
information_schema_name.length, 0);
make_lex_string(thd, &db, INFORMATION_SCHEMA_NAME.str,
INFORMATION_SCHEMA_NAME.length, 0);
make_lex_string(thd, &table, schema_table->table_name,
strlen(schema_table->table_name), 0);
if (schema_table->old_format(thd, schema_table) || /* Handle old syntax */

View File

@ -3968,7 +3968,7 @@ copy_data_between_tables(TABLE *from,TABLE *to,
alter_table_manage_keys(to, from->file->indexes_are_disabled(), keys_onoff);
/* We can abort alter table for any table type */
thd->no_trans_update= 0;
thd->no_trans_update.stmt= FALSE;
thd->abort_on_warning= !ignore && test(thd->variables.sql_mode &
(MODE_STRICT_TRANS_TABLES |
MODE_STRICT_ALL_TABLES));

View File

@ -429,7 +429,7 @@ int mysql_update(THD *thd,
query_id=thd->query_id;
transactional_table= table->file->has_transactions();
thd->no_trans_update= 0;
thd->no_trans_update.stmt= FALSE;
thd->abort_on_warning= test(!ignore &&
(thd->variables.sql_mode &
(MODE_STRICT_TRANS_TABLES |
@ -474,7 +474,7 @@ int mysql_update(THD *thd,
(byte*) table->record[0])))
{
updated++;
thd->no_trans_update= !transactional_table;
thd->no_trans_update.stmt= !transactional_table;
if (table->triggers &&
table->triggers->process_triggers(thd, TRG_EVENT_UPDATE,
@ -546,7 +546,7 @@ int mysql_update(THD *thd,
error=1; // Rollback update
}
if (!transactional_table)
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
thd->no_trans_update.all= TRUE;
}
free_underlaid_joins(thd, select_lex);
if (transactional_table)
@ -910,7 +910,7 @@ bool mysql_multi_update(THD *thd,
handle_duplicates, ignore)))
DBUG_RETURN(TRUE);
thd->no_trans_update= 0;
thd->no_trans_update.stmt= FALSE;
thd->abort_on_warning= test(thd->variables.sql_mode &
(MODE_STRICT_TRANS_TABLES |
MODE_STRICT_ALL_TABLES));
@ -1224,7 +1224,7 @@ multi_update::~multi_update()
delete [] copy_field;
thd->count_cuted_fields= CHECK_FIELD_IGNORE; // Restore this setting
if (!trans_safe)
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
thd->no_trans_update.all= TRUE;
}
@ -1311,7 +1311,7 @@ bool multi_update::send_data(List<Item> &not_used_values)
else
{
if (!table->file->has_transactions())
thd->no_trans_update= 1;
thd->no_trans_update.stmt= TRUE;
if (table->triggers &&
table->triggers->process_triggers(thd, TRG_EVENT_UPDATE,
TRG_ACTION_AFTER, TRUE))
@ -1544,7 +1544,7 @@ bool multi_update::send_eof()
local_error= 1; // Rollback update
}
if (!transactional_tables)
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
thd->no_trans_update.all= TRUE;
}
if (transactional_tables)

View File

@ -496,37 +496,48 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
/*
Compare/check grants on view with grants of underlying tables
*/
fill_effective_table_privileges(thd, &view->grant, view->db,
view->table_name);
{
Item *report_item= NULL;
uint final_priv= VIEW_ANY_ACL;
for (sl= select_lex; sl; sl= sl->next_select())
{
DBUG_ASSERT(view->db); /* Must be set in the parser */
List_iterator_fast<Item> it(sl->item_list);
Item *item;
fill_effective_table_privileges(thd, &view->grant, view->db,
view->table_name);
while ((item= it++))
{
Item_field *fld;
Item_field *fld= item->filed_for_view_update();
uint priv= (get_column_grant(thd, &view->grant, view->db,
view->table_name, item->name) &
VIEW_ANY_ACL);
if ((fld= item->filed_for_view_update()))
if (fld && !fld->field->table->s->tmp_table)
{
/*
Do we have more privileges on view field then underlying table field?
*/
if (!fld->field->table->s->tmp_table && (~fld->have_privileges & priv))
final_priv&= fld->have_privileges;
if (~fld->have_privileges & priv)
report_item= item;
}
}
}
if (!final_priv)
{
/* VIEW column has more privileges */
DBUG_ASSERT(report_item);
my_error(ER_COLUMNACCESS_DENIED_ERROR, MYF(0),
"create view", thd->security_ctx->priv_user,
thd->security_ctx->priv_host, item->name,
thd->security_ctx->priv_host, report_item->name,
view->table_name);
res= TRUE;
goto err;
}
}
}
}
#endif
if (wait_if_global_read_lock(thd, 0, 0))
@ -1007,6 +1018,11 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table,
CHARSET_INFO *save_cs= thd->variables.character_set_client;
thd->variables.character_set_client= system_charset_info;
res= MYSQLparse((void *)thd);
if ((old_lex->sql_command == SQLCOM_SHOW_FIELDS) ||
(old_lex->sql_command == SQLCOM_SHOW_CREATE))
lex->sql_command= old_lex->sql_command;
thd->variables.character_set_client= save_cs;
thd->variables.sql_mode= save_mode;
}
@ -1032,7 +1048,7 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table,
}
}
else if (!table->prelocking_placeholder &&
old_lex->sql_command == SQLCOM_SHOW_CREATE &&
(old_lex->sql_command == SQLCOM_SHOW_CREATE) &&
!table->belong_to_view)
{
if (check_table_access(thd, SHOW_VIEW_ACL, table, 0))

View File

@ -2441,7 +2441,8 @@ bool st_table_list::prepare_view_securety_context(THD *thd)
definer.host.str,
thd->db))
{
if (thd->lex->sql_command == SQLCOM_SHOW_CREATE)
if ((thd->lex->sql_command == SQLCOM_SHOW_CREATE) ||
(thd->lex->sql_command == SQLCOM_SHOW_FIELDS))
{
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_NO_SUCH_USER,