summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/mysqlbinlog.cc12
-rw-r--r--mysql-test/r/grant3.result38
-rw-r--r--mysql-test/r/myisam_crash_before_flush_keys.result28
-rw-r--r--mysql-test/r/sp.result45
-rw-r--r--mysql-test/t/grant3.test35
-rw-r--r--mysql-test/t/myisam_crash_before_flush_keys.test12
-rw-r--r--mysql-test/t/sp.test46
-rw-r--r--sql/sql_acl.cc46
-rw-r--r--sql/sql_yacc.yy61
-rw-r--r--strings/ctype-uca.c3
10 files changed, 258 insertions, 68 deletions
diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc
index ebe34231238..4652b27639b 100644
--- a/client/mysqlbinlog.cc
+++ b/client/mysqlbinlog.cc
@@ -992,13 +992,11 @@ static struct my_option my_long_options[] =
/* 'unspec' is not mentioned because it is just a placeholder. */
"Determine when the output statements should be base64-encoded BINLOG "
"statements: 'never' disables it and works only for binlogs without "
- "row-based events; 'auto' is the default and prints base64 only when "
- "necessary (i.e., for row-based events and format description events); "
- "'decode-rows' suppresses BINLOG statements for row events, but does "
- "not exit as an error if a row event is found, unlike 'never'; "
- "'always' prints base64 whenever possible. 'always' is for debugging "
- "only and should not be used in a production system. The default is "
- "'auto'. --base64-output is a short form for --base64-output=always."
+ "row-based events; 'auto' prints base64 only when necessary (i.e., "
+ "for row-based events and format description events); 'always' prints "
+ "base64 whenever possible. 'always' is for debugging only and should "
+ "not be used in a production system. If this argument is not given, "
+ "the default is 'auto'; if it is given with no argument, 'always' is used."
,(uchar**) &opt_base64_output_mode_str,
(uchar**) &opt_base64_output_mode_str,
0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
diff --git a/mysql-test/r/grant3.result b/mysql-test/r/grant3.result
index f38848111ad..59c64ee84ae 100644
--- a/mysql-test/r/grant3.result
+++ b/mysql-test/r/grant3.result
@@ -154,4 +154,42 @@ SELECT * FROM mysqltest_1.t1;
a
DROP USER 'mysqltest1'@'%';
DROP DATABASE mysqltest_1;
+#
+# Bug#41597 - After rename of user, there are additional grants
+# when grants are reapplied.
+#
+CREATE DATABASE temp;
+CREATE TABLE temp.t1(a INT, b VARCHAR(10));
+INSERT INTO temp.t1 VALUES(1, 'name1');
+INSERT INTO temp.t1 VALUES(2, 'name2');
+INSERT INTO temp.t1 VALUES(3, 'name3');
+CREATE USER 'user1'@'%';
+RENAME USER 'user1'@'%' TO 'user2'@'%';
+# Show privileges after rename and BEFORE grant
+SHOW GRANTS FOR 'user2'@'%';
+Grants for user2@%
+GRANT USAGE ON *.* TO 'user2'@'%'
+GRANT SELECT (a), INSERT (b) ON `temp`.`t1` TO 'user2'@'%';
+# Show privileges after rename and grant
+SHOW GRANTS FOR 'user2'@'%';
+Grants for user2@%
+GRANT USAGE ON *.* TO 'user2'@'%'
+GRANT SELECT (a), INSERT (b) ON `temp`.`t1` TO 'user2'@'%'
+# Connect as the renamed user
+SHOW GRANTS;
+Grants for user2@%
+GRANT USAGE ON *.* TO 'user2'@'%'
+GRANT SELECT (a), INSERT (b) ON `temp`.`t1` TO 'user2'@'%'
+SELECT a FROM temp.t1;
+a
+1
+2
+3
+# Check for additional privileges by accessing a
+# non privileged column. We shouldn't be able to
+# access this column.
+SELECT b FROM temp.t1;
+ERROR 42000: SELECT command denied to user 'user2'@'localhost' for column 'b' in table 't1'
+DROP USER 'user2'@'%';
+DROP DATABASE temp;
End of 5.0 tests
diff --git a/mysql-test/r/myisam_crash_before_flush_keys.result b/mysql-test/r/myisam_crash_before_flush_keys.result
index 372f2e41590..d3545ea47d0 100644
--- a/mysql-test/r/myisam_crash_before_flush_keys.result
+++ b/mysql-test/r/myisam_crash_before_flush_keys.result
@@ -15,31 +15,13 @@ SET SESSION debug="d,crash_before_flush_keys";
# Run the crashing query
FLUSH TABLE t1;
ERROR HY000: Lost connection to MySQL server during query
-# Run MYISAMCHK tool to check the table t1 and repair
-myisamchk: MyISAM file MYSQLD_DATADIR/test/t1
-myisamchk: warning: 1 client is using or hasn't closed the table properly
-myisamchk: error: Size of indexfile is: 1024 Should be: 3072
-MYISAMCHK: Unknown error 126
-myisamchk: error: Can't read indexpage from filepos: 1024
-MyISAM-table 'MYSQLD_DATADIR/test/t1' is corrupted
-Fix it using switch "-r" or "-o"
# Write file to make mysql-test-run.pl start the server
# Turn on reconnect
# Call script that will poll the server waiting for
# it to be back online again
-SHOW CREATE TABLE t1;
-Table Create Table
-t1 CREATE TABLE `t1` (
- `a` int(11) NOT NULL DEFAULT '0',
- `b` int(11) NOT NULL DEFAULT '0',
- PRIMARY KEY (`a`,`b`),
- KEY `b` (`b`)
-) ENGINE=MyISAM DEFAULT CHARSET=latin1 DELAY_KEY_WRITE=1
-SELECT * FROM t1 FORCE INDEX (PRIMARY);
-a b
-1 2
-2 3
-3 4
-4 5
-5 6
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check warning 1 client is using or hasn't closed the table properly
+test.t1 check error Size of indexfile is: 1024 Should be: 3072
+test.t1 check error Corrupt
DROP TABLE t1;
diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result
index 67514c314f4..752edf8db41 100644
--- a/mysql-test/r/sp.result
+++ b/mysql-test/r/sp.result
@@ -6979,6 +6979,51 @@ CALL p1;
ERROR 42S22: Unknown column 'A.b' in 'IN/ALL/ANY subquery'
DROP PROCEDURE p1;
DROP TABLE t1, t2;
+#
+# Bug47627 SET @@{global.session}.local_variable in stored routine causes crash
+#
+DROP PROCEDURE IF EXISTS p1;
+DROP PROCEDURE IF EXISTS p2;
+DROP PROCEDURE IF EXISTS p3;
+CREATE PROCEDURE p1()
+BEGIN
+DECLARE v INT DEFAULT 0;
+SET @@session.v= 10;
+END//
+ERROR HY000: Unknown system variable 'v'
+CREATE PROCEDURE p2()
+BEGIN
+DECLARE v INT DEFAULT 0;
+SET v= 10;
+END//
+call p2()//
+CREATE PROCEDURE p3()
+BEGIN
+DECLARE v INT DEFAULT 0;
+SELECT @@session.v;
+END//
+ERROR HY000: Unknown system variable 'v'
+CREATE PROCEDURE p4()
+BEGIN
+DECLARE v INT DEFAULT 0;
+SET @@global.v= 10;
+END//
+ERROR HY000: Unknown system variable 'v'
+CREATE PROCEDURE p5()
+BEGIN
+DECLARE v INT DEFAULT 0;
+SET @@global.query_cache_size= 0;
+SET @@session.identity= 1;
+SELECT @@session.identity;
+SELECT @@global.query_cache_size;
+END//
+CALL p5();
+@@session.identity
+1
+@@global.query_cache_size
+0
+DROP PROCEDURE p2;
+DROP PROCEDURE p5;
# ------------------------------------------------------------------
# -- End of 5.1 tests
# ------------------------------------------------------------------
diff --git a/mysql-test/t/grant3.test b/mysql-test/t/grant3.test
index 9a635048774..437fc9a278f 100644
--- a/mysql-test/t/grant3.test
+++ b/mysql-test/t/grant3.test
@@ -163,6 +163,41 @@ connection default;
DROP USER 'mysqltest1'@'%';
DROP DATABASE mysqltest_1;
+--echo #
+--echo # Bug#41597 - After rename of user, there are additional grants
+--echo # when grants are reapplied.
+--echo #
+
+CREATE DATABASE temp;
+CREATE TABLE temp.t1(a INT, b VARCHAR(10));
+INSERT INTO temp.t1 VALUES(1, 'name1');
+INSERT INTO temp.t1 VALUES(2, 'name2');
+INSERT INTO temp.t1 VALUES(3, 'name3');
+
+
+CREATE USER 'user1'@'%';
+RENAME USER 'user1'@'%' TO 'user2'@'%';
+--echo # Show privileges after rename and BEFORE grant
+SHOW GRANTS FOR 'user2'@'%';
+GRANT SELECT (a), INSERT (b) ON `temp`.`t1` TO 'user2'@'%';
+--echo # Show privileges after rename and grant
+SHOW GRANTS FOR 'user2'@'%';
+
+--echo # Connect as the renamed user
+connect (conn1, localhost, user2,,);
+connection conn1;
+SHOW GRANTS;
+SELECT a FROM temp.t1;
+--echo # Check for additional privileges by accessing a
+--echo # non privileged column. We shouldn't be able to
+--echo # access this column.
+--error ER_COLUMNACCESS_DENIED_ERROR
+SELECT b FROM temp.t1;
+disconnect conn1;
+
+connection default;
+DROP USER 'user2'@'%';
+DROP DATABASE temp;
--echo End of 5.0 tests
diff --git a/mysql-test/t/myisam_crash_before_flush_keys.test b/mysql-test/t/myisam_crash_before_flush_keys.test
index d6559f7760d..1860ddd27e3 100644
--- a/mysql-test/t/myisam_crash_before_flush_keys.test
+++ b/mysql-test/t/myisam_crash_before_flush_keys.test
@@ -26,12 +26,6 @@ SET SESSION debug="d,crash_before_flush_keys";
--error 2013
FLUSH TABLE t1;
---echo # Run MYISAMCHK tool to check the table t1 and repair
---replace_result $MYISAMCHK MYISAMCHK $MYSQLD_DATADIR MYSQLD_DATADIR
---error 255
---exec $MYISAMCHK -cs $MYSQLD_DATADIR/test/t1 2>&1
---exec $MYISAMCHK -rs $MYSQLD_DATADIR/test/t1
-
--echo # Write file to make mysql-test-run.pl start the server
--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
@@ -42,8 +36,6 @@ FLUSH TABLE t1;
--echo # it to be back online again
--source include/wait_until_connected_again.inc
-SHOW CREATE TABLE t1;
-
-SELECT * FROM t1 FORCE INDEX (PRIMARY);
-
+# Must report that the table wasn't closed properly
+CHECK TABLE t1;
DROP TABLE t1;
diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test
index 44c4556340e..328dde4b26f 100644
--- a/mysql-test/t/sp.test
+++ b/mysql-test/t/sp.test
@@ -8263,7 +8263,51 @@ CALL p1;
DROP PROCEDURE p1;
DROP TABLE t1, t2;
-
+--echo #
+--echo # Bug47627 SET @@{global.session}.local_variable in stored routine causes crash
+--echo #
+--disable_warnings
+DROP PROCEDURE IF EXISTS p1;
+DROP PROCEDURE IF EXISTS p2;
+DROP PROCEDURE IF EXISTS p3;
+--enable_warnings
+delimiter //;
+--error ER_UNKNOWN_SYSTEM_VARIABLE
+CREATE PROCEDURE p1()
+BEGIN
+ DECLARE v INT DEFAULT 0;
+ SET @@session.v= 10;
+END//
+CREATE PROCEDURE p2()
+BEGIN
+ DECLARE v INT DEFAULT 0;
+ SET v= 10;
+END//
+call p2()//
+--error ER_UNKNOWN_SYSTEM_VARIABLE
+CREATE PROCEDURE p3()
+BEGIN
+ DECLARE v INT DEFAULT 0;
+ SELECT @@session.v;
+END//
+--error ER_UNKNOWN_SYSTEM_VARIABLE
+CREATE PROCEDURE p4()
+BEGIN
+ DECLARE v INT DEFAULT 0;
+ SET @@global.v= 10;
+END//
+CREATE PROCEDURE p5()
+BEGIN
+ DECLARE v INT DEFAULT 0;
+ SET @@global.query_cache_size= 0;
+ SET @@session.identity= 1;
+ SELECT @@session.identity;
+ SELECT @@global.query_cache_size;
+END//
+delimiter ;//
+CALL p5();
+DROP PROCEDURE p2;
+DROP PROCEDURE p5;
--echo # ------------------------------------------------------------------
--echo # -- End of 5.1 tests
--echo # ------------------------------------------------------------------
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 6ebdae49bd4..35047ca7407 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -2255,6 +2255,8 @@ public:
GRANT_NAME (TABLE *form);
virtual ~GRANT_NAME() {};
virtual bool ok() { return privs != 0; }
+ void set_user_details(const char *h, const char *d,
+ const char *u, const char *t);
};
@@ -2272,27 +2274,36 @@ public:
};
-
-GRANT_NAME::GRANT_NAME(const char *h, const char *d,const char *u,
- const char *t, ulong p)
- :privs(p)
+void GRANT_NAME::set_user_details(const char *h, const char *d,
+ const char *u, const char *t)
{
/* Host given by user */
update_hostname(&host, strdup_root(&memex, h));
- db = strdup_root(&memex,d);
+ if (db != d)
+ {
+ db= strdup_root(&memex, d);
+ if (lower_case_table_names)
+ my_casedn_str(files_charset_info, db);
+ }
user = strdup_root(&memex,u);
sort= get_sort(3,host.hostname,db,user);
- tname= strdup_root(&memex,t);
- if (lower_case_table_names)
+ if (tname != t)
{
- my_casedn_str(files_charset_info, db);
- my_casedn_str(files_charset_info, tname);
+ tname= strdup_root(&memex, t);
+ if (lower_case_table_names)
+ my_casedn_str(files_charset_info, tname);
}
key_length= strlen(d) + strlen(u)+ strlen(t)+3;
hash_key= (char*) alloc_root(&memex,key_length);
strmov(strmov(strmov(hash_key,user)+1,db)+1,tname);
}
+GRANT_NAME::GRANT_NAME(const char *h, const char *d,const char *u,
+ const char *t, ulong p)
+ :db(0), tname(0), privs(p)
+{
+ set_user_details(h, d, u, t);
+}
GRANT_TABLE::GRANT_TABLE(const char *h, const char *d,const char *u,
const char *t, ulong p, ulong c)
@@ -5436,9 +5447,20 @@ static int handle_grant_struct(uint struct_no, bool drop,
case 2:
case 3:
- grant_name->user= strdup_root(&mem, user_to->user.str);
- update_hostname(&grant_name->host,
- strdup_root(&mem, user_to->host.str));
+ /*
+ Update the grant structure with the new user name and
+ host name
+ */
+ grant_name->set_user_details(user_to->host.str, grant_name->db,
+ user_to->user.str, grant_name->tname);
+
+ /*
+ Since username is part of the hash key, when the user name
+ is renamed, the hash key is changed. Update the hash to
+ ensure that the position matches the new hash key value
+ */
+ hash_update(&column_priv_hash, (uchar*) grant_name,
+ (uchar*) grant_name->hash_key, grant_name->key_length);
break;
}
}
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 37c583ad572..a837a10325b 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -11783,8 +11783,17 @@ option_type:
;
option_type2:
- /* empty */ { $$= OPT_DEFAULT; }
- | ONE_SHOT_SYM { Lex->one_shot_set= 1; $$= OPT_SESSION; }
+ /* empty */
+ {
+ $$= OPT_DEFAULT;
+ Lex->option_type= OPT_DEFAULT;
+ }
+ | ONE_SHOT_SYM
+ {
+ Lex->one_shot_set= 1;
+ $$= OPT_SESSION;
+ Lex->option_type= OPT_SESSION;
+ }
;
opt_var_type:
@@ -11795,10 +11804,26 @@ opt_var_type:
;
opt_var_ident_type:
- /* empty */ { $$=OPT_DEFAULT; }
- | GLOBAL_SYM '.' { $$=OPT_GLOBAL; }
- | LOCAL_SYM '.' { $$=OPT_SESSION; }
- | SESSION_SYM '.' { $$=OPT_SESSION; }
+ /* empty */
+ {
+ $$=OPT_DEFAULT;
+ Lex->option_type= OPT_DEFAULT;
+ }
+ | GLOBAL_SYM '.'
+ {
+ $$=OPT_GLOBAL;
+ Lex->option_type= OPT_GLOBAL;
+ }
+ | LOCAL_SYM '.'
+ {
+ $$=OPT_SESSION;
+ Lex->option_type= OPT_SESSION;
+ }
+ | SESSION_SYM '.'
+ {
+ $$=OPT_SESSION;
+ Lex->option_type= OPT_SESSION;
+ }
;
ext_option_value:
@@ -12038,8 +12063,22 @@ internal_variable_name:
sp_pcontext *spc= lex->spcont;
sp_variable_t *spv;
- /* We have to lookup here since local vars can shadow sysvars */
- if (!spc || !(spv = spc->find_variable(&$1)))
+ /*
+ We have to lookup here since local vars can shadow sysvars.
+
+ We also have to inspect the option_type first since the variable
+ identifier might have been prefixed with @@session or @@global
+ prefixes. Without this check we would wrongly identify them
+ as SP local variables.
+ */
+ if (lex->option_type == OPT_DEFAULT && spc &&
+ (spv= spc->find_variable(&$1)))
+ {
+ /* An SP local variable */
+ $$.var= NULL;
+ $$.base_name= $1;
+ }
+ else
{
/* Not an SP local variable */
sys_var *tmp=find_sys_var(thd, $1.str, $1.length);
@@ -12056,12 +12095,6 @@ internal_variable_name:
lex->sphead->m_flags|= sp_head::HAS_SET_AUTOCOMMIT_STMT;
}
}
- else
- {
- /* An SP local variable */
- $$.var= NULL;
- $$.base_name= $1;
- }
}
| ident '.' ident
{
diff --git a/strings/ctype-uca.c b/strings/ctype-uca.c
index 9fb18c0c472..6ae0cc3a293 100644
--- a/strings/ctype-uca.c
+++ b/strings/ctype-uca.c
@@ -7858,7 +7858,8 @@ static my_bool create_tailoring(CHARSET_INFO *cs, void *(*alloc)(size_t))
return 1;
}
- cs->caseinfo= my_unicase_default;
+ if (!cs->caseinfo)
+ cs->caseinfo= my_unicase_default;
if (!(newweights= (uint16**) (*alloc)(256*sizeof(uint16*))))
return 1;