Updates for multi-byte character sets

(Note: test 'union' fails, but Sanja promised to fix this)
This commit is contained in:
monty@mashka.mysql.fi 2003-01-14 14:28:36 +02:00
parent c9dc5a206b
commit 7e9b27eaf5
38 changed files with 567 additions and 492 deletions

View file

@ -134,7 +134,7 @@ typedef struct charset_info_st
ulong (*strntoul)(struct charset_info_st *, const char *s, uint l, char **e, int base);
longlong (*strntoll)(struct charset_info_st *, const char *s, uint l, char **e, int base);
ulonglong (*strntoull)(struct charset_info_st *, const char *s, uint l, char **e, int base);
double (*strntod)(struct charset_info_st *, const char *s, uint l, char **e);
double (*strntod)(struct charset_info_st *, char *s, uint l, char **e);
} CHARSET_INFO;
@ -178,7 +178,7 @@ long my_strntol_8bit(CHARSET_INFO *, const char *s, uint l,char **e, int
ulong my_strntoul_8bit(CHARSET_INFO *, const char *s, uint l,char **e, int base);
longlong my_strntoll_8bit(CHARSET_INFO *, const char *s, uint l,char **e, int base);
ulonglong my_strntoull_8bit(CHARSET_INFO *, const char *s, uint l,char **e, int base);
double my_strntod_8bit(CHARSET_INFO *, const char *s, uint l,char **e);
double my_strntod_8bit(CHARSET_INFO *, char *s, uint l,char **e);
int my_l10tostr_8bit(CHARSET_INFO *, char *to, uint l, int radix, long int val);
int my_ll10tostr_8bit(CHARSET_INFO *, char *to, uint l, int radix, longlong val);

View file

@ -238,6 +238,12 @@ extern ulonglong strtoull(const char *str, char **ptr, int base);
#endif
#endif
/* my_vsnprintf.c */
extern int my_vsnprintf( char *str, size_t n,
const char *format, va_list ap );
extern int my_snprintf(char* to, size_t n, const char* fmt, ...);
#if defined(__cplusplus) && !defined(OS2)
}
#endif

View file

@ -569,9 +569,6 @@ extern int my_error _VARARGS((int nr,myf MyFlags, ...));
extern int my_printf_error _VARARGS((uint my_err, const char *format,
myf MyFlags, ...)
__attribute__ ((format (printf, 2, 4))));
extern int my_vsnprintf( char *str, size_t n,
const char *format, va_list ap );
extern int my_snprintf(char* to, size_t n, const char* fmt, ...);
extern int my_message(uint my_err, const char *str,myf MyFlags);
extern int my_message_no_curses(uint my_err, const char *str,myf MyFlags);
extern int my_message_curses(uint my_err, const char *str,myf MyFlags);

View file

@ -37,7 +37,7 @@ mystringsobjects = strmov.lo strxmov.lo strxnmov.lo strnmov.lo \
int2str.lo str2int.lo strinstr.lo strcont.lo \
strcend.lo bcmp.lo \
bchange.lo bmove.lo bmove_upp.lo longlong2str.lo \
strtoull.lo strtoll.lo llstr.lo \
strtoull.lo strtoll.lo llstr.lo my_vsnprintf.lo \
ctype.lo ctype-simple.lo ctype-bin.lo ctype-mb.lo \
ctype-big5.lo ctype-czech.lo ctype-euc_kr.lo \
ctype-win1250ch.lo ctype-utf8.lo \
@ -60,7 +60,7 @@ mysysobjects1 = my_init.lo my_static.lo my_malloc.lo my_realloc.lo \
my_compress.lo array.lo my_once.lo list.lo my_net.lo \
charset.lo xml.lo hash.lo mf_iocache.lo \
mf_iocache2.lo my_seek.lo \
my_pread.lo mf_cache.lo my_vsnprintf.lo md5.lo sha1.lo\
my_pread.lo mf_cache.lo md5.lo sha1.lo\
my_getopt.lo my_gethostbyname.lo my_port.lo
sqlobjects = net.lo

View file

@ -53,7 +53,7 @@ SHOW FULL COLUMNS FROM t1;
Field Type Collation Null Key Default Extra Privileges Comment
GROUP_ID int(10) unsigned binary PRI 0 select,insert,update,references
LANG_ID smallint(5) unsigned binary PRI 0 select,insert,update,references
NAME char(80) character set latin1 latin1 MUL select,insert,update,references
NAME char(80) latin1 MUL select,insert,update,references
DROP TABLE t1;
create table t1 (n int);
insert into t1 values(9),(3),(12),(10);
@ -120,5 +120,5 @@ alter table t2 rename t1, add c char(10) comment "no comment";
show columns from t1;
Field Type Collation Null Key Default Extra
i int(10) unsigned binary PRI NULL auto_increment
c char(10) character set latin1 latin1 YES NULL
c char(10) latin1 YES NULL
drop table t1;

View file

@ -76,10 +76,10 @@ create table t1(x varchar(50) );
create table t2 select x from t1 where 1=2;
describe t1;
Field Type Collation Null Key Default Extra
x varchar(50) character set latin1 latin1 YES NULL
x varchar(50) latin1 YES NULL
describe t2;
Field Type Collation Null Key Default Extra
x char(50) character set latin1 latin1 YES NULL
x char(50) latin1 YES NULL
drop table t2;
create table t2 select now() as a , curtime() as b, curdate() as c , 1+1 as d , 1.0 + 1 as e , 33333333333333333 + 3 as f;
describe t2;
@ -181,7 +181,7 @@ show create table t3;
Table Create Table
t3 CREATE TABLE `t3` (
`id` int(11) NOT NULL default '0',
`name` char(20) character set latin1 default NULL
`name` char(20) default NULL
) TYPE=MyISAM CHARSET=latin1
select * from t3;
id name
@ -204,7 +204,7 @@ show create table t3;
Table Create Table
t3 CREATE TABLE `t3` (
`id` int(11) NOT NULL default '0',
`name` char(20) character set latin1 default NULL
`name` char(20) default NULL
) TYPE=MyISAM CHARSET=latin1
select * from t3;
id name
@ -219,14 +219,14 @@ show create table t3;
Table Create Table
t3 CREATE TEMPORARY TABLE `t3` (
`id` int(11) NOT NULL default '0',
`name` char(20) character set latin1 default NULL
`name` char(20) default NULL
) TYPE=MyISAM CHARSET=latin1
create table t2 like t3;
show create table t2;
Table Create Table
t2 CREATE TABLE `t2` (
`id` int(11) NOT NULL default '0',
`name` char(20) character set latin1 default NULL
`name` char(20) default NULL
) TYPE=MyISAM CHARSET=latin1
select * from t2;
id name

View file

@ -22,23 +22,23 @@ Table Create Table
t1 CREATE TABLE `t1` (
`comment` char(32) character set latin2 NOT NULL default '',
`koi8_ru_f` char(32) character set koi8r NOT NULL default '',
`latin5_f` char(32) character set latin5 NOT NULL default ''
`latin5_f` char(32) NOT NULL default ''
) TYPE=MyISAM CHARSET=latin5
ALTER TABLE t1 CHARSET=latin2;
ALTER TABLE t1 ADD latin2_f CHAR(32) NOT NULL;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`comment` char(32) character set latin2 NOT NULL default '',
`comment` char(32) NOT NULL default '',
`koi8_ru_f` char(32) character set koi8r NOT NULL default '',
`latin5_f` char(32) character set latin5 NOT NULL default '',
`latin2_f` char(32) character set latin2 NOT NULL default ''
`latin2_f` char(32) NOT NULL default ''
) TYPE=MyISAM CHARSET=latin2
ALTER TABLE t1 DROP latin2_f, DROP latin5_f;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`comment` char(32) character set latin2 NOT NULL default '',
`comment` char(32) NOT NULL default '',
`koi8_ru_f` char(32) character set koi8r NOT NULL default ''
) TYPE=MyISAM CHARSET=latin2
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('a','LAT SMALL A');

View file

@ -141,7 +141,7 @@ show create table t2;
Table Create Table
t2 CREATE TABLE `t2` (
`ticket` int(11) default NULL,
`inhalt` text character set latin1,
`inhalt` text,
KEY `tig` (`ticket`),
FULLTEXT KEY `tix` (`inhalt`)
) TYPE=MyISAM CHARSET=latin1

View file

