Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
aea1e14e
Commit
aea1e14e
authored
Nov 07, 2006
by
lars/lthalmann@mysql.com/dl145h.mysql.com
Browse files
Options
Browse Files
Download
Plain Diff
Merge mysql.com:/users/lthalmann/bkroot/mysql-5.0-rpl
into mysql.com:/users/lthalmann/bk/MERGE/mysql-5.0-merge
parents
56f10ac8
c378d3a1
Changes
32
Hide whitespace changes
Inline
Side-by-side
Showing
32 changed files
with
768 additions
and
214 deletions
+768
-214
BitKeeper/etc/collapsed
BitKeeper/etc/collapsed
+2
-0
include/m_ctype.h
include/m_ctype.h
+6
-6
myisam/mi_key.c
myisam/mi_key.c
+8
-7
myisam/mi_open.c
myisam/mi_open.c
+2
-0
mysql-test/include/strict_autoinc.inc
mysql-test/include/strict_autoinc.inc
+4
-0
mysql-test/r/ctype_recoding.result
mysql-test/r/ctype_recoding.result
+2
-2
mysql-test/r/ctype_ucs.result
mysql-test/r/ctype_ucs.result
+22
-0
mysql-test/r/ctype_utf8.result
mysql-test/r/ctype_utf8.result
+3
-3
mysql-test/r/fulltext.result
mysql-test/r/fulltext.result
+4
-4
mysql-test/r/lowercase_table.result
mysql-test/r/lowercase_table.result
+24
-0
mysql-test/r/rpl_deadlock.result
mysql-test/r/rpl_deadlock.result
+23
-15
mysql-test/r/rpl_ignore_table.result
mysql-test/r/rpl_ignore_table.result
+16
-0
mysql-test/r/strict_autoinc_1myisam.result
mysql-test/r/strict_autoinc_1myisam.result
+1
-0
mysql-test/r/strict_autoinc_2innodb.result
mysql-test/r/strict_autoinc_2innodb.result
+1
-0
mysql-test/r/strict_autoinc_3heap.result
mysql-test/r/strict_autoinc_3heap.result
+1
-0
mysql-test/r/strict_autoinc_4bdb.result
mysql-test/r/strict_autoinc_4bdb.result
+1
-0
mysql-test/r/strict_autoinc_5ndb.result
mysql-test/r/strict_autoinc_5ndb.result
+1
-0
mysql-test/t/ctype_ucs.test
mysql-test/t/ctype_ucs.test
+17
-0
mysql-test/t/lowercase_table.test
mysql-test/t/lowercase_table.test
+20
-0
mysql-test/t/rpl_deadlock.test
mysql-test/t/rpl_deadlock.test
+10
-6
mysql-test/t/rpl_ignore_table-slave.opt
mysql-test/t/rpl_ignore_table-slave.opt
+1
-1
mysql-test/t/rpl_ignore_table.test
mysql-test/t/rpl_ignore_table.test
+23
-0
sql/field.cc
sql/field.cc
+217
-136
sql/slave.cc
sql/slave.cc
+15
-6
sql/sql_parse.cc
sql/sql_parse.cc
+18
-2
sql/sql_string.cc
sql/sql_string.cc
+156
-0
sql/sql_string.h
sql/sql_string.h
+8
-0
strings/ctype-bin.c
strings/ctype-bin.c
+2
-1
strings/ctype-mb.c
strings/ctype-mb.c
+14
-10
strings/ctype-simple.c
strings/ctype-simple.c
+12
-6
strings/ctype-ucs2.c
strings/ctype-ucs2.c
+5
-3
strings/ctype-utf8.c
strings/ctype-utf8.c
+129
-6
No files found.
BitKeeper/etc/collapsed
View file @
aea1e14e
...
...
@@ -15,3 +15,5 @@
45214442pBGT9KuZEGixBH71jTzbOA
45214a07hVsIGwvwa-WrO-jpeaSwVw
452a92d0-31-8wSzSfZi165fcGcXPA
452c6c6dAjuNghfc1ObZ_UQ5SCl85g
4538a7b0EbDHHkWPbIwxO6ZIDdg6Dg
include/m_ctype.h
View file @
aea1e14e
...
...
@@ -178,8 +178,8 @@ typedef struct my_charset_handler_st
unsigned
char
*
s
,
unsigned
char
*
e
);
/* Functions for case and sort convertion */
void
(
*
caseup_str
)(
struct
charset_info_st
*
,
char
*
);
void
(
*
casedn_str
)(
struct
charset_info_st
*
,
char
*
);
uint
(
*
caseup_str
)(
struct
charset_info_st
*
,
char
*
);
uint
(
*
casedn_str
)(
struct
charset_info_st
*
,
char
*
);
uint
(
*
caseup
)(
struct
charset_info_st
*
,
char
*
src
,
uint
srclen
,
char
*
dst
,
uint
dstlen
);
uint
(
*
casedn
)(
struct
charset_info_st
*
,
char
*
src
,
uint
srclen
,
...
...
@@ -311,8 +311,8 @@ extern uint my_instr_simple(struct charset_info_st *,
/* Functions for 8bit */
extern
void
my_caseup_str_8bit
(
CHARSET_INFO
*
,
char
*
);
extern
void
my_casedn_str_8bit
(
CHARSET_INFO
*
,
char
*
);
extern
uint
my_caseup_str_8bit
(
CHARSET_INFO
*
,
char
*
);
extern
uint
my_casedn_str_8bit
(
CHARSET_INFO
*
,
char
*
);
extern
uint
my_caseup_8bit
(
CHARSET_INFO
*
,
char
*
src
,
uint
srclen
,
char
*
dst
,
uint
dstlen
);
extern
uint
my_casedn_8bit
(
CHARSET_INFO
*
,
char
*
src
,
uint
srclen
,
...
...
@@ -399,8 +399,8 @@ int my_mbcharlen_8bit(CHARSET_INFO *, uint c);
/* Functions for multibyte charsets */
extern
void
my_caseup_str_mb
(
CHARSET_INFO
*
,
char
*
);
extern
void
my_casedn_str_mb
(
CHARSET_INFO
*
,
char
*
);
extern
uint
my_caseup_str_mb
(
CHARSET_INFO
*
,
char
*
);
extern
uint
my_casedn_str_mb
(
CHARSET_INFO
*
,
char
*
);
extern
uint
my_caseup_mb
(
CHARSET_INFO
*
,
char
*
src
,
uint
srclen
,
char
*
dst
,
uint
dstlen
);
extern
uint
my_casedn_mb
(
CHARSET_INFO
*
,
char
*
src
,
uint
srclen
,
...
...
myisam/mi_key.c
View file @
aea1e14e
...
...
@@ -52,7 +52,7 @@ static int _mi_put_key_in_record(MI_INFO *info,uint keynr,byte *record);
uint
_mi_make_key
(
register
MI_INFO
*
info
,
uint
keynr
,
uchar
*
key
,
const
byte
*
record
,
my_off_t
filepos
)
{
byte
*
pos
,
*
end
;
byte
*
pos
;
uchar
*
start
;
reg1
HA_KEYSEG
*
keyseg
;
my_bool
is_ft
=
info
->
s
->
keyinfo
[
keynr
].
flag
&
HA_FULLTEXT
;
...
...
@@ -107,18 +107,17 @@ uint _mi_make_key(register MI_INFO *info, uint keynr, uchar *key,
}
if
(
keyseg
->
flag
&
HA_SPACE_PACK
)
{
end
=
pos
+
length
;
if
(
type
!=
HA_KEYTYPE_NUM
)
{
while
(
end
>
pos
&&
end
[
-
1
]
==
' '
)
end
--
;
length
=
cs
->
cset
->
lengthsp
(
cs
,
pos
,
length
);
}
else
{
byte
*
end
=
pos
+
length
;
while
(
pos
<
end
&&
pos
[
0
]
==
' '
)
pos
++
;
length
=
(
uint
)
(
end
-
pos
);
}
length
=
(
uint
)
(
end
-
pos
);
FIX_LENGTH
(
cs
,
pos
,
length
,
char_length
);
store_key_length_inc
(
key
,
char_length
);
memcpy
((
byte
*
)
key
,(
byte
*
)
pos
,(
size_t
)
char_length
);
...
...
@@ -403,8 +402,10 @@ static int _mi_put_key_in_record(register MI_INFO *info, uint keynr,
pos
=
record
+
keyseg
->
start
;
if
(
keyseg
->
type
!=
(
int
)
HA_KEYTYPE_NUM
)
{
memcpy
(
pos
,
key
,(
size_t
)
length
);
bfill
(
pos
+
length
,
keyseg
->
length
-
length
,
' '
);
memcpy
(
pos
,
key
,(
size_t
)
length
);
keyseg
->
charset
->
cset
->
fill
(
keyseg
->
charset
,
pos
+
length
,
keyseg
->
length
-
length
,
' '
);
}
else
{
...
...
myisam/mi_open.c
View file @
aea1e14e
...
...
@@ -336,6 +336,8 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
goto
err
;
}
}
else
if
(
pos
->
type
==
HA_KEYTYPE_BINARY
)
pos
->
charset
=
&
my_charset_bin
;
}
if
(
share
->
keyinfo
[
i
].
flag
&
HA_SPATIAL
)
{
...
...
mysql-test/include/strict_autoinc.inc
View file @
aea1e14e
...
...
@@ -2,6 +2,10 @@
# Test for strict-mode autoincrement
#
--
disable_warnings
drop
table
if
exists
t1
;
--
enable_warnings
set
@
org_mode
=@@
sql_mode
;
eval
create
table
t1
(
...
...
mysql-test/r/ctype_recoding.result
View file @
aea1e14e
...
...
@@ -171,8 +171,8 @@ create table t1 (a char(10) character set koi8r, b text character set koi8r);
insert into t1 values ('test','test');
insert into t1 values ('','');
Warnings:
Warning 1
265 Data truncated
for column 'a' at row 1
Warning 1
265 Data truncated
for column 'b' at row 1
Warning 1
366 Incorrect string value: '\xCA\xC3\xD5\xCB'
for column 'a' at row 1
Warning 1
366 Incorrect string value: '\xCA\xC3\xD5\xCB'
for column 'b' at row 1
drop table t1;
set names koi8r;
create table t1 (a char(10) character set cp1251);
...
...
mysql-test/r/ctype_ucs.result
View file @
aea1e14e
...
...
@@ -723,6 +723,28 @@ lily
river
drop table t1;
deallocate prepare stmt;
create table t1 (
a char(10) unicode not null,
index a (a)
) engine=myisam;
insert into t1 values (repeat(0x201f, 10));
insert into t1 values (repeat(0x2020, 10));
insert into t1 values (repeat(0x2021, 10));
explain select hex(a) from t1 order by a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index NULL a 20 NULL 3 Using index
select hex(a) from t1 order by a;
hex(a)
201F201F201F201F201F201F201F201F201F201F
2020202020202020202020202020202020202020
2021202120212021202120212021202120212021
alter table t1 drop index a;
select hex(a) from t1 order by a;
hex(a)
201F201F201F201F201F201F201F201F201F201F
2020202020202020202020202020202020202020
2021202120212021202120212021202120212021
drop table t1;
CREATE TABLE t1 (id int, s char(5) CHARACTER SET ucs2 COLLATE ucs2_unicode_ci);
INSERT INTO t1 VALUES (1, 'ZZZZZ'), (1, 'ZZZ'), (2, 'ZZZ'), (2, 'ZZZZZ');
SELECT id, MIN(s) FROM t1 GROUP BY id;
...
...
mysql-test/r/ctype_utf8.result
View file @
aea1e14e
...
...
@@ -197,7 +197,7 @@ drop table t1;
create table t1 (s1 char(10) character set utf8);
insert into t1 values (0x41FF);
Warnings:
Warning 1
265 Data truncated
for column 's1' at row 1
Warning 1
366 Incorrect string value: '\xFF'
for column 's1' at row 1
select hex(s1) from t1;
hex(s1)
41
...
...
@@ -205,7 +205,7 @@ drop table t1;
create table t1 (s1 varchar(10) character set utf8);
insert into t1 values (0x41FF);
Warnings:
Warning 1
265 Data truncated
for column 's1' at row 1
Warning 1
366 Incorrect string value: '\xFF'
for column 's1' at row 1
select hex(s1) from t1;
hex(s1)
41
...
...
@@ -213,7 +213,7 @@ drop table t1;
create table t1 (s1 text character set utf8);
insert into t1 values (0x41FF);
Warnings:
Warning 1
265 Data truncated
for column 's1' at row 1
Warning 1
366 Incorrect string value: '\xFF'
for column 's1' at row 1
select hex(s1) from t1;
hex(s1)
41
...
...
mysql-test/r/fulltext.result
View file @
aea1e14e
...
...
@@ -372,10 +372,10 @@ t collation(t) FORMAT(MATCH t AGAINST ('Osnabruck'),6)
aus Osnabrck utf8_general_ci 1.591140
alter table t1 modify t varchar(200) collate latin1_german2_ci not null;
Warnings:
Warning 1
265 Data truncated
for column 't' at row 3
Warning 1
265 Data truncated
for column 't' at row 4
Warning 1
265 Data truncated
for column 't' at row 5
Warning 1
265 Data truncated
for column 't' at row 6
Warning 1
366 Incorrect string value: '\xD0\xAD\xD1\x82\xD0\xBE...'
for column 't' at row 3
Warning 1
366 Incorrect string value: '\xD0\x9E\xD1\x82\xD0\xBB...'
for column 't' at row 4
Warning 1
366 Incorrect string value: '\xD0\x9D\xD0\xB5 \xD0...'
for column 't' at row 5
Warning 1
366 Incorrect string value: '\xD0\xB8 \xD0\xB1\xD1...'
for column 't' at row 6
SELECT t, collation(t) FROM t1 WHERE MATCH t AGAINST ('Osnabrck');
t collation(t)
aus Osnabrck latin1_german2_ci
...
...
mysql-test/r/lowercase_table.result
View file @
aea1e14e
...
...
@@ -84,3 +84,27 @@ create table t2 like T1;
drop table t1, t2;
show tables;
Tables_in_test
set names utf8;
drop table if exists İ,İİ;
create table İ (s1 int);
show create table İ;
Table Create Table
İ CREATE TABLE `i` (
`s1` int(11) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
show tables;
Tables_in_test
i
drop table İ;
create table İİ (s1 int);
show create table İİ;
Table Create Table
İİ CREATE TABLE `ii` (
`s1` int(11) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
show tables;
Tables_in_test
ii
drop table İİ;
set names latin1;
End of 5.0 tests
mysql-test/r/rpl_deadlock.result
View file @
aea1e14e
...
...
@@ -6,7 +6,7 @@ drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
create table t1 (a int not null, key(a)) engine=innodb;
create table t2 (a int not null, key(a)) engine=innodb;
create table t3 (a int) engine=innodb;
create table t3 (a int
unique
) engine=innodb;
create table t4 (a int) engine=innodb;
show variables like 'slave_transaction_retries';
Variable_name Value
...
...
@@ -35,14 +35,14 @@ begin;
select * from t1 for update;
a
start slave;
insert into t2 values(2
2
);
insert into t2 values(2
01
);
commit;
select * from t1;
a
1
select * from t2;
a
2
2
2
01
show slave status;
Slave_IO_State #
Master_Host 127.0.0.1
...
...
@@ -50,7 +50,7 @@ Master_User root
Master_Port MASTER_MYPORT
Connect_Retry 1
Master_Log_File master-bin.000001
Read_Master_Log_Pos 1891
1
Read_Master_Log_Pos 1891
8
Relay_Log_File #
Relay_Log_Pos #
Relay_Master_Log_File master-bin.000001
...
...
@@ -65,7 +65,7 @@ Replicate_Wild_Ignore_Table
Last_Errno 0
Last_Error
Skip_Counter 0
Exec_Master_Log_Pos 1891
1
Exec_Master_Log_Pos 1891
8
Relay_Log_Space #
Until_Condition None
Until_Log_File
...
...
@@ -78,12 +78,16 @@ Master_SSL_Cipher
Master_SSL_Key
Seconds_Behind_Master #
stop slave;
change master to master_log_pos=532;
delete from t3;
change master to master_log_pos=539;
begin;
select * from t2 for update;
a
2
2
2
01
start slave;
select count(*) from t3 /* must be zero */;
count(*)
0
commit;
select * from t1;
a
...
...
@@ -91,7 +95,7 @@ a
1
select * from t2;
a
2
2
2
01
show slave status;
Slave_IO_State #
Master_Host 127.0.0.1
...
...
@@ -99,7 +103,7 @@ Master_User root
Master_Port MASTER_MYPORT
Connect_Retry 1
Master_Log_File master-bin.000001
Read_Master_Log_Pos 1891
1
Read_Master_Log_Pos 1891
8
Relay_Log_File #
Relay_Log_Pos #
Relay_Master_Log_File master-bin.000001
...
...
@@ -114,7 +118,7 @@ Replicate_Wild_Ignore_Table
Last_Errno 0
Last_Error
Skip_Counter 0
Exec_Master_Log_Pos 1891
1
Exec_Master_Log_Pos 1891
8
Relay_Log_Space #
Until_Condition None
Until_Log_File
...
...
@@ -128,12 +132,16 @@ Master_SSL_Key
Seconds_Behind_Master #
set global max_relay_log_size=0;
stop slave;
change master to master_log_pos=532;
delete from t3;
change master to master_log_pos=539;
begin;
select * from t2 for update;
a
2
2
2
01
start slave;
select count(*) from t3 /* must be zero */;
count(*)
0
commit;
select * from t1;
a
...
...
@@ -142,7 +150,7 @@ a
1
select * from t2;
a
2
2
2
01
show slave status;
Slave_IO_State #
Master_Host 127.0.0.1
...
...
@@ -150,7 +158,7 @@ Master_User root
Master_Port MASTER_MYPORT
Connect_Retry 1
Master_Log_File master-bin.000001
Read_Master_Log_Pos 1891
1
Read_Master_Log_Pos 1891
8
Relay_Log_File #
Relay_Log_Pos #
Relay_Master_Log_File master-bin.000001
...
...
@@ -165,7 +173,7 @@ Replicate_Wild_Ignore_Table
Last_Errno 0
Last_Error
Skip_Counter 0
Exec_Master_Log_Pos 1891
1
Exec_Master_Log_Pos 1891
8
Relay_Log_Space #
Until_Condition None
Until_Log_File
...
...
mysql-test/r/rpl_ignore_table.result
View file @
aea1e14e
...
...
@@ -14,3 +14,19 @@ SELECT * FROM t4;
a
DROP TABLE t1;
DROP TABLE t4;
DROP TABLE IF EXISTS t5;
CREATE TABLE t5 (
word varchar(50) collate utf8_unicode_ci NOT NULL default ''
) DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
SET @@session.character_set_client=33,@@session.collation_connection=192;
CREATE TEMPORARY TABLE tmptbl504451f4258$1 (id INT NOT NULL) ENGINE=MEMORY;
INSERT INTO t5 (word) VALUES ('TEST’');
SELECT HEX(word) FROM t5;
HEX(word)
54455354E28099
SELECT HEX(word) FROM t5;
HEX(word)
54455354E28099
SELECT * FROM tmptbl504451f4258$1;
ERROR 42S02: Table 'test.tmptbl504451f4258$1' doesn't exist
DROP TABLE t5;
mysql-test/r/strict_autoinc_1myisam.result
View file @
aea1e14e
drop table if exists t1;
set @org_mode=@@sql_mode;
create table t1
(
...
...
mysql-test/r/strict_autoinc_2innodb.result
View file @
aea1e14e
drop table if exists t1;
set @org_mode=@@sql_mode;
create table t1
(
...
...
mysql-test/r/strict_autoinc_3heap.result
View file @
aea1e14e
drop table if exists t1;
set @org_mode=@@sql_mode;
create table t1
(
...
...
mysql-test/r/strict_autoinc_4bdb.result
View file @
aea1e14e
drop table if exists t1;
set @org_mode=@@sql_mode;
create table t1
(
...
...
mysql-test/r/strict_autoinc_5ndb.result
View file @
aea1e14e
drop table if exists t1;
set @org_mode=@@sql_mode;
create table t1
(
...
...
mysql-test/t/ctype_ucs.test
View file @
aea1e14e
...
...
@@ -454,6 +454,23 @@ select utext from t1 where utext like '%%';
drop
table
t1
;
deallocate
prepare
stmt
;
#
# Bug#22052 Trailing spaces are not removed from UNICODE fields in an index
#
create
table
t1
(
a
char
(
10
)
unicode
not
null
,
index
a
(
a
)
)
engine
=
myisam
;
insert
into
t1
values
(
repeat
(
0x201f
,
10
));
insert
into
t1
values
(
repeat
(
0x2020
,
10
));
insert
into
t1
values
(
repeat
(
0x2021
,
10
));
# make sure "index read" is used
explain
select
hex
(
a
)
from
t1
order
by
a
;
select
hex
(
a
)
from
t1
order
by
a
;
alter
table
t1
drop
index
a
;
select
hex
(
a
)
from
t1
order
by
a
;
drop
table
t1
;
#
# Bug #20076: server crashes for a query with GROUP BY if MIN/MAX aggregation
# over a 'ucs2' field uses a temporary table
...
...
mysql-test/t/lowercase_table.test
View file @
aea1e14e
...
...
@@ -85,3 +85,23 @@ drop table t1, t2;
show
tables
;
# End of 4.1 tests
#
# Bug#20404: SHOW CREATE TABLE fails with Turkish I
#
set
names
utf8
;
--
disable_warnings
drop
table
if
exists
İ
,
İİ
;
--
enable_warnings
create
table
İ
(
s1
int
);
show
create
table
İ
;
show
tables
;
drop
table
İ
;
create
table
İİ
(
s1
int
);
show
create
table
İİ
;
show
tables
;
drop
table
İİ
;
set
names
latin1
;
--
echo
End
of
5.0
tests
mysql-test/t/rpl_deadlock.test
View file @
aea1e14e
...
...
@@ -16,7 +16,8 @@ source include/master-slave.inc;
connection
master
;
create
table
t1
(
a
int
not
null
,
key
(
a
))
engine
=
innodb
;
create
table
t2
(
a
int
not
null
,
key
(
a
))
engine
=
innodb
;
create
table
t3
(
a
int
)
engine
=
innodb
;
# requiring 'unique' for the timeout part of the test
create
table
t3
(
a
int
unique
)
engine
=
innodb
;
create
table
t4
(
a
int
)
engine
=
innodb
;
show
variables
like
'slave_transaction_retries'
;
sync_slave_with_master
;
...
...
@@ -31,8 +32,7 @@ stop slave;
connection
master
;
begin
;
# Let's keep BEGIN and the locked statement in two different relay logs.
let
$
1
=
200
;
disable_query_log
;
let
$
1
=
200
;
disable_query_log
;
while
(
$
1
)
{
eval
insert
into
t3
values
(
$
1
);
...
...
@@ -59,7 +59,7 @@ enable_query_log;
select
*
from
t1
for
update
;
start
slave
;
--
real_sleep
3
# hope that slave is blocked now
insert
into
t2
values
(
2
2
);
# provoke deadlock, slave should be victim
insert
into
t2
values
(
2
01
);
# provoke deadlock, slave should be victim
commit
;
sync_with_master
;
select
*
from
t1
;
# check that slave succeeded finally
...
...
@@ -74,11 +74,13 @@ show slave status;
# 2) Test lock wait timeout
stop
slave
;
change
master
to
master_log_pos
=
532
;
# the BEGIN log event
delete
from
t3
;
change
master
to
master_log_pos
=
539
;
# the BEGIN log event
begin
;
select
*
from
t2
for
update
;
# hold lock
start
slave
;
--
real_sleep
10
# slave should have blocked, and be retrying
select
count
(
*
)
from
t3
/* must be zero */
;
# replaying begins after rollback
commit
;
sync_with_master
;
select
*
from
t1
;
# check that slave succeeded finally
...
...
@@ -97,11 +99,13 @@ set global max_relay_log_size=0;
# This is really copy-paste of 2) of above
stop
slave
;
change
master
to
master_log_pos
=
532
;
delete
from
t3
;
change
master
to
master_log_pos
=
539
;
begin
;
select
*
from
t2
for
update
;
start
slave
;
--
real_sleep
10
select
count
(
*
)
from
t3
/* must be zero */
;
# replaying begins after rollback
commit
;
sync_with_master
;
select
*
from
t1
;
...
...
mysql-test/t/rpl_ignore_table-slave.opt
View file @
aea1e14e
--replicate-ignore-table=test.t1 --replicate-ignore-table=test.t2 --replicate-ignore-table=test.t3
--replicate-ignore-table=test.t1 --replicate-ignore-table=test.t2 --replicate-ignore-table=test.t3
--replicate-wild-ignore-table=%.tmptbl%
mysql-test/t/rpl_ignore_table.test
View file @
aea1e14e
...
...
@@ -26,3 +26,26 @@ SELECT * FROM t4;
connection
master
;
DROP
TABLE
t1
;
DROP
TABLE
t4
;
#
# bug#22877 replication character sets get out of sync
# using replicate-wild-ignore-table
#
--
disable_warnings
DROP
TABLE
IF
EXISTS
t5
;
--
enable_warnings
CREATE
TABLE
t5
(
word
varchar
(
50
)
collate
utf8_unicode_ci
NOT
NULL
default
''
)
DEFAULT
CHARSET
=
utf8
COLLATE
=
utf8_unicode_ci
;
SET
@@
session
.
character_set_client
=
33
,
@@
session
.
collation_connection
=
192
;
CREATE
TEMPORARY
TABLE
tmptbl504451f4258
$
1
(
id
INT
NOT
NULL
)
ENGINE
=
MEMORY
;
INSERT
INTO
t5
(
word
)
VALUES
(
'TEST’'
);
SELECT
HEX
(
word
)
FROM
t5
;
sync_slave_with_master
;
connection
slave
;
SELECT
HEX
(
word
)
FROM
t5
;
--
error
1146
SELECT
*
FROM
tmptbl504451f4258
$
1
;
connection
master
;
DROP
TABLE
t5
;
sql/field.cc
View file @
aea1e14e
...
...
@@ -5783,37 +5783,148 @@ void Field_datetime::sql_type(String &res) const
** A string may be varchar or binary
****************************************************************************/
/*
Report "not well formed" or "cannot convert" error
after storing a character string info a field.
SYNOPSIS
check_string_copy_error()
field - Field
well_formed_error_pos - where not well formed data was first met
cannot_convert_error_pos - where a not-convertable character was first met
end - end of the string
NOTES
As of version 5.0 both cases return the same error:
"Invalid string value: 'xxx' for column 't' at row 1"
Future versions will possibly introduce a new error message:
"Cannot convert character string: 'xxx' for column 't' at row 1"
RETURN
FALSE - If errors didn't happen
TRUE - If an error happened
*/
static
bool
check_string_copy_error
(
Field_str
*
field
,
const
char
*
well_formed_error_pos
,
const
char
*
cannot_convert_error_pos
,
const
char
*
end
)
{
const
char
*
pos
,
*
end_orig
;
char
tmp
[
64
],
*
t
;
if
(
!
(
pos
=
well_formed_error_pos
)
&&
!
(
pos
=
cannot_convert_error_pos
))
return
FALSE
;
end_orig
=
end
;
set_if_smaller
(
end
,
pos
+
6
);
for
(
t
=
tmp
;
pos
<
end
;
pos
++
)
{
if
(((
unsigned
char
)
*
pos
)
>=
0x20
&&
((
unsigned
char
)
*
pos
)
<=
0x7F
)
{
*
t
++=
*
pos
;
}
else
{
*
t
++=
'\\'
;
*
t
++=
'x'
;
*
t
++=
_dig_vec_upper
[((
unsigned
char
)
*
pos
)
>>
4
];
*
t
++=
_dig_vec_upper
[((
unsigned
char
)
*
pos
)
&
15
];
}
}
if
(
end_orig
>
end
)
{
*
t
++=
'.'
;
*
t
++=
'.'
;
*
t
++=
'.'
;
}
*
t
=
'\0'
;
push_warning_printf
(
field
->
table
->
in_use
,
field
->
table
->
in_use
->
abort_on_warning
?
MYSQL_ERROR
::
WARN_LEVEL_ERROR
:
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
ER_TRUNCATED_WRONG_VALUE_FOR_FIELD
,
ER
(
ER_TRUNCATED_WRONG_VALUE_FOR_FIELD
),
"string"
,
tmp
,
field
->
field_name
,
(
ulong
)
field
->
table
->
in_use
->
row_count
);
return
TRUE
;
}
/*
Send a truncation warning or a truncation error
after storing a too long character string info a field.
SYNOPSIS
report_data_too_long()
field - Field
RETURN
N/A
*/
inline
void
report_data_too_long
(
Field_str
*
field
)
{
if
(
field
->
table
->
in_use
->
abort_on_warning
)
field
->
set_warning
(
MYSQL_ERROR
::
WARN_LEVEL_ERROR
,
ER_DATA_TOO_LONG
,
1
);
else
field
->
set_warning
(
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
WARN_DATA_TRUNCATED
,
1
);
}
/*
Test if the given string contains important data:
not spaces for character string,
or any data for binary string.
SYNOPSIS
test_if_important_data()
cs Character set
str String to test
strend String end
RETURN
FALSE - If string does not have important data
TRUE - If string has some important data
*/
static
bool
test_if_important_data
(
CHARSET_INFO
*
cs
,
const
char
*
str
,
const
char
*
strend
)
{
if
(
cs
!=
&
my_charset_bin
)
str
+=
cs
->
cset
->
scan
(
cs
,
str
,
strend
,
MY_SEQ_SPACES
);
return
(
str
<
strend
);
}
/* Copy a string and fill with space */
int
Field_string
::
store
(
const
char
*
from
,
uint
length
,
CHARSET_INFO
*
cs
)
{
int
error
=
0
,
well_formed_error
;
uint32
not_used
;
char
buff
[
STRING_BUFFER_USUAL_SIZE
];
String
tmpstr
(
buff
,
sizeof
(
buff
),
&
my_charset_bin
);
uint
copy_length
;
const
char
*
well_formed_error_pos
;
const
char
*
cannot_convert_error_pos
;
const
char
*
from_end_pos
;
/* See the comment for Field_long::store(long long) */
DBUG_ASSERT
(
table
->
in_use
==
current_thd
);
/* Convert character set if necessary */
if
(
String
::
needs_conversion
(
length
,
cs
,
field_charset
,
&
not_used
))
{
uint
conv_errors
;
tmpstr
.
copy
(
from
,
length
,
cs
,
field_charset
,
&
conv_errors
);
from
=
tmpstr
.
ptr
();
length
=
tmpstr
.
length
();
if
(
conv_errors
)
error
=
2
;
}
/* Make sure we don't break a multibyte sequence or copy malformed data. */
copy_length
=
field_charset
->
cset
->
well_formed_len
(
field_charset
,
from
,
from
+
length
,
field_length
/
field_charset
->
mbmaxlen
,
&
well_formed_error
);
memmove
(
ptr
,
from
,
copy_length
);
copy_length
=
well_formed_copy_nchars
(
field_charset
,
ptr
,
field_length
,
cs
,
from
,
length
,
field_length
/
field_charset
->
mbmaxlen
,
&
well_formed_error_pos
,
&
cannot_convert_error_pos
,
&
from_end_pos
);
/* Append spaces if the string was shorter than the field. */
if
(
copy_length
<
field_length
)
...
...
@@ -5821,32 +5932,23 @@ int Field_string::store(const char *from,uint length,CHARSET_INFO *cs)
field_length
-
copy_length
,
field_charset
->
pad_char
);
if
(
check_string_copy_error
(
this
,
well_formed_error_pos
,
cannot_convert_error_pos
,
from
+
length
))
return
2
;
/*
Check if we lost any important data (anything in a binary string,
or any non-space in others).
*/
if
((
copy_length
<
length
)
&&
table
->
in_use
->
count_cuted_fields
)
if
((
from_end_pos
<
from
+
length
)
&&
table
->
in_use
->
count_cuted_fields
)
{
if
(
binary
())
error
=
2
;
else
if
(
test_if_important_data
(
field_charset
,
from_end_pos
,
from
+
length
))
{
const
char
*
end
=
from
+
length
;
from
+=
copy_length
;
from
+=
field_charset
->
cset
->
scan
(
field_charset
,
from
,
end
,
MY_SEQ_SPACES
);
if
(
from
!=
end
)
error
=
2
;
report_data_too_long
(
this
);
return
2
;
}
}
if
(
error
)
{
if
(
table
->
in_use
->
abort_on_warning
)
set_warning
(
MYSQL_ERROR
::
WARN_LEVEL_ERROR
,
ER_DATA_TOO_LONG
,
1
);
else
set_warning
(
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
WARN_DATA_TRUNCATED
,
1
);
}
return
error
;
return
0
;
}
...
...
@@ -6179,58 +6281,35 @@ Field *Field_string::new_field(MEM_ROOT *root, struct st_table *new_table,
int
Field_varstring
::
store
(
const
char
*
from
,
uint
length
,
CHARSET_INFO
*
cs
)
{
uint32
not_used
,
copy_length
;
char
buff
[
STRING_BUFFER_USUAL_SIZE
];
String
tmpstr
(
buff
,
sizeof
(
buff
),
&
my_charset_bin
);
int
error_code
=
0
,
well_formed_error
;
enum
MYSQL_ERROR
::
enum_warning_level
level
=
MYSQL_ERROR
::
WARN_LEVEL_WARN
;
uint
copy_length
;
const
char
*
well_formed_error_pos
;
const
char
*
cannot_convert_error_pos
;
const
char
*
from_end_pos
;
copy_length
=
well_formed_copy_nchars
(
field_charset
,
ptr
+
length_bytes
,
field_length
,
cs
,
from
,
length
,
field_length
/
field_charset
->
mbmaxlen
,
&
well_formed_error_pos
,
&
cannot_convert_error_pos
,
&
from_end_pos
);
/* Convert character set if necessary */
if
(
String
::
needs_conversion
(
length
,
cs
,
field_charset
,
&
not_used
))
{
uint
conv_errors
;
tmpstr
.
copy
(
from
,
length
,
cs
,
field_charset
,
&
conv_errors
);
from
=
tmpstr
.
ptr
();
length
=
tmpstr
.
length
();
if
(
conv_errors
)
error_code
=
WARN_DATA_TRUNCATED
;
}
/*
Make sure we don't break a multibyte sequence
as well as don't copy a malformed data.
*/
copy_length
=
field_charset
->
cset
->
well_formed_len
(
field_charset
,
from
,
from
+
length
,
field_length
/
field_charset
->
mbmaxlen
,
&
well_formed_error
);
memmove
(
ptr
+
length_bytes
,
from
,
copy_length
);
if
(
length_bytes
==
1
)
*
ptr
=
(
uchar
)
copy_length
;
else
int2store
(
ptr
,
copy_length
);
if
(
check_string_copy_error
(
this
,
well_formed_error_pos
,
cannot_convert_error_pos
,
from
+
length
))
return
2
;
// Check if we lost something other than just trailing spaces
if
((
copy_length
<
length
)
&&
table
->
in_use
->
count_cuted_fields
&&
!
error_code
)
{
if
(
!
binary
())
{
const
char
*
end
=
from
+
length
;
from
+=
copy_length
;
from
+=
field_charset
->
cset
->
scan
(
field_charset
,
from
,
end
,
MY_SEQ_SPACES
);
/* If we lost only spaces then produce a NOTE, not a WARNING */
if
(
from
==
end
)
level
=
MYSQL_ERROR
::
WARN_LEVEL_NOTE
;
}
error_code
=
WARN_DATA_TRUNCATED
;
}
if
(
error_code
)
if
((
from_end_pos
<
from
+
length
)
&&
table
->
in_use
->
count_cuted_fields
)
{
if
(
level
==
MYSQL_ERROR
::
WARN_LEVEL_WARN
&&
table
->
in_use
->
abort_on_warning
)
error_code
=
ER_DATA_TOO_LONG
;
set_warning
(
level
,
error_code
,
1
);
if
(
test_if_important_data
(
field_charset
,
from_end_pos
,
from
+
length
))
report_data_too_long
(
this
);
else
/* If we lost only spaces then produce a NOTE, not a WARNING */
set_warning
(
MYSQL_ERROR
::
WARN_LEVEL_NOTE
,
WARN_DATA_TRUNCATED
,
1
);
return
2
;
}
return
0
;
...
...
@@ -6812,68 +6891,70 @@ void Field_blob::put_length(char *pos, uint32 length)
int
Field_blob
::
store
(
const
char
*
from
,
uint
length
,
CHARSET_INFO
*
cs
)
{
int
error
=
0
,
well_formed_error
;
uint
copy_length
,
new_length
;
const
char
*
well_formed_error_pos
;
const
char
*
cannot_convert_error_pos
;
const
char
*
from_end_pos
,
*
tmp
;
char
buff
[
STRING_BUFFER_USUAL_SIZE
];
String
tmpstr
(
buff
,
sizeof
(
buff
),
&
my_charset_bin
);
if
(
!
length
)
{
bzero
(
ptr
,
Field_blob
::
pack_length
());
return
0
;
}
else
{
bool
was_conversion
;
char
buff
[
STRING_BUFFER_USUAL_SIZE
];
String
tmpstr
(
buff
,
sizeof
(
buff
),
&
my_charset_bin
);
uint
copy_length
;
uint32
not_used
;
/* Convert character set if necessary */
if
((
was_conversion
=
String
::
needs_conversion
(
length
,
cs
,
field_charset
,
&
not_used
)))
{
uint
conv_errors
;
if
(
tmpstr
.
copy
(
from
,
length
,
cs
,
field_charset
,
&
conv_errors
))
{
/* Fatal OOM error */
bzero
(
ptr
,
Field_blob
::
pack_length
());
return
-
1
;
}
from
=
tmpstr
.
ptr
();
length
=
tmpstr
.
length
();
if
(
conv_errors
)
error
=
2
;
}
copy_length
=
max_data_length
();
/*
copy_length is OK as last argument to well_formed_len as this is never
used to limit the length of the data. The cut of long data is done with
the 'min()' call below.
*/
copy_length
=
field_charset
->
cset
->
well_formed_len
(
field_charset
,
from
,
from
+
min
(
length
,
copy_length
),
copy_length
,
&
well_formed_error
);
if
(
copy_length
<
length
)
error
=
2
;
Field_blob
::
store_length
(
copy_length
);
if
(
was_conversion
||
table
->
copy_blobs
||
copy_length
<=
MAX_FIELD_WIDTH
)
{
// Must make a copy
if
(
from
!=
value
.
ptr
())
// For valgrind
{
value
.
copy
(
from
,
copy_length
,
charset
());
from
=
value
.
ptr
();
}
if
(
from
==
value
.
ptr
())
{
uint32
dummy_offset
;
if
(
!
String
::
needs_conversion
(
length
,
cs
,
field_charset
,
&
dummy_offset
))
{
Field_blob
::
store_length
(
length
);
bmove
(
ptr
+
packlength
,(
char
*
)
&
from
,
sizeof
(
char
*
));
return
0
;
}
bmove
(
ptr
+
packlength
,(
char
*
)
&
from
,
sizeof
(
char
*
));
if
(
tmpstr
.
copy
(
from
,
length
,
cs
))
goto
oom_error
;
from
=
tmpstr
.
ptr
();
}
if
(
error
)
new_length
=
min
(
max_data_length
(),
field_charset
->
mbmaxlen
*
length
);
if
(
value
.
alloc
(
new_length
))
goto
oom_error
;
/*
"length" is OK as "nchars" argument to well_formed_copy_nchars as this
is never used to limit the length of the data. The cut of long data
is done with the new_length value.
*/
copy_length
=
well_formed_copy_nchars
(
field_charset
,
(
char
*
)
value
.
ptr
(),
new_length
,
cs
,
from
,
length
,
length
,
&
well_formed_error_pos
,
&
cannot_convert_error_pos
,
&
from_end_pos
);
Field_blob
::
store_length
(
copy_length
);
tmp
=
value
.
ptr
();
bmove
(
ptr
+
packlength
,(
char
*
)
&
tmp
,
sizeof
(
char
*
));
if
(
check_string_copy_error
(
this
,
well_formed_error_pos
,
cannot_convert_error_pos
,
from
+
length
))
return
2
;
if
(
copy_length
<
length
)
{
if
(
table
->
in_use
->
abort_on_warning
)
set_warning
(
MYSQL_ERROR
::
WARN_LEVEL_ERROR
,
ER_DATA_TOO_LONG
,
1
);
else
set_warning
(
MYSQL_ERROR
::
WARN_LEVEL_WARN
,
WARN_DATA_TRUNCATED
,
1
);
report_data_too_long
(
this
);
return
2
;
}
return
0
;
oom_error:
/* Fatal OOM error */
bzero
(
ptr
,
Field_blob
::
pack_length
());
return
-
1
;
}
...
...
sql/slave.cc
View file @
aea1e14e
...
...
@@ -3345,9 +3345,9 @@ static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli)
const
char
*
errmsg
;
/*
We were in a transaction which has been rolled back because of a
deadlock (currently, InnoDB deadlock detected by InnoDB) or lock
wait timeout (innodb_lock_wait_timeout exceeded); let's seek back to
BEGIN log event and retry it all again.
Sonera deadlock. if lock wait timeout (innodb_lock_wait_timeout exceeded)
there is no rollback since 5.0.13 (ref: manual).
let's seek back to
BEGIN log event and retry it all again.
We have to not only seek but also
a) init_master_info(), to seek back to hot relay log's start for later
(for when we will come back to this hot log after re-processing the
...
...
@@ -3369,6 +3369,7 @@ static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli)
else
{
exec_res
=
0
;
end_trans
(
thd
,
ROLLBACK
);
/* chance for concurrent connection to get more locks */
safe_sleep
(
thd
,
min
(
rli
->
trans_retries
,
MAX_SLAVE_RETRY_PAUSE
),
(
CHECK_KILLED_FUNC
)
sql_slave_killed
,
(
void
*
)
rli
);
...
...
@@ -3386,9 +3387,17 @@ static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli)
"the slave_transaction_retries variable."
,
slave_trans_retries
);
}
if
(
!
((
thd
->
options
&
OPTION_BEGIN
)
&&
opt_using_transactions
))
rli
->
trans_retries
=
0
;
// restart from fresh
}
else
if
(
!
((
thd
->
options
&
OPTION_BEGIN
)
&&
opt_using_transactions
))
{
/*
Only reset the retry counter if the event succeeded or
failed with a non-transient error. On a successful event,
the execution will proceed as usual; in the case of a
non-transient error, the slave will stop with an error.
*/
rli
->
trans_retries
=
0
;
// restart from fresh
}
}
return
exec_res
;
}
else
...
...
sql/sql_parse.cc
View file @
aea1e14e
...
...
@@ -2503,7 +2503,23 @@ mysql_execute_command(THD *thd)
{
/* we warn the slave SQL thread */
my_message
(
ER_SLAVE_IGNORED_TABLE
,
ER
(
ER_SLAVE_IGNORED_TABLE
),
MYF
(
0
));
reset_one_shot_variables
(
thd
);
if
(
thd
->
one_shot_set
)
{
/*
It's ok to check thd->one_shot_set here:
The charsets in a MySQL 5.0 slave can change by both a binlogged
SET ONE_SHOT statement and the event-internal charset setting,
and these two ways to change charsets do not seems to work
together.
At least there seems to be problems in the rli cache for
charsets if we are using ONE_SHOT. Note that this is normally no
problem because either the >= 5.0 slave reads a 4.1 binlog (with
ONE_SHOT) *or* or 5.0 binlog (without ONE_SHOT) but never both."
*/
reset_one_shot_variables
(
thd
);
}
DBUG_RETURN
(
0
);
}
}
...
...
@@ -6121,7 +6137,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
ptr
->
alias
=
alias_str
;
if
(
lower_case_table_names
&&
table
->
table
.
length
)
my_casedn_str
(
files_charset_info
,
table
->
table
.
str
);
table
->
table
.
length
=
my_casedn_str
(
files_charset_info
,
table
->
table
.
str
);
ptr
->
table_name
=
table
->
table
.
str
;
ptr
->
table_name_length
=
table
->
table
.
length
;
ptr
->
lock_type
=
lock_type
;
...
...
sql/sql_string.cc
View file @
aea1e14e
...
...
@@ -854,6 +854,162 @@ copy_and_convert(char *to, uint32 to_length, CHARSET_INFO *to_cs,
}
/*
copy a string,
with optional character set conversion,
with optional left padding (for binary -> UCS2 conversion)
SYNOPSIS
well_formed_copy_nhars()
to Store result here
to_length Maxinum length of "to" string
to_cs Character set of "to" string
from Copy from here
from_length Length of from string
from_cs From character set
nchars Copy not more that nchars characters
well_formed_error_pos Return position when "from" is not well formed
or NULL otherwise.
cannot_convert_error_pos Return position where a not convertable
character met, or NULL otherwise.
from_end_pos Return position where scanning of "from"
string stopped.
NOTES
RETURN
length of bytes copied to 'to'
*/
uint32
well_formed_copy_nchars
(
CHARSET_INFO
*
to_cs
,
char
*
to
,
uint
to_length
,
CHARSET_INFO
*
from_cs
,
const
char
*
from
,
uint
from_length
,
uint
nchars
,
const
char
**
well_formed_error_pos
,
const
char
**
cannot_convert_error_pos
,
const
char
**
from_end_pos
)
{
uint
res
;
if
((
to_cs
==
&
my_charset_bin
)
||
(
from_cs
==
&
my_charset_bin
)
||
(
to_cs
==
from_cs
)
||
my_charset_same
(
from_cs
,
to_cs
))
{
if
(
to_length
<
to_cs
->
mbminlen
||
!
nchars
)
{
*
from_end_pos
=
from
;
*
cannot_convert_error_pos
=
NULL
;
*
well_formed_error_pos
=
NULL
;
return
0
;
}
if
(
to_cs
==
&
my_charset_bin
)
{
res
=
min
(
min
(
nchars
,
to_length
),
from_length
);
memmove
(
to
,
from
,
res
);
*
from_end_pos
=
from
+
res
;
*
well_formed_error_pos
=
NULL
;
*
cannot_convert_error_pos
=
NULL
;
}
else
{
int
well_formed_error
;
uint
from_offset
;
if
((
from_offset
=
(
from_length
%
to_cs
->
mbminlen
))
&&
(
from_cs
==
&
my_charset_bin
))
{
/*
Copying from BINARY to UCS2 needs to prepend zeros sometimes:
INSERT INTO t1 (ucs2_column) VALUES (0x01);
0x01 -> 0x0001
*/
uint
pad_length
=
to_cs
->
mbminlen
-
from_offset
;
bzero
(
to
,
pad_length
);
memmove
(
to
+
pad_length
,
from
,
from_offset
);
nchars
--
;
from
+=
from_offset
;
from_length
-=
from_offset
;
to
+=
to_cs
->
mbminlen
;
to_length
-=
to_cs
->
mbminlen
;
}
set_if_smaller
(
from_length
,
to_length
);
res
=
to_cs
->
cset
->
well_formed_len
(
to_cs
,
from
,
from
+
from_length
,
nchars
,
&
well_formed_error
);
memmove
(
to
,
from
,
res
);
*
from_end_pos
=
from
+
res
;
*
well_formed_error_pos
=
well_formed_error
?
from
+
res
:
NULL
;
*
cannot_convert_error_pos
=
NULL
;
if
(
from_offset
)
res
+=
to_cs
->
mbminlen
;
}
}
else
{
int
cnvres
;
my_wc_t
wc
;
int
(
*
mb_wc
)(
struct
charset_info_st
*
,
my_wc_t
*
,
const
uchar
*
,
const
uchar
*
)
=
from_cs
->
cset
->
mb_wc
;
int
(
*
wc_mb
)(
struct
charset_info_st
*
,
my_wc_t
,
uchar
*
s
,
uchar
*
e
)
=
to_cs
->
cset
->
wc_mb
;
const
uchar
*
from_end
=
(
const
uchar
*
)
from
+
from_length
;
uchar
*
to_end
=
(
uchar
*
)
to
+
to_length
;
char
*
to_start
=
to
;
*
well_formed_error_pos
=
NULL
;
*
cannot_convert_error_pos
=
NULL
;
for
(
;
nchars
;
nchars
--
)
{
const
char
*
from_prev
=
from
;
if
((
cnvres
=
(
*
mb_wc
)(
from_cs
,
&
wc
,
(
uchar
*
)
from
,
from_end
))
>
0
)
from
+=
cnvres
;
else
if
(
cnvres
==
MY_CS_ILSEQ
)
{
if
(
!*
well_formed_error_pos
)
*
well_formed_error_pos
=
from
;
from
++
;
wc
=
'?'
;
}
else
if
(
cnvres
>
MY_CS_TOOSMALL
)
{
/*
A correct multibyte sequence detected
But it doesn't have Unicode mapping.
*/
if
(
!*
cannot_convert_error_pos
)
*
cannot_convert_error_pos
=
from
;
from
+=
(
-
cnvres
);
wc
=
'?'
;
}
else
break
;
// Not enough characters
outp:
if
((
cnvres
=
(
*
wc_mb
)(
to_cs
,
wc
,
(
uchar
*
)
to
,
to_end
))
>
0
)
to
+=
cnvres
;
else
if
(
cnvres
==
MY_CS_ILUNI
&&
wc
!=
'?'
)
{
if
(
!*
cannot_convert_error_pos
)
*
cannot_convert_error_pos
=
from_prev
;
wc
=
'?'
;
goto
outp
;
}
else
break
;
}
*
from_end_pos
=
from
;
res
=
to
-
to_start
;
}
return
(
uint32
)
res
;
}
void
String
::
print
(
String
*
str
)
{
char
*
st
=
(
char
*
)
Ptr
,
*
end
=
st
+
str_length
;
...
...
sql/sql_string.h
View file @
aea1e14e
...
...
@@ -32,6 +32,14 @@ String *copy_if_not_alloced(String *a,String *b,uint32 arg_length);
uint32
copy_and_convert
(
char
*
to
,
uint32
to_length
,
CHARSET_INFO
*
to_cs
,
const
char
*
from
,
uint32
from_length
,
CHARSET_INFO
*
from_cs
,
uint
*
errors
);
uint32
well_formed_copy_nchars
(
CHARSET_INFO
*
to_cs
,
char
*
to
,
uint
to_length
,
CHARSET_INFO
*
from_cs
,
const
char
*
from
,
uint
from_length
,
uint
nchars
,
const
char
**
well_formed_error_pos
,
const
char
**
cannot_convert_error_pos
,
const
char
**
from_end_pos
);
class
String
{
...
...
strings/ctype-bin.c
View file @
aea1e14e
...
...
@@ -211,9 +211,10 @@ static int my_strnncollsp_8bit_bin(CHARSET_INFO * cs __attribute__((unused)),
/* This function is used for all conversion functions */
static
void
my_case_str_bin
(
CHARSET_INFO
*
cs
__attribute__
((
unused
)),
static
uint
my_case_str_bin
(
CHARSET_INFO
*
cs
__attribute__
((
unused
)),
char
*
str
__attribute__
((
unused
)))
{
return
0
;
}
static
uint
my_case_bin
(
CHARSET_INFO
*
cs
__attribute__
((
unused
)),
...
...
strings/ctype-mb.c
View file @
aea1e14e
...
...
@@ -21,40 +21,44 @@
#ifdef USE_MB
void
my_caseup_str_mb
(
CHARSET_INFO
*
cs
,
char
*
str
)
uint
my_caseup_str_mb
(
CHARSET_INFO
*
cs
,
char
*
str
)
{
register
uint32
l
;
register
uchar
*
map
=
cs
->
to_upper
;
register
uchar
*
map
=
cs
->
to_upper
;
char
*
str_orig
=
str
;
while
(
*
str
)
{
/* Pointing after the '\0' is safe here. */
if
((
l
=
my_ismbchar
(
cs
,
str
,
str
+
cs
->
mbmaxlen
)))
str
+=
l
;
if
((
l
=
my_ismbchar
(
cs
,
str
,
str
+
cs
->
mbmaxlen
)))
str
+=
l
;
else
{
*
str
=
(
char
)
map
[(
uchar
)
*
str
];
*
str
=
(
char
)
map
[(
uchar
)
*
str
];
str
++
;
}
}
return
str
-
str_orig
;
}
void
my_casedn_str_mb
(
CHARSET_INFO
*
cs
,
char
*
str
)
uint
my_casedn_str_mb
(
CHARSET_INFO
*
cs
,
char
*
str
)
{
register
uint32
l
;
register
uchar
*
map
=
cs
->
to_lower
;
register
uchar
*
map
=
cs
->
to_lower
;
char
*
str_orig
=
str
;
while
(
*
str
)
{
/* Pointing after the '\0' is safe here. */
if
((
l
=
my_ismbchar
(
cs
,
str
,
str
+
cs
->
mbmaxlen
)))
str
+=
l
;
if
((
l
=
my_ismbchar
(
cs
,
str
,
str
+
cs
->
mbmaxlen
)))
str
+=
l
;
else
{
*
str
=
(
char
)
map
[(
uchar
)
*
str
];
*
str
=
(
char
)
map
[(
uchar
)
*
str
];
str
++
;
}
}
return
str
-
str_orig
;
}
uint
my_caseup_mb
(
CHARSET_INFO
*
cs
,
char
*
src
,
uint
srclen
,
...
...
strings/ctype-simple.c
View file @
aea1e14e
...
...
@@ -188,20 +188,26 @@ int my_strnncollsp_simple(CHARSET_INFO * cs, const uchar *a, uint a_length,
}
void
my_caseup_str_8bit
(
CHARSET_INFO
*
cs
,
char
*
str
)
uint
my_caseup_str_8bit
(
CHARSET_INFO
*
cs
,
char
*
str
)
{
register
uchar
*
map
=
cs
->
to_upper
;
while
((
*
str
=
(
char
)
map
[(
uchar
)
*
str
])
!=
0
)
register
uchar
*
map
=
cs
->
to_upper
;
char
*
str_orig
=
str
;
while
((
*
str
=
(
char
)
map
[(
uchar
)
*
str
])
!=
0
)
str
++
;
return
str
-
str_orig
;
}
void
my_casedn_str_8bit
(
CHARSET_INFO
*
cs
,
char
*
str
)
uint
my_casedn_str_8bit
(
CHARSET_INFO
*
cs
,
char
*
str
)
{
register
uchar
*
map
=
cs
->
to_lower
;
while
((
*
str
=
(
char
)
map
[(
uchar
)
*
str
])
!=
0
)
register
uchar
*
map
=
cs
->
to_lower
;
char
*
str_orig
=
str
;
while
((
*
str
=
(
char
)
map
[(
uchar
)
*
str
])
!=
0
)
str
++
;
return
str
-
str_orig
;
}
uint
my_caseup_8bit
(
CHARSET_INFO
*
cs
,
char
*
src
,
uint
srclen
,
char
*
dst
__attribute__
((
unused
)),
uint
dstlen
__attribute__
((
unused
)))
...
...
strings/ctype-ucs2.c
View file @
aea1e14e
...
...
@@ -159,13 +159,13 @@ static void my_hash_sort_ucs2(CHARSET_INFO *cs, const uchar *s, uint slen,
}
static
void
my_caseup_str_ucs2
(
CHARSET_INFO
*
cs
__attribute__
((
unused
)),
static
uint
my_caseup_str_ucs2
(
CHARSET_INFO
*
cs
__attribute__
((
unused
)),
char
*
s
__attribute__
((
unused
)))
{
return
0
;
}
static
uint
my_casedn_ucs2
(
CHARSET_INFO
*
cs
,
char
*
src
,
uint
srclen
,
char
*
dst
__attribute__
((
unused
)),
uint
dstlen
__attribute__
((
unused
)))
...
...
@@ -188,9 +188,11 @@ static uint my_casedn_ucs2(CHARSET_INFO *cs, char *src, uint srclen,
return
srclen
;
}
static
void
my_casedn_str_ucs2
(
CHARSET_INFO
*
cs
__attribute__
((
unused
)),
static
uint
my_casedn_str_ucs2
(
CHARSET_INFO
*
cs
__attribute__
((
unused
)),
char
*
s
__attribute__
((
unused
)))
{
return
0
;
}
...
...
strings/ctype-utf8.c
View file @
aea1e14e
...
...
@@ -2045,6 +2045,52 @@ static int my_utf8_uni(CHARSET_INFO *cs __attribute__((unused)),
return
MY_CS_ILSEQ
;
}
/*
The same as above, but without range check
for example, for a null-terminated string
*/
static
int
my_utf8_uni_no_range
(
CHARSET_INFO
*
cs
__attribute__
((
unused
)),
my_wc_t
*
pwc
,
const
uchar
*
s
)
{
unsigned
char
c
;
c
=
s
[
0
];
if
(
c
<
0x80
)
{
*
pwc
=
c
;
return
1
;
}
if
(
c
<
0xc2
)
return
MY_CS_ILSEQ
;
if
(
c
<
0xe0
)
{
if
(
!
((
s
[
1
]
^
0x80
)
<
0x40
))
return
MY_CS_ILSEQ
;
*
pwc
=
((
my_wc_t
)
(
c
&
0x1f
)
<<
6
)
|
(
my_wc_t
)
(
s
[
1
]
^
0x80
);
return
2
;
}
if
(
c
<
0xf0
)
{
if
(
!
((
s
[
1
]
^
0x80
)
<
0x40
&&
(
s
[
2
]
^
0x80
)
<
0x40
&&
(
c
>=
0xe1
||
s
[
1
]
>=
0xa0
)))
return
MY_CS_ILSEQ
;
*
pwc
=
((
my_wc_t
)
(
c
&
0x0f
)
<<
12
)
|
((
my_wc_t
)
(
s
[
1
]
^
0x80
)
<<
6
)
|
(
my_wc_t
)
(
s
[
2
]
^
0x80
);
return
3
;
}
return
MY_CS_ILSEQ
;
}
static
int
my_uni_utf8
(
CHARSET_INFO
*
cs
__attribute__
((
unused
))
,
my_wc_t
wc
,
uchar
*
r
,
uchar
*
e
)
{
...
...
@@ -2091,6 +2137,34 @@ static int my_uni_utf8 (CHARSET_INFO *cs __attribute__((unused)) ,
}
/*
The same as above, but without range check.
*/
static
int
my_uni_utf8_no_range
(
CHARSET_INFO
*
cs
__attribute__
((
unused
)),
my_wc_t
wc
,
uchar
*
r
)
{
int
count
;
if
(
wc
<
0x80
)
count
=
1
;
else
if
(
wc
<
0x800
)
count
=
2
;
else
if
(
wc
<
0x10000
)
count
=
3
;
else
return
MY_CS_ILUNI
;
switch
(
count
)
{
/* Fall through all cases!!! */
case
3
:
r
[
2
]
=
(
uchar
)
(
0x80
|
(
wc
&
0x3f
));
wc
=
wc
>>
6
;
wc
|=
0x800
;
case
2
:
r
[
1
]
=
(
uchar
)
(
0x80
|
(
wc
&
0x3f
));
wc
=
wc
>>
6
;
wc
|=
0xc0
;
case
1
:
r
[
0
]
=
(
uchar
)
wc
;
}
return
count
;
}
static
uint
my_caseup_utf8
(
CHARSET_INFO
*
cs
,
char
*
src
,
uint
srclen
,
char
*
dst
,
uint
dstlen
)
{
...
...
@@ -2141,10 +2215,26 @@ static void my_hash_sort_utf8(CHARSET_INFO *cs, const uchar *s, uint slen,
}
static
void
my_caseup_str_utf8
(
CHARSET_INFO
*
cs
,
char
*
s
)
static
uint
my_caseup_str_utf8
(
CHARSET_INFO
*
cs
,
char
*
src
)
{
uint
len
=
(
uint
)
strlen
(
s
);
my_caseup_utf8
(
cs
,
s
,
len
,
s
,
len
);
my_wc_t
wc
;
int
srcres
,
dstres
;
char
*
dst
=
src
,
*
dst0
=
src
;
MY_UNICASE_INFO
**
uni_plane
=
cs
->
caseinfo
;
DBUG_ASSERT
(
cs
->
caseup_multiply
==
1
);
while
(
*
src
&&
(
srcres
=
my_utf8_uni_no_range
(
cs
,
&
wc
,
(
uchar
*
)
src
))
>
0
)
{
int
plane
=
(
wc
>>
8
)
&
0xFF
;
wc
=
uni_plane
[
plane
]
?
uni_plane
[
plane
][
wc
&
0xFF
].
toupper
:
wc
;
if
((
dstres
=
my_uni_utf8_no_range
(
cs
,
wc
,
(
uchar
*
)
dst
))
<=
0
)
break
;
src
+=
srcres
;
dst
+=
dstres
;
}
*
dst
=
'\0'
;
return
(
uint
)
(
dst
-
dst0
);
}
...
...
@@ -2170,10 +2260,43 @@ static uint my_casedn_utf8(CHARSET_INFO *cs, char *src, uint srclen,
return
(
uint
)
(
dst
-
dst0
);
}
static
void
my_casedn_str_utf8
(
CHARSET_INFO
*
cs
,
char
*
s
)
static
uint
my_casedn_str_utf8
(
CHARSET_INFO
*
cs
,
char
*
src
)
{
uint
len
=
(
uint
)
strlen
(
s
);
my_casedn_utf8
(
cs
,
s
,
len
,
s
,
len
);
my_wc_t
wc
;
int
srcres
,
dstres
;
char
*
dst
=
src
,
*
dst0
=
src
;
MY_UNICASE_INFO
**
uni_plane
=
cs
->
caseinfo
;
DBUG_ASSERT
(
cs
->
casedn_multiply
==
1
);
while
(
*
src
&&
(
srcres
=
my_utf8_uni_no_range
(
cs
,
&
wc
,
(
uchar
*
)
src
))
>
0
)
{
int
plane
=
(
wc
>>
8
)
&
0xFF
;
wc
=
uni_plane
[
plane
]
?
uni_plane
[
plane
][
wc
&
0xFF
].
tolower
:
wc
;
if
((
dstres
=
my_uni_utf8_no_range
(
cs
,
wc
,
(
uchar
*
)
dst
))
<=
0
)
break
;
src
+=
srcres
;
dst
+=
dstres
;
}
/*
In rare cases lower string can be shorter than
the original string, for example:
"U+0130 LATIN CAPITAL LETTER I WITH DOT ABOVE"
(which is 0xC4B0 in utf8, i.e. two bytes)
is converted into
"U+0069 LATIN SMALL LETTER I"
(which is 0x69 in utf8, i.e. one byte)
So, we need to put '\0' terminator after converting.
*/
*
dst
=
'\0'
;
return
(
uint
)
(
dst
-
dst0
);
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment