diff options
author | bar@bar.mysql.r18.ru <> | 2003-03-05 12:37:39 +0400 |
---|---|---|
committer | bar@bar.mysql.r18.ru <> | 2003-03-05 12:37:39 +0400 |
commit | 4f930a7c2a5bc25a9651f3340fc8e234a1f1383c (patch) | |
tree | a674ef2b385da9ac117d9477fa498143f627ece2 | |
parent | a95c0240678d4066faf71fd56ea7353ac076e680 (diff) | |
download | mariadb-git-4f930a7c2a5bc25a9651f3340fc8e234a1f1383c.tar.gz |
SET NAMES has been extended to support optional collation:
SET NAMES <charset name> [COLLATE <collation name>]
-rw-r--r-- | mysql-test/r/ctype_collate.result | 18 | ||||
-rw-r--r-- | mysql-test/t/ctype_collate.test | 14 | ||||
-rw-r--r-- | sql/set_var.cc | 18 | ||||
-rw-r--r-- | sql/set_var.h | 4 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 34 |
5 files changed, 70 insertions, 18 deletions
diff --git a/mysql-test/r/ctype_collate.result b/mysql-test/r/ctype_collate.result index 4217bd5de23..4e48a94bb57 100644 --- a/mysql-test/r/ctype_collate.result +++ b/mysql-test/r/ctype_collate.result @@ -510,4 +510,22 @@ t1 CREATE TABLE `t1` ( SHOW FIELDS FROM t1; Field Type Collation Null Key Default Extra 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; diff --git a/mysql-test/t/ctype_collate.test b/mysql-test/t/ctype_collate.test index 26a18c5f279..3dc6d3a2dfe 100644 --- a/mysql-test/t/ctype_collate.test +++ b/mysql-test/t/ctype_collate.test @@ -127,4 +127,18 @@ ALTER TABLE t1 CHARACTER SET latin1 COLLATE latin1_bin; SHOW CREATE TABLE 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; diff --git a/sql/set_var.cc b/sql/set_var.cc index 89e86471f67..0c73da992e1 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -104,7 +104,7 @@ sys_var_str sys_charset("character_set", sys_check_charset, sys_update_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_bool_ptr sys_concurrent_insert("concurrent_insert", &myisam_concurrent_insert); @@ -332,7 +332,7 @@ sys_var *sys_variables[]= &sys_binlog_cache_size, &sys_buffer_results, &sys_bulk_insert_buff_size, - &sys_client_charset, + &sys_client_collation, &sys_concurrent_insert, &sys_connect_timeout, &sys_convert_charset, @@ -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_charset.name, (char*) &sys_charset, SHOW_SYS}, {"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_connect_timeout.name, (char*) &sys_connect_timeout, 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) } -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; char buff[80]; @@ -1187,14 +1187,14 @@ bool sys_var_thd_client_charset::check(THD *thd, set_var *var) { var->save_result.charset= (var->type != OPT_GLOBAL ? global_system_variables.thd_charset - : default_charset_info); + : thd->db_charset); return 0; } if (!(res=var->value->val_str(&str))) 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()); return 1; @@ -1203,7 +1203,7 @@ bool sys_var_thd_client_charset::check(THD *thd, set_var *var) 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) 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) } -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) ? global_system_variables.thd_charset : thd->variables.thd_charset); - return cs ? (byte*) cs->csname : (byte*) ""; + return cs ? (byte*) cs->name : (byte*) ""; } diff --git a/sql/set_var.h b/sql/set_var.h index d80285d0e40..b84e0b888e2 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -423,10 +423,10 @@ public: 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: - 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 update(THD *thd, set_var *var); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index fe87a1a9a2e..e5d94c30521 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -635,6 +635,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %type <lex_user> user grant_user %type <charset> + opt_collate charset_name charset_name_or_default collation_name @@ -1302,7 +1303,7 @@ attribute: charset_name: - ident + ident_or_text { if (!($$=get_charset_by_csname($1.str,MY_CS_PRIMARY,MYF(0)))) { @@ -1316,7 +1317,7 @@ charset_name_or_default: | DEFAULT { $$=NULL; } ; collation_name: - ident + ident_or_text { if (!($$=get_charset_by_name($1.str,MYF(0)))) { @@ -1325,6 +1326,11 @@ collation_name: } }; +opt_collate: + /* empty */ { $$=NULL; } + | COLLATE_SYM collation_name { $$=$2; } + ; + collation_name_or_default: collation_name { $$=$1; } | DEFAULT { $$=NULL; } ; @@ -1989,7 +1995,7 @@ expr_expr: { $$= new Item_date_add_interval($1,$3,$4,0); } | expr '-' interval_expr interval { $$= 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, YYTHD->variables.thd_charset)); @@ -4216,12 +4222,26 @@ option_value: find_sys_var("convert_character_set"), $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, - find_sys_var("client_character_set"), - $3)); + find_sys_var("client_collation"), + csname)); } | PASSWORD equal text_or_password { |