Commit 64d48cd6 authored by unknown's avatar unknown

SET NAMES has been extended to support optional collation:

SET NAMES <charset name> [COLLATE <collation name>]

parent b7b75213
...@@ -510,4 +510,22 @@ t1 CREATE TABLE `t1` ( ...@@ -510,4 +510,22 @@ t1 CREATE TABLE `t1` (
SHOW FIELDS FROM t1; SHOW FIELDS FROM t1;
Field Type Collation Null Key Default Extra Field Type Collation Null Key Default Extra
latin1_f char(32) latin1_bin YES NULL latin1_f char(32) latin1_bin YES NULL
SET NAMES 'latin1';
SET NAMES latin1;
SELECT charset('a'),collation('a'),coercibility('a'),'a'='A';
charset('a') collation('a') coercibility('a') 'a'='A'
latin1 latin1 2 1
SET NAMES latin1 COLLATE latin1_bin;
SET NAMES 'latin1' COLLATE 'latin1_bin';
SELECT charset('a'),collation('a'),coercibility('a'),'a'='A';
charset('a') collation('a') coercibility('a') 'a'='A'
latin1 latin1_bin 2 0
SET NAMES DEFAULT;
SELECT charset('a'),collation('a'),coercibility('a'),'a'='A';
charset('a') collation('a') coercibility('a') 'a'='A'
latin1 latin1 2 1
SET NAMES latin1 COLLATE koi8r;
COLLATION 'koi8r' is not valid for CHARACTER SET 'latin1'
SET NAMES 'DEFAULT';
Unknown character set: 'DEFAULT'
DROP TABLE t1; DROP TABLE t1;
...@@ -127,4 +127,18 @@ ALTER TABLE t1 CHARACTER SET latin1 COLLATE latin1_bin; ...@@ -127,4 +127,18 @@ ALTER TABLE t1 CHARACTER SET latin1 COLLATE latin1_bin;
SHOW CREATE TABLE t1; SHOW CREATE TABLE t1;
SHOW FIELDS FROM t1; SHOW FIELDS FROM t1;
SET NAMES 'latin1';
SET NAMES latin1;
SELECT charset('a'),collation('a'),coercibility('a'),'a'='A';
SET NAMES latin1 COLLATE latin1_bin;
SET NAMES 'latin1' COLLATE 'latin1_bin';
SELECT charset('a'),collation('a'),coercibility('a'),'a'='A';
SET NAMES DEFAULT;
SELECT charset('a'),collation('a'),coercibility('a'),'a'='A';
--error 1251
SET NAMES latin1 COLLATE koi8r;
--error 1115
SET NAMES 'DEFAULT';
DROP TABLE t1; DROP TABLE t1;
...@@ -104,7 +104,7 @@ sys_var_str sys_charset("character_set", ...@@ -104,7 +104,7 @@ sys_var_str sys_charset("character_set",
sys_check_charset, sys_check_charset,
sys_update_charset, sys_update_charset,
sys_set_default_charset); sys_set_default_charset);
sys_var_thd_client_charset sys_client_charset("client_character_set"); sys_var_client_collation sys_client_collation("client_collation");
sys_var_thd_conv_charset sys_convert_charset("convert_character_set"); sys_var_thd_conv_charset sys_convert_charset("convert_character_set");
sys_var_bool_ptr sys_concurrent_insert("concurrent_insert", sys_var_bool_ptr sys_concurrent_insert("concurrent_insert",
&myisam_concurrent_insert); &myisam_concurrent_insert);
...@@ -332,7 +332,7 @@ sys_var *sys_variables[]= ...@@ -332,7 +332,7 @@ sys_var *sys_variables[]=
&sys_binlog_cache_size, &sys_binlog_cache_size,
&sys_buffer_results, &sys_buffer_results,
&sys_bulk_insert_buff_size, &sys_bulk_insert_buff_size,
&sys_client_charset, &sys_client_collation,
&sys_concurrent_insert, &sys_concurrent_insert,
&sys_connect_timeout, &sys_connect_timeout,
&sys_convert_charset, &sys_convert_charset,
...@@ -439,7 +439,7 @@ struct show_var_st init_vars[]= { ...@@ -439,7 +439,7 @@ struct show_var_st init_vars[]= {
{sys_bulk_insert_buff_size.name,(char*) &sys_bulk_insert_buff_size,SHOW_SYS}, {sys_bulk_insert_buff_size.name,(char*) &sys_bulk_insert_buff_size,SHOW_SYS},
{sys_charset.name, (char*) &sys_charset, SHOW_SYS}, {sys_charset.name, (char*) &sys_charset, SHOW_SYS},
{"character_sets", (char*) &charsets_list, SHOW_CHAR_PTR}, {"character_sets", (char*) &charsets_list, SHOW_CHAR_PTR},
{sys_client_charset.name, (char*) &sys_client_charset, SHOW_SYS}, {sys_client_collation.name, (char*) &sys_client_collation, SHOW_SYS},
{sys_concurrent_insert.name,(char*) &sys_concurrent_insert, SHOW_SYS}, {sys_concurrent_insert.name,(char*) &sys_concurrent_insert, SHOW_SYS},
{sys_connect_timeout.name, (char*) &sys_connect_timeout, SHOW_SYS}, {sys_connect_timeout.name, (char*) &sys_connect_timeout, SHOW_SYS},
{sys_convert_charset.name, (char*) &sys_convert_charset, SHOW_SYS}, {sys_convert_charset.name, (char*) &sys_convert_charset, SHOW_SYS},
...@@ -1177,7 +1177,7 @@ byte *sys_var_thd_conv_charset::value_ptr(THD *thd, enum_var_type type) ...@@ -1177,7 +1177,7 @@ byte *sys_var_thd_conv_charset::value_ptr(THD *thd, enum_var_type type)
} }
bool sys_var_thd_client_charset::check(THD *thd, set_var *var) bool sys_var_client_collation::check(THD *thd, set_var *var)
{ {
CHARSET_INFO *tmp; CHARSET_INFO *tmp;
char buff[80]; char buff[80];
...@@ -1187,14 +1187,14 @@ bool sys_var_thd_client_charset::check(THD *thd, set_var *var) ...@@ -1187,14 +1187,14 @@ bool sys_var_thd_client_charset::check(THD *thd, set_var *var)
{ {
var->save_result.charset= (var->type != OPT_GLOBAL ? var->save_result.charset= (var->type != OPT_GLOBAL ?
global_system_variables.thd_charset global_system_variables.thd_charset
: default_charset_info); : thd->db_charset);
return 0; return 0;
} }
if (!(res=var->value->val_str(&str))) if (!(res=var->value->val_str(&str)))
res= &empty_string; res= &empty_string;
if (!(tmp=get_charset_by_csname(res->c_ptr(),MY_CS_PRIMARY,MYF(0)))) if (!(tmp=get_charset_by_name(res->c_ptr(),MYF(0))))
{ {
my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), res->c_ptr()); my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), res->c_ptr());
return 1; return 1;
...@@ -1203,7 +1203,7 @@ bool sys_var_thd_client_charset::check(THD *thd, set_var *var) ...@@ -1203,7 +1203,7 @@ bool sys_var_thd_client_charset::check(THD *thd, set_var *var)
return 0; return 0;
} }
bool sys_var_thd_client_charset::update(THD *thd, set_var *var) bool sys_var_client_collation::update(THD *thd, set_var *var)
{ {
if (var->type == OPT_GLOBAL) if (var->type == OPT_GLOBAL)
global_system_variables.thd_charset= var->save_result.charset; global_system_variables.thd_charset= var->save_result.charset;
...@@ -1217,12 +1217,12 @@ bool sys_var_thd_client_charset::update(THD *thd, set_var *var) ...@@ -1217,12 +1217,12 @@ bool sys_var_thd_client_charset::update(THD *thd, set_var *var)
} }
byte *sys_var_thd_client_charset::value_ptr(THD *thd, enum_var_type type) byte *sys_var_client_collation::value_ptr(THD *thd, enum_var_type type)
{ {
CHARSET_INFO *cs= ((type == OPT_GLOBAL) ? CHARSET_INFO *cs= ((type == OPT_GLOBAL) ?
global_system_variables.thd_charset : global_system_variables.thd_charset :
thd->variables.thd_charset); thd->variables.thd_charset);
return cs ? (byte*) cs->csname : (byte*) ""; return cs ? (byte*) cs->name : (byte*) "";
} }
......
...@@ -423,10 +423,10 @@ class sys_var_thd_conv_charset :public sys_var_thd ...@@ -423,10 +423,10 @@ class sys_var_thd_conv_charset :public sys_var_thd
bool check_default(enum_var_type type) { return 0; } bool check_default(enum_var_type type) { return 0; }
}; };
class sys_var_thd_client_charset :public sys_var_thd class sys_var_client_collation :public sys_var_thd
{ {
public: public:
sys_var_thd_client_charset(const char *name_arg) :sys_var_thd(name_arg) sys_var_client_collation(const char *name_arg) :sys_var_thd(name_arg)
{} {}
bool check(THD *thd, set_var *var); bool check(THD *thd, set_var *var);
bool update(THD *thd, set_var *var); bool update(THD *thd, set_var *var);
......
...@@ -635,6 +635,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); ...@@ -635,6 +635,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%type <lex_user> user grant_user %type <lex_user> user grant_user
%type <charset> %type <charset>
opt_collate
charset_name charset_name
charset_name_or_default charset_name_or_default
collation_name collation_name
...@@ -1302,7 +1303,7 @@ attribute: ...@@ -1302,7 +1303,7 @@ attribute:
charset_name: charset_name:
ident ident_or_text
{ {
if (!($$=get_charset_by_csname($1.str,MY_CS_PRIMARY,MYF(0)))) if (!($$=get_charset_by_csname($1.str,MY_CS_PRIMARY,MYF(0))))
{ {
...@@ -1316,7 +1317,7 @@ charset_name_or_default: ...@@ -1316,7 +1317,7 @@ charset_name_or_default:
| DEFAULT { $$=NULL; } ; | DEFAULT { $$=NULL; } ;
collation_name: collation_name:
ident ident_or_text
{ {
if (!($$=get_charset_by_name($1.str,MYF(0)))) if (!($$=get_charset_by_name($1.str,MYF(0))))
{ {
...@@ -1325,6 +1326,11 @@ collation_name: ...@@ -1325,6 +1326,11 @@ collation_name:
} }
}; };
opt_collate:
/* empty */ { $$=NULL; }
| COLLATE_SYM collation_name { $$=$2; }
;
collation_name_or_default: collation_name_or_default:
collation_name { $$=$1; } collation_name { $$=$1; }
| DEFAULT { $$=NULL; } ; | DEFAULT { $$=NULL; } ;
...@@ -1989,7 +1995,7 @@ expr_expr: ...@@ -1989,7 +1995,7 @@ expr_expr:
{ $$= new Item_date_add_interval($1,$3,$4,0); } { $$= new Item_date_add_interval($1,$3,$4,0); }
| expr '-' interval_expr interval | expr '-' interval_expr interval
{ $$= new Item_date_add_interval($1,$3,$4,1); } { $$= new Item_date_add_interval($1,$3,$4,1); }
| expr COLLATE_SYM ident | expr COLLATE_SYM ident_or_text
{ {
$$= new Item_func_set_collation($1,new Item_string($3.str,$3.length, $$= new Item_func_set_collation($1,new Item_string($3.str,$3.length,
YYTHD->variables.thd_charset)); YYTHD->variables.thd_charset));
...@@ -4216,12 +4222,26 @@ option_value: ...@@ -4216,12 +4222,26 @@ option_value:
find_sys_var("convert_character_set"), find_sys_var("convert_character_set"),
$4)); $4));
} }
| NAMES_SYM opt_equal set_expr_or_default | NAMES_SYM charset_name_or_default opt_collate
{ {
LEX *lex=Lex; THD* thd= YYTHD;
LEX *lex= &thd->lex;
system_variables vars= thd->variables;
CHARSET_INFO *cs= $2 ? $2 : thd->db_charset;
CHARSET_INFO *cl= $3 ? $3 : cs;
if ((cl != cs) && strcmp(cs->csname,cl->csname))
{
net_printf(YYTHD,ER_COLLATION_CHARSET_MISMATCH,
cl->name,cs->csname);
YYABORT;
}
Item_string *csname= new Item_string(cl->name,
strlen(cl->name),
&my_charset_latin1);
lex->var_list.push_back(new set_var(lex->option_type, lex->var_list.push_back(new set_var(lex->option_type,
find_sys_var("client_character_set"), find_sys_var("client_collation"),
$3)); csname));
} }
| PASSWORD equal text_or_password | PASSWORD equal text_or_password
{ {
......
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