Below is the list of changes that have just been committed into a local
4.1 repository of igor. When igor does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet
1.2510 06/06/20 19:57:21 igor@stripped +3 -0
Fixed bug #16674.
The length of the prefix of the pattern string in the LIKE predicate that
determined the index range to be scanned was calculated incorrectly for
multi-byte character sets.
As a result of this in 4. 1 the the scanned range was wider then necessary
if the prefix contained not only one-byte characters.
In 5.0 additionally it caused missing some rows from the result set.
strings/ctype-mb.c
1.42 06/06/20 19:57:17 igor@stripped +16 -9
Fixed bug #16674.
The length of the prefix of the pattern string in the LIKE predicate that
determined the index range to be scanned was calculated incorrectly for
multi-byte character sets.
As a result of this in 4. 1 the the scanned range was wider then necessary
if the prefix contained not only one-byte characters.
In 5.0 additionally it caused missing some rows from the result set.
The function my_like_range_mb was fixed to calculate the length of
the prefix in a pattern string correctly in all cases.
mysql-test/t/ctype_utf8.test
1.72 06/06/20 19:57:17 igor@stripped +55 -0
Added test cases for bug #16674.
mysql-test/r/ctype_utf8.result
1.70 06/06/20 19:57:17 igor@stripped +67 -0
Added test cases for bug #16674.
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: igor
# Host: rurik.mysql.com
# Root: /home/igor/mysql-4.1-opt
--- 1.69/mysql-test/r/ctype_utf8.result 2006-03-29 14:50:50 -08:00
+++ 1.70/mysql-test/r/ctype_utf8.result 2006-06-20 19:57:17 -07:00
@@ -1124,3 +1124,70 @@
Table Op Msg_type Msg_text
test.t1 check status OK
drop table t1;
+SET NAMES utf8;
+CREATE TABLE t1 (
+a CHAR(13) DEFAULT '',
+INDEX(a)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
+INSERT INTO t1 VALUES
+('Käli Käli 2-4'), ('Käli Käli 2-4'),
+('Käli Käli 2+4'), ('Käli Käli 2+4'),
+('Käli Käli 2-6'), ('Käli Käli 2-6');
+CREATE TABLE t2 (
+a CHAR(13) DEFAULT '',
+INDEX(a)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
+INSERT INTO t2 VALUES
+('Kali Kali 2-4'), ('Kali Kali 2-4'),
+('Kali Kali 2+4'), ('Kali Kali 2+4'),
+('Kali Kali 2-6'), ('Kali Kali 2-6');
+SELECT a FROM t1 WHERE a LIKE 'Käli Käli 2+4';
+a
+Käli Käli 2+4
+Käli Käli 2+4
+SELECT a FROM t2 WHERE a LIKE 'Kali Kali 2+4';
+a
+Kali Kali 2+4
+Kali Kali 2+4
+EXPLAIN SELECT a FROM t1 WHERE a LIKE 'Käli Käli 2+4';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range a a 40 NULL 2 Using where; Using index
+EXPLAIN SELECT a FROM t1 WHERE a = 'Käli Käli 2+4';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ref a a 40 const 2 Using where; Using index
+EXPLAIN SELECT a FROM t2 WHERE a LIKE 'Kali Kali 2+4';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 range a a 14 NULL 2 Using where; Using index
+EXPLAIN SELECT a FROM t2 WHERE a = 'Kali Kali 2+4';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t2 ref a a 14 const 2 Using where; Using index
+DROP TABLE t1,t2;
+CREATE TABLE t1 (
+a char(255) DEFAULT '',
+KEY(a(10))
+) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
+INSERT INTO t1 VALUES ('Käli Käli 2-4');
+SELECT * FROM t1 WHERE a LIKE 'Käli Käli 2%';
+a
+Käli Käli 2-4
+INSERT INTO t1 VALUES ('Käli Käli 2-4');
+SELECT * FROM t1 WHERE a LIKE 'Käli Käli 2%';
+a
+Käli Käli 2-4
+Käli Käli 2-4
+DROP TABLE t1;
+CREATE TABLE t1 (
+a char(255) DEFAULT ''
+) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
+INSERT INTO t1 VALUES ('Käli Käli 2-4');
+INSERT INTO t1 VALUES ('Käli Käli 2-4');
+SELECT * FROM t1 WHERE a LIKE 'Käli Käli 2%';
+a
+Käli Käli 2-4
+Käli Käli 2-4
+ALTER TABLE t1 ADD KEY (a(10));
+SELECT * FROM t1 WHERE a LIKE 'Käli Käli 2%';
+a
+Käli Käli 2-4
+Käli Käli 2-4
+DROP TABLE t1;
--- 1.71/mysql-test/t/ctype_utf8.test 2006-03-29 14:50:50 -08:00
+++ 1.72/mysql-test/t/ctype_utf8.test 2006-06-20 19:57:17 -07:00
@@ -926,4 +926,59 @@
check table t1;
drop table t1;
+#
+# Bug#16674: LIKE predicate for a utf8 character set column
+#
+
+SET NAMES utf8;
+
+CREATE TABLE t1 (
+ a CHAR(13) DEFAULT '',
+ INDEX(a)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
+INSERT INTO t1 VALUES
+ ('Käli Käli 2-4'), ('Käli Käli 2-4'),
+ ('Käli Käli 2+4'), ('Käli Käli 2+4'),
+ ('Käli Käli 2-6'), ('Käli Käli 2-6');
+
+CREATE TABLE t2 (
+ a CHAR(13) DEFAULT '',
+ INDEX(a)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
+
+INSERT INTO t2 VALUES
+ ('Kali Kali 2-4'), ('Kali Kali 2-4'),
+ ('Kali Kali 2+4'), ('Kali Kali 2+4'),
+ ('Kali Kali 2-6'), ('Kali Kali 2-6');
+
+SELECT a FROM t1 WHERE a LIKE 'Käli Käli 2+4';
+SELECT a FROM t2 WHERE a LIKE 'Kali Kali 2+4';
+
+EXPLAIN SELECT a FROM t1 WHERE a LIKE 'Käli Käli 2+4';
+EXPLAIN SELECT a FROM t1 WHERE a = 'Käli Käli 2+4';
+EXPLAIN SELECT a FROM t2 WHERE a LIKE 'Kali Kali 2+4';
+EXPLAIN SELECT a FROM t2 WHERE a = 'Kali Kali 2+4';
+
+DROP TABLE t1,t2;
+
+CREATE TABLE t1 (
+ a char(255) DEFAULT '',
+ KEY(a(10))
+) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
+INSERT INTO t1 VALUES ('Käli Käli 2-4');
+SELECT * FROM t1 WHERE a LIKE 'Käli Käli 2%';
+INSERT INTO t1 VALUES ('Käli Käli 2-4');
+SELECT * FROM t1 WHERE a LIKE 'Käli Käli 2%';
+DROP TABLE t1;
+
+CREATE TABLE t1 (
+ a char(255) DEFAULT ''
+) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
+INSERT INTO t1 VALUES ('Käli Käli 2-4');
+INSERT INTO t1 VALUES ('Käli Käli 2-4');
+SELECT * FROM t1 WHERE a LIKE 'Käli Käli 2%';
+ALTER TABLE t1 ADD KEY (a(10));
+SELECT * FROM t1 WHERE a LIKE 'Käli Käli 2%';
+DROP TABLE t1;
+
# End of 4.1 tests
--- 1.41/strings/ctype-mb.c 2005-09-21 10:12:14 -07:00
+++ 1.42/strings/ctype-mb.c 2006-06-20 19:57:17 -07:00
@@ -502,21 +502,19 @@
char *min_str,char *max_str,
uint *min_length,uint *max_length)
{
+ uint mblen;
const char *end= ptr + ptr_length;
char *min_org= min_str;
char *min_end= min_str + res_length;
char *max_end= max_str + res_length;
- uint charlen= res_length / cs->mbmaxlen;
+ uint maxcharlen= res_length / cs->mbmaxlen;
- for (; ptr != end && min_str != min_end && charlen > 0 ; ptr++,
charlen--)
+ for (; ptr != end && min_str != min_end && maxcharlen ; maxcharlen--)
{
+ /* We assume here that escape, w_any, w_namy are one-byte characters */
if (*ptr == escape && ptr+1 != end)
- {
- ptr++; /* Skip escape */
- *min_str++= *max_str++ = *ptr;
- continue;
- }
- if (*ptr == w_one || *ptr == w_many) /* '_' and '%' in SQL */
+ ptr++; /* Skip escape */
+ else if (*ptr == w_one || *ptr == w_many) /* '_' and '%' in SQL */
{
/* Write min key */
*min_length= (uint) (min_str - min_org);
@@ -534,7 +532,16 @@
pad_max_char(cs, max_str, max_end);
return 0;
}
- *min_str++= *max_str++ = *ptr;
+ if ((mblen= my_ismbchar(cs, ptr, end)) > 1)
+ {
+ if (ptr+mblen > end || min_str+mblen > min_end)
+ break;
+ while (mblen--)
+ *min_str++= *max_str++= *ptr++;
+ }
+ else
+ *min_str++= *max_str++= *ptr++;
+
}
*min_length= *max_length = (uint) (min_str - min_org);
| Thread |
|---|
| • bk commit into 4.1 tree (igor:1.2510) BUG#16674 | igor | 21 Jun |