diff options
-rw-r--r-- | client/mysqldump.c | 5 | ||||
-rw-r--r-- | heap/hp_rkey.c | 4 | ||||
-rw-r--r-- | myisam/ft_update.c | 66 | ||||
-rw-r--r-- | myisam/mi_delete.c | 15 | ||||
-rw-r--r-- | myisam/mi_page.c | 15 | ||||
-rw-r--r-- | mysql-test/r/func_str.result | 34 | ||||
-rw-r--r-- | mysql-test/r/func_test.result | 57 | ||||
-rw-r--r-- | mysql-test/r/grant.result | 4 | ||||
-rw-r--r-- | mysql-test/r/heap_btree.result | 4 | ||||
-rw-r--r-- | mysql-test/r/isam.result | 16 | ||||
-rw-r--r-- | mysql-test/r/replace.result | 4 | ||||
-rw-r--r-- | mysql-test/r/type_blob.result | 11 | ||||
-rw-r--r-- | mysql-test/t/func_str.test | 15 | ||||
-rw-r--r-- | mysql-test/t/func_test.test | 35 | ||||
-rw-r--r-- | mysql-test/t/heap_btree.test | 4 | ||||
-rw-r--r-- | mysql-test/t/type_blob.test | 7 | ||||
-rw-r--r-- | sql/item_cmpfunc.h | 7 | ||||
-rw-r--r-- | sql/item_strfunc.cc | 13 | ||||
-rw-r--r-- | sql/item_strfunc.h | 10 |
19 files changed, 266 insertions, 60 deletions
diff --git a/client/mysqldump.c b/client/mysqldump.c index 18705b9e375..67e83d58768 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -34,6 +34,7 @@ ** XML by Gary Huntress <ghuntress@mediaone.net> 10/10/01, cleaned up ** and adapted to mysqldump 05/11/01 by Jani Tolonen ** Added --single-transaction option 06/06/2002 by Peter Zaitsev +** 10 Jun 2003: SET NAMES and --no-set-names by Alexander Barkov */ #define DUMP_VERSION "10.2" @@ -434,6 +435,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), char buff[255]; opt_quoted= 1; + opt_set_names= 1; opt_compatible_mode_str= argument; opt_compatible_mode= find_set(&compatible_mode_typelib, argument, strlen(argument), @@ -563,7 +565,8 @@ static int dbConnect(char *host, char *user,char *passwd) if (shared_memory_base_name) mysql_options(&mysql_connection,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name); #endif - mysql_options(&mysql_connection, MYSQL_SET_CHARSET_NAME, default_charset); + if (!opt_set_names) + mysql_options(&mysql_connection, MYSQL_SET_CHARSET_NAME, default_charset); if (!(sock= mysql_real_connect(&mysql_connection,host,user,passwd, NULL,opt_mysql_port,opt_mysql_unix_port, 0))) diff --git a/heap/hp_rkey.c b/heap/hp_rkey.c index 91d762ab4db..2c23d9d721e 100644 --- a/heap/hp_rkey.c +++ b/heap/hp_rkey.c @@ -38,7 +38,7 @@ int heap_rkey(HP_INFO *info, byte *record, int inx, const byte *key, custom_arg.keyseg= info->s->keydef[inx].seg; custom_arg.key_length= info->lastkey_len= - hp_rb_pack_key(keyinfo, (uchar*) info->recbuf, + hp_rb_pack_key(keyinfo, (uchar*) info->lastkey, (uchar*) key, key_len); custom_arg.search_flag= SEARCH_FIND | SEARCH_SAME; /* for next rkey() after deletion */ @@ -48,7 +48,7 @@ int heap_rkey(HP_INFO *info, byte *record, int inx, const byte *key, info->last_find_flag= HA_READ_KEY_OR_PREV; else info->last_find_flag= find_flag; - if (!(pos= tree_search_key(&keyinfo->rb_tree, info->recbuf, info->parents, + if (!(pos= tree_search_key(&keyinfo->rb_tree, info->lastkey, info->parents, &info->last_pos, find_flag, &custom_arg))) { info->update= 0; diff --git a/myisam/ft_update.c b/myisam/ft_update.c index 4b6d1c4bffc..365fe0d98e3 100644 --- a/myisam/ft_update.c +++ b/myisam/ft_update.c @@ -31,18 +31,24 @@ void _mi_ft_segiterator_init(MI_INFO *info, uint keynr, const byte *record, FT_SEG_ITERATOR *ftsi) { + DBUG_ENTER("_mi_ft_segiterator_init"); + ftsi->num=info->s->keyinfo[keynr].keysegs; ftsi->seg=info->s->keyinfo[keynr].seg; ftsi->rec=record; + DBUG_VOID_RETURN; } void _mi_ft_segiterator_dummy_init(const byte *record, uint len, FT_SEG_ITERATOR *ftsi) { + DBUG_ENTER("_mi_ft_segiterator_dummy_init"); + ftsi->num=1; ftsi->seg=0; ftsi->pos=record; ftsi->len=len; + DBUG_VOID_RETURN; } /* @@ -56,14 +62,16 @@ void _mi_ft_segiterator_dummy_init(const byte *record, uint len, uint _mi_ft_segiterator(register FT_SEG_ITERATOR *ftsi) { - if (!ftsi->num) return 0; else ftsi->num--; - if (!ftsi->seg) return 1; else ftsi->seg--; + DBUG_ENTER("_mi_ft_segiterator"); + + if (!ftsi->num) DBUG_RETURN(0) else ftsi->num--; + if (!ftsi->seg) DBUG_RETURN(1) else ftsi->seg--; if (ftsi->seg->null_bit && (ftsi->rec[ftsi->seg->null_pos] & ftsi->seg->null_bit)) { ftsi->pos=0; - return 1; + DBUG_RETURN(1); } ftsi->pos= ftsi->rec+ftsi->seg->start; if (ftsi->seg->flag & HA_VAR_LENGTH) @@ -71,7 +79,7 @@ uint _mi_ft_segiterator(register FT_SEG_ITERATOR *ftsi) ftsi->len=uint2korr(ftsi->pos); ftsi->pos+=2; /* Skip VARCHAR length */ set_if_smaller(ftsi->len,ftsi->seg->length); - return 1; + DBUG_RETURN(1); } if (ftsi->seg->flag & HA_BLOB_PART) { @@ -79,10 +87,10 @@ uint _mi_ft_segiterator(register FT_SEG_ITERATOR *ftsi) memcpy_fixed((char*) &ftsi->pos, ftsi->pos+ftsi->seg->bit_start, sizeof(char*)); set_if_smaller(ftsi->len,ftsi->seg->length); - return 1; + DBUG_RETURN(1); } ftsi->len=ftsi->seg->length; - return 1; + DBUG_RETURN(1); } @@ -91,6 +99,8 @@ uint _mi_ft_segiterator(register FT_SEG_ITERATOR *ftsi) uint _mi_ft_parse(TREE *parsed, MI_INFO *info, uint keynr, const byte *record) { FT_SEG_ITERATOR ftsi; + DBUG_ENTER("_mi_ft_parse"); + _mi_ft_segiterator_init(info, keynr, record, &ftsi); ft_parse_init(parsed, info->s->keyinfo[keynr].seg->charset); @@ -98,9 +108,9 @@ uint _mi_ft_parse(TREE *parsed, MI_INFO *info, uint keynr, const byte *record) { if (ftsi.pos) if (ft_parse(parsed, (byte *)ftsi.pos, ftsi.len)) - return 1; + DBUG_RETURN(1); } - return 0; + DBUG_RETURN(0); } FT_WORD * _mi_ft_parserecord(MI_INFO *info, uint keynr, @@ -108,32 +118,35 @@ FT_WORD * _mi_ft_parserecord(MI_INFO *info, uint keynr, const byte *record) { TREE ptree; + DBUG_ENTER("_mi_ft_parserecord"); bzero((char*) &ptree, sizeof(ptree)); if (_mi_ft_parse(&ptree, info, keynr, record)) - return NULL; + DBUG_RETURN(NULL); - return ft_linearize(&ptree); + DBUG_RETURN(ft_linearize(&ptree)); } static int _mi_ft_store(MI_INFO *info, uint keynr, byte *keybuf, FT_WORD *wlist, my_off_t filepos) { uint key_length; + DBUG_ENTER("_mi_ft_store"); for (; wlist->pos; wlist++) { key_length=_ft_make_key(info,keynr,keybuf,wlist,filepos); if (_mi_ck_write(info,keynr,(uchar*) keybuf,key_length)) - return 1; + DBUG_RETURN(1); } - return 0; + DBUG_RETURN(0); } static int _mi_ft_erase(MI_INFO *info, uint keynr, byte *keybuf, FT_WORD *wlist, my_off_t filepos) { uint key_length, err=0; + DBUG_ENTER("_mi_ft_erase"); for (; wlist->pos; wlist++) { @@ -141,7 +154,7 @@ static int _mi_ft_erase(MI_INFO *info, uint keynr, byte *keybuf, if (_mi_ck_delete(info,keynr,(uchar*) keybuf,key_length)) err=1; } - return err; + DBUG_RETURN(err); } /* @@ -156,6 +169,8 @@ int _mi_ft_cmp(MI_INFO *info, uint keynr, const byte *rec1, const byte *rec2) { FT_SEG_ITERATOR ftsi1, ftsi2; CHARSET_INFO *cs=info->s->keyinfo[keynr].seg->charset; + DBUG_ENTER("_mi_ft_cmp"); + _mi_ft_segiterator_init(info, keynr, rec1, &ftsi1); _mi_ft_segiterator_init(info, keynr, rec2, &ftsi2); @@ -165,9 +180,9 @@ int _mi_ft_cmp(MI_INFO *info, uint keynr, const byte *rec1, const byte *rec2) (!ftsi1.pos || !ftsi2.pos || mi_compare_text(cs, (uchar*) ftsi1.pos,ftsi1.len, (uchar*) ftsi2.pos,ftsi2.len,0))) - return THOSE_TWO_DAMN_KEYS_ARE_REALLY_DIFFERENT; + DBUG_RETURN(THOSE_TWO_DAMN_KEYS_ARE_REALLY_DIFFERENT); } - return GEE_THEY_ARE_ABSOLUTELY_IDENTICAL; + DBUG_RETURN(GEE_THEY_ARE_ABSOLUTELY_IDENTICAL); } @@ -181,6 +196,7 @@ int _mi_ft_update(MI_INFO *info, uint keynr, byte *keybuf, CHARSET_INFO *cs=info->s->keyinfo[keynr].seg->charset; uint key_length; int cmp, cmp2; + DBUG_ENTER("_mi_ft_update"); if (!(old_word=oldlist=_mi_ft_parserecord(info, keynr, keybuf, oldrec))) goto err0; @@ -219,7 +235,7 @@ err2: err1: my_free((char*) oldlist,MYF(0)); err0: - return error; + DBUG_RETURN(error); } @@ -230,13 +246,14 @@ int _mi_ft_add(MI_INFO *info, uint keynr, byte *keybuf, const byte *record, { int error= -1; FT_WORD *wlist; + DBUG_ENTER("_mi_ft_add"); if ((wlist=_mi_ft_parserecord(info, keynr, keybuf, record))) { error=_mi_ft_store(info,keynr,keybuf,wlist,pos); my_free((char*) wlist,MYF(0)); } - return error; + DBUG_RETURN(error); } @@ -247,27 +264,34 @@ int _mi_ft_del(MI_INFO *info, uint keynr, byte *keybuf, const byte *record, { int error= -1; FT_WORD *wlist; + DBUG_ENTER("_mi_ft_del"); + DBUG_PRINT("enter",("keynr: %d",keynr)); + if ((wlist=_mi_ft_parserecord(info, keynr, keybuf, record))) { error=_mi_ft_erase(info,keynr,keybuf,wlist,pos); my_free((char*) wlist,MYF(0)); } - return error; + DBUG_PRINT("exit",("Return: %d",error)); + DBUG_RETURN(error); } uint _ft_make_key(MI_INFO *info, uint keynr, byte *keybuf, FT_WORD *wptr, my_off_t filepos) { byte buf[HA_FT_MAXLEN+16]; + DBUG_ENTER("_ft_make_key"); #if HA_FT_WTYPE == HA_KEYTYPE_FLOAT - float weight=(float) ((filepos==HA_OFFSET_ERROR) ? 0 : wptr->weight); - mi_float4store(buf,weight); + { + float weight=(float) ((filepos==HA_OFFSET_ERROR) ? 0 : wptr->weight); + mi_float4store(buf,weight); + } #else #error #endif int2store(buf+HA_FT_WLEN,wptr->len); memcpy(buf+HA_FT_WLEN+2,wptr->pos,wptr->len); - return _mi_make_key(info,keynr,(uchar*) keybuf,buf,filepos); + DBUG_RETURN(_mi_make_key(info,keynr,(uchar*) keybuf,buf,filepos)); } diff --git a/myisam/mi_delete.c b/myisam/mi_delete.c index 36dd0d2d62c..97d2f531f6f 100644 --- a/myisam/mi_delete.c +++ b/myisam/mi_delete.c @@ -33,7 +33,7 @@ static int underflow(MI_INFO *info,MI_KEYDEF *keyinfo,uchar *anc_buff, static uint remove_key(MI_KEYDEF *keyinfo,uint nod_flag,uchar *keypos, uchar *lastkey,uchar *page_end, my_off_t *next_block); -static int _mi_ck_real_delete(register MI_INFO *info, MI_KEYDEF *keyinfo, +static int _mi_ck_real_delete(register MI_INFO *info,MI_KEYDEF *keyinfo, uchar *key, uint key_length, my_off_t *root); @@ -188,6 +188,7 @@ static int _mi_ck_real_delete(register MI_INFO *info, MI_KEYDEF *keyinfo, } err: my_afree((gptr) root_buff); + DBUG_PRINT("exit",("Return: %d",error)); DBUG_RETURN(error); } /* _mi_ck_real_delete */ @@ -234,6 +235,7 @@ static int d_search(register MI_INFO *info, register MI_KEYDEF *keyinfo, if (subkeys >= 0) { /* normal word, one-level tree structure */ + DBUG_PRINT("info",("FT1")); flag=(*keyinfo->bin_search)(info,keyinfo,anc_buff,key,USE_WHOLE_KEY, comp_flag, &keypos, lastkey, &last_key); /* fall through to normal delete */ @@ -250,11 +252,13 @@ static int d_search(register MI_INFO *info, register MI_KEYDEF *keyinfo, if (subkeys == -1) { /* the last entry in sub-tree */ + DBUG_PRINT("info",("FT2: the last entry")); _mi_dispose(info, keyinfo, root); /* fall through to normal delete */ } else { + DBUG_PRINT("info",("FT2: going down")); keyinfo=&info->s->ft2_keyinfo; kpos-=keyinfo->keylength; /* we'll modify key entry 'in vivo' */ key+=off; @@ -265,6 +269,7 @@ static int d_search(register MI_INFO *info, register MI_KEYDEF *keyinfo, ft_intXstore(kpos, subkeys); if (!ret_value) ret_value=_mi_write_keypage(info,keyinfo,page,anc_buff); + DBUG_PRINT("exit",("Return: %d",ret_value)); DBUG_RETURN(ret_value); } } @@ -279,6 +284,7 @@ static int d_search(register MI_INFO *info, register MI_KEYDEF *keyinfo, { DBUG_PRINT("error",("Couldn't allocate memory")); my_errno=ENOMEM; + DBUG_PRINT("exit",("Return: %d",-1)); DBUG_RETURN(-1); } if (!_mi_fetch_keypage(info,keyinfo,leaf_page,leaf_buff,0)) @@ -304,14 +310,20 @@ static int d_search(register MI_INFO *info, register MI_KEYDEF *keyinfo, tmp=remove_key(keyinfo,nod_flag,keypos,lastkey,anc_buff+length, &next_block); if (tmp == 0) + { + DBUG_PRINT("exit",("Return: %d",0)); DBUG_RETURN(0); + } length-= tmp; mi_putint(anc_buff,length,nod_flag); if (!nod_flag) { /* On leaf page */ if (_mi_write_keypage(info,keyinfo,page,anc_buff)) + { + DBUG_PRINT("exit",("Return: %d",-1)); DBUG_RETURN(-1); + } /* Page will be update later if we return 1 */ DBUG_RETURN(test(length <= (info->quick_mode ? MI_MIN_KEYBLOCK_LENGTH : (uint) keyinfo->underflow_block_length))); @@ -348,6 +360,7 @@ static int d_search(register MI_INFO *info, register MI_KEYDEF *keyinfo, DBUG_DUMP("page",(byte*) anc_buff,mi_getint(anc_buff)); } my_afree((byte*) leaf_buff); + DBUG_PRINT("exit",("Return: %d",ret_value)); DBUG_RETURN(ret_value); err: my_afree((byte*) leaf_buff); diff --git a/myisam/mi_page.c b/myisam/mi_page.c index 1d40980e309..49f3243e08d 100644 --- a/myisam/mi_page.c +++ b/myisam/mi_page.c @@ -28,6 +28,9 @@ uchar *_mi_fetch_keypage(register MI_INFO *info, MI_KEYDEF *keyinfo, { uchar *tmp; uint page_size; + DBUG_ENTER("_mi_fetch_keypage"); + DBUG_PRINT("enter",("page: %ld",page)); + tmp=(uchar*) key_cache_read(info->s->kfile,page,(byte*) buff, (uint) keyinfo->block_length, (uint) keyinfo->block_length, @@ -39,7 +42,7 @@ uchar *_mi_fetch_keypage(register MI_INFO *info, MI_KEYDEF *keyinfo, DBUG_PRINT("error",("Got errno: %d from key_cache_read",my_errno)); info->last_keypage=HA_OFFSET_ERROR; my_errno=HA_ERR_CRASHED; - return 0; + DBUG_RETURN(0); } info->last_keypage=page; page_size=mi_getint(tmp); @@ -51,7 +54,7 @@ uchar *_mi_fetch_keypage(register MI_INFO *info, MI_KEYDEF *keyinfo, my_errno = HA_ERR_CRASHED; tmp = 0; } - return tmp; + DBUG_RETURN(tmp); } /* _mi_fetch_keypage */ @@ -61,6 +64,8 @@ int _mi_write_keypage(register MI_INFO *info, register MI_KEYDEF *keyinfo, my_off_t page, uchar *buff) { reg3 uint length; + DBUG_ENTER("_mi_write_keypage"); + #ifndef FAST /* Safety check */ if (page < info->s->base.keystart || page+keyinfo->block_length > info->state->key_file_length || @@ -71,7 +76,7 @@ int _mi_write_keypage(register MI_INFO *info, register MI_KEYDEF *keyinfo, (long) info->state->key_file_length, (long) page)); my_errno=EINVAL; - return(-1); + DBUG_RETURN((-1)); } DBUG_PRINT("page",("write page at: %lu",(long) page,buff)); DBUG_DUMP("buff",(byte*) buff,mi_getint(buff)); @@ -87,10 +92,10 @@ int _mi_write_keypage(register MI_INFO *info, register MI_KEYDEF *keyinfo, length=keyinfo->block_length; } #endif - return (key_cache_write(info->s->kfile,page,(byte*) buff,length, + DBUG_RETURN((key_cache_write(info->s->kfile,page,(byte*) buff,length, (uint) keyinfo->block_length, (int) ((info->lock_type != F_UNLCK) || - info->s->delay_key_write))); + info->s->delay_key_write)))); } /* mi_write_keypage */ diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index c61563e6010..ffb7f2cd911 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -288,6 +288,24 @@ latin2_general_ci 3 select collation(trim(BOTH _latin2' ' FROM _latin2'a')), coercibility(trim(BOTH _latin2'a' FROM _latin2'a')); collation(trim(BOTH _latin2' ' FROM _latin2'a')) coercibility(trim(BOTH _latin2'a' FROM _latin2'a')) latin2_general_ci 3 +select collation(repeat(_latin2'a',10)), coercibility(repeat(_latin2'a',10)); +collation(repeat(_latin2'a',10)) coercibility(repeat(_latin2'a',10)) +latin2_general_ci 3 +select collation(reverse(_latin2'ab')), coercibility(reverse(_latin2'ab')); +collation(reverse(_latin2'ab')) coercibility(reverse(_latin2'ab')) +latin2_general_ci 3 +select collation(quote(_latin2'ab')), coercibility(quote(_latin2'ab')); +collation(quote(_latin2'ab')) coercibility(quote(_latin2'ab')) +latin2_general_ci 3 +select collation(soundex(_latin2'ab')), coercibility(soundex(_latin2'ab')); +collation(soundex(_latin2'ab')) coercibility(soundex(_latin2'ab')) +latin2_general_ci 3 +select collation(substring(_latin2'ab',1)), coercibility(substring(_latin2'ab',1)); +collation(substring(_latin2'ab',1)) coercibility(substring(_latin2'ab',1)) +latin2_general_ci 3 +select collation(insert(_latin2'abcd',2,3,_latin2'ef')), coercibility(insert(_latin2'abcd',2,3,_latin2'ef')); +collation(insert(_latin2'abcd',2,3,_latin2'ef')) coercibility(insert(_latin2'abcd',2,3,_latin2'ef')) +latin2_general_ci 3 create table t1 select left(_latin2'a',1), @@ -302,7 +320,13 @@ ltrim(_latin2' a '), rtrim(_latin2' a '), trim(LEADING _latin2' ' FROM _latin2' a '), trim(TRAILING _latin2' ' FROM _latin2' a '), -trim(BOTH _latin2' ' FROM _latin2' a ') +trim(BOTH _latin2' ' FROM _latin2' a '), +repeat(_latin2'a',10), +reverse(_latin2'ab'), +quote(_latin2'ab'), +soundex(_latin2'ab'), +substring(_latin2'ab',1), +insert(_latin2'abcd',2,3,_latin2'ef') ; show create table t1; Table Create Table @@ -319,6 +343,12 @@ t1 CREATE TABLE `t1` ( `rtrim(_latin2' a ')` char(3) character set latin2 NOT NULL default '', `trim(LEADING _latin2' ' FROM _latin2' a ')` char(3) character set latin2 NOT NULL default '', `trim(TRAILING _latin2' ' FROM _latin2' a ')` char(3) character set latin2 NOT NULL default '', - `trim(BOTH _latin2' ' FROM _latin2' a ')` char(3) character set latin2 NOT NULL default '' + `trim(BOTH _latin2' ' FROM _latin2' a ')` char(3) character set latin2 NOT NULL default '', + `repeat(_latin2'a',10)` char(10) character set latin2 NOT NULL default '', + `reverse(_latin2'ab')` char(2) character set latin2 NOT NULL default '', + `quote(_latin2'ab')` char(6) character set latin2 NOT NULL default '', + `soundex(_latin2'ab')` char(4) character set latin2 NOT NULL default '', + `substring(_latin2'ab',1)` char(2) character set latin2 NOT NULL default '', + `insert(_latin2'abcd',2,3,_latin2'ef')` char(6) character set latin2 NOT NULL default '' ) TYPE=MyISAM CHARSET=latin1 drop table t1; diff --git a/mysql-test/r/func_test.result b/mysql-test/r/func_test.result index d415b77692b..be0e3144fd6 100644 --- a/mysql-test/r/func_test.result +++ b/mysql-test/r/func_test.result @@ -52,6 +52,63 @@ select 10 % 7, 10 mod 7, 10 div 3; select (1 << 64)-1, ((1 << 64)-1) DIV 1, ((1 << 64)-1) DIV 2; (1 << 64)-1 ((1 << 64)-1) DIV 1 ((1 << 64)-1) DIV 2 18446744073709551615 18446744073709551615 9223372036854775807 +select _koi8r'a' = _koi8r'A'; +_koi8r'a' = _koi8r'A' +1 +select _koi8r'a' = _koi8r'A' COLLATE koi8r_general_ci; +_koi8r'a' = _koi8r'A' COLLATE koi8r_general_ci +1 +select _koi8r'a' = _koi8r'A' COLLATE koi8r_bin; +_koi8r'a' = _koi8r'A' COLLATE koi8r_bin +0 +select _koi8r'a' COLLATE koi8r_general_ci = _koi8r'A'; +_koi8r'a' COLLATE koi8r_general_ci = _koi8r'A' +1 +select _koi8r'a' COLLATE koi8r_bin = _koi8r'A'; +_koi8r'a' COLLATE koi8r_bin = _koi8r'A' +0 +select _koi8r'a' COLLATE koi8r_bin = _koi8r'A' COLLATE koi8r_general_ci; +ERROR HY000: Illegal mix of collations (koi8r_bin,EXPLICIT) and (koi8r_general_ci,EXPLICIT) for operation '=' +select _koi8r'a' = _latin1'A'; +ERROR HY000: Illegal mix of collations (koi8r_general_ci,COERCIBLE) and (latin1_swedish_ci,COERCIBLE) for operation '=' +select strcmp(_koi8r'a', _koi8r'A'); +strcmp(_koi8r'a', _koi8r'A') +0 +select strcmp(_koi8r'a', _koi8r'A' COLLATE koi8r_general_ci); +strcmp(_koi8r'a', _koi8r'A' COLLATE koi8r_general_ci) +0 +select strcmp(_koi8r'a', _koi8r'A' COLLATE koi8r_bin); +strcmp(_koi8r'a', _koi8r'A' COLLATE koi8r_bin) +1 +select strcmp(_koi8r'a' COLLATE koi8r_general_ci, _koi8r'A'); +strcmp(_koi8r'a' COLLATE koi8r_general_ci, _koi8r'A') +0 +select strcmp(_koi8r'a' COLLATE koi8r_bin, _koi8r'A'); +strcmp(_koi8r'a' COLLATE koi8r_bin, _koi8r'A') +1 +select strcmp(_koi8r'a' COLLATE koi8r_general_ci, _koi8r'A' COLLATE koi8r_bin); +ERROR HY000: Illegal mix of collations (koi8r_general_ci,EXPLICIT) and (koi8r_bin,EXPLICIT) for operation 'strcmp' +select strcmp(_koi8r'a', _latin1'A'); +ERROR HY000: Illegal mix of collations (koi8r_general_ci,COERCIBLE) and (latin1_swedish_ci,COERCIBLE) for operation 'strcmp' +select _koi8r'a' LIKE _koi8r'A'; +_koi8r'a' LIKE _koi8r'A' +1 +select _koi8r'a' LIKE _koi8r'A' COLLATE koi8r_general_ci; +_koi8r'a' LIKE _koi8r'A' COLLATE koi8r_general_ci +1 +select _koi8r'a' LIKE _koi8r'A' COLLATE koi8r_bin; +_koi8r'a' LIKE _koi8r'A' COLLATE koi8r_bin +0 +select _koi8r'a' COLLATE koi8r_general_ci LIKE _koi8r'A'; +_koi8r'a' COLLATE koi8r_general_ci LIKE _koi8r'A' +1 +select _koi8r'a' COLLATE koi8r_bin LIKE _koi8r'A'; +_koi8r'a' COLLATE koi8r_bin LIKE _koi8r'A' +0 +select _koi8r'a' COLLATE koi8r_general_ci LIKE _koi8r'A' COLLATE koi8r_bin; +ERROR HY000: Illegal mix of collations (koi8r_general_ci,EXPLICIT) and (koi8r_bin,EXPLICIT) for operation 'like' +select _koi8r'a' LIKE _latin1'A'; +ERROR HY000: Illegal mix of collations (koi8r_general_ci,COERCIBLE) and (latin1_swedish_ci,COERCIBLE) for operation 'like' select 5 between 0 and 10 between 0 and 1,(5 between 0 and 10) between 0 and 1; 5 between 0 and 10 between 0 and 1 (5 between 0 and 10) between 0 and 1 0 1 diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result index 715deac7965..6b33f6a7536 100644 --- a/mysql-test/r/grant.result +++ b/mysql-test/r/grant.result @@ -91,14 +91,14 @@ Grants for drop_user@localhost GRANT USAGE ON *.* TO 'drop_user'@'localhost' drop user drop_user@localhost; revoke all privileges, grant from drop_user@localhost; -Can't revoke all privileges, grant for one or more of the requested users +ERROR HY000: Can't revoke all privileges, grant for one or more of the requested users grant select(a) on test.t1 to drop_user1@localhost; grant select on test.t1 to drop_user2@localhost; grant select on test.* to drop_user3@localhost; grant select on *.* to drop_user4@localhost; drop user drop_user1@localhost, drop_user2@localhost, drop_user3@localhost, drop_user4@localhost; -Can't drop one or more of the requested users +ERROR HY000: Can't drop one or more of the requested users revoke all privileges, grant from drop_user1@localhost, drop_user2@localhost, drop_user3@localhost, drop_user4@localhost; drop user drop_user1@localhost, drop_user2@localhost, drop_user3@localhost, diff --git a/mysql-test/r/heap_btree.result b/mysql-test/r/heap_btree.result index 6ae00c89a3a..1ba8d429fc4 100644 --- a/mysql-test/r/heap_btree.result +++ b/mysql-test/r/heap_btree.result @@ -24,8 +24,8 @@ a b alter table t1 add c int not null, add key using BTREE (c,a); drop table t1; create table t1 (a int not null,b int not null, primary key using BTREE (a)) type=heap comment="testing heaps"; -insert into t1 values(1,1),(2,2),(3,3),(4,4); -delete from t1 where a > 0; +insert into t1 values(-2,-2),(-1,-1),(0,0),(1,1),(2,2),(3,3),(4,4); +delete from t1 where a > -3; select * from t1; a b drop table t1; diff --git a/mysql-test/r/isam.result b/mysql-test/r/isam.result index 5975ac8a8a0..5ac54668443 100644 --- a/mysql-test/r/isam.result +++ b/mysql-test/r/isam.result @@ -38,13 +38,13 @@ a b c 6 6 6 drop table t1; create table t1 (a int,b text, index(a)) type=isam; -Column 'a' is used with UNIQUE or INDEX but is not defined as NOT NULL +ERROR 42000: Column 'a' is used with UNIQUE or INDEX but is not defined as NOT NULL create table t1 (a int,b text, index(b)) type=isam; -BLOB column 'b' can't be used in key specification with the used table type +ERROR 42000: BLOB column 'b' can't be used in key specification with the used table type create table t1 (ordid int(8) not null auto_increment, ord varchar(50) not null, primary key (ord,ordid)) type=isam; -Incorrect table definition; There can only be one auto column and it must be defined as a key +ERROR 42000: Incorrect table definition; There can only be one auto column and it must be defined as a key create table t1 (ordid int(8), unique (ordid)) type=isam; -Column 'ordid' is used with UNIQUE or INDEX but is not defined as NOT NULL +ERROR 42000: Column 'ordid' is used with UNIQUE or INDEX but is not defined as NOT NULL drop table if exists t1; Warnings: Note 1051 Unknown table 't1' @@ -72,10 +72,10 @@ Table Op Msg_type Msg_text test.t2 check error Table 't2' was not locked with LOCK TABLES test.t1 check status OK show columns from t1; -Field Type Collation Null Key Default Extra -a int(11) NULL PRI 0 -b int(11) NULL MUL 0 -c int(11) NULL 0 +Field Type Null Key Default Extra +a int(11) PRI 0 +b int(11) MUL 0 +c int(11) 0 show full columns from t1; Field Type Collation Null Key Default Extra Privileges Comment a int(11) NULL PRI 0 select,insert,update,references diff --git a/mysql-test/r/replace.result b/mysql-test/r/replace.result index 4a71428b2f4..2d95343245b 100644 --- a/mysql-test/r/replace.result +++ b/mysql-test/r/replace.result @@ -15,9 +15,9 @@ drop table t1; create table t1 (a tinyint not null auto_increment primary key, b char(20) default "default_value"); insert into t1 values (126,"first"),(63, "middle"),(0,"last"); insert into t1 values (0,"error"); -Duplicate entry '127' for key 1 +ERROR 23000: Duplicate entry '127' for key 1 replace into t1 values (0,"error"); -Duplicate entry '127' for key 1 +ERROR 23000: Duplicate entry '127' for key 1 replace into t1 values (126,"first updated"); replace into t1 values (63,default); select * from t1; diff --git a/mysql-test/r/type_blob.result b/mysql-test/r/type_blob.result index c16c83e3c53..a537aeeca07 100644 --- a/mysql-test/r/type_blob.result +++ b/mysql-test/r/type_blob.result @@ -486,8 +486,19 @@ fish 10 drop table t1; create table t1 (id integer auto_increment unique,imagem LONGBLOB not null); insert into t1 (id) values (1); +select +charset(load_file('../../std_data/words.dat')), +collation(load_file('../../std_data/words.dat')), +coercibility(load_file('../../std_data/words.dat')); +charset(load_file('../../std_data/words.dat')) collation(load_file('../../std_data/words.dat')) coercibility(load_file('../../std_data/words.dat')) +binary binary 3 update t1 set imagem=load_file('../../std_data/words.dat') where id=1; select if(imagem is null, "ERROR", "OK"),length(imagem) from t1 where id = 1; if(imagem is null, "ERROR", "OK") length(imagem) OK 581 drop table t1; +create table t1 select load_file('../../std_data/words.dat'); +show full fields from t1; +Field Type Collation Null Key Default Extra Privileges Comment +load_file('../../std_data/words.dat') mediumblob NULL YES NULL select,insert,update,references +drop table t1; diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test index d99b54d88ff..93e35efa455 100644 --- a/mysql-test/t/func_str.test +++ b/mysql-test/t/func_str.test @@ -149,6 +149,13 @@ select collation(rtrim(_latin2' a ')), coercibility(rtrim(_latin2' a ')); select collation(trim(LEADING _latin2' ' FROM _latin2'a')), coercibility(trim(LEADING _latin2'a' FROM _latin2'a')); select collation(trim(TRAILING _latin2' ' FROM _latin2'a')), coercibility(trim(TRAILING _latin2'a' FROM _latin2'a')); select collation(trim(BOTH _latin2' ' FROM _latin2'a')), coercibility(trim(BOTH _latin2'a' FROM _latin2'a')); +select collation(repeat(_latin2'a',10)), coercibility(repeat(_latin2'a',10)); +select collation(reverse(_latin2'ab')), coercibility(reverse(_latin2'ab')); +select collation(quote(_latin2'ab')), coercibility(quote(_latin2'ab')); +select collation(soundex(_latin2'ab')), coercibility(soundex(_latin2'ab')); +select collation(substring(_latin2'ab',1)), coercibility(substring(_latin2'ab',1)); +select collation(insert(_latin2'abcd',2,3,_latin2'ef')), coercibility(insert(_latin2'abcd',2,3,_latin2'ef')); + create table t1 select left(_latin2'a',1), @@ -163,7 +170,13 @@ select rtrim(_latin2' a '), trim(LEADING _latin2' ' FROM _latin2' a '), trim(TRAILING _latin2' ' FROM _latin2' a '), - trim(BOTH _latin2' ' FROM _latin2' a ') + trim(BOTH _latin2' ' FROM _latin2' a '), + repeat(_latin2'a',10), + reverse(_latin2'ab'), + quote(_latin2'ab'), + soundex(_latin2'ab'), + substring(_latin2'ab',1), + insert(_latin2'abcd',2,3,_latin2'ef') ; show create table t1; diff --git a/mysql-test/t/func_test.test b/mysql-test/t/func_test.test index bdf58ee4b15..2834d5bd9c7 100644 --- a/mysql-test/t/func_test.test +++ b/mysql-test/t/func_test.test @@ -21,6 +21,41 @@ select 10 % 7, 10 mod 7, 10 div 3; select (1 << 64)-1, ((1 << 64)-1) DIV 1, ((1 << 64)-1) DIV 2; # +# Coercibility +# +select _koi8r'a' = _koi8r'A'; +select _koi8r'a' = _koi8r'A' COLLATE koi8r_general_ci; +select _koi8r'a' = _koi8r'A' COLLATE koi8r_bin; +select _koi8r'a' COLLATE koi8r_general_ci = _koi8r'A'; +select _koi8r'a' COLLATE koi8r_bin = _koi8r'A'; +--error 1265 +select _koi8r'a' COLLATE koi8r_bin = _koi8r'A' COLLATE koi8r_general_ci; +--error 1265 +select _koi8r'a' = _latin1'A'; + +select strcmp(_koi8r'a', _koi8r'A'); +select strcmp(_koi8r'a', _koi8r'A' COLLATE koi8r_general_ci); +select strcmp(_koi8r'a', _koi8r'A' COLLATE koi8r_bin); +select strcmp(_koi8r'a' COLLATE koi8r_general_ci, _koi8r'A'); +select strcmp(_koi8r'a' COLLATE koi8r_bin, _koi8r'A'); +--error 1265 +select strcmp(_koi8r'a' COLLATE koi8r_general_ci, _koi8r'A' COLLATE koi8r_bin); +--error 1265 +select strcmp(_koi8r'a', _latin1'A'); + +select _koi8r'a' LIKE _koi8r'A'; +select _koi8r'a' LIKE _koi8r'A' COLLATE koi8r_general_ci; +select _koi8r'a' LIKE _koi8r'A' COLLATE koi8r_bin; +select _koi8r'a' COLLATE koi8r_general_ci LIKE _koi8r'A'; +select _koi8r'a' COLLATE koi8r_bin LIKE _koi8r'A'; +--error 1265 +select _koi8r'a' COLLATE koi8r_general_ci LIKE _koi8r'A' COLLATE koi8r_bin; +--error 1265 +select _koi8r'a' LIKE _latin1'A'; + + + +# # Wrong usage of functions # diff --git a/mysql-test/t/heap_btree.test b/mysql-test/t/heap_btree.test index 3c2ff249415..80a7753d4b1 100644 --- a/mysql-test/t/heap_btree.test +++ b/mysql-test/t/heap_btree.test @@ -21,8 +21,8 @@ alter table t1 add c int not null, add key using BTREE (c,a); drop table t1; create table t1 (a int not null,b int not null, primary key using BTREE (a)) type=heap comment="testing heaps"; -insert into t1 values(1,1),(2,2),(3,3),(4,4); -delete from t1 where a > 0; +insert into t1 values(-2,-2),(-1,-1),(0,0),(1,1),(2,2),(3,3),(4,4); +delete from t1 where a > -3; select * from t1; drop table t1; diff --git a/mysql-test/t/type_blob.test b/mysql-test/t/type_blob.test index 9c00abe980b..ebe342a4ef5 100644 --- a/mysql-test/t/type_blob.test +++ b/mysql-test/t/type_blob.test @@ -294,6 +294,13 @@ drop table t1; create table t1 (id integer auto_increment unique,imagem LONGBLOB not null); insert into t1 (id) values (1); +select + charset(load_file('../../std_data/words.dat')), + collation(load_file('../../std_data/words.dat')), + coercibility(load_file('../../std_data/words.dat')); update t1 set imagem=load_file('../../std_data/words.dat') where id=1; select if(imagem is null, "ERROR", "OK"),length(imagem) from t1 where id = 1; drop table t1; +create table t1 select load_file('../../std_data/words.dat'); +show full fields from t1; +drop table t1; diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 4438b902011..549839b4f96 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -263,13 +263,6 @@ class Item_func_strcmp :public Item_bool_func2 public: Item_func_strcmp(Item *a,Item *b) :Item_bool_func2(a,b) {} longlong val_int(); - void fix_length_and_dec() - { - max_length=2; - /* QQ: COERCIBILITY */ - cmp_charset= args[0]->binary() || args[1]->binary() ? - &my_charset_bin : args[0]->charset(); - } optimize_type select_optimize() const { return OPTIMIZE_NONE; } const char *func_name() const { return "strcmp"; } }; diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index e5b73e7670f..d660f7c472c 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -702,6 +702,7 @@ String *Item_func_reverse::val_str(String *str) void Item_func_reverse::fix_length_and_dec() { + set_charset(args[0]->charset(),args[0]->coercibility); max_length = args[0]->max_length; } @@ -860,6 +861,14 @@ null: void Item_func_insert::fix_length_and_dec() { + if (set_charset(args[0]->charset(), args[0]->coercibility, + args[3]->charset(), args[3]->coercibility)) + { + my_error(ER_CANT_AGGREGATE_COLLATIONS,MYF(0), + args[0]->charset()->name,coercion_name(args[0]->coercibility), + args[3]->charset()->name,coercion_name(args[3]->coercibility), + func_name()); + } max_length=args[0]->max_length+args[3]->max_length; if (max_length > MAX_BLOB_WIDTH) { @@ -1521,6 +1530,7 @@ String *Item_func_user::val_str(String *str) void Item_func_soundex::fix_length_and_dec() { + set_charset(args[0]->charset(), args[0]->coercibility); max_length=args[0]->max_length; set_if_bigger(max_length,4); } @@ -1552,7 +1562,7 @@ String *Item_func_soundex::val_str(String *str) { String *res =args[0]->val_str(str); char last_ch,ch; - CHARSET_INFO *cs= &my_charset_latin1; + CHARSET_INFO *cs= charset(); if ((null_value=args[0]->null_value)) return 0; /* purecov: inspected */ @@ -2538,6 +2548,7 @@ String *Item_func_quote::val_str(String *str) } *to= '\''; str->length(new_length); + str->set_charset(charset()); return str; null: diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index a70c9b39255..26c69668b0a 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -536,8 +536,8 @@ public: const char *func_name() const { return "load_file"; } void fix_length_and_dec() { - set_charset(&my_charset_bin); - maybe_null=1; + set_charset(&my_charset_bin, COER_COERCIBLE); + maybe_null=1; max_length=MAX_BLOB_WIDTH; } }; @@ -571,7 +571,11 @@ public: Item_func_quote(Item *a) :Item_str_func(a) {} const char *func_name() const { return "quote"; } String *val_str(String *); - void fix_length_and_dec() { max_length= args[0]->max_length * 2 + 2; } + void fix_length_and_dec() + { + set_charset(args[0]->charset(), args[0]->coercibility); + max_length= args[0]->max_length * 2 + 2; + } }; class Item_func_conv_charset :public Item_str_func |