@ -805,7 +805,7 @@ create table t1 (a char(20), index (a(5))) type=innodb;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` char(20) character set latin1 default NULL,
`a` char(20) default NULL,
KEY `a` (`a`)
) TYPE=InnoDB CHARSET=latin1
drop table t1;

View file

@ -172,7 +172,7 @@ show create table t3;
Table Create Table
t3 CREATE TABLE `t3` (
`a` int(11) NOT NULL default '0',
`b` char(20) character set latin1 default NULL,
`b` char(20) default NULL,
KEY `a` (`a`)
) TYPE=MRG_MyISAM CHARSET=latin1 UNION=(t1,t2)
create table t4 (a int not null, b char(10), key(a)) type=MERGE UNION=(t1,t2);

View file

@ -3221,17 +3221,17 @@ Field Type Collation Null Key Default Extra Privileges Comment
auto int(11) binary PRI NULL auto_increment select,insert,update,references
fld1 int(6) unsigned zerofill binary UNI 000000 select,insert,update,references
companynr tinyint(2) unsigned zerofill binary 00 select,insert,update,references
fld3 char(30) character set latin1 latin1 MUL select,insert,update,references
fld4 char(35) character set latin1 latin1 select,insert,update,references
fld5 char(35) character set latin1 latin1 select,insert,update,references
fld6 char(4) character set latin1 latin1 select,insert,update,references
fld3 char(30) latin1 MUL select,insert,update,references
fld4 char(35) latin1 select,insert,update,references
fld5 char(35) latin1 select,insert,update,references
fld6 char(4) latin1 select,insert,update,references
show full columns from t2 from test like 'f%';
Field Type Collation Null Key Default Extra Privileges Comment
fld1 int(6) unsigned zerofill binary UNI 000000 select,insert,update,references
fld3 char(30) character set latin1 latin1 MUL select,insert,update,references
fld4 char(35) character set latin1 latin1 select,insert,update,references
fld5 char(35) character set latin1 latin1 select,insert,update,references
fld6 char(4) character set latin1 latin1 select,insert,update,references
fld3 char(30) latin1 MUL select,insert,update,references
fld4 char(35) latin1 select,insert,update,references
fld5 char(35) latin1 select,insert,update,references
fld6 char(4) latin1 select,insert,update,references
show full columns from t2 from test like 's%';
Field Type Collation Null Key Default Extra Privileges Comment
show keys from t2;

View file

@ -93,14 +93,14 @@ c int not null comment 'int column'
show create table t1 ;
Table Create Table
t1 CREATE TABLE `t1` (
`test_set` set('val1','val2','val3') character set latin1 NOT NULL default '',
`name` char(20) character set latin1 default 'O''Brien' COMMENT 'O''Brien as default',
`test_set` set('val1','val2','val3') NOT NULL default '',
`name` char(20) default 'O''Brien' COMMENT 'O''Brien as default',
`c` int(11) NOT NULL default '0' COMMENT 'int column'
) TYPE=MyISAM CHARSET=latin1 COMMENT='it''s a table'
show full columns from t1;
Field Type Collation Null Key Default Extra Privileges Comment
test_set set('val1','val2','val3') character set latin1 latin1 select,insert,update,references
name char(20) character set latin1 latin1 YES O'Brien select,insert,update,references O'Brien as default
test_set set('val1','val2','val3') latin1 select,insert,update,references
name char(20) latin1 YES O'Brien select,insert,update,references O'Brien as default
c int(11) binary 0 select,insert,update,references int column
drop table t1;
create table t1 (a int not null, unique aa (a));
@ -133,7 +133,7 @@ show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) NOT NULL default '0',
`b` char(10) character set latin1 default NULL,
`b` char(10) default NULL,
KEY `b` (`b`)
) TYPE=MyISAM CHARSET=latin1 MIN_ROWS=10 MAX_ROWS=100 AVG_ROW_LENGTH=10 PACK_KEYS=1 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=FIXED COMMENT='test'
alter table t1 MAX_ROWS=200 ROW_FORMAT=dynamic PACK_KEYS=0;
@ -141,7 +141,7 @@ show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) NOT NULL default '0',
`b` varchar(10) character set latin1 default NULL,
`b` varchar(10) default NULL,
KEY `b` (`b`)
) TYPE=MyISAM CHARSET=latin1 MIN_ROWS=10 MAX_ROWS=200 AVG_ROW_LENGTH=10 PACK_KEYS=0 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC COMMENT='test'
ALTER TABLE t1 AVG_ROW_LENGTH=0 CHECKSUM=0 COMMENT="" MIN_ROWS=0 MAX_ROWS=0 PACK_KEYS=DEFAULT DELAY_KEY_WRITE=0 ROW_FORMAT=default;
@ -149,7 +149,7 @@ show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) NOT NULL default '0',
`b` varchar(10) character set latin1 default NULL,
`b` varchar(10) default NULL,
KEY `b` (`b`)
) TYPE=MyISAM CHARSET=latin1
drop table t1;

View file

@ -3,10 +3,10 @@ CREATE TABLE t1 (a blob, b text, c blob(250), d text(70000), e text(70000000));
show columns from t1;
Field Type Collation Null Key Default Extra
a blob binary YES NULL
b text character set latin1 latin1 YES NULL
b text latin1 YES NULL
c blob binary YES NULL
d mediumtext character set latin1 latin1 YES NULL
e longtext character set latin1 latin1 YES NULL
d mediumtext latin1 YES NULL
e longtext latin1 YES NULL
CREATE TABLE t2 (a char(257), b varchar(70000) binary, c varchar(70000000));
Warnings:
Warning 1244 Converting column 'a' from CHAR to TEXT
@ -14,14 +14,14 @@ Warning 1244 Converting column 'b' from CHAR to BLOB
Warning 1244 Converting column 'c' from CHAR to TEXT
show columns from t2;
Field Type Collation Null Key Default Extra
a text character set latin1 latin1 YES NULL
a text latin1 YES NULL
b mediumblob binary YES NULL
c longtext character set latin1 latin1 YES NULL
c longtext latin1 YES NULL
create table t3 (a long, b long byte);
show create TABLE t3;
Table Create Table
t3 CREATE TABLE `t3` (
`a` mediumtext character set latin1,
`a` mediumtext,
`b` mediumblob
) TYPE=MyISAM CHARSET=latin1
drop table t1,t2,t3
@ -70,15 +70,15 @@ update t1 set c="",b=null where c="1";
lock tables t1 READ;
show full fields from t1;
Field Type Collation Null Key Default Extra Privileges Comment
t text character set latin1 latin1 YES NULL select,insert,update,references
c varchar(10) character set latin1 latin1 YES NULL select,insert,update,references
t text latin1 YES NULL select,insert,update,references
c varchar(10) latin1 YES NULL select,insert,update,references
b blob binary YES NULL select,insert,update,references
d varchar(10) binary binary YES NULL select,insert,update,references
lock tables t1 WRITE;
show full fields from t1;
Field Type Collation Null Key Default Extra Privileges Comment
t text character set latin1 latin1 YES NULL select,insert,update,references
c varchar(10) character set latin1 latin1 YES NULL select,insert,update,references
t text latin1 YES NULL select,insert,update,references
c varchar(10) latin1 YES NULL select,insert,update,references
b blob binary YES NULL select,insert,update,references
d varchar(10) binary binary YES NULL select,insert,update,references
unlock tables;

View file

@ -1626,13 +1626,13 @@ create table t1 (a enum (' ','a','b') not null);
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` enum('','a','b') character set latin1 NOT NULL default ''
`a` enum('','a','b') NOT NULL default ''
) TYPE=MyISAM CHARSET=latin1
drop table t1;
create table t1 (a enum (' ','a','b ') not null default 'b ');
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` enum('','a','b') character set latin1 NOT NULL default 'b'
`a` enum('','a','b') NOT NULL default 'b'
) TYPE=MyISAM CHARSET=latin1
drop table t1;

View file

@ -40,7 +40,7 @@ KEY (options,flags)
show full fields from t1;
Field Type Collation Null Key Default Extra Privileges Comment
auto int(5) unsigned binary PRI NULL auto_increment select,insert,update,references
string varchar(10) character set latin1 latin1 YES hello select,insert,update,references
string varchar(10) latin1 YES hello select,insert,update,references
tiny tinyint(4) binary MUL 0 select,insert,update,references
short smallint(6) binary MUL 1 select,insert,update,references
medium mediumint(8) binary MUL 0 select,insert,update,references
@ -61,8 +61,8 @@ blob_col blob binary YES NULL select,insert,update,references
tinyblob_col tinyblob binary YES NULL select,insert,update,references
mediumblob_col mediumblob binary select,insert,update,references
longblob_col longblob binary select,insert,update,references
options enum('one','two','tree') character set latin1 latin1 MUL one select,insert,update,references
flags set('one','two','tree') character set latin1 latin1 select,insert,update,references
options enum('one','two','tree') latin1 MUL one select,insert,update,references
flags set('one','two','tree') latin1 select,insert,update,references
show keys from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
t1 0 PRIMARY 1 auto A 0 NULL NULL BTREE
@ -170,7 +170,7 @@ update t2 set string="changed" where auto=16;
show full columns from t1;
Field Type Collation Null Key Default Extra Privileges Comment
auto int(5) unsigned binary MUL NULL auto_increment select,insert,update,references
string varchar(10) character set latin1 latin1 YES new defaul select,insert,update,references
string varchar(10) latin1 YES new defaul select,insert,update,references
tiny tinyint(4) binary MUL 0 select,insert,update,references
short smallint(6) binary MUL 0 select,insert,update,references
medium mediumint(8) binary MUL 0 select,insert,update,references
@ -184,19 +184,19 @@ umedium mediumint(8) unsigned binary MUL 0 select,insert,update,references
ulong int(11) unsigned binary MUL 0 select,insert,update,references
ulonglong bigint(13) unsigned binary MUL 0 select,insert,update,references
time_stamp timestamp latin1 YES NULL select,insert,update,references
date_field varchar(10) character set latin1 latin1 YES NULL select,insert,update,references
date_field varchar(10) latin1 YES NULL select,insert,update,references
time_field time latin1 YES NULL select,insert,update,references
date_time datetime latin1 YES NULL select,insert,update,references
new_blob_col varchar(20) character set latin1 latin1 YES NULL select,insert,update,references
new_blob_col varchar(20) latin1 YES NULL select,insert,update,references
tinyblob_col tinyblob binary YES NULL select,insert,update,references
mediumblob_col mediumblob binary select,insert,update,references
options enum('one','two','tree') character set latin1 latin1 MUL one select,insert,update,references
flags set('one','two','tree') character set latin1 latin1 select,insert,update,references
new_field varchar(10) character set latin1 latin1 new select,insert,update,references
options enum('one','two','tree') latin1 MUL one select,insert,update,references
flags set('one','two','tree') latin1 select,insert,update,references
new_field varchar(10) latin1 new select,insert,update,references
show full columns from t2;
Field Type Collation Null Key Default Extra Privileges Comment
auto int(5) unsigned binary 0 select,insert,update,references
string varchar(10) character set latin1 latin1 YES new defaul select,insert,update,references
string varchar(10) latin1 YES new defaul select,insert,update,references
tiny tinyint(4) binary 0 select,insert,update,references
short smallint(6) binary 0 select,insert,update,references
medium mediumint(8) binary 0 select,insert,update,references
@ -210,15 +210,15 @@ umedium mediumint(8) unsigned binary 0 select,insert,update,references
ulong int(11) unsigned binary 0 select,insert,update,references
ulonglong bigint(13) unsigned binary 0 select,insert,update,references
time_stamp timestamp latin1 YES NULL select,insert,update,references
date_field varchar(10) character set latin1 latin1 YES NULL select,insert,update,references
date_field varchar(10) latin1 YES NULL select,insert,update,references
time_field time latin1 YES NULL select,insert,update,references
date_time datetime latin1 YES NULL select,insert,update,references
new_blob_col varchar(20) character set latin1 latin1 YES NULL select,insert,update,references
new_blob_col varchar(20) latin1 YES NULL select,insert,update,references
tinyblob_col tinyblob binary YES NULL select,insert,update,references
mediumblob_col mediumblob binary select,insert,update,references
options enum('one','two','tree') character set latin1 latin1 one select,insert,update,references
flags set('one','two','tree') character set latin1 latin1 select,insert,update,references
new_field varchar(10) character set latin1 latin1 new select,insert,update,references
options enum('one','two','tree') latin1 one select,insert,update,references
flags set('one','two','tree') latin1 select,insert,update,references
new_field varchar(10) latin1 new select,insert,update,references
select t1.auto,t2.auto from t1,t2 where t1.auto=t2.auto and ((t1.string<>t2.string and (t1.string is not null or t2.string is not null)) or (t1.tiny<>t2.tiny and (t1.tiny is not null or t2.tiny is not null)) or (t1.short<>t2.short and (t1.short is not null or t2.short is not null)) or (t1.medium<>t2.medium and (t1.medium is not null or t2.medium is not null)) or (t1.long_int<>t2.long_int and (t1.long_int is not null or t2.long_int is not null)) or (t1.longlong<>t2.longlong and (t1.longlong is not null or t2.longlong is not null)) or (t1.real_float<>t2.real_float and (t1.real_float is not null or t2.real_float is not null)) or (t1.real_double<>t2.real_double and (t1.real_double is not null or t2.real_double is not null)) or (t1.utiny<>t2.utiny and (t1.utiny is not null or t2.utiny is not null)) or (t1.ushort<>t2.ushort and (t1.ushort is not null or t2.ushort is not null)) or (t1.umedium<>t2.umedium and (t1.umedium is not null or t2.umedium is not null)) or (t1.ulong<>t2.ulong and (t1.ulong is not null or t2.ulong is not null)) or (t1.ulonglong<>t2.ulonglong and (t1.ulonglong is not null or t2.ulonglong is not null)) or (t1.time_stamp<>t2.time_stamp and (t1.time_stamp is not null or t2.time_stamp is not null)) or (t1.date_field<>t2.date_field and (t1.date_field is not null or t2.date_field is not null)) or (t1.time_field<>t2.time_field and (t1.time_field is not null or t2.time_field is not null)) or (t1.date_time<>t2.date_time and (t1.date_time is not null or t2.date_time is not null)) or (t1.new_blob_col<>t2.new_blob_col and (t1.new_blob_col is not null or t2.new_blob_col is not null)) or (t1.tinyblob_col<>t2.tinyblob_col and (t1.tinyblob_col is not null or t2.tinyblob_col is not null)) or (t1.mediumblob_col<>t2.mediumblob_col and (t1.mediumblob_col is not null or t2.mediumblob_col is not null)) or (t1.options<>t2.options and (t1.options is not null or t2.options is not null)) or (t1.flags<>t2.flags and (t1.flags is not null or t2.flags is not null)) or (t1.new_field<>t2.new_field and (t1.new_field is not null or t2.new_field is not null)));
auto auto
16 16
@ -231,8 +231,8 @@ show full columns from t2;
Field Type Collation Null Key Default Extra Privileges Comment
auto bigint(17) unsigned binary PRI 0 select,insert,update,references
t1 bigint(1) binary 0 select,insert,update,references
t2 char(1) character set latin1 latin1 select,insert,update,references
t3 mediumtext character set latin1 latin1 select,insert,update,references
t2 char(1) latin1 select,insert,update,references
t3 mediumtext latin1 select,insert,update,references
t4 mediumblob binary select,insert,update,references
select * from t2;
auto t1 t2 t3 t4

View file

@ -3,13 +3,13 @@ create table t1 (a set (' ','a','b') not null);
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` set('','a','b') character set latin1 NOT NULL default ''
`a` set('','a','b') NOT NULL default ''
) TYPE=MyISAM CHARSET=latin1
drop table t1;
create table t1 (a set (' ','a','b ') not null default 'b ');
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` set('','a','b') character set latin1 NOT NULL default 'b'
`a` set('','a','b') NOT NULL default 'b'
) TYPE=MyISAM CHARSET=latin1
drop table t1;

View file

@ -50,7 +50,7 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c\
my_getopt.c my_mkdir.c \
default.c my_compress.c checksum.c raid.cc \
my_net.c my_semaphore.c my_port.c \
my_vsnprintf.c charset.c xml.c my_bitmap.c my_bit.c md5.c \
charset.c xml.c my_bitmap.c my_bit.c md5.c \
my_gethostbyname.c rijndael.c my_aes.c sha1.c \
my_handler.c
EXTRA_DIST = thr_alarm.c thr_lock.c my_pthread.c my_thr_init.c \

View file

@ -34,8 +34,6 @@
// Maximum allowed exponent value for converting string to decimal
#define MAX_EXPONENT 1024
/*****************************************************************************
Instansiate templates and static variables
*****************************************************************************/
@ -67,39 +65,44 @@ void Field_num::prepend_zeros(String *value)
/*
Test if given number is a int (or a fixed format float with .000)
This is only used to give warnings in ALTER TABLE or LOAD DATA...
SYNOPSIS
test_if_int()
str String to test
end Pointer to char after last used digit
cs Character set
NOTES
This is called after one has called my_strntol() or similar function.
This is only used to give warnings in ALTER TABLE or LOAD DATA...
TODO
Make this multi-byte-character safe
RETURN
0 ok
1 error
*/
bool test_if_int(const char *str,int length, CHARSET_INFO *cs)
bool test_if_int(const char *str, int length, const char *int_end,
CHARSET_INFO *cs)
{
if (str == int_end)
return 0; // Empty string
const char *end=str+length;
if ((str= int_end) == end)
return 1; // All digits was used
cs=system_charset_info; // QQ move test_if_int into CHARSET_INFO struct
// Allow start space
while (str != end && my_isspace(cs,*str))
str++; /* purecov: inspected */
if (str != end && (*str == '-' || *str == '+'))
str++;
if (str == end)
return 0; // Error: Empty string
for (; str != end ; str++)
/* Allow end .0000 */
if (*str == '.')
{
if (!my_isdigit(cs,*str))
{
if (*str == '.')
{ // Allow '.0000'
for (str++ ; str != end && *str == '0'; str++) ;
if (str == end)
return 1;
}
if (!my_isspace(cs,*str))
return 0;
for (str++ ; str != end ; str++)
if (!my_isspace(cs,*str))
return 0;
return 1;
}
for (str++ ; str != end && *str == '0'; str++) ;
}
/* Allow end space */
for (str++ ; str != end ; str++)
{
if (!my_isspace(cs,*str))
return 0;
}
return 1;
}
@ -107,7 +110,7 @@ bool test_if_int(const char *str,int length, CHARSET_INFO *cs)
static bool test_if_real(const char *str,int length, CHARSET_INFO *cs)
{
cs=system_charset_info; // QQ move test_if_int into CHARSET_INFO struct
cs= system_charset_info; // QQ move test_if_real into CHARSET_INFO struct
while (length && my_isspace(cs,*str))
{ // Allow start space
@ -207,17 +210,10 @@ bool Field::send_binary(Protocol *protocol)
void Field_num::add_zerofill_and_unsigned(String &res) const
{
uint oldlen=res.length();
if (oldlen < res.alloced_length())
{
uint len=res.alloced_length()-oldlen;
char *end=(char*)(res.ptr()+oldlen);
CHARSET_INFO *cs=res.charset();
len=cs->snprintf(cs,end,len,"%s%s",
unsigned_flag ? " unsigned" : "",
zerofill ? " zerofill" : "");
res.length(len+oldlen);
}
if (unsigned_flag)
res.append(" unsigned");
if (zerofill)
res.append(" zerofill");
}
void Field_num::make_field(Send_field *field)
@ -247,19 +243,15 @@ void Field_str::make_field(Send_field *field)
field->decimals=0;
}
void Field_str::add_binary_or_charset(String &res) const
{
uint oldlen=res.length();
if (oldlen < res.alloced_length())
if (binary())
res.append(" binary");
else if (field_charset != table->table_charset)
{
CHARSET_INFO *cs=res.charset();
uint len=res.alloced_length() - oldlen;
char *end=(char*)(res.ptr()+oldlen);
if (binary())
len=cs->snprintf(cs,end,len," binary");
else
len=cs->snprintf(cs,end,len," character set %s",field_charset->csname);
res.length(oldlen+len);
res.append(" character set ");
res.append(field_charset->csname);
}
}
@ -287,7 +279,7 @@ uint Field::fill_cache_field(CACHE_FIELD *copy)
bool Field::get_date(TIME *ltime,bool fuzzydate)
{
char buff[40];
String tmp(buff,sizeof(buff),my_charset_latin1),tmp2,*res;
String tmp(buff,sizeof(buff),my_charset_bin),tmp2,*res;
if (!(res=val_str(&tmp,&tmp2)) ||
str_to_TIME(res->ptr(),res->length(),ltime,fuzzydate) == TIMESTAMP_NONE)
return 1;
@ -297,7 +289,7 @@ bool Field::get_date(TIME *ltime,bool fuzzydate)
bool Field::get_time(TIME *ltime)
{
char buff[40];
String tmp(buff,sizeof(buff),my_charset_latin1),tmp2,*res;
String tmp(buff,sizeof(buff),my_charset_bin),tmp2,*res;
if (!(res=val_str(&tmp,&tmp2)) ||
str_to_time(res->ptr(),res->length(),ltime))
return 1;
@ -311,23 +303,23 @@ void Field::store_time(TIME *ltime,timestamp_type type)
char buff[25];
switch (type) {
case TIMESTAMP_NONE:
store("",0,my_charset_latin1); // Probably an error
store("",0,my_charset_bin); // Probably an error
break;
case TIMESTAMP_DATE:
sprintf(buff,"%04d-%02d-%02d", ltime->year,ltime->month,ltime->day);
store(buff,10,my_charset_latin1);
store(buff,10,my_charset_bin);
break;
case TIMESTAMP_FULL:
sprintf(buff,"%04d-%02d-%02d %02d:%02d:%02d",
ltime->year,ltime->month,ltime->day,
ltime->hour,ltime->minute,ltime->second);
store(buff,19,my_charset_latin1);
store(buff,19,my_charset_bin);
break;
case TIMESTAMP_TIME:
{
ulong length= my_sprintf(buff, (buff, "%02d:%02d:%02d",
ltime->hour,ltime->minute,ltime->second));
store(buff,(uint) length, my_charset_latin1);
store(buff,(uint) length, my_charset_bin);
break;
}
}
@ -340,15 +332,12 @@ bool Field::optimize_range(uint idx)
}
/****************************************************************************
Functions for the Field_null
Field_null, a field that always return NULL
****************************************************************************/
void Field_null::sql_type(String &res) const
{
CHARSET_INFO *cs=res.charset();
uint len;
len=cs->snprintf(cs,(char*)res.ptr(),res.alloced_length(),"null");
res.length(len);
res.set_latin1("null", 4);
}
@ -360,7 +349,7 @@ void Field_null::sql_type(String &res) const
void
Field_decimal::reset(void)
{
Field_decimal::store("0",1,my_charset_latin1);
Field_decimal::store("0",1,my_charset_bin);
}
void Field_decimal::overflow(bool negative)
@ -404,11 +393,16 @@ void Field_decimal::overflow(bool negative)
int Field_decimal::store(const char *from, uint len, CHARSET_INFO *cs)
{
String l1from;
char buff[80];
String tmp(buff,sizeof(buff), my_charset_bin);
l1from.copy(from,len,cs,my_charset_latin1);
from=l1from.ptr();
len=l1from.length();
/* Convert character set if the old one is multi byte */
if (cs->mbmaxlen > 1)
{
tmp.copy(from, len, cs, my_charset_bin);
from= tmp.ptr();
len= tmp.length();
}
const char *end= from+len;
/* The pointer where the field value starts (i.e., "where to write") */
@ -461,7 +455,7 @@ int Field_decimal::store(const char *from, uint len, CHARSET_INFO *cs)
There are three steps in this function :
- parse the input string
- modify the position of digits around the decimal dot '.'
according to the exponent value (if specified)
according to the exponent value (if specified)
- write the formatted number
*/
@ -469,7 +463,7 @@ int Field_decimal::store(const char *from, uint len, CHARSET_INFO *cs)
tmp_dec++;
/* skip pre-space */
while (from != end && my_isspace(my_charset_latin1,*from))
while (from != end && my_isspace(my_charset_bin,*from))
from++;
if (from == end)
{
@ -506,13 +500,13 @@ int Field_decimal::store(const char *from, uint len, CHARSET_INFO *cs)
for (; from!=end && *from == '0'; from++) ; // Read prezeros
pre_zeros_end=int_digits_from=from;
/* Read non zero digits at the left of '.'*/
for (; from != end && my_isdigit(my_charset_latin1, *from) ; from++) ;
for (; from != end && my_isdigit(my_charset_bin, *from) ; from++) ;
int_digits_end=from;
if (from!=end && *from == '.') // Some '.' ?
from++;
frac_digits_from= from;
/* Read digits at the right of '.' */
for (;from!=end && my_isdigit(my_charset_latin1, *from); from++) ;
for (;from!=end && my_isdigit(my_charset_bin, *from); from++) ;
frac_digits_end=from;
// Some exponentiation symbol ?
if (from != end && (*from == 'e' || *from == 'E'))
@ -528,7 +522,7 @@ int Field_decimal::store(const char *from, uint len, CHARSET_INFO *cs)
exponents will become small (e.g. 1e4294967296 will become 1e0, and the
field will finally contain 1 instead of its max possible value).
*/
for (;from!=end && my_isdigit(my_charset_latin1, *from); from++)
for (;from!=end && my_isdigit(my_charset_bin, *from); from++)
{
exponent=10*exponent+(*from-'0');
if (exponent>MAX_EXPONENT)
@ -546,7 +540,7 @@ int Field_decimal::store(const char *from, uint len, CHARSET_INFO *cs)
if (current_thd->count_cuted_fields)
{
// Skip end spaces
for (;from != end && my_isspace(my_charset_latin1, *from); from++) ;
for (;from != end && my_isspace(my_charset_bin, *from); from++) ;
if (from != end) // If still something left, warn
{
current_thd->cuted_fields++;
@ -838,30 +832,29 @@ int Field_decimal::store(longlong nr)
double Field_decimal::val_real(void)
{
CHARSET_INFO *cs=charset();
return my_strntod(cs,ptr,field_length,NULL);
return my_strntod(my_charset_bin, ptr, field_length, NULL);
}
longlong Field_decimal::val_int(void)
{
CHARSET_INFO *cs=charset();
if (unsigned_flag)
return my_strntoull(cs,ptr,field_length,NULL,10);
return my_strntoull(my_charset_bin, ptr, field_length, NULL, 10);
else
return my_strntoll(cs,ptr,field_length,NULL,10);
return my_strntoll( my_charset_bin, ptr, field_length, NULL, 10);
}
String *Field_decimal::val_str(String *val_buffer __attribute__((unused)),
String *val_ptr)
{
char *str;
CHARSET_INFO *cs=current_thd->variables.thd_charset;
for (str=ptr ; *str == ' ' ; str++) ;
uint tmp_length=(uint) (str-ptr);
val_ptr->set_charset(my_charset_bin);
if (field_length < tmp_length) // Error in data
val_ptr->length(0);
else
val_ptr->copy((const char*) str,field_length-tmp_length,my_charset_latin1,cs);
val_ptr->set_latin1((const char*) str, field_length-tmp_length);
return val_ptr;
}
@ -878,9 +871,9 @@ int Field_decimal::cmp(const char *a_ptr,const char *b_ptr)
for (end=a_ptr+field_length;
a_ptr != end &&
(*a_ptr == *b_ptr ||
((my_isspace(my_charset_latin1,*a_ptr) || *a_ptr == '+' ||
((my_isspace(my_charset_bin,*a_ptr) || *a_ptr == '+' ||
*a_ptr == '0') &&
(my_isspace(my_charset_latin1,*b_ptr) || *b_ptr == '+' ||
(my_isspace(my_charset_bin,*b_ptr) || *b_ptr == '+' ||
*b_ptr == '0')));
a_ptr++,b_ptr++)
{
@ -908,7 +901,7 @@ void Field_decimal::sort_string(char *to,uint length)
char *str,*end;
for (str=ptr,end=ptr+length;
str != end &&
((my_isspace(my_charset_latin1,*str) || *str == '+' ||
((my_isspace(my_charset_bin,*str) || *str == '+' ||
*str == '0')) ;
str++)
*to++=' ';
@ -920,7 +913,7 @@ void Field_decimal::sort_string(char *to,uint length)
*to++=1; // Smaller than any number
str++;
while (str != end)
if (my_isdigit(my_charset_latin1,*str))
if (my_isdigit(my_charset_bin,*str))
*to++= (char) ('9' - *str++);
else
*to++= *str++;
@ -933,14 +926,12 @@ void Field_decimal::sql_type(String &res) const
{
CHARSET_INFO *cs=res.charset();
uint tmp=field_length;
uint len;
if (!unsigned_flag)
tmp--;
if (dec)
tmp--;
len=cs->snprintf(cs,(char*) res.ptr(),res.alloced_length(),
"decimal(%d,%d)",tmp,dec);
res.length(len);
res.length(cs->snprintf(cs,(char*) res.ptr(),res.alloced_length(),
"decimal(%d,%d)",tmp,dec));
add_zerofill_and_unsigned(res);
}
@ -951,7 +942,8 @@ void Field_decimal::sql_type(String &res) const
int Field_tiny::store(const char *from,uint len,CHARSET_INFO *cs)
{
long tmp= my_strntol(cs,from,len,(char **)NULL,10);
char *end;
long tmp= my_strntol(cs, from, len, &end,10);
int error= 0;
if (unsigned_flag)
@ -968,7 +960,7 @@ int Field_tiny::store(const char *from,uint len,CHARSET_INFO *cs)
current_thd->cuted_fields++;
error= 1;
}
else if (current_thd->count_cuted_fields && !test_if_int(from,len,cs))
else if (current_thd->count_cuted_fields && !test_if_int(from,len,end,cs))
{
current_thd->cuted_fields++;
error= 1;
@ -988,7 +980,7 @@ int Field_tiny::store(const char *from,uint len,CHARSET_INFO *cs)
current_thd->cuted_fields++;
error= 1;
}
else if (current_thd->count_cuted_fields && !test_if_int(from,len,cs))
else if (current_thd->count_cuted_fields && !test_if_int(from,len,end,cs))
{
current_thd->cuted_fields++;
error= 1;
@ -1098,7 +1090,7 @@ longlong Field_tiny::val_int(void)
String *Field_tiny::val_str(String *val_buffer,
String *val_ptr __attribute__((unused)))
{
CHARSET_INFO *cs=current_thd->variables.thd_charset;
CHARSET_INFO *cs= my_charset_bin;
uint length;
uint mlength=max(field_length+1,5*cs->mbmaxlen);
val_buffer->alloc(mlength);
@ -1140,22 +1132,19 @@ void Field_tiny::sort_string(char *to,uint length __attribute__((unused)))
void Field_tiny::sql_type(String &res) const
{
CHARSET_INFO *cs=res.charset();
uint len=cs->snprintf(cs,(char*) res.ptr(),res.alloced_length(),
"tinyint(%d)",(int) field_length);
res.length(len);
res.length(cs->snprintf(cs,(char*) res.ptr(),res.alloced_length(),
"tinyint(%d)",(int) field_length));
add_zerofill_and_unsigned(res);
}
/****************************************************************************
** short int
Field type short int (2 byte)
****************************************************************************/
// Note: Sometimes this should be fixed to check for garbage after number.
int Field_short::store(const char *from,uint len,CHARSET_INFO *cs)
{
long tmp= my_strntol(cs,from,len,NULL,10);
char *end;
long tmp= my_strntol(cs, from, len, &end, 10);
int error= 0;
if (unsigned_flag)
{
@ -1171,7 +1160,7 @@ int Field_short::store(const char *from,uint len,CHARSET_INFO *cs)
current_thd->cuted_fields++;
error= 1;
}
else if (current_thd->count_cuted_fields && !test_if_int(from,len,cs))
else if (current_thd->count_cuted_fields && !test_if_int(from,len,end,cs))
{
current_thd->cuted_fields++;
error= 1;
@ -1191,7 +1180,7 @@ int Field_short::store(const char *from,uint len,CHARSET_INFO *cs)
current_thd->cuted_fields++;
error= 1;
}
else if (current_thd->count_cuted_fields && !test_if_int(from,len,cs))
else if (current_thd->count_cuted_fields && !test_if_int(from,len,end,cs))
{
current_thd->cuted_fields++;
error= 1;
@ -1337,7 +1326,7 @@ longlong Field_short::val_int(void)
String *Field_short::val_str(String *val_buffer,
String *val_ptr __attribute__((unused)))
{
CHARSET_INFO *cs=current_thd->variables.thd_charset;
CHARSET_INFO *cs= my_charset_bin;
uint length;
uint mlength=max(field_length+1,7*cs->mbmaxlen);
val_buffer->alloc(mlength);
@ -1351,9 +1340,9 @@ String *Field_short::val_str(String *val_buffer,
shortget(j,ptr);
if (unsigned_flag)
length=(uint) cs->l10tostr(cs,to,mlength, 10, (long) (uint16) j);
length=(uint) cs->l10tostr(cs, to, mlength, 10, (long) (uint16) j);
else
length=(uint) cs->l10tostr(cs,to,mlength,-10, (long) j);
length=(uint) cs->l10tostr(cs, to, mlength,-10, (long) j);
val_buffer->length(length);
if (zerofill)
prepend_zeros(val_buffer);
@ -1414,22 +1403,20 @@ void Field_short::sort_string(char *to,uint length __attribute__((unused)))
void Field_short::sql_type(String &res) const
{
CHARSET_INFO *cs=res.charset();
uint len=cs->snprintf(cs,(char*) res.ptr(),res.alloced_length(),
"smallint(%d)",(int) field_length);
res.length(len);
res.length(cs->snprintf(cs,(char*) res.ptr(),res.alloced_length(),
"smallint(%d)",(int) field_length));
add_zerofill_and_unsigned(res);
}
/****************************************************************************
** medium int
Field type medium int (3 byte)
****************************************************************************/
// Note: Sometimes this should be fixed to check for garbage after number.
int Field_medium::store(const char *from,uint len,CHARSET_INFO *cs)
{
long tmp= my_strntol(cs,from,len,NULL,10);
char *end;
long tmp= my_strntol(cs, from, len, &end, 10);
int error= 0;
if (unsigned_flag)
@ -1446,7 +1433,7 @@ int Field_medium::store(const char *from,uint len,CHARSET_INFO *cs)
current_thd->cuted_fields++;
error= 1;
}
else if (current_thd->count_cuted_fields && !test_if_int(from,len,cs))
else if (current_thd->count_cuted_fields && !test_if_int(from,len,end,cs))
{
current_thd->cuted_fields++;
error= 1;
@ -1466,7 +1453,7 @@ int Field_medium::store(const char *from,uint len,CHARSET_INFO *cs)
current_thd->cuted_fields++;
error= 1;
}
else if (current_thd->count_cuted_fields && !test_if_int(from,len,cs))
else if (current_thd->count_cuted_fields && !test_if_int(from,len,end,cs))
{
current_thd->cuted_fields++;
error= 1;
@ -1572,16 +1559,18 @@ double Field_medium::val_real(void)
return (double) j;
}
longlong Field_medium::val_int(void)
{
long j= unsigned_flag ? (long) uint3korr(ptr) : sint3korr(ptr);
return (longlong) j;
}
String *Field_medium::val_str(String *val_buffer,
String *val_ptr __attribute__((unused)))
{
CHARSET_INFO *cs=current_thd->variables.thd_charset;
CHARSET_INFO *cs= my_charset_bin;
uint length;
uint mlength=max(field_length+1,10*cs->mbmaxlen);
val_buffer->alloc(mlength);
@ -1632,9 +1621,8 @@ void Field_medium::sort_string(char *to,uint length __attribute__((unused)))
void Field_medium::sql_type(String &res) const
{
CHARSET_INFO *cs=res.charset();
uint len=cs->snprintf(cs,(char*) res.ptr(),res.alloced_length(),
"mediumint(%d)",(int) field_length);
res.length(len);
res.length(cs->snprintf(cs,(char*) res.ptr(),res.alloced_length(),
"mediumint(%d)",(int) field_length));
add_zerofill_and_unsigned(res);
}
@ -1643,26 +1631,23 @@ void Field_medium::sql_type(String &res) const
****************************************************************************/
// Note: Sometimes this should be fixed to check for garbage after number.
int Field_long::store(const char *from,uint len,CHARSET_INFO *cs)
{
long tmp;
int error= 0;
char *end;
/* TODO: Make multi-byte-character safe */
while (len && my_isspace(cs,*from))
{
len--; from++;
}
long tmp;
String tmp_str(from, len, cs);
from= tmp_str.c_ptr(); // Add end null if needed
int error= 0;
errno=0;
my_errno=0;
if (unsigned_flag)
{
if (!len || *from == '-')
{
tmp=0; // Set negative to 0
errno=ERANGE;
my_errno=ERANGE;
error= 1;
}
else
@ -1670,9 +1655,9 @@ int Field_long::store(const char *from,uint len,CHARSET_INFO *cs)
}
else
tmp=my_strntol(cs,from,len,&end,10);
if (errno ||
if (my_errno ||
(from+len != end && current_thd->count_cuted_fields &&
!test_if_int(from,len,cs)))
!test_if_int(from,len,end,cs)))
{
current_thd->cuted_fields++;
error= 1;
@ -1817,7 +1802,7 @@ longlong Field_long::val_int(void)
String *Field_long::val_str(String *val_buffer,
String *val_ptr __attribute__((unused)))
{
CHARSET_INFO *cs=current_thd->variables.thd_charset;
CHARSET_INFO *cs= my_charset_bin;
uint length;
uint mlength=max(field_length+1,12*cs->mbmaxlen);
val_buffer->alloc(mlength);
@ -1896,34 +1881,32 @@ void Field_long::sort_string(char *to,uint length __attribute__((unused)))
void Field_long::sql_type(String &res) const
{
CHARSET_INFO *cs=res.charset();
uint len=cs->snprintf(cs,(char*) res.ptr(),res.alloced_length(),
"int(%d)",(int) field_length);
res.length(len);
res.length(cs->snprintf(cs,(char*) res.ptr(),res.alloced_length(),
"int(%d)",(int) field_length));
add_zerofill_and_unsigned(res);
}
/****************************************************************************
** longlong int
Field type longlong int (8 bytes)
****************************************************************************/
int Field_longlong::store(const char *from,uint len,CHARSET_INFO *cs)
{
longlong tmp;
int error= 0;
char *end;
/* TODO: Make multi byte safe */
while (len && my_isspace(cs,*from))
{ // For easy error check
len--; from++;
}
longlong tmp;
String tmp_str(from, len, cs);
from= tmp_str.c_ptr(); // Add end null if needed
int error= 0;
errno=0;
my_errno=0;
if (unsigned_flag)
{
if (!len || *from == '-')
{
tmp=0; // Set negative to 0
errno=ERANGE;
my_errno= ERANGE;
error= 1;
}
else
@ -1931,9 +1914,9 @@ int Field_longlong::store(const char *from,uint len,CHARSET_INFO *cs)
}
else
tmp=my_strntoll(cs,from,len,&end,10);
if (errno ||
if (my_errno ||
(from+len != end && current_thd->count_cuted_fields &&
!test_if_int(from,len,cs)))
!test_if_int(from,len,end,cs)))
current_thd->cuted_fields++;
#ifdef WORDS_BIGENDIAN
if (table->db_low_byte_first)
@ -2042,7 +2025,7 @@ longlong Field_longlong::val_int(void)
String *Field_longlong::val_str(String *val_buffer,
String *val_ptr __attribute__((unused)))
{
CHARSET_INFO *cs=current_thd->variables.thd_charset;
CHARSET_INFO *cs= my_charset_bin;
uint length;
uint mlength=max(field_length+1,22*cs->mbmaxlen);
val_buffer->alloc(mlength);
@ -2128,9 +2111,8 @@ void Field_longlong::sort_string(char *to,uint length __attribute__((unused)))
void Field_longlong::sql_type(String &res) const
{
CHARSET_INFO *cs=res.charset();
uint len=cs->snprintf(cs,(char*) res.ptr(),res.alloced_length(),
"bigint(%d)",(int) field_length);
res.length(len);
res.length(cs->snprintf(cs,(char*) res.ptr(),res.alloced_length(),
"bigint(%d)",(int) field_length));
add_zerofill_and_unsigned(res);
}
@ -2140,8 +2122,8 @@ void Field_longlong::sql_type(String &res) const
int Field_float::store(const char *from,uint len,CHARSET_INFO *cs)
{
errno=0;
Field_float::store(my_strntod(cs,from,len,(char**)NULL));
errno=0; // my_strntod() changes errno
Field_float::store(my_strntod(cs,(char*) from,len,(char**)NULL));
if (errno || current_thd->count_cuted_fields && !test_if_real(from,len,cs))
{
current_thd->cuted_fields++;
@ -2394,18 +2376,16 @@ bool Field_float::send_binary(Protocol *protocol)
void Field_float::sql_type(String &res) const
{
CHARSET_INFO *cs=res.charset();
uint len;
if (dec == NOT_FIXED_DEC)
{
len=cs->snprintf(cs,(char*) res.ptr(),res.alloced_length(),"float");
res.set_latin1("float", 5);
}
else
{
len=cs->snprintf(cs,(char*) res.ptr(),res.alloced_length(),
"float(%d,%d)",(int) field_length,dec);
CHARSET_INFO *cs= res.charset();
res.length(cs->snprintf(cs,(char*) res.ptr(),res.alloced_length(),
"float(%d,%d)",(int) field_length,dec));
}
res.length(len);
add_zerofill_and_unsigned(res);
}
@ -2415,9 +2395,9 @@ void Field_float::sql_type(String &res) const
int Field_double::store(const char *from,uint len,CHARSET_INFO *cs)
{
errno=0;
errno=0; // my_strntod() changes errno
int error= 0;
double j= my_strntod(cs,from,len,(char**)0);
double j= my_strntod(cs,(char*) from,len,(char**)0);
if (errno || current_thd->count_cuted_fields && !test_if_real(from,len,cs))
{
current_thd->cuted_fields++;
@ -2655,17 +2635,15 @@ void Field_double::sort_string(char *to,uint length __attribute__((unused)))
void Field_double::sql_type(String &res) const
{
CHARSET_INFO *cs=res.charset();
uint len;
if (dec == NOT_FIXED_DEC)
{
len=cs->snprintf(cs,(char*) res.ptr(),res.alloced_length(),"double");
res.set_latin1("double",6);
}
else
{
len=cs->snprintf(cs,(char*) res.ptr(),res.alloced_length(),
"double(%d,%d)",(int) field_length,dec);
res.length(cs->snprintf(cs,(char*) res.ptr(),res.alloced_length(),
"double(%d,%d)",(int) field_length,dec));
}
res.length(len);
add_zerofill_and_unsigned(res);
}
@ -2722,9 +2700,9 @@ int Field_timestamp::store(double nr)
/*
** Convert a datetime of formats YYMMDD, YYYYMMDD or YYMMDDHHMSS to
** YYYYMMDDHHMMSS. The high date '99991231235959' is checked before this
** function.
Convert a datetime of formats YYMMDD, YYYYMMDD or YYMMDDHHMSS to
YYYYMMDDHHMMSS. The high date '99991231235959' is checked before this
function.
*/
static longlong fix_datetime(longlong nr)
@ -2854,9 +2832,10 @@ String *Field_timestamp::val_str(String *val_buffer,
if (temp == 0L)
{ /* Zero time is "000000" */
strmov(to, "0000-00-00 00:00:00");
return val_buffer;
val_ptr->set("0000-00-00 00:00:00", 19, my_charset_bin);
return val_ptr;
}
val_buffer->set_charset(my_charset_bin); // Safety
time_arg=(time_t) temp;
localtime_r(&time_arg,&tm_tmp);
l_time=&tm_tmp;
@ -2995,9 +2974,7 @@ void Field_timestamp::sort_string(char *to,uint length __attribute__((unused)))
void Field_timestamp::sql_type(String &res) const
{
CHARSET_INFO *cs=res.charset();
uint len=cs->snprintf(cs,(char*)res.ptr(),res.alloced_length(),"timestamp");
res.length(len);
res.set_latin1("timestamp", 9);
}
@ -3125,6 +3102,12 @@ longlong Field_time::val_int(void)
return (longlong) sint3korr(ptr);
}
/*
This function is multi-byte safe as the result string is always of type
my_charset_bin
*/
String *Field_time::val_str(String *val_buffer,
String *val_ptr __attribute__((unused)))
{
@ -3189,9 +3172,7 @@ void Field_time::sort_string(char *to,uint length __attribute__((unused)))
void Field_time::sql_type(String &res) const
{
CHARSET_INFO *cs=res.charset();
uint len=cs->snprintf(cs,(char*)res.ptr(),res.alloced_length(),"time");
res.length(len);
res.set_latin1("time", 4);
}
/****************************************************************************
@ -3202,7 +3183,8 @@ void Field_time::sql_type(String &res) const
int Field_year::store(const char *from, uint len,CHARSET_INFO *cs)
{
long nr= my_strntol(cs,from,len,NULL,10);
char *end;
long nr= my_strntol(cs, from, len, &end, 10);
if (nr < 0 || nr >= 100 && nr <= 1900 || nr > 2155)
{
@ -3210,7 +3192,7 @@ int Field_year::store(const char *from, uint len,CHARSET_INFO *cs)
current_thd->cuted_fields++;
return 1;
}
else if (current_thd->count_cuted_fields && !test_if_int(from,len,cs))
else if (current_thd->count_cuted_fields && !test_if_int(from,len,end,cs))
current_thd->cuted_fields++;
if (nr != 0 || len != 4)
{
@ -3287,9 +3269,8 @@ String *Field_year::val_str(String *val_buffer,
void Field_year::sql_type(String &res) const
{
CHARSET_INFO *cs=res.charset();
ulong len=cs->snprintf(cs,(char*)res.ptr(),res.alloced_length(),
"year(%d)",(int) field_length);
res.length(len);
res.length(cs->snprintf(cs,(char*)res.ptr(),res.alloced_length(),
"year(%d)",(int) field_length));
}
@ -3375,6 +3356,7 @@ int Field_date::store(longlong nr)
return error;
}
bool Field_date::send_binary(Protocol *protocol)
{
longlong tmp= Field_date::val_int();
@ -3469,9 +3451,7 @@ void Field_date::sort_string(char *to,uint length __attribute__((unused)))
void Field_date::sql_type(String &res) const
{
CHARSET_INFO *cs=res.charset();
uint len=cs->snprintf(cs,(char*)res.ptr(),res.alloced_length(),"date");
res.length(len);
res.set_latin1("date", 4);
}
/****************************************************************************
@ -3639,9 +3619,7 @@ void Field_newdate::sort_string(char *to,uint length __attribute__((unused)))
void Field_newdate::sql_type(String &res) const
{
CHARSET_INFO *cs=res.charset();
uint len=cs->snprintf(cs,(char*)res.ptr(),res.alloced_length(),"date");
res.length(len);
res.set_latin1("date", 4);
}
@ -3872,9 +3850,7 @@ void Field_datetime::sort_string(char *to,uint length __attribute__((unused)))
void Field_datetime::sql_type(String &res) const
{
CHARSET_INFO *cs=res.charset();
uint len=cs->snprintf(cs,(char*)res.ptr(),res.alloced_length(),"datetime");
res.length(len);
res.set_latin1("datetime", 8);
}
/****************************************************************************
@ -3929,7 +3905,7 @@ int Field_string::store(double nr)
int width=min(field_length,DBL_DIG+5);
sprintf(buff,"%-*.*g",width,max(width-5,0),nr);
end=strcend(buff,' ');
return Field_string::store(buff,(uint) (end - buff), my_charset_latin1);
return Field_string::store(buff,(uint) (end - buff), my_charset_bin);
}
@ -4118,7 +4094,7 @@ int Field_varstring::store(double nr)
int width=min(field_length,DBL_DIG+5);
sprintf(buff,"%-*.*g",width,max(width-5,0),nr);
end=strcend(buff,' ');
return Field_varstring::store(buff,(uint) (end - buff), my_charset_latin1);
return Field_varstring::store(buff,(uint) (end - buff), my_charset_bin);
}
@ -4464,22 +4440,23 @@ int Field_blob::store(const char *from,uint len,CHARSET_INFO *cs)
int Field_blob::store(double nr)
{
value.set(nr,2,current_thd->variables.thd_charset);
return Field_blob::store(value.ptr(),(uint) value.length(), value.charset());
CHARSET_INFO *cs=charset();
value.set(nr, 2, cs);
return Field_blob::store(value.ptr(),(uint) value.length(), cs);
}
int Field_blob::store(longlong nr)
{
value.set(nr,current_thd->variables.thd_charset);
return Field_blob::store(value.ptr(), (uint) value.length(), value.charset());
CHARSET_INFO *cs=charset();
value.set(nr, cs);
return Field_blob::store(value.ptr(), (uint) value.length(), cs);
}
double Field_blob::val_real(void)
{
char *blob;
memcpy_fixed(&blob,ptr+packlength,sizeof(char*));
if (!blob)
return 0.0;
@ -4496,8 +4473,7 @@ longlong Field_blob::val_int(void)
if (!blob)
return 0;
uint32 length=get_length(ptr);
CHARSET_INFO *cs=charset();
return my_strntoll(cs,blob,length,NULL,10);
return my_strntoll(charset(),blob,length,NULL,10);
}
@ -4507,9 +4483,9 @@ String *Field_blob::val_str(String *val_buffer __attribute__((unused)),
char *blob;
memcpy_fixed(&blob,ptr+packlength,sizeof(char*));
if (!blob)
val_ptr->set("",0,field_charset); // A bit safer than ->length(0)
val_ptr->set("",0,charset()); // A bit safer than ->length(0)
else
val_ptr->set((const char*) blob,get_length(ptr),field_charset);
val_ptr->set((const char*) blob,get_length(ptr),charset());
return val_ptr;
}
@ -4567,7 +4543,8 @@ int Field_blob::cmp_binary(const char *a_ptr, const char *b_ptr,
/* The following is used only when comparing a key */
void Field_blob::get_key_image(char *buff,uint length, CHARSET_INFO *cs,imagetype type)
void Field_blob::get_key_image(char *buff,uint length,
CHARSET_INFO *cs,imagetype type)
{
length-= HA_KEY_BLOB_LENGTH;
uint32 blob_length= get_length(ptr);
@ -4695,22 +4672,26 @@ void Field_blob::sort_string(char *to,uint length)
void Field_blob::sql_type(String &res) const
{
CHARSET_INFO *cs=res.charset();
const char *str;
uint len;
uint length;
switch (packlength) {
default: str="tiny"; break;
case 2: str=""; break;
case 3: str="medium"; break;
case 4: str="long"; break;
default: str="tiny"; length=4; break;
case 2: str=""; length=0; break;
case 3: str="medium"; length= 6; break;
case 4: str="long"; length=4; break;
}
res.set_latin1(str,length);
if (binary())
res.append("blob");
else
{
res.append("text");
if (field_charset != table->table_charset)
{
res.append(" character set ");
res.append(field_charset->csname);
}
}
len=cs->snprintf(cs,(char*)res.ptr(),res.alloced_length(),"%s%s%s%s",
str,
binary() ? "blob" : "text",
binary() ? "" : " character set ",
binary() ? "" : field_charset->name);
res.length(len);
}
@ -5452,8 +5433,7 @@ create_field::create_field(Field *old_field,Field *orig_field)
orig_field)
{
char buff[MAX_FIELD_WIDTH],*pos;
CHARSET_INFO *field_charset= charset;
String tmp(buff,sizeof(buff),field_charset);
String tmp(buff,sizeof(buff), charset);
/* Get the value from record[2] (the default value row) */
my_ptrdiff_t diff= (my_ptrdiff_t) (orig_field->table->rec_buff_length*2);
@ -5465,7 +5445,7 @@ create_field::create_field(Field *old_field,Field *orig_field)
{
pos= (char*) sql_memdup(tmp.ptr(),tmp.length()+1);
pos[tmp.length()]=0;
def=new Item_string(pos,tmp.length(),field_charset);
def=new Item_string(pos,tmp.length(), charset);
}
}
}

View file

@ -133,7 +133,9 @@ public:
tmp->unireg_check=Field::NONE;
tmp->flags&= (NOT_NULL_FLAG | BLOB_FLAG | UNSIGNED_FLAG |
ZEROFILL_FLAG | BINARY_FLAG | ENUM_FLAG | SET_FLAG);
#ifdef PROBABLY_WRONG
tmp->table_name= new_table->table_name;
#endif
tmp->reset_fields();
}
return tmp;
@ -1094,7 +1096,8 @@ bool set_field_to_null(Field *field);
bool set_field_to_null_with_conversions(Field *field, bool no_conversions);
uint find_enum(TYPELIB *typelib,const char *x, uint length);
ulonglong find_set(TYPELIB *typelib,const char *x, uint length);
bool test_if_int(const char *str,int length,CHARSET_INFO *cs);
bool test_if_int(const char *str, int length, const char *int_end,
CHARSET_INFO *cs);
/*
The following are for the interface with the .frm file

View file

@ -116,7 +116,7 @@ bool Item_string::eq(const Item *item, bool binary_cmp) const
bool Item::get_date(TIME *ltime,bool fuzzydate)
{
char buff[40];
String tmp(buff,sizeof(buff),NULL),*res;
String tmp(buff,sizeof(buff), my_charset_bin),*res;
if (!(res=val_str(&tmp)) ||
str_to_TIME(res->ptr(),res->length(),ltime,fuzzydate) == TIMESTAMP_NONE)
{
@ -134,7 +134,7 @@ bool Item::get_date(TIME *ltime,bool fuzzydate)
bool Item::get_time(TIME *ltime)
{
char buff[40];
String tmp(buff,sizeof(buff),NULL),*res;
String tmp(buff,sizeof(buff),my_charset_bin),*res;
if (!(res=val_str(&tmp)) ||
str_to_time(res->ptr(),res->length(),ltime))
{
@ -380,7 +380,8 @@ double Item_param::val()
{
switch (item_result_type) {
case STRING_RESULT:
return (double)my_strntod(str_value.charset(),str_value.ptr(),str_value.length(),(char**)0);
return (double) my_strntod(str_value.charset(), (char*) str_value.ptr(),
str_value.length(), (char**) 0);
case INT_RESULT:
return (double)int_value;
default:
@ -1149,7 +1150,7 @@ Item *resolve_const_item(Item *item,Item *comp_item)
if (res_type == STRING_RESULT)
{
char buff[MAX_FIELD_WIDTH];
String tmp(buff,sizeof(buff),NULL),*result;
String tmp(buff,sizeof(buff),my_charset_bin),*result;
result=item->val_str(&tmp);
if (item->null_value)
{
@ -1204,8 +1205,8 @@ bool field_is_equal_to_item(Field *field,Item *item)
{
char item_buff[MAX_FIELD_WIDTH];
char field_buff[MAX_FIELD_WIDTH];
String item_tmp(item_buff,sizeof(item_buff),NULL),*item_result;
String field_tmp(field_buff,sizeof(field_buff),NULL);
String item_tmp(item_buff,sizeof(item_buff),my_charset_bin),*item_result;
String field_tmp(field_buff,sizeof(field_buff),my_charset_bin);
item_result=item->val_str(&item_tmp);
if (item->null_value)
return 1; // This must be true
@ -1263,8 +1264,8 @@ void Item_cache_str::store(Item *item)
double Item_cache_str::val()
{
if (value)
return my_strntod(value->charset(), value->ptr(),
value->length(), (char**)0);
return my_strntod(value->charset(), (char*) value->ptr(),
value->length(), (char**) 0);
else
return (double)0;
}

View file

@ -344,7 +344,7 @@ public:
enum Type type() const { return STRING_ITEM; }
double val()
{
return my_strntod(str_value.charset(), str_value.ptr(),
return my_strntod(str_value.charset(), (char*) str_value.ptr(),
str_value.length(), (char**) 0);
}
longlong val_int()
@ -598,7 +598,11 @@ public:
enum Item_result result_type () const { return STRING_RESULT; }
enum_field_types field_type() const { return cached_field_type; }
double val()
{ return null_value ? 0.0 : my_strntod(str_value.charset(),str_value.ptr(),str_value.length(),NULL); }
{
return (null_value ? 0.0 :
my_strntod(str_value.charset(), (char*) str_value.ptr(),
str_value.length(),NULL));
}
longlong val_int()
{ return null_value ? LL(0) : my_strntoll(str_value.charset(),str_value.ptr(),str_value.length(),(char**) 0,10); }
String *val_str(String*);

View file

@ -1893,7 +1893,7 @@ longlong Item_func_set_last_insert_id::val_int()
longlong Item_func_benchmark::val_int()
{
char buff[MAX_FIELD_WIDTH];
String tmp(buff,sizeof(buff), NULL);
String tmp(buff,sizeof(buff), my_charset_bin);
THD *thd=current_thd;
for (ulong loop=0 ; loop < loop_count && !thd->killed; loop++)
@ -2039,7 +2039,7 @@ Item_func_set_user_var::update()
case STRING_RESULT:
{
char buffer[MAX_FIELD_WIDTH];
String tmp(buffer,sizeof(buffer),NULL);
String tmp(buffer,sizeof(buffer),my_charset_bin);
(void) val_str(&tmp);
break;
}
@ -2234,7 +2234,7 @@ longlong Item_func_inet_aton::val_int()
char c = '.'; // we mark c to indicate invalid IP in case length is 0
char buff[36];
String *s,tmp(buff,sizeof(buff),NULL);
String *s,tmp(buff,sizeof(buff),my_charset_bin);
if (!(s = args[0]->val_str(&tmp))) // If null value
goto err;
null_value=0;
@ -2288,7 +2288,7 @@ void Item_func_match::init_search(bool no_order)
String *ft_tmp= 0;
char tmp1[FT_QUERY_MAXLEN];
String tmp2(tmp1,sizeof(tmp1),NULL);
String tmp2(tmp1,sizeof(tmp1),default_charset_info);
// MATCH ... AGAINST (NULL) is meaningless, but possible
if (!(ft_tmp=key_item()->val_str(&tmp2)))

View file

@ -813,7 +813,7 @@ public:
double val()
{
String *res; res=val_str(&str_value);
return res ? my_strntod(res->charset(),res->ptr(),res->length(),0) : 0.0;
return res ? my_strntod(res->charset(),(char*) res->ptr(),res->length(),0) : 0.0;
}
longlong val_int()
{

View file

@ -54,7 +54,8 @@ double Item_str_func::val()
{
String *res;
res=val_str(&str_value);
return res ? my_strntod(res->charset(),res->ptr(),res->length(),NULL) : 0.0;
return res ? my_strntod(res->charset(), (char*) res->ptr(),res->length(),
NULL) : 0.0;
}
longlong Item_str_func::val_int()

View file

@ -341,7 +341,8 @@ double Item_sum_hybrid::val()
switch (hybrid_type) {
case STRING_RESULT:
String *res; res=val_str(&str_value);
return res ? my_strntod(res->charset(),res->ptr(),res->length(),(char**)0) : 0.0;
return (res ? my_strntod(res->charset(), (char*) res->ptr(),res->length(),
(char**) 0) : 0.0);
case INT_RESULT:
if (unsigned_flag)
return ulonglong2double(sum_int);

View file

@ -484,7 +484,8 @@ public:
double val()
{
String *res; res=val_str(&str_value);
return res ? my_strntod(res->charset(),res->ptr(),res->length(),(char**) 0) : 0.0;
return res ? my_strntod(res->charset(),(char*) res->ptr(),res->length(),
(char**) 0) : 0.0;
}
longlong val_int()
{

View file

@ -529,7 +529,7 @@ void Item_func_now::fix_length_and_dec()
{
struct tm tm_tmp,*start;
time_t query_start=current_thd->query_start();
CHARSET_INFO *cs=thd_charset();
CHARSET_INFO *cs=my_charset_bin;
decimals=0;
max_length=19*cs->mbmaxlen;

View file

@ -4665,8 +4665,11 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
berkeley_lock_type=berkeley_lock_types[type-1];
else
{
if (test_if_int(argument,(uint) strlen(argument), my_charset_latin1))
berkeley_lock_scan_time=atoi(argument);
char *end;
uint length= strlen(argument);
long value= my_strntol(my_charset_latin1, argument, length, &end, 10);
if (test_if_int(argument,(uint) length, end, my_charset_latin1))
berkeley_lock_scan_time= value;
else
{
fprintf(stderr,"Unknown lock type: %s\n",argument);

View file

@ -2796,7 +2796,7 @@ static void
print_key(KEY_PART *key_part,const char *key,uint used_length)
{
char buff[1024];
String tmp(buff,sizeof(buff),NULL);
String tmp(buff,sizeof(buff),my_charset_bin);
for (uint length=0;
length < used_length ;

View file

@ -59,7 +59,7 @@ public:
void set(double nr) { value=nr; }
void set(longlong nr) { value=(double) nr; }
void set(const char *str,uint length,CHARSET_INFO *cs)
{ value=my_strntod(cs,str,length,(char**)0); }
{ value=my_strntod(cs,(char*) str,length,(char**)0); }
double val() { return value; }
longlong val_int() { return (longlong) value; }
String *val_str(String *s) { s->set(value,decimals,thd_charset()); return s; }
@ -99,7 +99,8 @@ public:
double val()
{
CHARSET_INFO *cs=str_value.charset();
return my_strntod(cs, str_value.ptr(), str_value.length(),(char**)0);
return my_strntod(cs, (char*) str_value.ptr(), str_value.length(),
(char**) 0);
}
longlong val_int()
{

View file

@ -526,7 +526,7 @@ bool select_send::send_data(List<Item> &items)
List_iterator_fast<Item> li(items);
Protocol *protocol= thd->protocol;
char buff[MAX_FIELD_WIDTH];
String buffer(buff, sizeof(buff), NULL);
String buffer(buff, sizeof(buff), my_charset_bin);
DBUG_ENTER("send_data");
protocol->prepare_for_resend();
@ -649,7 +649,7 @@ bool select_export::send_data(List<Item> &items)
DBUG_ENTER("send_data");
char buff[MAX_FIELD_WIDTH],null_buff[2],space[MAX_FIELD_WIDTH];
bool space_inited=0;
String tmp(buff,sizeof(buff),NULL),*res;
String tmp(buff,sizeof(buff),my_charset_bin),*res;
tmp.length(0);
if (unit->offset_limit_cnt)
@ -857,7 +857,7 @@ bool select_dump::send_data(List<Item> &items)
{
List_iterator_fast<Item> li(items);
char buff[MAX_FIELD_WIDTH];
String tmp(buff,sizeof(buff),NULL),*res;
String tmp(buff,sizeof(buff),my_charset_bin),*res;
tmp.length(0);
Item *item;
DBUG_ENTER("send_data");

View file

@ -30,6 +30,9 @@
extern gptr sql_alloc(unsigned size);
extern void sql_element_free(void *ptr);
static uint32
copy_and_convert(char *to, uint32 to_length, CHARSET_INFO *to_cs,
const char *from, uint32 from_length, CHARSET_INFO *from_cs);
#include "sql_string.h"
@ -223,55 +226,51 @@ bool String::copy(const char *str,uint32 arg_length, CHARSET_INFO *cs)
return FALSE;
}
/* Copy with charset convertion */
bool String::copy(const char *str,uint32 arg_length, CHARSET_INFO *from, CHARSET_INFO *to)
{
uint32 new_length=to->mbmaxlen*arg_length;
int cnvres;
my_wc_t wc;
const uchar *s=(const uchar *)str;
const uchar *se=s+arg_length;
uchar *d, *de;
/* Copy with charset convertion */
bool String::copy(const char *str, uint32 arg_length,
CHARSET_INFO *from_cs, CHARSET_INFO *to_cs)
{
uint32 new_length= to_cs->mbmaxlen*arg_length;
if (alloc(new_length))
return TRUE;
d=(uchar *)Ptr;
de=d+new_length;
for (str_length=new_length ; s < se && d < de ; )
{
if ((cnvres=from->mb_wc(from,&wc,s,se)) > 0 )
{
s+=cnvres;
}
else if (cnvres==MY_CS_ILSEQ)
{
s++;
wc='?';
}
else
break;
outp:
if ((cnvres=to->wc_mb(to,wc,d,de)) >0 )
{
d+=cnvres;
}
else if (cnvres==MY_CS_ILUNI && wc!='?')
{
wc='?';
goto outp;
}
else
break;
}
Ptr[new_length]=0;
length((uint32) (d-(uchar *)Ptr));
str_charset=to;
str_length=copy_and_convert((char*) Ptr, new_length, to_cs,
str, arg_length, from_cs);
str_charset=to_cs;
return FALSE;
}
/*
Set a string to the value of a latin1-string, keeping the original charset
SYNOPSIS
copy_or_set()
str String of a simple charset (latin1)
arg_length Length of string
IMPLEMENTATION
If string object is of a simple character set, set it to point to the
given string.
If not, make a copy and convert it to the new character set.
RETURN
0 ok
1 Could not allocate result buffer
*/
bool String::set_latin1(const char *str, uint32 arg_length)
{
if (str_charset->mbmaxlen == 1)
{
set(str, arg_length, str_charset);
return 0;
}
return copy(str, arg_length, my_charset_latin1, str_charset);
}
/* This is used by mysql.cc */
bool String::fill(uint32 max_length,char fill_char)
@ -306,11 +305,26 @@ bool String::append(const String &s)
return FALSE;
}
/*
Append a latin1 string to the a string of the current character set
*/
bool String::append(const char *s,uint32 arg_length)
{
if (!arg_length) // Default argument
if (!(arg_length= (uint32) strlen(s)))
return FALSE;
if (str_charset->mbmaxlen > 1)
{
uint32 add_length=arg_length * str_charset->mbmaxlen;
if (realloc(str_length+ add_length))
return TRUE;
str_length+= copy_and_convert(Ptr+str_length, add_length, str_charset,
s, arg_length, my_charset_latin1);
return FALSE;
}
if (realloc(str_length+arg_length))
return TRUE;
memcpy(Ptr+str_length,s,arg_length);
@ -318,6 +332,7 @@ bool String::append(const char *s,uint32 arg_length)
return FALSE;
}
#ifdef TO_BE_REMOVED
bool String::append(FILE* file, uint32 arg_length, myf my_flags)
{
@ -658,4 +673,61 @@ String *copy_if_not_alloced(String *to,String *from,uint32 from_length)
}
/****************************************************************************
Help functions
****************************************************************************/
/*
copy a string from one character set to another
SYNOPSIS
copy_and_convert()
to Store result here
to_cs Character set of result string
from Copy from here
from_length Length of from string
from_cs From character set
NOTES
'to' must be big enough as form_length * to_cs->mbmaxlen
RETURN
length of bytes copied to 'to'
*/
static uint32
copy_and_convert(char *to, uint32 to_length, CHARSET_INFO *to_cs,
const char *from, uint32 from_length, CHARSET_INFO *from_cs)
{
int cnvres;
my_wc_t wc;
const uchar *from_end= (const uchar*) from+from_length;
char *to_start= to;
uchar *to_end= (uchar*) to+to_length;
while ((uchar*) from < from_end)
{
if ((cnvres=from_cs->mb_wc(from_cs, &wc, (uchar*) from, from_end)) > 0)
from+= cnvres;
else if (cnvres == MY_CS_ILSEQ)
{
from++;
wc= '?';
}
else
break; // Impossible char.
outp:
if ((cnvres= to_cs->wc_mb(to_cs, wc, (uchar*) to, to_end)) > 0)
to+= cnvres;
else if (cnvres == MY_CS_ILUNI && wc != '?')
{
wc= '?';
goto outp;
}
else
break;
}
return (uint32) (to - to_start);
}

View file

@ -115,6 +115,7 @@ public:
Ptr=(char*) str; str_length=arg_length; Alloced_length=0 ; alloced=0;
str_charset=cs;
}
bool String::set_latin1(const char *str, uint32 arg_length);
inline void set_quick(char *str,uint32 arg_length, CHARSET_INFO *cs)
{
if (!alloced)

View file

@ -233,6 +233,7 @@ int mysql_update(THD *thd,
}
}
end_read_record(&info);
if (table->key_read)
{
table->key_read=0;

View file

@ -22,19 +22,19 @@ pkglib_LIBRARIES = libmystrings.a
# Exact one of ASSEMBLER_X
if ASSEMBLER_x86
ASRCS = strings-x86.s longlong2str-x86.s
CSRCS = bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c atof.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-czech.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-latin1_de.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-win1250ch.c ctype-bin.c
CSRCS = bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c atof.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-czech.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-latin1_de.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-win1250ch.c ctype-bin.c my_vsnprintf.c
else
if ASSEMBLER_sparc32
# These file MUST all be on the same line!! Otherwise automake
# generats a very broken makefile
ASRCS = bmove_upp-sparc.s strappend-sparc.s strend-sparc.s strinstr-sparc.s strmake-sparc.s strmov-sparc.s strnmov-sparc.s strstr-sparc.s
CSRCS = strcont.c strfill.c strcend.c is_prefix.c longlong2str.c bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c atof.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c strxmov.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-czech.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-latin1_de.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-win1250ch.c ctype-bin.c
CSRCS = strcont.c strfill.c strcend.c is_prefix.c longlong2str.c bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c atof.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c strxmov.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-czech.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-latin1_de.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-win1250ch.c ctype-bin.c my_vsnprintf.c
else
#no assembler
ASRCS =
# These file MUST all be on the same line!! Otherwise automake
# generats a very broken makefile
CSRCS = strxmov.c bmove_upp.c strappend.c strcont.c strend.c strfill.c strcend.c is_prefix.c strstr.c strinstr.c strmake.c strnmov.c strmov.c longlong2str.c bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c atof.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-czech.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-latin1_de.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-win1250ch.c ctype-bin.c
CSRCS = strxmov.c bmove_upp.c strappend.c strcont.c strend.c strfill.c strcend.c is_prefix.c strstr.c strinstr.c strmake.c strnmov.c strmov.c longlong2str.c bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c atof.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-czech.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-latin1_de.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-win1250ch.c ctype-bin.c my_vsnprintf.c
endif
endif

View file

@ -110,88 +110,40 @@ int my_mb_wc_8bit(CHARSET_INFO *cs,my_wc_t *wc,
}
int my_wc_mb_8bit(CHARSET_INFO *cs,my_wc_t wc,
unsigned char *s,
unsigned char *e __attribute__((unused)))
unsigned char *str,
unsigned char *end __attribute__((unused)))
{
MY_UNI_IDX *idx;
for(idx=cs->tab_from_uni; idx->tab ; idx++){
if(idx->from<=wc && idx->to>=wc){
s[0]=idx->tab[wc-idx->from];
return (!s[0] && wc) ? MY_CS_ILUNI : 1;
for (idx=cs->tab_from_uni; idx->tab ; idx++)
{
if (idx->from <= wc && idx->to >= wc)
{
str[0]= idx->tab[wc - idx->from];
return (!str[0] && wc) ? MY_CS_ILUNI : 1;
}
}
return MY_CS_ILUNI;
}
#ifdef NOT_USED
static int my_vsnprintf_8bit(char *to, size_t n, const char* fmt, va_list ap)
{
char *start=to, *end=to+n-1;
for (; *fmt ; fmt++)
{
if (fmt[0] != '%')
{
if (to == end) /* End of buffer */
break;
*to++= *fmt; /* Copy ordinary char */
continue;
}
/* Skip if max size is used (to be compatible with printf) */
fmt++;
while (my_isdigit(system_charset_info,*fmt) || *fmt == '.' || *fmt == '-')
fmt++;
if (*fmt == 'l')
fmt++;
if (*fmt == 's') /* String parameter */
{
reg2 char *par = va_arg(ap, char *);
uint plen,left_len = (uint)(end-to);
if (!par) par = (char*)"(null)";
plen = (uint) strlen(par);
if (left_len <= plen)
plen = left_len - 1;
to=strnmov(to,par,plen);
continue;
}
else if (*fmt == 'd' || *fmt == 'u') /* Integer parameter */
{
register int iarg;
if ((uint) (end-to) < 16)
break;
iarg = va_arg(ap, int);
if (*fmt == 'd')
to=int10_to_str((long) iarg,to, -10);
else
to=int10_to_str((long) (uint) iarg,to,10);
continue;
}
/* We come here on '%%', unknown code or too long parameter */
if (to == end)
break;
*to++='%'; /* % used as % or unknown code */
}
DBUG_ASSERT(to <= end);
*to='\0'; /* End of errmessage */
return (uint) (to - start);
}
#endif
/*
We can't use vsprintf here as it's not guaranteed to return
the length on all operating systems.
This function is also not called in a safe environment, so the
end buffer must be checked.
*/
int my_snprintf_8bit(CHARSET_INFO *cs __attribute__((unused)),
char* to, uint n __attribute__((unused)),
const char* fmt, ...)
{
va_list args;
int result;
va_start(args,fmt);
#ifdef NOT_USED
return my_vsnprintf_8bit(to, n, fmt, args);
#endif
/*
FIXME: generally not safe, but it is OK for now
FIXME: as far as it's not called unsafely in the current code
*/
return vsprintf(to,fmt,args); /* FIXME */
result= my_vsnprintf(to, n, fmt, args);
va_end(args);
return result;
}
@ -690,28 +642,48 @@ noconv:
return 0L;
}
double my_strntod_8bit(CHARSET_INFO *cs __attribute__((unused)),
const char *s, uint l, char **e)
/*
Read double from string
SYNOPSIS:
my_strntod_8bit()
cs Character set information
str String to convert to double
length Optional length for string.
end pointer to end of converted string
NOTES:
If length is not INT_MAX32 or str[length] != 0 then the given str must
be writeable
If length == INT_MAX32 the str must be \0 terminated.
It's implemented this way to save a buffer allocation and a memory copy.
RETURN
value of number in string
*/
double my_strntod_8bit(CHARSET_INFO *cs __attribute__((unused)),
char *str, uint length, char **end)
{
char buf[256];
double res;
if((l+1)>sizeof(buf))
{
if (e)
memcpy(*e,s,sizeof(s));
return 0;
}
strncpy(buf,s,l);
buf[l]='\0';
res=strtod(buf,e);
if (e)
memcpy(*e,*e-buf+s,sizeof(s));
return res;
char end_char;
double result;
if (length == INT_MAX32 || str[length] == 0)
return strtod(str, end);
end_char= str[length];
str[length]= 0;
result= strtod(str, end);
str[length]= end_char; /* Restore end char */
return result;
}
/*
This is a fast version optimized for the case of radix 10 / -10
Assume len >= 1
*/
int my_l10tostr_8bit(CHARSET_INFO *cs __attribute__((unused)),
@ -720,18 +692,19 @@ int my_l10tostr_8bit(CHARSET_INFO *cs __attribute__((unused)),
char buffer[66];
register char *p, *e;
long int new_val;
int sl=0;
uint l;
uint sign=0;
e = p = &buffer[sizeof(buffer)-1];
*e='\0';
*p= 0;
if (radix < 0)
{
if (val < 0)
{
sl = 1;
val = -val;
val= -val;
*dst++= '-';
len--;
sign= 1;
}
}
@ -746,41 +719,38 @@ int my_l10tostr_8bit(CHARSET_INFO *cs __attribute__((unused)),
val= new_val;
}
if (sl)
{
*--p='-';
}
l=e-p;
l=(l>len)?len:l;
memcpy(dst,p,l);
return (int)l;
len= min(len, (uint) (e-p));
memcpy(dst, p, len);
return (int) len+sign;
}
int my_ll10tostr_8bit(CHARSET_INFO *cs __attribute__((unused)),
char *dst, uint len, int radix, longlong val)
{
char buffer[65];
register char *p, *e;
long long_val;
int sl=0;
uint l;
uint sign= 0;
if (radix < 0)
{
if (val < 0)
{
sl=1;
val = -val;
*dst++= '-';
len--;
sign= 1;
}
}
e = p = &buffer[sizeof(buffer)-1];
*p='\0';
*p= 0;
if (val == 0)
{
*--p='0';
*--p= '0';
len= 1;
goto cnv;
}
@ -800,16 +770,10 @@ int my_ll10tostr_8bit(CHARSET_INFO *cs __attribute__((unused)),
long_val= quo;
}
len= min(len, (uint) (e-p));
cnv:
if (sl)
{
*--p='-';
}
l=e-p;
l=(l>len)?len:l;
memcpy(dst,p,l);
return (int)(e-p);
memcpy(dst, p, len);
return len+sign;
}

View file

@ -2874,37 +2874,31 @@ bs:
double my_strntod_ucs2(CHARSET_INFO *cs __attribute__((unused)),
const char *nptr, uint l, char **endptr)
char *nptr, uint length, char **endptr)
{
char buf[256];
double res;
register char *b=buf;
register const char *s=nptr;
register const char *e=nptr+l;
register const char *end;
my_wc_t wc;
int cnv;
if((l+1)>sizeof(buf))
{
if (endptr)
*endptr=(char*)nptr;
my_errno=ERANGE;
return 0;
}
while ((cnv=cs->mb_wc(cs,&wc,s,e))>0)
/* Cut too long strings */
if (length >= sizeof(buf))
length= sizeof(buf)-1;
end=nptr+length;
while ((cnv=cs->mb_wc(cs,&wc,s,end)) > 0)
{
s+=cnv;
if (wc < 128)
{
*b++=wc;
}
else
break;
if (wc > (int) (uchar) 'e' || !wc)
break; /* Can't be part of double */
*b++=wc;
}
*b='\0';
*b= 0;
res=strtod(buf,endptr);
res=strtod(buf, endptr);
if (endptr)
*endptr=(char*) (*endptr-buf+nptr);
return res;

View file

@ -14,13 +14,25 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
#include "mysys_err.h"
#include <my_global.h>
#include <m_string.h>
#include <stdarg.h>
#include <m_ctype.h>
#include <assert.h>
/*
Limited snprintf() implementations
IMPLEMENTION:
Supports following formats:
%#d
%#u
%#.#s Note #.# is skiped
RETURN
length of result string
*/
int my_snprintf(char* to, size_t n, const char* fmt, ...)
{
va_list args;
@ -31,9 +43,12 @@ int my_snprintf(char* to, size_t n, const char* fmt, ...)
return result;
}
int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap)
{
char *start=to, *end=to+n-1;
uint length, num_state, pre_zero;
for (; *fmt ; fmt++)
{
if (fmt[0] != '%')
@ -43,10 +58,27 @@ int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap)
*to++= *fmt; /* Copy ordinary char */
continue;
}
/* Skip if max size is used (to be compatible with printf) */
fmt++;
while (my_isdigit(system_charset_info,*fmt) || *fmt == '.' || *fmt == '-')
fmt++; /* skip '%' */
/* Read max fill size (only used with %d and %u) */
if (*fmt == '-')
fmt++;
length= num_state= pre_zero= 0;
for (;; fmt++)
{
if (my_isdigit(system_charset_info,*fmt))
{
if (!num_state)
{
length=length*10+ (uint) (*fmt-'0');
if (!length)
pre_zero= 1; /* first digit was 0 */
}
continue;
}
if (*fmt != '.' || num_state)
break;
num_state= 1;
}
if (*fmt == 'l')
fmt++;
if (*fmt == 's') /* String parameter */
@ -63,13 +95,26 @@ int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap)
else if (*fmt == 'd' || *fmt == 'u') /* Integer parameter */
{
register int iarg;
if ((uint) (end-to) < 16)
char *to_start= to;
if ((uint) (end-to) < max(16,length))
break;
iarg = va_arg(ap, int);
if (*fmt == 'd')
to=int10_to_str((long) iarg,to, -10);
else
to=int10_to_str((long) (uint) iarg,to,10);
/* If %#d syntax was used, we have to pre-zero/pre-space the string */
if (length)
{
uint res_length= (uint) (to - to_start);
if (res_length < length)
{
uint diff= (length- res_length);
bmove_upp(to+diff, to, res_length);
bfill(to-res_length, diff, pre_zero ? '0' : ' ');
to+= diff;
}
}
continue;
}
/* We come here on '%%', unknown code or too long parameter */