mirror of
https://github.com/MariaDB/server.git
synced 2025-01-17 20:42:30 +01:00
Now this syntax works too: CONVERT(string,charset_to,charset_from)
where charset_to and charset_from are expressions. For example: CONVERT('test','latin2','cp1250')
This commit is contained in:
parent
ae03ccc403
commit
648bd2788a
3 changed files with 87 additions and 0 deletions
|
@ -1843,6 +1843,79 @@ void Item_func_conv_charset::fix_length_and_dec()
|
|||
/* BAR TODO: What to do here??? */
|
||||
}
|
||||
|
||||
|
||||
String *Item_func_conv_charset3::val_str(String *str)
|
||||
{
|
||||
my_wc_t wc;
|
||||
int cnvres;
|
||||
const uchar *s, *se;
|
||||
uchar *d, *d0, *de;
|
||||
uint dmaxlen;
|
||||
String *arg= args[0]->val_str(str);
|
||||
String *to_cs= args[1]->val_str(str);
|
||||
String *from_cs= args[2]->val_str(str);
|
||||
CHARSET_INFO *from_charset;
|
||||
CHARSET_INFO *to_charset;
|
||||
|
||||
if (!arg || args[0]->null_value ||
|
||||
!to_cs || args[1]->null_value ||
|
||||
!from_cs || args[2]->null_value ||
|
||||
!(from_charset=find_compiled_charset_by_name(from_cs->ptr())) ||
|
||||
!(to_charset=find_compiled_charset_by_name(to_cs->ptr())))
|
||||
{
|
||||
null_value=1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
s=(const uchar*)arg->ptr();
|
||||
se=s+arg->length();
|
||||
|
||||
dmaxlen=arg->length()*(to_charset->mbmaxlen?to_charset->mbmaxlen:1)+1;
|
||||
str->alloc(dmaxlen);
|
||||
d0=d=(unsigned char*)str->ptr();
|
||||
de=d+dmaxlen;
|
||||
|
||||
while( s < se && d < de){
|
||||
|
||||
cnvres=from_charset->mb_wc(from_charset,&wc,s,se);
|
||||
if (cnvres>0)
|
||||
{
|
||||
s+=cnvres;
|
||||
}
|
||||
else if (cnvres==MY_CS_ILSEQ)
|
||||
{
|
||||
s++;
|
||||
wc='?';
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
||||
outp:
|
||||
cnvres=to_charset->wc_mb(to_charset,wc,d,de);
|
||||
if (cnvres>0)
|
||||
{
|
||||
d+=cnvres;
|
||||
}
|
||||
else if (cnvres==MY_CS_ILUNI && wc!='?')
|
||||
{
|
||||
wc='?';
|
||||
goto outp;
|
||||
}
|
||||
else
|
||||
break;
|
||||
};
|
||||
|
||||
str->length((uint) (d-d0));
|
||||
str->set_charset(to_charset);
|
||||
return str;
|
||||
}
|
||||
|
||||
void Item_func_conv_charset3::fix_length_and_dec()
|
||||
{
|
||||
/* BAR TODO: What to do here??? */
|
||||
}
|
||||
|
||||
|
||||
String *Item_func_hex::val_str(String *str)
|
||||
{
|
||||
if (args[0]->result_type() != STRING_RESULT)
|
||||
|
|
|
@ -489,6 +489,16 @@ public:
|
|||
const char *func_name() const { return "conv_charset"; }
|
||||
};
|
||||
|
||||
class Item_func_conv_charset3 :public Item_str_func
|
||||
{
|
||||
public:
|
||||
Item_func_conv_charset3(Item *arg1,Item *arg2,Item *arg3)
|
||||
:Item_str_func(arg1,arg2,arg3) {}
|
||||
String *val_str(String *);
|
||||
void fix_length_and_dec();
|
||||
const char *func_name() const { return "conv_charset3"; }
|
||||
};
|
||||
|
||||
|
||||
/*******************************************************
|
||||
Spatial functions
|
||||
|
|
|
@ -1664,6 +1664,10 @@ simple_expr:
|
|||
}
|
||||
$$= new Item_func_conv_charset($3,cs);
|
||||
}
|
||||
| CONVERT_SYM '(' expr ',' expr ',' expr ')'
|
||||
{
|
||||
$$= new Item_func_conv_charset3($3,$5,$7);
|
||||
}
|
||||
| FUNC_ARG0 '(' ')'
|
||||
{ $$= ((Item*(*)(void))($1.symbol->create_func))();}
|
||||
| FUNC_ARG1 '(' expr ')'
|
||||
|
|
Loading…
Reference in a new issue