Commit 7eb8c130 authored by jimw@mysql.com's avatar jimw@mysql.com

Merge

parents 613e09a9 3c700572
...@@ -19,6 +19,13 @@ BK_STATUS=$BK_STATUS$BK_COMMIT ...@@ -19,6 +19,13 @@ BK_STATUS=$BK_STATUS$BK_COMMIT
if [ "$BK_STATUS" = OK ] if [ "$BK_STATUS" = OK ]
then then
HAS_ACTUAL_CHANGES=`bk cset -r+ -d | grep -v "^#"`
if [ "$HAS_ACTUAL_CHANGES" = "" ]
then
echo ChangeSet had no real changes, not sending emails
exit
fi
CHANGESET=`bk -R prs -r+ -h -d':P:::I:' ChangeSet` CHANGESET=`bk -R prs -r+ -h -d':P:::I:' ChangeSet`
BUG=`bk -R prs -r+ -h -d':C:' ChangeSet | sed -ne 's/^.*[Bb][Uu][Gg] *# *\([0-9][0-9]*\).*$/\1/p'` BUG=`bk -R prs -r+ -h -d':C:' ChangeSet | sed -ne 's/^.*[Bb][Uu][Gg] *# *\([0-9][0-9]*\).*$/\1/p'`
WL=`bk -R prs -r+ -h -d':C:' ChangeSet | sed -ne 's/^.*[Ww][Ll] *# *\([0-9][0-9]*\).*$/ WL#\1/p'` WL=`bk -R prs -r+ -h -d':C:' ChangeSet | sed -ne 's/^.*[Ww][Ll] *# *\([0-9][0-9]*\).*$/ WL#\1/p'`
......
...@@ -311,7 +311,7 @@ rl_generic_bind (type, keyseq, data, map) ...@@ -311,7 +311,7 @@ rl_generic_bind (type, keyseq, data, map)
mapped to something, `abc' to be mapped to something else, mapped to something, `abc' to be mapped to something else,
and the function bound to `a' to be executed when the user and the function bound to `a' to be executed when the user
types `abx', leaving `bx' in the input queue. */ types `abx', leaving `bx' in the input queue. */
if (k.function /* && k.type == ISFUNC */) if (k.function && ((k.type == ISFUNC && k.function != rl_do_lowercase_version) || k.type == ISMACR))
{ {
map[ANYOTHERKEY] = k; map[ANYOTHERKEY] = k;
k.function = 0; k.function = 0;
......
...@@ -91,3 +91,7 @@ sjis_bin 6109 ...@@ -91,3 +91,7 @@ sjis_bin 6109
sjis_bin 61 sjis_bin 61
sjis_bin 6120 sjis_bin 6120
drop table t1; drop table t1;
SET NAMES sjis;
SELECT HEX('佐淘 \圭') FROM DUAL;
HEX('佐淘 \圭')
8DB2939181408C5C
...@@ -141,3 +141,21 @@ select * from T1; ...@@ -141,3 +141,21 @@ select * from T1;
a b a b
1 abc 1 abc
drop table T1; drop table T1;
create database mysqltest_LC2;
use mysqltest_LC2;
create table myUC (i int);
insert into myUC values (1),(2),(3);
select * from myUC;
i
1
2
3
use test;
drop database mysqltest_LC2;
create database mysqltest_LC2;
use mysqltest_LC2;
create table myUC (i int);
select * from myUC;
i
use test;
drop database mysqltest_LC2;
use mysql;
create database MYSQLtest;
grant all on MySQLtest.* to mysqltest_1@localhost;
show grants for mysqltest_1@localhost;
Grants for mysqltest_1@localhost
GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
GRANT ALL PRIVILEGES ON `mysqltest`.* TO 'mysqltest_1'@'localhost'
select * from db where user = 'mysqltest_1';
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
localhost mysqltest mysqltest_1 Y Y Y Y Y Y N Y Y Y Y Y
update db set db = 'MYSQLtest' where db = 'mysqltest' and user = 'mysqltest_1' and host = 'localhost';
flush privileges;
show grants for mysqltest_1@localhost;
Grants for mysqltest_1@localhost
GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost'
GRANT ALL PRIVILEGES ON `mysqltest`.* TO 'mysqltest_1'@'localhost'
select * from db where user = 'mysqltest_1';
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
localhost MYSQLtest mysqltest_1 Y Y Y Y Y Y N Y Y Y Y Y
delete from db where db = 'MYSQLtest' and user = 'mysqltest_1' and host = 'localhost';
flush privileges;
drop user mysqltest_1@localhost;
drop database MYSQLtest;
GRANT ALL ON test.* TO mysqltest_1@'127.0.0.1/255.255.255.255';
SHOW GRANTS FOR mysqltest_1@'127.0.0.1/255.255.255.255';
Grants for mysqltest_1@127.0.0.1/255.255.255.255
GRANT USAGE ON *.* TO 'mysqltest_1'@'127.0.0.1/255.255.255.255'
GRANT ALL PRIVILEGES ON `test`.* TO 'mysqltest_1'@'127.0.0.1/255.255.255.255'
REVOKE ALL ON test.* FROM mysqltest_1@'127.0.0.1/255.255.255.255';
DROP USER mysqltest_1@'127.0.0.1/255.255.255.255';
This diff is collapsed.
...@@ -515,3 +515,8 @@ SET GLOBAL MYISAM_DATA_POINTER_SIZE= 8; ...@@ -515,3 +515,8 @@ SET GLOBAL MYISAM_DATA_POINTER_SIZE= 8;
SHOW VARIABLES LIKE 'MYISAM_DATA_POINTER_SIZE'; SHOW VARIABLES LIKE 'MYISAM_DATA_POINTER_SIZE';
Variable_name Value Variable_name Value
myisam_data_pointer_size 8 myisam_data_pointer_size 8
SET GLOBAL table_cache=-1;
SHOW VARIABLES LIKE 'table_cache';
Variable_name Value
table_cache 1
SET GLOBAL table_cache=DEFAULT;
...@@ -68,3 +68,10 @@ SET collation_connection='sjis_japanese_ci'; ...@@ -68,3 +68,10 @@ SET collation_connection='sjis_japanese_ci';
-- source include/ctype_filesort.inc -- source include/ctype_filesort.inc
SET collation_connection='sjis_bin'; SET collation_connection='sjis_bin';
-- source include/ctype_filesort.inc -- source include/ctype_filesort.inc
# Check parsing of string literals in SJIS with multibyte characters that
# have an embedded \ in them. (Bug #8303)
--character_set sjis
SET NAMES sjis;
SELECT HEX('@\\') FROM DUAL;
...@@ -111,3 +111,20 @@ select * from T1; ...@@ -111,3 +111,20 @@ select * from T1;
alter table T1 add index (a); alter table T1 add index (a);
select * from T1; select * from T1;
drop table T1; drop table T1;
#
# Bug #8355: Tables not dropped from table cache on drop db
#
create database mysqltest_LC2;
use mysqltest_LC2;
create table myUC (i int);
insert into myUC values (1),(2),(3);
select * from myUC;
use test;
drop database mysqltest_LC2;
create database mysqltest_LC2;
use mysqltest_LC2;
create table myUC (i int);
select * from myUC;
use test;
drop database mysqltest_LC2;
# Test of grants when lower_case_table_names is on
use mysql;
# mixed-case database name for testing
create database MYSQLtest;
# check that database name gets forced to lowercase
grant all on MySQLtest.* to mysqltest_1@localhost;
show grants for mysqltest_1@localhost;
# now force it to mixed case, but see that it is lowercased in the acl cache
select * from db where user = 'mysqltest_1';
update db set db = 'MYSQLtest' where db = 'mysqltest' and user = 'mysqltest_1' and host = 'localhost';
flush privileges;
show grants for mysqltest_1@localhost;
select * from db where user = 'mysqltest_1';
# clear out the user we created
#
# can't use REVOKE because of the mixed-case database name
delete from db where db = 'MYSQLtest' and user = 'mysqltest_1' and host = 'localhost';
flush privileges;
drop user mysqltest_1@localhost;
drop database MYSQLtest;
# Bug #8471: IP address with mask fail when skip-name-resolve is on
GRANT ALL ON test.* TO mysqltest_1@'127.0.0.1/255.255.255.255';
SHOW GRANTS FOR mysqltest_1@'127.0.0.1/255.255.255.255';
REVOKE ALL ON test.* FROM mysqltest_1@'127.0.0.1/255.255.255.255';
DROP USER mysqltest_1@'127.0.0.1/255.255.255.255';
...@@ -380,3 +380,11 @@ drop table t1; ...@@ -380,3 +380,11 @@ drop table t1;
SET GLOBAL MYISAM_DATA_POINTER_SIZE= 8; SET GLOBAL MYISAM_DATA_POINTER_SIZE= 8;
SHOW VARIABLES LIKE 'MYISAM_DATA_POINTER_SIZE'; SHOW VARIABLES LIKE 'MYISAM_DATA_POINTER_SIZE';
#
# Bug #6958: negative arguments to integer options wrap around
#
SET GLOBAL table_cache=-1;
SHOW VARIABLES LIKE 'table_cache';
SET GLOBAL table_cache=DEFAULT;
...@@ -581,6 +581,23 @@ ulong escape_string_for_mysql(CHARSET_INFO *charset_info, char *to, ...@@ -581,6 +581,23 @@ ulong escape_string_for_mysql(CHARSET_INFO *charset_info, char *to,
from--; from--;
continue; continue;
} }
/*
If the next character appears to begin a multi-byte character, we
escape that first byte of that apparent multi-byte character. (The
character just looks like a multi-byte character -- if it were actually
a multi-byte character, it would have been passed through in the test
above.)
Without this check, we can create a problem by converting an invalid
multi-byte character into a valid one. For example, 0xbf27 is not
a valid GBK character, but 0xbf5c is. (0x27 = ', 0x5c = \)
*/
if (use_mb_flag && (l= my_mbcharlen(charset_info, *from)) > 1)
{
*to++= '\\';
*to++= *from;
continue;
}
#endif #endif
switch (*from) { switch (*from) {
case 0: /* Must be escaped for 'mysql' */ case 0: /* Must be escaped for 'mysql' */
......
This diff is collapsed.
This diff is collapsed.
...@@ -867,7 +867,7 @@ bool close_temporary_table(THD *thd, const char *db, const char *table_name); ...@@ -867,7 +867,7 @@ bool close_temporary_table(THD *thd, const char *db, const char *table_name);
void close_temporary(TABLE *table, bool delete_table=1); void close_temporary(TABLE *table, bool delete_table=1);
bool rename_temporary_table(THD* thd, TABLE *table, const char *new_db, bool rename_temporary_table(THD* thd, TABLE *table, const char *new_db,
const char *table_name); const char *table_name);
void remove_db_from_cache(const my_string db); void remove_db_from_cache(const char *db);
void flush_tables(); void flush_tables();
bool remove_table_from_cache(THD *thd, const char *db, const char *table, bool remove_table_from_cache(THD *thd, const char *db, const char *table,
bool return_if_owned_by_thd=0); bool return_if_owned_by_thd=0);
......
...@@ -1309,6 +1309,12 @@ static void fix_server_id(THD *thd, enum_var_type type) ...@@ -1309,6 +1309,12 @@ static void fix_server_id(THD *thd, enum_var_type type)
server_id_supplied = 1; server_id_supplied = 1;
} }
bool sys_var_long_ptr::check(THD *thd, set_var *var)
{
longlong v= var->value->val_int();
var->save_result.ulonglong_value= v < 0 ? 0 : v;
return 0;
}
bool sys_var_long_ptr::update(THD *thd, set_var *var) bool sys_var_long_ptr::update(THD *thd, set_var *var)
{ {
......
...@@ -87,6 +87,7 @@ public: ...@@ -87,6 +87,7 @@ public:
sys_var_long_ptr(const char *name_arg, ulong *value_ptr, sys_var_long_ptr(const char *name_arg, ulong *value_ptr,
sys_after_update_func func) sys_after_update_func func)
:sys_var(name_arg,func), value(value_ptr) {} :sys_var(name_arg,func), value(value_ptr) {}
bool check(THD *thd, set_var *var);
bool update(THD *thd, set_var *var); bool update(THD *thd, set_var *var);
void set_default(THD *thd, enum_var_type type); void set_default(THD *thd, enum_var_type type);
SHOW_TYPE type() { return SHOW_LONG; } SHOW_TYPE type() { return SHOW_LONG; }
......
...@@ -141,6 +141,8 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables) ...@@ -141,6 +141,8 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables)
MYSQL_LOCK *lock; MYSQL_LOCK *lock;
my_bool return_val=1; my_bool return_val=1;
bool check_no_resolve= specialflag & SPECIAL_NO_RESOLVE; bool check_no_resolve= specialflag & SPECIAL_NO_RESOLVE;
char tmp_name[NAME_LEN+1];
DBUG_ENTER("acl_init"); DBUG_ENTER("acl_init");
if (!acl_cache) if (!acl_cache)
...@@ -199,6 +201,24 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables) ...@@ -199,6 +201,24 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables)
ACL_HOST host; ACL_HOST host;
update_hostname(&host.host,get_field(&mem, table->field[0])); update_hostname(&host.host,get_field(&mem, table->field[0]));
host.db= get_field(&mem, table->field[1]); host.db= get_field(&mem, table->field[1]);
if (lower_case_table_names)
{
/*
We make a temporary copy of the database, force it to lower case,
and then copy it back over the original name. We can't just update
the host.db pointer, because tmp_name is allocated on the stack.
*/
(void)strmov(tmp_name, host.db);
my_casedn_str(files_charset_info, tmp_name);
if (strcmp(host.db, tmp_name) != 0)
{
sql_print_warning("'host' entry '%s|%s' had database in mixed "
"case that has been forced to lowercase because "
"lower_case_table_names is set.",
host.host.hostname, host.db);
(void)strmov(host.db, tmp_name);
}
}
host.access= get_access(table,2); host.access= get_access(table,2);
host.access= fix_rights_for_db(host.access); host.access= fix_rights_for_db(host.access);
host.sort= get_sort(2,host.host.hostname,host.db); host.sort= get_sort(2,host.host.hostname,host.db);
...@@ -409,6 +429,24 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables) ...@@ -409,6 +429,24 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables)
} }
db.access=get_access(table,3); db.access=get_access(table,3);
db.access=fix_rights_for_db(db.access); db.access=fix_rights_for_db(db.access);
if (lower_case_table_names)
{
/*
We make a temporary copy of the database, force it to lower case,
and then copy it back over the original name. We can't just update
the db.db pointer, because tmp_name is allocated on the stack.
*/
(void)strmov(tmp_name, db.db);
my_casedn_str(files_charset_info, tmp_name);
if (strcmp(db.db, tmp_name) != 0)
{
sql_print_warning("'db' entry '%s %s@%s' had database in mixed "
"case that has been forced to lowercase because "
"lower_case_table_names is set.",
db.db, db.user, db.host.hostname, db.host.hostname);
(void)strmov(db.db, tmp_name);
}
}
db.sort=get_sort(3,db.host.hostname,db.db,db.user); db.sort=get_sort(3,db.host.hostname,db.db,db.user);
#ifndef TO_BE_REMOVED #ifndef TO_BE_REMOVED
if (table->s->fields <= 9) if (table->s->fields <= 9)
...@@ -1447,7 +1485,7 @@ bool hostname_requires_resolving(const char *hostname) ...@@ -1447,7 +1485,7 @@ bool hostname_requires_resolving(const char *hostname)
return FALSE; return FALSE;
for (; (cur=*hostname); hostname++) for (; (cur=*hostname); hostname++)
{ {
if ((cur != '%') && (cur != '_') && (cur != '.') && if ((cur != '%') && (cur != '_') && (cur != '.') && (cur != '/') &&
((cur < '0') || (cur > '9'))) ((cur < '0') || (cur > '9')))
return TRUE; return TRUE;
} }
......
...@@ -3586,8 +3586,18 @@ static void mysql_rm_tmp_tables(void) ...@@ -3586,8 +3586,18 @@ static void mysql_rm_tmp_tables(void)
** and afterwards delete those marked unused. ** and afterwards delete those marked unused.
*/ */
void remove_db_from_cache(const my_string db) void remove_db_from_cache(const char *db)
{ {
char name_buff[NAME_LEN+1];
if (db && lower_case_table_names)
{
/*
convert database to lower case for comparision.
*/
strmake(name_buff, db, sizeof(name_buff)-1);
my_casedn_str(files_charset_info, name_buff);
db= name_buff;
}
for (uint idx=0 ; idx < open_cache.records ; idx++) for (uint idx=0 ; idx < open_cache.records ; idx++)
{ {
TABLE *table=(TABLE*) hash_element(&open_cache,idx); TABLE *table=(TABLE*) hash_element(&open_cache,idx);
......
...@@ -296,6 +296,17 @@ static char *get_text(LEX *lex) ...@@ -296,6 +296,17 @@ static char *get_text(LEX *lex)
found_escape=1; found_escape=1;
if (lex->ptr == lex->end_of_query) if (lex->ptr == lex->end_of_query)
return 0; return 0;
#ifdef USE_MB
int l;
if (use_mb(cs) &&
(l = my_ismbchar(cs,
(const char *)lex->ptr,
(const char *)lex->end_of_query))) {
lex->ptr += l;
continue;
}
else
#endif
yySkip(); yySkip();
} }
else if (c == sep) else if (c == sep)
...@@ -324,6 +335,10 @@ static char *get_text(LEX *lex) ...@@ -324,6 +335,10 @@ static char *get_text(LEX *lex)
else else
{ {
uchar *to; uchar *to;
/* Re-use found_escape for tracking state of escapes */
found_escape= 0;
for (to=start ; str != end ; str++) for (to=start ; str != end ; str++)
{ {
#ifdef USE_MB #ifdef USE_MB
...@@ -337,7 +352,8 @@ static char *get_text(LEX *lex) ...@@ -337,7 +352,8 @@ static char *get_text(LEX *lex)
continue; continue;
} }
#endif #endif
if (!(lex->thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES) && if (!found_escape &&
!(lex->thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES) &&
*str == '\\' && str+1 != end) *str == '\\' && str+1 != end)
{ {
switch(*++str) { switch(*++str) {
...@@ -364,15 +380,20 @@ static char *get_text(LEX *lex) ...@@ -364,15 +380,20 @@ static char *get_text(LEX *lex)
*to++= '\\'; // remember prefix for wildcard *to++= '\\'; // remember prefix for wildcard
/* Fall through */ /* Fall through */
default: default:
*to++ = *str; found_escape= 1;
str--;
break; break;
} }
} }
else if (*str == sep) else if (!found_escape && *str == sep)
*to++= *str++; // Two ' or " {
found_escape= 1;
}
else else
{
*to++ = *str; *to++ = *str;
found_escape= 0;
}
} }
*to=0; *to=0;
lex->yytoklen=(uint) (to-start); lex->yytoklen=(uint) (to-start);
......
...@@ -12584,6 +12584,54 @@ static void test_bug7990() ...@@ -12584,6 +12584,54 @@ static void test_bug7990()
} }
/*
Test mysql_real_escape_string() with gbk charset
The important part is that 0x27 (') is the second-byte in a invalid
two-byte GBK character here. But 0xbf5c is a valid GBK character, so
it needs to be escaped as 0x5cbf27
*/
#define TEST_BUG8378_IN "\xef\xbb\xbf\x27\xbf\x10"
#define TEST_BUG8378_OUT "\xef\xbb\x5c\xbf\x5c\x27\x5c\xbf\x10"
static void test_bug8378()
{
MYSQL *lmysql;
char out[9]; /* strlen(TEST_BUG8378)*2+1 */
int len;
myheader("test_bug8378");
if (!opt_silent)
fprintf(stdout, "\n Establishing a test connection ...");
if (!(lmysql= mysql_init(NULL)))
{
myerror("mysql_init() failed");
exit(1);
}
if (mysql_options(lmysql, MYSQL_SET_CHARSET_NAME, "gbk"))
{
myerror("mysql_options() failed");
exit(1);
}
if (!(mysql_real_connect(lmysql, opt_host, opt_user,
opt_password, current_db, opt_port,
opt_unix_socket, 0)))
{
myerror("connection failed");
exit(1);
}
if (!opt_silent)
fprintf(stdout, " OK");
len= mysql_real_escape_string(lmysql, out, TEST_BUG8378_IN, 4);
/* No escaping should have actually happened. */
DIE_UNLESS(memcmp(out, TEST_BUG8378_OUT, len) == 0);
mysql_close(lmysql);
}
/* /*
Read and parse arguments and MySQL options from my.cnf Read and parse arguments and MySQL options from my.cnf
*/ */
...@@ -12804,6 +12852,7 @@ static struct my_tests_st my_tests[]= { ...@@ -12804,6 +12852,7 @@ static struct my_tests_st my_tests[]= {
{ "test_truncation_option", test_truncation_option }, { "test_truncation_option", test_truncation_option },
{ "test_bug8330", test_bug8330 }, { "test_bug8330", test_bug8330 },
{ "test_bug7990", test_bug7990 }, { "test_bug7990", test_bug7990 },
{ "test_bug8378", test_bug8378 },
{ 0, 0 } { 0, 0 }
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment