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:
unknown 2007-04-03 14:51:32 +03:00
commit fbd929f802
44 changed files with 1047 additions and 378 deletions

View File

@ -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:

View File

@ -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

View File

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

View File

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

View File

@ -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;

View File

@ -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()

View File

@ -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;

View File

@ -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

View File

@ -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

View File

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

View File

@ -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;

View File

@ -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
#

View File

@ -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.

View File

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

View File

@ -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)))

View File

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

View File

@ -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

View File

@ -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);

View File

@ -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)))

View File

@ -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,

View File

@ -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;
}

View File

@ -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;

View File

@ -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,

View File

@ -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 */

View File

@ -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:

View File

@ -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)
/*

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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",

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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();

View File

@ -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);

View File

@ -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.

View File

@ -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)

View File

@ -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 |

View File

@ -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)

View File

@ -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;

View File

@ -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();

View File

@ -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 */

View File

@ -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));

View File

@ -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> &not_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)

View File

@ -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