From f75ac7fb82d426b7392781b6292dc9780aae3b8d Mon Sep 17 00:00:00 2001 From: "andrey@lmy004." <> Date: Thu, 1 Sep 2005 00:13:02 +0200 Subject: [PATCH 1/5] fix for bug#12913 (Simple SQL can crash server or connection) (not initialized member leads to server crash) --- mysql-test/r/create.result | 5 +++++ mysql-test/t/create.test | 7 +++++++ sql/sql_table.cc | 1 + 3 files changed, 13 insertions(+) diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result index 95757fbd7dc..4de428868a0 100644 --- a/mysql-test/r/create.result +++ b/mysql-test/r/create.result @@ -587,6 +587,11 @@ DESC t2; Field Type Null Key Default Extra f2 varchar(86) YES NULL DROP TABLE t1,t2; +CREATE TABLE t12913 (f1 ENUM ('a','b')) AS SELECT 'a' AS f1; +SELECT * FROM t12913; +f1 +a +DROP TABLE t12913; create database mysqltest; use mysqltest; drop database mysqltest; diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test index 55321a81f5e..5c69d8f7edf 100644 --- a/mysql-test/t/create.test +++ b/mysql-test/t/create.test @@ -501,6 +501,13 @@ AS f2 FROM t1; DESC t2; DROP TABLE t1,t2; +# +# Bug#12913 Simple SQL can crash server or connection +# +CREATE TABLE t12913 (f1 ENUM ('a','b')) AS SELECT 'a' AS f1; +SELECT * FROM t12913; +DROP TABLE t12913; + # # Bug#11028: Crash on create table like # diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 92db0143980..b8ef6ed342a 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -649,6 +649,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, sql_field->decimals= dup_field->decimals; sql_field->flags= dup_field->flags; sql_field->unireg_check= dup_field->unireg_check; + sql_field->interval= dup_field->interval; it2.remove(); // Remove first (create) definition select_field_pos--; break; From 48d48bc93603d9f77db4e86907f84103d45c5709 Mon Sep 17 00:00:00 2001 From: "konstantin@mysql.com" <> Date: Sat, 14 Jan 2006 04:55:07 +0300 Subject: [PATCH 2/5] A fix and a test case for Bug#12734 " prepared statement may return incorrect result set for a select SQL request" --- mysql-test/r/ps.result | 34 ++++++++++++++++++++++++++++++++++ mysql-test/t/ps.test | 30 ++++++++++++++++++++++++++++++ sql/item_cmpfunc.cc | 6 ++++++ sql/item_cmpfunc.h | 1 + 4 files changed, 71 insertions(+) diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index d46c2d5b3d5..aa9ff083cbb 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -718,3 +718,37 @@ execute stmt; drop table t1; set names default; deallocate prepare stmt; +create table t1 ( +word_id mediumint(8) unsigned not null default '0', +formatted varchar(20) not null default '' +); +insert into t1 values +(80,'pendant'), (475,'pretendants'), (989,'tendances'), +(1019,'cependant'),(1022,'abondance'),(1205,'independants'), +(13,'lessiver'),(25,'lambiner'),(46,'situer'),(71,'terminer'), +(82,'decrocher'); +select count(*) from t1 where formatted like '%NDAN%'; +count(*) +6 +select count(*) from t1 where formatted like '%ER'; +count(*) +5 +prepare stmt from "select count(*) from t1 where formatted like ?"; +set @like="%NDAN%"; +execute stmt using @like; +count(*) +6 +set @like="%ER"; +execute stmt using @like; +count(*) +5 +set @like="%NDAN%"; +execute stmt using @like; +count(*) +6 +set @like="%ER"; +execute stmt using @like; +count(*) +5 +deallocate prepare stmt; +drop table t1; diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index 82dfc643801..23eb2e11ae3 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -746,5 +746,35 @@ drop table t1; set names default; deallocate prepare stmt; +# +# A test case for Bug#12734 "prepared statement may return incorrect result +# set for a select SQL request": test that canDoTurboBM is reset for each +# execute of a prepared statement. +# +create table t1 ( + word_id mediumint(8) unsigned not null default '0', + formatted varchar(20) not null default '' +); + +insert into t1 values + (80,'pendant'), (475,'pretendants'), (989,'tendances'), + (1019,'cependant'),(1022,'abondance'),(1205,'independants'), + (13,'lessiver'),(25,'lambiner'),(46,'situer'),(71,'terminer'), + (82,'decrocher'); + +select count(*) from t1 where formatted like '%NDAN%'; +select count(*) from t1 where formatted like '%ER'; +prepare stmt from "select count(*) from t1 where formatted like ?"; +set @like="%NDAN%"; +execute stmt using @like; +set @like="%ER"; +execute stmt using @like; +set @like="%NDAN%"; +execute stmt using @like; +set @like="%ER"; +execute stmt using @like; +deallocate prepare stmt; +drop table t1; + # End of 4.1 tests diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 2c76c7ec7b3..f9aa220c181 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -2524,6 +2524,12 @@ bool Item_func_like::fix_fields(THD *thd, TABLE_LIST *tlist, Item ** ref) return 0; } +void Item_func_like::cleanup() +{ + canDoTurboBM= FALSE; + Item_bool_func2::cleanup(); +} + #ifdef USE_REGEX bool diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 045566a46d5..ade09113c63 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -911,6 +911,7 @@ public: cond_result eq_cmp_result() const { return COND_TRUE; } const char *func_name() const { return "like"; } bool fix_fields(THD *thd, struct st_table_list *tlist, Item **ref); + void cleanup(); }; #ifdef USE_REGEX From ee2b765751226cb07f787053aed9f6c89e11b18e Mon Sep 17 00:00:00 2001 From: "aivanov@mysql.com" <> Date: Sun, 15 Jan 2006 14:50:47 +0300 Subject: [PATCH 3/5] Changes from innodb-4.1-ss14 snapshot Fixed BUG#14056: Column prefix index on UTF-8 primary key causes "Can't find record.." Also fixed bug 15991. --- innobase/include/os0file.h | 5 +- innobase/os/os0file.c | 8 ++- mysql-test/r/innodb.result | 40 +++++++++++ mysql-test/t/innodb.test | 36 ++++++++++ sql/ha_innodb.cc | 131 +++++++++++++++++++++++++++++++++---- 5 files changed, 203 insertions(+), 17 deletions(-) diff --git a/innobase/include/os0file.h b/innobase/include/os0file.h index cd07eb49cd6..0091e942d2c 100644 --- a/innobase/include/os0file.h +++ b/innobase/include/os0file.h @@ -86,9 +86,10 @@ log. */ #define OS_FILE_NOT_FOUND 71 #define OS_FILE_DISK_FULL 72 #define OS_FILE_ALREADY_EXISTS 73 -#define OS_FILE_AIO_RESOURCES_RESERVED 74 /* wait for OS aio resources +#define OS_FILE_PATH_ERROR 74 +#define OS_FILE_AIO_RESOURCES_RESERVED 75 /* wait for OS aio resources to become available again */ -#define OS_FILE_ERROR_NOT_SPECIFIED 75 +#define OS_FILE_ERROR_NOT_SPECIFIED 76 /* Types for aio operations */ #define OS_FILE_READ 10 diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c index 49f88c0d62a..6ef6f7cd545 100644 --- a/innobase/os/os0file.c +++ b/innobase/os/os0file.c @@ -303,6 +303,8 @@ os_file_get_last_error( return(OS_FILE_NOT_FOUND); } else if (err == EEXIST) { return(OS_FILE_ALREADY_EXISTS); + } else if (err == EXDEV || err == ENOTDIR || err == EISDIR) { + return(OS_FILE_PATH_ERROR); } else { return(100 + err); } @@ -352,7 +354,8 @@ os_file_handle_error( return(TRUE); - } else if (err == OS_FILE_ALREADY_EXISTS) { + } else if (err == OS_FILE_ALREADY_EXISTS + || err == OS_FILE_PATH_ERROR) { return(FALSE); } else { @@ -456,7 +459,8 @@ os_file_handle_error_no_exit( return(TRUE); - } else if (err == OS_FILE_ALREADY_EXISTS) { + } else if (err == OS_FILE_ALREADY_EXISTS + || err == OS_FILE_PATH_ERROR) { return(FALSE); } else { diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result index b43d00bda1c..3ec78c518fc 100644 --- a/mysql-test/r/innodb.result +++ b/mysql-test/r/innodb.result @@ -1754,3 +1754,43 @@ rename table t3 to t1; ERROR HY000: Error on rename of './test/t3' to './test/t1' (errno: 150) set foreign_key_checks=1; drop table t2,t3; +create table t2 ( +a int, b char(10), filler char(10), primary key(a, b(2)) +) character set utf8 engine = innodb; +insert into t2 values (1,'abcdefg','one'); +insert into t2 values (2,'ijkilmn','two'); +insert into t2 values (3, 'qrstuvw','three'); +update t2 set a=5, filler='booo' where a=1; +drop table t2; +create table t2 ( +a int, b char(10), filler char(10), primary key(a, b(2)) +) character set ucs2 engine = innodb; +insert into t2 values (1,'abcdefg','one'); +insert into t2 values (2,'ijkilmn','two'); +insert into t2 values (3, 'qrstuvw','three'); +update t2 set a=5, filler='booo' where a=1; +drop table t2; +create table t1(a int not null, b char(110),primary key(a,b(100))) engine=innodb default charset=utf8; +insert into t1 values(1,'abcdefg'),(2,'defghijk'); +insert into t1 values(6,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1); +insert into t1 values(7,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B2); +select a,hex(b) from t1 order by b; +a hex(b) +1 61626364656667 +2 6465666768696A6B +6 D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1 +7 D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B2 +update t1 set b = 'three' where a = 6; +drop table t1; +create table t1(a int not null, b text(110),primary key(a,b(100))) engine=innodb default charset=utf8; +insert into t1 values(1,'abcdefg'),(2,'defghijk'); +insert into t1 values(6,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1); +insert into t1 values(7,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B2); +select a,hex(b) from t1 order by b; +a hex(b) +1 61626364656667 +2 6465666768696A6B +6 D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1 +7 D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B2 +update t1 set b = 'three' where a = 6; +drop table t1; diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test index 03aa113c662..e2c12eedcae 100644 --- a/mysql-test/t/innodb.test +++ b/mysql-test/t/innodb.test @@ -1329,4 +1329,40 @@ create table t3(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=utf8; rename table t3 to t1; set foreign_key_checks=1; drop table t2,t3; + +# tests for bug #14056 Column prefix index on UTF-8 primary key column causes 'Can't find record..' + +create table t2 ( + a int, b char(10), filler char(10), primary key(a, b(2)) +) character set utf8 engine = innodb; + +insert into t2 values (1,'abcdefg','one'); +insert into t2 values (2,'ijkilmn','two'); +insert into t2 values (3, 'qrstuvw','three'); +update t2 set a=5, filler='booo' where a=1; +drop table t2; +create table t2 ( + a int, b char(10), filler char(10), primary key(a, b(2)) +) character set ucs2 engine = innodb; + +insert into t2 values (1,'abcdefg','one'); +insert into t2 values (2,'ijkilmn','two'); +insert into t2 values (3, 'qrstuvw','three'); +update t2 set a=5, filler='booo' where a=1; +drop table t2; + +create table t1(a int not null, b char(110),primary key(a,b(100))) engine=innodb default charset=utf8; +insert into t1 values(1,'abcdefg'),(2,'defghijk'); +insert into t1 values(6,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1); +insert into t1 values(7,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B2); +select a,hex(b) from t1 order by b; +update t1 set b = 'three' where a = 6; +drop table t1; +create table t1(a int not null, b text(110),primary key(a,b(100))) engine=innodb default charset=utf8; +insert into t1 values(1,'abcdefg'),(2,'defghijk'); +insert into t1 values(6,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1); +insert into t1 values(7,_utf8 0xD0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B1D0B2); +select a,hex(b) from t1 order by b; +update t1 set b = 'three' where a = 6; +drop table t1; # End of 4.1 tests diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index b188cfcba21..d24587e23ea 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -2015,6 +2015,22 @@ get_innobase_type_from_mysql_type( return(0); } +/*********************************************************************** +Writes an unsigned integer value < 64k to 2 bytes, in the little-endian +storage format. */ +inline +void +innobase_write_to_2_little_endian( +/*==============================*/ + byte* buf, /* in: where to store */ + ulint val) /* in: value to write, must be < 64k */ +{ + ut_a(val < 256 * 256); + + buf[0] = (byte)(val & 0xFF); + buf[1] = (byte)(val / 256); +} + /*********************************************************************** Stores a key value for a row to a buffer. */ @@ -2034,8 +2050,6 @@ ha_innobase::store_key_val_for_row( char* buff_start = buff; enum_field_types mysql_type; Field* field; - ulint blob_len; - byte* blob_data; ibool is_null; DBUG_ENTER("store_key_val_for_row"); @@ -2084,13 +2098,25 @@ ha_innobase::store_key_val_for_row( || mysql_type == FIELD_TYPE_BLOB || mysql_type == FIELD_TYPE_LONG_BLOB) { + CHARSET_INFO* cs; + ulint key_len; + ulint len; + ulint true_len; + int error=0; + ulint blob_len; + byte* blob_data; + ut_a(key_part->key_part_flag & HA_PART_KEY_SEG); + key_len = key_part->length; + if (is_null) { - buff += key_part->length + 2; + buff += key_len + 2; continue; } + + cs = field->charset(); blob_data = row_mysql_read_blob_ref(&blob_len, (byte*) (record @@ -2099,29 +2125,108 @@ ha_innobase::store_key_val_for_row( ut_a(get_field_offset(table, field) == key_part->offset); - if (blob_len > key_part->length) { - blob_len = key_part->length; + + true_len = blob_len; + + /* For multi byte character sets we need to calculate + the true length of the key */ + + if (key_len > 0 && cs->mbmaxlen > 1) { + true_len = (ulint) cs->cset->well_formed_len(cs, + (const char *) blob_data, + (const char *) blob_data + + blob_len, + key_len / cs->mbmaxlen, + &error); + } + + /* All indexes on BLOB and TEXT are column prefix + indexes, and we may need to truncate the data to be + stored in the key value: */ + + if (true_len > key_len) { + true_len = key_len; } /* MySQL reserves 2 bytes for the length and the storage of the number is little-endian */ - ut_a(blob_len < 256); - *((byte*)buff) = (byte)blob_len; + innobase_write_to_2_little_endian( + (byte*)buff, true_len); buff += 2; - memcpy(buff, blob_data, blob_len); + memcpy(buff, blob_data, true_len); - buff += key_part->length; + /* Note that we always reserve the maximum possible + length of the BLOB prefix in the key value. */ + + buff += key_len; } else { + /* Here we handle all other data types except the + true VARCHAR, BLOB and TEXT. Note that the column + value we store may be also in a column prefix + index. */ + + CHARSET_INFO* cs; + ulint true_len; + ulint key_len; + const mysql_byte* src_start; + int error=0; + enum_field_types real_type; + + key_len = key_part->length; + if (is_null) { - buff += key_part->length; + buff += key_len; continue; } - memcpy(buff, record + key_part->offset, - key_part->length); - buff += key_part->length; + + src_start = record + key_part->offset; + real_type = field->real_type(); + true_len = key_len; + + /* Character set for the field is defined only + to fields whose type is string and real field + type is not enum or set. For these fields check + if character set is multi byte. */ + + if (real_type != FIELD_TYPE_ENUM + && real_type != FIELD_TYPE_SET + && ( mysql_type == MYSQL_TYPE_VAR_STRING + || mysql_type == MYSQL_TYPE_STRING)) { + + cs = field->charset(); + + /* For multi byte character sets we need to + calculate the true length of the key */ + + if (key_len > 0 && cs->mbmaxlen > 1) { + + true_len = (ulint) + cs->cset->well_formed_len(cs, + (const char *)src_start, + (const char *)src_start + + key_len, + key_len / cs->mbmaxlen, + &error); + } + } + + memcpy(buff, src_start, true_len); + buff += true_len; + + /* Pad the unused space with spaces. Note that no + padding is ever needed for UCS-2 because in MySQL, + all UCS2 characters are 2 bytes, as MySQL does not + support surrogate pairs, which are needed to represent + characters in the range U+10000 to U+10FFFF. */ + + if (true_len < key_len) { + ulint pad_len = key_len - true_len; + memset(buff, ' ', pad_len); + buff += pad_len; + } } } From b54920bce72074532b279d1d98eeb05cd1af3419 Mon Sep 17 00:00:00 2001 From: "msvensson@neptunus.(none)" <> Date: Mon, 16 Jan 2006 12:17:30 +0100 Subject: [PATCH 4/5] BUG#6554 Problem Building MySql on Fedora Core 3 - Remove the local static var --- sql/ha_berkeley.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sql/ha_berkeley.cc b/sql/ha_berkeley.cc index b307b3a4b75..4ee844ac719 100644 --- a/sql/ha_berkeley.cc +++ b/sql/ha_berkeley.cc @@ -336,8 +336,9 @@ void berkeley_cleanup_log_files(void) ** Berkeley DB tables *****************************************************************************/ +static const char *bdb_bas_exts[]= { ha_berkeley_ext, NullS }; const char **ha_berkeley::bas_ext() const -{ static const char *ext[]= { ha_berkeley_ext, NullS }; return ext; } +{ return bdb_bas_exts; } static int From 739ba76d646efe19d14e3aee068d92471fcf8f5a Mon Sep 17 00:00:00 2001 From: "konstantin@mysql.com" <> Date: Tue, 17 Jan 2006 01:03:03 +0300 Subject: [PATCH 5/5] A fix for Bug#13337 "ps test fails if configure wo/ usc2" --- mysql-test/r/ctype_ucs.result | 19 +++++++++++++++++++ mysql-test/r/ps.result | 19 ------------------- mysql-test/t/ctype_ucs.test | 14 ++++++++++++++ mysql-test/t/ps.test | 13 ------------- 4 files changed, 33 insertions(+), 32 deletions(-) diff --git a/mysql-test/r/ctype_ucs.result b/mysql-test/r/ctype_ucs.result index 3ca56548de9..0e12ec88662 100644 --- a/mysql-test/r/ctype_ucs.result +++ b/mysql-test/r/ctype_ucs.result @@ -684,3 +684,22 @@ select f1 from t1 where f1 like 'a%'; f1 a drop table t1; +create table t1 (utext varchar(20) character set ucs2); +insert into t1 values ("lily"); +insert into t1 values ("river"); +prepare stmt from 'select utext from t1 where utext like ?'; +set @param1='%%'; +execute stmt using @param1; +utext +lily +river +execute stmt using @param1; +utext +lily +river +select utext from t1 where utext like '%%'; +utext +lily +river +drop table t1; +deallocate prepare stmt; diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index aa9ff083cbb..ba9336c20bb 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -639,25 +639,6 @@ execute stmt using @a, @b; ?=? 1 deallocate prepare stmt; -create table t1 (utext varchar(20) character set ucs2); -insert into t1 values ("lily"); -insert into t1 values ("river"); -prepare stmt from 'select utext from t1 where utext like ?'; -set @param1='%%'; -execute stmt using @param1; -utext -lily -river -execute stmt using @param1; -utext -lily -river -select utext from t1 where utext like '%%'; -utext -lily -river -drop table t1; -deallocate prepare stmt; create table t1 (a int); prepare stmt from "select ??"; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '?' at line 1 diff --git a/mysql-test/t/ctype_ucs.test b/mysql-test/t/ctype_ucs.test index 3b3c2c70f32..ed55287ca05 100644 --- a/mysql-test/t/ctype_ucs.test +++ b/mysql-test/t/ctype_ucs.test @@ -427,4 +427,18 @@ insert into t1 values('a'); create index t1f1 on t1(f1); select f1 from t1 where f1 like 'a%'; drop table t1; + +# +# Bug#9442 Set parameter make query fail if column character set is UCS2 +# +create table t1 (utext varchar(20) character set ucs2); +insert into t1 values ("lily"); +insert into t1 values ("river"); +prepare stmt from 'select utext from t1 where utext like ?'; +set @param1='%%'; +execute stmt using @param1; +execute stmt using @param1; +select utext from t1 where utext like '%%'; +drop table t1; +deallocate prepare stmt; # End of 4.1 tests diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index 23eb2e11ae3..b0755d06414 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -665,19 +665,6 @@ set @b='CHRISTINE'; execute stmt using @a, @b; deallocate prepare stmt; # -# Bug#9442 Set parameter make query fail if column character set is UCS2 -# -create table t1 (utext varchar(20) character set ucs2); -insert into t1 values ("lily"); -insert into t1 values ("river"); -prepare stmt from 'select utext from t1 where utext like ?'; -set @param1='%%'; -execute stmt using @param1; -execute stmt using @param1; -select utext from t1 where utext like '%%'; -drop table t1; -deallocate prepare stmt; -# # Bug#11299 "prepared statement makes wrong SQL syntax in binlog which stops # replication": check that errouneous queries with placeholders are not # allowed