Commit 7e9b27ea authored by monty@mashka.mysql.fi's avatar monty@mashka.mysql.fi

Updates for multi-byte character sets

(Note: test 'union' fails, but Sanja promised to fix this)
parent c9dc5a20
......@@ -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);
......
......@@ -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
......
......@@ -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);
......
......@@ -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
......
......@@ -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;
......@@ -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
......
......@@ -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');
......
......@@ -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
......
......@@ -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;
......
......@@ -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);
......
......@@ -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;
......
......@@ -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;
......
......@@ -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;
......
......@@ -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;
......@@ -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
......
......@@ -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;
......@@ -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 \
......
This diff is collapsed.
......@@ -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
......
......@@ -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;
}
......
......@@ -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*);
......
......@@ -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)))
......
......@@ -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()
{
......
......@@ -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()
......
......@@ -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);
......
......@@ -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()
{
......
......@@ -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;
......
......@@ -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);
......
......@@ -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 ;
......
......@@ -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()
{
......
......@@ -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");
......
......@@ -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;
str_length=copy_and_convert((char*) Ptr, new_length, to_cs,
str, arg_length, from_cs);
str_charset=to_cs;
return FALSE;
}
d=(uchar *)Ptr;
de=d+new_length;
/*
Set a string to the value of a latin1-string, keeping the original charset
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;
SYNOPSIS
copy_or_set()
str String of a simple charset (latin1)
arg_length Length of string
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;
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;
}
Ptr[new_length]=0;
length((uint32) (d-(uchar *)Ptr));
str_charset=to;
return FALSE;
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);
}
......@@ -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)
......
......@@ -233,6 +233,7 @@ int mysql_update(THD *thd,
}
}
end_read_record(&info);
if (table->key_read)
{
table->key_read=0;
......
......@@ -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
......
......@@ -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;
}
......
......@@ -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;
......
......@@ -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 */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment