Merge jamppa@bk-internal.mysql.com:/home/bk/mysql-5.1-marvel
into ua141d10.elisa.omakaista.fi:/home/my/bk/mysql-5.1-marvel mysys/my_pread.c: Auto merged mysys/thr_alarm.c: Auto merged sql/ha_ndbcluster.cc: Auto merged sql/handler.cc: Auto merged sql/log.cc: Auto merged sql/log_event.cc: Auto merged sql/opt_range.cc: Auto merged sql/set_var.cc: Auto merged sql/slave.cc: Auto merged sql/sql_class.cc: 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 storage/heap/hp_write.c: Auto merged mysql-test/t/mysqlbinlog2.test: SCCS merged client/mysql.cc: Auto merged client/mysqlbinlog.cc: Auto merged sql/event_db_repository.cc: Auto merged sql/item.cc: Auto merged sql/mysql_priv.h: Auto merged sql/mysqld.cc: Auto merged sql/sql_base.cc: Auto merged sql/sql_class.h: Auto merged sql/sql_parse.cc: Auto merged sql/sql_show.cc: Auto merged
This commit is contained in:
commit
fbd929f802
@ -1099,7 +1099,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");
|
||||
|
||||
@ -1162,7 +1162,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,
|
||||
@ -1251,10 +1251,17 @@ could be out of memory");
|
||||
}
|
||||
}
|
||||
/*
|
||||
Let's adjust offset for remote log as for local log to produce
|
||||
similar text.
|
||||
Let's adjust offset for remote log as for local log to produce
|
||||
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.
|
||||
*/
|
||||
old_off+= len-1;
|
||||
if (old_off < start_position_mot)
|
||||
old_off= start_position_mot;
|
||||
else
|
||||
old_off+= len-1;
|
||||
}
|
||||
|
||||
err:
|
||||
|
@ -260,29 +260,29 @@ GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' IDENTIFIED BY PASSWORD '*2470C0C
|
||||
GRANT SELECT, INSERT, UPDATE ON `test`.* TO 'mysqltest_1'@'localhost'
|
||||
drop user mysqltest_1@localhost;
|
||||
SET NAMES koi8r;
|
||||
CREATE DATABASE ÂÄ;
|
||||
USE ÂÄ;
|
||||
CREATE TABLE ÔÁÂ (ËÏÌ int);
|
||||
GRANT SELECT ON ÂÄ.* TO ÀÚÅÒ@localhost;
|
||||
SHOW GRANTS FOR ÀÚÅÒ@localhost;
|
||||
Grants for ÀÚÅÒ@localhost
|
||||
GRANT USAGE ON *.* TO 'ÀÚÅÒ'@'localhost'
|
||||
GRANT SELECT ON `ÂÄ`.* TO 'ÀÚÅÒ'@'localhost'
|
||||
REVOKE SELECT ON ÂÄ.* FROM ÀÚÅÒ@localhost;
|
||||
GRANT SELECT ON ÂÄ.ÔÁÂ TO ÀÚÅÒ@localhost;
|
||||
SHOW GRANTS FOR ÀÚÅÒ@localhost;
|
||||
Grants for ÀÚÅÒ@localhost
|
||||
GRANT USAGE ON *.* TO 'ÀÚÅÒ'@'localhost'
|
||||
GRANT SELECT ON `ÂÄ`.`ÔÁÂ` TO 'ÀÚÅÒ'@'localhost'
|
||||
REVOKE SELECT ON ÂÄ.ÔÁÂ FROM ÀÚÅÒ@localhost;
|
||||
GRANT SELECT (ËÏÌ) ON ÂÄ.ÔÁÂ TO ÀÚÅÒ@localhost;
|
||||
SHOW GRANTS FOR ÀÚÅÒ@localhost;
|
||||
Grants for ÀÚÅÒ@localhost
|
||||
GRANT USAGE ON *.* TO 'ÀÚÅÒ'@'localhost'
|
||||
GRANT SELECT (ËÏÌ) ON `ÂÄ`.`ÔÁÂ` TO 'ÀÚÅÒ'@'localhost'
|
||||
REVOKE SELECT (ËÏÌ) ON ÂÄ.ÔÁÂ FROM ÀÚÅÒ@localhost;
|
||||
DROP USER ÀÚÅÒ@localhost;
|
||||
DROP DATABASE ÂÄ;
|
||||
CREATE DATABASE ツト;
|
||||
USE ツト;
|
||||
CREATE TABLE ヤチツ (ヒマフ int);
|
||||
GRANT SELECT ON ツト.* TO タレナメ@localhost;
|
||||
SHOW GRANTS FOR タレナメ@localhost;
|
||||
Grants for タレナメ@localhost
|
||||
GRANT USAGE ON *.* TO 'タレナメ'@'localhost'
|
||||
GRANT SELECT ON `ツト`.* TO 'タレナメ'@'localhost'
|
||||
REVOKE SELECT ON ツト.* FROM タレナメ@localhost;
|
||||
GRANT SELECT ON ツト.ヤチツ TO タレナメ@localhost;
|
||||
SHOW GRANTS FOR タレナメ@localhost;
|
||||
Grants for タレナメ@localhost
|
||||
GRANT USAGE ON *.* TO 'タレナメ'@'localhost'
|
||||
GRANT SELECT ON `ツト`.`ヤチツ` TO 'タレナメ'@'localhost'
|
||||
REVOKE SELECT ON ツト.ヤチツ FROM タレナメ@localhost;
|
||||
GRANT SELECT (ヒマフ) ON ツト.ヤチツ TO タレナメ@localhost;
|
||||
SHOW GRANTS FOR タレナメ@localhost;
|
||||
Grants for タレナメ@localhost
|
||||
GRANT USAGE ON *.* TO 'タレナメ'@'localhost'
|
||||
GRANT SELECT (ヒマフ) ON `ツト`.`ヤチツ` TO 'タレナメ'@'localhost'
|
||||
REVOKE SELECT (ヒマフ) ON ツト.ヤチツ FROM タレナメ@localhost;
|
||||
DROP USER タレナメ@localhost;
|
||||
DROP DATABASE ツト;
|
||||
SET NAMES latin1;
|
||||
USE test;
|
||||
CREATE TABLE t1 (a int );
|
||||
@ -613,22 +613,22 @@ set @user123="non-existent";
|
||||
select * from mysql.db where user=@user123;
|
||||
Host Db User Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Grant_priv References_priv Index_priv Alter_priv Create_tmp_table_priv Lock_tables_priv Create_view_priv Show_view_priv Create_routine_priv Alter_routine_priv Execute_priv Event_priv Trigger_priv
|
||||
set names koi8r;
|
||||
create database ÂÄ;
|
||||
grant select on ÂÄ.* to root@localhost;
|
||||
select hex(Db) from mysql.db where Db='ÂÄ';
|
||||
create database ツト;
|
||||
grant select on ツト.* to root@localhost;
|
||||
select hex(Db) from mysql.db where Db='ツト';
|
||||
hex(Db)
|
||||
D0B1D0B4
|
||||
show grants for root@localhost;
|
||||
Grants for root@localhost
|
||||
GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION
|
||||
GRANT SELECT ON `ÂÄ`.* TO 'root'@'localhost'
|
||||
GRANT SELECT ON `ツト`.* TO 'root'@'localhost'
|
||||
flush privileges;
|
||||
show grants for root@localhost;
|
||||
Grants for root@localhost
|
||||
GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION
|
||||
GRANT SELECT ON `ÂÄ`.* TO 'root'@'localhost'
|
||||
drop database ÂÄ;
|
||||
revoke all privileges on ÂÄ.* from root@localhost;
|
||||
GRANT SELECT ON `ツト`.* TO 'root'@'localhost'
|
||||
drop database ツト;
|
||||
revoke all privileges on ツト.* from root@localhost;
|
||||
show grants for root@localhost;
|
||||
Grants for root@localhost
|
||||
GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION
|
||||
@ -1059,4 +1059,51 @@ DROP DATABASE bug23556;
|
||||
DROP USER bug23556@localhost;
|
||||
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;
|
||||
End of 5.0 tests
|
||||
|
@ -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*/;
|
||||
@ -482,6 +500,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*/;
|
||||
|
@ -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;
|
||||
|
@ -6061,4 +6061,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;
|
||||
|
@ -530,6 +530,27 @@ 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
|
||||
CREATE DATABASE db_bug7787|
|
||||
use db_bug7787|
|
||||
CREATE PROCEDURE p1()
|
||||
|
@ -284,15 +284,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;
|
||||
@ -796,6 +787,94 @@ 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.
|
||||
DROP VIEW IF EXISTS v1;
|
||||
DROP TABLE IF EXISTS t1;
|
||||
|
@ -985,4 +985,87 @@ 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;
|
||||
|
||||
|
||||
--echo End of 5.0 tests
|
||||
|
@ -58,6 +58,10 @@ select "--- stop-position --" as "";
|
||||
--enable_query_log
|
||||
--exec $MYSQL_BINLOG --short-form --stop-position=608 $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 "--- start-position --" as "";
|
||||
--enable_query_log
|
||||
--exec $MYSQL_BINLOG --short-form --start-position=608 --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 "--- stop-position --" as "";
|
||||
--enable_query_log
|
||||
--exec $MYSQL_BINLOG --short-form --stop-position=608 --read-from-remote-server --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000001
|
||||
|
@ -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;
|
||||
|
@ -7017,6 +7017,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!
|
||||
@ -7034,3 +7075,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;
|
||||
|
@ -592,6 +592,37 @@ drop function bug13575|
|
||||
drop table t3|
|
||||
|
||||
|
||||
#
|
||||
# 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
|
||||
#
|
||||
|
@ -356,25 +356,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
|
||||
@ -1072,6 +1053,97 @@ 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.
|
||||
|
||||
|
||||
|
@ -557,4 +557,3 @@ HA_KEYSEG *ha_find_null(HA_KEYSEG *keyseg, uchar *a)
|
||||
}
|
||||
return keyseg;
|
||||
}
|
||||
|
||||
|
@ -518,7 +518,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));
|
||||
}
|
||||
|
||||
@ -527,7 +527,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)))
|
||||
|
@ -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)
|
||||
|
@ -76,7 +76,10 @@ void init_thr_alarm(uint max_alarms)
|
||||
sigfillset(&full_signal_set); /* Neaded to block signals */
|
||||
pthread_mutex_init(&LOCK_alarm,MY_MUTEX_INIT_FAST);
|
||||
pthread_cond_init(&COND_alarm,NULL);
|
||||
thr_client_alarm= thd_lib_detected == THD_LIB_LT ? SIGALRM : SIGUSR1;
|
||||
if (thd_lib_detected == THD_LIB_LT)
|
||||
thr_client_alarm= SIGALRM;
|
||||
else
|
||||
thr_client_alarm= SIGUSR1;
|
||||
#ifndef USE_ALARM_THREAD
|
||||
if (thd_lib_detected != THD_LIB_LT)
|
||||
#endif
|
||||
|
@ -653,7 +653,7 @@ Event_db_repository::create_event(THD *thd, Event_parse_data *parse_data,
|
||||
|
||||
ok:
|
||||
if (dbchanged)
|
||||
(void) mysql_change_db(thd, old_db.str, 1);
|
||||
(void) mysql_change_db(thd, &old_db, 1);
|
||||
/*
|
||||
This statement may cause a spooky valgrind warning at startup
|
||||
inside init_key_cache on my system (ahristov, 2006/08/10)
|
||||
@ -663,7 +663,7 @@ ok:
|
||||
|
||||
err:
|
||||
if (dbchanged)
|
||||
(void) mysql_change_db(thd, old_db.str, 1);
|
||||
(void) mysql_change_db(thd, &old_db, 1);
|
||||
if (table)
|
||||
close_thread_tables(thd);
|
||||
DBUG_RETURN(TRUE);
|
||||
|
@ -4151,8 +4151,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;
|
||||
@ -4838,7 +4837,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)))
|
||||
|
@ -844,7 +844,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 && thd->killed != THD::KILL_CONNECTION)
|
||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
ER_WARNING_NOT_COMPLETE_ROLLBACK,
|
||||
|
@ -2405,7 +2405,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;
|
||||
}
|
||||
|
@ -1440,7 +1440,7 @@ private:
|
||||
bool execute(Field **flp);
|
||||
bool execute_impl(THD *thd, Field *return_value_fld);
|
||||
Field *sp_result_field(void) const;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
Item_func_sp(Name_resolution_context *context_arg, sp_name *name);
|
||||
@ -1451,6 +1451,8 @@ public:
|
||||
virtual ~Item_func_sp()
|
||||
{}
|
||||
|
||||
table_map used_tables() const { return RAND_TABLE_BIT; }
|
||||
|
||||
void cleanup();
|
||||
|
||||
const char *func_name() const;
|
||||
|
@ -1587,8 +1587,7 @@ static int binlog_rollback(handlerton *hton, 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 |
|
||||
OPTION_KEEP_LOG)))
|
||||
if (unlikely(thd->no_trans_update.all || (thd->options & OPTION_KEEP_LOG)))
|
||||
{
|
||||
Query_log_event qev(thd, STRING_WITH_LEN("ROLLBACK"), TRUE, FALSE);
|
||||
qev.error_code= 0; // see comment in MYSQL_LOG::write(THD, IO_CACHE)
|
||||
@ -1643,8 +1642,7 @@ static int binlog_savepoint_rollback(handlerton *hton, 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 | OPTION_KEEP_LOG)))
|
||||
if (unlikely(thd->no_trans_update.all || (thd->options & OPTION_KEEP_LOG)))
|
||||
{
|
||||
int error=
|
||||
thd->binlog_query(THD::STMT_QUERY_TYPE,
|
||||
|
@ -340,9 +340,6 @@ MY_LOCALE *my_locale_by_number(uint number);
|
||||
/* The following is used to detect a conflict with DISTINCT */
|
||||
#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
|
||||
@ -835,7 +832,8 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent);
|
||||
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);
|
||||
@ -1114,7 +1112,7 @@ void init_status_vars();
|
||||
void free_status_vars();
|
||||
|
||||
/* information schema */
|
||||
extern LEX_STRING information_schema_name;
|
||||
extern LEX_STRING INFORMATION_SCHEMA_NAME;
|
||||
extern const LEX_STRING partition_keywords[];
|
||||
LEX_STRING *make_lex_string(THD *thd, LEX_STRING *lex_str,
|
||||
const char* str, uint length,
|
||||
@ -1133,7 +1131,7 @@ 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);
|
||||
#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 */
|
||||
|
||||
|
@ -274,7 +274,11 @@ static TYPELIB tc_heuristic_recover_typelib=
|
||||
};
|
||||
|
||||
static const char *thread_handling_names[]=
|
||||
{ "one-thread-per-connection", "no-threads", "pool-of-threads", NullS};
|
||||
{ "one-thread-per-connection", "no-threads",
|
||||
#if HAVE_POOL_OF_THREADS == 1
|
||||
"pool-of-threads",
|
||||
#endif
|
||||
NullS};
|
||||
|
||||
TYPELIB thread_handling_typelib=
|
||||
{
|
||||
@ -785,7 +789,6 @@ static void close_connections(void)
|
||||
DBUG_PRINT("info",("Waiting for select thread"));
|
||||
|
||||
#ifndef DONT_USE_THR_ALARM
|
||||
if (pthread_kill(select_thread, thr_client_alarm))
|
||||
break; // allready dead
|
||||
#endif
|
||||
set_timespec(abstime, 2);
|
||||
@ -7863,16 +7866,8 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
|
||||
break;
|
||||
case OPT_THREAD_HANDLING:
|
||||
{
|
||||
if ((global_system_variables.thread_handling=
|
||||
find_type(argument, &thread_handling_typelib, 2)) <= 0 ||
|
||||
(global_system_variables.thread_handling == SCHEDULER_POOL_OF_THREADS
|
||||
&& !HAVE_POOL_OF_THREADS))
|
||||
{
|
||||
/* purecov: begin tested */
|
||||
fprintf(stderr,"Unknown/unsupported thread-handling: %s\n",argument);
|
||||
exit(1);
|
||||
/* purecov: end */
|
||||
}
|
||||
global_system_variables.thread_handling=
|
||||
find_type_or_exit(argument, &thread_handling_typelib, opt->name);
|
||||
break;
|
||||
}
|
||||
case OPT_FT_BOOLEAN_SYNTAX:
|
||||
|
@ -298,7 +298,7 @@ void net_clear(NET *net, my_bool clear_buffer)
|
||||
{
|
||||
DBUG_PRINT("info",("skipped %d bytes from file: %s",
|
||||
count, vio_description(net->vio)));
|
||||
#if defined(EXTRA_DEBUG) && (MYSQL_VERSION_ID < 51000)
|
||||
#if defined(EXTRA_DEBUG) && (MYSQL_VERSION_ID < 50100)
|
||||
fprintf(stderr,"Error: net_clear() skipped %d bytes from file: %s\n",
|
||||
count, vio_description(net->vio));
|
||||
#endif
|
||||
@ -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(MYSQL_SERVER)
|
||||
/*
|
||||
|
@ -3086,16 +3086,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&= ~(ulonglong) (OPTION_BEGIN |
|
||||
OPTION_STATUS_NO_TRANS_UPDATE |
|
||||
OPTION_KEEP_LOG);
|
||||
thd->options&= ~(ulonglong) (OPTION_BEGIN | OPTION_KEEP_LOG);
|
||||
thd->no_trans_update.all= FALSE;
|
||||
thd->server_status|= SERVER_STATUS_AUTOCOMMIT;
|
||||
if (ha_commit(thd))
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
thd->options&= ~(ulonglong) (OPTION_STATUS_NO_TRANS_UPDATE);
|
||||
thd->no_trans_update.all= FALSE;
|
||||
thd->server_status&= ~SERVER_STATUS_AUTOCOMMIT;
|
||||
}
|
||||
}
|
||||
|
@ -391,14 +391,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);
|
||||
@ -1863,7 +1863,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);
|
||||
|
@ -349,13 +349,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. */
|
||||
|
||||
@ -363,7 +363,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)
|
||||
{
|
||||
@ -1171,7 +1171,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",
|
||||
|
@ -4052,6 +4052,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
|
||||
@ -4063,9 +4083,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++)
|
||||
@ -4076,11 +4097,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;
|
||||
}
|
||||
|
||||
|
@ -377,7 +377,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;
|
||||
@ -3685,7 +3685,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,
|
||||
@ -4008,7 +4008,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;
|
||||
}
|
||||
|
@ -841,7 +841,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)
|
||||
@ -851,7 +852,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;
|
||||
}
|
||||
@ -863,7 +864,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;
|
||||
}
|
||||
|
@ -1356,7 +1356,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 */
|
||||
@ -1584,7 +1588,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();
|
||||
|
@ -315,6 +315,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
|
||||
@ -326,7 +327,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);
|
||||
@ -472,7 +473,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);
|
||||
|
344
sql/sql_db.cc
344
sql/sql_db.cc
@ -22,6 +22,7 @@
|
||||
#include "events.h"
|
||||
#include <my_dir.h>
|
||||
#include <m_ctype.h>
|
||||
#include "log.h"
|
||||
#ifdef __WIN__
|
||||
#include <direct.h>
|
||||
#endif
|
||||
@ -577,7 +578,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);
|
||||
@ -1256,155 +1257,254 @@ 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)
|
||||
{
|
||||
LEX_STRING 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)
|
||||
{
|
||||
my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
|
||||
DBUG_RETURN(1); /* purecov: inspected */
|
||||
/*
|
||||
THD::set_db() does all the job -- it frees previous database name and
|
||||
sets the new one.
|
||||
*/
|
||||
|
||||
thd->set_db(NULL, 0);
|
||||
}
|
||||
else if (name[0] == '\0')
|
||||
else if (new_db_name == &INFORMATION_SCHEMA_NAME)
|
||||
{
|
||||
/* Called from SP to restore the original database, which was NULL */
|
||||
DBUG_ASSERT(no_access_check);
|
||||
system_db= 1;
|
||||
db_name.str= NULL;
|
||||
db_name.length= 0;
|
||||
goto end;
|
||||
/*
|
||||
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)
|
||||
{
|
||||
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(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
if (my_strcasecmp(system_charset_info, new_db_name->str,
|
||||
INFORMATION_SCHEMA_NAME.str) == 0)
|
||||
{
|
||||
/* 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. TODO: fix check_db_name.
|
||||
non-constant argument. Actually, it takes database file name.
|
||||
|
||||
TODO: fix check_db_name().
|
||||
*/
|
||||
if ((db_name.str= my_strdup(name, MYF(MY_WME))) == NULL)
|
||||
DBUG_RETURN(1); /* the error is set */
|
||||
db_name.length= strlen(db_name.str);
|
||||
if (check_db_name(&db_name))
|
||||
|
||||
new_db_file_name.str= my_strndup(new_db_name->str, new_db_name->length,
|
||||
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))
|
||||
{
|
||||
my_error(ER_WRONG_DB_NAME, MYF(0), db_name.str);
|
||||
my_free(db_name.str, MYF(0));
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
DBUG_PRINT("info",("Use database: %s", db_name.str));
|
||||
if (!my_strcasecmp(system_charset_info, db_name.str,
|
||||
information_schema_name.str))
|
||||
{
|
||||
system_db= 1;
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
db_access= SELECT_ACL;
|
||||
#endif
|
||||
goto end;
|
||||
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
|
||||
if (!no_access_check)
|
||||
if (!force_switch) /* FIXME: this is BUG#27337. */
|
||||
{
|
||||
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.str, 0) |
|
||||
sctx->master_access);
|
||||
if (!(db_access & DB_ACLS) && (!grant_option ||
|
||||
check_grant_db(thd, db_name.str)))
|
||||
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.str);
|
||||
new_db_file_name.str);
|
||||
general_log_print(thd, COM_INIT_DB, ER(ER_DBACCESS_DENIED_ERROR),
|
||||
sctx->priv_user, sctx->priv_host, db_name.str);
|
||||
my_free(db_name.str, 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.str))
|
||||
if (check_db_dir_existence(new_db_file_name.str))
|
||||
{
|
||||
my_error(ER_BAD_DB_ERROR, MYF(0), db_name.str);
|
||||
my_free(db_name.str, 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);
|
||||
|
||||
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
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
x_free(thd->db);
|
||||
DBUG_ASSERT(db_name.str == NULL || db_name.str[0] != '\0');
|
||||
thd->reset_db(db_name.str, db_name.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;
|
||||
}
|
||||
else
|
||||
{
|
||||
HA_CREATE_INFO create;
|
||||
/*
|
||||
NOTE: in mysql_change_db_impl() new_db_file_name is assigned to THD
|
||||
attributes and will be freed in THD::~THD().
|
||||
*/
|
||||
|
||||
load_db_opt_by_name(thd, db_name.str, &create);
|
||||
{
|
||||
HA_CREATE_INFO db_options;
|
||||
|
||||
thd->db_charset= create.default_table_charset ?
|
||||
create.default_table_charset :
|
||||
thd->variables.collation_server;
|
||||
thd->variables.collation_database= thd->db_charset;
|
||||
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(0);
|
||||
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
||||
|
||||
@ -1581,8 +1681,8 @@ bool mysql_rename_db(THD *thd, LEX_STRING *old_db, LEX_STRING *new_db)
|
||||
Failed to move all tables from the old database to the new one.
|
||||
In the best case mysql_rename_tables() moved all tables back to the old
|
||||
database. In the worst case mysql_rename_tables() moved some tables
|
||||
to the new database, then failed, then started to move the tables back, and
|
||||
then failed again. In this situation we have some tables in the
|
||||
to the new database, then failed, then started to move the tables back,
|
||||
and then failed again. In this situation we have some tables in the
|
||||
old database and some tables in the new database.
|
||||
Let's delete the option file, and then the new database directory.
|
||||
If some tables were left in the new directory, rmdir() will fail.
|
||||
@ -1703,7 +1803,7 @@ bool mysql_rename_db(THD *thd, LEX_STRING *old_db, LEX_STRING *new_db)
|
||||
|
||||
/* Step9: Let's do "use newdb" if we renamed the current database */
|
||||
if (change_to_newdb)
|
||||
error|= mysql_change_db(thd, new_db->str, 0);
|
||||
error|= mysql_change_db(thd, new_db, 0);
|
||||
|
||||
exit:
|
||||
pthread_mutex_lock(&LOCK_lock_db);
|
||||
@ -1718,6 +1818,8 @@ exit:
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Check if there is directory for the database name.
|
||||
|
||||
|
@ -340,7 +340,7 @@ cleanup:
|
||||
}
|
||||
}
|
||||
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)
|
||||
@ -832,7 +832,7 @@ bool multi_delete::send_eof()
|
||||
}
|
||||
}
|
||||
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)
|
||||
|
@ -570,7 +570,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
|
||||
if (lock_type != TL_WRITE_DELAYED && !thd->prelocked_mode)
|
||||
table->file->ha_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)));
|
||||
@ -712,7 +712,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
|
||||
}
|
||||
}
|
||||
if (!transactional_table)
|
||||
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
|
||||
thd->no_trans_update.all= TRUE;
|
||||
}
|
||||
}
|
||||
if (transactional_table)
|
||||
@ -1120,7 +1120,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
|
||||
@ -1323,7 +1323,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))
|
||||
@ -1364,7 +1364,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:
|
||||
@ -2637,7 +2637,7 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
|
||||
if (info.handle_duplicates == DUP_REPLACE &&
|
||||
(!table->triggers || !table->triggers->has_delete_triggers()))
|
||||
table->file->extra(HA_EXTRA_WRITE_CAN_REPLACE);
|
||||
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 |
|
||||
@ -2818,7 +2818,7 @@ void select_insert::send_error(uint errcode,const char *err)
|
||||
table->file->has_transactions(), FALSE);
|
||||
if (!thd->current_stmt_binlog_row_based && !table->s->tmp_table &&
|
||||
!can_rollback_data())
|
||||
thd->options|= OPTION_STATUS_NO_TRANS_UPDATE;
|
||||
thd->no_trans_update.all= TRUE;
|
||||
query_cache_invalidate3(thd, table, 1);
|
||||
}
|
||||
}
|
||||
@ -2859,7 +2859,7 @@ bool select_insert::send_eof()
|
||||
*/
|
||||
if (!trans_table &&
|
||||
(!table->s->tmp_table || !thd->current_stmt_binlog_row_based))
|
||||
thd->options|= OPTION_STATUS_NO_TRANS_UPDATE;
|
||||
thd->no_trans_update.all= TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3166,7 +3166,7 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
|
||||
table->file->extra(HA_EXTRA_WRITE_CAN_REPLACE);
|
||||
if (!thd->prelocked_mode)
|
||||
table->file->ha_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 |
|
||||
|
@ -376,7 +376,7 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
|
||||
table->file->ha_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 |
|
||||
@ -470,7 +470,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())
|
||||
{
|
||||
@ -552,7 +552,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;
|
||||
@ -580,7 +580,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);
|
||||
/*
|
||||
@ -646,7 +646,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;
|
||||
|
||||
/*
|
||||
We don't need to reset auto-increment field since we are restoring
|
||||
@ -681,12 +681,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())
|
||||
{
|
||||
@ -822,7 +822,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)
|
||||
|
@ -119,8 +119,8 @@ bool end_active_trans(THD *thd)
|
||||
if (ha_commit(thd))
|
||||
error=1;
|
||||
}
|
||||
thd->options&= ~(OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE |
|
||||
OPTION_KEEP_LOG);
|
||||
thd->options&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
|
||||
thd->no_trans_update.all= FALSE;
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
@ -546,8 +546,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 |
|
||||
OPTION_KEEP_LOG);
|
||||
thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_KEEP_LOG);
|
||||
thd->no_trans_update.all= FALSE;
|
||||
break;
|
||||
case COMMIT_RELEASE:
|
||||
do_release= 1; /* fall through */
|
||||
@ -564,8 +564,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 |
|
||||
OPTION_KEEP_LOG);
|
||||
thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_KEEP_LOG);
|
||||
thd->no_trans_update.all= FALSE;
|
||||
if (!res && (completion == ROLLBACK_AND_CHAIN))
|
||||
res= begin_trans(thd);
|
||||
break;
|
||||
@ -720,7 +720,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
||||
&LOCK_status);
|
||||
thd->convert_string(&tmp, system_charset_info,
|
||||
packet, packet_length-1, thd->charset());
|
||||
if (!mysql_change_db(thd, tmp.str, FALSE))
|
||||
if (!mysql_change_db(thd, &tmp, FALSE))
|
||||
{
|
||||
general_log_print(thd, command, "%s",thd->db);
|
||||
send_ok(thd);
|
||||
@ -961,7 +961,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
||||
packet= arg_end + 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)
|
||||
@ -2844,7 +2844,7 @@ end_with_restore_list:
|
||||
we silently add IF EXISTS if TEMPORARY was used.
|
||||
*/
|
||||
if (thd->slave_thread)
|
||||
lex->drop_if_exists= 1;
|
||||
lex->drop_if_exists= 1;
|
||||
|
||||
/* So that DROP TEMPORARY TABLE gets to binlog at commit/rollback */
|
||||
thd->options|= OPTION_KEEP_LOG;
|
||||
@ -2901,9 +2901,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:
|
||||
{
|
||||
@ -3566,9 +3571,8 @@ end_with_restore_list:
|
||||
res= TRUE; // cannot happen
|
||||
else
|
||||
{
|
||||
if ((thd->options &
|
||||
(OPTION_STATUS_NO_TRANS_UPDATE | OPTION_KEEP_LOG)) &&
|
||||
!thd->slave_thread)
|
||||
if ((thd->options & OPTION_KEEP_LOG) &&
|
||||
thd->no_trans_update.all && !thd->slave_thread)
|
||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
ER_WARNING_NOT_COMPLETE_ROLLBACK,
|
||||
ER(ER_WARNING_NOT_COMPLETE_ROLLBACK));
|
||||
@ -4139,9 +4143,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 & ~(OPTION_STATUS_NO_TRANS_UPDATE |
|
||||
OPTION_KEEP_LOG)) |
|
||||
OPTION_BEGIN);
|
||||
thd->options= ((thd->options & ~(OPTION_KEEP_LOG)) | OPTION_BEGIN);
|
||||
thd->no_trans_update.all= FALSE;
|
||||
thd->server_status|= SERVER_STATUS_IN_TRANS;
|
||||
send_ok(thd);
|
||||
break;
|
||||
@ -4234,8 +4237,8 @@ create_sp_error:
|
||||
xa_state_names[thd->transaction.xid_state.xa_state]);
|
||||
break;
|
||||
}
|
||||
thd->options&= ~(OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE |
|
||||
OPTION_KEEP_LOG);
|
||||
thd->options&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
|
||||
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;
|
||||
@ -4265,8 +4268,8 @@ create_sp_error:
|
||||
my_error(ER_XAER_RMERR, MYF(0));
|
||||
else
|
||||
send_ok(thd);
|
||||
thd->options&= ~(OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE |
|
||||
OPTION_KEEP_LOG);
|
||||
thd->options&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
|
||||
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;
|
||||
@ -4773,7 +4776,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;
|
||||
}
|
||||
/*
|
||||
@ -5061,8 +5064,10 @@ void mysql_reset_thd_for_next_command(THD *thd)
|
||||
in ha_rollback_trans() about some tables couldn't be rolled back.
|
||||
*/
|
||||
if (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
|
||||
thd->options&= ~(OPTION_STATUS_NO_TRANS_UPDATE | OPTION_KEEP_LOG);
|
||||
|
||||
{
|
||||
thd->options&= ~OPTION_KEEP_LOG;
|
||||
thd->no_trans_update.all= FALSE;
|
||||
}
|
||||
DBUG_ASSERT(thd->security_ctx== &thd->main_security_ctx);
|
||||
thd->tmp_table_used= 0;
|
||||
if (!thd->in_sub_stmt)
|
||||
@ -5562,7 +5567,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 ||
|
||||
@ -5570,7 +5575,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
|
||||
(sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND) == 0))
|
||||
{
|
||||
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;
|
||||
|
@ -1670,7 +1670,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();
|
||||
|
@ -715,9 +715,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
|
||||
@ -2197,7 +2197,7 @@ LEX_STRING *make_lex_string(THD *thd, LEX_STRING *lex_str,
|
||||
|
||||
|
||||
/* INFORMATION_SCHEMA name */
|
||||
LEX_STRING information_schema_name= { C_STRING_WITH_LEN("information_schema")};
|
||||
LEX_STRING INFORMATION_SCHEMA_NAME= { C_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[];
|
||||
@ -2413,11 +2413,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,
|
||||
@ -2431,11 +2431,11 @@ int make_db_list(THD *thd, List<char> *files,
|
||||
*/
|
||||
if (sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND)
|
||||
{
|
||||
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));
|
||||
}
|
||||
@ -2444,7 +2444,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,
|
||||
@ -5048,8 +5048,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 */
|
||||
|
@ -6751,7 +6751,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));
|
||||
|
@ -447,7 +447,7 @@ int mysql_update(THD *thd,
|
||||
thd->proc_info="Updating";
|
||||
|
||||
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,
|
||||
if (fill_record_n_invoke_before_triggers(thd, fields, values, 0,
|
||||
table->triggers,
|
||||
TRG_EVENT_UPDATE))
|
||||
break; /* purecov: inspected */
|
||||
break; /* purecov: inspected */
|
||||
|
||||
found++;
|
||||
|
||||
@ -535,7 +535,7 @@ int mysql_update(THD *thd,
|
||||
if (!error)
|
||||
{
|
||||
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,
|
||||
@ -661,11 +661,11 @@ int mysql_update(THD *thd,
|
||||
transactional_table, FALSE) &&
|
||||
transactional_table)
|
||||
{
|
||||
error=1; // Rollback update
|
||||
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)
|
||||
@ -1030,7 +1030,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));
|
||||
@ -1344,7 +1344,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;
|
||||
}
|
||||
|
||||
|
||||
@ -1405,40 +1405,40 @@ bool multi_update::send_data(List<Item> ¬_used_values)
|
||||
else if (error == VIEW_CHECK_ERROR)
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
if (!updated++)
|
||||
{
|
||||
/*
|
||||
Inform the main table that we are going to update the table even
|
||||
while we may be scanning it. This will flush the read cache
|
||||
if it's used.
|
||||
*/
|
||||
main_table->file->extra(HA_EXTRA_PREPARE_FOR_UPDATE);
|
||||
}
|
||||
if ((error=table->file->ha_update_row(table->record[1],
|
||||
table->record[0])))
|
||||
{
|
||||
updated--;
|
||||
if (!updated++)
|
||||
{
|
||||
/*
|
||||
Inform the main table that we are going to update the table even
|
||||
while we may be scanning it. This will flush the read cache
|
||||
if it's used.
|
||||
*/
|
||||
main_table->file->extra(HA_EXTRA_PREPARE_FOR_UPDATE);
|
||||
}
|
||||
if ((error=table->file->ha_update_row(table->record[1],
|
||||
table->record[0])))
|
||||
{
|
||||
updated--;
|
||||
if (!ignore ||
|
||||
table->file->is_fatal_error(error, HA_CHECK_DUP_KEY))
|
||||
{
|
||||
{
|
||||
/*
|
||||
If (ignore && error == is ignorable) we don't have to
|
||||
do anything; otherwise...
|
||||
*/
|
||||
if (table->file->is_fatal_error(error, HA_CHECK_DUP_KEY))
|
||||
thd->fatal_error(); /* Other handler errors are fatal */
|
||||
table->file->print_error(error,MYF(0));
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
}
|
||||
table->file->print_error(error,MYF(0));
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
}
|
||||
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))
|
||||
DBUG_RETURN(1);
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1674,7 +1674,7 @@ bool multi_update::send_eof()
|
||||
}
|
||||
}
|
||||
if (!transactional_tables)
|
||||
thd->options|=OPTION_STATUS_NO_TRANS_UPDATE;
|
||||
thd->no_trans_update.all= TRUE;
|
||||
}
|
||||
|
||||
if (transactional_tables)
|
||||
|
@ -496,35 +496,46 @@ 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
|
||||
|
Loading…
x
Reference in New Issue
Block a user