diff options
-rw-r--r-- | include/my_sys.h | 3 | ||||
-rw-r--r-- | mysql-test/r/type_ranges.result | 2 | ||||
-rw-r--r-- | mysys/charset.c | 6 | ||||
-rw-r--r-- | sql/item_strfunc.cc | 36 | ||||
-rw-r--r-- | sql/item_strfunc.h | 6 | ||||
-rw-r--r-- | sql/set_var.cc | 2 | ||||
-rw-r--r-- | sql/sql_lex.cc | 3 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 16 |
8 files changed, 51 insertions, 23 deletions
diff --git a/include/my_sys.h b/include/my_sys.h index c4fc157e6f2..b23de114ede 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -211,7 +211,8 @@ extern const char *get_charset_name(uint cs_number); extern CHARSET_INFO *get_charset(uint cs_number, myf flags); extern my_bool set_default_charset(uint cs, myf flags); extern CHARSET_INFO *get_charset_by_name(const char *cs_name, myf flags); -extern CHARSET_INFO *get_charset_by_csname(const char *cs_name, myf flags); +extern CHARSET_INFO *get_charset_by_csname(const char *cs_name, + uint cs_flags, myf my_flags); extern my_bool set_default_charset_by_name(const char *cs_name, myf flags); extern void free_charsets(void); extern char *list_charsets(myf want_flags); /* my_free() this string... */ diff --git a/mysql-test/r/type_ranges.result b/mysql-test/r/type_ranges.result index 8215977ea39..1b2c775509e 100644 --- a/mysql-test/r/type_ranges.result +++ b/mysql-test/r/type_ranges.result @@ -233,7 +233,7 @@ auto bigint(17) unsigned binary PRI 0 select,insert,update,references t1 bigint(1) binary 0 select,insert,update,references t2 char(1) latin1 select,insert,update,references t3 mediumtext latin1 select,insert,update,references -t4 mediumblob binary select,insert,update,references +t4 mediumtext character set latin1 latin1_bin select,insert,update,references select * from t2; auto t1 t2 t3 t4 11 1 a aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb diff --git a/mysys/charset.c b/mysys/charset.c index c5d86f9c856..cfe1dcefcaf 100644 --- a/mysys/charset.c +++ b/mysys/charset.c @@ -572,7 +572,9 @@ CHARSET_INFO *get_charset_by_name(const char *cs_name, myf flags) } -CHARSET_INFO *get_charset_by_csname(const char *cs_name, myf flags) +CHARSET_INFO *get_charset_by_csname(const char *cs_name, + uint cs_flags, + myf flags) { CHARSET_INFO *cs=NULL; CHARSET_INFO **css; @@ -580,7 +582,7 @@ CHARSET_INFO *get_charset_by_csname(const char *cs_name, myf flags) for (css= all_charsets; css < all_charsets+255; ++css) { - if ( css[0] && (css[0]->state & MY_CS_PRIMARY) && + if ( css[0] && (css[0]->state & cs_flags) && css[0]->csname && !strcmp(css[0]->csname, cs_name)) { cs= css[0]->number ? get_internal_charset(css[0]->number,flags) : NULL; diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 68f186982ed..5738f217063 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -2181,12 +2181,15 @@ String *Item_func_set_collation::val_str(String *str) str=args[0]->val_str(str); if ((null_value=args[0]->null_value)) return 0; - str->set_charset(set_collation); + str->set_charset(charset()); return str; } bool Item_func_set_collation::fix_fields(THD *thd,struct st_table_list *tables, Item **ref) { + CHARSET_INFO *set_collation; + String tmp, *str; + const char *colname; char buff[STACK_BUFF_ALLOC]; // Max argument in function used_tables_cache=0; const_item_cache=1; @@ -2195,17 +2198,32 @@ bool Item_func_set_collation::fix_fields(THD *thd,struct st_table_list *tables, return 0; // Fatal error if flag is set! if (args[0]->fix_fields(thd, tables, args) || args[0]->check_cols(1)) return 1; - maybe_null=args[0]->maybe_null; + if (args[0]->fix_fields(thd, tables, args) || args[0]->check_cols(1)) + return 2; + maybe_null=args[0]->maybe_null || args[1]->maybe_null; + + str= args[1]->val_str(&tmp); + colname= str->c_ptr(); + if (!strncmp(colname,"BINARY",6)) + set_collation= get_charset_by_csname(args[0]->charset()->csname, + MY_CS_BINSORT,MYF(0)); + else + set_collation= get_charset_by_name(colname,MYF(0)); + + if (!set_collation) + { + my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), str->c_ptr()); + return 1; + } + if (strcmp(args[0]->charset()->csname,set_collation->csname)) { - if (strcmp(set_collation->name,"binary")) - { - my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0), - set_collation->name,args[0]->charset()->csname); - return 1; - } + my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0), + set_collation->name,args[0]->charset()->csname); + return 1; } set_charset(set_collation); + coercibility= COER_EXPLICIT; with_sum_func= with_sum_func || args[0]->with_sum_func; used_tables_cache=args[0]->used_tables(); @@ -2227,7 +2245,7 @@ bool Item_func_set_collation::eq(const Item *item, bool binary_cmp) const func_name() != item_func->func_name()) return 0; Item_func_set_collation *item_func_sc=(Item_func_set_collation*) item; - if (set_collation != item_func_sc->set_collation) + if (charset() != item_func_sc->charset()) return 0; for (uint i=0; i < arg_count ; i++) if (!args[i]->eq(item_func_sc->args[i], binary_cmp)) diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index b01787d0d20..8bfa4317698 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -581,12 +581,10 @@ public: class Item_func_set_collation :public Item_str_func { - CHARSET_INFO *set_collation; public: - Item_func_set_collation(Item *a, CHARSET_INFO *cs) :Item_str_func(a) - { set_collation=cs; } - bool fix_fields(THD *thd,struct st_table_list *tables, Item **ref); + Item_func_set_collation(Item *a, Item *b) :Item_str_func(a,b) {}; String *val_str(String *); + bool fix_fields(THD *thd,struct st_table_list *tables, Item **ref); void fix_length_and_dec() { max_length = args[0]->max_length; } bool eq(const Item *item, bool binary_cmp) const; diff --git a/sql/set_var.cc b/sql/set_var.cc index 1f31633980a..89e86471f67 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -1194,7 +1194,7 @@ bool sys_var_thd_client_charset::check(THD *thd, set_var *var) if (!(res=var->value->val_str(&str))) res= &empty_string; - if (!(tmp=get_charset_by_csname(res->c_ptr(),MYF(0)))) + if (!(tmp=get_charset_by_csname(res->c_ptr(),MY_CS_PRIMARY,MYF(0)))) { my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), res->c_ptr()); return 1; diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 9181b41be67..94c06d41634 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -578,7 +578,8 @@ int yylex(void *arg, void *yythd) */ if ((yylval->lex_str.str[0]=='_') && - (lex->charset=get_charset_by_csname(yylval->lex_str.str+1,MYF(0)))) + (lex->charset=get_charset_by_csname(yylval->lex_str.str+1, + MY_CS_PRIMARY,MYF(0)))) return(UNDERSCORE_CHARSET); else return(IDENT); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 54d70910d57..fe87a1a9a2e 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1304,7 +1304,7 @@ attribute: charset_name: ident { - if (!($$=get_charset_by_csname($1.str,MYF(0)))) + if (!($$=get_charset_by_csname($1.str,MY_CS_PRIMARY,MYF(0)))) { net_printf(YYTHD,ER_UNKNOWN_CHARACTER_SET,$1.str); YYABORT; @@ -1989,8 +1989,12 @@ 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 collation_name - { $$= new Item_func_set_collation($1,$3); }; + | expr COLLATE_SYM ident + { + $$= new Item_func_set_collation($1,new Item_string($3.str,$3.length, + YYTHD->variables.thd_charset)); + } + ; /* expressions that begin with 'expr' that do NOT follow IN_SYM */ no_in_expr: @@ -2142,7 +2146,11 @@ simple_expr: { Select->add_ftfunc_to_list((Item_func_match *) ($$=new Item_func_match_bool(*$2,$5))); } | ASCII_SYM '(' expr ')' { $$= new Item_func_ascii($3); } - | BINARY expr %prec NEG { $$= new Item_func_set_collation($2,&my_charset_bin); } + | BINARY expr %prec NEG + { + $$= new Item_func_set_collation($2,new Item_string("BINARY",6, + &my_charset_latin1)); + } | CAST_SYM '(' expr AS cast_type ')' { $$= create_func_cast($3, $5); } | CASE_SYM opt_expr WHEN_SYM when_list opt_else END { $$= new Item_func_case(* $4, $2, $5 ); } |