mirror of
https://github.com/MariaDB/server.git
synced 2025-01-17 20:42:30 +01:00
Portability fixes
Fixed bug in end space handle for WHERE text_column="constant"
This commit is contained in:
parent
4ca548bcc6
commit
ea687ba5da
28 changed files with 254 additions and 164 deletions
|
@ -246,12 +246,12 @@ ulong hp_hashnr(register HP_KEYDEF *keydef, register const byte *key)
|
|||
if (seg->type == HA_KEYTYPE_TEXT)
|
||||
{
|
||||
CHARSET_INFO *cs= seg->charset;
|
||||
uint length= ((uchar*)key) - pos;
|
||||
uint char_length= length / cs->mbmaxlen;
|
||||
if (length > char_length)
|
||||
uint char_length= (uint) ((uchar*) key - pos);
|
||||
if (cs->mbmaxlen > 1)
|
||||
{
|
||||
char_length= my_charpos(cs, pos, pos + length, char_length);
|
||||
set_if_smaller(char_length, length);
|
||||
uint length= char_length;
|
||||
char_length= my_charpos(cs, pos, pos + length, length/cs->mbmaxlen);
|
||||
set_if_smaller(char_length, length); /* QQ: ok to remove? */
|
||||
}
|
||||
cs->coll->hash_sort(cs, pos, char_length, &nr, &nr2);
|
||||
}
|
||||
|
@ -289,11 +289,12 @@ ulong hp_rec_hashnr(register HP_KEYDEF *keydef, register const byte *rec)
|
|||
if (seg->type == HA_KEYTYPE_TEXT)
|
||||
{
|
||||
CHARSET_INFO *cs= seg->charset;
|
||||
uint char_length= seg->length / cs->mbmaxlen;
|
||||
if (seg->length > char_length)
|
||||
uint char_length= seg->length;
|
||||
if (cs->mbmaxlen > 1)
|
||||
{
|
||||
char_length= my_charpos(cs, pos, pos + seg->length, char_length);
|
||||
set_if_smaller(char_length, seg->length);
|
||||
char_length= my_charpos(cs, pos, pos + char_length,
|
||||
char_length / cs->mbmaxlen);
|
||||
set_if_smaller(char_length, seg->length); /* QQ: ok to remove? */
|
||||
}
|
||||
cs->coll->hash_sort(cs, pos, char_length, &nr, &nr2);
|
||||
}
|
||||
|
@ -417,17 +418,17 @@ int hp_rec_key_cmp(HP_KEYDEF *keydef, const byte *rec1, const byte *rec2)
|
|||
if (seg->type == HA_KEYTYPE_TEXT)
|
||||
{
|
||||
CHARSET_INFO *cs= seg->charset;
|
||||
uint char_length= seg->length / cs->mbmaxlen;
|
||||
uint char_length1;
|
||||
uint char_length2;
|
||||
uchar *pos1= (uchar*)rec1 + seg->start;
|
||||
uchar *pos2= (uchar*)rec2 + seg->start;
|
||||
if (seg->length > char_length)
|
||||
if (cs->mbmaxlen > 1)
|
||||
{
|
||||
uint char_length= seg->length / cs->mbmaxlen;
|
||||
char_length1= my_charpos(cs, pos1, pos1 + seg->length, char_length);
|
||||
set_if_smaller(char_length1, seg->length);
|
||||
set_if_smaller(char_length1, seg->length); /* QQ: ok to remove? */
|
||||
char_length2= my_charpos(cs, pos2, pos2 + seg->length, char_length);
|
||||
set_if_smaller(char_length2, seg->length);
|
||||
set_if_smaller(char_length2, seg->length); /* QQ: ok to remove? */
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -468,12 +469,12 @@ int hp_key_cmp(HP_KEYDEF *keydef, const byte *rec, const byte *key)
|
|||
if (seg->type == HA_KEYTYPE_TEXT)
|
||||
{
|
||||
CHARSET_INFO *cs= seg->charset;
|
||||
uint char_length= seg->length / cs->mbmaxlen;
|
||||
uint char_length_key;
|
||||
uint char_length_rec;
|
||||
uchar *pos= (uchar*) rec + seg->start;
|
||||
if (seg->length > char_length)
|
||||
if (cs->mbmaxlen > 1)
|
||||
{
|
||||
uint char_length= seg->length / cs->mbmaxlen;
|
||||
char_length_key= my_charpos(cs, key, key + seg->length, char_length);
|
||||
set_if_smaller(char_length_key, seg->length);
|
||||
char_length_rec= my_charpos(cs, pos, pos + seg->length, char_length);
|
||||
|
@ -509,21 +510,22 @@ void hp_make_key(HP_KEYDEF *keydef, byte *key, const byte *rec)
|
|||
for (seg=keydef->seg,endseg=seg+keydef->keysegs ; seg < endseg ; seg++)
|
||||
{
|
||||
CHARSET_INFO *cs= seg->charset;
|
||||
uint char_length= (cs && cs->mbmaxlen > 1) ? seg->length / cs->mbmaxlen :
|
||||
seg->length;
|
||||
uint char_length= seg->length;
|
||||
uchar *pos= (uchar*) rec + seg->start;
|
||||
if (seg->null_bit)
|
||||
*key++= test(rec[seg->null_pos] & seg->null_bit);
|
||||
if (seg->length > char_length)
|
||||
if (cs->mbmaxlen > 1)
|
||||
{
|
||||
char_length= my_charpos(cs, pos, pos + seg->length, char_length);
|
||||
set_if_smaller(char_length, seg->length);
|
||||
char_length= my_charpos(cs, pos, pos + seg->length,
|
||||
char_length / cs->mbmaxlen);
|
||||
set_if_smaller(char_length, seg->length); /* QQ: ok to remove? */
|
||||
}
|
||||
memcpy(key,rec+seg->start,(size_t) char_length);
|
||||
key+= char_length;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint hp_rb_make_key(HP_KEYDEF *keydef, byte *key,
|
||||
const byte *rec, byte *recpos)
|
||||
{
|
||||
|
@ -575,13 +577,13 @@ uint hp_rb_make_key(HP_KEYDEF *keydef, byte *key,
|
|||
}
|
||||
continue;
|
||||
}
|
||||
char_length= seg->length / (seg->charset ? seg->charset->mbmaxlen : 1);
|
||||
if (seg->length > char_length)
|
||||
char_length= seg->length;
|
||||
if (seg->charset->mbmaxlen > 1)
|
||||
{
|
||||
char_length= my_charpos(seg->charset,
|
||||
rec + seg->start, rec + seg->start + seg->length,
|
||||
char_length);
|
||||
set_if_smaller(char_length, seg->length);
|
||||
rec + seg->start, rec + seg->start + char_length,
|
||||
char_length / seg->charset->mbmaxlen);
|
||||
set_if_smaller(char_length, seg->length); /* QQ: ok to remove? */
|
||||
if (char_length < seg->length)
|
||||
seg->charset->cset->fill(seg->charset, key + char_length,
|
||||
seg->length - char_length, ' ');
|
||||
|
@ -593,7 +595,9 @@ uint hp_rb_make_key(HP_KEYDEF *keydef, byte *key,
|
|||
return key - start_key;
|
||||
}
|
||||
|
||||
uint hp_rb_pack_key(HP_KEYDEF *keydef, uchar *key, const uchar *old, uint k_len)
|
||||
|
||||
uint hp_rb_pack_key(HP_KEYDEF *keydef, uchar *key, const uchar *old,
|
||||
uint k_len)
|
||||
{
|
||||
HA_KEYSEG *seg, *endseg;
|
||||
uchar *start_key= key;
|
||||
|
@ -623,11 +627,12 @@ uint hp_rb_pack_key(HP_KEYDEF *keydef, uchar *key, const uchar *old, uint k_len)
|
|||
}
|
||||
continue;
|
||||
}
|
||||
char_length= seg->length / (seg->charset ? seg->charset->mbmaxlen : 1);
|
||||
if (seg->length > char_length)
|
||||
char_length= seg->length;
|
||||
if (seg->charset->mbmaxlen > 1)
|
||||
{
|
||||
char_length= my_charpos(seg->charset, old, old+seg->length, char_length);
|
||||
set_if_smaller(char_length, seg->length);
|
||||
char_length= my_charpos(seg->charset, old, old+char_length,
|
||||
char_length / seg->charset->mbmaxlen);
|
||||
set_if_smaller(char_length, seg->length); /* QQ: ok to remove? */
|
||||
if (char_length < seg->length)
|
||||
seg->charset->cset->fill(seg->charset, key + char_length,
|
||||
seg->length - char_length, ' ');
|
||||
|
@ -639,12 +644,14 @@ uint hp_rb_pack_key(HP_KEYDEF *keydef, uchar *key, const uchar *old, uint k_len)
|
|||
return key - start_key;
|
||||
}
|
||||
|
||||
|
||||
uint hp_rb_key_length(HP_KEYDEF *keydef,
|
||||
const byte *key __attribute__((unused)))
|
||||
{
|
||||
return keydef->length;
|
||||
}
|
||||
|
||||
|
||||
uint hp_rb_null_key_length(HP_KEYDEF *keydef, const byte *key)
|
||||
{
|
||||
const byte *start_key= key;
|
||||
|
|
|
@ -3429,7 +3429,7 @@ static void fetch_long_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field,
|
|||
char buff[22]; /* Enough for longlong */
|
||||
char *end= longlong10_to_str(value, buff, field_is_unsigned ? 10: -10);
|
||||
/* Resort to string conversion which supports all typecodes */
|
||||
fetch_string_with_conversion(param, buff, end - buff);
|
||||
fetch_string_with_conversion(param, buff, (uint) (end - buff));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -3505,7 +3505,7 @@ static void fetch_float_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field,
|
|||
sprintf(buff, "%.*f", (int) field->decimals, value);
|
||||
end= strend(buff);
|
||||
}
|
||||
fetch_string_with_conversion(param, buff, end - buff);
|
||||
fetch_string_with_conversion(param, buff, (uint) (end - buff));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,9 +23,9 @@
|
|||
#include <ieeefp.h>
|
||||
#endif
|
||||
|
||||
#define CHECK_KEYS
|
||||
#define CHECK_KEYS /* Enable safety checks */
|
||||
|
||||
#define FIX_LENGTH \
|
||||
#define FIX_LENGTH(cs, pos, length, char_length) \
|
||||
do { \
|
||||
if (length > char_length) \
|
||||
char_length= my_charpos(cs, pos, pos+length, char_length); \
|
||||
|
@ -48,7 +48,7 @@ uint _mi_make_key(register MI_INFO *info, uint keynr, uchar *key,
|
|||
my_bool is_ft= info->s->keyinfo[keynr].flag & HA_FULLTEXT;
|
||||
DBUG_ENTER("_mi_make_key");
|
||||
|
||||
if(info->s->keyinfo[keynr].flag & HA_SPATIAL)
|
||||
if (info->s->keyinfo[keynr].flag & HA_SPATIAL)
|
||||
{
|
||||
/*
|
||||
TODO: nulls processing
|
||||
|
@ -78,7 +78,8 @@ uint _mi_make_key(register MI_INFO *info, uint keynr, uchar *key,
|
|||
*key++=1; /* Not NULL */
|
||||
}
|
||||
|
||||
char_length= (!is_ft && cs && cs->mbmaxlen > 1) ? length/cs->mbmaxlen : length;
|
||||
char_length= ((!is_ft && cs && cs->mbmaxlen > 1) ? length/cs->mbmaxlen :
|
||||
length);
|
||||
|
||||
pos= (byte*) record+keyseg->start;
|
||||
if (keyseg->flag & HA_SPACE_PACK)
|
||||
|
@ -95,7 +96,7 @@ uint _mi_make_key(register MI_INFO *info, uint keynr, uchar *key,
|
|||
pos++;
|
||||
}
|
||||
length=(uint) (end-pos);
|
||||
FIX_LENGTH;
|
||||
FIX_LENGTH(cs, pos, length, char_length);
|
||||
store_key_length_inc(key,char_length);
|
||||
memcpy((byte*) key,(byte*) pos,(size_t) char_length);
|
||||
key+=char_length;
|
||||
|
@ -106,7 +107,7 @@ uint _mi_make_key(register MI_INFO *info, uint keynr, uchar *key,
|
|||
uint tmp_length=uint2korr(pos);
|
||||
pos+=2; /* Skip VARCHAR length */
|
||||
set_if_smaller(length,tmp_length);
|
||||
FIX_LENGTH;
|
||||
FIX_LENGTH(cs, pos, length, char_length);
|
||||
store_key_length_inc(key,char_length);
|
||||
memcpy((byte*) key,(byte*) pos,(size_t) char_length);
|
||||
key+= char_length;
|
||||
|
@ -117,7 +118,7 @@ uint _mi_make_key(register MI_INFO *info, uint keynr, uchar *key,
|
|||
uint tmp_length=_mi_calc_blob_length(keyseg->bit_start,pos);
|
||||
memcpy_fixed((byte*) &pos,pos+keyseg->bit_start,sizeof(char*));
|
||||
set_if_smaller(length,tmp_length);
|
||||
FIX_LENGTH;
|
||||
FIX_LENGTH(cs, pos, length, char_length);
|
||||
store_key_length_inc(key,char_length);
|
||||
memcpy((byte*) key,(byte*) pos,(size_t) char_length);
|
||||
key+= char_length;
|
||||
|
@ -157,7 +158,7 @@ uint _mi_make_key(register MI_INFO *info, uint keynr, uchar *key,
|
|||
}
|
||||
continue;
|
||||
}
|
||||
FIX_LENGTH;
|
||||
FIX_LENGTH(cs, pos, length, char_length);
|
||||
memcpy((byte*) key, pos, char_length);
|
||||
if (length > char_length)
|
||||
cs->cset->fill(cs, key+char_length, length-char_length, ' ');
|
||||
|
@ -237,7 +238,7 @@ uint _mi_pack_key(register MI_INFO *info, uint keynr, uchar *key, uchar *old,
|
|||
}
|
||||
k_length-=length;
|
||||
length=(uint) (end-pos);
|
||||
FIX_LENGTH;
|
||||
FIX_LENGTH(cs, pos, length, char_length);
|
||||
store_key_length_inc(key,char_length);
|
||||
memcpy((byte*) key,pos,(size_t) char_length);
|
||||
key+= char_length;
|
||||
|
@ -250,7 +251,7 @@ uint _mi_pack_key(register MI_INFO *info, uint keynr, uchar *key, uchar *old,
|
|||
k_length-= 2+length;
|
||||
pos+=2;
|
||||
set_if_smaller(length,tmp_length); /* Safety */
|
||||
FIX_LENGTH;
|
||||
FIX_LENGTH(cs, pos, length, char_length);
|
||||
store_key_length_inc(key,char_length);
|
||||
old+=2; /* Skip length */
|
||||
memcpy((byte*) key, pos,(size_t) char_length);
|
||||
|
@ -267,7 +268,7 @@ uint _mi_pack_key(register MI_INFO *info, uint keynr, uchar *key, uchar *old,
|
|||
}
|
||||
continue;
|
||||
}
|
||||
FIX_LENGTH;
|
||||
FIX_LENGTH(cs, pos, length, char_length);
|
||||
memcpy((byte*) key, pos, char_length);
|
||||
if (length > char_length)
|
||||
cs->cset->fill(cs,key+char_length, length-char_length, ' ');
|
||||
|
|
|
@ -40,6 +40,7 @@ show tables;
|
|||
Tables_in_test
|
||||
update mysql.user set password=old_password("gambling2") where user=_binary"test";
|
||||
flush privileges;
|
||||
set password="";
|
||||
set password='gambling3';
|
||||
ERROR HY000: Password hash should be a 41-digit hexadecimal number
|
||||
set password=old_password('gambling3');
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
drop table if exists t1, t2;
|
||||
CREATE TABLE t1 ( a int );
|
||||
INSERT INTO t1 VALUES (1),(2),(1);
|
||||
CREATE TABLE t2 ( PRIMARY KEY (a) ) TYPE=INNODB SELECT a FROM t1;
|
||||
CREATE TABLE t2 ( PRIMARY KEY (a) ) ENGINE=INNODB SELECT a FROM t1;
|
||||
ERROR 23000: Duplicate entry '1' for key 1
|
||||
select * from t2;
|
||||
ERROR 42S02: Table 'test.t2' doesn't exist
|
||||
CREATE TEMPORARY TABLE t2 ( PRIMARY KEY (a) ) TYPE=INNODB SELECT a FROM t1;
|
||||
CREATE TEMPORARY TABLE t2 ( PRIMARY KEY (a) ) ENGINE=INNODB SELECT a FROM t1;
|
||||
ERROR 23000: Duplicate entry '1' for key 1
|
||||
select * from t2;
|
||||
ERROR 42S02: Table 'test.t2' doesn't exist
|
||||
CREATE TABLE t2 ( PRIMARY KEY (a) ) TYPE=MYISAM SELECT a FROM t1;
|
||||
CREATE TABLE t2 ( PRIMARY KEY (a) ) ENGINE=MYISAM SELECT a FROM t1;
|
||||
ERROR 23000: Duplicate entry '1' for key 1
|
||||
select * from t2;
|
||||
ERROR 42S02: Table 'test.t2' doesn't exist
|
||||
CREATE TEMPORARY TABLE t2 ( PRIMARY KEY (a) ) TYPE=MYISAM SELECT a FROM t1;
|
||||
CREATE TEMPORARY TABLE t2 ( PRIMARY KEY (a) ) ENGINE=MYISAM SELECT a FROM t1;
|
||||
ERROR 23000: Duplicate entry '1' for key 1
|
||||
select * from t2;
|
||||
ERROR 42S02: Table 'test.t2' doesn't exist
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
drop table if exists t1;
|
||||
drop table if exists t2;
|
||||
drop table if exists t1,t2;
|
||||
set names utf8;
|
||||
select left(_utf8 0xD0B0D0B1D0B2,1);
|
||||
left(_utf8 0xD0B0D0B1D0B2,1)
|
||||
|
|
|
@ -52,13 +52,13 @@ select * from t1 ignore key (key1) where text1='teststring' or text1 like 'tests
|
|||
text1
|
||||
teststring
|
||||
teststring
|
||||
select * from t1 where text1='teststring' or text1 like 'teststring_%';
|
||||
text1
|
||||
teststring
|
||||
teststring
|
||||
select * from t1 where text1='teststring' or text1 > 'teststring\t';
|
||||
text1
|
||||
teststring
|
||||
select concat('|', text1, '|') from t1 where text1='teststring' or text1 like 'teststring_%';
|
||||
concat('|', text1, '|')
|
||||
|teststring |
|
||||
|teststring|
|
||||
select concat('|', text1, '|') from t1 where text1='teststring' or text1 > 'teststring\t';
|
||||
concat('|', text1, '|')
|
||||
|teststring|
|
||||
select text1, length(text1) from t1 order by text1;
|
||||
text1 length(text1)
|
||||
nothing 7
|
||||
|
@ -77,7 +77,28 @@ concat('|', text1, '|')
|
|||
|teststring|
|
||||
|teststring |
|
||||
|teststring |
|
||||
select concat('|', text1, '|') from t1 where text1='teststring' or text1 > 'teststring\t';
|
||||
concat('|', text1, '|')
|
||||
|teststring|
|
||||
|teststring |
|
||||
select concat('|', text1, '|') from t1 where text1='teststring';
|
||||
concat('|', text1, '|')
|
||||
|teststring|
|
||||
select concat('|', text1, '|') from t1 where text1='teststring ';
|
||||
concat('|', text1, '|')
|
||||
|teststring |
|
||||
alter table t1 modify text1 text not null, pack_keys=1;
|
||||
select concat('|', text1, '|') from t1 where text1='teststring';
|
||||
concat('|', text1, '|')
|
||||
|teststring|
|
||||
|teststring |
|
||||
select concat('|', text1, '|') from t1 where text1='teststring ';
|
||||
concat('|', text1, '|')
|
||||
|teststring|
|
||||
|teststring |
|
||||
explain select concat('|', text1, '|') from t1 where text1='teststring ';
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 range key1 key1 22 NULL 2 Using where
|
||||
select * from t1 where text1 like 'teststring_%';
|
||||
text1
|
||||
teststring
|
||||
|
@ -87,10 +108,10 @@ text1
|
|||
teststring
|
||||
teststring
|
||||
teststring
|
||||
select * from t1 where text1='teststring' or text1 > 'teststring\t';
|
||||
text1
|
||||
teststring
|
||||
teststring
|
||||
select concat('|', text1, '|') from t1 where text1='teststring' or text1 > 'teststring\t';
|
||||
concat('|', text1, '|')
|
||||
|teststring|
|
||||
|teststring |
|
||||
select concat('|', text1, '|') from t1 order by text1;
|
||||
concat('|', text1, '|')
|
||||
|nothing|
|
||||
|
|
|
@ -127,3 +127,4 @@ having (a.description is not null) and (c=0);
|
|||
id description c
|
||||
1 test 0
|
||||
2 test2 0
|
||||
drop table t1,t2,t3;
|
||||
|
|
|
@ -593,9 +593,12 @@ create table t1 (id integer primary key auto_increment, txt text, unique index t
|
|||
insert into t1 (txt) values ('Chevy'), ('Chevy '), (NULL);
|
||||
select * from t1 where txt='Chevy' or txt is NULL;
|
||||
id txt
|
||||
3 NULL
|
||||
1 Chevy
|
||||
2 Chevy
|
||||
3 NULL
|
||||
explain select * from t1 where txt='Chevy' or txt is NULL;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 range txt_index txt_index 23 NULL 2 Using where
|
||||
select * from t1 where txt='Chevy ';
|
||||
id txt
|
||||
1 Chevy
|
||||
|
@ -663,6 +666,21 @@ id txt
|
|||
1 Chevy
|
||||
2 Chevy
|
||||
4 Ford
|
||||
alter table t1 modify column txt blob;
|
||||
explain select * from t1 where txt='Chevy' or txt is NULL;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ref_or_null txt_index txt_index 23 const 2 Using where
|
||||
select * from t1 where txt='Chevy' or txt is NULL;
|
||||
id txt
|
||||
1 Chevy
|
||||
3 NULL
|
||||
explain select * from t1 where txt='Chevy' or txt is NULL order by txt;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ref_or_null txt_index txt_index 23 const 2 Using where; Using filesort
|
||||
select * from t1 where txt='Chevy' or txt is NULL order by txt;
|
||||
id txt
|
||||
3 NULL
|
||||
1 Chevy
|
||||
drop table t1;
|
||||
CREATE TABLE t1 ( i int(11) NOT NULL default '0', c text NOT NULL, PRIMARY KEY (i), KEY (c(1),c(1)));
|
||||
INSERT t1 VALUES (1,''),(2,''),(3,'asdfh'),(4,'');
|
||||
|
|
|
@ -365,3 +365,15 @@ select * from t1;
|
|||
t1 i
|
||||
2004-04-01 00:00:00 10
|
||||
drop table t1;
|
||||
create table t1 (ts timestamp(19));
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`ts` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
set TIMESTAMP=1000000000;
|
||||
insert into t1 values ();
|
||||
select * from t1;
|
||||
ts
|
||||
2001-09-09 04:46:40
|
||||
drop table t1;
|
||||
|
|
|
@ -48,6 +48,7 @@ flush privileges;
|
|||
#connect (con1,localhost,test,gambling2,"");
|
||||
#show tables;
|
||||
connect (con1,localhost,test,gambling2,mysql);
|
||||
set password="";
|
||||
--error 1105
|
||||
set password='gambling3';
|
||||
set password=old_password('gambling3');
|
||||
|
|
|
@ -12,18 +12,18 @@ drop table if exists t1, t2;
|
|||
CREATE TABLE t1 ( a int );
|
||||
INSERT INTO t1 VALUES (1),(2),(1);
|
||||
--error 1062;
|
||||
CREATE TABLE t2 ( PRIMARY KEY (a) ) TYPE=INNODB SELECT a FROM t1;
|
||||
CREATE TABLE t2 ( PRIMARY KEY (a) ) ENGINE=INNODB SELECT a FROM t1;
|
||||
--error 1146;
|
||||
select * from t2;
|
||||
--error 1062;
|
||||
CREATE TEMPORARY TABLE t2 ( PRIMARY KEY (a) ) TYPE=INNODB SELECT a FROM t1;
|
||||
CREATE TEMPORARY TABLE t2 ( PRIMARY KEY (a) ) ENGINE=INNODB SELECT a FROM t1;
|
||||
--error 1146;
|
||||
select * from t2;
|
||||
--error 1062;
|
||||
CREATE TABLE t2 ( PRIMARY KEY (a) ) TYPE=MYISAM SELECT a FROM t1;
|
||||
CREATE TABLE t2 ( PRIMARY KEY (a) ) ENGINE=MYISAM SELECT a FROM t1;
|
||||
--error 1146;
|
||||
select * from t2;
|
||||
--error 1062;
|
||||
CREATE TEMPORARY TABLE t2 ( PRIMARY KEY (a) ) TYPE=MYISAM SELECT a FROM t1;
|
||||
CREATE TEMPORARY TABLE t2 ( PRIMARY KEY (a) ) ENGINE=MYISAM SELECT a FROM t1;
|
||||
--error 1146;
|
||||
select * from t2;
|
||||
|
|
|
@ -3,8 +3,7 @@
|
|||
#
|
||||
|
||||
--disable_warnings
|
||||
drop table if exists t1;
|
||||
drop table if exists t2;
|
||||
drop table if exists t1,t2;
|
||||
--enable_warnings
|
||||
set names utf8;
|
||||
|
||||
|
|
|
@ -31,19 +31,25 @@ explain select * from t1 order by text1;
|
|||
alter table t1 modify text1 char(32) binary not null;
|
||||
check table t1;
|
||||
select * from t1 ignore key (key1) where text1='teststring' or text1 like 'teststring_%';
|
||||
select * from t1 where text1='teststring' or text1 like 'teststring_%';
|
||||
select * from t1 where text1='teststring' or text1 > 'teststring\t';
|
||||
select concat('|', text1, '|') from t1 where text1='teststring' or text1 like 'teststring_%';
|
||||
select concat('|', text1, '|') from t1 where text1='teststring' or text1 > 'teststring\t';
|
||||
select text1, length(text1) from t1 order by text1;
|
||||
select text1, length(text1) from t1 order by binary text1;
|
||||
|
||||
alter table t1 modify text1 blob not null, drop key key1, add key key1 (text1(20));
|
||||
insert into t1 values ('teststring ');
|
||||
select concat('|', text1, '|') from t1 order by text1;
|
||||
select concat('|', text1, '|') from t1 where text1='teststring' or text1 > 'teststring\t';
|
||||
select concat('|', text1, '|') from t1 where text1='teststring';
|
||||
select concat('|', text1, '|') from t1 where text1='teststring ';
|
||||
|
||||
alter table t1 modify text1 text not null, pack_keys=1;
|
||||
select concat('|', text1, '|') from t1 where text1='teststring';
|
||||
select concat('|', text1, '|') from t1 where text1='teststring ';
|
||||
explain select concat('|', text1, '|') from t1 where text1='teststring ';
|
||||
select * from t1 where text1 like 'teststring_%';
|
||||
select * from t1 where text1='teststring' or text1 like 'teststring_%';
|
||||
select * from t1 where text1='teststring' or text1 > 'teststring\t';
|
||||
select concat('|', text1, '|') from t1 where text1='teststring' or text1 > 'teststring\t';
|
||||
select concat('|', text1, '|') from t1 order by text1;
|
||||
drop table t1;
|
||||
|
||||
|
|
|
@ -121,3 +121,4 @@ select
|
|||
from t1 a left join t3 b on a.id=b.order_id
|
||||
group by a.id, a.description
|
||||
having (a.description is not null) and (c=0);
|
||||
drop table t1,t2,t3;
|
||||
|
|
|
@ -340,6 +340,7 @@ drop table t1;
|
|||
create table t1 (id integer primary key auto_increment, txt text, unique index txt_index (txt (20)));
|
||||
insert into t1 (txt) values ('Chevy'), ('Chevy '), (NULL);
|
||||
select * from t1 where txt='Chevy' or txt is NULL;
|
||||
explain select * from t1 where txt='Chevy' or txt is NULL;
|
||||
select * from t1 where txt='Chevy ';
|
||||
select * from t1 where txt='Chevy ' or txt='Chevy';
|
||||
select * from t1 where txt='Chevy' or txt='Chevy ';
|
||||
|
@ -358,7 +359,13 @@ select * from t1 where txt < 'Chevy ' or txt is NULL;
|
|||
select * from t1 where txt <= 'Chevy';
|
||||
select * from t1 where txt > 'Chevy';
|
||||
select * from t1 where txt >= 'Chevy';
|
||||
alter table t1 modify column txt blob;
|
||||
explain select * from t1 where txt='Chevy' or txt is NULL;
|
||||
select * from t1 where txt='Chevy' or txt is NULL;
|
||||
explain select * from t1 where txt='Chevy' or txt is NULL order by txt;
|
||||
select * from t1 where txt='Chevy' or txt is NULL order by txt;
|
||||
drop table t1;
|
||||
|
||||
CREATE TABLE t1 ( i int(11) NOT NULL default '0', c text NOT NULL, PRIMARY KEY (i), KEY (c(1),c(1)));
|
||||
INSERT t1 VALUES (1,''),(2,''),(3,'asdfh'),(4,'');
|
||||
select max(i) from t1 where c = '';
|
||||
|
|
|
@ -234,3 +234,13 @@ alter table t1 add i int default 10;
|
|||
select * from t1;
|
||||
drop table t1;
|
||||
|
||||
|
||||
# Test for bug #4491, TIMESTAMP(19) should be possible to create and not
|
||||
# only read in 4.0
|
||||
#
|
||||
create table t1 (ts timestamp(19));
|
||||
show create table t1;
|
||||
set TIMESTAMP=1000000000;
|
||||
insert into t1 values ();
|
||||
select * from t1;
|
||||
drop table t1;
|
||||
|
|
38
sql/field.cc
38
sql/field.cc
|
@ -1753,7 +1753,7 @@ void Field_medium::sql_type(String &res) const
|
|||
int Field_long::store(const char *from,uint len,CHARSET_INFO *cs)
|
||||
{
|
||||
long tmp;
|
||||
int error= 0, cuted_fields= 0;
|
||||
int error= 0;
|
||||
char *end;
|
||||
|
||||
tmp= cs->cset->scan(cs, from, from+len, MY_SEQ_SPACES);
|
||||
|
@ -1781,7 +1781,7 @@ int Field_long::store(const char *from,uint len,CHARSET_INFO *cs)
|
|||
#if SIZEOF_LONG > 4
|
||||
if (unsigned_flag)
|
||||
{
|
||||
if (tmp > UINT_MAX32)
|
||||
if ((ulong) tmp > UINT_MAX32)
|
||||
{
|
||||
tmp= UINT_MAX32;
|
||||
error= 1;
|
||||
|
@ -4277,27 +4277,17 @@ int Field_string::store(const char *from,uint length,CHARSET_INFO *cs)
|
|||
|
||||
int Field_str::store(double nr)
|
||||
{
|
||||
bool use_scientific_notation=TRUE;
|
||||
char buff[DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE];
|
||||
uint length;
|
||||
if (field_length < 32 && nr > 1) // TODO: negative numbers
|
||||
{
|
||||
if (ceiling == 0)
|
||||
{
|
||||
static double e[]= {1e1, 1e2, 1e4, 1e8, 1e16 };
|
||||
double p= 1;
|
||||
for (int i= sizeof(e)/sizeof(e[0]), j= 1<<i ; j; i--, j>>= 1 )
|
||||
{
|
||||
if (field_length & j)
|
||||
p*= e[i];
|
||||
}
|
||||
ceiling= p-1;
|
||||
}
|
||||
use_scientific_notation= (ceiling < nr);
|
||||
}
|
||||
length= (uint)sprintf(buff, "%-.*g",
|
||||
use_scientific_notation ? max(0,(int)field_length-5) : field_length,
|
||||
nr);
|
||||
bool use_scientific_notation= TRUE;
|
||||
use_scientific_notation= TRUE;
|
||||
if (field_length < 32 && fabs(nr) < log_10[field_length]-1)
|
||||
use_scientific_notation= FALSE;
|
||||
length= (uint) my_sprintf(buff, (buff, "%-.*g",
|
||||
(use_scientific_notation ?
|
||||
max(0, (int)field_length-5) :
|
||||
field_length),
|
||||
nr));
|
||||
/*
|
||||
+1 below is because "precision" in %g above means the
|
||||
max. number of significant digits, not the output width.
|
||||
|
@ -4310,6 +4300,7 @@ int Field_str::store(double nr)
|
|||
return store((const char *)buff, min(length, field_length), charset());
|
||||
}
|
||||
|
||||
|
||||
int Field_string::store(longlong nr)
|
||||
{
|
||||
char buff[64];
|
||||
|
@ -4403,9 +4394,8 @@ char *Field_string::pack(char *to, const char *from, uint max_length)
|
|||
|
||||
char *Field_string::pack_key(char *to, const char *from, uint max_length)
|
||||
{
|
||||
int length=min(field_length,max_length);
|
||||
uint char_length= (field_charset->mbmaxlen > 1) ?
|
||||
max_length/field_charset->mbmaxlen : max_length;
|
||||
uint length= min(field_length,max_length);
|
||||
uint char_length= max_length/field_charset->mbmaxlen;
|
||||
if (length > char_length)
|
||||
char_length= my_charpos(field_charset, from, from+length, char_length);
|
||||
set_if_smaller(length, char_length);
|
||||
|
|
|
@ -336,14 +336,13 @@ public:
|
|||
class Field_str :public Field {
|
||||
protected:
|
||||
CHARSET_INFO *field_charset;
|
||||
double ceiling; // for ::store(double nr)
|
||||
public:
|
||||
Field_str(char *ptr_arg,uint32 len_arg, uchar *null_ptr_arg,
|
||||
uchar null_bit_arg, utype unireg_check_arg,
|
||||
const char *field_name_arg,
|
||||
struct st_table *table_arg,CHARSET_INFO *charset)
|
||||
:Field(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
|
||||
unireg_check_arg, field_name_arg, table_arg), ceiling(0.0)
|
||||
unireg_check_arg, field_name_arg, table_arg)
|
||||
{
|
||||
field_charset=charset;
|
||||
if (charset->state & MY_CS_BINSORT)
|
||||
|
|
|
@ -1732,8 +1732,8 @@ bool Item_func_in::nulls_in_row()
|
|||
static int srtcmp_in(CHARSET_INFO *cs, const String *x,const String *y)
|
||||
{
|
||||
return cs->coll->strnncollsp(cs,
|
||||
(unsigned char *) x->ptr(),x->length(),
|
||||
(unsigned char *) y->ptr(),y->length());
|
||||
(uchar *) x->ptr(),x->length(),
|
||||
(uchar *) y->ptr(),y->length());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -39,7 +39,8 @@ C_MODE_END
|
|||
|
||||
String my_empty_string("",default_charset_info);
|
||||
|
||||
static void my_coll_agg_error(DTCollation &c1, DTCollation &c2, const char *fname)
|
||||
static void my_coll_agg_error(DTCollation &c1, DTCollation &c2,
|
||||
const char *fname)
|
||||
{
|
||||
my_error(ER_CANT_AGGREGATE_2COLLATIONS,MYF(0),
|
||||
c1.collation->name,c1.derivation_name(),
|
||||
|
@ -62,8 +63,9 @@ double Item_str_func::val()
|
|||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
int err;
|
||||
String *res;
|
||||
res=val_str(&str_value);
|
||||
char buff[64];
|
||||
String *res, tmp(buff,sizeof(buff), &my_charset_bin);
|
||||
res= val_str(&tmp);
|
||||
return res ? my_strntod(res->charset(), (char*) res->ptr(),res->length(),
|
||||
NULL, &err) : 0.0;
|
||||
}
|
||||
|
@ -72,8 +74,9 @@ longlong Item_str_func::val_int()
|
|||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
int err;
|
||||
String *res;
|
||||
res=val_str(&str_value);
|
||||
char buff[22];
|
||||
String *res, tmp(buff,sizeof(buff), &my_charset_bin);
|
||||
res= val_str(&tmp);
|
||||
return (res ?
|
||||
my_strntoll(res->charset(), res->ptr(), res->length(), 10, NULL,
|
||||
&err) :
|
||||
|
@ -986,10 +989,7 @@ String *Item_func_left::val_str(String *str)
|
|||
if (res->length() <= (uint) length ||
|
||||
res->length() <= (char_pos= res->charpos(length)))
|
||||
return res;
|
||||
if (&str_value == res)
|
||||
str_value.length(char_pos);
|
||||
else
|
||||
str_value.set(*res, 0, char_pos);
|
||||
str_value.set(*res, 0, char_pos);
|
||||
return &str_value;
|
||||
}
|
||||
|
||||
|
@ -2200,7 +2200,8 @@ String *Item_func_conv_charset::val_str(String *str)
|
|||
null_value=1;
|
||||
return 0;
|
||||
}
|
||||
null_value= str_value.copy(arg->ptr(),arg->length(),arg->charset(),conv_charset);
|
||||
null_value= str_value.copy(arg->ptr(),arg->length(),arg->charset(),
|
||||
conv_charset);
|
||||
return null_value ? 0 : &str_value;
|
||||
}
|
||||
|
||||
|
|
|
@ -1945,13 +1945,12 @@ void Item_func_group_concat::reset_field()
|
|||
bool
|
||||
Item_func_group_concat::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
||||
{
|
||||
uint i; /* for loop variable */
|
||||
DBUG_ASSERT(fixed == 0);
|
||||
|
||||
if (save_args_for_prepared_statement(thd))
|
||||
return 1;
|
||||
|
||||
uint i; /* for loop variable */
|
||||
|
||||
if (!thd->allow_sum_func)
|
||||
{
|
||||
my_error(ER_INVALID_GROUP_FUNC_USE,MYF(0));
|
||||
|
@ -1971,7 +1970,7 @@ Item_func_group_concat::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
|
|||
if (args[i]->fix_fields(thd, tables, args + i) || args[i]->check_cols(1))
|
||||
return 1;
|
||||
if (i < arg_count_field)
|
||||
maybe_null |= args[i]->maybe_null;
|
||||
maybe_null|= args[i]->maybe_null;
|
||||
}
|
||||
|
||||
result_field= 0;
|
||||
|
@ -2048,7 +2047,8 @@ bool Item_func_group_concat::setup(THD *thd)
|
|||
of a record instead of a pointer of one.
|
||||
*/
|
||||
if (!(table=create_tmp_table(thd, tmp_table_param, all_fields,
|
||||
(ORDER*) 0, 0, TRUE,select_lex->options | thd->options,
|
||||
(ORDER*) 0, 0, TRUE,
|
||||
select_lex->options | thd->options,
|
||||
HA_POS_ERROR,(char *) "")))
|
||||
DBUG_RETURN(1);
|
||||
table->file->extra(HA_EXTRA_NO_ROWS);
|
||||
|
|
|
@ -200,7 +200,7 @@ net_printf(THD *thd, uint errcode, ...)
|
|||
2+SQLSTATE_LENGTH+1 : 2) : 0);
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
text_pos=(char*) net->buff + head_length + offset + 1;
|
||||
length=(char*)net->buff_end-text_pos;
|
||||
length= (uint) ((char*)net->buff_end - text_pos);
|
||||
#else
|
||||
length=sizeof(text_pos)-1;
|
||||
#endif
|
||||
|
|
|
@ -551,21 +551,19 @@ static ulong get_sort(uint count,...)
|
|||
uint chars= 0;
|
||||
uint wild_pos= 0; /* first wildcard position */
|
||||
|
||||
if (start= str)
|
||||
if ((start= str))
|
||||
{
|
||||
for (; *str ; str++)
|
||||
{
|
||||
if (*str == wild_many || *str == wild_one || *str == wild_prefix)
|
||||
{
|
||||
wild_pos= str - start + 1;
|
||||
wild_pos= (uint) (str - start) + 1;
|
||||
break;
|
||||
}
|
||||
else
|
||||
chars++;
|
||||
chars= 128; // Marker that chars existed
|
||||
}
|
||||
}
|
||||
sort= (sort << 8) + (wild_pos ? (wild_pos > 127 ? 127 : wild_pos) :
|
||||
(chars ? 128 : 0));
|
||||
sort= (sort << 8) + (wild_pos ? min(wild_pos, 127) : chars);
|
||||
}
|
||||
va_end(args);
|
||||
return sort;
|
||||
|
|
|
@ -833,7 +833,8 @@ JOIN::optimize()
|
|||
((group_list && const_tables != tables &&
|
||||
(!simple_group ||
|
||||
!test_if_skip_sort_order(&join_tab[const_tables], group_list,
|
||||
unit->select_limit_cnt, 0))) || select_distinct) &&
|
||||
unit->select_limit_cnt, 0))) ||
|
||||
select_distinct) &&
|
||||
tmp_table_param.quick_group && !procedure)
|
||||
{
|
||||
need_tmp=1; simple_order=simple_group=0; // Force tmp table without sort
|
||||
|
@ -2163,22 +2164,32 @@ add_key_field(KEY_FIELD **key_fields,uint and_level, COND *cond,
|
|||
number. cmp_type() is checked to allow compare of dates to numbers.
|
||||
eq_func is NEVER true when num_values > 1
|
||||
*/
|
||||
if (!eq_func ||
|
||||
field->result_type() == STRING_RESULT &&
|
||||
(*value)->result_type() != STRING_RESULT &&
|
||||
field->cmp_type() != (*value)->result_type())
|
||||
return;
|
||||
|
||||
/*
|
||||
We can't use indexes if the effective collation
|
||||
of the operation differ from the field collation.
|
||||
*/
|
||||
if (field->result_type() == STRING_RESULT &&
|
||||
(*value)->result_type() == STRING_RESULT &&
|
||||
field->cmp_type() == STRING_RESULT &&
|
||||
((Field_str*)field)->charset() != cond->compare_collation())
|
||||
return;
|
||||
if (!eq_func)
|
||||
return;
|
||||
if (field->result_type() == STRING_RESULT)
|
||||
{
|
||||
if ((*value)->result_type() != STRING_RESULT)
|
||||
{
|
||||
if (field->cmp_type() != (*value)->result_type())
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
We can't use indexes if the effective collation
|
||||
of the operation differ from the field collation.
|
||||
|
||||
We can also not used index on a text column, as the column may
|
||||
contain 'x' 'x\t' 'x ' and 'read_next_same' will stop after
|
||||
'x' when searching for WHERE col='x '
|
||||
*/
|
||||
if (field->cmp_type() == STRING_RESULT &&
|
||||
(((Field_str*)field)->charset() != cond->compare_collation() ||
|
||||
((*value)->type() != Item::NULL_ITEM &&
|
||||
(field->flags & BLOB_FLAG) && !field->binary())))
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
DBUG_ASSERT(num_values == 1);
|
||||
|
@ -5564,9 +5575,7 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
|
|||
table->file->info(HA_STATUS_VARIABLE); /* update table->file->records */
|
||||
new_table.file->start_bulk_insert(table->file->records);
|
||||
#else
|
||||
/*
|
||||
HA_EXTRA_WRITE_CACHE can stay until close, no need to disable it explicitly.
|
||||
*/
|
||||
/* HA_EXTRA_WRITE_CACHE can stay until close, no need to disable it */
|
||||
new_table.file->extra(HA_EXTRA_WRITE_CACHE);
|
||||
#endif
|
||||
|
||||
|
@ -7234,9 +7243,9 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
|
|||
keys.merge(table->used_keys);
|
||||
|
||||
/*
|
||||
We are adding here also the index speified in FORCE INDEX clause,
|
||||
We are adding here also the index specified in FORCE INDEX clause,
|
||||
if any.
|
||||
This is to allow users to use index in ORDER BY.
|
||||
This is to allow users to use index in ORDER BY.
|
||||
*/
|
||||
if (table->force_index)
|
||||
keys.merge(table->keys_in_use_for_query);
|
||||
|
|
|
@ -2158,20 +2158,21 @@ my_tz_find(const String * name, TABLE_LIST *tz_tables)
|
|||
if (!(result_tz= new (&tz_storage) Time_zone_offset(offset)) ||
|
||||
my_hash_insert(&offset_tzs, (const byte *) result_tz))
|
||||
{
|
||||
result_tz= 0;
|
||||
sql_print_error("Fatal error: Out of memory "
|
||||
"while setting new time zone");
|
||||
result_tz= 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
result_tz= 0;
|
||||
if ((tmp_tzname= (TZ_NAMES_ENTRY *)hash_search(&tz_names,
|
||||
(const byte *)name->ptr(),
|
||||
name->length())))
|
||||
result_tz= tmp_tzname->tz;
|
||||
else if(time_zone_tables_exist)
|
||||
else if (time_zone_tables_exist)
|
||||
result_tz= tz_load_from_open_tables(name, tz_tables);
|
||||
else
|
||||
result_tz= 0;
|
||||
}
|
||||
|
||||
VOID(pthread_mutex_unlock(&tz_LOCK));
|
||||
|
|
|
@ -93,7 +93,7 @@ static int my_strnncoll_binary(CHARSET_INFO * cs __attribute__((unused)),
|
|||
NOTE
|
||||
This function is used for real binary strings, i.e. for
|
||||
BLOB, BINARY(N) and VARBINARY(N).
|
||||
It does not ignore trailing spaces.
|
||||
It compares trailing spaces as spaces.
|
||||
|
||||
RETURN
|
||||
< 0 s < t
|
||||
|
@ -133,7 +133,8 @@ static int my_strnncoll_8bit_bin(CHARSET_INFO * cs __attribute__((unused)),
|
|||
|
||||
NOTE
|
||||
This function is used for character strings with binary collations.
|
||||
It ignores trailing spaces.
|
||||
The shorter string is extended with end space to be as long as the longer
|
||||
one.
|
||||
|
||||
RETURN
|
||||
< 0 s < t
|
||||
|
|
|
@ -237,7 +237,8 @@ int my_wildcmp_mb(CHARSET_INFO *cs,
|
|||
if (str++ == str_end) return (-1);
|
||||
}
|
||||
{
|
||||
int tmp=my_wildcmp_mb(cs,str,str_end,wildstr,wildend,escape,w_one,w_many);
|
||||
int tmp=my_wildcmp_mb(cs,str,str_end,wildstr,wildend,escape,w_one,
|
||||
w_many);
|
||||
if (tmp <= 0)
|
||||
return (tmp);
|
||||
}
|
||||
|
@ -248,41 +249,46 @@ int my_wildcmp_mb(CHARSET_INFO *cs,
|
|||
return (str != str_end ? 1 : 0);
|
||||
}
|
||||
|
||||
|
||||
uint my_numchars_mb(CHARSET_INFO *cs __attribute__((unused)),
|
||||
const char *b, const char *e)
|
||||
const char *pos, const char *end)
|
||||
{
|
||||
register uint32 n=0,mblen;
|
||||
while (b < e)
|
||||
register uint32 count=0;
|
||||
while (pos < end)
|
||||
{
|
||||
b+= (mblen= my_ismbchar(cs,b,e)) ? mblen : 1;
|
||||
++n;
|
||||
uint mblen;
|
||||
pos+= (mblen= my_ismbchar(cs,pos,end)) ? mblen : 1;
|
||||
count++;
|
||||
}
|
||||
return n;
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
uint my_charpos_mb(CHARSET_INFO *cs __attribute__((unused)),
|
||||
const char *b, const char *e, uint pos)
|
||||
const char *pos, const char *end, uint length)
|
||||
{
|
||||
uint mblen;
|
||||
const char *b0=b;
|
||||
const char *start= pos;
|
||||
|
||||
while (pos && b<e)
|
||||
while (length && pos < end)
|
||||
{
|
||||
b+= (mblen= my_ismbchar(cs,b,e)) ? mblen : 1;
|
||||
pos--;
|
||||
uint mblen;
|
||||
pos+= (mblen= my_ismbchar(cs, pos, end)) ? mblen : 1;
|
||||
length--;
|
||||
}
|
||||
return pos ? e+2-b0 : b-b0;
|
||||
return length ? end+2-start : pos-start;
|
||||
}
|
||||
|
||||
|
||||
uint my_well_formed_len_mb(CHARSET_INFO *cs,
|
||||
const char *b, const char *e, uint pos)
|
||||
{
|
||||
my_wc_t wc;
|
||||
int mblen;
|
||||
const char *b_start= b;
|
||||
|
||||
while (pos)
|
||||
{
|
||||
my_wc_t wc;
|
||||
int mblen;
|
||||
|
||||
if ((mblen= cs->cset->mb_wc(cs, &wc, (uchar*) b, (uchar*) e)) <0)
|
||||
break;
|
||||
b+= mblen;
|
||||
|
@ -374,7 +380,8 @@ static int my_strnncoll_mb_bin(CHARSET_INFO * cs __attribute__((unused)),
|
|||
|
||||
NOTE
|
||||
This function is used for character strings with binary collations.
|
||||
It ignores trailing spaces.
|
||||
The shorter string is extended with end space to be as long as the longer
|
||||
one.
|
||||
|
||||
RETURN
|
||||
A negative number if s < t
|
||||
|
|
Loading…
Reference in a new issue