Commit f29e7f57 authored by unknown's avatar unknown

Charset convertion operator CONVERT( string USING charset)

parent 4fd893e5
...@@ -1776,6 +1776,73 @@ String *Item_func_conv::val_str(String *str) ...@@ -1776,6 +1776,73 @@ String *Item_func_conv::val_str(String *str)
} }
String *Item_func_conv_charset::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);
CHARSET_INFO *from,*to;
if (!arg)
{
null_value=1;
return 0;
}
from=arg->charset();
to=conv_charset;
s=(const uchar*)arg->ptr();
se=s+arg->length();
dmaxlen=arg->length()*(conv_charset->mbmaxlen?conv_charset->mbmaxlen:1)+1;
str->alloc(dmaxlen);
d0=d=(unsigned char*)str->ptr();
de=d+dmaxlen;
while( s < se && d < de){
cnvres=from->mb_wc(from,&wc,s,se);
if (cnvres>0)
{
s+=cnvres;
}
else if (cnvres==MY_CS_ILSEQ)
{
s++;
wc='?';
}
else
break;
outp:
cnvres=to->wc_mb(to,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);
return str;
}
void Item_func_conv_charset::fix_length_and_dec()
{
/* BAR TODO: What to do here??? */
}
String *Item_func_hex::val_str(String *str) String *Item_func_hex::val_str(String *str)
{ {
if (args[0]->result_type() != STRING_RESULT) if (args[0]->result_type() != STRING_RESULT)
......
...@@ -476,6 +476,19 @@ public: ...@@ -476,6 +476,19 @@ public:
void fix_length_and_dec() { decimals = 0; max_length=3*8+7; } void fix_length_and_dec() { decimals = 0; max_length=3*8+7; }
}; };
class Item_func_conv_charset :public Item_str_func
{
CHARSET_INFO *conv_charset;
public:
Item_func_conv_charset(Item *a, CHARSET_INFO *cs) :Item_str_func(a)
{
conv_charset=cs;
}
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "conv_charset"; }
};
/******************************************************* /*******************************************************
Spatial functions Spatial functions
......
...@@ -1654,6 +1654,16 @@ simple_expr: ...@@ -1654,6 +1654,16 @@ simple_expr:
| CASE_SYM opt_expr WHEN_SYM when_list opt_else END | CASE_SYM opt_expr WHEN_SYM when_list opt_else END
{ $$= new Item_func_case(* $4, $2, $5 ); } { $$= new Item_func_case(* $4, $2, $5 ); }
| CONVERT_SYM '(' expr ',' cast_type ')' { $$= create_func_cast($3, $5); } | CONVERT_SYM '(' expr ',' cast_type ')' { $$= create_func_cast($3, $5); }
| CONVERT_SYM '(' expr USING IDENT ')'
{
CHARSET_INFO *cs=find_compiled_charset_by_name($5.str);
if (!cs)
{
net_printf(&current_thd->net,ER_UNKNOWN_CHARACTER_SET,$5);
YYABORT;
}
$$= new Item_func_conv_charset($3,cs);
}
| FUNC_ARG0 '(' ')' | FUNC_ARG0 '(' ')'
{ $$= ((Item*(*)(void))($1.symbol->create_func))();} { $$= ((Item*(*)(void))($1.symbol->create_func))();}
| FUNC_ARG1 '(' expr ')' | FUNC_ARG1 '(' expr ')'
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment