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); 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); 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); 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; } 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); 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); 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); 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_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); 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
#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) #if defined(__cplusplus) && !defined(OS2)
} }
#endif #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, extern int my_printf_error _VARARGS((uint my_err, const char *format,
myf MyFlags, ...) myf MyFlags, ...)
__attribute__ ((format (printf, 2, 4)))); __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(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_no_curses(uint my_err, const char *str,myf MyFlags);
extern int my_message_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 \ int2str.lo str2int.lo strinstr.lo strcont.lo \
strcend.lo bcmp.lo \ strcend.lo bcmp.lo \
bchange.lo bmove.lo bmove_upp.lo longlong2str.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.lo ctype-simple.lo ctype-bin.lo ctype-mb.lo \
ctype-big5.lo ctype-czech.lo ctype-euc_kr.lo \ ctype-big5.lo ctype-czech.lo ctype-euc_kr.lo \
ctype-win1250ch.lo ctype-utf8.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 \ my_compress.lo array.lo my_once.lo list.lo my_net.lo \
charset.lo xml.lo hash.lo mf_iocache.lo \ charset.lo xml.lo hash.lo mf_iocache.lo \
mf_iocache2.lo my_seek.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 my_getopt.lo my_gethostbyname.lo my_port.lo
sqlobjects = net.lo sqlobjects = net.lo

View File

@ -53,7 +53,7 @@ SHOW FULL COLUMNS FROM t1;
Field Type Collation Null Key Default Extra Privileges Comment Field Type Collation Null Key Default Extra Privileges Comment
GROUP_ID int(10) unsigned binary PRI 0 select,insert,update,references GROUP_ID int(10) unsigned binary PRI 0 select,insert,update,references
LANG_ID smallint(5) 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; DROP TABLE t1;
create table t1 (n int); create table t1 (n int);
insert into t1 values(9),(3),(12),(10); 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; show columns from t1;
Field Type Collation Null Key Default Extra Field Type Collation Null Key Default Extra
i int(10) unsigned binary PRI NULL auto_increment 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; 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; create table t2 select x from t1 where 1=2;
describe t1; describe t1;
Field Type Collation Null Key Default Extra Field Type Collation Null Key Default Extra
x varchar(50) character set latin1 latin1 YES NULL x varchar(50) latin1 YES NULL
describe t2; describe t2;
Field Type Collation Null Key Default Extra 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; 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; 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; describe t2;
@ -181,7 +181,7 @@ show create table t3;
Table Create Table Table Create Table
t3 CREATE TABLE `t3` ( t3 CREATE TABLE `t3` (
`id` int(11) NOT NULL default '0', `id` int(11) NOT NULL default '0',
`name` char(20) character set latin1 default NULL `name` char(20) default NULL
) TYPE=MyISAM CHARSET=latin1 ) TYPE=MyISAM CHARSET=latin1
select * from t3; select * from t3;
id name id name
@ -204,7 +204,7 @@ show create table t3;
Table Create Table Table Create Table
t3 CREATE TABLE `t3` ( t3 CREATE TABLE `t3` (
`id` int(11) NOT NULL default '0', `id` int(11) NOT NULL default '0',
`name` char(20) character set latin1 default NULL `name` char(20) default NULL
) TYPE=MyISAM CHARSET=latin1 ) TYPE=MyISAM CHARSET=latin1
select * from t3; select * from t3;
id name id name
@ -219,14 +219,14 @@ show create table t3;
Table Create Table Table Create Table
t3 CREATE TEMPORARY TABLE `t3` ( t3 CREATE TEMPORARY TABLE `t3` (
`id` int(11) NOT NULL default '0', `id` int(11) NOT NULL default '0',
`name` char(20) character set latin1 default NULL `name` char(20) default NULL
) TYPE=MyISAM CHARSET=latin1 ) TYPE=MyISAM CHARSET=latin1
create table t2 like t3; create table t2 like t3;
show create table t2; show create table t2;
Table Create Table Table Create Table
t2 CREATE TABLE `t2` ( t2 CREATE TABLE `t2` (
`id` int(11) NOT NULL default '0', `id` int(11) NOT NULL default '0',
`name` char(20) character set latin1 default NULL `name` char(20) default NULL
) TYPE=MyISAM CHARSET=latin1 ) TYPE=MyISAM CHARSET=latin1
select * from t2; select * from t2;
id name id name

View File

@ -22,23 +22,23 @@ Table Create Table
t1 CREATE TABLE `t1` ( t1 CREATE TABLE `t1` (
`comment` char(32) character set latin2 NOT NULL default '', `comment` char(32) character set latin2 NOT NULL default '',
`koi8_ru_f` char(32) character set koi8r 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 ) TYPE=MyISAM CHARSET=latin5
ALTER TABLE t1 CHARSET=latin2; ALTER TABLE t1 CHARSET=latin2;
ALTER TABLE t1 ADD latin2_f CHAR(32) NOT NULL; ALTER TABLE t1 ADD latin2_f CHAR(32) NOT NULL;
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( 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 '', `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) 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 ) TYPE=MyISAM CHARSET=latin2
ALTER TABLE t1 DROP latin2_f, DROP latin5_f; ALTER TABLE t1 DROP latin2_f, DROP latin5_f;
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( 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 '' `koi8_ru_f` char(32) character set koi8r NOT NULL default ''
) TYPE=MyISAM CHARSET=latin2 ) TYPE=MyISAM CHARSET=latin2
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('a','LAT SMALL A'); 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 Table Create Table
t2 CREATE TABLE `t2` ( t2 CREATE TABLE `t2` (
`ticket` int(11) default NULL, `ticket` int(11) default NULL,
`inhalt` text character set latin1, `inhalt` text,
KEY `tig` (`ticket`), KEY `tig` (`ticket`),
FULLTEXT KEY `tix` (`inhalt`) FULLTEXT KEY `tix` (`inhalt`)
) TYPE=MyISAM CHARSET=latin1 ) 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; show create table t1;
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( t1 CREATE TABLE `t1` (
`a` char(20) character set latin1 default NULL, `a` char(20) default NULL,
KEY `a` (`a`) KEY `a` (`a`)
) TYPE=InnoDB CHARSET=latin1 ) TYPE=InnoDB CHARSET=latin1
drop table t1; drop table t1;

View File

@ -172,7 +172,7 @@ show create table t3;
Table Create Table Table Create Table
t3 CREATE TABLE `t3` ( t3 CREATE TABLE `t3` (
`a` int(11) NOT NULL default '0', `a` int(11) NOT NULL default '0',
`b` char(20) character set latin1 default NULL, `b` char(20) default NULL,
KEY `a` (`a`) KEY `a` (`a`)
) TYPE=MRG_MyISAM CHARSET=latin1 UNION=(t1,t2) ) 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); 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 auto int(11) binary PRI NULL auto_increment select,insert,update,references
fld1 int(6) unsigned zerofill binary UNI 000000 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 companynr tinyint(2) unsigned zerofill binary 00 select,insert,update,references
fld3 char(30) character set latin1 latin1 MUL select,insert,update,references fld3 char(30) latin1 MUL select,insert,update,references
fld4 char(35) character set latin1 latin1 select,insert,update,references fld4 char(35) latin1 select,insert,update,references
fld5 char(35) character set latin1 latin1 select,insert,update,references fld5 char(35) latin1 select,insert,update,references
fld6 char(4) character set latin1 latin1 select,insert,update,references fld6 char(4) latin1 select,insert,update,references
show full columns from t2 from test like 'f%'; show full columns from t2 from test like 'f%';
Field Type Collation Null Key Default Extra Privileges Comment Field Type Collation Null Key Default Extra Privileges Comment
fld1 int(6) unsigned zerofill binary UNI 000000 select,insert,update,references fld1 int(6) unsigned zerofill binary UNI 000000 select,insert,update,references
fld3 char(30) character set latin1 latin1 MUL select,insert,update,references fld3 char(30) latin1 MUL select,insert,update,references
fld4 char(35) character set latin1 latin1 select,insert,update,references fld4 char(35) latin1 select,insert,update,references
fld5 char(35) character set latin1 latin1 select,insert,update,references fld5 char(35) latin1 select,insert,update,references
fld6 char(4) character set latin1 latin1 select,insert,update,references fld6 char(4) latin1 select,insert,update,references
show full columns from t2 from test like 's%'; show full columns from t2 from test like 's%';
Field Type Collation Null Key Default Extra Privileges Comment Field Type Collation Null Key Default Extra Privileges Comment
show keys from t2; show keys from t2;

View File

@ -93,14 +93,14 @@ c int not null comment 'int column'
show create table t1 ; show create table t1 ;
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( t1 CREATE TABLE `t1` (
`test_set` set('val1','val2','val3') character set latin1 NOT NULL default '', `test_set` set('val1','val2','val3') NOT NULL default '',
`name` char(20) character set latin1 default 'O''Brien' COMMENT 'O''Brien as default', `name` char(20) default 'O''Brien' COMMENT 'O''Brien as default',
`c` int(11) NOT NULL default '0' COMMENT 'int column' `c` int(11) NOT NULL default '0' COMMENT 'int column'
) TYPE=MyISAM CHARSET=latin1 COMMENT='it''s a table' ) TYPE=MyISAM CHARSET=latin1 COMMENT='it''s a table'
show full columns from t1; show full columns from t1;
Field Type Collation Null Key Default Extra Privileges Comment Field Type Collation Null Key Default Extra Privileges Comment
test_set set('val1','val2','val3') character set latin1 latin1 select,insert,update,references test_set set('val1','val2','val3') latin1 select,insert,update,references
name char(20) character set latin1 latin1 YES O'Brien select,insert,update,references O'Brien as default 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 c int(11) binary 0 select,insert,update,references int column
drop table t1; drop table t1;
create table t1 (a int not null, unique aa (a)); create table t1 (a int not null, unique aa (a));
@ -133,7 +133,7 @@ show create table t1;
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( t1 CREATE TABLE `t1` (
`a` int(11) NOT NULL default '0', `a` int(11) NOT NULL default '0',
`b` char(10) character set latin1 default NULL, `b` char(10) default NULL,
KEY `b` (`b`) 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' ) 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; alter table t1 MAX_ROWS=200 ROW_FORMAT=dynamic PACK_KEYS=0;
@ -141,7 +141,7 @@ show create table t1;
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( t1 CREATE TABLE `t1` (
`a` int(11) NOT NULL default '0', `a` int(11) NOT NULL default '0',
`b` varchar(10) character set latin1 default NULL, `b` varchar(10) default NULL,
KEY `b` (`b`) 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' ) 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; 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 Table Create Table
t1 CREATE TABLE `t1` ( t1 CREATE TABLE `t1` (
`a` int(11) NOT NULL default '0', `a` int(11) NOT NULL default '0',
`b` varchar(10) character set latin1 default NULL, `b` varchar(10) default NULL,
KEY `b` (`b`) KEY `b` (`b`)
) TYPE=MyISAM CHARSET=latin1 ) TYPE=MyISAM CHARSET=latin1
drop table t1; 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; show columns from t1;
Field Type Collation Null Key Default Extra Field Type Collation Null Key Default Extra
a blob binary YES NULL a blob binary YES NULL
b text character set latin1 latin1 YES NULL b text latin1 YES NULL
c blob binary YES NULL c blob binary YES NULL
d mediumtext character set latin1 latin1 YES NULL d mediumtext latin1 YES NULL
e longtext character set latin1 latin1 YES NULL e longtext latin1 YES NULL
CREATE TABLE t2 (a char(257), b varchar(70000) binary, c varchar(70000000)); CREATE TABLE t2 (a char(257), b varchar(70000) binary, c varchar(70000000));
Warnings: Warnings:
Warning 1244 Converting column 'a' from CHAR to TEXT 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 Warning 1244 Converting column 'c' from CHAR to TEXT
show columns from t2; show columns from t2;
Field Type Collation Null Key Default Extra 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 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); create table t3 (a long, b long byte);
show create TABLE t3; show create TABLE t3;
Table Create Table Table Create Table
t3 CREATE TABLE `t3` ( t3 CREATE TABLE `t3` (
`a` mediumtext character set latin1, `a` mediumtext,
`b` mediumblob `b` mediumblob
) TYPE=MyISAM CHARSET=latin1 ) TYPE=MyISAM CHARSET=latin1
drop table t1,t2,t3 drop table t1,t2,t3
@ -70,15 +70,15 @@ update t1 set c="",b=null where c="1";
lock tables t1 READ; lock tables t1 READ;
show full fields from t1; show full fields from t1;
Field Type Collation Null Key Default Extra Privileges Comment Field Type Collation Null Key Default Extra Privileges Comment
t text character set latin1 latin1 YES NULL select,insert,update,references t text latin1 YES NULL select,insert,update,references
c varchar(10) character set latin1 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 b blob binary YES NULL select,insert,update,references
d varchar(10) binary binary YES NULL select,insert,update,references d varchar(10) binary binary YES NULL select,insert,update,references
lock tables t1 WRITE; lock tables t1 WRITE;
show full fields from t1; show full fields from t1;
Field Type Collation Null Key Default Extra Privileges Comment Field Type Collation Null Key Default Extra Privileges Comment
t text character set latin1 latin1 YES NULL select,insert,update,references t text latin1 YES NULL select,insert,update,references
c varchar(10) character set latin1 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 b blob binary YES NULL select,insert,update,references
d varchar(10) binary binary YES NULL select,insert,update,references d varchar(10) binary binary YES NULL select,insert,update,references
unlock tables; unlock tables;

View File

@ -1626,13 +1626,13 @@ create table t1 (a enum (' ','a','b') not null);
show create table t1; show create table t1;
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( 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 ) TYPE=MyISAM CHARSET=latin1
drop table t1; drop table t1;
create table t1 (a enum (' ','a','b ') not null default 'b '); create table t1 (a enum (' ','a','b ') not null default 'b ');
show create table t1; show create table t1;
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( 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 ) TYPE=MyISAM CHARSET=latin1
drop table t1; drop table t1;

View File

@ -40,7 +40,7 @@ KEY (options,flags)
show full fields from t1; show full fields from t1;
Field Type Collation Null Key Default Extra Privileges Comment Field Type Collation Null Key Default Extra Privileges Comment
auto int(5) unsigned binary PRI NULL auto_increment select,insert,update,references 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 tiny tinyint(4) binary MUL 0 select,insert,update,references
short smallint(6) binary MUL 1 select,insert,update,references short smallint(6) binary MUL 1 select,insert,update,references
medium mediumint(8) binary MUL 0 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 tinyblob_col tinyblob binary YES NULL select,insert,update,references
mediumblob_col mediumblob binary select,insert,update,references mediumblob_col mediumblob binary select,insert,update,references
longblob_col longblob 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 options enum('one','two','tree') latin1 MUL one select,insert,update,references
flags set('one','two','tree') character set latin1 latin1 select,insert,update,references flags set('one','two','tree') latin1 select,insert,update,references
show keys from t1; show keys from t1;
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment 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 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; show full columns from t1;
Field Type Collation Null Key Default Extra Privileges Comment Field Type Collation Null Key Default Extra Privileges Comment
auto int(5) unsigned binary MUL NULL auto_increment select,insert,update,references 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 tiny tinyint(4) binary MUL 0 select,insert,update,references
short smallint(6) 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 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 ulong int(11) unsigned binary MUL 0 select,insert,update,references
ulonglong bigint(13) 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 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 time_field time latin1 YES NULL select,insert,update,references
date_time datetime 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 tinyblob_col tinyblob binary YES NULL select,insert,update,references
mediumblob_col mediumblob binary 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 options enum('one','two','tree') latin1 MUL one select,insert,update,references
flags set('one','two','tree') character set latin1 latin1 select,insert,update,references flags set('one','two','tree') latin1 select,insert,update,references
new_field varchar(10) character set latin1 latin1 new select,insert,update,references new_field varchar(10) latin1 new select,insert,update,references
show full columns from t2; show full columns from t2;
Field Type Collation Null Key Default Extra Privileges Comment Field Type Collation Null Key Default Extra Privileges Comment
auto int(5) unsigned binary 0 select,insert,update,references 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 tiny tinyint(4) binary 0 select,insert,update,references
short smallint(6) binary 0 select,insert,update,references short smallint(6) binary 0 select,insert,update,references
medium mediumint(8) 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 ulong int(11) unsigned binary 0 select,insert,update,references
ulonglong bigint(13) 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 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 time_field time latin1 YES NULL select,insert,update,references
date_time datetime 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 tinyblob_col tinyblob binary YES NULL select,insert,update,references
mediumblob_col mediumblob binary 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 options enum('one','two','tree') latin1 one select,insert,update,references
flags set('one','two','tree') character set latin1 latin1 select,insert,update,references flags set('one','two','tree') latin1 select,insert,update,references
new_field varchar(10) character set latin1 latin1 new 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))); 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 auto auto
16 16 16 16
@ -231,8 +231,8 @@ show full columns from t2;
Field Type Collation Null Key Default Extra Privileges Comment Field Type Collation Null Key Default Extra Privileges Comment
auto bigint(17) unsigned binary PRI 0 select,insert,update,references auto bigint(17) unsigned binary PRI 0 select,insert,update,references
t1 bigint(1) binary 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 t2 char(1) latin1 select,insert,update,references
t3 mediumtext character set latin1 latin1 select,insert,update,references t3 mediumtext latin1 select,insert,update,references
t4 mediumblob binary select,insert,update,references t4 mediumblob binary select,insert,update,references
select * from t2; select * from t2;
auto t1 t2 t3 t4 auto t1 t2 t3 t4

View File

@ -3,13 +3,13 @@ create table t1 (a set (' ','a','b') not null);
show create table t1; show create table t1;
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( 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 ) TYPE=MyISAM CHARSET=latin1
drop table t1; drop table t1;
create table t1 (a set (' ','a','b ') not null default 'b '); create table t1 (a set (' ','a','b ') not null default 'b ');
show create table t1; show create table t1;
Table Create Table Table Create Table
t1 CREATE TABLE `t1` ( 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 ) TYPE=MyISAM CHARSET=latin1
drop table t1; 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 \ my_getopt.c my_mkdir.c \
default.c my_compress.c checksum.c raid.cc \ default.c my_compress.c checksum.c raid.cc \
my_net.c my_semaphore.c my_port.c \ 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_gethostbyname.c rijndael.c my_aes.c sha1.c \
my_handler.c my_handler.c
EXTRA_DIST = thr_alarm.c thr_lock.c my_pthread.c my_thr_init.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 // Maximum allowed exponent value for converting string to decimal
#define MAX_EXPONENT 1024 #define MAX_EXPONENT 1024
/***************************************************************************** /*****************************************************************************
Instansiate templates and static variables 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) Test if given number is a int (or a fixed format float with .000)
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... 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; 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 end .0000 */
// 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++)
{
if (!my_isdigit(cs,*str))
{
if (*str == '.') if (*str == '.')
{ // Allow '.0000' {
for (str++ ; str != end && *str == '0'; str++) ; for (str++ ; str != end && *str == '0'; str++) ;
if (str == end)
return 1;
} }
if (!my_isspace(cs,*str)) /* Allow end space */
return 0;
for (str++ ; str != end ; str++) for (str++ ; str != end ; str++)
{
if (!my_isspace(cs,*str)) if (!my_isspace(cs,*str))
return 0; return 0;
return 1;
}
} }
return 1; 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) 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)) while (length && my_isspace(cs,*str))
{ // Allow start space { // Allow start space
@ -207,17 +210,10 @@ bool Field::send_binary(Protocol *protocol)
void Field_num::add_zerofill_and_unsigned(String &res) const void Field_num::add_zerofill_and_unsigned(String &res) const
{ {
uint oldlen=res.length(); if (unsigned_flag)
if (oldlen < res.alloced_length()) res.append(" unsigned");
{ if (zerofill)
uint len=res.alloced_length()-oldlen; res.append(" zerofill");
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);
}
} }
void Field_num::make_field(Send_field *field) void Field_num::make_field(Send_field *field)
@ -247,19 +243,15 @@ void Field_str::make_field(Send_field *field)
field->decimals=0; field->decimals=0;
} }
void Field_str::add_binary_or_charset(String &res) const void Field_str::add_binary_or_charset(String &res) const
{ {
uint oldlen=res.length();
if (oldlen < res.alloced_length())
{
CHARSET_INFO *cs=res.charset();
uint len=res.alloced_length() - oldlen;
char *end=(char*)(res.ptr()+oldlen);
if (binary()) if (binary())
len=cs->snprintf(cs,end,len," binary"); res.append(" binary");
else else if (field_charset != table->table_charset)
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) bool Field::get_date(TIME *ltime,bool fuzzydate)
{ {
char buff[40]; 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)) || if (!(res=val_str(&tmp,&tmp2)) ||
str_to_TIME(res->ptr(),res->length(),ltime,fuzzydate) == TIMESTAMP_NONE) str_to_TIME(res->ptr(),res->length(),ltime,fuzzydate) == TIMESTAMP_NONE)
return 1; return 1;
@ -297,7 +289,7 @@ bool Field::get_date(TIME *ltime,bool fuzzydate)
bool Field::get_time(TIME *ltime) bool Field::get_time(TIME *ltime)
{ {
char buff[40]; 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)) || if (!(res=val_str(&tmp,&tmp2)) ||
str_to_time(res->ptr(),res->length(),ltime)) str_to_time(res->ptr(),res->length(),ltime))
return 1; return 1;
@ -311,23 +303,23 @@ void Field::store_time(TIME *ltime,timestamp_type type)
char buff[25]; char buff[25];
switch (type) { switch (type) {
case TIMESTAMP_NONE: case TIMESTAMP_NONE:
store("",0,my_charset_latin1); // Probably an error store("",0,my_charset_bin); // Probably an error
break; break;
case TIMESTAMP_DATE: case TIMESTAMP_DATE:
sprintf(buff,"%04d-%02d-%02d", ltime->year,ltime->month,ltime->day); sprintf(buff,"%04d-%02d-%02d", ltime->year,ltime->month,ltime->day);
store(buff,10,my_charset_latin1); store(buff,10,my_charset_bin);
break; break;
case TIMESTAMP_FULL: case TIMESTAMP_FULL:
sprintf(buff,"%04d-%02d-%02d %02d:%02d:%02d", sprintf(buff,"%04d-%02d-%02d %02d:%02d:%02d",
ltime->year,ltime->month,ltime->day, ltime->year,ltime->month,ltime->day,
ltime->hour,ltime->minute,ltime->second); ltime->hour,ltime->minute,ltime->second);
store(buff,19,my_charset_latin1); store(buff,19,my_charset_bin);
break; break;
case TIMESTAMP_TIME: case TIMESTAMP_TIME:
{ {
ulong length= my_sprintf(buff, (buff, "%02d:%02d:%02d", ulong length= my_sprintf(buff, (buff, "%02d:%02d:%02d",
ltime->hour,ltime->minute,ltime->second)); ltime->hour,ltime->minute,ltime->second));
store(buff,(uint) length, my_charset_latin1); store(buff,(uint) length, my_charset_bin);
break; 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 void Field_null::sql_type(String &res) const
{ {
CHARSET_INFO *cs=res.charset(); res.set_latin1("null", 4);
uint len;
len=cs->snprintf(cs,(char*)res.ptr(),res.alloced_length(),"null");
res.length(len);
} }
@ -360,7 +349,7 @@ void Field_null::sql_type(String &res) const
void void
Field_decimal::reset(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) 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) 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); /* Convert character set if the old one is multi byte */
from=l1from.ptr(); if (cs->mbmaxlen > 1)
len=l1from.length(); {
tmp.copy(from, len, cs, my_charset_bin);
from= tmp.ptr();
len= tmp.length();
}
const char *end= from+len; const char *end= from+len;
/* The pointer where the field value starts (i.e., "where to write") */ /* The pointer where the field value starts (i.e., "where to write") */
@ -469,7 +463,7 @@ int Field_decimal::store(const char *from, uint len, CHARSET_INFO *cs)
tmp_dec++; tmp_dec++;
/* skip pre-space */ /* skip pre-space */
while (from != end && my_isspace(my_charset_latin1,*from)) while (from != end && my_isspace(my_charset_bin,*from))
from++; from++;
if (from == end) 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 for (; from!=end && *from == '0'; from++) ; // Read prezeros
pre_zeros_end=int_digits_from=from; pre_zeros_end=int_digits_from=from;
/* Read non zero digits at the left of '.'*/ /* 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; int_digits_end=from;
if (from!=end && *from == '.') // Some '.' ? if (from!=end && *from == '.') // Some '.' ?
from++; from++;
frac_digits_from= from; frac_digits_from= from;
/* Read digits at the right of '.' */ /* 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; frac_digits_end=from;
// Some exponentiation symbol ? // Some exponentiation symbol ?
if (from != end && (*from == 'e' || *from == 'E')) 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 exponents will become small (e.g. 1e4294967296 will become 1e0, and the
field will finally contain 1 instead of its max possible value). 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'); exponent=10*exponent+(*from-'0');
if (exponent>MAX_EXPONENT) 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) if (current_thd->count_cuted_fields)
{ {
// Skip end spaces // 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 if (from != end) // If still something left, warn
{ {
current_thd->cuted_fields++; current_thd->cuted_fields++;
@ -838,30 +832,29 @@ int Field_decimal::store(longlong nr)
double Field_decimal::val_real(void) double Field_decimal::val_real(void)
{ {
CHARSET_INFO *cs=charset(); return my_strntod(my_charset_bin, ptr, field_length, NULL);
return my_strntod(cs,ptr,field_length,NULL);
} }
longlong Field_decimal::val_int(void) longlong Field_decimal::val_int(void)
{ {
CHARSET_INFO *cs=charset();
if (unsigned_flag) if (unsigned_flag)
return my_strntoull(cs,ptr,field_length,NULL,10); return my_strntoull(my_charset_bin, ptr, field_length, NULL, 10);
else 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 *Field_decimal::val_str(String *val_buffer __attribute__((unused)),
String *val_ptr) String *val_ptr)
{ {
char *str; char *str;
CHARSET_INFO *cs=current_thd->variables.thd_charset;
for (str=ptr ; *str == ' ' ; str++) ; for (str=ptr ; *str == ' ' ; str++) ;
uint tmp_length=(uint) (str-ptr); uint tmp_length=(uint) (str-ptr);
val_ptr->set_charset(my_charset_bin);
if (field_length < tmp_length) // Error in data if (field_length < tmp_length) // Error in data
val_ptr->length(0); val_ptr->length(0);
else 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; 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; for (end=a_ptr+field_length;
a_ptr != end && a_ptr != end &&
(*a_ptr == *b_ptr || (*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') && *a_ptr == '0') &&
(my_isspace(my_charset_latin1,*b_ptr) || *b_ptr == '+' || (my_isspace(my_charset_bin,*b_ptr) || *b_ptr == '+' ||
*b_ptr == '0'))); *b_ptr == '0')));
a_ptr++,b_ptr++) a_ptr++,b_ptr++)
{ {
@ -908,7 +901,7 @@ void Field_decimal::sort_string(char *to,uint length)
char *str,*end; char *str,*end;
for (str=ptr,end=ptr+length; for (str=ptr,end=ptr+length;
str != end && str != end &&
((my_isspace(my_charset_latin1,*str) || *str == '+' || ((my_isspace(my_charset_bin,*str) || *str == '+' ||
*str == '0')) ; *str == '0')) ;
str++) str++)
*to++=' '; *to++=' ';
@ -920,7 +913,7 @@ void Field_decimal::sort_string(char *to,uint length)
*to++=1; // Smaller than any number *to++=1; // Smaller than any number
str++; str++;
while (str != end) while (str != end)
if (my_isdigit(my_charset_latin1,*str)) if (my_isdigit(my_charset_bin,*str))
*to++= (char) ('9' - *str++); *to++= (char) ('9' - *str++);
else else
*to++= *str++; *to++= *str++;
@ -933,14 +926,12 @@ void Field_decimal::sql_type(String &res) const
{ {
CHARSET_INFO *cs=res.charset(); CHARSET_INFO *cs=res.charset();
uint tmp=field_length; uint tmp=field_length;
uint len;
if (!unsigned_flag) if (!unsigned_flag)
tmp--; tmp--;
if (dec) if (dec)
tmp--; tmp--;
len=cs->snprintf(cs,(char*) res.ptr(),res.alloced_length(), res.length(cs->snprintf(cs,(char*) res.ptr(),res.alloced_length(),
"decimal(%d,%d)",tmp,dec); "decimal(%d,%d)",tmp,dec));
res.length(len);
add_zerofill_and_unsigned(res); 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) 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; int error= 0;
if (unsigned_flag) if (unsigned_flag)
@ -968,7 +960,7 @@ int Field_tiny::store(const char *from,uint len,CHARSET_INFO *cs)
current_thd->cuted_fields++; current_thd->cuted_fields++;
error= 1; 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++; current_thd->cuted_fields++;
error= 1; error= 1;
@ -988,7 +980,7 @@ int Field_tiny::store(const char *from,uint len,CHARSET_INFO *cs)
current_thd->cuted_fields++; current_thd->cuted_fields++;
error= 1; 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++; current_thd->cuted_fields++;
error= 1; error= 1;
@ -1098,7 +1090,7 @@ longlong Field_tiny::val_int(void)
String *Field_tiny::val_str(String *val_buffer, String *Field_tiny::val_str(String *val_buffer,
String *val_ptr __attribute__((unused))) String *val_ptr __attribute__((unused)))
{ {
CHARSET_INFO *cs=current_thd->variables.thd_charset; CHARSET_INFO *cs= my_charset_bin;
uint length; uint length;
uint mlength=max(field_length+1,5*cs->mbmaxlen); uint mlength=max(field_length+1,5*cs->mbmaxlen);
val_buffer->alloc(mlength); 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 void Field_tiny::sql_type(String &res) const
{ {
CHARSET_INFO *cs=res.charset(); CHARSET_INFO *cs=res.charset();
uint len=cs->snprintf(cs,(char*) res.ptr(),res.alloced_length(), res.length(cs->snprintf(cs,(char*) res.ptr(),res.alloced_length(),
"tinyint(%d)",(int) field_length); "tinyint(%d)",(int) field_length));
res.length(len);
add_zerofill_and_unsigned(res); 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) 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; int error= 0;
if (unsigned_flag) if (unsigned_flag)
{ {
@ -1171,7 +1160,7 @@ int Field_short::store(const char *from,uint len,CHARSET_INFO *cs)
current_thd->cuted_fields++; current_thd->cuted_fields++;
error= 1; 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++; current_thd->cuted_fields++;
error= 1; error= 1;
@ -1191,7 +1180,7 @@ int Field_short::store(const char *from,uint len,CHARSET_INFO *cs)
current_thd->cuted_fields++; current_thd->cuted_fields++;
error= 1; 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++; current_thd->cuted_fields++;
error= 1; error= 1;
@ -1337,7 +1326,7 @@ longlong Field_short::val_int(void)
String *Field_short::val_str(String *val_buffer, String *Field_short::val_str(String *val_buffer,
String *val_ptr __attribute__((unused))) String *val_ptr __attribute__((unused)))
{ {
CHARSET_INFO *cs=current_thd->variables.thd_charset; CHARSET_INFO *cs= my_charset_bin;
uint length; uint length;
uint mlength=max(field_length+1,7*cs->mbmaxlen); uint mlength=max(field_length+1,7*cs->mbmaxlen);
val_buffer->alloc(mlength); val_buffer->alloc(mlength);
@ -1414,22 +1403,20 @@ void Field_short::sort_string(char *to,uint length __attribute__((unused)))
void Field_short::sql_type(String &res) const void Field_short::sql_type(String &res) const
{ {
CHARSET_INFO *cs=res.charset(); CHARSET_INFO *cs=res.charset();
uint len=cs->snprintf(cs,(char*) res.ptr(),res.alloced_length(), res.length(cs->snprintf(cs,(char*) res.ptr(),res.alloced_length(),
"smallint(%d)",(int) field_length); "smallint(%d)",(int) field_length));
res.length(len);
add_zerofill_and_unsigned(res); 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) 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; int error= 0;
if (unsigned_flag) if (unsigned_flag)
@ -1446,7 +1433,7 @@ int Field_medium::store(const char *from,uint len,CHARSET_INFO *cs)
current_thd->cuted_fields++; current_thd->cuted_fields++;
error= 1; 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++; current_thd->cuted_fields++;
error= 1; error= 1;
@ -1466,7 +1453,7 @@ int Field_medium::store(const char *from,uint len,CHARSET_INFO *cs)
current_thd->cuted_fields++; current_thd->cuted_fields++;
error= 1; 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++; current_thd->cuted_fields++;
error= 1; error= 1;
@ -1572,16 +1559,18 @@ double Field_medium::val_real(void)
return (double) j; return (double) j;
} }
longlong Field_medium::val_int(void) longlong Field_medium::val_int(void)
{ {
long j= unsigned_flag ? (long) uint3korr(ptr) : sint3korr(ptr); long j= unsigned_flag ? (long) uint3korr(ptr) : sint3korr(ptr);
return (longlong) j; return (longlong) j;
} }
String *Field_medium::val_str(String *val_buffer, String *Field_medium::val_str(String *val_buffer,
String *val_ptr __attribute__((unused))) String *val_ptr __attribute__((unused)))
{ {
CHARSET_INFO *cs=current_thd->variables.thd_charset; CHARSET_INFO *cs= my_charset_bin;
uint length; uint length;
uint mlength=max(field_length+1,10*cs->mbmaxlen); uint mlength=max(field_length+1,10*cs->mbmaxlen);
val_buffer->alloc(mlength); 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 void Field_medium::sql_type(String &res) const
{ {
CHARSET_INFO *cs=res.charset(); CHARSET_INFO *cs=res.charset();
uint len=cs->snprintf(cs,(char*) res.ptr(),res.alloced_length(), res.length(cs->snprintf(cs,(char*) res.ptr(),res.alloced_length(),
"mediumint(%d)",(int) field_length); "mediumint(%d)",(int) field_length));
res.length(len);
add_zerofill_and_unsigned(res); 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) int Field_long::store(const char *from,uint len,CHARSET_INFO *cs)
{ {
long tmp;
int error= 0;
char *end; char *end;
/* TODO: Make multi-byte-character safe */
while (len && my_isspace(cs,*from)) while (len && my_isspace(cs,*from))
{ {
len--; from++; len--; from++;
} }
long tmp; my_errno=0;
String tmp_str(from, len, cs);
from= tmp_str.c_ptr(); // Add end null if needed
int error= 0;
errno=0;
if (unsigned_flag) if (unsigned_flag)
{ {
if (!len || *from == '-') if (!len || *from == '-')
{ {
tmp=0; // Set negative to 0 tmp=0; // Set negative to 0
errno=ERANGE; my_errno=ERANGE;
error= 1; error= 1;
} }
else else
@ -1670,9 +1655,9 @@ int Field_long::store(const char *from,uint len,CHARSET_INFO *cs)
} }
else else
tmp=my_strntol(cs,from,len,&end,10); tmp=my_strntol(cs,from,len,&end,10);
if (errno || if (my_errno ||
(from+len != end && current_thd->count_cuted_fields && (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++; current_thd->cuted_fields++;
error= 1; error= 1;
@ -1817,7 +1802,7 @@ longlong Field_long::val_int(void)
String *Field_long::val_str(String *val_buffer, String *Field_long::val_str(String *val_buffer,
String *val_ptr __attribute__((unused))) String *val_ptr __attribute__((unused)))
{ {
CHARSET_INFO *cs=current_thd->variables.thd_charset; CHARSET_INFO *cs= my_charset_bin;
uint length; uint length;
uint mlength=max(field_length+1,12*cs->mbmaxlen); uint mlength=max(field_length+1,12*cs->mbmaxlen);
val_buffer->alloc(mlength); 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 void Field_long::sql_type(String &res) const
{ {
CHARSET_INFO *cs=res.charset(); CHARSET_INFO *cs=res.charset();
uint len=cs->snprintf(cs,(char*) res.ptr(),res.alloced_length(), res.length(cs->snprintf(cs,(char*) res.ptr(),res.alloced_length(),
"int(%d)",(int) field_length); "int(%d)",(int) field_length));
res.length(len);
add_zerofill_and_unsigned(res); 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) int Field_longlong::store(const char *from,uint len,CHARSET_INFO *cs)
{ {
longlong tmp;
int error= 0;
char *end; char *end;
/* TODO: Make multi byte safe */
while (len && my_isspace(cs,*from)) while (len && my_isspace(cs,*from))
{ // For easy error check { // For easy error check
len--; from++; len--; from++;
} }
longlong tmp; my_errno=0;
String tmp_str(from, len, cs);
from= tmp_str.c_ptr(); // Add end null if needed
int error= 0;
errno=0;
if (unsigned_flag) if (unsigned_flag)
{ {
if (!len || *from == '-') if (!len || *from == '-')
{ {
tmp=0; // Set negative to 0 tmp=0; // Set negative to 0
errno=ERANGE; my_errno= ERANGE;
error= 1; error= 1;
} }
else else
@ -1931,9 +1914,9 @@ int Field_longlong::store(const char *from,uint len,CHARSET_INFO *cs)
} }
else else
tmp=my_strntoll(cs,from,len,&end,10); tmp=my_strntoll(cs,from,len,&end,10);
if (errno || if (my_errno ||
(from+len != end && current_thd->count_cuted_fields && (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++; current_thd->cuted_fields++;
#ifdef WORDS_BIGENDIAN #ifdef WORDS_BIGENDIAN
if (table->db_low_byte_first) 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 *Field_longlong::val_str(String *val_buffer,
String *val_ptr __attribute__((unused))) String *val_ptr __attribute__((unused)))
{ {
CHARSET_INFO *cs=current_thd->variables.thd_charset; CHARSET_INFO *cs= my_charset_bin;
uint length; uint length;
uint mlength=max(field_length+1,22*cs->mbmaxlen); uint mlength=max(field_length+1,22*cs->mbmaxlen);
val_buffer->alloc(mlength); 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 void Field_longlong::sql_type(String &res) const
{ {
CHARSET_INFO *cs=res.charset(); CHARSET_INFO *cs=res.charset();
uint len=cs->snprintf(cs,(char*) res.ptr(),res.alloced_length(), res.length(cs->snprintf(cs,(char*) res.ptr(),res.alloced_length(),
"bigint(%d)",(int) field_length); "bigint(%d)",(int) field_length));
res.length(len);
add_zerofill_and_unsigned(res); 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) int Field_float::store(const char *from,uint len,CHARSET_INFO *cs)
{ {
errno=0; errno=0; // my_strntod() changes errno
Field_float::store(my_strntod(cs,from,len,(char**)NULL)); Field_float::store(my_strntod(cs,(char*) from,len,(char**)NULL));
if (errno || current_thd->count_cuted_fields && !test_if_real(from,len,cs)) if (errno || current_thd->count_cuted_fields && !test_if_real(from,len,cs))
{ {
current_thd->cuted_fields++; current_thd->cuted_fields++;
@ -2394,18 +2376,16 @@ bool Field_float::send_binary(Protocol *protocol)
void Field_float::sql_type(String &res) const void Field_float::sql_type(String &res) const
{ {
CHARSET_INFO *cs=res.charset();
uint len;
if (dec == NOT_FIXED_DEC) if (dec == NOT_FIXED_DEC)
{ {
len=cs->snprintf(cs,(char*) res.ptr(),res.alloced_length(),"float"); res.set_latin1("float", 5);
} }
else else
{ {
len=cs->snprintf(cs,(char*) res.ptr(),res.alloced_length(), CHARSET_INFO *cs= res.charset();
"float(%d,%d)",(int) field_length,dec); 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); 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) int Field_double::store(const char *from,uint len,CHARSET_INFO *cs)
{ {
errno=0; errno=0; // my_strntod() changes errno
int error= 0; 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)) if (errno || current_thd->count_cuted_fields && !test_if_real(from,len,cs))
{ {
current_thd->cuted_fields++; 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 void Field_double::sql_type(String &res) const
{ {
CHARSET_INFO *cs=res.charset(); CHARSET_INFO *cs=res.charset();
uint len;
if (dec == NOT_FIXED_DEC) if (dec == NOT_FIXED_DEC)
{ {
len=cs->snprintf(cs,(char*) res.ptr(),res.alloced_length(),"double"); res.set_latin1("double",6);
} }
else else
{ {
len=cs->snprintf(cs,(char*) res.ptr(),res.alloced_length(), res.length(cs->snprintf(cs,(char*) res.ptr(),res.alloced_length(),
"double(%d,%d)",(int) field_length,dec); "double(%d,%d)",(int) field_length,dec));
} }
res.length(len);
add_zerofill_and_unsigned(res); 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 Convert a datetime of formats YYMMDD, YYYYMMDD or YYMMDDHHMSS to
** YYYYMMDDHHMMSS. The high date '99991231235959' is checked before this YYYYMMDDHHMMSS. The high date '99991231235959' is checked before this
** function. function.
*/ */
static longlong fix_datetime(longlong nr) static longlong fix_datetime(longlong nr)
@ -2854,9 +2832,10 @@ String *Field_timestamp::val_str(String *val_buffer,
if (temp == 0L) if (temp == 0L)
{ /* Zero time is "000000" */ { /* Zero time is "000000" */
strmov(to, "0000-00-00 00:00:00"); val_ptr->set("0000-00-00 00:00:00", 19, my_charset_bin);
return val_buffer; return val_ptr;
} }
val_buffer->set_charset(my_charset_bin); // Safety
time_arg=(time_t) temp; time_arg=(time_t) temp;
localtime_r(&time_arg,&tm_tmp); localtime_r(&time_arg,&tm_tmp);
l_time=&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 void Field_timestamp::sql_type(String &res) const
{ {
CHARSET_INFO *cs=res.charset(); res.set_latin1("timestamp", 9);
uint len=cs->snprintf(cs,(char*)res.ptr(),res.alloced_length(),"timestamp");
res.length(len);
} }
@ -3125,6 +3102,12 @@ longlong Field_time::val_int(void)
return (longlong) sint3korr(ptr); 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 *Field_time::val_str(String *val_buffer,
String *val_ptr __attribute__((unused))) 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 void Field_time::sql_type(String &res) const
{ {
CHARSET_INFO *cs=res.charset(); res.set_latin1("time", 4);
uint len=cs->snprintf(cs,(char*)res.ptr(),res.alloced_length(),"time");
res.length(len);
} }
/**************************************************************************** /****************************************************************************
@ -3202,7 +3183,8 @@ void Field_time::sql_type(String &res) const
int Field_year::store(const char *from, uint len,CHARSET_INFO *cs) 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) 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++; current_thd->cuted_fields++;
return 1; 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++; current_thd->cuted_fields++;
if (nr != 0 || len != 4) 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 void Field_year::sql_type(String &res) const
{ {
CHARSET_INFO *cs=res.charset(); CHARSET_INFO *cs=res.charset();
ulong len=cs->snprintf(cs,(char*)res.ptr(),res.alloced_length(), res.length(cs->snprintf(cs,(char*)res.ptr(),res.alloced_length(),
"year(%d)",(int) field_length); "year(%d)",(int) field_length));
res.length(len);
} }
@ -3375,6 +3356,7 @@ int Field_date::store(longlong nr)
return error; return error;
} }
bool Field_date::send_binary(Protocol *protocol) bool Field_date::send_binary(Protocol *protocol)
{ {
longlong tmp= Field_date::val_int(); 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 void Field_date::sql_type(String &res) const
{ {
CHARSET_INFO *cs=res.charset(); res.set_latin1("date", 4);
uint len=cs->snprintf(cs,(char*)res.ptr(),res.alloced_length(),"date");
res.length(len);
} }
/**************************************************************************** /****************************************************************************
@ -3639,9 +3619,7 @@ void Field_newdate::sort_string(char *to,uint length __attribute__((unused)))
void Field_newdate::sql_type(String &res) const void Field_newdate::sql_type(String &res) const
{ {
CHARSET_INFO *cs=res.charset(); res.set_latin1("date", 4);
uint len=cs->snprintf(cs,(char*)res.ptr(),res.alloced_length(),"date");
res.length(len);
} }
@ -3872,9 +3850,7 @@ void Field_datetime::sort_string(char *to,uint length __attribute__((unused)))
void Field_datetime::sql_type(String &res) const void Field_datetime::sql_type(String &res) const
{ {
CHARSET_INFO *cs=res.charset(); res.set_latin1("datetime", 8);
uint len=cs->snprintf(cs,(char*)res.ptr(),res.alloced_length(),"datetime");
res.length(len);
} }
/**************************************************************************** /****************************************************************************
@ -3929,7 +3905,7 @@ int Field_string::store(double nr)
int width=min(field_length,DBL_DIG+5); int width=min(field_length,DBL_DIG+5);
sprintf(buff,"%-*.*g",width,max(width-5,0),nr); sprintf(buff,"%-*.*g",width,max(width-5,0),nr);
end=strcend(buff,' '); 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); int width=min(field_length,DBL_DIG+5);
sprintf(buff,"%-*.*g",width,max(width-5,0),nr); sprintf(buff,"%-*.*g",width,max(width-5,0),nr);
end=strcend(buff,' '); 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) int Field_blob::store(double nr)
{ {
value.set(nr,2,current_thd->variables.thd_charset); CHARSET_INFO *cs=charset();
return Field_blob::store(value.ptr(),(uint) value.length(), value.charset()); value.set(nr, 2, cs);
return Field_blob::store(value.ptr(),(uint) value.length(), cs);
} }
int Field_blob::store(longlong nr) int Field_blob::store(longlong nr)
{ {
value.set(nr,current_thd->variables.thd_charset); CHARSET_INFO *cs=charset();
return Field_blob::store(value.ptr(), (uint) value.length(), value.charset()); value.set(nr, cs);
return Field_blob::store(value.ptr(), (uint) value.length(), cs);
} }
double Field_blob::val_real(void) double Field_blob::val_real(void)
{ {
char *blob; char *blob;
memcpy_fixed(&blob,ptr+packlength,sizeof(char*)); memcpy_fixed(&blob,ptr+packlength,sizeof(char*));
if (!blob) if (!blob)
return 0.0; return 0.0;
@ -4496,8 +4473,7 @@ longlong Field_blob::val_int(void)
if (!blob) if (!blob)
return 0; return 0;
uint32 length=get_length(ptr); uint32 length=get_length(ptr);
CHARSET_INFO *cs=charset(); return my_strntoll(charset(),blob,length,NULL,10);
return my_strntoll(cs,blob,length,NULL,10);
} }
@ -4507,9 +4483,9 @@ String *Field_blob::val_str(String *val_buffer __attribute__((unused)),
char *blob; char *blob;
memcpy_fixed(&blob,ptr+packlength,sizeof(char*)); memcpy_fixed(&blob,ptr+packlength,sizeof(char*));
if (!blob) 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 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; 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 */ /* 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; length-= HA_KEY_BLOB_LENGTH;
uint32 blob_length= get_length(ptr); 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 void Field_blob::sql_type(String &res) const
{ {
CHARSET_INFO *cs=res.charset();
const char *str; const char *str;
uint len; uint length;
switch (packlength) { switch (packlength) {
default: str="tiny"; break; default: str="tiny"; length=4; break;
case 2: str=""; break; case 2: str=""; length=0; break;
case 3: str="medium"; break; case 3: str="medium"; length= 6; break;
case 4: str="long"; 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) orig_field)
{ {
char buff[MAX_FIELD_WIDTH],*pos; char buff[MAX_FIELD_WIDTH],*pos;
CHARSET_INFO *field_charset= charset; String tmp(buff,sizeof(buff), charset);
String tmp(buff,sizeof(buff),field_charset);
/* Get the value from record[2] (the default value row) */ /* Get the value from record[2] (the default value row) */
my_ptrdiff_t diff= (my_ptrdiff_t) (orig_field->table->rec_buff_length*2); 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= (char*) sql_memdup(tmp.ptr(),tmp.length()+1);
pos[tmp.length()]=0; 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->unireg_check=Field::NONE;
tmp->flags&= (NOT_NULL_FLAG | BLOB_FLAG | UNSIGNED_FLAG | tmp->flags&= (NOT_NULL_FLAG | BLOB_FLAG | UNSIGNED_FLAG |
ZEROFILL_FLAG | BINARY_FLAG | ENUM_FLAG | SET_FLAG); ZEROFILL_FLAG | BINARY_FLAG | ENUM_FLAG | SET_FLAG);
#ifdef PROBABLY_WRONG
tmp->table_name= new_table->table_name; tmp->table_name= new_table->table_name;
#endif
tmp->reset_fields(); tmp->reset_fields();
} }
return tmp; 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); bool set_field_to_null_with_conversions(Field *field, bool no_conversions);
uint find_enum(TYPELIB *typelib,const char *x, uint length); uint find_enum(TYPELIB *typelib,const char *x, uint length);
ulonglong find_set(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 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) bool Item::get_date(TIME *ltime,bool fuzzydate)
{ {
char buff[40]; char buff[40];
String tmp(buff,sizeof(buff),NULL),*res; String tmp(buff,sizeof(buff), my_charset_bin),*res;
if (!(res=val_str(&tmp)) || if (!(res=val_str(&tmp)) ||
str_to_TIME(res->ptr(),res->length(),ltime,fuzzydate) == TIMESTAMP_NONE) 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) bool Item::get_time(TIME *ltime)
{ {
char buff[40]; char buff[40];
String tmp(buff,sizeof(buff),NULL),*res; String tmp(buff,sizeof(buff),my_charset_bin),*res;
if (!(res=val_str(&tmp)) || if (!(res=val_str(&tmp)) ||
str_to_time(res->ptr(),res->length(),ltime)) str_to_time(res->ptr(),res->length(),ltime))
{ {
@ -380,7 +380,8 @@ double Item_param::val()
{ {
switch (item_result_type) { switch (item_result_type) {
case STRING_RESULT: 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: case INT_RESULT:
return (double)int_value; return (double)int_value;
default: default:
@ -1149,7 +1150,7 @@ Item *resolve_const_item(Item *item,Item *comp_item)
if (res_type == STRING_RESULT) if (res_type == STRING_RESULT)
{ {
char buff[MAX_FIELD_WIDTH]; 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); result=item->val_str(&tmp);
if (item->null_value) 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 item_buff[MAX_FIELD_WIDTH];
char field_buff[MAX_FIELD_WIDTH]; char field_buff[MAX_FIELD_WIDTH];
String item_tmp(item_buff,sizeof(item_buff),NULL),*item_result; String item_tmp(item_buff,sizeof(item_buff),my_charset_bin),*item_result;
String field_tmp(field_buff,sizeof(field_buff),NULL); String field_tmp(field_buff,sizeof(field_buff),my_charset_bin);
item_result=item->val_str(&item_tmp); item_result=item->val_str(&item_tmp);
if (item->null_value) if (item->null_value)
return 1; // This must be true return 1; // This must be true
@ -1263,7 +1264,7 @@ void Item_cache_str::store(Item *item)
double Item_cache_str::val() double Item_cache_str::val()
{ {
if (value) if (value)
return my_strntod(value->charset(), value->ptr(), return my_strntod(value->charset(), (char*) value->ptr(),
value->length(), (char**) 0); value->length(), (char**) 0);
else else
return (double)0; return (double)0;

View File

@ -344,7 +344,7 @@ public:
enum Type type() const { return STRING_ITEM; } enum Type type() const { return STRING_ITEM; }
double val() 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); str_value.length(), (char**) 0);
} }
longlong val_int() longlong val_int()
@ -598,7 +598,11 @@ public:
enum Item_result result_type () const { return STRING_RESULT; } enum Item_result result_type () const { return STRING_RESULT; }
enum_field_types field_type() const { return cached_field_type; } enum_field_types field_type() const { return cached_field_type; }
double val() 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() longlong val_int()
{ return null_value ? LL(0) : my_strntoll(str_value.charset(),str_value.ptr(),str_value.length(),(char**) 0,10); } { return null_value ? LL(0) : my_strntoll(str_value.charset(),str_value.ptr(),str_value.length(),(char**) 0,10); }
String *val_str(String*); 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() longlong Item_func_benchmark::val_int()
{ {
char buff[MAX_FIELD_WIDTH]; char buff[MAX_FIELD_WIDTH];
String tmp(buff,sizeof(buff), NULL); String tmp(buff,sizeof(buff), my_charset_bin);
THD *thd=current_thd; THD *thd=current_thd;
for (ulong loop=0 ; loop < loop_count && !thd->killed; loop++) for (ulong loop=0 ; loop < loop_count && !thd->killed; loop++)
@ -2039,7 +2039,7 @@ Item_func_set_user_var::update()
case STRING_RESULT: case STRING_RESULT:
{ {
char buffer[MAX_FIELD_WIDTH]; char buffer[MAX_FIELD_WIDTH];
String tmp(buffer,sizeof(buffer),NULL); String tmp(buffer,sizeof(buffer),my_charset_bin);
(void) val_str(&tmp); (void) val_str(&tmp);
break; 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 c = '.'; // we mark c to indicate invalid IP in case length is 0
char buff[36]; 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 if (!(s = args[0]->val_str(&tmp))) // If null value
goto err; goto err;
null_value=0; null_value=0;
@ -2288,7 +2288,7 @@ void Item_func_match::init_search(bool no_order)
String *ft_tmp= 0; String *ft_tmp= 0;
char tmp1[FT_QUERY_MAXLEN]; 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 // MATCH ... AGAINST (NULL) is meaningless, but possible
if (!(ft_tmp=key_item()->val_str(&tmp2))) if (!(ft_tmp=key_item()->val_str(&tmp2)))

View File

@ -813,7 +813,7 @@ public:
double val() double val()
{ {
String *res; res=val_str(&str_value); 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() longlong val_int()
{ {

View File

@ -54,7 +54,8 @@ double Item_str_func::val()
{ {
String *res; String *res;
res=val_str(&str_value); 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() longlong Item_str_func::val_int()

View File

@ -341,7 +341,8 @@ double Item_sum_hybrid::val()
switch (hybrid_type) { switch (hybrid_type) {
case STRING_RESULT: case STRING_RESULT:
String *res; res=val_str(&str_value); 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: case INT_RESULT:
if (unsigned_flag) if (unsigned_flag)
return ulonglong2double(sum_int); return ulonglong2double(sum_int);

View File

@ -484,7 +484,8 @@ public:
double val() double val()
{ {
String *res; res=val_str(&str_value); 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() longlong val_int()
{ {

View File

@ -529,7 +529,7 @@ void Item_func_now::fix_length_and_dec()
{ {
struct tm tm_tmp,*start; struct tm tm_tmp,*start;
time_t query_start=current_thd->query_start(); time_t query_start=current_thd->query_start();
CHARSET_INFO *cs=thd_charset(); CHARSET_INFO *cs=my_charset_bin;
decimals=0; decimals=0;
max_length=19*cs->mbmaxlen; 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]; berkeley_lock_type=berkeley_lock_types[type-1];
else else
{ {
if (test_if_int(argument,(uint) strlen(argument), my_charset_latin1)) char *end;
berkeley_lock_scan_time=atoi(argument); 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 else
{ {
fprintf(stderr,"Unknown lock type: %s\n",argument); 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) print_key(KEY_PART *key_part,const char *key,uint used_length)
{ {
char buff[1024]; char buff[1024];
String tmp(buff,sizeof(buff),NULL); String tmp(buff,sizeof(buff),my_charset_bin);
for (uint length=0; for (uint length=0;
length < used_length ; length < used_length ;

View File

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

View File

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

View File

@ -30,6 +30,9 @@
extern gptr sql_alloc(unsigned size); extern gptr sql_alloc(unsigned size);
extern void sql_element_free(void *ptr); 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" #include "sql_string.h"
@ -224,54 +227,50 @@ bool String::copy(const char *str,uint32 arg_length, CHARSET_INFO *cs)
} }
/* Copy with charset convertion */ /* 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;
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)) if (alloc(new_length))
return TRUE; return TRUE;
str_length=copy_and_convert((char*) Ptr, new_length, to_cs,
d=(uchar *)Ptr; str, arg_length, from_cs);
de=d+new_length; str_charset=to_cs;
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;
return FALSE; 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 */ /* This is used by mysql.cc */
bool String::fill(uint32 max_length,char fill_char) bool String::fill(uint32 max_length,char fill_char)
@ -306,11 +305,26 @@ bool String::append(const String &s)
return FALSE; return FALSE;
} }
/*
Append a latin1 string to the a string of the current character set
*/
bool String::append(const char *s,uint32 arg_length) bool String::append(const char *s,uint32 arg_length)
{ {
if (!arg_length) // Default argument if (!arg_length) // Default argument
if (!(arg_length= (uint32) strlen(s))) if (!(arg_length= (uint32) strlen(s)))
return FALSE; 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)) if (realloc(str_length+arg_length))
return TRUE; return TRUE;
memcpy(Ptr+str_length,s,arg_length); memcpy(Ptr+str_length,s,arg_length);
@ -318,6 +332,7 @@ bool String::append(const char *s,uint32 arg_length)
return FALSE; return FALSE;
} }
#ifdef TO_BE_REMOVED #ifdef TO_BE_REMOVED
bool String::append(FILE* file, uint32 arg_length, myf my_flags) 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; Ptr=(char*) str; str_length=arg_length; Alloced_length=0 ; alloced=0;
str_charset=cs; 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) inline void set_quick(char *str,uint32 arg_length, CHARSET_INFO *cs)
{ {
if (!alloced) if (!alloced)

View File

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

View File

@ -22,19 +22,19 @@ pkglib_LIBRARIES = libmystrings.a
# Exact one of ASSEMBLER_X # Exact one of ASSEMBLER_X
if ASSEMBLER_x86 if ASSEMBLER_x86
ASRCS = strings-x86.s longlong2str-x86.s 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 else
if ASSEMBLER_sparc32 if ASSEMBLER_sparc32
# These file MUST all be on the same line!! Otherwise automake # These file MUST all be on the same line!! Otherwise automake
# generats a very broken makefile # 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 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 else
#no assembler #no assembler
ASRCS = ASRCS =
# These file MUST all be on the same line!! Otherwise automake # These file MUST all be on the same line!! Otherwise automake
# generats a very broken makefile # 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
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, int my_wc_mb_8bit(CHARSET_INFO *cs,my_wc_t wc,
unsigned char *s, unsigned char *str,
unsigned char *e __attribute__((unused))) unsigned char *end __attribute__((unused)))
{ {
MY_UNI_IDX *idx; MY_UNI_IDX *idx;
for(idx=cs->tab_from_uni; idx->tab ; idx++){ for (idx=cs->tab_from_uni; idx->tab ; idx++)
if(idx->from<=wc && idx->to>=wc){ {
s[0]=idx->tab[wc-idx->from]; if (idx->from <= wc && idx->to >= wc)
return (!s[0] && wc) ? MY_CS_ILUNI : 1; {
str[0]= idx->tab[wc - idx->from];
return (!str[0] && wc) ? MY_CS_ILUNI : 1;
} }
} }
return MY_CS_ILUNI; return MY_CS_ILUNI;
} }
#ifdef NOT_USED /*
static int my_vsnprintf_8bit(char *to, size_t n, const char* fmt, va_list ap) We can't use vsprintf here as it's not guaranteed to return
{ the length on all operating systems.
char *start=to, *end=to+n-1; This function is also not called in a safe environment, so the
for (; *fmt ; fmt++) end buffer must be checked.
{ */
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
int my_snprintf_8bit(CHARSET_INFO *cs __attribute__((unused)), int my_snprintf_8bit(CHARSET_INFO *cs __attribute__((unused)),
char* to, uint n __attribute__((unused)), char* to, uint n __attribute__((unused)),
const char* fmt, ...) const char* fmt, ...)
{ {
va_list args; va_list args;
int result;
va_start(args,fmt); va_start(args,fmt);
#ifdef NOT_USED result= my_vsnprintf(to, n, fmt, args);
return my_vsnprintf_8bit(to, n, fmt, args); va_end(args);
#endif return result;
/*
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 */
} }
@ -690,28 +642,48 @@ noconv:
return 0L; return 0L;
} }
/*
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)), double my_strntod_8bit(CHARSET_INFO *cs __attribute__((unused)),
const char *s, uint l, char **e) char *str, uint length, char **end)
{ {
char buf[256]; char end_char;
double res; double result;
if((l+1)>sizeof(buf))
{ if (length == INT_MAX32 || str[length] == 0)
if (e) return strtod(str, end);
memcpy(*e,s,sizeof(s)); end_char= str[length];
return 0; str[length]= 0;
} result= strtod(str, end);
strncpy(buf,s,l); str[length]= end_char; /* Restore end char */
buf[l]='\0'; return result;
res=strtod(buf,e);
if (e)
memcpy(*e,*e-buf+s,sizeof(s));
return res;
} }
/* /*
This is a fast version optimized for the case of radix 10 / -10 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)), 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]; char buffer[66];
register char *p, *e; register char *p, *e;
long int new_val; long int new_val;
int sl=0; uint sign=0;
uint l;
e = p = &buffer[sizeof(buffer)-1]; e = p = &buffer[sizeof(buffer)-1];
*e='\0'; *p= 0;
if (radix < 0) if (radix < 0)
{ {
if (val < 0) if (val < 0)
{ {
sl = 1;
val= -val; val= -val;
*dst++= '-';
len--;
sign= 1;
} }
} }
@ -746,16 +719,11 @@ int my_l10tostr_8bit(CHARSET_INFO *cs __attribute__((unused)),
val= new_val; val= new_val;
} }
if (sl) len= min(len, (uint) (e-p));
{ memcpy(dst, p, len);
*--p='-'; return (int) len+sign;
} }
l=e-p;
l=(l>len)?len:l;
memcpy(dst,p,l);
return (int)l;
}
int my_ll10tostr_8bit(CHARSET_INFO *cs __attribute__((unused)), int my_ll10tostr_8bit(CHARSET_INFO *cs __attribute__((unused)),
char *dst, uint len, int radix, longlong val) char *dst, uint len, int radix, longlong val)
@ -763,24 +731,26 @@ int my_ll10tostr_8bit(CHARSET_INFO *cs __attribute__((unused)),
char buffer[65]; char buffer[65];
register char *p, *e; register char *p, *e;
long long_val; long long_val;
int sl=0; uint sign= 0;
uint l;
if (radix < 0) if (radix < 0)
{ {
if (val < 0) if (val < 0)
{ {
sl=1;
val = -val; val = -val;
*dst++= '-';
len--;
sign= 1;
} }
} }
e = p = &buffer[sizeof(buffer)-1]; e = p = &buffer[sizeof(buffer)-1];
*p='\0'; *p= 0;
if (val == 0) if (val == 0)
{ {
*--p= '0'; *--p= '0';
len= 1;
goto cnv; goto cnv;
} }
@ -800,16 +770,10 @@ int my_ll10tostr_8bit(CHARSET_INFO *cs __attribute__((unused)),
long_val= quo; long_val= quo;
} }
len= min(len, (uint) (e-p));
cnv: cnv:
if (sl) memcpy(dst, p, len);
{ return len+sign;
*--p='-';
}
l=e-p;
l=(l>len)?len:l;
memcpy(dst,p,l);
return (int)(e-p);
} }

View File

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

View File

@ -14,13 +14,25 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h" #include <my_global.h>
#include "mysys_err.h"
#include <m_string.h> #include <m_string.h>
#include <stdarg.h> #include <stdarg.h>
#include <m_ctype.h> #include <m_ctype.h>
#include <assert.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, ...) int my_snprintf(char* to, size_t n, const char* fmt, ...)
{ {
va_list args; va_list args;
@ -31,9 +43,12 @@ int my_snprintf(char* to, size_t n, const char* fmt, ...)
return result; return result;
} }
int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap) int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap)
{ {
char *start=to, *end=to+n-1; char *start=to, *end=to+n-1;
uint length, num_state, pre_zero;
for (; *fmt ; fmt++) for (; *fmt ; fmt++)
{ {
if (fmt[0] != '%') 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 */ *to++= *fmt; /* Copy ordinary char */
continue; continue;
} }
/* Skip if max size is used (to be compatible with printf) */ fmt++; /* skip '%' */
fmt++; /* Read max fill size (only used with %d and %u) */
while (my_isdigit(system_charset_info,*fmt) || *fmt == '.' || *fmt == '-') if (*fmt == '-')
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') if (*fmt == 'l')
fmt++; fmt++;
if (*fmt == 's') /* String parameter */ 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 */ else if (*fmt == 'd' || *fmt == 'u') /* Integer parameter */
{ {
register int iarg; register int iarg;
if ((uint) (end-to) < 16) char *to_start= to;
if ((uint) (end-to) < max(16,length))
break; break;
iarg = va_arg(ap, int); iarg = va_arg(ap, int);
if (*fmt == 'd') if (*fmt == 'd')
to=int10_to_str((long) iarg,to, -10); to=int10_to_str((long) iarg,to, -10);
else else
to=int10_to_str((long) (uint) iarg,to,10); 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; continue;
} }
/* We come here on '%%', unknown code or too long parameter */ /* We come here on '%%', unknown code or too long parameter */