summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <holyfoot/hf@deer.(none)>2006-10-12 15:42:05 +0500
committerunknown <holyfoot/hf@deer.(none)>2006-10-12 15:42:05 +0500
commit89d5a1a541262b6902a636d4911eb9b48a2e476b (patch)
tree01f4bc3b8707f03ab053973132c8b7ccbcbe62a9
parent16f2de1df2e585182ed558b01dd0f3ed0d1ae549 (diff)
parentbac62fa32e2bb89613948205950f140b622ebd15 (diff)
downloadmariadb-git-89d5a1a541262b6902a636d4911eb9b48a2e476b.tar.gz
Merge mysql.com:/home/hf/mysql-5.0.mrg
into mysql.com:/home/hf/mysql-5.1.mrg include/m_ctype.h: Auto merged mysql-test/r/ctype_utf8.result: Auto merged mysql-test/r/type_enum.result: Auto merged mysql-test/t/ctype_utf8.test: Auto merged sql/item_func.cc: Auto merged sql/sql_select.cc: Auto merged sql/table.cc: Auto merged sql/unireg.cc: Auto merged strings/CHARSET_INFO.txt: Auto merged strings/ctype-mb.c: Auto merged strings/ctype-utf8.c: Auto merged
-rw-r--r--include/m_ctype.h4
-rw-r--r--mysql-test/r/ctype_utf8.result75
-rw-r--r--mysql-test/r/type_enum.result9
-rw-r--r--mysql-test/t/ctype_utf8.test70
-rw-r--r--mysql-test/t/type_enum.test9
-rw-r--r--sql/table.cc16
-rw-r--r--sql/unireg.cc15
-rw-r--r--strings/CHARSET_INFO.txt12
-rw-r--r--strings/ctype-mb.c32
-rw-r--r--strings/ctype-utf8.c2
10 files changed, 234 insertions, 10 deletions
diff --git a/include/m_ctype.h b/include/m_ctype.h
index c357f067358..5f946a3b443 100644
--- a/include/m_ctype.h
+++ b/include/m_ctype.h
@@ -120,6 +120,8 @@ enum my_lex_states
struct charset_info_st;
+
+/* See strings/CHARSET_INFO.txt for information about this structure */
typedef struct my_collation_handler_st
{
my_bool (*init)(struct charset_info_st *, void *(*alloc)(uint));
@@ -162,6 +164,7 @@ extern MY_COLLATION_HANDLER my_collation_8bit_simple_ci_handler;
extern MY_COLLATION_HANDLER my_collation_ucs2_uca_handler;
+/* See strings/CHARSET_INFO.txt about information on this structure */
typedef struct my_charset_handler_st
{
my_bool (*init)(struct charset_info_st *, void *(*alloc)(uint));
@@ -228,6 +231,7 @@ extern MY_CHARSET_HANDLER my_charset_8bit_handler;
extern MY_CHARSET_HANDLER my_charset_ucs2_handler;
+/* See strings/CHARSET_INFO.txt about information on this structure */
typedef struct charset_info_st
{
uint number;
diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result
index f3351a2973b..4ae19fc8f7c 100644
--- a/mysql-test/r/ctype_utf8.result
+++ b/mysql-test/r/ctype_utf8.result
@@ -1155,6 +1155,81 @@ check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
drop table t1;
+set names utf8;
+create table t1 (s1 char(5) character set utf8);
+insert into t1 values
+('a'),('b'),(null),('ペテルグル'),('ü'),('Y');
+create index it1 on t1 (s1);
+select s1 as before_delete_general_ci from t1 where s1 like 'ペテ%';
+before_delete_general_ci
+ペテルグル
+delete from t1 where s1 = 'Y';
+select s1 as after_delete_general_ci from t1 where s1 like 'ペテ%';
+after_delete_general_ci
+ペテルグル
+drop table t1;
+set names utf8;
+create table t1 (s1 char(5) character set utf8 collate utf8_unicode_ci);
+insert into t1 values
+('a'),('b'),(null),('ペテルグル'),('ü'),('Y');
+create index it1 on t1 (s1);
+select s1 as before_delete_unicode_ci from t1 where s1 like 'ペテ%';
+before_delete_unicode_ci
+ペテルグル
+delete from t1 where s1 = 'Y';
+select s1 as after_delete_unicode_ci from t1 where s1 like 'ペテ%';
+after_delete_unicode_ci
+ペテルグル
+drop table t1;
+set names utf8;
+create table t1 (s1 char(5) character set utf8 collate utf8_bin);
+insert into t1 values
+('a'),('b'),(null),('ペテルグル'),('ü'),('Y');
+create index it1 on t1 (s1);
+select s1 as before_delete_bin from t1 where s1 like 'ペテ%';
+before_delete_bin
+ペテルグル
+delete from t1 where s1 = 'Y';
+select s1 as after_delete_bin from t1 where s1 like 'ペテ%';
+after_delete_bin
+ペテルグル
+drop table t1;
+set names utf8;
+create table t1 (a varchar(30) not null primary key)
+engine=innodb default character set utf8 collate utf8_general_ci;
+insert into t1 values ('あいうえおかきくけこさしすせそ');
+insert into t1 values ('さしすせそかきくけこあいうえお');
+select a as gci1 from t1 where a like 'さしすせそかきくけこあいうえお%';
+gci1
+さしすせそかきくけこあいうえお
+select a as gci2 from t1 where a like 'あいうえおかきくけこさしすせそ';
+gci2
+あいうえおかきくけこさしすせそ
+drop table t1;
+set names utf8;
+create table t1 (a varchar(30) not null primary key)
+engine=innodb default character set utf8 collate utf8_unicode_ci;
+insert into t1 values ('あいうえおかきくけこさしすせそ');
+insert into t1 values ('さしすせそかきくけこあいうえお');
+select a as uci1 from t1 where a like 'さしすせそかきくけこあいうえお%';
+uci1
+さしすせそかきくけこあいうえお
+select a as uci2 from t1 where a like 'あいうえおかきくけこさしすせそ';
+uci2
+あいうえおかきくけこさしすせそ
+drop table t1;
+set names utf8;
+create table t1 (a varchar(30) not null primary key)
+engine=innodb default character set utf8 collate utf8_bin;
+insert into t1 values ('あいうえおかきくけこさしすせそ');
+insert into t1 values ('さしすせそかきくけこあいうえお');
+select a as bin1 from t1 where a like 'さしすせそかきくけこあいうえお%';
+bin1
+さしすせそかきくけこあいうえお
+select a as bin2 from t1 where a like 'あいうえおかきくけこさしすせそ';
+bin2
+あいうえおかきくけこさしすせそ
+drop table t1;
SET NAMES utf8;
CREATE TABLE t1 (id int PRIMARY KEY,
a varchar(16) collate utf8_unicode_ci NOT NULL default '',
diff --git a/mysql-test/r/type_enum.result b/mysql-test/r/type_enum.result
index 251af31249a..da913df4dd3 100644
--- a/mysql-test/r/type_enum.result
+++ b/mysql-test/r/type_enum.result
@@ -1745,3 +1745,12 @@ create table t1 (a set('x','y') default 'x');
alter table t1 alter a set default 'z';
ERROR 42000: Invalid default value for 'a'
drop table t1;
+create table t1 (f1 int);
+alter table t1 add f2 enum(0xFFFF);
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `f1` int(11) default NULL,
+ `f2` enum('') default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test
index ecf118dae59..7ee7c9d00cb 100644
--- a/mysql-test/t/ctype_utf8.test
+++ b/mysql-test/t/ctype_utf8.test
@@ -942,6 +942,76 @@ check table t1;
drop table t1;
#
+# Bug#20471 LIKE search fails with indexed utf8 char column
+#
+set names utf8;
+create table t1 (s1 char(5) character set utf8);
+insert into t1 values
+('a'),('b'),(null),('ペテルグル'),('ü'),('Y');
+create index it1 on t1 (s1);
+select s1 as before_delete_general_ci from t1 where s1 like 'ペテ%';
+delete from t1 where s1 = 'Y';
+select s1 as after_delete_general_ci from t1 where s1 like 'ペテ%';
+drop table t1;
+
+set names utf8;
+create table t1 (s1 char(5) character set utf8 collate utf8_unicode_ci);
+insert into t1 values
+('a'),('b'),(null),('ペテルグル'),('ü'),('Y');
+create index it1 on t1 (s1);
+select s1 as before_delete_unicode_ci from t1 where s1 like 'ペテ%';
+delete from t1 where s1 = 'Y';
+select s1 as after_delete_unicode_ci from t1 where s1 like 'ペテ%';
+drop table t1;
+
+set names utf8;
+create table t1 (s1 char(5) character set utf8 collate utf8_bin);
+insert into t1 values
+('a'),('b'),(null),('ペテルグル'),('ü'),('Y');
+create index it1 on t1 (s1);
+select s1 as before_delete_bin from t1 where s1 like 'ペテ%';
+delete from t1 where s1 = 'Y';
+select s1 as after_delete_bin from t1 where s1 like 'ペテ%';
+drop table t1;
+
+# additional tests from duplicate bug#20744 MySQL return no result
+
+set names utf8;
+--disable_warnings
+create table t1 (a varchar(30) not null primary key)
+engine=innodb default character set utf8 collate utf8_general_ci;
+--enable_warnings
+insert into t1 values ('あいうえおかきくけこさしすせそ');
+insert into t1 values ('さしすせそかきくけこあいうえお');
+select a as gci1 from t1 where a like 'さしすせそかきくけこあいうえお%';
+select a as gci2 from t1 where a like 'あいうえおかきくけこさしすせそ';
+drop table t1;
+
+set names utf8;
+--disable_warnings
+create table t1 (a varchar(30) not null primary key)
+engine=innodb default character set utf8 collate utf8_unicode_ci;
+--enable_warnings
+insert into t1 values ('あいうえおかきくけこさしすせそ');
+insert into t1 values ('さしすせそかきくけこあいうえお');
+select a as uci1 from t1 where a like 'さしすせそかきくけこあいうえお%';
+select a as uci2 from t1 where a like 'あいうえおかきくけこさしすせそ';
+drop table t1;
+
+set names utf8;
+--disable_warnings
+create table t1 (a varchar(30) not null primary key)
+engine=innodb default character set utf8 collate utf8_bin;
+--enable_warnings
+insert into t1 values ('あいうえおかきくけこさしすせそ');
+insert into t1 values ('さしすせそかきくけこあいうえお');
+select a as bin1 from t1 where a like 'さしすせそかきくけこあいうえお%';
+select a as bin2 from t1 where a like 'あいうえおかきくけこさしすせそ';
+drop table t1;
+
+
+
+#
# Bug#14896: Comparison with a key in a partial index over mb chararacter field
#
diff --git a/mysql-test/t/type_enum.test b/mysql-test/t/type_enum.test
index 0d479f312cd..68f5664c36d 100644
--- a/mysql-test/t/type_enum.test
+++ b/mysql-test/t/type_enum.test
@@ -127,4 +127,13 @@ create table t1 (a set('x','y') default 'x');
alter table t1 alter a set default 'z';
drop table t1;
+
+#
+# Bug#20922 mysql removes a name of first column in a table
+#
+create table t1 (f1 int);
+alter table t1 add f2 enum(0xFFFF);
+show create table t1;
+drop table t1;
+
# End of 4.1 tests
diff --git a/sql/table.cc b/sql/table.cc
index 5b41ad48696..1877e3f926c 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -802,7 +802,21 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
count)))
goto err;
for (count= 0; count < interval->count; count++)
- interval->type_lengths[count]= strlen(interval->type_names[count]);
+ {
+ char *val= (char*) interval->type_names[count];
+ interval->type_lengths[count]= strlen(val);
+ /*
+ Replace all ',' symbols with NAMES_SEP_CHAR.
+ See the comment in unireg.cc, pack_fields() function
+ for details.
+ */
+ for (uint cnt= 0 ; cnt < interval->type_lengths[count] ; cnt++)
+ {
+ char c= val[cnt];
+ if (c == ',')
+ val[cnt]= NAMES_SEP_CHAR;
+ }
+ }
interval->type_lengths[count]= 0;
}
}
diff --git a/sql/unireg.cc b/sql/unireg.cc
index 2ea572c782c..a20c59fd796 100644
--- a/sql/unireg.cc
+++ b/sql/unireg.cc
@@ -793,6 +793,21 @@ static bool pack_fields(File file, List<create_field> &create_fields,
tmp.append(NAMES_SEP_CHAR);
for (const char **pos=field->interval->type_names ; *pos ; pos++)
{
+ char *val= (char*) *pos;
+ uint str_len= strlen(val);
+ /*
+ Note, hack: in old frm NAMES_SEP_CHAR is used to separate
+ names in the interval (ENUM/SET). To allow names to contain
+ NAMES_SEP_CHAR, we replace it with a comma before writing frm.
+ Backward conversion is done during frm file opening,
+ See table.cc, openfrm() function
+ */
+ for (uint cnt= 0 ; cnt < str_len ; cnt++)
+ {
+ char c= val[cnt];
+ if (c == NAMES_SEP_CHAR)
+ val[cnt]= ',';
+ }
tmp.append(*pos);
tmp.append(NAMES_SEP_CHAR);
}
diff --git a/strings/CHARSET_INFO.txt b/strings/CHARSET_INFO.txt
index 40f171440a4..1336d5ae3bb 100644
--- a/strings/CHARSET_INFO.txt
+++ b/strings/CHARSET_INFO.txt
@@ -33,7 +33,7 @@ typedef struct charset_info_st
uint strxfrm_multiply;
uint mbminlen;
uint mbmaxlen;
- char max_sort_char; /* For LIKE optimization */
+ uint16 max_sort_char; /* For LIKE optimization */
MY_CHARSET_HANDLER *cset;
MY_COLLATION_HANDLER *coll;
@@ -134,7 +134,15 @@ Misc fields
mbmaxlen - maximum multibyte sequence length.
1 for 8bit charsets. Can be also 2 or 3.
-
+ max_sort_char - for LIKE range
+ in case of 8bit character sets - native code
+ of maximum character (max_str pad byte);
+ in case of UTF8 and UCS2 - Unicode code of the maximum
+ possible character (usually U+FFFF). This code is
+ converted to multibyte representation (usually 0xEFBFBF)
+ and then used as a pad sequence for max_str.
+ in case of other multibyte character sets -
+ max_str pad byte (usually 0xFF).
MY_CHARSET_HANDLER
==================
diff --git a/strings/ctype-mb.c b/strings/ctype-mb.c
index 898b7a4a57d..c945164ac9c 100644
--- a/strings/ctype-mb.c
+++ b/strings/ctype-mb.c
@@ -474,15 +474,35 @@ static void my_hash_sort_mb_bin(CHARSET_INFO *cs __attribute__((unused)),
/*
- Write max key: create a buffer with multibyte
- representation of the max_sort_char character,
- and copy it into max_str in a loop.
+ Fill the given buffer with 'maximum character' for given charset
+ SYNOPSIS
+ pad_max_char()
+ cs Character set
+ str Start of buffer to fill
+ end End of buffer to fill
+
+ DESCRIPTION
+ Write max key:
+ - for non-Unicode character sets:
+ just set to 255.
+ - for Unicode character set (utf-8):
+ create a buffer with multibyte representation of the max_sort_char
+ character, and copy it into max_str in a loop.
*/
static void pad_max_char(CHARSET_INFO *cs, char *str, char *end)
{
char buf[10];
- char buflen= cs->cset->wc_mb(cs, cs->max_sort_char, (uchar*) buf,
- (uchar*) buf + sizeof(buf));
+ char buflen;
+
+ if (!(cs->state & MY_CS_UNICODE))
+ {
+ bfill(str, end - str, 255);
+ return;
+ }
+
+ buflen= cs->cset->wc_mb(cs, cs->max_sort_char, (uchar*) buf,
+ (uchar*) buf + sizeof(buf));
+
DBUG_ASSERT(buflen > 0);
do
{
@@ -943,7 +963,7 @@ MY_COLLATION_HANDLER my_collation_mb_bin_handler =
my_strnncollsp_mb_bin,
my_strnxfrm_mb_bin,
my_strnxfrmlen_simple,
- my_like_range_simple,
+ my_like_range_mb,
my_wildcmp_mb_bin,
my_strcasecmp_mb_bin,
my_instr_mb,
diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c
index e221297eb55..6c3ceaf868b 100644
--- a/strings/ctype-utf8.c
+++ b/strings/ctype-utf8.c
@@ -2615,7 +2615,7 @@ CHARSET_INFO my_charset_utf8_bin=
1, /* mbminlen */
3, /* mbmaxlen */
0, /* min_sort_char */
- 255, /* max_sort_char */
+ 0xFFFF, /* max_sort_char */
' ', /* pad char */
0, /* escape_with_backslash_is_dangerous */
&my_charset_utf8_handler,