From faaddbd21495900c9599d226428bb441aeff10ab Mon Sep 17 00:00:00 2001 From: "bar@bar.mysql.r18.ru" <> Date: Thu, 22 Aug 2002 18:12:45 +0500 Subject: [PATCH] Stupid bug fixes in sql_yacc.cc New class Item_func_set_collation() Fixed that "SELECT CONVERT(expr USING charset) GROUP BY 1" was not working New COLLATION syntax: COLLATE latin1 --- mysql-test/r/ctype_many.result | 59 ++++++++++++++++++++++++++++++++++ mysql-test/t/ctype_many.test | 2 ++ sql/item_strfunc.cc | 29 +++++++++++++++++ sql/item_strfunc.h | 22 ++++++++++--- sql/lex.h | 1 + sql/sql_yacc.yy | 18 ++++++++--- 6 files changed, 123 insertions(+), 8 deletions(-) diff --git a/mysql-test/r/ctype_many.result b/mysql-test/r/ctype_many.result index 7a09c008309..ddc3989282b 100644 --- a/mysql-test/r/ctype_many.result +++ b/mysql-test/r/ctype_many.result @@ -157,6 +157,65 @@ INSERT INTO t1 (koi8_ru_f,comment) VALUES (' INSERT INTO t1 (koi8_ru_f,comment) VALUES ('','CYR CAPIT E'); INSERT INTO t1 (koi8_ru_f,comment) VALUES ('','CYR CAPIT YU'); INSERT INTO t1 (koi8_ru_f,comment) VALUES ('','CYR CAPIT YA'); +SELECT CONVERT(koi8_ru_f USING utf8),MIN(comment),COUNT(*) FROM t1 GROUP BY 1; +CONVERT(koi8_ru_f USING utf8) MIN(comment) COUNT(*) +a LAT CAPIT A 2 +b LAT CAPIT B 2 +c LAT CAPIT C 2 +d LAT CAPIT D 2 +e LAT CAPIT E 2 +f LAT CAPIT F 2 +g LAT CAPIT G 2 +h LAT CAPIT H 2 +i LAT CAPIT I 2 +j LAT CAPIT J 2 +k LAT CAPIT K 2 +l LAT CAPIT L 2 +m LAT CAPIT M 2 +n LAT CAPIT N 2 +o LAT CAPIT O 2 +p LAT CAPIT P 2 +q LAT CAPIT Q 2 +r LAT CAPIT R 2 +s LAT CAPIT S 2 +t LAT CAPIT T 2 +u LAT CAPIT U 2 +v LAT CAPIT V 2 +w LAT CAPIT W 2 +x LAT CAPIT X 2 +y LAT CAPIT Y 2 +z LAT CAPIT Z 2 +а CYR CAPIT A 2 +б CYR CAPIT BE 2 +в CYR CAPIT VE 2 +г CYR CAPIT GE 2 +д CYR CAPIT DE 2 +е CYR CAPIT IE 4 +ж CYR CAPIT ZHE 2 +з CYR CAPIT ZE 2 +и CYR CAPIT I 2 +к CYR CAPIT KA 2 +л CYR CAPIT EL 2 +м CYR CAPIT EM 2 +н CYR CAPIT EN 2 +о CYR CAPIT O 2 +п CYR CAPIT PE 2 +р CYR CAPIT ER 2 +с CYR CAPIT ES 2 +т CYR CAPIT TE 2 +у CYR CAPIT U 2 +ф CYR CAPIT EF 2 +х CYR CAPIT HA 2 +ц CYR CAPIT TSE 2 +ч CYR CAPIT CHE 2 +ш CYR CAPIT SHA 2 +щ CYR CAPIT SCHA 2 +ъ CYR CAPIT HARD SIGN 2 +ы CYR CAPIT YERU 2 +ь CYR CAPIT SOFT SIGN 2 +э CYR CAPIT E 2 +ю CYR CAPIT YU 2 +я CYR CAPIT YA 2 ALTER TABLE t1 ADD utf8_f CHAR(32) CHARACTER SET utf8 NOT NULL; UPDATE t1 SET utf8_f=CONVERT(koi8_ru_f USING utf8); SELECT * FROM t1; diff --git a/mysql-test/t/ctype_many.test b/mysql-test/t/ctype_many.test index 572784b8d34..1e89b1419d2 100644 --- a/mysql-test/t/ctype_many.test +++ b/mysql-test/t/ctype_many.test @@ -133,6 +133,8 @@ INSERT INTO t1 (koi8_ru_f,comment) VALUES (' INSERT INTO t1 (koi8_ru_f,comment) VALUES ('','CYR CAPIT YU'); INSERT INTO t1 (koi8_ru_f,comment) VALUES ('','CYR CAPIT YA'); +SELECT CONVERT(koi8_ru_f USING utf8),MIN(comment),COUNT(*) FROM t1 GROUP BY 1; + ALTER TABLE t1 ADD utf8_f CHAR(32) CHARACTER SET utf8 NOT NULL; UPDATE t1 SET utf8_f=CONVERT(koi8_ru_f USING utf8); diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 1aee4e7d553..b5b9ed2931e 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1843,9 +1843,11 @@ outp: void Item_func_conv_charset::fix_length_and_dec() { max_length = args[0]->max_length*(conv_charset->mbmaxlen?conv_charset->mbmaxlen:1); + str_value.set_charset(conv_charset); } + String *Item_func_conv_charset3::val_str(String *str) { my_wc_t wc; @@ -1938,6 +1940,33 @@ void Item_func_conv_charset3::fix_length_and_dec() max_length = args[0]->max_length; } +String *Item_func_set_collation::val_str(String *str) +{ + str=args[0]->val_str(str); + null_value=args[0]->null_value; + str->set_charset(set_collation); + return str; +} + +bool Item_func_set_collation::fix_fields(THD *thd,struct st_table_list *tables) +{ + char buff[STACK_BUFF_ALLOC]; // Max argument in function + binary=0; + used_tables_cache=0; + const_item_cache=1; + + if (thd && check_stack_overrun(thd,buff)) + return 0; // Fatal error if flag is set! + if (args[0]->fix_fields(thd, tables, args)) + return 1; + maybe_null=args[0]->maybe_null; + binary=args[0]->binary; + const_item_cache=args[0]->const_item(); + str_value.set_charset(set_collation); + fix_length_and_dec(); + return 0; +} + String *Item_func_charset::val_str(String *str) { diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 7b5bd7ae90b..7f82cd3b5de 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -472,7 +472,7 @@ class Item_func_export_set: public Item_str_func const char *func_name() const { return "export_set"; } }; - class Item_func_inet_ntoa : public Item_str_func +class Item_func_inet_ntoa : public Item_str_func { public: Item_func_inet_ntoa(Item *a) :Item_str_func(a) @@ -488,15 +488,29 @@ 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; - } + { conv_charset=cs; } bool fix_fields(THD *thd,struct st_table_list *tables); String *val_str(String *); void fix_length_and_dec(); const char *func_name() const { return "conv_charset"; } }; +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); + String *val_str(String *); + void fix_length_and_dec() + { + max_length = args[0]->max_length; + str_value.set_charset(set_collation); + } + const char *func_name() const { return "set_collation"; } +}; + class Item_func_conv_charset3 :public Item_str_func { public: diff --git a/sql/lex.h b/sql/lex.h index c41ad8c1d44..cd25c3883fe 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -89,6 +89,7 @@ static SYMBOL symbols[] = { { "CHECKSUM", SYM(CHECKSUM_SYM),0,0}, { "CIPHER", SYM(CIPHER_SYM),0,0}, { "CLOSE", SYM(CLOSE_SYM),0,0}, + { "COLLATE", SYM(COLLATE_SYM),0,0}, { "COLUMN", SYM(COLUMN_SYM),0,0}, { "COLUMNS", SYM(COLUMNS),0,0}, { "COMMENT", SYM(COMMENT_SYM),0,0}, diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 160bc253dc9..01894bfb7ad 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -167,6 +167,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token CHECK_SYM %token CIPHER %token COMMITTED_SYM +%token COLLATE_SYM %token COLUMNS %token COLUMN_SYM %token CONCURRENT @@ -522,7 +523,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %left '*' '/' '%' %left NEG '~' %right NOT -%right BINARY +%right BINARY COLLATE_SYM %type IDENT TEXT_STRING REAL_NUM FLOAT_NUM NUM LONG_NUM HEX_NUM LEX_HOSTNAME @@ -1129,7 +1130,7 @@ charset: { if (!(Lex->charset=get_charset_by_name($1.str,MYF(0)))) { - net_printf(¤t_thd->net,ER_UNKNOWN_CHARACTER_SET,$1); + net_printf(¤t_thd->net,ER_UNKNOWN_CHARACTER_SET,$1.str); YYABORT; } }; @@ -1658,7 +1659,16 @@ expr_expr: | expr '+' INTERVAL_SYM expr interval { $$= new Item_date_add_interval($1,$4,$5,0); } | expr '-' INTERVAL_SYM expr interval - { $$= new Item_date_add_interval($1,$4,$5,1); }; + { $$= new Item_date_add_interval($1,$4,$5,1); } + | expr COLLATE_SYM ident + { + if (!(Lex->charset=get_charset_by_name($3.str,MYF(0)))) + { + net_printf(¤t_thd->net,ER_UNKNOWN_CHARACTER_SET,$3.str); + YYABORT; + } + $$= new Item_func_set_collation($1,Lex->charset); + }; /* expressions that begin with 'expr' that do NOT follow IN_SYM */ no_in_expr: @@ -3446,7 +3456,7 @@ option_value: CONVERT *tmp; if (!(tmp=get_convert_set($3.str))) { - net_printf(¤t_thd->net,ER_UNKNOWN_CHARACTER_SET,$3); + net_printf(¤t_thd->net,ER_UNKNOWN_CHARACTER_SET,$3.str); YYABORT; } current_thd->convert_set=tmp;