mirror of
https://github.com/MariaDB/server.git
synced 2025-01-18 13:02:28 +01:00
Merge sinisa@work.mysql.com:/home/bk/mysql-4.1
into sinisa.nasamreza.org:/mnt/work/mysql-4.1
This commit is contained in:
commit
3f30ccd85b
49 changed files with 1066 additions and 965 deletions
|
@ -581,3 +581,4 @@ vio/test-sslserver
|
|||
vio/viotest-ssl
|
||||
libmysqld/protocol.cc
|
||||
test_xml
|
||||
extra/mysql_waitpid
|
||||
|
|
|
@ -27,6 +27,13 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
|
||||
#define MY_CS_NAME_SIZE 32
|
||||
#define MY_CS_CTYPE_TABLE_SIZE 257
|
||||
#define MY_CS_TO_LOWER_TABLE_SIZE 256
|
||||
#define MY_CS_TO_UPPER_TABLE_SIZE 256
|
||||
#define MY_CS_SORT_ORDER_TABLE_SIZE 256
|
||||
#define MY_CS_TO_UNI_TABLE_SIZE 256
|
||||
|
||||
#define CHARSET_DIR "charsets/"
|
||||
|
||||
#define my_wc_t ulong
|
||||
|
@ -134,7 +141,7 @@ typedef struct charset_info_st
|
|||
ulong (*strntoul)(struct charset_info_st *, const char *s, uint l, char **e, int base);
|
||||
longlong (*strntoll)(struct charset_info_st *, const char *s, uint l, char **e, int base);
|
||||
ulonglong (*strntoull)(struct charset_info_st *, const char *s, uint l, char **e, int base);
|
||||
double (*strntod)(struct charset_info_st *, const char *s, uint l, char **e);
|
||||
double (*strntod)(struct charset_info_st *, char *s, uint l, char **e);
|
||||
|
||||
} CHARSET_INFO;
|
||||
|
||||
|
@ -145,7 +152,8 @@ extern CHARSET_INFO *default_charset_info;
|
|||
extern CHARSET_INFO *system_charset_info;
|
||||
extern CHARSET_INFO *all_charsets[256];
|
||||
extern my_bool init_compiled_charsets(myf flags);
|
||||
|
||||
extern my_bool my_parse_charset_xml(const char *bug, uint len,
|
||||
int (*add)(CHARSET_INFO *cs));
|
||||
|
||||
/* declarations for simple charsets */
|
||||
extern int my_strnxfrm_simple(CHARSET_INFO *, uchar *, uint, const uchar *, uint);
|
||||
|
@ -178,7 +186,7 @@ long my_strntol_8bit(CHARSET_INFO *, const char *s, uint l,char **e, int
|
|||
ulong my_strntoul_8bit(CHARSET_INFO *, const char *s, uint l,char **e, int base);
|
||||
longlong my_strntoll_8bit(CHARSET_INFO *, const char *s, uint l,char **e, int base);
|
||||
ulonglong my_strntoull_8bit(CHARSET_INFO *, const char *s, uint l,char **e, int base);
|
||||
double my_strntod_8bit(CHARSET_INFO *, const char *s, uint l,char **e);
|
||||
double my_strntod_8bit(CHARSET_INFO *, char *s, uint l,char **e);
|
||||
|
||||
int my_l10tostr_8bit(CHARSET_INFO *, char *to, uint l, int radix, long int val);
|
||||
int my_ll10tostr_8bit(CHARSET_INFO *, char *to, uint l, int radix, longlong val);
|
||||
|
|
|
@ -31,6 +31,9 @@
|
|||
#include <string.h>
|
||||
#endif
|
||||
|
||||
/* need by my_vsnprintf */
|
||||
#include <stdarg.h>
|
||||
|
||||
/* Correct some things for UNIXWARE7 */
|
||||
#ifdef HAVE_UNIXWARE7_THREADS
|
||||
#undef HAVE_STRINGS_H
|
||||
|
@ -238,6 +241,12 @@ extern ulonglong strtoull(const char *str, char **ptr, int base);
|
|||
#endif
|
||||
#endif
|
||||
|
||||
/* my_vsnprintf.c */
|
||||
|
||||
extern int my_vsnprintf( char *str, size_t n,
|
||||
const char *format, va_list ap );
|
||||
extern int my_snprintf(char* to, size_t n, const char* fmt, ...);
|
||||
|
||||
#if defined(__cplusplus) && !defined(OS2)
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -569,9 +569,6 @@ extern int my_error _VARARGS((int nr,myf MyFlags, ...));
|
|||
extern int my_printf_error _VARARGS((uint my_err, const char *format,
|
||||
myf MyFlags, ...)
|
||||
__attribute__ ((format (printf, 2, 4))));
|
||||
extern int my_vsnprintf( char *str, size_t n,
|
||||
const char *format, va_list ap );
|
||||
extern int my_snprintf(char* to, size_t n, const char* fmt, ...);
|
||||
extern int my_message(uint my_err, const char *str,myf MyFlags);
|
||||
extern int my_message_no_curses(uint my_err, const char *str,myf MyFlags);
|
||||
extern int my_message_curses(uint my_err, const char *str,myf MyFlags);
|
||||
|
|
|
@ -37,7 +37,7 @@ mystringsobjects = strmov.lo strxmov.lo strxnmov.lo strnmov.lo \
|
|||
int2str.lo str2int.lo strinstr.lo strcont.lo \
|
||||
strcend.lo bcmp.lo \
|
||||
bchange.lo bmove.lo bmove_upp.lo longlong2str.lo \
|
||||
strtoull.lo strtoll.lo llstr.lo \
|
||||
strtoull.lo strtoll.lo llstr.lo my_vsnprintf.lo \
|
||||
ctype.lo ctype-simple.lo ctype-bin.lo ctype-mb.lo \
|
||||
ctype-big5.lo ctype-czech.lo ctype-euc_kr.lo \
|
||||
ctype-win1250ch.lo ctype-utf8.lo \
|
||||
|
@ -60,7 +60,7 @@ mysysobjects1 = my_init.lo my_static.lo my_malloc.lo my_realloc.lo \
|
|||
my_compress.lo array.lo my_once.lo list.lo my_net.lo \
|
||||
charset.lo hash.lo mf_iocache.lo \
|
||||
mf_iocache2.lo my_seek.lo \
|
||||
my_pread.lo mf_cache.lo my_vsnprintf.lo md5.lo sha1.lo\
|
||||
my_pread.lo mf_cache.lo md5.lo sha1.lo\
|
||||
my_getopt.lo my_gethostbyname.lo my_port.lo
|
||||
sqlobjects = net.lo
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ SHOW FULL COLUMNS FROM t1;
|
|||
Field Type Collation Null Key Default Extra Privileges Comment
|
||||
GROUP_ID int(10) unsigned binary PRI 0 select,insert,update,references
|
||||
LANG_ID smallint(5) unsigned binary PRI 0 select,insert,update,references
|
||||
NAME char(80) character set latin1 latin1 MUL select,insert,update,references
|
||||
NAME char(80) latin1 MUL select,insert,update,references
|
||||
DROP TABLE t1;
|
||||
create table t1 (n int);
|
||||
insert into t1 values(9),(3),(12),(10);
|
||||
|
@ -120,5 +120,5 @@ alter table t2 rename t1, add c char(10) comment "no comment";
|
|||
show columns from t1;
|
||||
Field Type Collation Null Key Default Extra
|
||||
i int(10) unsigned binary PRI NULL auto_increment
|
||||
c char(10) character set latin1 latin1 YES NULL
|
||||
c char(10) latin1 YES NULL
|
||||
drop table t1;
|
||||
|
|
|
@ -76,10 +76,10 @@ create table t1(x varchar(50) );
|
|||
create table t2 select x from t1 where 1=2;
|
||||
describe t1;
|
||||
Field Type Collation Null Key Default Extra
|
||||
x varchar(50) character set latin1 latin1 YES NULL
|
||||
x varchar(50) latin1 YES NULL
|
||||
describe t2;
|
||||
Field Type Collation Null Key Default Extra
|
||||
x char(50) character set latin1 latin1 YES NULL
|
||||
x char(50) latin1 YES NULL
|
||||
drop table t2;
|
||||
create table t2 select now() as a , curtime() as b, curdate() as c , 1+1 as d , 1.0 + 1 as e , 33333333333333333 + 3 as f;
|
||||
describe t2;
|
||||
|
@ -181,7 +181,7 @@ show create table t3;
|
|||
Table Create Table
|
||||
t3 CREATE TABLE `t3` (
|
||||
`id` int(11) NOT NULL default '0',
|
||||
`name` char(20) character set latin1 default NULL
|
||||
`name` char(20) default NULL
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
select * from t3;
|
||||
id name
|
||||
|
@ -204,7 +204,7 @@ show create table t3;
|
|||
Table Create Table
|
||||
t3 CREATE TABLE `t3` (
|
||||
`id` int(11) NOT NULL default '0',
|
||||
`name` char(20) character set latin1 default NULL
|
||||
`name` char(20) default NULL
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
select * from t3;
|
||||
id name
|
||||
|
@ -219,14 +219,14 @@ show create table t3;
|
|||
Table Create Table
|
||||
t3 CREATE TEMPORARY TABLE `t3` (
|
||||
`id` int(11) NOT NULL default '0',
|
||||
`name` char(20) character set latin1 default NULL
|
||||
`name` char(20) default NULL
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
create table t2 like t3;
|
||||
show create table t2;
|
||||
Table Create Table
|
||||
t2 CREATE TABLE `t2` (
|
||||
`id` int(11) NOT NULL default '0',
|
||||
`name` char(20) character set latin1 default NULL
|
||||
`name` char(20) default NULL
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
select * from t2;
|
||||
id name
|
||||
|
|
|
@ -22,23 +22,23 @@ Table Create Table
|
|||
t1 CREATE TABLE `t1` (
|
||||
`comment` char(32) character set latin2 NOT NULL default '',
|
||||
`koi8_ru_f` char(32) character set koi8r NOT NULL default '',
|
||||
`latin5_f` char(32) character set latin5 NOT NULL default ''
|
||||
`latin5_f` char(32) NOT NULL default ''
|
||||
) TYPE=MyISAM CHARSET=latin5
|
||||
ALTER TABLE t1 CHARSET=latin2;
|
||||
ALTER TABLE t1 ADD latin2_f CHAR(32) NOT NULL;
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`comment` char(32) character set latin2 NOT NULL default '',
|
||||
`comment` char(32) NOT NULL default '',
|
||||
`koi8_ru_f` char(32) character set koi8r NOT NULL default '',
|
||||
`latin5_f` char(32) character set latin5 NOT NULL default '',
|
||||
`latin2_f` char(32) character set latin2 NOT NULL default ''
|
||||
`latin2_f` char(32) NOT NULL default ''
|
||||
) TYPE=MyISAM CHARSET=latin2
|
||||
ALTER TABLE t1 DROP latin2_f, DROP latin5_f;
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`comment` char(32) character set latin2 NOT NULL default '',
|
||||
`comment` char(32) NOT NULL default '',
|
||||
`koi8_ru_f` char(32) character set koi8r NOT NULL default ''
|
||||
) TYPE=MyISAM CHARSET=latin2
|
||||
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('a','LAT SMALL A');
|
||||
|
|
|
@ -141,7 +141,7 @@ show create table t2;
|
|||
Table Create Table
|
||||
t2 CREATE TABLE `t2` (
|
||||
`ticket` int(11) default NULL,
|
||||
`inhalt` text character set latin1,
|
||||
`inhalt` text,
|
||||
KEY `tig` (`ticket`),
|
||||
FULLTEXT KEY `tix` (`inhalt`)
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
|
|
|
@ -805,7 +805,7 @@ create table t1 (a char(20), index (a(5))) type=innodb;
|
|||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` char(20) character set latin1 default NULL,
|
||||
`a` char(20) default NULL,
|
||||
KEY `a` (`a`)
|
||||
) TYPE=InnoDB CHARSET=latin1
|
||||
drop table t1;
|
||||
|
|
|
@ -172,7 +172,7 @@ show create table t3;
|
|||
Table Create Table
|
||||
t3 CREATE TABLE `t3` (
|
||||
`a` int(11) NOT NULL default '0',
|
||||
`b` char(20) character set latin1 default NULL,
|
||||
`b` char(20) default NULL,
|
||||
KEY `a` (`a`)
|
||||
) TYPE=MRG_MyISAM CHARSET=latin1 UNION=(t1,t2)
|
||||
create table t4 (a int not null, b char(10), key(a)) type=MERGE UNION=(t1,t2);
|
||||
|
|
|
@ -3221,17 +3221,17 @@ Field Type Collation Null Key Default Extra Privileges Comment
|
|||
auto int(11) binary PRI NULL auto_increment select,insert,update,references
|
||||
fld1 int(6) unsigned zerofill binary UNI 000000 select,insert,update,references
|
||||
companynr tinyint(2) unsigned zerofill binary 00 select,insert,update,references
|
||||
fld3 char(30) character set latin1 latin1 MUL select,insert,update,references
|
||||
fld4 char(35) character set latin1 latin1 select,insert,update,references
|
||||
fld5 char(35) character set latin1 latin1 select,insert,update,references
|
||||
fld6 char(4) character set latin1 latin1 select,insert,update,references
|
||||
fld3 char(30) latin1 MUL select,insert,update,references
|
||||
fld4 char(35) latin1 select,insert,update,references
|
||||
fld5 char(35) latin1 select,insert,update,references
|
||||
fld6 char(4) latin1 select,insert,update,references
|
||||
show full columns from t2 from test like 'f%';
|
||||
Field Type Collation Null Key Default Extra Privileges Comment
|
||||
fld1 int(6) unsigned zerofill binary UNI 000000 select,insert,update,references
|
||||
fld3 char(30) character set latin1 latin1 MUL select,insert,update,references
|
||||
fld4 char(35) character set latin1 latin1 select,insert,update,references
|
||||
fld5 char(35) character set latin1 latin1 select,insert,update,references
|
||||
fld6 char(4) character set latin1 latin1 select,insert,update,references
|
||||
fld3 char(30) latin1 MUL select,insert,update,references
|
||||
fld4 char(35) latin1 select,insert,update,references
|
||||
fld5 char(35) latin1 select,insert,update,references
|
||||
fld6 char(4) latin1 select,insert,update,references
|
||||
show full columns from t2 from test like 's%';
|
||||
Field Type Collation Null Key Default Extra Privileges Comment
|
||||
show keys from t2;
|
||||
|
|
|
@ -93,14 +93,14 @@ c int not null comment 'int column'
|
|||
show create table t1 ;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`test_set` set('val1','val2','val3') character set latin1 NOT NULL default '',
|
||||
`name` char(20) character set latin1 default 'O''Brien' COMMENT 'O''Brien as default',
|
||||
`test_set` set('val1','val2','val3') NOT NULL default '',
|
||||
`name` char(20) default 'O''Brien' COMMENT 'O''Brien as default',
|
||||
`c` int(11) NOT NULL default '0' COMMENT 'int column'
|
||||
) TYPE=MyISAM CHARSET=latin1 COMMENT='it''s a table'
|
||||
show full columns from t1;
|
||||
Field Type Collation Null Key Default Extra Privileges Comment
|
||||
test_set set('val1','val2','val3') character set latin1 latin1 select,insert,update,references
|
||||
name char(20) character set latin1 latin1 YES O'Brien select,insert,update,references O'Brien as default
|
||||
test_set set('val1','val2','val3') latin1 select,insert,update,references
|
||||
name char(20) latin1 YES O'Brien select,insert,update,references O'Brien as default
|
||||
c int(11) binary 0 select,insert,update,references int column
|
||||
drop table t1;
|
||||
create table t1 (a int not null, unique aa (a));
|
||||
|
@ -133,7 +133,7 @@ show create table t1;
|
|||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` int(11) NOT NULL default '0',
|
||||
`b` char(10) character set latin1 default NULL,
|
||||
`b` char(10) default NULL,
|
||||
KEY `b` (`b`)
|
||||
) TYPE=MyISAM CHARSET=latin1 MIN_ROWS=10 MAX_ROWS=100 AVG_ROW_LENGTH=10 PACK_KEYS=1 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=FIXED COMMENT='test'
|
||||
alter table t1 MAX_ROWS=200 ROW_FORMAT=dynamic PACK_KEYS=0;
|
||||
|
@ -141,7 +141,7 @@ show create table t1;
|
|||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` int(11) NOT NULL default '0',
|
||||
`b` varchar(10) character set latin1 default NULL,
|
||||
`b` varchar(10) default NULL,
|
||||
KEY `b` (`b`)
|
||||
) TYPE=MyISAM CHARSET=latin1 MIN_ROWS=10 MAX_ROWS=200 AVG_ROW_LENGTH=10 PACK_KEYS=0 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC COMMENT='test'
|
||||
ALTER TABLE t1 AVG_ROW_LENGTH=0 CHECKSUM=0 COMMENT="" MIN_ROWS=0 MAX_ROWS=0 PACK_KEYS=DEFAULT DELAY_KEY_WRITE=0 ROW_FORMAT=default;
|
||||
|
@ -149,7 +149,7 @@ show create table t1;
|
|||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` int(11) NOT NULL default '0',
|
||||
`b` varchar(10) character set latin1 default NULL,
|
||||
`b` varchar(10) default NULL,
|
||||
KEY `b` (`b`)
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
drop table t1;
|
||||
|
|
|
@ -3,10 +3,10 @@ CREATE TABLE t1 (a blob, b text, c blob(250), d text(70000), e text(70000000));
|
|||
show columns from t1;
|
||||
Field Type Collation Null Key Default Extra
|
||||
a blob binary YES NULL
|
||||
b text character set latin1 latin1 YES NULL
|
||||
b text latin1 YES NULL
|
||||
c blob binary YES NULL
|
||||
d mediumtext character set latin1 latin1 YES NULL
|
||||
e longtext character set latin1 latin1 YES NULL
|
||||
d mediumtext latin1 YES NULL
|
||||
e longtext latin1 YES NULL
|
||||
CREATE TABLE t2 (a char(257), b varchar(70000) binary, c varchar(70000000));
|
||||
Warnings:
|
||||
Warning 1244 Converting column 'a' from CHAR to TEXT
|
||||
|
@ -14,14 +14,14 @@ Warning 1244 Converting column 'b' from CHAR to BLOB
|
|||
Warning 1244 Converting column 'c' from CHAR to TEXT
|
||||
show columns from t2;
|
||||
Field Type Collation Null Key Default Extra
|
||||
a text character set latin1 latin1 YES NULL
|
||||
a text latin1 YES NULL
|
||||
b mediumblob binary YES NULL
|
||||
c longtext character set latin1 latin1 YES NULL
|
||||
c longtext latin1 YES NULL
|
||||
create table t3 (a long, b long byte);
|
||||
show create TABLE t3;
|
||||
Table Create Table
|
||||
t3 CREATE TABLE `t3` (
|
||||
`a` mediumtext character set latin1,
|
||||
`a` mediumtext,
|
||||
`b` mediumblob
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
drop table t1,t2,t3
|
||||
|
@ -70,15 +70,15 @@ update t1 set c="",b=null where c="1";
|
|||
lock tables t1 READ;
|
||||
show full fields from t1;
|
||||
Field Type Collation Null Key Default Extra Privileges Comment
|
||||
t text character set latin1 latin1 YES NULL select,insert,update,references
|
||||
c varchar(10) character set latin1 latin1 YES NULL select,insert,update,references
|
||||
t text latin1 YES NULL select,insert,update,references
|
||||
c varchar(10) latin1 YES NULL select,insert,update,references
|
||||
b blob binary YES NULL select,insert,update,references
|
||||
d varchar(10) binary binary YES NULL select,insert,update,references
|
||||
lock tables t1 WRITE;
|
||||
show full fields from t1;
|
||||
Field Type Collation Null Key Default Extra Privileges Comment
|
||||
t text character set latin1 latin1 YES NULL select,insert,update,references
|
||||
c varchar(10) character set latin1 latin1 YES NULL select,insert,update,references
|
||||
t text latin1 YES NULL select,insert,update,references
|
||||
c varchar(10) latin1 YES NULL select,insert,update,references
|
||||
b blob binary YES NULL select,insert,update,references
|
||||
d varchar(10) binary binary YES NULL select,insert,update,references
|
||||
unlock tables;
|
||||
|
|
|
@ -1626,13 +1626,13 @@ create table t1 (a enum (' ','a','b') not null);
|
|||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` enum('','a','b') character set latin1 NOT NULL default ''
|
||||
`a` enum('','a','b') NOT NULL default ''
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
drop table t1;
|
||||
create table t1 (a enum (' ','a','b ') not null default 'b ');
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` enum('','a','b') character set latin1 NOT NULL default 'b'
|
||||
`a` enum('','a','b') NOT NULL default 'b'
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
drop table t1;
|
||||
|
|
|
@ -40,7 +40,7 @@ KEY (options,flags)
|
|||
show full fields from t1;
|
||||
Field Type Collation Null Key Default Extra Privileges Comment
|
||||
auto int(5) unsigned binary PRI NULL auto_increment select,insert,update,references
|
||||
string varchar(10) character set latin1 latin1 YES hello select,insert,update,references
|
||||
string varchar(10) latin1 YES hello select,insert,update,references
|
||||
tiny tinyint(4) binary MUL 0 select,insert,update,references
|
||||
short smallint(6) binary MUL 1 select,insert,update,references
|
||||
medium mediumint(8) binary MUL 0 select,insert,update,references
|
||||
|
@ -61,8 +61,8 @@ blob_col blob binary YES NULL select,insert,update,references
|
|||
tinyblob_col tinyblob binary YES NULL select,insert,update,references
|
||||
mediumblob_col mediumblob binary select,insert,update,references
|
||||
longblob_col longblob binary select,insert,update,references
|
||||
options enum('one','two','tree') character set latin1 latin1 MUL one select,insert,update,references
|
||||
flags set('one','two','tree') character set latin1 latin1 select,insert,update,references
|
||||
options enum('one','two','tree') latin1 MUL one select,insert,update,references
|
||||
flags set('one','two','tree') latin1 select,insert,update,references
|
||||
show keys from t1;
|
||||
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
|
||||
t1 0 PRIMARY 1 auto A 0 NULL NULL BTREE
|
||||
|
@ -170,7 +170,7 @@ update t2 set string="changed" where auto=16;
|
|||
show full columns from t1;
|
||||
Field Type Collation Null Key Default Extra Privileges Comment
|
||||
auto int(5) unsigned binary MUL NULL auto_increment select,insert,update,references
|
||||
string varchar(10) character set latin1 latin1 YES new defaul select,insert,update,references
|
||||
string varchar(10) latin1 YES new defaul select,insert,update,references
|
||||
tiny tinyint(4) binary MUL 0 select,insert,update,references
|
||||
short smallint(6) binary MUL 0 select,insert,update,references
|
||||
medium mediumint(8) binary MUL 0 select,insert,update,references
|
||||
|
@ -184,19 +184,19 @@ umedium mediumint(8) unsigned binary MUL 0 select,insert,update,references
|
|||
ulong int(11) unsigned binary MUL 0 select,insert,update,references
|
||||
ulonglong bigint(13) unsigned binary MUL 0 select,insert,update,references
|
||||
time_stamp timestamp latin1 YES NULL select,insert,update,references
|
||||
date_field varchar(10) character set latin1 latin1 YES NULL select,insert,update,references
|
||||
date_field varchar(10) latin1 YES NULL select,insert,update,references
|
||||
time_field time latin1 YES NULL select,insert,update,references
|
||||
date_time datetime latin1 YES NULL select,insert,update,references
|
||||
new_blob_col varchar(20) character set latin1 latin1 YES NULL select,insert,update,references
|
||||
new_blob_col varchar(20) latin1 YES NULL select,insert,update,references
|
||||
tinyblob_col tinyblob binary YES NULL select,insert,update,references
|
||||
mediumblob_col mediumblob binary select,insert,update,references
|
||||
options enum('one','two','tree') character set latin1 latin1 MUL one select,insert,update,references
|
||||
flags set('one','two','tree') character set latin1 latin1 select,insert,update,references
|
||||
new_field varchar(10) character set latin1 latin1 new select,insert,update,references
|
||||
options enum('one','two','tree') latin1 MUL one select,insert,update,references
|
||||
flags set('one','two','tree') latin1 select,insert,update,references
|
||||
new_field varchar(10) latin1 new select,insert,update,references
|
||||
show full columns from t2;
|
||||
Field Type Collation Null Key Default Extra Privileges Comment
|
||||
auto int(5) unsigned binary 0 select,insert,update,references
|
||||
string varchar(10) character set latin1 latin1 YES new defaul select,insert,update,references
|
||||
string varchar(10) latin1 YES new defaul select,insert,update,references
|
||||
tiny tinyint(4) binary 0 select,insert,update,references
|
||||
short smallint(6) binary 0 select,insert,update,references
|
||||
medium mediumint(8) binary 0 select,insert,update,references
|
||||
|
@ -210,15 +210,15 @@ umedium mediumint(8) unsigned binary 0 select,insert,update,references
|
|||
ulong int(11) unsigned binary 0 select,insert,update,references
|
||||
ulonglong bigint(13) unsigned binary 0 select,insert,update,references
|
||||
time_stamp timestamp latin1 YES NULL select,insert,update,references
|
||||
date_field varchar(10) character set latin1 latin1 YES NULL select,insert,update,references
|
||||
date_field varchar(10) latin1 YES NULL select,insert,update,references
|
||||
time_field time latin1 YES NULL select,insert,update,references
|
||||
date_time datetime latin1 YES NULL select,insert,update,references
|
||||
new_blob_col varchar(20) character set latin1 latin1 YES NULL select,insert,update,references
|
||||
new_blob_col varchar(20) latin1 YES NULL select,insert,update,references
|
||||
tinyblob_col tinyblob binary YES NULL select,insert,update,references
|
||||
mediumblob_col mediumblob binary select,insert,update,references
|
||||
options enum('one','two','tree') character set latin1 latin1 one select,insert,update,references
|
||||
flags set('one','two','tree') character set latin1 latin1 select,insert,update,references
|
||||
new_field varchar(10) character set latin1 latin1 new select,insert,update,references
|
||||
options enum('one','two','tree') latin1 one select,insert,update,references
|
||||
flags set('one','two','tree') latin1 select,insert,update,references
|
||||
new_field varchar(10) latin1 new select,insert,update,references
|
||||
select t1.auto,t2.auto from t1,t2 where t1.auto=t2.auto and ((t1.string<>t2.string and (t1.string is not null or t2.string is not null)) or (t1.tiny<>t2.tiny and (t1.tiny is not null or t2.tiny is not null)) or (t1.short<>t2.short and (t1.short is not null or t2.short is not null)) or (t1.medium<>t2.medium and (t1.medium is not null or t2.medium is not null)) or (t1.long_int<>t2.long_int and (t1.long_int is not null or t2.long_int is not null)) or (t1.longlong<>t2.longlong and (t1.longlong is not null or t2.longlong is not null)) or (t1.real_float<>t2.real_float and (t1.real_float is not null or t2.real_float is not null)) or (t1.real_double<>t2.real_double and (t1.real_double is not null or t2.real_double is not null)) or (t1.utiny<>t2.utiny and (t1.utiny is not null or t2.utiny is not null)) or (t1.ushort<>t2.ushort and (t1.ushort is not null or t2.ushort is not null)) or (t1.umedium<>t2.umedium and (t1.umedium is not null or t2.umedium is not null)) or (t1.ulong<>t2.ulong and (t1.ulong is not null or t2.ulong is not null)) or (t1.ulonglong<>t2.ulonglong and (t1.ulonglong is not null or t2.ulonglong is not null)) or (t1.time_stamp<>t2.time_stamp and (t1.time_stamp is not null or t2.time_stamp is not null)) or (t1.date_field<>t2.date_field and (t1.date_field is not null or t2.date_field is not null)) or (t1.time_field<>t2.time_field and (t1.time_field is not null or t2.time_field is not null)) or (t1.date_time<>t2.date_time and (t1.date_time is not null or t2.date_time is not null)) or (t1.new_blob_col<>t2.new_blob_col and (t1.new_blob_col is not null or t2.new_blob_col is not null)) or (t1.tinyblob_col<>t2.tinyblob_col and (t1.tinyblob_col is not null or t2.tinyblob_col is not null)) or (t1.mediumblob_col<>t2.mediumblob_col and (t1.mediumblob_col is not null or t2.mediumblob_col is not null)) or (t1.options<>t2.options and (t1.options is not null or t2.options is not null)) or (t1.flags<>t2.flags and (t1.flags is not null or t2.flags is not null)) or (t1.new_field<>t2.new_field and (t1.new_field is not null or t2.new_field is not null)));
|
||||
auto auto
|
||||
16 16
|
||||
|
@ -231,8 +231,8 @@ show full columns from t2;
|
|||
Field Type Collation Null Key Default Extra Privileges Comment
|
||||
auto bigint(17) unsigned binary PRI 0 select,insert,update,references
|
||||
t1 bigint(1) binary 0 select,insert,update,references
|
||||
t2 char(1) character set latin1 latin1 select,insert,update,references
|
||||
t3 mediumtext character set latin1 latin1 select,insert,update,references
|
||||
t2 char(1) latin1 select,insert,update,references
|
||||
t3 mediumtext latin1 select,insert,update,references
|
||||
t4 mediumblob binary select,insert,update,references
|
||||
select * from t2;
|
||||
auto t1 t2 t3 t4
|
||||
|
|
|
@ -3,13 +3,13 @@ create table t1 (a set (' ','a','b') not null);
|
|||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` set('','a','b') character set latin1 NOT NULL default ''
|
||||
`a` set('','a','b') NOT NULL default ''
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
drop table t1;
|
||||
create table t1 (a set (' ','a','b ') not null default 'b ');
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` set('','a','b') character set latin1 NOT NULL default 'b'
|
||||
`a` set('','a','b') NOT NULL default 'b'
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
drop table t1;
|
||||
|
|
|
@ -85,7 +85,7 @@ a b
|
|||
2 b
|
||||
1 a
|
||||
(select a,b from t1 limit 2) union all (select a,b from t2 order by a limit 1) order by t1.b;
|
||||
Table 't1' from one of SELECT's can not be used in order clause
|
||||
Table 't1' from one of SELECT's can not be used in global ORDER clause
|
||||
explain (select a,b from t1 limit 2) union all (select a,b from t2 order by a limit 1) order by b desc;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 4
|
||||
|
|
|
@ -50,7 +50,7 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c\
|
|||
my_getopt.c my_mkdir.c \
|
||||
default.c my_compress.c checksum.c raid.cc \
|
||||
my_net.c my_semaphore.c my_port.c \
|
||||
my_vsnprintf.c charset.c my_bitmap.c my_bit.c md5.c \
|
||||
charset.c my_bitmap.c my_bit.c md5.c \
|
||||
my_gethostbyname.c rijndael.c my_aes.c sha1.c \
|
||||
my_handler.c
|
||||
EXTRA_DIST = thr_alarm.c thr_lock.c my_pthread.c my_thr_init.c \
|
||||
|
|
618
mysys/charset.c
618
mysys/charset.c
|
@ -22,134 +22,27 @@
|
|||
#include <my_xml.h>
|
||||
|
||||
|
||||
static void set_max_sort_char(CHARSET_INFO *cs);
|
||||
static my_bool create_fromuni(CHARSET_INFO *cs);
|
||||
|
||||
|
||||
#define MY_CHARSET_INDEX "Index.xml"
|
||||
|
||||
const char *charsets_dir= NULL;
|
||||
static int charset_initialized=0;
|
||||
|
||||
#define MAX_LINE 1024
|
||||
|
||||
#define CTYPE_TABLE_SIZE 257
|
||||
#define TO_LOWER_TABLE_SIZE 256
|
||||
#define TO_UPPER_TABLE_SIZE 256
|
||||
#define SORT_ORDER_TABLE_SIZE 256
|
||||
#define TO_UNI_TABLE_SIZE 256
|
||||
|
||||
|
||||
char *get_charsets_dir(char *buf)
|
||||
static void set_max_sort_char(CHARSET_INFO *cs)
|
||||
{
|
||||
const char *sharedir= SHAREDIR;
|
||||
DBUG_ENTER("get_charsets_dir");
|
||||
|
||||
if (charsets_dir != NULL)
|
||||
strmake(buf, charsets_dir, FN_REFLEN-1);
|
||||
else
|
||||
uchar max_char;
|
||||
uint i;
|
||||
|
||||
if (!cs->sort_order)
|
||||
return;
|
||||
|
||||
max_char=cs->sort_order[(uchar) cs->max_sort_char];
|
||||
for (i= 0; i < 256; i++)
|
||||
{
|
||||
if (test_if_hard_path(sharedir) ||
|
||||
is_prefix(sharedir, DEFAULT_CHARSET_HOME))
|
||||
strxmov(buf, sharedir, "/", CHARSET_DIR, NullS);
|
||||
else
|
||||
strxmov(buf, DEFAULT_CHARSET_HOME, "/", sharedir, "/", CHARSET_DIR,
|
||||
NullS);
|
||||
if ((uchar) cs->sort_order[i] > max_char)
|
||||
{
|
||||
max_char=(uchar) cs->sort_order[i];
|
||||
cs->max_sort_char= (char) i;
|
||||
}
|
||||
}
|
||||
convert_dirname(buf,buf,NullS);
|
||||
DBUG_PRINT("info",("charsets dir: '%s'", buf));
|
||||
DBUG_RETURN(strend(buf));
|
||||
}
|
||||
|
||||
|
||||
#define MAX_BUF 1024*16
|
||||
|
||||
#ifndef DBUG_OFF
|
||||
static void mstr(char *str,const char *src,uint l1,uint l2)
|
||||
{
|
||||
l1= l1<l2 ? l1 : l2;
|
||||
memcpy(str,src,l1);
|
||||
str[l1]='\0';
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
struct my_cs_file_section_st
|
||||
{
|
||||
int state;
|
||||
const char *str;
|
||||
};
|
||||
|
||||
#define _CS_MISC 1
|
||||
#define _CS_ID 2
|
||||
#define _CS_NAME 3
|
||||
#define _CS_FAMILY 4
|
||||
#define _CS_ORDER 5
|
||||
#define _CS_COLNAME 6
|
||||
#define _CS_FLAG 7
|
||||
#define _CS_CHARSET 8
|
||||
#define _CS_COLLATION 9
|
||||
#define _CS_UPPERMAP 10
|
||||
#define _CS_LOWERMAP 11
|
||||
#define _CS_UNIMAP 12
|
||||
#define _CS_COLLMAP 13
|
||||
#define _CS_CTYPEMAP 14
|
||||
|
||||
static struct my_cs_file_section_st sec[] =
|
||||
{
|
||||
{_CS_MISC, "xml"},
|
||||
{_CS_MISC, "xml.version"},
|
||||
{_CS_MISC, "xml.encoding"},
|
||||
{_CS_MISC, "charsets"},
|
||||
{_CS_MISC, "charsets.max-id"},
|
||||
{_CS_MISC, "charsets.description"},
|
||||
{_CS_CHARSET, "charsets.charset"},
|
||||
{_CS_NAME, "charsets.charset.name"},
|
||||
{_CS_FAMILY, "charsets.charset.family"},
|
||||
{_CS_MISC, "charsets.charset.alias"},
|
||||
{_CS_MISC, "charsets.charset.ctype"},
|
||||
{_CS_CTYPEMAP, "charsets.charset.ctype.map"},
|
||||
{_CS_MISC, "charsets.charset.upper"},
|
||||
{_CS_UPPERMAP, "charsets.charset.upper.map"},
|
||||
{_CS_MISC, "charsets.charset.lower"},
|
||||
{_CS_LOWERMAP, "charsets.charset.lower.map"},
|
||||
{_CS_MISC, "charsets.charset.unicode"},
|
||||
{_CS_UNIMAP, "charsets.charset.unicode.map"},
|
||||
{_CS_COLLATION, "charsets.charset.collation"},
|
||||
{_CS_COLNAME, "charsets.charset.collation.name"},
|
||||
{_CS_ID, "charsets.charset.collation.id"},
|
||||
{_CS_ORDER, "charsets.charset.collation.order"},
|
||||
{_CS_FLAG, "charsets.charset.collation.flag"},
|
||||
{_CS_COLLMAP, "charsets.charset.collation.map"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
static struct my_cs_file_section_st * cs_file_sec(const char *attr, uint len)
|
||||
{
|
||||
struct my_cs_file_section_st *s;
|
||||
for (s=sec; s->str; s++)
|
||||
{
|
||||
if (!strncmp(attr,s->str,len))
|
||||
return s;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define CS_MAX_NM_LEN 32
|
||||
|
||||
struct my_cs_file_info
|
||||
{
|
||||
char csname[CS_MAX_NM_LEN];
|
||||
char name[CS_MAX_NM_LEN];
|
||||
uchar ctype[CTYPE_TABLE_SIZE];
|
||||
uchar to_lower[TO_LOWER_TABLE_SIZE];
|
||||
uchar to_upper[TO_UPPER_TABLE_SIZE];
|
||||
uchar sort_order[SORT_ORDER_TABLE_SIZE];
|
||||
uint16 tab_to_uni[TO_UNI_TABLE_SIZE];
|
||||
CHARSET_INFO cs;
|
||||
myf myflags;
|
||||
};
|
||||
|
||||
static void simple_cs_init_functions(CHARSET_INFO *cs)
|
||||
{
|
||||
cs->like_range = my_like_range_simple;
|
||||
|
@ -176,301 +69,6 @@ static void simple_cs_init_functions(CHARSET_INFO *cs)
|
|||
}
|
||||
|
||||
|
||||
static void simple_cs_copy_data(CHARSET_INFO *to, CHARSET_INFO *from)
|
||||
{
|
||||
to->number= from->number ? from->number : to->number;
|
||||
to->state|= from->state;
|
||||
|
||||
if (from->csname)
|
||||
to->csname= my_once_strdup(from->csname,MYF(MY_WME));
|
||||
|
||||
if (from->name)
|
||||
to->name= my_once_strdup(from->name,MYF(MY_WME));
|
||||
|
||||
if (from->ctype)
|
||||
to->ctype= (uchar*) my_once_memdup((char*) from->ctype,
|
||||
CTYPE_TABLE_SIZE, MYF(MY_WME));
|
||||
if (from->to_lower)
|
||||
to->to_lower= (uchar*) my_once_memdup((char*) from->to_lower,
|
||||
TO_LOWER_TABLE_SIZE, MYF(MY_WME));
|
||||
if (from->to_upper)
|
||||
to->to_upper= (uchar*) my_once_memdup((char*) from->to_upper,
|
||||
TO_UPPER_TABLE_SIZE, MYF(MY_WME));
|
||||
if (from->sort_order)
|
||||
{
|
||||
to->sort_order= (uchar*) my_once_memdup((char*) from->sort_order,
|
||||
SORT_ORDER_TABLE_SIZE,
|
||||
MYF(MY_WME));
|
||||
set_max_sort_char(to);
|
||||
}
|
||||
if (from->tab_to_uni)
|
||||
{
|
||||
uint sz=TO_UNI_TABLE_SIZE*sizeof(uint16);
|
||||
to->tab_to_uni= (uint16*) my_once_memdup((char*)from->tab_to_uni, sz,
|
||||
MYF(MY_WME));
|
||||
create_fromuni(to);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static my_bool simple_cs_is_full(CHARSET_INFO *cs)
|
||||
{
|
||||
return ((cs->csname && cs->tab_to_uni && cs->ctype && cs->to_upper &&
|
||||
cs->to_lower) &&
|
||||
(cs->number && cs->name && cs->sort_order));
|
||||
}
|
||||
|
||||
|
||||
static int fill_uchar(uchar *a,uint size,const char *str, uint len)
|
||||
{
|
||||
uint i= 0;
|
||||
const char *s, *b, *e=str+len;
|
||||
|
||||
for (s=str ; s < e ; i++)
|
||||
{
|
||||
for ( ; (s < e) && strchr(" \t\r\n",s[0]); s++) ;
|
||||
b=s;
|
||||
for ( ; (s < e) && !strchr(" \t\r\n",s[0]); s++) ;
|
||||
if (s == b || i > size)
|
||||
break;
|
||||
a[i]= my_strntoul(my_charset_latin1,b,s-b,NULL,16);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fill_uint16(uint16 *a,uint size,const char *str, uint len)
|
||||
{
|
||||
uint i= 0;
|
||||
const char *s, *b, *e=str+len;
|
||||
for (s=str ; s < e ; i++)
|
||||
{
|
||||
for ( ; (s < e) && strchr(" \t\r\n",s[0]); s++) ;
|
||||
b=s;
|
||||
for ( ; (s < e) && !strchr(" \t\r\n",s[0]); s++) ;
|
||||
if (s == b || i > size)
|
||||
break;
|
||||
a[i]= my_strntol(my_charset_latin1,b,s-b,NULL,16);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int cs_enter(MY_XML_PARSER *st,const char *attr, uint len)
|
||||
{
|
||||
struct my_cs_file_info *i= (struct my_cs_file_info *)st->user_data;
|
||||
struct my_cs_file_section_st *s= cs_file_sec(attr,len);
|
||||
|
||||
if ( s && (s->state == _CS_CHARSET))
|
||||
{
|
||||
bzero(&i->cs,sizeof(i->cs));
|
||||
}
|
||||
return MY_XML_OK;
|
||||
}
|
||||
|
||||
|
||||
static int cs_leave(MY_XML_PARSER *st,const char *attr, uint len)
|
||||
{
|
||||
struct my_cs_file_info *i= (struct my_cs_file_info *)st->user_data;
|
||||
struct my_cs_file_section_st *s= cs_file_sec(attr,len);
|
||||
int state= s ? s->state : 0;
|
||||
|
||||
if (state == _CS_COLLATION)
|
||||
{
|
||||
if (i->cs.name && (i->cs.number ||
|
||||
(i->cs.number=get_charset_number(i->cs.name))))
|
||||
{
|
||||
if (!all_charsets[i->cs.number])
|
||||
{
|
||||
if (!(all_charsets[i->cs.number]=
|
||||
(CHARSET_INFO*) my_once_alloc(sizeof(CHARSET_INFO),i->myflags)))
|
||||
return MY_XML_ERROR;
|
||||
bzero((void*)all_charsets[i->cs.number],sizeof(CHARSET_INFO));
|
||||
}
|
||||
|
||||
if (!(all_charsets[i->cs.number]->state & MY_CS_COMPILED))
|
||||
{
|
||||
simple_cs_copy_data(all_charsets[i->cs.number],&i->cs);
|
||||
if (simple_cs_is_full(all_charsets[i->cs.number]))
|
||||
{
|
||||
simple_cs_init_functions(all_charsets[i->cs.number]);
|
||||
all_charsets[i->cs.number]->state |= MY_CS_LOADED;
|
||||
}
|
||||
}
|
||||
i->cs.number= 0;
|
||||
i->cs.name= NULL;
|
||||
i->cs.state= 0;
|
||||
i->cs.sort_order= NULL;
|
||||
i->cs.state= 0;
|
||||
}
|
||||
}
|
||||
return MY_XML_OK;
|
||||
}
|
||||
|
||||
|
||||
static int cs_value(MY_XML_PARSER *st,const char *attr, uint len)
|
||||
{
|
||||
struct my_cs_file_info *i= (struct my_cs_file_info *)st->user_data;
|
||||
struct my_cs_file_section_st *s;
|
||||
int state= (s=cs_file_sec(st->attr,strlen(st->attr))) ? s->state : 0;
|
||||
|
||||
#ifndef DBUG_OFF
|
||||
if(0){
|
||||
char str[1024];
|
||||
mstr(str,attr,len,sizeof(str)-1);
|
||||
printf("VALUE %d %s='%s'\n",state,st->attr,str);
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (state) {
|
||||
case _CS_ID:
|
||||
i->cs.number= my_strntoul(my_charset_latin1,attr,len,(char**)NULL,0);
|
||||
break;
|
||||
case _CS_COLNAME:
|
||||
memcpy(i->name,attr,len=min(len,CS_MAX_NM_LEN-1));
|
||||
i->name[len]='\0';
|
||||
i->cs.name=i->name;
|
||||
break;
|
||||
case _CS_NAME:
|
||||
memcpy(i->csname,attr,len=min(len,CS_MAX_NM_LEN-1));
|
||||
i->csname[len]='\0';
|
||||
i->cs.csname=i->csname;
|
||||
break;
|
||||
case _CS_FLAG:
|
||||
if (!strncmp("primary",attr,len))
|
||||
i->cs.state|= MY_CS_PRIMARY;
|
||||
break;
|
||||
case _CS_UPPERMAP:
|
||||
fill_uchar(i->to_upper,TO_UPPER_TABLE_SIZE,attr,len);
|
||||
i->cs.to_upper=i->to_upper;
|
||||
break;
|
||||
case _CS_LOWERMAP:
|
||||
fill_uchar(i->to_lower,TO_LOWER_TABLE_SIZE,attr,len);
|
||||
i->cs.to_lower=i->to_lower;
|
||||
break;
|
||||
case _CS_UNIMAP:
|
||||
fill_uint16(i->tab_to_uni,TO_UNI_TABLE_SIZE,attr,len);
|
||||
i->cs.tab_to_uni=i->tab_to_uni;
|
||||
break;
|
||||
case _CS_COLLMAP:
|
||||
fill_uchar(i->sort_order,SORT_ORDER_TABLE_SIZE,attr,len);
|
||||
i->cs.sort_order=i->sort_order;
|
||||
break;
|
||||
case _CS_CTYPEMAP:
|
||||
fill_uchar(i->ctype,CTYPE_TABLE_SIZE,attr,len);
|
||||
i->cs.ctype=i->ctype;
|
||||
break;
|
||||
}
|
||||
return MY_XML_OK;
|
||||
}
|
||||
|
||||
|
||||
static my_bool read_charset_index(const char *filename, myf myflags)
|
||||
{
|
||||
char *buf;
|
||||
int fd;
|
||||
uint len;
|
||||
MY_XML_PARSER p;
|
||||
struct my_cs_file_info i;
|
||||
|
||||
if (!(buf= (char *)my_malloc(MAX_BUF,myflags)))
|
||||
return FALSE;
|
||||
|
||||
strmov(get_charsets_dir(buf), filename);
|
||||
|
||||
if ((fd=my_open(buf,O_RDONLY,myflags)) < 0)
|
||||
{
|
||||
my_free(buf,myflags);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
len=read(fd,buf,MAX_BUF);
|
||||
my_xml_parser_create(&p);
|
||||
my_close(fd,myflags);
|
||||
|
||||
my_xml_set_enter_handler(&p,cs_enter);
|
||||
my_xml_set_value_handler(&p,cs_value);
|
||||
my_xml_set_leave_handler(&p,cs_leave);
|
||||
my_xml_set_user_data(&p,(void*)&i);
|
||||
|
||||
if (my_xml_parse(&p,buf,len) != MY_XML_OK)
|
||||
{
|
||||
#ifdef NOT_YET
|
||||
printf("ERROR at line %d pos %d '%s'\n",
|
||||
my_xml_error_lineno(&p)+1,
|
||||
my_xml_error_pos(&p),
|
||||
my_xml_error_string(&p));
|
||||
#endif
|
||||
}
|
||||
|
||||
my_xml_parser_free(&p);
|
||||
my_free(buf, myflags);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void set_max_sort_char(CHARSET_INFO *cs)
|
||||
{
|
||||
uchar max_char;
|
||||
uint i;
|
||||
|
||||
if (!cs->sort_order)
|
||||
return;
|
||||
|
||||
max_char=cs->sort_order[(uchar) cs->max_sort_char];
|
||||
for (i= 0; i < 256; i++)
|
||||
{
|
||||
if ((uchar) cs->sort_order[i] > max_char)
|
||||
{
|
||||
max_char=(uchar) cs->sort_order[i];
|
||||
cs->max_sort_char= (char) i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static my_bool init_available_charsets(myf myflags)
|
||||
{
|
||||
my_bool error=FALSE;
|
||||
/*
|
||||
We have to use charset_initialized to not lock on THR_LOCK_charset
|
||||
inside get_internal_charset...
|
||||
*/
|
||||
if (!charset_initialized)
|
||||
{
|
||||
CHARSET_INFO **cs;
|
||||
/*
|
||||
To make things thread safe we are not allowing other threads to interfere
|
||||
while we may changing the cs_info_table
|
||||
*/
|
||||
pthread_mutex_lock(&THR_LOCK_charset);
|
||||
|
||||
bzero(&all_charsets,sizeof(all_charsets));
|
||||
init_compiled_charsets(myflags);
|
||||
|
||||
/* Copy compiled charsets */
|
||||
for (cs=all_charsets; cs < all_charsets+255 ; cs++)
|
||||
{
|
||||
if (*cs)
|
||||
set_max_sort_char(*cs);
|
||||
}
|
||||
error= read_charset_index(MY_CHARSET_INDEX,myflags);
|
||||
charset_initialized=1;
|
||||
pthread_mutex_unlock(&THR_LOCK_charset);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
void free_charsets(void)
|
||||
{
|
||||
charset_initialized=0;
|
||||
}
|
||||
|
||||
|
||||
static void get_charset_conf_name(const char *cs_name, char *buf)
|
||||
{
|
||||
strxmov(get_charsets_dir(buf), cs_name, ".conf", NullS);
|
||||
}
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int nchars;
|
||||
|
@ -563,6 +161,190 @@ static my_bool create_fromuni(CHARSET_INFO *cs)
|
|||
}
|
||||
|
||||
|
||||
static void simple_cs_copy_data(CHARSET_INFO *to, CHARSET_INFO *from)
|
||||
{
|
||||
to->number= from->number ? from->number : to->number;
|
||||
to->state|= from->state;
|
||||
|
||||
if (from->csname)
|
||||
to->csname= my_once_strdup(from->csname,MYF(MY_WME));
|
||||
|
||||
if (from->name)
|
||||
to->name= my_once_strdup(from->name,MYF(MY_WME));
|
||||
|
||||
if (from->ctype)
|
||||
to->ctype= (uchar*) my_once_memdup((char*) from->ctype,
|
||||
MY_CS_CTYPE_TABLE_SIZE, MYF(MY_WME));
|
||||
if (from->to_lower)
|
||||
to->to_lower= (uchar*) my_once_memdup((char*) from->to_lower,
|
||||
MY_CS_TO_LOWER_TABLE_SIZE, MYF(MY_WME));
|
||||
if (from->to_upper)
|
||||
to->to_upper= (uchar*) my_once_memdup((char*) from->to_upper,
|
||||
MY_CS_TO_UPPER_TABLE_SIZE, MYF(MY_WME));
|
||||
if (from->sort_order)
|
||||
{
|
||||
to->sort_order= (uchar*) my_once_memdup((char*) from->sort_order,
|
||||
MY_CS_SORT_ORDER_TABLE_SIZE,
|
||||
MYF(MY_WME));
|
||||
set_max_sort_char(to);
|
||||
}
|
||||
if (from->tab_to_uni)
|
||||
{
|
||||
uint sz= MY_CS_TO_UNI_TABLE_SIZE*sizeof(uint16);
|
||||
to->tab_to_uni= (uint16*) my_once_memdup((char*)from->tab_to_uni, sz,
|
||||
MYF(MY_WME));
|
||||
create_fromuni(to);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static my_bool simple_cs_is_full(CHARSET_INFO *cs)
|
||||
{
|
||||
return ((cs->csname && cs->tab_to_uni && cs->ctype && cs->to_upper &&
|
||||
cs->to_lower) &&
|
||||
(cs->number && cs->name && cs->sort_order));
|
||||
}
|
||||
|
||||
|
||||
static int add_collation(CHARSET_INFO *cs)
|
||||
{
|
||||
if (cs->name && (cs->number || (cs->number=get_charset_number(cs->name))))
|
||||
{
|
||||
if (!all_charsets[cs->number])
|
||||
{
|
||||
if (!(all_charsets[cs->number]=
|
||||
(CHARSET_INFO*) my_once_alloc(sizeof(CHARSET_INFO),MYF(0))))
|
||||
return MY_XML_ERROR;
|
||||
bzero((void*)all_charsets[cs->number],sizeof(CHARSET_INFO));
|
||||
}
|
||||
|
||||
if (!(all_charsets[cs->number]->state & MY_CS_COMPILED))
|
||||
{
|
||||
simple_cs_copy_data(all_charsets[cs->number],cs);
|
||||
if (simple_cs_is_full(all_charsets[cs->number]))
|
||||
{
|
||||
simple_cs_init_functions(all_charsets[cs->number]);
|
||||
all_charsets[cs->number]->state |= MY_CS_LOADED;
|
||||
}
|
||||
}
|
||||
cs->number= 0;
|
||||
cs->name= NULL;
|
||||
cs->state= 0;
|
||||
cs->sort_order= NULL;
|
||||
cs->state= 0;
|
||||
}
|
||||
return MY_XML_OK;
|
||||
}
|
||||
|
||||
|
||||
#define MAX_BUF 1024*16
|
||||
#define MY_CHARSET_INDEX "Index.xml"
|
||||
|
||||
const char *charsets_dir= NULL;
|
||||
static int charset_initialized=0;
|
||||
|
||||
|
||||
static my_bool my_read_charset_file(const char *filename, myf myflags)
|
||||
{
|
||||
char *buf;
|
||||
int fd;
|
||||
uint len;
|
||||
|
||||
if (!(buf= (char *)my_malloc(MAX_BUF,myflags)))
|
||||
return FALSE;
|
||||
|
||||
if ((fd=my_open(filename,O_RDONLY,myflags)) < 0)
|
||||
{
|
||||
my_free(buf,myflags);
|
||||
return TRUE;
|
||||
}
|
||||
len=read(fd,buf,MAX_BUF);
|
||||
my_close(fd,myflags);
|
||||
|
||||
if (my_parse_charset_xml(buf,len,add_collation))
|
||||
{
|
||||
#ifdef NOT_YET
|
||||
printf("ERROR at line %d pos %d '%s'\n",
|
||||
my_xml_error_lineno(&p)+1,
|
||||
my_xml_error_pos(&p),
|
||||
my_xml_error_string(&p));
|
||||
#endif
|
||||
}
|
||||
|
||||
my_free(buf, myflags);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
char *get_charsets_dir(char *buf)
|
||||
{
|
||||
const char *sharedir= SHAREDIR;
|
||||
DBUG_ENTER("get_charsets_dir");
|
||||
|
||||
if (charsets_dir != NULL)
|
||||
strmake(buf, charsets_dir, FN_REFLEN-1);
|
||||
else
|
||||
{
|
||||
if (test_if_hard_path(sharedir) ||
|
||||
is_prefix(sharedir, DEFAULT_CHARSET_HOME))
|
||||
strxmov(buf, sharedir, "/", CHARSET_DIR, NullS);
|
||||
else
|
||||
strxmov(buf, DEFAULT_CHARSET_HOME, "/", sharedir, "/", CHARSET_DIR,
|
||||
NullS);
|
||||
}
|
||||
convert_dirname(buf,buf,NullS);
|
||||
DBUG_PRINT("info",("charsets dir: '%s'", buf));
|
||||
DBUG_RETURN(strend(buf));
|
||||
}
|
||||
|
||||
static my_bool init_available_charsets(myf myflags)
|
||||
{
|
||||
char fname[FN_REFLEN];
|
||||
my_bool error=FALSE;
|
||||
/*
|
||||
We have to use charset_initialized to not lock on THR_LOCK_charset
|
||||
inside get_internal_charset...
|
||||
*/
|
||||
if (!charset_initialized)
|
||||
{
|
||||
CHARSET_INFO **cs;
|
||||
/*
|
||||
To make things thread safe we are not allowing other threads to interfere
|
||||
while we may changing the cs_info_table
|
||||
*/
|
||||
pthread_mutex_lock(&THR_LOCK_charset);
|
||||
|
||||
bzero(&all_charsets,sizeof(all_charsets));
|
||||
init_compiled_charsets(myflags);
|
||||
|
||||
/* Copy compiled charsets */
|
||||
for (cs=all_charsets; cs < all_charsets+255 ; cs++)
|
||||
{
|
||||
if (*cs)
|
||||
set_max_sort_char(*cs);
|
||||
}
|
||||
|
||||
strmov(get_charsets_dir(fname), MY_CHARSET_INDEX);
|
||||
error= my_read_charset_file(fname,myflags);
|
||||
charset_initialized=1;
|
||||
pthread_mutex_unlock(&THR_LOCK_charset);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
void free_charsets(void)
|
||||
{
|
||||
charset_initialized=0;
|
||||
}
|
||||
|
||||
|
||||
static void get_charset_conf_name(const char *cs_name, char *buf)
|
||||
{
|
||||
strxmov(get_charsets_dir(buf), cs_name, ".conf", NullS);
|
||||
}
|
||||
|
||||
|
||||
uint get_charset_number(const char *charset_name)
|
||||
{
|
||||
CHARSET_INFO **cs;
|
||||
|
@ -606,8 +388,8 @@ static CHARSET_INFO *get_internal_charset(uint cs_number, myf flags)
|
|||
|
||||
if (cs && !(cs->state & (MY_CS_COMPILED | MY_CS_LOADED)))
|
||||
{
|
||||
strxmov(buf, cs->csname, ".xml", NullS);
|
||||
read_charset_index(buf,flags);
|
||||
strxmov(get_charsets_dir(buf), cs->csname, ".xml", NullS);
|
||||
my_read_charset_file(buf,flags);
|
||||
cs= (cs->state & MY_CS_LOADED) ? cs : NULL;
|
||||
}
|
||||
pthread_mutex_unlock(&THR_LOCK_charset);
|
||||
|
|
436
sql/field.cc
436
sql/field.cc
File diff suppressed because it is too large
Load diff
|
@ -133,7 +133,9 @@ public:
|
|||
tmp->unireg_check=Field::NONE;
|
||||
tmp->flags&= (NOT_NULL_FLAG | BLOB_FLAG | UNSIGNED_FLAG |
|
||||
ZEROFILL_FLAG | BINARY_FLAG | ENUM_FLAG | SET_FLAG);
|
||||
#ifdef PROBABLY_WRONG
|
||||
tmp->table_name= new_table->table_name;
|
||||
#endif
|
||||
tmp->reset_fields();
|
||||
}
|
||||
return tmp;
|
||||
|
@ -1094,7 +1096,8 @@ bool set_field_to_null(Field *field);
|
|||
bool set_field_to_null_with_conversions(Field *field, bool no_conversions);
|
||||
uint find_enum(TYPELIB *typelib,const char *x, uint length);
|
||||
ulonglong find_set(TYPELIB *typelib,const char *x, uint length);
|
||||
bool test_if_int(const char *str,int length,CHARSET_INFO *cs);
|
||||
bool test_if_int(const char *str, int length, const char *int_end,
|
||||
CHARSET_INFO *cs);
|
||||
|
||||
/*
|
||||
The following are for the interface with the .frm file
|
||||
|
|
|
@ -1600,6 +1600,8 @@ build_template(
|
|||
ibool fetch_all_in_key = FALSE;
|
||||
ulint i;
|
||||
|
||||
ut_a(templ_type != ROW_MYSQL_REC_FIELDS || thd == current_thd);
|
||||
|
||||
clust_index = dict_table_get_first_index_noninline(prebuilt->table);
|
||||
|
||||
if (!prebuilt->hint_no_need_to_fetch_extra_cols) {
|
||||
|
@ -2466,7 +2468,9 @@ ha_innobase::index_read_last(
|
|||
}
|
||||
|
||||
/************************************************************************
|
||||
Changes the active index of a handle. */
|
||||
Changes the active index of a handle. Note that since we build also the
|
||||
template for a search, update_thd() must already have been called, in
|
||||
::external_lock, for example. */
|
||||
|
||||
int
|
||||
ha_innobase::change_active_index(
|
||||
|
@ -2481,6 +2485,10 @@ ha_innobase::change_active_index(
|
|||
statistic_increment(ha_read_key_count, &LOCK_status);
|
||||
DBUG_ENTER("change_active_index");
|
||||
|
||||
ut_a(prebuilt->trx ==
|
||||
(trx_t*) current_thd->transaction.all.innobase_tid);
|
||||
ut_a(user_thd == current_thd);
|
||||
|
||||
active_index = keynr;
|
||||
|
||||
if (keynr != MAX_KEY && table->keys > 0) {
|
||||
|
|
17
sql/item.cc
17
sql/item.cc
|
@ -116,7 +116,7 @@ bool Item_string::eq(const Item *item, bool binary_cmp) const
|
|||
bool Item::get_date(TIME *ltime,bool fuzzydate)
|
||||
{
|
||||
char buff[40];
|
||||
String tmp(buff,sizeof(buff),NULL),*res;
|
||||
String tmp(buff,sizeof(buff), my_charset_bin),*res;
|
||||
if (!(res=val_str(&tmp)) ||
|
||||
str_to_TIME(res->ptr(),res->length(),ltime,fuzzydate) == TIMESTAMP_NONE)
|
||||
{
|
||||
|
@ -134,7 +134,7 @@ bool Item::get_date(TIME *ltime,bool fuzzydate)
|
|||
bool Item::get_time(TIME *ltime)
|
||||
{
|
||||
char buff[40];
|
||||
String tmp(buff,sizeof(buff),NULL),*res;
|
||||
String tmp(buff,sizeof(buff),my_charset_bin),*res;
|
||||
if (!(res=val_str(&tmp)) ||
|
||||
str_to_time(res->ptr(),res->length(),ltime))
|
||||
{
|
||||
|
@ -380,7 +380,8 @@ double Item_param::val()
|
|||
{
|
||||
switch (item_result_type) {
|
||||
case STRING_RESULT:
|
||||
return (double)my_strntod(str_value.charset(),str_value.ptr(),str_value.length(),(char**)0);
|
||||
return (double) my_strntod(str_value.charset(), (char*) str_value.ptr(),
|
||||
str_value.length(), (char**) 0);
|
||||
case INT_RESULT:
|
||||
return (double)int_value;
|
||||
default:
|
||||
|
@ -1149,7 +1150,7 @@ Item *resolve_const_item(Item *item,Item *comp_item)
|
|||
if (res_type == STRING_RESULT)
|
||||
{
|
||||
char buff[MAX_FIELD_WIDTH];
|
||||
String tmp(buff,sizeof(buff),NULL),*result;
|
||||
String tmp(buff,sizeof(buff),my_charset_bin),*result;
|
||||
result=item->val_str(&tmp);
|
||||
if (item->null_value)
|
||||
{
|
||||
|
@ -1204,8 +1205,8 @@ bool field_is_equal_to_item(Field *field,Item *item)
|
|||
{
|
||||
char item_buff[MAX_FIELD_WIDTH];
|
||||
char field_buff[MAX_FIELD_WIDTH];
|
||||
String item_tmp(item_buff,sizeof(item_buff),NULL),*item_result;
|
||||
String field_tmp(field_buff,sizeof(field_buff),NULL);
|
||||
String item_tmp(item_buff,sizeof(item_buff),my_charset_bin),*item_result;
|
||||
String field_tmp(field_buff,sizeof(field_buff),my_charset_bin);
|
||||
item_result=item->val_str(&item_tmp);
|
||||
if (item->null_value)
|
||||
return 1; // This must be true
|
||||
|
@ -1263,8 +1264,8 @@ void Item_cache_str::store(Item *item)
|
|||
double Item_cache_str::val()
|
||||
{
|
||||
if (value)
|
||||
return my_strntod(value->charset(), value->ptr(),
|
||||
value->length(), (char**)0);
|
||||
return my_strntod(value->charset(), (char*) value->ptr(),
|
||||
value->length(), (char**) 0);
|
||||
else
|
||||
return (double)0;
|
||||
}
|
||||
|
|
|
@ -344,7 +344,7 @@ public:
|
|||
enum Type type() const { return STRING_ITEM; }
|
||||
double val()
|
||||
{
|
||||
return my_strntod(str_value.charset(), str_value.ptr(),
|
||||
return my_strntod(str_value.charset(), (char*) str_value.ptr(),
|
||||
str_value.length(), (char**) 0);
|
||||
}
|
||||
longlong val_int()
|
||||
|
@ -598,7 +598,11 @@ public:
|
|||
enum Item_result result_type () const { return STRING_RESULT; }
|
||||
enum_field_types field_type() const { return cached_field_type; }
|
||||
double val()
|
||||
{ return null_value ? 0.0 : my_strntod(str_value.charset(),str_value.ptr(),str_value.length(),NULL); }
|
||||
{
|
||||
return (null_value ? 0.0 :
|
||||
my_strntod(str_value.charset(), (char*) str_value.ptr(),
|
||||
str_value.length(),NULL));
|
||||
}
|
||||
longlong val_int()
|
||||
{ return null_value ? LL(0) : my_strntoll(str_value.charset(),str_value.ptr(),str_value.length(),(char**) 0,10); }
|
||||
String *val_str(String*);
|
||||
|
|
|
@ -1893,7 +1893,7 @@ longlong Item_func_set_last_insert_id::val_int()
|
|||
longlong Item_func_benchmark::val_int()
|
||||
{
|
||||
char buff[MAX_FIELD_WIDTH];
|
||||
String tmp(buff,sizeof(buff), NULL);
|
||||
String tmp(buff,sizeof(buff), my_charset_bin);
|
||||
THD *thd=current_thd;
|
||||
|
||||
for (ulong loop=0 ; loop < loop_count && !thd->killed; loop++)
|
||||
|
@ -2039,7 +2039,7 @@ Item_func_set_user_var::update()
|
|||
case STRING_RESULT:
|
||||
{
|
||||
char buffer[MAX_FIELD_WIDTH];
|
||||
String tmp(buffer,sizeof(buffer),NULL);
|
||||
String tmp(buffer,sizeof(buffer),my_charset_bin);
|
||||
(void) val_str(&tmp);
|
||||
break;
|
||||
}
|
||||
|
@ -2234,7 +2234,7 @@ longlong Item_func_inet_aton::val_int()
|
|||
char c = '.'; // we mark c to indicate invalid IP in case length is 0
|
||||
char buff[36];
|
||||
|
||||
String *s,tmp(buff,sizeof(buff),NULL);
|
||||
String *s,tmp(buff,sizeof(buff),my_charset_bin);
|
||||
if (!(s = args[0]->val_str(&tmp))) // If null value
|
||||
goto err;
|
||||
null_value=0;
|
||||
|
@ -2288,7 +2288,7 @@ void Item_func_match::init_search(bool no_order)
|
|||
|
||||
String *ft_tmp= 0;
|
||||
char tmp1[FT_QUERY_MAXLEN];
|
||||
String tmp2(tmp1,sizeof(tmp1),NULL);
|
||||
String tmp2(tmp1,sizeof(tmp1),default_charset_info);
|
||||
|
||||
// MATCH ... AGAINST (NULL) is meaningless, but possible
|
||||
if (!(ft_tmp=key_item()->val_str(&tmp2)))
|
||||
|
|
|
@ -813,7 +813,7 @@ public:
|
|||
double val()
|
||||
{
|
||||
String *res; res=val_str(&str_value);
|
||||
return res ? my_strntod(res->charset(),res->ptr(),res->length(),0) : 0.0;
|
||||
return res ? my_strntod(res->charset(),(char*) res->ptr(),res->length(),0) : 0.0;
|
||||
}
|
||||
longlong val_int()
|
||||
{
|
||||
|
|
|
@ -54,7 +54,8 @@ double Item_str_func::val()
|
|||
{
|
||||
String *res;
|
||||
res=val_str(&str_value);
|
||||
return res ? my_strntod(res->charset(),res->ptr(),res->length(),NULL) : 0.0;
|
||||
return res ? my_strntod(res->charset(), (char*) res->ptr(),res->length(),
|
||||
NULL) : 0.0;
|
||||
}
|
||||
|
||||
longlong Item_str_func::val_int()
|
||||
|
@ -2771,10 +2772,8 @@ String *Item_func_spatial_collection::val_str(String *str)
|
|||
uint32 n_points;
|
||||
double x1, y1, x2, y2;
|
||||
|
||||
if (len < WKB_HEADER_SIZE + 4 + 8 + 8)
|
||||
if (len < 4 + 2 * POINT_DATA_SIZE)
|
||||
goto ret;
|
||||
data+=WKB_HEADER_SIZE;
|
||||
len-=WKB_HEADER_SIZE;
|
||||
|
||||
uint32 llen=len;
|
||||
const char *ldata=data;
|
||||
|
@ -2786,10 +2785,6 @@ String *Item_func_spatial_collection::val_str(String *str)
|
|||
float8get(y1,data);
|
||||
data+=8;
|
||||
|
||||
len-= 4 + 8 + 8;
|
||||
|
||||
if (len < n_points * POINT_DATA_SIZE)
|
||||
goto ret;
|
||||
data+=(n_points-2) * POINT_DATA_SIZE;
|
||||
|
||||
float8get(x2,data);
|
||||
|
|
|
@ -341,7 +341,8 @@ double Item_sum_hybrid::val()
|
|||
switch (hybrid_type) {
|
||||
case STRING_RESULT:
|
||||
String *res; res=val_str(&str_value);
|
||||
return res ? my_strntod(res->charset(),res->ptr(),res->length(),(char**)0) : 0.0;
|
||||
return (res ? my_strntod(res->charset(), (char*) res->ptr(),res->length(),
|
||||
(char**) 0) : 0.0);
|
||||
case INT_RESULT:
|
||||
if (unsigned_flag)
|
||||
return ulonglong2double(sum_int);
|
||||
|
|
|
@ -484,7 +484,8 @@ public:
|
|||
double val()
|
||||
{
|
||||
String *res; res=val_str(&str_value);
|
||||
return res ? my_strntod(res->charset(),res->ptr(),res->length(),(char**) 0) : 0.0;
|
||||
return res ? my_strntod(res->charset(),(char*) res->ptr(),res->length(),
|
||||
(char**) 0) : 0.0;
|
||||
}
|
||||
longlong val_int()
|
||||
{
|
||||
|
|
|
@ -529,7 +529,7 @@ void Item_func_now::fix_length_and_dec()
|
|||
{
|
||||
struct tm tm_tmp,*start;
|
||||
time_t query_start=current_thd->query_start();
|
||||
CHARSET_INFO *cs=thd_charset();
|
||||
CHARSET_INFO *cs=my_charset_bin;
|
||||
|
||||
decimals=0;
|
||||
max_length=19*cs->mbmaxlen;
|
||||
|
|
|
@ -4665,8 +4665,11 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
|
|||
berkeley_lock_type=berkeley_lock_types[type-1];
|
||||
else
|
||||
{
|
||||
if (test_if_int(argument,(uint) strlen(argument), my_charset_latin1))
|
||||
berkeley_lock_scan_time=atoi(argument);
|
||||
char *end;
|
||||
uint length= strlen(argument);
|
||||
long value= my_strntol(my_charset_latin1, argument, length, &end, 10);
|
||||
if (test_if_int(argument,(uint) length, end, my_charset_latin1))
|
||||
berkeley_lock_scan_time= value;
|
||||
else
|
||||
{
|
||||
fprintf(stderr,"Unknown lock type: %s\n",argument);
|
||||
|
|
|
@ -2796,7 +2796,7 @@ static void
|
|||
print_key(KEY_PART *key_part,const char *key,uint used_length)
|
||||
{
|
||||
char buff[1024];
|
||||
String tmp(buff,sizeof(buff),NULL);
|
||||
String tmp(buff,sizeof(buff),my_charset_bin);
|
||||
|
||||
for (uint length=0;
|
||||
length < used_length ;
|
||||
|
|
|
@ -59,7 +59,7 @@ public:
|
|||
void set(double nr) { value=nr; }
|
||||
void set(longlong nr) { value=(double) nr; }
|
||||
void set(const char *str,uint length,CHARSET_INFO *cs)
|
||||
{ value=my_strntod(cs,str,length,(char**)0); }
|
||||
{ value=my_strntod(cs,(char*) str,length,(char**)0); }
|
||||
double val() { return value; }
|
||||
longlong val_int() { return (longlong) value; }
|
||||
String *val_str(String *s) { s->set(value,decimals,thd_charset()); return s; }
|
||||
|
@ -99,7 +99,8 @@ public:
|
|||
double val()
|
||||
{
|
||||
CHARSET_INFO *cs=str_value.charset();
|
||||
return my_strntod(cs, str_value.ptr(), str_value.length(),(char**)0);
|
||||
return my_strntod(cs, (char*) str_value.ptr(), str_value.length(),
|
||||
(char**) 0);
|
||||
}
|
||||
longlong val_int()
|
||||
{
|
||||
|
|
|
@ -1749,12 +1749,8 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables,
|
|||
}
|
||||
if (report_error)
|
||||
{
|
||||
if (thd->lex.current_select->get_master()->order_list.elements)
|
||||
my_printf_error(ER_TABLENAME_NOT_ALLOWED_HERE, ER(ER_TABLENAME_NOT_ALLOWED_HERE),
|
||||
MYF(0), table_name, thd->where);
|
||||
else
|
||||
my_printf_error(ER_UNKNOWN_TABLE, ER(ER_UNKNOWN_TABLE), MYF(0),
|
||||
table_name, thd->where);
|
||||
my_printf_error(ER_UNKNOWN_TABLE, ER(ER_UNKNOWN_TABLE), MYF(0),
|
||||
table_name, thd->where);
|
||||
}
|
||||
else
|
||||
return (Field*) not_found_field;
|
||||
|
|
|
@ -526,7 +526,7 @@ bool select_send::send_data(List<Item> &items)
|
|||
List_iterator_fast<Item> li(items);
|
||||
Protocol *protocol= thd->protocol;
|
||||
char buff[MAX_FIELD_WIDTH];
|
||||
String buffer(buff, sizeof(buff), NULL);
|
||||
String buffer(buff, sizeof(buff), my_charset_bin);
|
||||
DBUG_ENTER("send_data");
|
||||
|
||||
protocol->prepare_for_resend();
|
||||
|
@ -649,7 +649,7 @@ bool select_export::send_data(List<Item> &items)
|
|||
DBUG_ENTER("send_data");
|
||||
char buff[MAX_FIELD_WIDTH],null_buff[2],space[MAX_FIELD_WIDTH];
|
||||
bool space_inited=0;
|
||||
String tmp(buff,sizeof(buff),NULL),*res;
|
||||
String tmp(buff,sizeof(buff),my_charset_bin),*res;
|
||||
tmp.length(0);
|
||||
|
||||
if (unit->offset_limit_cnt)
|
||||
|
@ -857,7 +857,7 @@ bool select_dump::send_data(List<Item> &items)
|
|||
{
|
||||
List_iterator_fast<Item> li(items);
|
||||
char buff[MAX_FIELD_WIDTH];
|
||||
String tmp(buff,sizeof(buff),NULL),*res;
|
||||
String tmp(buff,sizeof(buff),my_charset_bin),*res;
|
||||
tmp.length(0);
|
||||
Item *item;
|
||||
DBUG_ENTER("send_data");
|
||||
|
|
|
@ -109,6 +109,10 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables,
|
|||
if (cond && (cond->check_cols(1) || cond->fix_fields(thd, tables, &cond)))
|
||||
return -1;
|
||||
|
||||
/* InnoDB needs to know that this table handle is used in the HANDLER */
|
||||
|
||||
table->file->init_table_handle_for_HANDLER();
|
||||
|
||||
if (keyname)
|
||||
{
|
||||
if ((keyno=find_type(keyname, &table->keynames, 1+2)-1)<0)
|
||||
|
@ -131,8 +135,6 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables,
|
|||
|
||||
insert_fields(thd,tables,tables->db,tables->alias,&it);
|
||||
|
||||
table->file->init_table_handle_for_HANDLER(); // Only InnoDB requires it
|
||||
|
||||
select_limit+=offset_limit;
|
||||
protocol->send_fields(&list,1);
|
||||
|
||||
|
@ -142,6 +144,12 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables,
|
|||
if (!lock)
|
||||
goto err0; // mysql_lock_tables() printed error message already
|
||||
|
||||
/* In ::external_lock InnoDB resets the fields which tell it that
|
||||
the handle is used in the HANDLER interface. Tell it again that
|
||||
we are using it for HANDLER. */
|
||||
|
||||
table->file->init_table_handle_for_HANDLER();
|
||||
|
||||
for (num_rows=0; num_rows < select_limit; )
|
||||
{
|
||||
switch (mode) {
|
||||
|
|
|
@ -943,7 +943,7 @@ int yylex(void *arg, void *yythd)
|
|||
|
||||
void st_select_lex_node::init_query()
|
||||
{
|
||||
dependent= 0;
|
||||
no_table_names_allowed= dependent= 0;
|
||||
}
|
||||
|
||||
void st_select_lex_node::init_select()
|
||||
|
|
|
@ -212,6 +212,7 @@ public:
|
|||
bool with_sum_func;
|
||||
bool create_refs;
|
||||
bool dependent; /* dependent from outer select subselect */
|
||||
bool no_table_names_allowed; /* used for global order by */
|
||||
|
||||
static void *operator new(size_t size)
|
||||
{
|
||||
|
|
|
@ -30,6 +30,9 @@
|
|||
|
||||
extern gptr sql_alloc(unsigned size);
|
||||
extern void sql_element_free(void *ptr);
|
||||
static uint32
|
||||
copy_and_convert(char *to, uint32 to_length, CHARSET_INFO *to_cs,
|
||||
const char *from, uint32 from_length, CHARSET_INFO *from_cs);
|
||||
|
||||
#include "sql_string.h"
|
||||
|
||||
|
@ -223,55 +226,51 @@ bool String::copy(const char *str,uint32 arg_length, CHARSET_INFO *cs)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/* Copy with charset convertion */
|
||||
bool String::copy(const char *str,uint32 arg_length, CHARSET_INFO *from, CHARSET_INFO *to)
|
||||
{
|
||||
uint32 new_length=to->mbmaxlen*arg_length;
|
||||
int cnvres;
|
||||
my_wc_t wc;
|
||||
const uchar *s=(const uchar *)str;
|
||||
const uchar *se=s+arg_length;
|
||||
uchar *d, *de;
|
||||
/* Copy with charset convertion */
|
||||
|
||||
bool String::copy(const char *str, uint32 arg_length,
|
||||
CHARSET_INFO *from_cs, CHARSET_INFO *to_cs)
|
||||
{
|
||||
uint32 new_length= to_cs->mbmaxlen*arg_length;
|
||||
if (alloc(new_length))
|
||||
return TRUE;
|
||||
|
||||
d=(uchar *)Ptr;
|
||||
de=d+new_length;
|
||||
|
||||
for (str_length=new_length ; s < se && d < de ; )
|
||||
{
|
||||
if ((cnvres=from->mb_wc(from,&wc,s,se)) > 0 )
|
||||
{
|
||||
s+=cnvres;
|
||||
}
|
||||
else if (cnvres==MY_CS_ILSEQ)
|
||||
{
|
||||
s++;
|
||||
wc='?';
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
||||
outp:
|
||||
if ((cnvres=to->wc_mb(to,wc,d,de)) >0 )
|
||||
{
|
||||
d+=cnvres;
|
||||
}
|
||||
else if (cnvres==MY_CS_ILUNI && wc!='?')
|
||||
{
|
||||
wc='?';
|
||||
goto outp;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
Ptr[new_length]=0;
|
||||
length((uint32) (d-(uchar *)Ptr));
|
||||
str_charset=to;
|
||||
str_length=copy_and_convert((char*) Ptr, new_length, to_cs,
|
||||
str, arg_length, from_cs);
|
||||
str_charset=to_cs;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Set a string to the value of a latin1-string, keeping the original charset
|
||||
|
||||
SYNOPSIS
|
||||
copy_or_set()
|
||||
str String of a simple charset (latin1)
|
||||
arg_length Length of string
|
||||
|
||||
IMPLEMENTATION
|
||||
If string object is of a simple character set, set it to point to the
|
||||
given string.
|
||||
If not, make a copy and convert it to the new character set.
|
||||
|
||||
RETURN
|
||||
0 ok
|
||||
1 Could not allocate result buffer
|
||||
|
||||
*/
|
||||
|
||||
bool String::set_latin1(const char *str, uint32 arg_length)
|
||||
{
|
||||
if (str_charset->mbmaxlen == 1)
|
||||
{
|
||||
set(str, arg_length, str_charset);
|
||||
return 0;
|
||||
}
|
||||
return copy(str, arg_length, my_charset_latin1, str_charset);
|
||||
}
|
||||
|
||||
|
||||
/* This is used by mysql.cc */
|
||||
|
||||
bool String::fill(uint32 max_length,char fill_char)
|
||||
|
@ -306,11 +305,26 @@ bool String::append(const String &s)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Append a latin1 string to the a string of the current character set
|
||||
*/
|
||||
|
||||
|
||||
bool String::append(const char *s,uint32 arg_length)
|
||||
{
|
||||
if (!arg_length) // Default argument
|
||||
if (!(arg_length= (uint32) strlen(s)))
|
||||
return FALSE;
|
||||
if (str_charset->mbmaxlen > 1)
|
||||
{
|
||||
uint32 add_length=arg_length * str_charset->mbmaxlen;
|
||||
if (realloc(str_length+ add_length))
|
||||
return TRUE;
|
||||
str_length+= copy_and_convert(Ptr+str_length, add_length, str_charset,
|
||||
s, arg_length, my_charset_latin1);
|
||||
return FALSE;
|
||||
}
|
||||
if (realloc(str_length+arg_length))
|
||||
return TRUE;
|
||||
memcpy(Ptr+str_length,s,arg_length);
|
||||
|
@ -318,6 +332,7 @@ bool String::append(const char *s,uint32 arg_length)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
#ifdef TO_BE_REMOVED
|
||||
bool String::append(FILE* file, uint32 arg_length, myf my_flags)
|
||||
{
|
||||
|
@ -658,4 +673,61 @@ String *copy_if_not_alloced(String *to,String *from,uint32 from_length)
|
|||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
Help functions
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
copy a string from one character set to another
|
||||
|
||||
SYNOPSIS
|
||||
copy_and_convert()
|
||||
to Store result here
|
||||
to_cs Character set of result string
|
||||
from Copy from here
|
||||
from_length Length of from string
|
||||
from_cs From character set
|
||||
|
||||
NOTES
|
||||
'to' must be big enough as form_length * to_cs->mbmaxlen
|
||||
|
||||
RETURN
|
||||
length of bytes copied to 'to'
|
||||
*/
|
||||
|
||||
|
||||
static uint32
|
||||
copy_and_convert(char *to, uint32 to_length, CHARSET_INFO *to_cs,
|
||||
const char *from, uint32 from_length, CHARSET_INFO *from_cs)
|
||||
{
|
||||
int cnvres;
|
||||
my_wc_t wc;
|
||||
const uchar *from_end= (const uchar*) from+from_length;
|
||||
char *to_start= to;
|
||||
uchar *to_end= (uchar*) to+to_length;
|
||||
|
||||
while ((uchar*) from < from_end)
|
||||
{
|
||||
if ((cnvres=from_cs->mb_wc(from_cs, &wc, (uchar*) from, from_end)) > 0)
|
||||
from+= cnvres;
|
||||
else if (cnvres == MY_CS_ILSEQ)
|
||||
{
|
||||
from++;
|
||||
wc= '?';
|
||||
}
|
||||
else
|
||||
break; // Impossible char.
|
||||
|
||||
outp:
|
||||
if ((cnvres= to_cs->wc_mb(to_cs, wc, (uchar*) to, to_end)) > 0)
|
||||
to+= cnvres;
|
||||
else if (cnvres == MY_CS_ILUNI && wc != '?')
|
||||
{
|
||||
wc= '?';
|
||||
goto outp;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
return (uint32) (to - to_start);
|
||||
}
|
||||
|
|
|
@ -115,6 +115,7 @@ public:
|
|||
Ptr=(char*) str; str_length=arg_length; Alloced_length=0 ; alloced=0;
|
||||
str_charset=cs;
|
||||
}
|
||||
bool String::set_latin1(const char *str, uint32 arg_length);
|
||||
inline void set_quick(char *str,uint32 arg_length, CHARSET_INFO *cs)
|
||||
{
|
||||
if (!alloced)
|
||||
|
|
|
@ -233,6 +233,7 @@ int mysql_update(THD *thd,
|
|||
}
|
||||
}
|
||||
end_read_record(&info);
|
||||
|
||||
if (table->key_read)
|
||||
{
|
||||
table->key_read=0;
|
||||
|
|
|
@ -3746,17 +3746,41 @@ simple_ident:
|
|||
}
|
||||
| ident '.' ident
|
||||
{
|
||||
SELECT_LEX_NODE *sel=Select;
|
||||
THD *thd= YYTHD;
|
||||
LEX *lex= &thd->lex;
|
||||
SELECT_LEX_NODE *sel= lex->current_select;
|
||||
if (sel->no_table_names_allowed)
|
||||
{
|
||||
my_printf_error(ER_TABLENAME_NOT_ALLOWED_HERE,
|
||||
ER(ER_TABLENAME_NOT_ALLOWED_HERE),
|
||||
MYF(0), $1.str, thd->where);
|
||||
}
|
||||
$$ = !sel->create_refs || sel->get_in_sum_expr() > 0 ? (Item*) new Item_field(NullS,$1.str,$3.str) : (Item*) new Item_ref(NullS,$1.str,$3.str);
|
||||
}
|
||||
| '.' ident '.' ident
|
||||
{
|
||||
SELECT_LEX_NODE *sel=Select;
|
||||
THD *thd= YYTHD;
|
||||
LEX *lex= &thd->lex;
|
||||
SELECT_LEX_NODE *sel= lex->current_select;
|
||||
if (sel->no_table_names_allowed)
|
||||
{
|
||||
my_printf_error(ER_TABLENAME_NOT_ALLOWED_HERE,
|
||||
ER(ER_TABLENAME_NOT_ALLOWED_HERE),
|
||||
MYF(0), $2.str, thd->where);
|
||||
}
|
||||
$$ = !sel->create_refs || sel->get_in_sum_expr() > 0 ? (Item*) new Item_field(NullS,$2.str,$4.str) : (Item*) new Item_ref(NullS,$2.str,$4.str);
|
||||
}
|
||||
| ident '.' ident '.' ident
|
||||
{
|
||||
SELECT_LEX_NODE *sel=Select;
|
||||
THD *thd= YYTHD;
|
||||
LEX *lex= &thd->lex;
|
||||
SELECT_LEX_NODE *sel= lex->current_select;
|
||||
if (sel->no_table_names_allowed)
|
||||
{
|
||||
my_printf_error(ER_TABLENAME_NOT_ALLOWED_HERE,
|
||||
ER(ER_TABLENAME_NOT_ALLOWED_HERE),
|
||||
MYF(0), $3.str, thd->where);
|
||||
}
|
||||
$$ = !sel->create_refs || sel->get_in_sum_expr() > 0 ? (Item*) new Item_field((YYTHD->client_capabilities & CLIENT_NO_SCHEMA ? NullS :$1.str),$3.str,$5.str) : (Item*) new Item_ref((YYTHD->client_capabilities & CLIENT_NO_SCHEMA ? NullS :$1.str),$3.str,$5.str);
|
||||
};
|
||||
|
||||
|
@ -4541,7 +4565,8 @@ optional_order_or_limit:
|
|||
/* Empty */ {}
|
||||
|
|
||||
{
|
||||
LEX *lex=Lex;
|
||||
THD *thd= YYTHD;
|
||||
LEX *lex= &thd->lex;
|
||||
if (!lex->current_select->linkage == GLOBAL_OPTIONS_TYPE)
|
||||
{
|
||||
send_error(lex->thd, ER_SYNTAX_ERROR);
|
||||
|
@ -4553,8 +4578,15 @@ optional_order_or_limit:
|
|||
lex->current_select= sel->master_unit();
|
||||
lex->current_select->select_limit=
|
||||
lex->thd->variables.select_limit;
|
||||
lex->current_select->no_table_names_allowed= 1;
|
||||
thd->where= "global ORDER clause";
|
||||
}
|
||||
order_or_limit
|
||||
{
|
||||
THD *thd= YYTHD;
|
||||
thd->lex.current_select->no_table_names_allowed= 0;
|
||||
thd->where= "";
|
||||
}
|
||||
;
|
||||
|
||||
order_or_limit:
|
||||
|
|
|
@ -22,19 +22,19 @@ pkglib_LIBRARIES = libmystrings.a
|
|||
# Exact one of ASSEMBLER_X
|
||||
if ASSEMBLER_x86
|
||||
ASRCS = strings-x86.s longlong2str-x86.s
|
||||
CSRCS = bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c atof.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-czech.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-latin1_de.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-win1250ch.c ctype-bin.c xml.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 xml.c
|
||||
else
|
||||
if ASSEMBLER_sparc32
|
||||
# These file MUST all be on the same line!! Otherwise automake
|
||||
# generats a very broken makefile
|
||||
ASRCS = bmove_upp-sparc.s strappend-sparc.s strend-sparc.s strinstr-sparc.s strmake-sparc.s strmov-sparc.s strnmov-sparc.s strstr-sparc.s
|
||||
CSRCS = strcont.c strfill.c strcend.c is_prefix.c longlong2str.c bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c atof.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c strxmov.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-czech.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-latin1_de.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-win1250ch.c ctype-bin.c xml.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 xml.c
|
||||
else
|
||||
#no assembler
|
||||
ASRCS =
|
||||
# These file MUST all be on the same line!! Otherwise automake
|
||||
# generats a very broken makefile
|
||||
CSRCS = strxmov.c bmove_upp.c strappend.c strcont.c strend.c strfill.c strcend.c is_prefix.c strstr.c strinstr.c strmake.c strnmov.c strmov.c longlong2str.c bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c atof.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-czech.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-latin1_de.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-win1250ch.c ctype-bin.c xml.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 xml.c
|
||||
endif
|
||||
endif
|
||||
|
||||
|
|
|
@ -47,8 +47,8 @@ static int my_strnncoll_binary(CHARSET_INFO * cs __attribute__((unused)),
|
|||
const uchar *s, uint slen,
|
||||
const uchar *t, uint tlen)
|
||||
{
|
||||
int len = ( slen > tlen ) ? tlen : slen;
|
||||
return memcmp(s,t,len);
|
||||
int cmp= memcmp(s,t,min(slen,tlen));
|
||||
return cmp ? cmp : (int) (slen - tlen);
|
||||
}
|
||||
|
||||
static void my_caseup_str_bin(CHARSET_INFO *cs __attribute__((unused)),
|
||||
|
|
|
@ -110,88 +110,40 @@ int my_mb_wc_8bit(CHARSET_INFO *cs,my_wc_t *wc,
|
|||
}
|
||||
|
||||
int my_wc_mb_8bit(CHARSET_INFO *cs,my_wc_t wc,
|
||||
unsigned char *s,
|
||||
unsigned char *e __attribute__((unused)))
|
||||
unsigned char *str,
|
||||
unsigned char *end __attribute__((unused)))
|
||||
{
|
||||
MY_UNI_IDX *idx;
|
||||
|
||||
for(idx=cs->tab_from_uni; idx->tab ; idx++){
|
||||
if(idx->from<=wc && idx->to>=wc){
|
||||
s[0]=idx->tab[wc-idx->from];
|
||||
return (!s[0] && wc) ? MY_CS_ILUNI : 1;
|
||||
for (idx=cs->tab_from_uni; idx->tab ; idx++)
|
||||
{
|
||||
if (idx->from <= wc && idx->to >= wc)
|
||||
{
|
||||
str[0]= idx->tab[wc - idx->from];
|
||||
return (!str[0] && wc) ? MY_CS_ILUNI : 1;
|
||||
}
|
||||
}
|
||||
return MY_CS_ILUNI;
|
||||
}
|
||||
|
||||
|
||||
#ifdef NOT_USED
|
||||
static int my_vsnprintf_8bit(char *to, size_t n, const char* fmt, va_list ap)
|
||||
{
|
||||
char *start=to, *end=to+n-1;
|
||||
for (; *fmt ; fmt++)
|
||||
{
|
||||
if (fmt[0] != '%')
|
||||
{
|
||||
if (to == end) /* End of buffer */
|
||||
break;
|
||||
*to++= *fmt; /* Copy ordinary char */
|
||||
continue;
|
||||
}
|
||||
/* Skip if max size is used (to be compatible with printf) */
|
||||
fmt++;
|
||||
while (my_isdigit(system_charset_info,*fmt) || *fmt == '.' || *fmt == '-')
|
||||
fmt++;
|
||||
if (*fmt == 'l')
|
||||
fmt++;
|
||||
if (*fmt == 's') /* String parameter */
|
||||
{
|
||||
reg2 char *par = va_arg(ap, char *);
|
||||
uint plen,left_len = (uint)(end-to);
|
||||
if (!par) par = (char*)"(null)";
|
||||
plen = (uint) strlen(par);
|
||||
if (left_len <= plen)
|
||||
plen = left_len - 1;
|
||||
to=strnmov(to,par,plen);
|
||||
continue;
|
||||
}
|
||||
else if (*fmt == 'd' || *fmt == 'u') /* Integer parameter */
|
||||
{
|
||||
register int iarg;
|
||||
if ((uint) (end-to) < 16)
|
||||
break;
|
||||
iarg = va_arg(ap, int);
|
||||
if (*fmt == 'd')
|
||||
to=int10_to_str((long) iarg,to, -10);
|
||||
else
|
||||
to=int10_to_str((long) (uint) iarg,to,10);
|
||||
continue;
|
||||
}
|
||||
/* We come here on '%%', unknown code or too long parameter */
|
||||
if (to == end)
|
||||
break;
|
||||
*to++='%'; /* % used as % or unknown code */
|
||||
}
|
||||
DBUG_ASSERT(to <= end);
|
||||
*to='\0'; /* End of errmessage */
|
||||
return (uint) (to - start);
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
We can't use vsprintf here as it's not guaranteed to return
|
||||
the length on all operating systems.
|
||||
This function is also not called in a safe environment, so the
|
||||
end buffer must be checked.
|
||||
*/
|
||||
|
||||
int my_snprintf_8bit(CHARSET_INFO *cs __attribute__((unused)),
|
||||
char* to, uint n __attribute__((unused)),
|
||||
const char* fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
int result;
|
||||
va_start(args,fmt);
|
||||
#ifdef NOT_USED
|
||||
return my_vsnprintf_8bit(to, n, fmt, args);
|
||||
#endif
|
||||
/*
|
||||
FIXME: generally not safe, but it is OK for now
|
||||
FIXME: as far as it's not called unsafely in the current code
|
||||
*/
|
||||
return vsprintf(to,fmt,args); /* FIXME */
|
||||
result= my_vsnprintf(to, n, fmt, args);
|
||||
va_end(args);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
@ -690,28 +642,48 @@ noconv:
|
|||
return 0L;
|
||||
}
|
||||
|
||||
double my_strntod_8bit(CHARSET_INFO *cs __attribute__((unused)),
|
||||
const char *s, uint l, char **e)
|
||||
/*
|
||||
Read double from string
|
||||
|
||||
SYNOPSIS:
|
||||
my_strntod_8bit()
|
||||
cs Character set information
|
||||
str String to convert to double
|
||||
length Optional length for string.
|
||||
end pointer to end of converted string
|
||||
|
||||
NOTES:
|
||||
If length is not INT_MAX32 or str[length] != 0 then the given str must
|
||||
be writeable
|
||||
If length == INT_MAX32 the str must be \0 terminated.
|
||||
|
||||
It's implemented this way to save a buffer allocation and a memory copy.
|
||||
|
||||
RETURN
|
||||
value of number in string
|
||||
*/
|
||||
|
||||
|
||||
double my_strntod_8bit(CHARSET_INFO *cs __attribute__((unused)),
|
||||
char *str, uint length, char **end)
|
||||
{
|
||||
char buf[256];
|
||||
double res;
|
||||
if((l+1)>sizeof(buf))
|
||||
{
|
||||
if (e)
|
||||
memcpy(*e,s,sizeof(s));
|
||||
return 0;
|
||||
}
|
||||
strncpy(buf,s,l);
|
||||
buf[l]='\0';
|
||||
res=strtod(buf,e);
|
||||
if (e)
|
||||
memcpy(*e,*e-buf+s,sizeof(s));
|
||||
return res;
|
||||
char end_char;
|
||||
double result;
|
||||
|
||||
if (length == INT_MAX32 || str[length] == 0)
|
||||
return strtod(str, end);
|
||||
end_char= str[length];
|
||||
str[length]= 0;
|
||||
result= strtod(str, end);
|
||||
str[length]= end_char; /* Restore end char */
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
This is a fast version optimized for the case of radix 10 / -10
|
||||
|
||||
Assume len >= 1
|
||||
*/
|
||||
|
||||
int my_l10tostr_8bit(CHARSET_INFO *cs __attribute__((unused)),
|
||||
|
@ -720,18 +692,19 @@ int my_l10tostr_8bit(CHARSET_INFO *cs __attribute__((unused)),
|
|||
char buffer[66];
|
||||
register char *p, *e;
|
||||
long int new_val;
|
||||
int sl=0;
|
||||
uint l;
|
||||
|
||||
uint sign=0;
|
||||
|
||||
e = p = &buffer[sizeof(buffer)-1];
|
||||
*e='\0';
|
||||
*p= 0;
|
||||
|
||||
if (radix < 0)
|
||||
{
|
||||
if (val < 0)
|
||||
{
|
||||
sl = 1;
|
||||
val = -val;
|
||||
val= -val;
|
||||
*dst++= '-';
|
||||
len--;
|
||||
sign= 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -746,41 +719,38 @@ int my_l10tostr_8bit(CHARSET_INFO *cs __attribute__((unused)),
|
|||
val= new_val;
|
||||
}
|
||||
|
||||
if (sl)
|
||||
{
|
||||
*--p='-';
|
||||
}
|
||||
|
||||
l=e-p;
|
||||
l=(l>len)?len:l;
|
||||
memcpy(dst,p,l);
|
||||
return (int)l;
|
||||
len= min(len, (uint) (e-p));
|
||||
memcpy(dst, p, len);
|
||||
return (int) len+sign;
|
||||
}
|
||||
|
||||
|
||||
int my_ll10tostr_8bit(CHARSET_INFO *cs __attribute__((unused)),
|
||||
char *dst, uint len, int radix, longlong val)
|
||||
{
|
||||
char buffer[65];
|
||||
register char *p, *e;
|
||||
long long_val;
|
||||
int sl=0;
|
||||
uint l;
|
||||
uint sign= 0;
|
||||
|
||||
if (radix < 0)
|
||||
{
|
||||
if (val < 0)
|
||||
{
|
||||
sl=1;
|
||||
val = -val;
|
||||
*dst++= '-';
|
||||
len--;
|
||||
sign= 1;
|
||||
}
|
||||
}
|
||||
|
||||
e = p = &buffer[sizeof(buffer)-1];
|
||||
*p='\0';
|
||||
*p= 0;
|
||||
|
||||
if (val == 0)
|
||||
{
|
||||
*--p='0';
|
||||
*--p= '0';
|
||||
len= 1;
|
||||
goto cnv;
|
||||
}
|
||||
|
||||
|
@ -800,16 +770,10 @@ int my_ll10tostr_8bit(CHARSET_INFO *cs __attribute__((unused)),
|
|||
long_val= quo;
|
||||
}
|
||||
|
||||
len= min(len, (uint) (e-p));
|
||||
cnv:
|
||||
if (sl)
|
||||
{
|
||||
*--p='-';
|
||||
}
|
||||
|
||||
l=e-p;
|
||||
l=(l>len)?len:l;
|
||||
memcpy(dst,p,l);
|
||||
return (int)(e-p);
|
||||
memcpy(dst, p, len);
|
||||
return len+sign;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -2874,37 +2874,31 @@ bs:
|
|||
|
||||
|
||||
double my_strntod_ucs2(CHARSET_INFO *cs __attribute__((unused)),
|
||||
const char *nptr, uint l, char **endptr)
|
||||
char *nptr, uint length, char **endptr)
|
||||
{
|
||||
char buf[256];
|
||||
double res;
|
||||
register char *b=buf;
|
||||
register const char *s=nptr;
|
||||
register const char *e=nptr+l;
|
||||
register const char *end;
|
||||
my_wc_t wc;
|
||||
int cnv;
|
||||
|
||||
if((l+1)>sizeof(buf))
|
||||
{
|
||||
if (endptr)
|
||||
*endptr=(char*)nptr;
|
||||
my_errno=ERANGE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
while ((cnv=cs->mb_wc(cs,&wc,s,e))>0)
|
||||
/* Cut too long strings */
|
||||
if (length >= sizeof(buf))
|
||||
length= sizeof(buf)-1;
|
||||
end=nptr+length;
|
||||
|
||||
while ((cnv=cs->mb_wc(cs,&wc,s,end)) > 0)
|
||||
{
|
||||
s+=cnv;
|
||||
if (wc < 128)
|
||||
{
|
||||
*b++=wc;
|
||||
}
|
||||
else
|
||||
break;
|
||||
if (wc > (int) (uchar) 'e' || !wc)
|
||||
break; /* Can't be part of double */
|
||||
*b++=wc;
|
||||
}
|
||||
*b='\0';
|
||||
*b= 0;
|
||||
|
||||
res=strtod(buf,endptr);
|
||||
res=strtod(buf, endptr);
|
||||
if (endptr)
|
||||
*endptr=(char*) (*endptr-buf+nptr);
|
||||
return res;
|
||||
|
|
223
strings/ctype.c
223
strings/ctype.c
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include <my_global.h>
|
||||
#include <m_ctype.h>
|
||||
#include <my_xml.h>
|
||||
#ifndef SCO
|
||||
#include <m_string.h>
|
||||
#endif
|
||||
|
@ -3895,6 +3896,228 @@ static CHARSET_INFO compiled_charsets[] = {
|
|||
};
|
||||
|
||||
|
||||
static char *mstr(char *str,const char *src,uint l1,uint l2)
|
||||
{
|
||||
l1= l1<l2 ? l1 : l2;
|
||||
memcpy(str,src,l1);
|
||||
str[l1]='\0';
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
struct my_cs_file_section_st
|
||||
{
|
||||
int state;
|
||||
const char *str;
|
||||
};
|
||||
|
||||
#define _CS_MISC 1
|
||||
#define _CS_ID 2
|
||||
#define _CS_CSNAME 3
|
||||
#define _CS_FAMILY 4
|
||||
#define _CS_ORDER 5
|
||||
#define _CS_COLNAME 6
|
||||
#define _CS_FLAG 7
|
||||
#define _CS_CHARSET 8
|
||||
#define _CS_COLLATION 9
|
||||
#define _CS_UPPERMAP 10
|
||||
#define _CS_LOWERMAP 11
|
||||
#define _CS_UNIMAP 12
|
||||
#define _CS_COLLMAP 13
|
||||
#define _CS_CTYPEMAP 14
|
||||
|
||||
static struct my_cs_file_section_st sec[] =
|
||||
{
|
||||
{_CS_MISC, "xml"},
|
||||
{_CS_MISC, "xml.version"},
|
||||
{_CS_MISC, "xml.encoding"},
|
||||
{_CS_MISC, "charsets"},
|
||||
{_CS_MISC, "charsets.max-id"},
|
||||
{_CS_MISC, "charsets.description"},
|
||||
{_CS_CHARSET, "charsets.charset"},
|
||||
{_CS_CSNAME, "charsets.charset.name"},
|
||||
{_CS_FAMILY, "charsets.charset.family"},
|
||||
{_CS_MISC, "charsets.charset.alias"},
|
||||
{_CS_MISC, "charsets.charset.ctype"},
|
||||
{_CS_CTYPEMAP, "charsets.charset.ctype.map"},
|
||||
{_CS_MISC, "charsets.charset.upper"},
|
||||
{_CS_UPPERMAP, "charsets.charset.upper.map"},
|
||||
{_CS_MISC, "charsets.charset.lower"},
|
||||
{_CS_LOWERMAP, "charsets.charset.lower.map"},
|
||||
{_CS_MISC, "charsets.charset.unicode"},
|
||||
{_CS_UNIMAP, "charsets.charset.unicode.map"},
|
||||
{_CS_COLLATION, "charsets.charset.collation"},
|
||||
{_CS_COLNAME, "charsets.charset.collation.name"},
|
||||
{_CS_ID, "charsets.charset.collation.id"},
|
||||
{_CS_ORDER, "charsets.charset.collation.order"},
|
||||
{_CS_FLAG, "charsets.charset.collation.flag"},
|
||||
{_CS_COLLMAP, "charsets.charset.collation.map"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
static struct my_cs_file_section_st * cs_file_sec(const char *attr, uint len)
|
||||
{
|
||||
struct my_cs_file_section_st *s;
|
||||
for (s=sec; s->str; s++)
|
||||
{
|
||||
if (!strncmp(attr,s->str,len))
|
||||
return s;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
typedef struct my_cs_file_info
|
||||
{
|
||||
char csname[MY_CS_NAME_SIZE];
|
||||
char name[MY_CS_NAME_SIZE];
|
||||
uchar ctype[MY_CS_CTYPE_TABLE_SIZE];
|
||||
uchar to_lower[MY_CS_TO_LOWER_TABLE_SIZE];
|
||||
uchar to_upper[MY_CS_TO_UPPER_TABLE_SIZE];
|
||||
uchar sort_order[MY_CS_SORT_ORDER_TABLE_SIZE];
|
||||
uint16 tab_to_uni[MY_CS_TO_UNI_TABLE_SIZE];
|
||||
CHARSET_INFO cs;
|
||||
int (*add_collation)(CHARSET_INFO *cs);
|
||||
} MY_CHARSET_LOADER;
|
||||
|
||||
|
||||
|
||||
static int fill_uchar(uchar *a,uint size,const char *str, uint len)
|
||||
{
|
||||
uint i= 0;
|
||||
const char *s, *b, *e=str+len;
|
||||
|
||||
for (s=str ; s < e ; i++)
|
||||
{
|
||||
for ( ; (s < e) && strchr(" \t\r\n",s[0]); s++) ;
|
||||
b=s;
|
||||
for ( ; (s < e) && !strchr(" \t\r\n",s[0]); s++) ;
|
||||
if (s == b || i > size)
|
||||
break;
|
||||
a[i]= my_strntoul(my_charset_latin1,b,s-b,NULL,16);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fill_uint16(uint16 *a,uint size,const char *str, uint len)
|
||||
{
|
||||
uint i= 0;
|
||||
const char *s, *b, *e=str+len;
|
||||
for (s=str ; s < e ; i++)
|
||||
{
|
||||
for ( ; (s < e) && strchr(" \t\r\n",s[0]); s++) ;
|
||||
b=s;
|
||||
for ( ; (s < e) && !strchr(" \t\r\n",s[0]); s++) ;
|
||||
if (s == b || i > size)
|
||||
break;
|
||||
a[i]= my_strntol(my_charset_latin1,b,s-b,NULL,16);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int cs_enter(MY_XML_PARSER *st,const char *attr, uint len)
|
||||
{
|
||||
struct my_cs_file_info *i= (struct my_cs_file_info *)st->user_data;
|
||||
struct my_cs_file_section_st *s= cs_file_sec(attr,len);
|
||||
|
||||
if ( s && (s->state == _CS_CHARSET))
|
||||
{
|
||||
bzero(&i->cs,sizeof(i->cs));
|
||||
}
|
||||
return MY_XML_OK;
|
||||
}
|
||||
|
||||
|
||||
static int cs_leave(MY_XML_PARSER *st,const char *attr, uint len)
|
||||
{
|
||||
struct my_cs_file_info *i= (struct my_cs_file_info *)st->user_data;
|
||||
struct my_cs_file_section_st *s= cs_file_sec(attr,len);
|
||||
int state= s ? s->state : 0;
|
||||
int rc;
|
||||
|
||||
switch(state){
|
||||
case _CS_COLLATION:
|
||||
rc= i->add_collation ? i->add_collation(&i->cs) : MY_XML_OK;
|
||||
break;
|
||||
default:
|
||||
rc=MY_XML_OK;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static int cs_value(MY_XML_PARSER *st,const char *attr, uint len)
|
||||
{
|
||||
struct my_cs_file_info *i= (struct my_cs_file_info *)st->user_data;
|
||||
struct my_cs_file_section_st *s;
|
||||
int state= (s=cs_file_sec(st->attr,strlen(st->attr))) ? s->state : 0;
|
||||
|
||||
#ifndef DBUG_OFF
|
||||
if(0){
|
||||
char str[1024];
|
||||
mstr(str,attr,len,sizeof(str)-1);
|
||||
printf("VALUE %d %s='%s'\n",state,st->attr,str);
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (state) {
|
||||
case _CS_ID:
|
||||
i->cs.number= my_strntoul(my_charset_latin1,attr,len,(char**)NULL,0);
|
||||
break;
|
||||
case _CS_COLNAME:
|
||||
i->cs.name=mstr(i->name,attr,len,MY_CS_NAME_SIZE-1);
|
||||
break;
|
||||
case _CS_CSNAME:
|
||||
i->cs.csname=mstr(i->csname,attr,len,MY_CS_NAME_SIZE-1);
|
||||
break;
|
||||
case _CS_FLAG:
|
||||
if (!strncmp("primary",attr,len))
|
||||
i->cs.state|= MY_CS_PRIMARY;
|
||||
break;
|
||||
case _CS_UPPERMAP:
|
||||
fill_uchar(i->to_upper,MY_CS_TO_UPPER_TABLE_SIZE,attr,len);
|
||||
i->cs.to_upper=i->to_upper;
|
||||
break;
|
||||
case _CS_LOWERMAP:
|
||||
fill_uchar(i->to_lower,MY_CS_TO_LOWER_TABLE_SIZE,attr,len);
|
||||
i->cs.to_lower=i->to_lower;
|
||||
break;
|
||||
case _CS_UNIMAP:
|
||||
fill_uint16(i->tab_to_uni,MY_CS_TO_UNI_TABLE_SIZE,attr,len);
|
||||
i->cs.tab_to_uni=i->tab_to_uni;
|
||||
break;
|
||||
case _CS_COLLMAP:
|
||||
fill_uchar(i->sort_order,MY_CS_SORT_ORDER_TABLE_SIZE,attr,len);
|
||||
i->cs.sort_order=i->sort_order;
|
||||
break;
|
||||
case _CS_CTYPEMAP:
|
||||
fill_uchar(i->ctype,MY_CS_CTYPE_TABLE_SIZE,attr,len);
|
||||
i->cs.ctype=i->ctype;
|
||||
break;
|
||||
}
|
||||
return MY_XML_OK;
|
||||
}
|
||||
|
||||
|
||||
my_bool my_parse_charset_xml(const char *buf, uint len,
|
||||
int (*add_collation)(CHARSET_INFO *cs))
|
||||
{
|
||||
MY_XML_PARSER p;
|
||||
struct my_cs_file_info i;
|
||||
my_bool rc;
|
||||
|
||||
my_xml_parser_create(&p);
|
||||
my_xml_set_enter_handler(&p,cs_enter);
|
||||
my_xml_set_value_handler(&p,cs_value);
|
||||
my_xml_set_leave_handler(&p,cs_leave);
|
||||
i.add_collation= add_collation;
|
||||
my_xml_set_user_data(&p,(void*)&i);
|
||||
rc= (my_xml_parse(&p,buf,len) == MY_XML_OK) ? FALSE : TRUE;
|
||||
my_xml_parser_free(&p);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
CHARSET_INFO *my_charset_latin1 = &compiled_charsets[0];
|
||||
CHARSET_INFO *all_charsets[256];
|
||||
CHARSET_INFO *default_charset_info = &compiled_charsets[0];
|
||||
|
|
|
@ -14,13 +14,25 @@
|
|||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
#include "mysys_priv.h"
|
||||
#include "mysys_err.h"
|
||||
#include <my_global.h>
|
||||
#include <m_string.h>
|
||||
#include <stdarg.h>
|
||||
#include <m_ctype.h>
|
||||
#include <assert.h>
|
||||
|
||||
/*
|
||||
Limited snprintf() implementations
|
||||
|
||||
IMPLEMENTION:
|
||||
Supports following formats:
|
||||
%#d
|
||||
%#u
|
||||
%#.#s Note #.# is skiped
|
||||
|
||||
RETURN
|
||||
length of result string
|
||||
*/
|
||||
|
||||
int my_snprintf(char* to, size_t n, const char* fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
@ -31,9 +43,12 @@ int my_snprintf(char* to, size_t n, const char* fmt, ...)
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap)
|
||||
{
|
||||
char *start=to, *end=to+n-1;
|
||||
uint length, num_state, pre_zero;
|
||||
|
||||
for (; *fmt ; fmt++)
|
||||
{
|
||||
if (fmt[0] != '%')
|
||||
|
@ -43,10 +58,27 @@ int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap)
|
|||
*to++= *fmt; /* Copy ordinary char */
|
||||
continue;
|
||||
}
|
||||
/* Skip if max size is used (to be compatible with printf) */
|
||||
fmt++;
|
||||
while (my_isdigit(system_charset_info,*fmt) || *fmt == '.' || *fmt == '-')
|
||||
fmt++; /* skip '%' */
|
||||
/* Read max fill size (only used with %d and %u) */
|
||||
if (*fmt == '-')
|
||||
fmt++;
|
||||
length= num_state= pre_zero= 0;
|
||||
for (;; fmt++)
|
||||
{
|
||||
if (my_isdigit(system_charset_info,*fmt))
|
||||
{
|
||||
if (!num_state)
|
||||
{
|
||||
length=length*10+ (uint) (*fmt-'0');
|
||||
if (!length)
|
||||
pre_zero= 1; /* first digit was 0 */
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (*fmt != '.' || num_state)
|
||||
break;
|
||||
num_state= 1;
|
||||
}
|
||||
if (*fmt == 'l')
|
||||
fmt++;
|
||||
if (*fmt == 's') /* String parameter */
|
||||
|
@ -63,13 +95,26 @@ int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap)
|
|||
else if (*fmt == 'd' || *fmt == 'u') /* Integer parameter */
|
||||
{
|
||||
register int iarg;
|
||||
if ((uint) (end-to) < 16)
|
||||
char *to_start= to;
|
||||
if ((uint) (end-to) < max(16,length))
|
||||
break;
|
||||
iarg = va_arg(ap, int);
|
||||
if (*fmt == 'd')
|
||||
to=int10_to_str((long) iarg,to, -10);
|
||||
else
|
||||
to=int10_to_str((long) (uint) iarg,to,10);
|
||||
/* If %#d syntax was used, we have to pre-zero/pre-space the string */
|
||||
if (length)
|
||||
{
|
||||
uint res_length= (uint) (to - to_start);
|
||||
if (res_length < length)
|
||||
{
|
||||
uint diff= (length- res_length);
|
||||
bmove_upp(to+diff, to, res_length);
|
||||
bfill(to-res_length, diff, pre_zero ? '0' : ' ');
|
||||
to+= diff;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
/* We come here on '%%', unknown code or too long parameter */
|
Loading…
Reference in a new issue