summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/mysqldump.c5
-rw-r--r--heap/hp_rkey.c4
-rw-r--r--myisam/ft_update.c66
-rw-r--r--myisam/mi_delete.c15
-rw-r--r--myisam/mi_page.c15
-rw-r--r--mysql-test/r/func_str.result34
-rw-r--r--mysql-test/r/func_test.result57
-rw-r--r--mysql-test/r/grant.result4
-rw-r--r--mysql-test/r/heap_btree.result4
-rw-r--r--mysql-test/r/isam.result16
-rw-r--r--mysql-test/r/replace.result4
-rw-r--r--mysql-test/r/type_blob.result11
-rw-r--r--mysql-test/t/func_str.test15
-rw-r--r--mysql-test/t/func_test.test35
-rw-r--r--mysql-test/t/heap_btree.test4
-rw-r--r--mysql-test/t/type_blob.test7
-rw-r--r--sql/item_cmpfunc.h7
-rw-r--r--sql/item_strfunc.cc13
-rw-r--r--sql/item_strfunc.h10
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