Hi Daogang,
Daogang Qu wrote:
> 2010-10-08 18:54, Alexander Barkov wrote:
>> Hi Daogang,
>>
>> Daogang Qu wrote:
>>> Hi Bar,
>>> Thanks for the review. See reply in-line.
>>> Please review:
>>> http://lists.mysql.com/commits/120340
>>>
>>> 2010-09-30 20:49, Alexander Barkov wrote:
>>>> Hi Daogang,
>>>>
>>>>
>>>> Daogang Qu wrote:
>>>>> Hi Bar,
>>>>> Please review the updated patch:
>>>>> http://lists.mysql.com/commits/118275
>>>>
>>>> my_strcasecmp() in these two chunks is not correct.
>>>>
>>>> @@ -167,8 +172,13 @@ Rpl_filter::db_ok(const char* db)
>>>>
>>>> while ((tmp=it++))
>>>> {
>>>> - if (!strcmp(tmp->ptr, db))
>>>> - DBUG_RETURN(1); // match
>>>> + /*
>>>> + Filters will follow the setting of lower_case_table_name
>>>> + to be case sensitive when setting lower_case_table_name=0.
>>>> + Otherwise they will be case insensitive.
>>>> + */
>>>> + if (!my_strcasecmp(table_alias_charset, tmp->ptr, db))
>>>> + DBUG_RETURN(1); // match
>>>> }
>>>> DBUG_RETURN(0);
>>>> }
>>>> @@ -179,8 +189,13 @@ Rpl_filter::db_ok(const char* db)
>>>>
>>>> while ((tmp=it++))
>>>> {
>>>> - if (!strcmp(tmp->ptr, db))
>>>> - DBUG_RETURN(0); // match
>>>> + /*
>>>> + Filters will follow the setting of lower_case_table_name
>>>> + to be case sensitive when setting lower_case_table_name=0.
>>>> + Otherwise they will be case insensitive.
>>>> + */
>>>> + if (!my_strcasecmp(table_alias_charset, tmp->ptr, db))
>>>> + DBUG_RETURN(0); // match
>>>> }
>>>> DBUG_RETURN(1);
>>>> }
>>>>
>>>> This comparison will always be case insensitive,
>>> No. It will be case sensitive when setting lower_case_table_name=0.
>>> The 'rpl_do_db_filter.test' will verify the point. Please check.
>>
>> I am sorry for confusion. You're right:
>> - In case of lower_case_table_names=0 it will
>> call my_strcasecmp_bin() which then calls strcmp(),
>> which is case sensitive.
>> - In case of lower_case_table_name=1 it will
>> call my_strcasecmp_utf8() which is case insensitive.
>> Everything is correct here.
>>
>> (last time I checked my_strcasecmp(&my_charset_utf8_bin,a,b)
>> instead of my_strcasecmp(&my_charset_bin,a,b)
>> in a mistake).
> No problem.
>>
>>
>>>
>>>> even if lower_case_table_name=0. This is not what we need.
>>>> You need to use my_strnncoll() instead.
>>>>
>>>>
>>>> Please also add a test covering this.
>>>> You need .opt file with these settings:
>>>>
>>>> --replicate-do-db=MYDB --lower-case-table-names=0
>>> Added in 'rpl_do_db_filter.test'
>>>>
>>>> This test will check that nothing is replicated,
>>>> because database name is "mydb" which is not equal to MYDB
>>>> when lower_case_table_name=0.
>>>>
>>>> Currently this combination is not covered.
>>>>
>>>>>
>>>>> Could you please add a test for testing new collation
>>>>> for supporting the case insensitive but accent sensitive?
>>>>
>>>> It will be very similar to how you test case sensitivity.
>>>> Just use some accented letters in db or table names in
>>>> SQL queries. For example,
>>>>
>>>> ý in database name: mýdb
>>>> ţ in table name: ţ1
>>>>
>>>> Use non-accented letters in .opt file.
>>>>
>>>> This is to make sure that filters recognize
>>>> that "mydb" and "mýdb" are different database names,
>>>> and that "t1" and "ţ1" are different table names.
>>>>
>>>> no matter what lower-case-table-name is.
>>> I tested the non-accented letters in rpl_do_table_filter-slave.opt file.
>>> But it didn't work as expected. The filters still will be case
>>> insensitive
>>> but non-accent sensitive when setting lower_case_table_name>0.
>>> Please double check the definition of 'my_charset_utf8_tolower_ci'.
>>> Thanks!
>>
>> The problem is likely that
>> my_strcasecmp_utf8('mydb', 'mýdb')
>> my_strcasecmpsp_utf8('mydb', 'mýdb')
>>
>> return TRUE for my_charset_utf8_tolower_ci for some reasons,
>> for the above strings, or get wrong parameters.
>> The idea is to set break-points in these functions and check.
>>
>> I'll compile your patch later, and write a separate letter.
I tested these functions and they seem to work fine.
I exposed utf8_tolower_ci to SQL level by adding this patch:
=== modified file 'mysys/charset-def.c'
--- mysys/charset-def.c 2010-07-08 10:57:38 +0000
+++ mysys/charset-def.c 2010-10-12 10:27:56 +0000
@@ -258,6 +258,7 @@ my_bool init_compiled_charsets(myf flags
#ifdef HAVE_CHARSET_utf8
add_compiled_collation(&my_charset_utf8_general_ci);
+ add_compiled_collation(&my_charset_utf8_tolower_ci);
add_compiled_collation(&my_charset_utf8_bin);
#ifdef HAVE_UTF8_GENERAL_CS
add_compiled_collation(&my_charset_utf8_general_cs);
Now I can use "COLLATE utf8_tolower_ci" in SQL syntax.
mysql> drop table if exists t1;
mysql> create table t1 (a varchar(16) character set utf8 collate
utf8_tolower_ci);
mysql> insert into t1 values
('mýdb'),('mydb'),('MYDB'),('MÝDB'),('ţ1'),('t1'),('T1'),('Ţ1');
-- make sure we get correct HEX utf8 values
mysql> select hex(a), a from t1;
+------------+-------+
| hex(a) | a |
+------------+-------+
| 6DC3BD6462 | mýdb |
| 6D796462 | mydb |
| 4D594442 | MYDB |
| 4DC39D4442 | MÝDB |
| C5A331 | ţ1 |
| 7431 | t1 |
| 5431 | T1 |
| C5A231 | Ţ1 |
+------------+-------+
8 rows in set (0.00 sec)
-- check GROUP BY is accent sensitive
mysql> select group_concat(a), count(*) from t1 group by a;
+-----------------+----------+
| group_concat(a) | count(*) |
+-----------------+----------+
| mydb,MYDB | 2 |
| mýdb,MÝDB | 2 |
| t1,T1 | 2 |
| ţ1,Ţ1 | 2 |
+-----------------+----------+
4 rows in set (0.00 sec)
-- check comparison is accent sensitive
mysql> select * from t1 where a='mydb';
+------+
| a |
+------+
| mydb |
| MYDB |
+------+
2 rows in set (0.00 sec)
-- check comparison is accent sensitive
mysql> select * from t1 where a='mýdb';
+-------+
| a |
+-------+
| mýdb |
| MÝDB |
+-------+
2 rows in set (0.00 sec)
So the collation code works as expected.
Now checking mtr --gdb.
>>
>> Is there a way to run slave under "gdb" in mysql-test?
>
> If './mtr rpl_do_table_filter --gdb' does not work, use --manual-gdb
> follow the following four steps:
>
> 1.
> ./mtr rpl_do_table_filter --mysqld=--log-bin=/var/tmp/masterdg-bin
> --record --manual-gdb --testcase-timeout=1000
>
> 2. open and rewrite var/tmp/gdbinit.mysqld.2
> vi var/tmp/gdbinit.mysqld.2
>
> Disable the break point in the file as following:
> set args --defaults-group-suffix=.1
>
> --defaults-file=/home/daogangqu/mysql/bzrwork/bug34739/mysql-5.1-bugteam/mysql-test/var/my.cnf
>
> --log-output=file --gdb --loose-skip-innodb
> --log-bin=/var/tmp/masterdg-bin --binlog-format=statement --core-file
> --loose-debug-sync-timeout=300
> #break mysql_parse
> #commands 1
> #disable 1
> #end
> #run
>
> 3. Run the following command copied from the result of first step.
> like this:
> libtool --mode execute gdb -cd
> /home/daogangqu/mysql/bzrwork/bug34739/mysql-5.1-bugteam/mysql-test -x
>
> /home/daogangqu/mysql/bzrwork/bug34739/mysql-5.1-bugteam/mysql-test/var/tmp/gdbinit.mysqld.1
>
> /home/daogangqu/mysql/bzrwork/bug34739/mysql-5.1-bugteam/sql/mysqld
>
> (libtool --mode execute) is added extra.
>
>
> 4. Set breakpoint and run it in gdb
>
> Best Regards,
>
> Daogang
>>
>>>
>>> Best Regards,
>>>
>>> Daogang
>>>>
>>>>
>>>>
>>>>>
>>>>> Best Regards,
>>>>>
>>>>> Daogang
>>>>>
>>>>
>>>
>>
>>
>